sdeboy 2003/06/07 21:58:00 Modified: src/java/org/apache/log4j/chainsaw FilterChangeExecutor.java LogUI.java ChainsawCyclicBufferTableModel.java AbstractChainsawTableModel.java Removed: src/java/org/apache/log4j/chainsaw DefaultSortTableModel.java Log: - Only one tablemodel now exists - ChainsawCyclicBufferTableModel. Completed implementation by adding support for detail display, find, and event re-selection after sort. - CyclicBufferTableModel now handles both cases where a buffer is required and where one is not required (either a CyclicBufferList or an ArrayList are the backing collection). - Added a system property to allow for a configurable buffer size. Revision Changes Path 1.5 +2 -2 jakarta-log4j-sandbox/src/java/org/apache/log4j/chainsaw/FilterChangeExecutor.java Index: FilterChangeExecutor.java =================================================================== RCS file: /home/cvs/jakarta-log4j-sandbox/src/java/org/apache/log4j/chainsaw/FilterChangeExecutor.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- FilterChangeExecutor.java 28 May 2003 07:34:57 -0000 1.4 +++ FilterChangeExecutor.java 8 Jun 2003 04:58:00 -0000 1.5 @@ -59,7 +59,8 @@ private final Object syncLock; /** - * @param DefaultSortTableModel + * @param EventContainer + * @param synchronization lock */ FilterChangeExecutor(EventContainer model, final Object syncLock) { this.model = model; @@ -78,7 +79,6 @@ v2 = (Vector) iter.next(); if (model.getDisplayFilter() != null) { - if (this.model.getDisplayFilter().isDisplayed(v2)) { model.addFilteredRow(v2); } 1.87 +21 -10 jakarta-log4j-sandbox/src/java/org/apache/log4j/chainsaw/LogUI.java Index: LogUI.java =================================================================== RCS file: /home/cvs/jakarta-log4j-sandbox/src/java/org/apache/log4j/chainsaw/LogUI.java,v retrieving revision 1.86 retrieving revision 1.87 diff -u -r1.86 -r1.87 --- LogUI.java 4 Jun 2003 05:02:34 -0000 1.86 +++ LogUI.java 8 Jun 2003 04:58:00 -0000 1.87 @@ -151,12 +151,27 @@ * that is used to display a Welcome panel, and any other panels that * are generated because Logging Events are streamed via a Receiver, or other * mechanism. + * + * If a system property 'chainsaw.usecyclicbuffer' is set to 'true', each panel will use a cyclic + * buffer for displaying events and once events reach the buffer limit, the oldest events + * are removed from the table. + * + * If the property is not provided, there is no limit on the table's buffer size. + * + * If 'chainsaw.usecyclicbuffer' is set to 'true' and a system + * property 'chainsaw.cyclicbuffersize' is set to some integer value, that value will + * be used as the buffer size - if the buffersize is not provided, a default + * size of 500 is used. + * * * @author Scott Deboy <[EMAIL PROTECTED]> * @author Paul Smith <[EMAIL PROTECTED]> * */ public class LogUI extends JFrame implements ChainsawViewer, SettingsListener { + + private static final String USE_CYCLIC_BUFFER_PROP_NAME = "chainsaw.usecyclicbuffer"; + private static final String CYCLIC_BUFFER_SIZE_PROP_NAME = "chainsaw.cyclicbuffersize"; private static final String MAIN_WINDOW_HEIGHT = "main.window.height"; private static final String MAIN_WINDOW_WIDTH = "main.window.width"; private static final String MAIN_WINDOW_Y = "main.window.y"; @@ -781,16 +796,12 @@ final String eventType = ((ChainsawEventBatch.Entry) eventBatchEntrys.get(0)).getEventType(); - if ( - Boolean.valueOf(System.getProperty("chainsaw.usecyclicbuffer")) - .booleanValue()) { - tableModel = new ChainsawCyclicBufferTableModel(); - } else { - tableModel = - new DefaultSortTableModel( - new Vector(), new Vector(ChainsawColumns.getColumnsNames()), - eventType); - } + int bufferSize = 500; + //if buffer size not provided, set default buffer size to 500 (only used if usecyclicbuffer true) + if (System.getProperty(CYCLIC_BUFFER_SIZE_PROP_NAME) != null) { + bufferSize = Integer.valueOf(System.getProperty(CYCLIC_BUFFER_SIZE_PROP_NAME)).intValue(); + } + tableModel = new ChainsawCyclicBufferTableModel(Boolean.valueOf(System.getProperty(USE_CYCLIC_BUFFER_PROP_NAME)).booleanValue(), bufferSize); map = new HashMap(); table = new JSortTable(tableModel); 1.8 +108 -17 jakarta-log4j-sandbox/src/java/org/apache/log4j/chainsaw/ChainsawCyclicBufferTableModel.java Index: ChainsawCyclicBufferTableModel.java =================================================================== RCS file: /home/cvs/jakarta-log4j-sandbox/src/java/org/apache/log4j/chainsaw/ChainsawCyclicBufferTableModel.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- ChainsawCyclicBufferTableModel.java 7 Jun 2003 04:30:27 -0000 1.7 +++ ChainsawCyclicBufferTableModel.java 8 Jun 2003 04:58:00 -0000 1.8 @@ -51,11 +51,15 @@ import org.apache.log4j.helpers.LogLog; +import java.util.ArrayList; import java.util.Collection; +import java.util.Iterator; import java.util.List; +import java.util.ListIterator; import java.util.StringTokenizer; import java.util.Vector; + /** * A CyclicBuffer implementation of the EventContainer. * @@ -65,9 +69,22 @@ */ class ChainsawCyclicBufferTableModel extends AbstractChainsawTableModel implements EventContainer { - public static final int DEFAULT_BUFFER_SIZE = 500; - List cyclicBufferList = new CyclicBufferList(DEFAULT_BUFFER_SIZE); - List filteredList = new CyclicBufferList(DEFAULT_BUFFER_SIZE); + final List unfilteredList; + final List filteredList; + + //because we may be using a cyclic buffer, if an ID is not provided in the property, + //use and increment this row counter as the ID for each received row + int uniqueRow; + + public ChainsawCyclicBufferTableModel(boolean isCyclic, int bufferSize) { + if (isCyclic) { + unfilteredList = new CyclicBufferList(bufferSize); + filteredList = new CyclicBufferList(bufferSize); + } else { + unfilteredList = new ArrayList(); + filteredList = new ArrayList(); + } + } /* (non-Javadoc) * @see org.apache.log4j.chainsaw.EventContainer#addFilteredRow(java.util.Vector) @@ -80,7 +97,7 @@ public void addRow(Vector row) { synchronized (syncLock) { - cyclicBufferList.add(row); + unfilteredList.add(row); } } @@ -97,29 +114,65 @@ */ public void clearModel() { synchronized (syncLock) { - cyclicBufferList.clear(); + unfilteredList.clear(); filteredList.clear(); } } public int find(int startRow, String text) { - throw new UnsupportedOperationException("Not implemented at this time"); + if (text == null) { + text = ""; + } else { + text = text.toLowerCase(); + } + + int currentRow = -1; + String thisVal = null; + + synchronized (syncLock) { + Iterator iter = filteredList.iterator(); + + while (iter.hasNext()) { + currentRow++; + + Vector v2 = (Vector) iter.next(); + + if (currentRow < startRow) { + continue; + } + + Iterator iter2 = v2.iterator(); + + while (iter2.hasNext()) { + thisVal = iter2.next().toString(); + + boolean result = + ((thisVal != null) && (thisVal.toLowerCase().indexOf(text) > -1)); + + if (result) { + return currentRow; + } + } + } + } + + return -1; } public Vector getAllEvents() { synchronized (syncLock) { - Vector v = new Vector(cyclicBufferList); + Vector v = new Vector(unfilteredList); return v; } } public int getRowIndex(Vector v) { - synchronized(syncLock) { - return cyclicBufferList.indexOf(v); - } + synchronized (syncLock) { + return filteredList.indexOf(v); + } } - + public int getColumnCount() { return ChainsawColumns.getColumnsNames().size(); } @@ -131,9 +184,47 @@ /* (non-Javadoc) * @see org.apache.log4j.chainsaw.EventContainer#getDetailText(int) */ - public String getDetailText(int selectedRow) { - // TODO Auto-generated method stub - return null; + public String getDetailText(int row) { + boolean pastFirst = false; + StringBuffer detail = new StringBuffer(128); + detail.append("<html><body><table cellspacing=0 cellpadding=0>"); + + List columnNames = ChainsawColumns.getColumnsNames(); + + Vector v; + + synchronized (syncLock) { + v = (Vector) filteredList.get(row); + } + + if (v == null) { + return ""; + } + + ListIterator iter = getDisplayFilter().getDetailColumns().listIterator(); + String column = null; + int index = -1; + + while (iter.hasNext()) { + column = (String) iter.next(); + index = columnNames.indexOf(column); + + if (index > -1) { + if (pastFirst) { + detail.append("</td></tr>"); + } + + detail.append("<tr><td valign=\"top\"><b>"); + detail.append(column); + detail.append(": </b></td><td>"); + detail.append(escape(v.get(index).toString())); + pastFirst = true; + } + } + + detail.append("</table></body></html>"); + + return detail.toString(); } public Vector getRow(int row) { @@ -151,11 +242,11 @@ } public Collection getUnfilteredEvents() { - return cyclicBufferList; + return unfilteredList; } public int getUnfilteredRowCount() { - return cyclicBufferList.size(); + return unfilteredList.size(); } public Object getValueAt(int rowIndex, int columnIndex) { @@ -206,7 +297,7 @@ } if (thisInt == null) { - thisInt = new Integer(cyclicBufferList.size() + 1); + thisInt = new Integer(++uniqueRow); } row.add(thisInt); 1.5 +51 -13 jakarta-log4j-sandbox/src/java/org/apache/log4j/chainsaw/AbstractChainsawTableModel.java Index: AbstractChainsawTableModel.java =================================================================== RCS file: /home/cvs/jakarta-log4j-sandbox/src/java/org/apache/log4j/chainsaw/AbstractChainsawTableModel.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- AbstractChainsawTableModel.java 27 May 2003 05:49:46 -0000 1.4 +++ AbstractChainsawTableModel.java 8 Jun 2003 04:58:00 -0000 1.5 @@ -50,9 +50,7 @@ package org.apache.log4j.chainsaw; import java.util.Collections; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Vector; import javax.swing.SwingUtilities; @@ -68,8 +66,6 @@ */ abstract class AbstractChainsawTableModel extends AbstractTableModel implements EventContainer { - /** The <code>Vector</code> of column identifiers. */ - protected Vector columnIdentifiers; private Vector countListeners = new Vector(); private boolean currentSortAscending; private int currentSortColumn; @@ -77,7 +73,6 @@ private final FilterChangeExecutor filterExecutor; private boolean sortEnabled; protected final Object syncLock = new Object(); - private Map unfilteredEvents = new HashMap(); protected AbstractChainsawTableModel() { filterExecutor = new FilterChangeExecutor(this, syncLock); @@ -88,11 +83,6 @@ } public void filterChanged() { - // TODO do we need reset the tableModel with displayed columns if they are part of the filter? - // if (!displayFilter.getDisplayedColumns().equals(columnIdentifiers)) { - // setColumnIdentifiers(displayFilter.getDisplayedColumns()); - // } - // Vector detailColumns = displayFilter.getDetailColumns(); SwingUtilities.invokeLater(filterExecutor); } @@ -123,10 +113,10 @@ ((EventCountListener) countListeners.get(i)).eventCountChanged( getRowCount(), getUnfilteredRowCount()); } + TableModelEvent event = new TableModelEvent(this); fireTableChanged(event); - } public void setCurrentSortColumn(int col, boolean ascending) { @@ -157,11 +147,59 @@ public void sortColumn( JSortTable table, int col, int row, boolean ascending) { - - System.out.println("request to sort col=" + col + ", which is " + ChainsawColumns.getColumnsNames().get(col)); + System.out.println( + "request to sort col=" + col + ", which is " + + ChainsawColumns.getColumnsNames().get(col)); SwingUtilities.invokeLater( new SortExecutor(this, this, table, col, row, ascending)); fireTableDataChanged(); + } + + /** + * Escape <, > & and " as their entities. It is very + * dumb about & handling. + * @param aStr the String to escape. + * @return the escaped String + */ + String escape(String string) { + if (string == null) { + return null; + } + + final StringBuffer buf = new StringBuffer(); + + for (int i = 0; i < string.length(); i++) { + char c = string.charAt(i); + + switch (c) { + case '<': + buf.append("<"); + + break; + + case '>': + buf.append(">"); + + break; + + case '\"': + buf.append("""); + + break; + + case '&': + buf.append("&"); + + break; + + default: + buf.append(c); + + break; + } + } + + return buf.toString(); } }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]