1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package com.mindtree.techworks.insight.gui;
26
27 import java.awt.BorderLayout;
28 import java.awt.Dimension;
29 import java.awt.Toolkit;
30 import java.awt.event.KeyAdapter;
31 import java.awt.event.KeyEvent;
32 import java.text.MessageFormat;
33 import java.util.Iterator;
34 import java.util.LinkedList;
35 import java.util.regex.Matcher;
36 import java.util.regex.Pattern;
37
38 import javax.swing.BorderFactory;
39 import javax.swing.JComponent;
40 import javax.swing.JPanel;
41 import javax.swing.JScrollPane;
42 import javax.swing.JTextPane;
43 import javax.swing.UIManager;
44 import javax.swing.text.BadLocationException;
45 import javax.swing.text.DefaultHighlighter;
46 import javax.swing.text.Document;
47 import javax.swing.text.Highlighter;
48
49 import com.mindtree.techworks.insight.Controller;
50 import com.mindtree.techworks.insight.InsightConstants;
51 import com.mindtree.techworks.insight.eventsearch.SearchCriteria;
52 import com.mindtree.techworks.insight.gui.action.FindAction;
53 import com.mindtree.techworks.insight.gui.widgets.StatusBar;
54 import com.mindtree.techworks.insight.pagination.IPage;
55 import com.mindtree.techworks.insight.spi.LogEvent;
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 public class EventDetailsPresentation extends JPanel implements Presentation {
71
72
73
74
75 private static final long serialVersionUID = -3210768545540400816L;
76
77
78
79
80 private static final int WIDTH = 900;
81 private static final int HEIGHT = 300;
82
83
84
85
86
87 private static final String EVENT_LIST_PRESENTATION = EventListPresentation.class.getName();
88
89
90
91
92 private Controller controller;
93
94
95
96
97 private LogEvent event;
98
99
100
101
102 private static final MessageFormat FORMATTER = new MessageFormat(
103 "<b>" + InsightConstants.getLiteral("NAMESPACE") + ":</b> <code>{0}</code>" +
104 "<br><b>" + InsightConstants.getLiteral("PRIORITY_LABEL") + ":</b> <code>{1}</code>" +
105 "<br><b>" + InsightConstants.getLiteral("THREAD_NAME_LABEL") + ":</b> <code>{2}</code>" +
106 "<br><b>" + InsightConstants.getLiteral("LOGGER_NAME") + ":</b> <code>{3}</code>" +
107 "<br><b>" + InsightConstants.getLiteral("MESSAGE_LABEL") + ":</b>" +
108 "<pre>{4}</pre>" +
109 "<b>" + InsightConstants.getLiteral("THROWABLE") + ":</b>" +
110 "<pre>{5}</pre>");
111
112
113
114
115 private JTextPane eventDetails;
116
117
118
119
120
121 public EventDetailsPresentation(Controller controller) {
122
123 setLayout(new BorderLayout());
124 setBorder(BorderFactory.createTitledBorder(InsightConstants.getLiteral("DETAILS")));
125
126 this.eventDetails = new JTextPane();
127 this.eventDetails.setEditable(false);
128 this.eventDetails.setContentType("text/html");
129
130
131
132 this.eventDetails.addKeyListener(new KeyAdapter() {
133 public void keyPressed(KeyEvent event) {
134 if (getEvent() != null && event.getKeyCode() == KeyEvent.VK_F && event.isControlDown()) {
135 FindAction.getInstance(getController().getInsight()).showSearchTextFrame();
136 }
137 }
138 });
139
140 add(new JScrollPane(eventDetails), BorderLayout.CENTER);
141
142 this.setPreferredSize(getIdealPreferredSize());
143
144 this.controller = controller;
145 this.controller.registerPresentation(this);
146 this.controller.registerWidgetChangeListener(controller.getPresentation(EVENT_LIST_PRESENTATION),this);
147
148 }
149
150
151
152
153
154
155 public String getUID() {
156 return this.getClass().getName();
157 }
158
159
160
161
162
163
164
165 public void notifyWidgetStateChange(Presentation presentation, int identifier, Object data) {
166 this.event = (LogEvent)data;
167 final Object[] args = {
168 event.getNamespace().getNamespaceAsString(),
169 event.getLevel(),
170 escape(event.getThreadName()),
171 escape(event.getLoggerName()),
172 escape(event.getMessage().toString()),
173 escape(getThrowableInfoAsString(event.getThrowableStrRepresentation())),
174 };
175 eventDetails.setText(FORMATTER.format(args));
176 eventDetails.setCaretPosition(0);
177 }
178
179
180
181
182
183 public JComponent getViewComponent() {
184 return this;
185 }
186
187
188
189
190
191 public boolean doesProcessRealTimeUpdates() {
192 return false;
193 }
194
195
196
197
198
199 public void processRealTimeUpdate(LogEvent logEvent) {
200
201 }
202
203
204
205
206
207 public void resetWidgets() {
208 this.event = null;
209 eventDetails.setText("");
210 }
211
212
213
214
215
216
217
218
219
220 public boolean highlightText(String searchText, int searchType) {
221 int firstIndex = -1;
222 try {
223 Document document = eventDetails.getDocument();
224 String sourceText = document.getText(0,document.getLength()).toUpperCase();
225
226 LinkedList matchAttributeBoundaryList = new LinkedList();
227
228
229 constructMatchAttributeBoundaryList(sourceText, matchAttributeBoundaryList, searchType);
230 Highlighter highlighter = eventDetails.getHighlighter();
231 highlighter.removeAllHighlights();
232
233 Highlighter.HighlightPainter highlightPainter =
234 new DefaultHighlighter.DefaultHighlightPainter(UIManager.getDefaults().getColor(InsightConstants.TEXT_HIGHLIGHT));
235 Pattern pattern = Pattern.compile(searchText, Pattern.CASE_INSENSITIVE | Pattern.DOTALL | Pattern.MULTILINE
236 | Pattern.CANON_EQ | Pattern.UNICODE_CASE);
237 Matcher matcher = pattern.matcher(sourceText);
238 while (matcher.find()) {
239 int searchIndex = matcher.start();
240 Iterator iterator = matchAttributeBoundaryList.iterator();
241 while(iterator.hasNext()) {
242 AttributeBoundary ab = (AttributeBoundary)iterator.next();
243
244 if (ab.containsEquals(searchType, searchIndex)) {
245 highlighter.addHighlight(searchIndex, matcher.end(), highlightPainter);
246 }
247 }
248 if (firstIndex == -1 && searchIndex > -1) {
249 firstIndex = searchIndex;
250 }
251 }
252 if (firstIndex > -1) {
253 eventDetails.setCaretPosition(firstIndex);
254 } else {
255 StatusBar.getInstance().setDisplayText(0,InsightConstants.getLiteral("ERROR_FIND_FAILURE"), false);
256 }
257 } catch (BadLocationException ble) {
258 ble.printStackTrace();
259 }
260 return ((firstIndex > -1));
261 }
262
263
264
265
266
267 public void displayPage(IPage page, long eventSequenceNumber) {
268
269
270 if (eventSequenceNumber < 0) {
271 resetWidgets();
272 }
273 }
274
275
276
277
278 public Controller getController() {
279 return controller;
280 }
281
282
283
284
285 public LogEvent getEvent() {
286 return event;
287 }
288
289
290
291
292
293 public void setScrollLock(boolean status) {
294
295 }
296
297
298
299
300
301
302
303 private String escape(String aStr) {
304 if (aStr == null) {
305 return null;
306 }
307 final StringBuffer buf = new StringBuffer();
308 for (int i = 0; i < aStr.length(); i++) {
309 char c = aStr.charAt(i);
310 switch (c) {
311 case '<':
312 buf.append("<");
313 break;
314 case '>':
315 buf.append(">");
316 break;
317 case '\"':
318 buf.append(""");
319 break;
320 case '&':
321 buf.append("&");
322 break;
323 default:
324 buf.append(c);
325 break;
326 }
327 }
328 return buf.toString();
329 }
330
331
332
333
334
335
336
337 private String getThrowableInfoAsString(String[] trace) {
338 StringBuffer buffer = new StringBuffer();
339 for (int i = 0; i < trace.length; i++) {
340 buffer.append(trace[i]).append("\n");
341 }
342 return buffer.toString();
343 }
344
345
346
347
348
349
350 private Dimension getIdealPreferredSize() {
351 Dimension dimension = null;
352 Dimension screenDim = Toolkit.getDefaultToolkit().getScreenSize();
353 dimension = new Dimension((int)Math.min(screenDim.getWidth() - 50, WIDTH),
354 (int)Math.min(screenDim.getHeight()/3, HEIGHT));
355 return dimension;
356 }
357
358
359
360
361
362
363
364
365
366 private void constructMatchAttributeBoundaryList(String sourceText, LinkedList matchAttributeBoundaryList, int searchType) {
367 if (this.event == null) {
368 return;
369 }
370 int attributeTextStartIndex = 0;
371
372
373
374
375
376
377 int attributeIndex = sourceText.indexOf(this.event.getNamespace().getNamespaceAsString().toUpperCase(), attributeTextStartIndex);
378 int attributeLength = this.event.getNamespace().getNamespaceAsString().length();
379 if ((searchType & SearchCriteria.NAMESPACE_SEARCH) == SearchCriteria.NAMESPACE_SEARCH) {
380 matchAttributeBoundaryList.add(new AttributeBoundary(SearchCriteria.NAMESPACE_SEARCH,
381 attributeTextStartIndex, attributeIndex + attributeLength));
382 }
383 attributeTextStartIndex = attributeIndex + attributeLength;
384
385
386 attributeIndex = sourceText.indexOf(this.event.getLevel().toString().toUpperCase(), attributeTextStartIndex);
387 attributeLength = this.event.getLevel().toString().length();
388 if ((searchType & SearchCriteria.PRIORITY_SEARCH) == SearchCriteria.PRIORITY_SEARCH) {
389 matchAttributeBoundaryList.add(new AttributeBoundary(SearchCriteria.PRIORITY_SEARCH,
390 attributeTextStartIndex, attributeIndex + attributeLength));
391 }
392 attributeTextStartIndex = attributeIndex + attributeLength;
393
394
395 attributeIndex = sourceText.indexOf(this.event.getThreadName().toUpperCase(), attributeTextStartIndex);
396 attributeLength = this.event.getThreadName().length();
397 if ((searchType & SearchCriteria.THREAD_SEARCH) == SearchCriteria.THREAD_SEARCH) {
398 matchAttributeBoundaryList.add(new AttributeBoundary(SearchCriteria.THREAD_SEARCH,
399 attributeTextStartIndex, attributeIndex + attributeLength));
400 }
401 attributeTextStartIndex = attributeIndex + attributeLength;
402
403
404 attributeIndex = sourceText.indexOf(this.event.getLoggerName().toUpperCase(), attributeTextStartIndex);
405 attributeLength = this.event.getLoggerName().length();
406 if ((searchType & SearchCriteria.CATEGORY_SEARCH) == SearchCriteria.CATEGORY_SEARCH) {
407 matchAttributeBoundaryList.add(new AttributeBoundary(SearchCriteria.CATEGORY_SEARCH,
408 attributeTextStartIndex, attributeIndex + attributeLength));
409 }
410 attributeTextStartIndex = attributeIndex + attributeLength;
411
412
413
414
415 attributeIndex = sourceText.indexOf(this.event.getMessage().toString().toUpperCase().replaceAll("\r",""), attributeTextStartIndex);
416 attributeLength = this.event.getMessage().toString().length();
417 if (((searchType & SearchCriteria.MESSAGE_SEARCH) == SearchCriteria.MESSAGE_SEARCH) ||
418 ((searchType & SearchCriteria.EXCEPTION_CLASS_NAME_SEARCH) == SearchCriteria.EXCEPTION_CLASS_NAME_SEARCH)) {
419 matchAttributeBoundaryList.add(new AttributeBoundary(SearchCriteria.MESSAGE_SEARCH,
420 attributeTextStartIndex, attributeIndex + attributeLength));
421 matchAttributeBoundaryList.add(new AttributeBoundary(SearchCriteria.EXCEPTION_CLASS_NAME_SEARCH,
422 attributeTextStartIndex, attributeIndex + attributeLength));
423 }
424 attributeTextStartIndex = attributeIndex + attributeLength;
425
426
427
428 attributeIndex = sourceText.indexOf(getThrowableInfoAsString(this.event.getThrowableStrRepresentation()).toUpperCase(), attributeTextStartIndex);
429 attributeLength = getThrowableInfoAsString(this.event.getThrowableStrRepresentation()).length();
430 if (((searchType & SearchCriteria.THROWABLE_SEARCH) == SearchCriteria.THROWABLE_SEARCH) ||
431 ((searchType & SearchCriteria.EXCEPTION_CLASS_NAME_SEARCH) == SearchCriteria.EXCEPTION_CLASS_NAME_SEARCH)) {
432 matchAttributeBoundaryList.add(new AttributeBoundary(SearchCriteria.THROWABLE_SEARCH,
433 attributeTextStartIndex, attributeIndex + attributeLength));
434 matchAttributeBoundaryList.add(new AttributeBoundary(SearchCriteria.EXCEPTION_CLASS_NAME_SEARCH,
435 attributeTextStartIndex, attributeIndex + attributeLength));
436 }
437 }
438
439
440
441
442
443 private class AttributeBoundary {
444
445
446
447 private int attributeType;
448
449
450
451
452 private int startIndex = -1;
453
454
455
456
457 private int endIndex = -1;
458
459
460
461
462
463
464
465
466 public AttributeBoundary(int attributeType, int startIndex, int endIndex) {
467 this.attributeType = attributeType;
468 this.startIndex = startIndex;
469 this.endIndex = endIndex;
470 }
471
472
473
474
475
476
477
478 public boolean containsEquals(int attributeType, int index) {
479 return (((attributeType & this.attributeType) == this.attributeType)
480 && index >= startIndex
481 && index <= endIndex);
482 }
483 }
484
485 }