/******************************************************************************* * Copyright (c) 2005, 2007 committers of openArchitectureWare 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: * committers of openArchitectureWare - initial API and implementation *******************************************************************************/ package org.eclipse.xtend.util.stdlib; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Stack; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.mwe.core.WorkflowContext; import org.eclipse.emf.mwe.core.issues.Issues; import org.eclipse.emf.mwe.core.monitor.ProgressMonitor; import org.eclipse.emf.mwe.utils.AbstractEMFWorkflowComponent; import org.eclipse.emf.mwe.utils.StandaloneSetup; import org.eclipse.xtend.util.stdlib.tracing.M2CTraceElement; import org.eclipse.xtend.util.stdlib.tracing.M2MTraceElement; import org.eclipse.xtend.util.stdlib.tracing.MapList; import org.eclipse.xtend.util.stdlib.tracing.TraceElement; import org.eclipse.xtend.util.stdlib.tracing.TraceStore; public class TraceComponent extends AbstractEMFWorkflowComponent { private static final String COMPONENT_NAME = "Trace Component"; private String traceModelSlotName; private String traceName; private static TraceStore traceStore = new TraceStore(); private static Stack<String> fileStack = new Stack<String>(); private static int tokenValue = 0; private static MapList cache = new MapList(); public static void createTrace(Object from, Object to, String kind) { TraceElement t = new M2MTraceElement(kind, (EObject) from, (EObject) to); traceStore.add(t); } public static void createTrace(Object from, Collection to, String kind) { TraceElement t = new M2MTraceElement(kind, (EObject) from, (Collection<EObject>) to); traceStore.add(t); } public static void createTrace(Collection from, Object to, String kind) { TraceElement t = new M2MTraceElement(kind, (Collection<EObject>) from, (EObject) to); traceStore.add(t); } public static String createCodeTrace(Object from, String kind) { if (!fileStack.isEmpty()) { String currentFile = fileStack.peek(); String token = createNewToken(); TraceElement t = new M2CTraceElement(kind, (EObject) from, currentFile, token); traceStore.add(t); return token; } return "<unknown>"; } private static String createNewToken() { return "TRACE_" + (tokenValue++); } public static Object getSingleTraceTarget(Object from, String kind) { List traces = traceStore.getTraces(from, kind); if (traces.size() == 0) return null; M2MTraceElement e = (M2MTraceElement) traces.get(0); return e.getTargets().get(0); } public static Object getTraceTargets(Object from, String kind) { List traces = traceStore.getTraces(from, kind); List targets = new ArrayList(); for (Iterator iterator = traces.iterator(); iterator.hasNext();) { M2MTraceElement te = (M2MTraceElement) iterator.next(); targets.addAll(te.getTargets()); } return targets; } @Override public String getLogMessage() { return "building trace model in slot '" + traceModelSlotName + "'"; } public static void clearTrace() { traceStore.clear(); } public void setTraceModelSlot(String slot) { this.traceModelSlotName = slot; } public void setTraceName(String name) { this.traceName = name; } @Override public void checkConfiguration(Issues issues) { if (traceModelSlotName == null) { issues.addError(this, "you have to specify a traceModelSlot"); } if (traceName == null) { issues.addError(this, "you have to specify a traceName"); } } @Override public void invokeInternal(WorkflowContext ctx, ProgressMonitor mon, Issues issues) { setUseSingleGlobalResourceSet(true); try { StandaloneSetup setup = new StandaloneSetup(); setup .addRegisterEcoreFile("platform:/resource/eclipse.xtend.util.stdlib/src/org/eclipse/xtend/util/stdlib/trace.ecore"); EPackage pack = setup.getPackage("http://openarchitectureware.org/trace"); DynamicEcoreHelper h = new DynamicEcoreHelper(pack); EObject model = h.create("Trace"); createElementList(h, model); createBySource(h, model); ctx.set(traceModelSlotName, model); } catch (Exception e) { issues.addError(this, e.getMessage()); } } private void createBySource(DynamicEcoreHelper h, EObject model) { for (Iterator iter = cache.getKeys().iterator(); iter.hasNext();) { EObject source = (EObject) iter.next(); EObject bySource = h.create("TraceBySource"); h.set(bySource, "source", source); Collection traces = cache.get(source); for (Iterator iterator = traces.iterator(); iterator.hasNext();) { EObject item = (EObject) iterator.next(); h.add(bySource, "items", item); } h.add(model, "traceBySource", bySource); } } private void createElementList(DynamicEcoreHelper h, EObject model) { EObject list = h.create("TraceList"); h.set(model, "list", list); for (Iterator iter = traceStore.getAllTraces().iterator(); iter.hasNext();) { TraceElement element = (TraceElement) iter.next(); EObject item = null; if (element instanceof M2MTraceElement) { M2MTraceElement m2m = (M2MTraceElement) element; item = h.create("M2MTraceItem"); h.set(item, "kind", m2m.getKind()); h.addAll(item, "from", m2m.getSources()); h.addAll(item, "to", m2m.getTargets()); h.add(list, "items", item); } else { M2CTraceElement m2c = (M2CTraceElement) element; item = h.create("M2CTraceItem"); h.set(item, "kind", m2c.getKind()); h.addAll(item, "from", m2c.getSources()); h.set(item, "targetFile", m2c.getFileName()); h.set(item, "token", m2c.getToken()); h.add(list, "items", item); } for (Iterator<EObject> iterator = element.getSources().iterator(); iterator.hasNext();) { EObject source = iterator.next(); cache.add(source, item); } } } public static void reportFileOpen(String path) { fileStack.push(path); } public static void reportFileClose() { fileStack.pop(); } @Override public String getComponentName() { return COMPONENT_NAME; } }