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.activemq.broker.view;
018    
019    import java.io.PrintWriter;
020    import java.util.Collection;
021    import java.util.Iterator;
022    
023    import org.apache.activemq.broker.Broker;
024    import org.apache.activemq.broker.ConnectionContext;
025    import org.apache.activemq.broker.region.Destination;
026    import org.apache.activemq.command.ActiveMQDestination;
027    import org.apache.activemq.filter.DestinationMap;
028    import org.apache.activemq.filter.DestinationMapNode;
029    
030    /**
031     * @version $Revision: $
032     */
033    public class DestinationDotFileInterceptor extends DotFileInterceptorSupport {
034    
035        protected static final String ID_SEPARATOR = "_";
036    
037        public DestinationDotFileInterceptor(Broker next, String file) {
038            super(next, file);
039        }
040    
041        public Destination addDestination(ConnectionContext context, ActiveMQDestination destination) throws Exception {
042            Destination answer = super.addDestination(context, destination);
043            generateFile();
044            return answer;
045        }
046    
047        public void removeDestination(ConnectionContext context, ActiveMQDestination destination, long timeout) throws Exception {
048            super.removeDestination(context, destination, timeout);
049            generateFile();
050        }
051    
052        protected void generateFile(PrintWriter writer) throws Exception {
053            ActiveMQDestination[] destinations = getDestinations();
054    
055            // lets split into a tree
056            DestinationMap map = new DestinationMap();
057    
058            for (int i = 0; i < destinations.length; i++) {
059                ActiveMQDestination destination = destinations[i];
060                map.put(destination, destination);
061            }
062    
063            // now lets navigate the tree
064            writer.println("digraph \"ActiveMQ Destinations\" {");
065            writer.println();
066            writer.println("node [style = \"rounded,filled\", fontname=\"Helvetica-Oblique\"];");
067            writer.println();
068            writer.println("topic_root [fillcolor = deepskyblue, label = \"Topics\" ];");
069            writer.println("queue_root [fillcolor = deepskyblue, label = \"Queues\" ];");
070            writer.println();
071    
072            writer.println("subgraph queues {");
073            writer.println("  node [fillcolor=red];     ");
074            writer.println("  label = \"Queues\"");
075            writer.println();
076            printNodeLinks(writer, map.getQueueRootNode(), "queue");
077            writer.println("}");
078            writer.println();
079    
080            writer.println("subgraph topics {");
081            writer.println("  node [fillcolor=green];     ");
082            writer.println("  label = \"Topics\"");
083            writer.println();
084            printNodeLinks(writer, map.getTopicRootNode(), "topic");
085            writer.println("}");
086            writer.println();
087    
088            printNodes(writer, map.getQueueRootNode(), "queue");
089            writer.println();
090    
091            printNodes(writer, map.getTopicRootNode(), "topic");
092            writer.println();
093    
094            writer.println("}");
095        }
096    
097        protected void printNodes(PrintWriter writer, DestinationMapNode node, String prefix) {
098            String path = getPath(node);
099            writer.print("  ");
100            writer.print(prefix);
101            writer.print(ID_SEPARATOR);
102            writer.print(path);
103            String label = path;
104            if (prefix.equals("topic")) {
105                label = "Topics";
106            } else if (prefix.equals("queue")) {
107                label = "Queues";
108            }
109            writer.print("[ label = \"");
110            writer.print(label);
111            writer.println("\" ];");
112    
113            Collection children = node.getChildren();
114            for (Iterator iter = children.iterator(); iter.hasNext();) {
115                DestinationMapNode child = (DestinationMapNode)iter.next();
116                printNodes(writer, child, prefix + ID_SEPARATOR + path);
117            }
118        }
119    
120        protected void printNodeLinks(PrintWriter writer, DestinationMapNode node, String prefix) {
121            String path = getPath(node);
122            Collection children = node.getChildren();
123            for (Iterator iter = children.iterator(); iter.hasNext();) {
124                DestinationMapNode child = (DestinationMapNode)iter.next();
125    
126                writer.print("  ");
127                writer.print(prefix);
128                writer.print(ID_SEPARATOR);
129                writer.print(path);
130                writer.print(" -> ");
131                writer.print(prefix);
132                writer.print(ID_SEPARATOR);
133                writer.print(path);
134                writer.print(ID_SEPARATOR);
135                writer.print(getPath(child));
136                writer.println(";");
137    
138                printNodeLinks(writer, child, prefix + ID_SEPARATOR + path);
139            }
140        }
141    
142        protected String getPath(DestinationMapNode node) {
143            String path = node.getPath();
144            if (path.equals("*")) {
145                return "root";
146            }
147            return path;
148        }
149    }