blob: 90054aa71ca0e637f7d2495f42f58928656dc626 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011, 2021 Willink Transformations and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* E.D.Willink - Initial API and implementation
*******************************************************************************/
package org.eclipse.ocl.pivot.internal.library.executor;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.CollectionType;
import org.eclipse.ocl.pivot.CompleteInheritance;
import org.eclipse.ocl.pivot.MapType;
import org.eclipse.ocl.pivot.Operation;
import org.eclipse.ocl.pivot.Property;
import org.eclipse.ocl.pivot.Type;
import org.eclipse.ocl.pivot.ids.TypeId;
import org.eclipse.ocl.pivot.internal.library.ecore.EcoreExecutorPackage;
import org.eclipse.ocl.pivot.oclstdlib.OCLstdlibTables;
import org.eclipse.ocl.pivot.utilities.NameUtil;
public class ExecutorStandardLibrary extends ExecutableStandardLibrary
{
private @NonNull Map<@NonNull String, WeakReference<@NonNull EcoreExecutorPackage>> ePackageMap = new WeakHashMap<>();
private Map<org.eclipse.ocl.pivot.@NonNull Package, @NonNull WeakReference<@NonNull DomainReflectivePackage>> asPackageMap = null;
private /*@LazyNonNull*/ Map<@NonNull EcoreExecutorPackage, @NonNull List<@NonNull EcoreExecutorPackage>> extensions = null;
private /*@LazyNonNull*/ org.eclipse.ocl.pivot.Class classType = null;
private /*@LazyNonNull*/ org.eclipse.ocl.pivot.Class enumerationType = null;
public ExecutorStandardLibrary(EcoreExecutorPackage... execPackages) {
OCLstdlibTables.PACKAGE.getClass();
for (EcoreExecutorPackage execPackage : execPackages) {
assert execPackage != null;
addPackage(execPackage, null);
}
}
public void addExtension(@NonNull EcoreExecutorPackage basePackage, @NonNull EcoreExecutorPackage extensionPackage) {
Map<@NonNull EcoreExecutorPackage, @NonNull List<@NonNull EcoreExecutorPackage>> extensions2 = extensions;
if (extensions2 == null) {
extensions = extensions2 = new HashMap<>();
}
List<@NonNull EcoreExecutorPackage> list = extensions2.get(basePackage);
if (list == null) {
list = new ArrayList<>();
extensions2.put(basePackage, list);
}
list.add(extensionPackage);
}
public synchronized void addPackage(@NonNull EcoreExecutorPackage execPackage, @Nullable EcoreExecutorPackage extendedPackage) {
String uri = execPackage.getURI();
assert uri != null;
@SuppressWarnings("unused")
WeakReference<@NonNull EcoreExecutorPackage> oldExecPackage = ePackageMap.put(uri, new WeakReference<>(execPackage));
// if ((oldExecPackage != null) && (oldExecPackage != execPackage)) {
// Iterable<ExecutorType> newTypes = execPackage.getOwnedType();
// for (DomainType oldType : oldExecPackage.getOwnedType()) {
// -- check for type compatibility
// }
// }
}
@Override
public org.eclipse.ocl.pivot.@NonNull Class getClassType() {
Map<@NonNull EcoreExecutorPackage, @NonNull List<@NonNull EcoreExecutorPackage>> extensions2 = extensions;
if (extensions2 == null) {
throw new IllegalStateException("No extension package registered to define Class type"); //$NON-NLS-1$
}
if (classType != null) {
return classType;
}
classType = getPivotType(TypeId.CLASS_NAME);
if (classType != null) {
return classType;
}
throw new IllegalStateException("No extension package defines Class type"); //$NON-NLS-1$
}
@Override
public org.eclipse.ocl.pivot.@NonNull Class getEnumerationType() {
Map<@NonNull EcoreExecutorPackage, @NonNull List<@NonNull EcoreExecutorPackage>> extensions2 = extensions;
if (extensions2 == null) {
throw new IllegalStateException("No extension package registered to define Enumeration type"); //$NON-NLS-1$
}
if (enumerationType != null) {
return enumerationType;
}
enumerationType = getPivotType(TypeId.ENUMERATION_NAME);
if (enumerationType != null) {
return enumerationType;
}
throw new IllegalStateException("No extension package defines Enumeration type"); //$NON-NLS-1$
}
@Override
public @NonNull CompleteInheritance getInheritance(org.eclipse.ocl.pivot.@NonNull Class asClass) {
if (asClass instanceof CompleteInheritance) {
return (CompleteInheritance) asClass;
}
/* if (type instanceof DomainMetaclass) {
DomainType instanceType = ClassUtil.nonNullPivot(((DomainMetaclass)type).getInstanceType());
org.eclipse.ocl.pivot.Class metaclass = getMetaclass(instanceType);
DomainType containerType = metaclass;//.getContainerType();
return containerType.getInheritance(this);
} */
if (asClass instanceof CollectionType) {
Type containerType = ((CollectionType)asClass).getContainerType();
if (containerType != asClass) {
return containerType.getInheritance(this);
}
}
if (asClass instanceof MapType) {
Type containerType = ((MapType)asClass).getContainerType();
if (containerType != asClass) {
return containerType.getInheritance(this);
}
}
org.eclipse.ocl.pivot.Package asPackage = asClass.getOwningPackage();
Map<org.eclipse.ocl.pivot.@NonNull Package, @NonNull WeakReference<@NonNull DomainReflectivePackage>> asPackageMap2;
synchronized (this) {
String nsURI = asPackage.getURI();
EcoreExecutorPackage ecoreExecutorPackage = nsURI != null ? weakGet(ePackageMap, nsURI) : null;
if (ecoreExecutorPackage != null) {
String name = asClass.getName();
CompleteInheritance executorType = ecoreExecutorPackage.getOwnedClass(name);
if (executorType != null) {
return executorType;
}
Map<@NonNull EcoreExecutorPackage, @NonNull List<@NonNull EcoreExecutorPackage>> extensions2 = extensions;
if (extensions2 != null) {
List<@NonNull EcoreExecutorPackage> packages = extensions2.get(ecoreExecutorPackage);
if (packages != null) {
for (@NonNull EcoreExecutorPackage extensionPackage : packages) {
executorType = extensionPackage.getOwnedClass(name);
if (executorType != null) {
break;
}
}
}
}
if (executorType != null) {
return executorType;
}
}
asPackageMap2 = asPackageMap;
if (asPackageMap2 == null) {
asPackageMap2 = asPackageMap = new WeakHashMap<>();
}
}
synchronized (asPackageMap2) {
DomainReflectivePackage executorPackage = weakGet(asPackageMap2, asPackage);
if (executorPackage == null) {
executorPackage = new DomainReflectivePackage(this, asPackage);
asPackageMap2.put(asPackage, new WeakReference<>(executorPackage));
}
return executorPackage.getInheritance(asClass);
}
}
@Override
public org.eclipse.ocl.pivot.@Nullable Class getNestedType(org.eclipse.ocl.pivot.@NonNull Package parentPackage, @NonNull String name) {
org.eclipse.ocl.pivot.Class nestedType = NameUtil.getNameable(parentPackage.getOwnedClasses(), name);
if (nestedType != null) {
return nestedType;
}
nestedType = getPivotType(name);
return nestedType;
}
@Override
public org.eclipse.ocl.pivot.Package getNsURIPackage(@NonNull String nsURI) {
WeakReference<EcoreExecutorPackage> weakReference = ePackageMap.get(nsURI);
if (weakReference == null) {
return null;
}
return weakReference.get();
}
/**
* @since 1.14
*/
@Override
public @NonNull Set<@NonNull String> getNsURIs() {
return ePackageMap.keySet();
}
@Override
public @NonNull Operation getOclInvalidOperation() {
throw new UnsupportedOperationException();
}
/**
* @since 1.4
*/
@Override
public @NonNull Property getOclInvalidProperty() {
throw new UnsupportedOperationException();
}
public synchronized @Nullable EcoreExecutorPackage getPackage(@NonNull EPackage ePackage) {
String nsURI = ePackage.getNsURI();
return nsURI != null ? weakGet(ePackageMap, nsURI) : null;
}
@Override
public synchronized org.eclipse.ocl.pivot.Class getOclType(@NonNull String typeName) {
for (WeakReference<EcoreExecutorPackage> dPackage : ePackageMap.values()) {
// FIXME if (OCLstdlibTables.PACKAGE.getNsURI().equals(dPackage.getNsURI())) {
if (dPackage != null) {
EcoreExecutorPackage packageRef = dPackage.get();
if (packageRef != null) {
org.eclipse.ocl.pivot.Class type = packageRef.getOwnedClass(typeName);
if (type != null) {
return type;
}
}
}
}
return null;
}
@Override
public org.eclipse.ocl.pivot.@Nullable Class getPivotType(@NonNull String className) {
Map<EcoreExecutorPackage, List<EcoreExecutorPackage>> extensions2 = extensions;
if (extensions2 != null) {
for (@SuppressWarnings("null")@NonNull List<EcoreExecutorPackage> packages : extensions2.values()) {
for (@SuppressWarnings("null")@NonNull EcoreExecutorPackage extensionPackage : packages) {
org.eclipse.ocl.pivot.Class executorType = extensionPackage.getOwnedClass(className);
if (executorType != null) {
return executorType;
}
}
}
}
return null;
}
}