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.activemq.broker.view;
018
019import java.io.PrintWriter;
020import java.util.Collection;
021import java.util.Iterator;
022import org.apache.activemq.broker.Broker;
023import org.apache.activemq.broker.ConnectionContext;
024import org.apache.activemq.broker.region.Destination;
025import org.apache.activemq.command.ActiveMQDestination;
026import org.apache.activemq.filter.DestinationMap;
027import org.apache.activemq.filter.DestinationMapNode;
028
029/**
030 * 
031 */
032public 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}