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-2003 (C) Intalio, Inc. All Rights Reserved.
32   *
33   * $Id$
34   */
35  
36  package org.exolab.castor.xml.schema;
37  
38  import org.exolab.castor.xml.Namespaces;
39  import org.exolab.castor.xml.ValidationException;
40  
41  import java.util.ArrayList;
42  import java.util.Collection;
43  import java.util.Iterator;
44  import java.util.Map;
45  import java.util.Vector;
46  import java.util.Hashtable;
47  import java.util.Enumeration;
48  
49  
50  /**
51   * A class representing an XML Schema Definition. This class also contains some Factory methods for
52   * creating Top-Level structures.
53   * 
54   * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a>
55   * @version $Revision$ $Date: 2006-04-26 13:58:52 -0600 (Wed, 26 Apr 2006) $
56   */
57  public class Schema extends Annotated {
58    /** SerialVersionUID */
59    private static final long serialVersionUID = -8130246250710502508L;
60  
61    // -----------------------------/
62    // - Class Fields / Constants -/
63    // -----------------------------/
64  
65    /*
66     * // Old schema namespaces, left here for // reference
67     * 
68     * April 2000 Working Draft Namespace = "http://www.w3.org/1999/XMLSchema";
69     * 
70     * October 2000 Candidate Release Namespace = "http://www.w3.org/2000/10/XMLSchema";
71     * 
72     */
73  
74    /**
75     * The Namespace supported by the W3C XML Schema Recommendation.
76     */
77    public static final String DEFAULT_SCHEMA_NS = "http://www.w3.org/2001/XMLSchema";
78  
79    /**
80     * The Namespace supported by the W3C XML Schema Recommendation for the built-in types: xsi:type,
81     * xsi:nil, and xsi:schemaLocation.
82     */
83    public static final String XSI_NAMESPACE = "http://www.w3.org/2001/XMLSchema-instance";
84  
85    /**
86     * Null argument error message
87     */
88    private static final String NULL_ARGUMENT =
89        "A null argument was passed to " + Schema.class.getName() + "#";
90  
91    /**
92     * The SimpleTypesFactory used by this Schema
93     */
94    private static SimpleTypesFactory simpleTypesFactory = new SimpleTypesFactory();
95  
96    // --------------------/
97    // - Member Variables -/
98    // --------------------/
99  
100   /**
101    * The attributeFormDefault property
102    **/
103   private Form _attributeFormDefault = null;
104 
105   /**
106    * The global AttribteGroups for this Schema
107    **/
108   private final Map<String, AttributeGroup> _attributeGroups =
109       new Hashtable<String, AttributeGroup>();
110 
111   /**
112    * The global attributes for this Schema
113    **/
114   private final Map<String, AttributeDecl> _attributes = new Hashtable<String, AttributeDecl>();
115 
116   /**
117    * The value of the block attribute.
118    **/
119   private BlockList _block = null;
120 
121 
122   /**
123    * A list of defined architypes
124    **/
125   private final Map<String, ComplexType> _complexTypes = new Hashtable<String, ComplexType>();
126 
127   /**
128    * The elementFormDefault attribute for this Schema
129    **/
130   private Form _elementFormDefault = null;
131 
132   /**
133    * A list of defined elements
134    **/
135   private final Map<String, ElementDecl> _elements = new Hashtable<String, ElementDecl>();
136 
137   /**
138    * The value of the final attribute.
139    **/
140   private FinalList _final = null;
141 
142   /**
143    * A list of defined top-levels groups
144    */
145   private final Map<String, ModelGroup> _groups = new Hashtable<String, ModelGroup>();
146 
147   /**
148    * A list of defined <redefine>
149    */
150   private final Map<String, RedefineSchema> _redefineSchemas =
151       new Hashtable<String, RedefineSchema>();
152 
153   /**
154    * The ID for this Schema
155    **/
156   private String _id = null;
157 
158   /**
159    * A list of imported schemas
160    **/
161   private final Map<String, Schema> _importedSchemas = new Hashtable<String, Schema>();
162 
163   /**
164    * A list of included schemas meant to be used only when the cache mechanism is enabled.
165    **/
166   private final Map<String, Schema> _cachedincludedSchemas = new Hashtable<String, Schema>();
167 
168 
169   /**
170    * A list of XML Schema files included in this schema
171    **/
172   private final Vector<String> _includedSchemas = new Vector<String>();
173 
174   /**
175    * A list of namespaces declared in this schema
176    */
177   private final Namespaces _namespaces = new Namespaces();
178 
179   /**
180    * The schemaLocation hint provided in the 'import' tag. By default the schemaLocation is the
181    * locator of the SaxUnmarshaller
182    **/
183   private String _schemaLocation = null;
184 
185   /**
186    * The namespace of this XML Schema (ie the namespace of the W3C Schema supported by this Schema).
187    **/
188   private final String _schemaNamespace;
189 
190 
191   /**
192    * A list of defined SimpleTypes
193    **/
194   private final Hashtable<String, SimpleType> _simpleTypes = new Hashtable<String, SimpleType>();
195 
196   /**
197    * The targetNamespace for this Schema
198    **/
199   private String _targetNamespace = null;
200 
201   /**
202    * The version information as specified by the version attribute
203    **/
204   private String _version = null;
205 
206   /**
207    * A reference to the master schema used when this instance of Schema is used in another schema
208    * (redefine, include or import)
209    */
210   private Schema _masterSchema = null;
211 
212   // ----------------/
213   // - Constructors -/
214   // ----------------/
215 
216   /**
217    * Creates a new Schema definition
218    */
219   public Schema() {
220     this(null, DEFAULT_SCHEMA_NS);
221   }
222 
223 
224   /**
225    * Creates a new Schema definition
226    *
227    * @param schemaNS the namespace of the XML Schema itself. Note this is not the same as the
228    *        targetNamespace.
229    */
230   public Schema(String schemaNS) {
231     this(null, schemaNS);
232   }
233 
234   /**
235    * Creates a new Schema definition
236    *
237    * @param prefix the desired namespace prefix for the schemaNS.
238    * @param schemaNamespace the namespace of the XML Schema itself. Note this is not the same as the
239    *        targetNamespace.
240    */
241   public Schema(String prefix, String schemaNamespace) {
242     super();
243 
244     if (schemaNamespace == null) {
245       _schemaNamespace = DEFAULT_SCHEMA_NS;
246     } else {
247       _schemaNamespace = schemaNamespace;
248     }
249 
250     // -- declare default namespace bindings
251     if (prefix == null) {
252       prefix = "";
253     }
254 
255     addNamespace(prefix, _schemaNamespace);
256 
257   }
258 
259   /**
260    * Adds the given attribute definition to this Schema definition
261    *
262    * @param attribute the AttributeDecl to add
263    * @sexception SchemaException if an AttributeDecl already exisits with the same name
264    **/
265   public void addAttribute(AttributeDecl attribute) throws SchemaException {
266     if (attribute == null)
267       return;
268 
269     String name = attribute.getName();
270 
271     if (attribute.getSchema() != this) {
272       String err = "invalid attempt to add an AttributeDecl which ";
273       err += "belongs to a different Schema; " + name;
274       throw new SchemaException(err);
275     }
276 
277     if ((name == null) && (attribute.isReference())) {
278       String err = "Error attempting to add a top-level AttributeDecl that "
279           + "is a reference. Top-level attributes can only be attribute declarations: "
280           + attribute.getName(false);
281       throw new SchemaException(err);
282     }
283     // -- we check if the attribute is not already present in the schema
284     // -- the attribute can be already added
285     // -- the attribute can be part of a schema redefinition
286     // -- the attribute can be part of a cached included schema
287     Object obj = getAttribute(name);
288 
289     if (obj == attribute)
290       return;
291 
292     if (obj != null) {
293       String err = "Error attempting to add an AttributeDecl to this "
294           + "Schema definition, an AttributeDecl already exists with " + "the given name: ";
295       throw new SchemaException(err + name);
296     }
297 
298     _attributes.put(name, attribute);
299     // --set the parent
300     attribute.setParent(this);
301   } // -- addAttribute
302 
303   /**
304    * Adds the given attribute group definition to this Schema definition.
305    *
306    * @param attrGroup the AttributeGroupDecl to add
307    * @exception SchemaException if an AttributeGroupDecl already exisits with the same name
308    **/
309   public void addAttributeGroup(AttributeGroupDecl attrGroup) throws SchemaException {
310     if (attrGroup == null)
311       return;
312 
313     String name = attrGroup.getName();
314 
315     // -- handle namespace prefix, if necessary
316     int idx = name.indexOf(':');
317     if (idx >= 0) {
318       String nsPrefix = name.substring(0, idx);
319       name = name.substring(idx + 1);
320       String ns = _namespaces.getNamespaceURI(nsPrefix);
321       if (ns == null) {
322         String err = "addAttributeGroup: ";
323         err += "Namespace prefix not recognized '" + nsPrefix + "'";
324         throw new IllegalArgumentException(err);
325       }
326       if (!ns.equals(_targetNamespace)) {
327         String err = "AttributeGroup has different namespace " + "than this Schema definition.";
328         throw new IllegalArgumentException(err);
329       }
330     }
331 
332     if (attrGroup.getSchema() != this) {
333       String err = "invalid attempt to add an AttributeGroup which ";
334       err += "belongs to a different Schema; " + name;
335       throw new SchemaException(err);
336     }
337 
338     Object obj = getAttributeGroup(name);
339 
340     if (obj == attrGroup)
341       return;
342     boolean redefine = attrGroup.isRedefined();
343 
344     if (obj != null && !redefine) {
345       String err = "Error attempting to add an AttributeGroup to this "
346           + "Schema definition, an AttributeGroup already exists with " + "the given name: ";
347       throw new SchemaException(err + name);
348     }
349 
350     _attributeGroups.put(name, attrGroup);
351 
352   } // -- addAttributeGroup
353 
354 
355   /**
356    * Adds the given Complextype definition to this Schema defintion
357    * 
358    * @param complexType the Complextype to add to this Schema
359    * @exception SchemaException if the Complextype does not have a name or if another Complextype
360    *            already exists with the same name
361    **/
362   public synchronized void addComplexType(ComplexType complexType) throws SchemaException {
363 
364     String name = complexType.getName();
365 
366     if (name == null) {
367       String err = "a global ComplexType must contain a name.";
368       throw new SchemaException(err);
369     }
370     if (complexType.getSchema() != this) {
371       String err = "invalid attempt to add an ComplexType which ";
372       err += "belongs to a different Schema; type name: " + name;
373       throw new SchemaException(err);
374     }
375     // -- we check if the complexType is not already present in the schema
376     // -- the complexType can be already added
377     // -- the complexType can be part of a schema redefinition
378     // -- the complexType can be part of a cached included schema
379     if (getComplexType(name) != null && !complexType.isRedefined()) {
380       String err = "a ComplexType already exists with the given name: ";
381       throw new SchemaException(err + name);
382     }
383     _complexTypes.put(name, complexType);
384     complexType.setParent(this);
385 
386   } // -- addComplextype
387 
388   /**
389    * Adds the given Element declaration to this Schema defintion
390    * 
391    * @param elementDecl the ElementDecl to add to this SchemaDef
392    * @exception SchemaException when an ElementDecl already exists with the same name as the given
393    *            ElementDecl
394    **/
395   public void addElementDecl(ElementDecl elementDecl) throws SchemaException {
396 
397     String name = elementDecl.getName(true);
398 
399     if ((name == null) && (elementDecl.isReference())) {
400       String err = "Error attempting to add a top-level Element that "
401           + "is a reference. Top-level elements can only be element declarations: "
402           + elementDecl.getName(false);
403       throw new SchemaException(err);
404     }
405 
406     if (name == null) {
407       String err = "an element declaration must contain a name.";
408       throw new SchemaException(err);
409     }
410     if (getElementDecl(name) != null) {
411       String err = "an element declaration already exists with the given name: ";
412       throw new SchemaException(err + name);
413     }
414 
415     _elements.put(name, elementDecl);
416     elementDecl.setParent(this);
417 
418   } // -- addElementDecl
419 
420   /**
421    * Adds the given Group declaration to this Schema definition
422    * 
423    * @param group the Group to add to this SchemaDef
424    * @exception SchemaException when an Group already exists with the same name as the given Group
425    **/
426   public void addModelGroup(ModelGroup group) throws SchemaException {
427 
428     String name = group.getName();
429 
430     if (name == null) {
431       String err = "a group declaration must contain a name.";
432       throw new SchemaException(err);
433     }
434 
435     if (getModelGroup(name) != null && !group.isRedefined()) {
436       String err = "a group declaration already exists with the given name: ";
437       throw new SchemaException(err + name);
438     }
439 
440     _groups.put(name, group);
441     group.setParent(this);
442   } // -- addModelGroup
443 
444   /**
445    * Adds the given redefinition of structures to this Schema definition. This structure is mainly
446    * used to allow the writing of an XML schema that contains redefinitions. The validation process
447    * is permissive since the method won't check that the XML Schema is already imported nor will it
448    * check that the redefined structures exist.
449    * 
450    * @param schema the Group to add to this SchemaDef
451    * @exception SchemaException when an redefintion already exists with the same name as the given
452    *            ElementDecl
453    **/
454   public void addRedefineSchema(RedefineSchema schema) throws SchemaException {
455 
456     String uri = schema.getSchemaLocation();
457 
458     if ((uri == null) && (schema.hasRedefinition())) {
459       String err =
460           "A <redefine> structure with no 'schemaLocation' attribute must contain only <annotation> elements";
461       throw new SchemaException(err);
462     }
463     if (_redefineSchemas.get(uri) != null) {
464       String err = "The redefinition for schema:" + uri + " can only be used once.";
465       throw new SchemaException(err);
466     }
467 
468     _redefineSchemas.put(uri, schema);
469   } // -- addModelGroup
470 
471 
472   /**
473    * Adds the given Schema definition to this Schema definition as an imported schenma
474    * 
475    * @param schema the Schema to add to this Schema as an imported schema
476    * @exception SchemaException if the Schema already exists
477    */
478   public synchronized void addImportedSchema(Schema schema) throws SchemaException {
479     String targetNamespace = schema.getTargetNamespace();
480     if (targetNamespace == null)
481       targetNamespace = "";
482     if (_importedSchemas.get(targetNamespace) != null) {
483       String err = "a Schema has already been imported with the given namespace: ";
484       throw new SchemaException(err + targetNamespace);
485     }
486     _importedSchemas.put(targetNamespace, schema);
487   } // -- addImportedSchema
488 
489   /**
490    * Caches the given Schema definition as an included XML Schema of this Schema definition.
491    * 
492    * @param schema the Schema to add to this Schema as a cached included schema.
493    * @exception SchemaException if the Schema already exists
494    */
495   public synchronized void cacheIncludedSchema(Schema schema) throws SchemaException {
496     String schemaLocation = schema.getSchemaLocation();
497     if (schemaLocation == null)
498       schemaLocation = "";
499     if (_cachedincludedSchemas.get(schemaLocation) != null) {
500       String err = "a Schema has already been included with the given schemaLocation: ";
501       throw new SchemaException(err + schemaLocation);
502     }
503     _cachedincludedSchemas.put(schemaLocation, schema);
504   } // -- addImportedSchema
505 
506 
507   /**
508    * Adds to the namespaces declared in this Schema
509    */
510   public void addNamespace(String prefix, String ns) {
511     _namespaces.addNamespace(prefix, ns);
512   } // -- setNamespaces
513 
514   /**
515    * Adds the given SimpletType definition to this Schema defintion
516    * 
517    * @param simpleType the SimpleType to add to this Schema
518    * @exception SchemaException if the SimpleType does not have a name or if another SimpleType
519    *            already exists with the same name
520    **/
521   public synchronized void addSimpleType(SimpleType simpleType) throws SchemaException {
522 
523     String name = simpleType.getName();
524 
525     if ((name == null) || (name.length() == 0)) {
526       String err =
527           "No name found for top-level SimpleType. " + " A top-level SimpleType must have a name.";
528       throw new SchemaException(err);
529     }
530 
531     if (simpleType.getSchema() != this) {
532       String err = "invalid attempt to add a SimpleType which ";
533       err += "belongs to a different Schema; type name: " + name;
534       throw new SchemaException(err);
535     }
536     if (getSimpleType(name, _targetNamespace) != null && !simpleType.isRedefined()) {
537       String err = "a SimpleType already exists with the given name: ";
538       throw new SchemaException(err + name);
539     }
540     simpleType.setParent(this);
541     _simpleTypes.put(name, simpleType);
542 
543   } // -- addSimpleType
544 
545 
546 
547   /**
548    * Creates a new ComplexType using this Schema as the owning Schema document. A call to
549    * #addComplexType must still be made in order to add the complexType to this Schema.
550    * 
551    * @return the new ComplexType
552    **/
553   public ComplexType createComplexType() {
554     return new ComplexType(this);
555   } // -- createComplexType
556 
557   /**
558    * Creates a new ComplexType using this Schema as the owning Schema document. A call to
559    * #addComplexType must still be made in order to add the complexType to this Schema.
560    * 
561    * @param name the name of the ComplexType
562    * @return the new ComplexType
563    **/
564   public ComplexType createComplexType(String name) {
565     return new ComplexType(this, name);
566   } // -- createComplexType
567 
568   /**
569    * Creates a new SimpleType using this Schema as the owning Schema document. A call to
570    * #addSimpleType must till be made in order to add the SimpleType to this Schema.
571    * 
572    * @param name the name of the SimpleType
573    * @param baseName the name of the SimpleType's base type
574    * @param derivation the name of the derivation method (""/"list"/"restriction")
575    * @return the new SimpleType.
576    **/
577   public SimpleType createSimpleType(String name, String baseName, String derivation) {
578     return simpleTypesFactory.createUserSimpleType(this, name, baseName, derivation, true);
579   } // -- createSimpleType
580 
581   /**
582    * Creates a new SimpleType using this Schema as the owning Schema document. A call to
583    * #addSimpleType must till be made in order to add the SimpleType to this Schema if the type is
584    * to be global.
585    * 
586    * @param name the name of the SimpleType
587    * @param baseType the base type of the SimpleType to create
588    * @return the new SimpleType.
589    **/
590   public SimpleType createSimpleType(String name, SimpleType baseType) {
591     return simpleTypesFactory.createUserSimpleType(this, name, baseType, "restriction");
592   } // -- createSimpleType
593 
594   /**
595    * Returns the attributeFormDefault property of this Schema.
596    *
597    * @return the attributeFormDefault property of this Schema, or null if no default Form was set.
598    *         If no default Form has been set, the user should assume Form.Unqualified.
599    **/
600   public Form getAttributeFormDefault() {
601     return _attributeFormDefault;
602   } // -- getAttributeFormDefault
603 
604   /**
605    * Returns an Enumeration of all top-level Attribute declarations
606    * 
607    * @return an Enumeration of all top-level Attribute declarations
608    **/
609   public Collection<AttributeDecl> getAttributes() {
610     Collection<AttributeDecl> result = new ArrayList<>(_attributes.size() * 2);
611 
612     result.addAll(_attributes.values());
613 
614     Collection<Schema> cachedincluded = _cachedincludedSchemas.values();
615     for (Schema includedSchema : cachedincluded) {
616       Collection<AttributeDecl> tempAtt = includedSchema.getAttributes();
617       for (AttributeDecl attributeDecl : tempAtt) {
618         result.add(attributeDecl);
619       }
620     }
621 
622     Collection<RedefineSchema> redefinition = _redefineSchemas.values();
623     for (RedefineSchema redefineSchema : redefinition) {
624       Schema tempSchema = redefineSchema.getOriginalSchema();
625       // -- a redefinition doesn't always contain a schema
626       if (tempSchema != null) {
627         // -- Sets the master schema
628         // -- The master schema will help resolving the links at runtime between
629         // -- an structure and its type.
630         tempSchema.setMasterSchema(this);
631         Collection<AttributeDecl> tempAtt = tempSchema.getAttributes();
632         for (AttributeDecl attributeDecl : tempAtt) {
633           result.add(attributeDecl);
634         }
635       }
636     }
637 
638     return result;
639   }
640 
641   /**
642    * Returns the top-level Attribute associated with the given name.
643    *
644    * @return the Attribute associated with the given name, or null if no Attribute association is
645    *         found.
646    **/
647   public AttributeDecl getAttribute(String name) {
648 
649     // -- Null?
650     if (name == null) {
651       String err = NULL_ARGUMENT + "getAttribute: " + "'name' cannot be null.";
652       throw new IllegalArgumentException(err);
653     }
654 
655     // -- Namespace prefix?
656     String canonicalName = name;
657     String nsprefix = "";
658     String ns = _targetNamespace;
659     int colon = name.indexOf(':');
660     if (colon != -1) {
661       canonicalName = name.substring(colon + 1);
662       nsprefix = name.substring(0, colon);
663       ns = _namespaces.getNamespaceURI(nsprefix);
664       if (ns == null) {
665         String err = "getAttribute: " + "Namespace prefix not recognized '" + name + "'";
666         throw new IllegalArgumentException(err);
667       }
668     }
669 
670     if ((ns == null) || (ns.equals(_targetNamespace))) {
671       AttributeDecl tempAtt = _attributes.get(canonicalName);
672       if (tempAtt == null) {
673         Collection<Schema> cacheIncluded = _cachedincludedSchemas.values();
674         boolean found = false;
675         for (Schema includedSchema : cacheIncluded) {
676           tempAtt = includedSchema.getAttribute(canonicalName);
677           if (tempAtt != null) {
678             found = true;
679             break;
680           }
681         }
682         // boolean found = false;
683         // while (cacheIncluded.hasMoreElements() && !found) {
684         // Schema temp = cacheIncluded.nextElement();
685         // tempAtt = temp.getAttribute(canonicalName);
686         // if (tempAtt != null)
687         // found = true;
688         // }
689 
690         // --look in the redefinition
691         if (!found) {
692           Iterator<RedefineSchema> redefinition = _redefineSchemas.values().iterator();
693           while (redefinition.hasNext() && !found) {
694             Schema tempSchema = redefinition.next().getOriginalSchema();
695             if (tempSchema != null) {
696               // -- Sets the master schema
697               // -- The master schema will help resolving the links at runtime between
698               // -- an structure and its type.
699               tempSchema.setMasterSchema(this);
700               tempAtt = tempSchema.getAttribute(canonicalName);
701               if (tempAtt != null)
702                 found = true;
703             }
704           }
705         }
706       }
707       return tempAtt;
708     }
709     Schema schema = getImportedSchema(ns);
710     if (schema != null) {
711       AttributeDecl att = schema.getAttribute(canonicalName);
712       return att;
713     }
714 
715     return null;
716 
717   } // -- getAttribute
718 
719 
720   /**
721    * Returns an Enumeration of all top-level AttributeGroup declarations
722    * 
723    * @return an Enumeration of all top-level AttributeGroup declarations
724    **/
725   public Collection<AttributeGroup> getAttributeGroups() {
726     Collection<AttributeGroup> result = new ArrayList<>(_attributeGroups.size() * 2);
727 
728     result.addAll(_attributeGroups.values());
729 
730     Collection<Schema> cachedincluded = _cachedincludedSchemas.values();
731     for (Schema includedSchema : cachedincluded) {
732       Collection<AttributeGroup> tempAtt = includedSchema.getAttributeGroups();
733       for (AttributeGroup attributeGroup : tempAtt) {
734         result.add(attributeGroup);
735       }
736     }
737 
738     Collection<RedefineSchema> redefinition = _redefineSchemas.values();
739     for (RedefineSchema redefineSchema : redefinition) {
740       // 1-- Add the AttributeGroups from the RedefineSchema
741       for (AttributeGroup attributeGroup : redefineSchema.enumerateAttributeGroups()) {
742         result.add(attributeGroup);
743       }
744 
745       // 2-- Add the AttributeGroups from the Original Schema of the
746       // -- RedefineSchema Structure by making sure that the AttributeGroups
747       // -- are not redefined.
748       Schema tempSchema = redefineSchema.getOriginalSchema();
749       // -- a redefinition doesn't always contain a schema
750       if (tempSchema != null) {
751         // -- Sets the master schema
752         // -- The master schema will help resolving the links at runtime between
753         // -- a structure and its type.
754         tempSchema.setMasterSchema(this);
755         for (AttributeGroup attributeGroup : tempSchema.getAttributeGroups()) {
756           boolean alreadyRedefined = true;
757           if (attributeGroup instanceof AttributeGroupDecl) {
758             alreadyRedefined = redefineSchema
759                 .hasAttributeGroupRedefinition(((AttributeGroupDecl) attributeGroup).getName());
760           }
761           if (!alreadyRedefined) {
762             result.add(attributeGroup);
763           }
764         }
765       }
766     }
767 
768     return result;
769   } // -- getAttributeGroups
770 
771   /**
772    * Returns the AttributeGroup associated with the given name.
773    *
774    * @return the AttributeGroup associated with the given name, or null if no AttributeGroup
775    *         association is found.
776    **/
777   public AttributeGroup getAttributeGroup(String name) {
778 
779     // -- Null?
780     if (name == null) {
781       String err = NULL_ARGUMENT + "getAttributeGroup: ";
782       err += "'name' cannot be null.";
783       throw new IllegalArgumentException(err);
784     }
785 
786     AttributeGroup result = null;
787     // -- Namespace prefix?
788     String canonicalName = name;
789     String nsprefix = "";
790     String ns = _targetNamespace;
791     int colon = name.indexOf(':');
792     if (colon != -1) {
793       canonicalName = name.substring(colon + 1);
794       nsprefix = name.substring(0, colon);
795       ns = _namespaces.getNamespaceURI(nsprefix);
796       if (ns == null) {
797         String err = "getAttributeGroup: ";
798         err += "Namespace prefix not recognized '" + name + "'";
799         throw new IllegalArgumentException(err);
800       }
801     }
802 
803     if ((ns == null) || (ns.equals(_targetNamespace))) {
804       result = _attributeGroups.get(canonicalName);
805 
806       if (result == null) {
807         Iterator<Schema> cacheIncluded = _cachedincludedSchemas.values().iterator();
808         boolean found = false;
809         while (cacheIncluded.hasNext() && !found) {
810           Schema temp = cacheIncluded.next();
811           result = temp.getAttributeGroup(canonicalName);
812           if (result != null) {
813             found = true;
814           }
815         }
816 
817         // --we look in the redefinitions
818         if (!found) {
819           // -- Search through the redefinition:
820           Iterator<RedefineSchema> redefinitions = getRedefineSchema().iterator();
821           while (redefinitions.hasNext() && !found) {
822             RedefineSchema redefine = redefinitions.next();
823 
824             // -- the AttributeGroup can be redefined
825             if (redefine.hasAttributeGroupRedefinition(canonicalName)) {
826               result = redefine.getAttributeGroup(canonicalName);
827               if (result != null)
828                 found = true;
829               break;
830             }
831 
832             // -- or if can be part of the Original Schema of the Redefined structures.
833             Schema schema = redefine.getOriginalSchema();
834             if (schema != null) {
835               // -- Sets the master schema
836               // -- The master schema will help resolving the links at runtime between
837               // -- an structure and its type.
838               schema.setMasterSchema(this);
839               result = schema.getAttributeGroup(name);
840             }
841           }
842         } // --end of redefinition
843       } // --result == null
844     } else {
845       Schema schema = getImportedSchema(ns);
846       if (schema != null)
847         result = schema.getAttributeGroup(canonicalName);
848     }
849 
850     return result;
851 
852   } // -- getAttributeGroup
853 
854   /**
855    * Returns the default BlockList for this Schema.
856    *
857    * @return the default BlockList for this Schema.
858    **/
859   public BlockList getBlockDefault() {
860     return _block;
861   } // -- getBlockDefault
862 
863   /**
864    * Gets a built in type's name given its code.
865    */
866   public String getBuiltInTypeName(int builtInTypeCode) {
867     return simpleTypesFactory.getBuiltInTypeName(builtInTypeCode);
868   } // -- getBuiltInTypeName
869 
870 
871   /**
872    * Returns the ComplexType of associated with the given name
873    * 
874    * @return the ComplexType of associated with the given name, or null if no ComplexType with the
875    *         given name was found.
876    **/
877   public ComplexType getComplexType(String name) {
878 
879     // -- Null?
880     if (name == null) {
881       String err = NULL_ARGUMENT + "getComplexType: ";
882       err += "'name' cannot be null.";
883       throw new IllegalArgumentException(err);
884     }
885     ComplexType result = null;
886     // -- Namespace prefix?
887     String canonicalName = name;
888     String nsprefix = "";
889     String ns = _targetNamespace;
890     int colon = name.indexOf(':');
891     if (colon != -1) {
892       canonicalName = name.substring(colon + 1);
893       nsprefix = name.substring(0, colon);
894       ns = _namespaces.getNamespaceURI(nsprefix);
895       if (ns == null) {
896         String err = "getComplexType: ";
897         err += "Namespace prefix not recognized '" + name + "'";
898         throw new IllegalArgumentException(err);
899       }
900     }
901 
902     // -- Get GetComplexType object
903     if ((ns == null) || (ns.equals(_targetNamespace))) {
904       result = _complexTypes.get(canonicalName);
905       if (result == null) {
906         boolean found = false;
907         // -- check for any included schemas that are cached
908         Iterator<Schema> cacheIncluded = _cachedincludedSchemas.values().iterator();
909         while (cacheIncluded.hasNext() && !found) {
910           Schema temp = cacheIncluded.next();
911           result = temp.getComplexType(canonicalName);
912           if (result != null)
913             found = true;
914         }
915         if (!found) {
916           // --we might face a redefinition
917           Iterator<RedefineSchema> redefinitions = getRedefineSchema().iterator();
918           while (redefinitions.hasNext() && result == null) {
919             RedefineSchema redefine = redefinitions.next();
920             // -- the ComplexType can be redefined
921             if (redefine.hasComplexTypeRedefinition(canonicalName)) {
922               result = redefine.getComplexType(canonicalName);
923 
924               if (result != null)
925                 found = true;
926               break;
927             }
928 
929             Schema schema = redefine.getOriginalSchema();
930             if (schema != null) {
931               // -- Sets the master schema
932               // -- The master schema will help resolving the links at runtime between
933               // -- an structure and its type.
934               schema.setMasterSchema(this);
935               result = schema.getComplexType(canonicalName);
936             }
937           }
938         }
939 
940       }
941     } else {
942       Schema schema = getImportedSchema(ns);
943       if (schema != null) {
944         result = schema.getComplexType(canonicalName);
945       }
946     }
947 
948     return result;
949 
950   } // -- getComplexType
951 
952   /**
953    * Returns an Enumeration of all top-level ComplexType declarations
954    * 
955    * @return an Enumeration of all top-level ComplexType declarations
956    **/
957   public Collection<ComplexType> getComplexTypes() {
958     Collection<ComplexType> result = new ArrayList<>(_complexTypes.size() * 2);
959 
960     result.addAll(_complexTypes.values());
961 
962     Collection<Schema> cachedincluded = _cachedincludedSchemas.values();
963     for (Schema includedSchema : cachedincluded) {
964       Collection<ComplexType> tempEnum = includedSchema.getComplexTypes();
965       for (ComplexType complexType : tempEnum) {
966         result.add(complexType);
967       }
968     }
969 
970     Collection<RedefineSchema> redefinition = _redefineSchemas.values();
971     for (RedefineSchema redefineSchema : redefinition) {
972       // 1-- Add the ComplexType from the RedefineSchema
973       for (ComplexType complexType : redefineSchema.enumerateComplexTypes()) {
974         result.add(complexType);
975       }
976 
977       Schema tempSchema = redefineSchema.getOriginalSchema();
978       // -- a redefinition doesn't always contain a schema
979       if (tempSchema != null) {
980         // -- Sets the master schema
981         // -- The master schema will help resolving the links at runtime between
982         // -- an structure and its type.
983         tempSchema.setMasterSchema(this);
984         Iterator<ComplexType> tempEnum = tempSchema.getComplexTypes().iterator();
985         while (tempEnum.hasNext()) {
986           ComplexType tempType = tempEnum.next();
987           if (!redefineSchema.hasComplexTypeRedefinition(tempType.getName()))
988             result.add(tempType);
989         }
990       }
991     }
992 
993     return result;
994 
995   } // -- getComplextypes
996 
997   /**
998    * Returns the ElementDecl of associated with the given name
999    * 
1000    * @return the ElementDecl of associated with the given name, or null if no ElementDecl with the
1001    *         given name was found.
1002    **/
1003   public ElementDecl getElementDecl(String name) {
1004 
1005     String ns = null;
1006     if (name == null) {
1007       String err = NULL_ARGUMENT + "getElementDecl: ";
1008       err += " 'name' can not be null";
1009       throw new IllegalArgumentException(err);
1010     }
1011     ElementDecl result = null;
1012     int idx = name.indexOf(':');
1013     if (idx >= 0) {
1014       String nsPrefix = name.substring(0, idx);
1015       name = name.substring(idx + 1);
1016       ns = _namespaces.getNamespaceURI(nsPrefix);
1017       if (ns == null) {
1018         String err = "getElementDecl: ";
1019         err += "Namespace prefix not recognized '" + nsPrefix + "'";
1020         throw new IllegalArgumentException(err);
1021       }
1022     }
1023 
1024     if ((ns == null) || (ns.equals(_targetNamespace))) {
1025       result = _elements.get(name);
1026       if (result == null) {
1027         // -- check for any included schemas that are cached
1028         Iterator<Schema> cacheIncluded = _cachedincludedSchemas.values().iterator();
1029         boolean found = false;
1030         while (cacheIncluded.hasNext() && !found) {
1031           Schema temp = cacheIncluded.next();
1032           result = temp.getElementDecl(name);
1033           if (result != null)
1034             found = true;
1035         }
1036         // --look in the redefinition
1037         if (!found) {
1038           Iterator<RedefineSchema> redefinition = _redefineSchemas.values().iterator();
1039           while (redefinition.hasNext() && !found) {
1040             Schema schema = redefinition.next().getOriginalSchema();
1041             if (schema != null) {
1042               // -- Sets the master schema
1043               // -- The master schema will help resolving the links at runtime between
1044               // -- an structure and its type.
1045               schema.setMasterSchema(this);
1046               result = schema.getElementDecl(name);
1047               if (result != null)
1048                 found = true;
1049             }
1050           }
1051         }
1052       }
1053     } else {
1054       Schema schema = getImportedSchema(ns);
1055       if (schema != null) {
1056         result = schema.getElementDecl(name);
1057       }
1058     }
1059 
1060     return result;
1061   } // --getElementDecl
1062 
1063   /**
1064    * Returns an Enumeration of all top-level element declarations
1065    * 
1066    * @return an Enumeration of all top-level element declarations
1067    **/
1068   public Collection<ElementDecl> getElementDecls() {
1069     Collection<ElementDecl> result = new ArrayList<>(_elements.size() * 2);
1070 
1071     result.addAll(_elements.values());
1072 
1073     Collection<Schema> cachedincluded = _cachedincludedSchemas.values();
1074     for (Schema includedSchema : cachedincluded) {
1075       Collection<ElementDecl> tempEnum = includedSchema.getElementDecls();
1076       for (ElementDecl elementDecl : tempEnum) {
1077         result.add(elementDecl);
1078       }
1079     }
1080 
1081     Collection<RedefineSchema> redefinition = _redefineSchemas.values();
1082     for (RedefineSchema redefineSchema : redefinition) {
1083       Schema tempSchema = redefineSchema.getOriginalSchema();
1084       // -- a redefinition doesn't always contain a schema
1085       if (tempSchema != null) {
1086         // -- Sets the master schema
1087         // -- The master schema will help resolving the links at runtime between
1088         // -- an structure and its type.
1089         tempSchema.setMasterSchema(this);
1090         Collection<ElementDecl> redefinedElementDeclarations = tempSchema.getElementDecls();
1091         for (ElementDecl elementDecl : redefinedElementDeclarations) {
1092           result.add(elementDecl);
1093         }
1094       }
1095     }
1096 
1097     return result;
1098   } // -- getElementDecls
1099 
1100   /**
1101    * Returns the elementFormDefault property of this Schema.
1102    *
1103    * @return the elementFormDefault property of this Schema, or null if no default Form was set. If
1104    *         no default Form has been set, the user should assume Form.Unqualified.
1105    **/
1106   public Form getElementFormDefault() {
1107     return _elementFormDefault;
1108   } // -- getElementFormDefault
1109 
1110   /**
1111    * Returns the default FinalList for this Schema.
1112    *
1113    * @return final the default FinalList for this Schema.
1114    **/
1115   public FinalList getFinalDefault() {
1116     return _final;
1117   } // -- getFinalDefault
1118 
1119   /**
1120    * Returns the SimpleType associated with the given name, or null if no such SimpleType exists.
1121    *
1122    * @param name the name of the SimpleType. The name may be a QName (contain a namespace prefix).
1123    * @return the SimpleType associated with the given name, or null if no such SimpleType exists.
1124    **/
1125   public SimpleType getSimpleType(String name) {
1126 
1127     // -- name must not be null
1128     if (name == null) {
1129       String err = NULL_ARGUMENT + "getSimpleType: ";
1130       err += "'name' cannot be null.";
1131       throw new IllegalArgumentException(err);
1132     }
1133 
1134     // -- Handle namespace resolution?
1135     String nsPrefix = "";
1136     String ns = null;
1137     int colon = name.indexOf(':');
1138     if (colon >= 0) {
1139       nsPrefix = name.substring(0, colon);
1140       name = name.substring(colon + 1);
1141       ns = _namespaces.getNamespaceURI(nsPrefix);
1142       if (ns == null) {
1143         String err = "getSimpleType: ";
1144         err += "Namespace prefix not recognised '" + nsPrefix + "'";
1145         err += "for simpleType:" + name;
1146         throw new IllegalArgumentException(err);
1147       }
1148     } else {
1149       ns = _namespaces.getNamespaceURI(nsPrefix);
1150     }
1151 
1152     // --if at this point, there is no namespace
1153     // --then we assume it is the targetNamespace
1154     if (ns == null)
1155       ns = _targetNamespace;
1156 
1157     return getSimpleType(name, ns);
1158 
1159   } // -- getSimpleType
1160 
1161 
1162   /**
1163    * Returns the SimpleType associated with the given name and namespace, or null if no such
1164    * SimpleType exists.
1165    *
1166    * @param name the name of the simpleType. It is an error if this name contains a prefix, it must
1167    *        be an NCName.
1168    * @param namespace the namespace URI of the simpleType.
1169    * @return the SimpleType, or null if no such SimpleType exists.
1170    **/
1171   public SimpleType getSimpleType(String name, String namespace) {
1172 
1173     // -- name must not be null
1174     if (name == null) {
1175       String err = NULL_ARGUMENT + "getSimpleType: ";
1176       err += "'name' cannot be null.";
1177       throw new IllegalArgumentException(err);
1178     }
1179 
1180     // --Is the declaration in the default namespace (if any)
1181     boolean isDefaultNS = false;
1182     if (namespace == null) {
1183       namespace = _namespaces.getNamespaceURI("");
1184       isDefaultNS = true;
1185     }
1186 
1187     // -- Get SimpleType object
1188     SimpleType result = null;
1189     if ((namespace == null) || (isDefaultNS)) {
1190 
1191       // -- first check user-defined types
1192       result = _simpleTypes.get(name);
1193       if (result != null) {
1194         // -- resolve deferred type if necessary
1195         if (result.getType() != result) {
1196           // -- can result.getType ever return null?
1197           // -- We can check, just in case.
1198           if (result.getType() != null) {
1199             result = (SimpleType) result.getType();
1200             result.setParent(this);
1201             _simpleTypes.put(name, result);
1202           }
1203         }
1204       }
1205       // -- otherwise try built-in types
1206       else {
1207         result = simpleTypesFactory.getBuiltInType(name);
1208         // if we have a built-in type not declared in the good namespace -> Exception
1209         if ((result != null) && (!_schemaNamespace.equals(namespace))) {
1210           String err = "getSimpleType: the simple type '" + name
1211               + "' has not been declared in XML Schema namespace.";
1212           throw new IllegalArgumentException(err);
1213         }
1214       }
1215     } else if (namespace.equals(_schemaNamespace)) {
1216       result = simpleTypesFactory.getBuiltInType(name);
1217       if (result == null) {
1218         String err = "getSimpleType: the simple type '" + name
1219             + "' is not a built-in type as defined in XML Schema specification.";
1220         throw new IllegalArgumentException(err);
1221       }
1222     } else if (namespace.equals(_targetNamespace)) {
1223       result = _simpleTypes.get(name);
1224       if (result != null) {
1225         // -- resolve deferred type if necessary
1226         if (result.getType() != result) {
1227           // -- can result.getType ever return null?
1228           // -- We can check, just in case.
1229           if (result.getType() != null) {
1230             result = (SimpleType) result.getType();
1231             result.setParent(this);
1232             _simpleTypes.put(name, result);
1233           }
1234         }
1235       }
1236       if (result == null) {
1237         // -- check the cached included schema
1238         Iterator<Schema> cacheIncluded = _cachedincludedSchemas.values().iterator();
1239         boolean found = false;
1240         while (cacheIncluded.hasNext() && !found) {
1241           Schema temp = cacheIncluded.next();
1242           result = temp.getSimpleType(name, namespace);
1243           if (result != null)
1244             found = true;
1245         }
1246         if (!found) {
1247           // --we might face a redefinition
1248           Iterator<RedefineSchema> redefinitions = getRedefineSchema().iterator();
1249           while (redefinitions.hasNext() && result == null) {
1250             RedefineSchema redefine = redefinitions.next();
1251             // -- the SimpleType can be redefined
1252             if (redefine.hasSimpleTypeRedefinition(name)) {
1253               result = redefine.getSimpleType(name);
1254               if (result != null)
1255                 found = true;
1256               break;
1257             }
1258 
1259             Schema schema = redefine.getOriginalSchema();
1260             if (schema != null) {
1261               // -- Sets the master schema
1262               // -- The master schema will help resolving the links at runtime between
1263               // -- an structure and its type.
1264               schema.setMasterSchema(this);
1265               result = schema.getSimpleType(name, namespace);
1266             }
1267           }
1268         }
1269       }
1270     } else {
1271       Schema schema = getImportedSchema(namespace);
1272       if (schema != null) {
1273         result = schema.getSimpleType(name, namespace);
1274       }
1275     }
1276 
1277     // -- Result could be a deferredSimpleType => getType will resolve it
1278     if (result != null)
1279       result = (SimpleType) result.getType();
1280 
1281     return result;
1282   } // -- getSimpleType
1283 
1284   /**
1285    * Returns an Enumeration of all SimpleType declarations
1286    * 
1287    * @return an Enumeration of all SimpleType declarations
1288    **/
1289   public Collection<SimpleType> getSimpleTypes() {
1290 
1291     // -- clean up "deferred types" if necessary
1292     Enumeration<SimpleType> enumeration = _simpleTypes.elements();
1293     while (enumeration.hasMoreElements()) {
1294       SimpleType type = enumeration.nextElement();
1295       if (type != type.getType()) {
1296         // -- resolve deferred type if necessary
1297         if (type.getType() != null) {
1298           String name = type.getName();
1299           type = (SimpleType) type.getType();
1300           type.setParent(this);
1301           _simpleTypes.put(name, type);
1302         }
1303       }
1304     }
1305     Collection<SimpleType> result = new ArrayList<>(_simpleTypes.size() * 2);
1306 
1307     result.addAll(_simpleTypes.values());
1308 
1309     Collection<Schema> cachedincluded = _cachedincludedSchemas.values();
1310     for (Schema includedSchema : cachedincluded) {
1311       Collection<SimpleType> tempEnum = includedSchema.getSimpleTypes();
1312       for (SimpleType simpleType : tempEnum) {
1313         result.add(simpleType);
1314       }
1315     }
1316 
1317     Collection<RedefineSchema> redefinition = _redefineSchemas.values();
1318     for (RedefineSchema redefineSchema : redefinition) {
1319       // 1-- Add the SimpleType from the RedefineSchema
1320       for (SimpleType simpleType : redefineSchema.enumerateSimpleTypes()) {
1321         result.add(simpleType);
1322       }
1323 
1324       Schema tempSchema = redefineSchema.getOriginalSchema();
1325       // -- a redefinition doesn't always contain a schema
1326       if (tempSchema != null) {
1327         // -- Sets the master schema
1328         // -- The master schema will help resolving the links at runtime between
1329         // -- an structure and its type.
1330         tempSchema.setMasterSchema(this);
1331         Collection<SimpleType> tempEnum = tempSchema.getSimpleTypes();
1332         for (SimpleType simpleType : tempEnum) {
1333           if (!redefineSchema.hasSimpleTypeRedefinition(simpleType.getName())) {
1334             result.add(simpleType);
1335           }
1336         }
1337       }
1338     }
1339 
1340     return result;
1341   } // -- getSimpleTypes
1342 
1343   /**
1344    * Returns the schemaLocation hint provided of this schema
1345    * 
1346    * @return the schemaLocation hint provided of this schema
1347    */
1348   public String getSchemaLocation() {
1349     return _schemaLocation;
1350   }
1351 
1352 
1353   /**
1354    * Returns the ModeGroup of associated with the given name
1355    * 
1356    * @return the ModelGroup of associated with the given name, or null if no ModelGroup with the
1357    *         given name was found.
1358    **/
1359   public ModelGroup getModelGroup(String name) {
1360 
1361     String ns = null;
1362     if (name == null) {
1363       String err = NULL_ARGUMENT + "getModelGroup: ";
1364       err += " 'name' can not be null";
1365       throw new IllegalArgumentException(err);
1366     }
1367     ModelGroup result = null;
1368     int idx = name.indexOf(':');
1369     if (idx >= 0) {
1370       String nsPrefix = name.substring(0, idx);
1371       name = name.substring(idx + 1);
1372       ns = _namespaces.getNamespaceURI(nsPrefix);
1373       if (ns == null) {
1374         String err = "getModelGroup: ";
1375         err += "Namespace prefix not recognized '" + nsPrefix + "'";
1376         throw new IllegalArgumentException(err);
1377       }
1378     }
1379 
1380     if ((ns == null) || (ns.equals(_targetNamespace))) {
1381       result = _groups.get(name);
1382       if (result == null) {
1383         // -- check for any included schemas that are cached
1384         Iterator<Schema> cacheIncluded = _cachedincludedSchemas.values().iterator();
1385         boolean found = false;
1386         while (cacheIncluded.hasNext() && !found) {
1387           Schema temp = cacheIncluded.next();
1388           result = temp.getModelGroup(name);
1389           if (result != null)
1390             found = true;
1391         }
1392 
1393         if (!found) {
1394           // --we might face a redefinition
1395           Iterator<RedefineSchema> redefinitions = getRedefineSchema().iterator();
1396           while (redefinitions.hasNext() && result == null) {
1397             RedefineSchema redefine = redefinitions.next();
1398             // -- the ModelGroup can be redefined
1399             if (redefine.hasGroupRedefinition(name)) {
1400               result = redefine.getModelGroup(name);
1401               if (result != null)
1402                 found = true;
1403               break;
1404             }
1405 
1406             Schema schema = redefine.getOriginalSchema();
1407             if (schema != null) {
1408               // -- Sets the master schema
1409               // -- The master schema will help resolving the links at runtime between
1410               // -- an structure and its type.
1411               schema.setMasterSchema(this);
1412               result = schema.getModelGroup(name);
1413             }
1414           }
1415         }
1416       }
1417     } else {
1418       Schema schema = getImportedSchema(ns);
1419       if (schema != null) {
1420         result = schema.getModelGroup(name);
1421       }
1422     }
1423 
1424     return result;
1425   } // --getModelGroup
1426 
1427   /**
1428    * Returns an Enumeration of all top-level ModelGroup declarations
1429    * 
1430    * @return an Enumeration of all top-level ModelGroup declarations
1431    **/
1432   public Collection<ModelGroup> getModelGroups() {
1433     Collection<ModelGroup> result = new ArrayList<>(_groups.size() * 2);
1434 
1435     result.addAll(_groups.values());
1436 
1437     Collection<Schema> cachedincluded = _cachedincludedSchemas.values();
1438     for (Schema includedSchema : cachedincluded) {
1439       Collection<ModelGroup> tempEnum = includedSchema.getModelGroups();
1440       for (ModelGroup modelGroup : tempEnum) {
1441         result.add(modelGroup);
1442       }
1443     }
1444 
1445     Collection<RedefineSchema> redefinition = _redefineSchemas.values();
1446     for (RedefineSchema redefineSchema : redefinition) {
1447       // 1-- Add the AttributeGroups from the RedefineSchema
1448       for (ModelGroup modelGroup : redefineSchema.enumerateGroups()) {
1449         result.add(modelGroup);
1450       }
1451 
1452       Schema tempSchema = redefineSchema.getOriginalSchema();
1453       // -- a redefinition doesn't always contain a schema
1454       if (tempSchema != null) {
1455         // -- Sets the master schema
1456         // -- The master schema will help resolving the links at runtime between
1457         // -- an structure and its type.
1458         tempSchema.setMasterSchema(this);
1459 
1460         for (ModelGroup modelGroup : tempSchema.getModelGroups()) {
1461           if (!redefineSchema.hasGroupRedefinition(modelGroup.getName()))
1462             result.add(modelGroup);
1463         }
1464       }
1465     }
1466 
1467     return result;
1468   } // -- getmodelGroup
1469 
1470   /**
1471    * Returns the Id for this Schema, as specified by the Id attribute, or null if no Id exists.
1472    *
1473    * @return the Id for this Scheam, or null if no Id exists
1474    **/
1475   public String getId() {
1476     return _id;
1477   } // -- getId
1478 
1479   /**
1480    * Returns the imported schemas of this schema
1481    * 
1482    * @return the hashtable of the imported schemas
1483    */
1484   public Collection<Schema> getImportedSchema() {
1485     return _importedSchemas.values();
1486   }
1487 
1488   /**
1489    * Returns the imported schema with the given namespace
1490    * 
1491    * @param ns the namespace of the imported schema to return
1492    * @return the imported schema
1493    */
1494   public Schema getImportedSchema(String ns) {
1495     return getImportedSchema(ns, null);
1496   } // -- getImportedSchema
1497 
1498   /**
1499    * Returns an enumeration of redefined schemas.
1500    * 
1501    * @return an enumeration of redefined schemas.
1502    */
1503   public Collection<RedefineSchema> getRedefineSchema() {
1504     return _redefineSchemas.values();
1505   }
1506 
1507   /**
1508    * Returns the redefined schema corresponding schemaLocation.
1509    * 
1510    * @param schemaLocation the string corresponding to the schemaLocation.
1511    * @return the redefined schema corresponding schemaLocation.
1512    */
1513   public RedefineSchema getRedefineSchema(String schemaLocation) {
1514     RedefineSchema result = _redefineSchemas.get(schemaLocation);
1515     return result;
1516   }
1517 
1518   /**
1519    * Returns the cached included schema with the given SchemaLocation
1520    * 
1521    * @param schemaLocation the schemaLocation value used as a key to store the cached included XML
1522    *        schema
1523    * @return the cached included XML schema
1524    */
1525   public Schema getCachedIncludedSchema(String schemaLocation) {
1526     return _cachedincludedSchemas.get(schemaLocation);
1527   } // -- getCachedIncludedSchema
1528 
1529   /**
1530    * Returns an enumeration of all the included schemas that are cached in this XML Schema
1531    * Definition.
1532    * 
1533    * @return an enumeration of all the included schemas that are cached in this XML Schema
1534    *         Definition.
1535    * 
1536    */
1537   public Collection<Schema> getCachedIncludedSchemas() {
1538     return _cachedincludedSchemas.values();
1539   }
1540 
1541   /**
1542    * Returns the imported schema with the given namespace
1543    * 
1544    * @param ns the namespace of the imported schema to return
1545    * @param localOnly a boolean that indicates only local imports should be searched.
1546    * @return the imported schema
1547    */
1548   public Schema getImportedSchema(String ns, boolean localOnly) {
1549     if (localOnly) {
1550       return _importedSchemas.get(ns);
1551     }
1552     return getImportedSchema(ns, null);
1553   } // -- getImportedSchema
1554 
1555   /**
1556    * Returns the imported schema with the given namespace
1557    * 
1558    * @param ns the namespace of the imported schema to return
1559    * @return the imported schema
1560    */
1561   private Schema getImportedSchema(String ns, Schema caller) {
1562 
1563     // -- Check for recursive calls
1564     if (caller == this) {
1565       return null;
1566     }
1567     // -- Associate caller if necessary
1568     if (caller == null) {
1569       caller = this;
1570     }
1571 
1572     Schema result = _importedSchemas.get(ns);
1573     // --maybe we are the schema imported is at
1574     // --a depth > 1
1575     if (result == null) {
1576       Iterator<Schema> schemas = _importedSchemas.values().iterator();
1577       while (schemas.hasNext()) {
1578         Schema temp = schemas.next();
1579         result = temp.getImportedSchema(ns, caller);
1580         if (result != null) {
1581           break;
1582         }
1583       }
1584     }
1585     return result;
1586   }
1587 
1588   /**
1589    * Returns the namespace associated with the given prefix.
1590    *
1591    * @return the namespace associated with the given prefix, or null if no associated namespace
1592    *         exists.
1593    */
1594   public final String getNamespace(String prefix) {
1595     if (prefix == null)
1596       prefix = "";
1597     return _namespaces.getNamespaceURI(prefix);
1598   } // -- getNamespace
1599 
1600   /**
1601    * Returns the namespaces declared for this Schema
1602    *
1603    * @return the namespaces declared for this Schema
1604    */
1605   public Namespaces getNamespaces() {
1606     return _namespaces;
1607   } // -- getNamespaces
1608 
1609 
1610 
1611   /**
1612    * Indicates that the given XML Schema file has been processed via an <xs:include>
1613    */
1614   public void addInclude(String include) {
1615     _includedSchemas.add(include);
1616   } // -- addInclude
1617 
1618   /**
1619    * Returns True if the given XML Schema has already been included via <xs:include>
1620    * 
1621    * @return True if the file specified has already been processed
1622    */
1623   public boolean includeProcessed(String includeFile) {
1624     return _includedSchemas.contains(includeFile);
1625   } // -- includeProcessed
1626 
1627   /**
1628    * Returns the namespace of the XML Schema <BR />
1629    * Note: This is not the same as targetNamespace. This is the namespace of "XML Schema" itself and
1630    * not the namespace of the schema that is represented by this object model (see
1631    * #getTargetNamespace).
1632    * 
1633    * @return the namespace of the XML Schema
1634    *
1635    **/
1636   public String getSchemaNamespace() {
1637     return _schemaNamespace;
1638   } // -- getSchemaNamespace
1639 
1640   /**
1641    * Returns the target namespace for this Schema, or null if no namespace has been defined.
1642    * 
1643    * @return the target namespace for this Schema, or null if no namespace has been defined
1644    **/
1645   public String getTargetNamespace() {
1646     return this._targetNamespace;
1647   } // -- getTargetNamespace
1648 
1649 
1650   /**
1651    * Returns the version information of the XML Schema definition represented by this Schema
1652    * instance.
1653    *
1654    * @return the version information of the XML Schema definition, or null if no version information
1655    *         exists.
1656    **/
1657   public String getVersion() {
1658     return _version;
1659   } // -- getVersion
1660 
1661   /**
1662    * Returns True if the namespace is known to this schema
1663    * 
1664    * @param namespaceURL the namespace URL
1665    * @return True if the namespace was declared in the schema
1666    */
1667   public boolean isKnownNamespace(String namespaceURL) {
1668     return (_namespaces.getNamespacePrefix(namespaceURL) != null);
1669   }
1670 
1671   /**
1672    * Removes the given top level ComplexType from this Schema
1673    * 
1674    * @param complexType the ComplexType to remove
1675    * @return true if the complexType has been removed, or false if the complexType wasn't top level
1676    *         or didn't exist in this Schema
1677    **/
1678   public boolean removeComplexType(ComplexType complexType) {
1679     boolean result = false;
1680     if (complexType.isTopLevel()) {
1681       if (_complexTypes.containsValue(complexType)) {
1682         _complexTypes.remove(complexType.getName());
1683         complexType.setParent(null);
1684         result = true;
1685       }
1686       if (!result) {
1687         // --check the cached included schemas
1688         Iterator<Schema> cacheIncluded = _cachedincludedSchemas.values().iterator();
1689         while (cacheIncluded.hasNext() && !result) {
1690           Schema temp = cacheIncluded.next();
1691           result = temp.removeComplexType(complexType);
1692         }
1693         // --Still false?
1694         if (!result) {
1695           // --check the redefinition
1696           Iterator<RedefineSchema> redefinitions = getRedefineSchema().iterator();
1697           while (redefinitions.hasNext() && !result) {
1698             RedefineSchema redefine = redefinitions.next();
1699             result = redefine.removeComplexType(complexType);
1700           }
1701         }
1702       }
1703     }
1704     return result;
1705   } // -- removeComplexType
1706 
1707   /**
1708    * Removes the given top level Element from this Schema
1709    * 
1710    * @param element the ElementDecl to remove
1711    * @return true if the ElementDecl has been removed, or false if the ElementDecl wasn't top level
1712    *         or didn't exist in this Schema
1713    **/
1714   public boolean removeElement(ElementDecl element) {
1715     boolean result = false;
1716     if (_elements.containsValue(element)) {
1717       _elements.remove(element.getName());
1718       result = true;
1719     }
1720     if (!result) {
1721       // --check the cached included schemas
1722       Iterator<Schema> cacheIncluded = _cachedincludedSchemas.values().iterator();
1723       while (cacheIncluded.hasNext() && !result) {
1724         Schema temp = cacheIncluded.next();
1725         result = temp.removeElement(element);
1726       }
1727     }
1728     return result;
1729   } // -- removeElement
1730 
1731 
1732   /**
1733    * Removes the given top level Attribute from this Schema
1734    * 
1735    * @param attribute the AttributeDecl to remove
1736    * @return true if the AttributeDecl has been removed, or false if the AttributeDecl wasn't top
1737    *         level or didn't exist in this Schema
1738    */
1739   public boolean removeAttribute(AttributeDecl attribute) {
1740     boolean result = false;
1741     if (_attributes.containsValue(attribute)) {
1742       _attributes.remove(attribute.getName());
1743       result = true;
1744     }
1745     if (result == false) {
1746       // --check the cached included schemas
1747       Iterator<Schema> cacheIncluded = _cachedincludedSchemas.values().iterator();
1748       while (cacheIncluded.hasNext() && !result) {
1749         Schema temp = cacheIncluded.next();
1750         result = temp.removeAttribute(attribute);
1751       }
1752     }
1753     return false;
1754   } // -- removeAttribute
1755 
1756   /**
1757    * Removes the given top level ModelGroup definition from this Schema
1758    * 
1759    * @param group the ModelGroup definition to remove
1760    * @return true if the ModelGroup definition has been removed, or false if the ModelGroup
1761    *         definition wasn't top level or didn't exist in this Schema.
1762    */
1763   public boolean removeGroup(ModelGroup group) {
1764     boolean result = false;
1765     if (_groups.containsValue(group)) {
1766       _groups.remove(group.getName());
1767       result = true;
1768     }
1769     if (!result) {
1770       // --check the cached included schemas
1771       Iterator<Schema> cacheIncluded = _cachedincludedSchemas.values().iterator();
1772       while (cacheIncluded.hasNext() && !result) {
1773         Schema temp = cacheIncluded.next();
1774         result = temp.removeGroup(group);
1775       }
1776 
1777       if (!result) {
1778         // --check the redefinition
1779         Iterator<RedefineSchema> redefinitions = getRedefineSchema().iterator();
1780         while (redefinitions.hasNext() && !result) {
1781           RedefineSchema redefine = redefinitions.next();
1782           result = redefine.removeGroup(group);
1783         }
1784       }
1785     }
1786 
1787 
1788     return result;
1789   } // -- removeGroup
1790 
1791   /**
1792    * Removes the given AttributeGroup definition from this Schema
1793    * 
1794    * @param group the AttributeGroup definition to remove
1795    * @return true if the AttributeGroup definition has been removed.
1796    */
1797   public boolean removeAttributeGroup(AttributeGroupDecl group) {
1798     boolean result = false;
1799     if (_attributeGroups.containsValue(group)) {
1800       _attributeGroups.remove(group.getName());
1801       result = true;
1802     }
1803     if (result == false) {
1804       // --check the cached included schemas
1805       Iterator<Schema> cacheIncluded = _cachedincludedSchemas.values().iterator();
1806       while (cacheIncluded.hasNext() && !result) {
1807         Schema temp = cacheIncluded.next();
1808         result = temp.removeAttributeGroup(group);
1809       }
1810 
1811       if (!result) {
1812         // --check the redefinition
1813         Iterator<RedefineSchema> redefinitions = getRedefineSchema().iterator();
1814         while (redefinitions.hasNext() && !result) {
1815           RedefineSchema redefine = redefinitions.next();
1816           result = redefine.removeAttributeGroup(group);
1817         }
1818       }
1819     }
1820 
1821     return result;
1822   } // -- removeGroup
1823 
1824   /**
1825    * Removes the given cached included schema from this Schema definition's list of cached included
1826    * schema.
1827    *
1828    * @param schema the Schema to remove from this Schema's redefinition list
1829    *
1830    * @return true if the Schema was removed, otherwise false
1831    */
1832   public synchronized boolean removeCachedIncludedSchema(Schema schema) {
1833     if (schema == null)
1834       return false;
1835     String schemaLocation = schema.getSchemaLocation();
1836     Schema tmp = _cachedincludedSchemas.get(schemaLocation);
1837     if (schema.equals(tmp)) {
1838       _cachedincludedSchemas.remove(schemaLocation);
1839       return true;
1840     }
1841     return false;
1842   } // -- removeImportedSchema
1843 
1844   /**
1845    * Removes the given Schema definition from this Schema definition's list of imported schenma
1846    *
1847    * @param schema the Schema to remove from this Schema's import list
1848    *
1849    * @return true if the Schema was removed, otherwise false
1850    */
1851   public synchronized boolean removeImportedSchema(Schema schema) {
1852     if (schema == null)
1853       return false;
1854     String targetNamespace = schema.getTargetNamespace();
1855     if (targetNamespace == null)
1856       targetNamespace = "";
1857     Schema tmp = _importedSchemas.get(targetNamespace);
1858     if (schema.equals(tmp)) {
1859       _importedSchemas.remove(targetNamespace);
1860       return true;
1861     }
1862     return false;
1863   } // -- removeImportedSchema
1864 
1865   /**
1866    * Removes the namespace from the set of namespace declarations for this Schema definition.
1867    *
1868    * @param prefix the namespace prefix of the namespace to remove.
1869    */
1870   public boolean removeNamespace(String prefix) {
1871     if (prefix == null)
1872       prefix = "";
1873     return _namespaces.removeNamespace(prefix);
1874   } // -- removeNamespace
1875 
1876   /**
1877    * Removes the given redefined structure from this Schema definition's list of redefinitions.
1878    *
1879    * @param schema the Schema to remove from this Schema's redefinition list
1880    *
1881    * @return true if the Schema was removed, otherwise false
1882    */
1883   public synchronized boolean removeRedefineSchema(RedefineSchema schema) {
1884     if (schema == null)
1885       return false;
1886     String schemaLocation = schema.getSchemaLocation();
1887     RedefineSchema tmp = _redefineSchemas.get(schemaLocation);
1888     if (schema.equals(tmp)) {
1889       _redefineSchemas.remove(schemaLocation);
1890       return true;
1891     }
1892     return false;
1893   } // -- removeRedefineSchema
1894 
1895   /**
1896    * Removes the given top level SimpleType from this Schema
1897    * 
1898    * @param simpleType the SimpleType to remove
1899    * @return true if the SimpleType has been removed, or false if the SimpleType wasn't top level or
1900    *         didn't exist in this Schema
1901    **/
1902   public boolean removeSimpleType(SimpleType simpleType) {
1903     boolean result = false;
1904     if (_simpleTypes.containsValue(simpleType)) {
1905       _simpleTypes.remove(simpleType.getName());
1906       result = true;
1907     }
1908     if (result == false) {
1909       // --check the cached included schemas
1910       Iterator<Schema> cacheIncluded = _cachedincludedSchemas.values().iterator();
1911       while (cacheIncluded.hasNext() && !result) {
1912         Schema temp = cacheIncluded.next();
1913         result = temp.removeSimpleType(simpleType);
1914       }
1915 
1916       if (!result) {
1917         // --check the redefinition
1918         Iterator<RedefineSchema> redefinitions = getRedefineSchema().iterator();
1919         while (redefinitions.hasNext() && !result) {
1920           RedefineSchema redefine = redefinitions.next();
1921           result = redefine.removeSimpleType(simpleType);
1922         }
1923       }
1924     }
1925     return result;
1926   } // -- removeSimpleType
1927 
1928   /**
1929    * Sets the attributeFormDefault property of this Schema.
1930    *
1931    * @param attributeFormDefault the Form value of the attributeFormDefault property for this
1932    *        Schema.
1933    **/
1934   public void setAttributeFormDefault(Form attributeFormDefault) {
1935     _attributeFormDefault = attributeFormDefault;
1936   } // -- setAttributeFormDefault
1937 
1938   /**
1939    * Sets the default BlockList for this Schema.
1940    *
1941    * @param block the default BlockList to set for this Schema.
1942    **/
1943   public void setBlockDefault(BlockList block) {
1944     _block = block;
1945   } // -- setBlockDefault
1946 
1947   /**
1948    * Sets the default Block values for this Schema.
1949    *
1950    * @param block the default Block values to set for this Schema.
1951    **/
1952   public void setBlockDefault(String block) {
1953     _block = new BlockList(block);
1954   } // -- setBlockDefault
1955 
1956   /**
1957    * Sets the elementFormDefault property of this Schema.
1958    *
1959    * @param elementFormDefault the Form value of the elementFormDefault property for this Schema.
1960    **/
1961   public void setElementFormDefault(Form elementFormDefault) {
1962     _elementFormDefault = elementFormDefault;
1963   } // -- setElementFormDefault
1964 
1965   /**
1966    * Sets the default FinalList for this Schema.
1967    *
1968    * @param finalList the default FinalList to set for this Schema.
1969    **/
1970   public void setFinalDefault(FinalList finalList) {
1971     _final = finalList;
1972   } // -- setFinalDefault
1973 
1974   /**
1975    * Sets the default final values for this Schema.
1976    *
1977    * @param finalValues the default final values to set for this Schema.
1978    **/
1979   public void setFinalDefault(String finalValues) {
1980     _final = new FinalList(finalValues);
1981   } // -- setFinalDefault
1982 
1983   /**
1984    * Set the schemaLocation for this schema. This is useful when this schema has been imported by
1985    * another schema
1986    * 
1987    * @param schemaLocation the location hint for this Schema
1988    */
1989   public void setSchemaLocation(String schemaLocation) {
1990     _schemaLocation = schemaLocation;
1991   }
1992 
1993 
1994   /**
1995    * Returns the first simple or complex type which name equals TypeName
1996    */
1997   public XMLType getType(String typeName) {
1998     // -- Null?
1999     if (typeName == null) {
2000       String err = NULL_ARGUMENT + "Schema#getType: ";
2001       err += "'name' cannot be null.";
2002       throw new IllegalArgumentException(err);
2003     }
2004 
2005     XMLType result = null;
2006 
2007     String localName = typeName;
2008     String prefix = "";
2009     String ns = null;
2010 
2011     int colon = typeName.indexOf(':');
2012 
2013     if (colon >= 0) {
2014       localName = typeName.substring(colon + 1);
2015       prefix = typeName.substring(0, colon);
2016       ns = _namespaces.getNamespaceURI(prefix);
2017       if (ns == null) {
2018         String err = "Schema#getType: ";
2019         err += "Namespace prefix not recognised '" + typeName + "'";
2020         throw new IllegalArgumentException(err);
2021       }
2022     }
2023 
2024     // -- use default namespace if necessary
2025     if (ns == null) {
2026       ns = _namespaces.getNamespaceURI(prefix);
2027     }
2028 
2029     // --if at this point, there is no namespace
2030     // --then we assume it is the targetNamespace
2031     if (ns == null) {
2032       // --SHOULD WE THROW AN EXCEPTION?
2033       ns = _targetNamespace;
2034     }
2035 
2036     // 1--support for anyType
2037     if (localName.equals(SchemaNames.ANYTYPE)) {
2038       // --if 'anyType' in the default schema namespace-->type is anyType
2039       if (ns.equals(DEFAULT_SCHEMA_NS)) {
2040         result = new AnyType(this);
2041       }
2042     } // --anyType
2043 
2044     IllegalArgumentException exception = null;
2045     // 2--look for a simpleType
2046     if (result == null) {
2047       try {
2048         result = getSimpleType(localName, ns);
2049       } catch (IllegalArgumentException iox) {
2050         exception = iox;
2051       }
2052     }
2053 
2054     // 3--look for a complexType
2055     if (result == null) {
2056       try {
2057         result = getComplexType(typeName);
2058       } catch (IllegalArgumentException iox) {
2059         exception = iox;
2060       }
2061     }
2062 
2063     if ((result == null) && (exception != null))
2064       throw exception;
2065 
2066     return result;
2067   }
2068 
2069   /**
2070    * Sets the Id for this Schema
2071    *
2072    * @param id the Id for this Schema
2073    **/
2074   public void setId(String id) {
2075     this._id = id;
2076   } // -- setId
2077 
2078   /**
2079    * Sets the target namespace for this Schema
2080    * 
2081    * @param targetNamespace the target namespace for this Schema
2082    * @see "&sect; 2.7 XML Schema Part 1: Structures"
2083    **/
2084   public void setTargetNamespace(String targetNamespace) {
2085     if (targetNamespace != null) {
2086       targetNamespace = targetNamespace.trim();
2087       if (targetNamespace.length() == 0)
2088         throw new IllegalStateException("an empty string is not a valid namespace.");
2089     }
2090     _targetNamespace = targetNamespace;
2091   } // -- setTargetNamespace
2092 
2093   /**
2094    * Sets the version information for the XML Schema defintion represented by this Schema instance.
2095    *
2096    * @param version the version for this XML Schema defination.
2097    **/
2098   public void setVersion(String version) {
2099     _version = version;
2100   } // -- setVersion
2101 
2102 
2103   /** Gets the type factory, package private */
2104   static SimpleTypesFactory getTypeFactory() {
2105     return simpleTypesFactory;
2106   }
2107 
2108   // -------------------------------/
2109   // - Implementation of Structure -/
2110   // -------------------------------/
2111 
2112   /**
2113    * Returns the type of this Schema Structure
2114    * 
2115    * @return the type of this Schema Structure
2116    **/
2117   public short getStructureType() {
2118     return Structure.SCHEMA;
2119   } // -- getStructureType
2120 
2121   /**
2122    * Checks the validity of this {@link Schema} definition.
2123    *
2124    * @throws ValidationException when this {@link Schema} definition is invalid.
2125    **/
2126   public void validate() throws ValidationException {
2127 
2128     // -- Note: This method needs to be completed.
2129 
2130     // -- top-level complexTypes
2131     for (ComplexType complexType : _complexTypes.values()) {
2132       complexType.validate();
2133     }
2134 
2135     // -- top-level simpleTypes
2136     for (SimpleType simpleType : _simpleTypes.values()) {
2137       simpleType.validate();
2138     }
2139 
2140     // -- top-level elements
2141     for (ElementDecl element : _elements.values()) {
2142       element.validate();
2143     }
2144 
2145     // -- top-level attributes
2146     for (AttributeDecl attribute : _attributes.values()) {
2147       attribute.validate();
2148     }
2149 
2150     // -- top-level groups
2151     for (ModelGroup group : _groups.values()) {
2152       group.validate();
2153     }
2154     // -- top-level attribute groups
2155 
2156   } // -- validate
2157 
2158 
2159   // -- private methods:
2160 
2161   /**
2162    * Returns the namespace prefix associated with the given namespace. If more than one prefix has
2163    * been associated, the first one found will be returned.
2164    *
2165    * @return the namespace prefix associaed with the given namespace.
2166    **/
2167   public String getNamespacePrefix(String namespace) {
2168     return _namespaces.getNamespacePrefix(namespace);
2169   }
2170 
2171   /**
2172    * Returns the master schema in which this instance of schema is used at runtime. This method is
2173    * meant to be used at runtime.
2174    * 
2175    * @return the master schema in which this instance of schema is used at runtime. This method is
2176    *         meant to be used at runtime.
2177    */
2178   protected Schema getMasterSchema() {
2179     return _masterSchema;
2180   }
2181 
2182   /**
2183    * Sets the master schema in which this instance of schema is used at runtime. This method is
2184    * meant to be used at runtime. A master schema is a schema in which this instance of Schema is
2185    * included, redefined or imported.
2186    * 
2187    * @param masterSchema the master schema in which this instance of schema is used at runtime. This
2188    *        method is meant to be used at runtime.
2189    */
2190   protected void setMasterSchema(Schema masterSchema) {
2191     _masterSchema = masterSchema;
2192   }
2193 
2194 
2195 } // -- Schema
2196 
2197