/** * Copyright (c) 2006 Borland Software Corp. * * 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: * Alexander Shatalin (Borland) - initial API and implementation */ package org.eclipse.gmf.internal.bridge.trace; import java.io.IOException; import java.util.Collection; import java.util.HashMap; import java.util.Map; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.resource.ContentHandler; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.eclipse.emf.ecore.xmi.XMIResource; import org.eclipse.gmf.codegen.gmfgen.GenChildNode; import org.eclipse.gmf.codegen.gmfgen.GenCompartment; import org.eclipse.gmf.codegen.gmfgen.GenDiagram; import org.eclipse.gmf.codegen.gmfgen.GenLink; import org.eclipse.gmf.codegen.gmfgen.GenLinkLabel; import org.eclipse.gmf.codegen.gmfgen.GenNodeLabel; import org.eclipse.gmf.codegen.gmfgen.GenTopLevelNode; import org.eclipse.gmf.codegen.gmfgen.ToolGroup; import org.eclipse.gmf.internal.bridge.StatefulVisualIdentifierDispencer; import org.eclipse.ocl.ParserException; public class MergingIdentifierDispenser implements StatefulVisualIdentifierDispencer { private static final int CANVAS_COUNT_BASE = 1000; private static final int TOP_NODE_COUNT_BASE = 2000; private static final int CHILD_NODE_COUNT_BASE = 3000; private static final int LINK_COUNT_BASE = 4000; private static final int NODE_LABEL_COUNT_BASE = 5000; private static final int LINK_LABEL_COUNT_BASE = 6000; private static final int COMPARTMENT_COUNT_BASE = 7000; private static final int OVERFLOW_COUNT_BASE = 8000; private static final int TOOL_GROUP_COUNT_BASE = 0; private int myTopNodeCount = TOP_NODE_COUNT_BASE; private int myChildNodeCount = CHILD_NODE_COUNT_BASE; private int myLinkCount = LINK_COUNT_BASE; private int myNodeLabelCount = NODE_LABEL_COUNT_BASE; private int myLinkLabelCount = LINK_LABEL_COUNT_BASE; private int myCompartmentCount = COMPARTMENT_COUNT_BASE; private int myToolGroupCount = TOOL_GROUP_COUNT_BASE; private int myOverflowCount = OVERFLOW_COUNT_BASE; private TraceModel myTraceModel; private Map<String, String> mySavingOptions; public void loadState(URI genModelFileURI) { loadTraceModel(genModelFileURI); initCounters(); } public void saveState() { myTraceModel.purgeUnprocessedTraces(); try { myTraceModel.eResource().save(getSavingOptions()); } catch (IOException e) { GmfTracePlugin.getInstance().logError("Unable to save trace model", e); } myTraceModel = null; } private Map<?, ?> getSavingOptions() { if (mySavingOptions == null) { mySavingOptions = new HashMap<String, String>(); mySavingOptions.put(XMIResource.OPTION_ENCODING, "UTF-8"); mySavingOptions.put(Resource.OPTION_SAVE_ONLY_IF_CHANGED, Resource.OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER); } return mySavingOptions; } private void loadTraceModel(URI genModelFileURI) { URI traceModelURI = genModelFileURI.trimFileExtension().appendFileExtension("trace"); ResourceSet resSet = new ResourceSetImpl(); Resource traceRes; try { traceRes = resSet.getResource(traceModelURI, true); } catch (RuntimeException e) { traceRes = resSet.createResource(traceModelURI, ContentHandler.UNSPECIFIED_CONTENT_TYPE); } if (traceRes.getContents().size() > 0 && traceRes.getContents().get(0) instanceof TraceModel) { myTraceModel = (TraceModel) traceRes.getContents().get(0); } else { myTraceModel = TraceFactory.eINSTANCE.createTraceModel(); traceRes.getContents().add(0, myTraceModel); } } private void initCounters() { myTopNodeCount = Math.max(myTopNodeCount, getMaxVid(myTraceModel.getNodeTraces())); myChildNodeCount = Math.max(myChildNodeCount, getMaxVid(myTraceModel.getChildNodeTraces())); myLinkCount = Math.max(myLinkCount, getMaxVid(myTraceModel.getLinkTraces())); initNodeChildrenCounters(myTraceModel.getNodeTraces()); initNodeChildrenCounters(myTraceModel.getChildNodeTraces()); for (GenLinkTrace trace : myTraceModel.getLinkTraces()) { myLinkLabelCount = Math.max(myLinkLabelCount, getMaxVid(trace.getLinkLabelTraces())); } myToolGroupCount = Math.max(myToolGroupCount, getMaxVid(myTraceModel.getToolGroupTraces())); } private void initNodeChildrenCounters(Collection<? extends GenNodeTrace> nodeTraces) { for (GenNodeTrace trace : nodeTraces) { myNodeLabelCount = Math.max(myNodeLabelCount, getMaxVid(trace.getNodeLabelTraces())); myCompartmentCount = Math.max(myCompartmentCount, getMaxVid(trace.getCompartmentTraces())); } } private int getMaxVid(Collection<? extends AbstractTrace> abstractTraces) { int id = -1; for (AbstractTrace trace : abstractTraces) { id = Math.max(id, trace.getVisualID()); myOverflowCount = Math.max(myOverflowCount, trace.getVisualID()); } return id; } public int get(GenDiagram diagram) { return CANVAS_COUNT_BASE; } public int get(GenTopLevelNode node) { int visualID = getMatchingVID(node, myTraceModel.getNodeTraces()); if (visualID > -1) { return visualID; } visualID = getNextTopNodeVID(); GenNodeTrace nodeTrace = TraceFactory.eINSTANCE.createGenNodeTrace(); nodeTrace.setVisualID(visualID); nodeTrace.setContext(node); nodeTrace.setProcessed(true); myTraceModel.getNodeTraces().add(nodeTrace); return visualID; } public int get(GenNodeLabel nodeLabel) { GenNodeTrace nodeTrace = myTraceModel.getNodeTrace(nodeLabel.getNode().getVisualID()); int visualID = getMatchingVID(nodeLabel, nodeTrace.getNodeLabelTraces()); if (visualID > -1) { return visualID; } visualID = getNextNodeLabelVID(); GenNodeLabelTrace nodeLabelTrace = TraceFactory.eINSTANCE.createGenNodeLabelTrace(); nodeLabelTrace.setVisualID(visualID); nodeTrace.getNodeLabelTraces().add(nodeLabelTrace); nodeLabelTrace.setContext(nodeLabel); nodeLabelTrace.setProcessed(true); return visualID; } public int get(GenLink link) { int visualID = getMatchingVID(link, myTraceModel.getLinkTraces()); if (visualID > -1) { return visualID; } visualID = getNextLinkVID(); GenLinkTrace nodeLabelTrace = TraceFactory.eINSTANCE.createGenLinkTrace(); nodeLabelTrace.setVisualID(visualID); nodeLabelTrace.setContext(link); myTraceModel.getLinkTraces().add(nodeLabelTrace); nodeLabelTrace.setProcessed(true); return visualID; } public int get(GenChildNode childNode) { int visualID = getMatchingVID(childNode, myTraceModel.getChildNodeTraces()); if (visualID > -1) { return visualID; } visualID = getNextChildNodeVID(); GenChildNodeTrace childNodeTrace = TraceFactory.eINSTANCE.createGenChildNodeTrace(); childNodeTrace.setVisualID(visualID); childNodeTrace.setContext(childNode); myTraceModel.getChildNodeTraces().add(childNodeTrace); childNodeTrace.setProcessed(true); return visualID; } public int get(GenCompartment compartment) { GenNodeTrace nodeTrace = myTraceModel.getNodeTrace(compartment.getNode().getVisualID()); int visualID = getMatchingVID(compartment, nodeTrace.getCompartmentTraces()); if (visualID > -1) { return visualID; } visualID = getNextCompartmentVID(); GenCompartmentTrace compartmentTrace = TraceFactory.eINSTANCE.createGenCompartmentTrace(); compartmentTrace.setVisualID(visualID); nodeTrace.getCompartmentTraces().add(compartmentTrace); compartmentTrace.setContext(compartment); compartmentTrace.setProcessed(true); return visualID; } public int get(GenLinkLabel label) { GenLinkTrace linkTrace = myTraceModel.getLinkTrace(label.getLink().getVisualID()); int visualID = getMatchingVID(label, linkTrace.getLinkLabelTraces()); if (visualID > -1) { return visualID; } visualID = getNextLinkLabelVID(); GenLinkLabelTrace linkLabelTrace = TraceFactory.eINSTANCE.createGenLinkLabelTrace(); linkLabelTrace.setVisualID(visualID); linkTrace.getLinkLabelTraces().add(linkLabelTrace); linkLabelTrace.setContext(label); linkLabelTrace.setProcessed(true); return visualID; } public int get(ToolGroup toolGroup) { int visualID = getMatchingVID(toolGroup, myTraceModel.getToolGroupTraces()); if (visualID > -1) { return visualID; } visualID = getNextToolVID(); ToolGroupTrace toolGroupTrace = TraceFactory.eINSTANCE.createToolGroupTrace(); toolGroupTrace.setVisualID(visualID); toolGroupTrace.setContext(toolGroup); myTraceModel.getToolGroupTraces().add(toolGroupTrace); toolGroupTrace.setProcessed(true); return visualID; } private int getMatchingVID(Object context, Collection<? extends MatchingTrace> matchingTraces) { for (MatchingTrace trace : matchingTraces) { if (trace.isProcessed()) { continue; } try { Object result = trace.getQuery().evaluate(context); if (result instanceof Boolean && ((Boolean) result).booleanValue()) { trace.setProcessed(true); return trace.getVisualID(); } } catch (ParserException e) { GmfTracePlugin.getInstance().logError("Error while parcing expression body from trace", e); } } return -1; } private int getNextToolVID() { if (++myToolGroupCount < CANVAS_COUNT_BASE) { GmfTracePlugin.getInstance().logDebugInfo("New tool visualID issued: " + myToolGroupCount); return myToolGroupCount; } return ++myOverflowCount; } private int getNextTopNodeVID() { if (++myTopNodeCount < CHILD_NODE_COUNT_BASE) { GmfTracePlugin.getInstance().logDebugInfo("New top node visualID issued: " + myTopNodeCount); return myTopNodeCount; } return ++myOverflowCount; } private int getNextChildNodeVID() { if (++myChildNodeCount < LINK_COUNT_BASE) { GmfTracePlugin.getInstance().logDebugInfo("New child node visualID issued: " + myChildNodeCount); return myChildNodeCount; } return ++myOverflowCount; } private int getNextLinkVID() { if (++myLinkCount < NODE_LABEL_COUNT_BASE) { GmfTracePlugin.getInstance().logDebugInfo("New link visualID issued: " + myLinkCount); return myLinkCount; } return ++myOverflowCount; } private int getNextNodeLabelVID() { if (++myNodeLabelCount < LINK_LABEL_COUNT_BASE) { GmfTracePlugin.getInstance().logDebugInfo("New node label visualID issued: " + myNodeLabelCount); return myNodeLabelCount; } return ++myOverflowCount; } private int getNextLinkLabelVID() { if (++myLinkLabelCount < COMPARTMENT_COUNT_BASE) { GmfTracePlugin.getInstance().logDebugInfo("New link label visualID issued: " + myLinkLabelCount); return myLinkLabelCount; } return ++myOverflowCount; } private int getNextCompartmentVID() { if (++myCompartmentCount < OVERFLOW_COUNT_BASE) { GmfTracePlugin.getInstance().logDebugInfo("New compartment visualID issued: " + myCompartmentCount); return myCompartmentCount; } return ++myOverflowCount; } }