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 }