001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.camel.view;
018
019import java.io.PrintWriter;
020import java.util.List;
021import java.util.Map;
022import java.util.Set;
023
024import org.apache.camel.model.FromDefinition;
025import org.apache.camel.model.MulticastDefinition;
026import org.apache.camel.model.ProcessorDefinition;
027import org.apache.camel.model.RouteDefinition;
028import static org.apache.camel.util.ObjectHelper.isNotEmpty;
029/**
030 * A <a href="http://www.graphviz.org/">DOT</a> file creator plugin which
031 * creates a DOT file showing the current routes
032 *
033 * @version 
034 */
035@Deprecated
036public class RouteDotGenerator extends GraphGeneratorSupport {
037
038    public RouteDotGenerator(String dir) {
039        super(dir, ".dot");
040    }
041
042    // Implementation methods
043    //-------------------------------------------------------------------------
044
045    protected void printRoutes(PrintWriter writer, Map<String, List<RouteDefinition>> map) {
046        Set<Map.Entry<String, List<RouteDefinition>>> entries = map.entrySet();
047        for (Map.Entry<String, List<RouteDefinition>> entry : entries) {
048            String group = entry.getKey();
049            printRoutes(writer, group, entry.getValue());
050        }
051    }
052
053    protected void printRoutes(PrintWriter writer, String group, List<RouteDefinition> routes) {
054        if (group != null) {
055            writer.println("subgraph cluster_" + (clusterCounter++) + " {");
056            writer.println("label = \"" + group + "\";");
057            writer.println("color = grey;");
058            writer.println("style = \"dashed\";");
059            writer.println("URL = \"" + group + ".html\";");
060            writer.println();
061        }
062        for (RouteDefinition route : routes) {
063            List<FromDefinition> inputs = route.getInputs();
064            for (FromDefinition input : inputs) {
065                printRoute(writer, route, input);
066            }
067            writer.println();
068        }
069        if (group != null) {
070            writer.println("}");
071            writer.println();
072        }
073    }
074
075    protected void printRoute(PrintWriter writer, final RouteDefinition route, FromDefinition input) {
076        NodeData nodeData = getNodeData(input);
077
078        printNode(writer, nodeData);
079
080        NodeData from = nodeData;
081        for (ProcessorDefinition<?> output : route.getOutputs()) {
082            NodeData newData = printNode(writer, from, output);
083            from = newData;
084        }
085    }
086
087    protected NodeData printNode(PrintWriter writer, NodeData fromData, ProcessorDefinition<?> node) {
088        if (node instanceof MulticastDefinition) {
089            // no need for a multicast or interceptor node
090            List<ProcessorDefinition<?>> outputs = node.getOutputs();
091            boolean isPipeline = isPipeline(node);
092            for (ProcessorDefinition<?> output : outputs) {
093                NodeData out = printNode(writer, fromData, output);
094                // if in pipeline then we should move the from node to the next in the pipeline
095                if (isPipeline) {
096                    fromData = out;
097                }
098            }
099            return fromData;
100        }
101        NodeData toData = getNodeData(node);
102
103        printNode(writer, toData);
104
105        if (fromData != null) {
106            writer.print(fromData.id);
107            writer.print(" -> ");
108            writer.print(toData.id);
109            writer.println(" [");
110
111            String label = fromData.edgeLabel;
112            if (isNotEmpty(label)) {
113                writer.println("label = \"" + label + "\"");
114            }
115            writer.println("];");
116        }
117
118        // now lets write any children
119        List<ProcessorDefinition<?>> outputs = toData.outputs;
120        if (outputs != null) {
121            for (ProcessorDefinition<?> output : outputs) {
122                NodeData newData = printNode(writer, toData, output);
123                if (!isMulticastNode(node)) {
124                    toData = newData;
125                }
126            }
127        }
128        return toData;
129    }
130
131    protected void printNode(PrintWriter writer, NodeData data) {
132        if (!data.nodeWritten) {
133            data.nodeWritten = true;
134
135            writer.println();
136            writer.print(data.id);
137            writer.println(" [");
138            writer.println("label = \"" + data.label + "\"");
139            writer.println("tooltip = \"" + data.tooltop + "\"");
140            if (data.url != null) {
141                writer.println("URL = \"" + data.url + "\"");
142            }
143
144            String image = data.image;
145            if (image != null) {
146                writer.println("shapefile = \"" + image + "\"");
147                writer.println("peripheries=0");
148            }
149            String shape = data.shape;
150            if (shape == null && image != null) {
151                shape = "custom";
152            }
153            if (shape != null) {
154                writer.println("shape = \"" + shape + "\"");
155            }
156            writer.println("];");
157            writer.println();
158        }
159    }
160
161    protected void generateFile(PrintWriter writer, Map<String, List<RouteDefinition>> map) {
162        writer.println("digraph CamelRoutes {");
163        writer.println();
164
165        writer.println("node [style = \"rounded,filled\", fillcolor = yellow, "
166                + "fontname=\"Helvetica-Oblique\"];");
167        writer.println();
168        printRoutes(writer, map);
169
170        writer.println("}");
171    }
172
173
174}