blob: 8fe67ab94080eba61cbec73bd414a5b0cdb0c2c1 [file] [log] [blame]
/**
* Copyright (c) 2008 INRIA 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:
* INRIA - initial API and implementation
* William Piers - oclType implementation
* Dennis Wagelaar (Vrije Universiteit Brussel)
*/
package org.eclipse.m2m.atl.engine.emfvm.adapter;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.Enumerator;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EEnum;
import org.eclipse.emf.ecore.EEnumLiteral;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.impl.EClassImpl;
import org.eclipse.emf.ecore.impl.EObjectImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xmi.XMIResource;
import org.eclipse.m2m.atl.common.ATLLogger;
import org.eclipse.m2m.atl.core.IModel;
import org.eclipse.m2m.atl.core.IReferenceModel;
import org.eclipse.m2m.atl.core.emf.EMFModel;
import org.eclipse.m2m.atl.engine.emfvm.Messages;
import org.eclipse.m2m.atl.engine.emfvm.VMException;
import org.eclipse.m2m.atl.engine.emfvm.lib.AbstractStackFrame;
import org.eclipse.m2m.atl.engine.emfvm.lib.EnumLiteral;
import org.eclipse.m2m.atl.engine.emfvm.lib.ExecEnv;
import org.eclipse.m2m.atl.engine.emfvm.lib.HasFields;
import org.eclipse.m2m.atl.engine.emfvm.lib.OclType;
import org.eclipse.m2m.atl.engine.emfvm.lib.OclUndefined;
import org.eclipse.m2m.atl.engine.emfvm.lib.Operation;
/**
* The model adapter dedicated to EMF.
*
* @author <a href="mailto:frederic.jouault@univ-nantes.fr">Frederic Jouault</a>
* @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
* @author <a href="mailto:william.piers@obeo.fr">William Piers</a>
* @author <a href="mailto:dennis.wagelaar@vub.ac.be">Dennis Wagelaar</a>
*/
public class EMFModelAdapter implements IModelAdapter {
private boolean allowInterModelReferences;
/**
* Creates an EMF model adapter.
*/
public EMFModelAdapter() {
}
/**
* Sets "allow inter-model references" for this model adapter.
*
* @param allowInterModelRefs
* the parameter value
* @author <a href="mailto:dennis.wagelaar@vub.ac.be">Dennis Wagelaar</a>
*/
public void setAllowInterModelReferences(boolean allowInterModelRefs) {
allowInterModelReferences = allowInterModelRefs;
}
/**
* Returns the name of an eObject.
*
* @param eo
* the eObject
* @return the name of an eObject
*/
public static Object getNameOf(EObject eo) {
Object ret = null;
final EClass ec = eo.eClass();
final EStructuralFeature sf = ec.getEStructuralFeature("name"); //$NON-NLS-1$
if (sf != null) {
ret = eo.eGet(sf);
}
if (ret == null) {
ret = "<unnamed>"; //$NON-NLS-1$
}
return ret;
}
// fix 255613
/**
* Returns the literal matching the given name or literal.
*
* @param eEnum
* the enumeration
* @param id
* the name or the literal
* @return the literal
*/
public static EEnumLiteral getEENumLiteral(EEnum eEnum, String id) {
EEnumLiteral ret = eEnum.getEEnumLiteralByLiteral(id);
if (ret == null) {
ret = eEnum.getEEnumLiteral(id);
}
return ret;
}
/**
* {@inheritDoc}
*
* @see org.eclipse.m2m.atl.engine.emfvm.adapter.IModelAdapter#getSupertypes(java.lang.Object)
*/
@SuppressWarnings("unchecked")
public List<Object> getSupertypes(Object type) {
List ret = null;
if (type != null) {
if (type instanceof EClass) {
ret = ((EClass)type).getESuperTypes();
if (ret.size() == 0) { // extends OclAny
ret = Arrays.asList(new Class[] {Object.class});
} else {
// invert list to comply with regular ATL VM behaviour
final List sts = ret;
ret = new ArrayList(sts.size());
for (int i = sts.size() - 1; i >= 0; i--) {
ret.add(sts.get(i));
}
}
} else {
ret = OclType.getSupertypes().get(type);
if (ret == null) {
// Support for Java subclasses that do not correspond to OCL subtypes
Class sc = ((Class)type).getSuperclass();
if (sc != null) {
ret = Arrays.asList(new Class[] {sc});
}
}
}
}
if (ret == null) {
ret = Collections.EMPTY_LIST;
}
return ret;
}
/**
* {@inheritDoc}
*
* @see org.eclipse.m2m.atl.engine.emfvm.adapter.IModelAdapter#getType(java.lang.Object)
*/
public Object getType(Object value) {
if (value instanceof EObject) {
return ((EObject)value).eClass();
} else if (value instanceof EList) {
return ArrayList.class;
} else if (value != null) {
return value.getClass();
}
return null;
}
/**
* {@inheritDoc}
*
* @see org.eclipse.m2m.atl.engine.emfvm.adapter.IModelAdapter#prettyPrint(org.eclipse.m2m.atl.engine.emfvm.lib.ExecEnv,
* java.io.PrintStream, java.lang.Object)
*/
public boolean prettyPrint(ExecEnv execEnv, PrintStream out, Object value) {
if (value instanceof EClass) {
final EClass c = (EClass)value;
final String mName = execEnv.getModelNameOf(c);
if (mName != null) {
out.print(mName);
} else {
out.print("<unknown>"); //$NON-NLS-1$
}
out.print('!');
String name = c.getName();
if (name == null) {
name = "<unnamed>"; //$NON-NLS-1$
}
out.print(name);
return true;
} else if (value instanceof EObject) {
final EObject eo = (EObject)value;
final IModel model = execEnv.getModelOf(eo);
if (model != null) {
out.print(execEnv.getNameOf(model));
} else {
out.print("<unknown>"); //$NON-NLS-1$
}
out.print('!');
out.print(getNameOf(eo));
out.print(':');
if (model != null) {
final IReferenceModel mModel = model.getReferenceModel();
out.print(execEnv.getNameOf(mModel));
out.print('!');
String name = eo.eClass().getName();
if (name == null) {
name = "<unnamed>"; //$NON-NLS-1$
}
out.print(name);
} else {
prettyPrint(execEnv, out, eo.eClass());
}
return true;
} else if (value instanceof EList) {
out.print("Sequence {"); //$NON-NLS-1$
execEnv.prettyPrintCollection(out, (EList<?>)value);
return true;
}
return false;
}
/**
* {@inheritDoc}
*
* @see org.eclipse.m2m.atl.engine.emfvm.adapter.IModelAdapter#registerVMSupertypes(java.util.Map)
*/
public void registerVMSupertypes(Map<Class<?>, List<Class<?>>> vmSupertypes) {
// EClass extends EObject
vmSupertypes.put(EClassImpl.class, Arrays.asList(new Class<?>[] {EObjectImpl.class}));
// is necessary ? vmSupertypes.put(EObjectImpl.class, Arrays.asList(new Class[] {Object.class}));
}
/**
* {@inheritDoc}
*
* @see org.eclipse.m2m.atl.engine.emfvm.adapter.IModelAdapter#registerVMTypeOperations(java.util.Map)
*/
public void registerVMTypeOperations(Map<Object, Map<String, Operation>> vmTypeOperations) {
// Object
Map<String, Operation> operationsByName = vmTypeOperations.get(Object.class);
operationsByName.put("=", new Operation(2) { //$NON-NLS-1$
@Override
public Object exec(AbstractStackFrame frame) {
Object[] localVars = frame.getLocalVars();
/*
* handle EMF enumeration literals by calling other end's equals() method. Other end
* can be Enumerator, in which case comparison is done according to EMF semantics.
* Other end can also be EnumLiteral, in which case EnumLiteral.equals() handles the
* comparison against EMF Enumerators.
*/
if (localVars[0] instanceof Enumerator) {
return new Boolean(localVars[1].equals(localVars[0]));
}
return new Boolean(localVars[0].equals(localVars[1]));
}
});
operationsByName.put("refGetValue", new Operation(2) { //$NON-NLS-1$
@Override
public Object exec(AbstractStackFrame frame) {
Object[] localVars = frame.getLocalVars();
if (localVars[0] instanceof EObject) {
return EMFModelAdapter.this.get(frame, (EObject)localVars[0],
(String)localVars[1]);
} else {
return ((HasFields)localVars[0]).get(frame, localVars[1]);
}
}
});
operationsByName.put("refSetValue", new Operation(3) { //$NON-NLS-1$
@Override
public Object exec(AbstractStackFrame frame) {
Object[] localVars = frame.getLocalVars();
if (localVars[0] instanceof EObject) {
EMFModelAdapter.this.set(frame, (EObject)localVars[0], (String)localVars[1],
localVars[2]);
} else {
((HasFields)localVars[0]).set(frame, localVars[1], localVars[2]);
}
return localVars[0];
}
});
// TODO document
operationsByName.put("refUnSetValue", new Operation(3) { //$NON-NLS-1$
@Override
public Object exec(AbstractStackFrame frame) {
Object[] localVars = frame.getLocalVars();
if (localVars[0] instanceof EObject) {
EMFModelAdapter.this.unSet(frame, (EObject)localVars[0], (String)localVars[1]);
}
return localVars[0];
}
});
operationsByName.put("oclType", new Operation(1) { //$NON-NLS-1$
@Override
public Object exec(AbstractStackFrame frame) {
Object[] localVars = frame.getLocalVars();
if (localVars[0] instanceof EObject) {
return ((EObject)localVars[0]).eClass();
}
return OclType.getOclTypeFromObject(localVars[0]);
}
});
operationsByName.put("oclIsTypeOf", new Operation(2) { //$NON-NLS-1$
@Override
public Object exec(AbstractStackFrame frame) {
Object[] localVars = frame.getLocalVars();
if (localVars[1] instanceof Class) {
return new Boolean(localVars[1].equals(localVars[0].getClass()));
} else if (localVars[1] instanceof EClass) {
if (localVars[0] instanceof EObject) {
return new Boolean(localVars[1].equals(((EObject)localVars[0]).eClass()));
} else {
return Boolean.FALSE;
}
} else if (localVars[1] instanceof OclType) {
return new Boolean(((OclType)localVars[1]).equals(OclType
.getOclTypeFromObject(localVars[0])));
} else {
throw new VMException(frame, Messages.getString(
"EMFModelAdapter.UNHANDLEDTYPE", localVars[1])); //$NON-NLS-1$
}
}
});
operationsByName.put("oclIsKindOf", new Operation(2) { //$NON-NLS-1$
@Override
public Object exec(AbstractStackFrame frame) {
Object[] localVars = frame.getLocalVars();
if (localVars[1] instanceof Class) {
return new Boolean(((Class<?>)localVars[1]).isInstance(localVars[0]));
} else if (localVars[1] instanceof EClass) {
return new Boolean(((EClass)localVars[1]).isInstance(localVars[0]));
} else if (localVars[1] instanceof OclType) {
OclType selfType = OclType.getOclTypeFromObject(localVars[0]);
return new Boolean(selfType.conformsTo((OclType)localVars[1]));
} else {
throw new VMException(frame, Messages.getString(
"EMFModelAdapter.UNHANDLEDTYPE", localVars[1])); //$NON-NLS-1$
}
}
});
operationsByName.put("refImmediateComposite", new Operation(1) { //$NON-NLS-1$
@Override
// TODO: should only exist on EObject
public Object exec(AbstractStackFrame frame) {
Object[] localVars = frame.getLocalVars();
if (localVars[0] instanceof EObject) {
Object ret = ((EObject)localVars[0]).eContainer();
if (ret == null) {
ret = OclUndefined.SINGLETON;
}
return ret;
} else {
throw new VMException(frame, Messages
.getString("EMFModelAdapter.REFIMMEDIATECOMPOSITE")); //$NON-NLS-1$
}
}
});
// EClass
operationsByName = new HashMap<String, Operation>();
vmTypeOperations.put(EcorePackage.eINSTANCE.getEClass(), operationsByName);
operationsByName.put("allInstancesFrom", new Operation(2) { //$NON-NLS-1$
@Override
public Object exec(AbstractStackFrame frame) {
Object[] localVars = frame.getLocalVars();
IModel model = frame.getExecEnv().getModel(localVars[1]);
if (model == null) {
throw new VMException(frame, Messages.getString(
"EMFModelAdapter.MODELNOTFOUND", localVars[1])); //$NON-NLS-1$
}
return model.getElementsByType(localVars[0]);
}
});
operationsByName.put("allInstances", new Operation(1) { //$NON-NLS-1$
@Override
public Object exec(AbstractStackFrame frame) {
Object[] localVars = frame.getLocalVars();
// could be a Set (actually was) instead of an OrderedSet
Set<Object> ret = new LinkedHashSet<Object>();
EClass ec = (EClass)localVars[0];
// Model rm = getModelOf(ec); // this is not possible when considering referenced
// resources!
for (Iterator<IModel> i = frame.getExecEnv().getModelsByName().values().iterator(); i
.hasNext();) {
IModel model = i.next();
// if ((!model.isTarget()) && (model.getReferenceModel().isModelOf(ec))) {
// ret.addAll(model.getElementsByType(ec));
// }
if (model.getReferenceModel().isModelOf(ec)) {
ret.addAll(model.getElementsByType(ec));
}
}
return ret;
}
});
operationsByName.put("registerHelperAttribute", new Operation(3) { //$NON-NLS-1$
@Override
public Object exec(AbstractStackFrame frame) {
Object[] localVars = frame.getLocalVars();
String name = (String)localVars[1];
String initOperationName = (String)localVars[2];
frame.getExecEnv().registerHelperAttribute(localVars[0], name, initOperationName);
return null;
}
});
operationsByName.put("newInstance", new Operation(1) { //$NON-NLS-1$
@Override
public Object exec(AbstractStackFrame frame) {
Object[] localVars = frame.getLocalVars();
EClass ec = (EClass)localVars[0];
return frame.getExecEnv().newElement(frame, ec);
}
});
operationsByName.put("newInstanceIn", new Operation(2) { //$NON-NLS-1$
@Override
public Object exec(AbstractStackFrame frame) {
Object[] localVars = frame.getLocalVars();
EClass ec = (EClass)localVars[0];
String modelName = (String)localVars[1];
return frame.getExecEnv().newElementIn(frame, ec, modelName);
}
});
operationsByName.put("getInstanceById", new Operation(3) { //$NON-NLS-1$
@Override
public Object exec(AbstractStackFrame frame) {
final Object[] localVars = frame.getLocalVars();
final EMFModel model = (EMFModel)frame.getExecEnv().getModel(localVars[1]);
final Resource resource = model.getResource();
Object ret = resource.getEObject((String)localVars[2]);
if (ret == null) {
ret = OclUndefined.SINGLETON;
}
return ret;
}
});
operationsByName.put("conformsTo", new Operation(2) { //$NON-NLS-1$
@Override
public Object exec(AbstractStackFrame frame) {
Object[] localVars = frame.getLocalVars();
return new Boolean(((EClass)localVars[1]).isSuperTypeOf((EClass)localVars[0]));
}
});
}
/**
* {@inheritDoc}
*
* @see org.eclipse.m2m.atl.engine.emfvm.adapter.IModelAdapter#get(org.eclipse.m2m.atl.engine.emfvm.lib.AbstractStackFrame,
* java.lang.Object, java.lang.String)
*/
public Object get(AbstractStackFrame frame, Object modelElement, String name) {
Object ret = null;
if (modelElement instanceof Collection<?>) {
throw new VMException(frame, Messages.getString("EMFModelAdapter.GET_ON_COLLECTION")); //$NON-NLS-1$
}
if (modelElement == null || modelElement.equals(OclUndefined.SINGLETON)) {
throw new VMException(frame, Messages.getString("EMFModelAdapter.GET_PROBLEM", name)); //$NON-NLS-1$
} else if (modelElement instanceof EObject) {
EObject eo = (EObject)modelElement;
EClass ec = eo.eClass();
if ((frame != null) && frame.getExecEnv().isHelper(ec, name)) {
ret = frame.getExecEnv().getHelperValue(frame, ec, eo, name);
} else if ("__xmiID__".equals(name)) { //$NON-NLS-1$
ret = getID(eo);
} else {
EStructuralFeature sf = ec.getEStructuralFeature(name);
if (sf == null) {
throw new VMException(frame, Messages.getString(
"EMFModelAdapter.FEATURE_NOT_EXISTS", new Object[] {name, ec.getName()})); //$NON-NLS-1$
}
Object val = eo.eGet(sf);
if (val == null) {
val = OclUndefined.SINGLETON;
} else if (val instanceof Enumerator) {
val = new EnumLiteral(val.toString());
} else if (val instanceof Collection) {
if (sf.getEType() instanceof EEnum) {
Collection<Object> c = new ArrayList<Object>();
for (Iterator<?> i = ((Collection<?>)val).iterator(); i.hasNext();) {
Object v = i.next();
c.add(new EnumLiteral(v.toString()));
}
val = c;
}
}
ret = val;
}
} else {
throw new VMException(frame, Messages.getString("EMFModelAdapter.GET_ON_OBJECT", modelElement.getClass().getName())); //$NON-NLS-1$
}
return ret;
}
// TODO analyze:
// - could be different (faster?) when same metamodel in source and target
// - may be too permissive (any value for which toString returns a valid literal name works)
// - should flatten nested collections
/**
* {@inheritDoc}
*
* @see org.eclipse.m2m.atl.engine.emfvm.adapter.IModelAdapter#set(org.eclipse.m2m.atl.engine.emfvm.lib.AbstractStackFrame,
* java.lang.Object, java.lang.String, java.lang.Object)
*/
@SuppressWarnings("unchecked")
public void set(AbstractStackFrame frame, Object modelElement, String name, Object value) {
Object settableValue = value;
if (settableValue == null || value.equals(OclUndefined.SINGLETON)) {
return;
}
final EObject eo = (EObject)modelElement;
if ("__xmiID__".equals(name)) { //$NON-NLS-1$
setID(eo, value);
}
final EStructuralFeature feature = eo.eClass().getEStructuralFeature(name);
if (frame != null) {
if (frame.getExecEnv().isWeavingHelper(eo.eClass(), name)) {
frame.getExecEnv().setHelperValue(modelElement, name, value);
return;
}
}
if (feature == null) {
throw new VMException(frame, Messages.getString(
"EMFModelAdapter.FEATURE_NOT_EXISTS", name, eo.eClass().getName())); //$NON-NLS-1$
}
if (!feature.isChangeable()) {
throw new VMException(frame, Messages.getString(
"EMFModelAdapter.FEATURE_NOT_CHANGEABLE", name)); //$NON-NLS-1$
}
if (settableValue instanceof Integer) {
String targetType = feature.getEType().getInstanceClassName();
if ("java.lang.Double".equals(targetType) || "double".equals(targetType)) { //$NON-NLS-1$ //$NON-NLS-2$
settableValue = new Double(((Integer)value).doubleValue());
} else if ("java.lang.Float".equals(targetType) || "float".equals(targetType)) { //$NON-NLS-1$ //$NON-NLS-2$
settableValue = new Float(((Integer)value).floatValue());
}
} else if (settableValue instanceof Double) {
String targetType = feature.getEType().getInstanceClassName();
if ("java.lang.Float".equals(targetType) || "float".equals(targetType)) { //$NON-NLS-1$//$NON-NLS-2$
settableValue = new Float(((Double)value).floatValue());
}
}
EClassifier type = feature.getEType();
boolean targetIsEnum = type instanceof EEnum;
try {
ExecEnv execEnv = frame.getExecEnv();
Object oldValue = eo.eGet(feature);
if (oldValue instanceof Collection) {
Collection<Object> oldCol = (Collection<Object>)oldValue;
if (settableValue instanceof Collection) {
if (targetIsEnum) {
EEnum eenum = (EEnum)type;
for (Iterator<?> i = ((Collection<?>)settableValue).iterator(); i.hasNext();) {
Object v = i.next();
oldCol.add(getEENumLiteral(eenum, v.toString()).getInstance());
}
} else {
for (Iterator<?> i = ((Collection<?>)settableValue).iterator(); i.hasNext();) {
Object v = i.next();
if (v instanceof EObject) {
if (execEnv.getModelOf(eo) == execEnv.getModelOf(v)) {
oldCol.add(v);
} else if (allowInterModelReferences && feature instanceof EReference) {
EReference ref = (EReference)feature;
if (!ref.isContainer() && !ref.isContainment()) {
oldCol.add(v);
} else {
// containment references cannot span across models
}
}
} else {
oldCol.add(v);
}
}
}
} else {
if (targetIsEnum) {
EEnum eenum = (EEnum)type;
oldCol.add(getEENumLiteral(eenum, settableValue.toString()).getInstance());
} else if (allowInterModelReferences || !(settableValue instanceof EObject)) {
oldCol.add(settableValue);
} else { // (!allowIntermodelReferences) && (value instanceof EObject)
if (execEnv.getModelOf(eo) == execEnv.getModelOf(settableValue)) {
oldCol.add(settableValue);
}
}
}
} else {
if (settableValue instanceof Collection) {
ATLLogger.warning(Messages.getString("EMFModelAdapter.ASSIGNMENTWARNING")); //$NON-NLS-1$
Collection<?> c = (Collection<?>)settableValue;
if (!c.isEmpty()) {
settableValue = c.iterator().next();
} else {
settableValue = null;
}
}
if (targetIsEnum) {
EEnum eenum = (EEnum)type;
if (settableValue != null) {
EEnumLiteral literal = getEENumLiteral(eenum, settableValue.toString());
if (literal != null) {
eo.eSet(feature, literal.getInstance());
} else {
throw new VMException(
frame,
Messages
.getString(
"EMFModelAdapter.LITERALERROR", new Object[] {settableValue, eenum.getName()})); //$NON-NLS-1$
}
}
} else if (allowInterModelReferences || !(settableValue instanceof EObject)) {
eo.eSet(feature, settableValue);
} else { // (!allowIntermodelReferences) && (value intanceof EObject)
if (execEnv.getModelOf(eo) == execEnv.getModelOf(settableValue)) {
eo.eSet(feature, settableValue);
}
}
}
} catch (Throwable e) {
throw new VMException(frame, e.getMessage(), e);
}
}
/**
* {@inheritDoc}
*
* @see org.eclipse.m2m.atl.engine.emfvm.adapter.IModelAdapter#unSet(org.eclipse.m2m.atl.engine.emfvm.lib.AbstractStackFrame,
* java.lang.Object, java.lang.String)
*/
public void unSet(AbstractStackFrame frame, Object modelElement, String name) {
final EObject eo = (EObject)modelElement;
final EStructuralFeature feature = eo.eClass().getEStructuralFeature(name);
if (feature == null) {
throw new VMException(frame, Messages.getString(
"EMFModelAdapter.FEATURE_NOT_EXISTS", name, eo.eClass().getName())); //$NON-NLS-1$
}
eo.eUnset(feature);
}
/**
* {@inheritDoc}
*
* @see org.eclipse.m2m.atl.engine.emfvm.adapter.IModelAdapter#delete(org.eclipse.m2m.atl.engine.emfvm.lib.AbstractStackFrame,
* java.lang.Object)
*/
public void delete(AbstractStackFrame frame, Object modelElement) {
EObject eo = (EObject)modelElement;
eo.eAdapters().clear();
EcoreUtil.remove(eo);
}
/**
* {@inheritDoc}
*
* @see org.eclipse.m2m.atl.engine.emfvm.adapter.IModelAdapter#invoke(java.lang.reflect.Method,
* java.lang.Object, java.lang.Object[])
*/
public Object invoke(Method method, Object self, Object[] arguments) {
Object res = null;
try {
res = method.invoke(self, arguments);
} catch (IllegalAccessException e) {
throw new VMException(null, Messages.getString(
"EMFModelAdapter.UNABLE_TO_INVOKE_OPERATION", method.getName(), self), e); //$NON-NLS-1$
} catch (InvocationTargetException e) {
Throwable cause = e.getCause();
Exception toReport = (cause instanceof Exception) ? (Exception)cause : e;
throw new VMException(null, Messages.getString(
"EMFModelAdapter.INVOKE_OPERATION_ERROR", method.getName(), self), toReport); //$NON-NLS-1$
}
return res == null && method.getReturnType() != void.class ? OclUndefined.SINGLETON : res;
}
/**
* {@inheritDoc}
*
* @see org.eclipse.m2m.atl.engine.emfvm.adapter.IModelAdapter#finalizeModel(org.eclipse.m2m.atl.core.IModel)
*/
public void finalizeModel(IModel model) {
if (model.isTarget()) {
((EMFModel)model).commitToResource();
}
}
/**
* {@inheritDoc}
*
* @see org.eclipse.m2m.atl.engine.emfvm.adapter.IModelAdapter#getID(java.lang.Object)
*/
public Object getID(Object element) {
if (element instanceof EObject) {
EObject eo = (EObject)element;
return eo.eResource().getURIFragment(eo);
}
return null;
}
/**
* {@inheritDoc}
*
* @see org.eclipse.m2m.atl.engine.emfvm.adapter.IModelAdapter#setID(java.lang.Object, java.lang.Object)
*/
public void setID(Object element, Object id) {
if (element instanceof EObject) {
EObject eo = (EObject)element;
Resource resource = eo.eResource();
if (resource instanceof XMIResource) {
XMIResource xmiResource = (XMIResource)resource;
// WARNING: Allowed manual setting of XMI ID for the current model element
// This operation is advised against but seems necessary of some special case
ATLLogger
.warning("Manual setting of " + getNameOf(eo) + ":" + eo.eClass().getName() + " XMI ID."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
xmiResource.setID(eo, id.toString());
}
}
}
/**
* {@inheritDoc}
*
* @see org.eclipse.m2m.atl.engine.emfvm.adapter.IModelAdapter#isModelElement(java.lang.Object)
*/
public boolean isModelElement(Object o) {
return o instanceof EObject;
}
}