1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.log4j.chainsaw;
19
20 import java.beans.PropertyChangeEvent;
21 import java.beans.PropertyChangeListener;
22 import java.beans.PropertyChangeSupport;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.Collections;
26 import java.util.Date;
27 import java.util.HashSet;
28 import java.util.Iterator;
29 import java.util.List;
30 import java.util.Locale;
31 import java.util.Map;
32 import java.util.Set;
33
34 import javax.swing.ProgressMonitor;
35 import javax.swing.event.EventListenerList;
36 import javax.swing.table.AbstractTableModel;
37
38 import org.apache.log4j.LogManager;
39 import org.apache.log4j.Logger;
40 import org.apache.log4j.chainsaw.color.RuleColorizer;
41 import org.apache.log4j.chainsaw.helper.SwingHelper;
42 import org.apache.log4j.helpers.Constants;
43 import org.apache.log4j.rule.Rule;
44 import org.apache.log4j.spi.LocationInfo;
45 import org.apache.log4j.spi.LoggingEvent;
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 class ChainsawCyclicBufferTableModel extends AbstractTableModel
63 implements EventContainer, PropertyChangeListener {
64
65 private static final int DEFAULT_CAPACITY = 5000;
66
67 private boolean cyclic = true;
68 private int cyclicBufferSize = DEFAULT_CAPACITY;
69
70 List unfilteredList;
71
72 List filteredList;
73 private boolean currentSortAscending;
74 private int currentSortColumn;
75 private final EventListenerList eventListenerList = new EventListenerList();
76 private final List columnNames = new ArrayList(ChainsawColumns.getColumnsNames());
77 private boolean sortEnabled = false;
78 private boolean reachedCapacity = false;
79 private final Logger logger = LogManager.getLogger(ChainsawCyclicBufferTableModel.class);
80
81
82 private final LoggerNameModel loggerNameModelDelegate = new LoggerNameModelSupport();
83 private final Object mutex = new Object();
84
85
86
87 int uniqueRow;
88 private final Set uniquePropertyKeys = new HashSet();
89 private Rule ruleMediator;
90 private final PropertyChangeSupport propertySupport = new PropertyChangeSupport(this);
91 private RuleColorizer colorizer;
92 private final String tableModelName;
93
94 public ChainsawCyclicBufferTableModel(int cyclicBufferSize, RuleColorizer colorizer, String tableModelName) {
95 propertySupport.addPropertyChangeListener("cyclic", new ModelChanger());
96 this.cyclicBufferSize = cyclicBufferSize;
97 this.colorizer = colorizer;
98 this.tableModelName = tableModelName;
99
100 unfilteredList = new CyclicBufferList(cyclicBufferSize);
101 filteredList = new CyclicBufferList(cyclicBufferSize);
102 }
103
104
105
106
107 public void propertyChange(PropertyChangeEvent evt) {
108 if (evt.getSource() instanceof Rule) {
109 if (evt.getSource() == ruleMediator && evt.getPropertyName().equals("findRule")) {
110 if (((RuleMediator) evt.getSource()).isFindRuleRequired()) {
111
112 reFilter();
113 }
114 } else {
115 reFilter();
116 }
117 }
118 }
119
120 public List getMatchingEvents(Rule rule) {
121 List list = new ArrayList();
122 List unfilteredCopy;
123 synchronized (mutex) {
124 unfilteredCopy = new ArrayList(unfilteredList);
125 }
126 Iterator iter = unfilteredCopy.iterator();
127
128 while (iter.hasNext()) {
129 LoggingEventWrapper loggingEventWrapper = (LoggingEventWrapper) iter.next();
130
131 if (rule.evaluate(loggingEventWrapper.getLoggingEvent(), null)) {
132 list.add(loggingEventWrapper);
133 }
134 }
135
136 return list;
137 }
138
139 public void reFilter() {
140 final int previousSize;
141 final int newSize;
142 synchronized (mutex) {
143
144 propertySupport.firePropertyChange("refilter", Boolean.FALSE, Boolean.TRUE);
145 previousSize = filteredList.size();
146 filteredList.clear();
147 if (ruleMediator == null) {
148 LoggingEventWrapper lastEvent = null;
149 for (Iterator iter = unfilteredList.iterator();iter.hasNext();) {
150 LoggingEventWrapper loggingEventWrapper = (LoggingEventWrapper)iter.next();
151 loggingEventWrapper.setDisplayed(true);
152 updateEventMillisDelta(loggingEventWrapper, lastEvent);
153 filteredList.add(loggingEventWrapper);
154 lastEvent = loggingEventWrapper;
155 }
156 } else {
157 Iterator iter = unfilteredList.iterator();
158 LoggingEventWrapper lastEvent = null;
159 while (iter.hasNext()) {
160 LoggingEventWrapper loggingEventWrapper = (LoggingEventWrapper) iter.next();
161
162 if (ruleMediator.evaluate(loggingEventWrapper.getLoggingEvent(), null)) {
163 loggingEventWrapper.setDisplayed(true);
164 filteredList.add(loggingEventWrapper);
165 updateEventMillisDelta(loggingEventWrapper, lastEvent);
166 lastEvent = loggingEventWrapper;
167 } else {
168 loggingEventWrapper.setDisplayed(false);
169 }
170 }
171 }
172 newSize = filteredList.size();
173 }
174 SwingHelper.invokeOnEDT(new Runnable() {
175 public void run() {
176 if (newSize > 0) {
177 if (previousSize == newSize) {
178
179 fireTableRowsUpdated(0, newSize - 1);
180 } else if (previousSize > newSize) {
181
182 fireTableRowsUpdated(0, newSize - 1);
183
184 fireTableDataChanged();
185 } else if (previousSize < newSize) {
186
187 if (previousSize > 0) {
188 fireTableRowsUpdated(0, previousSize - 1);
189 }
190 fireTableRowsInserted(Math.max(0, previousSize), newSize - 1);
191 }
192 } else {
193
194 fireTableDataChanged();
195 }
196 notifyCountListeners();
197
198 SwingHelper.invokeOnEDT(new Runnable() {
199 public void run() {
200 propertySupport.firePropertyChange("refilter", Boolean.TRUE, Boolean.FALSE);
201 }
202 });
203 }});
204 }
205
206 public int locate(Rule rule, int startLocation, boolean searchForward) {
207 List filteredListCopy;
208 synchronized (mutex) {
209 filteredListCopy = new ArrayList(filteredList);
210 }
211 if (searchForward) {
212 for (int i = startLocation; i < filteredListCopy.size(); i++) {
213 if (rule.evaluate(((LoggingEventWrapper) filteredListCopy.get(i)).getLoggingEvent(), null)) {
214 return i;
215 }
216 }
217
218 for (int i = 0; i < startLocation; i++) {
219 if (rule.evaluate(((LoggingEventWrapper) filteredListCopy.get(i)).getLoggingEvent(), null)) {
220 return i;
221 }
222 }
223 } else {
224 for (int i = startLocation; i > -1; i--) {
225 if (rule.evaluate(((LoggingEventWrapper) filteredListCopy.get(i)).getLoggingEvent(), null)) {
226 return i;
227 }
228 }
229
230 for (int i = filteredListCopy.size() - 1; i > startLocation; i--) {
231 if (rule.evaluate(((LoggingEventWrapper) filteredListCopy.get(i)).getLoggingEvent(), null)) {
232 return i;
233 }
234 }
235 }
236
237 return -1;
238 }
239
240
241
242
243 public void removeLoggerNameListener(LoggerNameListener l) {
244 loggerNameModelDelegate.removeLoggerNameListener(l);
245 }
246
247
248
249
250
251 public boolean addLoggerName(String loggerName) {
252 return loggerNameModelDelegate.addLoggerName(loggerName);
253 }
254
255 public String toString() {
256 return "ChainsawCyclicBufferTableModel{" +
257 "name='" + tableModelName + '\'' +
258 '}';
259 }
260
261 public void reset() {
262 loggerNameModelDelegate.reset();
263 }
264
265
266
267
268 public void addLoggerNameListener(LoggerNameListener l) {
269 loggerNameModelDelegate.addLoggerNameListener(l);
270 }
271
272
273
274
275 public Collection getLoggerNames() {
276 return loggerNameModelDelegate.getLoggerNames();
277 }
278
279 public void addEventCountListener(EventCountListener listener) {
280 eventListenerList.add(EventCountListener.class, listener);
281 }
282
283 public boolean isSortable(int col) {
284 return true;
285 }
286
287 public void notifyCountListeners() {
288 EventCountListener[] listeners =
289 (EventCountListener[]) eventListenerList.getListeners(
290 EventCountListener.class);
291
292 int filteredListSize;
293 int unfilteredListSize;
294 synchronized (mutex) {
295 filteredListSize = filteredList.size();
296 unfilteredListSize = unfilteredList.size();
297 }
298 for (int i = 0; i < listeners.length; i++) {
299 listeners[i].eventCountChanged(
300 filteredListSize, unfilteredListSize);
301 }
302 }
303
304
305
306
307
308
309
310
311 public void setRuleMediator(RuleMediator ruleMediator) {
312 if (this.ruleMediator != null) {
313 this.ruleMediator.removePropertyChangeListener(this);
314 }
315
316 this.ruleMediator = ruleMediator;
317
318 if (this.ruleMediator != null) {
319 this.ruleMediator.addPropertyChangeListener(this);
320 }
321 reFilter();
322 }
323
324
325
326
327 public void sort() {
328 boolean sort;
329 final int filteredListSize;
330 synchronized (mutex) {
331 filteredListSize = filteredList.size();
332 sort = (sortEnabled && filteredListSize > 0);
333 if (sort) {
334
335 LoggingEventWrapper lastEvent = null;
336 for (Iterator iter = filteredList.iterator();iter.hasNext();) {
337 LoggingEventWrapper e = (LoggingEventWrapper)iter.next();
338 e.setDisplayed(true);
339 updateEventMillisDelta(e, lastEvent);
340 lastEvent = e;
341 }
342 Collections.sort(
343 filteredList,
344 new ColumnComparator(
345 getColumnName(currentSortColumn), currentSortColumn,
346 currentSortAscending));
347 }
348 }
349 if (sort) {
350 SwingHelper.invokeOnEDT(new Runnable() {
351 public void run() {
352 fireTableRowsUpdated(0, Math.max(filteredListSize - 1, 0));
353 }
354 });
355 }
356 }
357
358 public boolean isSortEnabled() {
359 return sortEnabled;
360 }
361
362 public void sortColumn(int col, boolean ascending) {
363 logger.debug("request to sort col=" + col);
364 currentSortAscending = ascending;
365 currentSortColumn = col;
366 sortEnabled = true;
367 sort();
368 }
369
370
371
372
373 public void clearModel() {
374 reachedCapacity = false;
375
376 synchronized (mutex) {
377 unfilteredList.clear();
378 filteredList.clear();
379 uniqueRow = 0;
380 }
381
382 SwingHelper.invokeOnEDT(new Runnable() {
383 public void run() {
384 fireTableDataChanged();
385 }
386 });
387
388 notifyCountListeners();
389 loggerNameModelDelegate.reset();
390 }
391
392 public List getAllEvents() {
393 synchronized (mutex) {
394 return new ArrayList(unfilteredList);
395 }
396 }
397
398
399 public List getFilteredEvents() {
400
401 synchronized (mutex) {
402 return new ArrayList(filteredList);
403 }
404 }
405
406 public int getRowIndex(LoggingEventWrapper loggingEventWrapper) {
407 synchronized (mutex) {
408 return filteredList.indexOf(loggingEventWrapper);
409 }
410 }
411
412 public void removePropertyFromEvents(String propName) {
413
414 List filteredListCopy;
415 List unfilteredListCopy;
416 synchronized(mutex) {
417 filteredListCopy = new ArrayList(filteredList);
418 unfilteredListCopy = new ArrayList(unfilteredList);
419 }
420 for (int i=0;i<filteredListCopy.size();i++) {
421 LoggingEventWrapper loggingEventWrapper = (LoggingEventWrapper)filteredListCopy.get(i);
422 Object result = loggingEventWrapper.removeProperty(propName);
423 if (result != null) {
424 fireRowUpdated(i, false);
425 }
426 }
427
428 for (Iterator iter = unfilteredListCopy.iterator();iter.hasNext();) {
429 LoggingEventWrapper loggingEventWrapper = (LoggingEventWrapper)iter.next();
430 loggingEventWrapper.removeProperty(propName);
431 }
432 }
433
434 public int updateEventsWithFindRule(Rule findRule) {
435 int count = 0;
436 List unfilteredListCopy;
437 synchronized(mutex) {
438 unfilteredListCopy = new ArrayList(unfilteredList);
439 }
440 for (Iterator iter = unfilteredListCopy.iterator();iter.hasNext();) {
441 LoggingEventWrapper loggingEventWrapper = (LoggingEventWrapper) iter.next();
442 loggingEventWrapper.evaluateSearchRule(findRule);
443
444 if (loggingEventWrapper.isSearchMatch() && loggingEventWrapper.isDisplayed()) {
445 count++;
446 }
447 }
448 return count;
449 }
450
451 public int findColoredRow(int startLocation, boolean searchForward) {
452 List filteredListCopy;
453 synchronized (mutex) {
454 filteredListCopy = new ArrayList(filteredList);
455 }
456 if (searchForward) {
457 for (int i = startLocation; i < filteredListCopy.size(); i++) {
458 LoggingEventWrapper event = (LoggingEventWrapper)filteredListCopy.get(i);
459 if (!event.getColorRuleBackground().equals(ChainsawConstants.COLOR_DEFAULT_BACKGROUND) ||
460 !event.getColorRuleForeground().equals(ChainsawConstants.COLOR_DEFAULT_FOREGROUND)) {
461 return i;
462 }
463 }
464
465 for (int i = 0; i < startLocation; i++) {
466 LoggingEventWrapper event = (LoggingEventWrapper)filteredListCopy.get(i);
467 if (!event.getColorRuleBackground().equals(ChainsawConstants.COLOR_DEFAULT_BACKGROUND) ||
468 !event.getColorRuleForeground().equals(ChainsawConstants.COLOR_DEFAULT_FOREGROUND)) {
469 return i;
470 }
471 }
472 } else {
473 for (int i = startLocation; i > -1; i--) {
474 LoggingEventWrapper event = (LoggingEventWrapper)filteredListCopy.get(i);
475 if (!event.getColorRuleBackground().equals(ChainsawConstants.COLOR_DEFAULT_BACKGROUND) ||
476 !event.getColorRuleForeground().equals(ChainsawConstants.COLOR_DEFAULT_FOREGROUND)) {
477 return i;
478 }
479 }
480
481 for (int i = filteredListCopy.size() - 1; i > startLocation; i--) {
482 LoggingEventWrapper event = (LoggingEventWrapper)filteredListCopy.get(i);
483 if (!event.getColorRuleBackground().equals(ChainsawConstants.COLOR_DEFAULT_BACKGROUND) ||
484 !event.getColorRuleForeground().equals(ChainsawConstants.COLOR_DEFAULT_FOREGROUND)) {
485 return i;
486 }
487 }
488 }
489
490 return -1;
491 }
492
493 public int getSearchMatchCount() {
494 int searchMatchCount = 0;
495 synchronized(mutex) {
496 for (Iterator iter = filteredList.iterator();iter.hasNext();) {
497 LoggingEventWrapper wrapper = (LoggingEventWrapper) iter.next();
498 if (wrapper.isSearchMatch() && wrapper.isDisplayed()) {
499 searchMatchCount++;
500 }
501 }
502 }
503 return searchMatchCount;
504 }
505
506 public int getColumnCount() {
507 return columnNames.size();
508 }
509
510 public String getColumnName(int column) {
511 return (String) columnNames.get(column);
512 }
513
514 public LoggingEventWrapper getRow(int row) {
515 synchronized (mutex) {
516 if (row < filteredList.size() && row > -1) {
517 return (LoggingEventWrapper) filteredList.get(row);
518 }
519 }
520
521 return null;
522 }
523
524 public int getRowCount() {
525 synchronized (mutex) {
526 return filteredList.size();
527 }
528 }
529
530 public Object getValueAt(int rowIndex, int columnIndex) {
531 LoggingEvent event = null;
532
533 synchronized (mutex) {
534 if (rowIndex < filteredList.size() && rowIndex > -1) {
535 event = ((LoggingEventWrapper) filteredList.get(rowIndex)).getLoggingEvent();
536 }
537 }
538
539 if (event == null) {
540 return null;
541 }
542
543 LocationInfo info = null;
544
545 if (event.locationInformationExists()) {
546 info = event.getLocationInformation();
547 }
548
549 switch (columnIndex + 1) {
550 case ChainsawColumns.INDEX_ID_COL_NAME:
551
552 Object id = event.getProperty(Constants.LOG4J_ID_KEY);
553
554 if (id != null) {
555 return id;
556 }
557
558 return new Integer(rowIndex);
559
560 case ChainsawColumns.INDEX_LEVEL_COL_NAME:
561 return event.getLevel();
562
563 case ChainsawColumns.INDEX_LOG4J_MARKER_COL_NAME:
564 return event.getProperty(ChainsawConstants.LOG4J_MARKER_COL_NAME_LOWERCASE);
565
566 case ChainsawColumns.INDEX_MILLIS_DELTA_COL_NAME:
567 return event.getProperty(ChainsawConstants.MILLIS_DELTA_COL_NAME_LOWERCASE);
568
569 case ChainsawColumns.INDEX_LOGGER_COL_NAME:
570 return event.getLoggerName();
571
572 case ChainsawColumns.INDEX_TIMESTAMP_COL_NAME:
573 return new Date(event.getTimeStamp());
574
575 case ChainsawColumns.INDEX_MESSAGE_COL_NAME:
576 return event.getRenderedMessage();
577
578 case ChainsawColumns.INDEX_NDC_COL_NAME:
579 return event.getNDC();
580
581 case ChainsawColumns.INDEX_THREAD_COL_NAME:
582 return event.getThreadName();
583
584 case ChainsawColumns.INDEX_THROWABLE_COL_NAME:
585 return event.getThrowableStrRep();
586
587 case ChainsawColumns.INDEX_CLASS_COL_NAME:
588 return ((info == null) || ("?".equals(info.getClassName()))) ? "" : info.getClassName();
589
590 case ChainsawColumns.INDEX_FILE_COL_NAME:
591 return ((info == null) || ("?".equals(info.getFileName()))) ? "" : info.getFileName();
592
593 case ChainsawColumns.INDEX_LINE_COL_NAME:
594 return ((info == null) || ("?".equals(info.getLineNumber()))) ? "" : info.getLineNumber();
595
596 case ChainsawColumns.INDEX_METHOD_COL_NAME:
597 return ((info == null) || ("?".equals(info.getMethodName()))) ? "" : info.getMethodName();
598
599 default:
600
601 if (columnIndex < columnNames.size()) {
602
603 String result = event.getProperty(columnNames.get(columnIndex).toString());
604 if (result == null) {
605 String lowerColName = columnNames.get(columnIndex).toString().toLowerCase(Locale.ENGLISH);
606 Set entrySet = event.getProperties().entrySet();
607 for (Iterator iter = entrySet.iterator();iter.hasNext();) {
608 Map.Entry thisEntry = (Map.Entry) iter.next();
609 if (thisEntry.getKey().toString().equalsIgnoreCase(lowerColName)) {
610 result = thisEntry.getValue().toString();
611 }
612 }
613 }
614 if (result != null) {
615 return result;
616 }
617 }
618 }
619 return "";
620 }
621
622 public boolean isAddRow(LoggingEventWrapper loggingEventWrapper) {
623 Object id = loggingEventWrapper.getLoggingEvent().getProperty(Constants.LOG4J_ID_KEY);
624
625
626 if (id == null) {
627 id = new Integer(++uniqueRow);
628 loggingEventWrapper.setProperty(Constants.LOG4J_ID_KEY, id.toString());
629 }
630
631 loggingEventWrapper.updateColorRuleColors(colorizer.getBackgroundColor(loggingEventWrapper.getLoggingEvent()), colorizer.getForegroundColor(loggingEventWrapper.getLoggingEvent()));
632 Rule findRule = colorizer.getFindRule();
633 if (findRule != null) {
634 loggingEventWrapper.evaluateSearchRule(colorizer.getFindRule());
635 }
636
637 boolean rowAdded = false;
638
639
640
641
642
643
644
645 synchronized(mutex) {
646 if (cyclic) {
647 CyclicBufferList bufferList = (CyclicBufferList) unfilteredList;
648 if (bufferList.size() == bufferList.getMaxSize()) {
649 reachedCapacity = true;
650 }
651 }
652 int unfilteredSize = unfilteredList.size();
653 LoggingEventWrapper lastLoggingEventWrapper = null;
654 if (unfilteredSize > 0) {
655 lastLoggingEventWrapper = (LoggingEventWrapper) unfilteredList.get(unfilteredSize - 1);
656 }
657 unfilteredList.add(loggingEventWrapper);
658 if ((ruleMediator == null) || (ruleMediator.evaluate(loggingEventWrapper.getLoggingEvent(), null))) {
659 loggingEventWrapper.setDisplayed(true);
660 updateEventMillisDelta(loggingEventWrapper, lastLoggingEventWrapper);
661 filteredList.add(loggingEventWrapper);
662 rowAdded = true;
663 } else {
664 loggingEventWrapper.setDisplayed(false);
665 }
666 }
667
668 checkForNewColumn(loggingEventWrapper);
669
670 return rowAdded;
671 }
672
673 private void updateEventMillisDelta(LoggingEventWrapper loggingEventWrapper, LoggingEventWrapper lastLoggingEventWrapper) {
674 if (lastLoggingEventWrapper != null) {
675 loggingEventWrapper.setPreviousDisplayedEventTimestamp(lastLoggingEventWrapper.getLoggingEvent().getTimeStamp());
676 } else {
677
678 loggingEventWrapper.setPreviousDisplayedEventTimestamp(loggingEventWrapper.getLoggingEvent().getTimeStamp());
679 }
680 }
681
682 private void checkForNewColumn(LoggingEventWrapper loggingEventWrapper)
683 {
684
685
686
687
688 boolean newColumn = uniquePropertyKeys.addAll(loggingEventWrapper.getPropertyKeySet());
689
690 if (newColumn) {
691
692
693
694 for (Iterator iter = loggingEventWrapper.getPropertyKeySet().iterator(); iter.hasNext();) {
695 String key = iter.next().toString().toUpperCase();
696
697
698 if (!columnNames.contains(key) && !(Constants.LOG4J_ID_KEY.equalsIgnoreCase(key))) {
699 columnNames.add(key);
700 logger.debug("Adding col '" + key + "', columnNames=" + columnNames);
701 fireNewKeyColumnAdded(
702 new NewKeyEvent(
703 this, columnNames.indexOf(key), key, loggingEventWrapper.getLoggingEvent().getProperty(key)));
704 }
705 }
706 }
707 }
708
709 public void fireTableEvent(final int begin, final int end, final int count) {
710 SwingHelper.invokeOnEDT(new Runnable() {
711 public void run() {
712 if (cyclic) {
713 if (!reachedCapacity) {
714
715 if ((begin + count) < cyclicBufferSize) {
716 fireTableRowsInserted(begin, end);
717 } else {
718
719
720 fireTableRowsInserted(begin, cyclicBufferSize - 1);
721 fireTableRowsUpdated(0, cyclicBufferSize - 1);
722 reachedCapacity = true;
723 }
724 } else {
725 fireTableRowsUpdated(0, cyclicBufferSize - 1);
726 }
727 } else {
728 fireTableRowsInserted(begin, end);
729 }
730 }});
731 }
732
733 public void fireRowUpdated(int row, boolean checkForNewColumns) {
734 LoggingEventWrapper loggingEventWrapper = getRow(row);
735 if (loggingEventWrapper != null)
736 {
737 loggingEventWrapper.updateColorRuleColors(colorizer.getBackgroundColor(loggingEventWrapper.getLoggingEvent()), colorizer.getForegroundColor(loggingEventWrapper.getLoggingEvent()));
738 Rule findRule = colorizer.getFindRule();
739 if (findRule != null) {
740 loggingEventWrapper.evaluateSearchRule(colorizer.getFindRule());
741 }
742
743 fireTableRowsUpdated(row, row);
744 if (checkForNewColumns) {
745
746 checkForNewColumn(loggingEventWrapper);
747 }
748 }
749 }
750
751
752
753
754 private void fireNewKeyColumnAdded(NewKeyEvent e) {
755 NewKeyListener[] listeners =
756 (NewKeyListener[]) eventListenerList.getListeners(NewKeyListener.class);
757
758 for (int i = 0; i < listeners.length; i++) {
759 NewKeyListener listener = listeners[i];
760 listener.newKeyAdded(e);
761 }
762 }
763
764
765
766
767 public int getMaxSize() {
768 return cyclicBufferSize;
769 }
770
771
772
773
774 public void addNewKeyListener(NewKeyListener l) {
775 eventListenerList.add(NewKeyListener.class, l);
776 }
777
778
779
780
781 public void removeNewKeyListener(NewKeyListener l) {
782 eventListenerList.remove(NewKeyListener.class, l);
783 }
784
785
786
787
788 public boolean isCellEditable(int rowIndex, int columnIndex) {
789 if (getColumnName(columnIndex).equalsIgnoreCase(ChainsawConstants.LOG4J_MARKER_COL_NAME_LOWERCASE)) {
790 return true;
791 }
792
793 if (columnIndex >= columnNames.size()) {
794 return false;
795 }
796
797 return super.isCellEditable(rowIndex, columnIndex);
798 }
799
800
801
802
803 public void setCyclic(final boolean cyclic) {
804 if (this.cyclic == cyclic) {
805 return;
806 }
807
808 final boolean old = this.cyclic;
809 this.cyclic = cyclic;
810 propertySupport.firePropertyChange("cyclic", old, cyclic);
811 }
812
813
814
815
816 public void addPropertyChangeListener(PropertyChangeListener l) {
817 propertySupport.addPropertyChangeListener(l);
818 }
819
820
821
822
823 public void addPropertyChangeListener(
824 String propertyName, PropertyChangeListener l) {
825 propertySupport.addPropertyChangeListener(propertyName, l);
826 }
827
828
829
830
831 public int size() {
832 synchronized(mutex) {
833 return unfilteredList.size();
834 }
835 }
836
837 private class ModelChanger implements PropertyChangeListener {
838
839
840
841 public void propertyChange(PropertyChangeEvent arg0) {
842 Thread thread =
843 new Thread(
844 new Runnable() {
845 public void run() {
846 ProgressMonitor monitor = null;
847
848 int index = 0;
849
850 try {
851 synchronized (mutex) {
852 monitor =
853 new ProgressMonitor(
854 null, "Switching models...",
855 "Transferring between data structures, please wait...", 0,
856 unfilteredList.size() + 1);
857 monitor.setMillisToDecideToPopup(250);
858 monitor.setMillisToPopup(100);
859 logger.debug(
860 "Changing Model, isCyclic is now " + cyclic);
861
862 List newUnfilteredList = null;
863 List newFilteredList = null;
864
865 if (cyclic) {
866 newUnfilteredList = new CyclicBufferList(cyclicBufferSize);
867 newFilteredList = new CyclicBufferList(cyclicBufferSize);
868 } else {
869 newUnfilteredList = new ArrayList(cyclicBufferSize);
870 newFilteredList = new ArrayList(cyclicBufferSize);
871 }
872
873 int increment = 0;
874
875 for (Iterator iter = unfilteredList.iterator();
876 iter.hasNext();) {
877 LoggingEventWrapper loggingEventWrapper = (LoggingEventWrapper) iter.next();
878 newUnfilteredList.add(loggingEventWrapper);
879 monitor.setProgress(index++);
880 }
881
882 unfilteredList = newUnfilteredList;
883 filteredList = newFilteredList;
884 }
885
886 monitor.setNote("Refiltering...");
887 reFilter();
888
889 monitor.setProgress(index++);
890 } finally {
891 monitor.close();
892 }
893
894 logger.debug("Model Change completed");
895 }
896 });
897 thread.setPriority(Thread.MIN_PRIORITY + 1);
898 thread.start();
899 }
900 }
901 }