blob: d9a01e82dd84d4359885915f2a5a015e8c146053 [file] [log] [blame]
/**
* <copyright>
*
* Copyright (c) 2010 E.D.Willink 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:
* E.D.Willink - initial API and implementation
*
* </copyright>
*
* $Id: OCLinEcore2Ecore.java,v 1.6 2010/05/23 18:58:05 ewillink Exp $
*/
package org.eclipse.ocl.examples.xtext.oclinecore.resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.EMap;
import org.eclipse.emf.common.util.URI;
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.ENamedElement;
import org.eclipse.emf.ecore.EObject;
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.ETypedElement;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreSwitch;
import org.eclipse.emf.ecore.xmi.XMIException;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.emf.ecore.xmi.impl.EcoreResourceFactoryImpl;
import org.eclipse.ocl.ecore.delegate.InvocationBehavior;
import org.eclipse.ocl.ecore.delegate.OCLDelegateDomain;
import org.eclipse.ocl.ecore.delegate.SettingBehavior;
import org.eclipse.ocl.ecore.delegate.ValidationBehavior;
import org.eclipse.ocl.examples.xtext.base.baseCST.AnnotationElementCS;
import org.eclipse.ocl.examples.xtext.base.baseCST.AttributeCSRef;
import org.eclipse.ocl.examples.xtext.base.baseCST.DetailCS;
import org.eclipse.ocl.examples.xtext.base.baseCST.BaseCSTPackage;
import org.eclipse.ocl.examples.xtext.base.baseCST.EnumLiteralCS;
import org.eclipse.ocl.examples.xtext.base.baseCST.ModelElementCS;
import org.eclipse.ocl.examples.xtext.base.baseCST.ModelElementCSRef;
import org.eclipse.ocl.examples.xtext.base.baseCST.NamedElementCS;
import org.eclipse.ocl.examples.xtext.base.baseCST.ParameterCS;
import org.eclipse.ocl.examples.xtext.base.baseCST.PrimitiveTypeRefCS;
import org.eclipse.ocl.examples.xtext.base.baseCST.QualifiedTypeRefCS;
import org.eclipse.ocl.examples.xtext.base.baseCST.ReferenceCSRef;
import org.eclipse.ocl.examples.xtext.base.baseCST.TypeCS;
import org.eclipse.ocl.examples.xtext.base.baseCST.TypeParameterCS;
import org.eclipse.ocl.examples.xtext.base.baseCST.TypeRefCS;
import org.eclipse.ocl.examples.xtext.base.baseCST.TypedElementCS;
import org.eclipse.ocl.examples.xtext.base.baseCST.TypedTypeRefCS;
import org.eclipse.ocl.examples.xtext.base.baseCST.WildcardTypeRefCS;
import org.eclipse.ocl.examples.xtext.base.baseCST.util.BaseCSTSwitch;
import org.eclipse.ocl.examples.xtext.base.util.ElementUtil;
import org.eclipse.ocl.examples.xtext.essentialocl.essentialOCLCST.ExpCS;
import org.eclipse.ocl.examples.xtext.oclinecore.oclinEcoreCST.AnnotationCS;
import org.eclipse.ocl.examples.xtext.oclinecore.oclinEcoreCST.ConstraintCS;
import org.eclipse.ocl.examples.xtext.oclinecore.oclinEcoreCST.DataTypeCS;
import org.eclipse.ocl.examples.xtext.oclinecore.oclinEcoreCST.DataTypeOrEnumCS;
import org.eclipse.ocl.examples.xtext.oclinecore.oclinEcoreCST.DocumentationCS;
import org.eclipse.ocl.examples.xtext.oclinecore.oclinEcoreCST.EnumCS;
import org.eclipse.ocl.examples.xtext.oclinecore.oclinEcoreCST.OCLinEcoreAttributeCS;
import org.eclipse.ocl.examples.xtext.oclinecore.oclinEcoreCST.OCLinEcoreCSTPackage;
import org.eclipse.ocl.examples.xtext.oclinecore.oclinEcoreCST.OCLinEcoreClassCS;
import org.eclipse.ocl.examples.xtext.oclinecore.oclinEcoreCST.OCLinEcoreClassifierCS;
import org.eclipse.ocl.examples.xtext.oclinecore.oclinEcoreCST.OCLinEcoreDocumentCS;
import org.eclipse.ocl.examples.xtext.oclinecore.oclinEcoreCST.OCLinEcoreOperationCS;
import org.eclipse.ocl.examples.xtext.oclinecore.oclinEcoreCST.OCLinEcorePackageCS;
import org.eclipse.ocl.examples.xtext.oclinecore.oclinEcoreCST.OCLinEcoreReferenceCS;
import org.eclipse.ocl.examples.xtext.oclinecore.oclinEcoreCST.OCLinEcoreStructuralFeatureCS;
import org.eclipse.ocl.examples.xtext.oclinecore.oclinEcoreCST.util.OCLinEcoreCSTSwitch;
import org.eclipse.xtext.parsetree.CompositeNode;
public class OCLinEcore2Ecore extends AbstractConversion
{
/**
* Mapping of all created CS elements to the resulting E elements.
*/
private Map<ModelElementCS, EObject> createMap = new HashMap<ModelElementCS, EObject>();
/**
* Mapping of all E elements created during pass 1 that require further work
* with respect to the corresponding CS element in pass 2.
*/
private Map<EObject, ModelElementCS> deferMap = new HashMap<EObject, ModelElementCS>();
private List<Resource.Diagnostic> errors = null;
protected final OCLinEcoreCSTSwitch<EObject> pass1 = new OCLinEcoreCSTSwitch<EObject>()
{
protected final BaseCSTSwitch<EObject> emofPass1 = new BaseCSTSwitch<EObject>()
{
@Override
public EObject caseEnumLiteralCS(EnumLiteralCS csEnumLiteral) {
EEnumLiteral eEnumLiteral = EcoreFactory.eINSTANCE.createEEnumLiteral();
setMapping(csEnumLiteral, eEnumLiteral);
for (AnnotationElementCS csAnnotation : csEnumLiteral.getAnnotations()) {
if ((csAnnotation instanceof AnnotationCS)
&& (EcorePackage.eNS_URI.equals(((AnnotationCS)csAnnotation).getIdSource()))) {
for (DetailCS csDetail : ((AnnotationCS)csAnnotation).getDetails()) {
String name = csDetail.getIdName();
if ("literal".equals(name)) {
eEnumLiteral.setLiteral(csDetail.getValue());
}
else {
error("Unsupported namespace detail " + name + " in pass1");
}
}
}
else {
EAnnotation eObject = (EAnnotation) doSwitch(csAnnotation);
eEnumLiteral.getEAnnotations().add(eObject);
}
}
eEnumLiteral.setName(csEnumLiteral.getName());
eEnumLiteral.setValue(csEnumLiteral.getValue());
return eEnumLiteral;
}
@Override
public EParameter caseParameterCS(ParameterCS csParameter) {
EParameter eParameter = EcoreFactory.eINSTANCE.createEParameter();
copyTypedElement(eParameter, csParameter);
return eParameter;
}
@Override
public EObject caseQualifiedTypeRefCS(QualifiedTypeRefCS csQualifiedTypeRef) {
return doSwitch(csQualifiedTypeRef.getElement());
}
@Override
public EObject caseTypeParameterCS(TypeParameterCS csTypeParameter) {
ETypeParameter eTypeParameter = EcoreFactory.eINSTANCE.createETypeParameter();
copyNamedElement(eTypeParameter, csTypeParameter);
doSwitchAll(eTypeParameter.getEAnnotations(), csTypeParameter.getAnnotations());
// FIXME super ..
doSwitchAll(eTypeParameter.getEBounds(), csTypeParameter.getExtends());
return eTypeParameter;
}
@Override
public EGenericType caseTypedTypeRefCS(TypedTypeRefCS csTypeRef) {
EGenericType eGenericType = EcoreFactory.eINSTANCE.createEGenericType();
deferMap.put(eGenericType, csTypeRef); // Defer eGenericType.getEType()
doSwitchAll(eGenericType.getETypeArguments(), csTypeRef.getTypeArguments());
return eGenericType;
}
@Override
public EGenericType caseWildcardTypeRefCS(WildcardTypeRefCS csTypeRef) {
EGenericType eGenericType = EcoreFactory.eINSTANCE.createEGenericType();
// doSwitchAll(eGenericType.getETypeArguments(), csTypeRef.getExtends());
// doSwitchAll(eGenericType.getETypeArguments(), csTypeRef.getSuper());
return eGenericType;
}
};
@Override
public EObject caseAnnotationCS(AnnotationCS csAnnotation) {
EAnnotation eAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
copyDetails(eAnnotation, csAnnotation);
String source = csAnnotation.getIdSource();
if (source == null) {
source = csAnnotation.getStringSource();
}
eAnnotation.setSource(source);
doSwitchAll(eAnnotation.getContents(), csAnnotation.getContents());
if (!csAnnotation.getReferences().isEmpty()) {
deferMap.put(eAnnotation, csAnnotation);
}
return eAnnotation;
}
@Override
public EObject caseConstraintCS(ConstraintCS csConstraint) {
ExpCS exprValue = csConstraint.getExprValue();
String exprString = null;
if (exprValue == null) {
exprString = csConstraint.getExprString();
}
else {
CompositeNode parserNode = ElementUtil.getParserNode(exprValue);
if (parserNode != null) {
exprString = parserNode.serialize();
for (int i = 0; i < exprString.length(); i++) {
if (exprString.charAt(i) != ' ') {
exprString = exprString.substring(i);
break;
}
}
}
}
if (exprString == null) { // null for a manually coded requirement
return csConstraint;
}
EAnnotation oclAnnotation = getOCLAnnotation(csConstraint);
String stereotype = csConstraint.getStereotype();
String name = csConstraint.getName();
if ("invariant".equals(stereotype)) {
oclAnnotation.getDetails().put(name, exprString);
}
else if ("derivation".equals(stereotype)) {
oclAnnotation.getDetails().put(SettingBehavior.DERIVATION_CONSTRAINT_KEY, exprString);
}
else if ("initial".equals(stereotype)) {
oclAnnotation.getDetails().put(SettingBehavior.INITIAL_CONSTRAINT_KEY, exprString);
}
else if ("body".equals(stereotype)) {
String key = name != null ? "body_" + name : InvocationBehavior.BODY_CONSTRAINT_KEY;
oclAnnotation.getDetails().put(key, exprString);
}
else if ("precondition".equals(stereotype)) {
oclAnnotation.getDetails().put("pre_" + name, exprString);
}
else if ("postcondition".equals(stereotype)) {
oclAnnotation.getDetails().put("post_" + name, exprString);
}
else {
error("Unsupported " + csConstraint);
}
return csConstraint; // A non-null value
}
@Override
public EObject caseDataTypeCS(DataTypeCS csDataType) {
EDataType eDataType = EcoreFactory.eINSTANCE.createEDataType();
copyDataTypeOrEnum(eDataType, csDataType);
return eDataType;
}
@Override
public EObject caseDocumentationCS(DocumentationCS csDocumentation) {
EAnnotation eAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
copyDetails(eAnnotation, csDocumentation);
eAnnotation.setSource(GEN_MODEL_PACKAGE_NS_URI);
String documentation = basicGet(csDocumentation, OCLinEcoreCSTPackage.Literals.DOCUMENTATION_CS__VALUE, String.class);
if (documentation != null) {
eAnnotation.getDetails().put("documentation", documentation);
}
return eAnnotation;
}
@Override
public EObject caseEnumCS(EnumCS csEnum) {
EEnum eEnum = EcoreFactory.eINSTANCE.createEEnum();
copyDataTypeOrEnum(eEnum, csEnum);
doSwitchAll(eEnum.getELiterals(), csEnum.getLiterals());
return eEnum;
}
@Override
public EObject caseOCLinEcoreAttributeCS(OCLinEcoreAttributeCS csAttribute) {
EAttribute eAttribute = EcoreFactory.eINSTANCE.createEAttribute();
copyStructuralFeature(eAttribute, csAttribute);
EList<String> qualifiers = csAttribute.getQualifiers();
setAttribute(eAttribute, EcorePackage.Literals.EATTRIBUTE__ID, qualifiers, "id", "!id");
return eAttribute;
}
@Override
public EObject caseOCLinEcoreClassCS(OCLinEcoreClassCS csClass) {
EClass eClass = EcoreFactory.eINSTANCE.createEClass();
copyClassifier(eClass, csClass);
EList<String> qualifiers = csClass.getQualifiers();
setAttribute(eClass, EcorePackage.Literals.ECLASS__ABSTRACT, qualifiers, "abstract", "!abstract");
setAttribute(eClass, EcorePackage.Literals.ECLASS__INTERFACE, qualifiers, "interface", "!interface");
deferMap.put(eClass, csClass);
doSwitchAll(eClass.getEGenericSuperTypes(), csClass.getSuperTypes());
doSwitchAll(eClass.getEOperations(), csClass.getOperations());
doSwitchAll(eClass.getEStructuralFeatures(), csClass.getStructuralFeatures());
return eClass;
}
@Override
public EObject caseOCLinEcoreOperationCS(OCLinEcoreOperationCS csOperation) {
EOperation eOperation = EcoreFactory.eINSTANCE.createEOperation();
copyTypedElement(eOperation, csOperation);
doSwitchAll(eOperation.getEParameters(), csOperation.getParameters());
doSwitchAll(eOperation.getETypeParameters(), csOperation.getTypeParameters());
doSwitchAll(eOperation.getEGenericExceptions(), csOperation.getExceptions());
for (ConstraintCS csConstraint : csOperation.getConstraints()) {
doSwitch(csConstraint); // Results are inserted directly
}
return eOperation;
}
@Override
public EObject caseOCLinEcorePackageCS(OCLinEcorePackageCS csPackage) {
EPackage ePackage = EcoreFactory.eINSTANCE.createEPackage();
copyNamedElement(ePackage, csPackage);
doSwitchAll(ePackage.getEAnnotations(), csPackage.getAnnotations());
deferMap.put(ePackage, csPackage); // Defer delegate annotation analysis
String prefix = basicGet(csPackage, BaseCSTPackage.Literals.PACKAGE_CS__PREFIX, String.class);
String uri = basicGet(csPackage, BaseCSTPackage.Literals.PACKAGE_CS__URI, String.class);
if ((prefix != null) && (uri != null)) {
ePackage.setNsPrefix(prefix);
ePackage.setNsURI(uri);
}
doSwitchAll(ePackage.getESubpackages(), csPackage.getSubpackages());
doSwitchAll(ePackage.getEClassifiers(), csPackage.getClassifiers());
return ePackage;
}
@Override
public EReference caseOCLinEcoreReferenceCS(OCLinEcoreReferenceCS csReference) {
EReference eReference = EcoreFactory.eINSTANCE.createEReference();
copyStructuralFeature(eReference, csReference);
if ((csReference.getOpposite() != null) || !csReference.getKeys().isEmpty()) {
deferMap.put(eReference, csReference);
}
EList<String> qualifiers = csReference.getQualifiers();
setAttribute(eReference, EcorePackage.Literals.EREFERENCE__CONTAINMENT, qualifiers, "composes", "!composes");
setAttribute(eReference, EcorePackage.Literals.EREFERENCE__RESOLVE_PROXIES, qualifiers, "resolve", "!resolve");
return eReference;
}
protected void copyClassifier(EClassifier eClassifier, OCLinEcoreClassifierCS csClassifier) {
copyNamedElement(eClassifier, csClassifier);
doSwitchAll(eClassifier.getEAnnotations(), csClassifier.getAnnotations());
if (csClassifier.eIsSet(OCLinEcoreCSTPackage.Literals.OC_LIN_ECORE_CLASSIFIER_CS__INSTANCE_CLASS_NAME)) {
eClassifier.setInstanceClassName(csClassifier.getInstanceClassName());
}
doSwitchAll(eClassifier.getETypeParameters(), csClassifier.getTypeParameters());
StringBuffer s = null;
for (ConstraintCS csConstraint : csClassifier.getConstraints()) {
doSwitch(csConstraint); // Results are inserted directly
if (s == null) {
s = new StringBuffer();
}
else {
s.append(" ");
}
s.append(csConstraint.getName());
}
EAnnotation eAnnotation = eClassifier.getEAnnotation(EcorePackage.eNS_URI);
if (s != null) {
if (eAnnotation == null) {
eAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
eAnnotation.setSource(EcorePackage.eNS_URI);
eClassifier.getEAnnotations().add(0, eAnnotation);
}
eAnnotation.getDetails().put("constraints", s.toString());
}
else {
eClassifier.getEAnnotations().remove(eAnnotation);
}
}
protected void copyDataTypeOrEnum(EDataType eDataType, DataTypeOrEnumCS csDataType) {
copyClassifier(eDataType, csDataType);
EList<String> qualifiers = csDataType.getQualifiers();
setAttribute(eDataType, EcorePackage.Literals.EDATA_TYPE__SERIALIZABLE, qualifiers, "serializable", "!serializable");
}
protected void copyDetails(EAnnotation eAnnotation, AnnotationElementCS csAnnotationElement) {
copyModelElement(eAnnotation, csAnnotationElement);
doSwitchAll(eAnnotation.getEAnnotations(), csAnnotationElement.getAnnotations());
for (DetailCS csDetail : csAnnotationElement.getDetails()) {
String name = csDetail.getIdName();
if (name == null) {
name = csDetail.getStringName();
}
eAnnotation.getDetails().put(name, csDetail.getValue());
}
}
protected void copyModelElement(EModelElement eModelElement, ModelElementCS csModelElement) {
setMapping(csModelElement, eModelElement);
}
protected void copyNamedElement(ENamedElement eNamedElement, NamedElementCS csNamedElement) {
copyModelElement(eNamedElement, csNamedElement);
eNamedElement.setName(csNamedElement.getName());
}
protected void copyStructuralFeature(EStructuralFeature eStructuralFeature, OCLinEcoreStructuralFeatureCS csStructuralFeature) {
copyTypedElement(eStructuralFeature, csStructuralFeature);
List<String> qualifiers = csStructuralFeature.getQualifiers();
setAttribute(eStructuralFeature, EcorePackage.Literals.ESTRUCTURAL_FEATURE__DERIVED, qualifiers, "derived", "!derived");
setAttribute(eStructuralFeature, EcorePackage.Literals.ESTRUCTURAL_FEATURE__CHANGEABLE, qualifiers, "!readonly", "readonly");
setAttribute(eStructuralFeature, EcorePackage.Literals.ESTRUCTURAL_FEATURE__TRANSIENT, qualifiers, "transient", "!transient");
setAttribute(eStructuralFeature, EcorePackage.Literals.ESTRUCTURAL_FEATURE__UNSETTABLE, qualifiers, "unsettable", "!unsettable");
setAttribute(eStructuralFeature, EcorePackage.Literals.ESTRUCTURAL_FEATURE__VOLATILE, qualifiers, "volatile", "!volatile");
if (csStructuralFeature.eIsSet(OCLinEcoreCSTPackage.Literals.OC_LIN_ECORE_STRUCTURAL_FEATURE_CS__DEFAULT_VALUE_LITERAL)) {
eStructuralFeature.setDefaultValueLiteral(csStructuralFeature.getDefaultValueLiteral());
}
for (ConstraintCS csConstraint : csStructuralFeature.getConstraints()) {
doSwitch(csConstraint); // Results are inserted directly
}
}
protected void copyTypedElement(ETypedElement eTypedElement, TypedElementCS csTypedElement) {
copyNamedElement(eTypedElement, csTypedElement);
doSwitchAll(eTypedElement.getEAnnotations(), csTypedElement.getAnnotations());
TypeRefCS type = csTypedElement.getType();
if (type != null) {
if (type instanceof PrimitiveTypeRefCS) {
String name = ((PrimitiveTypeRefCS)type).getName();
if ("Boolean".equals(name)) {
eTypedElement.setEType(EcorePackage.Literals.EBOOLEAN);
}
else if ("Integer".equals(name)) {
eTypedElement.setEType(EcorePackage.Literals.EBIG_INTEGER);
}
else if ("Real".equals(name)) {
eTypedElement.setEType(EcorePackage.Literals.EBIG_DECIMAL);
}
else if ("String".equals(name)) {
eTypedElement.setEType(EcorePackage.Literals.ESTRING);
}
else if ("UnlimitedNatural".equals(name)) {
eTypedElement.setEType(EcorePackage.Literals.EBIG_INTEGER);
}
else {
error("Unsupported primitive type '" + name + "' in pass1");
}
}
else {
eTypedElement.setEGenericType((EGenericType) doSwitch(type));
}
}
String multiplicity = csTypedElement.getMultiplicity();
if (multiplicity != null) {
if ("?".equals(multiplicity)) {
eTypedElement.setLowerBound(0);
eTypedElement.setUpperBound(1);
}
else if ("*".equals(multiplicity)) {
eTypedElement.setLowerBound(0);
eTypedElement.setUpperBound(-1);
}
else if ("+".equals(multiplicity)) {
eTypedElement.setLowerBound(1);
eTypedElement.setUpperBound(-1);
}
else {
error("Unsupported multiplicity " + multiplicity + " in pass1");
}
}
else {
int lower = csTypedElement.getLower();
eTypedElement.setLowerBound(lower);
if (!csTypedElement.eIsSet(BaseCSTPackage.Literals.TYPED_ELEMENT_CS__UPPER)) {
eTypedElement.setUpperBound(lower != 0 ? lower : 1);
}
else {
eTypedElement.setUpperBound(csTypedElement.getUpper());
}
}
EList<String> qualifiers = csTypedElement.getQualifiers();
setAttribute(eTypedElement, EcorePackage.Literals.ETYPED_ELEMENT__ORDERED, qualifiers, "ordered", "!ordered");
setAttribute(eTypedElement, EcorePackage.Literals.ETYPED_ELEMENT__UNIQUE, qualifiers, "unique", "!unique");
}
@Override
public EObject defaultCase(EObject object) {
error("Unsupported " + object + " in pass1");
doSwitch(object);
return null;
}
@Override
public EObject doSwitch(EObject eObject) {
EPackage ePackage = eObject.eClass().getEPackage();
if (ePackage == BaseCSTPackage.eINSTANCE) {
return emofPass1.doSwitch(eObject);
}
else {
return super.doSwitch(eObject);
}
}
public <T extends EObject> void doSwitchAll(List<T> eObjects, EList<? extends ModelElementCS> csObjects) {
for (EObject csObject : csObjects) {
@SuppressWarnings("unchecked")
T eObject = (T) doSwitch(csObject);
if (eObject != null) {
eObjects.add(eObject);
}
// else error
}
}
protected EAnnotation getOCLAnnotation(ConstraintCS csConstraint) {
ModelElementCS csModelElement = (ModelElementCS) csConstraint.eContainer();
EModelElement eModelElement = (EModelElement) createMap.get(csModelElement);
EAnnotation oclAnnotation = eModelElement.getEAnnotation(OCLDelegateDomain.OCL_DELEGATE_URI);
if (oclAnnotation == null) {
oclAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
oclAnnotation.setSource(OCLDelegateDomain.OCL_DELEGATE_URI);
eModelElement.getEAnnotations().add(oclAnnotation);
}
return oclAnnotation;
}
protected void setAttribute(EObject eObject, EAttribute eAttribute, List<String> qualifiers, String trueName, String falseName) {
boolean isTrue = qualifiers.contains(trueName);
boolean isFalse = qualifiers.contains(falseName);
if (isTrue && isFalse) {
error("Conflicting " + trueName + " and " + falseName);
}
else if (isTrue || isFalse) {
eObject.eSet(eAttribute, isTrue);
}
}
protected void setMapping(ModelElementCS csModelElement, EModelElement eModelElement) {
createMap.put(csModelElement, eModelElement);
String originalXmiId = csModelElement.getOriginalXmiId();
if (originalXmiId != null) {
eResource.setID(eModelElement, originalXmiId);
}
}
};
protected final EcoreSwitch<Object> pass2 = new EcoreSwitch<Object>()
{
@Override
public Object caseEAnnotation(EAnnotation eAnnotation) {
AnnotationCS csAnnotation = (AnnotationCS) deferMap.get(eAnnotation);
for (ModelElementCSRef csReference : csAnnotation.getReferences()) {
EObject eObject = createMap.get(csReference.getRef());
if (eObject != null) {
eAnnotation.getReferences().add(eObject);
}
}
return null;
}
@Override
public Object caseEGenericType(EGenericType eGenericType) {
TypedTypeRefCS csTypeRef = (TypedTypeRefCS) deferMap.get(eGenericType);
TypeCS typeRef = csTypeRef.getType();
if (typeRef != null) {
EModelElement eType = (EModelElement) createMap.get(typeRef);
if (eType == null) {
eGenericType.setEClassifier((EClassifier) ((ModelElementCS)typeRef).getOriginalObject());
}
else if (eType instanceof EClassifier) {
eGenericType.setEClassifier((EClassifier) eType);
}
else if (eType instanceof ETypeParameter) {
eGenericType.setETypeParameter((ETypeParameter) eType);
}
}
return null;
}
//
// Add the EPackage delegate annotations, if any delegates in use
//
@Override
public Object caseEPackage(EPackage ePackage) {
boolean needsDelegates = false;
for (EClassifier eClassifier : ePackage.getEClassifiers()) {
EAnnotation classifierAnnotation = eClassifier.getEAnnotation(OCLDelegateDomain.OCL_DELEGATE_URI);
if ((classifierAnnotation != null) && !classifierAnnotation.getDetails().isEmpty()) {
needsDelegates = true;
break;
}
if (eClassifier instanceof EClass) {
EClass eClass = (EClass) eClassifier;
for (EStructuralFeature eFeature : eClass.getEStructuralFeatures()) {
EAnnotation featureAnnotation = eFeature.getEAnnotation(OCLDelegateDomain.OCL_DELEGATE_URI);
if ((featureAnnotation != null) && !featureAnnotation.getDetails().isEmpty()) {
needsDelegates = true;
break;
}
}
if (needsDelegates) {
break;
}
for (EOperation eOperation : eClass.getEOperations()) {
EAnnotation operationAnnotation = eOperation.getEAnnotation(OCLDelegateDomain.OCL_DELEGATE_URI);
if ((operationAnnotation != null) && !operationAnnotation.getDetails().isEmpty()) {
needsDelegates = true;
break;
}
}
if (needsDelegates) {
break;
}
}
}
if (needsDelegates) {
EAnnotation packageAnnotation = ePackage.getEAnnotation(EcorePackage.eNS_URI);
if (packageAnnotation == null) {
packageAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
packageAnnotation.setSource(EcorePackage.eNS_URI);
ePackage.getEAnnotations().add(packageAnnotation);
}
EMap<String, String> details = packageAnnotation.getDetails();
details.put(InvocationBehavior.NAME, OCLDelegateDomain.OCL_DELEGATE_URI);
details.put(SettingBehavior.NAME, OCLDelegateDomain.OCL_DELEGATE_URI);
details.put(ValidationBehavior.NAME, OCLDelegateDomain.OCL_DELEGATE_URI);
}
return null;
}
@Override
public Object caseEReference(EReference eReference) {
OCLinEcoreReferenceCS csReference = (OCLinEcoreReferenceCS) deferMap.get(eReference);
ReferenceCSRef csOpposite = csReference.getOpposite();
if (csOpposite != null) {
EReference eOpposite = (EReference) createMap.get(csOpposite.getRef());
if (eOpposite != null) {
eReference.setEOpposite(eOpposite);
}
}
for (AttributeCSRef csKey : csReference.getKeys()) {
EAttribute eAttribute = (EAttribute) createMap.get(csKey.getRef());
if (eAttribute != null) {
eReference.getEKeys().add(eAttribute);
}
}
return null;
}
@Override
public Object caseETypeParameter(ETypeParameter eTypeParameter) {
TypeParameterCS csTypeParameter = (TypeParameterCS) deferMap.get(eTypeParameter);
/* ClassifierRef classifierRef = csTypedElement.getType();
if (classifierRef != null) {
EClassifier eClassifier = resolveClassifierRef(classifierRef);
if (eClassifier != null) {
eTypedElement.setEType(eClassifier);
}
} */
return null;
}
};
protected final Resource csResource;
protected final XMLResource eResource;
public OCLinEcore2Ecore(ResourceSet resourceSet, Resource csResource, URI ecoreURI) {
super(resourceSet);
this.csResource = csResource;
this.eResource = (XMLResource) new EcoreResourceFactoryImpl().createResource(ecoreURI);
}
protected EObject convert(EObject csObject) {
EObject eObject = pass1.doSwitch(csObject);
for (EObject eKey : deferMap.keySet()) {
pass2.doSwitch(eKey);
}
return eObject;
}
protected List<EObject> convertAll(List<? extends EObject> csObjects) {
List<EObject> eObjects = new ArrayList<EObject>();
for (EObject csObject : csObjects) {
eObjects.add(pass1.doSwitch(csObject));
}
for (EObject eKey : deferMap.keySet()) {
pass2.doSwitch(eKey);
}
return eObjects;
}
protected void error(String message) {
if (errors == null) {
errors = new ArrayList<Resource.Diagnostic>();
}
errors.add(new XMIException(message));
}
public Resource exportToEcore() {
OCLinEcoreDocumentCS document = (OCLinEcoreDocumentCS) csResource.getContents().get(0);
Collection<? extends EObject> ecoreContents = convertAll(document.getPackages());
eResource.getContents().addAll(ecoreContents);
if (errors != null) {
eResource.getErrors().addAll(errors);
}
return eResource;
}
}