diff options
author | lresende <lresende@13f79535-47bb-0310-9956-ffa450edef68> | 2009-11-10 19:20:12 +0000 |
---|---|---|
committer | lresende <lresende@13f79535-47bb-0310-9956-ffa450edef68> | 2009-11-10 19:20:12 +0000 |
commit | 195774c489a1a671aca514b0afa88332bf9c6ee3 (patch) | |
tree | a22cb1f3f70f0c13a9a7049075205072901459aa /sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper | |
parent | c54bda13cb403d10675a6244bd00b8b536111ad6 (diff) |
Moving SDO tags
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@834617 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper')
22 files changed, 7667 insertions, 0 deletions
diff --git a/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/BaseSDOExtendedMetaDataImpl.java b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/BaseSDOExtendedMetaDataImpl.java new file mode 100644 index 0000000000..422f5342d8 --- /dev/null +++ b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/BaseSDOExtendedMetaDataImpl.java @@ -0,0 +1,167 @@ +/**
+ *
+ * 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 org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.ETypedElement;
+import org.eclipse.emf.ecore.EcoreFactory;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.ecore.util.BasicExtendedMetaData;
+import org.eclipse.emf.ecore.util.ExtendedMetaData;
+import org.eclipse.emf.ecore.xml.type.XMLTypePackage;
+
+/**
+ * A BasicExtendedMetaData that uses a supplied (SDO) ecore factory to create properties and types.
+ */
+public class BaseSDOExtendedMetaDataImpl extends BasicExtendedMetaData
+{
+ protected EcoreFactory ecoreFactory = EcoreFactory.eINSTANCE;
+ protected DemandMetaData demandMetaData = new DemandMetaData();
+
+ public static class DemandMetaData {
+ EClassifier getEObject() { return EcorePackage.eINSTANCE.getEObject(); }
+ EClassifier getAnyType() { return XMLTypePackage.eINSTANCE.getAnyType(); }
+ EClassifier getAnySimpleType() { return XMLTypePackage.eINSTANCE.getAnySimpleType(); }
+ EClassifier getXMLTypeDocumentRoot() { return XMLTypePackage.eINSTANCE.getXMLTypeDocumentRoot(); }
+ }
+
+ public BaseSDOExtendedMetaDataImpl(EPackage.Registry registry)
+ {
+ super(registry);
+ }
+
+ public EPackage demandPackage(String namespace)
+ {
+ EPackage ePackage = demandRegistry.getEPackage(namespace);
+ if (ePackage == null)
+ {
+ ePackage = ecoreFactory.createEPackage();
+ ePackage.setNsURI(namespace);
+ setQualified(ePackage, namespace != null);
+ if (namespace != null)
+ {
+ ePackage.setNsPrefix
+ (namespace.equals(ExtendedMetaData.XMLNS_URI) ?
+ namespace.equals(ExtendedMetaData.XML_URI) ?
+ "xml" :
+ "xmlns" :
+ computePrefix(namespace));
+ }
+ demandRegistry.put(namespace, ePackage);
+
+ // demandDocumentRoot(ePackage);
+
+ EClass documentRootEClass = ecoreFactory.createEClass();
+ documentRootEClass.getESuperTypes().add(demandMetaData.getXMLTypeDocumentRoot());
+ documentRootEClass.setName("DocumentRoot");
+ ePackage.getEClassifiers().add(documentRootEClass);
+ setDocumentRoot(documentRootEClass);
+ }
+ return ePackage;
+ }
+
+ public EClassifier demandType(String namespace, String name)
+ {
+ EPackage ePackage = demandPackage(namespace);
+ EClassifier eClassifier = getType(ePackage, name);
+ if (eClassifier != null)
+ {
+ return eClassifier;
+ }
+ else
+ {
+ EClass eClass = ecoreFactory.createEClass();
+ eClass.setName(name);
+ eClass.getESuperTypes().add(demandMetaData.getAnyType());
+ setContentKind(eClass, MIXED_CONTENT);
+ ePackage.getEClassifiers().add(eClass);
+ return eClass;
+ }
+ }
+
+ public EStructuralFeature demandFeature(String namespace, String name, boolean isElement, boolean isReference)
+ {
+ EPackage ePackage = demandPackage(namespace);
+ EClass documentRootEClass = getDocumentRoot(ePackage);
+ EStructuralFeature eStructuralFeature =
+ isElement ?
+ getLocalElement(documentRootEClass, namespace, name) :
+ getLocalAttribute(documentRootEClass, namespace, name);
+ if (eStructuralFeature != null)
+ {
+ return eStructuralFeature;
+ }
+ else
+ {
+ if (isReference)
+ {
+ EReference eReference = ecoreFactory.createEReference();
+ eReference.setContainment(isElement);
+ eReference.setEType(demandMetaData.getEObject());
+ eReference.setName(name);
+ eReference.setDerived(true);
+ eReference.setTransient(true);
+ eReference.setVolatile(true);
+ documentRootEClass.getEStructuralFeatures().add(eReference);
+
+ setFeatureKind(eReference, isElement ? ELEMENT_FEATURE : ATTRIBUTE_FEATURE);
+ setNamespace(eReference, namespace);
+
+ // Mark the bound as unspecified so that it won't be considered many
+ // but can nevertheless be recognized as being unspecified and perhaps still be treat as many.
+ //
+ if (isElement)
+ {
+ eReference.setUpperBound(ETypedElement.UNSPECIFIED_MULTIPLICITY);
+ }
+
+ return eReference;
+ }
+ else
+ {
+ EAttribute eAttribute = ecoreFactory.createEAttribute();
+ eAttribute.setName(name);
+ eAttribute.setEType(demandMetaData.getAnySimpleType());
+ eAttribute.setDerived(true);
+ eAttribute.setTransient(true);
+ eAttribute.setVolatile(true);
+ documentRootEClass.getEStructuralFeatures().add(eAttribute);
+
+ setFeatureKind(eAttribute, isElement ? ELEMENT_FEATURE : ATTRIBUTE_FEATURE);
+ setNamespace(eAttribute, namespace);
+
+ // Mark the bound as unspecified so that it won't be considered many
+ // but can nevertheless be recognized as being unspecified and perhaps still be treat as many.
+ //
+ if (isElement)
+ {
+ eAttribute.setUpperBound(ETypedElement.UNSPECIFIED_MULTIPLICITY);
+ }
+
+ return eAttribute;
+ }
+ }
+ }
+}
diff --git a/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/BaseSDOXSDEcoreBuilder.java b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/BaseSDOXSDEcoreBuilder.java new file mode 100644 index 0000000000..f21a3398b7 --- /dev/null +++ b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/BaseSDOXSDEcoreBuilder.java @@ -0,0 +1,1771 @@ +/**
+ *
+ * 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.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.emf.ecore.EAttribute;
+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.EOperation;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EParameter;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.ETypedElement;
+import org.eclipse.emf.ecore.EcoreFactory;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.ecore.util.ExtendedMetaData;
+import org.eclipse.emf.ecore.xml.type.XMLTypePackage;
+import org.eclipse.xsd.XSDAnnotation;
+import org.eclipse.xsd.XSDAttributeDeclaration;
+import org.eclipse.xsd.XSDAttributeUse;
+import org.eclipse.xsd.XSDComplexTypeContent;
+import org.eclipse.xsd.XSDComplexTypeDefinition;
+import org.eclipse.xsd.XSDComponent;
+import org.eclipse.xsd.XSDContentTypeCategory;
+import org.eclipse.xsd.XSDDerivationMethod;
+import org.eclipse.xsd.XSDElementDeclaration;
+import org.eclipse.xsd.XSDFeature;
+import org.eclipse.xsd.XSDLengthFacet;
+import org.eclipse.xsd.XSDMaxLengthFacet;
+import org.eclipse.xsd.XSDMinLengthFacet;
+import org.eclipse.xsd.XSDModelGroup;
+import org.eclipse.xsd.XSDModelGroupDefinition;
+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.XSDVariety;
+import org.eclipse.xsd.XSDWildcard;
+import org.eclipse.xsd.ecore.XSDEcoreBuilder;
+import org.eclipse.xsd.util.XSDConstants;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * An XSDEcoreBuilder that uses a supplied (SDO) ecore factory to create properties and types.
+ */
+public class BaseSDOXSDEcoreBuilder extends XSDEcoreBuilder
+{
+ protected EcorePackage ecorePackage = EcorePackage.eINSTANCE;
+ protected EcoreFactory ecoreFactory = EcoreFactory.eINSTANCE;
+
+ public BaseSDOXSDEcoreBuilder(ExtendedMetaData extendedMetaData)
+ {
+ super(extendedMetaData);
+ }
+
+ private void createDocumentRoot(XSDSchema xsdSchema, EPackage ePackage) {
+ EClass documentEClass = ecoreFactory.createEClass();
+ String name = getEcoreAttribute(xsdSchema, "documentRoot");
+ if (name == null)
+ {
+ name = "DocumentRoot";
+ }
+ documentEClass.setName(name);
+
+ extendedMetaData.setDocumentRoot(documentEClass);
+
+ ePackage.getEClassifiers().add(documentEClass);
+
+ createFeature
+ (documentEClass,
+ "mixed",
+ ecorePackage.getEFeatureMapEntry(),
+ null,
+ 0,
+ -1);
+
+ EStructuralFeature xmlnsPrefixMapFeature =
+ createFeature
+ (documentEClass,
+ "xMLNSPrefixMap",
+ ecorePackage.getEStringToStringMapEntry(),
+ null,
+ 0,
+ -1);
+ extendedMetaData.setName(xmlnsPrefixMapFeature, "xmlns:prefix");
+
+ EStructuralFeature xsiSchemaLocationMapFeature =
+ createFeature
+ (documentEClass,
+ "xSISchemaLocation",
+ ecorePackage.getEStringToStringMapEntry(),
+ null,
+ 0,
+ -1);
+ extendedMetaData.setName(xsiSchemaLocationMapFeature, "xsi:schemaLocation");
+ }
+
+ public EPackage getEPackage(XSDNamedComponent xsdNamedComponent)
+ {
+ XSDSchema containingXSDSchema = xsdNamedComponent.getSchema();
+ if (containingXSDSchema != null && !xsdSchemas.contains(containingXSDSchema))
+ {
+ xsdSchemas.add(containingXSDSchema);
+ addInput(containingXSDSchema);
+ validate(containingXSDSchema);
+ }
+
+ String targetNamespace =
+ containingXSDSchema == null ?
+ xsdNamedComponent.getTargetNamespace() :
+ containingXSDSchema.getTargetNamespace();
+ EPackage ePackage = (EPackage)targetNamespaceToEPackageMap.get(targetNamespace);
+ if (ePackage == null)
+ {
+ ePackage = ecoreFactory.createEPackage();
+ setAnnotations(ePackage, containingXSDSchema);
+ addOutput(ePackage);
+ if (targetNamespace == null)
+ {
+ if (containingXSDSchema == null)
+ {
+ containingXSDSchema = rootSchema;
+ }
+ ePackage.setName(validName(containingXSDSchema.eResource().getURI().trimFileExtension().lastSegment(), true));
+ ePackage.setNsURI(containingXSDSchema.eResource().getURI().toString());
+
+ // Also register against the nsURI for the case that the target namespace is null.
+ //
+ // extendedMetaData.putPackage(ePackage.getNsURI(), ePackage);
+ }
+ else
+ {
+ String qualifiedPackageName = qualifiedPackageName(targetNamespace);
+ ePackage.setName(qualifiedPackageName);
+ ePackage.setNsURI(targetNamespace);
+ }
+
+ String nsPrefix = ePackage.getName();
+ int index = nsPrefix.lastIndexOf('.');
+ nsPrefix = index == -1 ? nsPrefix : nsPrefix.substring(index + 1);
+
+ // http://www.w3.org/TR/REC-xml-names/#xmlReserved
+ // Namespace Constraint: Leading "XML"
+ // Prefixes beginning with the three-letter sequence x, m, l, in any case combination,
+ // are reserved for use by XML and XML-related specifications.
+ //
+ if (nsPrefix.toLowerCase().startsWith("xml"))
+ {
+ nsPrefix = "_" + nsPrefix;
+ }
+ ePackage.setNsPrefix(nsPrefix);
+
+ extendedMetaData.setQualified(ePackage, targetNamespace != null);
+ extendedMetaData.putPackage(targetNamespace, ePackage);
+
+ targetNamespaceToEPackageMap.put(targetNamespace, ePackage);
+
+ createDocumentRoot(xsdNamedComponent.getSchema(), ePackage);
+ }
+
+ return ePackage;
+ }
+
+ protected EClassifier computeEClassifier(XSDTypeDefinition xsdTypeDefinition)
+ {
+ if (xsdTypeDefinition == null)
+ {
+ return getBuiltInEClassifier(rootSchema.getSchemaForSchemaNamespace(), "anySimpleType");
+ }
+ else if (xsdTypeDefinition instanceof XSDSimpleTypeDefinition)
+ {
+ return computeEDataType((XSDSimpleTypeDefinition)xsdTypeDefinition);
+ }
+ else
+ {
+ return computeEClass((XSDComplexTypeDefinition)xsdTypeDefinition);
+ }
+ }
+
+ protected EDataType computeEDataType(XSDSimpleTypeDefinition xsdSimpleTypeDefinition)
+ {
+ if (xsdSimpleTypeDefinition == null)
+ {
+ return (EDataType)getBuiltInEClassifier(rootSchema.getSchemaForSchemaNamespace(), "anySimpleType");
+ }
+ else if (XSDConstants.isSchemaForSchemaNamespace(xsdSimpleTypeDefinition.getTargetNamespace()))
+ {
+ String name = xsdSimpleTypeDefinition.getName();
+ if (name != null)
+ {
+ EDataType result = (EDataType)getBuiltInEClassifier(xsdSimpleTypeDefinition.getTargetNamespace(), "anyType".equals(name) ? "anySimpleType" : name);
+ if (result != null)
+ {
+ return result;
+ }
+ }
+ }
+ else if (xsdSimpleTypeDefinition.getContainer() == null)
+ {
+ return (EDataType)getBuiltInEClassifier(rootSchema.getSchemaForSchemaNamespace(), "anySimpleType");
+ }
+
+ String explicitInstanceClassName = getEcoreAttribute(xsdSimpleTypeDefinition, "instanceClass");
+ if (explicitInstanceClassName != null)
+ {
+ EDataType eDataType = ecoreFactory.createEDataType();
+ setAnnotations(eDataType, xsdSimpleTypeDefinition);
+
+ String aliasName = getEcoreAttribute(xsdSimpleTypeDefinition, "name");
+ if (aliasName == null)
+ {
+ aliasName = validAliasName(xsdSimpleTypeDefinition, true);
+ }
+ eDataType.setName(aliasName);
+ extendedMetaData.setName(eDataType, xsdSimpleTypeDefinition.getAliasName());
+
+ eDataType.setInstanceClassName(explicitInstanceClassName);
+
+ EPackage ePackage = getEPackage(xsdSimpleTypeDefinition);
+ addToSortedList(ePackage.getEClassifiers(), eDataType);
+
+ checkForPrimitive(xsdSimpleTypeDefinition, eDataType);
+
+ handleFacets(xsdSimpleTypeDefinition, eDataType);
+
+ String constraints = getEcoreAttribute(xsdSimpleTypeDefinition, "constraints");
+ if (constraints != null)
+ {
+ EcoreUtil.setAnnotation(eDataType, EcorePackage.eNS_URI, "constraints", constraints);
+ }
+
+ if ("false".equals(getEcoreAttribute(xsdSimpleTypeDefinition, "serializable")))
+ {
+ eDataType.setSerializable(false);
+ }
+ return eDataType;
+ }
+ else
+ {
+ EEnum eEnum = computeEEnum(xsdSimpleTypeDefinition);
+ if (eEnum != null)
+ {
+ return eEnum;
+ }
+ else
+ {
+ XSDSimpleTypeDefinition baseTypeDefinition = xsdSimpleTypeDefinition.getBaseTypeDefinition();
+ if (baseTypeDefinition != null)
+ {
+ EDataType eDataType = ecoreFactory.createEDataType();
+ setAnnotations(eDataType, xsdSimpleTypeDefinition);
+
+ String name = getEcoreAttribute(xsdSimpleTypeDefinition, "name");
+ if (name == null)
+ {
+ name = validAliasName(xsdSimpleTypeDefinition, true);
+ }
+
+ eDataType.setName(name);
+ extendedMetaData.setName(eDataType, xsdSimpleTypeDefinition.getAliasName());
+
+ EPackage ePackage = getEPackage(xsdSimpleTypeDefinition);
+ addToSortedList(ePackage.getEClassifiers(), eDataType);
+
+ if (baseTypeDefinition.getVariety() != xsdSimpleTypeDefinition.getVariety())
+ {
+ if (xsdSimpleTypeDefinition.getVariety() == XSDVariety.LIST_LITERAL)
+ {
+ EDataType itemEDataType = getEDataType(xsdSimpleTypeDefinition.getItemTypeDefinition());
+ extendedMetaData.setItemType(eDataType, itemEDataType);
+ eDataType.setInstanceClassName("java.util.List");
+ }
+ else
+ {
+ String instanceClassName = null;
+ List memberTypes = new ArrayList();
+ for (Iterator i = xsdSimpleTypeDefinition.getMemberTypeDefinitions().iterator(); i.hasNext(); )
+ {
+ XSDSimpleTypeDefinition memberTypeDefinition = (XSDSimpleTypeDefinition)i.next();
+ EDataType memberEDataType = getEDataType(memberTypeDefinition);
+ memberTypes.add(memberEDataType);
+ String memberInstanceClassName = memberEDataType.getInstanceClassName();
+ if (memberInstanceClassName == null && memberEDataType instanceof EEnum)
+ {
+ memberInstanceClassName = "org.eclipse.emf.common.util.Enumerator";
+ }
+ if (instanceClassName == null)
+ {
+ instanceClassName = memberInstanceClassName;
+ }
+ else if (instanceClassName != memberInstanceClassName)
+ {
+ instanceClassName = "java.lang.Object";
+ }
+ }
+ extendedMetaData.setMemberTypes(eDataType, memberTypes);
+ eDataType.setInstanceClassName(instanceClassName);
+ }
+ }
+ else
+ {
+ EDataType baseEDataType = getEDataType(baseTypeDefinition);
+ extendedMetaData.setBaseType(eDataType, baseEDataType);
+ String instanceClassName = getInstanceClassName(xsdSimpleTypeDefinition, baseEDataType);
+ eDataType.setInstanceClassName
+ (instanceClassName == null ?
+ "org.eclipse.emf.common.util.Enumerator" :
+ instanceClassName);
+ }
+
+ checkForPrimitive(xsdSimpleTypeDefinition, eDataType);
+ handleFacets(xsdSimpleTypeDefinition, eDataType);
+
+ String constraints = getEcoreAttribute(xsdSimpleTypeDefinition, "constraints");
+ if (constraints != null)
+ {
+ EcoreUtil.setAnnotation(eDataType, EcorePackage.eNS_URI, "constraints", constraints);
+ }
+
+ if ("false".equals(getEcoreAttribute(xsdSimpleTypeDefinition, "serializable")))
+ {
+ eDataType.setSerializable(false);
+ }
+
+ return eDataType;
+ }
+ }
+ return (EDataType)getBuiltInEClassifier(rootSchema.getSchemaForSchemaNamespace(), "anySimpleType");
+ }
+ }
+
+ protected void checkForPrimitive(EDataType eDataType)
+ {
+ int index = PRIMITIVES.indexOf(eDataType.getInstanceClassName());
+ if (index != -1 || eDataType instanceof EEnum)
+ {
+ EDataType eDataTypeObject = ecoreFactory.createEDataType();
+ eDataTypeObject.setName(eDataType.getName() + "Object");
+ if (index != -1)
+ {
+ eDataTypeObject.setInstanceClassName(PRIMITIVE_WRAPPERS[index]);
+ }
+ else
+ {
+ eDataTypeObject.setInstanceClassName("org.eclipse.emf.common.util.Enumerator");
+ }
+ extendedMetaData.setName(eDataTypeObject, extendedMetaData.getName(eDataType) + ":Object");
+ addToSortedList(eDataType.getEPackage().getEClassifiers(), eDataTypeObject);
+ extendedMetaData.setBaseType(eDataTypeObject, eDataType);
+
+ typeToTypeObjectMap.put(eDataType, eDataTypeObject);
+ }
+ }
+
+ public EClass computeEClass(XSDComplexTypeDefinition xsdComplexTypeDefinition)
+ {
+ if (xsdComplexTypeDefinition == null)
+ {
+ return (EClass)getBuiltInEClassifier(rootSchema.getSchemaForSchemaNamespace(), "anyType");
+ }
+ else if (XSDConstants.isSchemaForSchemaNamespace(xsdComplexTypeDefinition.getTargetNamespace()))
+ {
+ String name = xsdComplexTypeDefinition.getName();
+ if (name != null)
+ {
+ EClass result = (EClass)getBuiltInEClassifier(xsdComplexTypeDefinition.getTargetNamespace(), name);
+ if (result != null)
+ {
+ return result;
+ }
+ }
+ }
+ else if (xsdComplexTypeDefinition.getContainer() == null)
+ {
+ return (EClass)getBuiltInEClassifier(rootSchema.getSchemaForSchemaNamespace(), "anyType");
+ }
+
+ EClass eClass = ecoreFactory.createEClass();
+ setAnnotations(eClass, xsdComplexTypeDefinition);
+ // Do this early to prevent recursive loop.
+ xsdComponentToEModelElementMap.put(xsdComplexTypeDefinition, eClass);
+
+ if ("true".equals(getEcoreAttribute(xsdComplexTypeDefinition, "interface")))
+ {
+ eClass.setInterface(true);
+ }
+
+ String instanceClassName = getEcoreAttribute(xsdComplexTypeDefinition, "instanceClass");
+ if (instanceClassName != null)
+ {
+ eClass.setInstanceClassName(instanceClassName);
+ }
+
+ String aliasName = getEcoreAttribute(xsdComplexTypeDefinition, "name");
+ if (aliasName == null)
+ {
+ aliasName = validAliasName(xsdComplexTypeDefinition, true);
+ }
+ eClass.setName(aliasName);
+ extendedMetaData.setName(eClass, xsdComplexTypeDefinition.getAliasName());
+
+ String constraints = getEcoreAttribute(xsdComplexTypeDefinition, "constraints");
+ if (constraints != null)
+ {
+ EcoreUtil.setAnnotation(eClass, EcorePackage.eNS_URI, "constraints", constraints);
+ }
+
+ EPackage ePackage = getEPackage(xsdComplexTypeDefinition);
+ addToSortedList(ePackage.getEClassifiers(), eClass);
+
+ if (xsdComplexTypeDefinition.isAbstract())
+ {
+ eClass.setAbstract(true);
+ }
+
+ EClass baseClass = null;
+ XSDTypeDefinition baseTypeDefinition = xsdComplexTypeDefinition.getBaseTypeDefinition();
+ if (!baseTypeDefinition.isCircular())
+ {
+ EClassifier baseType = getEClassifier(baseTypeDefinition);
+ if (baseType instanceof EClass && baseType != ecorePackage.getEObject())
+ {
+ eClass.getESuperTypes().add(baseClass = (EClass)baseType);
+ }
+ }
+
+ boolean isRestriction =
+ !eClass.getESuperTypes().isEmpty() &&
+ xsdComplexTypeDefinition.getDerivationMethod() == XSDDerivationMethod.RESTRICTION_LITERAL;
+
+ for (Iterator i = getEcoreTypeQNamesAttribute(xsdComplexTypeDefinition, "implements").iterator(); i.hasNext(); )
+ {
+ XSDTypeDefinition mixin = (XSDTypeDefinition)i.next();
+ if (!XSDConstants.isURType(mixin))
+ {
+ EClassifier mixinType = getEClassifier(mixin);
+ if (mixinType instanceof EClass && mixinType != ecorePackage.getEObject())
+ {
+ eClass.getESuperTypes().add(mixinType);
+ }
+ }
+ }
+
+ // 51210
+ // EAnnotation contentParticle = null;
+
+ if (xsdComplexTypeDefinition.getContentTypeCategory() == XSDContentTypeCategory.SIMPLE_LITERAL)
+ {
+ extendedMetaData.setContentKind(eClass, ExtendedMetaData.SIMPLE_CONTENT);
+ if (!"SimpleAnyType".equals(eClass.getName()) || !XMLTypePackage.eNS_URI.equals(eClass.getEPackage().getNsURI()))
+ {
+ if (eClass.getEAllStructuralFeatures().isEmpty())
+ {
+ XSDComplexTypeContent xsdComplexTypeContent = xsdComplexTypeDefinition.getContent();
+ String name = getEcoreAttribute(xsdComplexTypeContent, "name");
+ if (name == null)
+ {
+ name = "value";
+ }
+ createFeature
+ (eClass,
+ null,
+ name,
+ xsdComplexTypeContent,
+ false);
+ }
+ else
+ {
+ XSDSimpleTypeDefinition xsdSimpleTypeDefinition = xsdComplexTypeDefinition.getSimpleType();
+ getEClassifier(xsdSimpleTypeDefinition);
+ }
+ }
+ }
+ else
+ {
+ EStructuralFeature globalGroup = null;
+ boolean isMixed = xsdComplexTypeDefinition.getContentTypeCategory() == XSDContentTypeCategory.MIXED_LITERAL;
+ String featureMapName = getEcoreAttribute(xsdComplexTypeDefinition, "featureMap");
+ if (eClass.getESuperTypes().isEmpty() ?
+ "true".equals(getEcoreAttribute(xsdComplexTypeDefinition, "mixed")) :
+ extendedMetaData.getMixedFeature((EClass)eClass.getESuperTypes().get(0)) != null)
+ {
+ isMixed = true;
+ }
+ extendedMetaData.setContentKind
+ (eClass,
+ isMixed ?
+ ExtendedMetaData.MIXED_CONTENT :
+ xsdComplexTypeDefinition.getContentTypeCategory() == XSDContentTypeCategory.EMPTY_LITERAL ?
+ ExtendedMetaData.EMPTY_CONTENT :
+ ExtendedMetaData.ELEMENT_ONLY_CONTENT);
+ if (isMixed)
+ {
+ EStructuralFeature mixedFeature = extendedMetaData.getMixedFeature(eClass);
+ if (mixedFeature == null)
+ {
+ if (featureMapName == null)
+ {
+ featureMapName = "mixed";
+ }
+ mixedFeature =
+ createFeature
+ (eClass,
+ featureMapName,
+ ecorePackage.getEFeatureMapEntry(),
+ null,
+ 0,
+ -1);
+ extendedMetaData.setName(mixedFeature, ":mixed");
+ }
+ }
+ else
+ {
+ globalGroup = extendedMetaData.getElement(eClass, null, ":group");
+ if (globalGroup == null && featureMapName != null && eClass.getESuperTypes().isEmpty())
+ {
+ globalGroup =
+ createFeature
+ (eClass,
+ featureMapName,
+ ecorePackage.getEFeatureMapEntry(),
+ null,
+ 0,
+ -1);
+ extendedMetaData.setName(globalGroup, ":group");
+ extendedMetaData.setFeatureKind(globalGroup, ExtendedMetaData.GROUP_FEATURE);
+ }
+ }
+
+ if (xsdComplexTypeDefinition.getContent() != null)
+ {
+ // 51210
+ // Map particleMap = new HashMap();
+ Map groups = new HashMap();
+ List particleInformation = collectParticles((XSDParticle)xsdComplexTypeDefinition.getContent());
+ for (Iterator i = particleInformation.iterator(); i.hasNext(); )
+ {
+ EffectiveOccurrence effectiveOccurrence = (EffectiveOccurrence)i.next();
+ XSDParticle xsdParticle = effectiveOccurrence.xsdParticle;
+ EStructuralFeature group = (EStructuralFeature)groups.get(effectiveOccurrence.xsdModelGroup);
+ XSDTerm xsdTerm = xsdParticle.getTerm();
+ EStructuralFeature eStructuralFeature = null;
+ String name = getEcoreAttribute(xsdParticle, "name");
+ if (xsdTerm instanceof XSDModelGroup)
+ {
+ if (!isRestriction)
+ {
+ XSDModelGroup xsdModelGroup = (XSDModelGroup)xsdTerm;
+ if (name == null)
+ {
+ name = getEcoreAttribute(xsdParticle, "featureMap");
+ if (name == null)
+ {
+ name = getEcoreAttribute(xsdModelGroup, "name");
+ if (name == null)
+ {
+ name = getEcoreAttribute(xsdModelGroup, "featureMap");
+ if (name == null)
+ {
+ if (xsdModelGroup.getContainer() instanceof XSDModelGroupDefinition)
+ {
+ XSDModelGroupDefinition xsdModelGroupDefinition = (XSDModelGroupDefinition)xsdModelGroup.getContainer();
+ name = getEcoreAttribute(xsdModelGroupDefinition, "name");
+ if (name == null)
+ {
+ name = validName(xsdModelGroupDefinition.getName(), true);
+ }
+ }
+ else
+ {
+ name = "group";
+ }
+ }
+ }
+ }
+ }
+
+ eStructuralFeature =
+ createFeature
+ (eClass,
+ name,
+ ecorePackage.getEFeatureMapEntry(),
+ xsdParticle,
+ 0,
+ -1);
+ groups.put(xsdTerm, eStructuralFeature);
+ extendedMetaData.setName(eStructuralFeature, name + ":" + eClass.getEAllStructuralFeatures().indexOf(eStructuralFeature));
+ }
+ }
+ else if (xsdTerm instanceof XSDWildcard)
+ {
+ if (!isRestriction)
+ {
+ if (name == null)
+ {
+ name = getEcoreAttribute(xsdTerm, "name");
+ if (name == null)
+ {
+ name = "any";
+ }
+ }
+ eStructuralFeature =
+ createFeature
+ (eClass,
+ name,
+ ecorePackage.getEFeatureMapEntry(),
+ xsdParticle,
+ effectiveOccurrence.minOccurs,
+ effectiveOccurrence.maxOccurs);
+ // 51210
+ // particleMap.put(xsdParticle, eStructuralFeature);
+ }
+ }
+ else
+ {
+ XSDElementDeclaration xsdElementDeclaration = (XSDElementDeclaration)xsdTerm;
+
+ boolean isRedundant = false;
+ if (isRestriction)
+ {
+ isRedundant =
+ extendedMetaData.getElement
+ (baseClass, xsdElementDeclaration.getTargetNamespace(), xsdElementDeclaration.getName()) != null;
+
+ if (!isRedundant)
+ {
+ group =
+ extendedMetaData.getElementWildcardAffiliation
+ (baseClass, xsdElementDeclaration.getTargetNamespace(), xsdElementDeclaration.getName());
+ }
+ }
+
+ if (!isRedundant)
+ {
+ if (name == null)
+ {
+ name = getEcoreAttribute(xsdElementDeclaration, "name");
+ if (name == null)
+ {
+ name = validName(xsdElementDeclaration.getName(), true);
+ }
+ }
+
+ String groupName = getEcoreAttribute(xsdParticle, "featureMap");
+ if (groupName == null)
+ {
+ groupName = getEcoreAttribute(xsdElementDeclaration, "featureMap");
+ }
+
+ if (!"".equals(groupName) &&
+ (groupName != null ||
+ xsdElementDeclaration.isAbstract() ||
+ xsdElementDeclaration.getSubstitutionGroup().size() > 1))
+ {
+ if (groupName == null)
+ {
+ groupName = name + "Group";
+ }
+ eStructuralFeature =
+ createFeature
+ (eClass,
+ groupName,
+ ecorePackage.getEFeatureMapEntry(),
+ xsdParticle,
+ effectiveOccurrence.minOccurs,
+ effectiveOccurrence.maxOccurs);
+
+ eStructuralFeature.setChangeable(true);
+
+ extendedMetaData.setFeatureKind(eStructuralFeature, ExtendedMetaData.GROUP_FEATURE);
+ extendedMetaData.setName(eStructuralFeature, xsdElementDeclaration.getName() + ":group");
+
+ if (group != null)
+ {
+ extendedMetaData.setGroup(eStructuralFeature, group);
+ eStructuralFeature.setDerived(true);
+ eStructuralFeature.setTransient(true);
+ eStructuralFeature.setVolatile(true);
+ }
+ else if (isMixed)
+ {
+ eStructuralFeature.setDerived(true);
+ eStructuralFeature.setTransient(true);
+ eStructuralFeature.setVolatile(true);
+ }
+ else if (globalGroup != null)
+ {
+ extendedMetaData.setGroup(eStructuralFeature, globalGroup);
+ eStructuralFeature.setDerived(true);
+ eStructuralFeature.setTransient(true);
+ eStructuralFeature.setVolatile(true);
+ }
+
+ group = eStructuralFeature;
+ }
+
+ eStructuralFeature =
+ createFeature(eClass, xsdElementDeclaration, name, xsdParticle, effectiveOccurrence.minOccurs, effectiveOccurrence.maxOccurs);
+ // 51210
+ // particleMap.put(xsdParticle, eStructuralFeature);
+
+ // If the group is turned off, we better make the feature changeable.
+ //
+ if (!eStructuralFeature.isChangeable() && group == null && getEcoreAttribute(xsdParticle, xsdElementDeclaration, "changeable") == null)
+ {
+ eStructuralFeature.setChangeable(true);
+ }
+ }
+ }
+
+ if (eStructuralFeature != null)
+ {
+ if (group != null)
+ {
+ extendedMetaData.setGroup(eStructuralFeature, group);
+ eStructuralFeature.setDerived(true);
+ eStructuralFeature.setTransient(true);
+ eStructuralFeature.setVolatile(true);
+ }
+ else if (isMixed)
+ {
+ eStructuralFeature.setDerived(true);
+ eStructuralFeature.setTransient(true);
+ eStructuralFeature.setVolatile(true);
+ }
+ else if (globalGroup != null)
+ {
+ extendedMetaData.setGroup(eStructuralFeature, globalGroup);
+ eStructuralFeature.setDerived(true);
+ eStructuralFeature.setTransient(true);
+ eStructuralFeature.setVolatile(true);
+ }
+ }
+ }
+
+ // 51210
+ // contentParticle = computeParticleConstraints(eClass, particleMap, (XSDParticle)xsdComplexTypeDefinition.getContent());
+ }
+ }
+
+ // 51210
+ // EAnnotation attributeParticle = null;
+ // if (isRestriction)
+ // {
+ // attributeParticle = ecoreFactory.createEAnnotation();
+ // attributeParticle.setSource("attributes");
+ // }
+
+ XSDWildcard baseXSDWildcard = null;
+ Collection baseAttributeUses = Collections.EMPTY_LIST;
+ Map baseAttributeURIs = new HashMap();
+ if (baseTypeDefinition instanceof XSDComplexTypeDefinition)
+ {
+ XSDComplexTypeDefinition complexBaseTypeDefinition = (XSDComplexTypeDefinition)baseTypeDefinition;
+ baseXSDWildcard = complexBaseTypeDefinition.getAttributeWildcard();
+ baseAttributeUses = complexBaseTypeDefinition.getAttributeUses();
+ for (Iterator i = baseAttributeUses.iterator(); i.hasNext(); )
+ {
+ XSDAttributeUse xsdAttributeUse = (XSDAttributeUse)i.next();
+ baseAttributeURIs.put(xsdAttributeUse.getAttributeDeclaration().getURI(), xsdAttributeUse);
+ }
+ }
+
+ for (Iterator i = getAttributeUses(xsdComplexTypeDefinition).iterator(); i.hasNext(); )
+ {
+ XSDAttributeUse xsdAttributeUse = (XSDAttributeUse)i.next();
+ XSDAttributeDeclaration xsdAttributeDeclaration = xsdAttributeUse.getAttributeDeclaration();
+ if (baseAttributeURIs.remove(xsdAttributeDeclaration.getURI()) == null)
+ {
+ String name = getEcoreAttribute(xsdAttributeUse, "name");
+ if (name == null)
+ {
+ name = getEcoreAttribute(xsdAttributeDeclaration, "name");
+ }
+ if (name == null)
+ {
+ name = validName(xsdAttributeDeclaration.getName(), true);
+ }
+
+ EStructuralFeature eStructuralFeature =
+ createFeature(eClass, xsdAttributeDeclaration, name, xsdAttributeUse, xsdAttributeUse.isRequired());
+
+ if (isRestriction)
+ {
+ EStructuralFeature attributeWildcardEStructuralFeature =
+ extendedMetaData.getAttributeWildcardAffiliation
+ (baseClass, xsdAttributeDeclaration.getTargetNamespace(), xsdAttributeDeclaration.getName());
+ if (attributeWildcardEStructuralFeature != null)
+ {
+ extendedMetaData.setGroup(eStructuralFeature, attributeWildcardEStructuralFeature);
+ eStructuralFeature.setDerived(true);
+ eStructuralFeature.setTransient(true);
+ eStructuralFeature.setVolatile(true);
+ }
+ }
+ }
+ /* 51210
+ else if (isRestriction && !baseAttributeUses.contains(xsdAttributeUse))
+ {
+ EStructuralFeature eStructuralFeature =
+ extendedMetaData.getAttribute(eClass, xsdAttributeDeclaration.getTargetNamespace(), xsdAttributeDeclaration.getName());
+ if (eStructuralFeature != null)
+ {
+ EAnnotation attributeEAnnotation = ecoreFactory.createEAnnotation();
+ if (xsdAttributeUse.isRequired())
+ {
+ attributeEAnnotation.getDetails().put("minOccurs", "1");
+ }
+ attributeEAnnotation.getReferences().add(eStructuralFeature);
+
+ if (xsdAttributeDeclaration.getTypeDefinition() != null)
+ {
+ EClassifier type = getEClassifier(xsdAttributeDeclaration.getTypeDefinition());
+ if (type != eStructuralFeature.getEType() && type != null)
+ {
+ attributeEAnnotation.getReferences().add(type);
+ }
+ }
+
+ attributeParticle.getContents().add(attributeEAnnotation);
+ }
+ }
+ */
+ }
+
+ /* 51210
+ if (isRestriction && !baseAttributeURIs.isEmpty())
+ {
+ for (Iterator i = baseAttributeURIs.values().iterator(); i.hasNext(); )
+ {
+ XSDAttributeUse xsdAttributeUse = (XSDAttributeUse)i.next();
+ XSDAttributeDeclaration xsdAttributeDeclaration = xsdAttributeUse.getAttributeDeclaration();
+ EStructuralFeature eStructuralFeature =
+ extendedMetaData.getAttribute(eClass, xsdAttributeDeclaration.getTargetNamespace(), xsdAttributeDeclaration.getName());
+ if (eStructuralFeature != null)
+ {
+ EAnnotation attributeEAnnotation = ecoreFactory.createEAnnotation();
+ attributeEAnnotation.getReferences().add(eStructuralFeature);
+ attributeEAnnotation.getDetails().put("maxOccurs", "0");
+ attributeParticle.getContents().add(attributeEAnnotation);
+ }
+ }
+ }
+ */
+
+ XSDWildcard xsdWildcard = xsdComplexTypeDefinition.getAttributeWildcard();
+ if (xsdWildcard != null && baseXSDWildcard != xsdWildcard || XSDConstants.isURType(xsdComplexTypeDefinition))
+ {
+ if (isRestriction && !XSDConstants.isURType(xsdComplexTypeDefinition))
+ {
+ // 51210
+ // attributeParticle.getDetails().put
+ // ("wildcard", BasicExtendedMetaData.getEncodedWildcards(xsdComplexTypeDefinition.getTargetNamespace(), getWildcards(xsdWildcard)));
+ }
+ else
+ {
+ String name = getEcoreAttribute(xsdWildcard, "name");
+ if (name == null)
+ {
+ name = "anyAttribute";
+ }
+ createFeature
+ (eClass,
+ name,
+ ecorePackage.getEFeatureMapEntry(),
+ xsdWildcard,
+ 0,
+ -1);
+ }
+ }
+
+ if (isRestriction)
+ {
+ // 51210
+ // EAnnotation restrictionParticle = ecoreFactory.createEAnnotation();
+ // restrictionParticle.setSource("restriction");
+ // if (contentParticle != null)
+ // {
+ // restrictionParticle.getContents().add(contentParticle);
+ // }
+ // if (!attributeParticle.getContents().isEmpty() || !attributeParticle.getDetails().isEmpty())
+ // {
+ // restrictionParticle.getContents().add(attributeParticle);
+ // }
+ // contentParticle = restrictionParticle;
+
+ int baseContentKind = extendedMetaData.getContentKind((EClass)eClass.getESuperTypes().get(0));
+ if (baseContentKind == ExtendedMetaData.MIXED_CONTENT &&
+ xsdComplexTypeDefinition.getContentTypeCategory() == XSDContentTypeCategory.SIMPLE_LITERAL)
+ {
+ extendedMetaData.setContentKind(eClass, ExtendedMetaData.SIMPLE_CONTENT);
+ EStructuralFeature eStructuralFeature =
+ createFeature
+ (eClass,
+ "rawValue",
+ getBuiltInEClassifier(xsdComplexTypeDefinition.getSchema().getSchemaForSchemaNamespace(), "string"),
+ null,
+ 0,
+ 1);
+ eStructuralFeature.setDerived(true);
+ eStructuralFeature.setTransient(true);
+ eStructuralFeature.setVolatile(true);
+
+ eStructuralFeature =
+ createFeature
+ (eClass,
+ "value",
+ getBuiltInEClassifier(xsdComplexTypeDefinition.getSchema().getSchemaForSchemaNamespace(), "anySimpleType"),
+ null,
+ 0,
+ 1);
+ eStructuralFeature.setDerived(true);
+ eStructuralFeature.setTransient(true);
+ eStructuralFeature.setVolatile(true);
+
+ if ("SimpleAnyType".equals(eClass.getName()) && XMLTypePackage.eNS_URI.equals(eClass.getEPackage().getNsURI()))
+ {
+ eStructuralFeature =
+ createFeature
+ (eClass,
+ "instanceType",
+ ecorePackage.getEDataType(),
+ null,
+ 1,
+ 1);
+
+ ((EReference)eStructuralFeature).setResolveProxies(false);
+ }
+ }
+ else
+ {
+ extendedMetaData.setContentKind(eClass, baseContentKind);
+ }
+ }
+
+ // 51210
+ // extendedMetaData.setContent(eClass, contentParticle);
+
+ XSDAnnotation xsdAnnotation = xsdComplexTypeDefinition.getAnnotation();
+ if (xsdAnnotation != null)
+ {
+ List applicationInformationList = xsdAnnotation.getApplicationInformation(EcorePackage.eNS_URI);
+ for (Iterator i = applicationInformationList.iterator(); i.hasNext(); )
+ {
+ Element applicationInformation = (Element)i.next();
+ if ("operations".equals(applicationInformation.getAttributeNS(EcorePackage.eNS_URI, "key")))
+ {
+ for (Iterator j = getElements(applicationInformation, "operation").iterator(); j.hasNext(); )
+ {
+ EOperation eOperation = ecoreFactory.createEOperation();
+ Element operation = (Element)j.next();
+ String operationName = operation.getAttributeNS(null, "name");
+ eOperation.setName(operationName);
+ XSDTypeDefinition returnType = getEcoreTypeQNameAttribute(xsdComplexTypeDefinition, operation, null, "type");
+ if (returnType != null)
+ {
+ EClassifier returnEType = getEClassifier(returnType);
+ eOperation.setEType(returnEType);
+ }
+
+ List exceptions = getEcoreTypeQNamesAttribute(xsdComplexTypeDefinition, operation, null, "exceptions");
+ for (Iterator k = exceptions.iterator(); k.hasNext(); )
+ {
+ XSDTypeDefinition exceptionTypeDefinition = (XSDTypeDefinition)k.next();
+ eOperation.getEExceptions().add(getEClassifier(exceptionTypeDefinition));
+ }
+
+ for (Iterator k = getElements(operation, "parameter").iterator(); k.hasNext(); )
+ {
+ EParameter eParameter = ecoreFactory.createEParameter();
+ Element parameter = (Element)k.next();
+ String paramaterName = parameter.getAttributeNS(null, "name");
+ XSDTypeDefinition parameterType = getEcoreTypeQNameAttribute(xsdComplexTypeDefinition, parameter, null, "type");
+ EClassifier parameterEType = getEClassifier(parameterType);
+ eParameter.setName(paramaterName);
+ eParameter.setEType(parameterEType);
+
+ populateETypedElement(eParameter, parameter);
+ eOperation.getEParameters().add(eParameter);
+ }
+
+ List body = getElements(operation, "body");
+ if (!body.isEmpty())
+ {
+ EcoreUtil.setAnnotation(eOperation, "http://www.eclipse.org/emf/2002/GenModel", "body", getText((Element)body.get(0)));
+ }
+
+ populateETypedElement(eOperation, operation);
+ eClass.getEOperations().add(eOperation);
+ }
+ }
+ }
+ }
+ return eClass;
+ }
+
+ private String getText(Element element)
+ {
+ StringBuffer text = new StringBuffer();
+ for (Node node = element.getFirstChild(); node != null; node = node.getNextSibling())
+ {
+ switch (node.getNodeType())
+ {
+ case Node.TEXT_NODE:
+ case Node.CDATA_SECTION_NODE:
+ {
+ text.append(node.getNodeValue());
+ }
+ }
+ }
+ return text.toString();
+ }
+
+ private List getElements(Element element, String localName)
+ {
+ List result = new ArrayList();
+ for (Node node = element.getFirstChild(); node != null; node = node.getNextSibling())
+ {
+ if (node.getNodeType() == Node.ELEMENT_NODE)
+ {
+ Element child = (Element)node;
+ if (localName.equals(child.getLocalName()) && child.getNamespaceURI() == null)
+ {
+ result.add(child);
+ }
+ }
+ }
+ return result;
+ }
+
+ protected EStructuralFeature createFeature
+ (EClass eClass, String name, EClassifier type, XSDComponent xsdComponent, int minOccurs, int maxOccurs)
+ {
+ if (xsdComponent != null)
+ {
+ XSDSchema containingXSDSchema = xsdComponent.getSchema();
+ if (containingXSDSchema != null && !xsdSchemas.contains(containingXSDSchema))
+ {
+ xsdSchemas.add(containingXSDSchema);
+ addInput(containingXSDSchema);
+ validate(containingXSDSchema);
+ }
+ }
+ else if (extendedMetaData.getContentKind(eClass) == ExtendedMetaData.MIXED_CONTENT)
+ {
+ if (type == ecorePackage.getEFeatureMapEntry())
+ {
+ EAttribute eAttribute = ecoreFactory.createEAttribute();
+ setAnnotations(eAttribute, xsdComponent);
+ eAttribute.setName(Character.toLowerCase(name.charAt(0)) + name.substring(1));
+ eAttribute.setUnique(false);
+ eAttribute.setEType(type);
+ eAttribute.setLowerBound(minOccurs);
+ eAttribute.setUpperBound(maxOccurs);
+ eClass.getEStructuralFeatures().add(eAttribute);
+ extendedMetaData.setFeatureKind(eAttribute, ExtendedMetaData.ELEMENT_WILDCARD_FEATURE);
+ extendedMetaData.setName(eAttribute, ":" + eAttribute.getName());
+ return eAttribute;
+ }
+ else
+ {
+ EReference eReference = ecoreFactory.createEReference();
+ setAnnotations(eReference, xsdComponent);
+ eReference.setName(name);
+ eReference.setEType(ecorePackage.getEStringToStringMapEntry());
+ eReference.setLowerBound(0);
+ eReference.setUpperBound(-1);
+ eReference.setContainment(true);
+ eReference.setResolveProxies(false);
+ eReference.setTransient(true);
+ eClass.getEStructuralFeatures().add(eReference);
+ extendedMetaData.setFeatureKind(eReference, ExtendedMetaData.ATTRIBUTE_FEATURE);
+ return eReference;
+ }
+ }
+
+ if (type instanceof EClass)
+ {
+ EReference eReference = ecoreFactory.createEReference();
+ setAnnotations(eReference, xsdComponent);
+ eReference.setName(Character.toLowerCase(name.charAt(0)) + name.substring(1));
+ eReference.setEType(type);
+ eReference.setLowerBound(minOccurs);
+ eReference.setUpperBound(maxOccurs);
+
+ eClass.getEStructuralFeatures().add(eReference);
+ if (xsdComponent == null || xsdComponent instanceof XSDSimpleTypeDefinition)
+ {
+ extendedMetaData.setName(eReference, ":" + eClass.getEAllStructuralFeatures().indexOf(eReference));
+ extendedMetaData.setFeatureKind(eReference, ExtendedMetaData.SIMPLE_FEATURE);
+ eReference.setResolveProxies(!isLocalReferenceType((XSDSimpleTypeDefinition)xsdComponent));
+ }
+ else
+ {
+ map(xsdComponent, eReference);
+ if (xsdComponent instanceof XSDParticle)
+ {
+ eReference.setContainment(true);
+ eReference.setResolveProxies(false);
+
+ XSDParticle xsdParticle = (XSDParticle)xsdComponent;
+
+ XSDTerm xsdTerm = ((XSDParticle)xsdComponent).getTerm();
+ if (xsdTerm instanceof XSDElementDeclaration)
+ {
+ XSDElementDeclaration xsdElementDeclaration = (XSDElementDeclaration)xsdTerm;
+ extendedMetaData.setFeatureKind(eReference, ExtendedMetaData.ELEMENT_FEATURE);
+ extendedMetaData.setName(eReference, xsdElementDeclaration.getName());
+ extendedMetaData.setNamespace(eReference, xsdElementDeclaration.getTargetNamespace());
+
+ XSDTypeDefinition xsdType = getEffectiveTypeDefinition(xsdParticle, xsdElementDeclaration);
+ if (xsdType instanceof XSDSimpleTypeDefinition)
+ {
+ eReference.setContainment(false);
+ eReference.setResolveProxies(!isLocalReferenceType((XSDSimpleTypeDefinition)xsdType));
+ }
+
+ if (maxOccurs == 1 && xsdElementDeclaration.isNillable())
+ {
+ eReference.setUnsettable(true);
+ }
+
+ if (xsdElementDeclaration.isAbstract())
+ {
+ eReference.setChangeable(false);
+ }
+
+ String opposite = getEcoreAttribute(xsdParticle, "opposite");
+ if (opposite != null)
+ {
+ eReferenceToOppositeNameMap.put(eReference, opposite);
+ }
+ }
+ else if (xsdTerm instanceof XSDWildcard)
+ {
+ // EATM shouldn't happen
+ XSDWildcard xsdWildcard = (XSDWildcard)xsdTerm;
+ extendedMetaData.setFeatureKind(eReference, ExtendedMetaData.ELEMENT_WILDCARD_FEATURE);
+ extendedMetaData.setWildcards(eReference, getWildcards(xsdWildcard));
+ extendedMetaData.setProcessingKind(eReference, xsdWildcard.getProcessContents().getValue() + 1);
+ extendedMetaData.setName(eReference, ":" + eClass.getEAllStructuralFeatures().indexOf(eReference));
+ }
+ else
+ {
+ extendedMetaData.setFeatureKind(eReference, ExtendedMetaData.GROUP_FEATURE);
+ extendedMetaData.setName(eReference, ":" + eClass.getEAllStructuralFeatures().indexOf(eReference));
+ }
+ }
+ else if (xsdComponent instanceof XSDElementDeclaration)
+ {
+ XSDElementDeclaration xsdElementDeclaration = (XSDElementDeclaration)xsdComponent;
+ eReference.setContainment(true);
+ eReference.setResolveProxies(false);
+ extendedMetaData.setFeatureKind(eReference, ExtendedMetaData.ELEMENT_FEATURE);
+ extendedMetaData.setName(eReference, xsdElementDeclaration.getName());
+ extendedMetaData.setNamespace(eReference, xsdElementDeclaration.getTargetNamespace());
+
+ XSDElementDeclaration substitutionGroupAffiliation = xsdElementDeclaration.getSubstitutionGroupAffiliation();
+ if (substitutionGroupAffiliation != null)
+ {
+ EStructuralFeature affiliation = getEStructuralFeature(substitutionGroupAffiliation);
+ extendedMetaData.setAffiliation(eReference, affiliation);
+ }
+ XSDTypeDefinition xsdType = getEffectiveTypeDefinition(null, xsdElementDeclaration);
+ if (xsdType instanceof XSDSimpleTypeDefinition)
+ {
+ eReference.setResolveProxies(!isLocalReferenceType((XSDSimpleTypeDefinition)xsdType));
+ }
+
+ if (maxOccurs == 1 && xsdElementDeclaration.isNillable())
+ {
+ eReference.setUnsettable(true);
+ }
+
+ if (xsdElementDeclaration.isAbstract())
+ {
+ eReference.setChangeable(false);
+ }
+ }
+ else if (xsdComponent instanceof XSDAttributeUse)
+ {
+ String opposite = getEcoreAttribute(xsdComponent, "opposite");
+ if (opposite != null)
+ {
+ eReferenceToOppositeNameMap.put(eReference, opposite);
+ }
+
+ XSDAttributeUse xsdAttributeUse = (XSDAttributeUse)xsdComponent;
+ XSDAttributeDeclaration xsdAttributeDeclaration = xsdAttributeUse.getAttributeDeclaration();
+ extendedMetaData.setFeatureKind(eReference, ExtendedMetaData.ATTRIBUTE_FEATURE);
+ extendedMetaData.setName(eReference, xsdAttributeDeclaration.getName());
+ extendedMetaData.setNamespace(eReference, xsdAttributeDeclaration.getTargetNamespace());
+ eReference.setResolveProxies
+ (!isLocalReferenceType((XSDSimpleTypeDefinition)getEffectiveTypeDefinition(xsdAttributeUse, xsdAttributeDeclaration)));
+ }
+ else if (xsdComponent instanceof XSDAttributeDeclaration)
+ {
+ XSDAttributeDeclaration xsdAttributeDeclaration = (XSDAttributeDeclaration)xsdComponent;
+ extendedMetaData.setFeatureKind(eReference, ExtendedMetaData.ATTRIBUTE_FEATURE);
+ extendedMetaData.setName(eReference, xsdAttributeDeclaration.getName());
+ extendedMetaData.setNamespace(eReference, xsdAttributeDeclaration.getTargetNamespace());
+ eReference.setResolveProxies
+ (!isLocalReferenceType((XSDSimpleTypeDefinition)getEffectiveTypeDefinition(null, xsdAttributeDeclaration)));
+ }
+ }
+
+ return eReference;
+ }
+ else
+ {
+ EAttribute eAttribute = ecoreFactory.createEAttribute();
+ setAnnotations(eAttribute, xsdComponent);
+ eAttribute.setName(Character.toLowerCase(name.charAt(0)) + name.substring(1));
+ eAttribute.setUnique(false);
+ eAttribute.setEType(type);
+ eAttribute.setLowerBound(minOccurs);
+ eAttribute.setUpperBound(maxOccurs);
+ eClass.getEStructuralFeatures().add(eAttribute);
+
+ if (xsdComponent == null || xsdComponent instanceof XSDSimpleTypeDefinition)
+ {
+ extendedMetaData.setName(eAttribute, ":" + eClass.getEAllStructuralFeatures().indexOf(eAttribute));
+ extendedMetaData.setFeatureKind(eAttribute, ExtendedMetaData.SIMPLE_FEATURE);
+ }
+ else
+ {
+ map(xsdComponent, eAttribute);
+ if (xsdComponent instanceof XSDAttributeUse)
+ {
+ XSDAttributeUse xsdAttributeUse = (XSDAttributeUse)xsdComponent;
+ XSDAttributeDeclaration xsdAttributeDeclaration = xsdAttributeUse.getAttributeDeclaration();
+ extendedMetaData.setFeatureKind(eAttribute, ExtendedMetaData.ATTRIBUTE_FEATURE);
+ extendedMetaData.setName(eAttribute, xsdAttributeDeclaration.getName());
+ extendedMetaData.setNamespace(eAttribute, xsdAttributeDeclaration.getTargetNamespace());
+
+ String defaultValue = getEcoreAttribute(xsdComponent, "default");
+ if (defaultValue == null)
+ {
+ defaultValue = xsdAttributeUse.getLexicalValue();
+ }
+ eAttribute.setDefaultValueLiteral(defaultValue);
+ initialize(eAttribute, (XSDSimpleTypeDefinition)getEffectiveTypeDefinition(xsdAttributeUse, xsdAttributeDeclaration));
+ }
+ else if (xsdComponent instanceof XSDAttributeDeclaration)
+ {
+ XSDAttributeDeclaration xsdAttributeDeclaration = (XSDAttributeDeclaration)xsdComponent;
+ extendedMetaData.setFeatureKind(eAttribute, ExtendedMetaData.ATTRIBUTE_FEATURE);
+ extendedMetaData.setName(eAttribute, xsdAttributeDeclaration.getName());
+ extendedMetaData.setNamespace(eAttribute, xsdAttributeDeclaration.getTargetNamespace());
+
+ eAttribute.setDefaultValueLiteral(xsdAttributeDeclaration.getLexicalValue());
+ initialize(eAttribute, (XSDSimpleTypeDefinition)getEffectiveTypeDefinition(null, xsdAttributeDeclaration));
+ }
+ else if (xsdComponent instanceof XSDParticle)
+ {
+ XSDTerm xsdTerm = ((XSDParticle)xsdComponent).getTerm();
+ if (xsdTerm instanceof XSDElementDeclaration)
+ {
+ XSDElementDeclaration xsdElementDeclaration = (XSDElementDeclaration)xsdTerm;
+ extendedMetaData.setFeatureKind(eAttribute, ExtendedMetaData.ELEMENT_FEATURE);
+ extendedMetaData.setName(eAttribute, xsdElementDeclaration.getName());
+ extendedMetaData.setNamespace(eAttribute, xsdElementDeclaration.getTargetNamespace());
+
+ eAttribute.setDefaultValueLiteral(xsdElementDeclaration.getLexicalValue());
+ XSDTypeDefinition xsdType = getEffectiveTypeDefinition(xsdComponent, xsdElementDeclaration);
+ if (xsdType instanceof XSDSimpleTypeDefinition)
+ {
+ initialize(eAttribute, (XSDSimpleTypeDefinition)xsdType);
+ }
+
+ if (xsdElementDeclaration.isNillable())
+ {
+ if (!canSupportNull((EDataType)type))
+ {
+ eAttribute.setEType(type = (EDataType)typeToTypeObjectMap.get(type));
+ }
+ if (maxOccurs == 1)
+ {
+ eAttribute.setUnsettable(true);
+ }
+ }
+
+ if (xsdElementDeclaration.isAbstract())
+ {
+ eAttribute.setChangeable(false);
+ }
+ }
+ else if (xsdTerm instanceof XSDWildcard)
+ {
+ XSDWildcard xsdWildcard = (XSDWildcard)xsdTerm;
+ extendedMetaData.setFeatureKind(eAttribute, ExtendedMetaData.ELEMENT_WILDCARD_FEATURE);
+ extendedMetaData.setWildcards(eAttribute, getWildcards(xsdWildcard));
+ extendedMetaData.setProcessingKind(eAttribute, xsdWildcard.getProcessContents().getValue() + 1);
+ extendedMetaData.setName(eAttribute, ":" + eClass.getEAllStructuralFeatures().indexOf(eAttribute));
+ }
+ else
+ {
+ extendedMetaData.setFeatureKind(eAttribute, ExtendedMetaData.GROUP_FEATURE);
+ }
+ }
+ else if (xsdComponent instanceof XSDWildcard)
+ {
+ XSDWildcard xsdWildcard = (XSDWildcard)xsdComponent;
+ extendedMetaData.setFeatureKind(eAttribute, ExtendedMetaData.ATTRIBUTE_WILDCARD_FEATURE);
+ extendedMetaData.setWildcards(eAttribute, getWildcards(xsdWildcard));
+ extendedMetaData.setProcessingKind(eAttribute, xsdWildcard.getProcessContents().getValue() + 1);
+ extendedMetaData.setName(eAttribute, ":" + eClass.getEAllStructuralFeatures().indexOf(eAttribute));
+ }
+ else if (xsdComponent instanceof XSDElementDeclaration)
+ {
+ XSDElementDeclaration xsdElementDeclaration = (XSDElementDeclaration)xsdComponent;
+ extendedMetaData.setFeatureKind(eAttribute, ExtendedMetaData.ELEMENT_FEATURE);
+ extendedMetaData.setName(eAttribute, xsdElementDeclaration.getName());
+ extendedMetaData.setNamespace(eAttribute, xsdElementDeclaration.getTargetNamespace());
+
+ eAttribute.setDefaultValueLiteral(xsdElementDeclaration.getLexicalValue());
+ XSDTypeDefinition xsdType = getEffectiveTypeDefinition(null, xsdElementDeclaration);
+ if (xsdType instanceof XSDSimpleTypeDefinition)
+ {
+ initialize(eAttribute, (XSDSimpleTypeDefinition)xsdType);
+ }
+
+ XSDElementDeclaration substitutionGroupAffiliation = xsdElementDeclaration.getSubstitutionGroupAffiliation();
+ if (substitutionGroupAffiliation != null)
+ {
+ EStructuralFeature affiliation = getEStructuralFeature(substitutionGroupAffiliation);
+ extendedMetaData.setAffiliation(eAttribute, affiliation);
+ }
+
+ if (xsdElementDeclaration.isNillable() && !canSupportNull((EDataType)type))
+ {
+ eAttribute.setEType(type = (EDataType)typeToTypeObjectMap.get(type));
+ if (maxOccurs == 1)
+ {
+ eAttribute.setUnsettable(true);
+ }
+ }
+
+ if (xsdElementDeclaration.isAbstract())
+ {
+ eAttribute.setChangeable(false);
+ }
+ }
+ }
+
+ if (maxOccurs == 1 && (type.getDefaultValue() != null || eAttribute.getDefaultValueLiteral() != null))
+ {
+ eAttribute.setUnsettable(true);
+ }
+
+ return eAttribute;
+ }
+ }
+
+ protected XSDTypeDefinition getEffectiveTypeDefinition(XSDComponent xsdComponent, XSDFeature xsdFeature)
+ {
+ return xsdFeature == null ?
+ ((XSDComplexTypeDefinition)xsdComponent.eContainer()).getSimpleType() : xsdFeature.getType();
+ }
+
+ protected EStructuralFeature createFeature
+ (EClass eClass, XSDElementDeclaration xsdElementDeclaration, String name, XSDComponent xsdComponent, int minOccurs, int maxOccurs)
+ {
+ XSDTypeDefinition elementTypeDefinition = getEffectiveTypeDefinition(xsdComponent, xsdElementDeclaration);
+ EClassifier eClassifier = getEClassifier(elementTypeDefinition);
+
+ XSDTypeDefinition referenceType = getEcoreTypeQNameAttribute(xsdComponent, "reference");
+ if (referenceType == null)
+ {
+ referenceType = getEcoreTypeQNameAttribute(xsdElementDeclaration, "reference");
+ }
+ if (referenceType != null)
+ {
+ EClassifier referenceClassifier = getEClassifier(referenceType);
+ boolean needsHolder = false;
+ if (elementTypeDefinition instanceof XSDSimpleTypeDefinition)
+ {
+ XSDSimpleTypeDefinition xsdSimpleTypeDefinition = (XSDSimpleTypeDefinition)elementTypeDefinition;
+ if (xsdSimpleTypeDefinition.getVariety() == XSDVariety.LIST_LITERAL)
+ {
+ needsHolder = true;
+
+ EPackage holderPackage = getEPackage(xsdElementDeclaration);
+ String holderName = xsdElementDeclaration.getName() + ":holder";
+ EClass holderClass = (EClass)extendedMetaData.getType(holderPackage, holderName);
+ if (holderClass == null)
+ {
+ // Create a holder class like an anonymous complex type.
+ //
+ holderClass = ecoreFactory.createEClass();
+ setAnnotations(holderClass, xsdElementDeclaration);
+ holderClass.setName(validName(holderName, true));
+ extendedMetaData.setName(holderClass, holderName);
+ extendedMetaData.setContentKind(holderClass, ExtendedMetaData.SIMPLE_CONTENT);
+
+ addToSortedList(holderPackage.getEClassifiers(), holderClass);
+
+ EReference holderReference =
+ (EReference)createFeature
+ (holderClass,
+ "value",
+ referenceClassifier,
+ null,
+ 0,
+ -1);
+
+ holderReference.setResolveProxies(!isLocalReferenceType(xsdSimpleTypeDefinition));
+ }
+ referenceClassifier = holderClass;
+ }
+ }
+ EStructuralFeature result =
+ createFeature
+ (eClass,
+ name,
+ referenceClassifier,
+ xsdComponent,
+ minOccurs,
+ maxOccurs);
+ ((EReference)result).setContainment(needsHolder);
+ if (needsHolder)
+ {
+ ((EReference)result).setUnsettable(false);
+ ((EReference)result).setResolveProxies(false);
+ }
+ initialize(result, xsdElementDeclaration, xsdComponent);
+ return result;
+ }
+ else
+ {
+ EStructuralFeature result =
+ createFeature
+ (eClass,
+ name,
+ eClassifier,
+ xsdComponent,
+ minOccurs,
+ maxOccurs);
+ initialize(result, xsdElementDeclaration, xsdComponent);
+ return result;
+ }
+ }
+
+ protected EStructuralFeature createFeature
+ (EClass eClass, XSDAttributeDeclaration xsdAttributeDeclaration, String name, XSDComponent xsdComponent, boolean isRequired)
+ {
+ XSDSimpleTypeDefinition attributeTypeDefinition = (XSDSimpleTypeDefinition)getEffectiveTypeDefinition(xsdComponent, xsdAttributeDeclaration);
+ if (attributeTypeDefinition == null)
+ {
+ attributeTypeDefinition = xsdComponent.getSchema().getSchemaForSchema().resolveSimpleTypeDefinition("anySimpleType");
+ }
+
+ XSDTypeDefinition referenceType = getEcoreTypeQNameAttribute(xsdComponent, "reference");
+ if (referenceType == null && xsdAttributeDeclaration != null)
+ {
+ referenceType = getEcoreTypeQNameAttribute(xsdAttributeDeclaration, "reference");
+ }
+ if (referenceType != null)
+ {
+ int lowerBound = isRequired ? 1 : 0;
+ int upperBound = 1;
+ if (attributeTypeDefinition.getVariety() == XSDVariety.LIST_LITERAL)
+ {
+ XSDLengthFacet xsdLengthFacet = attributeTypeDefinition.getEffectiveLengthFacet();
+ if (isRequired)
+ {
+ if (xsdLengthFacet != null)
+ {
+ lowerBound = xsdLengthFacet.getValue();
+ }
+ else
+ {
+ XSDMinLengthFacet xsdMinLengthFacet = attributeTypeDefinition.getEffectiveMinLengthFacet();
+ if (xsdMinLengthFacet != null)
+ {
+ lowerBound = xsdMinLengthFacet.getValue();
+ }
+ }
+ }
+ if (xsdLengthFacet != null)
+ {
+ upperBound = xsdLengthFacet.getValue();
+ }
+ else
+ {
+ XSDMaxLengthFacet xsdMaxLengthFacet = attributeTypeDefinition.getEffectiveMaxLengthFacet();
+ if (xsdMaxLengthFacet != null)
+ {
+ upperBound = xsdMaxLengthFacet.getValue();
+ }
+ else
+ {
+ upperBound = -1;
+ }
+ }
+ }
+
+ EClassifier referenceClassifier = getEClassifier(referenceType);
+ EStructuralFeature result =
+ createFeature
+ (eClass,
+ name,
+ referenceClassifier,
+ xsdComponent,
+ lowerBound,
+ upperBound);
+ initialize(result, xsdAttributeDeclaration, xsdComponent);
+ return result;
+ }
+ else
+ {
+ boolean isMany =
+ attributeTypeDefinition.getVariety() == XSDVariety.LIST_LITERAL &&
+ xsdComponent instanceof XSDAttributeUse &&
+ "true".equals(getEcoreAttribute(xsdComponent, "many"));
+ if (isMany)
+ {
+ EDataType eDataType = getEDataType(attributeTypeDefinition.getItemTypeDefinition());
+ XSDLengthFacet xsdLengthFacet = attributeTypeDefinition.getEffectiveLengthFacet();
+ int lowerBound = isRequired ? 1 : 0;
+ int upperBound = -1;
+ if (isRequired)
+ {
+ if (xsdLengthFacet != null)
+ {
+ lowerBound = xsdLengthFacet.getValue();
+ }
+ else
+ {
+ XSDMinLengthFacet xsdMinLengthFacet = attributeTypeDefinition.getEffectiveMinLengthFacet();
+ if (xsdMinLengthFacet != null)
+ {
+ lowerBound = xsdMinLengthFacet.getValue();
+ }
+ }
+ }
+ if (xsdLengthFacet != null)
+ {
+ upperBound = xsdLengthFacet.getValue();
+ }
+ else
+ {
+ XSDMaxLengthFacet xsdMaxLengthFacet = attributeTypeDefinition.getEffectiveMaxLengthFacet();
+ if (xsdMaxLengthFacet != null)
+ {
+ upperBound = xsdMaxLengthFacet.getValue();
+ }
+ }
+ EStructuralFeature result =
+ createFeature
+ (eClass,
+ name,
+ eDataType,
+ xsdComponent,
+ lowerBound,
+ upperBound);
+ initialize(result, xsdAttributeDeclaration, xsdComponent);
+ return result;
+ }
+ else
+ {
+ EDataType eDataType = getEDataType(attributeTypeDefinition);
+ EStructuralFeature result =
+ createFeature
+ (eClass,
+ name,
+ eDataType,
+ xsdComponent,
+ isRequired ? 1 : 0,
+ 1);
+ initialize(result, xsdAttributeDeclaration, xsdComponent);
+ return result;
+ }
+ }
+ }
+
+ public EStructuralFeature getEStructuralFeature(XSDFeature xsdFeature)
+ {
+ if ("true".equals(getEcoreAttribute(xsdFeature, "ignore"))) return null;
+ EStructuralFeature eStructuralFeature = (EStructuralFeature)xsdComponentToEModelElementMap.get(xsdFeature);
+ if (eStructuralFeature == null)
+ {
+ EPackage ePackage = getEPackage(xsdFeature);
+ EClass documentEClass = extendedMetaData.getDocumentRoot(ePackage);
+ if (documentEClass == null)
+ {
+ createDocumentRoot(xsdFeature.getSchema(), ePackage);
+ }
+
+ String name = getEcoreAttribute(xsdFeature, "name");
+ if (name == null)
+ {
+ name= validName(xsdFeature.getName(), true);
+ }
+
+ if (xsdFeature instanceof XSDElementDeclaration)
+ {
+ // Mark the bound as unspecified so that it won't be considered many
+ // but can nevertheless be recognized as being unspecified and perhaps still be treat as many.
+ //
+ EStructuralFeature result =
+ createFeature(documentEClass, (XSDElementDeclaration)xsdFeature, name, xsdFeature, 0, ETypedElement.UNSPECIFIED_MULTIPLICITY);
+
+ result.setDerived(true);
+ result.setTransient(true);
+ result.setVolatile(true);
+ return result;
+ }
+ else
+ {
+ EStructuralFeature result =
+ createFeature(documentEClass, (XSDAttributeDeclaration)xsdFeature, name, xsdFeature, false);
+ return result;
+ }
+ }
+
+ return eStructuralFeature;
+ }
+
+ public void generate(XSDSchema xsdSchema)
+ {
+ this.rootSchema = xsdSchema;
+ if (xsdSchemas.add(xsdSchema))
+ {
+ addInput(xsdSchema);
+ validate(xsdSchema);
+ }
+
+ Collection visitedElementDeclarations = new ArrayList();
+ Collection elementDeclarations = new ArrayList(xsdSchema.getElementDeclarations());
+
+ Collection visitedAttributeDeclarations = new ArrayList();
+ Collection attributeDeclarations = new ArrayList(xsdSchema.getAttributeDeclarations());
+
+ Collection visitedTypeDefinitions = new ArrayList();
+ Collection typeDefinitions = new ArrayList(xsdSchema.getTypeDefinitions());
+
+ while (!elementDeclarations.isEmpty() || !attributeDeclarations.isEmpty() || !typeDefinitions.isEmpty())
+ {
+ for (Iterator i = elementDeclarations.iterator(); i.hasNext(); )
+ {
+ XSDElementDeclaration xsdElementDeclaration = (XSDElementDeclaration)i.next();
+ getEStructuralFeature(xsdElementDeclaration);
+ }
+ visitedElementDeclarations.addAll(elementDeclarations);
+ elementDeclarations = new ArrayList(xsdSchema.getElementDeclarations());
+ elementDeclarations.removeAll(visitedElementDeclarations);
+
+ for (Iterator i = attributeDeclarations.iterator(); i.hasNext(); )
+ {
+ XSDAttributeDeclaration xsdAttributeDeclaration = (XSDAttributeDeclaration)i.next();
+ if (!XSDConstants.isSchemaInstanceNamespace(xsdAttributeDeclaration.getTargetNamespace()))
+ {
+ getEStructuralFeature(xsdAttributeDeclaration);
+ }
+ }
+ visitedAttributeDeclarations.addAll(attributeDeclarations);
+ attributeDeclarations = new ArrayList(xsdSchema.getAttributeDeclarations());
+ attributeDeclarations.removeAll(visitedAttributeDeclarations);
+
+ for (Iterator i = typeDefinitions.iterator(); i.hasNext(); )
+ {
+ XSDTypeDefinition xsdTypeDefinition = (XSDTypeDefinition)i.next();
+ getEClassifier(xsdTypeDefinition);
+ }
+ visitedTypeDefinitions.addAll(typeDefinitions);
+ typeDefinitions = new ArrayList(xsdSchema.getTypeDefinitions());
+ typeDefinitions.removeAll(visitedTypeDefinitions);
+ }
+
+ resolveNameConflicts();
+
+ for (Iterator i = xsdSchemas.iterator(); i.hasNext(); )
+ {
+ XSDSchema generatedXSDSchema = (XSDSchema)i.next();
+ EPackage ePackage = (EPackage)targetNamespaceToEPackageMap.get(generatedXSDSchema.getTargetNamespace());
+ if (ePackage != null)
+ {
+ String packageName= getEcoreAttribute(generatedXSDSchema, "package");
+ if (packageName != null)
+ {
+ ePackage.setName(packageName);
+ }
+ String packageNsPrefix= getEcoreAttribute(generatedXSDSchema, "nsPrefix");
+ if (packageNsPrefix != null)
+ {
+ ePackage.setNsPrefix(packageNsPrefix);
+ }
+ }
+ }
+
+ for (Iterator i = eReferenceToOppositeNameMap.entrySet().iterator(); i.hasNext(); )
+ {
+ Map.Entry entry = (Map.Entry)i.next();
+ EReference eReference = (EReference)entry.getKey();
+ String opposite = (String)entry.getValue();
+ EClass oppositeEClass = eReference.getEReferenceType();
+ if (eReference.getEOpposite() == null)
+ {
+ EStructuralFeature eOppositeFeature = oppositeEClass.getEStructuralFeature(opposite);
+
+ // Match by XML name if this fails.
+ if (eOppositeFeature == null)
+ {
+ for (Iterator j = oppositeEClass.getEAllStructuralFeatures().iterator(); j.hasNext(); )
+ {
+ EStructuralFeature feature = (EStructuralFeature)j.next();
+ if (opposite.equals(extendedMetaData.getName(feature)))
+ {
+ eOppositeFeature = feature;
+ break;
+ }
+ }
+ }
+
+ if (eOppositeFeature instanceof EReference)
+ {
+ EReference eOpposite = (EReference)eOppositeFeature;
+ eOpposite.setEOpposite(eReference);
+ eReference.setEOpposite(eOpposite);
+ }
+ }
+
+ if (eReference.getEOpposite() == null && eReference.isContainment())
+ {
+ EReference eOpposite = ecoreFactory.createEReference();
+ eOpposite.setName(opposite);
+ eOpposite.setEType(eReference.getEContainingClass());
+ eOpposite.setLowerBound(0);
+ eOpposite.setEOpposite(eReference);
+ eReference.setEOpposite(eOpposite);
+ eOpposite.setTransient(true);
+ oppositeEClass.getEStructuralFeatures().add(eOpposite);
+ }
+ }
+
+ eReferenceToOppositeNameMap.clear();
+ }
+
+}
diff --git a/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/CopyHelperImpl.java b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/CopyHelperImpl.java new file mode 100644 index 0000000000..d768076ecb --- /dev/null +++ b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/CopyHelperImpl.java @@ -0,0 +1,84 @@ +/** + * + * 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 org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.util.EcoreUtil.Copier; + +import commonj.sdo.ChangeSummary; +import commonj.sdo.DataObject; +import commonj.sdo.helper.CopyHelper; + + +/** + * A helper for copying DataObjects. + */ +public class CopyHelperImpl implements CopyHelper +{ + public DataObject copyShallow(DataObject dataObject) + { + Copier copier = new Copier() + { + protected void copyContainment(EReference eReference, EObject eObject, EObject copyEObject) + { + } + + protected void copyAttribute(EAttribute eAttribute, EObject eObject, EObject copyEObject) { + if(("ChangeSummaryType".equals(eAttribute.getEType().getName()) && "commonj.sdo".equals(eAttribute.getEType().getEPackage().getNsURI()))) { + boolean isLogging = ((ChangeSummary)eObject.eGet(eAttribute)).isLogging(); + ChangeSummary destSum = (ChangeSummary)copyEObject.eGet(eAttribute); + if(isLogging) { + if(!destSum.isLogging()) destSum.beginLogging(); + } else { + if(destSum.isLogging()) destSum.endLogging(); + } + } else { + super.copyAttribute(eAttribute, eObject, copyEObject); + } + } + }; + EObject result = copier.copy((EObject)dataObject); + copier.copyReferences(); + return (DataObject)result; + } + + public DataObject copy(DataObject dataObject) + { + Copier copier = new Copier() + { + + protected void copyAttribute(EAttribute eAttribute, EObject eObject, EObject copyEObject) { + if(("ChangeSummaryType".equals(eAttribute.getEType().getName()) && "commonj.sdo".equals(eAttribute.getEType().getEPackage().getNsURI()))) { + throw new UnsupportedOperationException("This will be implemented when change summary serialization/deserialization is in place"); + } else { + super.copyAttribute(eAttribute, eObject, copyEObject); + } + } + }; + EObject result = copier.copy((EObject)dataObject); + copier.copyReferences(); + return (DataObject)result; + } + + +} diff --git a/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/CrossScopeCopyHelperImpl.java b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/CrossScopeCopyHelperImpl.java new file mode 100644 index 0000000000..b7a5534800 --- /dev/null +++ b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/CrossScopeCopyHelperImpl.java @@ -0,0 +1,255 @@ +/**
+ *
+ * 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.Iterator;
+import java.util.Map;
+
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.ecore.util.FeatureMap;
+import org.eclipse.emf.ecore.util.FeatureMapUtil;
+import org.eclipse.emf.ecore.util.InternalEList;
+import org.eclipse.emf.ecore.util.EcoreUtil.Copier;
+
+import commonj.sdo.DataObject;
+import commonj.sdo.Type;
+import commonj.sdo.helper.CopyHelper;
+import commonj.sdo.helper.TypeHelper;
+
+/**
+ * A CopyHelper implementation that creates the copy objects in a specific metadata scope.
+ * The target scope must contain a compatible version of the Types needed to create the copy objects.
+ */
+public class CrossScopeCopyHelperImpl implements CopyHelper
+{
+ protected TypeHelper scope;
+
+ public CrossScopeCopyHelperImpl(TypeHelper targetScope)
+ {
+ scope = targetScope;
+ }
+
+ public DataObject copyShallow(DataObject dataObject)
+ {
+ Copier copier = new CrossScopeCopier()
+ {
+ protected void copyContainment(EReference eReference, EObject eObject, EObject copyEObject)
+ {
+ }
+ protected void copyAttribute(EAttribute eAttribute, EObject eObject, EObject copyEObject)
+ {
+ if (eObject.eIsSet(eAttribute) && !FeatureMapUtil.isFeatureMap(eAttribute))
+ {
+ super.copyAttribute(eAttribute,eObject,copyEObject);
+ }
+ }
+ };
+ EObject result = copier.copy((EObject)dataObject);
+ copier.copyReferences();
+ return (DataObject)result;
+ }
+
+ public DataObject copy(DataObject dataObject)
+ {
+ Copier copier = new CrossScopeCopier();
+ DataObject result = (DataObject)copier.copy((EObject)dataObject);
+ copier.copyReferences();
+ return (DataObject)result;
+ }
+
+ protected class CrossScopeCopier extends EcoreUtil.Copier
+ {
+ protected boolean useOriginalReferences = false;
+
+ protected EClass getTarget(EClass eClass)
+ {
+ EClass target = (EClass)get(eClass);
+ if (target == null)
+ {
+ Type type = (Type)eClass;
+ target = (EClass)scope.getType(type.getURI(), type.getName());
+ }
+ return target;
+ }
+
+ protected EStructuralFeature getTarget(EStructuralFeature eStructuralFeature)
+ {
+ EClass eClass = getTarget(eStructuralFeature.getEContainingClass());
+ EStructuralFeature targetEf = eClass.getEStructuralFeature(eStructuralFeature.getName());
+ return targetEf;
+ }
+
+ /**
+ * This Method WILL BE REMOVED when EMF 3.0 is available
+ */
+ public void copyReferences()
+ {
+ for (Iterator i = entrySet().iterator(); i.hasNext();)
+ {
+ Map.Entry entry = (Map.Entry)i.next();
+ EObject eObject = (EObject)entry.getKey();
+ EObject copyEObject = (EObject)entry.getValue();
+ EClass eClass = eObject.eClass();
+ for (int j = 0, size = eClass.getFeatureCount(); j < size; ++j)
+ {
+ EStructuralFeature eStructuralFeature = eClass.getEStructuralFeature(j);
+ if (eStructuralFeature.isChangeable() && !eStructuralFeature.isDerived())
+ {
+ if (eStructuralFeature instanceof EReference)
+ {
+ EReference eReference = (EReference)eStructuralFeature;
+ if (!eReference.isContainment() && !eReference.isContainer())
+ {
+ copyReference(eReference, eObject, copyEObject);
+ }
+ }
+ else if (FeatureMapUtil.isFeatureMap(eStructuralFeature))
+ {
+ FeatureMap featureMap = (FeatureMap)eObject.eGet(eStructuralFeature);
+ FeatureMap copyFeatureMap = (FeatureMap)copyEObject.eGet(getTarget(eStructuralFeature));
+ int copyFeatureMapSize = copyFeatureMap.size();
+ for (int k = 0, featureMapSize = featureMap.size(); k < featureMapSize; ++k)
+ {
+ EStructuralFeature feature = featureMap.getEStructuralFeature(k);
+ if (feature instanceof EReference)
+ {
+ Object referencedEObject = featureMap.getValue(k);
+ Object copyReferencedEObject = get(referencedEObject);
+ if (copyReferencedEObject == null && referencedEObject != null)
+ {
+ EReference reference = (EReference)feature;
+ if (!useOriginalReferences || reference.isContainment() || reference.getEOpposite() != null)
+ {
+ continue;
+ }
+ copyReferencedEObject = referencedEObject;
+ }
+ // If we can't add it, it must aleady be in the list so find it and move it to the end.
+ //
+ if (!copyFeatureMap.add(feature, copyReferencedEObject))
+ {
+ for (int l = 0; l < copyFeatureMapSize; ++l)
+ {
+ if (copyFeatureMap.getEStructuralFeature(l) == feature && copyFeatureMap.getValue(l) == copyReferencedEObject)
+ {
+ copyFeatureMap.move(copyFeatureMap.size() - 1, l);
+ --copyFeatureMapSize;
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ copyFeatureMap.add(featureMap.get(k));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * This Method WILL BE REMOVED when EMF 3.0 is available
+ */
+ protected void copyReference(EReference eReference, EObject eObject, EObject copyEObject)
+ {
+ if (eObject.eIsSet(eReference))
+ {
+ if (eReference.isMany())
+ {
+ InternalEList source = (InternalEList)eObject.eGet(eReference);
+ InternalEList target = (InternalEList)copyEObject.eGet(getTarget(eReference));
+ if (source.isEmpty())
+ {
+ target.clear();
+ }
+ else
+ {
+ boolean isBidirectional = eReference.getEOpposite() != null;
+ int index = 0;
+ for (Iterator k = resolveProxies ? source.iterator() : source.basicIterator(); k.hasNext();)
+ {
+ Object referencedEObject = k.next();
+ Object copyReferencedEObject = get(referencedEObject);
+ if (copyReferencedEObject == null)
+ {
+ if (useOriginalReferences && !isBidirectional)
+ {
+ target.addUnique(index, referencedEObject);
+ ++index;
+ }
+ }
+ else
+ {
+ if (isBidirectional)
+ {
+ int position = target.indexOf(copyReferencedEObject);
+ if (position == -1)
+ {
+ target.addUnique(index, copyReferencedEObject);
+ }
+ else if (index != position)
+ {
+ target.move(index, copyReferencedEObject);
+ }
+ }
+ else
+ {
+ target.addUnique(index, copyReferencedEObject);
+ }
+ ++index;
+ }
+ }
+ }
+ }
+ else
+ {
+ Object referencedEObject = eObject.eGet(eReference, resolveProxies);
+ if (referencedEObject == null)
+ {
+ copyEObject.eSet(getTarget(eReference), null);
+ }
+ else
+ {
+ Object copyReferencedEObject = get(referencedEObject);
+ if (copyReferencedEObject == null)
+ {
+ if (useOriginalReferences && eReference.getEOpposite() == null)
+ {
+ copyEObject.eSet(getTarget(eReference), referencedEObject);
+ }
+ }
+ else
+ {
+ copyEObject.eSet(getTarget(eReference), copyReferencedEObject);
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/DataFactoryImpl.java b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/DataFactoryImpl.java new file mode 100644 index 0000000000..774d296eae --- /dev/null +++ b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/DataFactoryImpl.java @@ -0,0 +1,59 @@ +/** + * + * 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 org.apache.tuscany.sdo.util.DataObjectUtil; + +import commonj.sdo.DataObject; +import commonj.sdo.Type; +import commonj.sdo.helper.DataFactory; +import commonj.sdo.helper.HelperContext; + +/** + * A Factory for creating DataObjects. The created DataObjects are not connected + * to any other DataObjects. + */ +public class DataFactoryImpl implements DataFactory { + protected HelperContext helperContext; + + public DataFactoryImpl(HelperContext hc) { + this.helperContext = hc; + } + + public DataObject create(String uri, String typeName) { + Type type = helperContext.getTypeHelper().getType(uri, typeName); + return create(type); + } + + public DataObject create(Class interfaceClass) { + // TODO more efficient implementation ... this is a really bad one! + Type type = helperContext.getTypeHelper().getType(interfaceClass); + return create(type); + } + + public DataObject create(Type type) { + return DataObjectUtil.create(type); + } + + public HelperContext getHelperContext() { + return helperContext; + } + +} diff --git a/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/DataHelperImpl.java b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/DataHelperImpl.java new file mode 100644 index 0000000000..eafa78214d --- /dev/null +++ b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/DataHelperImpl.java @@ -0,0 +1,616 @@ +/** + * + * 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.math.BigDecimal; +import java.math.BigInteger; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.TimeZone; + +import org.apache.tuscany.sdo.util.DataObjectUtil; + +import commonj.sdo.Property; +import commonj.sdo.Type; +import commonj.sdo.helper.DataHelper; + +/** + * Data helper methods. + */ +public class DataHelperImpl implements DataHelper +{ + /** + * @param dateString - Must comply to the pattern of yyyy-MM-dd'T'HH:mm:ss'.'SSS'Z' + * @return null if dataString couldn't be parsed + */ + public synchronized Date toDate(String dateString) + { + if (dateString == null) + { + return null; + } + + SimpleDateFormat format; + Date result = null; + boolean negative = false; + String formatString; + dateString = dateString.trim(); + + // Determine if it is a negative Date, DateTime, or Duration + + if (dateString.length() > 2 && dateString.charAt(0) == '-' && dateString.charAt(1) != '-') + { + negative = true; + dateString = dateString.substring(1); + } + + // SDO Date Format ends with a Z + + if (dateString.endsWith("Z")) + { + if (dateString.indexOf('.') != -1) + formatString = new String("yyyy-MM-dd'T'HH:mm:ss'.'S'Z'"); + else + formatString = new String ("yyyy-MM-dd'T'HH:mm:ss'Z'"); + + format = new SimpleDateFormat(formatString); + format.setTimeZone(TimeZone.getTimeZone("UTC")); + + result = checkFormat(dateString, format); + + // If no match, continue to try further possibilities + + if (result != null) + { + if (negative) + return handleBCE(result); + else + return result; + } + + } + + // Duration format begins with a P + + if (dateString.startsWith("P")) + { + // Remove any spaces in the dateString + + String durationString = dateString.replaceAll(" ", ""); + + // Build the formatString based on the contents of dateString + + formatString = obtainDurationFormats(durationString); + format = new SimpleDateFormat(formatString); + result = checkFormat(durationString, format); + if (result != null) + { + if (negative) + return handleNegative(result); + else + return result; + } + } + + formatString = obtainSpecificFormat(dateString); + + if (formatString != null) + { + format = new SimpleDateFormat(formatString); + result = checkFormat(dateString, format); + + if (result != null) + { + if (negative) + return handleBCE(result); + else + return result; + } + } + + return null; + } + + private synchronized Date checkFormat(String dateString, SimpleDateFormat format) + { + String formatPattern = format.toPattern(); + StringBuffer addedFields = new StringBuffer(); + String fieldsString, parseString; + SimpleDateFormat compositeFormat; + Date dateValue; + + // For certain permissable input strings (e.g. those resulting from toYear + // toDay, toTime), there are fields missing which when converted to Date have + // default values. (e.g. Year -> 1970). Because of this, there can be great + // variation in how daylight savings time is accounted for. (e.g. In 1970 Britain + // was on DST year round, and during the summer of 1944 was on double daylight time.) + // Because these possible variations exist, it is assumed that the user would prefer + // the current handling of daylight savings time. As such, the year, month and day + // will default to their current values when absent. (The user should not be checking + // for Year=1970 (etc.) as evidence of taking the default, as explicitly setting a + // year to 1970 is valid and would then not be an instance of a default taken.) + + if (!(formatPattern.startsWith("P"))) + { + if (formatPattern.indexOf('y') == -1) + addedFields.append("yyyy "); + + if (formatPattern.indexOf('M') == -1) + addedFields.append("MM "); + + if (formatPattern.indexOf('d') == -1) + addedFields.append("dd "); + } + + fieldsString = addedFields.toString(); + + if (fieldsString.length() == 0) + { + parseString = dateString; + compositeFormat = format; + } + + else + { + compositeFormat = new SimpleDateFormat(fieldsString); + dateValue = new Date(System.currentTimeMillis()); + parseString = compositeFormat.format(dateValue) + dateString; + compositeFormat.applyPattern(fieldsString + formatPattern); + } + + try + { + return compositeFormat.parse(parseString); + } + + catch (ParseException parseException) + { + } + + return null; + } + + public synchronized String obtainSpecificFormat(String dateString) + { + StringBuffer formatBuffer = new StringBuffer(); + int colonIndex = dateString.indexOf(':'); + int hyphenIndex = dateString.indexOf('-'); + + if (dateString.startsWith("--")) + { + if (dateString.charAt(2) == '-') // starts with --- + formatBuffer.append("'---'dd"); + else if (dateString.substring(2).indexOf('-') == -1) + formatBuffer.append("'--'MM"); + else + formatBuffer.append("'--'MM'-'dd"); + } + + else if (colonIndex == 1 || colonIndex == 2) + { + if (dateString.indexOf('.') != -1) + formatBuffer.append("HH:mm:ss'.'S"); + else if (dateString.substring(colonIndex + 1).indexOf(':') != -1) + formatBuffer.append("HH:mm:ss"); + else + formatBuffer.append("HH:mm"); + } + + else if (hyphenIndex != -1) + { + if (dateString.substring(hyphenIndex + 1).indexOf('-') == -1) + formatBuffer.append("yyyy-MM"); + else if (colonIndex != -1) + { + if (dateString.indexOf('.') != -1) + formatBuffer.append("yyyy-MM-dd'T'HH:mm:ss'.'S"); + else if (dateString.substring(colonIndex + 1).indexOf(':') != -1) + formatBuffer.append("yyyy-MM-dd'T'HH:mm:ss"); + else + formatBuffer.append("yyyy-MM-dd'T'HH:mm"); + } + else + formatBuffer.append ("yyyy-MM-dd"); + } + else if (colonIndex == -1) // indexOf('-') == -1 + { + formatBuffer.append("yyyy"); + } + else + return null; + + // Determine if a Time Zone is included and needs to be parsed. + // --------------------------------- + // The only letter allowed in the above formats is 'T'. + // All times zones include at least one letter other than 'T'. + + int i = 0; + boolean letterFound = false; + char currentChar; + while (i < dateString.length() && !letterFound) + { + currentChar = dateString.charAt(i); + if (Character.isLetter(currentChar) && currentChar != 'T') + letterFound = true;; + i++; + } + + if (letterFound) + formatBuffer.append(" z"); + + return formatBuffer.toString(); + } + + public synchronized String obtainDurationFormats(String dateString) + { + String firstPart, secondPart; + StringBuffer formatBuffer = new StringBuffer("'P'"); + + // Must divide it into two parts to distinguish between Months and Minutes + + int time_index = dateString.indexOf('T'); + if (time_index != -1) + { + firstPart = dateString.substring(0, time_index + 1); + secondPart = dateString.substring(time_index); + } + else + { + firstPart = dateString; + secondPart = null; + } + + if (firstPart.indexOf('Y') != -1) + formatBuffer.append("yyyy'Y'"); + if (firstPart.indexOf('M') != -1) + formatBuffer.append("MM'M'"); + if (firstPart.indexOf('D') != -1) + formatBuffer.append("dd'D'"); + if (time_index != -1) + { + formatBuffer.append("'T'"); + + if (secondPart.indexOf('H') != -1) + formatBuffer.append("HH'H'"); + if (secondPart.indexOf('M') != -1) + formatBuffer.append("mm'M'"); + if (secondPart.indexOf("S.") != -1) + formatBuffer.append("ss'S'.S"); + else if (secondPart.indexOf('S') != -1) + formatBuffer.append("ss'S'"); + } + + return formatBuffer.toString().replaceAll("''", ""); + } + + // Return a negative Duration if a negative sign existed in dateString + public synchronized Date handleNegative(Date output) + { + return new Date(0 - output.getTime()); + } + + // Return the date in BCE if a negative sign existed in dateString + + public synchronized Date handleBCE(Date output) + { + GregorianCalendar temp = new GregorianCalendar(); + temp.setTime(output); + temp.set(GregorianCalendar.ERA, GregorianCalendar.BC); + + return temp.getTime(); + } + + public synchronized Calendar toCalendar(String dateString) + { + return toCalendar(dateString, null); + } + + public synchronized Calendar toCalendar(String dateString, Locale locale) + { + if (dateString == null) + { + return null; + } + + Date date = toDate(dateString); + if (date == null) + { + return null; + } + + Calendar calendar = locale != null ? new GregorianCalendar(locale) : new GregorianCalendar(); + calendar.setTime(date); + return calendar; + } + + public synchronized String toDateTime(Date date) + { + if (date == null) + { + return null; + } + + SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'.'SSS'Z'"); + f.setTimeZone(TimeZone.getTimeZone("UTC")); + + return f.format(date); + } + + public synchronized String toDuration(Date date) + { + if (date == null) + { + return null; + } + + SimpleDateFormat f = new SimpleDateFormat("'P'yyyy'Y' MM'M' dd'D' 'T' HH'H' mm'M' ss'S.'SSS"); + + return f.format(date); + } + + public synchronized String toTime(Date date) + { + if (date == null) + { + return null; + } + + SimpleDateFormat f = new SimpleDateFormat("HH:mm:ss'.'SSS zz"); + + return f.format(date); + } + + public synchronized String toDay(Date date) + { + if (date == null) + { + return null; + } + + SimpleDateFormat f = new SimpleDateFormat("---dd zz"); + + return f.format(date); + } + + public synchronized String toMonth(Date date) + { + if (date == null) + { + return null; + } + + SimpleDateFormat f = new SimpleDateFormat("--MM zz"); + + return f.format(date); + } + + public synchronized String toMonthDay(Date date) + { + if (date == null) + { + return null; + } + + SimpleDateFormat f = new SimpleDateFormat("--MM-dd zz"); + + return f.format(date); + } + + public synchronized String toYear(Date date) + { + if (date == null) + { + return null; + } + + SimpleDateFormat f = new SimpleDateFormat("yyyy zz"); + + return f.format(date); + } + + public synchronized String toYearMonth(Date date) + { + if (date == null) + { + return null; + } + + SimpleDateFormat f = new SimpleDateFormat("yyyy-MM zz"); + + return f.format(date); + } + + public synchronized String toYearMonthDay(Date date) + { + if (date == null) + { + return null; + } + + SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd zz"); + + return f.format(date); + } + + public synchronized String toDateTime(Calendar calendar) + { + if (calendar == null) + { + return null; + } + + return toDateTime(calendar.getTime()); + } + + public synchronized String toDuration(Calendar calendar) + { + if (calendar == null) + { + return null; + } + + return toDuration(calendar.getTime()); + } + + public synchronized String toTime(Calendar calendar) + { + if (calendar == null) + { + return null; + } + + return toTime(calendar.getTime()); + } + + public synchronized String toDay(Calendar calendar) + { + if (calendar == null) + { + return null; + } + + return toDay(calendar.getTime()); + } + + public synchronized String toMonth(Calendar calendar) + { + if (calendar == null) + { + return null; + } + + return toMonth(calendar.getTime()); + } + + public synchronized String toMonthDay(Calendar calendar) + { + if (calendar == null) + { + return null; + } + + return toMonthDay(calendar.getTime()); + } + + public synchronized String toYear(Calendar calendar) + { + if (calendar == null) + { + return null; + } + + return toYear(calendar.getTime()); + } + + public synchronized String toYearMonth(Calendar calendar) + { + if (calendar == null) + { + return null; + } + + return toYearMonth(calendar.getTime()); + } + + public synchronized String toYearMonthDay(Calendar calendar) + { + if (calendar == null) + { + return null; + } + + return toYearMonthDay(calendar.getTime()); + } + + public Object convert(Type type, Object value) + { + Class typeClass = type.getInstanceClass(); + if (typeClass.isInstance(value)) + return value; + + if (typeClass == BigDecimal.class) { + return DataObjectUtil.getBigDecimal(value); + } + else if (typeClass == BigInteger.class) { + return DataObjectUtil.getBigInteger(value); + } + else if (typeClass == boolean.class || typeClass == Boolean.class) { + return new Boolean(DataObjectUtil.getBoolean(value)); + } + else if (typeClass == byte.class || typeClass == Byte.class) { + return new Byte(DataObjectUtil.getByte(value)); + } + else if (typeClass == byte[].class) { + return DataObjectUtil.getBytes(value); + } + else if (typeClass == char.class || typeClass == Character.class) { + return new Character(DataObjectUtil.getChar(value)); + } + else if (typeClass == Date.class) { + return DataObjectUtil.getDate(value); + } + else if (typeClass == double.class || typeClass == Double.class) { + return new Double(DataObjectUtil.getDouble(value)); + } + else if (typeClass == float.class || typeClass == Float.class) { + return new Float(DataObjectUtil.getFloat(value)); + } + else if (typeClass == int.class || typeClass == Integer.class) { + return new Integer(DataObjectUtil.getInt(value)); + } + else if (typeClass == long.class || typeClass == Long.class) { + return new Long(DataObjectUtil.getLong(value)); + } + else if (typeClass == short.class || typeClass == Short.class) { + return new Short(DataObjectUtil.getShort(value)); + } + else if (typeClass == String.class) { + return DataObjectUtil.getString(value); + } + + throw new IllegalArgumentException(); + } + + public Object convert(Property property, Object value) + { + Type type = property.getType(); + if (!property.isMany()) + { + return convert(type, value); + } + else + { + List listValue = (List)value; + List listResult = new ArrayList(); + for (Iterator iter = listValue.iterator(); iter.hasNext(); ) { + listResult.add(convert(type, iter.next())); + } + return listResult; + } + } + +} diff --git a/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/DefaultHelperContextImpl.java b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/DefaultHelperContextImpl.java new file mode 100644 index 0000000000..a8804e9e5d --- /dev/null +++ b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/DefaultHelperContextImpl.java @@ -0,0 +1,72 @@ +/**
+ *
+ * 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.Map;
+import java.util.WeakHashMap;
+
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.impl.EPackageRegistryImpl;
+
+public class DefaultHelperContextImpl extends HelperContextImpl {
+ public DefaultHelperContextImpl(final boolean extensibleNamespaces) {
+ super(new SDOExtendedMetaDataImpl(new SDOPackageRegistryDelegator()), extensibleNamespaces);
+ }
+
+ public DefaultHelperContextImpl(final boolean extensibleNamespaces, final Map options) {
+ super(new SDOExtendedMetaDataImpl(new SDOPackageRegistryDelegator()), extensibleNamespaces, options);
+ }
+
+ protected static class SDOPackageRegistryDelegator extends EPackageRegistryImpl.Delegator {
+ /**
+ * A map from class loader to its associated registry.
+ */
+ protected Map classLoaderToRegistryMap = new WeakHashMap();
+
+ /**
+ * Returns the package registry associated with the given class loader.
+ * @param classLoader the class loader.
+ * @return the package registry associated with the given class loader.
+ */
+ public synchronized EPackage.Registry getRegistry(final ClassLoader classLoader)
+ {
+ EPackage.Registry result = (EPackage.Registry)classLoaderToRegistryMap.get(classLoader);
+ if (result == null)
+ {
+ if (classLoader == null)
+ {
+ result = HelperContextImpl.getBuiltInModelRegistry();
+ }
+ else
+ {
+ result = new EPackageRegistryImpl(getRegistry(classLoader.getParent()));
+ classLoaderToRegistryMap.put(classLoader, result);
+ }
+ }
+ return result;
+ }
+
+ protected EPackage.Registry delegateRegistry(final ClassLoader classLoader)
+ {
+ return getRegistry(classLoader);
+ }
+ }
+}
diff --git a/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/EqualityHelperImpl.java b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/EqualityHelperImpl.java new file mode 100644 index 0000000000..0d3d8ee5b7 --- /dev/null +++ b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/EqualityHelperImpl.java @@ -0,0 +1,96 @@ +/** + * + * 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 org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.util.EcoreUtil; + +import commonj.sdo.DataObject; +import commonj.sdo.helper.EqualityHelper; + + +/** + * A helper for comparing DataObjects. + */ +public class EqualityHelperImpl implements EqualityHelper +{ + public boolean equalShallow(DataObject dataObject1, DataObject dataObject2) + { + EcoreUtil.EqualityHelper equalityHelper = new EcoreUtil.EqualityHelper() + { + protected boolean haveEqualFeature(EObject eObject1, EObject eObject2, EStructuralFeature feature) + { + if (feature instanceof EAttribute) + { + if(!("ChangeSummaryType".equals(feature.getEType().getName()) && "commonj.sdo".equals(feature.getEType().getEPackage().getNsURI()))) { + boolean eIsSet = eObject1.eIsSet(feature); + if (eIsSet != eObject2.eIsSet(feature) || !haveEqualAttribute(eObject1, eObject2, (EAttribute)feature)) + { + return false; + } + } + } + return true; + } + + protected boolean equalFeatureMapValues(Object value1, Object value2, EStructuralFeature feature) + { + if (feature instanceof EAttribute) + { + return value1 == null ? value2 == null : value1.equals(value2); + } + return true; + } + }; + return equalityHelper.equals((EObject)dataObject1, (EObject)dataObject2); + } + + public boolean equal(DataObject dataObject1, DataObject dataObject2) + { + EcoreUtil.EqualityHelper equalityHelper = new EcoreUtil.EqualityHelper() + { + protected boolean haveEqualAttribute(EObject eObject1, EObject eObject2, EAttribute attribute) { + if(("ChangeSummaryType".equals(attribute.getEType().getName()) && "commonj.sdo".equals(attribute.getEType().getEPackage().getNsURI()))) { + throw new UnsupportedOperationException("This will be implemented when change summary serialzation/deserialization is in place"); + } + else if( "Bytes".equals(attribute.getEType().getName()) ) { + try + { + byte [] value1 = (byte [])eObject1.eGet(attribute); + byte [] value2 = (byte [])eObject2.eGet(attribute); + + return( java.util.Arrays.equals(value1,value2) ); + } + catch(Exception ex) + { + // if any exception is thrown, assumption is they are not equal + return false; + } + } + else { + return super.haveEqualAttribute(eObject1, eObject2, attribute); + } + } + }; + return equalityHelper.equals((EObject)dataObject1, (EObject)dataObject2); } +} diff --git a/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/HelperContextImpl.java b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/HelperContextImpl.java new file mode 100644 index 0000000000..64ee628693 --- /dev/null +++ b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/HelperContextImpl.java @@ -0,0 +1,193 @@ +/** + * + * 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.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EcorePackage; +import org.eclipse.emf.ecore.change.ChangePackage; +import org.eclipse.emf.ecore.impl.EPackageRegistryImpl; +import org.eclipse.emf.ecore.util.ExtendedMetaData; +import org.eclipse.emf.ecore.xml.namespace.XMLNamespacePackage; +import org.eclipse.emf.ecore.xml.type.XMLTypePackage; + +import commonj.sdo.helper.CopyHelper; +import commonj.sdo.helper.DataFactory; +import commonj.sdo.helper.DataHelper; +import commonj.sdo.helper.EqualityHelper; +import commonj.sdo.helper.HelperContext; +import commonj.sdo.helper.TypeHelper; +import commonj.sdo.helper.XMLHelper; +import commonj.sdo.helper.XSDHelper; + +import org.apache.tuscany.sdo.SDOPackage; +import org.apache.tuscany.sdo.api.XMLStreamHelper; + +public class HelperContextImpl implements HelperContext { + /* + * Relationship: HelperContext*Impl* ---1:1---> ExtendedMetaData ---1:1---> + * Map (:defaultOption) <---1:1---> TypeHelper <---1:1---> XMLHelper + * <---1:1---> XMLStreamHelper <---1:1---> XSDHelper <---1:1---> DataFactory + */ + + protected ExtendedMetaData extendedMetaData; + protected DataFactory dataFactory; + protected TypeHelper typeHelper; + protected XMLHelper xmlHelper; + protected XSDHelper xsdHelper; + protected XMLStreamHelper xmlStreamHelper; + protected Map defaultOptions = null; + + public HelperContextImpl(ExtendedMetaData extendedMetaData, boolean extensibleNamespaces) { + this.defaultOptions = null; + this.extendedMetaData = extendedMetaData; + typeHelper = new TypeHelperImpl(this); + dataFactory = new DataFactoryImpl(this); + xmlHelper = new XMLHelperImpl(this); + xsdHelper = new XSDHelperImpl(this, null, extensibleNamespaces); + xmlStreamHelper = new XMLStreamHelperImpl(this); + } + + + public HelperContextImpl(ExtendedMetaData extendedMetaData, boolean extensibleNamespaces, Map options) { + this.defaultOptions = options; + this.extendedMetaData = extendedMetaData; + typeHelper = new TypeHelperImpl(this); + dataFactory = new DataFactoryImpl(this); + xmlHelper = new XMLHelperImpl(this); + xsdHelper = new XSDHelperImpl(this, null, extensibleNamespaces); + xmlStreamHelper = new XMLStreamHelperImpl(this); + } + + // many places this is called in existing code + // This is used for supporting the deprecated util - + // org.apache.tuscany.sdo.util.SDOUtil + // Once we conpletely remove this deprecated util, we can remove the below + // constructor + public HelperContextImpl(TypeHelper scope) { + this(scope, null); + } + + + public HelperContextImpl(TypeHelper scope, Map options) { + this.defaultOptions = options; + typeHelper = scope; + this.extendedMetaData = ((TypeHelperImpl)scope).getExtendedMetaData(); + dataFactory = new DataFactoryImpl(this); + xmlHelper = new XMLHelperImpl(this); + xsdHelper = new XSDHelperImpl(this); + xmlStreamHelper = new XMLStreamHelperImpl(this); + } + + public HelperContextImpl(boolean extensibleNamespaces) { + this(new SDOExtendedMetaDataImpl(new EPackageRegistryImpl(getBuiltInModelRegistry())), extensibleNamespaces); + } + + + public HelperContextImpl(boolean extensibleNamespaces, Map options) { + this(new SDOExtendedMetaDataImpl(new EPackageRegistryImpl(getBuiltInModelRegistry())), extensibleNamespaces, + options); + } + + static protected EPackage.Registry builtInModelRegistry = null; + + static public EPackage.Registry getBuiltInModelRegistry() { + if (builtInModelRegistry == null) { + EPackageRegistryImpl registry = new EPackageRegistryImpl(); + for (Iterator iter = TypeHelperImpl.getBuiltInModels().iterator(); iter.hasNext();) { + EPackage ePackage = (EPackage)iter.next(); + registry.put(ePackage.getNsURI(), ePackage); + } + + registry.put(EcorePackage.eNS_URI, EcorePackage.eINSTANCE); + registry.put(XMLTypePackage.eNS_URI, XMLTypePackage.eINSTANCE); + registry.put(ChangePackage.eNS_URI, ChangePackage.eINSTANCE); + registry.put(XMLNamespacePackage.eNS_URI, XMLNamespacePackage.eINSTANCE); + registry.put(SDOPackage.eNS_URI, SDOPackage.eINSTANCE); + + builtInModelRegistry = registry; + } + return builtInModelRegistry; + } + + public CopyHelper getCopyHelper() { + return CopyHelper.INSTANCE; + } + + public DataFactory getDataFactory() { + return dataFactory; + } + + public DataHelper getDataHelper() { + return DataHelper.INSTANCE; + } + + public EqualityHelper getEqualityHelper() { + return EqualityHelper.INSTANCE; + } + + public TypeHelper getTypeHelper() { + return typeHelper; + } + + public XMLHelper getXMLHelper() { + return xmlHelper; + } + + public XMLStreamHelper getXMLStreamHelper() { + return xmlStreamHelper; + } + + public XSDHelper getXSDHelper() { + return xsdHelper; + } + + public void setOptions(Map options) { + this.defaultOptions = options; + } + + public Map getOptions() { + return this.defaultOptions; + } + + public Map getMergedOption(Map options) { + Map mergedOptions = null;// copy to be used for merge + + if (defaultOptions == null) { + return options; + } + + mergedOptions = new HashMap(defaultOptions); + if (options == null) { + return mergedOptions; + } + mergedOptions.putAll(options); + + return mergedOptions; + } + + public ExtendedMetaData getExtendedMetaData() { + return extendedMetaData; + } +} diff --git a/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/HelperProviderImpl.java b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/HelperProviderImpl.java new file mode 100644 index 0000000000..360617bd20 --- /dev/null +++ b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/HelperProviderImpl.java @@ -0,0 +1,50 @@ +/** + * + * 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 org.apache.tuscany.sdo.spi.HelperProviderBase; + +import commonj.sdo.helper.HelperContext; + +/** + * Create and manage all the default helper INSTANCEs + */ +public class HelperProviderImpl extends HelperProviderBase +{ + public HelperContext createDefaultHelpers() + { + //FB HelperContext hc = SDOUtil.createHelperContext(); + //FB The defulat HelperContext must use EMF's ClassLoader-delegating EPackage.Registry.INSTANCE, until we provide + //FB another way to get (ClassLoader scope) support for HelperContext. + HelperContext hc = new DefaultHelperContextImpl(false); + typeHelper = hc.getTypeHelper(); + dataFactory = hc.getDataFactory(); + xmlHelper = hc.getXMLHelper(); + xsdHelper = hc.getXSDHelper(); + copyHelper = new CopyHelperImpl(); + equalityHelper = new EqualityHelperImpl(); + dataHelper = new DataHelperImpl(); + sdoHelper = new SDOHelperImpl(); + xmlStreamHelper = ((HelperContextImpl)hc).getXMLStreamHelper(); + + return hc; + } +} diff --git a/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/SDOAnnotations.java b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/SDOAnnotations.java new file mode 100644 index 0000000000..816fb3bf9f --- /dev/null +++ b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/SDOAnnotations.java @@ -0,0 +1,51 @@ +/** + * + * 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; + +public class SDOAnnotations +{ + public static final String COLON = ":"; + public static final String COMMONJ_SDO_NS = "commonj.sdo"; + public static final String COMMONJ_SDO_NS_PREFIX = "sdo"; + public static final String SDO_JAVA_NS = "commonj.sdo/java"; + public static final String SDO_JAVA_NS_PREFIX = "sdoJava"; + + public static final String JAVA_PACKAGE = SDO_JAVA_NS_PREFIX + COLON + "package"; + public static final String ALIAS_NAMES = COMMONJ_SDO_NS_PREFIX + COLON + "aliasName"; + public static final String READ_ONLY = COMMONJ_SDO_NS_PREFIX + COLON + "readOnly"; + public static final String INSTANCE_CLASS = SDO_JAVA_NS_PREFIX + COLON + "instanceClass"; + public static final String ABSTRACT_TYPE = "abstract"; + public static final String PROPERTY_TYPE = COMMONJ_SDO_NS_PREFIX + COLON + "propertyType"; + public static final String OPPOSITE_PROPERTY = COMMONJ_SDO_NS_PREFIX + COLON + "oppositeProperty"; + + + //used by the annotations map to uniquely identify schema elements that need to be annotated + //and to store the corresponding annotations in a map + public static final String SCHEMA = "schema"; + public static final String ELEMENT = "element"; + public static final String COMPLEX_TYPE = "complexType"; + public static final String SIMPLE_TYPE = "simpleType"; + public static final String ATTRIBUTE = "attribute"; + + public static String makeAnnotationMapKey(String namespace, String schemaElementType, String nameAttrValue) + { + return namespace + schemaElementType + nameAttrValue; + } +} diff --git a/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/SDOExtendedMetaDataImpl.java b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/SDOExtendedMetaDataImpl.java new file mode 100644 index 0000000000..ba632a0523 --- /dev/null +++ b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/SDOExtendedMetaDataImpl.java @@ -0,0 +1,305 @@ +/** + * + * 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.Iterator; +import java.util.List; +import java.util.StringTokenizer; + +import org.apache.tuscany.sdo.SDOExtendedMetaData; +import org.apache.tuscany.sdo.impl.SDOFactoryImpl.SDOEcoreFactory; +import org.apache.tuscany.sdo.model.ModelFactory; +import org.apache.tuscany.sdo.model.impl.ModelFactoryImpl; +import org.eclipse.emf.ecore.EAnnotation; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EClassifier; +import org.eclipse.emf.ecore.EModelElement; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.EPackage.Registry; + +/** + * TODO make demand() methods synchronous? + */ +public class SDOExtendedMetaDataImpl + extends BaseSDOExtendedMetaDataImpl + implements SDOExtendedMetaData +{ + + public SDOExtendedMetaDataImpl() { + this(HelperContextImpl.getBuiltInModelRegistry()); + } + + public SDOExtendedMetaDataImpl(Registry registry) { + super(registry); + ecoreFactory = new SDOEcoreFactory(); + demandMetaData = new SDODemandMetaData(); + } + + public static class SDODemandMetaData extends DemandMetaData { + EClassifier getEObject() { return (EClassifier)((ModelFactoryImpl)ModelFactory.INSTANCE).getDataObject(); } + EClassifier getAnySimpleType() { return (EClassifier)((ModelFactoryImpl)ModelFactory.INSTANCE).getObject(); } + } + + public EPackage getPackage(String namespace) + { + if ("".equals(namespace)) namespace = null; //FB + EPackage result = registry.getEPackage(namespace); + return result == null ? super.getPackage(namespace) : result; + } + + /** + * Returns the listing of alias names as specified by the sdo:aliasNames + * property. + */ + public List getAliasNames(EModelElement modelElement) { + EAnnotation eAnnotation = getAnnotation(modelElement, false); + List list = null; + if (eAnnotation != null) { + String aliasNames = (String)eAnnotation.getDetails().get("aliasNames"); + if (aliasNames != null) { + list = new ArrayList(); + StringTokenizer st = new StringTokenizer(aliasNames, " "); + while (st.hasMoreTokens()) { + String t = st.nextToken(); + list.add(t); + } + } + } + return list; + } + + + public void setAliasNames(EModelElement modelElement, List aliasNames) { + if (aliasNames == null || aliasNames.isEmpty()) { + setAliasNames(modelElement, (String)null); + } else { + StringBuffer buf = new StringBuffer(); + for (int n = 0; n < aliasNames.size(); n++) { + String name = (String) aliasNames.get(n); + buf.append(name); + buf.append(" "); + } + setAliasNames(modelElement, buf.toString()); + } + } + + /** + * Adds an alias name per sdo:aliasName + */ + public void setAliasNames(EModelElement modelElement, String aliasNames) { + EAnnotation eAnnotation = getAnnotation(modelElement, true); + eAnnotation.getDetails().put("aliasNames", aliasNames); + } + + public EPackage.Registry getRegistry() + { + return registry; + } + + boolean featureNamespaceMatchingLax = true; + + public void setFeatureNamespaceMatchingLax(boolean b) { + featureNamespaceMatchingLax = b; + } + + protected boolean isFeatureNamespaceMatchingLax() { + return featureNamespaceMatchingLax; + } + + /* + * (non-Javadoc) + * + * Eagerly pre-cache the "holder"s for static packages. + * + * @see org.eclipse.emf.ecore.util.BasicExtendedMetaData#putPackage(java.lang.String, + * org.eclipse.emf.ecore.EPackage) + */ + public void putPackage(String namespace, EPackage ePackage) { + for (Iterator iterator = ePackage.eAllContents(); iterator.hasNext();) { + Object object = iterator.next(); + if (object instanceof EClassifier) { + this.getName((EClassifier) object); + } else if (object instanceof EStructuralFeature) { + this.getName((EStructuralFeature) object); + } + } + super.putPackage(namespace, ePackage); + } + + /****************************************************************************************************** + * Following methods, getLocalAttribute & getLocalElement, ARE TEMPORARY COPIES FROM THE BASE CLASS. + * One line (the last line)in each method is changed to support lax namespace matching. + * DO NOT EDIT THESE METHODS. THEY WILL BE REMOVED WHEN WE MOVE TO EMF 2.3, WHICH FIXES THE PROBLEM. + ******************************************************************************************************/ + + public EStructuralFeature getLocalAttribute(EClass eClass, String namespace, String name) + { + EStructuralFeature result = null; + if (isFeatureKindSpecific()) + { + List allAttributes = getAllAttributes(eClass); + for (int i = 0, size = allAttributes.size(); i < size; ++i) + { + EStructuralFeature eStructuralFeature = (EStructuralFeature) allAttributes.get(i); + if (name.equals(getName(eStructuralFeature))) + { + String featureNamespace = getNamespace(eStructuralFeature); + if (namespace == null) + { + if (featureNamespace == null) + { + return eStructuralFeature; + } + else if (result == null) + { + result = eStructuralFeature; + } + } + else if (namespace.equals(featureNamespace)) + { + return eStructuralFeature; + } + else if (featureNamespace == null && result == null) + { + result = eStructuralFeature; + } + } + } + } + else + { + for (int i = 0, size = eClass.getFeatureCount(); i < size; ++i) + { + EStructuralFeature eStructuralFeature = eClass.getEStructuralFeature(i); + switch (getFeatureKind(eStructuralFeature)) + { + case UNSPECIFIED_FEATURE: + case ATTRIBUTE_FEATURE: + { + if (name.equals(getName(eStructuralFeature))) + { + String featureNamespace = getNamespace(eStructuralFeature); + if (namespace == null) + { + if (featureNamespace == null) + { + return eStructuralFeature; + } + else if (result == null) + { + result = eStructuralFeature; + } + } + else if (namespace.equals(featureNamespace)) + { + return eStructuralFeature; + } + else if (featureNamespace == null && result == null) + { + result = eStructuralFeature; + } + } + break; + } + } + } + } + + return isFeatureNamespaceMatchingLax() ? result : null; + } + + protected EStructuralFeature getLocalElement(EClass eClass, String namespace, String name) + { + EStructuralFeature result = null; + if (isFeatureKindSpecific()) + { + List allElements = getAllElements(eClass); + for (int i = 0, size = allElements.size(); i < size; ++i) + { + EStructuralFeature eStructuralFeature = (EStructuralFeature) allElements.get(i); + if (name.equals(getName(eStructuralFeature))) + { + String featureNamespace = getNamespace(eStructuralFeature); + if (namespace == null) + { + if (featureNamespace == null) + { + return eStructuralFeature; + } + else if (result == null) + { + result = eStructuralFeature; + } + } + else if (namespace.equals(featureNamespace)) + { + return eStructuralFeature; + } + else if (featureNamespace == null && result == null) + { + result = eStructuralFeature; + } + } + } + } + else + { + for (int i = 0, size = eClass.getFeatureCount(); i < size; ++i) + { + EStructuralFeature eStructuralFeature = eClass.getEStructuralFeature(i); + switch (getFeatureKind(eStructuralFeature)) + { + case UNSPECIFIED_FEATURE: + case ELEMENT_FEATURE: + { + if (name.equals(getName(eStructuralFeature))) + { + String featureNamespace = getNamespace(eStructuralFeature); + if (namespace == null) + { + if (featureNamespace == null) + { + return eStructuralFeature; + } + else if (result == null) + { + result = eStructuralFeature; + } + } + else if (namespace.equals(featureNamespace)) + { + return eStructuralFeature; + } + else if (featureNamespace == null && result == null) + { + result = eStructuralFeature; + } + } + break; + } + } + } + } + + return isFeatureNamespaceMatchingLax() ? result : null; + } +} diff --git a/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/SDOHelperImpl.java b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/SDOHelperImpl.java new file mode 100644 index 0000000000..3efd8d03b7 --- /dev/null +++ b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/SDOHelperImpl.java @@ -0,0 +1,530 @@ +/**
+ *
+ * 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.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.tuscany.sdo.SDOExtendedMetaData;
+import org.apache.tuscany.sdo.SDOFactory;
+import org.apache.tuscany.sdo.SimpleAnyTypeDataObject;
+import org.apache.tuscany.sdo.api.SDOHelper;
+import org.apache.tuscany.sdo.api.XMLStreamHelper;
+import org.apache.tuscany.sdo.api.EventListener;
+import org.apache.tuscany.sdo.impl.ClassImpl;
+import org.apache.tuscany.sdo.impl.DataGraphImpl;
+import org.apache.tuscany.sdo.impl.DynamicDataObjectImpl;
+import org.apache.tuscany.sdo.model.ModelFactory;
+import org.apache.tuscany.sdo.model.impl.ModelFactoryImpl;
+import org.apache.tuscany.sdo.spi.SDOHelperBase;
+import org.apache.tuscany.sdo.util.DataObjectUtil;
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.common.util.UniqueEList;
+import org.eclipse.emf.ecore.EAnnotation;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EDataType;
+import org.eclipse.emf.ecore.EModelElement;
+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.ETypedElement;
+import org.eclipse.emf.ecore.EcoreFactory;
+import org.eclipse.emf.ecore.EcorePackage;
+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.FeatureMap;
+import org.eclipse.emf.ecore.util.FeatureMapUtil;
+import org.eclipse.emf.ecore.xmi.XMLResource;
+
+import commonj.sdo.DataGraph;
+import commonj.sdo.DataObject;
+import commonj.sdo.Property;
+import commonj.sdo.Sequence;
+import commonj.sdo.Type;
+import commonj.sdo.helper.CopyHelper;
+import commonj.sdo.helper.HelperContext;
+import commonj.sdo.helper.TypeHelper;
+import commonj.sdo.impl.HelperProvider;
+
+public class SDOHelperImpl extends SDOHelperBase implements SDOHelper, SDOHelper.MetaDataBuilder {
+
+ public DataObject createDataTypeWrapper(Type dataType, Object value) {
+ SimpleAnyTypeDataObject simpleAnyType = SDOFactory.eINSTANCE.createSimpleAnyTypeDataObject();
+ simpleAnyType.setInstanceType((EDataType)dataType);
+ simpleAnyType.setValue(value);
+ return simpleAnyType;
+ }
+
+ public Object createFromString(Type dataType, String literal) {
+ return EcoreUtil.createFromString((EDataType)dataType, literal);
+ }
+
+ public String convertToString(Type dataType, Object value) {
+ return EcoreUtil.convertToString((EDataType)dataType, value);
+ }
+
+ public Type getXSDSDOType(String xsdType) {
+ Type type = null;
+ String name = (String)xsdToSdoMappings.get(xsdType);
+ if (name != null)
+ type = (Type)((ModelFactoryImpl)ModelFactory.INSTANCE).getEClassifier(name);
+ return type;
+ }
+
+ public Sequence getSubstitutionValues(DataObject dataObject, Property head) {
+ final EStructuralFeature group = ExtendedMetaData.INSTANCE.getGroup((EStructuralFeature)head);
+ return null == group ? null : (Sequence)((FeatureMap.Internal)((EObject)dataObject).eGet(group)).getWrapper();
+ }
+
+ public Type getJavaSDOType(Class javaClass) {
+ String name = (String)javaToSdoMappings.get(javaClass);
+ if (name != null) {
+ return (Type)((ModelFactoryImpl)ModelFactory.INSTANCE).getEClassifier(name);
+ }
+ return null;
+ }
+
+ public boolean isRequired(Property property) {
+ return ((EStructuralFeature)property).isRequired();
+ }
+
+ public int getUpperBound(Property property) {
+ return ((EStructuralFeature)property).getUpperBound();
+ }
+
+ public int getLowerBound(Property property) {
+ return ((EStructuralFeature)property).getLowerBound();
+ }
+
+ public List getEnumerationFacet(Type type) {
+ List instProps = type.getInstanceProperties();
+ String propertyName = "enumeration";
+ Property enumProperty = null;
+
+ for (int i = 0; i < instProps.size(); i++)
+ {
+ Property prop = (Property)instProps.get(i);
+ if (propertyName.equals(prop.getName()))
+ enumProperty = prop;
+ }
+
+ return (List)DataObjectUtil.getMetaObjectInstanceProperty((EModelElement)type, enumProperty);
+ }
+
+ public List getPatternFacet(Type type) {
+ List instProps = type.getInstanceProperties();
+ String propertyName = "pattern";
+ Property patternProperty = null;
+
+ for (int i = 0; i < instProps.size(); i++)
+ {
+ Property prop = (Property)instProps.get(i);
+ if (propertyName.equals(prop.getName()))
+ patternProperty = prop;
+ }
+
+ return (List)DataObjectUtil.getMetaObjectInstanceProperty((EModelElement)type, patternProperty);
+ }
+
+ public boolean isMany(Property property, DataObject context) {
+ return FeatureMapUtil.isMany((EObject)context, (EStructuralFeature)property);
+ }
+
+ public DataGraph createDataGraph() {
+ return SDOFactory.eINSTANCE.createDataGraph();
+ }
+
+ public void setRootObject(DataGraph dataGraph, DataObject rootObject) {
+ ((DataGraphImpl)dataGraph).setERootObject((EObject)rootObject);
+ }
+
+ public static DataGraph loadDataGraph(InputStream inputStream, Map options) throws IOException {
+ ResourceSet resourceSet = DataObjectUtil.createResourceSet();
+ Resource resource = resourceSet.createResource(URI.createURI("all.datagraph"));
+ resource.load(inputStream, options);
+ return (DataGraph)resource.getContents().get(0);
+ }
+
+ static final Object LOADING_SCOPE = XMLResource.OPTION_EXTENDED_META_DATA;
+
+ protected void registerLoadingScope(Map options, TypeHelper scope) {
+ Object extendedMetaData = ((TypeHelperImpl)scope).getExtendedMetaData();
+ options.put(LOADING_SCOPE, extendedMetaData);
+ }
+
+ public DataGraph loadDataGraph(InputStream inputStream, Map options, HelperContext scope) throws IOException {
+ if (scope == null) {
+ scope = HelperProvider.getDefaultContext();
+ }
+ TypeHelper th = scope.getTypeHelper();
+ DataGraph result = null;
+ if (th == null || th == TypeHelper.INSTANCE) {
+ result = loadDataGraph(inputStream, options);
+ } else if (options == null) {
+ options = new HashMap();
+ registerLoadingScope(options, th);
+ result = loadDataGraph(inputStream, options);
+ } else if (options.containsKey(LOADING_SCOPE)) {
+ Object restore = options.get(LOADING_SCOPE);
+ registerLoadingScope(options, th);
+ try {
+ result = loadDataGraph(inputStream, options);
+ } finally {
+ options.put(LOADING_SCOPE, restore);
+ }
+ } else {
+ registerLoadingScope(options, th);
+ try {
+ result = loadDataGraph(inputStream, options);
+ } finally {
+ options.remove(LOADING_SCOPE);
+ }
+ }
+ return result;
+ }
+
+ public void saveDataGraph(DataGraph dataGraph, OutputStream outputStream, Map options) throws IOException {
+ ((DataGraphImpl)dataGraph).getDataGraphResource().save(outputStream, options);
+ }
+
+ public void registerDataGraphTypes(DataGraph dataGraph, List/* Type */types) {
+ // if (types == null)
+ // types = SDOUtil.getDataGraphTypes(dataGraph);
+
+ Set/* EPackage */packages = new HashSet();
+ for (final Iterator iterator = types.iterator(); iterator.hasNext();) {
+ EClassifier type = (EClassifier)iterator.next();
+ packages.add(type.getEPackage());
+ }
+
+ ResourceSet resourceSet = ((DataGraphImpl)dataGraph).getResourceSet();
+
+ for (Iterator iterator = packages.iterator(); iterator.hasNext();) {
+ EPackage typePackage = (EPackage)iterator.next();
+ Resource resource = typePackage.eResource();
+ if (resource == null) {
+ resource = resourceSet.createResource(URI.createURI(".ecore"));
+ resource.setURI(URI.createURI(typePackage.getNsURI()));
+ resource.getContents().add(typePackage);
+ } else if (resource.getResourceSet() != resourceSet)
+ resourceSet.getResources().add(resource);
+ }
+ }
+
+ public HelperContext createHelperContext() {
+ return new HelperContextImpl(false, null);
+ }
+
+ public HelperContext createHelperContext(boolean extensibleNamespaces) {
+ return new HelperContextImpl(extensibleNamespaces);
+ }
+
+ public HelperContext createHelperContext(Map options) {
+ return new HelperContextImpl(false, options);
+ }
+
+ public HelperContext createHelperContext(boolean extensibleNamespaces, Map options) {
+ return new HelperContextImpl(extensibleNamespaces, options);
+ }
+
+
+ public CopyHelper createCrossScopeCopyHelper(HelperContext hc) {
+ return new CrossScopeCopyHelperImpl(hc.getTypeHelper());
+ }
+
+
+ public XMLStreamHelper createXMLStreamHelper(HelperContext hc) {
+ return ((HelperContextImpl)hc).getXMLStreamHelper();
+ }
+
+
+ public List getTypes(HelperContext hc, String uri) {
+
+ EPackage ePackage = ((HelperContextImpl)hc).getExtendedMetaData().getPackage(uri);
+ if (ePackage != null) {
+ return new ArrayList(ePackage.getEClassifiers());
+ }
+ return null;
+ }
+
+ public List getOpenContentProperties(DataObject dataObject) {
+ List result = new UniqueEList();
+ ((ClassImpl)dataObject.getType()).addOpenProperties((EObject)dataObject, result);
+ return result;
+ }
+
+ public boolean isDocumentRoot(Type type) {
+ return "".equals(SDOExtendedMetaData.INSTANCE.getName((EClassifier)type));
+ }
+
+
+ public Type createType(HelperContext hc, String uri, String name, boolean isDataType) {
+ ExtendedMetaData extendedMetaData = ((HelperContextImpl)hc).getExtendedMetaData();
+ if ("".equals(uri))
+ uri = null; // FB
+
+ EPackage ePackage = extendedMetaData.getPackage(uri);
+ if (ePackage == null) {
+ ePackage = EcoreFactory.eINSTANCE.createEPackage();
+ ePackage.setEFactoryInstance(new DynamicDataObjectImpl.FactoryImpl());
+ ePackage.setNsURI(uri);
+ String packagePrefix = uri != null ? URI.createURI(uri).trimFileExtension().lastSegment() : ""; // FB
+ ePackage.setName(packagePrefix);
+ ePackage.setNsPrefix(packagePrefix);
+ extendedMetaData.putPackage(uri, ePackage);
+ }
+
+ EClassifier eClassifier = ePackage.getEClassifier(name);
+ if (eClassifier != null) // already defined?
+ {
+ // throw new IllegalArgumentException();
+ return null;
+ }
+
+ if (name != null) {
+ eClassifier =
+ isDataType ? (EClassifier)SDOFactory.eINSTANCE.createDataType() : (EClassifier)SDOFactory.eINSTANCE
+ .createClass();
+ eClassifier.setName(name);
+ } else {
+ eClassifier = DataObjectUtil.createDocumentRoot();
+ }
+
+ ePackage.getEClassifiers().add(eClassifier);
+
+ return (Type)eClassifier;
+ }
+
+ public void addBaseType(Type type, Type baseType) {
+ ((EClass)type).getESuperTypes().add(baseType);
+ }
+
+ public void addAliasName(Type type, String aliasName) {
+ throw new UnsupportedOperationException(); // TODO: implement this
+ // method properly
+ // type.getAliasNames().add(aliasName);
+ }
+
+ public void setOpen(Type type, boolean isOpen) {
+ if (isOpen == type.isOpen())
+ return;
+
+ if (isOpen) {
+ EAttribute eAttribute = (EAttribute)SDOFactory.eINSTANCE.createAttribute();
+ ((EClass)type).getEStructuralFeatures().add(eAttribute);
+
+ eAttribute.setName("any");
+ eAttribute.setUnique(false);
+ eAttribute.setUpperBound(ETypedElement.UNBOUNDED_MULTIPLICITY);
+ eAttribute.setEType(EcorePackage.eINSTANCE.getEFeatureMapEntry());
+ ExtendedMetaData.INSTANCE.setFeatureKind(eAttribute, ExtendedMetaData.ELEMENT_WILDCARD_FEATURE);
+ ExtendedMetaData.INSTANCE.setProcessingKind(eAttribute, ExtendedMetaData.LAX_PROCESSING);
+ ExtendedMetaData.INSTANCE.setWildcards(eAttribute, Collections.singletonList("##any"));
+
+ // FB TBD Add an "anyAttribute" EAttribute as well.
+
+ if (ExtendedMetaData.INSTANCE.getMixedFeature((EClass)type) != null) {
+ eAttribute.setDerived(true);
+ eAttribute.setTransient(true);
+ eAttribute.setVolatile(true);
+ }
+ } else {
+ EClass eClass = (EClass)type;
+ EAttribute any = (EAttribute)eClass.getEStructuralFeature("any");
+ eClass.getEStructuralFeatures().remove(any);
+ }
+ }
+
+ public void setSequenced(Type type, boolean isSequenced) {
+ // currently, we require setSequenced to be called first, before
+ // anything else is added to the type.
+ if (type.isDataType() || !type.getProperties().isEmpty()) {
+ if (type.getName() != "DocumentRoot") // document root is a
+ // special case
+ throw new IllegalArgumentException();
+ }
+
+ if (isSequenced) {
+ EClass eClass = (EClass)type;
+ ExtendedMetaData.INSTANCE.setContentKind(eClass, ExtendedMetaData.MIXED_CONTENT);
+ EAttribute mixedFeature = (EAttribute)SDOFactory.eINSTANCE.createAttribute();
+ mixedFeature.setName("mixed");
+ mixedFeature.setUnique(false);
+ mixedFeature.setEType(EcorePackage.eINSTANCE.getEFeatureMapEntry());
+ mixedFeature.setLowerBound(0);
+ mixedFeature.setUpperBound(-1);
+ // eClass.getEStructuralFeatures().add(mixedFeature);
+ ((ClassImpl)eClass).setSequenceFeature(mixedFeature);
+ ExtendedMetaData.INSTANCE.setFeatureKind(mixedFeature, ExtendedMetaData.ELEMENT_WILDCARD_FEATURE);
+ ExtendedMetaData.INSTANCE.setName(mixedFeature, ":mixed");
+ } else {
+ // nothing to do, because of current restriction that setSequence
+ // must be called first.
+ }
+ }
+
+ public void setAbstract(Type type, boolean isAbstract) {
+ ((EClass)type).setAbstract(isAbstract);
+ }
+
+ public void setJavaClassName(Type type, String javaClassName) {
+ ((EClassifier)type).setInstanceClassName(javaClassName);
+ }
+
+ public Property createProperty(Type containingType, String name, Type propertyType) {
+ EStructuralFeature eStructuralFeature =
+ propertyType.isDataType() ? (EStructuralFeature)SDOFactory.eINSTANCE.createAttribute()
+ : (EStructuralFeature)SDOFactory.eINSTANCE.createReference();
+
+ eStructuralFeature.setName(name);
+ eStructuralFeature.setEType((EClassifier)propertyType);
+ ((EClass)containingType).getEStructuralFeatures().add(eStructuralFeature);
+
+ if ("".equals(ExtendedMetaData.INSTANCE.getName((EClass)containingType))) // DocumentRoot
+ // containingType?
+ {
+ ExtendedMetaData.INSTANCE.setNamespace(eStructuralFeature, containingType.getURI());
+ //FB???eStructuralFeature.setUnique(false);
+ //FB???eStructuralFeature.setUpperBound(ETypedElement.UNSPECIFIED_MULTIPLICITY);
+ }
+
+ if (ExtendedMetaData.INSTANCE.getMixedFeature((EClass)containingType) != null) {
+ eStructuralFeature.setDerived(true);
+ eStructuralFeature.setTransient(true);
+ eStructuralFeature.setVolatile(true);
+ ExtendedMetaData.INSTANCE.setFeatureKind(eStructuralFeature, ExtendedMetaData.ELEMENT_FEATURE);
+ } else {
+ // By default, a SDO property is an XSD element
+ ExtendedMetaData.INSTANCE.setFeatureKind(eStructuralFeature, ExtendedMetaData.ELEMENT_FEATURE);
+ }
+
+ return (Property)eStructuralFeature;
+ }
+
+ public void setPropertyXMLKind(Property property, boolean isXmlElement) {
+ if (isXmlElement) {
+ ExtendedMetaData.INSTANCE.setFeatureKind((EStructuralFeature)property, ExtendedMetaData.ELEMENT_FEATURE);
+ }
+ else {
+ ExtendedMetaData.INSTANCE.setFeatureKind((EStructuralFeature)property, ExtendedMetaData.ATTRIBUTE_FEATURE);
+ }
+ }
+
+
+ public Property createOpenContentProperty(HelperContext hc, String uri, String name, Type type)
+ {
+ ExtendedMetaData extendedMetaData = ((HelperContextImpl)hc).getExtendedMetaData();
+
+ // get/create document root
+ EPackage ePackage = extendedMetaData.getPackage(uri);
+ Type documentRoot = ePackage != null ? (Type)extendedMetaData.getType(ePackage, "") : null;
+ if (documentRoot == null) {
+ documentRoot = createType(hc, uri, null, false);
+ }
+
+ // Determine if property already exists
+ Property newProperty = documentRoot.getProperty(name);
+ if (newProperty == null) {
+ // Create the new property 'under' the document root.....
+ newProperty = createProperty(documentRoot, name, type);
+ } else {
+ // if property already exists, validate the expected type
+ if (!newProperty.getType().equals(type))
+ throw new IllegalArgumentException();
+ }
+ return newProperty;
+ }
+
+
+ public void addAliasName(Property property, String aliasName) {
+ throw new UnsupportedOperationException(); // TODO: implement this
+ // method properly
+ // property.getAliasNames().add(aliasName);
+ }
+
+ public void setMany(Property property, boolean isMany) {
+ ((EStructuralFeature)property).setUpperBound(isMany ? EStructuralFeature.UNBOUNDED_MULTIPLICITY : 1);
+ }
+
+ public void setContainment(Property property, boolean isContainment) {
+ ((EReference)property).setContainment(isContainment);
+ }
+
+ public void setDefault(Property property, String defaultValue) {
+ ((EStructuralFeature)property).setDefaultValueLiteral(defaultValue);
+ }
+
+ public void setReadOnly(Property property, boolean isReadOnly) {
+ ((EStructuralFeature)property).setChangeable(!isReadOnly);
+ }
+
+ public void setOpposite(Property property, Property opposite) {
+ ((EReference)property).setEOpposite((EReference)opposite);
+ }
+
+ public void addTypeInstanceProperty(Type definedType, Property instanceProperty, Object value) {
+ addInstanceProperty((EModelElement)definedType, instanceProperty, value);
+ }
+
+ public void addPropertyInstanceProperty(Property definedProperty, Property instanceProperty, Object value) {
+ addInstanceProperty((EModelElement)definedProperty, instanceProperty, value);
+ }
+
+ protected void addInstanceProperty(EModelElement metaObject, Property property, Object value) {
+ String uri = property.getContainingType().getURI();
+ EAnnotation eAnnotation = metaObject.getEAnnotation(uri);
+ if (eAnnotation == null) {
+ eAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
+ eAnnotation.setSource(uri);
+ metaObject.getEAnnotations().add(eAnnotation);
+ }
+ // TODO if (property.isMany()) ... // convert list of values
+ String stringValue = convertToString(property.getType(), value);
+ eAnnotation.getDetails().put(property.getName(), stringValue);
+ }
+
+
+ public void addChangeListener(DataObject dob, EventListener listener) {
+ // Adapter l = (Adapter)listener;
+ ((Notifier)dob).eAdapters().add(listener);
+ }
+
+ public void removeChangeListener(DataObject dob, EventListener listener) {
+ ((Notifier)dob).eAdapters().remove(listener);
+ }
+
+
+}
diff --git a/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/SDOXSDEcoreBuilder.java b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/SDOXSDEcoreBuilder.java new file mode 100644 index 0000000000..7a3a409479 --- /dev/null +++ b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/SDOXSDEcoreBuilder.java @@ -0,0 +1,789 @@ +/** + * + * 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.api.SDOUtil; +import org.apache.tuscany.sdo.impl.AttributeImpl; +import org.apache.tuscany.sdo.impl.SDOFactoryImpl.SDOEcoreFactory; +import org.apache.tuscany.sdo.model.ModelFactory; +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.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.impl.EPackageRegistryImpl; +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.EcoreSchemaBuilder; +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()); + result.setPackageRegistry(new EPackageRegistryImpl(HelperContextImpl.getBuiltInModelRegistry())); + + 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); + if (container instanceof XSDTypeDefinition) + { + result = "_" + result; + } + } + + } + return result; + } + + protected XSDTypeDefinition getEffectiveTypeDefinition(XSDComponent xsdComponent, XSDFeature xsdFeature) + { + if (xsdFeature == null) + { + return super.getEffectiveTypeDefinition(xsdComponent, 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; + XSDEcoreSchemaBuilder schemaBuilder = new XSDEcoreSchemaBuilder(extendedMetaData); + ePackageXSDSchema = schemaBuilder.getSchema(ePackage); + xsdComponentToEModelElementMap.putAll(schemaBuilder.getXSDComponentToEModelElementMap()); + targetNamespaceToEPackageMap.put(ePackage.getNsURI(), ePackage); + populateTypeToTypeObjectMap(ePackage); + xsdSchemas.add(ePackageXSDSchema); + return ePackageXSDSchema; + } + + private static class XSDEcoreSchemaBuilder extends EcoreSchemaBuilder + { + public XSDEcoreSchemaBuilder(ExtendedMetaData extendedMetaData) + { + super(extendedMetaData); + } + + public Map getXSDComponentToEModelElementMap() + { + return xsdComponentToEModelElementMap; + } + } + + 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); + } + } + } + +} diff --git a/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/SchemaBuilder.java b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/SchemaBuilder.java new file mode 100644 index 0000000000..8ff7769041 --- /dev/null +++ b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/SchemaBuilder.java @@ -0,0 +1,786 @@ +/** + * + * 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.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Vector; + +import javax.xml.namespace.QName; + +import org.apache.tuscany.sdo.util.SDOUtil; +import org.eclipse.xsd.XSDAttributeDeclaration; +import org.eclipse.xsd.XSDAttributeUse; +import org.eclipse.xsd.XSDComplexTypeDefinition; +import org.eclipse.xsd.XSDCompositor; +import org.eclipse.xsd.XSDConstraint; +import org.eclipse.xsd.XSDDerivationMethod; +import org.eclipse.xsd.XSDElementDeclaration; +import org.eclipse.xsd.XSDFactory; +import org.eclipse.xsd.XSDForm; +import org.eclipse.xsd.XSDImport; +import org.eclipse.xsd.XSDInclude; +import org.eclipse.xsd.XSDModelGroup; +import org.eclipse.xsd.XSDParticle; +import org.eclipse.xsd.XSDProcessContents; +import org.eclipse.xsd.XSDSchema; +import org.eclipse.xsd.XSDSchemaContent; +import org.eclipse.xsd.XSDSimpleTypeDefinition; +import org.eclipse.xsd.XSDTypeDefinition; +import org.eclipse.xsd.XSDWildcard; + +import commonj.sdo.Property; +import commonj.sdo.Type; +import commonj.sdo.helper.XSDHelper; + +public class SchemaBuilder extends SDOAnnotations +{ + public static final String DEFAULT_SCHEMA_LOCATION = ""; + public static final String NAME_SPACE_PREFIX = "stn_"; + private static int prefixCount = 1; + + //public static final String MIXED = "mixed"; + //public static final String GROUP = "group"; + public static final String EFEATURE_MAP_ENTRY = "EFeatureMapEntry"; + + private Map schemaMap = null; + protected Map targetNamespacePrefixMap = new Hashtable(); + protected Map schemaLocationMap = null; + protected TypeTable typeTable = null; + protected XSDFactory xsdFactory = XSDFactory.eINSTANCE; + + + protected SchemaBuilder(Map schemaMap, + Map nsPrefixMap, + TypeTable typeTable, + Map schemaLocMap ) + { + this.schemaMap = schemaMap; + this.targetNamespacePrefixMap = nsPrefixMap; + this.typeTable = typeTable; + this.schemaLocationMap = schemaLocMap; + } + + + + + private QName addAttribute2ComplexType(String targetNamespace, + XSDComplexTypeDefinition complexType, + Property aProperty) + { + QName attributeSchemaType = null; + String prefix = null; + + try + { + attributeSchemaType = buildSchema(aProperty.getType()); + } + catch ( IllegalArgumentException e ) + { + //schema cannot be generated for this type as there exists an xsd already + //so include that original XSD + attributeSchemaType = new QName(aProperty.getType().getURI(), + aProperty.getType().getName(), + generatePrefix()); + if ( aProperty.getType().isDataType() ) + { + typeTable.addSimpleSchemaType(aProperty.getType().getName(), attributeSchemaType); + + XSDSimpleTypeDefinition simpleType = xsdFactory.createXSDSimpleTypeDefinition(); + simpleType.setName(aProperty.getType().getName()); + simpleType.setTargetNamespace(aProperty.getType().getURI()); + typeTable.addXSDTypeDef(attributeSchemaType.getNamespaceURI(), + attributeSchemaType.getLocalPart(), + simpleType); + } + else + { + typeTable.addComplexSchemaType(aProperty.getType().getURI(), + aProperty.getType().getName(), + attributeSchemaType); + + XSDComplexTypeDefinition extComplexType = xsdFactory.createXSDComplexTypeDefinition(); + extComplexType.setName(aProperty.getType().getName()); + extComplexType.setTargetNamespace(aProperty.getType().getURI()); + typeTable.addXSDTypeDef(attributeSchemaType.getNamespaceURI(), + attributeSchemaType.getLocalPart(), + extComplexType); + } + includeExtXSD(aProperty.getType()); + } + //ensure than an import is done rightaway so that the right prefixes will be used by the + //attribute whose type is set as 'this type'. Otherwise when setting the type for the attribute + //there will be a duplicate prefix (like Q1 or Q2... ) that will be created + prefix = addImports((XSDSchema)schemaMap.get(targetNamespace), attributeSchemaType); + + XSDAttributeDeclaration attribute = xsdFactory.createXSDAttributeDeclaration(); + attribute.setName(aProperty.getName()); + XSDAttributeUse orderDateAttributeUse = xsdFactory.createXSDAttributeUse(); + orderDateAttributeUse.setContent(attribute); + complexType.getAttributeContents().add(orderDateAttributeUse); + attribute.updateElement(); + + if ( aProperty.getType().isDataType() ) + { + attribute.setTypeDefinition((XSDSimpleTypeDefinition)typeTable.getXSDTypeDef(attributeSchemaType.getNamespaceURI(), + attributeSchemaType.getLocalPart())); + + } + else + { + attribute.setTypeDefinition((XSDSimpleTypeDefinition)typeTable.getXSDTypeDef( + typeTable.getSimpleSchemaTypeName("URI").getNamespaceURI(), + typeTable.getSimpleSchemaTypeName("URI").getLocalPart())); + + } + + if ( aProperty.getDefault() != null ) + { + attribute.setConstraint(XSDConstraint.DEFAULT_LITERAL); + attribute.setLexicalValue(aProperty.getDefault().toString()); + } + + addAnnotations(attribute, aProperty ); + if ( !aProperty.getType().isDataType() ) + { + String value = prefix + COLON + attributeSchemaType.getLocalPart(); + attribute.getElement().setAttribute(PROPERTY_TYPE, value); + } + + return attributeSchemaType; + } + + private QName addElement2ComplexType(String targetNamespace, + XSDComplexTypeDefinition complexType, + Property aProperty) + { + String prefix = null; + QName elementSchemaType = null; + try + { + elementSchemaType = buildSchema(aProperty.getType()); + } + catch ( IllegalArgumentException e ) + { + //schema cannot be generated for this type as there exists an xsd already + //so include that original XSD + elementSchemaType = new QName(aProperty.getType().getURI(), + aProperty.getType().getName(), + generatePrefix()); + if ( aProperty.getType().isDataType() ) + { + typeTable.addSimpleSchemaType(aProperty.getType().getName(), elementSchemaType); + + XSDSimpleTypeDefinition simpleType = xsdFactory.createXSDSimpleTypeDefinition(); + simpleType.setName(aProperty.getType().getName()); + simpleType.setTargetNamespace(aProperty.getType().getURI()); + typeTable.addXSDTypeDef(elementSchemaType.getNamespaceURI(), + elementSchemaType.getLocalPart(), + simpleType); + } + else + { + typeTable.addComplexSchemaType(aProperty.getType().getURI(), + aProperty.getType().getName(), + elementSchemaType); + XSDComplexTypeDefinition extComplexType = xsdFactory.createXSDComplexTypeDefinition(); + extComplexType.setName(aProperty.getType().getName()); + extComplexType.setTargetNamespace(aProperty.getType().getURI()); + typeTable.addXSDTypeDef(elementSchemaType.getNamespaceURI(), + elementSchemaType.getLocalPart(), + extComplexType); + } + includeExtXSD(aProperty.getType()); + } + + //ensure than an import is done rightaway so that the right prefixes will be used by the + //element whose type is set as 'this type'. Otherwise when setting the type for the element + //there will be a duplicate prefix (like Q1 or Q2... ) that will be created + prefix = addImports((XSDSchema)schemaMap.get(targetNamespace), elementSchemaType); + + //XmlSchemaElement element = new XmlSchemaElement(); + XSDElementDeclaration element = xsdFactory.createXSDElementDeclaration(); + element.setName(aProperty.getName()); + + XSDParticle aParticle = xsdFactory.createXSDParticle(); + aParticle.setContent(element); + + ((XSDModelGroup)((XSDParticle)complexType.getContent()).getContent()). + getContents().add(aParticle); + + element.updateElement(); + + if ( aProperty.isMany() ) + { + aParticle.setMaxOccurs(-1); + aParticle.setMinOccurs(0); + + } + + if ( aProperty.isContainment() ) + { + element.setTypeDefinition(typeTable.getXSDTypeDef(elementSchemaType.getNamespaceURI(), + elementSchemaType.getLocalPart())); + } + else + { + if ( !aProperty.getType().isDataType() ) + { + QName qName = typeTable.getSimpleSchemaTypeName("URI"); + element.setTypeDefinition(typeTable.getXSDTypeDef(qName.getNamespaceURI(), + qName.getLocalPart())); + } + } + + addAnnotations(element, aProperty); + if ( !aProperty.isContainment() && !aProperty.getType().isDataType() ) + { + String value = prefix + COLON + elementSchemaType.getLocalPart(); + element.getElement().setAttribute(PROPERTY_TYPE, value); + } + return elementSchemaType; + + } + + private void addAnnotations(XSDSchemaContent xsdContent, Property aProperty) + { + if ( !aProperty.getAliasNames().isEmpty() ) + { + addAliasNamesAnnotation(xsdContent, aProperty.getAliasNames()); + } + + if ( aProperty.isReadOnly() ) + { + xsdContent.getElement().setAttribute(READ_ONLY, Boolean.toString(aProperty.isReadOnly())); + } + + if ( aProperty.getOpposite() != null ) + { + xsdContent.getElement().setAttribute(OPPOSITE_PROPERTY, aProperty.getOpposite().getName()); + } + } + + + private QName buildComplexSchemaTypeContents(String targetNamespace, + XSDComplexTypeDefinition complexType, + Type dataType) + { + //clipProperties(dataType); + List properties = dataType.getDeclaredProperties(); + Iterator iterator = properties.iterator(); + Property aProperty; + QName propertySchemaTypeName = null; + + while ( iterator.hasNext() ) + { + aProperty = (Property)iterator.next(); + if ( aProperty.isContainment() || aProperty.isMany() || !aProperty.getType().isDataType() ) + { + propertySchemaTypeName = addElement2ComplexType(targetNamespace, complexType, aProperty); + } + else + { + propertySchemaTypeName = addAttribute2ComplexType(targetNamespace, complexType, aProperty); + } + + /*if ( !EFEATURE_MAP_ENTRY.equals(aProperty.getType().getName()) ) + { + addContents2ComplexType(targetNamespace, complexType, aProperty); + }*/ + } + + return propertySchemaTypeName; + + } + + public QName buildComplexSchemaType(Type dataType) + { + //this is called from buildSchema only if isXSD(dataType) is false + QName complexSchemaTypeName = null ; + if ( !dataType.isDataType() && + (complexSchemaTypeName = typeTable.getComplexSchemaTypeName(dataType.getURI(), dataType.getName())) == null ) + { + XSDSchema xmlSchema = getXmlSchema(dataType); + String targetNamespace = dataType.getURI(); + String targetNamespacePrefix = (String)targetNamespacePrefixMap.get(targetNamespace); + + complexSchemaTypeName = new QName(targetNamespace, + dataType.getName(), + targetNamespacePrefix); + + XSDComplexTypeDefinition complexType = xsdFactory.createXSDComplexTypeDefinition(); + complexType.setName(dataType.getName()); + complexType.setTargetNamespace(targetNamespace); + complexType.setAbstract(dataType.isAbstract()); + + xmlSchema.getTypeDefinitions().add(complexType); + xmlSchema.getContents().add(complexType); + + complexType.updateElement(); + + addAnnotations(complexType, dataType); + + handleBaseExtn(xmlSchema, dataType, complexType); + handleSDOSequence(dataType, complexType); + handleSDOOpenType(dataType, complexType); + + //add before constructing the contents because a content element could + //possibly be of type 'complexType'. + typeTable.addComplexSchemaType(dataType.getURI(), dataType.getName(), complexSchemaTypeName); + typeTable.addXSDTypeDef(dataType.getURI(), dataType.getName(), complexType); + + //now compose the contents for this complex type + buildComplexSchemaTypeContents(targetNamespace, complexType, dataType); + + //finally create a global element for this type + createGlobalElement(xmlSchema, complexType, complexSchemaTypeName); + } + + return complexSchemaTypeName; + } + + private void addAnnotations(XSDTypeDefinition xsdType, Type dataType) + { + if ( dataType.isAbstract() ) + { + if ( xsdType instanceof XSDComplexTypeDefinition ) + { + ((XSDComplexTypeDefinition)xsdType).setAbstract(dataType.isAbstract()); + } + else + { + xsdType.getElement().setAttribute(ABSTRACT_TYPE, + Boolean.toString(dataType.isAbstract())); + } + } + + //add alias names if it exists + addAliasNamesAnnotation(xsdType, + dataType.getAliasNames()); + + //add instanceClass annotation + if ( dataType.getInstanceClass() != null ) + { + xsdType.getElement().setAttribute(INSTANCE_CLASS, dataType.getInstanceClass().getName()); + } + } + + + private QName buildSimpleSchemaType(Type dataType) + { + QName simpleSchemaTypeName = null; + if ( dataType.isDataType() && + (simpleSchemaTypeName = typeTable.getSimpleSchemaTypeName(dataType.getName()) ) == null ) + { + XSDSchema xmlSchema = getXmlSchema(dataType); + XSDSimpleTypeDefinition simpleType = xsdFactory.createXSDSimpleTypeDefinition(); + //set the name + simpleType.setName(dataType.getName()); + simpleType.setTargetNamespace(dataType.getURI()); + //set abstract=true if abstract + simpleSchemaTypeName = new QName(dataType.getURI(), + dataType.getName(), + (String)targetNamespacePrefixMap.get(dataType.getURI())); + xmlSchema.getContents().add(simpleType); + simpleType.updateElement(); + + addAnnotations(simpleType, dataType); + + if ( !dataType.getBaseTypes().isEmpty() ) + { + Type baseType = (Type)dataType.getBaseTypes().get(0); + + QName baseSchemaType = null; + + try + { + baseSchemaType = buildSchema(baseType); + } + catch ( IllegalArgumentException e ) + { + //this means that the base type comes from a original xsd and hence not generated + baseSchemaType = new QName(baseType.getURI(), + baseType.getName(), + generatePrefix()); + + typeTable.addSimpleSchemaType(baseType.getName(), baseSchemaType); + + XSDSimpleTypeDefinition baseTypeDef = xsdFactory.createXSDSimpleTypeDefinition(); + baseTypeDef.setName(baseType.getName()); + baseTypeDef.setTargetNamespace(baseType.getURI()); + typeTable.addXSDTypeDef(baseType.getURI(), baseType.getName(), baseTypeDef); + + //include external XSD locations + includeExtXSD(baseType); + } + + simpleType.setBaseTypeDefinition((XSDSimpleTypeDefinition)typeTable. + getXSDTypeDef(baseSchemaType.getNamespaceURI(),baseSchemaType.getLocalPart())); + addImports(xmlSchema, baseSchemaType); + } + + + typeTable.addSimpleSchemaType(dataType.getName(), simpleSchemaTypeName); + typeTable.addXSDTypeDef(dataType.getURI(), dataType.getName(), simpleType); + } + return simpleSchemaTypeName; + } + + private void includeExtXSD(Type dataType) + { + //now we know there is a type for which the xsd must come from outside + //create a schema for the namespace of this type and add an include in it for + //the xsd that is defined externally + XSDSchema xmlSchema = getXmlSchema(dataType); + + //ideally there could be more than one external schema defintions for a namespace + //and hence schemalocations will be a list of locations + //List schemaLocations = (List)schemaLocationMap.get(dataType.getURI()); + + //since as per the specs the input to XSDHelper is a map of <String, String> allowing + //only one schemalocation for a namespace. So for now this single location will be + //picked up and put into a list + List schemaLocations = new Vector(); + if ( schemaLocationMap.get(dataType.getURI()) != null ) + { + schemaLocations.add(schemaLocationMap.get(dataType.getURI())); + } + + if ( schemaLocations.size() <= 0 ) + { + schemaLocations.add(DEFAULT_SCHEMA_LOCATION); + } + + Object schemaContent = null; + Iterator includesIterator = xmlSchema.getContents().iterator(); + Iterator schemaLocIterator = schemaLocations.iterator(); + String aSchemaLocation = null; + boolean includeExists = false; + //include all external schema locations + while ( schemaLocIterator.hasNext() ) + { + aSchemaLocation = (String)schemaLocIterator.next(); + while ( includesIterator.hasNext() ) + { + schemaContent = includesIterator.next(); + if ( schemaContent instanceof XSDInclude ) + { + if ( !includeExists && aSchemaLocation.equals( + ((XSDInclude)schemaContent).getSchemaLocation() + )) + { + includeExists = true; + } + } + } + + if ( !includeExists ) + { + XSDInclude includeElement = xsdFactory.createXSDInclude(); + includeElement.setSchemaLocation(aSchemaLocation); + xmlSchema.getContents().add(0, includeElement); + } + } + } + + protected QName buildSchema(Type dataType) throws IllegalArgumentException + { + QName schemaTypeName = null; + + if ( dataType.isDataType() ) + { + schemaTypeName = typeTable.getSimpleSchemaTypeName(dataType.getName()); + } + else + { + schemaTypeName = typeTable.getComplexSchemaTypeName(dataType.getURI(), dataType.getName()); + } + + //attempt to generate only if we have not done it already..i.e the type is + //not found in the typetable + if ( schemaTypeName == null ) + { + XSDHelper xsdHelper = SDOUtil.createHelperContext().getXSDHelper(); + + if ( !xsdHelper.isXSD( dataType ) ) + { + if ( dataType.isDataType() ) + { + schemaTypeName = buildSimpleSchemaType(dataType); + } + else + { + schemaTypeName = buildComplexSchemaType(dataType); + } + } + else + { + throw new IllegalArgumentException("Cannot generate XSD since SDO Type '" + + dataType.getName() + "' was orginally generated from XSD. Use original XSD"); + } + } + return schemaTypeName; + } + + + private XSDSchema getXmlSchema(Type dataType) + { + XSDSchema xmlSchema = null; + + if ((xmlSchema = (XSDSchema) schemaMap.get(dataType.getURI())) == null) + { + String targetNamespacePrefix = generatePrefix(); + + xmlSchema = xsdFactory.createXSDSchema(); + xmlSchema.setTargetNamespace(dataType.getURI()); + xmlSchema.setAttributeFormDefault(XSDForm.QUALIFIED_LITERAL); + xmlSchema.setElementFormDefault(XSDForm.QUALIFIED_LITERAL); + + targetNamespacePrefixMap.put(dataType.getURI(), targetNamespacePrefix); + schemaMap.put(dataType.getURI(), xmlSchema); + + xmlSchema.getQNamePrefixToNamespaceMap().put(TypeTable.XS_URI_PREFIX, TypeTable.XML_SCHEMA_URI); + xmlSchema.setSchemaForSchemaQNamePrefix(TypeTable.XS_URI_PREFIX); + + xmlSchema.getQNamePrefixToNamespaceMap().put(targetNamespacePrefix, dataType.getURI()); + //xmlSchema.setSchemaForSchemaQNamePrefix(targetNamespacePrefix); + + addSDONamespaces(xmlSchema); + addPackageAnnotation(xmlSchema, dataType); + } + return xmlSchema; + } + + + private void addSDONamespaces(XSDSchema xmlSchema) + { + xmlSchema.getQNamePrefixToNamespaceMap().put(COMMONJ_SDO_NS_PREFIX, COMMONJ_SDO_NS); + //xmlSchema.setSchemaForSchemaQNamePrefix(COMMONJ_SDO_NS_PREFIX); + + xmlSchema.getQNamePrefixToNamespaceMap().put(SDO_JAVA_NS_PREFIX, SDO_JAVA_NS); + //xmlSchema.setSchemaForSchemaQNamePrefix(SDO_JAVA_NS_PREFIX); + } + + + /** + * JAM convert first name of an attribute into UpperCase as an example if + * there is a instance variable called foo in a bean , then Jam give that as + * Foo so this method is to correct that error + * + * @param wrongName + * @return the right name, using english as the locale for case conversion + */ + public static String getCorrectName(String wrongName) + { + if (wrongName.length() > 1) { + return wrongName.substring(0, 1).toLowerCase(Locale.ENGLISH) + + wrongName.substring(1, wrongName.length()); + } else { + return wrongName.substring(0, 1).toLowerCase(Locale.ENGLISH); + } + } + + private String addImports(XSDSchema xmlSchema, QName schemaTypeName) + { + String prefix = null; + Iterator iterator = xmlSchema.getQNamePrefixToNamespaceMap().keySet().iterator(); + while ( iterator.hasNext() ) + { + prefix = (String)iterator.next(); + + if ( schemaTypeName.getNamespaceURI().equals( + xmlSchema.getQNamePrefixToNamespaceMap().get(prefix)) ) + { + return prefix; + } + } + + //the following lines are executed only if a prefix was not found which implies that the + //schemaTypeName was not imported earlier and also it does not belong to the targetnamespace + XSDImport importElement = xsdFactory.createXSDImport(); + importElement.setNamespace(schemaTypeName.getNamespaceURI()); + xmlSchema.getContents().add(0, importElement); + prefix = schemaTypeName.getPrefix(); + if ( prefix == null || prefix.length() <= 0 ) + { + prefix = generatePrefix(); + } + xmlSchema.getQNamePrefixToNamespaceMap().put(prefix, schemaTypeName.getNamespaceURI()); + + return prefix; + } + + private void handleSDOSequence(Type datatype, XSDComplexTypeDefinition complexType) + { + if ( datatype.isSequenced() ) + { + complexType.setMixed(true); + XSDModelGroup choice = xsdFactory.createXSDModelGroup(); + choice.setCompositor(XSDCompositor.CHOICE_LITERAL); + XSDParticle aParticle = xsdFactory.createXSDParticle(); + aParticle.setContent(choice); + aParticle.setMaxOccurs(-1); + complexType.setContent(aParticle); + } + else + { + //hack to handle group property as choice + /*if ( getPropertyStartsWithName(datatype.getDeclaredProperties(), GROUP).size() > 0 ) + { + XmlSchemaChoice choice = new XmlSchemaChoice(); + choice.setMaxOccurs(Long.MAX_VALUE); + complexType.setParticle(choice); + } + else*/ + { + XSDModelGroup sequence = xsdFactory.createXSDModelGroup(); + sequence.setCompositor(XSDCompositor.SEQUENCE_LITERAL); + XSDParticle aParticle = xsdFactory.createXSDParticle(); + aParticle.setContent(sequence); + complexType.setContent(aParticle); + } + } + } + + private void handleSDOOpenType(Type datatype, XSDComplexTypeDefinition complexType) + { + if ( datatype.isOpen() /*&& + getPropertyStartsWithName(datatype.getDeclaredProperties(), GROUP).size() <= 0 */) + { + XSDWildcard elementWildcard = xsdFactory.createXSDWildcard(); + elementWildcard.getLexicalNamespaceConstraint().add("##other"); + elementWildcard.setProcessContents(XSDProcessContents.LAX_LITERAL); + // Create a particle to hold the wildcard. + XSDParticle wildcardParticle = xsdFactory.createXSDParticle(); + wildcardParticle.setContent(elementWildcard); + wildcardParticle.setMaxOccurs(-1); + ((XSDModelGroup)((XSDParticle)complexType.getContent()).getContent()). + getContents().add(wildcardParticle); + + XSDWildcard attributeWildcard = xsdFactory.createXSDWildcard(); + attributeWildcard.getLexicalNamespaceConstraint().add("##other"); + attributeWildcard.setProcessContents(XSDProcessContents.LAX_LITERAL); + complexType.setAttributeWildcard(attributeWildcard); + } + } + + private void handleBaseExtn(XSDSchema xmlSchema, + Type datatype, + XSDComplexTypeDefinition complexType) + { + if ( datatype.getBaseTypes().size() > 0 ) + { + Type baseType = (Type)datatype.getBaseTypes().get(0); + QName baseSchemaType = null; + + try + { + baseSchemaType = buildSchema(baseType); + } + catch ( IllegalArgumentException e ) + { + //schema cannot be generated for this type as there exists an xsd already + //so include that original XSD + baseSchemaType = new QName(baseType.getURI(), + baseType.getName(), + generatePrefix()); + + XSDSimpleTypeDefinition baseTypeDef = xsdFactory.createXSDSimpleTypeDefinition(); + baseTypeDef.setName(baseType.getName()); + baseTypeDef.setTargetNamespace(baseType.getURI()); + typeTable.addXSDTypeDef(baseType.getURI(), baseType.getName(), baseTypeDef); + + includeExtXSD(baseType); + } + + complexType.setDerivationMethod(XSDDerivationMethod.EXTENSION_LITERAL); + + if ( baseType.isDataType() ) + { + XSDSimpleTypeDefinition anonymousSimpleTypeDefinition + = xsdFactory.createXSDSimpleTypeDefinition(); + anonymousSimpleTypeDefinition.setBaseTypeDefinition((XSDSimpleTypeDefinition)typeTable. + getXSDTypeDef(baseSchemaType.getNamespaceURI(),baseSchemaType.getLocalPart())); + complexType.setContent(anonymousSimpleTypeDefinition); + } + else + { + complexType.setBaseTypeDefinition((XSDSimpleTypeDefinition)typeTable. + getXSDTypeDef(baseSchemaType.getNamespaceURI(),baseSchemaType.getLocalPart())); + + } + + addImports(xmlSchema, baseSchemaType); + } + } + + private String formGlobalElementName(String typeName) + { + String firstChar = typeName.substring(0,1); + return typeName.replaceFirst(firstChar, firstChar.toLowerCase()); + } + + private void createGlobalElement(XSDSchema xmlSchema, + XSDComplexTypeDefinition complexType, + QName schemaElementName ) + { + XSDElementDeclaration globalElement = xsdFactory.createXSDElementDeclaration(); + globalElement.setTargetNamespace(xmlSchema.getTargetNamespace()); + globalElement.setName(formGlobalElementName(complexType.getName())); + globalElement.setTypeDefinition + (typeTable.getXSDTypeDef(schemaElementName.getNamespaceURI(), + schemaElementName.getLocalPart())); + xmlSchema.getContents().add(globalElement); + xmlSchema.getElementDeclarations().add(globalElement); + } + + private void addAliasNamesAnnotation(XSDSchemaContent typeDef, + List aliasNames) + { + if ( !aliasNames.isEmpty() ) + { + StringBuffer sb = new StringBuffer(); + Iterator iterator = aliasNames.iterator(); + while ( iterator.hasNext() ) + { + sb.append(iterator.next()); + } + typeDef.getElement().setAttribute(ALIAS_NAMES, sb.toString()); + } + } + + private void addPackageAnnotation(XSDSchema xmlSchema, Type dataType) + { + if ( dataType.getInstanceClass() != null ) + { + xmlSchema.updateElement(); + xmlSchema.getElement().setAttribute(JAVA_PACKAGE, + dataType.getInstanceClass().getPackage().getName()); + } + } + + private String generatePrefix() + { + return NAME_SPACE_PREFIX + prefixCount++; + } +} diff --git a/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/TypeHelperImpl.java b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/TypeHelperImpl.java new file mode 100644 index 0000000000..1aa2ae466b --- /dev/null +++ b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/TypeHelperImpl.java @@ -0,0 +1,317 @@ +/** + * + * 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.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.apache.tuscany.sdo.api.SDOUtil; +import org.apache.tuscany.sdo.model.ModelFactory; +import org.apache.tuscany.sdo.model.internal.InternalFactory; +import org.apache.tuscany.sdo.model.java.JavaFactory; +import org.apache.tuscany.sdo.model.xml.XMLFactory; +import org.apache.tuscany.sdo.model.xml.impl.XMLFactoryImpl; +import org.apache.tuscany.sdo.util.DataObjectUtil; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EClassifier; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.util.ExtendedMetaData; + +import commonj.sdo.DataObject; +import commonj.sdo.Property; +import commonj.sdo.Sequence; +import commonj.sdo.Type; +import commonj.sdo.helper.HelperContext; +import commonj.sdo.helper.TypeHelper; + +/** + * Look up a Type given the uri and typeName or interfaceClass. SDO Types are + * available through the getType("commonj.sdo", typeName) method. Defines Types + * from DataObjects. + */ +public class TypeHelperImpl implements TypeHelper { + protected HelperContext helperContext; + private ExtendedMetaData extendedMetaData; + + static protected Set builtInModels = null; + + static public Set getBuiltInModels() { + if (builtInModels == null) { + builtInModels = new HashSet(); + builtInModels.add(ModelFactory.INSTANCE); + builtInModels.add(JavaFactory.INSTANCE); + builtInModels.add(XMLFactory.INSTANCE); + builtInModels.add(InternalFactory.INSTANCE); + } + return TypeHelperImpl.builtInModels; + } + + public ExtendedMetaData getExtendedMetaData() { + return extendedMetaData; + } + + // JIRA-helperContext + public TypeHelperImpl(HelperContext hc) { + this.helperContext = hc; + this.extendedMetaData = ((HelperContextImpl)hc).extendedMetaData; + + // Register the standard (predefined) SDO types + getBuiltInModels(); // Simply accessing EMF packages causes auto + // registration in global registry + + // MetadataFactoryImpl.init(); //FB do we want to preregister this? + } + + + public Type getType(String uri, String typeName) { + EPackage ePackage = extendedMetaData.getPackage(uri); + + if (ePackage != null) { + EClassifier eClassifier = ePackage.getEClassifier(typeName); + if (eClassifier == null) { + eClassifier = extendedMetaData.getType(ePackage, typeName); + } + return (Type)eClassifier; + } + return null; + } + + private Method getGetStaticTypeMethod(Class classObj) { + try { + Method method = classObj.getMethod("getStaticType", null); + return method; + } + catch (Exception e) { + return null; + } + } + + public Type getType(Class interfaceClass) { + Type type = SDOUtil.getJavaSDOType(interfaceClass); + if (type != null) { + return type; + } + + Class sdoTypeImplClass = interfaceClass; + Method getStaticTypeMethod = getGetStaticTypeMethod(interfaceClass); + if (getStaticTypeMethod == null) { + String sdoTypeImplClassName = interfaceClass.getName(); + if (sdoTypeImplClassName.endsWith("Impl") == false) { + sdoTypeImplClass = DataObjectUtil.getImplementationClass(interfaceClass, false); + if (sdoTypeImplClass == null) { + return null; + } + + getStaticTypeMethod = getGetStaticTypeMethod(sdoTypeImplClass); + if (getStaticTypeMethod == null) { + return null; + } + } + else { + return null; + } + } + + try { + Object implInstance = sdoTypeImplClass.newInstance(); + return (Type)getStaticTypeMethod.invoke(implInstance, null); + } + catch (Exception e) { + return null; + } + } + + public Type define(DataObject type) { + if (!(type instanceof org.apache.tuscany.sdo.model.Type)) + throw new IllegalArgumentException(); + org.apache.tuscany.sdo.model.Type modeledType = (org.apache.tuscany.sdo.model.Type)type; + + boolean isDataType = modeledType.isDataType(); + Type definedType = SDOUtil.createType(helperContext, modeledType.getUri(), modeledType.getName(), isDataType); + if (definedType == null) { + // If type already defined, return existing Type. + return getType(modeledType.getUri(), modeledType.getName()); + } + + SDOUtil.setJavaClassName(definedType, modeledType.getInstanceClassName()); + + if (!isDataType) { + SDOUtil.setSequenced(definedType, modeledType.isSequenced()); + SDOUtil.setOpen(definedType, modeledType.isOpen()); + SDOUtil.setAbstract(definedType, modeledType.isAbstract()); + + for (Iterator iter = modeledType.getBaseType().iterator(); iter.hasNext();) { + Type baseType = getDefinedType((org.apache.tuscany.sdo.model.Type)iter.next()); + SDOUtil.addBaseType(definedType, baseType); + } + + for (Iterator iter = modeledType.getAliasName().iterator(); iter.hasNext();) { + String aliasName = (String)iter.next(); + SDOUtil.addAliasName(definedType, aliasName); + } + + for (Iterator iter = modeledType.getProperty().iterator(); iter.hasNext();) { + org.apache.tuscany.sdo.model.Property modeledProperty = + (org.apache.tuscany.sdo.model.Property)iter.next(); + + Type propertyType = getDefinedType(modeledProperty.getType_()); + Property definedProperty = SDOUtil.createProperty(definedType, modeledProperty.getName(), propertyType); + + initializeProperty(definedProperty, modeledProperty); + } + + // define a global property to accompany the type definition + if (!SDOUtil.isDocumentRoot(definedType)) { + String propertyName = definedType.getName(); + if (!Character.isLowerCase(propertyName.charAt(0))) { + propertyName = propertyName.substring(0, 1).toLowerCase() + propertyName.substring(1); + } + Property globalProperty = + SDOUtil.createOpenContentProperty(helperContext, definedType.getURI(), propertyName, definedType); + SDOUtil.setContainment(globalProperty, true); + } + } // if (!isDataType) + + addTypeInstanceProperties(definedType, (DataObject)modeledType); + + return definedType; + } + + protected void addTypeInstanceProperties(Type definedType, DataObject modeledType) { + List instanceProperties = SDOUtil.getOpenContentProperties(modeledType); + for (Iterator iter = instanceProperties.iterator(); iter.hasNext();) { + Property property = (Property)iter.next(); + SDOUtil.addTypeInstanceProperty(definedType, property, modeledType.get(property)); + } + } + + protected void addPropertyInstanceProperties(Property definedProperty, DataObject modeledProperty) { + List instanceProperties = SDOUtil.getOpenContentProperties(modeledProperty); + for (Iterator iter = instanceProperties.iterator(); iter.hasNext();) { + Property property = (Property)iter.next(); + SDOUtil.addPropertyInstanceProperty(definedProperty, property, modeledProperty.get(property)); + } + } + + public List /* Type */define(List /* DataObject */types) { + int count = types.size(); + List definedTypes = new ArrayList(count); + for (int i = 0; i < count; i++) { + definedTypes.add(define((DataObject)types.get(i))); + } + return definedTypes; + } + + protected Type getDefinedType(org.apache.tuscany.sdo.model.Type modeledType) { + if (modeledType instanceof Type) { + return (Type)modeledType; + } else { + EClassifier eClassifier = extendedMetaData.getType(modeledType.getUri(), modeledType.getName()); + if (eClassifier != null) { + return (Type)eClassifier; + } else { + return define((DataObject)modeledType); + } + } + } + + protected Property getDefinedProperty(org.apache.tuscany.sdo.model.Property modeledProperty) { + if (modeledProperty instanceof Property) { + return (Property)modeledProperty; + } else { + DataObject modeledContainingType = ((DataObject)modeledProperty).getContainer(); + + Type definedContainingType = getDefinedType((org.apache.tuscany.sdo.model.Type)modeledContainingType); + String propertyName = modeledProperty.getName(); + + return definedContainingType.getProperty(propertyName); + } + } + + protected void initializeProperty(Property newProperty, org.apache.tuscany.sdo.model.Property modeledProperty) { + SDOUtil.setMany(newProperty, modeledProperty.isMany()); + SDOUtil.setDefault(newProperty, modeledProperty.getDefault_()); + SDOUtil.setReadOnly(newProperty, modeledProperty.isReadOnly()); + for (Iterator iter = modeledProperty.getAliasName().iterator(); iter.hasNext();) { + String aliasName = (String)iter.next(); + SDOUtil.addAliasName(newProperty, aliasName); + } + + if (newProperty.getType().isDataType()) { + // Setting xmlElement to FALSE only makes sense here + Boolean isXmlElement = Boolean.TRUE; // By default, a SDO property is an XSD element + Sequence anyAttr = modeledProperty.getAnyAttribute(); + for (int i=0; i<anyAttr.size(); i++) { + Property anyProp = anyAttr.getProperty(i); + if (XMLFactoryImpl.NAMESPACE_URI.equals(anyProp.getContainingType().getURI())) { + String propName = anyProp.getName(); + if ("xmlElement".equals(propName)) { + isXmlElement = (Boolean)anyAttr.getValue(i); + } + } + } + if (!isXmlElement.booleanValue()) { + SDOUtil.setPropertyXMLKind(newProperty, false); + } + } + else + { + SDOUtil.setContainment(newProperty, modeledProperty.isContainment()); + if (modeledProperty.getOpposite_() != null) { + SDOUtil.setOpposite(newProperty, getDefinedProperty(modeledProperty.getOpposite_())); + } + } + addPropertyInstanceProperties(newProperty, (DataObject)modeledProperty); + } + + public static final String TUSCANY_NO_URI = "http://tuscany-no-uri"; + + public Property defineOpenContentProperty(String uri, DataObject property) { + // validate property and get type + if (!(property instanceof org.apache.tuscany.sdo.model.impl.PropertyImpl)) + throw new IllegalArgumentException(); + org.apache.tuscany.sdo.model.Property modeledProperty = (org.apache.tuscany.sdo.model.Property)property; + Type propertyType = getDefinedType(modeledProperty.getType_()); + + if (uri == null) + uri = TUSCANY_NO_URI; + + Property newProperty = SDOUtil.createOpenContentProperty(helperContext, uri, modeledProperty.getName(), propertyType); + + // Propagate the modeled property's attributes + initializeProperty(newProperty, modeledProperty); + + return newProperty; + } + + + public Property getOpenContentProperty(String uri, String propertyName) { + EClass documentRoot = (EClass)extendedMetaData.getType(uri, ""); + return documentRoot != null ? (Property)documentRoot.getEStructuralFeature(propertyName) : null; + } + + public HelperContext getHelperContext() { + return helperContext; + } +} diff --git a/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/TypeTable.java b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/TypeTable.java new file mode 100644 index 0000000000..a28492e28e --- /dev/null +++ b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/TypeTable.java @@ -0,0 +1,254 @@ +/** + * + * 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.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.Vector; + +import javax.xml.namespace.QName; + +//import org.apache.axiom.om.OMElement; +import org.eclipse.xsd.XSDFactory; +import org.eclipse.xsd.XSDTypeDefinition; +import org.w3c.dom.Element; + + + +public class TypeTable +{ + public static final String XML_SCHEMA_URI = "http://www.w3.org/2001/XMLSchema"; + public static final String XS_URI_PREFIX = "xs"; + public static final QName XS_QNAME = new QName(XML_SCHEMA_URI, "schema", XS_URI_PREFIX); + public static final String DELIMITER = "#"; + + private Hashtable simpleXSDTypes; + private Hashtable complexXSDTypes; + private Hashtable xsdTypeDefs; + + public static String asQualifiedName(String uri, String typeName) + { + return (uri + DELIMITER + typeName); + } + + + public TypeTable() + { + simpleXSDTypes = new Hashtable(); + complexXSDTypes = new Hashtable(); + xsdTypeDefs = new Hashtable(); + populateSimpleXSDTypes(); + populateStdSDOTypes(); + } + + private void populateStdSDOTypes() + { + simpleXSDTypes.put("Boolean", + new QName(XML_SCHEMA_URI, "boolean", XS_URI_PREFIX)); + simpleXSDTypes.put("Byte", + new QName(XML_SCHEMA_URI, "byte", XS_URI_PREFIX)); + simpleXSDTypes.put("Bytes", + new QName(XML_SCHEMA_URI, "hexBinary", XS_URI_PREFIX)); + simpleXSDTypes.put("Character", + new QName(XML_SCHEMA_URI, "string", XS_URI_PREFIX)); + simpleXSDTypes.put("DataObject", + new QName(XML_SCHEMA_URI, "anyType", XS_URI_PREFIX)); + simpleXSDTypes.put("Date", + new QName(XML_SCHEMA_URI, "dateTime", XS_URI_PREFIX)); + simpleXSDTypes.put("Day", + new QName(XML_SCHEMA_URI, "gDay", XS_URI_PREFIX)); + simpleXSDTypes.put("Decimal", + new QName(XML_SCHEMA_URI, "decimal", XS_URI_PREFIX)); + simpleXSDTypes.put("Double", + new QName(XML_SCHEMA_URI, "double", XS_URI_PREFIX)); + simpleXSDTypes.put("Duration", + new QName(XML_SCHEMA_URI, "duration", XS_URI_PREFIX)); + simpleXSDTypes.put("Float", + new QName(XML_SCHEMA_URI, "float", XS_URI_PREFIX)); + simpleXSDTypes.put("Int", + new QName(XML_SCHEMA_URI, "int", XS_URI_PREFIX)); + simpleXSDTypes.put("Integer", + new QName(XML_SCHEMA_URI, "integer", XS_URI_PREFIX)); + simpleXSDTypes.put("Long", + new QName(XML_SCHEMA_URI, "long", XS_URI_PREFIX)); + simpleXSDTypes.put("Month", + new QName(XML_SCHEMA_URI, "gMonth", XS_URI_PREFIX)); + simpleXSDTypes.put("monthDay", + new QName(XML_SCHEMA_URI, "gMonthDay", XS_URI_PREFIX)); + simpleXSDTypes.put("Object", + new QName(XML_SCHEMA_URI, "anySimpleType", XS_URI_PREFIX)); + simpleXSDTypes.put("Short", + new QName(XML_SCHEMA_URI, "short", XS_URI_PREFIX)); + simpleXSDTypes.put("String", + new QName(XML_SCHEMA_URI, "string", XS_URI_PREFIX)); + simpleXSDTypes.put("Strings", + new QName(XML_SCHEMA_URI, "string", XS_URI_PREFIX)); + simpleXSDTypes.put("Time", + new QName(XML_SCHEMA_URI, "time", XS_URI_PREFIX)); + simpleXSDTypes.put("Year", + new QName(XML_SCHEMA_URI, "gYear", XS_URI_PREFIX)); + simpleXSDTypes.put("YearMonth", + new QName(XML_SCHEMA_URI, "gYearMonth", XS_URI_PREFIX)); + simpleXSDTypes.put("YearMonthDay", + new QName(XML_SCHEMA_URI, "date", XS_URI_PREFIX)); + simpleXSDTypes.put("URI", + new QName(XML_SCHEMA_URI, "anyURI", XS_URI_PREFIX)); + } + + private void populateSimpleXSDTypes() { + //todo pls use the types from org.apache.ws.commons.schema.constants.Constants + simpleXSDTypes.put("int", + new QName(XML_SCHEMA_URI, "int", XS_URI_PREFIX)); + simpleXSDTypes.put("java.lang.String", + new QName(XML_SCHEMA_URI, "string", XS_URI_PREFIX)); + simpleXSDTypes.put("boolean", + new QName(XML_SCHEMA_URI, "boolean", XS_URI_PREFIX)); + simpleXSDTypes.put("float", + new QName(XML_SCHEMA_URI, "float", XS_URI_PREFIX)); + simpleXSDTypes.put("double", + new QName(XML_SCHEMA_URI, "double", XS_URI_PREFIX)); + simpleXSDTypes.put("short", + new QName(XML_SCHEMA_URI, "short", XS_URI_PREFIX)); + simpleXSDTypes.put("long", + new QName(XML_SCHEMA_URI, "long", XS_URI_PREFIX)); + simpleXSDTypes.put("byte", + new QName(XML_SCHEMA_URI, "byte", XS_URI_PREFIX)); + simpleXSDTypes.put("char", + new QName(XML_SCHEMA_URI, "anyType", XS_URI_PREFIX)); + simpleXSDTypes.put("java.lang.Integer", + new QName(XML_SCHEMA_URI, "int", XS_URI_PREFIX)); + simpleXSDTypes.put("java.lang.Double", + new QName(XML_SCHEMA_URI, "double", XS_URI_PREFIX)); + simpleXSDTypes.put("java.lang.Float", + new QName(XML_SCHEMA_URI, "float", XS_URI_PREFIX)); + simpleXSDTypes.put("java.lang.Long", + new QName(XML_SCHEMA_URI, "long", XS_URI_PREFIX)); + simpleXSDTypes.put("java.lang.Character", + new QName(XML_SCHEMA_URI, "anyType", XS_URI_PREFIX)); + simpleXSDTypes.put("java.lang.Boolean", + new QName(XML_SCHEMA_URI, "boolean", XS_URI_PREFIX)); + simpleXSDTypes.put("java.lang.Byte", + new QName(XML_SCHEMA_URI, "byte", XS_URI_PREFIX)); + simpleXSDTypes.put("java.lang.Short", + new QName(XML_SCHEMA_URI, "short", XS_URI_PREFIX)); + simpleXSDTypes.put("java.util.Date", + new QName(XML_SCHEMA_URI, "dateTime", XS_URI_PREFIX)); + simpleXSDTypes.put("java.util.Calendar", + new QName(XML_SCHEMA_URI, "dateTime", XS_URI_PREFIX)); + simpleXSDTypes.put("java.lang.Object", + new QName(XML_SCHEMA_URI, "anyType", XS_URI_PREFIX)); + simpleXSDTypes.put("java.math.BigDecimal", + new QName(XML_SCHEMA_URI, "decimal", XS_URI_PREFIX)); + + // Any types + simpleXSDTypes.put(Element.class.getName(), + new QName(XML_SCHEMA_URI, "anyType", XS_URI_PREFIX)); + simpleXSDTypes.put(ArrayList.class.getName(), + new QName(XML_SCHEMA_URI, "anyType", XS_URI_PREFIX)); + simpleXSDTypes.put(Vector.class.getName(), + new QName(XML_SCHEMA_URI, "anyType", XS_URI_PREFIX)); + simpleXSDTypes.put(List.class.getName(), + new QName(XML_SCHEMA_URI, "anyType", XS_URI_PREFIX)); + } + + public QName getStdSdoType(String typename) + { + return (QName) simpleXSDTypes.get(typename); + } + + public QName getComplexSchemaTypeName(String sdoURI, String sdoTypeName) + { + return (QName) complexXSDTypes.get(asQualifiedName(sdoURI, sdoTypeName)); + } + + public boolean isSimpleType(String typeName) + { + Iterator keys = simpleXSDTypes.keySet().iterator(); + while (keys.hasNext()) { + String s = (String) keys.next(); + if (s.equals(typeName)) { + return true; + } + } + return false; + } + + public QName getSimpleSchemaTypeName(String typename) + { + return (QName) simpleXSDTypes.get(typename); + } + + public void addSimpleSchemaType(String typeName, QName schemaType) + { + simpleXSDTypes.put(typeName, schemaType); + } + + + public void addComplexSchemaType(String namespaceURI, String name, QName schemaType) + { + complexXSDTypes.put(asQualifiedName(namespaceURI, name), schemaType); + } + + + public QName getQNamefortheType(String namespaceURI, String typeName) + { + if ( XML_SCHEMA_URI.equals(namespaceURI)) + { + return getSimpleSchemaTypeName(typeName); + } + else + { + return getComplexSchemaTypeName(namespaceURI, typeName); + } + } + + public void addXSDTypeDef(String namespaceURI, String typeName, XSDTypeDefinition aTypeDef) + { + if ( namespaceURI != null && typeName != null && aTypeDef != null ) + { + xsdTypeDefs.put(asQualifiedName(namespaceURI, typeName), aTypeDef); + } + } + + public XSDTypeDefinition getXSDTypeDef(String namespaceURI, String typeName) + { + XSDTypeDefinition typeDef = null; + if ( namespaceURI != null && typeName != null ) + { + if ( XML_SCHEMA_URI.equals(namespaceURI) ) + { + if ( ( typeDef = (XSDTypeDefinition)xsdTypeDefs.get(asQualifiedName(namespaceURI, typeName)) ) == null ) + { + typeDef = XSDFactory.eINSTANCE.createXSDSimpleTypeDefinition(); + typeDef.setName(typeName); + typeDef.setTargetNamespace(namespaceURI); + addXSDTypeDef(namespaceURI, typeName, typeDef); + } + } + else + { + typeDef = (XSDTypeDefinition)xsdTypeDefs.get(asQualifiedName(namespaceURI, typeName)); + } + } + return typeDef; + } +} diff --git a/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/XMLDocumentImpl.java b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/XMLDocumentImpl.java new file mode 100644 index 0000000000..bff8375e44 --- /dev/null +++ b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/XMLDocumentImpl.java @@ -0,0 +1,574 @@ +/** + * + * 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.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.sdo.SimpleAnyTypeDataObject; +import org.apache.tuscany.sdo.util.DataObjectUtil; +import org.apache.tuscany.sdo.util.SDOUtil; +import org.apache.tuscany.sdo.util.resource.SDOXMLResourceImpl; +import org.eclipse.emf.common.util.EMap; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +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.FeatureMap; +import org.eclipse.emf.ecore.util.FeatureMapUtil; +import org.eclipse.emf.ecore.xmi.XMLResource; +import org.eclipse.emf.ecore.xml.type.XMLTypePackage; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.xml.sax.InputSource; + +import commonj.sdo.DataObject; +import commonj.sdo.Type; +import commonj.sdo.helper.XMLDocument; + + +/** + * Represents an XML Document containing a tree of DataObjects. + * + * An example XMLDocument fragment is: + * <?xml version="1.0"?> + * <purchaseOrder orderDate="1999-10-20"> + * + * created from this XML Schema fragment: + * <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + * <xsd:element name="purchaseOrder" type="PurchaseOrderType"/> + * <xsd:complexType name="PurchaseOrderType"> + * + * Upon loading this XMLDocument: + * DataObject is an instance of Type PurchaseOrderType. + * RootElementURI is null because the XSD has no targetNamespace URI. + * RootElementName is purchaseOrder. + * Encoding is null because the document did not specify an encoding. + * XMLDeclaration is true because the document contained an XML declaration. + * XMLVersion is 1.0 + * SchemaLocation and noNamespaceSchemaLocation are null because they are + * not specified in the document. + * + * When saving the root element, if the type of the root dataObject is not the + * type of global element specified by rootElementURI and rootElementName, + * or if a global element does not exist for rootElementURI and rootElementName, + * then an xsi:type declaration is written to record the root DataObject's Type. + * + * When loading the root element and an xsi:type declaration is found + * it is used as the type of the root DataObject. In this case, + * if validation is not being performed, it is not an error if the + * rootElementName is not a global element. + */ +public class XMLDocumentImpl implements XMLDocument +{ + protected ExtendedMetaData extendedMetaData; + + protected EObject rootObject; + + protected XMLResource resource; + + protected EStructuralFeature rootElement; + + protected EObject documentRoot; + + protected final static String WHITESPACE_REGEX = "\\s"; + + //TODO clean up the options thing + protected XMLDocumentImpl(ExtendedMetaData extendedMetaData, Object options) + { + this.extendedMetaData = extendedMetaData; + ResourceSet resourceSet = DataObjectUtil.createResourceSet(); + + if (options instanceof Map) + { + Class resourceFactoryClass = (Class)((Map)options).get("GENERATED_LOADER"); + if (resourceFactoryClass != null) + { + try + { + Object resourceFactory = resourceFactoryClass.newInstance(); + resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("*", resourceFactory); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + } + + resource = (XMLResource)resourceSet.createResource(URI.createURI("http:///temp.xml")); + DataObjectUtil.configureXMLResource(resource, extendedMetaData); + } + + protected XMLDocumentImpl(ExtendedMetaData extendedMetaData) + { + this(extendedMetaData, null); + } + + protected XMLDocumentImpl(ExtendedMetaData extendedMetaData, DataObject dataObject, String rootElementURI, String rootElementName) + { + this(extendedMetaData); + + rootObject = (EObject)dataObject; + + rootElement = extendedMetaData.getElement(rootElementURI, rootElementName); + if (rootElement == null) + { + rootElement = ExtendedMetaData.INSTANCE.demandFeature(rootElementURI, rootElementName, true); + } + + EClass documentRootClass = rootElement.getEContainingClass(); + documentRoot = EcoreUtil.create(documentRootClass); + resource.getContents().add(documentRoot); + } + + protected void save(OutputStream outputStream, Object options) throws IOException + { + save(outputStream, null, options); + } + + protected void save(Writer outputWriter, Object options) throws IOException + { + // TODO temporary brute-force implementation ... to be replaced + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + save(outputStream, options); + outputWriter.write(new String(outputStream.toByteArray())); + } + + protected void save(Node node, Object options) throws IOException + { + save(null, (Document)node, options); + } + + protected void save(OutputStream outputStream, Document document, Object options) throws IOException + { + EObject oldContainer = null; + Resource oldResource = null; + EReference oldContainmentReference = null; + int oldContainmentIndex = -1; + + if (documentRoot != null) + { + oldContainer = rootObject.eContainer(); + if (oldContainer != null) + oldContainmentReference = rootObject.eContainmentFeature(); + else + oldResource = rootObject.eResource(); + if (oldContainer != documentRoot || oldContainmentReference != rootElement) + { + if (oldResource != null) + { + oldContainmentIndex = oldResource.getContents().indexOf(rootObject); + oldResource.getContents().remove(oldContainmentIndex); + } + else if (oldContainmentReference != null && FeatureMapUtil.isMany(oldContainer, oldContainmentReference)) + oldContainmentIndex = ((List)oldContainer.eGet(oldContainmentReference)).indexOf(rootObject); + + Object rootValue = + rootElement instanceof EAttribute && rootObject instanceof SimpleAnyTypeDataObject ? + ((SimpleAnyTypeDataObject)rootObject).getValue() : rootObject; + + documentRoot.eSet(rootElement, rootValue); + } + } + + if (outputStream != null) + resource.save(outputStream, (Map)options); + else // if (document != null) + resource.save(document, (Map)options, null); + + if (oldResource != null) + { + oldResource.getContents().add(oldContainmentIndex, rootObject); + } + if (rootElement instanceof EReference) + { + if (oldContainer != null) + { + if (oldContainer != documentRoot || oldContainmentReference != rootElement) + { + if (FeatureMapUtil.isMany(oldContainer, oldContainmentReference)) + ((List)oldContainer.eGet(oldContainmentReference)).add(oldContainmentIndex, rootObject); + else + oldContainer.eSet(oldContainmentReference, rootObject); + } + } + else if (documentRoot != null) + { + documentRoot.eSet(rootElement, null); + } + } + } + + protected void load(InputStream inputStream, String locationURI, Object options) throws IOException + { + InputSource inputSource = new InputSource(inputStream); + load(inputSource, locationURI, options); + } + + protected void load(Reader inputReader, String locationURI, Object options) throws IOException + { + InputSource inputSource = new InputSource(inputReader); + load(inputSource, locationURI, options); + } + + protected final void load(Node node, Object options) throws IOException { + resource.load(node, (Map)options); + initLoadedRoot(); + } + + protected final void load(XMLStreamReader reader, Map options) throws IOException + { + ((SDOXMLResourceImpl)resource).load(reader, options); + initLoadedRoot(); + } + + protected void load(InputSource inputSource, String locationURI, Object options) throws IOException + { + if (locationURI != null) + { + inputSource.setSystemId(locationURI); + resource.setURI(URI.createURI(locationURI)); + } + resource.load(inputSource, (Map)options); + initLoadedRoot(); + } + + /** + * @return a Map object with key-value pair where key is the DataObject and value contains the info + * about the unknown properties for the DataObject + */ + public Map getUnknownProperties(){ + return resource.getEObjectToExtensionMap(); + } + + private void initLoadedRoot() + { + rootObject = null; + rootElement = null; + documentRoot = null; + + if (!resource.getContents().isEmpty()) + { + documentRoot = (EObject)resource.getContents().get(0); + EClass documentRootClass = documentRoot.eClass(); + if ("".equals(extendedMetaData.getName(documentRootClass))) //TODO efficient way to check this? Maybe DataObject.getContainer should also check this? + { + FeatureMap featureMap = (FeatureMap)documentRoot.eGet(documentRootClass.getEStructuralFeature(0)); // get mixed feature + int size = featureMap.size(); + for (int index = 0; index < size; index++) + { + EStructuralFeature feature = featureMap.getEStructuralFeature(index); + boolean isText = + feature == XMLTypePackage.Literals.XML_TYPE_DOCUMENT_ROOT__TEXT || + feature == XMLTypePackage.Literals.XML_TYPE_DOCUMENT_ROOT__CDATA || + feature == XMLTypePackage.Literals.XML_TYPE_DOCUMENT_ROOT__COMMENT; + if (!isText) + { + if (feature instanceof EReference) + { + rootObject = (EObject)featureMap.getValue(index); + documentRoot.eUnset(feature); + } + else //EAttribute + { + rootObject = (EObject)SDOUtil.createDataTypeWrapper((Type)feature.getEType(), featureMap.getValue(index)); + } + rootElement = feature; + break; + } + } //for + if (rootObject == null) + rootObject = ((SDOXMLResourceImpl) resource).root; + } + else + { + rootObject = documentRoot; + documentRoot = null; + } + } + } + + public DataObject getRootObject() + { + return (DataObject)rootObject; + } + + public String getRootElementURI() + { + if (rootElement != null) + { + return extendedMetaData.getNamespace(rootElement); + } + else if (rootObject != null) + { + return extendedMetaData.getNamespace(rootObject.eClass()); + } + return null; + } + + public String getRootElementName() + { + if (rootElement != null) + { + return extendedMetaData.getName(rootElement); + } + else if (rootObject != null) + { + return extendedMetaData.getName(rootObject.eClass()); + } + return null; + } + + public String getEncoding() + { + return resource.getEncoding(); + } + + public void setEncoding(String encoding) + { + resource.setEncoding(encoding); + } + + public boolean isXMLDeclaration() + { + return Boolean.FALSE.equals(resource.getDefaultSaveOptions().get(XMLResource.OPTION_DECLARE_XML)); + } + + public void setXMLDeclaration(boolean xmlDeclaration) + { + resource.getDefaultSaveOptions().put(XMLResource.OPTION_DECLARE_XML, xmlDeclaration ? Boolean.TRUE : Boolean.FALSE); + } + + public String getXMLVersion() + { + return resource.getXMLVersion(); + } + + public void setXMLVersion(String xmlVersion) + { + resource.setXMLVersion(xmlVersion); + } + + /** + * @return an EMap containing the schema locations or null when no map + */ + protected EMap getSchemaLocationMap() + { + EMap result = null; + if ((documentRoot != null) && (extendedMetaData != null)) + { + EReference xsiSchemaLocationMapFeature = extendedMetaData + .getXSISchemaLocationMapFeature(documentRoot.eClass()); + if (xsiSchemaLocationMapFeature != null) + { + result = (EMap) documentRoot.eGet(xsiSchemaLocationMapFeature); + } + } + return result; + } + + /** + * @param value + * from schema location map. + * @return string form of URI from provided value, deresolved if appropriate. + */ + protected String deresolve(String value) + { + URI location = URI.createURI(value); + URI resourceURI = resource.getURI(); + boolean shouldDeresolve = resourceURI != null && !resourceURI.isRelative() + && resourceURI.isHierarchical(); + if (shouldDeresolve && !location.isRelative()) + { + URI deresolvedURI = location.deresolve(resourceURI, true, true, false); + if (deresolvedURI.hasRelativePath()) + { + location = deresolvedURI; + } + } + return location.toString(); + } + + /** + * @param value + * for schema location from input parameter. + * @return string form of URI from provided value, resolved if appropriate. + */ + protected String resolve(String value) + { + URI location = URI.createURI(value); + URI resourceURI = resource.getURI(); + boolean shouldResolve = resourceURI != null && resourceURI.isHierarchical() + && !resourceURI.isRelative(); + if (shouldResolve && location.isRelative() && location.hasRelativePath()) + { + location = location.resolve(resourceURI, false); + } + return location.toString(); + } + + public String getSchemaLocation() + { + EMap xsiSchemaLocationMap = getSchemaLocationMap(); + if (xsiSchemaLocationMap != null) + { + if (!xsiSchemaLocationMap.isEmpty()) + { + StringBuffer xsiSchemaLocation = new StringBuffer(); + for (Iterator i = xsiSchemaLocationMap.entrySet().iterator(); i + .hasNext();) + { + Map.Entry entry = (Map.Entry) i.next(); + String namespace = (String) entry.getKey(); + if (namespace != null) + { + if (xsiSchemaLocation.length() > 0) + { + xsiSchemaLocation.append(' '); + } + xsiSchemaLocation.append(namespace); + xsiSchemaLocation.append(' '); + String value = entry.getValue().toString(); + xsiSchemaLocation.append(deresolve(value)); + } + } + return xsiSchemaLocation.toString().equals("") ? null + : xsiSchemaLocation.toString(); + } + } + return null; + } + + public void setSchemaLocation(String schemaLocation) + { + EMap xsiSchemaLocationMap = getSchemaLocationMap(); + if (xsiSchemaLocationMap != null) + { + // only remove the entries from xsiSchemaLocationMap that contain a + // non-null key + for (Iterator i = xsiSchemaLocationMap.entrySet().iterator(); i.hasNext();) + { + Map.Entry entry = (Map.Entry) i.next(); + if (entry.getKey() != null) + { + i.remove(); + } + } + if (xsiSchemaLocationMap.size() == 0) + { + resource.getDefaultSaveOptions().put( + XMLResource.OPTION_SCHEMA_LOCATION, Boolean.FALSE); + } + if (schemaLocation != null) + { + String[] values = schemaLocation.split(WHITESPACE_REGEX); + for (int i = 0; i < values.length; i++) // note: also incremented in + // loop + { + String key = values[i++]; + if (i < values.length) + { + xsiSchemaLocationMap.put(key, resolve(values[i])); + } + } + if (xsiSchemaLocationMap.size() != 0) + { + resource.getDefaultSaveOptions().put( + XMLResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE); + } + } + } + } + + public String getNoNamespaceSchemaLocation() + { + EMap xsiSchemaLocationMap = getSchemaLocationMap(); + if (xsiSchemaLocationMap != null) + { + StringBuffer xsiSchemaLocation = new StringBuffer(); + if (!xsiSchemaLocationMap.isEmpty()) + { + Object valueObject = xsiSchemaLocationMap.get(null); + if (valueObject != null) + { + String valueString = (String) valueObject; + String[] values = valueString.split(WHITESPACE_REGEX); + for (int i = 0; i < values.length; i++) + { + if (xsiSchemaLocation.length() > 0) + { + xsiSchemaLocation.append(' '); + } + xsiSchemaLocation.append(deresolve(values[i])); + } + } + String result = xsiSchemaLocation.toString(); + return result.equals("") ? null : result; + } + } + return null; + } + + public void setNoNamespaceSchemaLocation(String schemaLocation) + { + EMap xsiSchemaLocationMap = getSchemaLocationMap(); + if (xsiSchemaLocationMap != null) + { + // only remove the entries from xsiSchemaLocationMap that contain a null + // key + xsiSchemaLocationMap.removeKey(null); + if (xsiSchemaLocationMap.size() == 0) + { + resource.getDefaultSaveOptions().put( + XMLResource.OPTION_SCHEMA_LOCATION, Boolean.FALSE); + } + if (schemaLocation != null) + { + String[] values = schemaLocation.split(WHITESPACE_REGEX); + for (int i = 0; i < values.length; i++) + { + xsiSchemaLocationMap.put(null, resolve(values[i])); + } + if (xsiSchemaLocationMap.size() != 0) + { + resource.getDefaultSaveOptions().put( + XMLResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE); + } + } + } + } +} diff --git a/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/XMLHelperImpl.java b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/XMLHelperImpl.java new file mode 100644 index 0000000000..4d0f3d7de8 --- /dev/null +++ b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/XMLHelperImpl.java @@ -0,0 +1,193 @@ +/** + * + * 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.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.StringReader; +import java.io.StringWriter; +import java.io.Writer; +import java.util.Map; + +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.dom.DOMResult; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.sax.SAXResult; +import javax.xml.transform.sax.SAXSource; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; + +import org.eclipse.emf.ecore.util.ExtendedMetaData; +import org.xml.sax.InputSource; + +import commonj.sdo.DataObject; +import commonj.sdo.helper.HelperContext; +import commonj.sdo.helper.XMLDocument; +import commonj.sdo.helper.XMLHelper; + +/** + * A helper to convert XML documents into DataObects and DataObjects into XML + * documnets. + */ +public class XMLHelperImpl implements XMLHelper { + protected HelperContext helperContext; + private ExtendedMetaData extendedMetaData; + + + public XMLHelperImpl(HelperContext hc) { + this.helperContext = hc; + this.extendedMetaData = ((HelperContextImpl)hc).extendedMetaData; + } + + public XMLDocument load(String inputString) { + try { + return load(new StringReader(inputString), null, null); + } catch (IOException e) { + throw new RuntimeException(e); // should never happen + } + } + + public XMLDocument load(String inputString, Object options) { + try { + return load(new StringReader(inputString), null, options); + } catch (IOException e) { + throw new RuntimeException(e); // should never happen + } + } + + public XMLDocument load(InputStream inputStream) throws IOException { + return load(inputStream, null, null); + } + + private Object checkSetOptions(Object options) throws IOException { + if (options != null && !(options instanceof Map)) { + throw new IOException("Invalid load options!"); + } + + if (helperContext != null) { + return ((HelperContextImpl)helperContext).getMergedOption((Map)options); + } else {// null is acceptable as it will be ignored + return options; + } + } + + public XMLDocument load(InputStream inputStream, String locationURI, Object options) throws IOException { + options = checkSetOptions(options); + XMLDocumentImpl document = new XMLDocumentImpl(extendedMetaData, options); + document.load(inputStream, locationURI, options); + return document; + } + + public XMLDocument load(Reader inputReader, String locationURI, Object options) throws IOException { + XMLDocumentImpl document = new XMLDocumentImpl(extendedMetaData, options); + options = checkSetOptions(options); + document.load(inputReader, locationURI, options); + return document; + } + + public XMLDocument load(Source source, String locationURI, Object options) throws IOException { + options = checkSetOptions(options); + if (source instanceof DOMSource) { + DOMSource domSource = (DOMSource)source; + XMLDocumentImpl document = new XMLDocumentImpl(extendedMetaData, options); + document.load(domSource.getNode(), options); + return document; + } else if (source instanceof SAXSource) { + XMLDocumentImpl document = new XMLDocumentImpl(extendedMetaData, options); + InputSource inputSource = SAXSource.sourceToInputSource(source); + document.load(inputSource, locationURI, options); + return document; + } else if (source instanceof StreamSource) { + return load(((StreamSource)source).getInputStream(), locationURI, options); + } else { + throw new UnsupportedOperationException(); + } + } + + public String save(DataObject dataObject, String rootElementURI, String rootElementName) { + StringWriter stringWriter = new StringWriter(); + try { + save(createDocument(dataObject, rootElementURI, rootElementName), stringWriter, null); + return stringWriter.toString(); + } catch (IOException e) { + throw new RuntimeException(e); // should never happen + } + } + + public String save(DataObject dataObject, String rootElementURI, String rootElementName, Object options) { + StringWriter stringWriter = new StringWriter(); + try { + save(createDocument(dataObject, rootElementURI, rootElementName), stringWriter, options); + return stringWriter.toString(); + } catch (IOException e) { + throw new RuntimeException(e); // should never happen + } + } + + public void save(DataObject dataObject, String rootElementURI, String rootElementName, OutputStream outputStream) + throws IOException { + save(createDocument(dataObject, rootElementURI, rootElementName), outputStream, null); + } + + + public void save(DataObject dataObject, + String rootElementURI, + String rootElementName, + OutputStream outputStream, + Object options) throws IOException { + save(createDocument(dataObject, rootElementURI, rootElementName), outputStream, null); + } + + public void save(XMLDocument xmlDocument, OutputStream outputStream, Object options) throws IOException { + options = checkSetOptions(options); + ((XMLDocumentImpl)xmlDocument).save(outputStream, options); + } + + public void save(XMLDocument xmlDocument, Writer outputWriter, Object options) throws IOException { + options = checkSetOptions(options); + ((XMLDocumentImpl)xmlDocument).save(outputWriter, options); + } + + public void save(XMLDocument xmlDocument, Result outputResult, Object options) throws IOException { + options = checkSetOptions(options); + if (outputResult instanceof DOMResult) { + ((XMLDocumentImpl)xmlDocument).save(((DOMResult)outputResult).getNode(), options); + } else if (outputResult instanceof SAXResult) { + throw new UnsupportedOperationException(); + } else if (outputResult instanceof StreamResult) { + save(xmlDocument, ((StreamResult)outputResult).getOutputStream(), options); + } else { + throw new UnsupportedOperationException(); + } + } + + public XMLDocument createDocument(DataObject dataObject, String rootElementURI, String rootElementName) { + XMLDocument xmlDocument = new XMLDocumentImpl(extendedMetaData, dataObject, rootElementURI, rootElementName); + xmlDocument.setEncoding("UTF-8"); + return xmlDocument; + } + + public HelperContext getHelperContext() { + return helperContext; + } +} diff --git a/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/XMLStreamHelper.java b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/XMLStreamHelper.java new file mode 100644 index 0000000000..851c7d93dd --- /dev/null +++ b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/XMLStreamHelper.java @@ -0,0 +1,26 @@ +/** + * + * 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; + +/** + * @deprecated + */ +public interface XMLStreamHelper extends org.apache.tuscany.sdo.api.XMLStreamHelper { +} diff --git a/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/XMLStreamHelperImpl.java b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/XMLStreamHelperImpl.java new file mode 100644 index 0000000000..7b0c2fc597 --- /dev/null +++ b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/XMLStreamHelperImpl.java @@ -0,0 +1,152 @@ +/** + * + * 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.io.IOException; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.sdo.util.resource.DataObjectXMLStreamReader; +import org.apache.tuscany.sdo.util.resource.XMLDocumentStreamReader; +import org.apache.tuscany.sdo.util.resource.XMLStreamSerializer; +//import org.apache.tuscany.sdo.api.XMLStreamHelper; +import org.eclipse.emf.ecore.resource.Resource; + +import commonj.sdo.DataObject; +import commonj.sdo.Property; +import commonj.sdo.helper.HelperContext; +import commonj.sdo.helper.XMLDocument; + +/** + * @version $Rev$ $Date$ + */ +public class XMLStreamHelperImpl implements XMLStreamHelper { + protected HelperContext helperContext; + + public XMLStreamHelperImpl(HelperContext hc) { + this.helperContext = hc; + } + + private Map checkSetOptions(Map options) { + if (helperContext != null) { + return ((HelperContextImpl)helperContext).getMergedOption(options); + } else {// null is acceptable as it will be ignored + return options; + } + } + + public XMLDocument load(XMLStreamReader reader) throws XMLStreamException, IllegalStateException { + if (reader.getEventType() != XMLStreamConstants.START_DOCUMENT) + throw new IllegalStateException(); + + return loadDocument(reader, null); + } + + public void save(XMLDocument document, XMLStreamWriter writer) throws XMLStreamException { + XMLStreamReader reader = createXMLStreamReader(document); + new XMLStreamSerializer().serialize(reader, writer); + } + + public void save(XMLDocument document, XMLStreamWriter writer, Map options) throws XMLStreamException { + XMLStreamReader reader = createXMLStreamReader(document); + options = checkSetOptions(options); + new XMLStreamSerializer().serialize(reader, writer, options); + } + + public XMLStreamReader createXMLStreamReader(XMLDocument document) throws XMLStreamException { + XMLStreamReader reader = + new DataObjectXMLStreamReader(document.getRootObject(), document.getRootElementURI(), document + .getRootElementName(), helperContext.getTypeHelper()); + // Wrap the reader so that its position will be START_ELEMENT + return new XMLDocumentStreamReader(reader); + + } + + public final DataObject loadObject(XMLStreamReader reader, Map options) throws XMLStreamException, + IllegalStateException { + if (reader.getEventType() != XMLStreamConstants.START_ELEMENT) + throw new IllegalStateException(); + + // StAX2SAXAdapter won't produce START_DOCUMENT if the reader is + // posisitioned at START_ELEMENT and the EMF loader will fail + // Wrap the reader so it represents a document + reader = new XMLDocumentStreamReader(reader); + + return loadDocument(reader, options).getRootObject(); + } + + public DataObject loadObject(XMLStreamReader reader) throws XMLStreamException, IllegalStateException { + return loadObject(reader, null); + } + + public void saveObject(DataObject sdo, XMLStreamWriter writer) throws XMLStreamException { + XMLStreamReader reader = createXMLStreamReader(sdo); + new XMLStreamSerializer().serialize(new XMLDocumentStreamReader(reader), writer); + } + + public void saveObject(DataObject sdo, XMLStreamWriter writer, Map options) throws XMLStreamException { + XMLStreamReader reader = createXMLStreamReader(sdo); + options = checkSetOptions(options); + new XMLStreamSerializer().serialize(new XMLDocumentStreamReader(reader), writer, options); + } + + public XMLStreamReader createXMLStreamReader(DataObject dataObject) { + String rootElementURI; + String rootElementName; + + Property property = dataObject.getContainmentProperty(); + if (property != null) { + rootElementName = property.getName(); + rootElementURI = property.getType().getURI(); + } else { + rootElementName = dataObject.getType().getName(); + rootElementURI = dataObject.getType().getURI(); + } + + return new DataObjectXMLStreamReader(dataObject, rootElementURI, rootElementName, helperContext.getTypeHelper()); + } + + protected XMLDocument loadDocument(XMLStreamReader reader, Map options) throws XMLStreamException { + try { + XMLDocumentImpl document = new XMLDocumentImpl(((HelperContextImpl)helperContext).extendedMetaData, null); + options = checkSetOptions(options); + document.load(reader, options); + return document; + } catch (Exception e) { + if (e instanceof Resource.IOWrappedException) { + Resource.IOWrappedException ioe = (Resource.IOWrappedException)e; + if (ioe.getWrappedException() instanceof XMLStreamException) { + throw (XMLStreamException)ioe.getWrappedException(); + } + } + throw new RuntimeException(e); // ???? + } + } + + public HelperContext getHelperContext() { + return helperContext; + } +} diff --git a/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/XSDHelperImpl.java b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/XSDHelperImpl.java new file mode 100644 index 0000000000..829acd38f4 --- /dev/null +++ b/sdo-java/tags/1.1-RC3/impl/src/main/java/org/apache/tuscany/sdo/helper/XSDHelperImpl.java @@ -0,0 +1,327 @@ +/** + * + * 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.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.Reader; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.apache.tuscany.sdo.impl.DynamicDataObjectImpl; +import org.apache.tuscany.sdo.util.DataObjectUtil; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EClassifier; +import org.eclipse.emf.ecore.EModelElement; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.impl.EPackageRegistryImpl; +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.xsd.XSDSchema; +import org.eclipse.xsd.ecore.XSDEcoreBuilder; +import org.eclipse.xsd.util.XSDResourceFactoryImpl; +import org.eclipse.xsd.util.XSDResourceImpl; +import org.xml.sax.InputSource; + +import commonj.sdo.Property; +import commonj.sdo.Type; +import commonj.sdo.helper.HelperContext; +import commonj.sdo.helper.TypeHelper; +import commonj.sdo.helper.XSDHelper; + +/** + * Provides access to additional information when the Type or Property is + * defined by an XML Schema (XSD). Methods return null/false otherwise or if the + * information is unavailable. Defines Types from an XSD. + */ +public class XSDHelperImpl implements XSDHelper { + protected boolean extensibleNamespaces = false; + protected HelperContext helperContext; + protected SDOXSDEcoreBuilder nondelegatingEcoreBuilder = null; + protected HashMap tcclToEcoreBuilderMap = null; + private ExtendedMetaData extendedMetaData; + + public XSDHelperImpl(HelperContext hc, String redefineBuiltIn, boolean extensibleNamespaces) { + this.helperContext = hc; + this.extensibleNamespaces = extensibleNamespaces; + extendedMetaData = ((HelperContextImpl)helperContext).extendedMetaData; + + SDOXSDEcoreBuilder ecoreBuilder = createEcoreBuilder(); + + if (extendedMetaData instanceof SDOExtendedMetaDataImpl && ((SDOExtendedMetaDataImpl)extendedMetaData) + .getRegistry() instanceof EPackageRegistryImpl.Delegator) { + tcclToEcoreBuilderMap = new HashMap(); + putTCCLEcoreBuilder(ecoreBuilder); + } else { + nondelegatingEcoreBuilder = ecoreBuilder; + } + + if (redefineBuiltIn != null) { // Redefining/regenerating this built-in + // model + ecoreBuilder.getTargetNamespaceToEPackageMap().remove(redefineBuiltIn); + } + } + + public XSDHelperImpl(HelperContext hc) { + this(hc, null, false); + } + + /** + * Redefine/regenerating the built-in model + * @param redefineBuiltIn + */ + public void setRedefineBuiltIn(String redefineBuiltIn) { + if (redefineBuiltIn != null) { + getEcoreBuilder().getTargetNamespaceToEPackageMap().remove(redefineBuiltIn); + } + } + + public void setExtensibleNamespaces(boolean extensibleNamespaces) { + this.extensibleNamespaces = extensibleNamespaces; + } + + protected SDOXSDEcoreBuilder createEcoreBuilder() { + SDOXSDEcoreBuilder ecoreBuilder = new SDOXSDEcoreBuilder(extendedMetaData, extensibleNamespaces); + + // Add the built-in models to the targetNamespaceToEPackageMap so they + // can't be (re)defined/overridden + for (Iterator iter = TypeHelperImpl.getBuiltInModels().iterator(); iter.hasNext();) { + EPackage ePackage = (EPackage)iter.next(); + ecoreBuilder.getTargetNamespaceToEPackageMap().put(ePackage.getNsURI(), ePackage); + } + + return ecoreBuilder; + } + + protected void putTCCLEcoreBuilder(XSDEcoreBuilder ecoreBuilder) { + ClassLoader tccl = Thread.currentThread().getContextClassLoader(); + if (tcclToEcoreBuilderMap.get(tccl) == null) { + tcclToEcoreBuilderMap.put(tccl, ecoreBuilder); + } + } + + protected SDOXSDEcoreBuilder getEcoreBuilder() { + if (nondelegatingEcoreBuilder != null) + return nondelegatingEcoreBuilder; + + SDOXSDEcoreBuilder result = null; + try { + for (ClassLoader tccl = Thread.currentThread().getContextClassLoader(); tccl != null; tccl = + tccl.getParent()) { + result = (SDOXSDEcoreBuilder)tcclToEcoreBuilderMap.get(tccl); + if (result != null) + return result; + } // for + } catch (SecurityException exception) { + // exception.printStackTrace(); + } + + result = createEcoreBuilder(); + putTCCLEcoreBuilder(result); + + return result; + } + + public String getLocalName(Type type) { + return extendedMetaData.getName((EClassifier)type); + } + + public String getLocalName(Property property) { + return extendedMetaData.getName((EStructuralFeature)property); + } + + public String getNamespaceURI(Property property) { + return extendedMetaData.getNamespace((EStructuralFeature)property); + } + + public boolean isAttribute(Property property) { + return extendedMetaData.getFeatureKind((EStructuralFeature)property) == ExtendedMetaData.ATTRIBUTE_FEATURE; + } + + public boolean isElement(Property property) { + return extendedMetaData.getFeatureKind((EStructuralFeature)property) == ExtendedMetaData.ELEMENT_FEATURE; + } + + public boolean isMixed(Type type) { + if (type instanceof EClass) { + return extendedMetaData.getContentKind((EClass)type) == ExtendedMetaData.MIXED_CONTENT; + } else { + return false; + } + } + + public boolean isXSD(Type type) { + return ((EModelElement)type).getEAnnotation(ExtendedMetaData.ANNOTATION_URI) != null; + } + + public Property getGlobalProperty(String uri, String propertyName, boolean isElement) { + if (isElement) { + return (Property)extendedMetaData.getElement(uri, propertyName); + } else { + return (Property)extendedMetaData.getAttribute(uri, propertyName); + } + } + + public String getAppinfo(Type type, String source) { + return getAppinfo((EModelElement)type, source); + } + + public String getAppinfo(Property property, String source) { + return getAppinfo((EModelElement)property, source); + } + + protected String getAppinfo(EModelElement eModelElement, String source) { + return (String)eModelElement.getEAnnotation(source).getDetails().get("appinfo"); + } + + public List /* Type */define(String xsd) { + InputStream inputStream = new ByteArrayInputStream(xsd.getBytes()); + return define(inputStream, "*.xsd"); + } + + public List /* Type */define(Reader xsdReader, String schemaLocation) { + InputSource inputSource = new InputSource(xsdReader); + return define(inputSource, schemaLocation); + + } + + public List /* Type */define(InputStream xsdInputStream, String schemaLocation) { + InputSource inputSource = new InputSource(xsdInputStream); + return define(inputSource, schemaLocation); + } + + protected List /* Type */define(InputSource inputSource, String schemaLocation) { + try { + SDOXSDEcoreBuilder ecoreBuilder = getEcoreBuilder(); + ResourceSet resourceSet = ecoreBuilder.createResourceSet(); + Resource model = + resourceSet.createResource(URI.createURI(schemaLocation != null ? schemaLocation : "null.xsd")); + ((XSDResourceImpl)model).load(inputSource, null); + + List newTypes = new ArrayList(); + for (Iterator schemaIter = model.getContents().iterator(); schemaIter.hasNext();) { + XSDSchema schema = (XSDSchema)schemaIter.next(); + + String targetNamespace = schema.getTargetNamespace(); + EPackage ePackage = extendedMetaData.getPackage(targetNamespace); + if (extensibleNamespaces || ePackage == null || TypeHelperImpl.getBuiltInModels().contains(ePackage)) { + Map targetNamespaceToEPackageMap = ecoreBuilder.getTargetNamespaceToEPackageMap(); + targetNamespaceToEPackageMap.remove(targetNamespace); + + Collection originalEPackages = new HashSet(targetNamespaceToEPackageMap.values()); + ecoreBuilder.generate(schema); + Collection newEPackages = ecoreBuilder.getTargetNamespaceToEPackageMap().values(); + + for (Iterator iter = newEPackages.iterator(); iter.hasNext();) { + EPackage currentPackage = (EPackage)iter.next(); + if (!originalEPackages.contains(currentPackage)) { + currentPackage.setEFactoryInstance(new DynamicDataObjectImpl.FactoryImpl()); + EcoreUtil.freeze(currentPackage); + newTypes.addAll(currentPackage.getEClassifiers()); + } + } + } + } + + return newTypes; + } catch (Exception e) { + e.printStackTrace(); + throw new IllegalArgumentException(e.getMessage()); + } + } + + public String generate(List /* Type */types) throws IllegalArgumentException { + return generate(types, new Hashtable()); + } + + public String generate(List /* Type */types, Map /* String, String */namespaceToSchemaLocation) + throws IllegalArgumentException { + if (types != null && !types.isEmpty()) { + Hashtable schemaMap = new Hashtable(); + Hashtable nsPrefixMap = new Hashtable(); + TypeTable typeTable = new TypeTable(); + + SchemaBuilder schemaBuilder = + new SchemaBuilder(schemaMap, nsPrefixMap, typeTable, namespaceToSchemaLocation); + + Iterator iterator = types.iterator(); + Type dataType = null; + + try { + while (iterator.hasNext()) { + dataType = (Type)iterator.next(); + schemaBuilder.buildSchema(dataType); + } + + XSDSchema xmlSchema = null; + iterator = schemaMap.values().iterator(); + StringWriter writer = new StringWriter(); + + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.setOutputProperty(OutputKeys.METHOD, "xml"); + transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); + + while (iterator.hasNext()) { + xmlSchema = (XSDSchema)iterator.next(); + + if (xmlSchema.getElement() == null) { + xmlSchema.updateElement(); + } + + transformer.transform(new DOMSource(xmlSchema.getElement().getOwnerDocument()), + new StreamResult(writer)); + } + writer.close(); + return writer.getBuffer().toString(); + } catch (Exception e) { + // System.out.println("Unable to generate schema due to ..." + + // e); + // e.printStackTrace(); + throw new IllegalArgumentException(e.getMessage()); + } + } else { + // System.out.println("No SDO Types to generate schema ..."); + return ""; + } + } + + public HelperContext getHelperContext() { + return helperContext; + } +} |