blob: 097c879a77e3100c8e914bdcff5a849bf33540ac [file] [log] [blame]
/**
* 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(facet, literal);
}
}
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);
}
}
}
}
}