View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17
    18  /*
    19   */
    20  package org.apache.log4j.chainsaw;
    21
    22  import java.beans.PropertyChangeListener;
    23  import java.beans.PropertyChangeSupport;
    24  import java.io.Serializable;
    25  import java.util.ArrayList;
    26  import java.util.Collection;
    27  import java.util.Collections;
    28  import java.util.HashSet;
    29  import java.util.Iterator;
    30  import java.util.List;
    31  import java.util.Map;
    32  import java.util.Properties;
    33
    34  import javax.swing.table.TableColumn;
    35
    36  import org.apache.log4j.chainsaw.prefs.SettingsManager;
    37  import org.apache.log4j.helpers.Constants;
    38
    39
    40  /**
    41   *  Used to encapsulate all the preferences for a given LogPanel
    42   * @author Paul Smith
    43   */
    44  public class LogPanelPreferenceModel implements Serializable{
    45    public static final String ISO8601 = "ISO8601";
    46    public static final Collection DATE_FORMATS;
    47
    48   private static final long serialVersionUID = 7526472295622776147L;
    49    static {
    50      Collection list = new ArrayList();
    51
    52      Properties properties = SettingsManager.getInstance().getDefaultSettings();
    53
    54      for (Iterator iter = properties.entrySet().iterator(); iter.hasNext();) {
    55        Map.Entry entry = (Map.Entry) iter.next();
    56
    57        if (entry.getKey().toString().startsWith("DateFormat")) {
    58          list.add(entry.getValue());
    59        }
    60      }
    61
    62      DATE_FORMATS = Collections.unmodifiableCollection(list);
    63    }
    64
    65    private transient final PropertyChangeSupport propertySupport =
    66      new PropertyChangeSupport(this);
    67    private String dateFormatPattern = Constants.SIMPLE_TIME_PATTERN;
    68    private boolean levelIcons;
    69    private List allColumns = new ArrayList();
    70    private List visibleColumns = new ArrayList();
    71    private List visibleColumnOrder = new ArrayList();
    72    //set to true to match default 'detailPaneVisible' setting
    73    private boolean detailPaneVisible = true;
    74    private boolean toolTips;
    75    //default thumbnail bar tooltips to true
    76    private boolean thumbnailBarToolTips = true;
    77    private boolean scrollToBottom;
    78    private boolean logTreePanelVisible;
    79    private String loggerPrecision = "";
    80
    81    private Collection hiddenLoggers = new HashSet();
    82    private String timeZone;
    83    //default wrapMsg to true
    84    private boolean wrapMsg = true;
    85    private boolean highlightSearchMatchText;
    86    private String hiddenExpression;
    87    private String alwaysDisplayExpression;
    88    private String clearTableExpression;
    89    //default to cyclic mode off
    90    private boolean cyclic = false;
    91    private boolean showMillisDeltaAsGap;
    92    //default search results to visible
    93    private boolean searchResultsVisible = true;
    94
    95      /**
    96     * Returns an <b>unmodifiable</b> list of the columns.
    97     *
    98     * The reason it is unmodifiable is to enforce the requirement that
    99     * the List is actually unique columns.  IT _could_ be a set,
    100    * but we need to maintain the order of insertion.
    101    *
    102    * @return
    103    */
    104   public List getColumns() {
    105       return Collections.unmodifiableList(allColumns);
    106   }
    107
    108   public void setCyclic(boolean cyclic) {
    109     this.cyclic = cyclic;
    110   }
    111
    112   public boolean isCyclic() {
    113       return cyclic;
    114   }
    115
    116   /**
    117    * Returns an <b>unmodifiable</b> list of the visible columns.
    118    *
    119    * The reason it is unmodifiable is to enforce the requirement that
    120    * the List is actually unique columns.  IT _could_ be a set,
    121    * but we need to maintain the order of insertion.
    122    *
    123    * @return
    124    */
    125   public List getVisibleColumns() {
    126       return Collections.unmodifiableList(visibleColumns);
    127   }
    128
    129   public void clearColumns(){
    130       Object oldValue = this.allColumns;
    131       allColumns = new ArrayList();
    132       propertySupport.firePropertyChange("columns", oldValue, allColumns);
    133   }
    134
    135   private TableColumn findColumnByHeader(List list, String header) {
    136 	  for (Iterator iter = list.iterator();iter.hasNext();) {
    137 		  TableColumn c = (TableColumn)iter.next();
    138           //columns may have changed - header may not exist
    139 		  if (c != null && c.getHeaderValue() != null && c.getHeaderValue().equals(header)) {
    140 			  return c;
    141 		  }
    142 	  }
    143 	  return null;
    144   }
    145
    146   public void setVisibleColumnOrder(List visibleColumnOrder) {
    147 	  this.visibleColumnOrder = visibleColumnOrder;
    148   }
    149
    150   public List getVisibleColumnOrder() {
    151 	  return visibleColumnOrder;
    152   }
    153
    154   public boolean addColumn(TableColumn column){
    155 	  if (findColumnByHeader(allColumns, column.getHeaderValue().toString()) != null) {
    156 		  return false;
    157 	  }
    158
    159       Object oldValue = allColumns;
    160       allColumns = new ArrayList(allColumns);
    161       allColumns.add(column);
    162
    163       propertySupport.firePropertyChange("columns", oldValue, allColumns);
    164       return true;
    165   }
    166
    167   private void setColumns(List columns) {
    168       Object oldValue = allColumns;
    169       allColumns = new ArrayList(columns);
    170       propertySupport.firePropertyChange("columns", oldValue, columns);
    171   }
    172
    173 /**
    174    * Returns the Date Pattern string for the alternate date formatter.
    175    * @return date pattern
    176    */
    177   public final String getDateFormatPattern() {
    178     return dateFormatPattern;
    179   }
    180
    181   public final void setDefaultDatePatternFormat() {
    182 	    String oldVal = this.dateFormatPattern;
    183 	    this.dateFormatPattern = Constants.SIMPLE_TIME_PATTERN;
    184 	    propertySupport.firePropertyChange(
    185 	    	      "dateFormatPattern", oldVal, this.dateFormatPattern);
    186   }
    187   /**
    188    * @param dateFormatPattern
    189    */
    190   public final void setDateFormatPattern(String dateFormatPattern) {
    191     String oldVal = this.dateFormatPattern;
    192     this.dateFormatPattern = dateFormatPattern;
    193     propertySupport.firePropertyChange(
    194       "dateFormatPattern", oldVal, this.dateFormatPattern);
    195   }
    196
    197   /**
    198    * @param listener
    199    */
    200   public synchronized void addPropertyChangeListener(
    201     PropertyChangeListener listener) {
    202     propertySupport.addPropertyChangeListener(listener);
    203   }
    204
    205   /**
    206    * @param propertyName
    207    * @param listener
    208    */
    209   public synchronized void addPropertyChangeListener(
    210     String propertyName, PropertyChangeListener listener) {
    211     propertySupport.addPropertyChangeListener(propertyName, listener);
    212   }
    213
    214   /**
    215    * @param listener
    216    */
    217   public synchronized void removePropertyChangeListener(
    218     PropertyChangeListener listener) {
    219     propertySupport.removePropertyChangeListener(listener);
    220   }
    221
    222   /**
    223    * @param propertyName
    224    * @param listener
    225    */
    226   public synchronized void removePropertyChangeListener(
    227     String propertyName, PropertyChangeListener listener) {
    228     propertySupport.removePropertyChangeListener(propertyName, listener);
    229   }
    230
    231   /**
    232    * Applies all the properties of another model to this model
    233    *
    234    * @param model the model to copy
    235    * all the properties from
    236    */
    237   public void apply(LogPanelPreferenceModel model) {
    238     setCyclic(model.isCyclic());
    239     setLoggerPrecision(model.getLoggerPrecision());
    240     setDateFormatPattern(model.getDateFormatPattern());
    241     setLevelIcons(model.isLevelIcons());
    242     setWrapMessage(model.isWrapMessage());
    243     setHighlightSearchMatchText(model.isHighlightSearchMatchText());
    244     setTimeZone(model.getTimeZone());
    245     setToolTips(model.isToolTips());
    246     setThumbnailBarToolTips((model.isThumbnailBarToolTips()));
    247     setScrollToBottom(model.isScrollToBottom());
    248     setDetailPaneVisible(model.isDetailPaneVisible());
    249     setLogTreePanelVisible(model.isLogTreePanelVisible());
    250     setVisibleColumnOrder(model.getVisibleColumnOrder());
    251     setSearchResultsVisible(model.isSearchResultsVisible());
    252     // we have to copy the list, because getColumns() is unmodifiable
    253     setColumns(model.getColumns());
    254
    255     setVisibleColumns(model.getVisibleColumns());
    256     setHiddenLoggers(model.getHiddenLoggers());
    257     setHiddenExpression(model.getHiddenExpression());
    258     setAlwaysDisplayExpression(model.getAlwaysDisplayExpression());
    259     setShowMillisDeltaAsGap(model.isShowMillisDeltaAsGap());
    260     setClearTableExpression(model.getClearTableExpression());
    261   }
    262
    263   /**
    264    * Returns true if this the fast ISO8601DateFormat object
    265    * should be used instead of SimpleDateFormat
    266    * @return use ISO8601 format flag
    267    */
    268   public boolean isUseISO8601Format() {
    269     return getDateFormatPattern().equals(ISO8601);
    270   }
    271
    272   /**
    273    * @return level icons flag
    274    */
    275   public boolean isLevelIcons() {
    276     return levelIcons;
    277   }
    278
    279   public boolean isWrapMessage() {
    280     return wrapMsg;
    281   }
    282
    283   public boolean isHighlightSearchMatchText() {
    284     return highlightSearchMatchText;
    285   }
    286
    287   /**
    288    * @param levelIcons
    289    */
    290   public void setLevelIcons(boolean levelIcons) {
    291     this.levelIcons = levelIcons;
    292     propertySupport.firePropertyChange("levelIcons", !levelIcons, levelIcons);
    293   }
    294
    295   public void setSearchResultsVisible(boolean searchResultsVisible) {
    296     boolean oldValue = this.searchResultsVisible;
    297     this.searchResultsVisible = searchResultsVisible;
    298     propertySupport.firePropertyChange("searchResultsVisible", oldValue, searchResultsVisible);
    299   }
    300
    301   public boolean isSearchResultsVisible() {
    302     return searchResultsVisible;
    303   }
    304
    305   /**
    306    * @param wrapMsg
    307    */
    308   public void setWrapMessage(boolean wrapMsg) {
    309     this.wrapMsg = wrapMsg;
    310     propertySupport.firePropertyChange("wrapMessage", !wrapMsg, wrapMsg);
    311   }
    312
    313     /**
    314      * @param highlightSearchMatchText
    315      */
    316     public void setHighlightSearchMatchText(boolean highlightSearchMatchText) {
    317       this.highlightSearchMatchText = highlightSearchMatchText;
    318       propertySupport.firePropertyChange("highlightSearchMatchText", !highlightSearchMatchText, highlightSearchMatchText);
    319     }
    320
    321   /**
    322    * @param loggerPrecision - an integer representing the number of packages to display,
    323    * or an empty string representing 'display all packages'
    324    */
    325   public void setLoggerPrecision(String loggerPrecision) {
    326     String oldVal = this.loggerPrecision;
    327     this.loggerPrecision = loggerPrecision;
    328     propertySupport.firePropertyChange("loggerPrecision", oldVal, this.loggerPrecision);
    329   }
    330
    331   /**
    332    * Returns the Logger precision.
    333    * @return logger precision
    334    */
    335   public final String getLoggerPrecision() {
    336     return loggerPrecision;
    337   }
    338
    339   /**
    340    * Returns true if the named column should be made visible otherwise
    341    * false.
    342    * @param column
    343    * @return column visible flag
    344    */
    345   public boolean isColumnVisible(TableColumn column) {
    346 	  return (findColumnByHeader(visibleColumns, column.getHeaderValue().toString()) != null);
    347   }
    348
    349   private void setVisibleColumns(List visibleColumns) {
    350       Object oldValue = new ArrayList();
    351       this.visibleColumns = new ArrayList(visibleColumns);
    352
    353       propertySupport.firePropertyChange("visibleColumns", oldValue, this.visibleColumns);
    354   }
    355
    356   public void setColumnVisible(String columnName, boolean isVisible) {
    357     boolean wasVisible = findColumnByHeader(visibleColumns, columnName) != null;
    358
    359       //because we're a list and not a set, ensure we keep at most
    360     //one entry for a tablecolumn
    361     Object col = findColumnByHeader(allColumns, columnName);
    362     if (isVisible && !wasVisible) {
    363 		visibleColumns.add(col);
    364 		visibleColumnOrder.add(col);
    365 	    propertySupport.firePropertyChange("visibleColumns", new Boolean(isVisible), new Boolean(wasVisible));
    366 	}
    367     if (!isVisible && wasVisible) {
    368 		visibleColumns.remove(col);
    369 		visibleColumnOrder.remove(col);
    370 	    propertySupport.firePropertyChange("visibleColumns", new Boolean(isVisible), new Boolean(wasVisible));
    371 	}
    372   }
    373
    374   /**
    375    * Toggles the state between visible, non-visible for a particular Column name
    376    * @param column
    377    */
    378   public void toggleColumn(TableColumn column) {
    379     setColumnVisible(column.getHeaderValue().toString(), !isColumnVisible(column));
    380   }
    381
    382   /**
    383    * @return detail pane visible flag
    384    */
    385   public final boolean isDetailPaneVisible() {
    386     return detailPaneVisible;
    387   }
    388
    389   /**
    390    * @param detailPaneVisible
    391    */
    392   public final void setDetailPaneVisible(boolean detailPaneVisible) {
    393     boolean oldValue = this.detailPaneVisible;
    394     this.detailPaneVisible = detailPaneVisible;
    395     propertySupport.firePropertyChange(
    396       "detailPaneVisible", oldValue, this.detailPaneVisible);
    397   }
    398
    399   /**
    400    * @return scroll to bottom flag
    401    */
    402   public final boolean isScrollToBottom() {
    403     return scrollToBottom;
    404   }
    405
    406
    407   public final boolean isShowMillisDeltaAsGap() {
    408       return showMillisDeltaAsGap;
    409   }
    410   /**
    411    * @param scrollToBottom
    412    */
    413   public final void setScrollToBottom(boolean scrollToBottom) {
    414     boolean oldValue = this.scrollToBottom;
    415     this.scrollToBottom = scrollToBottom;
    416     propertySupport.firePropertyChange(
    417       "scrollToBottom", oldValue, this.scrollToBottom);
    418   }
    419
    420     /**
    421      * @param showMillisDeltaAsGap
    422      */
    423     public final void setShowMillisDeltaAsGap(boolean showMillisDeltaAsGap) {
    424       boolean oldValue = this.showMillisDeltaAsGap;
    425       this.showMillisDeltaAsGap = showMillisDeltaAsGap;
    426       propertySupport.firePropertyChange(
    427         "showMillisDeltaAsGap", oldValue, this.showMillisDeltaAsGap);
    428     }
    429
    430   public final void setThumbnailBarToolTips(boolean thumbnailBarToolTips) {
    431       boolean oldValue = this.thumbnailBarToolTips;
    432       this.thumbnailBarToolTips = thumbnailBarToolTips;
    433       propertySupport.firePropertyChange("thumbnailBarToolTips", oldValue, this.thumbnailBarToolTips);
    434   }
    435
    436   public final boolean isThumbnailBarToolTips() {
    437       return thumbnailBarToolTips;
    438   }
    439
    440   /**
    441    * @return tool tips enabled flag
    442    */
    443   public final boolean isToolTips() {
    444     return toolTips;
    445   }
    446
    447   /**
    448    * @param toolTips
    449    */
    450   public final void setToolTips(boolean toolTips) {
    451     boolean oldValue = this.toolTips;
    452     this.toolTips = toolTips;
    453     propertySupport.firePropertyChange("toolTips", oldValue, this.toolTips);
    454   }
    455
    456   /**
    457    * @return log tree panel visible flag
    458    */
    459   public final boolean isLogTreePanelVisible() {
    460     return logTreePanelVisible;
    461   }
    462
    463   /**
    464    * @param logTreePanelVisible
    465    */
    466   public final void setLogTreePanelVisible(boolean logTreePanelVisible) {
    467     boolean oldValue = this.logTreePanelVisible;
    468     this.logTreePanelVisible = logTreePanelVisible;
    469     propertySupport.firePropertyChange(
    470       "logTreePanelVisible", oldValue, this.logTreePanelVisible);
    471   }
    472
    473   /**
    474    * @return custom date format flag
    475    */
    476   public boolean isCustomDateFormat()
    477   {
    478     return !DATE_FORMATS.contains(getDateFormatPattern()) && !isUseISO8601Format();
    479   }
    480
    481   public void setHiddenLoggers(Collection hiddenSet) {
    482       Object oldValue = this.hiddenLoggers;
    483       this.hiddenLoggers = hiddenSet;
    484       propertySupport.firePropertyChange("hiddenLoggers", oldValue, this.hiddenLoggers);
    485   }
    486
    487   public Collection getHiddenLoggers() {
    488     return hiddenLoggers;
    489   }
    490
    491   public String getTimeZone() {
    492     return timeZone;
    493   }
    494
    495   public void setTimeZone(String timeZone) {
    496       Object oldValue = this.timeZone;
    497       this.timeZone = timeZone;
    498       propertySupport.firePropertyChange("dateFormatTimeZone", oldValue, this.timeZone);
    499   }
    500
    501   public void setHiddenExpression(String hiddenExpression) {
    502     Object oldValue = this.hiddenExpression;
    503     this.hiddenExpression = hiddenExpression;
    504     propertySupport.firePropertyChange("hiddenExpression", oldValue, this.hiddenExpression);
    505   }
    506
    507   public String getHiddenExpression() {
    508     return hiddenExpression;
    509   }
    510
    511   public void setAlwaysDisplayExpression(String alwaysDisplayExpression) {
    512     Object oldValue = this.hiddenExpression;
    513     this.alwaysDisplayExpression = alwaysDisplayExpression;
    514     propertySupport.firePropertyChange("alwaysDisplayExpression", oldValue, this.alwaysDisplayExpression);
    515   }
    516
    517   public String getAlwaysDisplayExpression() {
    518     return alwaysDisplayExpression;
    519   }
    520
    521   public void setClearTableExpression(String clearTableExpression) {
    522     Object oldValue = this.clearTableExpression;
    523     this.clearTableExpression = clearTableExpression;
    524     //no propertychange if both null
    525     if (oldValue == null && this.clearTableExpression == null) {
    526         return;
    527     }
    528     propertySupport.firePropertyChange("clearTableExpression", oldValue, this.clearTableExpression);
    529   }
    530
    531   public String getClearTableExpression() {
    532     return clearTableExpression;
    533   }
    534 }