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