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 = uri.equals(pSchema.syntacticalTargetNamespace);
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 }