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