1 16 package org.apache.log4j.chainsaw; 17 18 import java.text.DateFormat ; 19 import java.util.ArrayList ; 20 import java.util.Comparator ; 21 import java.util.Date ; 22 import java.util.Iterator ; 23 import java.util.List ; 24 import java.util.SortedSet ; 25 import java.util.TreeSet ; 26 import javax.swing.table.AbstractTableModel ; 27 import org.apache.log4j.Priority; 28 import org.apache.log4j.Logger; 29 30 36 class MyTableModel 37 extends AbstractTableModel 38 { 39 40 41 private static final Logger LOG = Logger.getLogger(MyTableModel.class); 42 43 44 private static final Comparator MY_COMP = new Comparator () 45 { 46 47 public int compare(Object aObj1, Object aObj2) { 48 if ((aObj1 == null) && (aObj2 == null)) { 49 return 0; } else if (aObj1 == null) { 51 return -1; } else if (aObj2 == null) { 53 return 1; } 55 56 final EventDetails le1 = (EventDetails) aObj1; 58 final EventDetails le2 = (EventDetails) aObj2; 59 60 if (le1.getTimeStamp() < le2.getTimeStamp()) { 61 return 1; 62 } 63 return -1; 65 } 66 }; 67 68 72 private class Processor 73 implements Runnable 74 { 75 76 public void run() { 77 while (true) { 78 try { 79 Thread.sleep(1000); 80 } catch (InterruptedException e) { 81 } 83 84 synchronized (mLock) { 85 if (mPaused) { 86 continue; 87 } 88 89 boolean toHead = true; boolean needUpdate = false; 91 final Iterator it = mPendingEvents.iterator(); 92 while (it.hasNext()) { 93 final EventDetails event = (EventDetails) it.next(); 94 mAllEvents.add(event); 95 toHead = toHead && (event == mAllEvents.first()); 96 needUpdate = needUpdate || matchFilter(event); 97 } 98 mPendingEvents.clear(); 99 100 if (needUpdate) { 101 updateFilteredEvents(toHead); 102 } 103 } 104 } 105 106 } 107 } 108 109 110 111 private static final String [] COL_NAMES = { 112 "Time", "Priority", "Trace", "Category", "NDC", "Message"}; 113 114 115 private static final EventDetails[] EMPTY_LIST = new EventDetails[] {}; 116 117 118 private static final DateFormat DATE_FORMATTER = 119 DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM); 120 121 122 private final Object mLock = new Object (); 123 124 private final SortedSet mAllEvents = new TreeSet (MY_COMP); 125 126 private EventDetails[] mFilteredEvents = EMPTY_LIST; 127 128 private final List mPendingEvents = new ArrayList (); 129 130 private boolean mPaused = false; 131 132 133 private String mThreadFilter = ""; 134 135 private String mMessageFilter = ""; 136 137 private String mNDCFilter = ""; 138 139 private String mCategoryFilter = ""; 140 141 private Priority mPriorityFilter = Priority.DEBUG; 142 143 144 148 MyTableModel() { 149 final Thread t = new Thread (new Processor()); 150 t.setDaemon(true); 151 t.start(); 152 } 153 154 155 159 160 public int getRowCount() { 161 synchronized (mLock) { 162 return mFilteredEvents.length; 163 } 164 } 165 166 167 public int getColumnCount() { 168 return COL_NAMES.length; 170 } 171 172 173 public String getColumnName(int aCol) { 174 return COL_NAMES[aCol]; 176 } 177 178 179 public Class getColumnClass(int aCol) { 180 return (aCol == 2) ? Boolean .class : Object .class; 182 } 183 184 185 public Object getValueAt(int aRow, int aCol) { 186 synchronized (mLock) { 187 final EventDetails event = mFilteredEvents[aRow]; 188 189 if (aCol == 0) { 190 return DATE_FORMATTER.format(new Date (event.getTimeStamp())); 191 } else if (aCol == 1) { 192 return event.getPriority(); 193 } else if (aCol == 2) { 194 return (event.getThrowableStrRep() == null) 195 ? Boolean.FALSE : Boolean.TRUE; 196 } else if (aCol == 3) { 197 return event.getCategoryName(); 198 } else if (aCol == 4) { 199 return event.getNDC(); 200 } 201 return event.getMessage(); 202 } 203 } 204 205 209 215 public void setPriorityFilter(Priority aPriority) { 216 synchronized (mLock) { 217 mPriorityFilter = aPriority; 218 updateFilteredEvents(false); 219 } 220 } 221 222 227 public void setThreadFilter(String aStr) { 228 synchronized (mLock) { 229 mThreadFilter = aStr.trim(); 230 updateFilteredEvents(false); 231 } 232 } 233 234 239 public void setMessageFilter(String aStr) { 240 synchronized (mLock) { 241 mMessageFilter = aStr.trim(); 242 updateFilteredEvents(false); 243 } 244 } 245 246 251 public void setNDCFilter(String aStr) { 252 synchronized (mLock) { 253 mNDCFilter = aStr.trim(); 254 updateFilteredEvents(false); 255 } 256 } 257 258 263 public void setCategoryFilter(String aStr) { 264 synchronized (mLock) { 265 mCategoryFilter = aStr.trim(); 266 updateFilteredEvents(false); 267 } 268 } 269 270 275 public void addEvent(EventDetails aEvent) { 276 synchronized (mLock) { 277 mPendingEvents.add(aEvent); 278 } 279 } 280 281 284 public void clear() { 285 synchronized (mLock) { 286 mAllEvents.clear(); 287 mFilteredEvents = new EventDetails[0]; 288 mPendingEvents.clear(); 289 fireTableDataChanged(); 290 } 291 } 292 293 294 public void toggle() { 295 synchronized (mLock) { 296 mPaused = !mPaused; 297 } 298 } 299 300 301 public boolean isPaused() { 302 synchronized (mLock) { 303 return mPaused; 304 } 305 } 306 307 313 public EventDetails getEventDetails(int aRow) { 314 synchronized (mLock) { 315 return mFilteredEvents[aRow]; 316 } 317 } 318 319 323 329 private void updateFilteredEvents(boolean aInsertedToFront) { 330 final long start = System.currentTimeMillis(); 331 final List filtered = new ArrayList (); 332 final int size = mAllEvents.size(); 333 final Iterator it = mAllEvents.iterator(); 334 335 while (it.hasNext()) { 336 final EventDetails event = (EventDetails) it.next(); 337 if (matchFilter(event)) { 338 filtered.add(event); 339 } 340 } 341 342 final EventDetails lastFirst = (mFilteredEvents.length == 0) 343 ? null 344 : mFilteredEvents[0]; 345 mFilteredEvents = (EventDetails[]) filtered.toArray(EMPTY_LIST); 346 347 if (aInsertedToFront && (lastFirst != null)) { 348 final int index = filtered.indexOf(lastFirst); 349 if (index < 1) { 350 LOG.warn("In strange state"); 351 fireTableDataChanged(); 352 } else { 353 fireTableRowsInserted(0, index - 1); 354 } 355 } else { 356 fireTableDataChanged(); 357 } 358 359 final long end = System.currentTimeMillis(); 360 LOG.debug("Total time [ms]: " + (end - start) 361 + " in update, size: " + size); 362 } 363 364 370 private boolean matchFilter(EventDetails aEvent) { 371 if (aEvent.getPriority().isGreaterOrEqual(mPriorityFilter) && 372 (aEvent.getThreadName().indexOf(mThreadFilter) >= 0) && 373 (aEvent.getCategoryName().indexOf(mCategoryFilter) >= 0) && 374 ((mNDCFilter.length() == 0) || 375 ((aEvent.getNDC() != null) && 376 (aEvent.getNDC().indexOf(mNDCFilter) >= 0)))) 377 { 378 final String rm = aEvent.getMessage(); 379 if (rm == null) { 380 return (mMessageFilter.length() == 0); 382 } else { 383 return (rm.indexOf(mMessageFilter) >= 0); 384 } 385 } 386 387 return false; } 389 } 390 | Popular Tags |