blob: cffac6102b00e6f40c1a2d37e3b5860648d6b126 [file] [log] [blame]
/*******************************************************************************
* 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;
}
}