summaryrefslogtreecommitdiffstats
path: root/sdo-java/branches/sdo-1.0-incubating/impl/src/main/java/org/apache/tuscany/sdo/helper/SDOXSDEcoreBuilder.java
diff options
context:
space:
mode:
Diffstat (limited to 'sdo-java/branches/sdo-1.0-incubating/impl/src/main/java/org/apache/tuscany/sdo/helper/SDOXSDEcoreBuilder.java')
-rw-r--r--sdo-java/branches/sdo-1.0-incubating/impl/src/main/java/org/apache/tuscany/sdo/helper/SDOXSDEcoreBuilder.java831
1 files changed, 831 insertions, 0 deletions
diff --git a/sdo-java/branches/sdo-1.0-incubating/impl/src/main/java/org/apache/tuscany/sdo/helper/SDOXSDEcoreBuilder.java b/sdo-java/branches/sdo-1.0-incubating/impl/src/main/java/org/apache/tuscany/sdo/helper/SDOXSDEcoreBuilder.java
new file mode 100644
index 0000000000..906a35a4c8
--- /dev/null
+++ b/sdo-java/branches/sdo-1.0-incubating/impl/src/main/java/org/apache/tuscany/sdo/helper/SDOXSDEcoreBuilder.java
@@ -0,0 +1,831 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sdo.helper;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.xml.XMLConstants;
+
+import org.apache.tuscany.sdo.SDOExtendedMetaData;
+import org.apache.tuscany.sdo.impl.AttributeImpl;
+import org.apache.tuscany.sdo.impl.SDOFactoryImpl.SDOEcoreFactory;
+import org.apache.tuscany.sdo.model.ModelFactory;
+import org.apache.tuscany.sdo.api.SDOUtil;
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EDataType;
+import org.eclipse.emf.ecore.EEnum;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.ecore.util.ExtendedMetaData;
+import org.eclipse.emf.ecore.util.EcoreUtil.UsageCrossReferencer;
+import org.eclipse.xsd.XSDComplexTypeDefinition;
+import org.eclipse.xsd.XSDComponent;
+import org.eclipse.xsd.XSDConcreteComponent;
+import org.eclipse.xsd.XSDElementDeclaration;
+import org.eclipse.xsd.XSDFeature;
+import org.eclipse.xsd.XSDNamedComponent;
+import org.eclipse.xsd.XSDParticle;
+import org.eclipse.xsd.XSDSchema;
+import org.eclipse.xsd.XSDSimpleTypeDefinition;
+import org.eclipse.xsd.XSDTerm;
+import org.eclipse.xsd.XSDTypeDefinition;
+import org.eclipse.xsd.ecore.EcoreXMLSchemaBuilder;
+import org.eclipse.xsd.util.XSDResourceFactoryImpl;
+import org.eclipse.xsd.util.XSDResourceImpl;
+import org.eclipse.xsd.util.XSDSchemaLocator;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+public class SDOXSDEcoreBuilder extends BaseSDOXSDEcoreBuilder
+{
+ protected boolean replaceConflictingTypes = false;
+
+ public SDOXSDEcoreBuilder(ExtendedMetaData extendedMetaData, boolean replaceConflictingTypes)
+ {
+ super(extendedMetaData);
+ ecoreFactory = new SDOEcoreFactory();
+ this.replaceConflictingTypes = replaceConflictingTypes;
+ populateTypeToTypeObjectMap((EPackage)ModelFactory.INSTANCE);
+ }
+
+ /**
+ * Overrides method in EMF. This will cause the SDO Properties to be in the
+ * order in which the Attributes appeared in the XSD.
+ */
+ protected boolean useSortedAttributes()
+ {
+ return false;
+ }
+
+ /*
+ * Required for Java 1.4.2 support
+ * Node#lookupPrefix is only available since DOM Level 3 (Java 5)
+ * and it doesn't return rebound prefix.
+ * XSDConstants.lookupQualifier isn't supposed to return rebound prefix either.
+ * This lookupPrefix returns any bound prefix no matter rebound to other NameSpace or not, for {@link #getEPackage}.
+ */
+ static protected String lookupPrefix(Node element, String namespaceURI) {
+ String prefix = element.getPrefix();
+ if (prefix != null && namespaceURI != null && namespaceURI.equals(element.getNamespaceURI()))
+ return prefix;
+ NamedNodeMap attributes = element.getAttributes();
+ if (attributes != null)
+ for (int index = attributes.getLength(); index != 0;) {
+ Node attribute = attributes.item(--index);
+ if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(attribute.getNamespaceURI()) && attribute.getNodeValue().equals(namespaceURI)
+ && XMLConstants.XMLNS_ATTRIBUTE.equals(attribute.getPrefix()))
+ return attribute.getLocalName();
+ }
+ for (Node parent; (parent = element.getParentNode()) != null; element = parent)
+ if (parent.getNodeType() == Node.ELEMENT_NODE)
+ return lookupPrefix(parent, namespaceURI);
+ return null;
+ }
+
+ public EPackage getEPackage(XSDNamedComponent xsdNamedComponent) {
+ XSDSchema containingXSDSchema = xsdNamedComponent.getSchema();
+ String targetNamespace = containingXSDSchema == null ?
+ xsdNamedComponent.getTargetNamespace() : containingXSDSchema.getTargetNamespace();
+ EPackage ePackage = (EPackage) targetNamespaceToEPackageMap.get(targetNamespace);
+ if (ePackage != null)
+ return ePackage;
+ ePackage = super.getEPackage(xsdNamedComponent);
+ String nsPrefix = lookupPrefix(xsdNamedComponent.getElement(), targetNamespace);
+ if (nsPrefix != null)
+ ePackage.setNsPrefix(nsPrefix);
+ return ePackage;
+ }
+
+ public EClassifier getEClassifier(XSDTypeDefinition xsdTypeDefinition) {
+ EClassifier eClassifier = null;
+ if (xsdTypeDefinition != null)
+ {
+ if (rootSchema.getSchemaForSchemaNamespace().equals(xsdTypeDefinition.getTargetNamespace())) {
+ eClassifier =
+ getBuiltInEClassifier(xsdTypeDefinition.getURI(), xsdTypeDefinition.getName());
+ }
+ else if (xsdTypeDefinition.getContainer() == null) {
+ EPackage pkg = extendedMetaData.getPackage(xsdTypeDefinition.getTargetNamespace());
+ if(pkg != null) {
+ eClassifier = pkg.getEClassifier(xsdTypeDefinition.getName());
+ }
+ }
+ }
+ if (eClassifier == null) {
+ eClassifier = super.getEClassifier(xsdTypeDefinition);
+ }
+ return eClassifier;
+ }
+
+ public EDataType getEDataType(XSDSimpleTypeDefinition xsdSimpleTypeDefinition) {
+ EDataType eClassifier = null;
+ if (xsdSimpleTypeDefinition != null && rootSchema.getSchemaForSchemaNamespace().equals(xsdSimpleTypeDefinition.getTargetNamespace())) {
+ eClassifier =
+ (EDataType)getBuiltInEClassifier(
+ xsdSimpleTypeDefinition.getURI(),
+ xsdSimpleTypeDefinition.getName());
+ } else {
+ eClassifier = super.getEDataType(xsdSimpleTypeDefinition);
+ }
+ return (EDataType)eClassifier;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.xsd.ecore.XSDEcoreBuilder#createResourceSet()
+ */
+ protected ResourceSet createResourceSet() {
+ ResourceSet result = super.createResourceSet();
+ result.getResourceFactoryRegistry().getExtensionToFactoryMap().put("*", new XSDResourceFactoryImpl());
+ result.getAdapterFactories().add(new XSDSchemaAdapterFactoryImpl());
+
+ EList resources = result.getResources();
+ for (Iterator iter = targetNamespaceToEPackageMap.entrySet().iterator(); iter.hasNext();) {
+ Map.Entry mapEntry = (Map.Entry)iter.next();
+ EPackage ePackage = (EPackage)mapEntry.getValue();
+ Resource resource = ePackage.eResource();
+ if (resource != null) {
+ resources.add(resource);
+ }
+ }
+ return result;
+ }
+
+ protected EClassifier getBuiltInEClassifier(String namespace, String name)
+ {
+ EClassifier eClassifier = null;
+ if ("base64Binary".equals(name)) {
+ eClassifier = (EClassifier)AttributeImpl.INTERNAL_BASE64_BYTES;
+ }
+ else if ("QName".equals(name)) {
+ eClassifier = (EClassifier)AttributeImpl.INTERNAL_QNAME;
+ }
+ else {
+ eClassifier = (EClassifier)SDOUtil.getXSDSDOType(name);
+ }
+
+ if (eClassifier == null)
+ eClassifier = super.getBuiltInEClassifier(namespace, name);
+ return eClassifier;
+ }
+
+ private void updateReferences(EObject oldEObject, EObject newEObject)
+ {
+ Collection usages = UsageCrossReferencer.find(oldEObject, targetNamespaceToEPackageMap.values());
+ for (Iterator iter = usages.iterator(); iter.hasNext(); )
+ {
+ EStructuralFeature.Setting setting = (EStructuralFeature.Setting)iter.next();
+ EObject referencingEObject = setting.getEObject();
+ EStructuralFeature eStructuralFeature = setting.getEStructuralFeature();
+ if (eStructuralFeature.isChangeable())
+ {
+ if (eStructuralFeature.isMany())
+ {
+ List refList = (List)referencingEObject.eGet(eStructuralFeature);
+ int refIndex = refList.indexOf(oldEObject);
+ if (refIndex != -1) refList.set(refIndex, newEObject);
+ }
+ else
+ {
+ referencingEObject.eSet(eStructuralFeature, newEObject);
+ }
+ }
+ }
+ }
+
+ private XSDTypeDefinition getXSDTypeDefinition(EClassifier eClassifier)
+ {
+ //TODO Maybe we should create a reverse (eModelElementToXSDComponentMap) for better performance.
+ // Use a HashMap subclass for xsdComponentToEModelElementMap that overrides put() to also add the
+ // reverse mapping in eModelElementToXSDComponentMap
+ XSDTypeDefinition xsdTypeDefinition = null;
+ for (Iterator i = xsdComponentToEModelElementMap.entrySet().iterator(); i.hasNext(); )
+ {
+ Entry e = (Entry) i.next();
+ if (eClassifier == e.getValue())
+ {
+ xsdTypeDefinition = (XSDTypeDefinition)e.getKey();
+ break;
+ }
+ }
+ return xsdTypeDefinition;
+ }
+
+ private boolean sameType(XSDTypeDefinition t1, XSDTypeDefinition t2)
+ {
+ XSDConcreteComponent n1 = t1, n2 = t2;
+ while (n1 != null && n2 != null)
+ {
+ if (n1.eClass() != n2.eClass()) break;
+ if (n1 instanceof XSDNamedComponent /*&& n2 instanceof XSDNamedComponent*/)
+ {
+ String s1 = ((XSDNamedComponent)n1).getName();
+ String s2 = ((XSDNamedComponent)n2).getName();
+ if (s1 == null ? s1 != s2 : !s1.equals(s2)) break;
+ }
+ n1 = n1.getContainer();
+ n2 = n2.getContainer();
+ }
+ return n1 == null && n2 == null;
+ }
+
+ protected void removeDuplicateEClassifier(EClassifier eClassifier, XSDTypeDefinition xsdTypeDefinition)
+ {
+ EPackage ePackage = eClassifier.getEPackage();
+ List eClassifiers = ePackage.getEClassifiers();
+ String name = eClassifier.getName();
+ int size = eClassifiers.size();
+ for (int index = eClassifiers.indexOf(eClassifier); ++index < size; )
+ {
+ EClassifier nextEClassifier = (EClassifier)eClassifiers.get(index);
+ if (!name.equals(nextEClassifier.getName())) break;
+ if (extendedMetaData.getName(eClassifier).equals(extendedMetaData.getName(nextEClassifier)))
+ {
+ XSDTypeDefinition nextXSDTypeDefinition = getXSDTypeDefinition(nextEClassifier);
+ if (!sameType(nextXSDTypeDefinition, xsdTypeDefinition))
+ {
+ //System.out.println("###EClassifier mismatch: ");
+ //System.out.println(" old: " + extendedMetaData.getName(nextEClassifier));
+ //System.out.println(" new: " + extendedMetaData.getName(eClassifier));
+ continue;
+ }
+ eClassifiers.remove(index);
+ updateReferences(nextEClassifier, eClassifier);
+ break;
+ }
+ }
+ }
+
+ protected void removeDuplicateDocumentRootFeature(EClass eClass, EStructuralFeature eStructuralFeature)
+ {
+ List eStructuralFeatures = eClass.getEStructuralFeatures();
+ int last = eStructuralFeatures.size() - 1;
+ String name = extendedMetaData.getName(eStructuralFeature);
+ for (int index = 0; index < last; index++)
+ {
+ EStructuralFeature otherEStructuralFeature = (EStructuralFeature)eStructuralFeatures.get(index);
+ if (name.equals(extendedMetaData.getName(otherEStructuralFeature)))
+ {
+ if (otherEStructuralFeature.eClass() != eStructuralFeature.eClass())
+ {
+ //System.out.println("###EStructuralFeature mismatch: ");
+ //System.out.println(" old: " + extendedMetaData.getName(otherEStructuralFeature));
+ //System.out.println(" new: " + extendedMetaData.getName(eStructuralFeature));
+ continue;
+ }
+ eStructuralFeatures.remove(index);
+ updateReferences(otherEStructuralFeature, eStructuralFeature);
+ break;
+ }
+ }
+ }
+
+ public EClass computeEClass(XSDComplexTypeDefinition xsdComplexTypeDefinition) {
+ if (xsdComplexTypeDefinition == null) return super.computeEClass(xsdComplexTypeDefinition);
+ EPackage ePackage = (EPackage)targetNamespaceToEPackageMap.get(xsdComplexTypeDefinition.getTargetNamespace());
+ if (ePackage != null && TypeHelperImpl.getBuiltInModels().contains(ePackage)) {
+ EClassifier eclassifier = ePackage.getEClassifier(xsdComplexTypeDefinition.getName());
+ if (eclassifier != null) return (EClass)eclassifier;
+ }
+ EClass eClass = super.computeEClass(xsdComplexTypeDefinition);
+ if (replaceConflictingTypes) removeDuplicateEClassifier(eClass, xsdComplexTypeDefinition);
+ String aliasNames = getEcoreAttribute(xsdComplexTypeDefinition.getElement(), "aliasName");
+ if (aliasNames != null) {
+ SDOExtendedMetaData.INSTANCE.setAliasNames(eClass, aliasNames);
+ }
+ return eClass;
+ }
+
+ protected EClassifier computeEClassifier(XSDTypeDefinition xsdTypeDefinition) {
+ if (xsdTypeDefinition == null) return super.computeEClassifier(xsdTypeDefinition);
+ EPackage ePackage = (EPackage)targetNamespaceToEPackageMap.get(xsdTypeDefinition.getTargetNamespace());
+ if (ePackage != null && TypeHelperImpl.getBuiltInModels().contains(ePackage)) {
+ EClassifier eclassifier = ePackage.getEClassifier(xsdTypeDefinition.getName());
+ if (eclassifier != null) return eclassifier;
+ }
+ EClassifier eclassifier = super.computeEClassifier(xsdTypeDefinition);
+ EClassifier etype = (EClassifier) typeToTypeObjectMap.get(eclassifier);
+ String aliasNames = getEcoreAttribute(xsdTypeDefinition.getElement(), "aliasName");
+ if (aliasNames != null) {
+ SDOExtendedMetaData.INSTANCE.setAliasNames(eclassifier, aliasNames);
+ if (etype != null) {
+ SDOExtendedMetaData.INSTANCE.setAliasNames(etype, aliasNames);
+ }
+ }
+ return eclassifier;
+ }
+
+ protected EDataType computeEDataType(XSDSimpleTypeDefinition xsdSimpleTypeDefinition) {
+ if (xsdSimpleTypeDefinition == null) return super.computeEDataType(xsdSimpleTypeDefinition);
+ EPackage ePackage = (EPackage)targetNamespaceToEPackageMap.get(xsdSimpleTypeDefinition.getTargetNamespace());
+ if (ePackage != null && TypeHelperImpl.getBuiltInModels().contains(ePackage)) {
+ EClassifier eclassifier = ePackage.getEClassifier(xsdSimpleTypeDefinition.getName());
+ if (eclassifier != null) return (EDataType)eclassifier;
+ }
+ EDataType eDataType = super.computeEDataType(xsdSimpleTypeDefinition);
+ if (replaceConflictingTypes) removeDuplicateEClassifier(eDataType, xsdSimpleTypeDefinition);
+ String aliasNames = getEcoreAttribute(xsdSimpleTypeDefinition.getElement(), "aliasName");
+ if (aliasNames != null) {
+ SDOExtendedMetaData.INSTANCE.setAliasNames(eDataType, aliasNames);
+ }
+ return eDataType;
+ }
+
+ protected EEnum computeEEnum(XSDSimpleTypeDefinition xsdSimpleTypeDefinition) {
+ return null;
+ }
+
+ protected EStructuralFeature createFeature(EClass eClass, String name, EClassifier type, XSDComponent xsdComponent, int minOccurs, int maxOccurs) {
+ EStructuralFeature feature = super.createFeature(eClass, name, type, xsdComponent, minOccurs, maxOccurs);
+
+ if (xsdComponent instanceof XSDParticle) {
+ XSDTerm xsdTerm = ((XSDParticle)xsdComponent).getTerm();
+ if (xsdTerm instanceof XSDElementDeclaration && ((XSDElementDeclaration)xsdTerm).isNillable())
+ EcoreUtil.setAnnotation(feature, ExtendedMetaData.ANNOTATION_URI, "nillable", "true");
+ }
+
+ //FB What is the following for?
+ if (feature instanceof EReference)
+ {
+ EReference eReference = (EReference)feature;
+ if (xsdComponent != null && xsdComponent instanceof XSDParticle)
+ {
+ XSDTerm xsdTerm = ((XSDParticle)xsdComponent).getTerm();
+ if (xsdTerm instanceof XSDElementDeclaration)
+ {
+ XSDTypeDefinition elementTypeDefinition = getEffectiveTypeDefinition(xsdComponent, (XSDElementDeclaration)xsdTerm);
+ EClassifier eClassifier = getEClassifier(elementTypeDefinition);
+ if (elementTypeDefinition instanceof XSDSimpleTypeDefinition && eClassifier instanceof EClass)
+ {
+ eReference.setContainment(true);
+ }
+ }
+ }
+ }
+
+ feature.setName(name); // this is needed because super.createFeature() does EMF name mangling (toLower)
+
+ if (replaceConflictingTypes && "".equals(extendedMetaData.getName(eClass)))
+ removeDuplicateDocumentRootFeature(eClass, feature);
+
+ if (xsdComponent != null)
+ {
+ String aliasNames = getEcoreAttribute(xsdComponent.getElement(), "aliasName");
+ if (aliasNames != null)
+ {
+ SDOExtendedMetaData.INSTANCE.setAliasNames(feature, aliasNames);
+ }
+ }
+ return feature;
+ }
+
+ protected String getInstanceClassName(XSDTypeDefinition typeDefinition, EDataType baseEDataType) {
+ String name = getEcoreAttribute(typeDefinition, "extendedInstanceClass");
+ return (name != null) ? name : super.getInstanceClassName(typeDefinition, baseEDataType);
+ }
+
+ protected String getEcoreAttribute(Element element, String attribute)
+ {
+ String sdoAttribute = null;
+
+ if ("name".equals(attribute))
+ sdoAttribute = "name";
+ else if ("opposite".equals(attribute))
+ sdoAttribute = "oppositeProperty";
+ else if ("mixed".equals(attribute))
+ sdoAttribute = "sequence";
+ else if ("string".equals(attribute))
+ sdoAttribute = "string";
+ else if ("changeable".equals(attribute))
+ sdoAttribute = "readOnly";
+ else if ("aliasName".equals(attribute))
+ sdoAttribute = "aliasName";
+
+ if (sdoAttribute != null)
+ {
+ String value =
+ element != null && element.hasAttributeNS("commonj.sdo/xml", sdoAttribute) ?
+ element.getAttributeNS("commonj.sdo/xml", sdoAttribute) :
+ null;
+ if ("changeable".equals(attribute)) {
+ if ("true".equals(value)) value = "false";
+ else if ("false".equals(value)) value = "true";
+ }
+ return value;
+ }
+
+ if ("package".equals(attribute))
+ sdoAttribute = "package";
+ else if ("instanceClass".equals(attribute))
+ sdoAttribute = "instanceClass";
+ else if ("extendedInstanceClass".equals(attribute))
+ sdoAttribute = "extendedInstanceClass";
+ else if ("nestedInterfaces".equals(attribute))
+ sdoAttribute = "nestedInterfaces";
+
+ if (sdoAttribute != null)
+ {
+ return
+ element != null && element.hasAttributeNS("commonj.sdo/java", sdoAttribute) ?
+ element.getAttributeNS("commonj.sdo/java", sdoAttribute) :
+ null;
+ }
+
+ return super.getEcoreAttribute(element, attribute);
+ }
+
+ /*
+ protected String getEcoreAttribute(XSDConcreteComponent xsdConcreteComponent, String attribute)
+ {
+ String value = super.getEcoreAttribute(xsdConcreteComponent, attribute);
+ if ("package".equals(attribute) && value == null)
+ {
+ XSDSchema xsdSchema = (XSDSchema)xsdConcreteComponent;
+ value = getDefaultPackageName(xsdSchema.getTargetNamespace());
+ }
+ return value;
+ }
+ */
+
+ protected XSDTypeDefinition getEcoreTypeQNameAttribute(XSDConcreteComponent xsdConcreteComponent, String attribute)
+ {
+ if (xsdConcreteComponent == null) return null;
+ String sdoAttribute = null;
+
+ if ("reference".equals(attribute)) sdoAttribute = "propertyType";
+ if ("dataType".equals(attribute)) sdoAttribute = "dataType";
+
+ if (sdoAttribute != null)
+ {
+ Element element = xsdConcreteComponent.getElement();
+ return element == null ? null : getEcoreTypeQNameAttribute(xsdConcreteComponent, element, "commonj.sdo/xml", sdoAttribute);
+ }
+
+ return super.getEcoreTypeQNameAttribute(xsdConcreteComponent, attribute);
+ }
+
+ /**
+ * Override default EMF behavior so that the name is not mangled.
+ */
+ protected String validName(String name, int casing, String prefix) {
+ return name;
+ }
+
+ /**
+ * Override default EMF name mangling for anonymous types (simple and complex)
+ */
+ protected String validAliasName(XSDTypeDefinition xsdTypeDefinition, boolean isUpperCase) {
+ return getAliasName(xsdTypeDefinition);
+ }
+
+ protected String getAliasName(XSDNamedComponent xsdNamedComponent) {
+ String result = xsdNamedComponent.getName();
+ if (result == null)
+ {
+ XSDConcreteComponent container = xsdNamedComponent.getContainer();
+ if (container instanceof XSDNamedComponent)
+ {
+ result = getAliasName((XSDNamedComponent)container);
+ }
+ }
+ return result;
+ }
+
+ protected XSDTypeDefinition getEffectiveTypeDefinition(XSDComponent xsdComponent, XSDFeature xsdFeature) {
+ XSDTypeDefinition typeDef = getEcoreTypeQNameAttribute(xsdComponent, "dataType");
+
+ String isString = getEcoreAttribute(xsdComponent, xsdFeature, "string");
+ if ("true".equalsIgnoreCase(isString)) {
+ typeDef =
+ xsdFeature.resolveSimpleTypeDefinition(rootSchema.getSchemaForSchemaNamespace(), "string");
+ }
+ if (typeDef == null)
+ typeDef = xsdFeature.getType();
+ return typeDef;
+ }
+
+ /**
+ * Override EMF algorithm.
+ */
+ public String qualifiedPackageName(String namespace)
+ {
+ return getDefaultPackageName(namespace);
+ }
+
+ //Code below here to provide common URI to java packagname
+
+ public static String uncapNameStatic(String name)
+ {
+ if (name.length() == 0)
+ {
+ return name;
+ }
+ else
+ {
+ String lowerName = name.toLowerCase();
+ int i;
+ for (i = 0; i < name.length(); i++)
+ {
+ if (name.charAt(i) == lowerName.charAt(i))
+ {
+ break;
+ }
+ }
+ if (i > 1 && i < name.length() && !Character.isDigit(name.charAt(i)))
+ {
+ --i;
+ }
+ return name.substring(0, i).toLowerCase() + name.substring(i);
+ }
+ }
+
+ protected static String validNameStatic(String name, int casing, String prefix)
+ {
+ List parsedName = parseNameStatic(name, '_');
+ StringBuffer result = new StringBuffer();
+ for (Iterator i = parsedName.iterator(); i.hasNext(); )
+ {
+ String nameComponent = (String)i.next();
+ if (nameComponent.length() > 0)
+ {
+ if (result.length() > 0 || casing == UPPER_CASE)
+ {
+ result.append(Character.toUpperCase(nameComponent.charAt(0)));
+ result.append(nameComponent.substring(1));
+ }
+ else
+ {
+ result.append(nameComponent);
+ }
+ }
+ }
+
+ return
+ result.length() == 0 ?
+ prefix :
+ Character.isJavaIdentifierStart(result.charAt(0)) ?
+ casing == LOWER_CASE ?
+ uncapNameStatic(result.toString()) :
+ result.toString() :
+ prefix + result;
+ }
+
+ protected static List parseNameStatic(String sourceName, char separator)
+ {
+ List result = new ArrayList();
+ if (sourceName != null)
+ {
+ StringBuffer currentWord = new StringBuffer();
+ boolean lastIsLower = false;
+ for (int index = 0, length = sourceName.length(); index < length; ++index)
+ {
+ char curChar = sourceName.charAt(index);
+ if (!Character.isJavaIdentifierPart(curChar))
+ {
+ curChar = separator;
+ }
+ if (Character.isUpperCase(curChar) || (!lastIsLower && Character.isDigit(curChar)) || curChar == separator)
+ {
+ if (lastIsLower && currentWord.length() > 1 || curChar == separator && currentWord.length() > 0)
+ {
+ result.add(currentWord.toString());
+ currentWord = new StringBuffer();
+ }
+ lastIsLower = false;
+ }
+ else
+ {
+ if (!lastIsLower)
+ {
+ int currentWordLength = currentWord.length();
+ if (currentWordLength > 1)
+ {
+ char lastChar = currentWord.charAt(--currentWordLength);
+ currentWord.setLength(currentWordLength);
+ result.add(currentWord.toString());
+ currentWord = new StringBuffer();
+ currentWord.append(lastChar);
+ }
+ }
+ lastIsLower = true;
+ }
+
+ if (curChar != separator)
+ {
+ currentWord.append(curChar);
+ }
+ }
+
+ result.add(currentWord.toString());
+ }
+ return result;
+ }
+
+ public static String getDefaultPackageName(String targetNamespace)
+ {
+ if (targetNamespace == null)
+ return null;
+
+ URI uri = URI.createURI(targetNamespace);
+ List parsedName;
+ if (uri.isHierarchical())
+ {
+ String host = uri.host();
+ if (host != null && host.startsWith("www."))
+ {
+ host = host.substring(4);
+ }
+ parsedName = parseNameStatic(host, '.');
+ Collections.reverse(parsedName);
+ if (!parsedName.isEmpty())
+ {
+ parsedName.set(0, ((String)parsedName.get(0)).toLowerCase());
+ }
+
+ parsedName.addAll(parseNameStatic(uri.trimFileExtension().path(), '/'));
+ }
+ else
+ {
+ String opaquePart = uri.opaquePart();
+ int index = opaquePart.indexOf(":");
+ if (index != -1 && "urn".equalsIgnoreCase(uri.scheme()))
+ {
+ parsedName = parseNameStatic(opaquePart.substring(0, index), '-');
+ if (parsedName.size() > 0 && DOMAINS.contains(parsedName.get(parsedName.size() - 1)))
+ {
+ Collections.reverse(parsedName);
+ parsedName.set(0, ((String)parsedName.get(0)).toLowerCase());
+ }
+ parsedName.addAll(parseNameStatic(opaquePart.substring(index + 1), '/'));
+ }
+ else
+ {
+ parsedName = parseNameStatic(opaquePart, '/');
+ }
+ }
+
+ StringBuffer qualifiedPackageName = new StringBuffer();
+ for (Iterator i = parsedName.iterator(); i.hasNext(); )
+ {
+ String packageName = (String)i.next();
+ if (packageName.length() > 0)
+ {
+ if (qualifiedPackageName.length() > 0)
+ {
+ qualifiedPackageName.append('.');
+ }
+ qualifiedPackageName.append(validNameStatic(packageName, LOWER_CASE,"_"));
+ }
+ }
+
+ return qualifiedPackageName.toString().toLowerCase(); //make sure it's lower case .. we can't work with Axis if not.
+ }
+
+ private XSDSchema loadEPackage(EPackage ePackage)
+ {
+ XSDSchema ePackageXSDSchema = null;
+ XSDEcoreXMLSchemaBuilder xmlSchemaBuilder = new XSDEcoreXMLSchemaBuilder();
+ Collection xmlSchemas = xmlSchemaBuilder.generate(ePackage);
+ xsdComponentToEModelElementMap.putAll(xmlSchemaBuilder.getXSDComponentToEModelElementMap());
+ for (Iterator iter = xmlSchemas.iterator(); iter.hasNext();) {
+ Object xmlSchema = (Object)iter.next();
+ if (xmlSchema instanceof XSDSchema)
+ {
+ EPackage xmlSchemaEPackage = (EPackage) xsdComponentToEModelElementMap.get(xmlSchema);
+ addEPackageToXSDSchemaMapEntry(xmlSchemaEPackage, (XSDSchema) xmlSchema);
+ if (xmlSchemaEPackage.equals(ePackage))
+ {
+ ePackageXSDSchema = (XSDSchema) xmlSchema;
+ }
+ }
+ }
+ Map ePackageToXSDSchemaMap = xmlSchemaBuilder.getEPackageToXSDSchemaMap();
+ for (Iterator iter = ePackageToXSDSchemaMap.entrySet().iterator(); iter.hasNext();) {
+ Map.Entry mapEntry = (Map.Entry)iter.next();
+ EPackage xmlSchemaEPackage = (EPackage) mapEntry.getKey();
+ XSDSchema xmlSchema = (XSDSchema) mapEntry.getValue();
+ addEPackageToXSDSchemaMapEntry(xmlSchemaEPackage, xmlSchema);
+ }
+ return ePackageXSDSchema;
+ }
+
+ private void addEPackageToXSDSchemaMapEntry(EPackage ePackage, XSDSchema xsdSchema)
+ {
+ targetNamespaceToEPackageMap.put(ePackage.getNsURI(), ePackage);
+ populateTypeToTypeObjectMap(ePackage);
+ xsdSchemas.add(xsdSchema);
+ }
+
+ private static class XSDEcoreXMLSchemaBuilder extends EcoreXMLSchemaBuilder
+ {
+ public XSDEcoreXMLSchemaBuilder()
+ {
+ super();
+ }
+
+ public Map getXSDComponentToEModelElementMap()
+ {
+ return xsdComponentToEModelElementMap;
+ }
+
+ public Map getEPackageToXSDSchemaMap()
+ {
+ return ePackageToXSDSchemaMap;
+ }
+
+ protected void additionalProcessing(EClass cls, XSDComplexTypeDefinition xsdCTDComplexTypeDefinition)
+ {
+ // remove element definition
+ for(Iterator iter = xsdComponentToEModelElementMap.entrySet().iterator(); iter.hasNext();)
+ {
+ Map.Entry mapEntry = (Map.Entry)iter.next();
+ if (mapEntry.getValue().equals(cls) &&
+ mapEntry.getKey() instanceof XSDElementDeclaration)
+ {
+ xsdComponentToEModelElementMap.remove(mapEntry.getKey());
+ break;
+ }
+ }
+ }
+ }
+
+ class XSDSchemaAdapterFactoryImpl extends AdapterFactoryImpl
+ {
+ protected SchemaLocator schemaLocator = new SchemaLocator();
+
+ public boolean isFactoryForType(Object type)
+ {
+ return type == XSDSchemaLocator.class;
+ }
+
+ public Adapter adaptNew(Notifier target, Object type)
+ {
+ return schemaLocator;
+ }
+
+ class SchemaLocator extends XSDResourceImpl.SchemaLocator
+ {
+ public XSDSchema locateSchema(XSDSchema xsdSchema, String namespaceURI,
+ String rawSchemaLocationURI, String resolvedSchemaLocation)
+ {
+ if (targetNamespaceToEPackageMap.containsKey(namespaceURI))
+ {
+ for (Iterator iter = xsdSchemas.iterator(); iter.hasNext();) {
+ XSDSchema schema = (XSDSchema)iter.next();
+ String targetNamespace = schema.getTargetNamespace();
+ if (targetNamespace != null && targetNamespace.equals(namespaceURI))
+ {
+ return schema;
+ }
+ }
+ }
+ if (namespaceURI != null && !namespaceURI.equals(xsdSchema.getTargetNamespace()))
+ {
+ EPackage ePackage = extendedMetaData.getPackage(namespaceURI);
+ if (ePackage != null)
+ {
+ XSDSchema schema = loadEPackage(ePackage);
+ return schema;
+ }
+ }
+ return super.locateSchema(xsdSchema, namespaceURI, rawSchemaLocationURI, resolvedSchemaLocation);
+ }
+ }
+ }
+
+}