package tefkat.engine.runtime; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.eclipse.emf.ecore.EObject; import tefkat.engine.trace.BoolAny; import tefkat.engine.trace.IntAny; import tefkat.engine.trace.ObjectAny; import tefkat.engine.trace.StringAny; import tefkat.engine.trace.Trace; import tefkat.engine.trace.TraceFactory; import tefkat.engine.trace.TracePackage; public class Injections { private final Map injections = new HashMap(); private final Map traces = new HashMap(); void loadTrace(final Extent extent) { final List traceInstances = extent.getObjectsByClass(TracePackage.eINSTANCE.getTrace(), false); for (final Iterator itr = traceInstances.iterator(); itr.hasNext(); ) { final Trace trace = (Trace) itr.next(); final List keys = trace.getSources(); final EObject target = trace.getTarget(); store(keys, target); traces.put(target, keys); } } protected EObject lookup(Extent extent, List keys, TRule rule) { EObject obj = lookup(injections, keys, 0); Trace trace; if (null == obj) { obj = new DynamicObject(); store(keys, obj); trace = createTrace(extent, keys, obj); traces.put(obj, trace); } else { trace = (Trace) traces.get(obj); } if (rule != null) { trace.getRules().add(rule); } // ExtentUtil.highlightNode(obj, ExtentUtil.OBJECT_LOOKUP); // ExtentUtil.highlightNode(trace, ExtentUtil.OBJECT_LOOKUP); return obj; } /** * @param extent * @param keys * @param obj * @throws Error */ private Trace createTrace(Extent extent, List keys, EObject obj) throws Error { Trace trace = TraceFactory.eINSTANCE.createTrace(); trace.setTarget(obj); if (obj instanceof DynamicObject) { DynamicObject dynObj = (DynamicObject) obj; dynObj.addReferenceFrom(trace, TracePackage.eINSTANCE.getTrace_Target()); } extent.add(trace); List sources = trace.getSources(); for (int i = 0; i < keys.size(); i++) { Object key = keys.get(i); if (key instanceof BindingPair) { key = ((BindingPair) key).getValue(); } if (key instanceof EObject) { ObjectAny any = TraceFactory.eINSTANCE.createObjectAny(); any.getValue().add(key); sources.add(any); // In case a target object is used as an injection parameter if (key instanceof DynamicObject) { DynamicObject dynObj = (DynamicObject) key; dynObj.addMultiReferenceFrom(any, TracePackage.eINSTANCE.getObjectAny_Value()); } } else if (key instanceof String) { StringAny any = TraceFactory.eINSTANCE.createStringAny(); any.setValue((String) key); sources.add(any); } else if (key instanceof Integer) { IntAny any = TraceFactory.eINSTANCE.createIntAny(); any.setValue(((Integer) key).intValue()); sources.add(any); } else if (key instanceof Boolean) { BoolAny any = TraceFactory.eINSTANCE.createBoolAny(); any.setValue(((Boolean) key).booleanValue()); sources.add(any); } else { throw new Error("Internal Error: trace support for " + key.getClass() + " not yet implemented."); } } return trace; } private void store(List keys, EObject value) { store(injections, keys, value, 0); } private EObject lookup(Map map, List keys, int idx) { Object key = keys.get(idx); Object keyVal = map.get(key); if (null == keyVal) { return null; } else if ((idx + 1) < keys.size()) { return lookup((Map) keyVal, keys, idx + 1); } else { return (EObject) keyVal; } } private void store(Map map, List keys, EObject value, int idx) { Object key = keys.get(idx); if ((idx + 1) < keys.size()) { Map subMap = (Map) map.get(key); if (null == subMap) { subMap = new HashMap(); map.put(key, subMap); } store(subMap, keys, value, idx + 1); } else { map.put(key, value); } } }