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