You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by js...@apache.org on 2007/09/19 10:38:41 UTC

svn commit: r577194 - in /activemq/camel/trunk/camel-core/src: main/java/org/apache/camel/view/ test/java/org/apache/camel/view/

Author: jstrachan
Date: Wed Sep 19 01:38:38 2007
New Revision: 577194

URL: http://svn.apache.org/viewvc?rev=577194&view=rev
Log:
minor refactor to also support an XML version of the EIP diagrams

Added:
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/view/GraphGeneratorSupport.java   (with props)
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/view/NodeData.java   (with props)
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/view/XmlGraphGenerator.java   (with props)
    activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/view/XmlGraphTest.java   (with props)
Modified:
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/view/RouteDotGenerator.java
    activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/view/DotViewTest.java
    activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/view/RouteDotGeneratorTest.java

Added: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/view/GraphGeneratorSupport.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/view/GraphGeneratorSupport.java?rev=577194&view=auto
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/view/GraphGeneratorSupport.java (added)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/view/GraphGeneratorSupport.java Wed Sep 19 01:38:38 2007
@@ -0,0 +1,165 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.view;
+
+import java.io.IOException;
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.FileWriter;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.HashMap;
+import java.util.ArrayList;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.util.CollectionStringBuffer;
+import org.apache.camel.model.RouteType;
+import org.apache.camel.model.ProcessorType;
+import org.apache.camel.model.MulticastType;
+import org.apache.camel.model.ChoiceType;
+import org.apache.camel.model.FromType;
+import org.apache.camel.model.ToType;
+import org.apache.camel.model.language.ExpressionType;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * @version $Revision: 1.1 $
+ */
+public abstract class GraphGeneratorSupport {
+    private static final transient Log LOG = LogFactory.getLog(RouteDotGenerator.class);
+    protected String dir;
+    private String imagePrefix = "http://www.enterpriseintegrationpatterns.com/img/";
+    private Map<Object, NodeData> nodeMap = new HashMap<Object, NodeData>();
+    private boolean makeParentDirs = true;
+    protected int clusterCounter;
+    private Map<String, List<RouteType>> routeGroupMap;
+    protected String extension;
+
+    protected GraphGeneratorSupport(String dir, String extension) {
+        this.dir = dir;
+        this.extension = extension;
+    }
+
+    public String getDir() {
+        return dir;
+    }
+
+    /**
+     * Sets the destination directory in which to create the diagrams
+     */
+    public void setDir(String dir) {
+        this.dir = dir;
+    }
+
+    public void drawRoutes(CamelContext context) throws IOException {
+        File parent = new File(dir);
+        if (makeParentDirs) {
+            parent.mkdirs();
+        }
+        List<RouteType> routes = context.getRouteDefinitions();
+        routeGroupMap = createRouteGroupMap(routes);
+
+        // generate the global file
+        generateFile(parent, "routes" + extension, routeGroupMap);
+
+        if (routeGroupMap.size() >= 1) {
+            Set<Map.Entry<String, List<RouteType>>> entries = routeGroupMap.entrySet();
+            for (Map.Entry<String, List<RouteType>> entry : entries) {
+
+                Map<String, List<RouteType>> map = new HashMap<String, List<RouteType>>();
+                String group = entry.getKey();
+                map.put(group, entry.getValue());
+
+                // generate the file containing just the routes in this group
+                generateFile(parent, group + extension, map);
+            }
+        }
+    }
+
+    private void generateFile(File parent, String fileName, Map<String, List<RouteType>> map) throws IOException {
+        nodeMap.clear();
+        clusterCounter = 0;
+
+        PrintWriter writer = new PrintWriter(new FileWriter(new File(parent, fileName)));
+        try {
+            generateFile(writer, map);
+        }
+        finally {
+            writer.close();
+        }
+    }
+
+    protected abstract void generateFile(PrintWriter writer, Map<String, List<RouteType>> map);
+
+    protected boolean isMulticastNode(ProcessorType node) {
+        return node instanceof MulticastType || node instanceof ChoiceType;
+    }
+
+    protected String getLabel(List<ExpressionType> expressions) {
+        CollectionStringBuffer buffer = new CollectionStringBuffer();
+        for (ExpressionType expression : expressions) {
+            buffer.append(getLabel(expression));
+        }
+        return buffer.toString();
+    }
+
+    protected String getLabel(ExpressionType expression) {
+        if (expression != null) {
+            return expression.getLabel();
+        }
+        return "";
+    }
+
+    protected NodeData getNodeData(Object node) {
+        Object key = node;
+        if (node instanceof FromType) {
+            FromType fromType = (FromType) node;
+            key = fromType.getUriOrRef();
+        }
+        else if (node instanceof ToType) {
+            ToType toType = (ToType) node;
+            key = toType.getUriOrRef();
+        }
+        NodeData answer = nodeMap.get(key);
+        if (answer == null) {
+            String id = "node" + (nodeMap.size() + 1);
+            answer = new NodeData(id, node, imagePrefix);
+            nodeMap.put(key, answer);
+        }
+        return answer;
+    }
+
+    protected Map<String, List<RouteType>> createRouteGroupMap(List<RouteType> routes) {
+        Map<String, List<RouteType>> map = new HashMap<String, List<RouteType>>();
+        for (RouteType route : routes) {
+            String group = route.getGroup();
+            if (group == null) {
+                group = "Camel Routes";
+            }
+            List<RouteType> list = map.get(group);
+            if (list == null) {
+                list = new ArrayList<RouteType>();
+                map.put(group, list);
+            }
+            list.add(route);
+        }
+        return map;
+    }
+}

Propchange: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/view/GraphGeneratorSupport.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/view/NodeData.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/view/NodeData.java?rev=577194&view=auto
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/view/NodeData.java (added)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/view/NodeData.java Wed Sep 19 01:38:38 2007
@@ -0,0 +1,187 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.view;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.camel.model.*;
+import static org.apache.camel.util.ObjectHelper.isNotNullAndNonEmpty;
+import static org.apache.camel.util.ObjectHelper.isNullOrBlank;
+
+/**
+ * Represents a node in the EIP diagram tree
+ *
+ * @version $Revision: 1.1 $
+ */
+public class NodeData {
+    public String id;
+    private final String imagePrefix;
+    public String image;
+    public String label;
+    public String shape;
+    public String edgeLabel;
+    public String tooltop;
+    public String nodeType;
+    public boolean nodeWritten;
+    public String url;
+    public List<ProcessorType> outputs;
+    public String association = "property";
+
+    public NodeData(String id, Object node, String imagePrefix) {
+        this.id = id;
+        this.imagePrefix = imagePrefix;
+
+        if (node instanceof ProcessorType) {
+            ProcessorType processorType = (ProcessorType) node;
+            this.edgeLabel = processorType.getLabel();
+        }
+        if (node instanceof FromType) {
+            FromType fromType = (FromType) node;
+            this.tooltop = fromType.getLabel();
+            this.label = removeQueryString(this.tooltop);
+            this.url = "http://activemq.apache.org/camel/message-endpoint.html";
+        }
+        else if (node instanceof ToType) {
+            ToType toType = (ToType) node;
+            this.tooltop = toType.getLabel();
+            this.label = removeQueryString(this.tooltop);
+            this.edgeLabel = "";
+            this.url = "http://activemq.apache.org/camel/message-endpoint.html";
+        }
+        else if (node instanceof FilterType) {
+            this.image = imagePrefix + "MessageFilterIcon.gif";
+            this.nodeType = "Message Filter";
+        }
+        else if (node instanceof WhenType) {
+            this.image = imagePrefix + "MessageFilterIcon.gif";
+            this.nodeType = "When Filter";
+            this.url = "http://activemq.apache.org/camel/content-based-router.html";
+        }
+        else if (node instanceof OtherwiseType) {
+            this.nodeType = "Otherwise";
+            this.edgeLabel = "";
+            this.url = "http://activemq.apache.org/camel/content-based-router.html";
+            this.tooltop = "Otherwise";
+        }
+        else if (node instanceof ChoiceType) {
+            this.image = imagePrefix + "ContentBasedRouterIcon.gif";
+            this.nodeType = "Content Based Router";
+            this.label = "";
+            this.edgeLabel = "";
+
+            ChoiceType choice = (ChoiceType) node;
+            List<ProcessorType> outputs = new ArrayList<ProcessorType>(choice.getWhenClauses());
+            outputs.add(choice.getOtherwise());
+            this.outputs = outputs;
+        }
+        else if (node instanceof RecipientListType) {
+            this.image = imagePrefix + "RecipientListIcon.gif";
+            this.nodeType = "Recipient List";
+        }
+        else if (node instanceof SplitterType) {
+            this.image = imagePrefix + "SplitterIcon.gif";
+            this.nodeType = "Splitter";
+        }
+        else if (node instanceof AggregatorType) {
+            this.image = imagePrefix + "AggregatorIcon.gif";
+            this.nodeType = "Aggregator";
+        }
+        else if (node instanceof ResequencerType) {
+            this.image = imagePrefix + "ResequencerIcon.gif";
+            this.nodeType = "Resequencer";
+        }
+
+        // lets auto-default as many values as we can
+        if (isNullOrBlank(this.nodeType)) {
+            // TODO we could add this to the model?
+            String name = node.getClass().getName();
+            int idx = name.lastIndexOf('.');
+            if (idx > 0) {
+                name = name.substring(idx + 1);
+            }
+            if (name.endsWith("Type")) {
+                name = name.substring(0, name.length() - 4);
+            }
+            this.nodeType = insertSpacesBetweenCamelCase(name);
+        }
+        if (this.label == null) {
+            if (isNullOrBlank(this.image)) {
+                this.label = this.nodeType;
+                this.shape = "box";
+            }
+            else if (isNotNullAndNonEmpty(this.edgeLabel)) {
+                this.label = "";
+            }
+            else {
+                this.label = node.toString();
+            }
+        }
+        if (isNullOrBlank(this.tooltop)) {
+            if (isNotNullAndNonEmpty(this.nodeType)) {
+                String description = isNotNullAndNonEmpty(this.edgeLabel) ? this.edgeLabel : this.label;
+                this.tooltop = this.nodeType + ": " + description;
+            }
+            else {
+                this.tooltop = this.label;
+            }
+        }
+        if (isNullOrBlank(this.url) && isNotNullAndNonEmpty(this.nodeType)) {
+            this.url = "http://activemq.apache.org/camel/" + this.nodeType.toLowerCase().replace(' ', '-') + ".html";
+        }
+        if (node instanceof ProcessorType && this.outputs == null) {
+            ProcessorType processorType = (ProcessorType) node;
+            this.outputs = processorType.getOutputs();
+        }
+    }
+
+    protected String removeQueryString(String text) {
+        int idx = text.indexOf("?");
+        if (idx <= 0) {
+            return text;
+        }
+        else {
+            return text.substring(0, idx);
+        }
+    }
+
+    /**
+     * lets insert a space before each upper case letter after a lowercase
+     *
+     * @param name
+     * @return
+     */
+    public static String insertSpacesBetweenCamelCase(String name) {
+        boolean lastCharacterLowerCase = false;
+        StringBuffer buffer = new StringBuffer();
+        for (int i = 0, size = name.length(); i < size; i++) {
+            char ch = name.charAt(i);
+            if (Character.isUpperCase(ch)) {
+                if (lastCharacterLowerCase) {
+                    buffer.append(' ');
+                }
+                lastCharacterLowerCase = false;
+            }
+            else {
+                lastCharacterLowerCase = true;
+            }
+            buffer.append(ch);
+        }
+        return buffer.toString();
+    }
+}

Propchange: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/view/NodeData.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/view/RouteDotGenerator.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/view/RouteDotGenerator.java?rev=577194&r1=577193&r2=577194&view=diff
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/view/RouteDotGenerator.java (original)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/view/RouteDotGenerator.java Wed Sep 19 01:38:38 2007
@@ -16,24 +16,16 @@
  */
 package org.apache.camel.view;
 
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
 import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.camel.CamelContext;
-import org.apache.camel.model.*;
-import org.apache.camel.model.language.ExpressionType;
-import org.apache.camel.util.CollectionStringBuffer;
+import org.apache.camel.model.FromType;
+import org.apache.camel.model.MulticastType;
+import org.apache.camel.model.ProcessorType;
+import org.apache.camel.model.RouteType;
 import static org.apache.camel.util.ObjectHelper.isNotNullAndNonEmpty;
-import static org.apache.camel.util.ObjectHelper.isNullOrBlank;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 
 /**
  * A <a href="http://www.graphviz.org/">DOT</a> file creator plugin which
@@ -41,132 +33,20 @@
  *
  * @version $Revision: 523881 $
  */
-public class RouteDotGenerator {
-    private static final transient Log LOG = LogFactory.getLog(RouteDotGenerator.class);
-    private String dir;
-    private String imagePrefix = "http://www.enterpriseintegrationpatterns.com/img/";
-    private Map<Object, NodeData> nodeMap = new HashMap<Object, NodeData>();
-    private boolean makeParentDirs = true;
-    private int clusterCounter;
-    private Map<String, List<RouteType>> routeGroupMap;
-
-    /**
-     * lets insert a space before each upper case letter after a lowercase
-     *
-     * @param name
-     * @return
-     */
-    public static String insertSpacesBetweenCamelCase(String name) {
-        boolean lastCharacterLowerCase = false;
-        StringBuffer buffer = new StringBuffer();
-        for (int i = 0, size = name.length(); i < size; i++) {
-            char ch = name.charAt(i);
-            if (Character.isUpperCase(ch)) {
-                if (lastCharacterLowerCase) {
-                    buffer.append(' ');
-                }
-                lastCharacterLowerCase = false;
-            }
-            else {
-                lastCharacterLowerCase = true;
-            }
-            buffer.append(ch);
-        }
-        return buffer.toString();
-    }
-
-    public RouteDotGenerator() {
-        this("CamelRoutes.dot");
-    }
-
+public class RouteDotGenerator extends GraphGeneratorSupport {
     public RouteDotGenerator(String dir) {
-        this.dir = dir;
-    }
-
-    public String getDir() {
-        return dir;
-    }
-
-    /**
-     * Sets the destination directory in which to create the diagrams
-     */
-    public void setDir(String dir) {
-        this.dir = dir;
-    }
-
-    public void drawRoutes(CamelContext context) throws IOException {
-        File parent = new File(dir);
-        if (makeParentDirs) {
-            parent.mkdirs();
-        }
-        List<RouteType> routes = context.getRouteDefinitions();
-        routeGroupMap = createRouteGroupMap(routes);
-
-        // generate the global file
-        generateFile(parent, "routes.dot", routeGroupMap);
-
-        if (routeGroupMap.size() >= 1) {
-            Set<Map.Entry<String, List<RouteType>>> entries = routeGroupMap.entrySet();
-            for (Map.Entry<String, List<RouteType>> entry : entries) {
-
-                Map<String, List<RouteType>> map = new HashMap<String, List<RouteType>>();
-                String group = entry.getKey();
-                map.put(group, entry.getValue());
-
-                // generate the file containing just the routes in this group
-                generateFile(parent, group + ".dot", map);
-            }
-        }
-    }
-
-    private void generateFile(File parent, String fileName, Map<String, List<RouteType>> map) throws IOException {
-        nodeMap.clear();
-        clusterCounter = 0;
-                     
-        PrintWriter writer = new PrintWriter(new FileWriter(new File(parent, fileName)));
-        try {
-            generateFile(writer, map);
-        }
-        finally {
-            writer.close();
-        }
+        super(dir, ".dot");
     }
 
     // Implementation methods
     //-------------------------------------------------------------------------
 
-    protected class NodeData {
-        public String id;
-        public String image;
-        public String label;
-        public String shape;
-        public String edgeLabel;
-        public String tooltop;
-        public String nodeType;
-        public boolean nodeWritten;
-        public String url;
-        public List<ProcessorType> outputs;
-    }
-
-    protected void generateFile(PrintWriter writer, Map<String, List<RouteType>> map) {
-        writer.println("digraph CamelRoutes {");
-        writer.println();
-
-        writer.println("node [style = \"rounded,filled\", fillcolor = yellow, "
-                + "fontname=\"Helvetica-Oblique\"];");
-        writer.println();
-        printRoutes(writer, map);
-
-        writer.println("}");
-    }
-
     protected void printRoutes(PrintWriter writer, Map<String, List<RouteType>> map) {
-
-            Set<Map.Entry<String, List<RouteType>>> entries = map.entrySet();
-            for (Map.Entry<String, List<RouteType>> entry : entries) {
-                String group = entry.getKey();
-                printRoutes(writer, group, entry.getValue());
-            }
+        Set<Map.Entry<String, List<RouteType>>> entries = map.entrySet();
+        for (Map.Entry<String, List<RouteType>> entry : entries) {
+            String group = entry.getKey();
+            printRoutes(writer, group, entry.getValue());
+        }
     }
 
     protected void printRoutes(PrintWriter writer, String group, List<RouteType> routes) {
@@ -239,19 +119,17 @@
         // now lets write any children
         //List<ProcessorType> outputs = node.getOutputs();
         List<ProcessorType> outputs = toData.outputs;
-        for (ProcessorType output : outputs) {
-            NodeData newData = printNode(writer, toData, output);
-            if (!isMulticastNode(node)) {
-                toData = newData;
+        if (outputs != null) {
+            for (ProcessorType output : outputs) {
+                NodeData newData = printNode(writer, toData, output);
+                if (!isMulticastNode(node)) {
+                    toData = newData;
+                }
             }
         }
         return toData;
     }
 
-    protected boolean isMulticastNode(ProcessorType node) {
-        return node instanceof MulticastType || node instanceof ChoiceType;
-    }
-
     protected void printNode(PrintWriter writer, NodeData data) {
         if (!data.nodeWritten) {
             data.nodeWritten = true;
@@ -282,171 +160,15 @@
         }
     }
 
-    protected void configureNodeData(Object node, NodeData data) {
-        if (node instanceof ProcessorType) {
-            ProcessorType processorType = (ProcessorType) node;
-            data.edgeLabel = processorType.getLabel();
-        }
-        if (node instanceof FromType) {
-            FromType fromType = (FromType) node;
-            data.tooltop = fromType.getLabel();
-            data.label = removeQueryString(data.tooltop);
-            data.url = "http://activemq.apache.org/camel/message-endpoint.html";
-        }
-        else if (node instanceof ToType) {
-            ToType toType = (ToType) node;
-            data.tooltop = toType.getLabel();
-            data.label = removeQueryString(data.tooltop);
-            data.edgeLabel = "";
-            data.url = "http://activemq.apache.org/camel/message-endpoint.html";
-        }
-        else if (node instanceof FilterType) {
-            data.image = imagePrefix + "MessageFilterIcon.gif";
-            data.nodeType = "Message Filter";
-        }
-        else if (node instanceof WhenType) {
-            data.image = imagePrefix + "MessageFilterIcon.gif";
-            data.nodeType = "When Filter";
-            data.url = "http://activemq.apache.org/camel/content-based-router.html";
-        }
-        else if (node instanceof OtherwiseType) {
-            data.nodeType = "Otherwise";
-            data.edgeLabel = "";
-            data.url = "http://activemq.apache.org/camel/content-based-router.html";
-            data.tooltop = "Otherwise";
-        }
-        else if (node instanceof ChoiceType) {
-            data.image = imagePrefix + "ContentBasedRouterIcon.gif";
-            data.nodeType = "Content Based Router";
-            data.label = "";
-            data.edgeLabel = "";
-
-            ChoiceType choice = (ChoiceType) node;
-            List<ProcessorType> outputs = new ArrayList<ProcessorType>(choice.getWhenClauses());
-            outputs.add(choice.getOtherwise());
-            data.outputs = outputs;
-        }
-        else if (node instanceof RecipientListType) {
-            data.image = imagePrefix + "RecipientListIcon.gif";
-            data.nodeType = "Recipient List";
-        }
-        else if (node instanceof SplitterType) {
-            data.image = imagePrefix + "SplitterIcon.gif";
-            data.nodeType = "Splitter";
-        }
-        else if (node instanceof AggregatorType) {
-            data.image = imagePrefix + "AggregatorIcon.gif";
-            data.nodeType = "Aggregator";
-        }
-        else if (node instanceof ResequencerType) {
-            data.image = imagePrefix + "ResequencerIcon.gif";
-            data.nodeType = "Resequencer";
-        }
-
-        // lets auto-default as many values as we can
-        if (isNullOrBlank(data.nodeType)) {
-            // TODO we could add this to the model?
-            String name = node.getClass().getName();
-            int idx = name.lastIndexOf('.');
-            if (idx > 0) {
-                name = name.substring(idx + 1);
-            }
-            if (name.endsWith("Type")) {
-                name = name.substring(0, name.length() - 4);
-            }
-            data.nodeType = insertSpacesBetweenCamelCase(name);
-        }
-        if (data.label == null) {
-            if (isNullOrBlank(data.image)) {
-                data.label = data.nodeType;
-                data.shape = "box";
-            }
-            else if (isNotNullAndNonEmpty(data.edgeLabel)) {
-                data.label = "";
-            }
-            else {
-                data.label = node.toString();
-            }
-        }
-        if (isNullOrBlank(data.tooltop)) {
-            if (isNotNullAndNonEmpty(data.nodeType)) {
-                String description = isNotNullAndNonEmpty(data.edgeLabel) ? data.edgeLabel : data.label;
-                data.tooltop = data.nodeType + ": " + description;
-            }
-            else {
-                data.tooltop = data.label;
-            }
-        }
-        if (isNullOrBlank(data.url) && isNotNullAndNonEmpty(data.nodeType)) {
-            data.url = "http://activemq.apache.org/camel/" + data.nodeType.toLowerCase().replace(' ', '-') + ".html";
-        }
-        if (node instanceof ProcessorType && data.outputs == null) {
-            ProcessorType processorType = (ProcessorType) node;
-            data.outputs = processorType.getOutputs();
-        }
-    }
-
-    protected String removeQueryString(String text) {
-        int idx = text.indexOf("?");
-        if (idx <= 0) {
-            return text;
-        }
-        else {
-            return text.substring(0, idx);
-        }
-    }
-
-    protected String getLabel(List<ExpressionType> expressions) {
-        CollectionStringBuffer buffer = new CollectionStringBuffer();
-        for (ExpressionType expression : expressions) {
-            buffer.append(getLabel(expression));
-        }
-        return buffer.toString();
-    }
-
-    protected String getLabel(ExpressionType expression) {
-        if (expression != null) {
-            return expression.getLabel();
-        }
-        return "";
-    }
-
-    protected NodeData getNodeData(Object node) {
-        Object key = node;
-        if (node instanceof FromType) {
-            FromType fromType = (FromType) node;
-            key = fromType.getUriOrRef();
-        }
-        else if (node instanceof ToType) {
-            ToType toType = (ToType) node;
-            key = toType.getUriOrRef();
-        }
-        NodeData answer = nodeMap.get(key);
-        if (answer == null) {
-            answer = new NodeData();
-            answer.id = "node" + (nodeMap.size() + 1);
-            configureNodeData(node, answer);
-            nodeMap.put(key, answer);
-        }
-        return answer;
-    }
-
+    protected void generateFile(PrintWriter writer, Map<String, List<RouteType>> map) {
+        writer.println("digraph CamelRoutes {");
+        writer.println();
 
+        writer.println("node [style = \"rounded,filled\", fillcolor = yellow, "
+                + "fontname=\"Helvetica-Oblique\"];");
+        writer.println();
+        printRoutes(writer, map);
 
-    protected Map<String, List<RouteType>> createRouteGroupMap(List<RouteType> routes) {
-        Map<String, List<RouteType>> map = new HashMap<String, List<RouteType>>();
-        for (RouteType route : routes) {
-            String group = route.getGroup();
-            if (group == null) {
-                group = "Camel Routes";
-            }
-            List<RouteType> list = map.get(group);
-            if (list == null) {
-                list = new ArrayList<RouteType>();
-                map.put(group, list);
-            }
-            list.add(route);
-        }
-        return map;
+        writer.println("}");
     }
 }

Added: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/view/XmlGraphGenerator.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/view/XmlGraphGenerator.java?rev=577194&view=auto
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/view/XmlGraphGenerator.java (added)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/view/XmlGraphGenerator.java Wed Sep 19 01:38:38 2007
@@ -0,0 +1,148 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.view;
+
+import java.io.PrintWriter;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.camel.model.FromType;
+import org.apache.camel.model.MulticastType;
+import org.apache.camel.model.ProcessorType;
+import org.apache.camel.model.RouteType;
+import org.apache.camel.util.ObjectHelper;
+import static org.apache.camel.util.ObjectHelper.isNullOrBlank;
+
+/**
+ * @version $Revision: 1.1 $
+ */
+public class XmlGraphGenerator extends GraphGeneratorSupport {
+    public XmlGraphGenerator(String dir) {
+        super(dir, ".xml");
+    }
+
+    protected void generateFile(PrintWriter writer, Map<String, List<RouteType>> map) {
+        writer.println("<Graph>");
+        writer.println();
+
+        printRoutes(writer, map);
+
+        writer.println();
+        writer.println("</Graph>");
+    }
+
+    protected void printRoutes(PrintWriter writer, Map<String, List<RouteType>> map) {
+        Set<Map.Entry<String, List<RouteType>>> entries = map.entrySet();
+        for (Map.Entry<String, List<RouteType>> entry : entries) {
+            String group = entry.getKey();
+            printRoutes(writer, group, entry.getValue());
+        }
+    }
+
+    protected void printRoutes(PrintWriter writer, String group, List<RouteType> routes) {
+        if (group != null) {
+            // TODO
+        }
+        for (RouteType route : routes) {
+            List<FromType> inputs = route.getInputs();
+            for (FromType input : inputs) {
+                printRoute(writer, route, input);
+            }
+            writer.println();
+        }
+    }
+
+
+
+    protected void printRoute(PrintWriter writer, final RouteType route, FromType input) {
+        NodeData nodeData = getNodeData(input);
+
+        printNode(writer, nodeData);
+
+        // TODO we should add a transactional client / event driven consumer / polling client
+
+        List<ProcessorType> outputs = route.getOutputs();
+        NodeData from = nodeData;
+        for (ProcessorType output : outputs) {
+            NodeData newData = printNode(writer, from, output);
+            from = newData;
+        }
+    }
+
+    protected NodeData printNode(PrintWriter writer, NodeData fromData, ProcessorType node) {
+        if (node instanceof MulticastType) {
+            // no need for a multicast node
+            List<ProcessorType> outputs = node.getOutputs();
+            for (ProcessorType output : outputs) {
+                printNode(writer, fromData, output);
+            }
+            return fromData;
+        }
+        NodeData toData = getNodeData(node);
+
+        printNode(writer, toData);
+
+        if (fromData != null) {
+            writer.print("<Edge fromID='");
+            writer.print(fromData.id);
+            writer.print("' toID='");
+            writer.print(toData.id);
+            writer.print("' association='");
+            writer.print(toData.association);
+            writer.println("'/>");
+        }
+
+        // now lets write any children
+        List<ProcessorType> outputs = toData.outputs;
+        for (ProcessorType output : outputs) {
+            NodeData newData = printNode(writer, toData, output);
+            if (!isMulticastNode(node)) {
+                toData = newData;
+            }
+        }
+        return toData;
+    }
+
+    protected void printNode(PrintWriter writer, NodeData data) {
+        if (!data.nodeWritten) {
+            data.nodeWritten = true;
+
+            // <Node id="iedge" name="IEdge" nodeType="PrimitiveCircle" description=""   />
+            writer.println();
+            writer.print("<Node id='");
+            writer.print(data.id);
+            writer.print("' name='");
+            writer.print(data.label);
+            writer.print("' nodeType='");
+            String nodeType = data.image;
+            if (isNullOrBlank(nodeType)) {
+                nodeType = data.shape;
+                if (isNullOrBlank(nodeType)) {
+                    nodeType = "PrimitiveReverseBurst";
+                }            }
+            writer.print(nodeType);
+            writer.print("' description='");
+            writer.print(data.tooltop);
+            writer.print("' url='");
+            writer.print(data.url);
+            writer.println("'/>");
+        }
+    }
+
+}

Propchange: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/view/XmlGraphGenerator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/view/DotViewTest.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/view/DotViewTest.java?rev=577194&r1=577193&r2=577194&view=diff
==============================================================================
--- activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/view/DotViewTest.java (original)
+++ activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/view/DotViewTest.java Wed Sep 19 01:38:38 2007
@@ -16,21 +16,21 @@
  */
 package org.apache.camel.view;
 
+import java.io.File;
+
 import org.apache.camel.ContextTestSupport;
 import org.apache.camel.builder.RouteBuilder;
-
-import java.io.File;
+import org.apache.camel.builder.xml.XPathBuilder;
+import static org.apache.camel.builder.xml.XPathBuilder.xpath;
 
 /**
  * @version $Revision: 1.1 $
  */
 public class DotViewTest extends ContextTestSupport {
-    protected RouteDotGenerator generator = new RouteDotGenerator();
+    protected String outputDirectory = "target/site/cameldoc";
 
-    public void testDotFile() throws Exception {
-        new File("target").mkdirs();
-        
-        generator.setDir("target/site/cameldoc");
+    public void testGenerateFiles() throws Exception {
+        RouteDotGenerator generator = new RouteDotGenerator(outputDirectory);
         generator.drawRoutes(context);
     }
 
@@ -40,6 +40,9 @@
 
         context.addRoutes(new MulticastRoute());
         context.addRoutes(new PipelineRoute());
+        context.addRoutes(new ChoiceRoute());
+        context.addRoutes(new FilterRoute());
+        context.addRoutes(new ComplexRoute());
     }
 
     static class MulticastRoute extends RouteBuilder {
@@ -48,6 +51,7 @@
                     multicast().to("seda:multicast.out1", "seda:multicast.out2", "seda:multicast.out3");
         }
     }
+
     static class PipelineRoute extends RouteBuilder {
         public void configure() throws Exception {
             from("seda:pipeline.in").
@@ -55,26 +59,31 @@
         }
     }
 
-/*
-                from("file:foo/xyz?noop=true").
-                    choice().
-                      when(xpath("/person/city = 'London'")).to("file:target/messages/uk").
-                      otherwise().to("file:target/messages/others");
-*/
-
-/*
-
+    static class ChoiceRoute extends RouteBuilder {
+        public void configure() throws Exception {
+            from("file:foo/xyz?noop=true").
+                choice().
+                  when(xpath("/person/city = 'London'")).to("file:target/messages/uk").
+                  otherwise().to("file:target/messages/others");
+        }
+    }
 
+    static class FilterRoute extends RouteBuilder {
+        public void configure() throws Exception {
                 from("file:foo/bar?noop=true").
                         filter(header("foo").isEqualTo("bar")).
                         to("file:xyz?noop=true");
+        }
+    }
 
-                from("file:xyz?noop=true").
-                        filter(header("foo").isEqualTo("bar")).
-                        recipientList(header("bar")).
-                        splitter(XPathBuilder.xpath("/invoice/lineItems")).
-                        throttler(3).
-                        to("mock:result");
-*/
-
+    static class ComplexRoute extends RouteBuilder {
+        public void configure() throws Exception {
+            from("file:xyz?noop=true").
+                    filter(header("foo").isEqualTo("bar")).
+                    recipientList(header("bar")).
+                    splitter(XPathBuilder.xpath("/invoice/lineItems")).
+                    throttler(3).
+                    to("mock:result");
+        }
+    }
 }

Modified: activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/view/RouteDotGeneratorTest.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/view/RouteDotGeneratorTest.java?rev=577194&r1=577193&r2=577194&view=diff
==============================================================================
--- activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/view/RouteDotGeneratorTest.java (original)
+++ activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/view/RouteDotGeneratorTest.java Wed Sep 19 01:38:38 2007
@@ -25,7 +25,7 @@
 public class RouteDotGeneratorTest extends TestCase {
     
     public void testInsertSpacesBetweenCamelCase() throws Exception {
-        String value = RouteDotGenerator.insertSpacesBetweenCamelCase("FooBarType");
+        String value = NodeData.insertSpacesBetweenCamelCase("FooBarType");
         assertEquals("Converted value", "Foo Bar Type", value);
     }
 }

Added: activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/view/XmlGraphTest.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/view/XmlGraphTest.java?rev=577194&view=auto
==============================================================================
--- activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/view/XmlGraphTest.java (added)
+++ activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/view/XmlGraphTest.java Wed Sep 19 01:38:38 2007
@@ -0,0 +1,29 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.view;
+
+/**
+ * @version $Revision: 1.1 $
+ */
+public class XmlGraphTest extends DotViewTest {
+    @Override
+    public void testGenerateFiles() throws Exception {
+        XmlGraphGenerator generator = new XmlGraphGenerator(outputDirectory);
+        generator.drawRoutes(context);
+    }
+}

Propchange: activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/view/XmlGraphTest.java
------------------------------------------------------------------------------
    svn:eol-style = native