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 &lt;, &gt; &amp; and &quot; as their entities. It is very
  +   * dumb about &amp; 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("&lt;");
  +
  +        break;
  +
  +      case '>':
  +        buf.append("&gt;");
  +
  +        break;
  +
  +      case '\"':
  +        buf.append("&quot;");
  +
  +        break;
  +
  +      case '&':
  +        buf.append("&amp;");
  +
  +        break;
  +
  +      default:
  +        buf.append(c);
  +
  +        break;
  +      }
  +    }
  +
  +    return buf.toString();
     }
   }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to