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