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     */
017    package org.apache.camel.view;
018    
019    import java.io.File;
020    import java.io.FileWriter;
021    import java.io.IOException;
022    import java.io.PrintWriter;
023    import java.io.StringWriter;
024    import java.util.ArrayList;
025    import java.util.HashMap;
026    import java.util.List;
027    import java.util.Map;
028    import java.util.Set;
029    
030    import org.apache.camel.CamelContext;
031    import org.apache.camel.model.ChoiceDefinition;
032    import org.apache.camel.model.FromDefinition;
033    import org.apache.camel.model.MulticastDefinition;
034    import org.apache.camel.model.ProcessorDefinition;
035    import org.apache.camel.model.RouteDefinition;
036    import org.apache.camel.model.ToDefinition;
037    import org.apache.camel.model.language.ExpressionDefinition;
038    import org.apache.camel.util.CollectionStringBuffer;
039    import org.apache.commons.logging.Log;
040    import org.apache.commons.logging.LogFactory;
041    
042    /**
043     * @version $Revision: 752939 $
044     */
045    public abstract class GraphGeneratorSupport {
046        protected final transient Log log = LogFactory.getLog(getClass());
047        protected String dir;
048        protected int clusterCounter;
049        protected String extension;
050    
051        //private String imagePrefix = "http://www.enterpriseintegrationpatterns.com/img/";
052        private String imagePrefix = "http://camel.apache.org/images/eip/";
053        private Map<Object, NodeData> nodeMap = new HashMap<Object, NodeData>();
054        private boolean makeParentDirs = true;
055        private Map<String, List<RouteDefinition>> routeGroupMap;
056    
057        protected GraphGeneratorSupport(String dir, String extension) {
058            this.dir = dir;
059            this.extension = extension;
060        }
061    
062        public String getDir() {
063            return dir;
064        }
065    
066        /**
067         * Sets the destination directory in which to create the diagrams
068         */
069        public void setDir(String dir) {
070            this.dir = dir;
071        }
072    
073        public String getImagePrefix() {
074            return imagePrefix;
075        }
076    
077        public void setImagePrefix(String imagePrefix) {
078            this.imagePrefix = imagePrefix;
079        }
080    
081        public String getRoutesText(CamelContext context) throws IOException {
082            List<RouteDefinition> routes = context.getRouteDefinitions();
083            routeGroupMap = createRouteGroupMap(routes);
084            return createRouteMapText();
085        }
086    
087        public String getRouteText(RouteDefinition route) throws IOException {
088            routeGroupMap = createRouteGroupMap(route);
089            return createRouteMapText();
090        }
091    
092        private String createRouteMapText() {
093            StringWriter buffer = new StringWriter();
094            PrintWriter writer = new PrintWriter(buffer);
095            generateFile(writer, routeGroupMap);
096            writer.close();
097            return buffer.toString();
098        }
099    
100        public void drawRoutes(CamelContext context) throws IOException {
101            File parent = new File(dir);
102            if (makeParentDirs) {
103                parent.mkdirs();
104            }
105            List<RouteDefinition> routes = context.getRouteDefinitions();
106            routeGroupMap = createRouteGroupMap(routes);
107    
108            // generate the global file
109            generateFile(parent, "routes" + extension, routeGroupMap);
110    
111            if (routeGroupMap.size() >= 1) {
112                Set<Map.Entry<String, List<RouteDefinition>>> entries = routeGroupMap.entrySet();
113                for (Map.Entry<String, List<RouteDefinition>> entry : entries) {
114    
115                    Map<String, List<RouteDefinition>> map = new HashMap<String, List<RouteDefinition>>();
116                    String group = entry.getKey();
117                    map.put(group, entry.getValue());
118    
119                    // generate the file containing just the routes in this group
120                    generateFile(parent, group + extension, map);
121                }
122            }
123        }
124    
125        private void generateFile(File parent, String fileName, Map<String, List<RouteDefinition>> map) throws IOException {
126            nodeMap.clear();
127            clusterCounter = 0;
128    
129            PrintWriter writer = new PrintWriter(new FileWriter(new File(parent, fileName)));
130            try {
131                generateFile(writer, map);
132            } finally {
133                writer.close();
134            }
135        }
136    
137        protected abstract void generateFile(PrintWriter writer, Map<String, List<RouteDefinition>> map);
138    
139        protected boolean isMulticastNode(ProcessorDefinition node) {
140            return node instanceof MulticastDefinition || node instanceof ChoiceDefinition;
141        }
142    
143        protected String getLabel(List<ExpressionDefinition> expressions) {
144            CollectionStringBuffer buffer = new CollectionStringBuffer();
145            for (ExpressionDefinition expression : expressions) {
146                buffer.append(getLabel(expression));
147            }
148            return buffer.toString();
149        }
150    
151        protected String getLabel(ExpressionDefinition expression) {
152            if (expression != null) {
153                return expression.getLabel();
154            }
155            return "";
156        }
157    
158        protected NodeData getNodeData(Object node) {
159            Object key = node;
160            if (node instanceof FromDefinition) {
161                FromDefinition fromType = (FromDefinition) node;
162                key = fromType.getUriOrRef();
163            } else if (node instanceof ToDefinition) {
164                ToDefinition toType = (ToDefinition) node;
165                key = toType.getUriOrRef();
166            }
167            NodeData answer = nodeMap.get(key);
168            if (answer == null) {
169                String id = "node" + (nodeMap.size() + 1);
170                answer = new NodeData(id, node, imagePrefix);
171                nodeMap.put(key, answer);
172            }
173            return answer;
174        }
175    
176        protected Map<String, List<RouteDefinition>> createRouteGroupMap(List<RouteDefinition> routes) {
177            Map<String, List<RouteDefinition>> map = new HashMap<String, List<RouteDefinition>>();
178            for (RouteDefinition route : routes) {
179                addRouteToMap(map, route);
180            }
181            return map;
182        }
183    
184        protected Map<String, List<RouteDefinition>> createRouteGroupMap(RouteDefinition route) {
185            Map<String, List<RouteDefinition>> map = new HashMap<String, List<RouteDefinition>>();
186            addRouteToMap(map, route);
187            return map;
188        }
189    
190        protected void addRouteToMap(Map<String, List<RouteDefinition>> map, RouteDefinition route) {
191            String group = route.getGroup();
192            if (group == null) {
193                group = "Camel Routes";
194            }
195            List<RouteDefinition> list = map.get(group);
196            if (list == null) {
197                list = new ArrayList<RouteDefinition>();
198                map.put(group, list);
199            }
200            list.add(route);
201        }
202    }