blob: 6b972d772be7e7f24df7db5f5592d02acdda971b [file] [log] [blame]
/**
* Copyright (c) 2014 ESEO.
* 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:
* ESEO - initial API and implementation
*
* $Id$
*/
package org.eclipse.gmt.tcs.metadata.adhoc;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.gmt.tcs.injector.ModelAdapter;
import org.eclipse.m2m.atl.drivers.emf4atl.ASMEMFModelElement;
import org.eclipse.m2m.atl.engine.emfvm.lib.ExecEnv;
import org.eclipse.m2m.atl.engine.emfvm.lib.Operation;
import org.eclipse.m2m.atl.engine.emfvm.lib.Tuple;
/**
* This ModelAdapter delegates to another ModelAdapter but catches settings of non-existing properties, which it virtualizes.
*
* @author Frédéric Jouault
*/
public class VirtualModelAdapter implements ModelAdapter {
private ModelAdapter actualModelAdapter;
// <Tuple>
private Set allProperties = new LinkedHashSet();
// <Object, Map<String, Object>>
private Map virtualProperties = new HashMap();
private ExecEnv execEnv;
public VirtualModelAdapter(ModelAdapter actualModelAdapter) {
this(actualModelAdapter, null);
}
public VirtualModelAdapter(ModelAdapter actualModelAdapter, ExecEnv execEnv) {
this.actualModelAdapter = actualModelAdapter;
this.execEnv = execEnv;
}
public Object get(Object ame_, String propertyName) {
if(this.execEnv != null) {
Operation op = execEnv.getOperation(this.actualModelAdapter.getType(ame_), "get");
return op.exec(null);
} else {
return this.actualModelAdapter.get(ame_, propertyName);
}
}
public Object createElement(String typeName) {
return this.actualModelAdapter.createElement(typeName);
}
public Set getElementsByType(String typeName) {
return this.actualModelAdapter.getElementsByType(typeName);
}
public Object getType(Object me_) {
return this.actualModelAdapter.getType(me_);
}
public boolean isCandidate(Object ame, String typeName) {
return this.actualModelAdapter.isCandidate(ame, typeName);
}
public void set(Object ame, String prop, Object value) {
try {
this.actualModelAdapter.set(ame, prop, value);
} catch(RuntimeException vme) {
if(vme.getMessage().matches("Feature.* does not exist on .*")) { // TODO: improve detection of non-existing property
// <String, Object>
Map valueByPropertyName = (Map)this.virtualProperties.get(ame);
if(valueByPropertyName == null) {
valueByPropertyName = new HashMap();
this.virtualProperties.put(ame, valueByPropertyName);
}
if(valueByPropertyName.containsKey(prop)) {
Object prev = valueByPropertyName.get(prop);
if(prev instanceof Collection) {
((Collection)prev).add(value);
} else {
Collection c = new ArrayList();
c.add(prev);
c.add(value);
valueByPropertyName.put(prop, c);
}
} else {
valueByPropertyName.put(prop, value);
}
Tuple t = new Tuple();
t.set(null, "name", prop);
Object type = this.getType(ame);
if(type instanceof ASMEMFModelElement) {
type = ((ASMEMFModelElement)type).getObject();
}
t.set(null, "eContainingClass", type);
this.allProperties.add(t);
} else {
throw vme;
}
}
}
public String getString(Object ame, String propName) {
return this.actualModelAdapter.getString(ame, propName);
}
public boolean isAModelElement(Object me) {
return this.actualModelAdapter.isAModelElement(me);
}
public Object createEnumLiteral(String name) {
return this.actualModelAdapter.createEnumLiteral(name);
}
public Object getModel() {
return this.actualModelAdapter.getModel();
}
public Map getVirtualProperties() {
return this.virtualProperties;
}
public Set getAllProperties() {
return this.allProperties;
}
}