View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one
    3    * or more contributor license agreements. See the NOTICE file
    4    * distributed with this work for additional information
    5    * regarding copyright ownership. The ASF licenses this file
    6    * to you under the Apache License, Version 2.0 (the
    7    * "License"); you may not use this file except in compliance
    8    * with the License. You may obtain a copy of the License at
    9    *
    10   * http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing,
    13   * software distributed under the License is distributed on an
    14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    15   * KIND, either express or implied. See the License for the
    16   * specific language governing permissions and limitations
    17   * under the License.
    18   */
    19
    20  package org.apache.ws.commons.schema;
    21
    22  import org.apache.ws.commons.schema.XmlSchemaCollection.SchemaKey;
    23  import org.apache.ws.commons.schema.constants.Constants;
    24  import org.apache.ws.commons.schema.extensions.ExtensionRegistry;
    25  import org.apache.ws.commons.schema.utils.NodeNamespaceContext;
    26  import org.apache.ws.commons.schema.utils.TargetNamespaceValidator;
    27  import org.apache.ws.commons.schema.utils.XDOMUtil;
    28  import org.apache.ws.commons.schema.utils.DOMUtil;
    29  import org.w3c.dom.*;
    30  import org.xml.sax.InputSource;
    31
    32  import javax.xml.namespace.NamespaceContext;
    33  import javax.xml.namespace.QName;
    34  import javax.xml.parsers.DocumentBuilderFactory;
    35
    36  import java.lang.ref.SoftReference;
    37  import java.util.ArrayList;
    38  import java.util.Hashtable;
    39  import java.util.List;
    40  import java.util.StringTokenizer;
    41  import java.util.Vector;
    42
    43  public class SchemaBuilder {
    44  	Document doc;
    45  	XmlSchema schema;
    46  	XmlSchemaCollection collection;
    47  	private final TargetNamespaceValidator validator;
    48  	DocumentBuilderFactory docFac;
    49
    50  	/**
    51  	 * The extension registry to be used while building the
    52  	 * schema model
    53  	 */
    54  	private ExtensionRegistry extReg = null;
    55
    56  	public ExtensionRegistry getExtReg() {
    57  		return extReg;
    58  	}
    59
    60  	public void setExtReg(ExtensionRegistry extReg) {
    61  		this.extReg = extReg;
    62  	}
    63
    64      /*
    65       * cache of previously resolved schema documents.
    66       *
    67       * This cache might be usefull when an application has multiple webservices that each have WSDL documents
    68       * that import the same schema, for example.  On app startup, we may wish to cache XmlSchema objects so we
    69       * don't build up the schema graph multiple times.
    70       *
    71       * key - use a combination of thread id and all three parameters passed to resolveXmlSchema to give minimal thread safety*
    72       * value - XmlSchema object wrapped in a SoftReference to encourage GC in low memory situations
    73       *
    74       * *CAUTION:  XmlSchema objects are not likely to be thread-safe.  This cache should
    75       * only be used, then cleared, by callers aware of its existence.  It is VERY important that users of this
    76       * cache call clearCache() after they are done.
    77       *
    78       * Usage of the cache is controlled by calling initCache() which will initialize resolvedSchemas to non-null
    79       * Clearing of cache is done by calling clearCache() which will clear and nullify resolvedSchemas
    80       *
    81       */
    82      private static Hashtable resolvedSchemas = null;
    83
    84  	/**
    85  	 * Schema builder constructor
    86  	 * @param collection
    87  	 */
    88  	SchemaBuilder(XmlSchemaCollection collection,
    89  			TargetNamespaceValidator validator) {
    90  		this.collection = collection;
    91  		this.validator = validator;
    92
    93  		if (collection.getExtReg() != null) {
    94  			this.extReg = collection.getExtReg();
    95  		}
    96
    97  		schema = new XmlSchema();
    98  	}
    99
    100     public static synchronized void initCache() {
    101         if (resolvedSchemas == null) {
    102             resolvedSchemas = new Hashtable();
    103         }
    104     }
    105
    106     public static synchronized void clearCache() {
    107         if (resolvedSchemas != null) {
    108             resolvedSchemas.clear();  // necessary?
    109             resolvedSchemas = null;
    110         }
    111     }
    112
    113 	/**
    114 	 * build method taking in a document and a validation handler
    115 	 * @param doc
    116 	 * @param uri
    117 	 * @param veh
    118 	 */
    119 	XmlSchema build(Document doc, String uri, ValidationEventHandler veh) {
    120 		Element schemaEl = doc.getDocumentElement();
    121 		XmlSchema xmlSchema = handleXmlSchemaElement(schemaEl, uri);
    122 		xmlSchema.setInputEncoding(DOMUtil.getInputEncoding(doc));
    123 		return xmlSchema;
    124 	}
    125
    126 	/**
    127 	 * handles the schema element
    128 	 * @param schemaEl
    129 	 * @param systemId
    130 	 */
    131 	XmlSchema handleXmlSchemaElement(Element schemaEl, String systemId) {
    132 		// get all the attributes along with the namespace declns
    133 		schema.setNamespaceContext(NodeNamespaceContext.getNamespaceContext(schemaEl));
    134 		setNamespaceAttributes(schema, schemaEl);
    135
    136 		XmlSchemaCollection.SchemaKey schemaKey = new XmlSchemaCollection.SchemaKey(
    137 				schema.logicalTargetNamespace, systemId);
    138 		if (!collection.containsSchema(schemaKey)) {
    139 			collection.addSchema(schemaKey, schema);
    140 			schema.parent = collection; // establish parentage now.
    141 		} else {
    142 			throw new XmlSchemaException("Schema name conflict in collection. Namespace: " + schema.logicalTargetNamespace);
    143 		}
    144
    145 		schema.setElementFormDefault(this.getFormDefault(schemaEl,
    146 				"elementFormDefault"));
    147 		schema.setAttributeFormDefault(this.getFormDefault(schemaEl,
    148 				"attributeFormDefault"));
    149 		schema.setBlockDefault(this.getDerivation(schemaEl, "blockDefault"));
    150 		schema.setFinalDefault(this.getDerivation(schemaEl, "finalDefault"));
    151 		/* set id attribute */
    152 		if (schemaEl.hasAttribute("id")) {
    153 			schema.id = schemaEl.getAttribute("id");
    154 		}
    155
    156 		schema.setSourceURI(systemId);
    157
    158 		/***********
    159 		 * for ( each childElement)
    160 		 *		if( simpleTypeElement)
    161 		 *			handleSimpleType
    162 		 *		else if( complexType)
    163 		 *			handleComplexType
    164 		 *		else if( element)
    165 		 *			handleElement
    166 		 *		else if( include)
    167 		 *			handleInclude
    168 		 *		else if( import)
    169 		 *			handleImport
    170 		 *		else if (group)
    171 		 *			handleGroup
    172 		 *		else if (attributeGroup)
    173 		 *			handleattributeGroup
    174 		 *		else if( attribute)
    175 		 *			handleattribute
    176 		 *		else if (redefine)
    177 		 *			handleRedefine
    178 		 *		else if(notation)
    179 		 *			handleNotation
    180 		 *      else if (annotation)
    181 		 *          handleAnnotation
    182 		 */
    183
    184 		Element el = XDOMUtil.getFirstChildElementNS(schemaEl,
    185 				XmlSchema.SCHEMA_NS);
    186 		if (el == null
    187 				&& XDOMUtil.getFirstChildElementNS(schemaEl,
    188 						"http://www.w3.org/1999/XMLSchema") != null) {
    189 			throw new XmlSchemaException(
    190 					"Schema defined using \"http://www.w3.org/1999/XMLSchema\" is not supported. "
    191 							+ "Please update the schema to the \""
    192 							+ XmlSchema.SCHEMA_NS + "\" namespace");
    193 		}
    194 		for (; el != null; el = XDOMUtil.getNextSiblingElementNS(el,
    195 				XmlSchema.SCHEMA_NS)) {
    196
    197 			// String elPrefix = el.getPrefix() == null ? "" : el.getPrefix();
    198 			//if(elPrefix.equals(schema.schema_ns_prefix)) {
    199 			if (el.getLocalName().equals("simpleType")) {
    200 				XmlSchemaType type = handleSimpleType(schema, el, schemaEl);
    201 				schema.addType(type);
    202 				schema.items.add(type);
    203 				collection.resolveType(type.getQName(), type);
    204 			} else if (el.getLocalName().equals("complexType")) {
    205 				XmlSchemaType type = handleComplexType(schema, el, schemaEl);
    206 				schema.addType(type);
    207 				schema.items.add(type);
    208 				collection.resolveType(type.getQName(), type);
    209 			} else if (el.getLocalName().equals("element")) {
    210 				XmlSchemaElement element = handleElement(schema, el, schemaEl,
    211 						true);
    212 				if (element.qualifiedName != null)
    213 					schema.elements.collection.put(element.qualifiedName,
    214 							element);
    215 				else if (element.refName != null)
    216 					schema.elements.collection.put(element.refName, element);
    217 				schema.items.add(element);
    218 			} else if (el.getLocalName().equals("include")) {
    219 				XmlSchemaInclude include = handleInclude(schema, el, schemaEl);
    220 				schema.includes.add(include);
    221 				schema.items.add(include);
    222
    223 			} else if (el.getLocalName().equals("import")) {
    224 				XmlSchemaImport schemaImport = handleImport(schema, el,
    225 						schemaEl);
    226 				schema.includes.add(schemaImport);
    227 				schema.items.add(schemaImport);
    228
    229 			} else if (el.getLocalName().equals("group")) {
    230 				XmlSchemaGroup group = handleGroup(schema, el, schemaEl);
    231 				schema.groups.collection.put(group.name, group);
    232 				schema.items.add(group);
    233 			} else if (el.getLocalName().equals("attributeGroup")) {
    234 				XmlSchemaAttributeGroup group = handleAttributeGroup(schema,
    235 						el, schemaEl);
    236 				schema.attributeGroups.collection.put(group.name, group);
    237 				schema.items.add(group);
    238 			} else if (el.getLocalName().equals("attribute")) {
    239 				XmlSchemaAttribute attr = handleAttribute(schema, el, schemaEl,
    240 						true); //pass true to indicate that it is a top level child
    241 				schema.attributes.collection.put(attr.qualifiedName, attr);
    242 				schema.items.add(attr);
    243 			} else if (el.getLocalName().equals("redefine")) {
    244 				XmlSchemaRedefine redefine = handleRedefine(schema, el,
    245 						schemaEl);
    246 				schema.includes.add(redefine);
    247 			} else if (el.getLocalName().equals("notation")) {
    248 				XmlSchemaNotation notation = handleNotation(el);
    249 				schema.notations.collection.put(new QName(schema
    250 						.getTargetNamespace(), notation.name), notation);
    251 				schema.items.add(notation);
    252 			} else if (el.getLocalName().equals("annotation")) {
    253 				XmlSchemaAnnotation annotation = handleAnnotation(el);
    254 				schema.setAnnotation(annotation);
    255 			}
    256 		}
    257
    258 		//add the extesibility components
    259 		processExtensibilityComponents(schema, schemaEl);
    260
    261 		return schema;
    262 	}
    263
    264 	private XmlSchemaNotation handleNotation(Element notationEl) {
    265
    266 		XmlSchemaNotation notation = new XmlSchemaNotation();
    267
    268 		if (notationEl.hasAttribute("id")) {
    269 			notation.id = notationEl.getAttribute("id");
    270 		}
    271
    272 		if (notationEl.hasAttribute("name")) {
    273 			notation.name = notationEl.getAttribute("name");
    274 		}
    275
    276 		if (notationEl.hasAttribute("public")) {
    277 			notation.publicNotation = notationEl.getAttribute("public");
    278 		}
    279
    280 		if (notationEl.hasAttribute("system")) {
    281 			notation.system = notationEl.getAttribute("system");
    282 		}
    283
    284 		Element annotationEl = XDOMUtil.getFirstChildElementNS(notationEl,
    285 				XmlSchema.SCHEMA_NS, "annotation");
    286
    287 		if (annotationEl != null) {
    288 			XmlSchemaAnnotation annotation = handleAnnotation(annotationEl);
    289 			notation.setAnnotation(annotation);
    290 		}
    291
    292 		return notation;
    293 	}
    294
    295 	/**
    296 	 * Handle redefine
    297 	 * @param schema
    298 	 * @param redefineEl
    299 	 * @param schemaEl
    300 	 * @return
    301 	 */
    302 	private XmlSchemaRedefine handleRedefine(XmlSchema schema,
    303 			Element redefineEl, Element schemaEl) {
    304
    305 		XmlSchemaRedefine redefine = new XmlSchemaRedefine();
    306 		redefine.schemaLocation = redefineEl.getAttribute("schemaLocation");
    307 		final TargetNamespaceValidator validator = newIncludeValidator(schema);
    308
    309 		if (schema.getSourceURI() != null) {
    310 			redefine.schema = resolveXmlSchema(schema.logicalTargetNamespace,
    311 					redefine.schemaLocation, schema.getSourceURI(), validator);
    312 		} else {
    313 			redefine.schema = resolveXmlSchema(schema.logicalTargetNamespace,
    314 					redefine.schemaLocation, validator);
    315 		}
    316
    317 		/*
    318 		 * FIXME - This seems not right. Since the redefine should take into account
    319 		 * the attributes of the original element we cannot just build the type
    320 		 * defined in the redefine section - what we need to do is to get the original type
    321 		 * object and modify it. However one may argue (quite reasonably) that the purpose
    322 		 * of this object model is to provide just the representation and not the validation
    323 		 * (as it has been always the case)
    324 		 */
    325
    326 		for (Element el = XDOMUtil.getFirstChildElementNS(redefineEl,
    327 				XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
    328 				.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
    329
    330 			if (el.getLocalName().equals("simpleType")) {
    331 				XmlSchemaType type = handleSimpleType(schema, el, schemaEl);
    332
    333 				redefine.schemaTypes.collection.put(type.getQName(), type);
    334 				redefine.items.add(type);
    335 			} else if (el.getLocalName().equals("complexType")) {
    336
    337 				XmlSchemaType type = handleComplexType(schema, el, schemaEl);
    338
    339 				redefine.schemaTypes.collection.put(type.getQName(), type);
    340 				redefine.items.add(type);
    341 			} else if (el.getLocalName().equals("group")) {
    342 				XmlSchemaGroup group = handleGroup(schema, el, schemaEl);
    343 				redefine.groups.collection.put(group.name, group);
    344 				redefine.items.add(group);
    345 			} else if (el.getLocalName().equals("attributeGroup")) {
    346 				XmlSchemaAttributeGroup group = handleAttributeGroup(schema,
    347 						el, schemaEl);
    348
    349 				redefine.attributeGroups.collection.put(group.name, group);
    350 				redefine.items.add(group);
    351 			} else if (el.getLocalName().equals("annotation")) {
    352 				XmlSchemaAnnotation annotation = handleAnnotation(el);
    353 				redefine.setAnnotation(annotation);
    354 			}
    355 			//                  }
    356 		}
    357 		return redefine;
    358 	}
    359
    360 	void setNamespaceAttributes(XmlSchema schema, Element schemaEl) {
    361 		//no targetnamespace found !
    362 		if (schemaEl.getAttributeNode("targetNamespace") != null) {
    363 			String contain = schemaEl.getAttribute("targetNamespace");
    364 			schema.setTargetNamespace(contain);
    365 		} else {
    366 			//do nothing here
    367 		}
    368 		if (validator != null) {
    369 			validator.validate(schema);
    370 		}
    371 	}
    372
    373 	/**
    374 	 * Handles simple types
    375 	 * @param schema
    376 	 * @param simpleEl
    377 	 * @param schemaEl
    378 	 */
    379 	XmlSchemaSimpleType handleSimpleType(XmlSchema schema, Element simpleEl,
    380 			Element schemaEl) {
    381 		XmlSchemaSimpleType simpleType = new XmlSchemaSimpleType(schema);
    382 		if (simpleEl.hasAttribute("name")) {
    383 			simpleType.name = simpleEl.getAttribute("name");
    384 		}
    385
    386 		if (simpleEl.hasAttribute("final")) {
    387 			String finalstr = simpleEl.getAttribute("final");
    388
    389 			if (finalstr.equalsIgnoreCase("all")
    390 					| finalstr.equalsIgnoreCase("#all"))
    391
    392 				simpleType.setFinal(new XmlSchemaDerivationMethod(
    393 						Constants.BlockConstants.ALL));
    394 			else
    395 				simpleType.setFinal(new XmlSchemaDerivationMethod(finalstr));
    396 		}
    397
    398 		Element simpleTypeAnnotationEl = XDOMUtil.getFirstChildElementNS(
    399 				simpleEl, XmlSchema.SCHEMA_NS, "annotation");
    400
    401 		if (simpleTypeAnnotationEl != null) {
    402 			XmlSchemaAnnotation simpleTypeAnnotation = handleAnnotation(simpleTypeAnnotationEl);
    403
    404 			simpleType.setAnnotation(simpleTypeAnnotation);
    405 		}
    406
    407 		Element unionEl, listEl, restrictionEl;
    408
    409 		if ((restrictionEl = XDOMUtil.getFirstChildElementNS(simpleEl,
    410 				XmlSchema.SCHEMA_NS, "restriction")) != null) {
    411
    412 			XmlSchemaSimpleTypeRestriction restriction = new XmlSchemaSimpleTypeRestriction();
    413
    414 			Element restAnnotationEl = XDOMUtil.getFirstChildElementNS(
    415 					restrictionEl, XmlSchema.SCHEMA_NS, "annotation");
    416
    417 			if (restAnnotationEl != null) {
    418 				XmlSchemaAnnotation restAnnotation = handleAnnotation(restAnnotationEl);
    419 				restriction.setAnnotation(restAnnotation);
    420 			}
    421 			/** if (restriction has a base attribute )
    422 			 *		set the baseTypeName and look up the base type
    423 			 *	else if( restricion has a SimpleType Element as child)
    424 			 *		get that element and do a handleSimpleType;
    425 			 *	get the children of restriction other than annotation
    426 			 * and simpleTypes and construct facets from it;
    427 			 *
    428 			 *	set the restriction has the content of the simpleType
    429 			 *
    430 			 **/
    431
    432 			Element inlineSimpleType = XDOMUtil.getFirstChildElementNS(
    433 					restrictionEl, XmlSchema.SCHEMA_NS, "simpleType");
    434
    435 			if (restrictionEl.hasAttribute("base")) {
    436 				NamespaceContext ctx = NodeNamespaceContext.getNamespaceContext(restrictionEl);
    437 				restriction.baseTypeName = getRefQName(restrictionEl
    438 						.getAttribute("base"), ctx);
    439 			} else if (inlineSimpleType != null) {
    440
    441 				restriction.baseType = handleSimpleType(schema,
    442 						inlineSimpleType, schemaEl);
    443 			}
    444 			for (Element el = XDOMUtil.getFirstChildElementNS(restrictionEl,
    445 					XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
    446 					.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
    447
    448 				if (!el.getLocalName().equals("annotation")
    449 						&& !el.getLocalName().equals("simpleType")) {
    450
    451 					XmlSchemaFacet facet = XmlSchemaFacet.construct(el);
    452 					Element annotation = XDOMUtil.getFirstChildElementNS(el,
    453 							XmlSchema.SCHEMA_NS, "annotation");
    454
    455 					if (annotation != null) {
    456 						XmlSchemaAnnotation facetAnnotation = handleAnnotation(annotation);
    457 						facet.setAnnotation(facetAnnotation);
    458 					}
    459
    460 					//process extra attributes and elements
    461 					processExtensibilityComponents(facet, el);
    462 					restriction.facets.add(facet);
    463 				}
    464
    465 			}
    466 			simpleType.content = restriction;
    467
    468 		} else if ((listEl = XDOMUtil.getFirstChildElementNS(simpleEl,
    469 				XmlSchema.SCHEMA_NS, "list")) != null) {
    470
    471 			XmlSchemaSimpleTypeList list = new XmlSchemaSimpleTypeList();
    472
    473 			/******
    474 			 * if( list has an itemType attribute )
    475 			 *		set the baseTypeName and look up the base type
    476 			 * else if( list has a SimpleTypeElement as child)
    477 			 *		get that element and do a handleSimpleType
    478 			 *
    479 			 * set the list has the content of the simpleType
    480 			 */
    481 			Element inlineListType, listAnnotationEl;
    482 			if (listEl.hasAttribute("itemType")) {
    483 				String name = listEl.getAttribute("itemType");
    484 				list.itemTypeName = getRefQName(name, listEl);
    485 			} else if ((inlineListType = XDOMUtil.getFirstChildElementNS(
    486 					listEl, XmlSchema.SCHEMA_NS, "simpleType")) != null) {
    487
    488 				list.itemType = handleSimpleType(schema, inlineListType,
    489 						schemaEl);
    490 			}
    491
    492 			if ((listAnnotationEl = XDOMUtil.getFirstChildElementNS(listEl,
    493 					XmlSchema.SCHEMA_NS, "annotation")) != null) {
    494
    495 				XmlSchemaAnnotation listAnnotation = handleAnnotation(listAnnotationEl);
    496
    497 				list.setAnnotation(listAnnotation);
    498 			}
    499 			simpleType.content = list;
    500
    501 		} else if ((unionEl = XDOMUtil.getFirstChildElementNS(simpleEl,
    502 				XmlSchema.SCHEMA_NS, "union")) != null) {
    503
    504 			XmlSchemaSimpleTypeUnion union = new XmlSchemaSimpleTypeUnion();
    505
    506 			/******
    507 			 * if( union has a memberTypes attribute )
    508 			 *		add the memberTypeSources string
    509 			 *		for (each memberType in the list )
    510 			 *			lookup(memberType)
    511 			 *	for( all SimpleType child Elements)
    512 			 *		add the simpleTypeName (if any) to the memberType Sources
    513 			 *		do a handleSimpleType with the simpleTypeElement
    514 			 */
    515 			if (unionEl.hasAttribute("memberTypes")) {
    516 				String memberTypes = unionEl.getAttribute("memberTypes");
    517 				union.memberTypesSource = memberTypes;
    518 				Vector v = new Vector();
    519 				StringTokenizer tokenizer = new StringTokenizer(memberTypes,
    520 						" ");
    521 				while (tokenizer.hasMoreTokens()) {
    522 					String member = tokenizer.nextToken();
    523 					v.add(getRefQName(member, unionEl));
    524 				}
    525 				union.memberTypesQNames = new QName[v.size()];
    526 				v.copyInto(union.memberTypesQNames);
    527 			}
    528
    529 			Element inlineUnionType = XDOMUtil.getFirstChildElementNS(unionEl,
    530 					XmlSchema.SCHEMA_NS, "simpleType");
    531 			while (inlineUnionType != null) {
    532
    533 				XmlSchemaSimpleType unionSimpleType = handleSimpleType(schema,
    534 						inlineUnionType, schemaEl);
    535
    536 				union.baseTypes.add(unionSimpleType);
    537
    538 				if (unionSimpleType.name != null) {
    539 					union.memberTypesSource += " " + unionSimpleType.name;
    540 				}
    541
    542 				inlineUnionType = XDOMUtil.getNextSiblingElementNS(
    543 						inlineUnionType, XmlSchema.SCHEMA_NS, "simpleType");
    544 			}
    545
    546 			//NodeList annotations = unionEl.getElementsByTagNameNS(
    547 			//XmlSchema.SCHEMA_NS, "annotation");
    548 			Element unionAnnotationEl = XDOMUtil.getFirstChildElementNS(
    549 					unionEl, XmlSchema.SCHEMA_NS, "annotation");
    550
    551 			if (unionAnnotationEl != null) {
    552 				XmlSchemaAnnotation unionAnnotation = handleAnnotation(unionAnnotationEl);
    553
    554 				union.setAnnotation(unionAnnotation);
    555 			}
    556 			simpleType.content = union;
    557 		}
    558
    559 		//process extra attributes and elements
    560 		processExtensibilityComponents(simpleType, simpleEl);
    561
    562 		return simpleType;
    563 	}
    564
    565 	private QName getRefQName(String pName, Node pNode) {
    566 		return getRefQName(pName, NodeNamespaceContext.getNamespaceContext(pNode));
    567 	}
    568
    569 	private QName getRefQName(String pName, NamespaceContext pContext) {
    570 		final int offset = pName.indexOf(':');
    571 		String uri;
    572 		final String localName;
    573 		final String prefix;
    574 		if (offset == -1) {
    575 			uri = pContext.getNamespaceURI(Constants.DEFAULT_NS_PREFIX);
    576 			if (Constants.NULL_NS_URI.equals(uri)) {
    577 				return new QName(Constants.NULL_NS_URI, pName);
    578 			}
    579 			localName = pName;
    580 			prefix = Constants.DEFAULT_NS_PREFIX;
    581 		} else {
    582 			prefix = pName.substring(0, offset);
    583 			uri = pContext.getNamespaceURI(prefix);
    584 			if (uri == null || Constants.NULL_NS_URI.equals(uri)) {
    585 				if (schema.parent != null
    586 						&& schema.parent.getNamespaceContext() != null) {
    587 					uri = schema.parent.getNamespaceContext().getNamespaceURI(
    588 							prefix);
    589 				}
    590 			}
    591
    592 			if (uri == null || Constants.NULL_NS_URI.equals(uri)) {
    593 				throw new IllegalStateException("The prefix " + prefix
    594 						+ " is not bound.");
    595 			}
    596 			localName = pName.substring(offset + 1);
    597 		}
    598 		return new QName(uri, localName, prefix);
    599 	}
    600
    601 	/**
    602 	 * Handle complex types
    603 	 * @param schema
    604 	 * @param complexEl
    605 	 * @param schemaEl
    606 	 */
    607 	XmlSchemaComplexType handleComplexType(XmlSchema schema, Element complexEl,
    608 			Element schemaEl) {
    609
    610 		/******
    611 		 * set the complexTypeName if any
    612 		 * for( eachChildNode)
    613 		 * if ( simpleContent)
    614 		 *		if( restrcition)
    615 		 *			handle_simple_content_restriction
    616 		 *		else if( extension)
    617 		 *			handle_simple_content_extension
    618 		 *		break; // it has to be the only child
    619 		 * else if( complexContent)
    620 		 *		if( restriction)
    621 		 *			handle_complex_content_restriction
    622 		 *		else if( extension)
    623 		 *			handle_complex_content_extension
    624 		 *		break; // it has to be the only child
    625 		 * else if( group)
    626 		 *		if( group has ref)
    627 		 *			store the group name
    628 		 *		else
    629 		 *			handleGroup
    630 		 * else if( sequence )
    631 		 *		handleSequence
    632 		 * else if( all )
    633 		 *		handleAll
    634 		 * else if(choice)
    635 		 *		handleChoice
    636 		 * else if(attribute)
    637 		 *		handleAttribute
    638 		 * else if(attributeGroup)
    639 		 *		handleAttributeGroup
    640 		 *  else if(anyAttribute)
    641 		 *		handleAnyAttribute
    642 		 */
    643
    644 		XmlSchemaComplexType ct = new XmlSchemaComplexType(schema);
    645
    646 		if (complexEl.hasAttribute("name")) {
    647
    648 			//String namespace = (schema.targetNamespace==null)?
    649 			//                  "":schema.targetNamespace;
    650
    651 			ct.name = complexEl.getAttribute("name");
    652 		}
    653 		for (Element el = XDOMUtil.getFirstChildElementNS(complexEl,
    654 				XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
    655 				.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
    656
    657 			//String elPrefix = el.getPrefix() == null ? "" :
    658 			//el.getPrefix();
    659 			//if(elPrefix.equals(schema.schema_ns_prefix)) {
    660 			if (el.getLocalName().equals("sequence")) {
    661 				ct.particle = handleSequence(schema, el, schemaEl);
    662 			} else if (el.getLocalName().equals("choice")) {
    663 				ct.particle = handleChoice(schema, el, schemaEl);
    664 			} else if (el.getLocalName().equals("all")) {
    665 				ct.particle = handleAll(schema, el, schemaEl);
    666 			} else if (el.getLocalName().equals("attribute")) {
    667 				ct.attributes.add(handleAttribute(schema, el, schemaEl));
    668 			} else if (el.getLocalName().equals("attributeGroup")) {
    669 				ct.attributes.add(handleAttributeGroupRef(el));
    670 			} else if (el.getLocalName().equals("group")) {
    671 				XmlSchemaGroupRef group = handleGroupRef(schema, el, schemaEl);
    672 				ct.particle = (group.particle == null) ? (XmlSchemaParticle) group
    673 						: group.particle;
    674 			} else if (el.getLocalName().equals("simpleContent")) {
    675 				ct.contentModel = handleSimpleContent(schema, el, schemaEl);
    676 			} else if (el.getLocalName().equals("complexContent")) {
    677 				ct.contentModel = handleComplexContent(schema, el, schemaEl);
    678 			} else if (el.getLocalName().equals("annotation")) {
    679 				ct.setAnnotation(handleAnnotation(el));
    680 			} else if (el.getLocalName().equals("anyAttribute")) {
    681 				ct.setAnyAttribute(handleAnyAttribute(schema, el, schemaEl));
    682 			}
    683 			//}
    684 		}
    685 		if (complexEl.hasAttribute("block")) {
    686 			String blockStr = complexEl.getAttribute("block");
    687 			if (blockStr.equalsIgnoreCase("all")
    688 					| blockStr.equalsIgnoreCase("#all")) {
    689
    690 				ct.setBlock(new XmlSchemaDerivationMethod(
    691 						Constants.BlockConstants.ALL));
    692 			} else
    693 				ct.setBlock(new XmlSchemaDerivationMethod(blockStr));
    694 			//ct.setBlock(new XmlSchemaDerivationMethod(block));
    695 		}
    696 		if (complexEl.hasAttribute("final")) {
    697 			String finalstr = complexEl.getAttribute("final");
    698 			if (finalstr.equalsIgnoreCase("all")
    699 					| finalstr.equalsIgnoreCase("#all")) {
    700
    701 				ct.setFinal(new XmlSchemaDerivationMethod(
    702 						Constants.BlockConstants.ALL));
    703 			} else
    704 				ct.setFinal(new XmlSchemaDerivationMethod(finalstr));
    705 		}
    706 		if (complexEl.hasAttribute("abstract")) {
    707 			String abs = complexEl.getAttribute("abstract");
    708 			if (abs.equalsIgnoreCase("true"))
    709 				ct.setAbstract(true);
    710 			else
    711 				ct.setAbstract(false);
    712 		}
    713 		if (complexEl.hasAttribute("mixed")) {
    714 			String mixed = complexEl.getAttribute("mixed");
    715 			if (mixed.equalsIgnoreCase("true"))
    716 				ct.setMixed(true);
    717 			else
    718 				ct.setMixed(false);
    719 		}
    720
    721 		//process extra attributes and elements
    722 		processExtensibilityComponents(ct, complexEl);
    723
    724 		return ct;
    725 	}
    726
    727 	private XmlSchemaSimpleContent handleSimpleContent(XmlSchema schema,
    728 			Element simpleEl, Element schemaEl) {
    729
    730 		XmlSchemaSimpleContent simpleContent = new XmlSchemaSimpleContent();
    731
    732 		for (Element el = XDOMUtil.getFirstChildElementNS(simpleEl,
    733 				XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
    734 				.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
    735
    736 			if (el.getLocalName().equals("restriction")) {
    737 				simpleContent.content = handleSimpleContentRestriction(schema,
    738 						el, schemaEl);
    739 			} else if (el.getLocalName().equals("extension")) {
    740 				simpleContent.content = handleSimpleContentExtension(schema,
    741 						el, schemaEl);
    742 			} else if (el.getLocalName().equals("annotation")) {
    743 				simpleContent.setAnnotation(handleAnnotation(el));
    744 			}
    745 		}
    746 		return simpleContent;
    747 	}
    748
    749 	private XmlSchemaComplexContent handleComplexContent(XmlSchema schema,
    750 			Element complexEl, Element schemaEl) {
    751
    752 		XmlSchemaComplexContent complexContent = new XmlSchemaComplexContent();
    753
    754 		for (Element el = XDOMUtil.getFirstChildElementNS(complexEl,
    755 				XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
    756 				.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
    757
    758 			if (el.getLocalName().equals("restriction")) {
    759 				complexContent.content = handleComplexContentRestriction(
    760 						schema, el, schemaEl);
    761 			} else if (el.getLocalName().equals("extension")) {
    762 				complexContent.content = handleComplexContentExtension(schema,
    763 						el, schemaEl);
    764 			} else if (el.getLocalName().equals("annotation")) {
    765 				complexContent.setAnnotation(handleAnnotation(el));
    766 			}
    767 		}
    768
    769 		if (complexEl.hasAttribute("mixed")) {
    770 			String mixed = complexEl.getAttribute("mixed");
    771 			if (mixed.equalsIgnoreCase("true"))
    772 				complexContent.setMixed(true);
    773 			else
    774 				complexContent.setMixed(false);
    775 		}
    776
    777 		return complexContent;
    778 	}
    779
    780 	private XmlSchemaSimpleContentRestriction handleSimpleContentRestriction(
    781 			XmlSchema schema, Element restrictionEl, Element schemaEl) {
    782
    783 		XmlSchemaSimpleContentRestriction restriction = new XmlSchemaSimpleContentRestriction();
    784
    785 		if (restrictionEl.hasAttribute("base")) {
    786 			String name = restrictionEl.getAttribute("base");
    787 			restriction.baseTypeName = getRefQName(name, restrictionEl);
    788 		}
    789
    790 		if (restrictionEl.hasAttribute("id"))
    791 			restriction.id = restrictionEl.getAttribute("id");
    792
    793 		// check back simpleContent tag children to add attributes and simpleType if any occur
    794 		for (Element el = XDOMUtil.getFirstChildElementNS(restrictionEl,
    795 				XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
    796 				.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
    797
    798 			if (el.getLocalName().equals("attribute")) {
    799 				XmlSchemaAttribute attr = handleAttribute(schema, el, schemaEl);
    800 				restriction.attributes.add(attr);
    801 			} else if (el.getLocalName().equals("attributeGroup")) {
    802 				XmlSchemaAttributeGroupRef attrGroup = handleAttributeGroupRef(el);
    803 				restriction.attributes.add(attrGroup);
    804 			} else if (el.getLocalName().equals("simpleType")) {
    805 				restriction.baseType = handleSimpleType(schema, el, schemaEl);
    806 			} else if (el.getLocalName().equals("anyAttribute")) {
    807 				restriction.anyAttribute = handleAnyAttribute(schema, el,
    808 						schemaEl);
    809 			} else if (el.getLocalName().equals("annotation")) {
    810 				restriction.setAnnotation(handleAnnotation(el));
    811 			} else {
    812 				XmlSchemaFacet facet = XmlSchemaFacet.construct(el);
    813 				if(XDOMUtil.anyElementsWithNameNS(el, XmlSchema.SCHEMA_NS, "annotation")) {
    814 					XmlSchemaAnnotation facetAnnotation = handleAnnotation(el);
    815 					facet.setAnnotation(facetAnnotation);
    816 				}
    817 				restriction.facets.add(facet);
    818 			}
    819 		}
    820 		return restriction;
    821 	}
    822
    823 	private XmlSchemaSimpleContentExtension handleSimpleContentExtension(
    824 			XmlSchema schema, Element extEl, Element schemaEl) {
    825
    826 		XmlSchemaSimpleContentExtension ext = new XmlSchemaSimpleContentExtension();
    827
    828 		if (extEl.hasAttribute("base")) {
    829 			String name = extEl.getAttribute("base");
    830 			ext.baseTypeName = getRefQName(name, extEl);
    831 		}
    832
    833 		for (Element el = XDOMUtil.getFirstChildElementNS(extEl,
    834 				XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
    835 				.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
    836
    837 			if (el.getLocalName().equals("attribute")) {
    838 				XmlSchemaAttribute attr = handleAttribute(schema, el, schemaEl);
    839 				ext.attributes.add(attr);
    840 			} else if (el.getLocalName().equals("attributeGroup")) {
    841 				XmlSchemaAttributeGroupRef attrGroup = handleAttributeGroupRef(el);
    842 				ext.attributes.add(attrGroup);
    843 			} else if (el.getLocalName().equals("anyAttribute")) {
    844 				ext.anyAttribute = handleAnyAttribute(schema, el, schemaEl);
    845 			} else if (el.getLocalName().equals("annotation")) {
    846 				XmlSchemaAnnotation ann = handleAnnotation(el);
    847 				ext.setAnnotation(ann);
    848 			}
    849 		}
    850 		return ext;
    851 	}
    852
    853 	private XmlSchemaComplexContentRestriction handleComplexContentRestriction(
    854 			XmlSchema schema, Element restrictionEl, Element schemaEl) {
    855
    856 		XmlSchemaComplexContentRestriction restriction = new XmlSchemaComplexContentRestriction();
    857
    858 		if (restrictionEl.hasAttribute("base")) {
    859 			String name = restrictionEl.getAttribute("base");
    860 			restriction.baseTypeName = getRefQName(name, restrictionEl);
    861 		}
    862 		for (Element el = XDOMUtil.getFirstChildElementNS(restrictionEl,
    863 				XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
    864 				.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
    865
    866 			if (el.getLocalName().equals("sequence")) {
    867 				restriction.particle = handleSequence(schema, el, schemaEl);
    868 			} else if (el.getLocalName().equals("choice")) {
    869 				restriction.particle = handleChoice(schema, el, schemaEl);
    870 			} else if (el.getLocalName().equals("all")) {
    871 				restriction.particle = handleAll(schema, el, schemaEl);
    872 			} else if (el.getLocalName().equals("attribute")) {
    873 				restriction.attributes
    874 						.add(handleAttribute(schema, el, schemaEl));
    875 			} else if (el.getLocalName().equals("attributeGroup")) {
    876 				restriction.attributes.add(handleAttributeGroupRef(el));
    877 			} else if (el.getLocalName().equals("group")) {
    878 				restriction.particle = handleGroupRef(schema, el, schemaEl);
    879 			} else if (el.getLocalName().equals("anyAttribute")) {
    880 				restriction.anyAttribute = handleAnyAttribute(schema, el,
    881 						schemaEl);
    882 			} else if (el.getLocalName().equals("annotation")) {
    883 				restriction.setAnnotation(handleAnnotation(el));
    884 			}
    885 		}
    886 		return restriction;
    887 	}
    888
    889 	private XmlSchemaComplexContentExtension handleComplexContentExtension(
    890 			XmlSchema schema, Element extEl, Element schemaEl) {
    891
    892 		XmlSchemaComplexContentExtension ext = new XmlSchemaComplexContentExtension();
    893
    894 		if (extEl.hasAttribute("base")) {
    895 			String name = extEl.getAttribute("base");
    896 			ext.baseTypeName = getRefQName(name, extEl);
    897 		}
    898
    899 		for (Element el = XDOMUtil.getFirstChildElementNS(extEl,
    900 				XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
    901 				.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
    902
    903 			if (el.getLocalName().equals("sequence")) {
    904 				ext.particle = handleSequence(schema, el, schemaEl);
    905 			} else if (el.getLocalName().equals("choice")) {
    906 				ext.particle = handleChoice(schema, el, schemaEl);
    907 			} else if (el.getLocalName().equals("all")) {
    908 				ext.particle = handleAll(schema, el, schemaEl);
    909 			} else if (el.getLocalName().equals("attribute")) {
    910 				ext.attributes.add(handleAttribute(schema, el, schemaEl));
    911 			} else if (el.getLocalName().equals("attributeGroup")) {
    912 				ext.attributes.add(handleAttributeGroupRef(el));
    913 			} else if (el.getLocalName().equals("group")) {
    914 				ext.particle = handleGroupRef(schema, el, schemaEl);
    915 			} else if (el.getLocalName().equals("anyAttribute")) {
    916 				ext.anyAttribute = handleAnyAttribute(schema, el, schemaEl);
    917 			} else if (el.getLocalName().equals("annotation")) {
    918 				ext.setAnnotation(handleAnnotation(el));
    919 			}
    920 		}
    921 		return ext;
    922 	}
    923
    924 	private XmlSchemaAttributeGroupRef handleAttributeGroupRef(
    925 			Element attrGroupEl) {
    926
    927 		XmlSchemaAttributeGroupRef attrGroup = new XmlSchemaAttributeGroupRef();
    928
    929 		if (attrGroupEl.hasAttribute("ref")) {
    930 			String ref = attrGroupEl.getAttribute("ref");
    931 			attrGroup.refName = getRefQName(ref, attrGroupEl);
    932 		}
    933
    934 		if (attrGroupEl.hasAttribute("id"))
    935 			attrGroup.id = attrGroupEl.getAttribute("id");
    936
    937 		Element annotationEl = XDOMUtil.getFirstChildElementNS(attrGroupEl,
    938 				XmlSchema.SCHEMA_NS, "annotation");
    939
    940 		if (annotationEl != null) {
    941 			XmlSchemaAnnotation annotation = handleAnnotation(annotationEl);
    942 			attrGroup.setAnnotation(annotation);
    943 		}
    944 		return attrGroup;
    945 	}
    946
    947 	private XmlSchemaSequence handleSequence(XmlSchema schema,
    948 			Element sequenceEl, Element schemaEl) {
    949
    950 		XmlSchemaSequence sequence = new XmlSchemaSequence();
    951
    952 		//handle min and max occurences
    953 		sequence.minOccurs = getMinOccurs(sequenceEl);
    954 		sequence.maxOccurs = getMaxOccurs(sequenceEl);
    955
    956 		for (Element el = XDOMUtil.getFirstChildElementNS(sequenceEl,
    957 				XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
    958 				.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
    959
    960 			if (el.getLocalName().equals("sequence")) {
    961 				XmlSchemaSequence seq = handleSequence(schema, el, schemaEl);
    962 				sequence.items.add(seq);
    963 			} else if (el.getLocalName().equals("element")) {
    964 				XmlSchemaElement element = handleElement(schema, el, schemaEl,
    965 						false);
    966 				sequence.items.add(element);
    967 			} else if (el.getLocalName().equals("group")) {
    968 				XmlSchemaGroupRef group = handleGroupRef(schema, el, schemaEl);
    969 				sequence.items.add(group);
    970 			} else if (el.getLocalName().equals("choice")) {
    971 				XmlSchemaChoice choice = handleChoice(schema, el, schemaEl);
    972 				sequence.items.add(choice);
    973 			} else if (el.getLocalName().equals("any")) {
    974 				XmlSchemaAny any = handleAny(schema, el, schemaEl);
    975 				sequence.items.add(any);
    976 			} else if (el.getLocalName().equals("annotation")) {
    977 				XmlSchemaAnnotation annotation = handleAnnotation(el);
    978 				sequence.setAnnotation(annotation);
    979 			}
    980 		}
    981 		return sequence;
    982 	}
    983
    984 	/** @noinspection UnusedParameters*/
    985 	private XmlSchemaAny handleAny(XmlSchema schema, Element anyEl,
    986 			Element schemaEl) {
    987
    988 		XmlSchemaAny any = new XmlSchemaAny();
    989
    990 		if (anyEl.hasAttribute("namespace"))
    991 			any.namespace = anyEl.getAttribute("namespace");
    992
    993 		if (anyEl.hasAttribute("processContents")) {
    994 			String processContent = getEnumString(anyEl, "processContents");
    995
    996 			any.processContent = new XmlSchemaContentProcessing(processContent);
    997 		}
    998
    999 		Element annotationEl = XDOMUtil.getFirstChildElementNS(anyEl,
    1000 				XmlSchema.SCHEMA_NS, "annotation");
    1001
    1002 		if (annotationEl != null) {
    1003 			XmlSchemaAnnotation annotation = handleAnnotation(annotationEl);
    1004 			any.setAnnotation(annotation);
    1005 		}
    1006 		any.minOccurs = getMinOccurs(anyEl);
    1007 		any.maxOccurs = getMaxOccurs(anyEl);
    1008
    1009 		return any;
    1010 	}
    1011
    1012 	private XmlSchemaChoice handleChoice(XmlSchema schema, Element choiceEl,
    1013 			Element schemaEl) {
    1014 		XmlSchemaChoice choice = new XmlSchemaChoice();
    1015
    1016 		if (choiceEl.hasAttribute("id"))
    1017 			choice.id = choiceEl.getAttribute("id");
    1018
    1019 		choice.minOccurs = getMinOccurs(choiceEl);
    1020 		choice.maxOccurs = getMaxOccurs(choiceEl);
    1021
    1022 		for (Element el = XDOMUtil.getFirstChildElementNS(choiceEl,
    1023 				XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
    1024 				.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
    1025
    1026 			if (el.getLocalName().equals("sequence")) {
    1027 				XmlSchemaSequence seq = handleSequence(schema, el, schemaEl);
    1028 				choice.items.add(seq);
    1029 			} else if (el.getLocalName().equals("element")) {
    1030 				XmlSchemaElement element = handleElement(schema, el, schemaEl,
    1031 						false);
    1032 				choice.items.add(element);
    1033 			} else if (el.getLocalName().equals("group")) {
    1034 				XmlSchemaGroupRef group = handleGroupRef(schema, el, schemaEl);
    1035 				choice.items.add(group);
    1036 			} else if (el.getLocalName().equals("choice")) {
    1037 				XmlSchemaChoice choiceItem = handleChoice(schema, el, schemaEl);
    1038 				choice.items.add(choiceItem);
    1039 			} else if (el.getLocalName().equals("any")) {
    1040 				XmlSchemaAny any = handleAny(schema, el, schemaEl);
    1041 				choice.items.add(any);
    1042 			} else if (el.getLocalName().equals("annotation")) {
    1043 				XmlSchemaAnnotation annotation = handleAnnotation(el);
    1044 				choice.setAnnotation(annotation);
    1045 			}
    1046 		}
    1047 		return choice;
    1048 	}
    1049
    1050 	private XmlSchemaAll handleAll(XmlSchema schema, Element allEl,
    1051 			Element schemaEl) {
    1052
    1053 		XmlSchemaAll all = new XmlSchemaAll();
    1054
    1055 		//handle min and max occurences
    1056 		all.minOccurs = getMinOccurs(allEl);
    1057 		all.maxOccurs = getMaxOccurs(allEl);
    1058
    1059 		for (Element el = XDOMUtil.getFirstChildElementNS(allEl,
    1060 				XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
    1061 				.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
    1062
    1063 			if (el.getLocalName().equals("element")) {
    1064 				XmlSchemaElement element = handleElement(schema, el, schemaEl,
    1065 						false);
    1066 				all.items.add(element);
    1067 			} else if (el.getLocalName().equals("annotation")) {
    1068 				XmlSchemaAnnotation annotation = handleAnnotation(el);
    1069 				all.setAnnotation(annotation);
    1070 			}
    1071 		}
    1072 		return all;
    1073 	}
    1074
    1075 	private XmlSchemaGroup handleGroup(XmlSchema schema, Element groupEl,
    1076 			Element schemaEl) {
    1077
    1078 		XmlSchemaGroup group = new XmlSchemaGroup();
    1079 		group.name = new QName(schema.getTargetNamespace(), groupEl
    1080 				.getAttribute("name"));
    1081
    1082 		for (Element el = XDOMUtil.getFirstChildElementNS(groupEl,
    1083 				XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
    1084 				.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
    1085
    1086 			if (el.getLocalName().equals("all")) {
    1087 				group.particle = handleAll(schema, el, schemaEl);
    1088 			} else if (el.getLocalName().equals("sequence")) {
    1089 				group.particle = handleSequence(schema, el, schemaEl);
    1090 			} else if (el.getLocalName().equals("choice")) {
    1091 				group.particle = handleChoice(schema, el, schemaEl);
    1092 			} else if (el.getLocalName().equals("annotation")) {
    1093 				XmlSchemaAnnotation groupAnnotation = handleAnnotation(el);
    1094 				group.setAnnotation(groupAnnotation);
    1095 			}
    1096 		}
    1097 		return group;
    1098 	}
    1099
    1100 	private XmlSchemaAttributeGroup handleAttributeGroup(XmlSchema schema,
    1101 			Element groupEl, Element schemaEl) {
    1102 		XmlSchemaAttributeGroup attrGroup = new XmlSchemaAttributeGroup();
    1103
    1104 		if (groupEl.hasAttribute("name"))
    1105 			attrGroup.name = new QName(schema.getTargetNamespace(), groupEl
    1106 					.getAttribute("name"));
    1107 		if (groupEl.hasAttribute("id"))
    1108 			attrGroup.id = groupEl.getAttribute("id");
    1109
    1110 		for (Element el = XDOMUtil.getFirstChildElementNS(groupEl,
    1111 				XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
    1112 				.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
    1113
    1114 			if (el.getLocalName().equals("attribute")) {
    1115 				XmlSchemaAttribute attr = handleAttribute(schema, el, schemaEl);
    1116 				attrGroup.attributes.add(attr);
    1117 			} else if (el.getLocalName().equals("attributeGroup")) {
    1118 				XmlSchemaAttributeGroupRef attrGroupRef = handleAttributeGroupRef(el);
    1119 				attrGroup.attributes.add(attrGroupRef);
    1120 			} else if (el.getLocalName().equals("anyAttribute")) {
    1121 				attrGroup.anyAttribute = handleAnyAttribute(schema, el,
    1122 						schemaEl);
    1123 			} else if (el.getLocalName().equals("annotation")) {
    1124 				XmlSchemaAnnotation ann = handleAnnotation(el);
    1125 				attrGroup.setAnnotation(ann);
    1126 			}
    1127 		}
    1128 		return attrGroup;
    1129 	}
    1130
    1131 	/** @noinspection UnusedParameters*/
    1132 	private XmlSchemaAnyAttribute handleAnyAttribute(XmlSchema schema,
    1133 			Element anyAttrEl, Element schemaEl) {
    1134
    1135 		XmlSchemaAnyAttribute anyAttr = new XmlSchemaAnyAttribute();
    1136
    1137 		if (anyAttrEl.hasAttribute("namespace"))
    1138 			anyAttr.namespace = anyAttrEl.getAttribute("namespace");
    1139
    1140 		if (anyAttrEl.hasAttribute("processContents")) {
    1141
    1142 			String contentProcessing = getEnumString(anyAttrEl,
    1143 					"processContents");
    1144
    1145 			anyAttr.processContent = new XmlSchemaContentProcessing(
    1146 					contentProcessing);
    1147 		}
    1148 		if (anyAttrEl.hasAttribute("id"))
    1149 			anyAttr.id = anyAttrEl.getAttribute("id");
    1150
    1151 		Element annotationEl = XDOMUtil.getFirstChildElementNS(anyAttrEl,
    1152 				XmlSchema.SCHEMA_NS, "annotation");
    1153
    1154 		if (annotationEl != null) {
    1155 			XmlSchemaAnnotation annotation = handleAnnotation(annotationEl);
    1156
    1157 			anyAttr.setAnnotation(annotation);
    1158 		}
    1159 		return anyAttr;
    1160 	}
    1161
    1162 	private XmlSchemaGroupRef handleGroupRef(XmlSchema schema, Element groupEl,
    1163 			Element schemaEl) {
    1164
    1165 		XmlSchemaGroupRef group = new XmlSchemaGroupRef();
    1166
    1167 		group.maxOccurs = getMaxOccurs(groupEl);
    1168 		group.minOccurs = getMinOccurs(groupEl);
    1169
    1170 		Element annotationEl = XDOMUtil.getFirstChildElementNS(groupEl,
    1171 				XmlSchema.SCHEMA_NS, "annotation");
    1172
    1173 		if (annotationEl != null) {
    1174 			XmlSchemaAnnotation annotation = handleAnnotation(annotationEl);
    1175
    1176 			group.setAnnotation(annotation);
    1177 		}
    1178
    1179 		if (groupEl.hasAttribute("ref")) {
    1180 			String ref = groupEl.getAttribute("ref");
    1181 			group.refName = getRefQName(ref, groupEl);
    1182 			return group;
    1183 		}
    1184 		for (Element el = XDOMUtil.getFirstChildElementNS(groupEl,
    1185 				XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
    1186 				.getNextSiblingElement(el)) {
    1187
    1188 			if (el.getLocalName().equals("sequence")) {
    1189 				group.particle = handleSequence(schema, el, schemaEl);
    1190 			} else if (el.getLocalName().equals("all")) {
    1191 				group.particle = handleAll(schema, el, schemaEl);
    1192 			} else if (el.getLocalName().equals("choice")) {
    1193 				group.particle = handleChoice(schema, el, schemaEl);
    1194 			}
    1195 		}
    1196 		return group;
    1197 	}
    1198
    1199 	private QName newLocalQName(String pLocalName) {
    1200 		String uri = schema.logicalTargetNamespace;
    1201 		if (uri == null) {
    1202 			uri = Constants.NULL_NS_URI;
    1203 		}
    1204 		return new QName(uri, pLocalName);
    1205 	}
    1206
    1207 	/**
    1208 	 * Process non-toplevel attributes
    1209 	 * @param schema
    1210 	 * @param attrEl
    1211 	 * @param schemaEl
    1212 	 * @return
    1213 	 */
    1214 	private XmlSchemaAttribute handleAttribute(XmlSchema schema,
    1215 			Element attrEl, Element schemaEl) {
    1216 		return handleAttribute(schema, attrEl, schemaEl, false);
    1217 	}
    1218
    1219 	/**
    1220 	 * Process attributes
    1221 	 * @param schema
    1222 	 * @param attrEl
    1223 	 * @param schemaEl
    1224 	 * @param topLevel
    1225 	 * @return
    1226 	 */
    1227 	private XmlSchemaAttribute handleAttribute(XmlSchema schema,
    1228 			Element attrEl, Element schemaEl, boolean topLevel) {
    1229 		//todo: need to implement different rule of attribute such as
    1230 		//restriction between ref and name.  This can be implemented
    1231 		//in the compile function
    1232 		XmlSchemaAttribute attr = new XmlSchemaAttribute();
    1233
    1234 		if (attrEl.hasAttribute("name")) {
    1235 			String name = attrEl.getAttribute("name");
    1236 			//String namespace = (schema.targetNamespace==null)?
    1237 			//                  "" :schema.targetNamespace;
    1238
    1239 			attr.name = name;
    1240 		}
    1241
    1242 		boolean isQualified = schema.getAttributeFormDefault().getValue()
    1243 				.equals(XmlSchemaForm.QUALIFIED);
    1244 		if (attr.name != null) {
    1245 			final String name = attr.name;
    1246 			if (topLevel) {
    1247 				attr.qualifiedName = newLocalQName(name);
    1248 			} else {
    1249 				attr.qualifiedName = (isQualified) ? newLocalQName(name)
    1250 						: new QName(name);
    1251 			}
    1252 		}
    1253
    1254 		if (attrEl.hasAttribute("type")) {
    1255 			String name = attrEl.getAttribute("type");
    1256 			attr.schemaTypeName = getRefQName(name, attrEl);
    1257 		}
    1258
    1259 		if (attrEl.hasAttribute("default"))
    1260 			attr.defaultValue = attrEl.getAttribute("default");
    1261
    1262 		if (attrEl.hasAttribute("fixed"))
    1263 			attr.fixedValue = attrEl.getAttribute("fixed");
    1264
    1265 		if (attrEl.hasAttribute("form")) {
    1266 			String formValue = getEnumString(attrEl, "form");
    1267 			attr.form = new XmlSchemaForm(formValue);
    1268 		}
    1269 		if (attrEl.hasAttribute("id"))
    1270 			attr.id = attrEl.getAttribute("id");
    1271
    1272 		if (attrEl.hasAttribute("use")) {
    1273 			String useType = getEnumString(attrEl, "use");
    1274 			attr.use = new XmlSchemaUse(useType);
    1275 		}
    1276 		if (attrEl.hasAttribute("ref")) {
    1277 			String name = attrEl.getAttribute("ref");
    1278 			attr.refName = getRefQName(name, attrEl);
    1279 			attr.name = name;
    1280 		}
    1281
    1282 		Element simpleTypeEl = XDOMUtil.getFirstChildElementNS(attrEl,
    1283 				XmlSchema.SCHEMA_NS, "simpleType");
    1284
    1285 		if (simpleTypeEl != null) {
    1286 			attr.schemaType = handleSimpleType(schema, simpleTypeEl, schemaEl);
    1287 		}
    1288
    1289 		Element annotationEl = XDOMUtil.getFirstChildElementNS(attrEl,
    1290 				XmlSchema.SCHEMA_NS, "annotation");
    1291
    1292 		if (annotationEl != null) {
    1293 			XmlSchemaAnnotation annotation = handleAnnotation(annotationEl);
    1294
    1295 			attr.setAnnotation(annotation);
    1296 		}
    1297
    1298 		NamedNodeMap attrNodes = attrEl.getAttributes();
    1299 		Vector attrs = new Vector();
    1300 		NodeNamespaceContext ctx = null;
    1301 		for (int i = 0; i < attrNodes.getLength(); i++) {
    1302 			Attr att = (Attr) attrNodes.item(i);
    1303 			String attName = att.getName();
    1304 			if (!attName.equals("name") && !attName.equals("type")
    1305 					&& !attName.equals("default") && !attName.equals("fixed")
    1306 					&& !attName.equals("form") && !attName.equals("id")
    1307 					&& !attName.equals("use") && !attName.equals("ref")) {
    1308
    1309 				attrs.add(att);
    1310 				String value = att.getValue();
    1311
    1312 				if (value.indexOf(":") > -1) {
    1313 					// there is a possiblily of some namespace mapping
    1314 					String prefix = value.substring(0, value.indexOf(":"));
    1315 					if (ctx == null) {
    1316 						ctx = NodeNamespaceContext.getNamespaceContext(attrEl);
    1317 					}
    1318 					String namespace = ctx.getNamespaceURI(prefix);
    1319 					if (!Constants.NULL_NS_URI.equals(namespace)) {
    1320 						Attr nsAttr = attrEl.getOwnerDocument()
    1321 								.createAttribute("xmlns:" + prefix);
    1322 						nsAttr.setValue(namespace);
    1323 						attrs.add(nsAttr);
    1324 					}
    1325 				}
    1326 			}
    1327 		}
    1328
    1329 		if (attrs.size() > 0)
    1330 			attr.setUnhandledAttributes((Attr[]) attrs.toArray(new Attr[0]));
    1331
    1332 		//process extra attributes and elements
    1333 		processExtensibilityComponents(attr, attrEl);
    1334 		return attr;
    1335 	}
    1336
    1337 	/*
    1338 	 * handle_simple_content_restriction
    1339 	 *
    1340 	 * if( restriction has base attribute )
    1341 	 *		set the baseType
    1342 	 * else if( restriciton has an inline simpleType )
    1343 	 *		handleSimpleType
    1344 	 * add facets if any to the restriction
    1345 	 */
    1346
    1347 	/*
    1348 	 * handle_simple_content_extension
    1349 	 *
    1350 	 * extension should have a base name and cannot have any inline defn
    1351 	 * for( each childNode  )
    1352 	 *		if( attribute)
    1353 	 *			handleAttribute
    1354 	 *		else if( attributeGroup)
    1355 	 *			handleAttributeGroup
    1356 	 *		else if( anyAttribute)
    1357 	 *			handleAnyAttribute
    1358 	 */
    1359
    1360 	/*
    1361 	 * ********
    1362 	 * handle_complex_content_restriction
    1363 	 */
    1364 	/**
    1365 	 * handle elements
    1366 	 * @param schema
    1367 	 * @param el
    1368 	 * @param schemaEl
    1369 	 * @param isGlobal
    1370 	 */
    1371 	XmlSchemaElement handleElement(XmlSchema schema, Element el,
    1372 			Element schemaEl, boolean isGlobal) {
    1373
    1374 		XmlSchemaElement element = new XmlSchemaElement();
    1375
    1376 		if (el.getAttributeNode("name") != null)
    1377 			element.name = el.getAttribute("name");
    1378
    1379 		//                String namespace = (schema.targetNamespace==null)?
    1380 		//                                      "" : schema.targetNamespace;
    1381
    1382 		boolean isQualified = schema.getElementFormDefault().getValue().equals(
    1383 				XmlSchemaForm.QUALIFIED);
    1384 		if (el.hasAttribute("form")) {
    1385 			String formDef = el.getAttribute("form");
    1386 			element.form = new XmlSchemaForm(formDef);
    1387 			isQualified = formDef.equals(XmlSchemaForm.QUALIFIED);
    1388 		}
    1389
    1390 		if (element.name != null) {
    1391 			final String name = element.name;
    1392 			element.qualifiedName = (isQualified || isGlobal) ? newLocalQName(name)
    1393 					: new QName(Constants.NULL_NS_URI, name);
    1394 		}
    1395
    1396 		Element annotationEl = XDOMUtil.getFirstChildElementNS(el,
    1397 				XmlSchema.SCHEMA_NS, "annotation");
    1398
    1399 		if (annotationEl != null) {
    1400 			XmlSchemaAnnotation annotation = handleAnnotation(annotationEl);
    1401
    1402 			element.setAnnotation(annotation);
    1403 		}
    1404 		if (el.getAttributeNode("type") != null) {
    1405 			String typeName = el.getAttribute("type");
    1406 			QName typeQName = element.schemaTypeName = getRefQName(typeName, el);
    1407
    1408 			XmlSchemaType type = collection.getTypeByQName(typeQName);
    1409 			if (type == null) {
    1410 				// Could be a forward reference...
    1411 				collection.addUnresolvedType(typeQName, element);
    1412 			}
    1413 			element.schemaType = type;
    1414 		} else if (el.getAttributeNode("ref") != null) {
    1415 			String refName = el.getAttribute("ref");
    1416 			QName refQName = getRefQName(refName, el);
    1417 			element.setRefName(refQName);
    1418 			element.name = refQName.getLocalPart();
    1419 		}
    1420
    1421 		Element simpleTypeEl, complexTypeEl, keyEl, keyrefEl, uniqueEl;
    1422
    1423 		if ((simpleTypeEl = XDOMUtil.getFirstChildElementNS(el,
    1424 				XmlSchema.SCHEMA_NS, "simpleType")) != null) {
    1425
    1426 			XmlSchemaSimpleType simpleType = handleSimpleType(schema,
    1427 					simpleTypeEl, schemaEl);
    1428 			element.schemaType = simpleType;
    1429 			element.schemaTypeName = simpleType.getQName();
    1430 		} else if ((complexTypeEl = XDOMUtil.getFirstChildElementNS(el,
    1431 				XmlSchema.SCHEMA_NS, "complexType")) != null) {
    1432
    1433 			element.schemaType = handleComplexType(schema, complexTypeEl,
    1434 					schemaEl);
    1435 		}
    1436
    1437 		if ((keyEl = XDOMUtil.getFirstChildElementNS(el, XmlSchema.SCHEMA_NS,
    1438 				"key")) != null) {
    1439 			while (keyEl != null) {
    1440 				element.constraints.add(handleConstraint(keyEl, "Key"));
    1441 				keyEl = XDOMUtil.getNextSiblingElement(keyEl, "key");
    1442 			}
    1443 		}
    1444
    1445 		if ((keyrefEl = XDOMUtil.getFirstChildElementNS(el,
    1446 				XmlSchema.SCHEMA_NS, "keyref")) != null) {
    1447 			while (keyrefEl != null) {
    1448 				XmlSchemaKeyref keyRef = (XmlSchemaKeyref) handleConstraint(
    1449 						keyrefEl, "Keyref");
    1450 				if (keyrefEl.hasAttribute("refer")) {
    1451 					String name = keyrefEl.getAttribute("refer");
    1452 					keyRef.refer = getRefQName(name, el);
    1453 				}
    1454 				element.constraints.add(keyRef);
    1455 				keyrefEl = XDOMUtil.getNextSiblingElement(keyrefEl, "keyref");
    1456 			}
    1457 		}
    1458
    1459 		if ((uniqueEl = XDOMUtil.getFirstChildElementNS(el,
    1460 				XmlSchema.SCHEMA_NS, "unique")) != null) {
    1461 			while (uniqueEl != null) {
    1462 				element.constraints.add(handleConstraint(uniqueEl, "Unique"));
    1463 				uniqueEl = XDOMUtil.getNextSiblingElement(uniqueEl, "unique");
    1464 			}
    1465 		}
    1466
    1467 		if (el.hasAttribute("abstract")) {
    1468 			element.isAbstract = Boolean.valueOf(el.getAttribute("abstract"))
    1469 					.booleanValue();
    1470 		}
    1471
    1472 		if (el.hasAttribute("block"))
    1473 			element.block = getDerivation(el, "block");
    1474
    1475 		if (el.hasAttribute("default"))
    1476 			element.defaultValue = el.getAttribute("default");
    1477
    1478 		if (el.hasAttribute("final"))
    1479 			element.finalDerivation = getDerivation(el, "final");
    1480
    1481 		if (el.hasAttribute("fixed"))
    1482 			element.fixedValue = el.getAttribute("fixed");
    1483
    1484 		if (el.hasAttribute("id"))
    1485 			element.id = el.getAttribute("id");
    1486
    1487 		if (el.hasAttribute("nillable"))
    1488 			element.isNillable = Boolean.valueOf(el.getAttribute("nillable"))
    1489 					.booleanValue();
    1490
    1491 		if (el.hasAttribute("substitutionGroup")) {
    1492 			String substitutionGroup = el.getAttribute("substitutionGroup");
    1493 			element.setSubstitutionGroup(getRefQName(substitutionGroup, el));
    1494 		}
    1495
    1496 		element.minOccurs = getMinOccurs(el);
    1497 		element.maxOccurs = getMaxOccurs(el);
    1498
    1499 		//process extra attributes and elements
    1500 		processExtensibilityComponents(element, el);
    1501
    1502 		return element;
    1503 	}
    1504
    1505 	private XmlSchemaIdentityConstraint handleConstraint(Element constraintEl,
    1506 			String type) {
    1507
    1508 		try {
    1509 			XmlSchemaIdentityConstraint constraint = (XmlSchemaIdentityConstraint) Class
    1510 					.forName("org.apache.ws.commons.schema.XmlSchema" + type)
    1511 					.newInstance();
    1512
    1513 			if (constraintEl.hasAttribute("name"))
    1514 				constraint.name = constraintEl.getAttribute("name");
    1515
    1516 			if (constraintEl.hasAttribute("refer")) {
    1517 				String name = constraintEl.getAttribute("refer");
    1518 				((XmlSchemaKeyref) constraint).refer = getRefQName(name,
    1519 						constraintEl);
    1520 			}
    1521 			for (Element el = XDOMUtil.getFirstChildElementNS(constraintEl,
    1522 					XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
    1523 					.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
    1524
    1525 				//    String elPrefix = el.getPrefix() == null ? ""
    1526 				//     : el.getPrefix();
    1527 				//if(elPrefix.equals(schema.schema_ns_prefix)) {
    1528 				if (el.getLocalName().equals("selector")) {
    1529 					XmlSchemaXPath selectorXPath = new XmlSchemaXPath();
    1530 					selectorXPath.xpath = el.getAttribute("xpath");
    1531
    1532 					Element annotationEl = XDOMUtil.getFirstChildElementNS(el,
    1533 							XmlSchema.SCHEMA_NS, "annotation");
    1534 					if (annotationEl != null) {
    1535 						XmlSchemaAnnotation annotation = handleAnnotation(annotationEl);
    1536
    1537 						selectorXPath.setAnnotation(annotation);
    1538 					}
    1539 					constraint.selector = selectorXPath;
    1540 				} else if (el.getLocalName().equals("field")) {
    1541 					XmlSchemaXPath fieldXPath = new XmlSchemaXPath();
    1542 					fieldXPath.xpath = el.getAttribute("xpath");
    1543 					constraint.fields.add(fieldXPath);
    1544
    1545 					Element annotationEl = XDOMUtil.getFirstChildElementNS(el,
    1546 							XmlSchema.SCHEMA_NS, "annotation");
    1547
    1548 					if (annotationEl != null) {
    1549 						XmlSchemaAnnotation annotation = handleAnnotation(annotationEl);
    1550
    1551 						fieldXPath.setAnnotation(annotation);
    1552 					}
    1553 				} else if (el.getLocalName().equals("annotation")) {
    1554 					XmlSchemaAnnotation constraintAnnotation = handleAnnotation(el);
    1555 					constraint.setAnnotation(constraintAnnotation);
    1556 				}
    1557 			}
    1558 			return constraint;
    1559 		} catch (ClassNotFoundException e) {
    1560 			throw new XmlSchemaException(e.getMessage());
    1561 		} catch (InstantiationException e) {
    1562 			throw new XmlSchemaException(e.getMessage());
    1563 		} catch (IllegalAccessException e) {
    1564 			throw new XmlSchemaException(e.getMessage());
    1565 		}
    1566 	}
    1567
    1568 	/**
    1569 	 * Handle the import
    1570 	 * @param schema
    1571 	 * @param importEl
    1572 	 * @param schemaEl
    1573 	 * @return XmlSchemaObject
    1574 	 */
    1575 	XmlSchemaImport handleImport(XmlSchema schema, Element importEl,
    1576 			Element schemaEl) {
    1577
    1578 		XmlSchemaImport schemaImport = new XmlSchemaImport();
    1579
    1580 		Element annotationEl = XDOMUtil.getFirstChildElementNS(importEl,
    1581 				XmlSchema.SCHEMA_NS, "annotation");
    1582
    1583 		if (annotationEl != null) {
    1584 			XmlSchemaAnnotation importAnnotation = handleAnnotation(annotationEl);
    1585 			schemaImport.setAnnotation(importAnnotation);
    1586 		}
    1587
    1588 		final String uri = schemaImport.namespace = importEl
    1589 				.getAttribute("namespace");
    1590 		schemaImport.schemaLocation = importEl.getAttribute("schemaLocation");
    1591
    1592 		TargetNamespaceValidator validator = new TargetNamespaceValidator() {
    1593 			private boolean isEmpty(String pValue) {
    1594 				return pValue == null || Constants.NULL_NS_URI.equals(pValue);
    1595 			}
    1596
    1597 			public void validate(XmlSchema pSchema) {
    1598 				final boolean valid;
    1599 				if (isEmpty(uri)) {
    1600 					valid = isEmpty(pSchema.syntacticalTargetNamespace);
    1601 				} else {
    1602 					valid = pSchema.syntacticalTargetNamespace.equals(uri);
    1603 				}
    1604 				if (!valid) {
    1605 					throw new XmlSchemaException(
    1606 							"An imported schema was announced to have the namespace "
    1607 									+ uri + ", but has the namespace "
    1608 									+ pSchema.syntacticalTargetNamespace);
    1609 				}
    1610 			}
    1611 		};
    1612 		if ((schemaImport.schemaLocation != null)
    1613 				&& (!schemaImport.schemaLocation.equals(""))) {
    1614 			if (schema.getSourceURI() != null) {
    1615 				schemaImport.schema = resolveXmlSchema(uri,
    1616 						schemaImport.schemaLocation, schema.getSourceURI(),
    1617 						validator);
    1618 			} else {
    1619 				schemaImport.schema = resolveXmlSchema(schemaImport.namespace,
    1620 						schemaImport.schemaLocation, validator);
    1621 			}
    1622 		}
    1623 		return schemaImport;
    1624 	}
    1625
    1626 	/**
    1627 	 * Handles the include
    1628 	 * @param schema
    1629 	 * @param includeEl
    1630 	 * @param schemaEl
    1631 	 */
    1632 	XmlSchemaInclude handleInclude(final XmlSchema schema, Element includeEl,
    1633 			Element schemaEl) {
    1634
    1635 		XmlSchemaInclude include = new XmlSchemaInclude();
    1636
    1637 		Element annotationEl = XDOMUtil.getFirstChildElementNS(includeEl,
    1638 				XmlSchema.SCHEMA_NS, "annotation");
    1639
    1640 		if (annotationEl != null) {
    1641 			XmlSchemaAnnotation includeAnnotation = handleAnnotation(annotationEl);
    1642 			include.setAnnotation(includeAnnotation);
    1643 		}
    1644
    1645 		include.schemaLocation = includeEl.getAttribute("schemaLocation");
    1646
    1647 		//includes are not supposed to have a target namespace
    1648 		// we should be passing in a null in place of the target
    1649 		//namespace
    1650
    1651 		final TargetNamespaceValidator validator = newIncludeValidator(schema);
    1652 		if (schema.getSourceURI() != null) {
    1653 			include.schema = resolveXmlSchema(schema.logicalTargetNamespace,
    1654 					include.schemaLocation, schema.getSourceURI(), validator);
    1655 		} else {
    1656 			include.schema = resolveXmlSchema(schema.logicalTargetNamespace,
    1657 					include.schemaLocation, validator);
    1658 		}
    1659
    1660 		//process extra attributes and elements
    1661 		processExtensibilityComponents(include, includeEl);
    1662 		return include;
    1663 	}
    1664
    1665 	private TargetNamespaceValidator newIncludeValidator(final XmlSchema schema) {
    1666 		return new TargetNamespaceValidator() {
    1667 			private boolean isEmpty(String pValue) {
    1668 				return pValue == null || Constants.NULL_NS_URI.equals(pValue);
    1669 			}
    1670
    1671 			public void validate(XmlSchema pSchema) {
    1672 				if (isEmpty(pSchema.syntacticalTargetNamespace)) {
    1673 					pSchema.logicalTargetNamespace = schema.logicalTargetNamespace;
    1674 				} else {
    1675 					if (!pSchema.syntacticalTargetNamespace
    1676 							.equals(schema.logicalTargetNamespace)) {
    1677 						String msg = "An included schema was announced to have the default target namespace";
    1678 						if (!isEmpty(schema.logicalTargetNamespace)) {
    1679 							msg += " or the target namespace "
    1680 									+ schema.logicalTargetNamespace;
    1681 						}
    1682 						throw new XmlSchemaException(msg
    1683 								+ ", but has the target namespace "
    1684 								+ pSchema.logicalTargetNamespace);
    1685 					}
    1686 				}
    1687 			}
    1688 		};
    1689 	}
    1690
    1691 	/**
    1692 	 * Handles the annotation
    1693 	 * Traversing if encounter appinfo or documentation
    1694 	 * add it to annotation collection
    1695 	 *
    1696 	 */
    1697 	XmlSchemaAnnotation handleAnnotation(Element annotEl) {
    1698 		XmlSchemaObjectCollection content = new XmlSchemaObjectCollection();
    1699 		XmlSchemaAppInfo appInfoObj;
    1700 		XmlSchemaDocumentation docsObj;
    1701
    1702 		for (Element appinfo = XDOMUtil.getFirstChildElementNS(annotEl,
    1703 				XmlSchema.SCHEMA_NS, "appinfo"); appinfo != null; appinfo = XDOMUtil
    1704 				.getNextSiblingElementNS(appinfo, XmlSchema.SCHEMA_NS,
    1705 						"appinfo")) {
    1706
    1707 			appInfoObj = handleAppInfo(appinfo);
    1708 			if (appInfoObj != null) {
    1709 				content.add(appInfoObj);
    1710 			}
    1711 		}
    1712 		for (Element documentation = XDOMUtil.getFirstChildElementNS(annotEl,
    1713 				XmlSchema.SCHEMA_NS, "documentation"); documentation != null; documentation = XDOMUtil
    1714 				.getNextSiblingElementNS(documentation,
    1715
    1716 				XmlSchema.SCHEMA_NS, "documentation")) {
    1717
    1718 			docsObj = handleDocumentation(documentation);
    1719 			if (docsObj != null) {
    1720 				content.add(docsObj);
    1721 			}
    1722 		}
    1723
    1724 		XmlSchemaAnnotation annotation = new XmlSchemaAnnotation();
    1725 		annotation.items = content;
    1726
    1727 		//process extra attributes and elements
    1728 		processExtensibilityComponents(annotation, annotEl);
    1729 		return annotation;
    1730 	}
    1731
    1732 	/**
    1733 	 * create new XmlSchemaAppinfo and add value goten from element
    1734 	 * to this obj
    1735 	 * @param content
    1736 	 */
    1737 	XmlSchemaAppInfo handleAppInfo(Element content) {
    1738 		XmlSchemaAppInfo appInfo = new XmlSchemaAppInfo();
    1739 		NodeList markup = new DocumentFragmentNodeList(content);
    1740
    1741 		if (!content.hasAttribute("source") && markup.getLength() == 0) {
    1742 			return null;
    1743 		}
    1744 		appInfo.setSource(getAttribute(content, "source"));
    1745 		appInfo.setMarkup(markup);
    1746 		return appInfo;
    1747 	}
    1748
    1749 	//iterate each documentation element, create new XmlSchemaAppinfo and add to collection
    1750 	XmlSchemaDocumentation handleDocumentation(Element content) {
    1751 		XmlSchemaDocumentation documentation = new XmlSchemaDocumentation();
    1752 		List markup = getChildren(content);
    1753
    1754 		if (!content.hasAttribute("source")
    1755 				&& !content.hasAttribute("xml:lang")
    1756 				&& markup == null)
    1757 			return null;
    1758
    1759 		documentation.setSource(getAttribute(content, "source"));
    1760 		documentation.setLanguage(getAttribute(content, "xml:lang"));
    1761 		documentation.setMarkup(new DocumentFragmentNodeList(content));
    1762
    1763 		return documentation;
    1764 	}
    1765
    1766 	private String getAttribute(Element content, String attrName) {
    1767 		if (content.hasAttribute(attrName))
    1768 			return content.getAttribute(attrName);
    1769 		return null;
    1770 	}
    1771
    1772 	private List getChildren(Element content) {
    1773 		List result = new ArrayList();
    1774 		for(Node n = content.getFirstChild(); n != null; n = n.getNextSibling()) {
    1775 			result.add(n);
    1776 		}
    1777 		if(result.size() == 0) {
    1778 			return null;
    1779 		} else {
    1780 			return result;
    1781 		}
    1782 	}
    1783
    1784 	long getMinOccurs(Element el) {
    1785 		try {
    1786 			if (el.getAttributeNode("minOccurs") != null) {
    1787 				String value = el.getAttribute("minOccurs");
    1788 				if (value.equals("unbounded"))
    1789 					return Long.MAX_VALUE;
    1790 				else
    1791 					return Long.parseLong(value);
    1792 			}
    1793 			return 1;
    1794 		} catch (java.lang.NumberFormatException e) {
    1795 			return 1;
    1796 		}
    1797 	}
    1798
    1799 	long getMaxOccurs(Element el) {
    1800 		try {
    1801 			if (el.getAttributeNode("maxOccurs") != null) {
    1802 				String value = el.getAttribute("maxOccurs");
    1803 				if (value.equals("unbounded"))
    1804 					return Long.MAX_VALUE;
    1805 				else
    1806 					return Long.parseLong(value);
    1807 			}
    1808 			return 1;
    1809 		} catch (java.lang.NumberFormatException e) {
    1810 			return 1;
    1811 		}
    1812 	}
    1813
    1814 	XmlSchemaForm getFormDefault(Element el, String attrName) {
    1815 		if (el.getAttributeNode(attrName) != null) {
    1816 			String value = el.getAttribute(attrName);
    1817 			return new XmlSchemaForm(value);
    1818 		} else
    1819 			return new XmlSchemaForm("unqualified");
    1820 	}
    1821
    1822 	//Check value entered by user and change according to .net spec,
    1823 	//according to w3c spec have to be "#all"
    1824 	//but in .net the valid enum value is "all".
    1825 	XmlSchemaDerivationMethod getDerivation(Element el, String attrName) {
    1826 		if (el.hasAttribute(attrName) && !el.getAttribute(attrName).equals("")) {
    1827 			//#all | List of (extension | restriction | substitution
    1828 			String derivationMethod = el.getAttribute(attrName).trim();
    1829 			if (derivationMethod.equals("#all"))
    1830 				return new XmlSchemaDerivationMethod(
    1831 						Constants.BlockConstants.ALL);
    1832 			else
    1833 				return new XmlSchemaDerivationMethod(derivationMethod);
    1834 		}
    1835 		return new XmlSchemaDerivationMethod(Constants.BlockConstants.NONE);
    1836 	}
    1837
    1838 	//Check value entered by user and change according to .net spec, user
    1839 	String getEnumString(Element el, String attrName) {
    1840 		if (el.hasAttribute(attrName)) {
    1841 			return el.getAttribute(attrName).trim();
    1842 		}
    1843 		return Constants.BlockConstants.NONE;
    1844 	}
    1845
    1846 	/**
    1847 	 * Resolve the schemas
    1848 	 * @param targetNamespace
    1849 	 * @param schemaLocation
    1850 	 */
    1851 	XmlSchema resolveXmlSchema(String targetNamespace, String schemaLocation,
    1852 			String baseUri, TargetNamespaceValidator validator) {
    1853
    1854         String schemaKey = null;
    1855         if (resolvedSchemas != null) {  // cache is initialized, use it
    1856             // Not being very smart about this at the moment.  One could, for example,
    1857             // see that the schemaLocation or baseUri is the same as another, but differs
    1858             // only by a trailing slash.  As it is now, we assume a single character difference
    1859             // means it's a schema that has yet to be resolved.
    1860             schemaKey = Thread.currentThread().getId() + targetNamespace + schemaLocation + baseUri;
    1861             SoftReference softref = (SoftReference)resolvedSchemas.get(schemaKey);
    1862             if (softref != null) {
    1863                 XmlSchema resolvedSchema = (XmlSchema)softref.get();
    1864                 if (resolvedSchema != null) {
    1865                     return resolvedSchema;
    1866                 }
    1867             }
    1868         }
    1869
    1870 		//use the entity resolver provided if the schema location is present null
    1871 		if (schemaLocation != null && !"".equals(schemaLocation)) {
    1872 			InputSource source = collection.getSchemaResolver().resolveEntity(
    1873 					targetNamespace, schemaLocation, baseUri);
    1874
    1875 			//the entity resolver was unable to resolve this!!
    1876 			if (source == null) {
    1877 				//try resolving it with the target namespace only with the
    1878 				//known namespace map
    1879 				XmlSchema schema = collection.getKnownSchema(targetNamespace);
    1880 				if (schema != null) {
    1881 					return schema;
    1882 				}else{
    1883 					return null;
    1884 				}
    1885 			}
    1886 			final String systemId = source.getSystemId() == null ? schemaLocation
    1887 					: source.getSystemId();
    1888 			// Push repaired system id back into source where read sees it.
    1889 			// It is perhaps a bad thing to patch the source, but this fixes
    1890 			// a problem.
    1891 			source.setSystemId(systemId);
    1892 			final SchemaKey key = new XmlSchemaCollection.SchemaKey(
    1893 					targetNamespace, systemId);
    1894 			XmlSchema schema = collection.getSchema(key);
    1895 			if (schema != null) {
    1896 				return schema;
    1897 			}
    1898 			if (collection.check(key)) {
    1899 				collection.push(key);
    1900 				try {
    1901                     XmlSchema readSchema = collection.read(source, null, validator);
    1902                     if (resolvedSchemas != null) {
    1903                         resolvedSchemas.put(schemaKey, new SoftReference(readSchema));
    1904                     }
    1905 					return readSchema;
    1906 				} catch (Exception e) {
    1907 					throw new RuntimeException(e);
    1908 				} finally {
    1909 					collection.pop();
    1910 				}
    1911 			}
    1912 		}else{
    1913 			XmlSchema schema = collection.getKnownSchema(targetNamespace);
    1914 			if (schema != null) {
    1915 				return schema;
    1916 			}
    1917 		}
    1918
    1919 		return null;
    1920 	}
    1921
    1922 	/**
    1923 	 * Resolve the schemas
    1924 	 * @param targetNamespace
    1925 	 * @param schemaLocation
    1926 	 */
    1927 	XmlSchema resolveXmlSchema(String targetNamespace, String schemaLocation,
    1928 			TargetNamespaceValidator validator) {
    1929
    1930 		return resolveXmlSchema(targetNamespace, schemaLocation,
    1931 				collection.baseUri, validator);
    1932
    1933 	}
    1934
    1935 	/**
    1936 	 * A generic method to process the extra attributes and the the extra
    1937 	 * elements present within the schema.
    1938 	 * What are considered extensions are  child elements with non schema namespace
    1939 	 * and child attributes with any namespace
    1940 	 * @param schemaObject
    1941 	 * @param parentElement
    1942 	 */
    1943 	private void processExtensibilityComponents(XmlSchemaObject schemaObject,
    1944 			Element parentElement) {
    1945
    1946 		if (extReg != null) {
    1947 			//process attributes
    1948 			NamedNodeMap attributes = parentElement.getAttributes();
    1949 			for (int i = 0; i < attributes.getLength(); i++) {
    1950 				Attr attribute = (Attr) attributes.item(i);
    1951
    1952 				String namespaceURI = attribute.getNamespaceURI();
    1953 				String name = attribute.getLocalName();
    1954
    1955 				if (namespaceURI != null
    1956 						&& !"".equals(namespaceURI)
    1957 						&& //ignore unqualified attributes
    1958 						!namespaceURI
    1959 								.startsWith(Constants.XMLNS_ATTRIBUTE_NS_URI) && //ignore namespaces
    1960 						!Constants.URI_2001_SCHEMA_XSD.equals(namespaceURI))
    1961 				//does not belong to the schema namespace by any chance!
    1962 				{
    1963 					QName qName = new QName(namespaceURI, name);
    1964 					extReg.deserializeExtension(schemaObject, qName, attribute);
    1965
    1966 				}
    1967 			}
    1968
    1969 			//process elements
    1970 			Node child = parentElement.getFirstChild();
    1971 			while (child != null) {
    1972 				if (child.getNodeType() == Node.ELEMENT_NODE) {
    1973 					Element extElement = (Element) child;
    1974 					String namespaceURI = extElement.getNamespaceURI();
    1975 					String name = extElement.getLocalName();
    1976
    1977 					if (namespaceURI != null
    1978 							&& !Constants.URI_2001_SCHEMA_XSD
    1979 									.equals(namespaceURI))
    1980 					//does not belong to the schema namespace
    1981 					{
    1982 						QName qName = new QName(namespaceURI, name);
    1983 						extReg.deserializeExtension(schemaObject, qName,
    1984 								extElement);
    1985 					}
    1986 				}
    1987 				child = child.getNextSibling();
    1988 			}
    1989 		}
    1990
    1991 	}
    1992
    1993 }