1 package org.asteriskjava.tools;
2
3 import org.asteriskjava.live.DefaultAsteriskServer;
4 import org.asteriskjava.manager.ManagerEventListener;
5 import org.asteriskjava.manager.event.*;
6
7 import java.beans.BeanInfo;
8 import java.beans.Introspector;
9 import java.beans.PropertyDescriptor;
10 import java.io.IOException;
11 import java.io.PrintWriter;
12 import java.util.ArrayList;
13 import java.util.HashMap;
14 import java.util.List;
15 import java.util.Map;
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 public class HtmlEventTracer implements ManagerEventListener
34 {
35 private String filename = "trace.html";
36 private PrintWriter writer;
37 private final List<String> uniqueIds;
38 private final List<ManagerEvent> events;
39 private final Map<Class<? extends ManagerEvent>, String> colors;
40
41 public HtmlEventTracer()
42 {
43 uniqueIds = new ArrayList<String>();
44 events = new ArrayList<ManagerEvent>();
45 colors = new HashMap<Class<? extends ManagerEvent>, String>();
46
47 colors.put(NewChannelEvent.class, "#7cd300");
48 colors.put(NewStateEvent.class, "#a4b6c8");
49 colors.put(NewExtenEvent.class, "#efefef");
50 colors.put(RenameEvent.class, "#ddeeff");
51 colors.put(DialEvent.class, "#feec30");
52 colors.put(BridgeEvent.class, "#fff8ae");
53 colors.put(HangupEvent.class, "#ff6c17");
54
55 try
56 {
57 writer = new PrintWriter(filename);
58 }
59 catch (IOException e)
60 {
61 e.printStackTrace();
62 }
63 }
64
65 public static void main(String[] args) throws Exception
66 {
67 if (args.length != 3)
68 {
69 System.err.println("Usage: java org.asteriskjava.tools.HtmlEventTracer host username password");
70 System.exit(1);
71 }
72
73 final HtmlEventTracer tracer;
74 final DefaultAsteriskServer server;
75
76 tracer = new HtmlEventTracer();
77 server = new DefaultAsteriskServer(args[0], args[1], args[2]);
78 server.initialize();
79 server.getManagerConnection().addEventListener(tracer);
80
81 System.err.println("Event tracer successfully started. Press Ctrl-C to write trace file and exit.");
82
83 Runtime.getRuntime().addShutdownHook(new Thread()
84 {
85 @Override
86 public void run()
87 {
88 tracer.write();
89 server.shutdown();
90 }
91 }
92 );
93
94 while(true)
95 {
96 Thread.sleep(1000);
97 }
98 }
99
100 public void onManagerEvent(ManagerEvent event)
101 {
102 events.add(event);
103 System.out.println("> " + event);
104 for (String property : new String[]{"uniqueId", "uniqueId1", "uniqueId2", "srcUniqueId", "destUniqueId"})
105 {
106 String uniqueId;
107
108 uniqueId = getProperty(event, property);
109 if (uniqueId != null && !uniqueIds.contains(uniqueId))
110 {
111 uniqueIds.add(uniqueId);
112 }
113 }
114 }
115
116 public void write()
117 {
118 writer.append("<table border='1'><tr><td> </td>");
119 for (String uniqueId : uniqueIds)
120 {
121 writer.append("<td><font size='-2'>");
122 writer.append(uniqueId.substring(0, uniqueId.lastIndexOf('.') + 1));
123 writer.append("</font>");
124 writer.append(uniqueId.substring(uniqueId.lastIndexOf('.') + 1, uniqueId.length()));
125 writer.append("</td>");
126 }
127 writer.append("</tr>");
128 writer.println("");
129
130 for (ManagerEvent event : events)
131 {
132 boolean print = false;
133 StringBuilder line = new StringBuilder();
134
135 line.append("<tr><td>");
136 line.append(getLocalName(event.getClass()));
137 line.append("<br><font size='-2'>");
138 line.append(event.getDateReceived());
139 line.append("</font></td>");
140 for (String uniqueId : uniqueIds)
141 {
142 String text;
143 text = getText(uniqueId, event);
144 if (text == null)
145 {
146 line.append("<td> </td>");
147 }
148 else
149 {
150 String color = getColor(event.getClass());
151 line.append("<td bgcolor='").append(color).append("'><tt>").append(text).append("</tt></td>");
152 print = true;
153 }
154 }
155 line.append("</tr>");
156 if (print)
157 {
158 writer.println(line.toString());
159 }
160 }
161 writer.append("</table>");
162 writer.close();
163 System.err.println("Trace file successfully written to " + filename + ".");
164 }
165
166 private String getColor(Class<? extends ManagerEvent> clazz)
167 {
168 for (Map.Entry<Class<? extends ManagerEvent>, String> entry : colors.entrySet())
169 {
170 if (entry.getKey().isAssignableFrom(clazz))
171 {
172 return entry.getValue();
173 }
174 }
175 return "#ffffff";
176 }
177
178 protected String getProperty(Object obj, String property)
179 {
180 try
181 {
182 BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
183 for (PropertyDescriptor propertyDescriptor : beanInfo.getPropertyDescriptors())
184 {
185 if (!propertyDescriptor.getName().equals(property))
186 {
187 continue;
188 }
189
190 return propertyDescriptor.getReadMethod().invoke(obj).toString();
191 }
192 }
193 catch (Exception e)
194 {
195 System.err.println("Unable to read property '" + property + "' from object " + obj + ": " + e.getMessage());
196 return null;
197 }
198
199 return null;
200 }
201
202 protected String getLocalName(Class<?> c)
203 {
204 String s;
205
206 s = c.getName();
207 return s.substring(s.lastIndexOf(".") + 1, s.length());
208 }
209
210 protected String getText(String uniqueId, ManagerEvent event)
211 {
212 String format = null;
213 String[] properties = null;
214
215 if (uniqueId.equals(getProperty(event, "uniqueId")))
216 {
217 if (event instanceof NewChannelEvent)
218 {
219 format = "%s<br>%s";
220 properties = new String[]{"channel", "state"};
221 }
222 else if (event instanceof NewStateEvent)
223 {
224 format = "%s<br>%s";
225 properties = new String[]{"channel", "state"};
226 }
227 else if (event instanceof NewExtenEvent)
228 {
229 format = "%s,%s,%s<br>%s(%s)";
230 properties = new String[]{"context", "extension", "priority", "application", "appData"};
231 }
232 else if (event instanceof RenameEvent)
233 {
234 format = "old: %s<br>new: %s";
235 properties = new String[]{"oldname", "newname"};
236 }
237 else if (event instanceof HoldEvent)
238 {
239 format = "%s";
240 properties = new String[]{"status"};
241 }
242 else if (event instanceof AbstractParkedCallEvent)
243 {
244 format = "exten: %s<br>from: %s";
245 properties = new String[]{"exten", "from"};
246 }
247 else if (event instanceof HangupEvent)
248 {
249 format = "%s<br>%s (%s)";
250 properties = new String[]{"channel", "cause", "causeTxt"};
251 }
252 }
253
254 if (event instanceof BridgeEvent)
255 {
256 if (uniqueId.equals(getProperty(event, "uniqueId1")))
257 {
258 format = "%s<br>%s<br>%s";
259 properties = new String[]{"uniqueId2", "channel2", "bridgeState"};
260 }
261 else if (uniqueId.equals(getProperty(event, "uniqueId2")))
262 {
263 format = "%s<br>%s<br>%s";
264 properties = new String[]{"uniqueId1", "channel1", "bridgeState"};
265 }
266 }
267
268 if (event instanceof DialEvent)
269 {
270 if (uniqueId.equals(getProperty(event, "srcUniqueId")))
271 {
272 format = "To: %s";
273 properties = new String[]{"destination"};
274 }
275 else if (uniqueId.equals(getProperty(event, "destUniqueId")))
276 {
277 format = "From: %s";
278 properties = new String[]{"src"};
279 }
280 }
281
282 if (format != null)
283 {
284 String[] args = new String[properties.length];
285
286 for (int i = 0; i < properties.length; i++)
287 {
288 String value;
289
290 value = getProperty(event, properties[i]);
291 if (value == null)
292 {
293 args[i] = "";
294 }
295 else
296 {
297 value = value.replace("<", "<");
298 value = value.replace(">", ">");
299 args[i] = value;
300 }
301 }
302
303 return String.format(format, (Object[]) args);
304 }
305 return null;
306 }
307 }