| /** |
| * Copyright (c) 2005-2007 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM - Initial API and implementation |
| */ |
| package org.eclipse.xsd.ecore; |
| |
| |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.ListIterator; |
| import java.util.Map; |
| |
| 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.EEnum; |
| import org.eclipse.emf.ecore.EEnumLiteral; |
| import org.eclipse.emf.ecore.EGenericType; |
| import org.eclipse.emf.ecore.EModelElement; |
| 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.ETypeParameter; |
| import org.eclipse.emf.ecore.EcorePackage; |
| import org.eclipse.emf.ecore.util.BasicExtendedMetaData; |
| import org.eclipse.emf.ecore.util.EcoreUtil; |
| import org.eclipse.emf.ecore.util.ExtendedMetaData; |
| import org.eclipse.emf.ecore.xml.namespace.XMLNamespacePackage; |
| 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.XSDAttributeUseCategory; |
| import org.eclipse.xsd.XSDComplexTypeDefinition; |
| import org.eclipse.xsd.XSDComponent; |
| import org.eclipse.xsd.XSDCompositor; |
| import org.eclipse.xsd.XSDConcreteComponent; |
| import org.eclipse.xsd.XSDConstraint; |
| import org.eclipse.xsd.XSDDerivationMethod; |
| import org.eclipse.xsd.XSDElementDeclaration; |
| import org.eclipse.xsd.XSDEnumerationFacet; |
| import org.eclipse.xsd.XSDFacet; |
| import org.eclipse.xsd.XSDFactory; |
| import org.eclipse.xsd.XSDFeature; |
| import org.eclipse.xsd.XSDForm; |
| import org.eclipse.xsd.XSDFractionDigitsFacet; |
| import org.eclipse.xsd.XSDImport; |
| import org.eclipse.xsd.XSDLengthFacet; |
| import org.eclipse.xsd.XSDMaxExclusiveFacet; |
| import org.eclipse.xsd.XSDMaxInclusiveFacet; |
| import org.eclipse.xsd.XSDMaxLengthFacet; |
| import org.eclipse.xsd.XSDMinExclusiveFacet; |
| import org.eclipse.xsd.XSDMinInclusiveFacet; |
| import org.eclipse.xsd.XSDMinLengthFacet; |
| import org.eclipse.xsd.XSDModelGroup; |
| import org.eclipse.xsd.XSDNamedComponent; |
| import org.eclipse.xsd.XSDParticle; |
| import org.eclipse.xsd.XSDPatternFacet; |
| import org.eclipse.xsd.XSDSchema; |
| import org.eclipse.xsd.XSDSimpleTypeDefinition; |
| import org.eclipse.xsd.XSDTotalDigitsFacet; |
| import org.eclipse.xsd.XSDTypeDefinition; |
| import org.eclipse.xsd.XSDWhiteSpace; |
| import org.eclipse.xsd.XSDWhiteSpaceFacet; |
| import org.eclipse.xsd.XSDWildcard; |
| import org.eclipse.xsd.ecore.MapBuilder; |
| import org.eclipse.xsd.util.XSDConstants; |
| import org.eclipse.xsd.util.XSDParser; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.Node; |
| |
| |
| /** |
| * This class produces an XSDSchema given an Ecore EPackage. |
| */ |
| public class EcoreSchemaBuilder extends MapBuilder |
| { |
| /** |
| * The schema for schema namespace version to be used for new schemas. |
| */ |
| protected String defaultXMLSchemaNamespace = XSDConstants.SCHEMA_FOR_SCHEMA_URI_2001; |
| |
| /** |
| * The prefix to be used for the schema for schema namespace version in new schemas. |
| */ |
| protected String defaultXMLSchemaNamespacePrefix = "xsd"; |
| |
| /** |
| * The extended meta data used to determine the schema structure. |
| */ |
| protected ExtendedMetaData extendedMetaData; |
| |
| /** |
| * Store the reverse map too. |
| */ |
| protected Map<EModelElement, XSDComponent> eModelElementToXSDComponentMap = new HashMap<EModelElement, XSDComponent>(); |
| |
| public EcoreSchemaBuilder(ExtendedMetaData extendedMetaData) |
| { |
| this.extendedMetaData = extendedMetaData; |
| } |
| |
| @Override |
| protected void map(XSDComponent xsdComponent, EModelElement eModelElement) |
| { |
| super.map(xsdComponent, eModelElement); |
| |
| // Store the reverse map as well. |
| // |
| eModelElementToXSDComponentMap.put(eModelElement, xsdComponent); |
| } |
| |
| /* |
| public Collection generate(EPackage ePackage) |
| { |
| XSDSchema xsdSchema = getSchema(ePackage); |
| |
| Collection result = new ArrayList(); |
| result.add(xsdSchema); |
| if (mapper != null) |
| { |
| result.add(mapper.getRoot()); |
| } |
| |
| return result; |
| } |
| */ |
| |
| public XSDSchema getSchema(EPackage ePackage) |
| { |
| XSDSchema xsdSchema = (XSDSchema)eModelElementToXSDComponentMap.get(ePackage); |
| if (xsdSchema == null) |
| { |
| xsdSchema = buildSchema(ePackage); |
| } |
| return xsdSchema; |
| } |
| |
| protected String getQualifiedPackageName(EPackage ePackage) |
| { |
| return ePackage.getName(); |
| } |
| |
| protected XSDSchema buildSchema(EPackage ePackage) |
| { |
| XSDSchema xsdSchema = XSDFactory.eINSTANCE.createXSDSchema(); |
| |
| addInput(ePackage); |
| addOutput(xsdSchema); |
| map(xsdSchema, ePackage); |
| |
| // Set the namespace. |
| // |
| String targetNamespace = extendedMetaData.getNamespace(ePackage); |
| xsdSchema.setTargetNamespace(targetNamespace); |
| |
| // Choose the schema for schema namespace and prefix. |
| // |
| Map<String, String> namespaces = xsdSchema.getQNamePrefixToNamespaceMap(); |
| xsdSchema.setSchemaForSchemaQNamePrefix(defaultXMLSchemaNamespacePrefix); |
| namespaces.put(defaultXMLSchemaNamespacePrefix, defaultXMLSchemaNamespace); |
| |
| // Ensure that a prefix is assigned for the target namespace. |
| // |
| handlePrefix(namespaces, ePackage.getNsPrefix(), targetNamespace); |
| |
| // Create the node so that annotations can be added to the DOM. |
| // |
| xsdSchema.updateElement(); |
| |
| buildAnnotations(xsdSchema, ePackage); |
| |
| // Remember the package name and prefix. |
| // |
| createEcoreAnnotation(xsdSchema, "package", getQualifiedPackageName(ePackage)); |
| createEcoreAnnotation(xsdSchema, "nsPrefix", ePackage.getNsPrefix()); |
| |
| // Generate the global elements and attributes. |
| // |
| EClass documentRootEClass = extendedMetaData.getDocumentRoot(ePackage); |
| if (documentRootEClass == null) |
| { |
| for (EClassifier eClassifier : ePackage.getEClassifiers()) |
| { |
| if (eClassifier instanceof EClass) |
| { |
| EClass eClass = (EClass)eClassifier; |
| if (extendedMetaData.getContentKind(eClass) == ExtendedMetaData.UNSPECIFIED_CONTENT) |
| { |
| buildGlobalElement(xsdSchema, eClass); |
| } |
| } |
| } |
| } |
| else |
| { |
| if (!"DocumentRoot".equals(documentRootEClass.getName())) |
| { |
| createEcoreAnnotation(xsdSchema, "documentRoot", documentRootEClass.getName()); |
| } |
| |
| for (int i = 0, size = documentRootEClass.getFeatureCount(); i < size; ++i) |
| { |
| EStructuralFeature eStructuralFeature = documentRootEClass.getEStructuralFeature(i); |
| if (extendedMetaData.getName(eStructuralFeature).indexOf(':') == -1) |
| { |
| buildGlobalFeature(xsdSchema, eStructuralFeature); |
| } |
| } |
| } |
| |
| // Generate the type definitions. |
| // |
| for (EClassifier eClassifier : ePackage.getEClassifiers()) |
| { |
| if (eClassifier != documentRootEClass) |
| { |
| buildTypeDefinition(xsdSchema, eClassifier); |
| } |
| } |
| |
| return xsdSchema; |
| } |
| |
| protected XSDElementDeclaration buildGlobalElement(XSDSchema xsdSchema, EClass eClass) |
| { |
| XSDElementDeclaration xsdElementDeclaration = XSDFactory.eINSTANCE.createXSDElementDeclaration(); |
| xsdElementDeclaration.setName(extendedMetaData.getName(eClass)); |
| |
| XSDTypeDefinition xsdTypeDefinition = xsdSchema.resolveTypeDefinitionURI(getURI(eClass)); |
| handleImport(xsdSchema, xsdTypeDefinition); |
| xsdElementDeclaration.setTypeDefinition(xsdTypeDefinition); |
| |
| xsdSchema.getContents().add(xsdElementDeclaration); |
| map(xsdElementDeclaration, eClass); |
| |
| createEcoreAnnotation(xsdElementDeclaration, "ignore", "true"); |
| |
| return xsdElementDeclaration; |
| } |
| |
| protected XSDFeature buildGlobalFeature(XSDSchema xsdSchema, EStructuralFeature eStructuralFeature) |
| { |
| switch (extendedMetaData.getFeatureKind(eStructuralFeature)) |
| { |
| case ExtendedMetaData.ELEMENT_FEATURE: |
| { |
| XSDElementDeclaration xsdElementDeclaration = buildGlobalElement(xsdSchema, eStructuralFeature); |
| return xsdElementDeclaration; |
| } |
| case ExtendedMetaData.ATTRIBUTE_FEATURE: |
| { |
| XSDAttributeDeclaration xsdAttributeDeclaration = buildGlobalAttribute(xsdSchema, eStructuralFeature); |
| return xsdAttributeDeclaration; |
| } |
| case ExtendedMetaData.ELEMENT_WILDCARD_FEATURE: |
| case ExtendedMetaData.ATTRIBUTE_WILDCARD_FEATURE: |
| case ExtendedMetaData.SIMPLE_FEATURE: |
| case ExtendedMetaData.GROUP_FEATURE: |
| default: |
| { |
| return null; |
| } |
| } |
| } |
| |
| /** |
| * Handle difference lexical representations for default values, |
| * in particular, positive and negative infinity for float and double. |
| * @since 2.8 |
| */ |
| protected String transformDefaultValue(XSDSimpleTypeDefinition xsdSimpleTypeDefinition, String defaultValue) |
| { |
| XSDSimpleTypeDefinition primitiveTypeDefinition = xsdSimpleTypeDefinition.getPrimitiveTypeDefinition(); |
| if (primitiveTypeDefinition != null && |
| (primitiveTypeDefinition.hasNameAndTargetNamespace("float", defaultXMLSchemaNamespace) || |
| primitiveTypeDefinition.hasNameAndTargetNamespace("double", defaultXMLSchemaNamespace))) |
| { |
| if ("Infinity".equals(defaultValue)) |
| { |
| return "INF"; |
| } |
| else if ("-Infinity".equals(defaultValue)) |
| { |
| return "-INF"; |
| } |
| } |
| return defaultValue; |
| } |
| |
| protected XSDElementDeclaration buildGlobalElement(XSDSchema xsdSchema, EStructuralFeature eStructuralFeature) |
| { |
| XSDElementDeclaration xsdElementDeclaration = XSDFactory.eINSTANCE.createXSDElementDeclaration(); |
| xsdElementDeclaration.setName(extendedMetaData.getName(eStructuralFeature)); |
| |
| if (!eStructuralFeature.isChangeable()) |
| { |
| xsdElementDeclaration.setAbstract(true); |
| } |
| |
| EStructuralFeature affiliation = extendedMetaData.getAffiliation(eStructuralFeature); |
| if (affiliation != null) |
| { |
| XSDElementDeclaration xsdAffiliation = xsdSchema.resolveElementDeclarationURI(getURI(affiliation)); |
| handleImport(xsdSchema, xsdAffiliation); |
| xsdElementDeclaration.setSubstitutionGroupAffiliation(xsdAffiliation); |
| } |
| |
| EClassifier eType = eStructuralFeature.getEType(); |
| XSDTypeDefinition xsdTypeDefinition = xsdSchema.resolveTypeDefinitionURI(getURI(eType)); |
| handleImport(xsdSchema, xsdTypeDefinition); |
| xsdElementDeclaration.setTypeDefinition(xsdTypeDefinition); |
| |
| if (isWrapperType(eType)) |
| { |
| xsdElementDeclaration.setNillable(true); |
| } |
| |
| String defaultValue = eStructuralFeature.getDefaultValueLiteral(); |
| if (defaultValue != null) |
| { |
| xsdElementDeclaration.setConstraint(XSDConstraint.DEFAULT_LITERAL); |
| xsdElementDeclaration.setLexicalValue(transformDefaultValue((XSDSimpleTypeDefinition)xsdElementDeclaration.getTypeDefinition(), defaultValue)); |
| } |
| |
| xsdSchema.getContents().add(xsdElementDeclaration); |
| map(xsdElementDeclaration, eStructuralFeature); |
| |
| if (eStructuralFeature.eIsSet(EcorePackage.Literals.ETYPED_ELEMENT__EGENERIC_TYPE)) |
| { |
| createEcoreAnnotation(xsdElementDeclaration, "type", getGenericType(xsdSchema, eStructuralFeature.getEGenericType())); |
| } |
| |
| buildAnnotations(xsdElementDeclaration, eStructuralFeature); |
| |
| return xsdElementDeclaration; |
| } |
| |
| protected XSDAttributeDeclaration buildGlobalAttribute(XSDSchema xsdSchema, EStructuralFeature eStructuralFeature) |
| { |
| XSDAttributeDeclaration xsdAttributeDeclaration = XSDFactory.eINSTANCE.createXSDAttributeDeclaration(); |
| xsdAttributeDeclaration.setName(extendedMetaData.getName(eStructuralFeature)); |
| |
| XSDSimpleTypeDefinition xsdSimpleTypeDefinition = xsdSchema.resolveSimpleTypeDefinitionURI(getURI(eStructuralFeature.getEType())); |
| handleImport(xsdSchema, xsdSimpleTypeDefinition); |
| xsdAttributeDeclaration.setTypeDefinition(xsdSimpleTypeDefinition); |
| |
| String defaultValue = eStructuralFeature.getDefaultValueLiteral(); |
| if (defaultValue != null) |
| { |
| xsdAttributeDeclaration.setConstraint(XSDConstraint.DEFAULT_LITERAL); |
| xsdAttributeDeclaration.setLexicalValue(transformDefaultValue(xsdAttributeDeclaration.getTypeDefinition(), defaultValue)); |
| } |
| |
| xsdSchema.getContents().add(xsdAttributeDeclaration); |
| map(xsdAttributeDeclaration, eStructuralFeature); |
| |
| if (eStructuralFeature.eIsSet(EcorePackage.Literals.ETYPED_ELEMENT__EGENERIC_TYPE)) |
| { |
| createEcoreAnnotation(xsdAttributeDeclaration, "type", getGenericType(xsdSchema, eStructuralFeature.getEGenericType())); |
| } |
| |
| buildAnnotations(xsdAttributeDeclaration, eStructuralFeature); |
| |
| return xsdAttributeDeclaration; |
| } |
| |
| protected XSDTypeDefinition buildTypeDefinition(XSDSchema xsdSchema, EClassifier eClassifier) |
| { |
| if (eClassifier instanceof EClass) |
| { |
| return buildComplexTypeDefinition(xsdSchema, (EClass)eClassifier); |
| } |
| else |
| { |
| return buildSimpleTypeDefinition(xsdSchema, (EDataType)eClassifier); |
| } |
| } |
| |
| protected XSDSimpleTypeDefinition buildSimpleTypeDefinition(XSDSchema xsdSchema, EDataType eDataType) |
| { |
| String name = extendedMetaData.getName(eDataType); |
| boolean isAnonymousWrapperType = name.endsWith(":Object"); |
| if (isAnonymousWrapperType && EcorePackage.eNS_URI.equals(xsdSchema.getTargetNamespace())) |
| { |
| name = eDataType.getName(); |
| isAnonymousWrapperType = false; |
| } |
| if (!isAnonymousWrapperType) |
| { |
| XSDSimpleTypeDefinition xsdSimpleTypeDefinition = XSDFactory.eINSTANCE.createXSDSimpleTypeDefinition(); |
| |
| xsdSimpleTypeDefinition.setName(name); |
| |
| String instanceClass = null; |
| EDataType baseType = extendedMetaData.getBaseType(eDataType); |
| if (baseType != null) |
| { |
| XSDSimpleTypeDefinition baseTypeDefinition = xsdSchema.resolveSimpleTypeDefinitionURI(getURI(baseType)); |
| handleImport(xsdSchema, baseTypeDefinition); |
| xsdSimpleTypeDefinition.setBaseTypeDefinition(baseTypeDefinition); |
| |
| // Produce an instance class declaration if the type is different from that of the base. |
| // |
| instanceClass = eDataType.getInstanceTypeName(); |
| if (instanceClass != null && instanceClass.equals(baseType.getInstanceTypeName())) |
| { |
| instanceClass = null; |
| } |
| } |
| else |
| { |
| EDataType itemType = extendedMetaData.getItemType(eDataType); |
| if (itemType != null) |
| { |
| XSDSimpleTypeDefinition itemTypeDefinition = xsdSchema.resolveSimpleTypeDefinitionURI(getURI(itemType)); |
| handleImport(xsdSchema, itemTypeDefinition); |
| xsdSimpleTypeDefinition.setItemTypeDefinition(itemTypeDefinition); |
| } |
| else |
| { |
| List<EDataType> memberTypes = extendedMetaData.getMemberTypes(eDataType); |
| if (!memberTypes.isEmpty()) |
| { |
| for (EDataType memberType : memberTypes) |
| { |
| XSDSimpleTypeDefinition memberTypeDefinition = xsdSchema.resolveSimpleTypeDefinitionURI(getURI(memberType)); |
| handleImport(xsdSchema, memberTypeDefinition); |
| xsdSimpleTypeDefinition.getMemberTypeDefinitions().add(memberTypeDefinition); |
| } |
| } |
| else |
| { |
| xsdSimpleTypeDefinition.setBaseTypeDefinition(xsdSchema.getSchemaForSchema().resolveSimpleTypeDefinition("string")); |
| if (!(eDataType instanceof EEnum)) |
| { |
| instanceClass = eDataType.getInstanceTypeName(); |
| } |
| } |
| } |
| } |
| |
| xsdSchema.getContents().add(xsdSimpleTypeDefinition); |
| map(xsdSimpleTypeDefinition, eDataType); |
| |
| buildTypeParameters(xsdSimpleTypeDefinition, eDataType.getETypeParameters()); |
| |
| if (instanceClass != null) |
| { |
| createEcoreAnnotation(xsdSimpleTypeDefinition, "instanceClass", instanceClass.replace('<', '{').replace('>', '}')); |
| } |
| |
| String minInclusive = extendedMetaData.getMinInclusiveFacet(eDataType); |
| if (minInclusive != null) |
| { |
| XSDMinInclusiveFacet xsdMinInclusiveFacet = XSDFactory.eINSTANCE.createXSDMinInclusiveFacet(); |
| xsdMinInclusiveFacet.setLexicalValue(minInclusive); |
| xsdSimpleTypeDefinition.getFacetContents().add(xsdMinInclusiveFacet); |
| } |
| |
| String maxInclusive = extendedMetaData.getMaxInclusiveFacet(eDataType); |
| if (maxInclusive != null) |
| { |
| XSDMaxInclusiveFacet xsdMaxInclusiveFacet = XSDFactory.eINSTANCE.createXSDMaxInclusiveFacet(); |
| xsdMaxInclusiveFacet.setLexicalValue(maxInclusive); |
| xsdSimpleTypeDefinition.getFacetContents().add(xsdMaxInclusiveFacet); |
| } |
| |
| String minExclusive = extendedMetaData.getMinExclusiveFacet(eDataType); |
| if (minExclusive != null) |
| { |
| XSDMinExclusiveFacet xsdMinExclusiveFacet = XSDFactory.eINSTANCE.createXSDMinExclusiveFacet(); |
| xsdMinExclusiveFacet.setLexicalValue(minExclusive); |
| xsdSimpleTypeDefinition.getFacetContents().add(xsdMinExclusiveFacet); |
| } |
| |
| String maxExclusive = extendedMetaData.getMaxExclusiveFacet(eDataType); |
| if (maxExclusive != null) |
| { |
| XSDMaxExclusiveFacet xsdMaxExclusiveFacet = XSDFactory.eINSTANCE.createXSDMaxExclusiveFacet(); |
| xsdMaxExclusiveFacet.setLexicalValue(maxExclusive); |
| xsdSimpleTypeDefinition.getFacetContents().add(xsdMaxExclusiveFacet); |
| } |
| |
| int length = extendedMetaData.getLengthFacet(eDataType); |
| if (length != -1) |
| { |
| XSDLengthFacet xsdLengthFacet = XSDFactory.eINSTANCE.createXSDLengthFacet(); |
| xsdLengthFacet.setLexicalValue(Integer.toString(length)); |
| xsdSimpleTypeDefinition.getFacetContents().add(xsdLengthFacet); |
| } |
| |
| int maxLength = extendedMetaData.getMaxLengthFacet(eDataType); |
| if (maxLength != -1) |
| { |
| XSDMaxLengthFacet xsdMaxLengthFacet = XSDFactory.eINSTANCE.createXSDMaxLengthFacet(); |
| xsdMaxLengthFacet.setLexicalValue(Integer.toString(maxLength)); |
| xsdSimpleTypeDefinition.getFacetContents().add(xsdMaxLengthFacet); |
| } |
| |
| int minLength = extendedMetaData.getMinLengthFacet(eDataType); |
| if (minLength != -1) |
| { |
| XSDMinLengthFacet xsdMinLengthFacet = XSDFactory.eINSTANCE.createXSDMinLengthFacet(); |
| xsdMinLengthFacet.setLexicalValue(Integer.toString(minLength)); |
| xsdSimpleTypeDefinition.getFacetContents().add(xsdMinLengthFacet); |
| } |
| |
| int totalDigits = extendedMetaData.getTotalDigitsFacet(eDataType); |
| if (totalDigits != -1) |
| { |
| XSDTotalDigitsFacet xsdTotalDigitsFacet = XSDFactory.eINSTANCE.createXSDTotalDigitsFacet(); |
| xsdTotalDigitsFacet.setLexicalValue(Integer.toString(totalDigits)); |
| xsdSimpleTypeDefinition.getFacetContents().add(xsdTotalDigitsFacet); |
| } |
| |
| int fractionDigits = extendedMetaData.getFractionDigitsFacet(eDataType); |
| if (fractionDigits != -1) |
| { |
| XSDFractionDigitsFacet xsdFractionDigitsFacet = XSDFactory.eINSTANCE.createXSDFractionDigitsFacet(); |
| xsdFractionDigitsFacet.setLexicalValue(Integer.toString(fractionDigits)); |
| xsdSimpleTypeDefinition.getFacetContents().add(xsdFractionDigitsFacet); |
| } |
| |
| int whiteSpace = extendedMetaData.getWhiteSpaceFacet(eDataType); |
| if (whiteSpace != ExtendedMetaData.UNSPECIFIED_WHITE_SPACE) |
| { |
| XSDWhiteSpaceFacet xsdWhiteSpaceFacet = XSDFactory.eINSTANCE.createXSDWhiteSpaceFacet(); |
| xsdWhiteSpaceFacet.setLexicalValue(XSDWhiteSpace.get(whiteSpace - 1).toString()); |
| xsdSimpleTypeDefinition.getFacetContents().add(xsdWhiteSpaceFacet); |
| } |
| |
| for (String pattern : extendedMetaData.getPatternFacet(eDataType)) |
| { |
| XSDPatternFacet xsdPatternFacet = XSDFactory.eINSTANCE.createXSDPatternFacet(); |
| xsdPatternFacet.setLexicalValue(pattern); |
| xsdSimpleTypeDefinition.getFacetContents().add(xsdPatternFacet); |
| } |
| |
| for (String enumeration : extendedMetaData.getEnumerationFacet(eDataType)) |
| { |
| XSDEnumerationFacet xsdEnumerationFacet = XSDFactory.eINSTANCE.createXSDEnumerationFacet(); |
| xsdEnumerationFacet.setLexicalValue(enumeration); |
| xsdSimpleTypeDefinition.getFacetContents().add(xsdEnumerationFacet); |
| } |
| |
| String ecoreName = eDataType.getName(); |
| if (!name.equals(ecoreName) || Character.isLowerCase(ecoreName.charAt(0)) || ecoreName.indexOf('_') != -1) |
| { |
| createEcoreAnnotation(xsdSimpleTypeDefinition, "name", ecoreName); |
| } |
| |
| String constraints = EcoreUtil.getAnnotation(eDataType, EcorePackage.eNS_URI, "constraints"); |
| if (constraints != null) |
| { |
| createEcoreAnnotation(xsdSimpleTypeDefinition, "constraints", constraints); |
| } |
| |
| if (!eDataType.isSerializable()) |
| { |
| createEcoreAnnotation(xsdSimpleTypeDefinition, "serializable", "false"); |
| } |
| |
| if (eDataType instanceof EEnum) |
| { |
| EEnum eEnum = (EEnum)eDataType; |
| |
| for (ListIterator<EEnumLiteral> literals = eEnum.getELiterals().listIterator(); literals.hasNext();) |
| { |
| EEnumLiteral literal = literals.next(); |
| XSDEnumerationFacet facet = XSDFactory.eINSTANCE.createXSDEnumerationFacet(); |
| facet.setLexicalValue(literal.getLiteral()); |
| xsdSimpleTypeDefinition.getFacetContents().add(facet); |
| map(facet, literal); |
| |
| if (!literal.getLiteral().equals(literal.getName())) |
| { |
| createEcoreAnnotation(facet, "name", literal.getName()); |
| } |
| |
| if (literal.getValue() != literals.previousIndex()) |
| { |
| createEcoreAnnotation(facet, "value", Integer.toString(literal.getValue())); |
| } |
| } |
| } |
| |
| buildAnnotations(xsdSimpleTypeDefinition, eDataType); |
| |
| return xsdSimpleTypeDefinition; |
| } |
| else |
| { |
| return null; |
| } |
| } |
| |
| protected XSDComplexTypeDefinition buildComplexTypeDefinition(XSDSchema xsdSchema, EClass eClass) |
| { |
| XSDComplexTypeDefinition xsdComplexTypeDefinition = XSDFactory.eINSTANCE.createXSDComplexTypeDefinition(); |
| |
| String name = extendedMetaData.getName(eClass); |
| xsdComplexTypeDefinition.setName(name); |
| |
| if (eClass.isAbstract()) |
| { |
| xsdComplexTypeDefinition.setAbstract(true); |
| } |
| |
| List<EGenericType> genericTypeTypes = eClass.getEGenericSuperTypes(); |
| if (!genericTypeTypes.isEmpty()) |
| { |
| Iterator<EGenericType> i = genericTypeTypes.iterator(); |
| EGenericType genericSuperType = i.next(); |
| XSDTypeDefinition baseType = xsdSchema.resolveTypeDefinitionURI(getURI(genericSuperType.getERawType())); |
| if (!XSDConstants.isURType(baseType)) |
| { |
| handleImport(xsdSchema, baseType); |
| xsdComplexTypeDefinition.setDerivationMethod(XSDDerivationMethod.EXTENSION_LITERAL); |
| xsdComplexTypeDefinition.setBaseTypeDefinition(baseType); |
| } |
| |
| xsdSchema.getContents().add(xsdComplexTypeDefinition); |
| |
| if (!genericSuperType.getETypeArguments().isEmpty()) |
| { |
| createEcoreAnnotation(xsdComplexTypeDefinition, "extends", getGenericType(xsdSchema, genericSuperType)); |
| } |
| |
| if (i.hasNext()) |
| { |
| StringBuilder additionalSuperTypes = new StringBuilder(); |
| do |
| { |
| additionalSuperTypes.append(getGenericType(xsdSchema, i.next())); |
| additionalSuperTypes.append(' '); |
| } |
| while (i.hasNext()); |
| createEcoreAnnotation(xsdComplexTypeDefinition, "implements", additionalSuperTypes.toString().trim()); |
| } |
| } |
| else |
| { |
| xsdSchema.getContents().add(xsdComplexTypeDefinition); |
| } |
| |
| buildTypeParameters(xsdComplexTypeDefinition, eClass.getETypeParameters()); |
| |
| map(xsdComplexTypeDefinition, eClass); |
| |
| String instanceClass = eClass.getInstanceTypeName(); |
| if (instanceClass != null) |
| { |
| createEcoreAnnotation(xsdComplexTypeDefinition, "instanceClass", instanceClass.replace('<', '{').replace('>', '}')); |
| } |
| |
| String ecoreName = eClass.getName(); |
| if (!name.equals(ecoreName) || Character.isLowerCase(ecoreName.charAt(0)) || ecoreName.indexOf('_') != -1) |
| { |
| createEcoreAnnotation(xsdComplexTypeDefinition, "name", ecoreName); |
| } |
| |
| if (eClass.isInterface()) |
| { |
| createEcoreAnnotation(xsdComplexTypeDefinition, "interface", "true"); |
| } |
| |
| String constraints = EcoreUtil.getAnnotation(eClass, EcorePackage.eNS_URI, "constraints"); |
| if (constraints != null) |
| { |
| createEcoreAnnotation(xsdComplexTypeDefinition, "constraints", constraints); |
| } |
| |
| for (Iterator<EStructuralFeature> i = eClass.getEStructuralFeatures().iterator(); i.hasNext(); ) |
| { |
| EStructuralFeature eStructuralFeature = i.next(); |
| buildContentFeature(xsdComplexTypeDefinition, eStructuralFeature); |
| } |
| |
| List<EOperation> eOperations = eClass.getEOperations(); |
| if (!eOperations.isEmpty()) |
| { |
| XSDAnnotation xsdAnnotation = xsdComplexTypeDefinition.getAnnotation(); |
| if (xsdAnnotation == null) |
| { |
| xsdAnnotation = XSDFactory.eINSTANCE.createXSDAnnotation(); |
| xsdComplexTypeDefinition.setAnnotation(xsdAnnotation); |
| } |
| Element applicationInformation = xsdAnnotation.createApplicationInformation(EcorePackage.eNS_URI); |
| xsdAnnotation.getElement().appendChild(applicationInformation); |
| createEcoreAnnotation(xsdSchema.getQNamePrefixToNamespaceMap(), applicationInformation, "key", "operations"); |
| Document document = xsdSchema.getDocument(); |
| for (EOperation eOperation : eOperations) |
| { |
| Element operation = document.createElementNS(null, "operation"); |
| operation.setAttributeNS(null, "name", eOperation.getName()); |
| applicationInformation.appendChild(operation); |
| buildAnnotation(eOperation, operation); |
| buildTypeParameters(xsdAnnotation, eOperation.getETypeParameters()); |
| EGenericType returnEGenericType = eOperation.getEGenericType(); |
| if (returnEGenericType != null) |
| { |
| operation.setAttributeNS(null, "type", getGenericType(xsdSchema, returnEGenericType)); |
| } |
| List<EClassifier> exceptions = eOperation.getEExceptions(); |
| if (!exceptions.isEmpty()) |
| { |
| StringBuilder stringBuilder = new StringBuilder(); |
| for (EGenericType eGenericType : eOperation.getEGenericExceptions()) |
| { |
| stringBuilder.append(getGenericType(xsdSchema, eGenericType)); |
| stringBuilder.append(' '); |
| } |
| |
| operation.setAttributeNS(null, "exceptions", stringBuilder.substring(0, stringBuilder.length() - 1)); |
| } |
| |
| for (EParameter eParameter : eOperation.getEParameters()) |
| { |
| Element parameter = document.createElementNS(null, "parameter"); |
| parameter.setAttributeNS(null, "name", eParameter.getName()); |
| operation.appendChild(parameter); |
| buildAnnotation(eParameter, parameter); |
| parameter.setAttributeNS(null, "type", getGenericType(xsdSchema, eParameter.getEGenericType())); |
| |
| if (eParameter.getLowerBound() != 0) |
| { |
| parameter.setAttributeNS(null, "lowerBound", Integer.toString(eParameter.getLowerBound())); |
| } |
| if (eParameter.getUpperBound() != 1) |
| { |
| parameter.setAttributeNS(null, "upperBound", Integer.toString(eParameter.getUpperBound())); |
| } |
| if (!eParameter.isOrdered()) |
| { |
| parameter.setAttributeNS(null, "ordered", "false"); |
| } |
| if (!eParameter.isUnique()) |
| { |
| parameter.setAttributeNS(null, "unique", "false"); |
| } |
| } |
| |
| if (eOperation.getLowerBound() != 0) |
| { |
| operation.setAttributeNS(null, "lowerBound", Integer.toString(eOperation.getLowerBound())); |
| } |
| if (eOperation.getUpperBound() != 1) |
| { |
| operation.setAttributeNS(null, "upperBound", Integer.toString(eOperation.getUpperBound())); |
| } |
| if (!eOperation.isOrdered()) |
| { |
| operation.setAttributeNS(null, "ordered", "false"); |
| } |
| if (!eOperation.isUnique()) |
| { |
| operation.setAttributeNS(null, "unique", "false"); |
| } |
| |
| String body = EcoreUtil.getAnnotation(eOperation, GEN_MODEL_PACKAGE_NS_URI, "body"); |
| if (body != null) |
| { |
| Element bodyElement = document.createElementNS(null, "body"); |
| bodyElement.appendChild(document.createTextNode(body)); |
| operation.appendChild(bodyElement); |
| } |
| } |
| } |
| |
| buildAnnotations(xsdComplexTypeDefinition, eClass); |
| |
| return xsdComplexTypeDefinition; |
| } |
| |
| protected void buildTypeParameters(XSDComponent xsdComponent, List<ETypeParameter> eTypeParameters) |
| { |
| if (!eTypeParameters.isEmpty()) |
| { |
| XSDSchema xsdSchema = xsdComponent.getSchema(); |
| XSDAnnotation xsdAnnotation; |
| Element applicationInformation; |
| if (xsdComponent instanceof XSDTypeDefinition) |
| { |
| xsdAnnotation = XSDFactory.eINSTANCE.createXSDAnnotation(); |
| ((XSDTypeDefinition)xsdComponent).setAnnotation(xsdAnnotation); |
| applicationInformation = xsdAnnotation.createApplicationInformation(EcorePackage.eNS_URI); |
| xsdAnnotation.getElement().appendChild(applicationInformation); |
| createEcoreAnnotation(xsdSchema.getQNamePrefixToNamespaceMap(), applicationInformation, "key", "typeParameters"); |
| } |
| else |
| { |
| xsdAnnotation = (XSDAnnotation)xsdComponent; |
| applicationInformation = (Element)xsdAnnotation.getApplicationInformation().get(xsdAnnotation.getApplicationInformation().size() - 1).getLastChild(); |
| } |
| Document document = xsdSchema.getDocument(); |
| for (ETypeParameter eTypeParameter : eTypeParameters) |
| { |
| Element typeParameter = document.createElementNS(null, "typeParameter"); |
| typeParameter.setAttributeNS(null, "name", eTypeParameter.getName()); |
| applicationInformation.appendChild(typeParameter); |
| buildAnnotation(eTypeParameter, typeParameter); |
| List<EGenericType> eBounds = eTypeParameter.getEBounds(); |
| if (!eBounds.isEmpty()) |
| { |
| StringBuilder stringBuilder = new StringBuilder(); |
| for (Iterator<EGenericType> i = eBounds.iterator(); i.hasNext(); ) |
| { |
| String bound = getGenericType(xsdSchema, i.next()); |
| stringBuilder.append(bound); |
| if (i.hasNext()) |
| { |
| stringBuilder.append(' '); |
| } |
| } |
| |
| typeParameter.setAttributeNS(null, "bounds", stringBuilder.toString()); |
| } |
| } |
| } |
| } |
| |
| protected XSDComponent buildContentFeature(XSDComplexTypeDefinition xsdComplexTypeDefinition, EStructuralFeature eStructuralFeature) |
| { |
| switch (extendedMetaData.getFeatureKind(eStructuralFeature)) |
| { |
| case ExtendedMetaData.ELEMENT_FEATURE: |
| { |
| XSDParticle xsdParticle = buildElementParticle(xsdComplexTypeDefinition, eStructuralFeature); |
| return xsdParticle; |
| } |
| case ExtendedMetaData.ATTRIBUTE_FEATURE: |
| { |
| XSDAttributeUse xsdAttributeUse = buildAttributeUse(xsdComplexTypeDefinition, eStructuralFeature); |
| return xsdAttributeUse; |
| } |
| case ExtendedMetaData.GROUP_FEATURE: |
| { |
| XSDParticle xsdParticle = buildModelGroupParticle(xsdComplexTypeDefinition, eStructuralFeature); |
| return xsdParticle; |
| } |
| case ExtendedMetaData.ELEMENT_WILDCARD_FEATURE: |
| { |
| XSDWildcard xsdWildcard = buildElementWildcard(xsdComplexTypeDefinition, eStructuralFeature); |
| return xsdWildcard; |
| } |
| case ExtendedMetaData.ATTRIBUTE_WILDCARD_FEATURE: |
| { |
| XSDWildcard xsdWildcard = buildAttributeWildcard(xsdComplexTypeDefinition, eStructuralFeature); |
| return xsdWildcard; |
| } |
| case ExtendedMetaData.SIMPLE_FEATURE: |
| { |
| XSDSimpleTypeDefinition xsdSimpleTypeDefinition = buildSimpleContent(xsdComplexTypeDefinition, eStructuralFeature); |
| return xsdSimpleTypeDefinition; |
| } |
| default: |
| { |
| if (eStructuralFeature instanceof EAttribute) |
| { |
| EAttribute eAttribute = (EAttribute)eStructuralFeature; |
| if (eAttribute.isMany()) |
| { |
| return buildElementParticle(xsdComplexTypeDefinition, eAttribute); |
| } |
| else |
| { |
| return buildAttributeUse(xsdComplexTypeDefinition, eAttribute); |
| } |
| } |
| else |
| { |
| EReference eReference = (EReference)eStructuralFeature; |
| if (eReference.isContainment()) |
| { |
| return buildElementParticle(xsdComplexTypeDefinition, eReference); |
| } |
| else if (eReference.isContainer() && eReference.isTransient()) |
| { |
| return null; |
| } |
| else |
| { |
| return buildAttributeUse(xsdComplexTypeDefinition, eReference); |
| } |
| } |
| } |
| } |
| } |
| |
| protected XSDParticle buildModelGroupParticle(XSDComplexTypeDefinition xsdComplexTypeDefinition, EStructuralFeature eStructuralFeature) |
| { |
| XSDModelGroup xsdModelGroup = findOrCreateModelGroup(xsdComplexTypeDefinition); |
| |
| XSDModelGroup modelGroup = XSDFactory.eINSTANCE.createXSDModelGroup(); |
| modelGroup.setCompositor(XSDCompositor.CHOICE_LITERAL); |
| XSDParticle xsdParticle = XSDFactory.eINSTANCE.createXSDParticle(); |
| xsdParticle.setContent(modelGroup); |
| |
| if (eStructuralFeature.getUpperBound() != 1) |
| { |
| xsdParticle.setMaxOccurs(eStructuralFeature.getUpperBound()); |
| } |
| |
| xsdModelGroup.getContents().add(xsdParticle); |
| map(xsdParticle, eStructuralFeature); |
| |
| createEcoreAnnotation(xsdParticle, "featureMap", eStructuralFeature.getName()); |
| |
| buildAnnotations(xsdModelGroup, eStructuralFeature); |
| |
| return xsdParticle; |
| } |
| |
| protected XSDWildcard buildElementWildcard(XSDComplexTypeDefinition xsdComplexTypeDefinition, EStructuralFeature eStructuralFeature) |
| { |
| String name = extendedMetaData.getName(eStructuralFeature); |
| if (":mixed".equals(name)) |
| { |
| xsdComplexTypeDefinition.setMixed(true); |
| return null; |
| } |
| else |
| { |
| XSDWildcard xsdWildcard = XSDFactory.eINSTANCE.createXSDWildcard(); |
| xsdWildcard.setStringLexicalNamespaceConstraint |
| (BasicExtendedMetaData.getEncodedWildcards |
| (extendedMetaData.getNamespace(eStructuralFeature.getEContainingClass()), |
| extendedMetaData.getWildcards(eStructuralFeature))); |
| XSDModelGroup xsdModelGroup = findOrCreateModelGroup(xsdComplexTypeDefinition); |
| XSDParticle xsdParticle = XSDFactory.eINSTANCE.createXSDParticle(); |
| xsdParticle.setContent(xsdWildcard); |
| xsdModelGroup.getContents().add(xsdParticle); |
| map(xsdParticle, eStructuralFeature); |
| |
| if (eStructuralFeature.getLowerBound() != 1) |
| { |
| xsdParticle.setMinOccurs(eStructuralFeature.getLowerBound()); |
| } |
| |
| if (eStructuralFeature.getUpperBound() != 1) |
| { |
| xsdParticle.setMaxOccurs(eStructuralFeature.getUpperBound()); |
| } |
| createEcoreAnnotation(xsdWildcard, "name", eStructuralFeature.getName()); |
| |
| buildAnnotations(xsdWildcard, eStructuralFeature); |
| |
| return xsdWildcard; |
| } |
| } |
| |
| protected XSDWildcard buildAttributeWildcard(XSDComplexTypeDefinition xsdComplexTypeDefinition, EStructuralFeature eStructuralFeature) |
| { |
| XSDWildcard xsdWildcard = XSDFactory.eINSTANCE.createXSDWildcard(); |
| xsdWildcard.setStringLexicalNamespaceConstraint |
| (BasicExtendedMetaData.getEncodedWildcards |
| (extendedMetaData.getNamespace(eStructuralFeature.getEContainingClass()), |
| extendedMetaData.getWildcards(eStructuralFeature))); |
| xsdComplexTypeDefinition.setAttributeWildcardContent(xsdWildcard); |
| |
| map(xsdWildcard, eStructuralFeature); |
| |
| createEcoreAnnotation(xsdWildcard, "name", eStructuralFeature.getName()); |
| |
| buildAnnotations(xsdWildcard, eStructuralFeature); |
| |
| return xsdWildcard; |
| } |
| |
| protected XSDSimpleTypeDefinition buildSimpleContent(XSDComplexTypeDefinition xsdComplexTypeDefinition, EStructuralFeature eStructuralFeature) |
| { |
| XSDSchema xsdSchema = xsdComplexTypeDefinition.getSchema(); |
| XSDSimpleTypeDefinition xsdSimpleTypeDefinition = XSDFactory.eINSTANCE.createXSDSimpleTypeDefinition(); |
| EClassifier eType = eStructuralFeature.getEType(); |
| EClassifier referenceType = null; |
| XSDSimpleTypeDefinition baseType; |
| if (eStructuralFeature instanceof EReference) |
| { |
| referenceType = eType; |
| baseType = |
| xsdSchema.getSchemaForSchema().resolveSimpleTypeDefinition |
| (((EReference)eStructuralFeature).isResolveProxies() ? "anyURI" : "IDREF"); |
| handleMultiplicity(xsdSchema, eStructuralFeature, xsdSimpleTypeDefinition, baseType); |
| } |
| else |
| { |
| baseType = xsdComplexTypeDefinition.resolveSimpleTypeDefinitionURI(getURI(eType)); |
| handleImport(xsdSchema, baseType); |
| handleMultiplicity(xsdSchema, eStructuralFeature, xsdSimpleTypeDefinition, baseType); |
| } |
| xsdComplexTypeDefinition.setBaseTypeDefinition(xsdSimpleTypeDefinition.getBaseType()); |
| xsdComplexTypeDefinition.setDerivationMethod(xsdSimpleTypeDefinition.getContents().isEmpty() ? XSDDerivationMethod.EXTENSION_LITERAL : XSDDerivationMethod.RESTRICTION_LITERAL); |
| xsdComplexTypeDefinition.setContent(xsdSimpleTypeDefinition); |
| |
| map(xsdSimpleTypeDefinition, eStructuralFeature); |
| |
| buildAttributeInformation(xsdComplexTypeDefinition, "value", false, referenceType, xsdSimpleTypeDefinition, eStructuralFeature); |
| |
| if (eStructuralFeature instanceof EAttribute && |
| ((EAttribute)eStructuralFeature).isID() && |
| !XSDConstants.isOrIsDerivedFromID(xsdSimpleTypeDefinition)) |
| { |
| createEcoreAnnotation(xsdSimpleTypeDefinition, "id", "true"); |
| } |
| |
| if (eStructuralFeature.eIsSet(EcorePackage.Literals.ETYPED_ELEMENT__EGENERIC_TYPE)) |
| { |
| createEcoreAnnotation(xsdSimpleTypeDefinition, referenceType == null ? "type" : "reference", getGenericType(xsdSchema, eStructuralFeature.getEGenericType())); |
| } |
| |
| return xsdSimpleTypeDefinition; |
| } |
| |
| protected XSDAttributeUse buildAttributeUse(XSDComplexTypeDefinition xsdComplexTypeDefinition, EStructuralFeature eStructuralFeature) |
| { |
| XSDSchema xsdSchema = xsdComplexTypeDefinition.getSchema(); |
| String namespace = extendedMetaData.getNamespace(eStructuralFeature); |
| String name = extendedMetaData.getName(eStructuralFeature); |
| |
| // It must be a ref if it refers to another namespace. |
| // If it refers to this namespace, |
| // it's treated as a ref, |
| // if this feature has the same type as the feature for matching global attribute. |
| // |
| String typeNamespace = extendedMetaData.getNamespace(eStructuralFeature.getEContainingClass()); |
| boolean isRef = namespace != null && !namespace.equals(typeNamespace); |
| if (namespace == null ? typeNamespace == null : namespace.equals(typeNamespace)) |
| { |
| EStructuralFeature globalFeature = extendedMetaData.getAttribute(namespace, name); |
| isRef = globalFeature != null && EcoreUtil.equals(globalFeature.getEGenericType(), eStructuralFeature.getEGenericType()); |
| } |
| |
| XSDAttributeUse xsdAttributeUse = XSDFactory.eINSTANCE.createXSDAttributeUse(); |
| XSDAttributeDeclaration xsdAttributeDeclaration = XSDFactory.eINSTANCE.createXSDAttributeDeclaration(); |
| |
| EClassifier referenceType = null; |
| if (isRef) |
| { |
| XSDAttributeDeclaration referencedXSDAttributeDeclaration = xsdComplexTypeDefinition.resolveAttributeDeclaration(namespace, name); |
| handleImport(xsdSchema, referencedXSDAttributeDeclaration); |
| xsdAttributeDeclaration.setResolvedAttributeDeclaration(referencedXSDAttributeDeclaration); |
| } |
| else |
| { |
| xsdAttributeDeclaration.setName(name); |
| |
| if (namespace != null) |
| { |
| xsdAttributeDeclaration.setForm(XSDForm.QUALIFIED_LITERAL); |
| } |
| |
| EClassifier eType = eStructuralFeature.getEType(); |
| if (eStructuralFeature instanceof EReference) |
| { |
| referenceType = eType; |
| XSDSimpleTypeDefinition xsdSimpleTypeDefinition = |
| xsdSchema.getSchemaForSchema().resolveSimpleTypeDefinition |
| (((EReference)eStructuralFeature).isResolveProxies() ? "anyURI" : "IDREF"); |
| handleMultiplicity(xsdSchema, eStructuralFeature, xsdAttributeDeclaration, xsdSimpleTypeDefinition); |
| } |
| else |
| { |
| XSDSimpleTypeDefinition xsdSimpleTypeDefinition = xsdComplexTypeDefinition.resolveSimpleTypeDefinitionURI(getURI(eType)); |
| handleImport(xsdSchema, xsdSimpleTypeDefinition); |
| handleMultiplicity(xsdSchema, eStructuralFeature, xsdAttributeDeclaration, xsdSimpleTypeDefinition); |
| } |
| } |
| |
| xsdAttributeUse.setContent(xsdAttributeDeclaration); |
| xsdComplexTypeDefinition.getAttributeContents().add(xsdAttributeUse); |
| map(xsdAttributeUse, eStructuralFeature); |
| |
| buildAttributeInformation(xsdComplexTypeDefinition, name, isRef, referenceType, xsdAttributeUse, eStructuralFeature); |
| |
| if (eStructuralFeature instanceof EAttribute && |
| ((EAttribute)eStructuralFeature).isID() && |
| !XSDConstants.isOrIsDerivedFromID(xsdAttributeDeclaration.getTypeDefinition())) |
| { |
| createEcoreAnnotation(xsdAttributeUse, "id", "true"); |
| } |
| |
| if (eStructuralFeature.eIsSet(EcorePackage.Literals.ETYPED_ELEMENT__EGENERIC_TYPE)) |
| { |
| createEcoreAnnotation(xsdAttributeUse, referenceType == null ? "type" : "reference", getGenericType(xsdSchema, eStructuralFeature.getEGenericType())); |
| } |
| |
| return xsdAttributeUse; |
| } |
| |
| protected void buildAttributeInformation |
| (XSDComplexTypeDefinition xsdComplexTypeDefinition, |
| String name, |
| boolean isRef, |
| EClassifier referenceType, |
| XSDComponent xsdComponent, |
| EStructuralFeature eStructuralFeature) |
| { |
| List<EAttribute> eKeys = null; |
| |
| if (referenceType == null && eStructuralFeature.isMany()) |
| { |
| createEcoreAnnotation(xsdComponent, "many", "true"); |
| } |
| |
| if (eStructuralFeature instanceof EReference) |
| { |
| EReference eReference = (EReference)eStructuralFeature; |
| EReference eOpposite = eReference.getEOpposite(); |
| if (eOpposite != null) |
| { |
| createEcoreAnnotation(xsdComponent, "opposite", eOpposite.getName()); |
| } |
| eKeys = eReference.getEKeys(); |
| } |
| |
| if (eKeys != null && !eKeys.isEmpty()) |
| { |
| StringBuilder keys = new StringBuilder(); |
| for (EAttribute eKey : eKeys) |
| { |
| keys.append(eKey.getName()); |
| keys.append(' '); |
| } |
| createEcoreAnnotation(xsdComponent, "keys", keys.toString().trim()); |
| } |
| |
| XSDAttributeUse xsdAttriuteUse = xsdComponent instanceof XSDAttributeUse ? (XSDAttributeUse)xsdComponent : null; |
| |
| boolean canHaveDefault = xsdAttriuteUse != null; |
| if (eStructuralFeature.isRequired()) |
| { |
| if (eStructuralFeature.isTransient() || xsdAttriuteUse == null) |
| { |
| createEcoreAnnotation(xsdComponent, "lowerBound", Integer.toString(eStructuralFeature.getLowerBound())); |
| } |
| else |
| { |
| xsdAttriuteUse.setUse(XSDAttributeUseCategory.REQUIRED_LITERAL); |
| canHaveDefault = false; |
| } |
| } |
| |
| String defaultValue = eStructuralFeature.getDefaultValueLiteral(); |
| if (defaultValue != null) |
| { |
| if (canHaveDefault && xsdAttriuteUse != null) |
| { |
| if (isRef) |
| { |
| xsdAttriuteUse.setConstraint(XSDConstraint.DEFAULT_LITERAL); |
| xsdAttriuteUse.setLexicalValue(transformDefaultValue(xsdAttriuteUse.getAttributeDeclaration().getTypeDefinition(), defaultValue)); |
| } |
| else |
| { |
| XSDAttributeDeclaration xsdAttributeDeclaration = xsdAttriuteUse.getAttributeDeclaration(); |
| xsdAttributeDeclaration.setConstraint(XSDConstraint.DEFAULT_LITERAL); |
| xsdAttributeDeclaration.setLexicalValue(transformDefaultValue(xsdAttributeDeclaration.getTypeDefinition(), defaultValue)); |
| } |
| } |
| else |
| { |
| createEcoreAnnotation(xsdComponent, "default", defaultValue); |
| } |
| } |
| |
| if (eStructuralFeature.isMany()) |
| { |
| if (eStructuralFeature.isUnsettable()) |
| { |
| createEcoreAnnotation(xsdComponent, "unsettable", "true"); |
| } |
| } |
| else if ((eStructuralFeature.getEType().getDefaultValue() != null || eStructuralFeature.getDefaultValueLiteral() != null) != |
| eStructuralFeature.isUnsettable()) |
| { |
| createEcoreAnnotation(xsdComponent, "unsettable", Boolean.toString(eStructuralFeature.isUnsettable())); |
| } |
| |
| String ecoreName = eStructuralFeature.getName(); |
| if (!name.equals(ecoreName) || Character.isUpperCase(ecoreName.charAt(0)) || ecoreName.indexOf('_') != -1) |
| { |
| createEcoreAnnotation(xsdComponent, "name", ecoreName); |
| } |
| |
| if (eStructuralFeature.isMany() && !eStructuralFeature.isOrdered()) |
| { |
| createEcoreAnnotation(xsdComponent, "ordered", "false"); |
| } |
| |
| if (eStructuralFeature.isMany() && eStructuralFeature.isUnique() && eStructuralFeature instanceof EAttribute) |
| { |
| createEcoreAnnotation(xsdComponent, "unique", "true"); |
| } |
| |
| if (!eStructuralFeature.isChangeable()) |
| { |
| createEcoreAnnotation(xsdComponent, "changeable", "false"); |
| } |
| |
| if (extendedMetaData.getGroup(eStructuralFeature) == null) |
| { |
| if (eStructuralFeature.isDerived()) |
| { |
| createEcoreAnnotation(xsdComponent, "derived", "true"); |
| } |
| |
| if (eStructuralFeature.isTransient()) |
| { |
| createEcoreAnnotation(xsdComponent, "transient", "true"); |
| } |
| |
| if (eStructuralFeature.isVolatile()) |
| { |
| createEcoreAnnotation(xsdComponent, "volatile", "true"); |
| } |
| } |
| |
| if (referenceType != null) |
| { |
| XSDTypeDefinition xsdTypeDefinition = xsdComplexTypeDefinition.resolveTypeDefinitionURI(getURI(referenceType)); |
| handleImport(xsdComplexTypeDefinition.getSchema(), xsdTypeDefinition); |
| String prefix = |
| handlePrefix |
| (xsdComplexTypeDefinition.getSchema().getQNamePrefixToNamespaceMap(), |
| referenceType.getEPackage().getNsPrefix(), |
| xsdTypeDefinition.getTargetNamespace()); |
| createEcoreAnnotation(xsdComponent, "reference", prefix + ":" + xsdTypeDefinition.getName()); |
| } |
| |
| if (EcoreUtil.isSuppressedVisibility(eStructuralFeature, EcoreUtil.GET)) |
| { |
| createEcoreAnnotation(xsdComponent, "suppressedGetVisibility", "true"); |
| } |
| if (EcoreUtil.isSuppressedVisibility(eStructuralFeature, EcoreUtil.SET)) |
| { |
| createEcoreAnnotation(xsdComponent, "suppressedSetVisibility", "true"); |
| } |
| if (EcoreUtil.isSuppressedVisibility(eStructuralFeature, EcoreUtil.IS_SET)) |
| { |
| createEcoreAnnotation(xsdComponent, "suppressedIsSetVisibility", "true"); |
| } |
| if (EcoreUtil.isSuppressedVisibility(eStructuralFeature, EcoreUtil.UNSET)) |
| { |
| createEcoreAnnotation(xsdComponent, "suppressedUnsetVisibility", "true"); |
| } |
| |
| buildAnnotations(xsdComponent, eStructuralFeature); |
| } |
| |
| protected void handleMultiplicity |
| (XSDSchema xsdSchema, |
| EStructuralFeature eStructuralFeature, |
| XSDAttributeDeclaration xsdAttributeDeclaration, |
| XSDSimpleTypeDefinition xsdSimpleTypeDefinition) |
| { |
| handleMultiplicity(xsdSchema, eStructuralFeature, (XSDComponent)xsdAttributeDeclaration, xsdSimpleTypeDefinition); |
| } |
| |
| protected void handleMultiplicity |
| (XSDSchema xsdSchema, |
| EStructuralFeature eStructuralFeature, |
| XSDComponent xsdComponent, |
| XSDSimpleTypeDefinition xsdSimpleTypeDefinition) |
| { |
| if (eStructuralFeature.isMany()) |
| { |
| XSDSimpleTypeDefinition xsdListTypeDefinition; |
| if (xsdSimpleTypeDefinition.hasNameAndTargetNamespace("IDREF", defaultXMLSchemaNamespace)) |
| { |
| xsdListTypeDefinition = xsdSchema.getSchemaForSchema().resolveSimpleTypeDefinition("IDREFS"); |
| } |
| else |
| { |
| xsdListTypeDefinition = XSDFactory.eINSTANCE.createXSDSimpleTypeDefinition(); |
| xsdListTypeDefinition.setItemTypeDefinition(xsdSimpleTypeDefinition); |
| } |
| if (eStructuralFeature.getLowerBound() > 1 || eStructuralFeature.getUpperBound() > 1) |
| { |
| XSDSimpleTypeDefinition xsdRestrictedTypeDefinition = XSDFactory.eINSTANCE.createXSDSimpleTypeDefinition(); |
| if (xsdListTypeDefinition.getContainer() == null) |
| { |
| xsdRestrictedTypeDefinition.getContents().add(xsdListTypeDefinition); |
| } |
| else |
| { |
| xsdRestrictedTypeDefinition.setBaseTypeDefinition(xsdListTypeDefinition); |
| } |
| if (eStructuralFeature.getLowerBound() == eStructuralFeature.getUpperBound()) |
| { |
| XSDLengthFacet xsdLengthFacet = XSDFactory.eINSTANCE.createXSDLengthFacet(); |
| xsdLengthFacet.setLexicalValue(Integer.toString(eStructuralFeature.getLowerBound())); |
| xsdRestrictedTypeDefinition.getFacetContents().add(xsdLengthFacet); |
| } |
| else |
| { |
| if (eStructuralFeature.getLowerBound() > 1) |
| { |
| XSDMinLengthFacet xsdMinLengthFacet = XSDFactory.eINSTANCE.createXSDMinLengthFacet(); |
| xsdMinLengthFacet.setLexicalValue(Integer.toString(eStructuralFeature.getLowerBound())); |
| xsdRestrictedTypeDefinition.getFacetContents().add(xsdMinLengthFacet); |
| } |
| if (eStructuralFeature.getUpperBound() > 1) |
| { |
| XSDMaxLengthFacet xsdMaxLengthFacet = XSDFactory.eINSTANCE.createXSDMaxLengthFacet(); |
| xsdMaxLengthFacet.setLexicalValue(Integer.toString(eStructuralFeature.getUpperBound())); |
| xsdRestrictedTypeDefinition.getFacetContents().add(xsdMaxLengthFacet); |
| } |
| } |
| if (xsdComponent instanceof XSDAttributeDeclaration) |
| { |
| ((XSDAttributeDeclaration)xsdComponent).setAnonymousTypeDefinition(xsdRestrictedTypeDefinition); |
| } |
| else |
| { |
| ((XSDSimpleTypeDefinition)xsdComponent).getContents().add(xsdRestrictedTypeDefinition); |
| } |
| } |
| else |
| { |
| if (xsdListTypeDefinition.getContainer() == null) |
| { |
| if (xsdComponent instanceof XSDAttributeDeclaration) |
| { |
| ((XSDAttributeDeclaration)xsdComponent).setAnonymousTypeDefinition(xsdListTypeDefinition); |
| } |
| else |
| { |
| ((XSDSimpleTypeDefinition)xsdComponent).getContents().add(xsdListTypeDefinition); |
| } |
| } |
| else |
| { |
| if (xsdComponent instanceof XSDAttributeDeclaration) |
| { |
| ((XSDAttributeDeclaration)xsdComponent).setTypeDefinition(xsdListTypeDefinition); |
| } |
| else |
| { |
| ((XSDSimpleTypeDefinition)xsdComponent).setBaseTypeDefinition(xsdListTypeDefinition); |
| } |
| } |
| } |
| } |
| else |
| { |
| if (xsdComponent instanceof XSDAttributeDeclaration) |
| { |
| ((XSDAttributeDeclaration)xsdComponent).setTypeDefinition(xsdSimpleTypeDefinition); |
| } |
| else |
| { |
| ((XSDSimpleTypeDefinition)xsdComponent).setBaseTypeDefinition(xsdSimpleTypeDefinition); |
| } |
| } |
| } |
| |
| protected XSDParticle buildElementParticle(XSDComplexTypeDefinition xsdComplexTypeDefinition, EStructuralFeature eStructuralFeature) |
| { |
| String namespace = extendedMetaData.getNamespace(eStructuralFeature); |
| String name = extendedMetaData.getName(eStructuralFeature); |
| |
| // It must be a ref if it refers to another namespace. |
| // If it refers to this namespace, |
| // it's treated as a ref, |
| // if this feature has the same type as the feature for matching global element. |
| // |
| String typeNamespace = extendedMetaData.getNamespace(eStructuralFeature.getEContainingClass()); |
| boolean isRef = namespace != null && !namespace.equals(typeNamespace); |
| if (namespace == null ? typeNamespace == null : namespace.equals(typeNamespace)) |
| { |
| EStructuralFeature globalFeature = extendedMetaData.getElement(namespace, name); |
| isRef = globalFeature != null && EcoreUtil.equals(globalFeature.getEGenericType(), eStructuralFeature.getEGenericType()); |
| } |
| |
| XSDModelGroup xsdModelGroup = findOrCreateModelGroup(xsdComplexTypeDefinition); |
| |
| EStructuralFeature group = extendedMetaData.getGroup(eStructuralFeature); |
| if (group != null) |
| { |
| XSDParticle xsdParticle = (XSDParticle)eModelElementToXSDComponentMap.get(group); |
| if (xsdParticle != null) |
| { |
| xsdModelGroup = (XSDModelGroup)xsdParticle.getContent(); |
| } |
| } |
| |
| XSDElementDeclaration xsdElementDeclaration = XSDFactory.eINSTANCE.createXSDElementDeclaration(); |
| |
| EClassifier referenceType = null; |
| EReference eOpposite = null; |
| List<EAttribute> eKeys = null; |
| EClassifier eType = eStructuralFeature.getEType(); |
| if (isRef) |
| { |
| XSDElementDeclaration referencedXSDElementDeclaration = xsdComplexTypeDefinition.resolveElementDeclaration(namespace, name); |
| handleImport(xsdComplexTypeDefinition.getSchema(), referencedXSDElementDeclaration); |
| xsdElementDeclaration.setResolvedElementDeclaration(referencedXSDElementDeclaration); |
| |
| if (eStructuralFeature instanceof EReference) |
| { |
| EReference eReference = (EReference)eStructuralFeature; |
| eOpposite = eReference.getEOpposite(); |
| eKeys = eReference.getEKeys(); |
| } |
| } |
| else |
| { |
| xsdElementDeclaration.setName(name); |
| if (namespace != null) |
| { |
| xsdElementDeclaration.setForm(XSDForm.QUALIFIED_LITERAL); |
| } |
| |
| XSDTypeDefinition xsdTypeDefinition = |
| xsdComplexTypeDefinition.resolveTypeDefinitionURI(getURI(eType)); |
| |
| String defaultValue = eStructuralFeature.getDefaultValueLiteral(); |
| if (defaultValue != null) |
| { |
| xsdElementDeclaration.setConstraint(XSDConstraint.DEFAULT_LITERAL); |
| xsdElementDeclaration.setLexicalValue(transformDefaultValue((XSDSimpleTypeDefinition)xsdTypeDefinition, defaultValue)); |
| } |
| |
| if (eStructuralFeature instanceof EReference) |
| { |
| EReference eReference = (EReference)eStructuralFeature; |
| eOpposite = eReference.getEOpposite(); |
| eKeys = eReference.getEKeys(); |
| if (!eReference.isContainment() && !eReference.isContainer()) |
| { |
| referenceType = eType; |
| xsdTypeDefinition = |
| xsdComplexTypeDefinition.getSchema().getSchemaForSchema().resolveTypeDefinition |
| (eReference.isResolveProxies() ? "anyURI" : "IDREF"); |
| } |
| } |
| |
| handleImport(xsdComplexTypeDefinition.getSchema(), xsdTypeDefinition); |
| xsdElementDeclaration.setTypeDefinition(xsdTypeDefinition); |
| |
| // If the attribute can have a null value (primitives and enums can't), and |
| // if the attribute can hold many nulls or |
| // it can hold only a single value that is allowed to be null |
| // and it can be considered set when it has the null value... |
| // |
| if (isWrapperType(eType) || |
| (eStructuralFeature instanceof EAttribute && |
| eType.getDefaultValue() == null && |
| (eStructuralFeature.isMany() || |
| (!eStructuralFeature.isRequired() && |
| (eStructuralFeature.getDefaultValueLiteral() != null || eStructuralFeature.isUnsettable()))))) |
| { |
| xsdElementDeclaration.setNillable(true); |
| } |
| } |
| |
| XSDParticle xsdParticle = XSDFactory.eINSTANCE.createXSDParticle(); |
| xsdParticle.setContent(xsdElementDeclaration); |
| |
| xsdModelGroup.getContents().add(xsdParticle); |
| map(xsdParticle, eStructuralFeature); |
| |
| if (eStructuralFeature.isMany()) |
| { |
| if (eStructuralFeature.isUnsettable()) |
| { |
| createEcoreAnnotation(xsdParticle, "unsettable", "true"); |
| } |
| } |
| else if (xsdElementDeclaration.isNillable() ? |
| !eStructuralFeature.isUnsettable() : |
| (eType.getDefaultValue() != null || eStructuralFeature.getDefaultValueLiteral() != null) != |
| eStructuralFeature.isUnsettable()) |
| { |
| createEcoreAnnotation(xsdParticle, "unsettable", Boolean.toString(eStructuralFeature.isUnsettable())); |
| } |
| |
| if (eOpposite != null) |
| { |
| createEcoreAnnotation(xsdParticle, "opposite", eOpposite.getName()); |
| } |
| |
| if (eKeys != null && !eKeys.isEmpty()) |
| { |
| StringBuilder keys = new StringBuilder(); |
| for (EAttribute eKey : eKeys) |
| { |
| keys.append(eKey.getName()); |
| keys.append(' '); |
| } |
| createEcoreAnnotation(xsdParticle, "keys", keys.toString().trim()); |
| } |
| |
| if (group == null) |
| { |
| if (eStructuralFeature.isTransient() && !xsdComplexTypeDefinition.isMixed()) |
| { |
| xsdParticle.setMinOccurs(0); |
| if (eStructuralFeature.getLowerBound() != 0) |
| { |
| createEcoreAnnotation(xsdParticle, "lowerBound", Integer.toString(eStructuralFeature.getLowerBound())); |
| } |
| } |
| else if (eStructuralFeature.getLowerBound() != 1) |
| { |
| xsdParticle.setMinOccurs(eStructuralFeature.getLowerBound()); |
| } |
| |
| if (eStructuralFeature.getUpperBound() != 1) |
| { |
| xsdParticle.setMaxOccurs(eStructuralFeature.getUpperBound()); |
| } |
| } |
| else |
| { |
| if (eStructuralFeature.isTransient() && !xsdComplexTypeDefinition.isMixed()) |
| { |
| xsdParticle.setMinOccurs(0); |
| if (eStructuralFeature.getLowerBound() != 0) |
| { |
| createEcoreAnnotation(xsdParticle, "lowerBound", Integer.toString(eStructuralFeature.getLowerBound())); |
| } |
| } |
| else if (eStructuralFeature.getLowerBound() != 1) |
| { |
| createEcoreAnnotation(xsdParticle, "lowerBound", Integer.toString(eStructuralFeature.getLowerBound())); |
| } |
| |
| if (eStructuralFeature.getUpperBound() != 1) |
| { |
| createEcoreAnnotation(xsdParticle, "upperBound", Integer.toString(eStructuralFeature.getUpperBound())); |
| } |
| } |
| |
| String ecoreName = eStructuralFeature.getName(); |
| if (!name.equals(ecoreName) || Character.isUpperCase(ecoreName.charAt(0)) || ecoreName.indexOf('_') != -1) |
| { |
| createEcoreAnnotation(xsdParticle, "name", ecoreName); |
| } |
| |
| if (eStructuralFeature.isMany() && !eStructuralFeature.isOrdered()) |
| { |
| createEcoreAnnotation(xsdParticle, "ordered", "false"); |
| } |
| |
| if (eStructuralFeature.isMany() && eStructuralFeature.isUnique() && eStructuralFeature instanceof EAttribute) |
| { |
| createEcoreAnnotation(xsdParticle, "unique", "true"); |
| } |
| |
| if (!eStructuralFeature.isChangeable()) |
| { |
| createEcoreAnnotation(xsdParticle, "changeable", "false"); |
| } |
| |
| if (extendedMetaData.getContentKind(eStructuralFeature.getEContainingClass()) != ExtendedMetaData.MIXED_CONTENT && |
| extendedMetaData.getGroup(eStructuralFeature) == null) |
| { |
| if (eStructuralFeature.isDerived()) |
| { |
| createEcoreAnnotation(xsdParticle, "derived", "true"); |
| } |
| |
| if (eStructuralFeature.isTransient()) |
| { |
| createEcoreAnnotation(xsdParticle, "transient", "true"); |
| } |
| |
| if (eStructuralFeature.isVolatile()) |
| { |
| createEcoreAnnotation(xsdParticle, "volatile", "true"); |
| } |
| } |
| |
| if (eStructuralFeature instanceof EReference && |
| ((EReference)eStructuralFeature).isResolveProxies() && |
| ((EReference)eStructuralFeature).isContainment()) |
| { |
| createEcoreAnnotation(xsdParticle, "resolveProxies", "true"); |
| } |
| |
| if (eStructuralFeature.eIsSet(EcorePackage.Literals.ETYPED_ELEMENT__EGENERIC_TYPE)) |
| { |
| createEcoreAnnotation(xsdParticle, referenceType == null ? "type" : "reference", getGenericType(xsdComplexTypeDefinition.getSchema(), eStructuralFeature.getEGenericType())); |
| } |
| else if (referenceType != null) |
| { |
| XSDTypeDefinition xsdTypeDefinition = xsdComplexTypeDefinition.resolveTypeDefinitionURI(getURI(referenceType)); |
| handleImport(xsdComplexTypeDefinition.getSchema(), xsdTypeDefinition); |
| String prefix = |
| handlePrefix |
| (xsdComplexTypeDefinition.getSchema().getQNamePrefixToNamespaceMap(), |
| referenceType.getEPackage().getNsPrefix(), |
| xsdTypeDefinition.getTargetNamespace()); |
| createEcoreAnnotation(xsdElementDeclaration, "reference", prefix + ":" + xsdTypeDefinition.getName()); |
| } |
| |
| if (EcoreUtil.isSuppressedVisibility(eStructuralFeature, EcoreUtil.GET)) |
| { |
| createEcoreAnnotation(xsdElementDeclaration, "suppressedGetVisibility", "true"); |
| } |
| if (EcoreUtil.isSuppressedVisibility(eStructuralFeature, EcoreUtil.SET)) |
| { |
| createEcoreAnnotation(xsdElementDeclaration, "suppressedSetVisibility", "true"); |
| } |
| if (EcoreUtil.isSuppressedVisibility(eStructuralFeature, EcoreUtil.IS_SET)) |
| { |
| createEcoreAnnotation(xsdElementDeclaration, "suppressedIsSetVisibility", "true"); |
| } |
| if (EcoreUtil.isSuppressedVisibility(eStructuralFeature, EcoreUtil.UNSET)) |
| { |
| createEcoreAnnotation(xsdElementDeclaration, "suppressedUnsetVisibility", "true"); |
| } |
| |
| if (eStructuralFeature instanceof EAttribute && |
| ((EAttribute)eStructuralFeature).isID() && |
| xsdElementDeclaration.getTypeDefinition() instanceof XSDSimpleTypeDefinition && |
| !XSDConstants.isOrIsDerivedFromID((XSDSimpleTypeDefinition)xsdElementDeclaration.getTypeDefinition())) |
| { |
| createEcoreAnnotation(xsdParticle, "id", "true"); |
| } |
| |
| buildAnnotations(xsdParticle, eStructuralFeature); |
| |
| return xsdParticle; |
| } |
| |
| protected XSDModelGroup findOrCreateModelGroup(XSDComplexTypeDefinition xsdComplexTypeDefinition) |
| { |
| if (xsdComplexTypeDefinition.getContent() == null) |
| { |
| return buildModelGroup(xsdComplexTypeDefinition); |
| } |
| else |
| { |
| XSDParticle xsdParticle = (XSDParticle)xsdComplexTypeDefinition.getContent(); |
| return (XSDModelGroup)xsdParticle.getContent(); |
| } |
| } |
| |
| protected XSDModelGroup buildModelGroup(XSDComplexTypeDefinition xsdComplexTypeDefinition) |
| { |
| XSDModelGroup xsdModelGroup = XSDFactory.eINSTANCE.createXSDModelGroup(); |
| xsdModelGroup.setCompositor(XSDCompositor.SEQUENCE_LITERAL); |
| XSDParticle xsdParticle = XSDFactory.eINSTANCE.createXSDParticle(); |
| xsdParticle.setContent(xsdModelGroup); |
| xsdComplexTypeDefinition.setContent(xsdParticle); |
| return xsdModelGroup; |
| } |
| |
| protected boolean isWrapperType(EClassifier eClassifier) |
| { |
| String name = extendedMetaData.getName(eClassifier); |
| return name.endsWith(":Object") && !EcorePackage.eNS_URI.equals(extendedMetaData.getNamespace(eClassifier)); |
| } |
| |
| protected String getURI(EClassifier eClassifier) |
| { |
| String namespace = extendedMetaData.getNamespace(eClassifier); |
| String name = extendedMetaData.getName(eClassifier); |
| if (XMLTypePackage.eNS_URI.equals(namespace)) |
| { |
| namespace = defaultXMLSchemaNamespace; |
| if (name.endsWith(":Object")) |
| { |
| name = name.substring(0, name.length() - 7); |
| } |
| } |
| else if (EcorePackage.eNS_URI.equals(namespace)) |
| { |
| if ("EObject".equals(name)) |
| { |
| namespace = defaultXMLSchemaNamespace; |
| name = "anyType"; |
| } |
| else if (name.endsWith(":Object")) |
| { |
| name = eClassifier.getName(); |
| } |
| } |
| else if (name.endsWith(":Object")) |
| { |
| name = name.substring(0, name.length() - 7); |
| } |
| String result = |
| namespace == null ? |
| name : |
| namespace + "#" + name; |
| return result; |
| } |
| |
| protected String getURI(EStructuralFeature eStructuralFeature) |
| { |
| String namespace = extendedMetaData.getNamespace(eStructuralFeature); |
| String name = extendedMetaData.getName(eStructuralFeature); |
| if (XMLTypePackage.eNS_URI.equals(namespace)) |
| { |
| namespace = defaultXMLSchemaNamespace; |
| } |
| String result = |
| namespace == null ? |
| name : |
| namespace + "#" + name; |
| return result; |
| } |
| |
| protected String getGenericType(XSDSchema xsdSchema, EGenericType eGenericType) |
| { |
| Map<String, String> qNamePrefixToNamespaceMap = xsdSchema.getQNamePrefixToNamespaceMap(); |
| StringBuilder result = new StringBuilder(); |
| EClassifier eClassifier = eGenericType.getEClassifier(); |
| if (eClassifier != null) |
| { |
| XSDTypeDefinition type = xsdSchema.resolveTypeDefinitionURI(getURI(eClassifier)); |
| handleImport(xsdSchema, type); |
| String prefix = |
| handlePrefix |
| (qNamePrefixToNamespaceMap, |
| eClassifier.getEPackage().getNsPrefix(), |
| type.getTargetNamespace()); |
| result.append(prefix); |
| result.append(':'); |
| result.append(type.getName()); |
| List<EGenericType> eTypeArguments = eGenericType.getETypeArguments(); |
| if (!eTypeArguments.isEmpty()) |
| { |
| result.append('{'); |
| for (Iterator<EGenericType> i = eTypeArguments.iterator(); i.hasNext(); ) |
| { |
| result.append(getGenericType(xsdSchema, i.next())); |
| if (i.hasNext()) |
| { |
| result.append(", "); |
| } |
| } |
| result.append('}'); |
| } |
| } |
| else |
| { |
| ETypeParameter eTypeParameter = eGenericType.getETypeParameter(); |
| if (eTypeParameter != null) |
| { |
| result.append(eTypeParameter.getName()); |
| } |
| else |
| { |
| result.append('?'); |
| EGenericType eUpperBound = eGenericType.getEUpperBound(); |
| if (eUpperBound != null) |
| { |
| result.append(" extends "); |
| result.append(getGenericType(xsdSchema, eUpperBound)); |
| } |
| else |
| { |
| EGenericType eLowerBound = eGenericType.getELowerBound(); |
| if (eLowerBound != null) |
| { |
| result.append(" super "); |
| result.append(getGenericType(xsdSchema, eLowerBound)); |
| } |
| } |
| } |
| } |
| return result.toString(); |
| } |
| |
| protected void createEcoreAnnotation(XSDComponent xsdComponent, String key, String value) |
| { |
| Element element = xsdComponent.getElement(); |
| if (element != null) |
| { |
| createEcoreAnnotation(xsdComponent.getSchema().getQNamePrefixToNamespaceMap(), element, key, value); |
| } |
| } |
| |
| protected void createEcoreAnnotation(Map<String, String> qNamePrefixToNamespaceMap, Element element, String key, String value) |
| { |
| String ecorePrefix = handlePrefix(qNamePrefixToNamespaceMap, "ecore", EcorePackage.eNS_URI); |
| element.setAttributeNS(EcorePackage.eNS_URI, ecorePrefix + ':' + key, value); |
| } |
| |
| protected void createAnnotation(XSDComponent xsdComponent, String namespace, String key, String value) |
| { |
| Element element = xsdComponent.getElement(); |
| if (element != null) |
| { |
| createAnnotation(xsdComponent.getSchema().getQNamePrefixToNamespaceMap(), element, namespace, key, value); |
| } |
| } |
| |
| protected void createAnnotation(Map<String, String> qNamePrefixToNamespaceMap, Element element, String namespace, String key, String value) |
| { |
| String prefix = handlePrefix(qNamePrefixToNamespaceMap, qualifiedPackageName(namespace), namespace); |
| element.setAttributeNS(namespace, prefix + ':' + key, value); |
| } |
| |
| protected void handleImport(XSDSchema xsdSchema, XSDNamedComponent xsdNamedComponent) |
| { |
| String namespace = xsdNamedComponent.getTargetNamespace(); |
| |
| if (!defaultXMLSchemaNamespace.equals(namespace) && |
| (namespace == null ? xsdSchema.getTargetNamespace() != null : !namespace.equals(xsdSchema.getTargetNamespace()))) |
| { |
| for (Object content : xsdSchema.getContents()) |
| { |
| if (content instanceof XSDImport) |
| { |
| XSDImport xsdImport = (XSDImport)content; |
| if (namespace == null ? xsdImport.getNamespace() == null : namespace.equals(xsdImport.getNamespace())) |
| { |
| return; |
| } |
| } |
| else if (!(content instanceof XSDAnnotation)) |
| { |
| break; |
| } |
| } |
| |
| XSDImport xsdImport = XSDFactory.eINSTANCE.createXSDImport(); |
| xsdImport.setNamespace(namespace); |
| |
| EPackage ePackage = extendedMetaData.getPackage(namespace); |
| if (ePackage != null) |
| { |
| handlePrefix(xsdSchema.getQNamePrefixToNamespaceMap(), ePackage.getNsPrefix(), namespace); |
| //xsdImport.setSchemaLocation(ePackage.eResource().getURI().trimFileExtension().appendFileExtension("xsd").toString()); |
| xsdImport.setSchemaLocation(ePackage.getNsURI()); |
| } |
| |
| xsdSchema.getContents().add(0, xsdImport); |
| } |
| } |
| |
| protected String handlePrefix(Map<String, String> namespaces, String preferredPrefix, String namespace) |
| { |
| if (XMLNamespacePackage.eNS_URI.equals(namespace)) |
| { |
| return "xml"; |
| } |
| |
| String value = namespaces.get(preferredPrefix); |
| if (namespace == null ? value == null : namespace.equals(value)) |
| { |
| return preferredPrefix; |
| } |
| |
| // If there is a non-null value, i.e., if the prefix is in use, see if there is already a prefix chosen. |
| // |
| if (value != null || defaultXMLSchemaNamespace.equals(namespace)) |
| { |
| for (Map.Entry<String, String> entry : namespaces.entrySet()) |
| { |
| if (namespace == null ? entry.getValue() == null : namespace.equals(entry.getValue())) |
| { |
| // Return the previously assigned prefix; it may not match the preferred one. |
| // |
| return entry.getKey(); |
| } |
| } |
| } |
| |
| String uniquePrefix = preferredPrefix; |
| for (int i = 0; namespaces.containsKey(uniquePrefix); ++i) |
| { |
| uniquePrefix = preferredPrefix + "_" + i; |
| } |
| namespaces.put("".equals(uniquePrefix) ? null : uniquePrefix, namespace); |
| return uniquePrefix; |
| } |
| |
| protected static final String GEN_MODEL_PACKAGE_NS_URI = "http://www.eclipse.org/emf/2002/GenModel"; |
| |
| protected boolean isIgnoredAnnotationSource(String sourceURI) |
| { |
| return |
| EcorePackage.eNS_URI.equals(sourceURI) || |
| ExtendedMetaData.ANNOTATION_URI.equals(sourceURI) || |
| GEN_MODEL_PACKAGE_NS_URI.equals(sourceURI); |
| } |
| |
| protected void buildAnnotations(XSDComponent xsdComponent, EModelElement eModelElement) |
| { |
| for (EAnnotation eAnnotation : eModelElement.getEAnnotations()) |
| { |
| String source = eAnnotation.getSource(); |
| if (!isIgnoredAnnotationSource(source)) |
| { |
| XSDAnnotation xsdAnnotation = null; |
| for (Map.Entry<String, String> entry : eAnnotation.getDetails().entrySet()) |
| { |
| String key = entry.getKey(); |
| String value = entry.getValue(); |
| if (key != null && value.indexOf('\n') == -1 && value.indexOf('\r') == -1) |
| { |
| createAnnotation(xsdComponent, source, key, value); |
| } |
| else |
| { |
| if (xsdAnnotation == null) |
| { |
| xsdAnnotation = buildAnnotation(xsdComponent, eModelElement); |
| } |
| if (xsdAnnotation != null) |
| { |
| Element applicationInformation = xsdAnnotation.createApplicationInformation(source); |
| if (key != null) |
| { |
| createEcoreAnnotation(xsdComponent.getSchema().getQNamePrefixToNamespaceMap(), applicationInformation, "key", key); |
| } |
| if (value != null) |
| { |
| applicationInformation.appendChild(xsdAnnotation.getSchema().getDocument().createTextNode(value)); |
| } |
| xsdAnnotation.getElement().appendChild(applicationInformation); |
| } |
| } |
| } |
| } |
| } |
| |
| String documentation = EcoreUtil.getDocumentation(eModelElement); |
| if (documentation != null) |
| { |
| XSDAnnotation xsdAnnotation = buildAnnotation(xsdComponent, eModelElement); |
| if (xsdAnnotation != null) |
| { |
| createUserInfo(xsdAnnotation, documentation); |
| } |
| } |
| } |
| |
| protected XSDAnnotation buildAnnotation(XSDConcreteComponent xsdComponent, EModelElement eModelElement) |
| { |
| XSDAnnotation xsdAnnotation = null; |
| if (xsdComponent instanceof XSDAttributeUse) |
| { |
| xsdComponent = ((XSDAttributeUse)xsdComponent).getContent(); |
| } |
| else if (xsdComponent instanceof XSDParticle) |
| { |
| xsdComponent = ((XSDParticle)xsdComponent).getContent(); |
| } |
| |
| if (xsdComponent instanceof XSDSchema) |
| { |
| ((XSDSchema)xsdComponent).getContents().add(0, xsdAnnotation = XSDFactory.eINSTANCE.createXSDAnnotation()); |
| } |
| else if (xsdComponent instanceof XSDTypeDefinition) |
| { |
| XSDTypeDefinition xsdTypeDefinition = ((XSDTypeDefinition)xsdComponent); |
| if ((xsdAnnotation = xsdTypeDefinition.getAnnotation()) == null) |
| { |
| xsdTypeDefinition.setAnnotation(xsdAnnotation = XSDFactory.eINSTANCE.createXSDAnnotation()); |
| } |
| } |
| else if (xsdComponent instanceof XSDFacet) |
| { |
| XSDFacet xsdFacet = ((XSDFacet)xsdComponent); |
| if ((xsdAnnotation = xsdFacet.getAnnotation()) == null) |
| { |
| xsdFacet.setAnnotation(xsdAnnotation = XSDFactory.eINSTANCE.createXSDAnnotation()); |
| } |
| } |
| else if (xsdComponent instanceof XSDElementDeclaration) |
| { |
| XSDElementDeclaration xsdElementDeclaration = ((XSDElementDeclaration)xsdComponent); |
| if ((xsdAnnotation = xsdElementDeclaration.getAnnotation()) == null) |
| { |
| xsdElementDeclaration.setAnnotation(xsdAnnotation = XSDFactory.eINSTANCE.createXSDAnnotation()); |
| } |
| } |
| else if (xsdComponent instanceof XSDAttributeDeclaration) |
| { |
| XSDAttributeDeclaration xsdAttributeDeclaration = ((XSDAttributeDeclaration)xsdComponent); |
| if ((xsdAnnotation = xsdAttributeDeclaration.getAnnotation()) == null) |
| { |
| xsdAttributeDeclaration.setAnnotation(xsdAnnotation = XSDFactory.eINSTANCE.createXSDAnnotation()); |
| } |
| } |
| |
| return xsdAnnotation; |
| } |
| |
| protected void createUserInfo(XSDAnnotation xsdAnnotation, String documentation) |
| { |
| Element userInformation = xsdAnnotation.createUserInformation(null); |
| |
| // Try to parse the documentation and use the parsed version if it's successful. |
| // |
| XSDParser xsdParser = new XSDParser(null); |
| xsdParser.parseString("<documentation>" + documentation + "</documentation>"); |
| Document document = xsdParser.getDocument(); |
| if (xsdParser.getDiagnostics().isEmpty() && document.getDocumentElement().getFirstChild() != null) |
| { |
| Document xsdDocument = xsdAnnotation.getSchema().getDocument(); |
| for (Node node = document.getDocumentElement().getFirstChild(); node != null; node = node.getNextSibling()) |
| { |
| userInformation.appendChild(xsdDocument.importNode(node, true)); |
| } |
| } |
| else |
| { |
| userInformation.appendChild(xsdAnnotation.getSchema().getDocument().createTextNode(documentation)); |
| } |
| |
| xsdAnnotation.getElement().appendChild(userInformation); |
| } |
| |
| protected void buildAnnotation(EModelElement eModelElement, Element parent) |
| { |
| Document document = parent.getOwnerDocument(); |
| for (EAnnotation eAnnotation : eModelElement.getEAnnotations()) |
| { |
| String source = eAnnotation.getSource(); |
| if (!isIgnoredAnnotationSource(source)) |
| { |
| Element annotation = document.createElementNS(null, "annotation"); |
| if (source != null) |
| { |
| annotation.setAttributeNS(null, "source", source); |
| } |
| for (Map.Entry<String, String> entry : eAnnotation.getDetails()) |
| { |
| String key = entry.getKey(); |
| String value = entry.getValue(); |
| Element detail = document.createElementNS(null, "detail"); |
| if (key != null) |
| { |
| detail.setAttributeNS(null, "key", key); |
| } |
| if (value != null) |
| { |
| detail.appendChild(document.createTextNode(value)); |
| } |
| annotation.appendChild(detail); |
| } |
| parent.appendChild(annotation); |
| } |
| else if (GEN_MODEL_PACKAGE_NS_URI.equals(source) && eAnnotation.getDetails().containsKey("documentation")) |
| { |
| String documentation = EcoreUtil.getDocumentation(eModelElement); |
| if (documentation != null) |
| { |
| Element annotation = document.createElementNS(null, "annotation"); |
| annotation.setAttributeNS(null, "source", GEN_MODEL_PACKAGE_NS_URI); |
| Element detail = document.createElementNS(null, "detail"); |
| detail.setAttributeNS(null, "key", "documentation"); |
| detail.appendChild(document.createTextNode(documentation)); |
| annotation.appendChild(detail); |
| parent.appendChild(annotation); |
| } |
| } |
| } |
| } |
| } |