| /* |
| * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0, |
| * or the Eclipse Distribution License v. 1.0 which is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
| */ |
| |
| // Contributors: |
| // Oracle - initial API and implementation from Oracle TopLink |
| package org.eclipse.persistence.sdo.helper; |
| |
| import commonj.sdo.Property; |
| import commonj.sdo.Type; |
| import commonj.sdo.helper.HelperContext; |
| import java.io.StringWriter; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Vector; |
| import javax.xml.namespace.QName; |
| import org.eclipse.persistence.sdo.SDOConstants; |
| import org.eclipse.persistence.sdo.SDOProperty; |
| import org.eclipse.persistence.sdo.SDOType; |
| import org.eclipse.persistence.internal.helper.ClassConstants; |
| import org.eclipse.persistence.internal.oxm.Namespace; |
| import org.eclipse.persistence.internal.oxm.XMLConversionManager; |
| import org.eclipse.persistence.internal.oxm.schema.SchemaModelProject; |
| import org.eclipse.persistence.internal.oxm.schema.model.*; |
| import org.eclipse.persistence.oxm.XMLConstants; |
| import org.eclipse.persistence.oxm.XMLContext; |
| import org.eclipse.persistence.oxm.XMLDescriptor; |
| import org.eclipse.persistence.oxm.XMLLogin; |
| import org.eclipse.persistence.oxm.XMLMarshaller; |
| import org.eclipse.persistence.oxm.platform.DOMPlatform; |
| import org.eclipse.persistence.sessions.Project; |
| |
| /** |
| * <p><b>Purpose</b> SDOSchemaGenerator generates an XSD (returned as a String) |
| * from a list of SDO Type objects. Populates an org.eclipse.persistence.internal.oxm.schema.model.Schema |
| * object and makes use of org.eclipse.persistence.internal.oxm.schema.SchemaModelProject to marshal |
| * the Schema Object to XML. |
| * @see commonj.sdo.helper.XSDHelper |
| */ |
| public class SDOSchemaGenerator { |
| private Map<String, String> namespaceToSchemaLocation; |
| private SchemaLocationResolver schemaLocationResolver; |
| private List allTypes; |
| private Schema generatedSchema; |
| |
| // hold the context containing all helpers so that we can preserve inter-helper relationships |
| private HelperContext aHelperContext; |
| |
| public SDOSchemaGenerator(HelperContext aContext) { |
| aHelperContext = aContext; |
| } |
| |
| /** |
| * <p>Method to generate an XSD. Note the following:<ul> |
| * <li> All types must have same URI |
| * <li> Referenced types in same URI will also be generated in schema |
| * <li> Includes will never be generated |
| * <li> Imports will be generated for referenced types in other URIs |
| * </ul> |
| * @param types The list of commonj.sdo.Type objects to generate the XSD from |
| * @param aSchemaLocationResolver implementation of the org.eclipse.persistence.sdo.helper.SchemaLocationResolver interface |
| * used for getting the value of the schemaLocation attribute of generated imports and includes |
| * @return String The generated XSD. |
| */ |
| public String generate(List types, SchemaLocationResolver aSchemaLocationResolver) { |
| schemaLocationResolver = aSchemaLocationResolver; |
| if ((types == null) || (types.size() == 0)) { |
| throw new IllegalArgumentException("No Schema was generated from null or empty list of types."); |
| } |
| |
| String uri = null; |
| Type firstType = (Type)types.get(0); |
| uri = firstType.getURI(); |
| |
| allTypes = types; |
| generateSchema(uri, types); |
| |
| //Now we have a built schema model |
| Project p = new SchemaModelProject(); |
| Vector<Namespace> generatedNamespaces = generatedSchema.getNamespaceResolver().getNamespaces(); |
| XMLDescriptor desc = ((XMLDescriptor)p.getDescriptor(Schema.class)); |
| for (int i = 0; i < generatedNamespaces.size(); i++) { |
| Namespace next = generatedNamespaces.get(i); |
| desc.getNamespaceResolver().put(next.getPrefix(), next.getNamespaceURI()); |
| |
| if (next.getNamespaceURI().equals(SDOConstants.SDO_URL) || next.getNamespaceURI().equals(SDOConstants.SDOXML_URL) || next.getNamespaceURI().equals(SDOConstants.SDOJAVA_URL)) { |
| if (!importExists(generatedSchema.getImports(), next.getNamespaceURI())) { |
| Import theImport = new Import(); |
| theImport.setNamespace(next.getNamespaceURI()); |
| String schemaLocation = "classpath:/xml/"; |
| String customLocation = null; |
| if (next.getNamespaceURI().equals(SDOConstants.SDO_URL)) { |
| if(schemaLocationResolver != null) { |
| customLocation = schemaLocationResolver.resolveSchemaLocation(firstType, SDOConstants.SDO_BOOLEAN); |
| } |
| if(customLocation != null) { |
| schemaLocation = customLocation; |
| } else { |
| schemaLocation += "sdoModel.xsd"; |
| } |
| } else if (next.getNamespaceURI().equals(SDOConstants.SDOXML_URL)) { |
| if(schemaLocationResolver != null) { |
| customLocation = schemaLocationResolver.resolveSchemaLocation(firstType, new SDOType(SDOConstants.SDOXML_URL, "XMLInfo")); |
| } |
| if(customLocation != null) { |
| schemaLocation = customLocation; |
| } else { |
| schemaLocation += "sdoXML.xsd"; |
| } |
| } else if (next.getNamespaceURI().equals(SDOConstants.SDOJAVA_URL)) { |
| if(schemaLocationResolver != null) { |
| customLocation = schemaLocationResolver.resolveSchemaLocation(firstType, SDOConstants.SDO_BOOLEANOBJECT); |
| } |
| if(customLocation != null) { |
| schemaLocation = customLocation; |
| } else { |
| schemaLocation += "sdoJava.xsd"; |
| } |
| } |
| theImport.setSchemaLocation(schemaLocation); |
| generatedSchema.getImports().add(theImport); |
| } |
| } |
| } |
| |
| XMLLogin login = new XMLLogin(); |
| login.setDatasourcePlatform(new DOMPlatform()); |
| p.setDatasourceLogin(login); |
| |
| XMLContext context = new XMLContext(p); |
| |
| XMLMarshaller marshaller = context.createMarshaller(); |
| |
| StringWriter generatedSchemaWriter = new StringWriter(); |
| marshaller.marshal(generatedSchema, generatedSchemaWriter); |
| return generatedSchemaWriter.toString(); |
| } |
| |
| /** |
| * <p>Method to generate an XSD. Note the following:<ul> |
| * <li> All types must have same URI |
| * <li> Referenced types in same URI will also be generated in schema |
| * <li> Includes will never be generated |
| * <li> Imports will be generated for referenced types in other URIs |
| * </ul> |
| * @param types The list of commonj.sdo.Type objects to generate the XSD from |
| * @param aNamespaceToSchemaLocation map of namespaces to schemaLocations |
| * used for getting the value of the schemaLocation attribute of generated imports and includes |
| * @return String The generated XSD. |
| */ |
| public String generate(List types, Map<String, String> aNamespaceToSchemaLocation) { |
| if ((types == null) || (types.size() == 0)) { |
| throw new IllegalArgumentException("No Schema was generated from null or empty list of types."); |
| } |
| |
| String uri = null; |
| namespaceToSchemaLocation = aNamespaceToSchemaLocation; |
| |
| Type firstType = (Type)types.get(0); |
| if (firstType == null) { |
| throw new IllegalArgumentException("No Schema was generated from a list of types containing null elements"); |
| } else { |
| uri = firstType.getURI(); |
| } |
| allTypes = types; |
| generateSchema(uri, types); |
| |
| //Now we have a built schema model |
| Project p = new SchemaModelProject(); |
| Vector<Namespace> namespaces = generatedSchema.getNamespaceResolver().getNamespaces(); |
| for (int i = 0; i < namespaces.size(); i++) { |
| Namespace next = namespaces.get(i); |
| ((XMLDescriptor)p.getDescriptor(Schema.class)).getNamespaceResolver().put(next.getPrefix(), next.getNamespaceURI()); |
| } |
| |
| XMLLogin login = new XMLLogin(); |
| login.setDatasourcePlatform(new DOMPlatform()); |
| p.setDatasourceLogin(login); |
| XMLContext context = new XMLContext(p); |
| XMLMarshaller marshaller = context.createMarshaller(); |
| |
| StringWriter generatedSchemaWriter = new StringWriter(); |
| marshaller.marshal(generatedSchema, generatedSchemaWriter); |
| return generatedSchemaWriter.toString(); |
| } |
| |
| private void generateSchema(String uri, List typesWithSameUri) { |
| generatedSchema = new Schema(); |
| generatedSchema.setTargetNamespace(uri); |
| generatedSchema.setDefaultNamespace(uri); |
| |
| generatedSchema.setAttributeFormDefault(false); |
| generatedSchema.setElementFormDefault(true); |
| String javaPackage = null; |
| |
| for (int i = 0; i < typesWithSameUri.size(); i++) { |
| SDOType nextType = (SDOType)typesWithSameUri.get(i); |
| if (nextType.isSubType()) { |
| //A schema can not be generated because the following type has more than 1 base type + type |
| } |
| |
| if (!nextType.isDataType()) { |
| String fullName = nextType.getInstanceClassName(); |
| if (fullName != null) { |
| String nextPackage = null; |
| |
| int lastDot = fullName.lastIndexOf('.'); |
| if (lastDot != -1) { |
| nextPackage = fullName.substring(0, lastDot); |
| } |
| |
| if (nextPackage != null) { |
| javaPackage = nextPackage; |
| } |
| } |
| } |
| |
| if (nextType.isDataType()) { |
| //generate simple type |
| SimpleType generatedType = generateSimpleType(nextType); |
| generatedSchema.addTopLevelSimpleTypes(generatedType); |
| } else { |
| //generate complex type |
| ComplexType generatedType = generateComplexType(nextType); |
| generatedSchema.addTopLevelComplexTypes(generatedType); |
| |
| //generate global element for the complex type generated above |
| Element element = buildElementForComplexType(generatedSchema, generatedType); |
| if (element != null) { |
| generatedSchema.addTopLevelElement(element); |
| } |
| } |
| } |
| if (javaPackage != null) { |
| getPrefixForURI(SDOConstants.SDOJAVA_URL); |
| generatedSchema.getAttributesMap().put(SDOConstants.SDOJAVA_PACKAGE_QNAME, javaPackage); |
| } |
| } |
| |
| private SimpleType generateSimpleType(Type type) { |
| SDOType sdoType = (SDOType) type; |
| SimpleType simpleType = new SimpleType(); |
| |
| String xsdLocalName = sdoType.getXsdLocalName(); |
| if (xsdLocalName != null) { |
| simpleType.setName(xsdLocalName); |
| } else { |
| simpleType.setName(sdoType.getName()); |
| } |
| |
| if ((sdoType.getAppInfoElements() != null) && (sdoType.getAppInfoElements().size() > 0)) { |
| Annotation annotation = new Annotation(); |
| |
| annotation.setAppInfo(sdoType.getAppInfoElements()); |
| simpleType.setAnnotation(annotation); |
| } |
| |
| if ((xsdLocalName != null) && !(xsdLocalName.equals(sdoType.getName()))) { |
| String sdoXmlPrefix = getPrefixForURI(SDOConstants.SDOXML_URL); |
| QName qname = new QName(SDOConstants.SDOXML_URL, SDOConstants.SDOXML_NAME, sdoXmlPrefix); |
| simpleType.getAttributesMap().put(qname, sdoType.getName()); |
| } |
| |
| if ((sdoType.getAliasNames() != null) && (sdoType.getAliasNames().size() > 0)) { |
| String sdoXmlPrefix = getPrefixForURI(SDOConstants.SDOXML_URL); |
| String aliasNamesString = buildAliasNameString(sdoType.getAliasNames()); |
| QName qname = new QName(SDOConstants.SDOXML_URL, SDOConstants.SDOXML_ALIASNAME, sdoXmlPrefix); |
| simpleType.getAttributesMap().put(qname, aliasNamesString); |
| } |
| |
| Object value = sdoType.get(SDOConstants.JAVA_CLASS_PROPERTY); |
| if (value instanceof String) { |
| String sdoJavaPrefix = getPrefixForURI(SDOConstants.SDOJAVA_URL); |
| QName qname = new QName(SDOConstants.SDOJAVA_URL, SDOConstants.SDOJAVA_INSTANCECLASS, sdoJavaPrefix); |
| simpleType.getAttributesMap().put(qname, (String) value); |
| } |
| |
| SDOType baseType = null; |
| if (sdoType.isSubType()) { |
| baseType = (SDOType) sdoType.getBaseTypes().get(0); |
| } |
| |
| if (baseType != null) { |
| Restriction restriction = new Restriction(); |
| addTypeToListIfNeeded(sdoType, baseType); |
| QName schemaType = ((SDOTypeHelper)aHelperContext.getTypeHelper()).getXSDTypeFromSDOType(baseType); |
| |
| if (schemaType != null) { |
| String prefix = getPrefixStringForURI(schemaType.getNamespaceURI()); |
| restriction.setBaseType(prefix + schemaType.getLocalPart()); |
| } else { |
| String prefix = getPrefixStringForURI(baseType.getURI()); |
| restriction.setBaseType(prefix + baseType.getName()); |
| } |
| simpleType.setRestriction(restriction); |
| } |
| |
| return simpleType; |
| } |
| |
| private ComplexType generateComplexType(Type type) { |
| SDOType sdoType = (SDOType) type; |
| ComplexType complexType = new ComplexType(); |
| String xsdLocalName = sdoType.getXsdLocalName(); |
| if (xsdLocalName != null) { |
| complexType.setName(xsdLocalName); |
| } else { |
| complexType.setName(sdoType.getName()); |
| } |
| |
| if ((xsdLocalName != null) && !(xsdLocalName.equals(sdoType.getName()))) { |
| String sdoXmlPrefix = getPrefixForURI(SDOConstants.SDOXML_URL); |
| QName qname = new QName(SDOConstants.SDOXML_URL, SDOConstants.SDOXML_NAME, sdoXmlPrefix); |
| complexType.getAttributesMap().put(qname, sdoType.getName()); |
| } |
| |
| complexType.setAbstractValue(sdoType.isAbstract()); |
| if ((sdoType.getAppInfoElements() != null) && (sdoType.getAppInfoElements().size() > 0)) { |
| Annotation annotation = new Annotation(); |
| annotation.setAppInfo(sdoType.getAppInfoElements()); |
| complexType.setAnnotation(annotation); |
| } |
| |
| if ((sdoType.getAliasNames() != null) && (sdoType.getAliasNames().size() > 0)) { |
| String sdoXmlPrefix = getPrefixForURI(SDOConstants.SDOXML_URL); |
| String aliasNamesString = buildAliasNameString(sdoType.getAliasNames()); |
| |
| QName qname = new QName(SDOConstants.SDOXML_URL, SDOConstants.SDOXML_ALIASNAME, sdoXmlPrefix); |
| complexType.getAttributesMap().put(qname, aliasNamesString); |
| } |
| |
| complexType.setMixed(sdoType.isSequenced()); |
| Type baseType = null; |
| if (sdoType.isSubType()) { |
| baseType = (Type)sdoType.getBaseTypes().get(0); |
| |
| //baseName = base.getName(); |
| //String baseURI = ((Type)type.getBaseTypes().get(0)).getURI(); |
| //if (baseURI != type.getURI()) { |
| //need to add something to track referenced uris for includes/imports |
| //} |
| } |
| |
| if (baseType != null) { |
| addTypeToListIfNeeded(sdoType, baseType); |
| Extension extension = new Extension(); |
| QName schemaType = ((SDOTypeHelper)aHelperContext.getTypeHelper()).getXSDTypeFromSDOType(baseType); |
| |
| //fixed below for bug5893546 |
| if (schemaType != null) { |
| extension.setBaseType(getPrefixStringForURI(schemaType.getNamespaceURI()) + schemaType.getLocalPart()); |
| } else if ((baseType.getURI() == null) || (baseType.getURI().equalsIgnoreCase(generatedSchema.getTargetNamespace()))) { |
| extension.setBaseType(baseType.getName()); |
| } else { |
| extension.setBaseType(getPrefixStringForURI(baseType.getURI()) + baseType.getName()); |
| } |
| |
| buildElementsAndAttributes(extension, sdoType); |
| ComplexContent complexContent = new ComplexContent(); |
| complexContent.setExtension(extension); |
| complexType.setComplexContent(complexContent); |
| return complexType; |
| } |
| |
| buildElementsAndAttributes(complexType, sdoType); |
| |
| return complexType; |
| } |
| |
| private void buildElementsAndAttributes(Object owner, Type type) { |
| List properties = type.getDeclaredProperties(); |
| NestedParticle nestedParticle = null; |
| |
| if ((properties == null) || (properties.size() == 0)) { |
| if (type.isOpen()) { |
| nestedParticle = new Sequence(); |
| } else { |
| return; |
| } |
| } else { |
| if (type.isSequenced()) { |
| nestedParticle = new Choice(); |
| nestedParticle.setMaxOccurs(Occurs.UNBOUNDED); |
| } else { |
| nestedParticle = new Sequence(); |
| } |
| } |
| for (int i = 0; i < properties.size(); i++) { |
| Property nextProperty = (Property)properties.get(i); |
| |
| if (aHelperContext.getXSDHelper().isElement(nextProperty)) { |
| Element elem = buildElement(nextProperty, nestedParticle); |
| nestedParticle.addElement(elem); |
| } else if (aHelperContext.getXSDHelper().isAttribute(nextProperty)) { |
| Attribute attr = buildAttribute(nextProperty); |
| if (owner instanceof ComplexType) { |
| ((ComplexType)owner).getOrderedAttributes().add(attr); |
| } else if (owner instanceof Extension) { |
| ((Extension)owner).getOrderedAttributes().add(attr); |
| } |
| } |
| } |
| if (type.isOpen()) { |
| Any any = new Any(); |
| any.setProcessContents(AnyAttribute.LAX); |
| any.setMaxOccurs(Occurs.UNBOUNDED); |
| nestedParticle.addAny(any); |
| |
| AnyAttribute anyAttribute = new AnyAttribute(); |
| anyAttribute.setProcessContents(AnyAttribute.LAX); |
| if (owner instanceof ComplexType) { |
| ((ComplexType)owner).setAnyAttribute(anyAttribute); |
| } |
| } |
| |
| if (!nestedParticle.isEmpty()) { |
| if (owner instanceof ComplexType) { |
| ((ComplexType)owner).setTypeDefParticle((TypeDefParticle)nestedParticle); |
| //baseType.getAttributes().add(attr); |
| } else if (owner instanceof Extension) { |
| ((Extension)owner).setTypeDefParticle((TypeDefParticle)nestedParticle); |
| } |
| } |
| } |
| |
| private void addSimpleComponentAnnotations(SimpleComponent sc, Property property, boolean element) { |
| SDOProperty sdoProperty = (SDOProperty) property; |
| if (sdoProperty.isReadOnly()) { |
| String sdoXmlPrefix = getPrefixForURI(SDOConstants.SDOXML_URL); |
| QName qname = new QName(SDOConstants.SDOXML_URL, SDOConstants.SDOXML_READONLY, sdoXmlPrefix); |
| sc.getAttributesMap().put(qname, "true"); |
| } |
| if (sdoProperty.hasAliasNames()) { |
| String sdoXmlPrefix = getPrefixForURI(SDOConstants.SDOXML_URL); |
| String aliasNamesString = buildAliasNameString(sdoProperty.getAliasNames()); |
| QName qname = new QName(SDOConstants.SDOXML_URL, SDOConstants.SDOXML_ALIASNAME, sdoXmlPrefix); |
| sc.getAttributesMap().put(qname, aliasNamesString); |
| } |
| |
| String xsdLocalName = sdoProperty.getXsdLocalName(); |
| |
| if ((xsdLocalName != null) && !(xsdLocalName.equals(sdoProperty.getName()))) { |
| String sdoXmlPrefix = getPrefixForURI(SDOConstants.SDOXML_URL); |
| QName qname = new QName(SDOConstants.SDOXML_URL, SDOConstants.SDOXML_NAME, sdoXmlPrefix); |
| sc.getAttributesMap().put(qname, sdoProperty.getName()); |
| } |
| |
| if ((element && !sdoProperty.isContainment() && !sdoProperty.getType().isDataType()) || (!element && !sdoProperty.getType().isDataType())) { |
| String sdoXmlPrefix = getPrefixForURI(SDOConstants.SDOXML_URL); |
| String uri = sdoProperty.getType().getURI(); |
| String value = sdoProperty.getType().getName(); |
| if (uri != null) { |
| String typePrefix = getPrefixForURI(uri); |
| if (typePrefix != null) { |
| value = typePrefix + ":" + value; |
| } |
| } |
| QName qname = new QName(SDOConstants.SDOXML_URL, SDOConstants.SDOXML_PROPERTYTYPE, sdoXmlPrefix); |
| sc.getAttributesMap().put(qname, value); |
| } |
| |
| if (sdoProperty.getOpposite() != null) { |
| String value = sdoProperty.getOpposite().getName(); |
| String sdoXmlPrefix = getPrefixForURI(SDOConstants.SDOXML_URL); |
| QName qname = new QName(SDOConstants.SDOXML_URL, SDOConstants.SDOXML_OPPOSITEPROPERTY, sdoXmlPrefix); |
| sc.getAttributesMap().put(qname, value); |
| } |
| |
| Property xmlDataTypeProperty = aHelperContext.getTypeHelper().getOpenContentProperty(SDOConstants.SDOXML_URL, SDOConstants.SDOXML_DATATYPE); |
| Type dataType = (Type) sdoProperty.get(xmlDataTypeProperty); |
| if (dataType == null) { |
| dataType = getAutomaticDataTypeForType(sdoProperty.getType()); |
| } |
| if (dataType != null && !shouldSuppressDataType(sdoProperty, dataType)) { |
| String sdoXmlPrefix = getPrefixForURI(SDOConstants.SDOXML_URL); |
| QName qname = new QName(SDOConstants.SDOXML_URL, SDOConstants.SDOXML_DATATYPE, sdoXmlPrefix); |
| String dataTypeString = dataType.getName(); |
| if (dataType.getURI() != null) { |
| String dataTypePrefix = getPrefixForURI(dataType.getURI()); |
| if (dataTypePrefix != null) { |
| dataTypeString = dataTypePrefix + ":" + dataTypeString; |
| } |
| } |
| sc.getAttributesMap().put(qname, dataTypeString); |
| } |
| |
| if (element) { |
| String mimeType = (String) sdoProperty.get(SDOConstants.MIME_TYPE_PROPERTY); |
| if (mimeType != null) { |
| String prefix = getPrefixForURI(SDOConstants.MIMETYPE_URL); |
| QName qname = new QName(SDOConstants.XML_MIME_TYPE_QNAME.getNamespaceURI(), SDOConstants.XML_MIME_TYPE_QNAME.getLocalPart(), prefix); |
| sc.getAttributesMap().put(qname, mimeType); |
| } else { |
| mimeType = (String) sdoProperty.get(SDOConstants.MIME_TYPE_PROPERTY_PROPERTY); |
| if (mimeType != null) { |
| String prefix = getPrefixForURI(SDOConstants.ORACLE_SDO_URL); |
| QName qname = new QName(SDOConstants.XML_MIME_TYPE_PROPERTY_QNAME.getNamespaceURI(), SDOConstants.XML_MIME_TYPE_PROPERTY_QNAME.getLocalPart(), prefix); |
| sc.getAttributesMap().put(qname, mimeType); |
| } |
| } |
| } |
| } |
| |
| private boolean shouldSuppressDataType(SDOProperty prop, Type dataType){ |
| if(prop.isNullable()){ |
| SDOType type = prop.getType(); |
| if(dataType == SDOConstants.SDO_BOOLEANOBJECT && (type == SDOConstants.SDO_BOOLEAN || type == SDOConstants.SDO_BOOLEANOBJECT )){ |
| return true; |
| } |
| if(dataType == SDOConstants.SDO_BYTEOBJECT && (type == SDOConstants.SDO_BYTE || type == SDOConstants.SDO_BYTEOBJECT )){ |
| return true; |
| } |
| if(dataType == SDOConstants.SDO_CHARACTEROBJECT && (type == SDOConstants.SDO_CHARACTER || type == SDOConstants.SDO_CHARACTEROBJECT )){ |
| return true; |
| } |
| if(dataType == SDOConstants.SDO_DOUBLEOBJECT && (type == SDOConstants.SDO_DOUBLE || type == SDOConstants.SDO_DOUBLEOBJECT )){ |
| return true; |
| } |
| if(dataType == SDOConstants.SDO_FLOATOBJECT && (type == SDOConstants.SDO_FLOAT || type == SDOConstants.SDO_FLOATOBJECT )){ |
| return true; |
| } |
| if(dataType == SDOConstants.SDO_INTOBJECT && (type == SDOConstants.SDO_INT || type == SDOConstants.SDO_INTOBJECT )){ |
| return true; |
| } |
| if(dataType == SDOConstants.SDO_LONGOBJECT && (type == SDOConstants.SDO_LONG || type == SDOConstants.SDO_LONGOBJECT )){ |
| return true; |
| } |
| if(dataType == SDOConstants.SDO_SHORTOBJECT && (type == SDOConstants.SDO_SHORT || type == SDOConstants.SDO_SHORTOBJECT )){ |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| private String buildAliasNameString(List<String> aliasNames) { |
| StringBuilder aliasNamesStringBuilder = new StringBuilder(); |
| for (int i = 0, size = aliasNames.size(); i < size; i++) { |
| aliasNamesStringBuilder.append(aliasNames.get(i)); |
| if (i < (size - 1)) { |
| aliasNamesStringBuilder.append(' '); |
| } |
| } |
| return aliasNamesStringBuilder.toString(); |
| } |
| |
| private Element buildElement(Property property, NestedParticle nestedParticle) { |
| SDOProperty sdoProperty = (SDOProperty) property; |
| Element elem = new Element(); |
| String xsdLocalName = sdoProperty.getXsdLocalName(); |
| if (xsdLocalName != null) { |
| elem.setName(xsdLocalName); |
| } else { |
| elem.setName(sdoProperty.getName()); |
| } |
| elem.setMinOccurs(Occurs.ZERO); |
| elem.setNillable(sdoProperty.isNullable()); |
| if ((sdoProperty.getAppInfoElements() != null) && (sdoProperty.getAppInfoElements().size() > 0)) { |
| Annotation annotation = new Annotation(); |
| annotation.setAppInfo(sdoProperty.getAppInfoElements()); |
| elem.setAnnotation(annotation); |
| } |
| |
| // process default values that are defined in the schema (not via primitive numeric Object wrapped pseudo defaults) |
| if (sdoProperty.isDefaultSet()) { |
| if (!sdoProperty.isMany() && sdoProperty.getType().isDataType()) { |
| XMLConversionManager xmlConversionManager = ((SDOXMLHelper)aHelperContext.getXMLHelper()).getXmlConversionManager(); |
| elem.setDefaultValue(xmlConversionManager.convertObject(sdoProperty.getDefault(), ClassConstants.STRING, sdoProperty.getXsdType())); |
| } |
| |
| } |
| |
| addSimpleComponentAnnotations(elem, sdoProperty, true); |
| |
| /* |
| When containment is true, then DataObjects of that Type will appear as nested elements in an XML document. |
| When containment is false and the property's type is a DataObject, a URI reference |
| to the element containing the DataObject is used and an sdo:propertyType |
| declaration records the target type. Values in XML documents will be of the form |
| "#xpath" where the xpath is an SDO DataObject XPath subset. It is typical to |
| customize the declaration to IDREF if the target element has an attribute with type |
| customized to ID. |
| |
| [TYPE.NAME] is the type of the element. If property.type.dataType is true, |
| [TYPE.NAME] is the name of the XSD built in SimpleType corresponding to |
| property.type, where the prefix is for the xsd namespace. Otherwise, |
| [TYPE.NAME] is property.type.name where the tns: prefix is determined by the |
| namespace declaration for the Type's URI. |
| */ |
| Type schemaSDOType = null; |
| QName schemaType = sdoProperty.getXsdType(); |
| if (schemaType != null) { |
| schemaSDOType = aHelperContext.getTypeHelper().getType(schemaType.getNamespaceURI(), schemaType.getLocalPart()); |
| |
| if ((sdoProperty.getType() == SDOConstants.SDO_STRING) && (schemaSDOType != SDOConstants.SDO_STRING)) { |
| String sdoXmlPrefix = getPrefixForURI(SDOConstants.SDOXML_URL); |
| QName qname = new QName(SDOConstants.SDOXML_URL, SDOConstants.SDOXML_STRING_NAME, sdoXmlPrefix); |
| elem.getAttributesMap().put(qname, "true"); |
| } |
| } |
| if (!sdoProperty.isContainment() && !sdoProperty.getType().isDataType()) { |
| schemaType = SDOConstants.ANY_URI_QNAME; |
| } |
| |
| Type propertyType = sdoProperty.getType(); |
| |
| if (propertyType != null) { |
| if (sdoProperty.getContainingType() != null) { |
| addTypeToListIfNeeded(sdoProperty.getContainingType(), propertyType); |
| } |
| |
| if (schemaType == null) { |
| schemaType = ((SDOTypeHelper)aHelperContext.getTypeHelper()).getXSDTypeFromSDOType(propertyType); |
| } |
| |
| //get url for prefix in namespace resolver and map sure it is added to the schema if necessary |
| if (schemaType != null) { |
| elem.setType(getPrefixStringForURI(schemaType.getNamespaceURI()) + schemaType.getLocalPart()); |
| if (schemaSDOType != null) { |
| addTypeToListIfNeeded(sdoProperty.getContainingType(), schemaSDOType); |
| } |
| } else if ((propertyType.getURI() == null) || (propertyType.getURI().equalsIgnoreCase(generatedSchema.getTargetNamespace()))) { |
| String xsdTypeLocalName = ((SDOType)propertyType).getXsdLocalName(); |
| if (xsdTypeLocalName != null) { |
| elem.setType(xsdTypeLocalName); |
| } else { |
| elem.setType(propertyType.getName()); |
| } |
| } else { |
| String nameString = null; |
| String xsdTypeLocalName = ((SDOType)propertyType).getXsdLocalName(); |
| if (xsdTypeLocalName != null) { |
| nameString = xsdTypeLocalName; |
| } else { |
| nameString = propertyType.getName(); |
| } |
| |
| elem.setType(getPrefixStringForURI(propertyType.getURI()) + nameString); |
| } |
| } else { |
| elem.setType("anyURI"); |
| } |
| if (sdoProperty.isMany()) { |
| elem.setMaxOccurs(Occurs.UNBOUNDED); |
| } else if (nestedParticle.getMaxOccurs() == Occurs.UNBOUNDED) { |
| //this means property.isMany==false and the owning sequence of choice is unbounded Jira SDO-3 |
| String sdoXmlPrefix = getPrefixForURI(SDOConstants.SDOXML_URL); |
| QName qname = new QName(SDOConstants.SDOXML_URL, SDOConstants.SDOXML_MANY, sdoXmlPrefix); |
| elem.getAttributesMap().put(qname, "false"); |
| } |
| |
| return elem; |
| } |
| |
| private Attribute buildAttribute(Property property) { |
| Attribute attr = new Attribute(); |
| String xsdLocalName = ((SDOProperty)property).getXsdLocalName(); |
| if (xsdLocalName != null) { |
| attr.setName(xsdLocalName); |
| } else { |
| attr.setName(property.getName()); |
| } |
| |
| if ((((SDOProperty)property).getAppInfoElements() != null) && (((SDOProperty)property).getAppInfoElements().size() > 0)) { |
| Annotation annotation = new Annotation(); |
| annotation.setAppInfo(((SDOProperty)property).getAppInfoElements()); |
| attr.setAnnotation(annotation); |
| } |
| |
| // process default values that are defined in the schema (not via primitive numeric Object wrapped pseudo defaults) |
| if (((SDOProperty)property).isDefaultSet()) { |
| if (!property.isMany() && property.getType().isDataType()) { |
| XMLConversionManager xmlConversionManager = ((SDOXMLHelper)aHelperContext.getXMLHelper()).getXmlConversionManager(); |
| attr.setDefaultValue(xmlConversionManager.convertObject(property.getDefault(), ClassConstants.STRING, ((SDOProperty)property).getXsdType())); |
| } |
| } |
| addSimpleComponentAnnotations(attr, property, false); |
| |
| Type propertyType = property.getType(); |
| QName schemaType = ((SDOProperty)property).getXsdType(); |
| |
| if (schemaType != null) { |
| Type schemaSDOType = aHelperContext.getTypeHelper().getType(schemaType.getNamespaceURI(), schemaType.getLocalPart()); |
| |
| if ((property.getType() == SDOConstants.SDO_STRING) && (schemaSDOType != SDOConstants.SDO_STRING)) { |
| String sdoXmlPrefix = getPrefixForURI(SDOConstants.SDOXML_URL); |
| QName qname = new QName(SDOConstants.SDOXML_URL, SDOConstants.SDOXML_STRING_NAME, sdoXmlPrefix); |
| attr.getAttributesMap().put(qname, "true"); |
| } |
| } |
| |
| if (!property.getType().isDataType()) { |
| schemaType = SDOConstants.ANY_URI_QNAME; |
| } |
| |
| if (propertyType != null) { |
| if (property.getContainingType() != null) { |
| addTypeToListIfNeeded(property.getContainingType(), propertyType); |
| } |
| if (schemaType == null) { |
| schemaType = ((SDOTypeHelper)aHelperContext.getTypeHelper()).getXSDTypeFromSDOType(propertyType); |
| } |
| if (schemaType != null) { |
| attr.setType(getPrefixStringForURI(schemaType.getNamespaceURI()) + schemaType.getLocalPart()); |
| } else if ((propertyType.getURI() == null) || (propertyType.getURI().equalsIgnoreCase(generatedSchema.getTargetNamespace()))) { |
| String xsdTypeLocalName = ((SDOType)propertyType).getXsdLocalName(); |
| if (xsdTypeLocalName != null) { |
| attr.setType(xsdTypeLocalName); |
| } else { |
| attr.setType(propertyType.getName()); |
| } |
| } else { |
| String nameString = null; |
| String xsdTypeLocalName = ((SDOType)propertyType).getXsdLocalName(); |
| |
| if (xsdTypeLocalName != null) { |
| nameString = xsdTypeLocalName; |
| } else { |
| nameString = propertyType.getName(); |
| } |
| |
| attr.setType(getPrefixStringForURI(propertyType.getURI()) + nameString); |
| } |
| |
| //get url for prefix in namespace resolver and map sure it is added to the schema if necessary |
| |
| /* |
| if (schemaType != null) { |
| attr.setType(getPrefixStringForURI(schemaType.getNamespaceURI()) + schemaType.getLocalPart()); |
| } else { |
| attr.setType(propertyType.getName()); |
| }*/ |
| } |
| |
| return attr; |
| } |
| |
| private void addTypeToListIfNeeded(Type sourceType, Type targetType) { |
| if ((targetType.getURI() != null) && !targetType.getURI().equals(SDOConstants.SDO_URL) && !targetType.getURI().equals(SDOConstants.SDOJAVA_URL) && !targetType.getURI().equals(SDOConstants.SDOXML_URL)) { |
| boolean alreadyGenerated = allTypes.contains(targetType); |
| String schemaLocation = null; |
| if (namespaceToSchemaLocation != null) { |
| schemaLocation = namespaceToSchemaLocation.get(targetType.getURI()); |
| |
| if (targetType.getURI().equals(generatedSchema.getTargetNamespace())) { |
| if (!alreadyGenerated) { |
| allTypes.add(targetType); |
| } |
| } else { |
| if(!importExists(generatedSchema.getImports(), schemaLocation)){ |
| Import theImport = new Import(); |
| theImport.setSchemaLocation(schemaLocation); |
| theImport.setNamespace(targetType.getURI()); |
| generatedSchema.getImports().add(theImport); |
| } |
| } |
| } else if (schemaLocationResolver != null) { |
| schemaLocation = schemaLocationResolver.resolveSchemaLocation(sourceType, targetType); |
| if (schemaLocation != null) { |
| if (targetType.getURI().equals(generatedSchema.getTargetNamespace())) { |
| if(!importExists(generatedSchema.getIncludes(), schemaLocation)){ |
| Include include = new Include(); |
| include.setSchemaLocation(schemaLocation); |
| generatedSchema.getIncludes().add(include); |
| // 20060713 remove type from List of types when adding an include |
| allTypes.remove(targetType); |
| } |
| } else { |
| if(!importExists(generatedSchema.getImports(), schemaLocation)){ |
| Import theImport = new Import(); |
| theImport.setSchemaLocation(schemaLocation); |
| theImport.setNamespace(targetType.getURI()); |
| generatedSchema.getImports().add(theImport); |
| } |
| } |
| } else { |
| if (!alreadyGenerated) { |
| //we can #1 add to list of allTypes or #2 make an appropriate include |
| if (targetType.getURI().equals(generatedSchema.getTargetNamespace())) { |
| allTypes.add(targetType); |
| } |
| } |
| } |
| } else { |
| if (!alreadyGenerated) { |
| //we can #1 add to list of allTypes or #2 make an appropriate include |
| if (targetType.getURI().equals(generatedSchema.getTargetNamespace())) { |
| allTypes.add(targetType); |
| } |
| } |
| } |
| } |
| } |
| |
| private Element buildElementForComplexType(Schema schema, ComplexType type) { |
| Element elem = new Element(); |
| String name = type.getName(); |
| if (name == null) { |
| return null; |
| } |
| String lowerName = Character.toLowerCase(name.charAt(0)) + name.substring(1, name.length()); |
| |
| Element exists = schema.getTopLevelElements().get(lowerName); |
| if (exists != null) { |
| elem.setName(name); |
| } else { |
| elem.setName(lowerName); |
| } |
| |
| elem.setType(type.getName()); |
| |
| return elem; |
| } |
| |
| private String getPrefixStringForURI(String uri) { |
| if(null == uri || SDOConstants.EMPTY_STRING.equals(uri)) { |
| return SDOConstants.EMPTY_STRING; |
| } |
| String prefix = getPrefixForURI(uri); |
| if (prefix == null) { |
| return SDOConstants.EMPTY_STRING; |
| } else { |
| return prefix + ":"; |
| } |
| } |
| |
| private String getPrefixForURI(String uri) { |
| String prefix = null; |
| if (uri.equals(generatedSchema.getTargetNamespace())) { |
| return null; |
| } else if (uri.equals(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI)) { |
| return XMLConstants.SCHEMA_PREFIX; |
| } else if (uri.equals(SDOConstants.SDO_URL)) { |
| prefix = generatedSchema.getNamespaceResolver().resolveNamespaceURI(uri); |
| if (prefix == null) { |
| prefix = generatedSchema.getNamespaceResolver().generatePrefix(SDOConstants.SDO_PREFIX); |
| generatedSchema.getNamespaceResolver().put(prefix, uri); |
| } |
| } else if (uri.equals(SDOConstants.SDOJAVA_URL)) { |
| prefix = generatedSchema.getNamespaceResolver().resolveNamespaceURI(uri); |
| if (prefix == null) { |
| prefix = generatedSchema.getNamespaceResolver().generatePrefix(SDOConstants.SDOJAVA_PREFIX); |
| generatedSchema.getNamespaceResolver().put(prefix, uri); |
| } |
| } else if (uri.equals(SDOConstants.SDOXML_URL)) { |
| prefix = generatedSchema.getNamespaceResolver().resolveNamespaceURI(uri); |
| if (prefix == null) { |
| prefix = generatedSchema.getNamespaceResolver().generatePrefix(SDOConstants.SDOXML_PREFIX); |
| generatedSchema.getNamespaceResolver().put(prefix, uri); |
| } |
| } |
| if (prefix == null) { |
| prefix = generatedSchema.getNamespaceResolver().resolveNamespaceURI(uri); |
| } |
| if (prefix != null) { |
| return prefix; |
| } else { |
| String generatedPrefix = generatedSchema.getNamespaceResolver().generatePrefix(); |
| generatedSchema.getNamespaceResolver().put(generatedPrefix, uri); |
| return generatedPrefix; |
| } |
| } |
| |
| private Type getAutomaticDataTypeForType(Type theType) { |
| // Section 10.1 of the spec |
| //For the SDO Java Types, the corresponding base SDO Type is used. For the SDO Java |
| // Types, and for SDO Date, an sdo:dataType annotation is generated on the XML attribute |
| // or element referring to the SDO Type. |
| if (theType == SDOConstants.SDO_BOOLEANOBJECT) { |
| return SDOConstants.SDO_BOOLEANOBJECT; |
| } else if (theType == SDOConstants.SDO_BYTEOBJECT) { |
| return SDOConstants.SDO_BYTEOBJECT; |
| } else if (theType == SDOConstants.SDO_CHARACTEROBJECT) { |
| return SDOConstants.SDO_CHARACTEROBJECT; |
| } else if (theType == SDOConstants.SDO_DOUBLEOBJECT) { |
| return SDOConstants.SDO_DOUBLEOBJECT; |
| } else if (theType == SDOConstants.SDO_INTOBJECT) { |
| return SDOConstants.SDO_INTOBJECT; |
| } else if (theType == SDOConstants.SDO_FLOATOBJECT) { |
| return SDOConstants.SDO_FLOATOBJECT; |
| } else if (theType == SDOConstants.SDO_LONGOBJECT) { |
| return SDOConstants.SDO_LONGOBJECT; |
| } else if (theType == SDOConstants.SDO_SHORTOBJECT) { |
| return SDOConstants.SDO_SHORTOBJECT; |
| } else if (theType == SDOConstants.SDO_DATE) { |
| return SDOConstants.SDO_DATE; |
| } else if (theType == SDOConstants.SDO_DATETIME) { |
| return SDOConstants.SDO_DATETIME; |
| } |
| return null; |
| } |
| |
| private boolean importExists(java.util.List imports, String schemaName){ |
| for(int i=0;i < imports.size();i++){ |
| //Cast to the parent class, since this could be an Include or an Import |
| Include nextImport = (Include)imports.get(i); |
| if(nextImport.getSchemaLocation() != null && nextImport.getSchemaLocation().equals(schemaName)){ |
| return true; |
| } |
| } |
| return false; |
| } |
| } |