/** * * 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(); } }