use of org.eclipse.persistence.internal.oxm.schema.model.Extension in project eclipselink by eclipse-ee4j.
the class SchemaGenerator method buildSchemaComponentsForXPath.
/**
* 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.
*/
private 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());
// 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);
if (!currentElementExists) {
currentElement = new Element();
// don't set the element name yet, as it may end up being a ref
ComplexType cType = new ComplexType();
TypeDefParticle particle = null;
if (isChoice) {
particle = new Choice();
if (isUnbounded) {
particle.setMaxOccurs(Occurs.UNBOUNDED);
}
} else {
XPathFragment nextFragment = frag.getNextFragment();
if (frag.containsIndex() || frag.getPredicate() != null || (!next.isXmlList() && null != nextFragment && nextFragment.isAttribute() && helper.isCollectionType(next.getType()))) {
currentElement.setMaxOccurs(Occurs.UNBOUNDED);
}
particle = new Sequence();
}
cType.setTypeDefParticle(particle);
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) {
ComplexType cType = new ComplexType();
cType.setSimpleContent(new SimpleContent());
Extension extension = new Extension();
extension.setBaseType(type.getRestriction().getBaseType());
cType.getSimpleContent().setExtension(extension);
currentElement.setSimpleType(null);
currentElement.setComplexType(cType);
} else {
String eType = currentElement.getType();
ComplexType cType = new ComplexType();
SimpleContent sContent = new SimpleContent();
Extension extension = new Extension();
extension.setBaseType(eType);
sContent.setExtension(extension);
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 fragSchema is null, just generate the ref
if (fragSchema != null) {
Attribute globalAttribute = null;
globalAttribute = fragSchema.getTopLevelAttributes().get(frag.getLocalName());
if (globalAttribute == null) {
globalAttribute = createGlobalAttribute(frag, workingSchema, fragSchema, next);
}
} else {
// may need to add an import
addImportIfRequired(workingSchema, null, fragUri);
}
// add the attribute ref to the current element
String attributeRefName;
if (fragUri.equals(targetNS)) {
String prefix = fragSchema.getNamespaceResolver().resolveNamespaceURI(fragUri);
attributeRefName = prefix + COLON + frag.getLocalName();
} else {
attributeRefName = frag.getShortName();
}
TypeDefParticleOwner type;
if (currentParticle != null) {
type = currentParticle.getOwner();
} else {
type = xpr.simpleContentType;
}
if (type instanceof ComplexType) {
createRefAttribute(attributeRefName, (ComplexType) type);
}
// set the frag's schema as it may be different than the current schema
xpr.schema = fragSchema;
// 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 = 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) {
fragPrefix = workingSchema.getNamespaceResolver().generatePrefix(frag.getPrefix());
workingSchema.getNamespaceResolver().put(fragPrefix, fragUri);
}
currentElement = createRefElement(fragPrefix + COLON + frag.getLocalName(), currentParticle);
if (frag.containsIndex() || frag.getPredicate() != null || helper.isCollectionType(next.getType())) {
currentElement.setMaxOccurs(Occurs.UNBOUNDED);
}
currentElementExists = true;
}
// set the frag's schema as it may be different than the current schema
xpr.schema = fragSchema;
// at this point, if we are dealing with the last fragment we will need to return
if (lastFrag) {
// add a second one...unless we're dealing with an 'any'
if (isAny) {
// set the particle that the 'any' will be added to by the calling method
xpr.particle = globalElement.getComplexType().getTypeDefParticle();
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());
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
xpr.simpleContentType = currentElement.getComplexType();
xpr.particle = null;
} else {
xpr.particle = currentElement.getComplexType().getTypeDefParticle();
}
} else {
// If there's no complex type, we're building the path through an element with
// a simple type. In order to build the path through this
// element, switch to a complex type with simple content.
SimpleType type = currentElement.getSimpleType();
if (type != null) {
ComplexType cType = new ComplexType();
cType.setSimpleContent(new SimpleContent());
Extension extension = new Extension();
extension.setBaseType(type.getRestriction().getBaseType());
cType.getSimpleContent().setExtension(extension);
currentElement.setSimpleType(null);
currentElement.setComplexType(cType);
xpr.particle = null;
xpr.simpleContentType = cType;
} else {
String eType = currentElement.getType();
ComplexType cType = new ComplexType();
SimpleContent sContent = new SimpleContent();
Extension extension = new Extension();
extension.setBaseType(eType);
sContent.setExtension(extension);
cType.setSimpleContent(sContent);
currentElement.setType(null);
currentElement.setComplexType(cType);
xpr.particle = null;
xpr.simpleContentType = cType;
}
}
}
// if we're on the last fragment, we're done
if (lastFrag) {
return xpr;
}
// call back into this method to process the next path element
return buildSchemaComponentsForXPath(frag.getNextFragment(), xpr, isChoice, next);
}
use of org.eclipse.persistence.internal.oxm.schema.model.Extension in project eclipselink by eclipse-ee4j.
the class SchemaGenerator method createComplexTypeForClass.
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);
}
Extension extension = null;
if (superClass != null) {
TypeInfo parentTypeInfo = this.typeInfo.get(superClass.getQualifiedName());
if (parentTypeInfo != null) {
extension = new Extension();
// may need to qualify the type
String parentPrefix = getPrefixForNamespace(schema, parentTypeInfo.getClassNamespace());
if (parentPrefix != null) {
extension.setBaseType(parentPrefix + COLON + parentTypeInfo.getSchemaTypeName());
} else {
extension.setBaseType(parentTypeInfo.getSchemaTypeName());
}
if (parentTypeInfo.getXmlValueProperty() != null) {
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) {
// 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);
} else {
type.setSequence((Sequence) compositor);
}
} else if (extension != null) {
compositor = new All();
extension.setAll((All) compositor);
} else {
compositor = new All();
type.setAll((All) compositor);
}
} else {
// generate a sequence to satisfy TCK
compositor = new Sequence();
if (extension != null) {
extension.setSequence((Sequence) compositor);
} else {
type.setSequence((Sequence) compositor);
}
}
return type;
}
use of org.eclipse.persistence.internal.oxm.schema.model.Extension in project eclipselink by eclipse-ee4j.
the class SchemaModelGenerator method buildComplexType.
/**
* Create and return a ComplexType for a given XMLDescriptor. Assumes that the descriptor has a schema context
* set.
*/
protected ComplexType buildComplexType(boolean anonymous, Descriptor desc, HashMap<String, Schema> schemaForNamespace, Schema workingSchema, SchemaModelGeneratorProperties properties, List<Descriptor> descriptors) {
ComplexType ct = new ComplexType();
if (!anonymous) {
ct.setName(desc.getSchemaReference().getSchemaContextAsQName(workingSchema.getNamespaceResolver()).getLocalPart());
}
CoreInheritancePolicy inheritancePolicy = desc.getInheritancePolicyOrNull();
Extension extension = null;
if (inheritancePolicy != null && inheritancePolicy.getParentClass() != null) {
extension = new Extension();
extension.setBaseType(desc.getSchemaReference().getSchemaContextAsQName(workingSchema.getNamespaceResolver()).getLocalPart());
ComplexContent complexContent = new ComplexContent();
complexContent.setExtension(extension);
ct.setComplexContent(complexContent);
}
Sequence seq = new Sequence();
for (CoreMapping mapping : (Vector<CoreMapping>) desc.getMappings()) {
processMapping(mapping, seq, ct, schemaForNamespace, workingSchema, properties, descriptors);
}
if (extension != null) {
extension.setSequence(seq);
} else {
ct.setSequence(seq);
}
return ct;
}
use of org.eclipse.persistence.internal.oxm.schema.model.Extension in project eclipselink by eclipse-ee4j.
the class SchemaModelGenerator method buildComplexTypeWithSimpleContent.
/**
* Create and return a ComplexType containing simple content for a given XMLDescriptor. Assumes
* that the descriptor has a schema context set.
*/
private ComplexType buildComplexTypeWithSimpleContent(Descriptor desc, HashMap<String, Schema> schemaForNamespace, Schema workingSchema, SchemaModelGeneratorProperties properties, List<Descriptor> descriptors) {
ComplexType ct = new ComplexType();
SimpleContent sc = new SimpleContent();
Extension extension = new Extension();
sc.setExtension(extension);
ct.setSimpleContent(sc);
for (CoreMapping mapping : (Vector<CoreMapping>) desc.getMappings()) {
Field xFld = (Field) mapping.getField();
if (xFld.getXPath().equals(TEXT)) {
extension.setBaseType(getSchemaTypeForDirectMapping((DirectMapping) mapping, workingSchema));
} else if (xFld.getXPathFragment().isAttribute()) {
String schemaTypeString = getSchemaTypeForDirectMapping((DirectMapping) mapping, workingSchema);
Attribute attr = buildAttribute((DirectMapping) mapping, schemaTypeString);
extension.getOrderedAttributes().add(attr);
}
}
return ct;
}
use of org.eclipse.persistence.internal.oxm.schema.model.Extension in project eclipselink by eclipse-ee4j.
the class SchemaGenerator method addSchemaComponents.
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);
NamespaceInfo namespaceInfo = this.packageToPackageInfoMappings.get(myClass.getPackageName()).getNamespaceInfo();
if (namespaceInfo.getLocation() != null && !namespaceInfo.getLocation().equals(GENERATE)) {
return;
}
Schema schema = getSchemaForNamespace(info.getClassNamespace(), myClass.getPackageName());
info.setSchema(schema);
String typeName = info.getSchemaTypeName();
String pfx = EMPTY_STRING;
Property valueField = null;
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();
if (rootNamespace.equals(XMLProcessor.DEFAULT)) {
Schema rootElementSchema = getSchemaForNamespace(namespaceInfo.getNamespace());
if (rootElementSchema != null) {
rootElementSchema.addTopLevelElement(rootElement);
}
schemaTypeInfo.getGlobalElementDeclarations().add(new QName(namespaceInfo.getNamespace(), rootNamespace));
rootNamespace = namespaceInfo.getNamespace();
} else {
Schema rootElementSchema = getSchemaForNamespace(rootNamespace);
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());
// 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)) {
// A root elem or locally defined whenever used
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 && !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;
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;
} else {
prefix = getPrefixForNamespace(schema, baseType.getNamespaceURI());
}
}
String baseTypeName = baseType.getLocalPart();
if (prefix != null) {
baseTypeName = prefix + COLON + baseTypeName;
}
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);
// TODO: This assignment seems like a bug, probably this should be "baseTypeName" ?
baseType = new QName(schemaType.namespace(), schemaType.name());
}
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 (EMPTY_STRING.equals(typeName)) {
if (rootElement != null) {
rootElement.setComplexType(type);
}
info.setComplexType(type);
} else {
type.setName(typeName);
schema.addTopLevelComplexTypes(type);
if (rootElement != null) {
rootElement.setType(pfx + type.getName());
}
}
QName extensionType = getSchemaTypeFor(valueField.getType());
if (helper.isAnnotationPresent(valueField.getElement(), XmlSchemaType.class)) {
XmlSchemaType schemaType = (XmlSchemaType) helper.getAnnotation(valueField.getElement(), XmlSchemaType.class);
extensionType = new QName(schemaType.namespace(), schemaType.name());
}
String prefix = null;
if (extensionType.getNamespaceURI() != null && !extensionType.getNamespaceURI().equals(EMPTY_STRING)) {
if (extensionType.getNamespaceURI().equals(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI)) {
prefix = Constants.SCHEMA_PREFIX;
} else {
prefix = getPrefixForNamespace(schema, extensionType.getNamespaceURI());
}
}
String extensionTypeName = extensionType.getLocalPart();
if (prefix != null) {
extensionTypeName = prefix + COLON + extensionTypeName;
}
Extension extension = new Extension();
extension.setBaseType(extensionTypeName);
content.setExtension(extension);
type.setSimpleContent(content);
info.setComplexType(type);
} else {
ComplexType type = createComplexTypeForClass(myClass, info);
TypeDefParticle compositor = null;
if (type.getComplexContent() != null && type.getComplexContent().getExtension() != null) {
compositor = type.getComplexContent().getExtension().getTypeDefParticle();
} else {
compositor = type.getTypeDefParticle();
}
if (EMPTY_STRING.equals(typeName)) {
if (rootElement != null) {
rootElement.setComplexType(type);
}
info.setComplexType(type);
info.setCompositor(compositor);
} else {
type.setName(typeName);
if (rootElement != null) {
rootElement.setType(pfx + type.getName());
}
schema.addTopLevelComplexTypes(type);
info.setComplexType(type);
info.setCompositor(compositor);
}
}
}
Aggregations