blob: 142d0ede4714b98f7002c913f1032addc805d204 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010, 2016 Willink Transformations 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
* E.D.Willink (Obeo) - Bug 416287 - tuple-valued constraints
*******************************************************************************/
package org.eclipse.ocl.pivot.internal.ecore.as2es;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
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.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.util.EcoreUtil;
import org.eclipse.emf.ecore.xmi.impl.EMOFExtendedMetaData;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.Annotation;
import org.eclipse.ocl.pivot.AnyType;
import org.eclipse.ocl.pivot.CollectionType;
import org.eclipse.ocl.pivot.Constraint;
import org.eclipse.ocl.pivot.DataType;
import org.eclipse.ocl.pivot.Detail;
import org.eclipse.ocl.pivot.Element;
import org.eclipse.ocl.pivot.Enumeration;
import org.eclipse.ocl.pivot.EnumerationLiteral;
import org.eclipse.ocl.pivot.Import;
import org.eclipse.ocl.pivot.LanguageExpression;
import org.eclipse.ocl.pivot.Model;
import org.eclipse.ocl.pivot.NamedElement;
import org.eclipse.ocl.pivot.Namespace;
import org.eclipse.ocl.pivot.Operation;
import org.eclipse.ocl.pivot.Package;
import org.eclipse.ocl.pivot.Parameter;
import org.eclipse.ocl.pivot.PivotPackage;
import org.eclipse.ocl.pivot.PrimitiveType;
import org.eclipse.ocl.pivot.Property;
import org.eclipse.ocl.pivot.TemplateParameter;
import org.eclipse.ocl.pivot.TemplateSignature;
import org.eclipse.ocl.pivot.TemplateableElement;
import org.eclipse.ocl.pivot.Type;
import org.eclipse.ocl.pivot.TypedElement;
import org.eclipse.ocl.pivot.internal.delegate.DelegateInstaller;
import org.eclipse.ocl.pivot.internal.manager.Orphanage;
import org.eclipse.ocl.pivot.internal.utilities.PivotConstantsInternal;
import org.eclipse.ocl.pivot.internal.utilities.PivotUtilInternal;
import org.eclipse.ocl.pivot.util.AbstractExtendingVisitor;
import org.eclipse.ocl.pivot.util.Visitable;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
import org.eclipse.ocl.pivot.utilities.PivotConstants;
import org.eclipse.ocl.pivot.utilities.StringUtil;
import org.eclipse.ocl.pivot.utilities.ValueUtil;
import org.eclipse.ocl.pivot.values.Bag;
import org.eclipse.ocl.pivot.values.IntegerValue;
import org.eclipse.ocl.pivot.values.OrderedSet;
import org.eclipse.ocl.pivot.values.UnlimitedNaturalValue;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
public class AS2EcoreDeclarationVisitor
extends AbstractExtendingVisitor<Object, AS2Ecore>
{
public static final @NonNull DuplicateConstraintsFilter duplicateConstraintsFilter = new DuplicateConstraintsFilter();
public static final @NonNull DuplicateOperationsFilter duplicateOperationsFilter = new DuplicateOperationsFilter();
public static final @NonNull DuplicatePropertiesFilter duplicatePropertiesFilter = new DuplicatePropertiesFilter();
public static final @NonNull NonDuplicateConstraintsFilter nonDuplicateConstraintsFilter = new NonDuplicateConstraintsFilter();
public static final @NonNull NonDuplicateOperationsFilter nonDuplicateOperationsFilter = new NonDuplicateOperationsFilter();
public static final @NonNull NonDuplicatePropertiesFilter nonDuplicatePropertiesFilter = new NonDuplicatePropertiesFilter();
protected static class DuplicateConstraintsFilter implements Predicate<Constraint>
{
@Override
public boolean apply(@Nullable Constraint aConstraint) {
if (aConstraint == null) {
return false;
}
if (aConstraint.getRedefinedConstraints().size() == 0) {
return false;
}
return true;
}
}
protected static class DuplicateOperationsFilter implements Predicate<Operation>
{
@Override
public boolean apply(@Nullable Operation anOperation) {
if (anOperation == null) {
return false;
}
if (anOperation.getRedefinedOperations().size() == 0) {
return false;
}
if ("containingActivity".equals(anOperation.getName()) && "ActivityNode".equals(anOperation.getOwningClass().getName())) {
return false; // FIXME Bug 405061 workaround
}
return true;
// return (anOperation != null) && (anOperation.getRedefinedOperation().size() != 0);
}
}
protected static class DuplicatePropertiesFilter implements Predicate<Property>
{
@Override
public boolean apply(@Nullable Property aProperty) {
if (aProperty == null) {
return false;
}
if (aProperty.getRedefinedProperties().size() == 0) {
return false;
}
return ClassUtil.safeEquals(aProperty.getName(), aProperty.getRedefinedProperties().get(0).getName());
}
}
protected static class NonDuplicateConstraintsFilter implements Predicate<Constraint>
{
@Override
public boolean apply(@Nullable Constraint aConstraint) {
if (aConstraint == null) {
return false;
}
if (aConstraint.getRedefinedConstraints().size() == 0) {
return true;
}
return false;
}
}
protected static class NonDuplicateOperationsFilter implements Predicate<Operation>
{
@Override
public boolean apply(@Nullable Operation anOperation) {
if (anOperation == null) {
return false;
}
if (anOperation.getRedefinedOperations().size() == 0) {
return true;
}
if ("containingActivity".equals(anOperation.getName()) && "ActivityNode".equals(anOperation.getOwningClass().getName())) {
return true; // FIXME Bug 405061 workaround
}
return false;
// return (anOperation != null) && (anOperation.getRedefinedOperation().size() == 0);
}
}
protected static class NonDuplicatePropertiesFilter implements Predicate<Property>
{
@Override
public boolean apply(@Nullable Property aProperty) {
if (aProperty == null) {
return false;
}
if (aProperty.getRedefinedProperties().size() == 0) {
return true;
}
return !ClassUtil.safeEquals(aProperty.getName(), aProperty.getRedefinedProperties().get(0).getName());
// return (aProperty != null) && (aProperty.getRedefinedProperty().size() == 0);
}
}
protected final @NonNull DelegateInstaller delegateInstaller;
public AS2EcoreDeclarationVisitor(@NonNull AS2Ecore context) {
super(context);
this.delegateInstaller = context.getDelegateInstaller();
}
protected void copyClassifier(@NonNull EClassifier eClassifier, org.eclipse.ocl.pivot.@NonNull Class pivotType) {
copyNamedElement(eClassifier, pivotType);
@SuppressWarnings("null")@NonNull List<ETypeParameter> eTypeParameters = eClassifier.getETypeParameters();
copyTemplateSignature(eTypeParameters, pivotType);
if (pivotType.eIsSet(PivotPackage.Literals.CLASS__INSTANCE_CLASS_NAME)) {
eClassifier.setInstanceClassName(pivotType.getInstanceClassName());
}
else {
eClassifier.eUnset(EcorePackage.Literals.ECLASSIFIER__INSTANCE_CLASS_NAME);
}
// visitAll(eClassifier.getETypeParameters(), pivotType.getTypeParameters());
delegateInstaller.installDelegates(eClassifier, pivotType);
for (Constraint pivotInvariant : pivotType.getOwnedInvariants()) {
if (!pivotInvariant.isIsCallable()) {
safeVisit(pivotInvariant); // Results are inserted directly
}
}
}
protected @Nullable EAnnotation copyConstraint(@NonNull EModelElement eModelElement, @NonNull Constraint pivotConstraint) {
EAnnotation eAnnotation = delegateInstaller.createConstraintDelegate(eModelElement, pivotConstraint, context.getEcoreURI());
if (eAnnotation != null) {
if (eModelElement instanceof EOperation) {
AS2Ecore.copyAnnotationComments(eAnnotation, pivotConstraint);
}
else {
AS2Ecore.copyComments(eAnnotation, pivotConstraint);
}
}
return eAnnotation;
}
protected void copyDataTypeOrEnum(@NonNull EDataType eDataType, @NonNull DataType pivotDataType) {
copyClassifier(eDataType, pivotDataType);
eDataType.setSerializable(pivotDataType.isIsSerializable());
}
protected void copyDetails(@NonNull EAnnotation eAnnotation, @NonNull Annotation pivotAnnotation) {
copyModelElement(eAnnotation, pivotAnnotation);
@SuppressWarnings("null")@NonNull List<EAnnotation> eAnnotations = eAnnotation.getEAnnotations();
safeVisitAll(eAnnotations, pivotAnnotation.getOwnedAnnotations());
for (Detail pivotDetail : pivotAnnotation.getOwnedDetails()) {
String name = pivotDetail.getName();
String value = StringUtil.splice(pivotDetail.getValues(), "");
eAnnotation.getDetails().put(name, value);
}
}
protected void copyModelElement(@NonNull EModelElement eModelElement, @NonNull Element pivotModelElement) {
context.putCreated(pivotModelElement, eModelElement);
AS2Ecore.copyComments(eModelElement, pivotModelElement);
}
protected void copyNamedElement(@NonNull ENamedElement eNamedElement, @NonNull NamedElement pivotNamedElement) {
copyModelElement(eNamedElement, pivotNamedElement);
String name = pivotNamedElement.getName();
if ("containingActivity".equals(name)) { // FIXME Bug 405061 workaround
EObject eContainer = pivotNamedElement.eContainer();
if ((eContainer instanceof Type) && "ActivityNode".equals(((Type)eContainer).getName())) {
name = "ActivityNode_" + name;
}
}
else if ("inActivity".equals(name)) { // FIXME Bug 420330 workaround
EObject eContainer = pivotNamedElement.eContainer();
if ((eContainer instanceof Type) && "StructuredActivityNode".equals(((Type)eContainer).getName())) {
name = "activity";
}
}
eNamedElement.setName(name);
@SuppressWarnings("null")@NonNull List<EAnnotation> eAnnotations = eNamedElement.getEAnnotations();
safeVisitAll(eAnnotations, pivotNamedElement.getOwnedAnnotations());
}
protected void copyTemplateSignature(@NonNull List<ETypeParameter> eTypeParameters, TemplateableElement pivotElement) {
TemplateSignature templateSignature = pivotElement.getOwnedSignature();
if (templateSignature != null) {
List<TemplateParameter> parameters = templateSignature.getOwnedParameters();
safeVisitAll(eTypeParameters, parameters);
}
}
protected void copyTypedElement(@NonNull ETypedElement eTypedElement, @NonNull TypedElement pivotTypedElement) {
copyNamedElement(eTypedElement, pivotTypedElement);
context.defer(pivotTypedElement); // Defer type/multiplicity setting
}
protected @Nullable EAnnotation createOppositeEAnnotation(@NonNull Property property) {
String lower = null;
String ordered = null;
String unique = null;
String upper = null;
IntegerValue lowerValue;
UnlimitedNaturalValue upperValue;
Type propertyType = property.getType();
Type type;
if (propertyType instanceof CollectionType) {
CollectionType collectionType = (CollectionType)propertyType;
type = collectionType.getElementType();
lowerValue = collectionType.getLowerValue();
upperValue = collectionType.getUpperValue();
if (collectionType.isOrdered() != PivotConstantsInternal.DEFAULT_IMPLICIT_OPPOSITE_ORDERED) {
ordered = Boolean.toString(collectionType.isOrdered());
}
if (collectionType.isUnique() != PivotConstantsInternal.DEFAULT_IMPLICIT_OPPOSITE_UNIQUE) {
unique = Boolean.toString(collectionType.isUnique());
}
if (!PivotConstantsInternal.DEFAULT_IMPLICIT_OPPOSITE_LOWER_VALUE.equals(lowerValue)) {
lower = lowerValue.toString();
}
if (!PivotConstantsInternal.DEFAULT_IMPLICIT_OPPOSITE_UPPER_VALUE.equals(upperValue)) {
upper = upperValue.toString();
}
}
else {
type = propertyType;
lowerValue = property.isIsRequired() ? ValueUtil.ONE_VALUE : ValueUtil.ZERO_VALUE;
upperValue = ValueUtil.UNLIMITED_ONE_VALUE;
if (!ValueUtil.ZERO_VALUE.equals(lowerValue)) {
lower = lowerValue.toString();
}
if (!ValueUtil.UNLIMITED_ONE_VALUE.equals(upperValue)) {
upper = upperValue.toString();
}
}
String name = property.getName();
if (name.equals(type.getName()) && (lower == null) && (ordered == null) && (unique == null) && (upper == null)) {
return null;
}
lower = null;
ordered = null;
unique = null;
upper = null;
if (propertyType instanceof CollectionType) {
CollectionType collectionType = (CollectionType)propertyType;
if (collectionType.isOrdered() != PivotConstantsInternal.ANNOTATED_IMPLICIT_OPPOSITE_ORDERED) {
ordered = Boolean.toString(collectionType.isOrdered());
}
if (collectionType.isUnique() != PivotConstantsInternal.ANNOTATED_IMPLICIT_OPPOSITE_UNIQUE) {
unique = Boolean.toString(collectionType.isUnique());
}
}
if (!PivotConstantsInternal.ANNOTATED_IMPLICIT_OPPOSITE_LOWER_VALUE.equals(lowerValue)) {
lower = lowerValue.toString();
}
if (!PivotConstantsInternal.ANNOTATED_IMPLICIT_OPPOSITE_UPPER_VALUE.equals(upperValue)) {
upper = upperValue.toString();
}
EAnnotation eAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
eAnnotation.setSource(EMOFExtendedMetaData.EMOF_PROPERTY_OPPOSITE_ROLE_NAME_ANNOTATION_SOURCE);
EMap<String, String> details = eAnnotation.getDetails();
details.put(EMOFExtendedMetaData.EMOF_COMMENT_BODY, name);
if (lower != null) {
details.put("lower", lower);
}
if (ordered != null) {
details.put("ordered", ordered);
}
if (unique != null) {
details.put("unique", unique);
}
if (upper != null) {
details.put("upper", upper);
}
return eAnnotation;
}
public <T extends EObject> void safeVisitAll(@NonNull List<T> eObjects, @NonNull Iterable<? extends Element> pivotObjects) {
for (Element pivotObject : pivotObjects) {
@SuppressWarnings("unchecked")
T eObject = (T) safeVisit(pivotObject);
if (eObject != null) {
eObjects.add(eObject);
}
// else error
}
}
@Override
public EObject visiting(@NonNull Visitable visitable) {
throw new IllegalArgumentException("Unsupported " + visitable.eClass().getName() + " for AS2Ecore Declaration pass");
}
@Override
public EObject visitAnnotation(@NonNull Annotation pivotAnnotation) {
@SuppressWarnings("null")
@NonNull EAnnotation eAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
copyDetails(eAnnotation, pivotAnnotation);
eAnnotation.setSource(pivotAnnotation.getName());
@SuppressWarnings("null")@NonNull List<EObject> contents = eAnnotation.getContents();
safeVisitAll(contents, pivotAnnotation.getOwnedContents());
if (!pivotAnnotation.getReferences().isEmpty()) {
context.defer(pivotAnnotation);
}
return eAnnotation;
}
@Override
public EObject visitAnyType(@NonNull AnyType pivotAnyType) {
if (pivotAnyType.getOwnedBindings().size() > 0) {
return null;
}
@SuppressWarnings("null")
@NonNull EClass eClass = EcoreFactory.eINSTANCE.createEClass();
copyClassifier(eClass, pivotAnyType);
Class<?> instanceClass = null;
String name = pivotAnyType.getName();
if ("OclAny".equals(name)) {
instanceClass = Object.class;
}
eClass.setInstanceClass(instanceClass);
eClass.setAbstract(true);
eClass.setInterface(true);
return eClass;
}
@Override
public EObject visitClass(org.eclipse.ocl.pivot.@NonNull Class pivotClass) {
if (pivotClass.getOwnedBindings().size() > 0) {
return null;
}
@SuppressWarnings("null")
@NonNull EClass eClass = EcoreFactory.eINSTANCE.createEClass();
copyClassifier(eClass, pivotClass);
Class<?> instanceClass = null;
boolean isAbstract = pivotClass.isIsAbstract();
boolean isInterface = pivotClass.isIsInterface();
String className = pivotClass.getName();
if ("OclComparable".equals(className)) {
instanceClass = Object.class;
isAbstract = true;
isInterface = true;
}
else if ("OclElement".equals(className)) {
instanceClass = Object.class;
isAbstract = true;
isInterface = true;
}
else if ("OclInvalid".equals(className)) {
instanceClass = Object.class;
isAbstract = true;
isInterface = true;
}
else if ("OclLambda".equals(className)) {
instanceClass = Object.class;
isAbstract = true;
isInterface = true;
}
else if ("OclMessage".equals(className)) {
instanceClass = Object.class;
isAbstract = true;
isInterface = true;
}
// else if ("OclSelf".equals(className)) {
// instanceClass = Object.class;
// isAbstract = true;
// isInterface = true;
// }
else if ("OclState".equals(className)) {
instanceClass = Object.class;
isAbstract = true;
isInterface = true;
}
else if ("OclSummable".equals(className)) {
instanceClass = Object.class;
isAbstract = true;
isInterface = true;
}
else if ("OclTuple".equals(className)) {
instanceClass = Object.class;
isAbstract = true;
isInterface = true;
}
else if ("OclType".equals(className)) {
instanceClass = Object.class;
isAbstract = true;
isInterface = true;
}
else if ("OclVoid".equals(className)) {
instanceClass = Object.class;
isAbstract = true;
isInterface = true;
}
eClass.setAbstract(isAbstract);
eClass.setInterface(isInterface);
if (instanceClass != null) {
eClass.setInstanceClass(instanceClass);
}
context.defer(pivotClass); // Defer superclass resolution
@SuppressWarnings("null")@NonNull List<EOperation> eOperations = eClass.getEOperations();
@NonNull Iterable<Constraint> nonDuplicateConstraints = Iterables.filter(pivotClass.getOwnedInvariants(), nonDuplicateConstraintsFilter);
// safeVisitAll(eOperations, nonDuplicateConstraints);
@NonNull Iterable<Operation> nonDuplicateOperations = Iterables.filter(pivotClass.getOwnedOperations(), nonDuplicateOperationsFilter);
safeVisitAll(eOperations, nonDuplicateOperations);
@SuppressWarnings("null")@NonNull List<EStructuralFeature> eStructuralFeatures = eClass.getEStructuralFeatures();
@NonNull Iterable<Property> nonDuplicateProperties = Iterables.filter(pivotClass.getOwnedProperties(), nonDuplicatePropertiesFilter);
safeVisitAll(eStructuralFeatures, nonDuplicateProperties);
Map<String, Object> options = context.getOptions();
String invariantPrefix = AS2Ecore.getInvariantPrefix(options);
for (Constraint pivotInvariant : nonDuplicateConstraints) {
if (pivotInvariant.isIsCallable()) {
String name = pivotInvariant.getName();
if (invariantPrefix != null) {
name = invariantPrefix + name;
}
EOperation eOperation = AS2Ecore.createConstraintEOperation(pivotInvariant, name, options);
eOperations.add(eOperation);
context.putCreated(pivotInvariant, eOperation);
copyConstraint(eOperation, pivotInvariant);
}
}
if (!context.isSuppressDuplicates()) {
List<ETypedElement> eDuplicates = null;
@NonNull Iterable<Constraint> duplicateConstraints = Iterables.filter(pivotClass.getOwnedInvariants(), duplicateConstraintsFilter);
for (Constraint asConstraint : duplicateConstraints) {
if (eDuplicates == null) {
eDuplicates = new ArrayList<ETypedElement>();
}
// Object eOperation = safeVisit(asConstraint);
if (asConstraint.isIsCallable()) {
EOperation eOperation = AS2Ecore.createConstraintEOperation(asConstraint, asConstraint.getName(), options);
eOperations.add(eOperation);
context.putCreated(asConstraint, eOperation);
copyConstraint(eOperation, asConstraint);
eDuplicates.add(eOperation);
context.defer(asConstraint); // Defer references
}
}
@NonNull Iterable<Operation> duplicateOperations = Iterables.filter(pivotClass.getOwnedOperations(), duplicateOperationsFilter);
for (Operation asOperation : duplicateOperations) {
if (eDuplicates == null) {
eDuplicates = new ArrayList<ETypedElement>();
}
Object eOperation = safeVisit(asOperation);
if (eOperation instanceof EOperation) {
eDuplicates.add((EOperation)eOperation);
}
}
@NonNull Iterable<Property> duplicateProperties = Iterables.filter(pivotClass.getOwnedProperties(), duplicatePropertiesFilter);
for (Property asProperty : duplicateProperties) {
if (eDuplicates == null) {
eDuplicates = new ArrayList<ETypedElement>();
}
Object eStructuralFeature = safeVisit(asProperty);
if (eStructuralFeature instanceof EStructuralFeature) {
eDuplicates.add((EStructuralFeature) eStructuralFeature);
}
}
if (eDuplicates != null) {
EAnnotation eAnnotation = eClass.getEAnnotation(PivotConstantsInternal.DUPLICATES_ANNOTATION_SOURCE);
if (eAnnotation == null) {
eAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
eAnnotation.setSource(PivotConstantsInternal.DUPLICATES_ANNOTATION_SOURCE);
eClass.getEAnnotations().add(eAnnotation);
}
context.refreshList(eAnnotation.getContents(), eDuplicates);
}
}
return eClass;
}
@Override
public EObject visitCollectionType(@NonNull CollectionType pivotCollectionType) {
if (pivotCollectionType.getOwnedBindings().size() > 0) {
return null;
}
@SuppressWarnings("null")
@NonNull EClass eClass = EcoreFactory.eINSTANCE.createEClass();
copyClassifier(eClass, pivotCollectionType);
Class<?> instanceClass = null;
String name = pivotCollectionType.getName();
if ("Bag".equals(name)) {
instanceClass = Bag.class;
}
else if ("Collection".equals(name)) {
instanceClass = Collection.class;
}
else if ("OrderedCollection".equals(name)) {
instanceClass = Collection.class;
}
else if ("OrderedSet".equals(name)) {
instanceClass = OrderedSet.class;
}
else if ("Sequence".equals(name)) {
instanceClass = List.class;
}
else if ("Set".equals(name)) {
instanceClass = Set.class;
}
else if ("UniqueCollection".equals(name)) {
instanceClass = Collection.class;
}
@SuppressWarnings("null")@NonNull List<EStructuralFeature> eStructuralFeatures = eClass.getEStructuralFeatures();
@NonNull Iterable<Property> nonDuplicateProperties = Iterables.filter(pivotCollectionType.getOwnedProperties(), nonDuplicatePropertiesFilter);
safeVisitAll(eStructuralFeatures, nonDuplicateProperties);
eClass.setInstanceClass(instanceClass);
eClass.setAbstract(true);
eClass.setInterface(true);
context.defer(pivotCollectionType); // Defer superclass resolution
return eClass;
}
@Override
public EObject visitConstraint(@NonNull Constraint pivotConstraint) {
Element eContainer = (Element)pivotConstraint.eContainer();
if (eContainer != null) {
EModelElement eModelElement = context.getCreated(EModelElement.class, eContainer);
if (eModelElement != null) {
copyConstraint(eModelElement, pivotConstraint);
return null;
}
}
return null;
}
@Override
public EObject visitDataType(@NonNull DataType pivotDataType) {
if (pivotDataType.getOwnedBindings().size() > 0) {
return null;
}
@SuppressWarnings("null")
@NonNull EDataType eDataType = EcoreFactory.eINSTANCE.createEDataType();
copyDataTypeOrEnum(eDataType, pivotDataType);
return eDataType;
}
@Override
public EObject visitEnumeration(@NonNull Enumeration pivotEnumeration) {
if (pivotEnumeration.getOwnedBindings().size() > 0) {
return null;
}
@SuppressWarnings("null")
@NonNull EEnum eEnum = EcoreFactory.eINSTANCE.createEEnum();
copyDataTypeOrEnum(eEnum, pivotEnumeration);
@SuppressWarnings("null")@NonNull List<EEnumLiteral> eLiterals = eEnum.getELiterals();
safeVisitAll(eLiterals, pivotEnumeration.getOwnedLiterals());
return eEnum;
}
@Override
public EObject visitEnumerationLiteral(@NonNull EnumerationLiteral pivotEnumLiteral) {
@SuppressWarnings("null")
@NonNull EEnumLiteral eEnumLiteral = EcoreFactory.eINSTANCE.createEEnumLiteral();
copyNamedElement(eEnumLiteral, pivotEnumLiteral);
if (pivotEnumLiteral.eIsSet(PivotPackage.Literals.ENUMERATION_LITERAL__VALUE)) {
eEnumLiteral.setValue(pivotEnumLiteral.getValue().intValue());
}
else {
eEnumLiteral.eUnset(EcorePackage.Literals.EENUM_LITERAL__VALUE);
}
return eEnumLiteral;
}
@Override
public Object visitModel(@NonNull Model pivotModel) {
EModelElement firstElement = null;
List<EObject> outputObjects = new ArrayList<EObject>();
for (@SuppressWarnings("null")org.eclipse.ocl.pivot.@NonNull Package pivotObject : pivotModel.getOwnedPackages()) {
if (!Orphanage.isTypeOrphanage(pivotObject) && !PivotUtilInternal.isImplicitPackage(pivotObject)) {
Object ecoreObject = safeVisit(pivotObject);
if (ecoreObject instanceof EObject) {
outputObjects.add((EObject) ecoreObject);
if ((firstElement == null) && (ecoreObject instanceof EModelElement)) {
firstElement = (EModelElement) ecoreObject;
}
}
}
}
List<Import> imports = pivotModel.getOwnedImports();
if (imports.size() > 0) {
if (imports.size() > 0) {
imports = new ArrayList<Import>(imports);
Collections.sort(imports, new Comparator<Import>()
{
@Override
public int compare(Import o1, Import o2) {
String n1 = o1.getName();
String n2 = o2.getName();
if (n1 == null) n1 = "";
if (n2 == null) n1 = "";
return n1.compareTo(n2);
}
}
);
}
EAnnotation importAnnotation = null;
URI ecoreURI = context.getEcoreURI();
for (Import anImport : imports) {
Namespace importedNamespace = anImport.getImportedNamespace();
if (importedNamespace != null) {
if (importAnnotation == null) {
importAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
importAnnotation.setSource(PivotConstants.IMPORT_ANNOTATION_SOURCE);
}
EObject eTarget = importedNamespace.getESObject();
if (eTarget != null) {
URI uri = null;
if ((eTarget instanceof EPackage) && ClassUtil.isRegistered(eTarget.eResource())) {
String nsURI = ((EPackage)eTarget).getNsURI();
if (nsURI != null) {
uri = URI.createURI(nsURI);
}
}
if (uri == null) {
uri = EcoreUtil.getURI(eTarget);
}
URI uri2 = uri.deresolve(ecoreURI, true, true, true);
importAnnotation.getDetails().put(anImport.getName(), uri2.toString());
}
else if (importedNamespace instanceof org.eclipse.ocl.pivot.Package) {
importAnnotation.getDetails().put(anImport.getName(), ((org.eclipse.ocl.pivot.Package)importedNamespace).getURI());
}
else {
importAnnotation.getDetails().put(anImport.getName(), importedNamespace.toString());
}
}
}
if ((firstElement != null) && (importAnnotation != null)) {
firstElement.getEAnnotations().add(importAnnotation);
}
}
return outputObjects;
}
@Override
public EObject visitOperation(@NonNull Operation pivotOperation) {
if (pivotOperation.getOwnedBindings().size() > 0) {
return null;
}
@SuppressWarnings("null")
@NonNull EOperation eOperation = EcoreFactory.eINSTANCE.createEOperation();
copyTypedElement(eOperation, pivotOperation);
@SuppressWarnings("null")@NonNull List<ETypeParameter> eTypeParameters = eOperation.getETypeParameters();
copyTemplateSignature(eTypeParameters, pivotOperation);
@SuppressWarnings("null")@NonNull List<EParameter> eParameters = eOperation.getEParameters();
safeVisitAll(eParameters, pivotOperation.getOwnedParameters());
// safeVisitAll(eOperation.getEGenericExceptions(), pivotOperation.getRaisedException());
LanguageExpression bodyExpression = pivotOperation.getBodyExpression();
if (bodyExpression != null) {
EAnnotation eBodyConstraint = delegateInstaller.createOperationDelegate(eOperation, bodyExpression, context.getEcoreURI());
if (eBodyConstraint != null) {
// AS2Ecore.copyComments(eBodyConstraint, bodyExpression);
}
}
for (Constraint pivotConstraint : pivotOperation.getOwnedPreconditions()) {
safeVisit(pivotConstraint); // Results are inserted directly
}
for (Constraint pivotConstraint : pivotOperation.getOwnedPostconditions()) {
safeVisit(pivotConstraint); // Results are inserted directly
}
if (pivotOperation.isIsTransient()) {
EAnnotation eAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
eAnnotation.setSource(PivotConstants.OPERATION_ANNOTATION_SOURCE);
EMap<String, String> details = eAnnotation.getDetails();
details.put(PivotConstants.OPERATION_IS_TRANSIENT, "true");
eOperation.getEAnnotations().add(eAnnotation);
}
return eOperation;
}
@Override
public EObject visitPackage(@NonNull Package pivotPackage) {
@SuppressWarnings("null")
@NonNull EPackage ePackage = EcoreFactory.eINSTANCE.createEPackage();
copyNamedElement(ePackage, pivotPackage);
context.defer(pivotPackage); // Defer delegate annotation analysis
if (pivotPackage.eIsSet(PivotPackage.Literals.PACKAGE__NS_PREFIX)) {
ePackage.setNsPrefix(pivotPackage.getNsPrefix());
}
if (pivotPackage.eIsSet(PivotPackage.Literals.PACKAGE__URI)) {
ePackage.setNsURI(pivotPackage.getURI());
}
@SuppressWarnings("null")@NonNull List<EPackage> eSubpackages = ePackage.getESubpackages();
safeVisitAll(eSubpackages, pivotPackage.getOwnedPackages());
@SuppressWarnings("null")@NonNull List<EClassifier> eClassifiers = ePackage.getEClassifiers();
safeVisitAll(eClassifiers, pivotPackage.getOwnedClasses());
return ePackage;
}
@Override
public EObject visitParameter(@NonNull Parameter pivotParameter) {
@SuppressWarnings("null")
@NonNull EParameter eParameter = EcoreFactory.eINSTANCE.createEParameter();
copyTypedElement(eParameter, pivotParameter);
return eParameter;
}
@Override
public EObject visitPrimitiveType(@NonNull PrimitiveType pivotPrimitiveType) {
if (pivotPrimitiveType.getOwnedBindings().size() > 0) {
return null;
}
@SuppressWarnings("null")
@NonNull EDataType eDataType = EcoreFactory.eINSTANCE.createEDataType();
copyDataTypeOrEnum(eDataType, pivotPrimitiveType);
/* Class<?> instanceClass = null;
String name = pivotPrimitiveType.getName();
if ("Boolean".equals(name)) {
instanceClass = Boolean.class;
}
else if ("Integer".equals(name)) {
instanceClass = IntegerValue.class;
}
else if ("Real".equals(name)) {
instanceClass = RealValue.class;
}
else if ("String".equals(name)) {
instanceClass = String.class;
}
else if ("UnlimitedNatural".equals(name)) {
instanceClass = UnlimitedNaturalValue.class;
}
eDataType.setInstanceClass(instanceClass); */
return eDataType;
}
@Override
public EObject visitProperty(@NonNull Property pivotProperty) {
if (pivotProperty.isIsImplicit()) {
return null;
}
EStructuralFeature eStructuralFeature;
Type type = pivotProperty.getType();
CollectionType ecoreCollectionType = context.isEcoreCollection(type);
if (ecoreCollectionType != null) {
type = ecoreCollectionType.getElementType();
}
if (type instanceof DataType) {
EAttribute eAttribute = EcoreFactory.eINSTANCE.createEAttribute();
eAttribute.setID(pivotProperty.isIsID());
eStructuralFeature = eAttribute;
}
else {
EReference eReference = EcoreFactory.eINSTANCE.createEReference();
if ((pivotProperty.getOpposite() != null) || !pivotProperty.getKeys().isEmpty()) {
context.defer(pivotProperty);
}
eReference.setContainment(pivotProperty.isIsComposite());
eReference.setResolveProxies(pivotProperty.isIsResolveProxies());
eStructuralFeature = eReference;
}
Property opposite = pivotProperty.getOpposite();
if ((opposite != null) && opposite.isIsImplicit()) {
EAnnotation eAnnotation = createOppositeEAnnotation(opposite);
if (eAnnotation != null) {
eStructuralFeature.getEAnnotations().add(eAnnotation);
}
}
copyTypedElement(eStructuralFeature, pivotProperty);
eStructuralFeature.setChangeable(!pivotProperty.isIsReadOnly());
eStructuralFeature.setDerived(pivotProperty.isIsDerived());
eStructuralFeature.setTransient(pivotProperty.isIsTransient());
eStructuralFeature.setUnsettable(pivotProperty.isIsUnsettable());
eStructuralFeature.setVolatile(pivotProperty.isIsVolatile());
// Object defaultValue = pivotProperty.getDefaultValue();
String defaultValueLiteral = pivotProperty.getDefaultValueString();
/* if (defaultValue != null) {
if (defaultValue instanceof String) {
defaultValueLiteral = (String)defaultValue;
}
else if (defaultValue instanceof Boolean) {
defaultValueLiteral = defaultValue.toString();
}
else if (defaultValue instanceof Value) {
defaultValueLiteral = defaultValue.toString();
}
else if (defaultValue instanceof EnumerationLiteral) {
defaultValueLiteral = ((EnumerationLiteral)defaultValue).getName();
}
// else if (defaultValue instanceof EnumerationLiteralId) { // type is Enumeration
// defaultValueLiteral = ((EnumerationLiteralId)defaultValue).getName();
// }
else { // FIXME Use URI for lack of Ecore support
defaultValueLiteral = String.valueOf(defaultValue); // FIXME need init EAnnotation for generality
}
/ * String defaultValueLiteral = eObject.getDefaultValueLiteral();
Object boxedValue;
EClassifier eType = eObject.getEType();
if (type instanceof DataType) {
EDataType eDataType = (EDataType)eType;
EFactory eFactoryInstance = eDataType.getEPackage().getEFactoryInstance();
Object unboxedValue = eFactoryInstance.createFromString(eDataType, defaultValueLiteral);
boxedValue = metamodelManager.getIdResolver().boxedValueOf(unboxedValue);
pivotElement.setDefaultValue(boxedValue);
}
else {
URI uri = URI.createURI(defaultValueLiteral);
boxedValue = metamodelManager.getExternalResourceSet().getEObject(uri, false);
}
pivotElement.setDefaultValue(boxedValue); * /
} */
if (defaultValueLiteral != null) {
eStructuralFeature.setDefaultValueLiteral(defaultValueLiteral);
}
else {
eStructuralFeature.eUnset(EcorePackage.Literals.ESTRUCTURAL_FEATURE__DEFAULT_VALUE_LITERAL);
}
LanguageExpression defaultExpression = pivotProperty.getOwnedExpression();
if (defaultExpression != null) {
delegateInstaller.createPropertyDelegate(eStructuralFeature, defaultExpression, context.getEcoreURI());
}
/* for (Property redefinedProperty : pivotProperty.getRedefinedProperty()) {
EAnnotation eAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
eAnnotation.setSource(PivotConstants.REDEFINES_ANNOTATION_SOURCE);
eStructuralFeature.getEAnnotations().add(eAnnotation);
} */
return eStructuralFeature;
}
@Override
public EObject visitTemplateParameter(@NonNull TemplateParameter pivotTemplateParameter) {
ETypeParameter eTypeParameter = EcoreFactory.eINSTANCE.createETypeParameter();
eTypeParameter.setName(pivotTemplateParameter.getName());
context.putCreated(pivotTemplateParameter, eTypeParameter);
if (!pivotTemplateParameter.getConstrainingClasses().isEmpty()) {
context.defer(pivotTemplateParameter);
}
return eTypeParameter;
}
}