/******************************************************************************* * Copyright (c) 2015 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 *******************************************************************************/ package org.eclipse.ocl.pivot.uml.internal.utilities; import java.util.List; import org.eclipse.emf.ecore.EAnnotation; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EClassifier; import org.eclipse.emf.ecore.ENamedElement; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.ocl.pivot.Constraint; import org.eclipse.ocl.pivot.DynamicElement; import org.eclipse.ocl.pivot.Element; import org.eclipse.ocl.pivot.NamedElement; import org.eclipse.ocl.pivot.Profile; import org.eclipse.ocl.pivot.Property; import org.eclipse.ocl.pivot.ids.CollectionTypeId; import org.eclipse.ocl.pivot.ids.IdManager; import org.eclipse.ocl.pivot.ids.PackageId; import org.eclipse.ocl.pivot.ids.RootPackageId; import org.eclipse.ocl.pivot.ids.TypeId; import org.eclipse.ocl.pivot.internal.utilities.AbstractTechnology; import org.eclipse.ocl.pivot.internal.utilities.EnvironmentFactoryInternal; import org.eclipse.ocl.pivot.internal.utilities.PivotConstantsInternal; import org.eclipse.ocl.pivot.internal.utilities.PivotObjectImpl; import org.eclipse.ocl.pivot.library.LibraryProperty; import org.eclipse.ocl.pivot.uml.internal.library.InstanceSlotNavigationProperty; import org.eclipse.ocl.pivot.uml.internal.library.UMLBaseProperty; import org.eclipse.ocl.pivot.uml.internal.library.UMLExtensionProperty; import org.eclipse.ocl.pivot.uml.internal.library.UMLStereotypeProperty; import org.eclipse.ocl.pivot.util.DerivedConstants; import org.eclipse.ocl.pivot.utilities.ClassUtil; import org.eclipse.ocl.pivot.utilities.MetamodelManager; import org.eclipse.ocl.pivot.utilities.NameUtil; import org.eclipse.ocl.pivot.utilities.ParserException; import org.eclipse.ocl.pivot.utilities.PivotConstants; import org.eclipse.ocl.pivot.utilities.PivotUtil; import org.eclipse.uml2.types.TypesPackage; import org.eclipse.uml2.uml.UMLPackage; public class UMLEcoreTechnology extends AbstractTechnology { public static final @NonNull UMLEcoreTechnology INSTANCE = new UMLEcoreTechnology(); protected UMLEcoreTechnology() {} @Override public @NonNull UMLIdResolver createIdResolver(@NonNull EnvironmentFactoryInternal environmentFactory) { return new UMLIdResolver(environmentFactory); } @Override public @NonNull LibraryProperty createBasePropertyImplementation(@NonNull EnvironmentFactoryInternal environmentFactory, @NonNull Property property) { return new UMLBaseProperty(property); } @Override public @NonNull LibraryProperty createExplicitNavigationPropertyImplementation(@NonNull EnvironmentFactoryInternal environmentFactory, @Nullable Element asNavigationExp, @Nullable Object sourceValue, @NonNull Property property) { if (sourceValue instanceof org.eclipse.uml2.uml.InstanceSpecification) { org.eclipse.ocl.pivot.Package owningPackage = PivotUtil.getContainingPackage(asNavigationExp); if (!(owningPackage instanceof Profile)) { // FIXME see Bug 458326/458394 EObject eTarget = property.getESObject(); if (eTarget instanceof org.eclipse.uml2.uml.Property) { TypeId typeId = property.getTypeId(); CollectionTypeId collectionTypeId; if (typeId instanceof CollectionTypeId) { collectionTypeId = (CollectionTypeId)typeId; } else { collectionTypeId = null; } return new InstanceSlotNavigationProperty((org.eclipse.uml2.uml.Property)eTarget, collectionTypeId); } } } return super.createExplicitNavigationPropertyImplementation(environmentFactory, asNavigationExp, sourceValue, property); } @Override public @NonNull LibraryProperty createExtensionPropertyImplementation(@NonNull EnvironmentFactoryInternal environmentFactory, @NonNull Property property) { return new UMLExtensionProperty(property); } @Override public @NonNull LibraryProperty createStereotypePropertyImplementation(@NonNull EnvironmentFactoryInternal environmentFactory, @NonNull Property property) { return new UMLStereotypeProperty(property); } @Override public String getExtensionName(@NonNull Element asStereotypedElement) { String name = "????"; if (asStereotypedElement instanceof NamedElement) { name = ((NamedElement)asStereotypedElement).getName(); } else if (asStereotypedElement instanceof DynamicElement) { EObject eObject = ((DynamicElement)asStereotypedElement).getESObject(); if (eObject instanceof org.eclipse.uml2.uml.NamedElement) { name = ((org.eclipse.uml2.uml.NamedElement)eObject).getName(); } } return name; } @Override public RootPackageId getMetamodelId(@NonNull EnvironmentFactoryInternal environmentFactory, @NonNull EPackage eObject2) { RootPackageId metamodel = null; if (ClassUtil.basicGetMetamodelAnnotation(eObject2) != null) { metamodel = IdManager.METAMODEL; } else if (eObject2 instanceof UMLPackage) { @SuppressWarnings("null")@NonNull String nsUri = UMLPackage.eNS_URI; environmentFactory.getMetamodelManager().getCompleteModel().addPackageURI2completeURI(nsUri, PivotConstants.UML_METAMODEL_NAME); metamodel = IdManager.getRootPackageId(PivotConstants.UML_METAMODEL_NAME); } else if (eObject2 instanceof TypesPackage) { @SuppressWarnings("null")@NonNull String nsUri = TypesPackage.eNS_URI; environmentFactory.getMetamodelManager().getCompleteModel().addPackageURI2completeURI(nsUri, PivotConstants.TYPES_METAMODEL_NAME); metamodel = IdManager.getRootPackageId(PivotConstants.TYPES_METAMODEL_NAME); } else { String nsURI = eObject2.getNsURI(); String sharedNsURI = environmentFactory.getMetamodelManager().getCompleteModel().getCompleteURI(nsURI); if ((sharedNsURI != null) && !sharedNsURI.equals(nsURI)) { metamodel = IdManager.getRootPackageId(sharedNsURI); } } return metamodel; } @Override public @NonNull PackageId getMetapackageId(@NonNull EnvironmentFactoryInternal environmentFactory, org.eclipse.ocl.pivot.@NonNull Package asPackage) { if (asPackage instanceof PivotObjectImpl) { EObject eTarget = ((PivotObjectImpl)asPackage).getESObject(); if (eTarget != null) { EClass eClass = eTarget.eClass(); if (eClass != null) { EPackage ePackage = eClass.getEPackage(); if (ePackage instanceof UMLPackage) { return IdManager.getRootPackageId(PivotConstants.UML_METAMODEL_NAME); } else if (ePackage instanceof TypesPackage) { return IdManager.getRootPackageId(PivotConstants.TYPES_METAMODEL_NAME); } } } } return IdManager.METAMODEL; } @Override public @Nullable String getOriginalName(@NonNull ENamedElement eNamedElement) { EAnnotation eAnnotation = eNamedElement.getEAnnotation(PivotConstantsInternal.REDEFINES_ANNOTATION_SOURCE); if (eAnnotation != null) { EObject eContainer = eNamedElement.eContainer(); if (eContainer instanceof EAnnotation) { // duplicates ... redefines List<EObject> eReferences = eAnnotation.getReferences(); if ((eReferences != null) && (eReferences.size() > 0)) { EObject eObject = eReferences.get(0); if (eObject instanceof ENamedElement) { String originalName = getOriginalName((ENamedElement) eObject); return originalName; } } } else if (eContainer instanceof EClassifier) { String prefix = ((EClassifier)eContainer).getName() + "_"; // FIXME Bug 405061 workaround String originalName = NameUtil.getOriginalName(eNamedElement); if (originalName.startsWith(prefix)) { originalName = originalName.substring(prefix.length()); } return originalName; } } String originalName = NameUtil.getOriginalName(eNamedElement); return originalName; } @Override public @Nullable Element getParseableElement(@NonNull EnvironmentFactoryInternal environmentFactory, @NonNull EObject eObject) throws ParserException { Element pivotElement; if (eObject instanceof Element) { return (Element) eObject; } MetamodelManager metamodelManager = environmentFactory.getMetamodelManager(); pivotElement = metamodelManager.getASOf(Element.class, eObject); if ((eObject instanceof org.eclipse.uml2.uml.Constraint) && (pivotElement instanceof Constraint) && (pivotElement.eContainer() == null)) { pivotElement = metamodelManager.getASOf(Element.class, ((org.eclipse.uml2.uml.Constraint)eObject).getSpecification()); } return pivotElement; } @Override public boolean isStereotype(@NonNull EnvironmentFactoryInternal environmentFactory, @NonNull EClass eClass) { for (EStructuralFeature eFeature : eClass.getEAllStructuralFeatures()) { EClassifier eType = eFeature.getEType(); if (eType != null) { EPackage ePackage = eType.getEPackage(); if (ePackage == UMLPackage.eINSTANCE) { // ?? is this too narrow ?? SysML ?? String name = eFeature.getName(); if ((name != null) && name.startsWith(DerivedConstants.STEREOTYPE_BASE_PREFIX)) { return true; } } } } return false; } @Override public boolean isValidatable(@NonNull EClass eClass) { EPackage ePackage = eClass.getEPackage(); if (ePackage != null) { EObject eContainer = ePackage.eContainer(); if (eContainer instanceof EAnnotation) { EObject eContainerContainer = eContainer.eContainer(); if (eContainerContainer instanceof Profile) { return false; // Stereotype applications are validated where they applied } } } return true; } }