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]