View Javadoc
1   /**
2    * Redistribution and use of this software and associated documentation ("Software"), with or
3    * without modification, are permitted provided that the following conditions are met:
4    *
5    * 1. Redistributions of source code must retain copyright statements and notices. Redistributions
6    * must also contain a copy of this document.
7    *
8    * 2. Redistributions in binary form must reproduce the above copyright notice, this list of
9    * conditions and the following disclaimer in the documentation and/or other materials provided with
10   * the distribution.
11   *
12   * 3. The name "Exolab" must not be used to endorse or promote products derived from this Software
13   * without prior written permission of Intalio, Inc. For written permission, please contact
14   * info@exolab.org.
15   *
16   * 4. Products derived from this Software may not be called "Exolab" nor may "Exolab" appear in
17   * their names without prior written permission of Intalio, Inc. Exolab is a registered trademark of
18   * Intalio, Inc.
19   *
20   * 5. Due credit should be given to the Exolab Project (http://www.exolab.org/).
21   *
22   * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR
23   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
24   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTALIO, INC. OR ITS
25   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
29   * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30   *
31   * Copyright 1999-2004 (C) Intalio, Inc. All Rights Reserved.
32   *
33   * $Id$
34   */
35  
36  package org.exolab.castor.xml.schema.reader;
37  
38  import org.exolab.castor.net.URILocation;
39  import org.exolab.castor.net.URIResolver;
40  import org.exolab.castor.xml.AttributeSet;
41  import org.exolab.castor.xml.XMLException;
42  import org.exolab.castor.xml.schema.Schema;
43  import org.exolab.castor.xml.schema.SchemaContext;
44  import org.exolab.castor.xml.schema.SchemaException;
45  import org.exolab.castor.xml.schema.SchemaNames;
46  import org.xml.sax.Locator;
47  import org.xml.sax.Parser;
48  
49  /**
50   * A simple unmarshaller to read included schemas. Included schemas can be cached in the original
51   * parent Schema or can be inlined in that same XML Schema as recommended by the XML Schema
52   * specification.
53   * 
54   * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a>
55   * @author <a href="mailto:blandin@intalio.com">Arnaud Blandin</a>
56   * @version $Revision$ $Date: 2006-04-25 15:08:23 -0600 (Tue, 25 Apr 2006) $
57   **/
58  public class IncludeUnmarshaller extends ComponentReader {
59  
60  
61    public IncludeUnmarshaller(final SchemaContext schemaContext, final Schema schema,
62        final AttributeSet atts, final URIResolver uriResolver, final Locator locator,
63        final SchemaUnmarshallerState state) throws XMLException {
64      super(schemaContext);
65  
66      setURIResolver(uriResolver);
67      URILocation uri = null;
68      // -- Get schemaLocation
69      String include = atts.getValue("schemaLocation");
70      if (include == null)
71        throw new SchemaException("'schemaLocation' attribute missing on 'include'");
72  
73      if (include.indexOf("\\") != -1) {
74        String err = include + " is not a valid URI as defined by IETF RFC 2396.";
75        err += "The URI must not contain '\\'.";
76        throw new SchemaException(err);
77      }
78  
79      uri = derive(locator, include);
80      if (uri != null)
81        include = uri.getAbsoluteURI();
82  
83      // -- Has this schema location been included yet?
84      if (schema.includeProcessed(include)) {
85        return;
86      } else if (include.equals(schema.getSchemaLocation())) {
87        return;
88      }
89  
90      Schema includedSchema = null;
91      boolean alreadyLoaded = false;
92  
93      // -- caching is on
94      if (state.cacheIncludedSchemas) {
95        if (uri instanceof SchemaLocation) {
96          includedSchema = ((SchemaLocation) uri).getSchema();
97          schema.cacheIncludedSchema(includedSchema);
98          alreadyLoaded = true;
99        }
100       // -- Have we already imported this XML Schema file?
101       if (state.processed(include)) {
102         includedSchema = state.getSchema(include);
103         schema.cacheIncludedSchema(includedSchema);
104         alreadyLoaded = true;
105       }
106     }
107 
108     if (includedSchema == null) {
109       includedSchema = new Schema();
110     } else {
111       state.markAsProcessed(include, includedSchema);
112     }
113 
114     // -- keep track of the schemaLocation
115     schema.addInclude(include);
116 
117     if (alreadyLoaded) {
118       return;
119     }
120 
121     Parser parser = createParser("include");
122 
123     SchemaUnmarshaller schemaUnmarshaller =
124         new SchemaUnmarshaller(getSchemaContext(), true, state, getURIResolver());
125 
126     if (state.cacheIncludedSchemas) {
127       schemaUnmarshaller.setSchema(includedSchema);
128     } else {
129       schemaUnmarshaller.setSchema(schema);
130     }
131 
132     parseSchema(parser, schemaUnmarshaller, uri, include, "include");
133 
134     if (state.cacheIncludedSchemas) {
135       String ns = includedSchema.getTargetNamespace();
136       if (ns == null || ns == "")
137         includedSchema.setTargetNamespace(schema.getTargetNamespace());
138       else if (!ns.equals(schema.getTargetNamespace()))
139         throw new SchemaException(
140             "The target namespace of the included components must be the same as the target namespace of the including schema");
141       schema.cacheIncludedSchema(includedSchema);
142     }
143   }
144 
145 
146   /**
147    * Sets the name of the element that this UnknownUnmarshaller handles
148    **/
149   public String elementName() {
150     return SchemaNames.INCLUDE;
151   }
152 
153   /**
154    * Returns the Object created by this ComponentReader
155    * 
156    * @return the Object created by this ComponentReader
157    **/
158   public Object getObject() {
159     return null;
160   }
161 
162 }