FileDocCategorySizeDatePackage
MyTableModel.javaAPI DocApache log4j 1.2.1512471Sat Aug 25 00:09:40 BST 2007org.apache.log4j.chainsaw

MyTableModel

public class MyTableModel extends AbstractTableModel
Represents a list of EventDetails objects that are sorted on logging time. Methods are provided to filter the events that are visible.
author
Oliver Burn

Fields Summary
private static final Logger
LOG
used to log messages
private static final Comparator
MY_COMP
use the compare logging events
private static final String[]
COL_NAMES
names of the columns in the table
private static final EventDetails[]
EMPTY_LIST
definition of an empty list
private static final DateFormat
DATE_FORMATTER
used to format dates
private final Object
mLock
the lock to control access
private final SortedSet
mAllEvents
set of all logged events - not filtered
private EventDetails[]
mFilteredEvents
events that are visible after filtering
private final List
mPendingEvents
list of events that are buffered for processing
private boolean
mPaused
indicates whether event collection is paused to the UI
private String
mThreadFilter
filter for the thread
private String
mMessageFilter
filter for the message
private String
mNDCFilter
filter for the NDC
private String
mCategoryFilter
filter for the category
private Priority
mPriorityFilter
filter for the priority
Constructors Summary
MyTableModel()
Creates a new MyTableModel instance.



              
     
        final Thread t = new Thread(new Processor());
        t.setDaemon(true);
        t.start();
    
Methods Summary
public voidaddEvent(org.apache.log4j.chainsaw.EventDetails aEvent)
Add an event to the list.

param
aEvent a EventDetails value

        synchronized (mLock) {
            mPendingEvents.add(aEvent);
        }
    
public voidclear()
Clear the list of all events.

        synchronized (mLock) {
            mAllEvents.clear();
            mFilteredEvents = new EventDetails[0];
            mPendingEvents.clear();
            fireTableDataChanged();
        }
    
public java.lang.ClassgetColumnClass(int aCol)

see
javax.swing.table.TableModel

        // does not need to be synchronized
        return (aCol == 2) ? Boolean.class : Object.class;
    
public intgetColumnCount()

see
javax.swing.table.TableModel

        // does not need to be synchronized
        return COL_NAMES.length;
    
public java.lang.StringgetColumnName(int aCol)

see
javax.swing.table.TableModel

        // does not need to be synchronized
        return COL_NAMES[aCol];
    
public org.apache.log4j.chainsaw.EventDetailsgetEventDetails(int aRow)
Get the throwable information at a specified row in the filtered events.

param
aRow the row index of the event
return
the throwable information

        synchronized (mLock) {
            return mFilteredEvents[aRow];
        }
    
public intgetRowCount()

see
javax.swing.table.TableModel

        synchronized (mLock) {
            return mFilteredEvents.length;
        }
    
public java.lang.ObjectgetValueAt(int aRow, int aCol)

see
javax.swing.table.TableModel

        synchronized (mLock) {
            final EventDetails event = mFilteredEvents[aRow];

            if (aCol == 0) {
                return DATE_FORMATTER.format(new Date(event.getTimeStamp()));
            } else if (aCol == 1) {
                return event.getPriority();
            } else if (aCol == 2) {
                return (event.getThrowableStrRep() == null)
                    ? Boolean.FALSE : Boolean.TRUE;
            } else if (aCol == 3) {
                return event.getCategoryName();
            } else if (aCol == 4) {
                return event.getNDC();
            }
            return event.getMessage();
        }
    
public booleanisPaused()

return
whether currently paused collecting events

        synchronized (mLock) {
            return mPaused;
        }
    
private booleanmatchFilter(org.apache.log4j.chainsaw.EventDetails aEvent)
Returns whether an event matches the filters.

param
aEvent the event to check for a match
return
whether the event matches

        if (aEvent.getPriority().isGreaterOrEqual(mPriorityFilter) &&
            (aEvent.getThreadName().indexOf(mThreadFilter) >= 0) &&
            (aEvent.getCategoryName().indexOf(mCategoryFilter) >= 0) &&
            ((mNDCFilter.length() == 0) ||
             ((aEvent.getNDC() != null) &&
              (aEvent.getNDC().indexOf(mNDCFilter) >= 0))))
        {
            final String rm = aEvent.getMessage();
            if (rm == null) {
                // only match if we have not filtering in place
                return (mMessageFilter.length() == 0);
            } else {
                return (rm.indexOf(mMessageFilter) >= 0);
            }
        }

        return false; // by default not match
    
public voidsetCategoryFilter(java.lang.String aStr)
Set the filter for the category field.

param
aStr the string to match

        synchronized (mLock) {
            mCategoryFilter = aStr.trim();
            updateFilteredEvents(false);
        }
    
public voidsetMessageFilter(java.lang.String aStr)
Set the filter for the message field.

param
aStr the string to match

        synchronized (mLock) {
            mMessageFilter = aStr.trim();
            updateFilteredEvents(false);
        }
    
public voidsetNDCFilter(java.lang.String aStr)
Set the filter for the NDC field.

param
aStr the string to match

        synchronized (mLock) {
            mNDCFilter = aStr.trim();
            updateFilteredEvents(false);
        }
    
public voidsetPriorityFilter(org.apache.log4j.Priority aPriority)
Sets the priority to filter events on. Only events of equal or higher property are now displayed.

param
aPriority the priority to filter on

        synchronized (mLock) {
            mPriorityFilter = aPriority;
            updateFilteredEvents(false);
        }
    
public voidsetThreadFilter(java.lang.String aStr)
Set the filter for the thread field.

param
aStr the string to match

        synchronized (mLock) {
            mThreadFilter = aStr.trim();
            updateFilteredEvents(false);
        }
    
public voidtoggle()
Toggle whether collecting events

        synchronized (mLock) {
            mPaused = !mPaused;
        }
    
private voidupdateFilteredEvents(boolean aInsertedToFront)
Update the filtered events data structure.

param
aInsertedToFront indicates whether events were added to front of the events. If true, then the current first event must still exist in the list after the filter is applied.

        final long start = System.currentTimeMillis();
        final List filtered = new ArrayList();
        final int size = mAllEvents.size();
        final Iterator it = mAllEvents.iterator();

        while (it.hasNext()) {
            final EventDetails event = (EventDetails) it.next();
            if (matchFilter(event)) {
                filtered.add(event);
            }
        }

        final EventDetails lastFirst = (mFilteredEvents.length == 0)
            ? null
            : mFilteredEvents[0];
        mFilteredEvents = (EventDetails[]) filtered.toArray(EMPTY_LIST);

        if (aInsertedToFront && (lastFirst != null)) {
            final int index = filtered.indexOf(lastFirst);
            if (index < 1) {
                LOG.warn("In strange state");
                fireTableDataChanged();
            } else {
                fireTableRowsInserted(0, index - 1);
            }
        } else {
            fireTableDataChanged();
        }

        final long end = System.currentTimeMillis();
        LOG.debug("Total time [ms]: " + (end - start)
                  + " in update, size: " + size);