aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'moxy/org.eclipse.persistence.moxy/src/org/eclipse/persistence/jaxb/compiler/SchemaGenerator.java')
-rw-r--r--moxy/org.eclipse.persistence.moxy/src/org/eclipse/persistence/jaxb/compiler/SchemaGenerator.java2265
1 files changed, 1226 insertions, 1039 deletions
diff --git a/moxy/org.eclipse.persistence.moxy/src/org/eclipse/persistence/jaxb/compiler/SchemaGenerator.java b/moxy/org.eclipse.persistence.moxy/src/org/eclipse/persistence/jaxb/compiler/SchemaGenerator.java
index e62a757..8cc5a70 100644
--- a/moxy/org.eclipse.persistence.moxy/src/org/eclipse/persistence/jaxb/compiler/SchemaGenerator.java
+++ b/moxy/org.eclipse.persistence.moxy/src/org/eclipse/persistence/jaxb/compiler/SchemaGenerator.java
@@ -3,9 +3,9 @@
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
- * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
- * and the Eclipse Distribution License is available at
- * http://www.eclipse.org/org/documents/edl-v10.php.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Oracle - initial API and implementation from Oracle TopLink
@@ -18,22 +18,26 @@ import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import javax.xml.bind.SchemaOutputResolver;
-import javax.xml.bind.annotation.XmlElementDecl.GLOBAL;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.xml.bind.SchemaOutputResolver;
+import javax.xml.bind.annotation.XmlElementDecl.GLOBAL;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.namespace.QName;
-import javax.xml.transform.Result;
-import javax.xml.transform.Source;
-
-import org.eclipse.persistence.exceptions.JAXBException;
-import org.eclipse.persistence.internal.core.helper.CoreClassConstants;
-import org.eclipse.persistence.internal.jaxb.many.MapValue;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+
+import org.eclipse.persistence.exceptions.BeanValidationException;
+import org.eclipse.persistence.exceptions.JAXBException;
+import org.eclipse.persistence.internal.core.helper.CoreClassConstants;
+import org.eclipse.persistence.internal.jaxb.many.MapValue;
import org.eclipse.persistence.internal.oxm.Constants;
import org.eclipse.persistence.internal.oxm.Namespace;
import org.eclipse.persistence.internal.oxm.XPathFragment;
@@ -45,23 +49,32 @@ import org.eclipse.persistence.internal.oxm.schema.model.Attribute;
import org.eclipse.persistence.internal.oxm.schema.model.Choice;
import org.eclipse.persistence.internal.oxm.schema.model.ComplexContent;
import org.eclipse.persistence.internal.oxm.schema.model.ComplexType;
-import org.eclipse.persistence.internal.oxm.schema.model.Element;
-import org.eclipse.persistence.internal.oxm.schema.model.Extension;
-import org.eclipse.persistence.internal.oxm.schema.model.Import;
-import org.eclipse.persistence.internal.oxm.schema.model.List;
-import org.eclipse.persistence.internal.oxm.schema.model.Occurs;
-import org.eclipse.persistence.internal.oxm.schema.model.Restriction;
-import org.eclipse.persistence.internal.oxm.schema.model.Schema;
+import org.eclipse.persistence.internal.oxm.schema.model.Element;
+import org.eclipse.persistence.internal.oxm.schema.model.Extension;
+import org.eclipse.persistence.internal.oxm.schema.model.Import;
+import org.eclipse.persistence.internal.oxm.schema.model.Occurs;
+import org.eclipse.persistence.internal.oxm.schema.model.Restriction;
+import org.eclipse.persistence.internal.oxm.schema.model.Schema;
import org.eclipse.persistence.internal.oxm.schema.model.Sequence;
import org.eclipse.persistence.internal.oxm.schema.model.SimpleComponent;
import org.eclipse.persistence.internal.oxm.schema.model.SimpleContent;
import org.eclipse.persistence.internal.oxm.schema.model.SimpleType;
-import org.eclipse.persistence.internal.oxm.schema.model.TypeDefParticle;
-import org.eclipse.persistence.internal.oxm.schema.model.TypeDefParticleOwner;
-import org.eclipse.persistence.internal.sessions.AbstractSession;
-import org.eclipse.persistence.jaxb.javamodel.Helper;
-import org.eclipse.persistence.jaxb.javamodel.JavaClass;
-import org.eclipse.persistence.jaxb.javamodel.JavaMethod;
+import org.eclipse.persistence.internal.oxm.schema.model.TypeDefParticle;
+import org.eclipse.persistence.internal.oxm.schema.model.TypeDefParticleOwner;
+import org.eclipse.persistence.internal.sessions.AbstractSession;
+import org.eclipse.persistence.jaxb.compiler.facets.DecimalMaxFacet;
+import org.eclipse.persistence.jaxb.compiler.facets.DecimalMinFacet;
+import org.eclipse.persistence.jaxb.compiler.facets.DigitsFacet;
+import org.eclipse.persistence.jaxb.compiler.facets.Facet;
+import org.eclipse.persistence.jaxb.compiler.facets.FacetVisitor;
+import org.eclipse.persistence.jaxb.compiler.facets.MaxFacet;
+import org.eclipse.persistence.jaxb.compiler.facets.MinFacet;
+import org.eclipse.persistence.jaxb.compiler.facets.PatternFacet;
+import org.eclipse.persistence.jaxb.compiler.facets.PatternListFacet;
+import org.eclipse.persistence.jaxb.compiler.facets.SizeFacet;
+import org.eclipse.persistence.jaxb.javamodel.Helper;
+import org.eclipse.persistence.jaxb.javamodel.JavaClass;
+import org.eclipse.persistence.jaxb.javamodel.JavaMethod;
import org.eclipse.persistence.jaxb.xmlmodel.XmlElementWrapper;
import org.eclipse.persistence.jaxb.xmlmodel.XmlVirtualAccessMethodsSchema;
import org.eclipse.persistence.jaxb.xmlmodel.XmlJoinNodes.XmlJoinNode;
@@ -69,13 +82,13 @@ import org.eclipse.persistence.jaxb.xmlmodel.XmlTransformation.XmlWriteTransform
import org.eclipse.persistence.oxm.NamespaceResolver;
import org.eclipse.persistence.oxm.XMLField;
import org.eclipse.persistence.sessions.Session;
-
-/**
- * INTERNAL:
- * <p><b>Purpose:</b>To generate Schema objects based on a map of TypeInfo objects, and some
- * additional information gathered by the AnnotationsProcessing phase.
- * <p><b>Responsibilities:</b><ul>
- * <li>Create and maintain a collection of Schema objects based on the provided TypeInfo objects</li>
+
+/**
+ * INTERNAL:
+ * <p><b>Purpose:</b>To generate Schema objects based on a map of TypeInfo objects, and some
+ * additional information gathered by the AnnotationsProcessing phase.
+ * <p><b>Responsibilities:</b><ul>
+ * <li>Create and maintain a collection of Schema objects based on the provided TypeInfo objects</li>
* <li>Add additional global elements to the schema based on an optional map (for WS integration)</li>
* <li>Should create a schema for each namespace encountered during generation.</li>
* </ul>
@@ -86,25 +99,24 @@ import org.eclipse.persistence.sessions.Session;
* @see org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor
* @see org.eclipse.persistence.jaxb.compiler.Generator
* @since Oracle TopLink 11.1.1.0.0
- * @author mmacivor
- */
-public class SchemaGenerator {
- private HashMap<String, Schema> schemaForNamespace;
- private java.util.List<Schema> allSchemas;
- private Schema schema;
- private int schemaCount;
- private Helper helper;
- private HashMap<String, TypeInfo> typeInfo;
- private HashMap<String, PackageInfo> packageToPackageInfoMappings;
- private HashMap<String, SchemaTypeInfo> schemaTypeInfo;
- private HashMap<String, QName> userDefinedSchemaTypes;
- private Map<String, Class> arrayClassesToGeneratedClasses;
-
- private static final String JAVAX_ACTIVATION_DATAHANDLER = "javax.activation.DataHandler";
- private static final String JAVAX_MAIL_INTERNET_MIMEMULTIPART = "javax.mail.internet.MimeMultipart";
- private static final String SWA_REF_IMPORT = "http://ws-i.org/profiles/basic/1.1/swaref.xsd";
- private static final String BUILD_FIELD_VALUE_METHOD = "buildFieldValue";
-
+ * @author mmacivor
+ */
+public class SchemaGenerator {
+ private Map<String, Schema> schemaForNamespace;
+ private List<Schema> allSchemas;
+ private int schemaCount;
+ private Helper helper;
+ private Map<String, TypeInfo> typeInfo;
+ private Map<String, PackageInfo> packageToPackageInfoMappings;
+ private Map<String, SchemaTypeInfo> schemaTypeInfo;
+ private Map<String, QName> userDefinedSchemaTypes;
+ private Map<String, Class> arrayClassesToGeneratedClasses;
+
+ private static final String JAVAX_ACTIVATION_DATAHANDLER = "javax.activation.DataHandler";
+ private static final String JAVAX_MAIL_INTERNET_MIMEMULTIPART = "javax.mail.internet.MimeMultipart";
+ private static final String SWA_REF_IMPORT = "http://ws-i.org/profiles/basic/1.1/swaref.xsd";
+ private static final String BUILD_FIELD_VALUE_METHOD = "buildFieldValue";
+
private static final String COLON = ":";
private static final String ATT = "@";
private static final String EMPTY_STRING = "";
@@ -119,23 +131,25 @@ public class SchemaGenerator {
private static final String IDREF = "IDREF";
private static final Character DOT_CHAR = '.';
private static final Character SLASH = '/';
- private static final Character SLASHES = '\\';
-
- private SchemaOutputResolver outputResolver;
-
- public SchemaGenerator(Helper helper) {
- this.helper = helper;
- }
-
- public Schema generateSchema(ArrayList<JavaClass> typeInfoClasses, HashMap<String, TypeInfo> typeInfo, HashMap<String, QName> userDefinedSchemaTypes, HashMap<String, PackageInfo> packageToPackageInfoMappings, HashMap<QName, ElementDeclaration> additionalGlobalElements, Map<String, Class> arrayClassesToGeneratedClasses, SchemaOutputResolver outputResolver) {
- this.outputResolver = outputResolver;
- return generateSchema(typeInfoClasses, typeInfo, userDefinedSchemaTypes, packageToPackageInfoMappings, additionalGlobalElements, arrayClassesToGeneratedClasses);
- }
-
- public Schema generateSchema(ArrayList<JavaClass> typeInfoClasses, HashMap<String, TypeInfo> typeInfo, HashMap<String, QName> userDefinedSchemaTypes, HashMap<String, PackageInfo> packageToPackageInfoMappings, HashMap<QName, ElementDeclaration> additionalGlobalElements, Map<String, Class> arrayClassesToGeneratedClasses) {
- this.typeInfo = typeInfo;
- this.userDefinedSchemaTypes = userDefinedSchemaTypes;
- this.packageToPackageInfoMappings = packageToPackageInfoMappings;
+ private static final Character SLASHES = '\\';
+
+ private SchemaOutputResolver outputResolver;
+ private boolean facets;
+
+ public SchemaGenerator(Helper helper) {
+ this.helper = helper;
+ this.facets = helper.isFacets();
+ }
+
+ public void generateSchema(List<JavaClass> typeInfoClasses, Map<String, TypeInfo> typeInfo, Map<String, QName> userDefinedSchemaTypes, Map<String, PackageInfo> packageToPackageInfoMappings, Map<QName, ElementDeclaration> additionalGlobalElements, Map<String, Class> arrayClassesToGeneratedClasses, SchemaOutputResolver outputResolver) {
+ this.outputResolver = outputResolver;
+ generateSchema(typeInfoClasses, typeInfo, userDefinedSchemaTypes, packageToPackageInfoMappings, additionalGlobalElements, arrayClassesToGeneratedClasses);
+ }
+
+ public void generateSchema(List<JavaClass> typeInfoClasses, Map<String, TypeInfo> typeInfo, Map<String, QName> userDefinedSchemaTypes, Map<String, PackageInfo> packageToPackageInfoMappings, Map<QName, ElementDeclaration> additionalGlobalElements, Map<String, Class> arrayClassesToGeneratedClasses) {
+ this.typeInfo = typeInfo;
+ this.userDefinedSchemaTypes = userDefinedSchemaTypes;
+ this.packageToPackageInfoMappings = packageToPackageInfoMappings;
this.schemaCount = 1;
this.schemaTypeInfo = new HashMap<String, SchemaTypeInfo>(typeInfo.size());
this.arrayClassesToGeneratedClasses = arrayClassesToGeneratedClasses;
@@ -144,20 +158,19 @@ public class SchemaGenerator {
addSchemaComponents(javaClass);
}
populateSchemaTypes();
- if (additionalGlobalElements != null) {
- addGlobalElements(additionalGlobalElements);
- }
- return schema;
- }
-
- public void addSchemaComponents(JavaClass myClass) {
- // first check for type
- String myClassName = myClass.getQualifiedName();
- Element rootElement = null;
- TypeInfo info = (TypeInfo) typeInfo.get(myClassName);
- if (info.isTransient() || info.getClassNamespace().equals(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI)) {
- return;
- }
+ if (additionalGlobalElements != null) {
+ addGlobalElements(additionalGlobalElements);
+ }
+ }
+
+ public void addSchemaComponents(JavaClass myClass) {
+ // first check for type
+ String myClassName = myClass.getQualifiedName();
+ Element rootElement = null;
+ TypeInfo info = typeInfo.get(myClassName);
+ if (info.isTransient() || info.getClassNamespace().equals(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI)) {
+ return;
+ }
SchemaTypeInfo schemaTypeInfo = new SchemaTypeInfo();
schemaTypeInfo.setSchemaTypeName(new QName(info.getClassNamespace(), info.getSchemaTypeName()));
this.schemaTypeInfo.put(myClass.getQualifiedName(), schemaTypeInfo);
@@ -175,17 +188,17 @@ public class SchemaGenerator {
if (info.isSetXmlRootElement()) {
//Create the root element and add it to the schema
org.eclipse.persistence.jaxb.xmlmodel.XmlRootElement xmlRE = info.getXmlRootElement();
- rootElement = new Element();
- String elementName = xmlRE.getName();
- if (elementName.equals(XMLProcessor.DEFAULT) || elementName.equals(EMPTY_STRING)) {
- try{
- elementName = info.getXmlNameTransformer().transformRootElementName(myClassName);
- }catch (Exception ex){
- throw org.eclipse.persistence.exceptions.JAXBException.exceptionDuringNameTransformation(myClassName, info.getXmlNameTransformer().getClass().getName(), ex);
- }
- }
- rootElement.setName(elementName);
- String rootNamespace = xmlRE.getNamespace();
+ rootElement = new Element();
+ String elementName = xmlRE.getName();
+ if (elementName.equals(XMLProcessor.DEFAULT) || elementName.equals(EMPTY_STRING)) {
+ try{
+ elementName = info.getXmlNameTransformer().transformRootElementName(myClassName);
+ }catch (Exception ex){
+ throw org.eclipse.persistence.exceptions.JAXBException.exceptionDuringNameTransformation(myClassName, info.getXmlNameTransformer().getClass().getName(), ex);
+ }
+ }
+ rootElement.setName(elementName);
+ String rootNamespace = xmlRE.getNamespace();
if (rootNamespace.equals(XMLProcessor.DEFAULT)) {
Schema rootElementSchema = getSchemaForNamespace(namespaceInfo.getNamespace());
if (rootElementSchema != null) {
@@ -198,66 +211,66 @@ public class SchemaGenerator {
if (rootElementSchema != null) {
rootElementSchema.addTopLevelElement(rootElement);
}
- schemaTypeInfo.getGlobalElementDeclarations().add(new QName(rootNamespace, elementName));
- }
-
- // handle root-level imports/includes [schema = the type's schema]
- Schema rootSchema = getSchemaForNamespace(rootNamespace);
- addImportIfRequired(rootSchema, schema, schema.getTargetNamespace());
-
+ schemaTypeInfo.getGlobalElementDeclarations().add(new QName(rootNamespace, elementName));
+ }
+
+ // handle root-level imports/includes [schema = the type's schema]
+ Schema rootSchema = getSchemaForNamespace(rootNamespace);
+ addImportIfRequired(rootSchema, schema, schema.getTargetNamespace());
+
// setup a prefix, if necessary
if (rootSchema != null && !info.getClassNamespace().equals(EMPTY_STRING)) {
pfx = getOrGeneratePrefixForNamespace(info.getClassNamespace(), rootSchema);
pfx += COLON;
- }
- }
-
-
-
- if (CompilerHelper.isSimpleType(info)){
-
- SimpleType type = new SimpleType();
- //simple type case, we just need the name and namespace info
- if (typeName.equals(EMPTY_STRING)) {
+ }
+ }
+
+
+
+ if (CompilerHelper.isSimpleType(info)){
+
+ SimpleType type = new SimpleType();
+ //simple type case, we just need the name and namespace info
+ if (typeName.equals(EMPTY_STRING)) {
//In this case, it should be a type under
//A root elem or locally defined whenever used
- if (rootElement != null) {
- rootElement.setSimpleType(type);
- }
- } else {
- type.setName(typeName);
- schema.addTopLevelSimpleTypes(type);
- if (rootElement != null) {
+ if (rootElement != null) {
+ rootElement.setSimpleType(type);
+ }
+ } else {
+ type.setName(typeName);
+ schema.addTopLevelSimpleTypes(type);
+ if (rootElement != null) {
rootElement.setType(pfx + type.getName());
}
}
//Figure out schema type and set it as Restriction
QName restrictionType = null;
Restriction restriction = new Restriction();
- if (info.isEnumerationType()) {
- restrictionType = ((EnumTypeInfo) info).getRestrictionBase();
- restriction.setEnumerationFacets(this.getEnumerationFacetsFor((EnumTypeInfo) info));
-
- String prefix = null;
- if (restrictionType.getNamespaceURI() != null && !restrictionType.getNamespaceURI().equals(EMPTY_STRING)) {
- if (restrictionType.getNamespaceURI().equals(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI)) {
- prefix = Constants.SCHEMA_PREFIX;
- } else {
- prefix = getPrefixForNamespace(schema, restrictionType.getNamespaceURI());
+ if (info.isEnumerationType()) {
+ restrictionType = ((EnumTypeInfo) info).getRestrictionBase();
+ restriction.setEnumerationFacets(this.getEnumerationFacetsFor((EnumTypeInfo) info));
+
+ String prefix = null;
+ if (restrictionType.getNamespaceURI() != null && !EMPTY_STRING.equals(restrictionType.getNamespaceURI())) {
+ if (javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(restrictionType.getNamespaceURI())) {
+ prefix = Constants.SCHEMA_PREFIX;
+ } else {
+ prefix = getPrefixForNamespace(schema, restrictionType.getNamespaceURI());
}
}
- String extensionTypeName = restrictionType.getLocalPart();
- if (prefix != null) {
- extensionTypeName = prefix + COLON + extensionTypeName;
- }
- restriction.setBaseType(extensionTypeName);
-
- type.setRestriction(restriction);
- } else {
- valueField= info.getXmlValueProperty();
- JavaClass javaType = valueField.getActualType();
- QName baseType = getSchemaTypeFor(javaType);
- String prefix = null;
+ String extensionTypeName = restrictionType.getLocalPart();
+ if (prefix != null) {
+ extensionTypeName = prefix + COLON + extensionTypeName;
+ }
+ restriction.setBaseType(extensionTypeName);
+
+ type.setRestriction(restriction);
+ } else {
+ valueField= info.getXmlValueProperty();
+ JavaClass javaType = valueField.getActualType();
+ QName baseType = getSchemaTypeFor(javaType);
+ String prefix = null;
if (baseType.getNamespaceURI() != null && !baseType.getNamespaceURI().equals(EMPTY_STRING)) {
if (baseType.getNamespaceURI().equals(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI)) {
prefix = Constants.SCHEMA_PREFIX;
@@ -268,29 +281,29 @@ public class SchemaGenerator {
String baseTypeName = baseType.getLocalPart();
if (prefix != null) {
baseTypeName = prefix + COLON + baseTypeName;
- }
- if (valueField.isXmlList() || (valueField.getGenericType() != null)) {
- //generate a list instead of a restriction
- List list = new List();
- list.setItemType(baseTypeName);
- type.setList(list);
- } else {
- if (helper.isAnnotationPresent(valueField.getElement(), XmlSchemaType.class)) {
- XmlSchemaType schemaType = (XmlSchemaType) helper.getAnnotation(valueField.getElement(), XmlSchemaType.class);
- baseType = new QName(schemaType.namespace(), schemaType.name());
- }
- restriction.setBaseType(baseTypeName);
- type.setRestriction(restriction);
+ }
+ if (valueField.isXmlList() || (valueField.getGenericType() != null)) {
+ //generate a list instead of a restriction
+ org.eclipse.persistence.internal.oxm.schema.model.List list = new org.eclipse.persistence.internal.oxm.schema.model.List();
+ list.setItemType(baseTypeName);
+ type.setList(list);
+ } else {
+ if (helper.isAnnotationPresent(valueField.getElement(), XmlSchemaType.class)) {
+ XmlSchemaType schemaType = (XmlSchemaType) helper.getAnnotation(valueField.getElement(), XmlSchemaType.class);
+ baseType = new QName(schemaType.namespace(), schemaType.name()); // TODO: This assignment seems like a bug, probably this should be "baseTypeName" ?
+ }
+ restriction.setBaseType(baseTypeName);
+ type.setRestriction(restriction);
}
}
info.setSimpleType(type);
- } else if ((valueField = this.getXmlValueFieldForSimpleContent(info)) != null) {
- ComplexType type = new ComplexType();
- SimpleContent content = new SimpleContent();
- if (typeName.equals(EMPTY_STRING)) {
- if (rootElement != null) {
- rootElement.setComplexType(type);
- }
+ } else if ((valueField = this.getXmlValueFieldForSimpleContent(info)) != null) {
+ ComplexType type = new ComplexType();
+ SimpleContent content = new SimpleContent();
+ if (EMPTY_STRING.equals(typeName)) {
+ if (rootElement != null) {
+ rootElement.setComplexType(type);
+ }
info.setComplexType(type);
} else {
type.setName(typeName);
@@ -326,13 +339,13 @@ public class SchemaGenerator {
TypeDefParticle compositor = null;
if(type.getComplexContent() != null && type.getComplexContent().getExtension() != null) {
compositor = type.getComplexContent().getExtension().getTypeDefParticle();
- } else {
- compositor = type.getTypeDefParticle();
- }
- if (typeName.equals(EMPTY_STRING)) {
- if (rootElement != null) {
- rootElement.setComplexType(type);
- }
+ } else {
+ compositor = type.getTypeDefParticle();
+ }
+ if (EMPTY_STRING.equals(typeName)) {
+ if (rootElement != null) {
+ rootElement.setComplexType(type);
+ }
info.setComplexType(type);
info.setCompositor(compositor);
} else {
@@ -347,13 +360,13 @@ public class SchemaGenerator {
}
}
- private ComplexType createComplexTypeForClass(JavaClass myClass, TypeInfo info) {
-
- Schema schema = getSchemaForNamespace(info.getClassNamespace());
-
- ComplexType type = new ComplexType();
- JavaClass superClass = CompilerHelper.getNextMappedSuperClass(myClass, this.typeInfo, this.helper);
- // Handle abstract class
+ private ComplexType createComplexTypeForClass(JavaClass myClass, TypeInfo info) {
+
+ Schema schema = getSchemaForNamespace(info.getClassNamespace());
+
+ ComplexType type = new ComplexType();
+ JavaClass superClass = CompilerHelper.getNextMappedSuperClass(myClass, this.typeInfo, this.helper);
+ // Handle abstract class
if (myClass.isAbstract()) {
type.setAbstractValue(true);
}
@@ -367,36 +380,36 @@ public class SchemaGenerator {
String parentPrefix = getPrefixForNamespace(schema, parentTypeInfo.getClassNamespace());
if (parentPrefix != null) {
extension.setBaseType(parentPrefix + COLON + parentTypeInfo.getSchemaTypeName());
- } else {
- extension.setBaseType(parentTypeInfo.getSchemaTypeName());
- }
-
- if(CompilerHelper.isSimpleType(parentTypeInfo)){
- SimpleContent content = new SimpleContent();
- content.setExtension(extension);
- type.setSimpleContent(content);
- return type;
- }else{
- ComplexContent content = new ComplexContent();
- content.setExtension(extension);
- type.setComplexContent(content);
- }
-
- }
- }
-
- TypeDefParticle compositor = null;
- String[] propOrder = null;
- if (info.isSetPropOrder()) {
- propOrder = info.getPropOrder();
- }
-
- if (propOrder != null && propOrder.length == 0) {
- // Note that the spec requires an 'all' to be generated
- // in cases where propOrder == 0, however, the TCK
- // requires the extension case to use sequences
- if (info.hasElementRefs()) {
- // generate a sequence to satisfy TCK
+ } else {
+ extension.setBaseType(parentTypeInfo.getSchemaTypeName());
+ }
+
+ if(CompilerHelper.isSimpleType(parentTypeInfo)){
+ SimpleContent content = new SimpleContent();
+ content.setExtension(extension);
+ type.setSimpleContent(content);
+ return type;
+ }else{
+ ComplexContent content = new ComplexContent();
+ content.setExtension(extension);
+ type.setComplexContent(content);
+ }
+
+ }
+ }
+
+ TypeDefParticle compositor = null;
+ String[] propOrder = null;
+ if (info.isSetPropOrder()) {
+ propOrder = info.getPropOrder();
+ }
+
+ if (propOrder != null && propOrder.length == 0) {
+ // Note that the spec requires an 'all' to be generated
+ // in cases where propOrder == 0, however, the TCK
+ // requires the extension case to use sequences
+ if (info.hasElementRefs()) {
+ // generate a sequence to satisfy TCK
compositor = new Sequence();
if (extension != null) {
extension.setSequence((Sequence) compositor);
@@ -421,30 +434,30 @@ public class SchemaGenerator {
}
return type;
}
- public void addToSchemaType(TypeInfo ownerTypeInfo, java.util.List<Property> properties, TypeDefParticle compositor, ComplexType type, Schema workingSchema) {
- //If there are no properties we don't want a sequence/choice or all tag written out
- if (properties.size() == 0) {
- type.setAll(null);
- type.setSequence(null);
- type.setChoice(null);
- ownerTypeInfo.setCompositor(null);
- return;
- }
-
- boolean extAnyAdded = false;
+ public void addToSchemaType(TypeInfo ownerTypeInfo, java.util.List<Property> properties, TypeDefParticle compositor, ComplexType type, Schema workingSchema) {
+ //If there are no properties we don't want a sequence/choice or all tag written out
+ if (properties.size() == 0) {
+ type.setAll(null);
+ type.setSequence(null);
+ type.setChoice(null);
+ ownerTypeInfo.setCompositor(null);
+ return;
+ }
+
+ boolean extAnyAdded = false;
// generate schema components for each property
for (Property next : properties) {
if (next == null) { continue; }
Schema currentSchema = workingSchema;
- TypeDefParticle parentCompositor = compositor;
- boolean isChoice = (parentCompositor instanceof Choice);
- ComplexType parentType = type;
- // ignore transient and inverse reference/non-writeable properties
- if(!next.isTransient() && !(next.isInverseReference() && !next.isWriteableInverseReference())){
- // handle xml extensions
- if (next.isVirtual()) {
- boolean extSchemaAny = false;
+ TypeDefParticle parentCompositor = compositor;
+ boolean isChoice = (parentCompositor instanceof Choice);
+ ComplexType parentType = type;
+ // ignore transient and inverse reference/non-writeable properties
+ if(!next.isTransient() && !(next.isInverseReference() && !next.isWriteableInverseReference())){
+ // handle xml extensions
+ if (next.isVirtual()) {
+ boolean extSchemaAny = false;
if (ownerTypeInfo.getXmlVirtualAccessMethods().getSchema() != null) {
extSchemaAny = ownerTypeInfo.getXmlVirtualAccessMethods().getSchema().equals(XmlVirtualAccessMethodsSchema.ANY);
}
@@ -474,13 +487,13 @@ public class SchemaGenerator {
// deal with xml-path case
if (next.getXmlPath() != null) {
// create schema components based on the XmlPath
- AddToSchemaResult xpr = addXPathToSchema(next, parentCompositor, currentSchema, isChoice, type);
- // if the returned object or schema component is null there is nothing to do
- if (xpr == null || ((parentCompositor = xpr.particle) == null && xpr.simpleContentType == null)) {
- continue;
- }
- // now process the property as per usual, adding to the created schema component
- if(xpr.schema == null) {
+ AddToSchemaResult xpr = addXPathToSchema(next, parentCompositor, currentSchema, isChoice, type);
+ // if the returned object or schema component is null there is nothing to do
+ if (xpr == null || ((parentCompositor = xpr.particle) == null && xpr.simpleContentType == null)) {
+ continue;
+ }
+ // now process the property as per usual, adding to the created schema component
+ if(xpr.schema == null) {
//if there's no schema, this may be a ref to an attribute in an ungenerated schema
//no need to generate the attribute in the target schema
continue;
@@ -488,13 +501,13 @@ public class SchemaGenerator {
currentSchema = xpr.schema;
if(parentCompositor == null) {
parentType = xpr.simpleContentType;
- } else if (parentCompositor.getOwner() instanceof ComplexType) {
- parentType = ((ComplexType)parentCompositor.getOwner());
- }
- // deal with the XmlElementWrapper case
- } else if (!isChoice && !next.isMap() && next.isSetXmlElementWrapper()) {
- AddToSchemaResult asr = addXmlElementWrapperToSchema(next, currentSchema, compositor);
- // if returned object is null there is nothing to do
+ } else if (parentCompositor.getOwner() instanceof ComplexType) {
+ parentType = ((ComplexType)parentCompositor.getOwner());
+ }
+ // deal with the XmlElementWrapper case
+ } else if (!isChoice && !next.isMap() && next.isSetXmlElementWrapper()) {
+ AddToSchemaResult asr = addXmlElementWrapperToSchema(next, currentSchema, compositor);
+ // if returned object is null there is nothing to do
if (asr == null) {
continue;
}
@@ -506,35 +519,36 @@ public class SchemaGenerator {
if (next.isMixedContent()) {
parentType.setMixed(true);
}
- // handle attribute
- if (next.isAttribute() && !next.isAnyAttribute()) {
- addAttributeToSchema(buildAttribute(next, currentSchema), next.getSchemaName(), currentSchema, parentType);
- // handle any attribute
- } else if (next.isAnyAttribute()) {
- addAnyAttributeToSchema(parentType);
- // handle choice
- } else if (next.isChoice()) {
- addChoiceToSchema(next, ownerTypeInfo, parentType, parentCompositor, currentSchema);
- // handle reference
- } else if (next.isReference()) {
- addReferenceToSchema(next, currentSchema, parentCompositor);
- // handle any
- } else if (next.isAny() || next.getVariableAttributeName() !=null) {
- addAnyToSchema(next, parentCompositor);
- // add an element
- } else if (!(ownerTypeInfo.getXmlValueProperty() != null && ownerTypeInfo.getXmlValueProperty() == next)) {
- addElementToSchema(buildElement(next, parentCompositor instanceof All, currentSchema, ownerTypeInfo), next.getSchemaName().getNamespaceURI(), next.isPositional(), parentCompositor, currentSchema);
- }
- }
- }
- }
-
- /**
- * Return the schema type (as QName) based on a given JavaClass.
- *
- * @param javaClass
- * @return
- */
+ // handle attribute
+ if (next.isAttribute() && !next.isAnyAttribute()) {
+ addAttributeToSchema(buildAttribute(next, currentSchema), next.getSchemaName(), currentSchema, parentType);
+ // handle any attribute
+ } else if (next.isAnyAttribute()) {
+ addAnyAttributeToSchema(parentType);
+ // handle choice
+ } else if (next.isChoice()) {
+ addChoiceToSchema(next, ownerTypeInfo, parentType, parentCompositor, currentSchema);
+ // handle reference
+ } else if (next.isReference()) {
+ addReferenceToSchema(next, currentSchema, parentCompositor);
+ // handle any
+ } else if (next.isAny() || next.getVariableAttributeName() !=null) {
+ addAnyToSchema(next, parentCompositor);
+ // add an element
+ } else if (!(ownerTypeInfo.getXmlValueProperty() != null && ownerTypeInfo.getXmlValueProperty() == next)) {
+ Element element = buildElement(next, parentCompositor instanceof All, currentSchema, ownerTypeInfo);
+ addElementToSchema(element, next.getSchemaName().getNamespaceURI(), next.isPositional(), parentCompositor, currentSchema);
+ }
+ }
+ }
+ }
+
+ /**
+ * Return the schema type (as QName) based on a given JavaClass.
+ *
+ * @param javaClass
+ * @return
+ */
public QName getSchemaTypeFor(JavaClass javaClass) {
String className;
if (javaClass.isArray()) {
@@ -565,22 +579,20 @@ public class SchemaGenerator {
return Constants.ANY_SIMPLE_TYPE_QNAME;
}
return schemaType;
- }
-
- public void populateSchemaTypes() {
- Iterator<String> classNames = typeInfo.keySet().iterator();
- while (classNames.hasNext()) {
- String javaClassName = classNames.next();
- TypeInfo info = (TypeInfo) typeInfo.get(javaClassName);
- if (info.isComplexType()) {
- if (info.getSchema() != null) {
- java.util.List<Property> props = info.getNonTransientPropertiesInPropOrder();
- // handle class indicator field name
- if (info.isSetXmlDiscriminatorNode()) {
- String xpath = info.getXmlDiscriminatorNode();
- String pname = XMLProcessor.getNameFromXPath(xpath, EMPTY_STRING, true);
- if (!pname.equals(EMPTY_STRING)) {
- // since there is no property for the indicator field name, we'll need to make one
+ }
+
+ public void populateSchemaTypes() {
+ for (String javaClassName : typeInfo.keySet()) {
+ TypeInfo info = typeInfo.get(javaClassName);
+ if (info.isComplexType()) {
+ if (info.getSchema() != null) {
+ List<Property> props = info.getNonTransientPropertiesInPropOrder();
+ // handle class indicator field name
+ if (info.isSetXmlDiscriminatorNode()) {
+ String xpath = info.getXmlDiscriminatorNode();
+ String pname = XMLProcessor.getNameFromXPath(xpath, EMPTY_STRING, true);
+ if (!pname.equals(EMPTY_STRING)) {
+ // since there is no property for the indicator field name, we'll need to make one
Property prop = new Property(helper);
prop.setPropertyName(pname);
prop.setXmlPath(xpath);
@@ -588,13 +600,13 @@ public class SchemaGenerator {
prop.setType(helper.getJavaClass(String.class));
prop.setIsAttribute(true);
props.add(prop);
- }
- }
- addToSchemaType(info, props, info.getCompositor(), info.getComplexType(), info.getSchema());
- if(info.hasPredicateProperties()) {
- addToSchemaType(info, info.getPredicateProperties(), info.getCompositor(), info.getComplexType(), info.getSchema());
- }
- }
+ }
+ }
+ addToSchemaType(info, props, info.getCompositor(), info.getComplexType(), info.getSchema());
+ if (info.hasPredicateProperties()) {
+ addToSchemaType(info, info.getPredicateProperties(), info.getCompositor(), info.getComplexType(), info.getSchema());
+ }
+ }
}
}
}
@@ -627,27 +639,27 @@ public class SchemaGenerator {
}
return null;
}
-
- /**
- * Indicates if a given Property is a collection type.
- *
- * @param field
- * @return
- */
- public boolean isCollectionType(Property field) {
- JavaClass type = field.getType();
- return (helper.getJavaClass(java.util.Collection.class).isAssignableFrom(type)
- || helper.getJavaClass(java.util.List.class).isAssignableFrom(type)
- || helper.getJavaClass(java.util.Set.class).isAssignableFrom(type));
- }
-
- /**
- * Return the Schema for a given namespace. If no schema exists for the
- * given namespace, one will be created.
- *
- * @param namespace
- * @return
- */
+
+ /**
+ * Indicates if a given Property is a collection type.
+ *
+ * @param field
+ * @return
+ */
+ public boolean isCollectionType(Property field) {
+ JavaClass type = field.getType();
+ return (helper.getJavaClass(java.util.Collection.class).isAssignableFrom(type)
+ || helper.getJavaClass(java.util.List.class).isAssignableFrom(type)
+ || helper.getJavaClass(java.util.Set.class).isAssignableFrom(type));
+ }
+
+ /**
+ * Return the Schema for a given namespace. If no schema exists for the
+ * given namespace, one will be created.
+ *
+ * @param namespace
+ * @return
+ */
private Schema getSchemaForNamespace(String namespace) {
if (schemaForNamespace == null) {
schemaForNamespace = new HashMap<String, Schema>();
@@ -727,17 +739,17 @@ public class SchemaGenerator {
}
}
return null;
- }
-
- public String getPrefixForNamespace(Schema schema, String URI) {
- //add Import if necessary
- Schema referencedSchema = this.getSchemaForNamespace(URI);
- addImportIfRequired(schema, referencedSchema, URI);
-
- NamespaceResolver namespaceResolver = schema.getNamespaceResolver();
- Enumeration keys = namespaceResolver.getPrefixes();
- while (keys.hasMoreElements()) {
- String next = (String) keys.nextElement();
+ }
+
+ public String getPrefixForNamespace(Schema schema, String URI) {
+ //add Import if necessary
+ Schema referencedSchema = this.getSchemaForNamespace(URI);
+ addImportIfRequired(schema, referencedSchema, URI);
+
+ NamespaceResolver namespaceResolver = schema.getNamespaceResolver();
+ Enumeration keys = namespaceResolver.getPrefixes();
+ while (keys.hasMoreElements()) {
+ String next = (String) keys.nextElement();
String nextUri = namespaceResolver.resolveNamespacePrefix(next);
if (nextUri.equals(URI)) {
return next;
@@ -746,40 +758,40 @@ public class SchemaGenerator {
return null;
}
- /**
- * Attempt to resolve the given URI to a prefix. If this is unsuccessful, one
- * will be generated and added to the resolver.
- *
- * @param URI
- * @param schema
- * @return
+ /**
+ * Attempt to resolve the given URI to a prefix. If this is unsuccessful, one
+ * will be generated and added to the resolver.
+ *
+ * @param URI
+ * @param schema
+ * @return
*/
public String getOrGeneratePrefixForNamespace(String URI, Schema schema) {
String prefix = schema.getNamespaceResolver().resolveNamespaceURI(URI);
if (prefix == null) {
if (URI.equals(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI)) {
- prefix = schema.getNamespaceResolver().generatePrefix(Constants.SCHEMA_PREFIX);
- } else if (URI.equals(Constants.REF_URL)) {
- prefix = schema.getNamespaceResolver().generatePrefix(Constants.REF_PREFIX);
-
- if(!importExists(schema, SWA_REF_IMPORT)){
- Import schemaImport = new Import();
- schemaImport.setSchemaLocation(SWA_REF_IMPORT);
- schemaImport.setNamespace(URI);
- schema.getImports().add(schemaImport);
- }
- } else {
- prefix = schema.getNamespaceResolver().generatePrefix();
+ prefix = schema.getNamespaceResolver().generatePrefix(Constants.SCHEMA_PREFIX);
+ } else if (URI.equals(Constants.REF_URL)) {
+ prefix = schema.getNamespaceResolver().generatePrefix(Constants.REF_PREFIX);
+
+ if(!importExists(schema, SWA_REF_IMPORT)){
+ Import schemaImport = new Import();
+ schemaImport.setSchemaLocation(SWA_REF_IMPORT);
+ schemaImport.setNamespace(URI);
+ schema.getImports().add(schemaImport);
+ }
+ } else {
+ prefix = schema.getNamespaceResolver().generatePrefix();
}
schema.getNamespaceResolver().put(prefix, URI);
}
- return prefix;
- }
-
- public void addGlobalElements(HashMap<QName, ElementDeclaration> additionalElements) {
- for (Entry<QName, ElementDeclaration> entry : additionalElements.entrySet()) {
- QName next = entry.getKey();
- if(next != null) {
+ return prefix;
+ }
+
+ public void addGlobalElements(Map<QName, ElementDeclaration> additionalElements) {
+ for (Entry<QName, ElementDeclaration> entry : additionalElements.entrySet()) {
+ QName next = entry.getKey();
+ if(next != null) {
ElementDeclaration nextElement = entry.getValue();
if (nextElement.getScopeClass() == GLOBAL.class) {
@@ -851,13 +863,13 @@ public class SchemaGenerator {
Schema complexTypeSchema = getSchemaForNamespace(type.getClassNamespace());
String complexTypeSchemaNS = type.getClassNamespace();
if (complexTypeSchemaNS == null) {
- complexTypeSchemaNS = EMPTY_STRING;
- }
- addImportIfRequired(targetSchema, complexTypeSchema, type.getClassNamespace());
-
- String prefix = targetSchema.getNamespaceResolver().resolveNamespaceURI(complexTypeSchemaNS);
- if (prefix != null) {
- element.setType(prefix + COLON + typeName);
+ complexTypeSchemaNS = EMPTY_STRING;
+ }
+ addImportIfRequired(targetSchema, complexTypeSchema, type.getClassNamespace());
+
+ String prefix = targetSchema.getNamespaceResolver().resolveNamespaceURI(complexTypeSchemaNS);
+ if (prefix != null) {
+ element.setType(prefix + COLON + typeName);
} else {
element.setType(typeName);
}
@@ -888,18 +900,18 @@ public class SchemaGenerator {
}
}
}
- }
-
- /**
- * Return the Map of SchemaTypeInfo instances. The Map is keyed on JavaClass
- * qualified name.
- *
- * @return
- */
- public HashMap<String, SchemaTypeInfo> getSchemaTypeInfo() {
- return this.schemaTypeInfo;
- }
-
+ }
+
+ /**
+ * Return the Map of SchemaTypeInfo instances. The Map is keyed on JavaClass
+ * qualified name.
+ *
+ * @return
+ */
+ public Map<String, SchemaTypeInfo> getSchemaTypeInfo() {
+ return this.schemaTypeInfo;
+ }
+
private boolean importExists(Schema schema, String schemaName) {
java.util.List imports = schema.getImports();
for (int i = 0; i < imports.size(); i++) {
@@ -913,13 +925,13 @@ public class SchemaGenerator {
private boolean addImportIfRequired(Schema sourceSchema, Schema importSchema, String importNamespace) {
if (importSchema != sourceSchema && !(importNamespace != null && importNamespace.equals(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI))) {
- String schemaName = null;
- if(javax.xml.XMLConstants.XML_NS_URI.equals(importNamespace)){
- schemaName = Constants.XML_NAMESPACE_SCHEMA_LOCATION;
- }else{
- if (importSchema != null) {
- schemaName = importSchema.getName();
- } else if (importNamespace != null) {
+ String schemaName = null;
+ if(javax.xml.XMLConstants.XML_NS_URI.equals(importNamespace)){
+ schemaName = Constants.XML_NAMESPACE_SCHEMA_LOCATION;
+ }else{
+ if (importSchema != null) {
+ schemaName = importSchema.getName();
+ } else if (importNamespace != null) {
NamespaceInfo nInfo = getNamespaceInfoForNamespace(importNamespace);
schemaName = nInfo.getLocation();
}
@@ -942,13 +954,13 @@ public class SchemaGenerator {
relativizedURI = null;
}
if (relativizedURI != null) {
- schemaName = relativizedURI.getPath();
- }
- }
-
- if (schemaName != null && !importExists(sourceSchema, schemaName)) {
- Import schemaImport = new Import();
- schemaImport.setSchemaLocation(schemaName);
+ schemaName = relativizedURI.getPath();
+ }
+ }
+
+ if (schemaName != null && !importExists(sourceSchema, schemaName)) {
+ Import schemaImport = new Import();
+ schemaImport.setSchemaLocation(schemaName);
if (importNamespace != null && !importNamespace.equals(EMPTY_STRING)) {
schemaImport.setNamespace(importNamespace);
}
@@ -966,70 +978,70 @@ public class SchemaGenerator {
}
return true;
}
- }
- return false;
- }
-
- /**
- * Compares a JavaModel JavaClass to a Class. Equality is based on
- * the raw name of the JavaClass compared to the canonical
- * name of the Class.
- *
- * @param src
- * @param tgt
- * @return
- */
- protected boolean areEquals(JavaClass src, String tgtCanonicalName) {
+ }
+ return false;
+ }
+
+ /**
+ * Compares a JavaModel JavaClass to a Class. Equality is based on
+ * the raw name of the JavaClass compared to the canonical
+ * name of the Class.
+ *
+ * @param src
+ * @param tgtCanonicalName
+ * @return
+ */
+ protected boolean areEquals(JavaClass src, String tgtCanonicalName) {
if (src == null || tgtCanonicalName == null) {
- return false;
- }
- return src.getRawName().equals(tgtCanonicalName);
- }
-
- /**
- * Compares a JavaModel JavaClass to a Class. Equality is based on
- * the raw name of the JavaClass compared to the canonical
- * name of the Class.
- *
- * @param src
- * @param tgt
- * @return
+ return false;
+ }
+ return src.getRawName().equals(tgtCanonicalName);
+ }
+
+ /**
+ * Compares a JavaModel JavaClass to a Class. Equality is based on
+ * the raw name of the JavaClass compared to the canonical
+ * name of the Class.
+ *
+ * @param src
+ * @param tgt
+ * @return
*/
protected boolean areEquals(JavaClass src, Class tgt) {
if (src == null || tgt == null) {
- return false;
- }
- return src.getRawName().equals(tgt.getCanonicalName());
- }
-
- /**
- * Return the type name for a given Property.
- *
- * @param next
- * @param javaType
- * @param theSchema
- * @return
- */
- private String getTypeName(Property next, JavaClass javaType, Schema theSchema){
- QName schemaType = next.getSchemaType();
- if (schemaType == null) {
- schemaType = getSchemaTypeFor(javaType);
+ return false;
+ }
+ return src.getRawName().equals(tgt.getCanonicalName());
+ }
+
+ /**
+ * Return the type name for a given Property.
+ *
+ * @param next
+ * @param javaType
+ * @param theSchema
+ * @return
+ */
+ private String getTypeName(Property next, JavaClass javaType, Schema theSchema){
+ QName schemaType = next.getSchemaType();
+ if (schemaType == null) {
+ schemaType = getSchemaTypeFor(javaType);
}
if (schemaType != null) {
if (schemaType.getNamespaceURI() == null) {
return schemaType.getLocalPart();
}
return getOrGeneratePrefixForNamespace(schemaType.getNamespaceURI(), theSchema) + COLON + schemaType.getLocalPart();
- }
- return Constants.SCHEMA_PREFIX + Constants.COLON + Constants.ANY_SIMPLE_TYPE;
- }
-
- /**
- * Return the qualified (if necessary) type name for a given Property.
- *
- * @param prop
- * @param schema
- * @return
+ }
+ return Constants.SCHEMA_PREFIX + Constants.COLON + Constants.ANY_SIMPLE_TYPE;
+ }
+
+ /**
+ * Return the qualified (if necessary) type name for a given Property.
+ *
+ * @param prop
+ * @param schema
+ * @return
*/
private String getQualifiedTypeName(Property prop, Schema schema) {
JavaClass javaType = prop.getActualType();
@@ -1042,52 +1054,52 @@ public class SchemaGenerator {
}
}
return typeName;
- }
-
- /**
- * This method will build element/complexType/typedefparticle components for a given xml-path,
- * and return an XmlPathResult instance containg the sequence that the target should be added
- * to, as well as the current schema - which could be different than the working schema used
- * before calling this method in the case of a prefixed path element from a different namespace.
- * Regarding the path 'target', if the xml-path was "contact-info/address/street", "street"
- * would be the target. In this case the sequence containing the "address" element would be
- * set in the XmlPathResult to be returned.
- *
- * The exception case is an 'any', where we want to process the last path element before
- * returning - this is necessary due to the fact that an Any will be added to the sequence
- * in place of the last path element by the calling method.
- *
- * @param frag
- * @param xpr
- * @param isAny
- * @param isChoice
- * @return
- */
- protected AddToSchemaResult buildSchemaComponentsForXPath(XPathFragment frag, AddToSchemaResult xpr, boolean isChoice, Property next) {
- boolean isAny = next.isAny() || next.isAnyAttribute();
- TypeDefParticle currentParticle = xpr.particle;
- Schema workingSchema = xpr.schema;
-
- // each nested choice on a collection will be unbounded
- boolean isUnbounded = false;
- if(currentParticle != null) {
- isUnbounded = (currentParticle.getMaxOccurs() != null && currentParticle.getMaxOccurs()==Occurs.UNBOUNDED);
- }
-
- // don't process the last frag; that will be handled by the calling method if necessary
- // note that we may need to process the last frag if it has a namespace or is an 'any'
- boolean lastFrag = (frag.getNextFragment() == null || frag.getNextFragment().nameIsText());
+ }
+
+ /**
+ * This method will build element/complexType/typedefparticle components for a given xml-path,
+ * and return an XmlPathResult instance containg the sequence that the target should be added
+ * to, as well as the current schema - which could be different than the working schema used
+ * before calling this method in the case of a prefixed path element from a different namespace.
+ * Regarding the path 'target', if the xml-path was "contact-info/address/street", "street"
+ * would be the target. In this case the sequence containing the "address" element would be
+ * set in the XmlPathResult to be returned.
+ *
+ * The exception case is an 'any', where we want to process the last path element before
+ * returning - this is necessary due to the fact that an Any will be added to the sequence
+ * in place of the last path element by the calling method.
+ *
+ * @param frag
+ * @param xpr
+ * @param isChoice
+ * @param next
+ * @return
+ */
+ protected AddToSchemaResult buildSchemaComponentsForXPath(XPathFragment frag, AddToSchemaResult xpr, boolean isChoice, Property next) {
+ boolean isAny = next.isAny() || next.isAnyAttribute();
+ TypeDefParticle currentParticle = xpr.particle;
+ Schema workingSchema = xpr.schema;
+
+ // each nested choice on a collection will be unbounded
+ boolean isUnbounded = false;
+ if(currentParticle != null) {
+ isUnbounded = (currentParticle.getMaxOccurs() != null && currentParticle.getMaxOccurs()==Occurs.UNBOUNDED);
+ }
+
+ // don't process the last frag; that will be handled by the calling method if necessary
+ // note that we may need to process the last frag if it has a namespace or is an 'any'
+ boolean lastFrag = (frag.getNextFragment() == null || frag.getNextFragment().nameIsText());
//boolean isNextAttribute = (frag.getNextFragment() != null) && (frag.getNextFragment().isAttribute());
// if the element is already in the sequence we don't want the calling method to add a second one
if (lastFrag && (elementExistsInParticle(frag.getLocalName(), frag.getShortName(), currentParticle) != null)) {
xpr.particle = null;
- return xpr;
- }
-
-
- // if the current element exists, use it; otherwise create a new one
- Element currentElement = elementExistsInParticle(frag.getLocalName(), frag.getShortName(), currentParticle);
- boolean currentElementExists = (currentElement != null);
+ return xpr;
+ }
+
+
+ // if the current element exists, use it; otherwise create a new one
+ Element currentElement = elementExistsInParticle(frag.getLocalName(), frag.getShortName(), currentParticle);
+ boolean currentElementExists = (currentElement != null);
if (!currentElementExists) {
currentElement = new Element();
@@ -1110,14 +1122,14 @@ public class SchemaGenerator {
currentElement.setComplexType(cType);
} else {
//if the current element already exists, we may need to change it's type
- XPathFragment nextFrag = frag.getNextFragment();
- if(nextFrag != null && nextFrag.isAttribute()) {
- if(currentElement.getType() != null && currentElement.getComplexType() == null) {
- //there's already a text mapping to this element, so
- //attributes can be added by making it complex with
- //simple content.
- SimpleType type = currentElement.getSimpleType();
- if(type != null) {
+ XPathFragment nextFrag = frag.getNextFragment();
+ if(nextFrag != null && nextFrag.isAttribute()) {
+ if(currentElement.getType() != null && currentElement.getComplexType() == null) {
+ //there's already a text mapping to this element, so
+ //attributes can be added by making it complex with
+ //simple content.
+ SimpleType type = currentElement.getSimpleType();
+ if(type != null) {
ComplexType cType = new ComplexType();
cType.setSimpleContent(new SimpleContent());
Extension extension = new Extension();
@@ -1132,24 +1144,24 @@ public class SchemaGenerator {
Extension extension = new Extension();
extension.setBaseType(eType);
sContent.setExtension(extension);
- cType.setSimpleContent(sContent);
- currentElement.setType(null);
- currentElement.setComplexType(cType);
- }
- }
- }
- }
+ cType.setSimpleContent(sContent);
+ currentElement.setType(null);
+ currentElement.setComplexType(cType);
+ }
+ }
+ }
+ }
// may need to create a ref, depending on the namespace
Element globalElement = null;
String fragUri = frag.getNamespaceURI();
- if (fragUri != null) {
- Schema fragSchema = getSchemaForNamespace(fragUri);
- String targetNS = workingSchema.getTargetNamespace();
-
- // handle Attribute case
- if (frag.isAttribute()) {
- if (fragSchema == null || (fragSchema.isAttributeFormDefault() && !fragUri.equals(targetNS)) || (!fragSchema.isAttributeFormDefault() && fragUri.length() > 0)) {
+ if (fragUri != null) {
+ Schema fragSchema = getSchemaForNamespace(fragUri);
+ String targetNS = workingSchema.getTargetNamespace();
+
+ // handle Attribute case
+ if (frag.isAttribute()) {
+ if (fragSchema == null || (fragSchema.isAttributeFormDefault() && !fragUri.equals(targetNS)) || (!fragSchema.isAttributeFormDefault() && fragUri.length() > 0)) {
// must generate a global attribute and create a reference to it
// if the global attribute exists, use it; otherwise create a new one
// if fragSchema is null, just generate the ref
@@ -1185,20 +1197,20 @@ public class SchemaGenerator {
// ref case - indicate to the calling method that there's nothing to do
xpr.particle = null;
}
- // since we are dealing with an attribute, we are on the last fragment; return
- return xpr;
- }
-
- // here we are dealing with an Element
- if ((fragSchema.isElementFormDefault() && !fragUri.equals(targetNS)) || (!fragSchema.isElementFormDefault() && fragUri.length() > 0)) {
- // must generate a global element and create a reference to it
- // if the global element exists, use it; otherwise create a new one
- globalElement = (Element) fragSchema.getTopLevelElements().get(frag.getLocalName());
- if (globalElement == null) {
- globalElement = createGlobalElement(frag, workingSchema, fragSchema, isChoice, isUnbounded, next, (lastFrag && !isAny));
- }
- // if the current element doesn't exist set a ref and add it to the sequence
- if (!currentElementExists) {
+ // since we are dealing with an attribute, we are on the last fragment; return
+ return xpr;
+ }
+
+ // here we are dealing with an Element
+ if ((fragSchema.isElementFormDefault() && !fragUri.equals(targetNS)) || (!fragSchema.isElementFormDefault() && fragUri.length() > 0)) {
+ // must generate a global element and create a reference to it
+ // if the global element exists, use it; otherwise create a new one
+ globalElement = (Element) fragSchema.getTopLevelElements().get(frag.getLocalName());
+ if (globalElement == null) {
+ globalElement = createGlobalElement(frag, workingSchema, fragSchema, isChoice, isUnbounded, next, (lastFrag && !isAny));
+ }
+ // if the current element doesn't exist set a ref and add it to the sequence
+ if (!currentElementExists) {
// use prefix from the working schema's resolver - add prefix/uri pair if necessary
String fragPrefix = workingSchema.getNamespaceResolver().resolveNamespaceURI(fragUri);
if (fragPrefix == null) {
@@ -1223,21 +1235,23 @@ public class SchemaGenerator {
return xpr;
}
// ref case - indicate to the calling method that there's nothing to do
- xpr.particle = null;
- return xpr;
- }
- // make the global element current
- currentElement = globalElement;
- }
- }
- if (!lastFrag || (lastFrag && isAny)) {
- // if we didn't process a global element, and the current element isn't already in the sequence, add it
- if (!currentElementExists && globalElement == null) {
- currentElement.setName(frag.getLocalName());
- currentElement.setMinOccurs(Occurs.ZERO);
- currentParticle.addElement(currentElement);
- }
- // set the correct particle to use/return
+ xpr.particle = null;
+ return xpr;
+ }
+ // make the global element current
+ currentElement = globalElement;
+ }
+ }
+ if (!lastFrag || (lastFrag && isAny)) {
+ // if we didn't process a global element, and the current element isn't already in the sequence, add it
+ if (!currentElementExists && globalElement == null) {
+ currentElement.setName(frag.getLocalName());
+ Integer minOccurs = next.getMinOccurs();
+ if (minOccurs != null) currentElement.setMinOccurs(String.valueOf(minOccurs));
+ else currentElement.setMinOccurs(Occurs.ZERO);
+ currentParticle.addElement(currentElement);
+ }
+ // set the correct particle to use/return
if(currentElement.getComplexType() != null) {
if(currentElement.getComplexType().getTypeDefParticle() == null) {
//complexType with simple-content
@@ -1280,28 +1294,28 @@ public class SchemaGenerator {
if (lastFrag) {
return xpr;
}
- // call back into this method to process the next path element
- return buildSchemaComponentsForXPath(frag.getNextFragment(), xpr, isChoice, next);
- }
-
- /**
- * Convenience method for determining if an element already exists in a given
- * typedefparticle. If an element exists whose ref is equal to 'refString'
- * or its name is equal to 'elementName', it is returned. Null otherwise.
- *
- * Note that ref takes precidence, so if either has a ref set name equality
- * will not be performed.
- *
- * @param elementName the non-null element name to look for
- * @param refString if the element is a ref, this will be the prefix qualified element name
- * @param particle the sequence/choice/all to search for an existing element
- * @return
- */
- protected Element elementExistsInParticle(String elementName, String refString, TypeDefParticle particle) {
- if (particle == null || particle.getElements() == null || particle.getElements().size() == 0) {
- return null;
- }
- java.util.List existingElements = particle.getElements();
+ // call back into this method to process the next path element
+ return buildSchemaComponentsForXPath(frag.getNextFragment(), xpr, isChoice, next);
+ }
+
+ /**
+ * Convenience method for determining if an element already exists in a given
+ * typedefparticle. If an element exists whose ref is equal to 'refString'
+ * or its name is equal to 'elementName', it is returned. Null otherwise.
+ *
+ * Note that ref takes precidence, so if either has a ref set name equality
+ * will not be performed.
+ *
+ * @param elementName the non-null element name to look for
+ * @param refString if the element is a ref, this will be the prefix qualified element name
+ * @param particle the sequence/choice/all to search for an existing element
+ * @return
+ */
+ protected Element elementExistsInParticle(String elementName, String refString, TypeDefParticle particle) {
+ if (particle == null || particle.getElements() == null || particle.getElements().size() == 0) {
+ return null;
+ }
+ java.util.List existingElements = particle.getElements();
if (existingElements != null) {
Iterator elementIt = existingElements.iterator();
while (elementIt.hasNext()) {
@@ -1332,22 +1346,22 @@ public class SchemaGenerator {
return element;
}
}
- }
- return null;
- }
-
- /**
- * Create a global attribute. An import is added if necessary. This method
- * will typically be called when processing an XPath and a prefixed path
- * element is encountered tha requires an attribute ref.
- *
- * @param frag
- * @param workingSchema
- * @param fragSchema
- * @param next
- * @return
- */
- public Attribute createGlobalAttribute(XPathFragment frag, Schema workingSchema, Schema fragSchema, Property prop) {
+ }
+ return null;
+ }
+
+ /**
+ * Create a global attribute. An import is added if necessary. This method
+ * will typically be called when processing an XPath and a prefixed path
+ * element is encountered tha requires an attribute ref.
+ *
+ * @param frag
+ * @param workingSchema
+ * @param fragSchema
+ * @param prop
+ * @return
+ */
+ public Attribute createGlobalAttribute(XPathFragment frag, Schema workingSchema, Schema fragSchema, Property prop) {
Attribute gAttribute = new Attribute();
gAttribute.setName(frag.getLocalName());
gAttribute.setType(getQualifiedTypeName(prop, fragSchema));
@@ -1357,19 +1371,19 @@ public class SchemaGenerator {
}
/**
- * Create a global element. An import is added if necessary. This method
- * will typically be called when processing an XPath and a prefixed path
- * element is encountered the requires an element ref.
- *
- * @param frag XPathFragment which wil lbe used to create the global element
- * @param workingSchema current schema
- * @param fragSchema frag's schema
- * @param isChoice indicates if we need to construct a choice
- * @param isUnbounded maxOccurs setting for choice
- * @param next property which owns the xml-path
- * @param shouldSetType if this is the last fragment in the xml-path and not an 'any', we should set the type
- * @return
- */
+ * Create a global element. An import is added if necessary. This method
+ * will typically be called when processing an XPath and a prefixed path
+ * element is encountered the requires an element ref.
+ *
+ * @param frag XPathFragment which wil lbe used to create the global element
+ * @param workingSchema current schema
+ * @param fragSchema frag's schema
+ * @param isChoice indicates if we need to construct a choice
+ * @param isUnbounded maxOccurs setting for choice
+ * @param prop property which owns the xml-path
+ * @param shouldSetType if this is the last fragment in the xml-path and not an 'any', we should set the type
+ * @return
+ */
public Element createGlobalElement(XPathFragment frag, Schema workingSchema, Schema fragSchema, boolean isChoice, boolean isUnbounded, Property prop, boolean shouldSetType) {
Element gElement = new Element();
gElement.setName(frag.getLocalName());
@@ -1392,37 +1406,37 @@ public class SchemaGenerator {
fragSchema.addTopLevelElement(gElement);
addImportIfRequired(workingSchema, fragSchema, frag.getNamespaceURI());
return gElement;
- }
-
- /**
- * Create an element reference and add it to a given particle. This
- * method will typically be called when processing an XPath and a
- * prefixed path element is encountered that requires an element ref.
- *
- * @param elementRefName
- * @param particle
- * @return
- */
- public Element createRefElement(String elementRefName, TypeDefParticle particle) {
- Element refElement = new Element();
- // ref won't have a complex type
- refElement.setComplexType(null);
- refElement.setMinOccurs(Occurs.ZERO);
- refElement.setMaxOccurs(Occurs.ONE);
+ }
+
+ /**
+ * Create an element reference and add it to a given particle. This
+ * method will typically be called when processing an XPath and a
+ * prefixed path element is encountered that requires an element ref.
+ *
+ * @param elementRefName
+ * @param particle
+ * @return
+ */
+ public Element createRefElement(String elementRefName, TypeDefParticle particle) {
+ Element refElement = new Element();
+ // ref won't have a complex type
+ refElement.setComplexType(null);
+ refElement.setMinOccurs(Occurs.ZERO);
+ refElement.setMaxOccurs(Occurs.ONE);
refElement.setRef(elementRefName);
particle.addElement(refElement);
return refElement;
}
-
- /**
- * Create an attribute reference and add it to a given complex type.
- * This method will typically be called when processing an XPath
- * and a prefixed path element is encountered that requires an
- * attribute ref.
- *
- * @param attributeRefName
- * @param owningComplexType
- * @return
+
+ /**
+ * Create an attribute reference and add it to a given complex type.
+ * This method will typically be called when processing an XPath
+ * and a prefixed path element is encountered that requires an
+ * attribute ref.
+ *
+ * @param attributeRefName
+ * @param owningComplexType
+ * @return
*/
public Attribute createRefAttribute(String attributeRefName, ComplexType owningComplexType) {
Attribute refAttribute = new Attribute();
@@ -1431,14 +1445,13 @@ public class SchemaGenerator {
owningComplexType.getSimpleContent().getExtension().getOrderedAttributes().add(refAttribute);
} else {
owningComplexType.getOrderedAttributes().add(refAttribute);
- }
- return refAttribute;
- }
-
- // Made static final for performance reasons.
- /**
- * This class will typically be used when building schema components. It will hold the
- * TypeDefParticle (all, sequence, choice), ComplexType, and/or Schema that are to be
+ }
+ return refAttribute;
+ }
+
+ /**
+ * This class will typically be used when building schema components. It will hold the
+ * TypeDefParticle (all, sequence, choice), ComplexType, and/or Schema that are to be
* used by the method that is processing the given property.
*
*/
@@ -1446,9 +1459,9 @@ public class SchemaGenerator {
ComplexType type;
TypeDefParticle particle;
Schema schema;
- ComplexType simpleContentType;
-
- AddToSchemaResult(TypeDefParticle particle, Schema schema) {
+ ComplexType simpleContentType;
+
+ AddToSchemaResult(TypeDefParticle particle, Schema schema) {
this.particle = particle;
this.schema = schema;
}
@@ -1459,13 +1472,13 @@ public class SchemaGenerator {
}
}
- /**
- * Convenience method for processing XmlWriteTransformer(s) for a given property.
- * Required schema components will be generated and set accordingly.
- *
- * @param property the property containing one or more XmlWriteTransformers.
- * @param typeInfo the TypeInfo that owns the property
- * @param compositor sequence/choice/all to modify
+ /**
+ * Convenience method for processing XmlWriteTransformer(s) for a given property.
+ * Required schema components will be generated and set accordingly.
+ *
+ * @param property the property containing one or more XmlWriteTransformers.
+ * @param typeInfo the TypeInfo that owns the property
+ * @param compositor sequence/choice/all to modify
* @param type ComplexType which compositor(s) should be added to
* @param schema current schema which ComplextType will be added to
*/
@@ -1495,16 +1508,16 @@ public class SchemaGenerator {
if (jMethod == null) {
throw JAXBException.noSuchWriteTransformationMethod(methodName);
}
- jType = jMethod.getReturnType();
- } else {
- // handle method
- // here it is assumed that the JavaModel is aware of the TypeInfo's class, hence jClass cannot be null
- jClass = helper.getJavaClass(typeInfo.getJavaClassName());
- methodName = writeTransformer.getMethod();
- // the method can have 0 args or 1 arg (either AbstractSession or Session)
- // first check 0 arg
- jMethod = jClass.getDeclaredMethod(methodName, new JavaClass[] {});
- if (jMethod == null) {
+ jType = jMethod.getReturnType();
+ } else {
+ // handle method
+ // here it is assumed that the JavaModel is aware of the TypeInfo's class, hence jClass cannot be null
+ jClass = helper.getJavaClass(typeInfo.getJavaClassName());
+ methodName = writeTransformer.getMethod();
+ // the method can have 0 args or 1 arg (either AbstractSession or Session)
+ // first check 0 arg
+ jMethod = jClass.getDeclaredMethod(methodName, new JavaClass[] {});
+ if (jMethod == null) {
// try AbstractSession
jMethod = jClass.getDeclaredMethod(methodName, new JavaClass[] { helper.getJavaClass(AbstractSession.class) });
if (jMethod == null) {
@@ -1519,27 +1532,27 @@ public class SchemaGenerator {
}
prop.setType(jType);
props.add(prop);
- }
- addToSchemaType(typeInfo, props, compositor, type, schema);
- }
-
- /**
- * Process a given XmlPath, and create the required schema components. The last
- * fragment may not be processed; in this case the returned XmlPathResult is
- * used to set the current schema and parent complex type, then the owning
- * property is processed as per usual. Note the last fragment may be processed
- * if it has a namespace or is an 'any'.
- *
- * @param property the property containing the XmlPath for which schema components are to be built
- * @param compositor the sequence/choice/all to modify
- * @param schema the schema being built when this method is called - this could
- * if the XmlPath contains an entry that references a different namespace
- * @param isChoice indicates if the given property is a choice property
- * @param type the ComplexType which compositor(s) should be added to
- * @return AddToSchemaResult containing current schema and sequence/all/choice build
- * based on the given XmlPath
- */
- private AddToSchemaResult addXPathToSchema(Property property, TypeDefParticle compositor, Schema schema, boolean isChoice, ComplexType type) {
+ }
+ addToSchemaType(typeInfo, props, compositor, type, schema);
+ }
+
+ /**
+ * Process a given XmlPath, and create the required schema components. The last
+ * fragment may not be processed; in this case the returned XmlPathResult is
+ * used to set the current schema and parent complex type, then the owning
+ * property is processed as per usual. Note the last fragment may be processed
+ * if it has a namespace or is an 'any'.
+ *
+ * @param property the property containing the XmlPath for which schema components are to be built
+ * @param compositor the sequence/choice/all to modify
+ * @param schema the schema being built when this method is called - this could
+ * if the XmlPath contains an entry that references a different namespace
+ * @param isChoice indicates if the given property is a choice property
+ * @param type the ComplexType which compositor(s) should be added to
+ * @return AddToSchemaResult containing current schema and sequence/all/choice build
+ * based on the given XmlPath
+ */
+ private AddToSchemaResult addXPathToSchema(Property property, TypeDefParticle compositor, Schema schema, boolean isChoice, ComplexType type) {
// '.' xml-path requires special handling
if (property.getXmlPath().equals(DOT)) {
TypeInfo info = (TypeInfo) typeInfo.get(property.getActualType().getQualifiedName());
@@ -1571,13 +1584,13 @@ public class SchemaGenerator {
addToSchemaType(info, info.getPropertyList(), compositor, type, info.getSchema());
}
- /**
- * Convenience method for processing an XmlElementWrapper for a given property. Required schema
- * components will be generated and set accordingly.
- *
- * @param property the property containing an XmlElementWrapper
- * @param schema the schema currently being generated
- * @param compositor sequence/choice/all that the generated wrapper Element will be added to
+ /**
+ * Convenience method for processing an XmlElementWrapper for a given property. Required schema
+ * components will be generated and set accordingly.
+ *
+ * @param property the property containing an XmlElementWrapper
+ * @param schema the schema currently being generated
+ * @param compositor sequence/choice/all that the generated wrapper Element will be added to
* @return AddToSchemaResult containing current ComplexType and TypeDefParticle
*/
private AddToSchemaResult addXmlElementWrapperToSchema(Property property, Schema schema, TypeDefParticle compositor) {
@@ -1624,47 +1637,47 @@ public class SchemaGenerator {
wrapperType.setSequence(wrapperSequence);
wrapperElement.setComplexType(wrapperType);
return new AddToSchemaResult(wrapperSequence, wrapperType);
- }
-
- /**
- * Build an Attribute with name and type set. This method will typically be
- * called when processing an XPath that has no associated Property that can
- * be used to build an Attribute, such as in the case of XmlJoinNodes.
- *
- * @param attributeName name of the Attribute
- * @param typeName type of the Attribute
- * @return
+ }
+
+ /**
+ * Build an Attribute with name and type set. This method will typically be
+ * called when processing an XPath that has no associated Property that can
+ * be used to build an Attribute, such as in the case of XmlJoinNodes.
+ *
+ * @param attributeName name of the Attribute
+ * @param typeName type of the Attribute
+ * @return
*/
private Attribute buildAttribute(QName attributeName, String typeName) {
Attribute attribute = new Attribute();
attribute.setName(attributeName.getLocalPart());
- attribute.setType(typeName);
- return attribute;
- }
-
- /**
- * Build an Attribute based on a given Property.
- *
- * @param property the Property used to build the Attribute
- * @param schema the schema currently being generated
- * @return
- */
- private Attribute buildAttribute(Property property, Schema schema) {
- Attribute attribute = new Attribute();
-
- QName attributeName = property.getSchemaName();
- attribute.setName(attributeName.getLocalPart());
- if (property.isRequired()) {
+ attribute.setType(typeName);
+ return attribute;
+ }
+
+ /**
+ * Build an Attribute based on a given Property.
+ *
+ * @param property the Property used to build the Attribute
+ * @param schema the schema currently being generated
+ * @return
+ */
+ private Attribute buildAttribute(Property property, Schema schema) {
+ Attribute attribute = new Attribute();
+
+ QName attributeName = property.getSchemaName();
+ attribute.setName(attributeName.getLocalPart());
+ if (property.isRequired()) {
attribute.setUse(Attribute.REQUIRED);
}
String fixedValue = property.getFixedValue();
- if (fixedValue != null){
- attribute.setFixed(fixedValue);
- }
- // Check to see if it's a collection
- TypeInfo info = (TypeInfo) typeInfo.get(property.getActualType().getQualifiedName());
- String typeName = getTypeNameForComponent(property, schema, property.getActualType(), attribute, false);
- if (isCollectionType(property)) {
+ if (fixedValue != null){
+ attribute.setFixed(fixedValue);
+ }
+ // Check to see if it's a collection
+ TypeInfo info = (TypeInfo) typeInfo.get(property.getActualType().getQualifiedName());
+ String typeName = getTypeNameForComponent(property, schema, property.getActualType(), attribute, false);
+ if (isCollectionType(property)) {
if(!property.isXmlList() && null != property.getXmlPath() && property.getXmlPath().contains("/")) {
attribute.setType(typeName);
} else {
@@ -1690,40 +1703,40 @@ public class SchemaGenerator {
}
}
attribute.setType(typeName);
- }
- return attribute;
- }
-
- /**
- * Convenience method for processing an attribute property. Required schema
- * components will be generated and set accordingly.
- *
- * @param property the attribute property to be processed
- * @param schema the schema currently being generated
- * @param type the ComplexType which compositor(s) should be added to
- */
- private void addAttributeToSchema(Attribute attribute, QName attributeName, Schema schema, ComplexType type) {
+ }
+ return attribute;
+ }
+
+ /**
+ * Convenience method for processing an attribute property. Required schema
+ * components will be generated and set accordingly.
+ *
+ * @param attribute the attribute property to be processed
+ * @param schema the schema currently being generated
+ * @param type the ComplexType which compositor(s) should be added to
+ */
+ private void addAttributeToSchema(Attribute attribute, QName attributeName, Schema schema, ComplexType type) {
String lookupNamespace = schema.getTargetNamespace();
if (lookupNamespace == null) {
lookupNamespace = EMPTY_STRING;
}
NamespaceInfo namespaceInfo = getNamespaceInfoForNamespace(lookupNamespace);
boolean isAttributeFormQualified = false;
- if (namespaceInfo != null) {
- isAttributeFormQualified = namespaceInfo.isAttributeFormQualified();
- }
-
- boolean addRef = shouldAddRefAndSetForm(attribute, attributeName.getNamespaceURI(), lookupNamespace, isAttributeFormQualified, false);
- if(addRef){
- Schema attributeSchema = this.getSchemaForNamespace(attributeName.getNamespaceURI());
+ if (namespaceInfo != null) {
+ isAttributeFormQualified = namespaceInfo.isAttributeFormQualified();
+ }
+
+ boolean addRef = shouldAddRefAndSetForm(attribute, attributeName.getNamespaceURI(), lookupNamespace, isAttributeFormQualified, false);
+ if(addRef){
+ Schema attributeSchema = this.getSchemaForNamespace(attributeName.getNamespaceURI());
if (attributeSchema != null && attributeSchema.getTopLevelAttributes().get(attribute.getName()) == null) {
- //don't overwrite existing global elements and attributes.
- attributeSchema.getTopLevelAttributes().put(attribute.getName(), attribute);
- }
- Attribute reference = new Attribute();
- String prefix = getPrefixForNamespace(schema, attributeName.getNamespaceURI());
- if (prefix == null) {
- reference.setRef(attribute.getName());
+ //don't overwrite existing global elements and attributes.
+ attributeSchema.getTopLevelAttributes().put(attribute.getName(), attribute);
+ }
+ Attribute reference = new Attribute();
+ String prefix = getPrefixForNamespace(schema, attributeName.getNamespaceURI());
+ if (prefix == null) {
+ reference.setRef(attribute.getName());
} else {
reference.setRef(prefix + COLON + attribute.getName());
}
@@ -1739,86 +1752,86 @@ public class SchemaGenerator {
type.getComplexContent().getExtension().getOrderedAttributes().add(attribute);
} else {
type.getOrderedAttributes().add(attribute);
- }
- }
- }
-
- private boolean shouldAddRefAndSetForm(SimpleComponent sc, String simpleComponentNamespace, String lookupNamespace, boolean formQualified, boolean isElement){
- if(sc.getRef() != null){
- return true;
- }
- boolean addRef = false;
- boolean sameNamespace = simpleComponentNamespace.equals(lookupNamespace);
-
- if (formQualified && !sameNamespace){
- if(simpleComponentNamespace.equals(EMPTY_STRING)){
- sc.setForm(Constants.UNQUALIFIED);
- }else{
- addRef = true;
- }
- } else if(!formQualified && !simpleComponentNamespace.equals(EMPTY_STRING)){
- if(sameNamespace && isElement){
- sc.setForm(Constants.QUALIFIED);
- }else{
- addRef = true;
- }
- }
- return addRef;
- }
-
- /**
- * Convenience method for processing an any attribute property. Required
- * schema components will be generated and set accordingly.
- *
- * @param type the ComplexType which compositor(s) should be added to
- */
- private void addAnyAttributeToSchema(ComplexType type) {
+ }
+ }
+ }
+
+ private boolean shouldAddRefAndSetForm(SimpleComponent sc, String simpleComponentNamespace, String lookupNamespace, boolean formQualified, boolean isElement){
+ if(sc.getRef() != null){
+ return true;
+ }
+ boolean addRef = false;
+ boolean sameNamespace = simpleComponentNamespace.equals(lookupNamespace);
+
+ if (formQualified && !sameNamespace){
+ if(simpleComponentNamespace.equals(EMPTY_STRING)){
+ sc.setForm(Constants.UNQUALIFIED);
+ }else{
+ addRef = true;
+ }
+ } else if(!formQualified && !simpleComponentNamespace.equals(EMPTY_STRING)){
+ if(sameNamespace && isElement){
+ sc.setForm(Constants.QUALIFIED);
+ }else{
+ addRef = true;
+ }
+ }
+ return addRef;
+ }
+
+ /**
+ * Convenience method for processing an any attribute property. Required
+ * schema components will be generated and set accordingly.
+ *
+ * @param type the ComplexType which compositor(s) should be added to
+ */
+ private void addAnyAttributeToSchema(ComplexType type) {
AnyAttribute anyAttribute = new AnyAttribute();
- anyAttribute.setProcessContents(SKIP);
- anyAttribute.setNamespace(Constants.ANY_NAMESPACE_OTHER);
- if (type.getSimpleContent() != null) {
- SimpleContent content = type.getSimpleContent();
- if(content.getExtension() != null){
- content.getExtension().setAnyAttribute(anyAttribute);
- }else if(content.getRestriction() != null){
- content.getRestriction().setAnyAttribute(anyAttribute);
- }
- } else {
- type.setAnyAttribute(anyAttribute);
- }
- }
-
- /**
- * Convenience method for processing an any property. Required
- * schema components will be generated and set accordingly.
- *
- * @param property the choice property to be processed
- * @param compositor the sequence/choice/all to modify
- */
- private void addAnyToSchema(Property property, TypeDefParticle compositor) {
+ anyAttribute.setProcessContents(SKIP);
+ anyAttribute.setNamespace(Constants.ANY_NAMESPACE_OTHER);
+ if (type.getSimpleContent() != null) {
+ SimpleContent content = type.getSimpleContent();
+ if(content.getExtension() != null){
+ content.getExtension().setAnyAttribute(anyAttribute);
+ }else if(content.getRestriction() != null){
+ content.getRestriction().setAnyAttribute(anyAttribute);
+ }
+ } else {
+ type.setAnyAttribute(anyAttribute);
+ }
+ }
+
+ /**
+ * Convenience method for processing an any property. Required
+ * schema components will be generated and set accordingly.
+ *
+ * @param property the choice property to be processed
+ * @param compositor the sequence/choice/all to modify
+ */
+ private void addAnyToSchema(Property property, TypeDefParticle compositor) {
addAnyToSchema(property, compositor, isCollectionType(property)|| property.getType().isArray(), Constants.ANY_NAMESPACE_OTHER);
}
/**
- * Convenience method for processing an any property. Required
- * schema components will be generated and set accordingly.
- *
- * @param property the choice property to be processed
- * @param compositor the sequence/choice/all to modify
- * @param isCollection if true will be unbounded
- */
- private void addAnyToSchema(Property property, TypeDefParticle compositor, boolean isCollection) {
- addAnyToSchema(property, compositor, isCollection, Constants.ANY_NAMESPACE_OTHER);
- }
-
- /**
- * Convenience method for processing an any property. Required
- * schema components will be generated and set accordingly.
- *
- * @param property the choice property to be processed
- * @param compositor the sequence/choice/all to modify
- * @param isCollection if true will be unbounded
- * @param anyNamespace value for the Any's namespace attribute
+ * Convenience method for processing an any property. Required
+ * schema components will be generated and set accordingly.
+ *
+ * @param property the choice property to be processed
+ * @param compositor the sequence/choice/all to modify
+ * @param isCollection if true will be unbounded
+ */
+ private void addAnyToSchema(Property property, TypeDefParticle compositor, boolean isCollection) {
+ addAnyToSchema(property, compositor, isCollection, Constants.ANY_NAMESPACE_OTHER);
+ }
+
+ /**
+ * Convenience method for processing an any property. Required
+ * schema components will be generated and set accordingly.
+ *
+ * @param property the choice property to be processed
+ * @param compositor the sequence/choice/all to modify
+ * @param isCollection if true will be unbounded
+ * @param anyNamespace value for the Any's namespace attribute
*/
private void addAnyToSchema(Property property, TypeDefParticle compositor, boolean isCollection, String anyNamespace) {
Any any = new Any();
@@ -1839,14 +1852,14 @@ public class SchemaGenerator {
}
}
- /**
- * Convenience method for processing a choice property. Required
- * schema components will be generated and set accordingly.
- *
- * @param property the choice property to be processed
- * @param typeInfo the TypeInfo that the given property belongs to
- * @param type the ComplexType which compositor(s) should be added to
- * @param compositor the sequence/choice/all to modify
+ /**
+ * Convenience method for processing a choice property. Required
+ * schema components will be generated and set accordingly.
+ *
+ * @param property the choice property to be processed
+ * @param typeInfo the TypeInfo that the given property belongs to
+ * @param type the ComplexType which compositor(s) should be added to
+ * @param compositor the sequence/choice/all to modify
* @param schema the schema being built
*/
private void addChoiceToSchema(Property property, TypeInfo typeInfo, ComplexType type, TypeDefParticle compositor, Schema schema) {
@@ -1859,55 +1872,55 @@ public class SchemaGenerator {
if (compositor instanceof Sequence) {
((Sequence) compositor).addChoice(choice);
} else if (compositor instanceof Choice) {
- ((Choice) compositor).addChoice(choice);
- }
- }
-
- /**
- * Convenience method for processing a reference property. Required
- * schema components will be generated and set accordingly.
- *
- * @param property the choice property to be processed
- * @param compositor the sequence/choice/all to modify
- * @param schema the schema being built
- */
+ ((Choice) compositor).addChoice(choice);
+ }
+ }
+
+ /**
+ * Convenience method for processing a reference property. Required
+ * schema components will be generated and set accordingly.
+ *
+ * @param property the choice property to be processed
+ * @param compositor the sequence/choice/all to modify
+ * @param schema the schema being built
+ */
private void addReferenceToSchema(Property property, Schema schema, TypeDefParticle compositor) {
java.util.List<ElementDeclaration> referencedElements = property.getReferencedElements();
if (referencedElements.size() == 1 && !property.isAny()) {
// if only a single reference, just add the element.
- Element element = new Element();
- ElementDeclaration decl = referencedElements.get(0);
- String localName = decl.getElementName().getLocalPart();
-
- String prefix = getPrefixForNamespace(schema, decl.getElementName().getNamespaceURI());
- if (decl.getScopeClass() == GLOBAL.class){
- if (prefix == null || prefix.equals(EMPTY_STRING)) {
- element.setRef(localName);
- } else {
- element.setRef(prefix + COLON + localName);
- }
+ Element element = new Element();
+ ElementDeclaration decl = referencedElements.get(0);
+ String localName = decl.getElementName().getLocalPart();
+
+ String prefix = getPrefixForNamespace(schema, decl.getElementName().getNamespaceURI());
+ if (decl.getScopeClass() == GLOBAL.class){
+ if (prefix == null || prefix.equals(EMPTY_STRING)) {
+ element.setRef(localName);
+ } else {
+ element.setRef(prefix + COLON + localName);
+ }
} else {
element.setType(getTypeName(property, decl.getJavaType(), schema));
element.setName(localName);
}
if (property.getGenericType() != null) {
- element.setMinOccurs(Occurs.ZERO);
- element.setMaxOccurs(Occurs.UNBOUNDED);
- }else if(!property.isRequired()){
- element.setMinOccurs(Occurs.ZERO);
- }
- compositor.addElement(element);
- } else {
+ element.setMinOccurs(Occurs.ZERO);
+ element.setMaxOccurs(Occurs.UNBOUNDED);
+ }else if(!property.isRequired()){
+ element.setMinOccurs(Occurs.ZERO);
+ }
+ compositor.addElement(element);
+ } else {
// otherwise, add a choice of referenced elements.
Choice choice = new Choice();
if (property.getGenericType() != null) {
- choice.setMaxOccurs(Occurs.UNBOUNDED);
- }
- if (!property.isRequired()){
- choice.setMinOccurs(Occurs.ZERO);
- }
- for (ElementDeclaration elementDecl : referencedElements) {
- Element element = new Element();
+ choice.setMaxOccurs(Occurs.UNBOUNDED);
+ }
+ if (!property.isRequired()){
+ choice.setMinOccurs(Occurs.ZERO);
+ }
+ for (ElementDeclaration elementDecl : referencedElements) {
+ Element element = new Element();
String localName = elementDecl.getElementName().getLocalPart();
String prefix = getPrefixForNamespace(schema, elementDecl.getElementName().getNamespaceURI());
@@ -1932,17 +1945,17 @@ public class SchemaGenerator {
((Sequence) compositor).addChoice(choice);
} else if (compositor instanceof Choice) {
((Choice) compositor).addChoice(choice);
- }
- }
- }
-
- /**
- * Convenience method for processing a reference property. Required
- * schema components will be generated and set accordingly.
- *
- * @param property the map property to be processed
- * @param element schema Element a new complex type will be added to
- * @param schema the schema being built
+ }
+ }
+ }
+
+ /**
+ * Convenience method for processing a reference property. Required
+ * schema components will be generated and set accordingly.
+ *
+ * @param property the map property to be processed
+ * @param element schema Element a new complex type will be added to
+ * @param schema the schema being built
* @param typeInfo the TypeInfo that the given property belongs to
*/
private void addMapToSchema(Property property, Element element, Schema schema, TypeInfo typeInfo) {
@@ -1952,21 +1965,21 @@ public class SchemaGenerator {
Element keyElement = new Element();
keyElement.setName(Property.DEFAULT_KEY_NAME);
keyElement.setMinOccurs(Occurs.ZERO);
-
- JavaClass keyType = property.getKeyType();
- JavaClass valueType = property.getValueType();
-
- if (keyType == null) {
- keyType = helper.getJavaClass(Object.class);
- }
-
- if (valueType == null) {
- valueType = helper.getJavaClass(Object.class);
- }
-
- String typeName;
- QName keySchemaType = getSchemaTypeFor(keyType);
- if (keySchemaType != null) {
+
+ JavaClass keyType = property.getKeyType();
+ JavaClass valueType = property.getValueType();
+
+ if (keyType == null) {
+ keyType = helper.getJavaClass(Object.class);
+ }
+
+ if (valueType == null) {
+ valueType = helper.getJavaClass(Object.class);
+ }
+
+ String typeName;
+ QName keySchemaType = getSchemaTypeFor(keyType);
+ if (keySchemaType != null) {
TypeInfo targetInfo = this.typeInfo.get(keyType.getQualifiedName());
if (targetInfo != null) {
Schema keyElementSchema = this.getSchemaForNamespace(keySchemaType.getNamespaceURI());
@@ -2034,20 +2047,20 @@ public class SchemaGenerator {
entryElement.setMaxOccurs(Occurs.UNBOUNDED);
sequence.addElement(entryElement);
entryElement.setComplexType(entryComplexType);
- element.setComplexType(complexType);
- }
- }
-
- /**
- * Convenience method that adds an element ref to a given schema.
- *
- * @param schema the schema being built
- * @param compositor the sequence/choice/all the new reference will be added to
- * @param referencedElement the element being referenced
- * @param referencedElementURI the URI of the element being referenced
- */
- private void addElementRefToSchema(Schema schema, TypeDefParticle compositor, Element referencedElement, String referencedElementURI) {
- Element reference = new Element();
+ element.setComplexType(complexType);
+ }
+ }
+
+ /**
+ * Convenience method that adds an element ref to a given schema.
+ *
+ * @param schema the schema being built
+ * @param compositor the sequence/choice/all the new reference will be added to
+ * @param referencedElement the element being referenced
+ * @param referencedElementURI the URI of the element being referenced
+ */
+ private void addElementRefToSchema(Schema schema, TypeDefParticle compositor, Element referencedElement, String referencedElementURI) {
+ Element reference = new Element();
reference.setMinOccurs(referencedElement.getMinOccurs());
reference.setMaxOccurs(referencedElement.getMaxOccurs());
Schema attributeSchema = this.getSchemaForNamespace(referencedElementURI);
@@ -2066,18 +2079,18 @@ public class SchemaGenerator {
}
// make sure a ref doesn't already exist before adding this one
if (elementExistsInParticle(reference.getName(), reference.getRef(), compositor) == null) {
- compositor.addElement(reference);
- }
- }
-
- /**
- * Build an Element with name, type and possibly minOccurs set. This method will
- * typically be called when processing an XPath that has no associated Property
- * that can be used to build an Element, such as in the case of XmlJoinNodes.
- *
- * @param elementName name of the Element
- * @param elementType type of the Element
- * @param isAll indicates if the Element will be added to an All structure
+ compositor.addElement(reference);
+ }
+ }
+
+ /**
+ * Build an Element with name, type and possibly minOccurs set. This method will
+ * typically be called when processing an XPath that has no associated Property
+ * that can be used to build an Element, such as in the case of XmlJoinNodes.
+ *
+ * @param elementName name of the Element
+ * @param elementType type of the Element
+ * @param isAll indicates if the Element will be added to an All structure
* @return
*/
private Element buildElement(String elementName, String elementType, boolean isAll) {
@@ -2087,28 +2100,28 @@ public class SchemaGenerator {
element.setMinOccurs(Occurs.ZERO);
}
element.setName(elementName);
- element.setType(elementType);
- return element;
- }
-
- /**
- * Build an Element based on a given Property.
- *
- * @param property the Property used to build the Element
- * @param isAll true if the Element will be added to an All structure
- * @param schema the schema currently being built
+ element.setType(elementType);
+ return element;
+ }
+
+ /**
+ * Build an Element based on a given Property.
+ *
+ * @param property the Property used to build the Element
+ * @param isAll true if the Element will be added to an All structure
+ * @param schema the schema currently being built
* @param typeInfo the TypeInfo that owns the given Property
* @return
- */
- private Element buildElement(Property property, boolean isAll, Schema schema, TypeInfo typeInfo) {
- Element element = new Element();
- // Set minOccurs based on the 'required' flag
- element.setMinOccurs(property.isRequired() ? Occurs.ONE : Occurs.ZERO);
- // handle nillable
- if (property.shouldSetNillable()) {
- element.setNillable(true);
- }
- // handle defaultValue
+ */
+ private Element buildElement(Property property, boolean isAll, Schema schema, TypeInfo typeInfo) {
+ Element element = new Element();
+
+ // handle nillable
+ if (property.shouldSetNillable()) {
+ if (property.isNotNullAnnotated()) throw BeanValidationException.notNullAndNillable(property.getPropertyName());
+ element.setNillable(true);
+ }
+ // handle defaultValue
if (property.isSetDefaultValue()) {
element.setDefaultValue(property.getDefaultValue());
}
@@ -2126,20 +2139,20 @@ public class SchemaGenerator {
NamespaceInfo namespaceInfo = getNamespaceInfoForNamespace(lookupNamespace);
boolean isElementFormQualified = false;
if (namespaceInfo != null) {
- isElementFormQualified = namespaceInfo.isElementFormQualified();
- }
- // handle element reference
-
- boolean addRef = shouldAddRefAndSetForm(element, elementNamespace, lookupNamespace, isElementFormQualified, true);
-
- if(addRef){
- schema = this.getSchemaForNamespace(elementNamespace);
- }
-
- JavaClass javaType = property.getActualType();
- element.setName(elementName.getLocalPart());
- String typeName = getTypeNameForComponent(property, schema, javaType, element, true);
-
+ isElementFormQualified = namespaceInfo.isElementFormQualified();
+ }
+ // handle element reference
+
+ boolean addRef = shouldAddRefAndSetForm(element, elementNamespace, lookupNamespace, isElementFormQualified, true);
+
+ if(addRef){
+ schema = this.getSchemaForNamespace(elementNamespace);
+ }
+
+ JavaClass javaType = property.getActualType();
+ element.setName(elementName.getLocalPart());
+ String typeName = getTypeNameForComponent(property, schema, javaType, element, true);
+
if (property.getGenericType() != null) {
if (property.isXmlList()) {
SimpleType localSimpleType = new SimpleType();
@@ -2148,31 +2161,124 @@ public class SchemaGenerator {
localSimpleType.setList(list);
element.setSimpleType(localSimpleType);
} else {
- element.setMaxOccurs(Occurs.UNBOUNDED);
- element.setType(typeName);
- }
- // handle map property
- } else if (property.isMap()) {
- addMapToSchema(property, element, schema, typeInfo);
- } else {
- element.setType(typeName);
- }
- return element;
- }
-
- /**
- * Convenience method that adds an element to a given schema.
- *
- * @param property the Property that the Element will be based on
- * @param compositor the sequence/choice/all that the Element will be added to
- * @param schema the schema currently being built
- * @param typeInfo the TypeInfo that owns the given Property
- */
- private void addElementToSchema(Element element, String elementURI, boolean isPositional, TypeDefParticle compositor, Schema schema) {
- String lookupNamespace = schema.getTargetNamespace();
- if (lookupNamespace == null) {
- lookupNamespace = EMPTY_STRING;
- }
+ element.setMaxOccurs(Occurs.UNBOUNDED);
+ element.setType(typeName);
+ }
+ // handle map property
+ } else if (property.isMap()) {
+ addMapToSchema(property, element, schema, typeInfo);
+ } else {
+ element.setType(typeName);
+ }
+
+ // Set minOccurs based on the 'required' flag
+ Integer minOccurs = property.getMinOccurs();
+ if (minOccurs != null) {
+ element.setMinOccurs(String.valueOf(minOccurs));
+ } else {
+ element.setMinOccurs(property.isRequired() ? Occurs.ONE : Occurs.ZERO);
+ }
+ // Overwrite maxOccurs if it has been explicitly set on property.
+ Integer maxOccurs = property.getMaxOccurs();
+ if (maxOccurs != null) element.setMaxOccurs(String.valueOf(maxOccurs));
+
+ if (facets) {
+ for (Facet facet : property.getFacets()) {
+ processFacet(element, facet);
+ }
+ }
+ return element;
+ }
+
+ private void processFacet(Element element, Facet facet) {
+ if (element.getSimpleType() == null) element.setSimpleType(new SimpleType());
+ Restriction restriction = element.getSimpleType().getRestriction();
+ if (restriction == null) {
+ restriction = new Restriction(element.getType());
+ element.getSimpleType().setRestriction(restriction);
+ }
+ element.setType(null); // Prevent error: "Cannot have both a 'type' attribute and an 'anonymous type' child".
+ facet.accept(FacetVisitorHolder.VISITOR, restriction);
+ }
+
+ private static final class FacetVisitorHolder {
+ private static final FacetVisitor<Void, Restriction> VISITOR = new FacetVisitor<Void, Restriction>() {
+ public Void visit(DecimalMinFacet t, Restriction restriction) {
+ if (t.isInclusive()) restriction.setMinInclusive(t.getValue());
+ else restriction.setMinExclusive(t.getValue());
+ return null;
+ }
+
+ public Void visit(DecimalMaxFacet t, Restriction restriction) {
+ if (t.isInclusive()) restriction.setMaxInclusive(t.getValue());
+ else restriction.setMaxExclusive(t.getValue());
+ return null;
+ }
+
+ public Void visit(DigitsFacet t, Restriction restriction) {
+ int fraction = t.getFraction();
+ if (fraction > 0) {
+ restriction.setFractionDigits(fraction);
+ restriction.setTotalDigits(fraction + t.getInteger());
+ } else if (fraction == 0) {
+ restriction.setTotalDigits(t.getInteger());
+ }
+ return null;
+ }
+
+ public Void visit(MaxFacet t, Restriction restriction) {
+ restriction.setMaxInclusive(String.valueOf(t.getValue()));
+ return null;
+ }
+
+ public Void visit(MinFacet t, Restriction restriction) {
+ restriction.setMinInclusive(String.valueOf(t.getValue()));
+ return null;
+ }
+
+ public Void visit(PatternFacet t, Restriction restriction) {
+ String regex = t.getRegexp();
+ regex = introduceShorthands(regex);
+ restriction.setPattern(regex);
+ return null;
+ }
+
+ public Void visit(PatternListFacet t, Restriction restriction) {
+ for (PatternFacet pf : t.getPatterns()) {
+ String regex = pf.getRegexp();
+ regex = introduceShorthands(regex);
+ restriction.addPattern(regex);
+ }
+ return null;
+ }
+
+ public Void visit(SizeFacet t, Restriction restriction) {
+ int minLength = t.getMin();
+ int maxLength = t.getMax();
+ if (minLength == maxLength) {
+ restriction.setLength(minLength);
+ } else {
+ if (minLength > 0) restriction.setMinLength(minLength); // 0 is the default minBoundary.
+ if (maxLength < Integer.MAX_VALUE) restriction.setMaxLength(maxLength); // 2^31 is the default maxBoundary.
+ }
+ return null;
+ }
+ };
+ }
+
+ /**
+ * Convenience method that adds an element to a given schema.
+ *
+ * @param element the Property that the Element will be based on
+ * @param compositor the sequence/choice/all that the Element will be added to
+ * @param schema the schema currently being built
+ * @param compositor the TypeInfo that owns the given Property
+ */
+ private void addElementToSchema(Element element, String elementURI, boolean isPositional, TypeDefParticle compositor, Schema schema) {
+ String lookupNamespace = schema.getTargetNamespace();
+ if (lookupNamespace == null) {
+ lookupNamespace = EMPTY_STRING;
+ }
NamespaceInfo namespaceInfo = getNamespaceInfoForNamespace(lookupNamespace);
boolean isElementFormQualified = false;
if (namespaceInfo != null) {
@@ -2188,40 +2294,40 @@ public class SchemaGenerator {
element.setMaxOccurs(Occurs.UNBOUNDED);
}
compositor.addElement(element);
- }
- }
- }
-
- /**
- * Convenience method that processes the XmlJoinNodes for a given Property and adds the
- * appropriate components to the schema.
- *
- * @param property the Property contianing one or more XmlJoinNode entries
- * @param compositor the sequence/choice/all that will be added to
- * @param schema the schema currently being built
+ }
+ }
+ }
+
+ /**
+ * Convenience method that processes the XmlJoinNodes for a given Property and adds the
+ * appropriate components to the schema.
+ *
+ * @param property the Property contianing one or more XmlJoinNode entries
+ * @param compositor the sequence/choice/all that will be added to
+ * @param schema the schema currently being built
* @param type the complex type currently being built
*/
private void addXmlJoinNodesToSchema(Property property, TypeDefParticle compositor, Schema schema, ComplexType type) {
for (XmlJoinNode xmlJoinNode : property.getXmlJoinNodes().getXmlJoinNode()) {
// create the XPathFragment(s) for the path
- Field xfld = new XMLField(xmlJoinNode.getXmlPath());
- xfld.setNamespaceResolver(schema.getNamespaceResolver());
- xfld.initialize();
-
- // build the schema components for the xml-path
- AddToSchemaResult asr = buildSchemaComponentsForXPath(xfld.getXPathFragment(), new AddToSchemaResult(compositor, schema), false, property);
-
+ Field xfld = new XMLField(xmlJoinNode.getXmlPath());
+ xfld.setNamespaceResolver(schema.getNamespaceResolver());
+ xfld.initialize();
+
+ // build the schema components for the xml-path
+ AddToSchemaResult asr = buildSchemaComponentsForXPath(xfld.getXPathFragment(), new AddToSchemaResult(compositor, schema), false, property);
+
// process the last fragment
TypeDefParticle currentParticle = asr.particle;
Schema currentSchema = asr.schema;
- if (currentParticle.getOwner() instanceof ComplexType) {
- type = ((ComplexType) currentParticle.getOwner());
- }
- // get a QName for the last part of the xpath - this will be used as the
- // attribute/element name, and also to figure out if a ref is required
- QName schemaName;
- XPathFragment frag = xfld.getLastXPathFragment();
- boolean isAttribute = xmlJoinNode.getXmlPath().contains(ATT);
+ if (currentParticle.getOwner() instanceof ComplexType) {
+ type = ((ComplexType) currentParticle.getOwner());
+ }
+ // get a QName for the last part of the xpath - this will be used as the
+ // attribute/element name, and also to figure out if a ref is required
+ QName schemaName;
+ XPathFragment frag = xfld.getLastXPathFragment();
+ boolean isAttribute = xmlJoinNode.getXmlPath().contains(ATT);
// for non-attributes, the last fragment may be 'text()'
if (!isAttribute) {
if (frag.nameIsText()) {
@@ -2238,67 +2344,67 @@ public class SchemaGenerator {
addAttributeToSchema(buildAttribute(schemaName, Constants.SCHEMA_PREFIX + COLON + Constants.ANY_SIMPLE_TYPE), schemaName, currentSchema, type);
} else {
addElementToSchema(buildElement(schemaName.getLocalPart(), Constants.SCHEMA_PREFIX + COLON + Constants.ANY_SIMPLE_TYPE, currentParticle instanceof All), schemaName.getNamespaceURI(), false, currentParticle, currentSchema);
- }
- }
- }
-
- /**
- * Return the type name for an Element based on a given property.
- *
- * @param property the Property that the type name will be based on
- * @param schema the schema currently being built
- * @param javaClass the given Property's 'actual' type
- * @param element the element being generated for the given Property
- * @return a type name based on the given Property, or null if not obtainable
- */
- private String getTypeNameForComponent(Property property, Schema schema, JavaClass javaClass, SimpleComponent sc, boolean isElement) {
+ }
+ }
+ }
+
+ /**
+ * Return the type name for an Element based on a given property.
+ *
+ * @param property the Property that the type name will be based on
+ * @param schema the schema currently being built
+ * @param javaClass the given Property's 'actual' type
+ * @param sc the element being generated for the given Property
+ * @return a type name based on the given Property, or null if not obtainable
+ */
+ private String getTypeNameForComponent(Property property, Schema schema, JavaClass javaClass, SimpleComponent sc, boolean isElement) {
String typeName = null;
- if (property.isXmlId()) {
- // handle user-set schema-type
- if (property.getSchemaType() != null) {
- typeName = getTypeName(property, property.getActualType(), schema);
- } else {
- // default to xsd:ID
- typeName = Constants.SCHEMA_PREFIX + COLON + ID;
- }
- } else if (property.isXmlIdRef()) {
- typeName = Constants.SCHEMA_PREFIX + COLON + IDREF;
- } else {
- TypeInfo info = (TypeInfo) typeInfo.get(javaClass.getQualifiedName());
- if (info != null) {
- if (info.isComplexType()) {
- typeName = info.getComplexType().getName();
+ if (property.isXmlId()) {
+ // handle user-set schema-type
+ if (property.getSchemaType() != null) {
+ typeName = getTypeName(property, property.getActualType(), schema);
+ } else {
+ // default to xsd:ID
+ typeName = Constants.SCHEMA_PREFIX + COLON + ID;
+ }
+ } else if (property.isXmlIdRef()) {
+ typeName = Constants.SCHEMA_PREFIX + COLON + IDREF;
+ } else {
+ TypeInfo info = typeInfo.get(javaClass.getQualifiedName());
+ if (info != null) {
+ if (info.isComplexType()) {
+ typeName = info.getComplexType().getName();
} else if (info.getSimpleType() != null) {
typeName = info.getSimpleType().getName();
} else {
typeName = info.getSchemaTypeName();
- }
- if (typeName == null) {
- // need to add complex-type locally, or reference global element
- if(isElement && info.hasRootElement() && info.getXmlRootElement().getName().equals(sc.getName())){
- String refName = info.getXmlRootElement().getName();
- ((Element)sc).setRef(refName);
- }else{
- if (isElement && info.isComplexType()) {
- ((Element)sc).setComplexType(info.getComplexType());
- } else {
- sc.setSimpleType(info.getSimpleType());
- }
- }
- } else {
- // check to see if we need to add an import
- if (addImportIfRequired(schema, info.getSchema(), info.getClassNamespace())) {
+ }
+ if (typeName == null) {
+ // need to add complex-type locally, or reference global element
+ if(isElement && info.hasRootElement() && info.getXmlRootElement().getName().equals(sc.getName())){
+ String refName = info.getXmlRootElement().getName();
+ (sc).setRef(refName);
+ }else{
+ if (isElement && info.isComplexType()) {
+ ((Element)sc).setComplexType(info.getComplexType());
+ } else {
+ sc.setSimpleType(info.getSimpleType());
+ }
+ }
+ } else {
+ // check to see if we need to add an import
+ if (addImportIfRequired(schema, info.getSchema(), info.getClassNamespace())) {
String prefix = schema.getNamespaceResolver().resolveNamespaceURI(info.getClassNamespace());
if (prefix != null && (!typeName.equals(EMPTY_STRING))) {
typeName = prefix + COLON + typeName;
}
- }
- }
- } else if (!property.isMap()) {
- typeName = getTypeName(property, javaClass, schema);
- }
- // may need to qualify the type
- if (typeName != null && !typeName.contains(COLON)) {
+ }
+ }
+ } else if (!property.isMap()) {
+ typeName = getTypeName(property, javaClass, schema);
+ }
+ // may need to qualify the type
+ if (typeName != null && !typeName.contains(COLON)) {
String prefix;
if (info.getClassNamespace().equals(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI)) {
prefix = Constants.SCHEMA_PREFIX;
@@ -2309,7 +2415,88 @@ public class SchemaGenerator {
typeName = prefix + COLON + typeName;
}
}
- }
- return typeName;
- }
-}
+ }
+ return typeName;
+ }
+ private static String introduceShorthands(String regex) {
+ return RegexMutator.mutate(regex);
+ }
+
+ /**
+ * Maintains compatibility between Java Pattern Regex and XML Schema regex.
+ * Replaces Java regexes with their respective XML Regex Shorthands, where applicable.
+ * <p>
+ * Recognized are Java regexes for the following XML Shorthands, and their negations:
+ * <blockquote><pre>
+ * \i - Matches any character that may be the first character of an XML name.
+ * "[_:A-Za-z]"
+ * \c - Matches any character that may occur after the first character in an XML name.
+ * "[-.0-9:A-Z_a-z]"
+ * \d - All digits.
+ * "\\p{Nd}"
+ * \w - Word character.
+ * "[\\pL\\pM\\p{Nd}\\p{Nl}\\p{Pc}[\\p{InEnclosedAlphanumerics}&&\\p{So}]]"
+ * \s - Whitespace character.
+ * "[\\u0009-\\u000D\\u0020\\u0085\\u00A0\\u1680\\u180E\\u2000-\\u200A\\u2028\\u2029\\u202F\\u205F\\u3000]"
+ * \b, \B - Boundary definitions.
+ * "(?:(?<=[\\pL\\pM\\p{Nd}\\p{Nl}\\p{Pc}[\\p{InEnclosedAlphanumerics}&&\\p{So}]])(?![\\pL\\pM\\p{Nd}\\p{Nl}\\p{Pc}[\\p{InEnclosedAlphanumerics}&&\\p{So}]])|(?<![\\pL\\pM\\p{Nd}\\p{Nl}\\p{Pc}[\\p{InEnclosedAlphanumerics}&&\\p{So}]])(?=[\\pL\\pM\\p{Nd}\\p{Nl}\\p{Pc}[\\p{InEnclosedAlphanumerics}&&\\p{So}]]))"
+ * "(?:(?<=[\\pL\\pM\\p{Nd}\\p{Nl}\\p{Pc}[\\p{InEnclosedAlphanumerics}&&\\p{So}]])(?=[\\pL\\pM\\p{Nd}\\p{Nl}\\p{Pc}[\\p{InEnclosedAlphanumerics}&&\\p{So}]])|(?<![\\pL\\pM\\p{Nd}\\p{Nl}\\p{Pc}[\\p{InEnclosedAlphanumerics}&&\\p{So}]])(?![\\pL\\pM\\p{Nd}\\p{Nl}\\p{Pc}[\\p{InEnclosedAlphanumerics}&&\\p{So}]]))"
+ * \h - Horizontal whitespace character - Java does not support, changed in Java 8 though.
+ * "[\\u0009\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u200A\\u202F\\u205F\\u3000]"
+ * \v - Vertical whitespace character - Java translates the shorthand to \cK only, meaning changed in Java 8 though.
+ * "[\\u000A-\\u000D\\u0085\\u2028\\u2029]"
+ * \X - Extended grapheme cluster.
+ * "(?:(?:\\u000D\\u000A)|(?:[\\u0E40\\u0E41\\u0E42\\u0E43\\u0E44\\u0EC0\\u0EC1\\u0EC2\\u0EC3\\u0EC4\\uAAB5\\uAAB6\\uAAB9\\uAABB\\uAABC]*(?:[\\u1100-\\u115F\\uA960-\\uA97C]+|([\\u1100-\\u115F\\uA960-\\uA97C]*((?:[[\\u1160-\\u11A2\\uD7B0-\\uD7C6][\\uAC00\\uAC1C\\uAC38]][\\u1160-\\u11A2\\uD7B0-\\uD7C6]*|[\\uAC01\\uAC02\\uAC03\\uAC04])[\\u11A8-\\u11F9\\uD7CB-\\uD7FB]*))|[\\u11A8-\\u11F9\\uD7CB-\\uD7FB]+|[^[\\p{Zl}\\p{Zp}\\p{Cc}\\p{Cf}&&[^\\u000D\\u000A\\u200C\\u200D]]\\u000D\\u000A])[[\\p{Mn}\\p{Me}\\u200C\\u200D\\u0488\\u0489\\u20DD\\u20DE\\u20DF\\u20E0\\u20E2\\u20E3\\u20E4\\uA670\\uA671\\uA672\\uFF9E\\uFF9F][\\p{Mc}\\u0E30\\u0E32\\u0E33\\u0E45\\u0EB0\\u0EB2\\u0EB3]]*)|(?s:.))"
+ * \R - Carriage return.
+ * "(?:(?>\\u000D\\u000A)|[\\u000A\\u000B\\u000C\\u000D\\u0085\\u2028\\u2029])"
+ * </pre></blockquote>
+ *
+ * CAUTION - ORDER SENSITIVE: Longer patterns should come first, because they may contain one of the shorter pattern.
+ * <p>
+ * Changes to this class should also be reflected in the opposite {@link org.eclipse.persistence.jaxb.plugins.BeanValidationPlugin.RegexMutator RegexMutator} class within XJC BeanValidation Plugin.
+ *
+ * @see <a href="http://stackoverflow.com/questions/4304928/unicode-equivalents-for-w-and-b-in-java-regular-expressions"/>tchrist's work</a>
+ * @see <a href="http://www.regular-expressions.info/shorthand.html#xml">Special shorthands in XML Schema.</a>
+ */
+ private static final class RegexMutator {
+ private static final Map<Pattern, String> shorthandReplacements = new HashMap<Pattern, String>(32) {{
+ put(Pattern.compile("[:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD]" , Pattern.LITERAL),"\\\\i");
+ put(Pattern.compile("[^:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD]" , Pattern.LITERAL),"\\\\I");
+ put(Pattern.compile("[-.0-9:A-Z_a-z\\u00B7\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u203F\\u2040\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD]" , Pattern.LITERAL),"\\\\c");
+ put(Pattern.compile("[^-.0-9:A-Z_a-z\\u00B7\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u203F\\u2040\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD]" , Pattern.LITERAL),"\\\\C");
+ put(Pattern.compile("[\\u0009-\\u000D\\u0020\\u0085\\u00A0\\u1680\\u180E\\u2000-\\u200A\\u2028\\u2029\\u202F\\u205F\\u3000]" , Pattern.LITERAL),"\\\\s");
+ put(Pattern.compile("[^\\u0009-\\u000D\\u0020\\u0085\\u00A0\\u1680\\u180E\\u2000-\\u200A\\u2028\\u2029\\u202F\\u205F\\u3000]" , Pattern.LITERAL),"\\\\S");
+ put(Pattern.compile("[\\u000A-\\u000D\\u0085\\u2028\\u2029]" , Pattern.LITERAL),"\\\\v");
+ put(Pattern.compile("[^\\u000A-\\u000D\\u0085\\u2028\\u2029]" , Pattern.LITERAL),"\\\\V");
+ put(Pattern.compile("[\\u0009\\u0020\\u00A0\\u1680\\u180E\\u2000-\\u200A\\u202F\\u205F\\u3000]" , Pattern.LITERAL),"\\\\h");
+ put(Pattern.compile("[^\\u0009\\u0020\\u00A0\\u1680\\u180E\\u2000\\u2001-\\u200A\\u202F\\u205F\\u3000]" , Pattern.LITERAL),"\\\\H");
+ put(Pattern.compile("[\\pL\\pM\\p{Nd}\\p{Nl}\\p{Pc}[\\p{InEnclosedAlphanumerics}&&\\p{So}]]" , Pattern.LITERAL),"\\\\w");
+ put(Pattern.compile("[^\\pL\\pM\\p{Nd}\\p{Nl}\\p{Pc}[\\p{InEnclosedAlphanumerics}&&\\p{So}]]" , Pattern.LITERAL),"\\\\W");
+ put(Pattern.compile("(?:(?<=[\\pL\\pM\\p{Nd}\\p{Nl}\\p{Pc}[\\p{InEnclosedAlphanumerics}&&\\p{So}]])(?![\\pL\\pM\\p{Nd}\\p{Nl}\\p{Pc}[\\p{InEnclosedAlphanumerics}&&\\p{So}]])|(?<![\\pL\\pM\\p{Nd}\\p{Nl}\\p{Pc}[\\p{InEnclosedAlphanumerics}&&\\p{So}]])(?=[\\pL\\pM\\p{Nd}\\p{Nl}\\p{Pc}[\\p{InEnclosedAlphanumerics}&&\\p{So}]]))", Pattern.LITERAL),"\\\\b");
+ put(Pattern.compile("(?:(?<=[\\pL\\pM\\p{Nd}\\p{Nl}\\p{Pc}[\\p{InEnclosedAlphanumerics}&&\\p{So}]])(?=[\\pL\\pM\\p{Nd}\\p{Nl}\\p{Pc}[\\p{InEnclosedAlphanumerics}&&\\p{So}]])|(?<![\\pL\\pM\\p{Nd}\\p{Nl}\\p{Pc}[\\p{InEnclosedAlphanumerics}&&\\p{So}]])(?![\\pL\\pM\\p{Nd}\\p{Nl}\\p{Pc}[\\p{InEnclosedAlphanumerics}&&\\p{So}]]))", Pattern.LITERAL),"\\\\B");
+ put(Pattern.compile("\\p{Nd}" , Pattern.LITERAL),"\\\\d");
+ put(Pattern.compile("\\P{Nd}" , Pattern.LITERAL),"\\\\D");
+ put(Pattern.compile("(?:(?>\\u000D\\u000A)|[\\u000A\\u000B\\u000C\\u000D\\u0085\\u2028\\u2029])" , Pattern.LITERAL),"\\\\R");
+ put(Pattern.compile("(?:(?:\\u000D\\u000A)|(?:[\\u0E40\\u0E41\\u0E42\\u0E43\\u0E44\\u0EC0\\u0EC1\\u0EC2\\u0EC3\\u0EC4\\uAAB5\\uAAB6\\uAAB9\\uAABB\\uAABC]*(?:[\\u1100-\\u115F\\uA960-\\uA97C]+|([\\u1100-\\u115F\\uA960-\\uA97C]*((?:[[\\u1160-\\u11A2\\uD7B0-\\uD7C6][\\uAC00\\uAC1C\\uAC38]][\\u1160-\\u11A2\\uD7B0-\\uD7C6]*|[\\uAC01\\uAC02\\uAC03\\uAC04])[\\u11A8-\\u11F9\\uD7CB-\\uD7FB]*))|[\\u11A8-\\u11F9\\uD7CB-\\uD7FB]+|[^[\\p{Zl}\\p{Zp}\\p{Cc}\\p{Cf}&&[^\\u000D\\u000A\\u200C\\u200D]]\\u000D\\u000A])[[\\p{Mn}\\p{Me}\\u200C\\u200D\\u0488\\u0489\\u20DD\\u20DE\\u20DF\\u20E0\\u20E2\\u20E3\\u20E4\\uA670\\uA671\\uA672\\uFF9E\\uFF9F][\\p{Mc}\\u0E30\\u0E32\\u0E33\\u0E45\\u0EB0\\u0EB2\\u0EB3]]*)|(?s:.))" , Pattern.LITERAL),"\\\\X");
+ put(Pattern.compile("[_:A-Za-z]" , Pattern.LITERAL),"\\\\i"); // ascii only
+ put(Pattern.compile("[^:A-Z_a-z]" , Pattern.LITERAL),"\\\\I"); // ascii only
+ put(Pattern.compile("[-.0-9:A-Z_a-z]" , Pattern.LITERAL),"\\\\c"); // ascii only
+ put(Pattern.compile("[^-.0-9:A-Z_a-z]" , Pattern.LITERAL),"\\\\C"); // ascii only
+ }};
+
+ private RegexMutator() {
+ }
+
+ /**
+ * @param input Java regex
+ * @return XML regex
+ */
+ private static String mutate(String input){
+ for (Map.Entry<Pattern, String> entry : shorthandReplacements.entrySet()) {
+ Matcher m = entry.getKey().matcher(input);
+ input = m.replaceAll(entry.getValue());
+ }
+ return input;
+ }
+ }
+}