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 uri
    130 	 */
    131 	XmlSchema handleXmlSchemaElement(Element schemaEl, String uri) {
    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, uri);
    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(uri);
    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 					restriction.facets.add(facet);
    460 				}
    461
    462 			}
    463 			simpleType.content = restriction;
    464
    465 		} else if ((listEl = XDOMUtil.getFirstChildElementNS(simpleEl,
    466 				XmlSchema.SCHEMA_NS, "list")) != null) {
    467
    468 			XmlSchemaSimpleTypeList list = new XmlSchemaSimpleTypeList();
    469
    470 			/******
    471 			 * if( list has an itemType attribute )
    472 			 *		set the baseTypeName and look up the base type
    473 			 * else if( list has a SimpleTypeElement as child)
    474 			 *		get that element and do a handleSimpleType
    475 			 *
    476 			 * set the list has the content of the simpleType
    477 			 */
    478 			Element inlineListType, listAnnotationEl;
    479 			if (listEl.hasAttribute("itemType")) {
    480 				String name = listEl.getAttribute("itemType");
    481 				list.itemTypeName = getRefQName(name, listEl);
    482 			} else if ((inlineListType = XDOMUtil.getFirstChildElementNS(
    483 					listEl, XmlSchema.SCHEMA_NS, "simpleType")) != null) {
    484
    485 				list.itemType = handleSimpleType(schema, inlineListType,
    486 						schemaEl);
    487 			}
    488
    489 			if ((listAnnotationEl = XDOMUtil.getFirstChildElementNS(listEl,
    490 					XmlSchema.SCHEMA_NS, "annotation")) != null) {
    491
    492 				XmlSchemaAnnotation listAnnotation = handleAnnotation(listAnnotationEl);
    493
    494 				list.setAnnotation(listAnnotation);
    495 			}
    496 			simpleType.content = list;
    497
    498 		} else if ((unionEl = XDOMUtil.getFirstChildElementNS(simpleEl,
    499 				XmlSchema.SCHEMA_NS, "union")) != null) {
    500
    501 			XmlSchemaSimpleTypeUnion union = new XmlSchemaSimpleTypeUnion();
    502
    503 			/******
    504 			 * if( union has a memberTypes attribute )
    505 			 *		add the memberTypeSources string
    506 			 *		for (each memberType in the list )
    507 			 *			lookup(memberType)
    508 			 *	for( all SimpleType child Elements)
    509 			 *		add the simpleTypeName (if any) to the memberType Sources
    510 			 *		do a handleSimpleType with the simpleTypeElement
    511 			 */
    512 			if (unionEl.hasAttribute("memberTypes")) {
    513 				String memberTypes = unionEl.getAttribute("memberTypes");
    514 				union.memberTypesSource = memberTypes;
    515 				Vector v = new Vector();
    516 				StringTokenizer tokenizer = new StringTokenizer(memberTypes,
    517 						" ");
    518 				while (tokenizer.hasMoreTokens()) {
    519 					String member = tokenizer.nextToken();
    520 					v.add(getRefQName(member, unionEl));
    521 				}
    522 				union.memberTypesQNames = new QName[v.size()];
    523 				v.copyInto(union.memberTypesQNames);
    524 			}
    525
    526 			Element inlineUnionType = XDOMUtil.getFirstChildElementNS(unionEl,
    527 					XmlSchema.SCHEMA_NS, "simpleType");
    528 			while (inlineUnionType != null) {
    529
    530 				XmlSchemaSimpleType unionSimpleType = handleSimpleType(schema,
    531 						inlineUnionType, schemaEl);
    532
    533 				union.baseTypes.add(unionSimpleType);
    534
    535 				if (unionSimpleType.name != null) {
    536 					union.memberTypesSource += " " + unionSimpleType.name;
    537 				}
    538
    539 				inlineUnionType = XDOMUtil.getNextSiblingElementNS(
    540 						inlineUnionType, XmlSchema.SCHEMA_NS, "simpleType");
    541 			}
    542
    543 			//NodeList annotations = unionEl.getElementsByTagNameNS(
    544 			//XmlSchema.SCHEMA_NS, "annotation");
    545 			Element unionAnnotationEl = XDOMUtil.getFirstChildElementNS(
    546 					unionEl, XmlSchema.SCHEMA_NS, "annotation");
    547
    548 			if (unionAnnotationEl != null) {
    549 				XmlSchemaAnnotation unionAnnotation = handleAnnotation(unionAnnotationEl);
    550
    551 				union.setAnnotation(unionAnnotation);
    552 			}
    553 			simpleType.content = union;
    554 		}
    555
    556 		//process extra attributes and elements
    557 		processExtensibilityComponents(simpleType, simpleEl);
    558
    559 		return simpleType;
    560 	}
    561
    562 	private QName getRefQName(String pName, Node pNode) {
    563 		return getRefQName(pName, NodeNamespaceContext.getNamespaceContext(pNode));
    564 	}
    565
    566 	private QName getRefQName(String pName, NamespaceContext pContext) {
    567 		final int offset = pName.indexOf(':');
    568 		String uri;
    569 		final String localName;
    570 		final String prefix;
    571 		if (offset == -1) {
    572 			uri = pContext.getNamespaceURI(Constants.DEFAULT_NS_PREFIX);
    573 			if (Constants.NULL_NS_URI.equals(uri)) {
    574 				return new QName(Constants.NULL_NS_URI, pName);
    575 			}
    576 			localName = pName;
    577 			prefix = Constants.DEFAULT_NS_PREFIX;
    578 		} else {
    579 			prefix = pName.substring(0, offset);
    580 			uri = pContext.getNamespaceURI(prefix);
    581 			if (uri == null || Constants.NULL_NS_URI.equals(uri)) {
    582 				if (schema.parent != null
    583 						&& schema.parent.getNamespaceContext() != null) {
    584 					uri = schema.parent.getNamespaceContext().getNamespaceURI(
    585 							prefix);
    586 				}
    587 			}
    588
    589 			if (uri == null || Constants.NULL_NS_URI.equals(uri)) {
    590 				throw new IllegalStateException("The prefix " + prefix
    591 						+ " is not bound.");
    592 			}
    593 			localName = pName.substring(offset + 1);
    594 		}
    595 		return new QName(uri, localName, prefix);
    596 	}
    597
    598 	/**
    599 	 * Handle complex types
    600 	 * @param schema
    601 	 * @param complexEl
    602 	 * @param schemaEl
    603 	 */
    604 	XmlSchemaComplexType handleComplexType(XmlSchema schema, Element complexEl,
    605 			Element schemaEl) {
    606
    607 		/******
    608 		 * set the complexTypeName if any
    609 		 * for( eachChildNode)
    610 		 * if ( simpleContent)
    611 		 *		if( restrcition)
    612 		 *			handle_simple_content_restriction
    613 		 *		else if( extension)
    614 		 *			handle_simple_content_extension
    615 		 *		break; // it has to be the only child
    616 		 * else if( complexContent)
    617 		 *		if( restriction)
    618 		 *			handle_complex_content_restriction
    619 		 *		else if( extension)
    620 		 *			handle_complex_content_extension
    621 		 *		break; // it has to be the only child
    622 		 * else if( group)
    623 		 *		if( group has ref)
    624 		 *			store the group name
    625 		 *		else
    626 		 *			handleGroup
    627 		 * else if( sequence )
    628 		 *		handleSequence
    629 		 * else if( all )
    630 		 *		handleAll
    631 		 * else if(choice)
    632 		 *		handleChoice
    633 		 * else if(attribute)
    634 		 *		handleAttribute
    635 		 * else if(attributeGroup)
    636 		 *		handleAttributeGroup
    637 		 *  else if(anyAttribute)
    638 		 *		handleAnyAttribute
    639 		 */
    640
    641 		XmlSchemaComplexType ct = new XmlSchemaComplexType(schema);
    642
    643 		if (complexEl.hasAttribute("name")) {
    644
    645 			//String namespace = (schema.targetNamespace==null)?
    646 			//                  "":schema.targetNamespace;
    647
    648 			ct.name = complexEl.getAttribute("name");
    649 		}
    650 		for (Element el = XDOMUtil.getFirstChildElementNS(complexEl,
    651 				XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
    652 				.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
    653
    654 			//String elPrefix = el.getPrefix() == null ? "" :
    655 			//el.getPrefix();
    656 			//if(elPrefix.equals(schema.schema_ns_prefix)) {
    657 			if (el.getLocalName().equals("sequence")) {
    658 				ct.particle = handleSequence(schema, el, schemaEl);
    659 			} else if (el.getLocalName().equals("choice")) {
    660 				ct.particle = handleChoice(schema, el, schemaEl);
    661 			} else if (el.getLocalName().equals("all")) {
    662 				ct.particle = handleAll(schema, el, schemaEl);
    663 			} else if (el.getLocalName().equals("attribute")) {
    664 				ct.attributes.add(handleAttribute(schema, el, schemaEl));
    665 			} else if (el.getLocalName().equals("attributeGroup")) {
    666 				ct.attributes.add(handleAttributeGroupRef(el));
    667 			} else if (el.getLocalName().equals("group")) {
    668 				XmlSchemaGroupRef group = handleGroupRef(schema, el, schemaEl);
    669 				ct.particle = (group.particle == null) ? (XmlSchemaParticle) group
    670 						: group.particle;
    671 			} else if (el.getLocalName().equals("simpleContent")) {
    672 				ct.contentModel = handleSimpleContent(schema, el, schemaEl);
    673 			} else if (el.getLocalName().equals("complexContent")) {
    674 				ct.contentModel = handleComplexContent(schema, el, schemaEl);
    675 			} else if (el.getLocalName().equals("annotation")) {
    676 				ct.setAnnotation(handleAnnotation(el));
    677 			} else if (el.getLocalName().equals("anyAttribute")) {
    678 				ct.setAnyAttribute(handleAnyAttribute(schema, el, schemaEl));
    679 			}
    680 			//}
    681 		}
    682 		if (complexEl.hasAttribute("block")) {
    683 			String blockStr = complexEl.getAttribute("block");
    684 			if (blockStr.equalsIgnoreCase("all")
    685 					| blockStr.equalsIgnoreCase("#all")) {
    686
    687 				ct.setBlock(new XmlSchemaDerivationMethod(
    688 						Constants.BlockConstants.ALL));
    689 			} else
    690 				ct.setBlock(new XmlSchemaDerivationMethod(blockStr));
    691 			//ct.setBlock(new XmlSchemaDerivationMethod(block));
    692 		}
    693 		if (complexEl.hasAttribute("final")) {
    694 			String finalstr = complexEl.getAttribute("final");
    695 			if (finalstr.equalsIgnoreCase("all")
    696 					| finalstr.equalsIgnoreCase("#all")) {
    697
    698 				ct.setFinal(new XmlSchemaDerivationMethod(
    699 						Constants.BlockConstants.ALL));
    700 			} else
    701 				ct.setFinal(new XmlSchemaDerivationMethod(finalstr));
    702 		}
    703 		if (complexEl.hasAttribute("abstract")) {
    704 			String abs = complexEl.getAttribute("abstract");
    705 			if (abs.equalsIgnoreCase("true"))
    706 				ct.setAbstract(true);
    707 			else
    708 				ct.setAbstract(false);
    709 		}
    710 		if (complexEl.hasAttribute("mixed")) {
    711 			String mixed = complexEl.getAttribute("mixed");
    712 			if (mixed.equalsIgnoreCase("true"))
    713 				ct.setMixed(true);
    714 			else
    715 				ct.setMixed(false);
    716 		}
    717
    718 		//process extra attributes and elements
    719 		processExtensibilityComponents(ct, complexEl);
    720
    721 		return ct;
    722 	}
    723
    724 	private XmlSchemaSimpleContent handleSimpleContent(XmlSchema schema,
    725 			Element simpleEl, Element schemaEl) {
    726
    727 		XmlSchemaSimpleContent simpleContent = new XmlSchemaSimpleContent();
    728
    729 		for (Element el = XDOMUtil.getFirstChildElementNS(simpleEl,
    730 				XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
    731 				.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
    732
    733 			if (el.getLocalName().equals("restriction")) {
    734 				simpleContent.content = handleSimpleContentRestriction(schema,
    735 						el, schemaEl);
    736 			} else if (el.getLocalName().equals("extension")) {
    737 				simpleContent.content = handleSimpleContentExtension(schema,
    738 						el, schemaEl);
    739 			} else if (el.getLocalName().equals("annotation")) {
    740 				simpleContent.setAnnotation(handleAnnotation(el));
    741 			}
    742 		}
    743 		return simpleContent;
    744 	}
    745
    746 	private XmlSchemaComplexContent handleComplexContent(XmlSchema schema,
    747 			Element complexEl, Element schemaEl) {
    748
    749 		XmlSchemaComplexContent complexContent = new XmlSchemaComplexContent();
    750
    751 		for (Element el = XDOMUtil.getFirstChildElementNS(complexEl,
    752 				XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
    753 				.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
    754
    755 			if (el.getLocalName().equals("restriction")) {
    756 				complexContent.content = handleComplexContentRestriction(
    757 						schema, el, schemaEl);
    758 			} else if (el.getLocalName().equals("extension")) {
    759 				complexContent.content = handleComplexContentExtension(schema,
    760 						el, schemaEl);
    761 			} else if (el.getLocalName().equals("annotation")) {
    762 				complexContent.setAnnotation(handleAnnotation(el));
    763 			}
    764 		}
    765
    766 		if (complexEl.hasAttribute("mixed")) {
    767 			String mixed = complexEl.getAttribute("mixed");
    768 			if (mixed.equalsIgnoreCase("true"))
    769 				complexContent.setMixed(true);
    770 			else
    771 				complexContent.setMixed(false);
    772 		}
    773
    774 		return complexContent;
    775 	}
    776
    777 	private XmlSchemaSimpleContentRestriction handleSimpleContentRestriction(
    778 			XmlSchema schema, Element restrictionEl, Element schemaEl) {
    779
    780 		XmlSchemaSimpleContentRestriction restriction = new XmlSchemaSimpleContentRestriction();
    781
    782 		if (restrictionEl.hasAttribute("base")) {
    783 			String name = restrictionEl.getAttribute("base");
    784 			restriction.baseTypeName = getRefQName(name, restrictionEl);
    785 		}
    786
    787 		if (restrictionEl.hasAttribute("id"))
    788 			restriction.id = restrictionEl.getAttribute("id");
    789
    790 		// check back simpleContent tag children to add attributes and simpleType if any occur
    791 		for (Element el = XDOMUtil.getFirstChildElementNS(restrictionEl,
    792 				XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
    793 				.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
    794
    795 			if (el.getLocalName().equals("attribute")) {
    796 				XmlSchemaAttribute attr = handleAttribute(schema, el, schemaEl);
    797 				restriction.attributes.add(attr);
    798 			} else if (el.getLocalName().equals("attributeGroup")) {
    799 				XmlSchemaAttributeGroupRef attrGroup = handleAttributeGroupRef(el);
    800 				restriction.attributes.add(attrGroup);
    801 			} else if (el.getLocalName().equals("simpleType")) {
    802 				restriction.baseType = handleSimpleType(schema, el, schemaEl);
    803 			} else if (el.getLocalName().equals("anyAttribute")) {
    804 				restriction.anyAttribute = handleAnyAttribute(schema, el,
    805 						schemaEl);
    806 			} else if (el.getLocalName().equals("annotation")) {
    807 				restriction.setAnnotation(handleAnnotation(el));
    808 			} else {
    809 				XmlSchemaFacet facet = XmlSchemaFacet.construct(el);
    810 				if(XDOMUtil.anyElementsWithNameNS(el, XmlSchema.SCHEMA_NS, "annotation")) {
    811 					XmlSchemaAnnotation facetAnnotation = handleAnnotation(el);
    812 					facet.setAnnotation(facetAnnotation);
    813 				}
    814 				restriction.facets.add(facet);
    815 			}
    816 		}
    817 		return restriction;
    818 	}
    819
    820 	private XmlSchemaSimpleContentExtension handleSimpleContentExtension(
    821 			XmlSchema schema, Element extEl, Element schemaEl) {
    822
    823 		XmlSchemaSimpleContentExtension ext = new XmlSchemaSimpleContentExtension();
    824
    825 		if (extEl.hasAttribute("base")) {
    826 			String name = extEl.getAttribute("base");
    827 			ext.baseTypeName = getRefQName(name, extEl);
    828 		}
    829
    830 		for (Element el = XDOMUtil.getFirstChildElementNS(extEl,
    831 				XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
    832 				.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
    833
    834 			if (el.getLocalName().equals("attribute")) {
    835 				XmlSchemaAttribute attr = handleAttribute(schema, el, schemaEl);
    836 				ext.attributes.add(attr);
    837 			} else if (el.getLocalName().equals("attributeGroup")) {
    838 				XmlSchemaAttributeGroupRef attrGroup = handleAttributeGroupRef(el);
    839 				ext.attributes.add(attrGroup);
    840 			} else if (el.getLocalName().equals("anyAttribute")) {
    841 				ext.anyAttribute = handleAnyAttribute(schema, el, schemaEl);
    842 			} else if (el.getLocalName().equals("annotation")) {
    843 				XmlSchemaAnnotation ann = handleAnnotation(el);
    844 				ext.setAnnotation(ann);
    845 			}
    846 		}
    847 		return ext;
    848 	}
    849
    850 	private XmlSchemaComplexContentRestriction handleComplexContentRestriction(
    851 			XmlSchema schema, Element restrictionEl, Element schemaEl) {
    852
    853 		XmlSchemaComplexContentRestriction restriction = new XmlSchemaComplexContentRestriction();
    854
    855 		if (restrictionEl.hasAttribute("base")) {
    856 			String name = restrictionEl.getAttribute("base");
    857 			restriction.baseTypeName = getRefQName(name, restrictionEl);
    858 		}
    859 		for (Element el = XDOMUtil.getFirstChildElementNS(restrictionEl,
    860 				XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
    861 				.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
    862
    863 			if (el.getLocalName().equals("sequence")) {
    864 				restriction.particle = handleSequence(schema, el, schemaEl);
    865 			} else if (el.getLocalName().equals("choice")) {
    866 				restriction.particle = handleChoice(schema, el, schemaEl);
    867 			} else if (el.getLocalName().equals("all")) {
    868 				restriction.particle = handleAll(schema, el, schemaEl);
    869 			} else if (el.getLocalName().equals("attribute")) {
    870 				restriction.attributes
    871 						.add(handleAttribute(schema, el, schemaEl));
    872 			} else if (el.getLocalName().equals("attributeGroup")) {
    873 				restriction.attributes.add(handleAttributeGroupRef(el));
    874 			} else if (el.getLocalName().equals("group")) {
    875 				restriction.particle = handleGroupRef(schema, el, schemaEl);
    876 			} else if (el.getLocalName().equals("anyAttribute")) {
    877 				restriction.anyAttribute = handleAnyAttribute(schema, el,
    878 						schemaEl);
    879 			} else if (el.getLocalName().equals("annotation")) {
    880 				restriction.setAnnotation(handleAnnotation(el));
    881 			}
    882 		}
    883 		return restriction;
    884 	}
    885
    886 	private XmlSchemaComplexContentExtension handleComplexContentExtension(
    887 			XmlSchema schema, Element extEl, Element schemaEl) {
    888
    889 		XmlSchemaComplexContentExtension ext = new XmlSchemaComplexContentExtension();
    890
    891 		if (extEl.hasAttribute("base")) {
    892 			String name = extEl.getAttribute("base");
    893 			ext.baseTypeName = getRefQName(name, extEl);
    894 		}
    895
    896 		for (Element el = XDOMUtil.getFirstChildElementNS(extEl,
    897 				XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
    898 				.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
    899
    900 			if (el.getLocalName().equals("sequence")) {
    901 				ext.particle = handleSequence(schema, el, schemaEl);
    902 			} else if (el.getLocalName().equals("choice")) {
    903 				ext.particle = handleChoice(schema, el, schemaEl);
    904 			} else if (el.getLocalName().equals("all")) {
    905 				ext.particle = handleAll(schema, el, schemaEl);
    906 			} else if (el.getLocalName().equals("attribute")) {
    907 				ext.attributes.add(handleAttribute(schema, el, schemaEl));
    908 			} else if (el.getLocalName().equals("attributeGroup")) {
    909 				ext.attributes.add(handleAttributeGroupRef(el));
    910 			} else if (el.getLocalName().equals("group")) {
    911 				ext.particle = handleGroupRef(schema, el, schemaEl);
    912 			} else if (el.getLocalName().equals("anyAttribute")) {
    913 				ext.anyAttribute = handleAnyAttribute(schema, el, schemaEl);
    914 			} else if (el.getLocalName().equals("annotation")) {
    915 				ext.setAnnotation(handleAnnotation(el));
    916 			}
    917 		}
    918 		return ext;
    919 	}
    920
    921 	private XmlSchemaAttributeGroupRef handleAttributeGroupRef(
    922 			Element attrGroupEl) {
    923
    924 		XmlSchemaAttributeGroupRef attrGroup = new XmlSchemaAttributeGroupRef();
    925
    926 		if (attrGroupEl.hasAttribute("ref")) {
    927 			String ref = attrGroupEl.getAttribute("ref");
    928 			attrGroup.refName = getRefQName(ref, attrGroupEl);
    929 		}
    930
    931 		if (attrGroupEl.hasAttribute("id"))
    932 			attrGroup.id = attrGroupEl.getAttribute("id");
    933
    934 		Element annotationEl = XDOMUtil.getFirstChildElementNS(attrGroupEl,
    935 				XmlSchema.SCHEMA_NS, "annotation");
    936
    937 		if (annotationEl != null) {
    938 			XmlSchemaAnnotation annotation = handleAnnotation(annotationEl);
    939 			attrGroup.setAnnotation(annotation);
    940 		}
    941 		return attrGroup;
    942 	}
    943
    944 	private XmlSchemaSequence handleSequence(XmlSchema schema,
    945 			Element sequenceEl, Element schemaEl) {
    946
    947 		XmlSchemaSequence sequence = new XmlSchemaSequence();
    948
    949 		//handle min and max occurences
    950 		sequence.minOccurs = getMinOccurs(sequenceEl);
    951 		sequence.maxOccurs = getMaxOccurs(sequenceEl);
    952
    953 		for (Element el = XDOMUtil.getFirstChildElementNS(sequenceEl,
    954 				XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
    955 				.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
    956
    957 			if (el.getLocalName().equals("sequence")) {
    958 				XmlSchemaSequence seq = handleSequence(schema, el, schemaEl);
    959 				sequence.items.add(seq);
    960 			} else if (el.getLocalName().equals("element")) {
    961 				XmlSchemaElement element = handleElement(schema, el, schemaEl,
    962 						false);
    963 				sequence.items.add(element);
    964 			} else if (el.getLocalName().equals("group")) {
    965 				XmlSchemaGroupRef group = handleGroupRef(schema, el, schemaEl);
    966 				sequence.items.add(group);
    967 			} else if (el.getLocalName().equals("choice")) {
    968 				XmlSchemaChoice choice = handleChoice(schema, el, schemaEl);
    969 				sequence.items.add(choice);
    970 			} else if (el.getLocalName().equals("any")) {
    971 				XmlSchemaAny any = handleAny(schema, el, schemaEl);
    972 				sequence.items.add(any);
    973 			} else if (el.getLocalName().equals("annotation")) {
    974 				XmlSchemaAnnotation annotation = handleAnnotation(el);
    975 				sequence.setAnnotation(annotation);
    976 			}
    977 		}
    978 		return sequence;
    979 	}
    980
    981 	/** @noinspection UnusedParameters*/
    982 	private XmlSchemaAny handleAny(XmlSchema schema, Element anyEl,
    983 			Element schemaEl) {
    984
    985 		XmlSchemaAny any = new XmlSchemaAny();
    986
    987 		if (anyEl.hasAttribute("namespace"))
    988 			any.namespace = anyEl.getAttribute("namespace");
    989
    990 		if (anyEl.hasAttribute("processContents")) {
    991 			String processContent = getEnumString(anyEl, "processContents");
    992
    993 			any.processContent = new XmlSchemaContentProcessing(processContent);
    994 		}
    995
    996 		Element annotationEl = XDOMUtil.getFirstChildElementNS(anyEl,
    997 				XmlSchema.SCHEMA_NS, "annotation");
    998
    999 		if (annotationEl != null) {
    1000 			XmlSchemaAnnotation annotation = handleAnnotation(annotationEl);
    1001 			any.setAnnotation(annotation);
    1002 		}
    1003 		any.minOccurs = getMinOccurs(anyEl);
    1004 		any.maxOccurs = getMaxOccurs(anyEl);
    1005
    1006 		return any;
    1007 	}
    1008
    1009 	private XmlSchemaChoice handleChoice(XmlSchema schema, Element choiceEl,
    1010 			Element schemaEl) {
    1011 		XmlSchemaChoice choice = new XmlSchemaChoice();
    1012
    1013 		if (choiceEl.hasAttribute("id"))
    1014 			choice.id = choiceEl.getAttribute("id");
    1015
    1016 		choice.minOccurs = getMinOccurs(choiceEl);
    1017 		choice.maxOccurs = getMaxOccurs(choiceEl);
    1018
    1019 		for (Element el = XDOMUtil.getFirstChildElementNS(choiceEl,
    1020 				XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
    1021 				.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
    1022
    1023 			if (el.getLocalName().equals("sequence")) {
    1024 				XmlSchemaSequence seq = handleSequence(schema, el, schemaEl);
    1025 				choice.items.add(seq);
    1026 			} else if (el.getLocalName().equals("element")) {
    1027 				XmlSchemaElement element = handleElement(schema, el, schemaEl,
    1028 						false);
    1029 				choice.items.add(element);
    1030 			} else if (el.getLocalName().equals("group")) {
    1031 				XmlSchemaGroupRef group = handleGroupRef(schema, el, schemaEl);
    1032 				choice.items.add(group);
    1033 			} else if (el.getLocalName().equals("choice")) {
    1034 				XmlSchemaChoice choiceItem = handleChoice(schema, el, schemaEl);
    1035 				choice.items.add(choiceItem);
    1036 			} else if (el.getLocalName().equals("any")) {
    1037 				XmlSchemaAny any = handleAny(schema, el, schemaEl);
    1038 				choice.items.add(any);
    1039 			} else if (el.getLocalName().equals("annotation")) {
    1040 				XmlSchemaAnnotation annotation = handleAnnotation(el);
    1041 				choice.setAnnotation(annotation);
    1042 			}
    1043 		}
    1044 		return choice;
    1045 	}
    1046
    1047 	private XmlSchemaAll handleAll(XmlSchema schema, Element allEl,
    1048 			Element schemaEl) {
    1049
    1050 		XmlSchemaAll all = new XmlSchemaAll();
    1051
    1052 		//handle min and max occurences
    1053 		all.minOccurs = getMinOccurs(allEl);
    1054 		all.maxOccurs = getMaxOccurs(allEl);
    1055
    1056 		for (Element el = XDOMUtil.getFirstChildElementNS(allEl,
    1057 				XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
    1058 				.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
    1059
    1060 			if (el.getLocalName().equals("element")) {
    1061 				XmlSchemaElement element = handleElement(schema, el, schemaEl,
    1062 						false);
    1063 				all.items.add(element);
    1064 			} else if (el.getLocalName().equals("annotation")) {
    1065 				XmlSchemaAnnotation annotation = handleAnnotation(el);
    1066 				all.setAnnotation(annotation);
    1067 			}
    1068 		}
    1069 		return all;
    1070 	}
    1071
    1072 	private XmlSchemaGroup handleGroup(XmlSchema schema, Element groupEl,
    1073 			Element schemaEl) {
    1074
    1075 		XmlSchemaGroup group = new XmlSchemaGroup();
    1076 		group.name = new QName(schema.getTargetNamespace(), groupEl
    1077 				.getAttribute("name"));
    1078
    1079 		for (Element el = XDOMUtil.getFirstChildElementNS(groupEl,
    1080 				XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
    1081 				.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
    1082
    1083 			if (el.getLocalName().equals("all")) {
    1084 				group.particle = handleAll(schema, el, schemaEl);
    1085 			} else if (el.getLocalName().equals("sequence")) {
    1086 				group.particle = handleSequence(schema, el, schemaEl);
    1087 			} else if (el.getLocalName().equals("choice")) {
    1088 				group.particle = handleChoice(schema, el, schemaEl);
    1089 			} else if (el.getLocalName().equals("annotation")) {
    1090 				XmlSchemaAnnotation groupAnnotation = handleAnnotation(el);
    1091 				group.setAnnotation(groupAnnotation);
    1092 			}
    1093 		}
    1094 		return group;
    1095 	}
    1096
    1097 	private XmlSchemaAttributeGroup handleAttributeGroup(XmlSchema schema,
    1098 			Element groupEl, Element schemaEl) {
    1099 		XmlSchemaAttributeGroup attrGroup = new XmlSchemaAttributeGroup();
    1100
    1101 		if (groupEl.hasAttribute("name"))
    1102 			attrGroup.name = new QName(schema.getTargetNamespace(), groupEl
    1103 					.getAttribute("name"));
    1104 		if (groupEl.hasAttribute("id"))
    1105 			attrGroup.id = groupEl.getAttribute("id");
    1106
    1107 		for (Element el = XDOMUtil.getFirstChildElementNS(groupEl,
    1108 				XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
    1109 				.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
    1110
    1111 			if (el.getLocalName().equals("attribute")) {
    1112 				XmlSchemaAttribute attr = handleAttribute(schema, el, schemaEl);
    1113 				attrGroup.attributes.add(attr);
    1114 			} else if (el.getLocalName().equals("attributeGroup")) {
    1115 				XmlSchemaAttributeGroupRef attrGroupRef = handleAttributeGroupRef(el);
    1116 				attrGroup.attributes.add(attrGroupRef);
    1117 			} else if (el.getLocalName().equals("anyAttribute")) {
    1118 				attrGroup.anyAttribute = handleAnyAttribute(schema, el,
    1119 						schemaEl);
    1120 			} else if (el.getLocalName().equals("annotation")) {
    1121 				XmlSchemaAnnotation ann = handleAnnotation(el);
    1122 				attrGroup.setAnnotation(ann);
    1123 			}
    1124 		}
    1125 		return attrGroup;
    1126 	}
    1127
    1128 	/** @noinspection UnusedParameters*/
    1129 	private XmlSchemaAnyAttribute handleAnyAttribute(XmlSchema schema,
    1130 			Element anyAttrEl, Element schemaEl) {
    1131
    1132 		XmlSchemaAnyAttribute anyAttr = new XmlSchemaAnyAttribute();
    1133
    1134 		if (anyAttrEl.hasAttribute("namespace"))
    1135 			anyAttr.namespace = anyAttrEl.getAttribute("namespace");
    1136
    1137 		if (anyAttrEl.hasAttribute("processContents")) {
    1138
    1139 			String contentProcessing = getEnumString(anyAttrEl,
    1140 					"processContents");
    1141
    1142 			anyAttr.processContent = new XmlSchemaContentProcessing(
    1143 					contentProcessing);
    1144 		}
    1145 		if (anyAttrEl.hasAttribute("id"))
    1146 			anyAttr.id = anyAttrEl.getAttribute("id");
    1147
    1148 		Element annotationEl = XDOMUtil.getFirstChildElementNS(anyAttrEl,
    1149 				XmlSchema.SCHEMA_NS, "annotation");
    1150
    1151 		if (annotationEl != null) {
    1152 			XmlSchemaAnnotation annotation = handleAnnotation(annotationEl);
    1153
    1154 			anyAttr.setAnnotation(annotation);
    1155 		}
    1156 		return anyAttr;
    1157 	}
    1158
    1159 	private XmlSchemaGroupRef handleGroupRef(XmlSchema schema, Element groupEl,
    1160 			Element schemaEl) {
    1161
    1162 		XmlSchemaGroupRef group = new XmlSchemaGroupRef();
    1163
    1164 		group.maxOccurs = getMaxOccurs(groupEl);
    1165 		group.minOccurs = getMinOccurs(groupEl);
    1166
    1167 		Element annotationEl = XDOMUtil.getFirstChildElementNS(groupEl,
    1168 				XmlSchema.SCHEMA_NS, "annotation");
    1169
    1170 		if (annotationEl != null) {
    1171 			XmlSchemaAnnotation annotation = handleAnnotation(annotationEl);
    1172
    1173 			group.setAnnotation(annotation);
    1174 		}
    1175
    1176 		if (groupEl.hasAttribute("ref")) {
    1177 			String ref = groupEl.getAttribute("ref");
    1178 			group.refName = getRefQName(ref, groupEl);
    1179 			return group;
    1180 		}
    1181 		for (Element el = XDOMUtil.getFirstChildElementNS(groupEl,
    1182 				XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
    1183 				.getNextSiblingElement(el)) {
    1184
    1185 			if (el.getLocalName().equals("sequence")) {
    1186 				group.particle = handleSequence(schema, el, schemaEl);
    1187 			} else if (el.getLocalName().equals("all")) {
    1188 				group.particle = handleAll(schema, el, schemaEl);
    1189 			} else if (el.getLocalName().equals("choice")) {
    1190 				group.particle = handleChoice(schema, el, schemaEl);
    1191 			}
    1192 		}
    1193 		return group;
    1194 	}
    1195
    1196 	private QName newLocalQName(String pLocalName) {
    1197 		String uri = schema.logicalTargetNamespace;
    1198 		if (uri == null) {
    1199 			uri = Constants.NULL_NS_URI;
    1200 		}
    1201 		return new QName(uri, pLocalName);
    1202 	}
    1203
    1204 	/**
    1205 	 * Process non-toplevel attributes
    1206 	 * @param schema
    1207 	 * @param attrEl
    1208 	 * @param schemaEl
    1209 	 * @return
    1210 	 */
    1211 	private XmlSchemaAttribute handleAttribute(XmlSchema schema,
    1212 			Element attrEl, Element schemaEl) {
    1213 		return handleAttribute(schema, attrEl, schemaEl, false);
    1214 	}
    1215
    1216 	/**
    1217 	 * Process attributes
    1218 	 * @param schema
    1219 	 * @param attrEl
    1220 	 * @param schemaEl
    1221 	 * @param topLevel
    1222 	 * @return
    1223 	 */
    1224 	private XmlSchemaAttribute handleAttribute(XmlSchema schema,
    1225 			Element attrEl, Element schemaEl, boolean topLevel) {
    1226 		//todo: need to implement different rule of attribute such as
    1227 		//restriction between ref and name.  This can be implemented
    1228 		//in the compile function
    1229 		XmlSchemaAttribute attr = new XmlSchemaAttribute();
    1230
    1231 		if (attrEl.hasAttribute("name")) {
    1232 			String name = attrEl.getAttribute("name");
    1233 			//String namespace = (schema.targetNamespace==null)?
    1234 			//                  "" :schema.targetNamespace;
    1235
    1236 			attr.name = name;
    1237 		}
    1238
    1239 		boolean isQualified = schema.getAttributeFormDefault().getValue()
    1240 				.equals(XmlSchemaForm.QUALIFIED);
    1241 		if (attr.name != null) {
    1242 			final String name = attr.name;
    1243 			if (topLevel) {
    1244 				attr.qualifiedName = newLocalQName(name);
    1245 			} else {
    1246 				attr.qualifiedName = (isQualified) ? newLocalQName(name)
    1247 						: new QName(name);
    1248 			}
    1249 		}
    1250
    1251 		if (attrEl.hasAttribute("type")) {
    1252 			String name = attrEl.getAttribute("type");
    1253 			attr.schemaTypeName = getRefQName(name, attrEl);
    1254 		}
    1255
    1256 		if (attrEl.hasAttribute("default"))
    1257 			attr.defaultValue = attrEl.getAttribute("default");
    1258
    1259 		if (attrEl.hasAttribute("fixed"))
    1260 			attr.fixedValue = attrEl.getAttribute("fixed");
    1261
    1262 		if (attrEl.hasAttribute("form")) {
    1263 			String formValue = getEnumString(attrEl, "form");
    1264 			attr.form = new XmlSchemaForm(formValue);
    1265 		}
    1266 		if (attrEl.hasAttribute("id"))
    1267 			attr.id = attrEl.getAttribute("id");
    1268
    1269 		if (attrEl.hasAttribute("use")) {
    1270 			String useType = getEnumString(attrEl, "use");
    1271 			attr.use = new XmlSchemaUse(useType);
    1272 		}
    1273 		if (attrEl.hasAttribute("ref")) {
    1274 			String name = attrEl.getAttribute("ref");
    1275 			attr.refName = getRefQName(name, attrEl);
    1276 			attr.name = name;
    1277 		}
    1278
    1279 		Element simpleTypeEl = XDOMUtil.getFirstChildElementNS(attrEl,
    1280 				XmlSchema.SCHEMA_NS, "simpleType");
    1281
    1282 		if (simpleTypeEl != null) {
    1283 			attr.schemaType = handleSimpleType(schema, simpleTypeEl, schemaEl);
    1284 		}
    1285
    1286 		Element annotationEl = XDOMUtil.getFirstChildElementNS(attrEl,
    1287 				XmlSchema.SCHEMA_NS, "annotation");
    1288
    1289 		if (annotationEl != null) {
    1290 			XmlSchemaAnnotation annotation = handleAnnotation(annotationEl);
    1291
    1292 			attr.setAnnotation(annotation);
    1293 		}
    1294
    1295 		NamedNodeMap attrNodes = attrEl.getAttributes();
    1296 		Vector attrs = new Vector();
    1297 		NodeNamespaceContext ctx = null;
    1298 		for (int i = 0; i < attrNodes.getLength(); i++) {
    1299 			Attr att = (Attr) attrNodes.item(i);
    1300 			String attName = att.getName();
    1301 			if (!attName.equals("name") && !attName.equals("type")
    1302 					&& !attName.equals("default") && !attName.equals("fixed")
    1303 					&& !attName.equals("form") && !attName.equals("id")
    1304 					&& !attName.equals("use") && !attName.equals("ref")) {
    1305
    1306 				attrs.add(att);
    1307 				String value = att.getValue();
    1308
    1309 				if (value.indexOf(":") > -1) {
    1310 					// there is a possiblily of some namespace mapping
    1311 					String prefix = value.substring(0, value.indexOf(":"));
    1312 					if (ctx == null) {
    1313 						ctx = NodeNamespaceContext.getNamespaceContext(attrEl);
    1314 					}
    1315 					String namespace = ctx.getNamespaceURI(prefix);
    1316 					if (!Constants.NULL_NS_URI.equals(namespace)) {
    1317 						Attr nsAttr = attrEl.getOwnerDocument()
    1318 								.createAttribute("xmlns:" + prefix);
    1319 						nsAttr.setValue(namespace);
    1320 						attrs.add(nsAttr);
    1321 					}
    1322 				}
    1323 			}
    1324 		}
    1325
    1326 		if (attrs.size() > 0)
    1327 			attr.setUnhandledAttributes((Attr[]) attrs.toArray(new Attr[0]));
    1328
    1329 		//process extra attributes and elements
    1330 		processExtensibilityComponents(attr, attrEl);
    1331 		return attr;
    1332 	}
    1333
    1334 	/*
    1335 	 * handle_simple_content_restriction
    1336 	 *
    1337 	 * if( restriction has base attribute )
    1338 	 *		set the baseType
    1339 	 * else if( restriciton has an inline simpleType )
    1340 	 *		handleSimpleType
    1341 	 * add facets if any to the restriction
    1342 	 */
    1343
    1344 	/*
    1345 	 * handle_simple_content_extension
    1346 	 *
    1347 	 * extension should have a base name and cannot have any inline defn
    1348 	 * for( each childNode  )
    1349 	 *		if( attribute)
    1350 	 *			handleAttribute
    1351 	 *		else if( attributeGroup)
    1352 	 *			handleAttributeGroup
    1353 	 *		else if( anyAttribute)
    1354 	 *			handleAnyAttribute
    1355 	 */
    1356
    1357 	/*
    1358 	 * ********
    1359 	 * handle_complex_content_restriction
    1360 	 */
    1361 	/**
    1362 	 * handle elements
    1363 	 * @param schema
    1364 	 * @param el
    1365 	 * @param schemaEl
    1366 	 * @param isGlobal
    1367 	 */
    1368 	XmlSchemaElement handleElement(XmlSchema schema, Element el,
    1369 			Element schemaEl, boolean isGlobal) {
    1370
    1371 		XmlSchemaElement element = new XmlSchemaElement();
    1372
    1373 		if (el.getAttributeNode("name") != null)
    1374 			element.name = el.getAttribute("name");
    1375
    1376 		//                String namespace = (schema.targetNamespace==null)?
    1377 		//                                      "" : schema.targetNamespace;
    1378
    1379 		boolean isQualified = schema.getElementFormDefault().getValue().equals(
    1380 				XmlSchemaForm.QUALIFIED);
    1381 		if (el.hasAttribute("form")) {
    1382 			String formDef = el.getAttribute("form");
    1383 			element.form = new XmlSchemaForm(formDef);
    1384 			isQualified = formDef.equals(XmlSchemaForm.QUALIFIED);
    1385 		}
    1386
    1387 		if (element.name != null) {
    1388 			final String name = element.name;
    1389 			element.qualifiedName = (isQualified || isGlobal) ? newLocalQName(name)
    1390 					: new QName(Constants.NULL_NS_URI, name);
    1391 		}
    1392
    1393 		Element annotationEl = XDOMUtil.getFirstChildElementNS(el,
    1394 				XmlSchema.SCHEMA_NS, "annotation");
    1395
    1396 		if (annotationEl != null) {
    1397 			XmlSchemaAnnotation annotation = handleAnnotation(annotationEl);
    1398
    1399 			element.setAnnotation(annotation);
    1400 		}
    1401 		if (el.getAttributeNode("type") != null) {
    1402 			String typeName = el.getAttribute("type");
    1403 			QName typeQName = element.schemaTypeName = getRefQName(typeName, el);
    1404
    1405 			XmlSchemaType type = collection.getTypeByQName(typeQName);
    1406 			if (type == null) {
    1407 				// Could be a forward reference...
    1408 				collection.addUnresolvedType(typeQName, element);
    1409 			}
    1410 			element.schemaType = type;
    1411 		} else if (el.getAttributeNode("ref") != null) {
    1412 			String refName = el.getAttribute("ref");
    1413 			QName refQName = getRefQName(refName, el);
    1414 			element.setRefName(refQName);
    1415 			element.name = refQName.getLocalPart();
    1416 		}
    1417
    1418 		Element simpleTypeEl, complexTypeEl, keyEl, keyrefEl, uniqueEl;
    1419
    1420 		if ((simpleTypeEl = XDOMUtil.getFirstChildElementNS(el,
    1421 				XmlSchema.SCHEMA_NS, "simpleType")) != null) {
    1422
    1423 			XmlSchemaSimpleType simpleType = handleSimpleType(schema,
    1424 					simpleTypeEl, schemaEl);
    1425 			element.schemaType = simpleType;
    1426 			element.schemaTypeName = simpleType.getQName();
    1427 		} else if ((complexTypeEl = XDOMUtil.getFirstChildElementNS(el,
    1428 				XmlSchema.SCHEMA_NS, "complexType")) != null) {
    1429
    1430 			element.schemaType = handleComplexType(schema, complexTypeEl,
    1431 					schemaEl);
    1432 		}
    1433
    1434 		if ((keyEl = XDOMUtil.getFirstChildElementNS(el, XmlSchema.SCHEMA_NS,
    1435 				"key")) != null) {
    1436 			while (keyEl != null) {
    1437 				element.constraints.add(handleConstraint(keyEl, "Key"));
    1438 				keyEl = XDOMUtil.getNextSiblingElement(keyEl, "key");
    1439 			}
    1440 		}
    1441
    1442 		if ((keyrefEl = XDOMUtil.getFirstChildElementNS(el,
    1443 				XmlSchema.SCHEMA_NS, "keyref")) != null) {
    1444 			while (keyrefEl != null) {
    1445 				XmlSchemaKeyref keyRef = (XmlSchemaKeyref) handleConstraint(
    1446 						keyrefEl, "Keyref");
    1447 				if (keyrefEl.hasAttribute("refer")) {
    1448 					String name = keyrefEl.getAttribute("refer");
    1449 					keyRef.refer = getRefQName(name, el);
    1450 				}
    1451 				element.constraints.add(keyRef);
    1452 				keyrefEl = XDOMUtil.getNextSiblingElement(keyrefEl, "keyref");
    1453 			}
    1454 		}
    1455
    1456 		if ((uniqueEl = XDOMUtil.getFirstChildElementNS(el,
    1457 				XmlSchema.SCHEMA_NS, "unique")) != null) {
    1458 			while (uniqueEl != null) {
    1459 				element.constraints.add(handleConstraint(uniqueEl, "Unique"));
    1460 				uniqueEl = XDOMUtil.getNextSiblingElement(uniqueEl, "unique");
    1461 			}
    1462 		}
    1463
    1464 		if (el.hasAttribute("abstract")) {
    1465 			element.isAbstract = Boolean.valueOf(el.getAttribute("abstract"))
    1466 					.booleanValue();
    1467 		}
    1468
    1469 		if (el.hasAttribute("block"))
    1470 			element.block = getDerivation(el, "block");
    1471
    1472 		if (el.hasAttribute("default"))
    1473 			element.defaultValue = el.getAttribute("default");
    1474
    1475 		if (el.hasAttribute("final"))
    1476 			element.finalDerivation = getDerivation(el, "final");
    1477
    1478 		if (el.hasAttribute("fixed"))
    1479 			element.fixedValue = el.getAttribute("fixed");
    1480
    1481 		if (el.hasAttribute("id"))
    1482 			element.id = el.getAttribute("id");
    1483
    1484 		if (el.hasAttribute("nillable"))
    1485 			element.isNillable = Boolean.valueOf(el.getAttribute("nillable"))
    1486 					.booleanValue();
    1487
    1488 		if (el.hasAttribute("substitutionGroup")) {
    1489 			String substitutionGroup = el.getAttribute("substitutionGroup");
    1490 			element.setSubstitutionGroup(getRefQName(substitutionGroup, el));
    1491 		}
    1492
    1493 		element.minOccurs = getMinOccurs(el);
    1494 		element.maxOccurs = getMaxOccurs(el);
    1495
    1496 		//process extra attributes and elements
    1497 		processExtensibilityComponents(element, el);
    1498
    1499 		return element;
    1500 	}
    1501
    1502 	private XmlSchemaIdentityConstraint handleConstraint(Element constraintEl,
    1503 			String type) {
    1504
    1505 		try {
    1506 			XmlSchemaIdentityConstraint constraint = (XmlSchemaIdentityConstraint) Class
    1507 					.forName("org.apache.ws.commons.schema.XmlSchema" + type)
    1508 					.newInstance();
    1509
    1510 			if (constraintEl.hasAttribute("name"))
    1511 				constraint.name = constraintEl.getAttribute("name");
    1512
    1513 			if (constraintEl.hasAttribute("refer")) {
    1514 				String name = constraintEl.getAttribute("refer");
    1515 				((XmlSchemaKeyref) constraint).refer = getRefQName(name,
    1516 						constraintEl);
    1517 			}
    1518 			for (Element el = XDOMUtil.getFirstChildElementNS(constraintEl,
    1519 					XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
    1520 					.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
    1521
    1522 				//    String elPrefix = el.getPrefix() == null ? ""
    1523 				//     : el.getPrefix();
    1524 				//if(elPrefix.equals(schema.schema_ns_prefix)) {
    1525 				if (el.getLocalName().equals("selector")) {
    1526 					XmlSchemaXPath selectorXPath = new XmlSchemaXPath();
    1527 					selectorXPath.xpath = el.getAttribute("xpath");
    1528
    1529 					Element annotationEl = XDOMUtil.getFirstChildElementNS(el,
    1530 							XmlSchema.SCHEMA_NS, "annotation");
    1531 					if (annotationEl != null) {
    1532 						XmlSchemaAnnotation annotation = handleAnnotation(annotationEl);
    1533
    1534 						selectorXPath.setAnnotation(annotation);
    1535 					}
    1536 					constraint.selector = selectorXPath;
    1537 				} else if (el.getLocalName().equals("field")) {
    1538 					XmlSchemaXPath fieldXPath = new XmlSchemaXPath();
    1539 					fieldXPath.xpath = el.getAttribute("xpath");
    1540 					constraint.fields.add(fieldXPath);
    1541
    1542 					Element annotationEl = XDOMUtil.getFirstChildElementNS(el,
    1543 							XmlSchema.SCHEMA_NS, "annotation");
    1544
    1545 					if (annotationEl != null) {
    1546 						XmlSchemaAnnotation annotation = handleAnnotation(annotationEl);
    1547
    1548 						fieldXPath.setAnnotation(annotation);
    1549 					}
    1550 				} else if (el.getLocalName().equals("annotation")) {
    1551 					XmlSchemaAnnotation constraintAnnotation = handleAnnotation(el);
    1552 					constraint.setAnnotation(constraintAnnotation);
    1553 				}
    1554 			}
    1555 			return constraint;
    1556 		} catch (ClassNotFoundException e) {
    1557 			throw new XmlSchemaException(e.getMessage());
    1558 		} catch (InstantiationException e) {
    1559 			throw new XmlSchemaException(e.getMessage());
    1560 		} catch (IllegalAccessException e) {
    1561 			throw new XmlSchemaException(e.getMessage());
    1562 		}
    1563 	}
    1564
    1565 	/**
    1566 	 * Handle the import
    1567 	 * @param schema
    1568 	 * @param importEl
    1569 	 * @param schemaEl
    1570 	 * @return XmlSchemaObject
    1571 	 */
    1572 	XmlSchemaImport handleImport(XmlSchema schema, Element importEl,
    1573 			Element schemaEl) {
    1574
    1575 		XmlSchemaImport schemaImport = new XmlSchemaImport();
    1576
    1577 		Element annotationEl = XDOMUtil.getFirstChildElementNS(importEl,
    1578 				XmlSchema.SCHEMA_NS, "annotation");
    1579
    1580 		if (annotationEl != null) {
    1581 			XmlSchemaAnnotation importAnnotation = handleAnnotation(annotationEl);
    1582 			schemaImport.setAnnotation(importAnnotation);
    1583 		}
    1584
    1585 		final String uri = schemaImport.namespace = importEl
    1586 				.getAttribute("namespace");
    1587 		schemaImport.schemaLocation = importEl.getAttribute("schemaLocation");
    1588
    1589 		TargetNamespaceValidator validator = new TargetNamespaceValidator() {
    1590 			private boolean isEmpty(String pValue) {
    1591 				return pValue == null || Constants.NULL_NS_URI.equals(pValue);
    1592 			}
    1593
    1594 			public void validate(XmlSchema pSchema) {
    1595 				final boolean valid;
    1596 				if (isEmpty(uri)) {
    1597 					valid = isEmpty(pSchema.syntacticalTargetNamespace);
    1598 				} else {
    1599 					valid = pSchema.syntacticalTargetNamespace.equals(uri);
    1600 				}
    1601 				if (!valid) {
    1602 					throw new XmlSchemaException(
    1603 							"An imported schema was announced to have the namespace "
    1604 									+ uri + ", but has the namespace "
    1605 									+ pSchema.syntacticalTargetNamespace);
    1606 				}
    1607 			}
    1608 		};
    1609 		if ((schemaImport.schemaLocation != null)
    1610 				&& (!schemaImport.schemaLocation.equals(""))) {
    1611 			if (schema.getSourceURI() != null) {
    1612 				schemaImport.schema = resolveXmlSchema(uri,
    1613 						schemaImport.schemaLocation, schema.getSourceURI(),
    1614 						validator);
    1615 			} else {
    1616 				schemaImport.schema = resolveXmlSchema(schemaImport.namespace,
    1617 						schemaImport.schemaLocation, validator);
    1618 			}
    1619 		}
    1620 		return schemaImport;
    1621 	}
    1622
    1623 	/**
    1624 	 * Handles the include
    1625 	 * @param schema
    1626 	 * @param includeEl
    1627 	 * @param schemaEl
    1628 	 */
    1629 	XmlSchemaInclude handleInclude(final XmlSchema schema, Element includeEl,
    1630 			Element schemaEl) {
    1631
    1632 		XmlSchemaInclude include = new XmlSchemaInclude();
    1633
    1634 		Element annotationEl = XDOMUtil.getFirstChildElementNS(includeEl,
    1635 				XmlSchema.SCHEMA_NS, "annotation");
    1636
    1637 		if (annotationEl != null) {
    1638 			XmlSchemaAnnotation includeAnnotation = handleAnnotation(annotationEl);
    1639 			include.setAnnotation(includeAnnotation);
    1640 		}
    1641
    1642 		include.schemaLocation = includeEl.getAttribute("schemaLocation");
    1643
    1644 		//includes are not supposed to have a target namespace
    1645 		// we should be passing in a null in place of the target
    1646 		//namespace
    1647
    1648 		final TargetNamespaceValidator validator = newIncludeValidator(schema);
    1649 		if (schema.getSourceURI() != null) {
    1650 			include.schema = resolveXmlSchema(schema.logicalTargetNamespace,
    1651 					include.schemaLocation, schema.getSourceURI(), validator);
    1652 		} else {
    1653 			include.schema = resolveXmlSchema(schema.logicalTargetNamespace,
    1654 					include.schemaLocation, validator);
    1655 		}
    1656
    1657 		//process extra attributes and elements
    1658 		processExtensibilityComponents(include, includeEl);
    1659 		return include;
    1660 	}
    1661
    1662 	private TargetNamespaceValidator newIncludeValidator(final XmlSchema schema) {
    1663 		return new TargetNamespaceValidator() {
    1664 			private boolean isEmpty(String pValue) {
    1665 				return pValue == null || Constants.NULL_NS_URI.equals(pValue);
    1666 			}
    1667
    1668 			public void validate(XmlSchema pSchema) {
    1669 				if (isEmpty(pSchema.syntacticalTargetNamespace)) {
    1670 					pSchema.logicalTargetNamespace = schema.logicalTargetNamespace;
    1671 				} else {
    1672 					if (!pSchema.syntacticalTargetNamespace
    1673 							.equals(schema.logicalTargetNamespace)) {
    1674 						String msg = "An included schema was announced to have the default target namespace";
    1675 						if (!isEmpty(schema.logicalTargetNamespace)) {
    1676 							msg += " or the target namespace "
    1677 									+ schema.logicalTargetNamespace;
    1678 						}
    1679 						throw new XmlSchemaException(msg
    1680 								+ ", but has the target namespace "
    1681 								+ pSchema.logicalTargetNamespace);
    1682 					}
    1683 				}
    1684 			}
    1685 		};
    1686 	}
    1687
    1688 	/**
    1689 	 * Handles the annotation
    1690 	 * Traversing if encounter appinfo or documentation
    1691 	 * add it to annotation collection
    1692 	 *
    1693 	 */
    1694 	XmlSchemaAnnotation handleAnnotation(Element annotEl) {
    1695 		XmlSchemaObjectCollection content = new XmlSchemaObjectCollection();
    1696 		XmlSchemaAppInfo appInfoObj;
    1697 		XmlSchemaDocumentation docsObj;
    1698
    1699 		for (Element appinfo = XDOMUtil.getFirstChildElementNS(annotEl,
    1700 				XmlSchema.SCHEMA_NS, "appinfo"); appinfo != null; appinfo = XDOMUtil
    1701 				.getNextSiblingElementNS(appinfo, XmlSchema.SCHEMA_NS,
    1702 						"appinfo")) {
    1703
    1704 			appInfoObj = handleAppInfo(appinfo);
    1705 			if (appInfoObj != null) {
    1706 				content.add(appInfoObj);
    1707 			}
    1708 		}
    1709 		for (Element documentation = XDOMUtil.getFirstChildElementNS(annotEl,
    1710 				XmlSchema.SCHEMA_NS, "documentation"); documentation != null; documentation = XDOMUtil
    1711 				.getNextSiblingElementNS(documentation,
    1712
    1713 				XmlSchema.SCHEMA_NS, "documentation")) {
    1714
    1715 			docsObj = handleDocumentation(documentation);
    1716 			if (docsObj != null) {
    1717 				content.add(docsObj);
    1718 			}
    1719 		}
    1720
    1721 		XmlSchemaAnnotation annotation = new XmlSchemaAnnotation();
    1722 		annotation.items = content;
    1723
    1724 		//process extra attributes and elements
    1725 		processExtensibilityComponents(annotation, annotEl);
    1726 		return annotation;
    1727 	}
    1728
    1729 	/**
    1730 	 * create new XmlSchemaAppinfo and add value goten from element
    1731 	 * to this obj
    1732 	 * @param content
    1733 	 */
    1734 	XmlSchemaAppInfo handleAppInfo(Element content) {
    1735 		XmlSchemaAppInfo appInfo = new XmlSchemaAppInfo();
    1736 		NodeList markup = new DocumentFragmentNodeList(content);
    1737
    1738 		if (!content.hasAttribute("source")) {
    1739 			return null;
    1740 		}
    1741 		appInfo.setSource(getAttribute(content, "source"));
    1742 		appInfo.setMarkup(markup);
    1743 		return appInfo;
    1744 	}
    1745
    1746 	//iterate each documentation element, create new XmlSchemaAppinfo and add to collection
    1747 	XmlSchemaDocumentation handleDocumentation(Element content) {
    1748 		XmlSchemaDocumentation documentation = new XmlSchemaDocumentation();
    1749 		List markup = getChildren(content);
    1750
    1751 		if (!content.hasAttribute("source")
    1752 				&& !content.hasAttribute("xml:lang")
    1753 				&& markup == null)
    1754 			return null;
    1755
    1756 		documentation.setSource(getAttribute(content, "source"));
    1757 		documentation.setLanguage(getAttribute(content, "xml:lang"));
    1758 		documentation.setMarkup(new DocumentFragmentNodeList(content));
    1759
    1760 		return documentation;
    1761 	}
    1762
    1763 	private String getAttribute(Element content, String attrName) {
    1764 		if (content.hasAttribute(attrName))
    1765 			return content.getAttribute(attrName);
    1766 		return null;
    1767 	}
    1768
    1769 	private List getChildren(Element content) {
    1770 		List result = new ArrayList();
    1771 		for(Node n = content.getFirstChild(); n != null; n = n.getNextSibling()) {
    1772 			result.add(n);
    1773 		}
    1774 		if(result.size() == 0) {
    1775 			return null;
    1776 		} else {
    1777 			return result;
    1778 		}
    1779 	}
    1780
    1781 	long getMinOccurs(Element el) {
    1782 		try {
    1783 			if (el.getAttributeNode("minOccurs") != null) {
    1784 				String value = el.getAttribute("minOccurs");
    1785 				if (value.equals("unbounded"))
    1786 					return Long.MAX_VALUE;
    1787 				else
    1788 					return Long.parseLong(value);
    1789 			}
    1790 			return 1;
    1791 		} catch (java.lang.NumberFormatException e) {
    1792 			return 1;
    1793 		}
    1794 	}
    1795
    1796 	long getMaxOccurs(Element el) {
    1797 		try {
    1798 			if (el.getAttributeNode("maxOccurs") != null) {
    1799 				String value = el.getAttribute("maxOccurs");
    1800 				if (value.equals("unbounded"))
    1801 					return Long.MAX_VALUE;
    1802 				else
    1803 					return Long.parseLong(value);
    1804 			}
    1805 			return 1;
    1806 		} catch (java.lang.NumberFormatException e) {
    1807 			return 1;
    1808 		}
    1809 	}
    1810
    1811 	XmlSchemaForm getFormDefault(Element el, String attrName) {
    1812 		if (el.getAttributeNode(attrName) != null) {
    1813 			String value = el.getAttribute(attrName);
    1814 			return new XmlSchemaForm(value);
    1815 		} else
    1816 			return new XmlSchemaForm("unqualified");
    1817 	}
    1818
    1819 	//Check value entered by user and change according to .net spec,
    1820 	//according to w3c spec have to be "#all"
    1821 	//but in .net the valid enum value is "all".
    1822 	XmlSchemaDerivationMethod getDerivation(Element el, String attrName) {
    1823 		if (el.hasAttribute(attrName) && !el.getAttribute(attrName).equals("")) {
    1824 			//#all | List of (extension | restriction | substitution
    1825 			String derivationMethod = el.getAttribute(attrName).trim();
    1826 			if (derivationMethod.equals("#all"))
    1827 				return new XmlSchemaDerivationMethod(
    1828 						Constants.BlockConstants.ALL);
    1829 			else
    1830 				return new XmlSchemaDerivationMethod(derivationMethod);
    1831 		}
    1832 		return new XmlSchemaDerivationMethod(Constants.BlockConstants.NONE);
    1833 	}
    1834
    1835 	//Check value entered by user and change according to .net spec, user
    1836 	String getEnumString(Element el, String attrName) {
    1837 		if (el.hasAttribute(attrName)) {
    1838 			return el.getAttribute(attrName).trim();
    1839 		}
    1840 		return Constants.BlockConstants.NONE;
    1841 	}
    1842
    1843 	/**
    1844 	 * Resolve the schemas
    1845 	 * @param targetNamespace
    1846 	 * @param schemaLocation
    1847 	 */
    1848 	XmlSchema resolveXmlSchema(String targetNamespace, String schemaLocation,
    1849 			String baseUri, TargetNamespaceValidator validator) {
    1850
    1851         String schemaKey = null;
    1852         if (resolvedSchemas != null) {  // cache is initialized, use it
    1853             // Not being very smart about this at the moment.  One could, for example,
    1854             // see that the schemaLocation or baseUri is the same as another, but differs
    1855             // only by a trailing slash.  As it is now, we assume a single character difference
    1856             // means it's a schema that has yet to be resolved.
    1857             schemaKey = Thread.currentThread().getId() + targetNamespace + schemaLocation + baseUri;
    1858             SoftReference softref = (SoftReference)resolvedSchemas.get(schemaKey);
    1859             if (softref != null) {
    1860                 XmlSchema resolvedSchema = (XmlSchema)softref.get();
    1861                 if (resolvedSchema != null) {
    1862                     return resolvedSchema;
    1863                 }
    1864             }
    1865         }
    1866
    1867 		//use the entity resolver provided if the schema location is present null
    1868 		if (schemaLocation != null && !"".equals(schemaLocation)) {
    1869 			InputSource source = collection.getSchemaResolver().resolveEntity(
    1870 					targetNamespace, schemaLocation, baseUri);
    1871
    1872 			//the entity resolver was unable to resolve this!!
    1873 			if (source == null) {
    1874 				//try resolving it with the target namespace only with the
    1875 				//known namespace map
    1876 				XmlSchema schema = collection.getKnownSchema(targetNamespace);
    1877 				if (schema != null) {
    1878 					return schema;
    1879 				}else{
    1880 					return null;
    1881 				}
    1882 			}
    1883 			final String systemId = source.getSystemId() == null ? schemaLocation
    1884 					: source.getSystemId();
    1885 			// Push repaired system id back into source where read sees it.
    1886 			// It is perhaps a bad thing to patch the source, but this fixes
    1887 			// a problem.
    1888 			source.setSystemId(systemId);
    1889 			final SchemaKey key = new XmlSchemaCollection.SchemaKey(
    1890 					targetNamespace, systemId);
    1891 			XmlSchema schema = collection.getSchema(key);
    1892 			if (schema != null) {
    1893 				return schema;
    1894 			}
    1895 			if (collection.check(key)) {
    1896 				collection.push(key);
    1897 				try {
    1898                     XmlSchema readSchema = collection.read(source, null, validator);
    1899                     if (resolvedSchemas != null) {
    1900                         resolvedSchemas.put(schemaKey, new SoftReference(readSchema));
    1901                     }
    1902 					return readSchema;
    1903 				} catch (Exception e) {
    1904 					throw new RuntimeException(e);
    1905 				} finally {
    1906 					collection.pop();
    1907 				}
    1908 			}
    1909 		}else{
    1910 			XmlSchema schema = collection.getKnownSchema(targetNamespace);
    1911 			if (schema != null) {
    1912 				return schema;
    1913 			}
    1914 		}
    1915
    1916 		return null;
    1917 	}
    1918
    1919 	/**
    1920 	 * Resolve the schemas
    1921 	 * @param targetNamespace
    1922 	 * @param schemaLocation
    1923 	 */
    1924 	XmlSchema resolveXmlSchema(String targetNamespace, String schemaLocation,
    1925 			TargetNamespaceValidator validator) {
    1926
    1927 		return resolveXmlSchema(targetNamespace, schemaLocation,
    1928 				collection.baseUri, validator);
    1929
    1930 	}
    1931
    1932 	/**
    1933 	 * A generic method to process the extra attributes and the the extra
    1934 	 * elements present within the schema.
    1935 	 * What are considered extensions are  child elements with non schema namespace
    1936 	 * and child attributes with any namespace
    1937 	 * @param schemaObject
    1938 	 * @param parentElement
    1939 	 */
    1940 	private void processExtensibilityComponents(XmlSchemaObject schemaObject,
    1941 			Element parentElement) {
    1942
    1943 		if (extReg != null) {
    1944 			//process attributes
    1945 			NamedNodeMap attributes = parentElement.getAttributes();
    1946 			for (int i = 0; i < attributes.getLength(); i++) {
    1947 				Attr attribute = (Attr) attributes.item(i);
    1948
    1949 				String namespaceURI = attribute.getNamespaceURI();
    1950 				String name = attribute.getLocalName();
    1951
    1952 				if (namespaceURI != null
    1953 						&& !"".equals(namespaceURI)
    1954 						&& //ignore unqualified attributes
    1955 						!namespaceURI
    1956 								.startsWith(Constants.XMLNS_ATTRIBUTE_NS_URI) && //ignore namespaces
    1957 						!Constants.URI_2001_SCHEMA_XSD.equals(namespaceURI))
    1958 				//does not belong to the schema namespace by any chance!
    1959 				{
    1960 					QName qName = new QName(namespaceURI, name);
    1961 					extReg.deserializeExtension(schemaObject, qName, attribute);
    1962
    1963 				}
    1964 			}
    1965
    1966 			//process elements
    1967 			Node child = parentElement.getFirstChild();
    1968 			while (child != null) {
    1969 				if (child.getNodeType() == Node.ELEMENT_NODE) {
    1970 					Element extElement = (Element) child;
    1971 					String namespaceURI = extElement.getNamespaceURI();
    1972 					String name = extElement.getLocalName();
    1973
    1974 					if (namespaceURI != null
    1975 							&& !Constants.URI_2001_SCHEMA_XSD
    1976 									.equals(namespaceURI))
    1977 					//does not belong to the schema namespace
    1978 					{
    1979 						QName qName = new QName(namespaceURI, name);
    1980 						extReg.deserializeExtension(schemaObject, qName,
    1981 								extElement);
    1982 					}
    1983 				}
    1984 				child = child.getNextSibling();
    1985 			}
    1986 		}
    1987
    1988 	}
    1989
    1990 }