blob: ad8b1e5d2c3178d2d74d58916f0f6d45096a194e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008, 2010 Borland Software Corporation 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:
* Borland Software Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.m2m.internal.qvt.oml.evaluator;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EFactory;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtOperationalEvaluationEnv;
import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtOperationalStdLibrary;
import org.eclipse.m2m.internal.qvt.oml.cst.adapters.AbstractGenericAdapter;
import org.eclipse.m2m.internal.qvt.oml.expressions.ContextualProperty;
import org.eclipse.m2m.internal.qvt.oml.expressions.Module;
import org.eclipse.m2m.internal.qvt.oml.expressions.ModuleImport;
/**
* @author sboyko
*
*/
public class IntermediatePropertyModelAdapter extends AbstractGenericAdapter<IntermediatePropertyModelAdapter> {
private IntermediatePropertyModelAdapter() {
}
public boolean isAdapterForType(Object type) {
return type == IntermediatePropertyModelAdapter.class;
}
@Override
public boolean equals(Object obj) {
return obj instanceof IntermediatePropertyModelAdapter;
}
@Override
public int hashCode() {
return IntermediatePropertyModelAdapter.class.hashCode();
}
public static ShadowEntry getPropertyHolder(EObject moduleInstance, ContextualProperty property, Object ownerInstance) {
IntermediatePropertyModelAdapter adapter = (IntermediatePropertyModelAdapter) EcoreUtil.getAdapter(moduleInstance.eAdapters(),
IntermediatePropertyModelAdapter.class);
if (adapter == null) {
adapter = new IntermediatePropertyModelAdapter();
moduleInstance.eAdapters().add(adapter);
}
return adapter.getPropertyHolder(property, ownerInstance);
}
private ShadowEntry getPropertyHolder(ContextualProperty property, Object ownerInstance) {
ShadowEntry runtimeShadow = myProp2HolderMap.get(property);
if(runtimeShadow == null) {
runtimeShadow = new ShadowEntry(myPropShadowHelper.createShadowProperty(property));
myProp2HolderMap.put(property, runtimeShadow);
}
return runtimeShadow;
}
private static Object getInitialValue(EStructuralFeature feature, QvtOperationalEvaluationEnv evalEnv) {
//return myInitExpression.accept(evalVisitor);
return EvaluationUtil.createInitialValue(feature.getEType(), QvtOperationalStdLibrary.INSTANCE.getOCLStdLib(), evalEnv);
}
private final Map<ContextualProperty, ShadowEntry> myProp2HolderMap = new IdentityHashMap<ContextualProperty, ShadowEntry>(2);
private final RuntimePropertyShadowHelper myPropShadowHelper = new RuntimePropertyShadowHelper();
public static class ShadowEntry {
private EStructuralFeature myFeature;
private Map<Object, EObject> myOwner2ShadowMap = new IdentityHashMap<Object, EObject>();
private ShadowEntry(EStructuralFeature runtimeFeature) {
assert runtimeFeature != null;
myFeature = runtimeFeature;
}
public EStructuralFeature getProperty() {
return myFeature;
}
public EObject getPropertyRuntimeOwner(Object shadowedInstance, QvtOperationalEvaluationEnv evalEnv) {
EObject owner = myOwner2ShadowMap.get(shadowedInstance);
if (owner == null) {
EClass ownerClass = myFeature.getEContainingClass();
EFactory eFactory = ownerClass.getEPackage().getEFactoryInstance();
owner = eFactory.create(ownerClass);
myOwner2ShadowMap.put(shadowedInstance, owner);
Object initialValue = getInitialValue(myFeature, evalEnv);
if (initialValue != null) {
owner.eSet(myFeature, initialValue);
}
}
return owner;
}
}
/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=279251 */
public static void cleanup(Module module) {
cleanup(module, new HashSet<Module>());
}
private static void cleanup(Module module, Set<Module> processed) {
Adapter adapter = EcoreUtil.getExistingAdapter(module, IntermediatePropertyModelAdapter.class);
if(adapter != null) {
module.eAdapters().remove(adapter);
}
processed.add(module);
for(ModuleImport nextImport : module.getModuleImport()) {
Module importedModule = nextImport.getImportedModule();
if(!processed.contains(importedModule)) {
cleanup(importedModule, processed);
}
}
}
}