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}