org.apache.ws.commons.schema.SchemaBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of XmlSchema Show documentation
Show all versions of XmlSchema Show documentation
Commons XMLSchema is a light weight schema object model that can be used to manipulate or
generate a schema. It has a clean, easy to use API and can easily be integrated into an existing project
since it has almost no dependencies on third party libraries.
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.ws.commons.schema;
import org.apache.ws.commons.schema.XmlSchemaCollection.SchemaKey;
import org.apache.ws.commons.schema.constants.Constants;
import org.apache.ws.commons.schema.extensions.ExtensionRegistry;
import org.apache.ws.commons.schema.utils.NodeNamespaceContext;
import org.apache.ws.commons.schema.utils.TargetNamespaceValidator;
import org.apache.ws.commons.schema.utils.XDOMUtil;
import org.apache.ws.commons.schema.utils.DOMUtil;
import org.w3c.dom.*;
import org.xml.sax.InputSource;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
import java.util.StringTokenizer;
import java.util.Vector;
public class SchemaBuilder {
Document doc;
XmlSchema schema;
XmlSchemaCollection collection;
private final TargetNamespaceValidator validator;
DocumentBuilderFactory docFac;
/**
* The extension registry to be used while building the
* schema model
*/
private ExtensionRegistry extReg = null;
public ExtensionRegistry getExtReg() {
return extReg;
}
public void setExtReg(ExtensionRegistry extReg) {
this.extReg = extReg;
}
/**
* Schema builder constructor
* @param collection
*/
SchemaBuilder(XmlSchemaCollection collection,
TargetNamespaceValidator validator) {
this.collection = collection;
this.validator = validator;
if (collection.getExtReg() != null) {
this.extReg = collection.getExtReg();
}
schema = new XmlSchema();
}
/**
* build method taking in a document and a validation handler
* @param doc
* @param uri
* @param veh
*/
XmlSchema build(Document doc, String uri, ValidationEventHandler veh) {
Element schemaEl = doc.getDocumentElement();
XmlSchema xmlSchema = handleXmlSchemaElement(schemaEl, uri);
xmlSchema.setInputEncoding(DOMUtil.getInputEncoding(doc));
return xmlSchema;
}
/**
* handles the schema element
* @param schemaEl
* @param uri
*/
XmlSchema handleXmlSchemaElement(Element schemaEl, String uri) {
// get all the attributes along with the namespace declns
schema.setNamespaceContext(new NodeNamespaceContext(schemaEl));
setNamespaceAttributes(schema, schemaEl);
XmlSchemaCollection.SchemaKey schemaKey = new XmlSchemaCollection.SchemaKey(
schema.logicalTargetNamespace, uri);
if (!collection.containsSchema(schemaKey)) {
collection.addSchema(schemaKey, schema);
schema.parent = collection; // establish parentage now.
} else {
throw new XmlSchemaException("Schema name conflict in collection. Namespace: " + schema.logicalTargetNamespace);
}
schema.setElementFormDefault(this.getFormDefault(schemaEl,
"elementFormDefault"));
schema.setAttributeFormDefault(this.getFormDefault(schemaEl,
"attributeFormDefault"));
schema.setBlockDefault(this.getDerivation(schemaEl, "blockDefault"));
schema.setFinalDefault(this.getDerivation(schemaEl, "finalDefault"));
/* set id attribute */
if (schemaEl.hasAttribute("id")) {
schema.id = schemaEl.getAttribute("id");
}
schema.setSourceURI(uri);
/***********
* for ( each childElement)
* if( simpleTypeElement)
* handleSimpleType
* else if( complexType)
* handleComplexType
* else if( element)
* handleElement
* else if( include)
* handleInclude
* else if( import)
* handleImport
* else if (group)
* handleGroup
* else if (attributeGroup)
* handleattributeGroup
* else if( attribute)
* handleattribute
* else if (redefine)
* handleRedefine
* else if(notation)
* handleNotation
* else if (annotation)
* handleAnnotation
*/
Element el = XDOMUtil.getFirstChildElementNS(schemaEl,
XmlSchema.SCHEMA_NS);
if (el == null
&& XDOMUtil.getFirstChildElementNS(schemaEl,
"http://www.w3.org/1999/XMLSchema") != null) {
throw new XmlSchemaException(
"Schema defined using \"http://www.w3.org/1999/XMLSchema\" is not supported. "
+ "Please update the schema to the \""
+ XmlSchema.SCHEMA_NS + "\" namespace");
}
for (; el != null; el = XDOMUtil.getNextSiblingElementNS(el,
XmlSchema.SCHEMA_NS)) {
// String elPrefix = el.getPrefix() == null ? "" : el.getPrefix();
//if(elPrefix.equals(schema.schema_ns_prefix)) {
if (el.getLocalName().equals("simpleType")) {
XmlSchemaType type = handleSimpleType(schema, el, schemaEl);
schema.addType(type);
schema.items.add(type);
collection.resolveType(type.getQName(), type);
} else if (el.getLocalName().equals("complexType")) {
XmlSchemaType type = handleComplexType(schema, el, schemaEl);
schema.addType(type);
schema.items.add(type);
collection.resolveType(type.getQName(), type);
} else if (el.getLocalName().equals("element")) {
XmlSchemaElement element = handleElement(schema, el, schemaEl,
true);
if (element.qualifiedName != null)
schema.elements.collection.put(element.qualifiedName,
element);
else if (element.refName != null)
schema.elements.collection.put(element.refName, element);
schema.items.add(element);
} else if (el.getLocalName().equals("include")) {
XmlSchemaInclude include = handleInclude(schema, el, schemaEl);
schema.includes.add(include);
schema.items.add(include);
} else if (el.getLocalName().equals("import")) {
XmlSchemaImport schemaImport = handleImport(schema, el,
schemaEl);
schema.includes.add(schemaImport);
schema.items.add(schemaImport);
} else if (el.getLocalName().equals("group")) {
XmlSchemaGroup group = handleGroup(schema, el, schemaEl);
schema.groups.collection.put(group.name, group);
schema.items.add(group);
} else if (el.getLocalName().equals("attributeGroup")) {
XmlSchemaAttributeGroup group = handleAttributeGroup(schema,
el, schemaEl);
schema.attributeGroups.collection.put(group.name, group);
schema.items.add(group);
} else if (el.getLocalName().equals("attribute")) {
XmlSchemaAttribute attr = handleAttribute(schema, el, schemaEl,
true); //pass true to indicate that it is a top level child
schema.attributes.collection.put(attr.qualifiedName, attr);
schema.items.add(attr);
} else if (el.getLocalName().equals("redefine")) {
XmlSchemaRedefine redefine = handleRedefine(schema, el,
schemaEl);
schema.includes.add(redefine);
} else if (el.getLocalName().equals("notation")) {
XmlSchemaNotation notation = handleNotation(el);
schema.notations.collection.put(new QName(schema
.getTargetNamespace(), notation.name), notation);
schema.items.add(notation);
} else if (el.getLocalName().equals("annotation")) {
XmlSchemaAnnotation annotation = handleAnnotation(el);
schema.setAnnotation(annotation);
}
}
//add the extesibility components
processExtensibilityComponents(schema, schemaEl);
return schema;
}
private XmlSchemaNotation handleNotation(Element notationEl) {
XmlSchemaNotation notation = new XmlSchemaNotation();
if (notationEl.hasAttribute("id")) {
notation.id = notationEl.getAttribute("id");
}
if (notationEl.hasAttribute("name")) {
notation.name = notationEl.getAttribute("name");
}
if (notationEl.hasAttribute("public")) {
notation.publicNotation = notationEl.getAttribute("public");
}
if (notationEl.hasAttribute("system")) {
notation.system = notationEl.getAttribute("system");
}
Element annotationEl = XDOMUtil.getFirstChildElementNS(notationEl,
XmlSchema.SCHEMA_NS, "annotation");
if (annotationEl != null) {
XmlSchemaAnnotation annotation = handleAnnotation(annotationEl);
notation.setAnnotation(annotation);
}
return notation;
}
/**
* Handle redefine
* @param schema
* @param redefineEl
* @param schemaEl
* @return
*/
private XmlSchemaRedefine handleRedefine(XmlSchema schema,
Element redefineEl, Element schemaEl) {
XmlSchemaRedefine redefine = new XmlSchemaRedefine();
redefine.schemaLocation = redefineEl.getAttribute("schemaLocation");
final TargetNamespaceValidator validator = newIncludeValidator(schema);
if (schema.getSourceURI() != null) {
redefine.schema = resolveXmlSchema(schema.logicalTargetNamespace,
redefine.schemaLocation, schema.getSourceURI(), validator);
} else {
redefine.schema = resolveXmlSchema(schema.logicalTargetNamespace,
redefine.schemaLocation, validator);
}
/*
* FIXME - This seems not right. Since the redefine should take into account
* the attributes of the original element we cannot just build the type
* defined in the redefine section - what we need to do is to get the original type
* object and modify it. However one may argue (quite reasonably) that the purpose
* of this object model is to provide just the representation and not the validation
* (as it has been always the case)
*/
for (Element el = XDOMUtil.getFirstChildElementNS(redefineEl,
XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
if (el.getLocalName().equals("simpleType")) {
XmlSchemaType type = handleSimpleType(schema, el, schemaEl);
redefine.schemaTypes.collection.put(type.getQName(), type);
redefine.items.add(type);
} else if (el.getLocalName().equals("complexType")) {
XmlSchemaType type = handleComplexType(schema, el, schemaEl);
redefine.schemaTypes.collection.put(type.getQName(), type);
redefine.items.add(type);
} else if (el.getLocalName().equals("group")) {
XmlSchemaGroup group = handleGroup(schema, el, schemaEl);
redefine.groups.collection.put(group.name, group);
redefine.items.add(group);
} else if (el.getLocalName().equals("attributeGroup")) {
XmlSchemaAttributeGroup group = handleAttributeGroup(schema,
el, schemaEl);
redefine.attributeGroups.collection.put(group.name, group);
redefine.items.add(group);
} else if (el.getLocalName().equals("annotation")) {
XmlSchemaAnnotation annotation = handleAnnotation(el);
redefine.setAnnotation(annotation);
}
// }
}
return redefine;
}
void setNamespaceAttributes(XmlSchema schema, Element schemaEl) {
//no targetnamespace found !
if (schemaEl.getAttributeNode("targetNamespace") != null) {
String contain = schemaEl.getAttribute("targetNamespace");
schema.setTargetNamespace(contain);
} else {
//do nothing here
}
if (validator != null) {
validator.validate(schema);
}
}
/**
* Handles simple types
* @param schema
* @param simpleEl
* @param schemaEl
*/
XmlSchemaSimpleType handleSimpleType(XmlSchema schema, Element simpleEl,
Element schemaEl) {
XmlSchemaSimpleType simpleType = new XmlSchemaSimpleType(schema);
if (simpleEl.hasAttribute("name")) {
simpleType.name = simpleEl.getAttribute("name");
}
if (simpleEl.hasAttribute("final")) {
String finalstr = simpleEl.getAttribute("final");
if (finalstr.equalsIgnoreCase("all")
| finalstr.equalsIgnoreCase("#all"))
simpleType.setFinal(new XmlSchemaDerivationMethod(
Constants.BlockConstants.ALL));
else
simpleType.setFinal(new XmlSchemaDerivationMethod(finalstr));
}
Element simpleTypeAnnotationEl = XDOMUtil.getFirstChildElementNS(
simpleEl, XmlSchema.SCHEMA_NS, "annotation");
if (simpleTypeAnnotationEl != null) {
XmlSchemaAnnotation simpleTypeAnnotation = handleAnnotation(simpleTypeAnnotationEl);
simpleType.setAnnotation(simpleTypeAnnotation);
}
Element unionEl, listEl, restrictionEl;
if ((restrictionEl = XDOMUtil.getFirstChildElementNS(simpleEl,
XmlSchema.SCHEMA_NS, "restriction")) != null) {
XmlSchemaSimpleTypeRestriction restriction = new XmlSchemaSimpleTypeRestriction();
Element restAnnotationEl = XDOMUtil.getFirstChildElementNS(
restrictionEl, XmlSchema.SCHEMA_NS, "annotation");
if (restAnnotationEl != null) {
XmlSchemaAnnotation restAnnotation = handleAnnotation(restAnnotationEl);
restriction.setAnnotation(restAnnotation);
}
/** if (restriction has a base attribute )
* set the baseTypeName and look up the base type
* else if( restricion has a SimpleType Element as child)
* get that element and do a handleSimpleType;
* get the children of restriction other than annotation
* and simpleTypes and construct facets from it;
*
* set the restriction has the content of the simpleType
*
**/
Element inlineSimpleType = XDOMUtil.getFirstChildElementNS(
restrictionEl, XmlSchema.SCHEMA_NS, "simpleType");
if (restrictionEl.hasAttribute("base")) {
NamespaceContext ctx = new NodeNamespaceContext(restrictionEl);
restriction.baseTypeName = getRefQName(restrictionEl
.getAttribute("base"), ctx);
} else if (inlineSimpleType != null) {
restriction.baseType = handleSimpleType(schema,
inlineSimpleType, schemaEl);
}
for (Element el = XDOMUtil.getFirstChildElementNS(restrictionEl,
XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
if (!el.getLocalName().equals("annotation")
&& !el.getLocalName().equals("simpleType")) {
XmlSchemaFacet facet = XmlSchemaFacet.construct(el);
Element annotation = XDOMUtil.getFirstChildElementNS(el,
XmlSchema.SCHEMA_NS, "annotation");
if (annotation != null) {
XmlSchemaAnnotation facetAnnotation = handleAnnotation(annotation);
facet.setAnnotation(facetAnnotation);
}
restriction.facets.add(facet);
}
}
simpleType.content = restriction;
} else if ((listEl = XDOMUtil.getFirstChildElementNS(simpleEl,
XmlSchema.SCHEMA_NS, "list")) != null) {
XmlSchemaSimpleTypeList list = new XmlSchemaSimpleTypeList();
/******
* if( list has an itemType attribute )
* set the baseTypeName and look up the base type
* else if( list has a SimpleTypeElement as child)
* get that element and do a handleSimpleType
*
* set the list has the content of the simpleType
*/
Element inlineListType, listAnnotationEl;
if (listEl.hasAttribute("itemType")) {
String name = listEl.getAttribute("itemType");
list.itemTypeName = getRefQName(name, listEl);
} else if ((inlineListType = XDOMUtil.getFirstChildElementNS(
listEl, XmlSchema.SCHEMA_NS, "simpleType")) != null) {
list.itemType = handleSimpleType(schema, inlineListType,
schemaEl);
}
if ((listAnnotationEl = XDOMUtil.getFirstChildElementNS(listEl,
XmlSchema.SCHEMA_NS, "annotation")) != null) {
XmlSchemaAnnotation listAnnotation = handleAnnotation(listAnnotationEl);
list.setAnnotation(listAnnotation);
}
simpleType.content = list;
} else if ((unionEl = XDOMUtil.getFirstChildElementNS(simpleEl,
XmlSchema.SCHEMA_NS, "union")) != null) {
XmlSchemaSimpleTypeUnion union = new XmlSchemaSimpleTypeUnion();
/******
* if( union has a memberTypes attribute )
* add the memberTypeSources string
* for (each memberType in the list )
* lookup(memberType)
* for( all SimpleType child Elements)
* add the simpleTypeName (if any) to the memberType Sources
* do a handleSimpleType with the simpleTypeElement
*/
if (unionEl.hasAttribute("memberTypes")) {
String memberTypes = unionEl.getAttribute("memberTypes");
union.memberTypesSource = memberTypes;
Vector v = new Vector();
StringTokenizer tokenizer = new StringTokenizer(memberTypes,
" ");
while (tokenizer.hasMoreTokens()) {
String member = tokenizer.nextToken();
v.add(getRefQName(member, unionEl));
}
union.memberTypesQNames = new QName[v.size()];
v.copyInto(union.memberTypesQNames);
}
Element inlineUnionType = XDOMUtil.getFirstChildElementNS(unionEl,
XmlSchema.SCHEMA_NS, "simpleType");
while (inlineUnionType != null) {
XmlSchemaSimpleType unionSimpleType = handleSimpleType(schema,
inlineUnionType, schemaEl);
union.baseTypes.add(unionSimpleType);
if (unionSimpleType.name != null) {
union.memberTypesSource += " " + unionSimpleType.name;
}
inlineUnionType = XDOMUtil.getNextSiblingElementNS(
inlineUnionType, XmlSchema.SCHEMA_NS, "simpleType");
}
//NodeList annotations = unionEl.getElementsByTagNameNS(
//XmlSchema.SCHEMA_NS, "annotation");
Element unionAnnotationEl = XDOMUtil.getFirstChildElementNS(
unionEl, XmlSchema.SCHEMA_NS, "annotation");
if (unionAnnotationEl != null) {
XmlSchemaAnnotation unionAnnotation = handleAnnotation(unionAnnotationEl);
union.setAnnotation(unionAnnotation);
}
simpleType.content = union;
}
//process extra attributes and elements
processExtensibilityComponents(simpleType, simpleEl);
return simpleType;
}
private QName getRefQName(String pName, Node pNode) {
return getRefQName(pName, new NodeNamespaceContext(pNode));
}
private QName getRefQName(String pName, NamespaceContext pContext) {
final int offset = pName.indexOf(':');
String uri;
final String localName;
final String prefix;
if (offset == -1) {
uri = pContext.getNamespaceURI(Constants.DEFAULT_NS_PREFIX);
if (Constants.NULL_NS_URI.equals(uri)) {
return new QName(Constants.NULL_NS_URI, pName);
}
localName = pName;
prefix = Constants.DEFAULT_NS_PREFIX;
} else {
prefix = pName.substring(0, offset);
uri = pContext.getNamespaceURI(prefix);
if (uri == null || Constants.NULL_NS_URI.equals(uri)) {
if (schema.parent != null
&& schema.parent.getNamespaceContext() != null) {
uri = schema.parent.getNamespaceContext().getNamespaceURI(
prefix);
}
}
if (uri == null || Constants.NULL_NS_URI.equals(uri)) {
throw new IllegalStateException("The prefix " + prefix
+ " is not bound.");
}
localName = pName.substring(offset + 1);
}
return new QName(uri, localName, prefix);
}
/**
* Handle complex types
* @param schema
* @param complexEl
* @param schemaEl
*/
XmlSchemaComplexType handleComplexType(XmlSchema schema, Element complexEl,
Element schemaEl) {
/******
* set the complexTypeName if any
* for( eachChildNode)
* if ( simpleContent)
* if( restrcition)
* handle_simple_content_restriction
* else if( extension)
* handle_simple_content_extension
* break; // it has to be the only child
* else if( complexContent)
* if( restriction)
* handle_complex_content_restriction
* else if( extension)
* handle_complex_content_extension
* break; // it has to be the only child
* else if( group)
* if( group has ref)
* store the group name
* else
* handleGroup
* else if( sequence )
* handleSequence
* else if( all )
* handleAll
* else if(choice)
* handleChoice
* else if(attribute)
* handleAttribute
* else if(attributeGroup)
* handleAttributeGroup
* else if(anyAttribute)
* handleAnyAttribute
*/
XmlSchemaComplexType ct = new XmlSchemaComplexType(schema);
if (complexEl.hasAttribute("name")) {
//String namespace = (schema.targetNamespace==null)?
// "":schema.targetNamespace;
ct.name = complexEl.getAttribute("name");
}
for (Element el = XDOMUtil.getFirstChildElementNS(complexEl,
XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
//String elPrefix = el.getPrefix() == null ? "" :
//el.getPrefix();
//if(elPrefix.equals(schema.schema_ns_prefix)) {
if (el.getLocalName().equals("sequence")) {
ct.particle = handleSequence(schema, el, schemaEl);
} else if (el.getLocalName().equals("choice")) {
ct.particle = handleChoice(schema, el, schemaEl);
} else if (el.getLocalName().equals("all")) {
ct.particle = handleAll(schema, el, schemaEl);
} else if (el.getLocalName().equals("attribute")) {
ct.attributes.add(handleAttribute(schema, el, schemaEl));
} else if (el.getLocalName().equals("attributeGroup")) {
ct.attributes.add(handleAttributeGroupRef(el));
} else if (el.getLocalName().equals("group")) {
XmlSchemaGroupRef group = handleGroupRef(schema, el, schemaEl);
ct.particle = (group.particle == null) ? (XmlSchemaParticle) group
: group.particle;
} else if (el.getLocalName().equals("simpleContent")) {
ct.contentModel = handleSimpleContent(schema, el, schemaEl);
} else if (el.getLocalName().equals("complexContent")) {
ct.contentModel = handleComplexContent(schema, el, schemaEl);
} else if (el.getLocalName().equals("annotation")) {
ct.setAnnotation(handleAnnotation(el));
} else if (el.getLocalName().equals("anyAttribute")) {
ct.setAnyAttribute(handleAnyAttribute(schema, el, schemaEl));
}
//}
}
if (complexEl.hasAttribute("block")) {
String blockStr = complexEl.getAttribute("block");
if (blockStr.equalsIgnoreCase("all")
| blockStr.equalsIgnoreCase("#all")) {
ct.setBlock(new XmlSchemaDerivationMethod(
Constants.BlockConstants.ALL));
} else
ct.setBlock(new XmlSchemaDerivationMethod(blockStr));
//ct.setBlock(new XmlSchemaDerivationMethod(block));
}
if (complexEl.hasAttribute("final")) {
String finalstr = complexEl.getAttribute("final");
if (finalstr.equalsIgnoreCase("all")
| finalstr.equalsIgnoreCase("#all")) {
ct.setFinal(new XmlSchemaDerivationMethod(
Constants.BlockConstants.ALL));
} else
ct.setFinal(new XmlSchemaDerivationMethod(finalstr));
}
if (complexEl.hasAttribute("abstract")) {
String abs = complexEl.getAttribute("abstract");
if (abs.equalsIgnoreCase("true"))
ct.setAbstract(true);
else
ct.setAbstract(false);
}
if (complexEl.hasAttribute("mixed")) {
String mixed = complexEl.getAttribute("mixed");
if (mixed.equalsIgnoreCase("true"))
ct.setMixed(true);
else
ct.setMixed(false);
}
//process extra attributes and elements
processExtensibilityComponents(ct, complexEl);
return ct;
}
private XmlSchemaSimpleContent handleSimpleContent(XmlSchema schema,
Element simpleEl, Element schemaEl) {
XmlSchemaSimpleContent simpleContent = new XmlSchemaSimpleContent();
for (Element el = XDOMUtil.getFirstChildElementNS(simpleEl,
XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
if (el.getLocalName().equals("restriction")) {
simpleContent.content = handleSimpleContentRestriction(schema,
el, schemaEl);
} else if (el.getLocalName().equals("extension")) {
simpleContent.content = handleSimpleContentExtension(schema,
el, schemaEl);
} else if (el.getLocalName().equals("annotation")) {
simpleContent.setAnnotation(handleAnnotation(el));
}
}
return simpleContent;
}
private XmlSchemaComplexContent handleComplexContent(XmlSchema schema,
Element complexEl, Element schemaEl) {
XmlSchemaComplexContent complexContent = new XmlSchemaComplexContent();
for (Element el = XDOMUtil.getFirstChildElementNS(complexEl,
XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
if (el.getLocalName().equals("restriction")) {
complexContent.content = handleComplexContentRestriction(
schema, el, schemaEl);
} else if (el.getLocalName().equals("extension")) {
complexContent.content = handleComplexContentExtension(schema,
el, schemaEl);
} else if (el.getLocalName().equals("annotation")) {
complexContent.setAnnotation(handleAnnotation(el));
}
}
if (complexEl.hasAttribute("mixed")) {
String mixed = complexEl.getAttribute("mixed");
if (mixed.equalsIgnoreCase("true"))
complexContent.setMixed(true);
else
complexContent.setMixed(false);
}
return complexContent;
}
private XmlSchemaSimpleContentRestriction handleSimpleContentRestriction(
XmlSchema schema, Element restrictionEl, Element schemaEl) {
XmlSchemaSimpleContentRestriction restriction = new XmlSchemaSimpleContentRestriction();
if (restrictionEl.hasAttribute("base")) {
String name = restrictionEl.getAttribute("base");
restriction.baseTypeName = getRefQName(name, restrictionEl);
}
if (restrictionEl.hasAttribute("id"))
restriction.id = restrictionEl.getAttribute("id");
// check back simpleContent tag children to add attributes and simpleType if any occur
for (Element el = XDOMUtil.getFirstChildElementNS(restrictionEl,
XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
if (el.getLocalName().equals("attribute")) {
XmlSchemaAttribute attr = handleAttribute(schema, el, schemaEl);
restriction.attributes.add(attr);
} else if (el.getLocalName().equals("attributeGroup")) {
XmlSchemaAttributeGroupRef attrGroup = handleAttributeGroupRef(el);
restriction.attributes.add(attrGroup);
} else if (el.getLocalName().equals("simpleType")) {
restriction.baseType = handleSimpleType(schema, el, schemaEl);
} else if (el.getLocalName().equals("anyAttribute")) {
restriction.anyAttribute = handleAnyAttribute(schema, el,
schemaEl);
} else if (el.getLocalName().equals("annotation")) {
restriction.setAnnotation(handleAnnotation(el));
} else {
XmlSchemaFacet facet = XmlSchemaFacet.construct(el);
NodeList annotations = el.getElementsByTagNameNS(
XmlSchema.SCHEMA_NS, "annotation");
if (annotations.getLength() > 0) {
XmlSchemaAnnotation facetAnnotation = handleAnnotation(el);
facet.setAnnotation(facetAnnotation);
}
restriction.facets.add(facet);
}
}
return restriction;
}
private XmlSchemaSimpleContentExtension handleSimpleContentExtension(
XmlSchema schema, Element extEl, Element schemaEl) {
XmlSchemaSimpleContentExtension ext = new XmlSchemaSimpleContentExtension();
if (extEl.hasAttribute("base")) {
String name = extEl.getAttribute("base");
ext.baseTypeName = getRefQName(name, extEl);
}
for (Element el = XDOMUtil.getFirstChildElementNS(extEl,
XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
if (el.getLocalName().equals("attribute")) {
XmlSchemaAttribute attr = handleAttribute(schema, el, schemaEl);
ext.attributes.add(attr);
} else if (el.getLocalName().equals("attributeGroup")) {
XmlSchemaAttributeGroupRef attrGroup = handleAttributeGroupRef(el);
ext.attributes.add(attrGroup);
} else if (el.getLocalName().equals("anyAttribute")) {
ext.anyAttribute = handleAnyAttribute(schema, el, schemaEl);
} else if (el.getLocalName().equals("annotation")) {
XmlSchemaAnnotation ann = handleAnnotation(el);
ext.setAnnotation(ann);
}
}
return ext;
}
private XmlSchemaComplexContentRestriction handleComplexContentRestriction(
XmlSchema schema, Element restrictionEl, Element schemaEl) {
XmlSchemaComplexContentRestriction restriction = new XmlSchemaComplexContentRestriction();
if (restrictionEl.hasAttribute("base")) {
String name = restrictionEl.getAttribute("base");
restriction.baseTypeName = getRefQName(name, restrictionEl);
}
for (Element el = XDOMUtil.getFirstChildElementNS(restrictionEl,
XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
if (el.getLocalName().equals("sequence")) {
restriction.particle = handleSequence(schema, el, schemaEl);
} else if (el.getLocalName().equals("choice")) {
restriction.particle = handleChoice(schema, el, schemaEl);
} else if (el.getLocalName().equals("all")) {
restriction.particle = handleAll(schema, el, schemaEl);
} else if (el.getLocalName().equals("attribute")) {
restriction.attributes
.add(handleAttribute(schema, el, schemaEl));
} else if (el.getLocalName().equals("attributeGroup")) {
restriction.attributes.add(handleAttributeGroupRef(el));
} else if (el.getLocalName().equals("group")) {
restriction.particle = handleGroupRef(schema, el, schemaEl);
} else if (el.getLocalName().equals("anyAttribute")) {
restriction.anyAttribute = handleAnyAttribute(schema, el,
schemaEl);
} else if (el.getLocalName().equals("annotation")) {
restriction.setAnnotation(handleAnnotation(el));
}
}
return restriction;
}
private XmlSchemaComplexContentExtension handleComplexContentExtension(
XmlSchema schema, Element extEl, Element schemaEl) {
XmlSchemaComplexContentExtension ext = new XmlSchemaComplexContentExtension();
if (extEl.hasAttribute("base")) {
String name = extEl.getAttribute("base");
ext.baseTypeName = getRefQName(name, extEl);
}
for (Element el = XDOMUtil.getFirstChildElementNS(extEl,
XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
if (el.getLocalName().equals("sequence")) {
ext.particle = handleSequence(schema, el, schemaEl);
} else if (el.getLocalName().equals("choice")) {
ext.particle = handleChoice(schema, el, schemaEl);
} else if (el.getLocalName().equals("all")) {
ext.particle = handleAll(schema, el, schemaEl);
} else if (el.getLocalName().equals("attribute")) {
ext.attributes.add(handleAttribute(schema, el, schemaEl));
} else if (el.getLocalName().equals("attributeGroup")) {
ext.attributes.add(handleAttributeGroupRef(el));
} else if (el.getLocalName().equals("group")) {
ext.particle = handleGroupRef(schema, el, schemaEl);
} else if (el.getLocalName().equals("anyAttribute")) {
ext.anyAttribute = handleAnyAttribute(schema, el, schemaEl);
} else if (el.getLocalName().equals("annotation")) {
ext.setAnnotation(handleAnnotation(el));
}
}
return ext;
}
private XmlSchemaAttributeGroupRef handleAttributeGroupRef(
Element attrGroupEl) {
XmlSchemaAttributeGroupRef attrGroup = new XmlSchemaAttributeGroupRef();
if (attrGroupEl.hasAttribute("ref")) {
String ref = attrGroupEl.getAttribute("ref");
attrGroup.refName = getRefQName(ref, attrGroupEl);
}
if (attrGroupEl.hasAttribute("id"))
attrGroup.id = attrGroupEl.getAttribute("id");
Element annotationEl = XDOMUtil.getFirstChildElementNS(attrGroupEl,
XmlSchema.SCHEMA_NS, "annotation");
if (annotationEl != null) {
XmlSchemaAnnotation annotation = handleAnnotation(annotationEl);
attrGroup.setAnnotation(annotation);
}
return attrGroup;
}
private XmlSchemaSequence handleSequence(XmlSchema schema,
Element sequenceEl, Element schemaEl) {
XmlSchemaSequence sequence = new XmlSchemaSequence();
//handle min and max occurences
sequence.minOccurs = getMinOccurs(sequenceEl);
sequence.maxOccurs = getMaxOccurs(sequenceEl);
for (Element el = XDOMUtil.getFirstChildElementNS(sequenceEl,
XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
if (el.getLocalName().equals("sequence")) {
XmlSchemaSequence seq = handleSequence(schema, el, schemaEl);
sequence.items.add(seq);
} else if (el.getLocalName().equals("element")) {
XmlSchemaElement element = handleElement(schema, el, schemaEl,
false);
sequence.items.add(element);
} else if (el.getLocalName().equals("group")) {
XmlSchemaGroupRef group = handleGroupRef(schema, el, schemaEl);
sequence.items.add(group);
} else if (el.getLocalName().equals("choice")) {
XmlSchemaChoice choice = handleChoice(schema, el, schemaEl);
sequence.items.add(choice);
} else if (el.getLocalName().equals("any")) {
XmlSchemaAny any = handleAny(schema, el, schemaEl);
sequence.items.add(any);
} else if (el.getLocalName().equals("annotation")) {
XmlSchemaAnnotation annotation = handleAnnotation(el);
sequence.setAnnotation(annotation);
}
}
return sequence;
}
/** @noinspection UnusedParameters*/
private XmlSchemaAny handleAny(XmlSchema schema, Element anyEl,
Element schemaEl) {
XmlSchemaAny any = new XmlSchemaAny();
if (anyEl.hasAttribute("namespace"))
any.namespace = anyEl.getAttribute("namespace");
if (anyEl.hasAttribute("processContents")) {
String processContent = getEnumString(anyEl, "processContents");
any.processContent = new XmlSchemaContentProcessing(processContent);
}
Element annotationEl = XDOMUtil.getFirstChildElementNS(anyEl,
XmlSchema.SCHEMA_NS, "annotation");
if (annotationEl != null) {
XmlSchemaAnnotation annotation = handleAnnotation(annotationEl);
any.setAnnotation(annotation);
}
any.minOccurs = getMinOccurs(anyEl);
any.maxOccurs = getMaxOccurs(anyEl);
return any;
}
private XmlSchemaChoice handleChoice(XmlSchema schema, Element choiceEl,
Element schemaEl) {
XmlSchemaChoice choice = new XmlSchemaChoice();
if (choiceEl.hasAttribute("id"))
choice.id = choiceEl.getAttribute("id");
choice.minOccurs = getMinOccurs(choiceEl);
choice.maxOccurs = getMaxOccurs(choiceEl);
for (Element el = XDOMUtil.getFirstChildElementNS(choiceEl,
XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
if (el.getLocalName().equals("sequence")) {
XmlSchemaSequence seq = handleSequence(schema, el, schemaEl);
choice.items.add(seq);
} else if (el.getLocalName().equals("element")) {
XmlSchemaElement element = handleElement(schema, el, schemaEl,
false);
choice.items.add(element);
} else if (el.getLocalName().equals("group")) {
XmlSchemaGroupRef group = handleGroupRef(schema, el, schemaEl);
choice.items.add(group);
} else if (el.getLocalName().equals("choice")) {
XmlSchemaChoice choiceItem = handleChoice(schema, el, schemaEl);
choice.items.add(choiceItem);
} else if (el.getLocalName().equals("any")) {
XmlSchemaAny any = handleAny(schema, el, schemaEl);
choice.items.add(any);
} else if (el.getLocalName().equals("annotation")) {
XmlSchemaAnnotation annotation = handleAnnotation(el);
choice.setAnnotation(annotation);
}
}
return choice;
}
private XmlSchemaAll handleAll(XmlSchema schema, Element allEl,
Element schemaEl) {
XmlSchemaAll all = new XmlSchemaAll();
//handle min and max occurences
all.minOccurs = getMinOccurs(allEl);
all.maxOccurs = getMaxOccurs(allEl);
for (Element el = XDOMUtil.getFirstChildElementNS(allEl,
XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
if (el.getLocalName().equals("element")) {
XmlSchemaElement element = handleElement(schema, el, schemaEl,
false);
all.items.add(element);
} else if (el.getLocalName().equals("annotation")) {
XmlSchemaAnnotation annotation = handleAnnotation(el);
all.setAnnotation(annotation);
}
}
return all;
}
private XmlSchemaGroup handleGroup(XmlSchema schema, Element groupEl,
Element schemaEl) {
XmlSchemaGroup group = new XmlSchemaGroup();
group.name = new QName(schema.getTargetNamespace(), groupEl
.getAttribute("name"));
for (Element el = XDOMUtil.getFirstChildElementNS(groupEl,
XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
if (el.getLocalName().equals("all")) {
group.particle = handleAll(schema, el, schemaEl);
} else if (el.getLocalName().equals("sequence")) {
group.particle = handleSequence(schema, el, schemaEl);
} else if (el.getLocalName().equals("choice")) {
group.particle = handleChoice(schema, el, schemaEl);
} else if (el.getLocalName().equals("annotation")) {
XmlSchemaAnnotation groupAnnotation = handleAnnotation(el);
group.setAnnotation(groupAnnotation);
}
}
return group;
}
private XmlSchemaAttributeGroup handleAttributeGroup(XmlSchema schema,
Element groupEl, Element schemaEl) {
XmlSchemaAttributeGroup attrGroup = new XmlSchemaAttributeGroup();
if (groupEl.hasAttribute("name"))
attrGroup.name = new QName(schema.getTargetNamespace(), groupEl
.getAttribute("name"));
if (groupEl.hasAttribute("id"))
attrGroup.id = groupEl.getAttribute("id");
for (Element el = XDOMUtil.getFirstChildElementNS(groupEl,
XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
if (el.getLocalName().equals("attribute")) {
XmlSchemaAttribute attr = handleAttribute(schema, el, schemaEl);
attrGroup.attributes.add(attr);
} else if (el.getLocalName().equals("attributeGroup")) {
XmlSchemaAttributeGroupRef attrGroupRef = handleAttributeGroupRef(el);
attrGroup.attributes.add(attrGroupRef);
} else if (el.getLocalName().equals("anyAttribute")) {
attrGroup.anyAttribute = handleAnyAttribute(schema, el,
schemaEl);
} else if (el.getLocalName().equals("annotation")) {
XmlSchemaAnnotation ann = handleAnnotation(el);
attrGroup.setAnnotation(ann);
}
}
return attrGroup;
}
/** @noinspection UnusedParameters*/
private XmlSchemaAnyAttribute handleAnyAttribute(XmlSchema schema,
Element anyAttrEl, Element schemaEl) {
XmlSchemaAnyAttribute anyAttr = new XmlSchemaAnyAttribute();
if (anyAttrEl.hasAttribute("namespace"))
anyAttr.namespace = anyAttrEl.getAttribute("namespace");
if (anyAttrEl.hasAttribute("processContents")) {
String contentProcessing = getEnumString(anyAttrEl,
"processContents");
anyAttr.processContent = new XmlSchemaContentProcessing(
contentProcessing);
}
if (anyAttrEl.hasAttribute("id"))
anyAttr.id = anyAttrEl.getAttribute("id");
Element annotationEl = XDOMUtil.getFirstChildElementNS(anyAttrEl,
XmlSchema.SCHEMA_NS, "annotation");
if (annotationEl != null) {
XmlSchemaAnnotation annotation = handleAnnotation(annotationEl);
anyAttr.setAnnotation(annotation);
}
return anyAttr;
}
private XmlSchemaGroupRef handleGroupRef(XmlSchema schema, Element groupEl,
Element schemaEl) {
XmlSchemaGroupRef group = new XmlSchemaGroupRef();
group.maxOccurs = getMaxOccurs(groupEl);
group.minOccurs = getMinOccurs(groupEl);
Element annotationEl = XDOMUtil.getFirstChildElementNS(groupEl,
XmlSchema.SCHEMA_NS, "annotation");
if (annotationEl != null) {
XmlSchemaAnnotation annotation = handleAnnotation(annotationEl);
group.setAnnotation(annotation);
}
if (groupEl.hasAttribute("ref")) {
String ref = groupEl.getAttribute("ref");
group.refName = getRefQName(ref, groupEl);
return group;
}
for (Element el = XDOMUtil.getFirstChildElementNS(groupEl,
XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
.getNextSiblingElement(el)) {
if (el.getLocalName().equals("sequence")) {
group.particle = handleSequence(schema, el, schemaEl);
} else if (el.getLocalName().equals("all")) {
group.particle = handleAll(schema, el, schemaEl);
} else if (el.getLocalName().equals("choice")) {
group.particle = handleChoice(schema, el, schemaEl);
}
}
return group;
}
private QName newLocalQName(String pLocalName) {
String uri = schema.logicalTargetNamespace;
if (uri == null) {
uri = Constants.NULL_NS_URI;
}
return new QName(uri, pLocalName);
}
/**
* Process non-toplevel attributes
* @param schema
* @param attrEl
* @param schemaEl
* @return
*/
private XmlSchemaAttribute handleAttribute(XmlSchema schema,
Element attrEl, Element schemaEl) {
return handleAttribute(schema, attrEl, schemaEl, false);
}
/**
* Process attributes
* @param schema
* @param attrEl
* @param schemaEl
* @param topLevel
* @return
*/
private XmlSchemaAttribute handleAttribute(XmlSchema schema,
Element attrEl, Element schemaEl, boolean topLevel) {
//todo: need to implement different rule of attribute such as
//restriction between ref and name. This can be implemented
//in the compile function
XmlSchemaAttribute attr = new XmlSchemaAttribute();
if (attrEl.hasAttribute("name")) {
String name = attrEl.getAttribute("name");
//String namespace = (schema.targetNamespace==null)?
// "" :schema.targetNamespace;
attr.name = name;
}
boolean isQualified = schema.getAttributeFormDefault().getValue()
.equals(XmlSchemaForm.QUALIFIED);
if (attr.name != null) {
final String name = attr.name;
if (topLevel) {
attr.qualifiedName = newLocalQName(name);
} else {
attr.qualifiedName = (isQualified) ? newLocalQName(name)
: new QName(name);
}
}
if (attrEl.hasAttribute("type")) {
String name = attrEl.getAttribute("type");
attr.schemaTypeName = getRefQName(name, attrEl);
}
if (attrEl.hasAttribute("default"))
attr.defaultValue = attrEl.getAttribute("default");
if (attrEl.hasAttribute("fixed"))
attr.fixedValue = attrEl.getAttribute("fixed");
if (attrEl.hasAttribute("form")) {
String formValue = getEnumString(attrEl, "form");
attr.form = new XmlSchemaForm(formValue);
}
if (attrEl.hasAttribute("id"))
attr.id = attrEl.getAttribute("id");
if (attrEl.hasAttribute("use")) {
String useType = getEnumString(attrEl, "use");
attr.use = new XmlSchemaUse(useType);
}
if (attrEl.hasAttribute("ref")) {
String name = attrEl.getAttribute("ref");
attr.refName = getRefQName(name, attrEl);
attr.name = name;
}
Element simpleTypeEl = XDOMUtil.getFirstChildElementNS(attrEl,
XmlSchema.SCHEMA_NS, "simpleType");
if (simpleTypeEl != null) {
attr.schemaType = handleSimpleType(schema, simpleTypeEl, schemaEl);
}
Element annotationEl = XDOMUtil.getFirstChildElementNS(attrEl,
XmlSchema.SCHEMA_NS, "annotation");
if (annotationEl != null) {
XmlSchemaAnnotation annotation = handleAnnotation(annotationEl);
attr.setAnnotation(annotation);
}
NamedNodeMap attrNodes = attrEl.getAttributes();
Vector attrs = new Vector();
NodeNamespaceContext ctx = null;
for (int i = 0; i < attrNodes.getLength(); i++) {
Attr att = (Attr) attrNodes.item(i);
String attName = att.getName();
if (!attName.equals("name") && !attName.equals("type")
&& !attName.equals("default") && !attName.equals("fixed")
&& !attName.equals("form") && !attName.equals("id")
&& !attName.equals("use") && !attName.equals("ref")) {
attrs.add(att);
String value = att.getValue();
if (value.indexOf(":") > -1) {
// there is a possiblily of some namespace mapping
String prefix = value.substring(0, value.indexOf(":"));
if (ctx == null) {
ctx = new NodeNamespaceContext(attrEl);
}
String namespace = ctx.getNamespaceURI(prefix);
if (!Constants.NULL_NS_URI.equals(namespace)) {
Attr nsAttr = attrEl.getOwnerDocument()
.createAttribute("xmlns:" + prefix);
nsAttr.setValue(namespace);
attrs.add(nsAttr);
}
}
}
}
if (attrs.size() > 0)
attr.setUnhandledAttributes((Attr[]) attrs.toArray(new Attr[0]));
//process extra attributes and elements
processExtensibilityComponents(attr, attrEl);
return attr;
}
/*
* handle_simple_content_restriction
*
* if( restriction has base attribute )
* set the baseType
* else if( restriciton has an inline simpleType )
* handleSimpleType
* add facets if any to the restriction
*/
/*
* handle_simple_content_extension
*
* extension should have a base name and cannot have any inline defn
* for( each childNode )
* if( attribute)
* handleAttribute
* else if( attributeGroup)
* handleAttributeGroup
* else if( anyAttribute)
* handleAnyAttribute
*/
/*
* ********
* handle_complex_content_restriction
*/
/**
* handle elements
* @param schema
* @param el
* @param schemaEl
* @param isGlobal
*/
XmlSchemaElement handleElement(XmlSchema schema, Element el,
Element schemaEl, boolean isGlobal) {
XmlSchemaElement element = new XmlSchemaElement();
if (el.getAttributeNode("name") != null)
element.name = el.getAttribute("name");
// String namespace = (schema.targetNamespace==null)?
// "" : schema.targetNamespace;
boolean isQualified = schema.getElementFormDefault().getValue().equals(
XmlSchemaForm.QUALIFIED);
if (el.hasAttribute("form")) {
String formDef = el.getAttribute("form");
element.form = new XmlSchemaForm(formDef);
isQualified = formDef.equals(XmlSchemaForm.QUALIFIED);
}
if (element.name != null) {
final String name = element.name;
element.qualifiedName = (isQualified || isGlobal) ? newLocalQName(name)
: new QName(Constants.NULL_NS_URI, name);
}
Element annotationEl = XDOMUtil.getFirstChildElementNS(el,
XmlSchema.SCHEMA_NS, "annotation");
if (annotationEl != null) {
XmlSchemaAnnotation annotation = handleAnnotation(annotationEl);
element.setAnnotation(annotation);
}
if (el.getAttributeNode("type") != null) {
String typeName = el.getAttribute("type");
QName typeQName = element.schemaTypeName = getRefQName(typeName, el);
XmlSchemaType type = collection.getTypeByQName(typeQName);
if (type == null) {
// Could be a forward reference...
collection.addUnresolvedType(typeQName, element);
}
element.schemaType = type;
} else if (el.getAttributeNode("ref") != null) {
String refName = el.getAttribute("ref");
QName refQName = getRefQName(refName, el);
element.setRefName(refQName);
element.name = refQName.getLocalPart();
}
Element simpleTypeEl, complexTypeEl, keyEl, keyrefEl, uniqueEl;
if ((simpleTypeEl = XDOMUtil.getFirstChildElementNS(el,
XmlSchema.SCHEMA_NS, "simpleType")) != null) {
XmlSchemaSimpleType simpleType = handleSimpleType(schema,
simpleTypeEl, schemaEl);
element.schemaType = simpleType;
element.schemaTypeName = simpleType.getQName();
} else if ((complexTypeEl = XDOMUtil.getFirstChildElementNS(el,
XmlSchema.SCHEMA_NS, "complexType")) != null) {
element.schemaType = handleComplexType(schema, complexTypeEl,
schemaEl);
}
if ((keyEl = XDOMUtil.getFirstChildElementNS(el, XmlSchema.SCHEMA_NS,
"key")) != null) {
while (keyEl != null) {
element.constraints.add(handleConstraint(keyEl, "Key"));
keyEl = XDOMUtil.getNextSiblingElement(keyEl, "key");
}
}
if ((keyrefEl = XDOMUtil.getFirstChildElementNS(el,
XmlSchema.SCHEMA_NS, "keyref")) != null) {
while (keyrefEl != null) {
XmlSchemaKeyref keyRef = (XmlSchemaKeyref) handleConstraint(
keyrefEl, "Keyref");
if (keyrefEl.hasAttribute("refer")) {
String name = keyrefEl.getAttribute("refer");
keyRef.refer = getRefQName(name, el);
}
element.constraints.add(keyRef);
keyrefEl = XDOMUtil.getNextSiblingElement(keyrefEl, "keyref");
}
}
if ((uniqueEl = XDOMUtil.getFirstChildElementNS(el,
XmlSchema.SCHEMA_NS, "unique")) != null) {
while (uniqueEl != null) {
element.constraints.add(handleConstraint(uniqueEl, "Unique"));
uniqueEl = XDOMUtil.getNextSiblingElement(uniqueEl, "unique");
}
}
if (el.hasAttribute("abstract")) {
element.isAbstract = Boolean.valueOf(el.getAttribute("abstract"))
.booleanValue();
}
if (el.hasAttribute("block"))
element.block = getDerivation(el, "block");
if (el.hasAttribute("default"))
element.defaultValue = el.getAttribute("default");
if (el.hasAttribute("final"))
element.finalDerivation = getDerivation(el, "final");
if (el.hasAttribute("fixed"))
element.fixedValue = el.getAttribute("fixed");
if (el.hasAttribute("id"))
element.id = el.getAttribute("id");
if (el.hasAttribute("nillable"))
element.isNillable = Boolean.valueOf(el.getAttribute("nillable"))
.booleanValue();
if (el.hasAttribute("substitutionGroup")) {
String substitutionGroup = el.getAttribute("substitutionGroup");
element.setSubstitutionGroup(getRefQName(substitutionGroup, el));
}
element.minOccurs = getMinOccurs(el);
element.maxOccurs = getMaxOccurs(el);
//process extra attributes and elements
processExtensibilityComponents(element, el);
return element;
}
private XmlSchemaIdentityConstraint handleConstraint(Element constraintEl,
String type) {
try {
XmlSchemaIdentityConstraint constraint = (XmlSchemaIdentityConstraint) Class
.forName("org.apache.ws.commons.schema.XmlSchema" + type)
.newInstance();
if (constraintEl.hasAttribute("name"))
constraint.name = constraintEl.getAttribute("name");
if (constraintEl.hasAttribute("refer")) {
String name = constraintEl.getAttribute("refer");
((XmlSchemaKeyref) constraint).refer = getRefQName(name,
constraintEl);
}
for (Element el = XDOMUtil.getFirstChildElementNS(constraintEl,
XmlSchema.SCHEMA_NS); el != null; el = XDOMUtil
.getNextSiblingElementNS(el, XmlSchema.SCHEMA_NS)) {
// String elPrefix = el.getPrefix() == null ? ""
// : el.getPrefix();
//if(elPrefix.equals(schema.schema_ns_prefix)) {
if (el.getLocalName().equals("selector")) {
XmlSchemaXPath selectorXPath = new XmlSchemaXPath();
selectorXPath.xpath = el.getAttribute("xpath");
Element annotationEl = XDOMUtil.getFirstChildElementNS(el,
XmlSchema.SCHEMA_NS, "annotation");
if (annotationEl != null) {
XmlSchemaAnnotation annotation = handleAnnotation(annotationEl);
selectorXPath.setAnnotation(annotation);
}
constraint.selector = selectorXPath;
} else if (el.getLocalName().equals("field")) {
XmlSchemaXPath fieldXPath = new XmlSchemaXPath();
fieldXPath.xpath = el.getAttribute("xpath");
constraint.fields.add(fieldXPath);
Element annotationEl = XDOMUtil.getFirstChildElementNS(el,
XmlSchema.SCHEMA_NS, "annotation");
if (annotationEl != null) {
XmlSchemaAnnotation annotation = handleAnnotation(annotationEl);
fieldXPath.setAnnotation(annotation);
}
} else if (el.getLocalName().equals("annotation")) {
XmlSchemaAnnotation constraintAnnotation = handleAnnotation(el);
constraint.setAnnotation(constraintAnnotation);
}
}
return constraint;
} catch (ClassNotFoundException e) {
throw new XmlSchemaException(e.getMessage());
} catch (InstantiationException e) {
throw new XmlSchemaException(e.getMessage());
} catch (IllegalAccessException e) {
throw new XmlSchemaException(e.getMessage());
}
}
/**
* Hanlde the import
* @param schema
* @param importEl
* @param schemaEl
* @return XmlSchemaObject
*/
XmlSchemaImport handleImport(XmlSchema schema, Element importEl,
Element schemaEl) {
XmlSchemaImport schemaImport = new XmlSchemaImport();
Element annotationEl = XDOMUtil.getFirstChildElementNS(importEl,
XmlSchema.SCHEMA_NS, "annotation");
if (annotationEl != null) {
XmlSchemaAnnotation importAnnotation = handleAnnotation(annotationEl);
schemaImport.setAnnotation(importAnnotation);
}
final String uri = schemaImport.namespace = importEl
.getAttribute("namespace");
schemaImport.schemaLocation = importEl.getAttribute("schemaLocation");
TargetNamespaceValidator validator = new TargetNamespaceValidator() {
private boolean isEmpty(String pValue) {
return pValue == null || Constants.NULL_NS_URI.equals(pValue);
}
public void validate(XmlSchema pSchema) {
final boolean valid;
if (isEmpty(uri)) {
valid = isEmpty(pSchema.syntacticalTargetNamespace);
} else {
valid = pSchema.syntacticalTargetNamespace.equals(uri);
}
if (!valid) {
throw new XmlSchemaException(
"An imported schema was announced to have the namespace "
+ uri + ", but has the namespace "
+ pSchema.syntacticalTargetNamespace);
}
}
};
if ((schemaImport.schemaLocation != null)
&& (!schemaImport.schemaLocation.equals(""))) {
if (schema.getSourceURI() != null) {
schemaImport.schema = resolveXmlSchema(uri,
schemaImport.schemaLocation, schema.getSourceURI(),
validator);
} else {
schemaImport.schema = resolveXmlSchema(schemaImport.namespace,
schemaImport.schemaLocation, validator);
}
}
return schemaImport;
}
/**
* Handles the include
* @param schema
* @param includeEl
* @param schemaEl
*/
XmlSchemaInclude handleInclude(final XmlSchema schema, Element includeEl,
Element schemaEl) {
XmlSchemaInclude include = new XmlSchemaInclude();
Element annotationEl = XDOMUtil.getFirstChildElementNS(includeEl,
XmlSchema.SCHEMA_NS, "annotation");
if (annotationEl != null) {
XmlSchemaAnnotation includeAnnotation = handleAnnotation(annotationEl);
include.setAnnotation(includeAnnotation);
}
include.schemaLocation = includeEl.getAttribute("schemaLocation");
//includes are not supposed to have a target namespace
// we should be passing in a null in place of the target
//namespace
final TargetNamespaceValidator validator = newIncludeValidator(schema);
if (schema.getSourceURI() != null) {
include.schema = resolveXmlSchema(schema.logicalTargetNamespace,
include.schemaLocation, schema.getSourceURI(), validator);
} else {
include.schema = resolveXmlSchema(schema.logicalTargetNamespace,
include.schemaLocation, validator);
}
//process extra attributes and elements
processExtensibilityComponents(include, includeEl);
return include;
}
private TargetNamespaceValidator newIncludeValidator(final XmlSchema schema) {
return new TargetNamespaceValidator() {
private boolean isEmpty(String pValue) {
return pValue == null || Constants.NULL_NS_URI.equals(pValue);
}
public void validate(XmlSchema pSchema) {
if (isEmpty(pSchema.syntacticalTargetNamespace)) {
pSchema.logicalTargetNamespace = schema.logicalTargetNamespace;
} else {
if (!pSchema.syntacticalTargetNamespace
.equals(schema.logicalTargetNamespace)) {
String msg = "An included schema was announced to have the default target namespace";
if (!isEmpty(schema.logicalTargetNamespace)) {
msg += " or the target namespace "
+ schema.logicalTargetNamespace;
}
throw new XmlSchemaException(msg
+ ", but has the target namespace "
+ pSchema.logicalTargetNamespace);
}
}
}
};
}
/**
* Handles the annotation
* Traversing if encounter appinfo or documentation
* add it to annotation collection
*
*/
XmlSchemaAnnotation handleAnnotation(Element annotEl) {
XmlSchemaObjectCollection content = new XmlSchemaObjectCollection();
XmlSchemaAppInfo appInfoObj;
XmlSchemaDocumentation docsObj;
for (Element appinfo = XDOMUtil.getFirstChildElementNS(annotEl,
XmlSchema.SCHEMA_NS, "appinfo"); appinfo != null; appinfo = XDOMUtil
.getNextSiblingElementNS(appinfo, XmlSchema.SCHEMA_NS,
"appinfo")) {
appInfoObj = handleAppInfo(appinfo);
if (appInfoObj != null) {
content.add(appInfoObj);
}
}
for (Element documentation = XDOMUtil.getFirstChildElementNS(annotEl,
XmlSchema.SCHEMA_NS, "documentation"); documentation != null; documentation = XDOMUtil
.getNextSiblingElementNS(documentation,
XmlSchema.SCHEMA_NS, "documentation")) {
docsObj = handleDocumentation(documentation);
if (docsObj != null) {
content.add(docsObj);
}
}
XmlSchemaAnnotation annotation = new XmlSchemaAnnotation();
annotation.items = content;
//process extra attributes and elements
processExtensibilityComponents(annotation, annotEl);
return annotation;
}
/**
* create new XmlSchemaAppinfo and add value goten from element
* to this obj
* @param content
*/
XmlSchemaAppInfo handleAppInfo(Element content) {
XmlSchemaAppInfo appInfo = new XmlSchemaAppInfo();
NodeList markup = getChildren(content);
if (!content.hasAttribute("source")
&& (markup == null || markup.getLength() <= 0)) {
return null;
}
appInfo.setSource(getAttribute(content, "source"));
appInfo.setMarkup(markup);
return appInfo;
}
//iterate each documentation element, create new XmlSchemaAppinfo and add to collection
XmlSchemaDocumentation handleDocumentation(Element content) {
XmlSchemaDocumentation documentation = new XmlSchemaDocumentation();
NodeList markup = getChildren(content);
if (!content.hasAttribute("source")
&& !content.hasAttribute("xml:lang")
&& (markup == null || markup.getLength() <= 0))
return null;
documentation.setSource(getAttribute(content, "source"));
documentation.setLanguage(getAttribute(content, "xml:lang"));
documentation.setMarkup(getChildren(content));
return documentation;
}
private String getAttribute(Element content, String attrName) {
if (content.hasAttribute(attrName))
return content.getAttribute(attrName);
return null;
}
private NodeList getChildren(Element content) {
NodeList childs = content.getChildNodes();
if (childs.getLength() > 0)
return childs;
return null;
}
long getMinOccurs(Element el) {
try {
if (el.getAttributeNode("minOccurs") != null) {
String value = el.getAttribute("minOccurs");
if (value.equals("unbounded"))
return Long.MAX_VALUE;
else
return Long.parseLong(value);
}
return 1;
} catch (java.lang.NumberFormatException e) {
return 1;
}
}
long getMaxOccurs(Element el) {
try {
if (el.getAttributeNode("maxOccurs") != null) {
String value = el.getAttribute("maxOccurs");
if (value.equals("unbounded"))
return Long.MAX_VALUE;
else
return Long.parseLong(value);
}
return 1;
} catch (java.lang.NumberFormatException e) {
return 1;
}
}
XmlSchemaForm getFormDefault(Element el, String attrName) {
if (el.getAttributeNode(attrName) != null) {
String value = el.getAttribute(attrName);
return new XmlSchemaForm(value);
} else
return new XmlSchemaForm("unqualified");
}
//Check value entered by user and change according to .net spec,
//according to w3c spec have to be "#all"
//but in .net the valid enum value is "all".
XmlSchemaDerivationMethod getDerivation(Element el, String attrName) {
if (el.hasAttribute(attrName) && !el.getAttribute(attrName).equals("")) {
//#all | List of (extension | restriction | substitution
String derivationMethod = el.getAttribute(attrName).trim();
if (derivationMethod.equals("#all"))
return new XmlSchemaDerivationMethod(
Constants.BlockConstants.ALL);
else
return new XmlSchemaDerivationMethod(derivationMethod);
}
return new XmlSchemaDerivationMethod(Constants.BlockConstants.NONE);
}
//Check value entered by user and change according to .net spec, user
String getEnumString(Element el, String attrName) {
if (el.hasAttribute(attrName)) {
return el.getAttribute(attrName).trim();
}
return Constants.BlockConstants.NONE;
}
/**
* Resolve the schemas
* @param targetNamespace
* @param schemaLocation
*/
XmlSchema resolveXmlSchema(String targetNamespace, String schemaLocation,
String baseUri, TargetNamespaceValidator validator) {
//use the entity resolver provided if the schema location is present null
if (schemaLocation != null && !"".equals(schemaLocation)) {
InputSource source = collection.schemaResolver.resolveEntity(
targetNamespace, schemaLocation, baseUri);
//the entity resolver was unable to resolve this!!
if (source == null) {
//try resolving it with the target namespace only with the
//known namespace map
XmlSchema schema = collection.getKnownSchema(targetNamespace);
if (schema != null) {
return schema;
}else{
return null;
}
}
final String systemId = source.getSystemId() == null ? schemaLocation
: source.getSystemId();
final SchemaKey key = new XmlSchemaCollection.SchemaKey(
targetNamespace, systemId);
XmlSchema schema = collection.getSchema(key);
if (schema != null) {
return schema;
}
if (collection.check(key)) {
collection.push(key);
try {
return collection.read(source, null, validator);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
collection.pop();
}
}
}else{
XmlSchema schema = collection.getKnownSchema(targetNamespace);
if (schema != null) {
return schema;
}
}
return null;
}
/**
* Resolve the schemas
* @param targetNamespace
* @param schemaLocation
*/
XmlSchema resolveXmlSchema(String targetNamespace, String schemaLocation,
TargetNamespaceValidator validator) {
return resolveXmlSchema(targetNamespace, schemaLocation,
collection.baseUri, validator);
}
/**
* A generic method to process the extra attributes and the the extra
* elements present within the schema.
* What are considered extensions are child elements with non schema namespace
* and child attributes with any namespace
* @param schemaObject
* @param parentElement
*/
private void processExtensibilityComponents(XmlSchemaObject schemaObject,
Element parentElement) {
if (extReg != null) {
//process attributes
NamedNodeMap attributes = parentElement.getAttributes();
for (int i = 0; i < attributes.getLength(); i++) {
Attr attribute = (Attr) attributes.item(i);
String namespaceURI = attribute.getNamespaceURI();
String name = attribute.getLocalName();
if (namespaceURI != null
&& !"".equals(namespaceURI)
&& //ignore unqualified attributes
!namespaceURI
.startsWith(Constants.XMLNS_ATTRIBUTE_NS_URI) && //ignore namespaces
!Constants.URI_2001_SCHEMA_XSD.equals(namespaceURI))
//does not belong to the schema namespace by any chance!
{
QName qName = new QName(namespaceURI, name);
extReg.deserializeExtension(schemaObject, qName, attribute);
}
}
//process elements
NodeList allChildren = parentElement.getChildNodes();
for (int i = 0; i < allChildren.getLength(); i++) {
if (allChildren.item(i).getNodeType() == Node.ELEMENT_NODE) {
Element extElement = (Element) allChildren.item(i);
String namespaceURI = extElement.getNamespaceURI();
String name = extElement.getLocalName();
if (namespaceURI != null
&& !Constants.URI_2001_SCHEMA_XSD
.equals(namespaceURI))
//does not belong to the schema namespace
{
QName qName = new QName(namespaceURI, name);
extReg.deserializeExtension(schemaObject, qName,
extElement);
}
}
}
}
}
}