blob: 3ab8e54269fa86f1ab8bc53a46de3e987a0ca3ad [file] [log] [blame]
/**
* <copyright>
*
* Copyright (c) 2010,2011 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$
*/
package org.eclipse.ocl.examples.pivot.manager;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.log4j.Logger;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.Resource.Factory.Registry;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
import org.eclipse.ocl.examples.domain.elements.DomainCollectionType;
import org.eclipse.ocl.examples.domain.elements.DomainOperation;
import org.eclipse.ocl.examples.domain.elements.DomainPackage;
import org.eclipse.ocl.examples.domain.elements.DomainTupleType;
import org.eclipse.ocl.examples.domain.elements.DomainType;
import org.eclipse.ocl.examples.domain.elements.DomainTypedElement;
import org.eclipse.ocl.examples.domain.library.LibraryFeature;
import org.eclipse.ocl.examples.domain.utilities.StandaloneProjectMap;
import org.eclipse.ocl.examples.domain.values.ValueFactory;
import org.eclipse.ocl.examples.library.executor.ReflectiveExecutorType;
import org.eclipse.ocl.examples.pivot.AnyType;
import org.eclipse.ocl.examples.pivot.ClassifierType;
import org.eclipse.ocl.examples.pivot.CollectionType;
import org.eclipse.ocl.examples.pivot.Comment;
import org.eclipse.ocl.examples.pivot.Constraint;
import org.eclipse.ocl.examples.pivot.DataType;
import org.eclipse.ocl.examples.pivot.Element;
import org.eclipse.ocl.examples.pivot.Feature;
import org.eclipse.ocl.examples.pivot.InvalidLiteralExp;
import org.eclipse.ocl.examples.pivot.InvalidType;
import org.eclipse.ocl.examples.pivot.Iteration;
import org.eclipse.ocl.examples.pivot.LambdaType;
import org.eclipse.ocl.examples.pivot.Library;
import org.eclipse.ocl.examples.pivot.NamedElement;
import org.eclipse.ocl.examples.pivot.Namespace;
import org.eclipse.ocl.examples.pivot.Operation;
import org.eclipse.ocl.examples.pivot.Parameter;
import org.eclipse.ocl.examples.pivot.ParameterableElement;
import org.eclipse.ocl.examples.pivot.PivotFactory;
import org.eclipse.ocl.examples.pivot.PivotPackage;
import org.eclipse.ocl.examples.pivot.Precedence;
import org.eclipse.ocl.examples.pivot.Property;
import org.eclipse.ocl.examples.pivot.SelfType;
import org.eclipse.ocl.examples.pivot.TemplateBinding;
import org.eclipse.ocl.examples.pivot.TemplateParameter;
import org.eclipse.ocl.examples.pivot.TemplateParameterSubstitution;
import org.eclipse.ocl.examples.pivot.TemplateSignature;
import org.eclipse.ocl.examples.pivot.TemplateableElement;
import org.eclipse.ocl.examples.pivot.TupleType;
import org.eclipse.ocl.examples.pivot.Type;
import org.eclipse.ocl.examples.pivot.TypedMultiplicityElement;
import org.eclipse.ocl.examples.pivot.UnspecifiedType;
import org.eclipse.ocl.examples.pivot.VoidType;
import org.eclipse.ocl.examples.pivot.ecore.Ecore2Pivot;
import org.eclipse.ocl.examples.pivot.library.StandardLibraryContribution;
import org.eclipse.ocl.examples.pivot.messages.OCLMessages;
import org.eclipse.ocl.examples.pivot.model.OclMetaModel;
import org.eclipse.ocl.examples.pivot.uml.UML2Ecore2Pivot;
import org.eclipse.ocl.examples.pivot.util.Nameable;
import org.eclipse.ocl.examples.pivot.utilities.CompleteElementIterable;
import org.eclipse.ocl.examples.pivot.utilities.External2Pivot;
import org.eclipse.ocl.examples.pivot.utilities.IllegalLibraryException;
import org.eclipse.ocl.examples.pivot.utilities.Pivot2Moniker;
import org.eclipse.ocl.examples.pivot.utilities.PivotResource;
import org.eclipse.ocl.examples.pivot.utilities.PivotResourceFactoryImpl;
import org.eclipse.ocl.examples.pivot.utilities.PivotUtil;
import org.eclipse.ocl.examples.pivot.values.PivotValueFactory;
import org.eclipse.osgi.util.NLS;
public class MetaModelManager extends PivotStandardLibrary implements Adapter.Internal, MetaModelManageable
{
public class CompleteTypeOperationsIterable extends CompleteElementIterable<Type, Operation>
{
protected final Boolean selectStatic; // null for static/non-static, true for static, false for non-static
public CompleteTypeOperationsIterable(Iterable<Type> types, Boolean selectStatic) {
super(types);
this.selectStatic = selectStatic;
}
@Override
protected Iterable<Operation> getInnerIterable(Type model) {
return model.getOwnedOperations();
}
@Override
protected Operation getInnerValue(Operation element) {
if (selectStatic != null) {
if (element.isStatic() != selectStatic.booleanValue()) {
return null;
}
}
return element;
}
}
public class CompleteClassPropertiesIterable extends CompleteElementIterable<Type, Property>
{
protected final Boolean selectStatic; // null for static/non-static, true for static, false for non-static
public CompleteClassPropertiesIterable(Iterable<Type> types, Boolean selectStatic) {
super(types);
this.selectStatic = selectStatic;
}
@Override
protected Iterable<Property> getInnerIterable(Type model) {
return model.getOwnedAttributes();
}
@Override
protected Property getInnerValue(Property element) {
if (selectStatic != null) {
if (element.isStatic() != selectStatic.booleanValue()) {
return null;
}
}
return element;
}
}
public class CompleteClassSuperClassesIterable
extends CompleteElementIterable<Type, Type> {
public CompleteClassSuperClassesIterable(Iterable<Type> types) {
super(types);
}
@Override
protected Iterable<Type> getInnerIterable(Type model) {
return model.getSuperClasses();
}
}
public class CompleteElementCommentsIterable
extends CompleteElementIterable<Element, Comment> {
public CompleteElementCommentsIterable(Iterable<? extends Element> models) {
super(models);
}
@Override
protected Iterable<Comment> getInnerIterable(Element model) {
return model.getOwnedComments();
}
}
public class CompleteElementConstraintsIterable
extends CompleteElementIterable<NamedElement, Constraint> {
public CompleteElementConstraintsIterable(Iterable<? extends NamedElement> models) {
super(models);
}
@Override
protected Iterable<Constraint> getInnerIterable(NamedElement model) {
return model.getOwnedRules();
}
}
public class CompletePackagePackagesIterable
extends CompleteElementIterable<org.eclipse.ocl.examples.pivot.Package, org.eclipse.ocl.examples.pivot.Package> {
public CompletePackagePackagesIterable(Iterable<org.eclipse.ocl.examples.pivot.Package> packages) {
super(packages);
}
@Override
protected Iterable<org.eclipse.ocl.examples.pivot.Package> getInnerIterable(org.eclipse.ocl.examples.pivot.Package model) {
return model.getNestedPackages();
}
}
public class CompletePackageTypesIterable
extends CompleteElementIterable<org.eclipse.ocl.examples.pivot.Package, Type> {
public CompletePackageTypesIterable(Iterable<org.eclipse.ocl.examples.pivot.Package> packages) {
super(packages);
}
@Override
protected Iterable<Type> getInnerIterable(org.eclipse.ocl.examples.pivot.Package model) {
return model.getOwnedTypes();
}
}
/**
* An OrphanServer maintains the set of OrphanClients identifying active references to an orphan element.
* When the final reference is removed the orphan is killed off.
*
public static class OrphanServer
{
protected final Element element;
private Set<OrphanClient> clients = null;
public OrphanServer(Element element) {
this.element = element;
}
public void addClient(OrphanClient client) {
if (client != null) {
if (clients == null) {
clients = new HashSet<OrphanClient>();
}
clients.add(client);
}
}
// public Element getElement() {
// return element;
// }
public void removeClient(OrphanClient client) {
if (client != null) {
if (clients != null) {
clients.remove(client);
if (clients.isEmpty()) {
clients = null;
element.eSet(element.eContainmentFeature(), null);
}
}
}
}
@Override
public String toString() {
return "<orphan-node> " + element;
}
} */
/**
* An OrphanClient adapts an EObject with an eReference to an OrphanServer within the domina of a TypeCache.
*
* Changes to eContainer and eReference cause the eReference to be activated and deactivated accordingly so that
* the OrphanServer is aware of how many active clients there are.
*
public static class OrphanClient implements Adapter
{
protected final TypeCaches typeCache;
protected final EObject target;
protected final EReference eReference;
private OrphanServer orphanServer;
public OrphanClient(TypeCaches typeCache, EObject target, EReference eReference) {
this.typeCache = typeCache;
this.target = target;
this.eReference = eReference;
this.orphanServer = null;
target.eAdapters().add(this);
}
protected void activate(NamedElement pivotElement) {
orphanServer = null; // W I P typeCache.getOrphanServer(pivotElement);
if (orphanServer != null) {
orphanServer.addClient(this);
}
}
protected void deActivate() {
if (orphanServer != null) {
orphanServer.removeClient(this);
orphanServer = null;
}
}
public Notifier getTarget() {
return target;
}
public boolean isAdapterForType(Object type) {
return type == OrphanClient.class;
}
public void notifyChanged(Notification notification) {
if (notification.getNotifier() == target) {
int eventType = notification.getEventType();
switch (eventType) {
case Notification.SET: {
Object oldValue = notification.getOldValue();
Object newValue = notification.getNewValue();
if (newValue != oldValue) {
Object feature = notification.getFeature();
if (feature == eReference) {
if (oldValue != null) {
deActivate();
}
if (newValue instanceof NamedElement) {
activate((NamedElement) newValue);
}
}
else if (feature == target.eContainmentFeature()) {
if (oldValue != null) {
deActivate();
}
if (newValue != null) {
assert target == newValue;
Object orphan = target.eGet(eReference);
if (orphan instanceof NamedElement) {
activate((NamedElement) orphan);
}
}
}
}
}
}
}
}
public void setTarget(Notifier newTarget) {
assert (newTarget == null) || (newTarget == target);
}
} */
public static interface Factory // FIXME Support this via an extension point
{
/**
* Return true if this factory can handle creatio of a Pivot resource from the
* available resource.
*/
boolean canHandle(Resource resource);
/**
* Configure the MetaModelManager's external ResourceSet. Implementations may install
* any required extension or content to factory mappinmgs in the resource factory registry.
* @param resourceSet
*/
void configure(ResourceSet resourceSet);
/**
* Return the URI of an eObject if it can be treated as a Package.
*/
URI getPackageURI(EObject eObject);
/**
* Return the root element in the Pivot resource resulting from import of the available
* resource.
* @param uriFragment
*/
Element importFromResource(MetaModelManager metaModelManager, Resource resource, String uriFragment);
}
private static Set<Factory> factoryMap = new HashSet<Factory>();
public static void addFactory(Factory factory) {
factoryMap.add(factory);
}
static {
Ecore2Pivot.FACTORY.getClass();
UML2Ecore2Pivot.FACTORY.getClass();
}
private static final Logger logger = Logger.getLogger(MetaModelManager.class);
// private static WeakHashMap<MetaModelManager,Object> liveMetaModelManagers = new WeakHashMap<MetaModelManager,Object>();
// public static final String OMG_OCL_LANG1 = "omg.ocl.lang";
// public static final String OMG_OCL_STDLIB1 = "omg.ocl.stdlib";
/* public static void disposeNotifier(Notifier notifier) {
List<Adapter> adapters = notifier.eAdapters();
for (int i = adapters.size(); i-- > 0; ) {
Adapter adapter = adapters.get(i);
if (adapter instanceof MetaModelManagedAdapter) {
adapters.remove(adapter);
((MetaModelManagedAdapter) adapter).dispose();
// metaModelManager.debugRemoveAdapter(adapter);
}
}
}
public static void disposeResource(Resource resource) {
// CacheAdapter.INSTANCE.clear(resource);
for (TreeIterator<EObject> tit = resource.getAllContents(); tit.hasNext(); ) {
EObject eObject = tit.next();
disposeNotifier(eObject);
}
disposeNotifier(resource);
}
public static void disposeResourceSet(ResourceSet resourceSet) {
for (Resource resource : resourceSet.getResources()) {
disposeResource(resource);
}
disposeNotifier(resourceSet);
} */
public static MetaModelManager findAdapter(ResourceSet resourceSet) {
if (resourceSet == null) {
return null;
}
return PivotUtil.getAdapter(MetaModelManager.class, resourceSet);
}
public static MetaModelManager getAdapter(ResourceSet resourceSet) {
if (resourceSet == null) {
return null;
}
List<Adapter> eAdapters = resourceSet.eAdapters();
MetaModelManager adapter = PivotUtil.getAdapter(MetaModelManager.class, eAdapters);
if (adapter == null) {
adapter = new MetaModelManager(resourceSet);
eAdapters.add(adapter);
}
return adapter;
}
public static void initializePivotResourceSet(ResourceSet pivotResourceSet) {
StandaloneProjectMap.initializeURIResourceMap(pivotResourceSet);
Registry resourceFactoryRegistry = pivotResourceSet.getResourceFactoryRegistry();
Map<String, Object> contentTypeToFactoryMap = resourceFactoryRegistry.getContentTypeToFactoryMap();
contentTypeToFactoryMap.put(PivotResource.CONTENT_TYPE, new PivotResourceFactoryImpl()); //$NON-NLS-1$
Map<String, Object> extensionToFactoryMap = resourceFactoryRegistry.getExtensionToFactoryMap();
extensionToFactoryMap.put("*", new XMIResourceFactoryImpl()); //$NON-NLS-1$
extensionToFactoryMap.put(PivotResource.FILE_EXTENSION, new PivotResourceFactoryImpl()); //$NON-NLS-1$
org.eclipse.emf.ecore.EPackage.Registry packageRegistry = pivotResourceSet.getPackageRegistry();
packageRegistry.put(PivotPackage.eNS_URI, PivotPackage.eINSTANCE);
}
/**
* The known packages.
*/
private final PackageManager packageManager = createPackageManager();
/**
* The known precedences.
*/
private PrecedenceManager precedenceManager = null; // Lazily created
/**
* The known tuple types.
*/
private TupleTypeManager tupleManager = null; // Lazily created
/**
* The known tuple types.
*/
private LambdaTypeManager lambdaManager = null; // Lazily created
/**
* The known implementation load capabilities.
*/
private ImplementationManager implementationManager = null; // Lazily created
/**
* The value creation capabilities.
*/
private ValueFactory valueFactory = null; // Lazily created
private Resource orphanage = null;
protected org.eclipse.ocl.examples.pivot.Package pivotMetaModel = null;
private boolean libraryLoadInProgress = false;
protected final ResourceSet pivotResourceSet;
/**
* All Library packages imported into the current type managed domain. All libraries
* share the same URI, which for supplementary libraries may be null.
*/
protected final List<Library> pivotLibraries = new ArrayList<Library>();
/**
* The resource of the first of the pivotLibraries. Set once actually loaded.
*/
protected Resource pivotLibraryResource = null;
protected ResourceSetImpl externalResourceSet = null;
private final Map<String, Namespace> globalNamespaces = new HashMap<String, Namespace>();
private final Set<Type> globalTypes = new HashSet<Type>();
private int unspecifiedTypeCount = 0;
/**
* Map of URI to external resource converter.
*/
private final Map<URI, External2Pivot> external2PivotMap = new HashMap<URI, External2Pivot>();
/**
* Map of arbitrary user context to the associated URI used for the concrete syntax
* of an expression. The map is used by getResourceIdentifier to cache URIs for contexts
* that are not Elements. Any object may be used, possibly the OCL string itself,
* provided the object has exactly one associated OCL expression.
*/
private Map<Object,URI> uriMap = null;
/**
* Elements protected from garbage collection
*/
private EAnnotation lockingAnnotation = null;
/**
* MetaModelManagerListener instances to be notified of significant state changes; most notably disposal.
*/
private List<MetaModelManagerListener> listeners = null;
public MetaModelManager() {
this(new ResourceSetImpl());
initializePivotResourceSet(pivotResourceSet);
}
/**
* Construct a MetaModelManager that will use projectMap to assist in locating resources.
*/
public MetaModelManager(StandaloneProjectMap projectMap) {
this(new ResourceSetImpl());
pivotResourceSet.eAdapters().add(projectMap);
initializePivotResourceSet(pivotResourceSet);
}
/**
* Construct a MetaModelManager that will use pivotResourceSet to contain pivot copies
* of meta-models, and {@link ProjectMap.getAdapter(ResourceSet)} to assist in locating resources.
*/
public MetaModelManager(ResourceSet pivotResourceSet) {
// System.out.println("ctor " + this);
this.pivotResourceSet = pivotResourceSet;
pivotResourceSet.eAdapters().add(this);
// liveMetaModelManagers.put(this, null);
// System.out.println(Thread.currentThread().getName() + " Create " + PivotUtil.debugSimpleName(this)
// + " " + PivotUtil.debugSimpleName(pivotResourceSet));
}
public void addClassLoader(ClassLoader classLoader) {
ImplementationManager implementationManager = getImplementationManager();
implementationManager.addClassLoader(classLoader);
}
public void addExternalResource(External2Pivot external2Pivot) {
external2PivotMap.put(external2Pivot.getURI(), external2Pivot);
}
public Namespace addGlobalNamespace(String name, Namespace namespace) {
return globalNamespaces.put(name, namespace);
}
public boolean addGlobalTypes(Collection<Type> types) {
return globalTypes.addAll(types);
}
public void addListener(MetaModelManagerListener listener) {
if (listeners == null) {
listeners = new ArrayList<MetaModelManagerListener>();
}
if (!listeners.contains(listener)) {
listeners.add(listener);
}
}
public void addLockedElement(Object lockedElement) {
if (lockedElement instanceof EObject) {
if (lockingAnnotation == null) {
lockingAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
}
List<EObject> lockingReferences = lockingAnnotation.getReferences();
if (!lockingReferences.contains(lockedElement)) {
lockingReferences.add((EObject) lockedElement);
}
}
}
public void addOrphanClass(Type pivotElement) {
if (pivotElement.getUnspecializedElement() != null) {
assert pivotElement.getUnspecializedElement().getUnspecializedElement() == null;
}
else {
assert (pivotElement instanceof LambdaType)
|| (pivotElement instanceof TupleType)
|| (pivotElement instanceof UnspecifiedType);
}
getOrphanResource().getContents().add(pivotElement);
}
public void addPackage(org.eclipse.ocl.examples.pivot.Package pivotPackage) {
packageManager.addPackage(pivotPackage);
}
/**
* Return -ve if match1 is inferior to match2, +ve if match2 is inferior to match1, or
* zero if both matches are of equal validity.
*/
public int compareOperationMatches(Operation reference, Map<TemplateParameter, ParameterableElement> referenceBindings,
Operation candidate, Map<TemplateParameter, ParameterableElement> candidateBindings) {
if ((reference instanceof Iteration) && (candidate instanceof Iteration)) {
int iteratorCountDelta = ((Iteration)candidate).getOwnedIterators().size() - ((Iteration)reference).getOwnedIterators().size();
if (iteratorCountDelta != 0) {
return iteratorCountDelta;
}
Type referenceType = PivotUtil.getOwningType((Iteration)reference);
Type candidateType = PivotUtil.getOwningType((Iteration)candidate);
Type specializedReferenceType = getSpecializedType(referenceType, referenceBindings);
Type specializedCandidateType = getSpecializedType(candidateType, candidateBindings);
if (referenceType != candidateType) {
if (conformsTo(specializedReferenceType, specializedCandidateType, null)) {
return 1;
}
else if (conformsTo(specializedCandidateType, specializedReferenceType, null)) {
return -1;
}
}
}
List<Parameter> candidateParameters = candidate.getOwnedParameters();
List<Parameter> referenceParameters = reference.getOwnedParameters();
int parameterCountDelta = candidateParameters.size() - referenceParameters.size();
if (parameterCountDelta != 0) {
return parameterCountDelta;
}
boolean referenceConformsToCandidate = true;
boolean candidateConformsReference = true;
for (int i = 0; i < candidateParameters.size(); i++) {
Type referenceType = getTypeWithMultiplicity(referenceParameters.get(i));
Type candidateType = getTypeWithMultiplicity(candidateParameters.get(i));
Type specializedReferenceType = getSpecializedType(referenceType, referenceBindings);
Type specializedCandidateType = getSpecializedType(candidateType, candidateBindings);
if (referenceType != candidateType) {
if (!conformsTo(specializedReferenceType, specializedCandidateType, null)) {
referenceConformsToCandidate = false;
}
if (!conformsTo(specializedCandidateType, specializedReferenceType, null)) {
candidateConformsReference = false;
}
}
}
if (referenceConformsToCandidate != candidateConformsReference) {
return referenceConformsToCandidate ? 1 : -1;
}
Type referenceType = PivotUtil.getOwningType(reference);
Type candidateType = PivotUtil.getOwningType(candidate);
Type specializedReferenceType = getSpecializedType(referenceType, referenceBindings);
Type specializedCandidateType = getSpecializedType(candidateType, candidateBindings);
if (referenceType != candidateType) {
if (conformsTo(specializedReferenceType, specializedCandidateType, null)) {
return 1;
}
else if (conformsTo(specializedCandidateType, specializedReferenceType, null)) {
return -1;
}
}
return 0;
}
@Deprecated
public boolean conformsTo(Type firstType, Type secondType) {
return conformsTo(firstType, secondType, null);
}
public boolean conformsTo(Type firstType, Type secondType, Map<TemplateParameter, ParameterableElement> bindings) {
if ((firstType == null) || (secondType == null)) {
return false;
}
if (bindings != null) {
TemplateParameter firstTemplateParameter = firstType.getOwningTemplateParameter();
if (firstTemplateParameter != null) {
ParameterableElement parameterableElement = bindings.get(firstTemplateParameter);
if (parameterableElement instanceof Type) {
firstType = (Type) parameterableElement;
}
}
TemplateParameter secondTemplateParameter = secondType.getOwningTemplateParameter();
if (secondTemplateParameter != null) {
ParameterableElement parameterableElement = bindings.get(secondTemplateParameter);
if (parameterableElement instanceof Type) {
secondType = (Type) parameterableElement;
}
else if ((parameterableElement == null) && bindings.containsKey(secondTemplateParameter)) {
bindings.put(secondTemplateParameter, firstType);
return true;
}
}
}
if (firstType == secondType) {
return true;
}
// firstType = getModelType(firstType);
// secondType = getModelType(secondType);
firstType = getPrimaryType(firstType);
secondType = getPrimaryType(secondType);
if (firstType == secondType) {
return true;
}
if (secondType instanceof AnyType) { // FIXME Shouldn't the library model definitions apply here too
return true;
}
else if (firstType instanceof AnyType) {
return false;
}
else if (firstType instanceof InvalidType) {
return true;
}
else if (secondType instanceof InvalidType) {
return false;
}
else if (firstType instanceof VoidType) {
return true;
}
else if (secondType instanceof VoidType) {
return false;
}
else if (firstType instanceof ClassifierType) {
if (secondType instanceof ClassifierType) {
return conformsToClassifierType((ClassifierType)firstType, (ClassifierType)secondType, bindings);
}
// Drop-through and maybe match xxClassifoer<xx> against OclType
}
else if (firstType instanceof CollectionType) {
if (secondType instanceof CollectionType) {
return conformsToCollectionType((CollectionType)firstType, (CollectionType)secondType, bindings);
}
return false;
}
else if (firstType instanceof LambdaType) {
if (secondType instanceof LambdaType) {
return conformsToLambdaType((LambdaType)firstType, (LambdaType)secondType, bindings);
}
return false;
}
else if (firstType instanceof TupleType) {
if (secondType instanceof TupleType) {
return conformsToTupleType((TupleType)firstType, (TupleType)secondType, bindings);
}
return false;
}
for (Type superClass : getSuperClasses(firstType)) {
if (conformsTo(superClass, secondType, bindings)) {
return true;
}
}
// List<TemplateBinding> templateBindings = actualType.getTemplateBindings();
// if (templateBindings.size() > 0) {
// TemplateableElement template = PivotUtil.getUnspecializedTemplateableElement(actualType);
// return conformsToClass((org.eclipse.ocl.examples.pivot.Class)template, requiredType);
// }
return false;
}
protected boolean conformsToClassifierType(ClassifierType firstType, ClassifierType secondType,
Map<TemplateParameter, ParameterableElement> bindings) {
Type firstElementType = firstType.getInstanceType();
Type secondElementType = secondType.getInstanceType();
if (bindings != null) {
TemplateParameter firstTemplateParameter = firstElementType.getOwningTemplateParameter();
if (firstTemplateParameter != null) {
ParameterableElement parameterableElement = bindings.get(firstTemplateParameter);
if (parameterableElement instanceof Type) {
firstElementType = (Type) parameterableElement;
}
}
TemplateParameter secondTemplateParameter = secondElementType.getOwningTemplateParameter();
if (secondTemplateParameter != null) {
ParameterableElement parameterableElement = bindings.get(secondTemplateParameter);
if (parameterableElement instanceof Type) {
secondElementType = (Type) parameterableElement;
}
else if ((parameterableElement == null) && bindings.containsKey(secondTemplateParameter)) {
bindings.put(secondTemplateParameter, firstElementType);
return true;
}
}
}
if (firstElementType instanceof UnspecifiedType) {
Type lowerBound = ((UnspecifiedType)firstElementType).getLowerBound();
if (conformsTo(secondElementType, lowerBound, bindings)) {
((UnspecifiedType)firstElementType).setLowerBound(secondElementType);
return true;
}
else {
return false;
}
}
else if (secondElementType instanceof UnspecifiedType) {
Type upperBound = ((UnspecifiedType)secondElementType).getUpperBound();
if (conformsTo(upperBound, firstElementType, bindings)) {
((UnspecifiedType)secondElementType).setUpperBound(firstElementType);
return true;
}
else {
return false;
}
}
else {
return conformsTo(firstElementType, secondElementType, bindings);
}
}
public Collection<org.eclipse.ocl.examples.pivot.Package> computePivotRootPackages() {
Set<org.eclipse.ocl.examples.pivot.Package> rootPackages =
new HashSet<org.eclipse.ocl.examples.pivot.Package>();
if (pivotLibraryResource != null) {
for (EObject eObject : pivotLibraryResource.getContents()) {
if (eObject instanceof org.eclipse.ocl.examples.pivot.Package) {
rootPackages.add((org.eclipse.ocl.examples.pivot.Package) eObject);
}
}
}
for (Resource pivotResource : pivotResourceSet.getResources()) {
for (EObject eObject : pivotResource.getContents()) {
if (eObject instanceof org.eclipse.ocl.examples.pivot.Package) {
rootPackages.add((org.eclipse.ocl.examples.pivot.Package) eObject);
}
}
}
return rootPackages;
}
@Override
public boolean conformsToCollectionType(DomainCollectionType firstCollectionType, DomainCollectionType secondCollectionType) {
return conformsToCollectionType((CollectionType)firstCollectionType, (CollectionType)secondCollectionType, null); // FIXME cast
}
protected boolean conformsToCollectionType(CollectionType firstType, CollectionType secondType,
Map<TemplateParameter, ParameterableElement> bindings) {
CollectionType unspecializedFirstType = PivotUtil.getUnspecializedTemplateableElement(firstType);
CollectionType unspecializedSecondType = PivotUtil.getUnspecializedTemplateableElement(secondType);
if (!isSuperClassOf(unspecializedSecondType, unspecializedFirstType)) {
return false;
}
Type firstElementType = firstType.getElementType();
Type secondElementType = secondType.getElementType();
if (bindings != null) {
if (firstElementType != null) {
TemplateParameter firstTemplateParameter = firstElementType.getOwningTemplateParameter();
if (firstTemplateParameter != null) {
ParameterableElement parameterableElement = bindings.get(firstTemplateParameter);
if (parameterableElement instanceof Type) {
firstElementType = (Type) parameterableElement;
}
}
}
if (secondElementType != null) {
TemplateParameter secondTemplateParameter = secondElementType.getOwningTemplateParameter();
if (secondTemplateParameter != null) {
ParameterableElement parameterableElement = bindings.get(secondTemplateParameter);
if (parameterableElement instanceof Type) {
secondElementType = (Type) parameterableElement;
}
else if ((parameterableElement == null) && bindings.containsKey(secondTemplateParameter)) {
bindings.put(secondTemplateParameter, firstElementType);
return true;
}
}
}
}
if (firstElementType instanceof UnspecifiedType) {
Type lowerBound = ((UnspecifiedType)firstElementType).getLowerBound();
if (conformsTo(secondElementType, lowerBound, bindings)) {
((UnspecifiedType)firstElementType).setLowerBound(secondElementType);
return true;
}
else {
return false;
}
}
else if (secondElementType instanceof UnspecifiedType) {
Type upperBound = ((UnspecifiedType)secondElementType).getUpperBound();
if (conformsTo(upperBound, firstElementType, bindings)) {
((UnspecifiedType)secondElementType).setUpperBound(firstElementType);
return true;
}
else {
return false;
}
}
else {
return conformsTo(firstElementType, secondElementType, bindings);
}
}
protected boolean conformsToLambdaType(LambdaType firstType, LambdaType secondType,
Map<TemplateParameter, ParameterableElement> bindings) {
throw new UnsupportedOperationException();
}
protected boolean conformsToTupleType(TupleType actualType, TupleType requiredType,
Map<TemplateParameter, ParameterableElement> bindings) {
List<Property> actualProperties = actualType.getOwnedAttributes();
List<Property> requiredProperties = requiredType.getOwnedAttributes();
if (actualProperties.size() != requiredProperties.size()) {
return false;
}
for (Property actualProperty : actualProperties) {
Property requiredProperty = PivotUtil.getNamedElement(requiredProperties, actualProperty.getName());
if (requiredProperty == null) {
return false;
}
if (!conformsTo(actualProperty.getType(), requiredProperty.getType(), bindings)) {
return false;
}
}
return true;
}
protected ImplementationManager createImplementationManager() {
return new ImplementationManager(this);
}
public InvalidLiteralExp createInvalidExpression(/*Object object, String boundMessage, Throwable e*/) {
InvalidLiteralExp invalidLiteralExp = PivotFactory.eINSTANCE.createInvalidLiteralExp();
invalidLiteralExp.setType(getOclInvalidType());
// invalidLiteralExp.setObject(object);
// invalidLiteralExp.setReason(boundMessage);
// invalidLiteralExp.setThrowable(e);
return invalidLiteralExp;
}
protected LambdaTypeManager createLambdaManager() {
return new LambdaTypeManager(this);
}
protected Resource createOrphanage() {
return Orphanage.getOrphanage(pivotResourceSet);
}
public org.eclipse.ocl.examples.pivot.Package createPackage(String string, String nsURI) {
return createPackage(org.eclipse.ocl.examples.pivot.Package.class, PivotPackage.Literals.PACKAGE, string, nsURI);
}
public <T extends org.eclipse.ocl.examples.pivot.Package> T createPackage(Class<T> pivotClass,
EClass pivotEClass, String name, String nsURI) {
@SuppressWarnings("unchecked")
T pivotPackage = (T) PivotFactory.eINSTANCE.create(pivotEClass);
pivotPackage.setName(name);
pivotPackage.setNsURI(nsURI);
addPackage(pivotPackage);
// installPackage(pivotPackage);
return pivotPackage;
}
protected PackageManager createPackageManager() {
return new PackageManager(this);
}
protected PrecedenceManager createPrecedenceManager() {
PrecedenceManager precedenceManager = new PrecedenceManager();
Collection<org.eclipse.ocl.examples.pivot.Package> rootPackages = computePivotRootPackages();
List<String> errors = precedenceManager.compilePrecedences(rootPackages);
for (String error : errors) {
logger.error(error);
}
return precedenceManager;
}
public Resource createResource(URI uri, String contentType) {
return pivotResourceSet.createResource(uri, contentType);
}
protected TupleTypeManager createTupleManager() {
return new TupleTypeManager(this);
}
public UnspecifiedType createUnspecifiedType() {
String value = "<unspecified:" + unspecifiedTypeCount++ + ">";
UnspecifiedType unspecifiedType = PivotFactory.eINSTANCE.createUnspecifiedType();
unspecifiedType.setName(value);
unspecifiedType.setLowerBound(getOclAnyType());
unspecifiedType.setUpperBound(getOclVoidType());
addOrphanClass(unspecifiedType);
return unspecifiedType;
}
protected ValueFactory createValueFactory() {
return new PivotValueFactory(this);
}
@Override
public void dispose() {
if (listeners != null) {
List<MetaModelManagerListener> savedListeners = listeners;
listeners = null;
for (MetaModelManagerListener listener : savedListeners) {
listener.metaModelManagerDisposed(this);
}
}
pivotResourceSet.eAdapters().remove(this);
pivotResourceSet.getPackageRegistry().clear();
for (Resource resource : pivotResourceSet.getResources()) {
resource.unload();
}
pivotResourceSet.getResources().clear();
pivotLibraries.clear();
pivotLibraryResource = null;
externalResourceSet = null;
globalNamespaces.clear();
globalTypes.clear();
external2PivotMap.clear();
uriMap = null;
lockingAnnotation = null;
packageManager.dispose();
if (tupleManager != null) {
tupleManager.dispose();
tupleManager = null;
}
if (lambdaManager != null) {
lambdaManager.dispose();
lambdaManager = null;
}
if (precedenceManager != null) {
precedenceManager.dispose();
precedenceManager = null;
}
if (implementationManager != null) {
implementationManager.dispose();
implementationManager = null;
}
if (valueFactory != null) {
valueFactory.dispose();
valueFactory = null;
}
orphanage = null;
pivotMetaModel = null;
super.dispose();
}
/* @Override
protected void finalize() throws Throwable {
System.out.println("Finalize " + getClass().getSimpleName() + "@" + Integer.toHexString(hashCode()));
super.finalize();
Set<MetaModelManager> keySet = liveMetaModelManagers.keySet();
if (!keySet.isEmpty()) {
StringBuilder s = new StringBuilder();
s.append(" live");
for (MetaModelManager metaModelManager : keySet) {
s.append(" @" + Integer.toHexString(metaModelManager.hashCode()));
}
System.out.println(s);
}
} */
/* public <T extends Type> T findOrphanClass(Class<T> unspecializedType, String moniker) {
List<Type> ownedSpecializations = getOrphanPackage().getOwnedTypes();
for (Type ownedSpecialization : ownedSpecializations) {
if (Pivot2Moniker.toString(ownedSpecialization).equals(moniker)) {
@SuppressWarnings("unchecked")
T castSpecialization = (T)ownedSpecialization; // FIXME validate
return castSpecialization;
}
}
return null;
} */
/* protected <T extends Operation> T findOrphanOperation(Class<T> unspecializedOperation, String moniker) {
List<Operation> ownedSpecializations = getOrphanClass().getOwnedOperations();
for (Operation ownedSpecialization : ownedSpecializations) {
if (Pivot2Moniker.toString(ownedSpecialization).equals(moniker)) {
@SuppressWarnings("unchecked")
T castSpecialization = (T)ownedSpecialization; // FIXME validate
return castSpecialization;
}
}
return null;
} */
public PackageTracker findPackageTracker(org.eclipse.ocl.examples.pivot.Package pivotPackage) {
return packageManager.findPackageTracker(pivotPackage);
}
public TypeTracker findTypeTracker(Type pivotType) {
return packageManager.findTypeTracker(pivotType);
}
/**
* Return all constraints applicable to a type and its superclasses.
*/
public Iterable<Constraint> getAllConstraints(Type pivotType) {
if (pivotType == null) {
return Collections.emptyList();
}
Set<Constraint> allConstraints = getAllConstraints(pivotType, null);
if (allConstraints != null) {
return allConstraints;
}
else {
return Collections.emptyList();
}
}
protected Set<Constraint> getAllConstraints(Type type, Set<Constraint> knownConstraints) {
for (Constraint constraint : getLocalConstraints(type)) {
if (knownConstraints == null) {
knownConstraints = new HashSet<Constraint>();
knownConstraints.add(constraint);
}
else if (!knownConstraints.add(constraint)) { // Already contained implies multiple inheritance second visit
return knownConstraints;
}
}
for (Type superType : getSuperClasses(type)) {
knownConstraints = getAllConstraints(superType, knownConstraints);
}
return knownConstraints;
}
public Iterable<Operation> getAllOperations(Operation pivotOperation) {
if (pivotOperation == null) {
return Collections.emptyList();
}
Type pivotClass = pivotOperation.getOwningType();
TypeTracker typeTracker = packageManager.findTypeTracker(pivotClass);
if (typeTracker != null) {
return typeTracker.getTypeServer().getOperations(pivotOperation);
}
else {
return Collections.singletonList(pivotOperation);
}
}
public Iterable<org.eclipse.ocl.examples.pivot.Package> getAllPackages() {
if (!libraryLoadInProgress && (pivotMetaModel == null)) {
lazyLoadPivotMetaModel();
}
return packageManager.getAllPackages();
}
public Iterable<org.eclipse.ocl.examples.pivot.Package> getAllPackages(org.eclipse.ocl.examples.pivot.Package pkg, boolean loadPivotMetaModelFirst) {
if (!libraryLoadInProgress && loadPivotMetaModelFirst && (pivotMetaModel == null)) {
lazyLoadPivotMetaModel();
}
PackageTracker packageTracker = packageManager.findPackageTracker(pkg);
if (packageTracker != null) {
return packageTracker.getPackageServer().getPackages();
}
else {
return Collections.singletonList(pkg);
}
}
public Iterable<Property> getAllProperties(Property pivotProperty) {
if (pivotProperty == null) {
return Collections.emptyList();
}
Type pivotClass = pivotProperty.getOwningType();
TypeTracker typeTracker = packageManager.findTypeTracker(pivotClass);
if (typeTracker != null) {
return typeTracker.getTypeServer().getProperties(pivotProperty);
}
else {
return Collections.singletonList(pivotProperty);
}
}
public Iterable<Type> getAllTypes(Type pivotType) {
if (pivotType == null) {
return Collections.emptyList();
}
TypeTracker typeTracker = packageManager.findTypeTracker(pivotType);
if (typeTracker != null) {
return typeTracker.getTypeServer().getTypes();
}
else {
return Collections.singletonList(pivotType);
}
}
public CollectionType getBagType(DomainType elementType) {
return getBagType(getType(elementType));
}
public CollectionType getBagType(Type elementType) {
return getLibraryType(getBagType(), Collections.singletonList(elementType));
}
public ClassifierType getClassifierType(DomainType instanceType) {
return getClassifierType(getType(instanceType));
}
public ClassifierType getClassifierType(Type instanceType) {
ClassifierType classifierType;
List<Type> templateArguments = new ArrayList<Type>();
templateArguments.add(instanceType);
if (instanceType instanceof org.eclipse.ocl.examples.pivot.Enumeration) {
classifierType = getEnumerationClassifierType();
}
else if (instanceType instanceof CollectionType) {
classifierType = getCollectionClassifierType();
templateArguments.add(((CollectionType) instanceType).getElementType());
}
else {
classifierType = getClassClassifierType();
}
return getLibraryType(classifierType, templateArguments);
}
public CollectionType getCollectionType(boolean isOrdered, boolean isUnique) {
if (isOrdered) {
if (isUnique) {
return getOrderedSetType();
}
else {
return getSequenceType();
}
}
else {
if (isUnique) {
return getSetType();
}
else {
return getBagType();
}
}
}
public CollectionType getCollectionType(boolean isOrdered, boolean isUnique, Type elementType) {
return getLibraryType(getCollectionType(isOrdered, isUnique), Collections.singletonList(elementType));
}
public Type getCollectionType(String collectionTypeName, Type elementType) {
if ((elementType == null) || elementType.eIsProxy()) {
return getOclInvalidType();
}
return getLibraryType(collectionTypeName, Collections.singletonList(elementType));
}
public CollectionType getCollectionType(DomainType genericType, DomainType elementType) {
return getLibraryType((CollectionType)getType(genericType), Collections.singletonList(getType(elementType)));
}
public List<Type> getCommonClasses(Type leftClass, Type rightClass) {
List<Type> commonClasses = null;
if (conformsTo(rightClass, leftClass, null)) {
commonClasses = new ArrayList<Type>();
commonClasses.add(leftClass);
}
for (Type superClass : leftClass.getSuperClasses()) {
List<Type> commonSuperClasses = getCommonClasses(superClass, rightClass);
if (commonSuperClasses != null) {
if (commonClasses == null) {
commonClasses = commonSuperClasses;
}
else {
commonClasses.addAll(commonSuperClasses);
}
}
}
return commonClasses;
}
public Type getCommonType(Type leftType, Type rightType, Map<TemplateParameter, ParameterableElement> templateParameterSubstitutions) {
if (leftType instanceof UnspecifiedType) {
((UnspecifiedType)leftType).setUpperBound(rightType);
return rightType;
}
if (rightType instanceof UnspecifiedType) {
((UnspecifiedType)rightType).setUpperBound(leftType);
return leftType;
}
if ((leftType instanceof TupleType) && (rightType instanceof TupleType)) {
TupleTypeManager tupleManager = getTupleManager();
return tupleManager.getCommonType((TupleType)leftType, (TupleType)rightType, templateParameterSubstitutions);
}
if (conformsTo(leftType, rightType, templateParameterSubstitutions)) {
return rightType;
}
if (conformsTo(rightType, leftType, templateParameterSubstitutions)) {
return leftType;
}
List<Type> commonClasses = getCommonClasses(leftType, rightType);
if (commonClasses == null) {
return null;
}
// FIXME If there are two different common types neither is inherently better
Type mostConformant = null;
for (Type commonClass : commonClasses) {
if (mostConformant == null) {
mostConformant = commonClass;
}
else if (conformsTo(commonClass, mostConformant, templateParameterSubstitutions)) {
mostConformant = commonClass;
}
}
return mostConformant;
}
public String getDefaultStandardLibraryURI() {
return defaultStandardLibraryURI;
}
public ResourceSet getExternalResourceSet() {
if (externalResourceSet == null) {
externalResourceSet = new ResourceSetImpl();
StandaloneProjectMap projectMap = StandaloneProjectMap.findAdapter(pivotResourceSet);
if (projectMap == null) {
StandaloneProjectMap.getAdapter(externalResourceSet);
}
else {
externalResourceSet.eAdapters().add(projectMap);
projectMap.initializeResourceSet(externalResourceSet);
}
MetaModelManagerResourceSetAdapter.getAdapter(externalResourceSet, this);
for (Factory factory : factoryMap) {
factory.configure(externalResourceSet);
}
}
return externalResourceSet;
}
public Set<Map.Entry<String, Namespace>> getGlobalNamespaces() {
return globalNamespaces.entrySet();
}
public Iterable<Type> getGlobalTypes() {
return globalTypes;
}
public LibraryFeature getImplementation(Feature feature) throws ClassNotFoundException, SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
LibraryFeature implementation = feature.getImplementation();
if (implementation == null) {
ImplementationManager implementationManager = getImplementationManager();
implementation = implementationManager.loadImplementation(feature);
}
return implementation;
}
public LibraryFeature getImplementation(Operation operation) throws ClassNotFoundException, SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
if (operation == null) {
return null;
}
LibraryFeature implementation = operation.getImplementation();
if (implementation == null) {
ImplementationManager implementationManager = getImplementationManager();
implementation = implementationManager.getOperationImplementation(operation);
operation.setImplementation(implementation);
}
return implementation;
}
public LibraryFeature getImplementation(Property property) throws ClassNotFoundException, SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
if (property == null) {
return null;
}
LibraryFeature implementation = property.getImplementation();
if (implementation == null) {
ImplementationManager implementationManager = getImplementationManager();
implementation = implementationManager.getPropertyImplementation(property);
property.setImplementation(implementation);
}
return implementation;
}
public ImplementationManager getImplementationManager() {
if (implementationManager == null) {
implementationManager = createImplementationManager();
}
return implementationManager;
}
public Precedence getInfixPrecedence(String operatorName) {
PrecedenceManager precedenceManager = getPrecedenceManager();
return precedenceManager.getInfixPrecedence(operatorName);
}
public ReflectiveExecutorType getInheritance(DomainType type) {
Type type1 = getType(type);
if (type1 == null) {
return null;
}
Type type2 = (Type) type1.getUnspecializedElement();
TypeServer typeServer = getTypeTracker(type2 != null ? type2 : type1).getTypeServer();
return typeServer.getExecutorType();
}
public LambdaTypeManager getLambdaManager() {
if (lambdaManager == null) {
lambdaManager = createLambdaManager();
}
return lambdaManager;
}
public LambdaType getLambdaType(String typeName, Type contextType, List<? extends Type> parameterTypes, Type resultType,
Map<TemplateParameter, ParameterableElement> bindings) {
LambdaTypeManager lambdaManager = getLambdaManager();
return lambdaManager.getLambdaType(typeName, contextType, parameterTypes, resultType, bindings);
}
public List<Library> getLibraries() { return pivotLibraries; }
public Resource getLibraryResource() { return pivotLibraryResource; }
public Type getLibraryType(String string, List<? extends ParameterableElement> templateArguments) {
Type libraryType = getRequiredLibraryType(string);
if (libraryType == null) {
return null;
}
return getLibraryType(libraryType, templateArguments);
}
public <T extends Type> T getLibraryType(T libraryType, List<? extends ParameterableElement> templateArguments) {
assert libraryType == PivotUtil.getUnspecializedTemplateableElement(libraryType);
if ((libraryType == getAnyClassifierType()) && (templateArguments != null) && (templateArguments.size() == 1) && (templateArguments.get(0) == libraryType)) {
return libraryType;
}
TemplateSignature templateSignature = libraryType.getOwnedTemplateSignature();
List<TemplateParameter> templateParameters = templateSignature != null ? templateSignature.getParameters() : Collections.<TemplateParameter>emptyList();
if (templateParameters.isEmpty()) {
return libraryType;
}
if ((templateArguments == null) || (templateArguments.size() != templateParameters.size())) {
throw new IllegalArgumentException(
"Incorrect template bindings for template type");
}
boolean isUnspecialized = isUnspecialized(templateParameters, templateArguments);
if (isUnspecialized) {
return libraryType;
}
TypeSpecializationAdapter typeSpecializationAdapter = TypeSpecializationAdapter.getAdapter(libraryType);
@SuppressWarnings("unchecked")
T specializedType = (T) typeSpecializationAdapter.getSpecializedType(templateArguments);
return specializedType;
}
public Iterable<Type> getLocalClasses(org.eclipse.ocl.examples.pivot.Package pkg) {
return new CompletePackageTypesIterable(getAllPackages(pkg, true));
}
public Iterable<Comment> getLocalComments(Operation operation) {
if (operation.getOwningTemplateParameter() != null) {
return Collections.emptyList();
}
else {
return new CompleteElementCommentsIterable(getAllOperations(operation));
}
}
public Iterable<Comment> getLocalComments(Property property) {
if (property.getOwningTemplateParameter() != null) {
return Collections.emptyList();
}
else {
return new CompleteElementCommentsIterable(getAllProperties(property));
}
}
public Iterable<Comment> getLocalComments(Type type) {
if ((type == null) || (type.getOwningTemplateParameter() != null)) {
return Collections.emptyList();
}
else {
type = PivotUtil.getUnspecializedTemplateableElement(type);
return new CompleteElementCommentsIterable(getAllTypes(type));
}
}
public Iterable<Constraint> getLocalConstraints(Operation operation) {
if (operation.getOwningTemplateParameter() != null) {
return Collections.emptyList();
}
else {
return new CompleteElementConstraintsIterable(getAllOperations(operation));
}
}
public Iterable<Constraint> getLocalConstraints(Property property) {
if (property.getOwningTemplateParameter() != null) {
return Collections.emptyList();
}
else {
return new CompleteElementConstraintsIterable(getAllProperties(property));
}
}
public Iterable<Constraint> getLocalConstraints(Type type) {
if ((type == null) || (type.getOwningTemplateParameter() != null)) {
return Collections.emptyList();
}
else {
type = PivotUtil.getUnspecializedTemplateableElement(type);
return new CompleteElementConstraintsIterable(getAllTypes(type));
}
}
public Iterable<Operation> getLocalOperations(Type type, Boolean selectStatic) {
if ((type == null) || (type.getOwningTemplateParameter() != null)) {
return Collections.emptyList();
}
else {
type = PivotUtil.getUnspecializedTemplateableElement(type);
return new CompleteTypeOperationsIterable(getAllTypes(type), selectStatic);
}
}
public Iterable<org.eclipse.ocl.examples.pivot.Package> getLocalPackages(org.eclipse.ocl.examples.pivot.Package pkg) {
return new CompletePackagePackagesIterable(getAllPackages(pkg, true));
}
public Iterable<Property> getLocalProperties(Type type, Boolean selectStatic) {
if ((type == null) || (type.getOwningTemplateParameter() != null)) {
return Collections.emptyList();
}
else {
type = PivotUtil.getUnspecializedTemplateableElement(type);
return new CompleteClassPropertiesIterable(getAllTypes(type), selectStatic);
}
}
public EObject getLockingObject() {
return lockingAnnotation;
}
public MetaModelManager getMetaModelManager() {
return this;
}
public DomainType getOclType(String typeName) {
return getInheritance(getPivotType(typeName));
}
public CollectionType getOrderedSetType(DomainType elementType) {
return getOrderedSetType(getType(elementType));
}
public CollectionType getOrderedSetType(Type elementType) {
return getLibraryType(getOrderedSetType(), Collections.singletonList(elementType));
}
private Resource getOrphanResource() {
if (orphanage == null) {
orphanage = createOrphanage();
}
return orphanage;
}
public PackageManager getPackageManager() {
return packageManager;
}
public PackageTracker getPackageTracker(org.eclipse.ocl.examples.pivot.Package pivotPackage) {
return packageManager.getPackageTracker(pivotPackage);
}
public org.eclipse.ocl.examples.pivot.Package getPivotMetaModel() { // WIP duplication
if (pivotMetaModel == null) {
AnyType oclAnyType = getOclAnyType();
if (oclAnyType != null) {
org.eclipse.ocl.examples.pivot.Package stdlibPackage = oclAnyType.getPackage();
for (org.eclipse.ocl.examples.pivot.Package aPackage : getAllPackages(stdlibPackage, false)) {
Type anyType = PivotUtil.getNamedElement(aPackage.getOwnedTypes(), PivotPackage.Literals.ELEMENT.getName());
if (anyType != null) {
pivotMetaModel = aPackage;
break;
}
}
if (pivotMetaModel == null) {
OclMetaModel metaModelResource = new OclMetaModel(this, stdlibPackage.getName(), stdlibPackage.getNsURI()); // FIXME duplication of TypeCaches.loadPivotMetaModel
pivotMetaModel = (org.eclipse.ocl.examples.pivot.Package)metaModelResource.getContents().get(0);
addPackage(pivotMetaModel);
}
}
}
return pivotMetaModel;
}
public <T extends NamedElement> T getPivotOfEcore(Class<T> pivotClass, EObject eObject) {
Resource metaModel = eObject.eResource();
Ecore2Pivot ecore2Pivot = Ecore2Pivot.getAdapter(metaModel, this);
return ecore2Pivot.getCreated(pivotClass, eObject);
}
public ResourceSet getPivotResourceSet() {
return pivotResourceSet;
}
/**
* Return the pivot model class for className with the Pivot Model.
*/
public Type getPivotType(String className) {
org.eclipse.ocl.examples.pivot.Package pivotMetaModel = getPivotMetaModel();
if (pivotMetaModel == null) {
return null;
}
return PivotUtil.getNamedElement(pivotMetaModel.getOwnedTypes(), className);
}
protected PrecedenceManager getPrecedenceManager() {
if (precedenceManager == null) {
precedenceManager = createPrecedenceManager();
}
return precedenceManager;
}
public Iterable<? extends Nameable> getPrecedences(org.eclipse.ocl.examples.pivot.Package pivotPackage) {
return pivotPackage.getOwnedPrecedences(); // FIXME make package independent
}
public Precedence getPrefixPrecedence(String operatorName) {
PrecedenceManager precedenceManager = getPrecedenceManager();
return precedenceManager.getPrefixPrecedence(operatorName);
}
@SuppressWarnings("unchecked")
public <T extends EObject> T getPrimaryElement(T element) {
if (element instanceof Operation) {
return (T) getPrimaryOperation((Operation)element);
}
else if (element instanceof org.eclipse.ocl.examples.pivot.Package) {
return (T) getPrimaryPackage((org.eclipse.ocl.examples.pivot.Package)element);
}
else if (element instanceof Property) {
return (T) getPrimaryProperty((Property)element);
}
else if (element instanceof Type) {
return (T) getPrimaryType((Type)element);
}
return element;
}
public Operation getPrimaryOperation(Operation pivotOperation) {
Type pivotClass = pivotOperation.getOwningType();
TypeTracker typeTracker = packageManager.findTypeTracker(pivotClass);
if (typeTracker != null) {
return typeTracker.getTypeServer().getOperation(pivotOperation);
}
else {
return pivotOperation;
}
}
/**
* Lookup a primary package by its URI and optionally a sub-package path.
*/
public org.eclipse.ocl.examples.pivot.Package getPrimaryPackage(String nsURI, String... subPackagePath) {
org.eclipse.ocl.examples.pivot.Package pivotPackage = packageManager.getPackageByURI(nsURI);
if (pivotPackage == null) {
return null;
}
if (subPackagePath != null) {
for (String subPackageName : subPackagePath) {
pivotPackage = getPrimaryPackage(pivotPackage, subPackageName);
if (pivotPackage == null) {
return null;
}
}
}
return pivotPackage;
}
/**
* Lookup a primary sub-package.
*/
public org.eclipse.ocl.examples.pivot.Package getPrimaryPackage(org.eclipse.ocl.examples.pivot.Package parentPackage, String subPackageName) {
PackageTracker packageTracker = packageManager.findPackageTracker(parentPackage);
if (packageTracker != null) {
return packageTracker.getPackageServer().getNestedPackage(subPackageName);
}
else {
return PivotUtil.getNamedElement(parentPackage.getNestedPackages(), subPackageName);
}
}
public org.eclipse.ocl.examples.pivot.Package getPrimaryPackage(org.eclipse.ocl.examples.pivot.Package pivotPackage) {
PackageTracker packageTracker = packageManager.findPackageTracker(pivotPackage);
if (packageTracker != null) {
return packageTracker.getPrimaryPackage();
}
else {
return pivotPackage;
}
}
public Property getPrimaryProperty(Property pivotProperty) {
Type pivotClass = pivotProperty.getOwningType();
TypeTracker typeTracker = packageManager.findTypeTracker(pivotClass);
if (typeTracker != null) {
return typeTracker.getTypeServer().getProperty(pivotProperty.getName());
}
else {
return pivotProperty;
}
}
public Type getPrimaryType(Type pivotType) {
TypeTracker typeTracker = packageManager.findTypeTracker(pivotType);
if (typeTracker != null) {
return typeTracker.getPrimaryType();
}
else {
return pivotType;
}
}
public org.eclipse.ocl.examples.pivot.Type getPrimaryType(String nsURI, String path, String... extraPath) {
org.eclipse.ocl.examples.pivot.Package pivotPackage = packageManager.getPackageByURI(nsURI);
if (pivotPackage == null) {
return null;
}
if ((extraPath == null) || (extraPath.length == 0)) {
return getPrimaryType(pivotPackage, path);
}
else {
pivotPackage = getPrimaryPackage(pivotPackage, path);
if (pivotPackage == null) {
return null;
}
int iMax = extraPath.length-1;
for (int i = 0; i < iMax; i++) {
pivotPackage = getPrimaryPackage(pivotPackage, extraPath[i]);
if (pivotPackage == null) {
return null;
}
}
return getPrimaryType(pivotPackage, extraPath[iMax]);
}
}
/**
* Lookup a primary type.
*/
public Type getPrimaryType(org.eclipse.ocl.examples.pivot.Package parentPackage, String typeName) {
PackageTracker packageTracker = packageManager.findPackageTracker(parentPackage);
if (packageTracker != null) {
return packageTracker.getPackageServer().getType(typeName);
}
else {
return PivotUtil.getNamedElement(getLocalClasses(parentPackage), typeName);
// return PivotUtil.getNamedElement(parentPackage.getOwnedTypes(), typeName);
}
}
/**
* Return the URI to be used for a concrete syntax resource for an expression associated
* with a uniqueContext. If uniqueContext is an Element the moniker is used as
* part of the URI, otherwise a unique value is created and cached for reuse.
*/
public URI getResourceIdentifier(Object uniqueContext, String subContext) {
if (subContext == null) {
subContext = "";
}
URI uri;
if (uniqueContext instanceof Element) {
uri = URI.createURI(Pivot2Moniker.toString((Element) uniqueContext) + subContext + ".essentialocl");
}
else {
if (uriMap == null) {
uriMap = new HashMap<Object,URI>();
}
uri = uriMap.get(uniqueContext);
if (uri == null) {
uri = URI.createURI(EcoreUtil.generateUUID() + subContext + ".essentialocl");
uriMap.put(uniqueContext, uri);
}
}
return uri;
}
public CollectionType getSequenceType(DomainType elementType) {
return getSequenceType(getType(elementType));
}
public CollectionType getSequenceType(Type elementType) {
return getLibraryType(getSequenceType(), Collections.singletonList(elementType));
}
public CollectionType getSetType(DomainType elementType) {
return getSetType(getType(elementType));
}
public CollectionType getSetType(Type elementType) {
return getLibraryType(getSetType(), Collections.singletonList(elementType));
}
protected Type getSpecializedLambdaType(LambdaType type, Map<TemplateParameter, ParameterableElement> usageBindings) {
LambdaType specializedLambdaType = getLambdaType(type.getName(), type.getContextType(), type.getParameterTypes(), type.getResultType(), usageBindings);
return specializedLambdaType;
}
public Type getSpecializedType(Type type, Map<TemplateParameter, ParameterableElement> usageBindings) {
TemplateParameter owningTemplateParameter = type.getOwningTemplateParameter();
if (owningTemplateParameter != null) {
if (usageBindings == null) {
return type;
}
ParameterableElement parameterableElement = usageBindings.get(owningTemplateParameter);
return parameterableElement instanceof Type ? (Type) parameterableElement : type;
}
else if (usageBindings == null) {
return type;
}
else if (type instanceof TupleType) {
return getTupleType((TupleType) type, usageBindings);
}
else if (type instanceof LambdaType) {
return getSpecializedLambdaType((LambdaType)type, usageBindings);
}
else {
//
// Get the bindings of the type.
//
Type unspecializedType = PivotUtil.getUnspecializedTemplateableElement(type);
// List<TemplateParameter> templateParameters = PivotUtil.getAllTemplateParameters(type);
Map<TemplateParameter, ParameterableElement> typeBindings = PivotUtil.getAllTemplateParametersAsBindings(type);
PivotUtil.getAllTemplateParameterSubstitutions(typeBindings, type);
if ((typeBindings != null) && !typeBindings.isEmpty()) {
//
// Re-bind the type bindings to use those of the usage.
//
for (TemplateParameter templateParameter : typeBindings.keySet()) {
ParameterableElement parameterableElement = typeBindings.get(templateParameter);
if (parameterableElement != null) {
TemplateParameter aTemplateParameter = parameterableElement.getOwningTemplateParameter();
if (aTemplateParameter != null) {
ParameterableElement aParameterableElement = usageBindings.get(aTemplateParameter);
if (aParameterableElement != null) {
typeBindings.put(templateParameter, aParameterableElement);
}
}
else if (parameterableElement instanceof SelfType) {
ParameterableElement aParameterableElement = usageBindings.get(null);
if (aParameterableElement != null) {
typeBindings.put(templateParameter, aParameterableElement);
}
}
}
}
//
// Prepare the template argument list, one template argument per template parameter.
//
// Set<TemplateParameter> templateParameters = typeBindings1.keySet();
List<TemplateParameter> templateParameters = PivotUtil.getAllTemplateParameters(unspecializedType);
List<ParameterableElement> templateArguments = new ArrayList<ParameterableElement>(templateParameters.size());
// boolean isSubstituted = false;
for (TemplateParameter templateParameter : templateParameters) {
ParameterableElement templateArgument = typeBindings.get(templateParameter);
if (templateArgument != null) {
// isSubstituted = true;
}
else {
templateArgument = templateParameter.getParameteredElement();
}
if (templateArgument instanceof Type) {
templateArgument = getSpecializedType((Type)templateArgument, usageBindings);
// isSubstituted = true;
}
templateArguments.add(templateArgument);
}
// if (!isSubstituted) {
// return type;
// }
return getLibraryType(unspecializedType, templateArguments);
}
}
return type;
}
protected <T extends Type> T getSpecializedTypeServer(T unspecializedType, List<? extends ParameterableElement> templateArguments) {
TypeSpecializationAdapter typeSpecializationAdapter = TypeSpecializationAdapter.getAdapter(unspecializedType);
@SuppressWarnings("unchecked")
T specializedType = (T) typeSpecializationAdapter.getSpecializedType(templateArguments);
return specializedType;
}
public Iterable<Type> getSuperClasses(Type pivotType) {
if ((pivotType == null) || (pivotType.getOwningTemplateParameter() != null)) {
return Collections.<Type>singletonList(getOclAnyType()); // FIXME lower bound
}
else {
// if (type.getTemplateBindings().size() > 0) { // FIXME need lazy specialization
// pivotType = PivotUtil.getUnspecializedTemplateableElement(pivotType);
// }
if ((pivotMetaModel == null) && (pivotType == getClassType())) {
lazyLoadPivotMetaModel();
}
return new CompleteClassSuperClassesIterable(getAllTypes(pivotType));
}
}
/* public Iterable<org.eclipse.ocl.examples.pivot.Class> getSuperTypes(Type type)
{
if (completeSuperTypes == null)
{
completeSuperTypes = new EObjectResolvingEList<CompleteType>(CompleteType.class, this, PivotPackage.COMPLETE_TYPE__COMPLETE_SUPER_TYPE);
// for (Type superType : getSuperClasses()) {
// completeSuperTypes.add(completeEnvironment.getCompleteType(superType));
// }
for (Type model : models) {
if (model instanceof org.eclipse.ocl.examples.pivot.Class) {
org.eclipse.ocl.examples.pivot.Class thisModelClass = (org.eclipse.ocl.examples.pivot.Class)model;
if (thisModelClass.getTemplateBindings().size() > 0) {
// thisModelClass = PivotUtil.getUnspecializedTemplateableElement((org.eclipse.ocl.examples.pivot.Class)model);
}
for (Type superType : thisModelClass.getSuperClasses()) {
completeSuperTypes.add(completeEnvironment.getCompleteType(superType));
}
}
}
}
return completeSuperTypes;
} */
public ResourceSet getTarget() {
return pivotResourceSet;
}
public TupleTypeManager getTupleManager() {
if (tupleManager == null) {
tupleManager = createTupleManager();
}
return tupleManager;
}
public DomainTupleType getTupleType(List<? extends DomainTypedElement> parts) {
return getTupleType("Tuple", parts, null);
}
public TupleType getTupleType(String typeName, Collection<? extends DomainTypedElement> parts,
Map<TemplateParameter, ParameterableElement> bindings) {
TupleTypeManager tupleManager = getTupleManager();
return tupleManager.getTupleType(typeName, parts, bindings);
}
public TupleType getTupleType(TupleType tupleType, Map<TemplateParameter, ParameterableElement> bindings) {
TupleTypeManager tupleManager = getTupleManager();
return tupleManager.getTupleType(tupleType, bindings);
}
public Type getType(DomainType dType) {
if (dType instanceof Type) {
return (Type) dType;
}
DomainPackage dPackage = dType.getPackage();
String nsURI = dPackage.getNsURI();
org.eclipse.ocl.examples.pivot.Package pPackage = packageManager.getPackageByURI(nsURI);
if (pPackage == null) {
throw new UnsupportedOperationException(); // FIXME
}
return getPrimaryType(pPackage, dType.getName());
}
public DomainType getType(EClass eClass) {
Ecore2Pivot ecore2Pivot = Ecore2Pivot.getAdapter(eClass.eResource(), this);
Type pivotType = ecore2Pivot.getCreated(Type.class, eClass);
return pivotType;
}
public TypeTracker getTypeTracker(Type pivotType) {
TypeTracker typeTracker = packageManager.findTypeTracker(pivotType);
if (typeTracker == null) {
PackageTracker packageTracker = getPackageTracker(pivotType.getPackage());
typeTracker = packageTracker.getTypeTracker(pivotType);
}
return typeTracker;
}
public Type getTypeWithMultiplicity(TypedMultiplicityElement element) {
Type elementType = PivotUtil.getBehavioralType(element.getType());
int upperBound = element.getUpper().intValue();
boolean isMany = (upperBound < 0) || (1 < upperBound);
if (!isMany) {
return elementType;
}
boolean isOrdered = element.isOrdered();
boolean isUnique = element.isUnique();
Type collectionType;
if (isOrdered) {
if (isUnique) {
collectionType = getOrderedSetType();
}
else {
collectionType = getSequenceType();
}
}
else {
if (isUnique) {
collectionType = getSetType();
}
else {
collectionType = getBagType();
}
}
return getLibraryType(collectionType, Collections.singletonList(elementType));
}
public ValueFactory getValueFactory() {
if (valueFactory == null) {
valueFactory = createValueFactory();
}
return valueFactory;
}
protected void installLibrary(Library pivotLibrary) {
String uri = pivotLibrary.getNsURI();
if (pivotLibraries.isEmpty()) {
if (uri == null) {
throw new IllegalLibraryException(OCLMessages.MissingLibraryURI_ERROR_);
}
setDefaultStandardLibraryURI(uri);
pivotLibraries.add(pivotLibrary);
}
else if (!pivotLibraries.contains(pivotLibrary)) {
String libraryURI = getDefaultStandardLibraryURI();
if ((uri != null) && !uri.equals(libraryURI)) {
throw new IllegalLibraryException(NLS.bind(OCLMessages.ImportedLibraryURI_ERROR_, uri , libraryURI));
}
pivotLibraries.add(pivotLibrary);
}
}
public void installPackage(org.eclipse.ocl.examples.pivot.Package pivotPackage) {
if (pivotPackage instanceof Library) {
installLibrary((Library)pivotPackage);
}
addPackage(pivotPackage);
}
/**
* Create implicit an opposite property if there is no explicit opposite.
*/
public void installPropertyDeclaration(Property thisProperty) {
if (thisProperty.isTransient() || thisProperty.isVolatile()) {
return;
}
Property opposite = thisProperty.getOpposite();
if (opposite != null) {
return;
}
Type thatType = thisProperty.getType();
if ((thatType == null) || (thatType instanceof DataType)) {
return;
}
Type thisType = thisProperty.getOwningType();
String name = thisType.getName();
// If there is an explicit property with the implicit name do nothing.
for (Property thatProperty : thatType.getOwnedAttributes()) {
if (name.equals(thatProperty.getName())) {
if (!thatProperty.isImplicit()) {
return;
}
opposite = thatProperty;
}
}
// If there is an implicit property with the implicit name, set its opposite null
// and do no more; result one name with no opposites
if (opposite != null) {
opposite.setOpposite(null);
thisProperty.setOpposite(null);
opposite.setUpper(BigInteger.valueOf(-1));
return;
}
// If there is no implicit property with the implicit name, create one
// result a pair of mutual opposites
opposite = PivotFactory.eINSTANCE.createProperty();
opposite.setImplicit(true);
opposite.setName(name);
opposite.setType(thisType);
opposite.setLower(BigInteger.valueOf(0));
if (thisProperty.isComposite()) {
opposite.setUpper(BigInteger.valueOf(1));
}
else {
opposite.setUpper(BigInteger.valueOf(-1));
}
thatType.getOwnedAttributes().add(opposite); // WIP moved for debugging
opposite.setOpposite(thisProperty);
thisProperty.setOpposite(opposite);
}
public void installResource(Resource pivotResource) {
for (EObject eObject : pivotResource.getContents()) {
if (eObject instanceof org.eclipse.ocl.examples.pivot.Package) {
org.eclipse.ocl.examples.pivot.Package pivotPackage = (org.eclipse.ocl.examples.pivot.Package)eObject;
installPackage(pivotPackage);
// installPackageContent(pivotPackage);
}
}
}
public boolean isAdapterFor(MetaModelManager metaModelManager) {
return this == metaModelManager;
}
protected boolean isUnspecialized(List<TemplateParameter> templateParameters,
List<? extends ParameterableElement> templateArguments) {
int iMax = templateParameters.size();
assert templateArguments.size() == iMax;
boolean isUnspecialized = true;
for (int i = 0; i < iMax; i++) {
if (templateArguments.get(i) != templateParameters.get(i).getParameteredElement()) {
isUnspecialized = false;
}
}
return isUnspecialized;
}
protected void lazyLoadPivotMetaModel() {
if (!pivotLibraries.isEmpty()) {
loadPivotMetaModel(pivotLibraries.get(0));
}
}
public boolean isAdapterForType(Object type) {
return type == MetaModelManager.class;
}
public boolean isSuperClassOf(Type unspecializedFirstType, Type secondType) {
Type unspecializedSecondType = PivotUtil.getUnspecializedTemplateableElement(secondType); // FIXME cast
if (unspecializedFirstType == unspecializedSecondType) {
return true;
}
for (Type superClass : getSuperClasses(unspecializedSecondType)) {
if (isSuperClassOf(unspecializedFirstType, superClass)) {
return true;
}
}
return false;
}
/**
* Retyurn true if this type involves an UnspecifiedType.
*/
public boolean isUnderspecified(ParameterableElement type) {
if (type == null) {
return false;
}
if (type instanceof TemplateableElement) {
for (TemplateBinding templateBinding : ((TemplateableElement)type).getTemplateBindings()) {
for (TemplateParameterSubstitution templateParameterSubstitution : templateBinding.getParameterSubstitutions()) {
if (isUnderspecified((Type) templateParameterSubstitution.getActual())) {
return true;
}
}
}
}
if (type instanceof UnspecifiedType) {
return true;
}
if (type instanceof CollectionType) {
return isUnderspecified(((CollectionType)type).getElementType());
}
if (type instanceof TupleType) {
for (Property part : ((TupleType)type).getOwnedAttributes()) {
if (isUnderspecified(part.getType())) {
return true;
}
}
}
if (type instanceof LambdaType) {
LambdaType lambdaType = (LambdaType)type;
if (isUnderspecified(lambdaType.getContextType())) {
return true;
}
for (Type parameterType : lambdaType.getParameterTypes()) {
if (isUnderspecified(parameterType)) {
return true;
}
}
if (isUnderspecified(lambdaType.getResultType())) {
return true;
}
}
return false;
}
@Override
protected Resource loadDefaultLibrary(String uri) {
if (!pivotLibraries.isEmpty() && (pivotLibraryResource == null)) {
loadLibrary(pivotLibraries.get(0).eResource());
return pivotLibraryResource;
}
if (uri == null) {
return null;
}
StandardLibraryContribution contribution = StandardLibraryContribution.REGISTRY.get(uri);
if (contribution == null) {
return null;
}
Resource resource = contribution.getResource();
loadLibrary(resource);
return resource;
}
public void loadLibrary(Resource pivotResource) {
assert (pivotLibraryResource == null) || (pivotLibraryResource == pivotResource);
if (pivotResource != null) {
pivotLibraryResource = pivotResource;
installResource(pivotResource);
}
for (org.eclipse.ocl.examples.pivot.Package rootPackage : computePivotRootPackages()) {
if (rootPackage instanceof Library) {
if (!pivotLibraries.contains(rootPackage)) {
pivotLibraries.add((Library) rootPackage);
}
loadLibraryPackage(rootPackage);
}
}
}
protected void loadLibraryPackage(org.eclipse.ocl.examples.pivot.Package pivotPackage) {
for (org.eclipse.ocl.examples.pivot.Package nestedPackage : pivotPackage.getNestedPackages()) {
loadLibraryPackage(nestedPackage);
}
for (Type type : pivotPackage.getOwnedTypes()) {
if (PivotUtil.isLibraryType(type)) {
defineLibraryType(type);
}
}
}
protected void loadPivotMetaModel(Library pivotLibrary) {
// PackageTracker libraryTracker = package2tracker.get(pivotLibrary);
for (org.eclipse.ocl.examples.pivot.Package libPackage : getAllPackages(pivotLibrary, false)) {
if (PivotUtil.getNamedElement(libPackage.getOwnedTypes(), PivotPackage.Literals.ELEMENT.getName()) != null) {
pivotMetaModel = libPackage; // Custom meta-model
return;
}
}
OclMetaModel metaModelResource = new OclMetaModel(this, pivotLibrary.getName(), pivotLibrary.getNsURI()); // Standard meta-model
pivotMetaModel = (org.eclipse.ocl.examples.pivot.Package)metaModelResource.getContents().get(0);
addPackage(pivotMetaModel);
}
public Element loadResource(URI uri, String alias, ResourceSet resourceSet) {
// if (EPackage.Registry.INSTANCE.containsKey(resourceOrNsURI))
// return EPackage.Registry.INSTANCE.getEPackage(resourceOrNsURI);
Resource resource;
URI resourceURI = uri.trimFragment();
String resourceURIstring = resourceURI.toString();
if (resourceURIstring.equals(defaultStandardLibraryURI)) {
resource = loadDefaultLibrary(resourceURIstring);
}
else {
StandardLibraryContribution contribution = StandardLibraryContribution.REGISTRY.get(resourceURIstring);
if (contribution != null) {
resource = contribution.getResource();
}
else {
External2Pivot external2Pivot = external2PivotMap.get(uri);
if (external2Pivot != null) {
resource = external2Pivot.getResource();
}
else {
if (resourceSet == null) {
resourceSet = getExternalResourceSet();
}
try {
resource = resourceSet.getResource(resourceURI, true);
}
catch (RuntimeException e) {
resource = resourceSet.getResource(resourceURI, false);
if (resource != null) {
resourceSet.getResources().remove(resource);
resource = null;
}
throw e;
}
// if (resource != null) {
// if (externalResources == null) {
// externalResources = new HashMap<URI, Resource>();
// }
// externalResources.put(uri, resource);
// }
//
// If this resource already loaded under its internal URI reuse old one
//
if (resource != null) {
List<EObject> contents = resource.getContents();
if (contents.size() > 0) {
EObject firstContent = contents.get(0);
for (Factory factory : factoryMap) {
URI packageURI = factory.getPackageURI(firstContent);
if (packageURI != null) {
External2Pivot external2Pivot2 = external2PivotMap.get(packageURI);
if (external2Pivot2 != null) {
resource = external2Pivot2.getResource();
}
break;
}
}
}
}
}
}
}
if (resource != null) {
for (Factory factory : factoryMap) {
if (factory.canHandle(resource)) {
return factory.importFromResource(this, resource, uri.fragment());
}
}
throw new IllegalArgumentException("Cannot create pivot from '" + uri + "'");
// logger.warn("Cannot convert to pivot for package with URI '" + uri + "'");
}
logger.warn("Cannot load package with URI '" + uri + "'");
return null;
}
public LibraryFeature lookupImplementation(DomainOperation dynamicOperation) throws SecurityException, IllegalArgumentException, ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
return getImplementation((Operation) dynamicOperation);
}
// public DomainOperation zzlookupDynamicOperation(DomainType type, DomainOperation staticOperation) {
// return getDynamicOperation(getType(type), getOperation(staticOperation));
// }
public void notifyChanged(Notification notification) {
}
public void removeExternalResource(External2Pivot external2Pivot) {
external2PivotMap.remove(external2Pivot.getURI());
}
public void removeListener(MetaModelManagerListener listener) {
if (listeners != null) {
listeners.remove(listener);
}
}
/**
* Return all matching operations.
*/
protected void resolveAllOperations(Set<Operation> allOperations, Type forType, Boolean selectStatic, String operationName, List<Parameter> parameters, Set<Type> alreadyVisited) {
if (alreadyVisited.add(forType)) {
int iMax = parameters.size();
for (Operation candidateOperation : getLocalOperations(forType, selectStatic)) {
if (operationName.equals(candidateOperation.getName())) {
List<Parameter> candidateParameters = candidateOperation.getOwnedParameters();
if (candidateParameters.size() == iMax) {
int i = 0;
for ( ; i < iMax; i++) {
Type type = parameters.get(i).getType();
Type candidateType = candidateParameters.get(i).getType();
if (type != candidateType) { // FIXME behavioural equivalence
break;
}
}
if (i >= iMax) {
allOperations.add(candidateOperation);
}
}
}
}
for (Type superType : getSuperClasses(forType)) {
resolveAllOperations(allOperations, superType, selectStatic, operationName, parameters, alreadyVisited);
}
}
}
/**
* Return the un-overloaded operation.
*/
public Operation resolveBaseOperation(Operation operation) {
Set<Operation> allOperations = new HashSet<Operation>();
resolveAllOperations(allOperations, operation.getOwningType(), operation.isStatic(), operation.getName(), operation.getOwnedParameters(), new HashSet<Type>());
Operation baseOperation = operation;
for (Operation candidateOperation : allOperations) {
if (candidateOperation != operation) {
Type baseType = baseOperation.getOwningType();
Type candidateType = candidateOperation.getOwningType();
if (conformsTo(baseType, candidateType, null)) {
baseOperation = candidateOperation;
}
}
}
return baseOperation;
}
public Set<Operation> resolveLocalOperation(Type pivotClass, String operationName, Type... pivotArguments) {
Map<TemplateParameter, ParameterableElement> templateParameterSubstitutions = null; // FIXME
Set<Operation> pivotOperations = null;
for (Operation pivotOperation : pivotClass.getOwnedOperations()) {
if (operationName.equals(pivotOperation.getName())) {
List<Parameter> pivotParameters = pivotOperation.getOwnedParameters();
if (pivotArguments.length == pivotParameters.size()) {
boolean typesConform = true;
for (int i = 0; i < pivotArguments.length; i++) {
Type argumentType = pivotArguments[i];
Parameter pivotParameter = pivotParameters.get(i);
Type parameterType = getTypeWithMultiplicity(pivotParameter);
if (parameterType instanceof SelfType) {
parameterType = pivotOperation.getOwningType();
}
if (!conformsTo(argumentType, parameterType, templateParameterSubstitutions)) {
typesConform = false;
break;
}
}
if (typesConform) {
if (pivotOperations == null) {
pivotOperations = new HashSet<Operation>();
}
pivotOperations.add(pivotOperation);
}
}
}
}
return pivotOperations;
}
public Operation resolveOperation(Type leftType, String operationName, Type... rightTypes) {
Set<Operation> candidateOperations = resolveOperations(leftType, operationName, rightTypes);
if (candidateOperations == null) {
return null;
}
if (candidateOperations.size() > 1) {
logger.warn("Ambiguous operation '" + operationName + "'");
}
return candidateOperations.iterator().next();
}
public Set<Operation> resolveOperations(Type pivotClass, String operationName, Type... pivotArguments) {
@SuppressWarnings("unused")
Map<TemplateParameter, ParameterableElement> templateParameterSubstitutions = PivotUtil.getAllTemplateParameterSubstitutions(null, pivotClass);
Set<Operation> pivotOperations = resolveLocalOperation(pivotClass, operationName, pivotArguments);
for (TemplateBinding templateBinding : pivotClass.getTemplateBindings()) {
TemplateSignature signature = templateBinding.getSignature();
TemplateableElement template = signature.getTemplate();
if (template instanceof Type) {
Set<Operation> morePivotOperations = resolveLocalOperation((Type) template, operationName, pivotArguments);
if (morePivotOperations != null) {
if (pivotOperations == null) {
pivotOperations = morePivotOperations;
}
else {
pivotOperations.addAll(morePivotOperations);
}
}
}
}
if (pivotOperations == null) {
List<Type> superClasses = pivotClass.getSuperClasses();
if (!superClasses.isEmpty()) {
for (Type superClass : superClasses) {
Set<Operation> superOperations = resolveOperations(superClass, operationName, pivotArguments);
if (superOperations != null) {
if (pivotOperations == null) {
pivotOperations = superOperations;
} else {
pivotOperations.addAll(superOperations);
}
}
}
}
else {
AnyType oclAnyType = getOclAnyType();
if (pivotClass != oclAnyType) { // Typically a template parameter type
pivotOperations = resolveOperations(oclAnyType, operationName, pivotArguments);
}
}
}
return pivotOperations;
}
public void setDefaultStandardLibraryURI(String defaultStandardLibraryURI) {
this.defaultStandardLibraryURI = defaultStandardLibraryURI;
}
public void setLibraryLoadInProgress(boolean libraryLoadInProgress) {
this.libraryLoadInProgress = libraryLoadInProgress;
}
public void setTarget(Notifier newTarget) {
// assert newTarget == pivotResourceSet;
}
public void unsetTarget(Notifier oldTarget) {
// assert oldTarget == pivotResourceSet;
}
}