blob: ebe3f34f47b13c7f22bd0f0058616e1bbc556810 [file] [log] [blame]
/**
* <copyright>
*
* Copyright (c) 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.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.ocl.examples.domain.library.LibraryFeature;
import org.eclipse.ocl.examples.pivot.Constraint;
import org.eclipse.ocl.examples.pivot.ExpressionInOcl;
import org.eclipse.ocl.examples.pivot.Feature;
import org.eclipse.ocl.examples.pivot.Operation;
import org.eclipse.ocl.examples.pivot.Property;
import org.eclipse.ocl.examples.pivot.TupleType;
import org.eclipse.ocl.examples.pivot.UMLReflection;
import org.eclipse.ocl.examples.pivot.ValueSpecification;
import org.eclipse.ocl.examples.pivot.library.ConstrainedOperation;
import org.eclipse.ocl.examples.pivot.library.ConstrainedProperty;
import org.eclipse.ocl.examples.pivot.library.ExplicitNavigationProperty;
import org.eclipse.ocl.examples.pivot.library.ImplicitCompositionProperty;
import org.eclipse.ocl.examples.pivot.library.ImplicitNonCompositionProperty;
import org.eclipse.ocl.examples.pivot.library.TuplePartProperty;
import org.eclipse.ocl.examples.pivot.library.UnimplementedOperation;
/**
* ImplementationManager encapsulates the knowledge about known feature implementations.
*/
public class ImplementationManager
{
protected final MetaModelManager metaModelManager;
/**
* ClassLoaders that may be able to load a library implementation.
*/
private List<ClassLoader> classLoaders = null;
protected ImplementationManager(MetaModelManager metaModelManager) {
this.metaModelManager = metaModelManager;
}
public void addClassLoader(ClassLoader classLoader) {
List<ClassLoader> classLoaders = getClassLoaders();
if (!classLoaders.contains(classLoader)) {
classLoaders.add(classLoader);
}
}
public List<ClassLoader> getClassLoaders() {
if (classLoaders == null) {
classLoaders = new ArrayList<ClassLoader>();
classLoaders.add(metaModelManager.getClass().getClassLoader());
}
return classLoaders;
}
protected LibraryFeature getOperationImplementation(Operation operation) throws ClassNotFoundException, SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
LibraryFeature implementation = operation.getImplementation();
String implementationClassName = operation.getImplementationClass();
if (implementationClassName != null) {
if ((implementation == null) || !implementation.getClass().getName().equals(implementationClassName)) {
return loadImplementation(operation);
}
}
for (Constraint constraint : metaModelManager.getLocalConstraints(operation)) {
if (UMLReflection.BODY.equals(constraint.getStereotype())) {
ValueSpecification specification = constraint.getSpecification();
if (specification instanceof ExpressionInOcl) {
return new ConstrainedOperation((ExpressionInOcl) specification);
}
}
}
return UnimplementedOperation.INSTANCE;
}
protected LibraryFeature getPropertyImplementation(Property property) throws ClassNotFoundException, SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
LibraryFeature implementation = property.getImplementation();
String implementationClassName = property.getImplementationClass();
if (implementationClassName != null) {
if ((implementation == null) || !implementation.getClass().getName().equals(implementationClassName)) {
return loadImplementation(property);
}
}
for (Constraint constraint : metaModelManager.getLocalConstraints(property)) {
if (UMLReflection.BODY.equals(constraint.getStereotype())) {
ValueSpecification specification = constraint.getSpecification();
if (specification instanceof ExpressionInOcl) {
return new ConstrainedProperty((ExpressionInOcl) specification);
}
}
}
if (property.isImplicit()) {
Property opposite = property.getOpposite();
if (opposite.isComposite()) {
return ImplicitCompositionProperty.INSTANCE;
}
else {
return ImplicitNonCompositionProperty.INSTANCE;
}
}
else if (property.getOwningType() instanceof TupleType) {
return TuplePartProperty.INSTANCE;
}
else {
return ExplicitNavigationProperty.INSTANCE;
}
}
public void dispose() {
classLoaders = null;
}
/**
* Return the implementation of a feature.
*
* @param feature to be implemented.
* @return the implementation, or null if the feature has no implementation
* as is the case for a normal model feature
* @throws ClassNotFoundException if the implementation class realising
* the implementation is not loadable
* @throws NoSuchFieldException if the implementation class realising
* the implementation does not provide a static INSTANCE field
* @throws SecurityException if the implementation class is not accessible
* @throws IllegalAccessException if the implementation class is not accessible
* @throws IllegalArgumentException if the implementation class is not accessible
*/
public LibraryFeature loadImplementation(Feature feature) throws ClassNotFoundException, SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
LibraryFeature implementation = feature.getImplementation();
if (implementation == null) {
String implementationClassName = feature.getImplementationClass();
if (implementationClassName != null) {
Class<?> theClass = null;
addClassLoader(feature.getClass().getClassLoader());
ClassNotFoundException e = null;
for (ClassLoader classLoader : getClassLoaders()) {
try {
theClass = classLoader.loadClass(implementationClassName);
e = null;
break;
} catch (ClassNotFoundException e1) {
if (e == null) {
e = e1;
}
}
}
if (e != null) {
throw e;
}
@SuppressWarnings("null")
Field field = theClass.getField("INSTANCE");
implementation = (LibraryFeature) field.get(null);
}
}
return implementation;
}
}