/** | |
* 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; | |
} | |
} |