/** * Adds the given trace to the given tree. * * @param root The root of the call tree. * @param t The trace to add. * @param pairFactory The factory creating the necessary pairs for the tree. * @param aggregated Determines whether the tree is aggregated or not. * @throws TraceProcessingException If the message type is not supported or the trace is somehow * invalid. * @param <T> The type of the tree. */ protected static <T> void addTraceToTree( final AbstractCallTreeNode<T> root, final MessageTrace t, final IPairFactory<T> pairFactory, final boolean aggregated) throws TraceProcessingException { final Stack<AbstractCallTreeNode<T>> curStack = new Stack<AbstractCallTreeNode<T>>(); final Collection<AbstractMessage> msgTraceVec = t.getSequenceAsVector(); AbstractCallTreeNode<T> curNode = root; curStack.push(curNode); for (final AbstractMessage m : msgTraceVec) { if (m instanceof SynchronousCallMessage) { curNode = curStack.peek(); AbstractCallTreeNode<T> child; child = curNode.newCall( pairFactory.createPair((SynchronousCallMessage) m), t, NoOriginRetentionPolicy.createInstance()); curNode = child; curStack.push(curNode); } else if (m instanceof SynchronousReplyMessage) { curNode = curStack.pop(); } else { throw new TraceProcessingException("Message type not supported:" + m.getClass().getName()); } } if (curStack.pop() != root) { throw new TraceProcessingException("Stack not empty after processing trace"); } }
@SuppressWarnings("unchecked") // javac reports unchecked casts protected static final String nodeLabel( final AbstractCallTreeNode<?> node, final boolean shortLabels) { if (node.getEntity() instanceof AllocationComponentOperationPair) { return AbstractCallTreeFilter.allocationComponentOperationPairNodeLabel( (AbstractCallTreeNode<AllocationComponentOperationPair>) node, shortLabels); } else if (node.getEntity() instanceof AssemblyComponentOperationPair) { return AbstractCallTreeFilter.assemblyComponentOperationPairNodeLabel( (AbstractCallTreeNode<AssemblyComponentOperationPair>) node, shortLabels); } else { throw new UnsupportedOperationException( "Node type not supported: " + node.getEntity().getClass().getName()); } }
private static final String assemblyComponentOperationPairNodeLabel( final AbstractCallTreeNode<AssemblyComponentOperationPair> node, final boolean shortLabels) { final AssemblyComponentOperationPair p = node.getEntity(); final AssemblyComponent component = p.getAssemblyComponent(); final Operation operation = p.getOperation(); final String assemblyComponentName = component.getName(); final String componentTypePackagePrefx = component.getType().getPackageName(); final String componentTypeIdentifier = component.getType().getTypeName(); final StringBuilder strBuild = new StringBuilder(assemblyComponentName).append(":"); if (!shortLabels) { strBuild.append(componentTypePackagePrefx).append('.'); } else { strBuild.append(".."); } strBuild.append(componentTypeIdentifier).append("\\n."); final Signature sig = operation.getSignature(); final StringBuilder opLabel = new StringBuilder(sig.getName()); opLabel.append('('); final String[] paramList = sig.getParamTypeList(); if (paramList.length > 0) { opLabel.append(".."); } opLabel.append(')'); strBuild.append(opLabel.toString()); return strBuild.toString(); }
/** * Traverse tree recursively and generate dot code for vertices. * * @param n The root node. * @param eoiCounter The counter for the execution order index. * @param nodeIds The map containing the node IDs. * @param ps The stream on which the generated code will be printed. * @param includeWeights Determines whether to include weights or not. */ private static void dotVerticesFromSubTree( final AbstractCallTreeNode<?> n, final AtomicInteger eoiCounter, final Map<AbstractCallTreeNode<?>, Integer> nodeIds, final PrintStream ps, final boolean includeWeights) { final int thisId = nodeIds.get(n); for (final WeightedDirectedCallTreeEdge<?> child : n.getChildEdges()) { final StringBuilder strBuild = new StringBuilder(1024); final int childId = nodeIds.get(child.getTarget()); strBuild .append('\n') .append(thisId) .append("->") .append(childId) .append("[style=solid,arrowhead=none"); if (includeWeights) { strBuild.append(",label=\"").append(child.getTargetWeight().get()).append('"'); } else if (eoiCounter != null) { strBuild.append(",label=\"").append(eoiCounter.getAndIncrement()).append(".\""); } strBuild.append(" ]"); ps.println(strBuild.toString()); AbstractCallTreeFilter.dotVerticesFromSubTree( child.getTarget(), eoiCounter, nodeIds, ps, includeWeights); } }
/** * Traverse tree recursively and generate dot code for edges. * * @param n The root node to start with. * @param nodeIds The map containing the node IDs. * @param nextNodeId The counter for the IDs of the nodes. * @param ps The stream in which the dot code will be written. * @param shortLabels Determines whether to use short labels or not. */ private static void dotEdgesFromSubTree( final AbstractCallTreeNode<?> n, final Map<AbstractCallTreeNode<?>, Integer> nodeIds, final AtomicInteger nextNodeId, final PrintStream ps, final boolean shortLabels) { final StringBuilder strBuild = new StringBuilder(64); nodeIds.put(n, nextNodeId.get()); strBuild .append(nextNodeId.getAndIncrement()) .append("[label =\"") .append( n.isRootNode() ? SystemModelRepository.ROOT_NODE_LABEL // NOCS : AbstractCallTreeFilter.nodeLabel(n, shortLabels)) // NOCS .append("\",shape=" + DotFactory.DOT_SHAPE_NONE + "];"); ps.println(strBuild.toString()); for (final WeightedDirectedCallTreeEdge<?> child : n.getChildEdges()) { AbstractCallTreeFilter.dotEdgesFromSubTree( child.getTarget(), nodeIds, nextNodeId, ps, shortLabels); } }