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 org.apache.log4j.chainsaw.prefs.SettingsManager;
    23  import org.apache.log4j.helpers.Constants;
    24
    25  import javax.swing.table.TableColumn;
    26  import java.beans.PropertyChangeListener;
    27  import java.beans.PropertyChangeSupport;
    28  import java.io.Serializable;
    29  import java.util.*;
    30
    31
    32  /**
    33   * Used to encapsulate all the preferences for a given LogPanel
    34   *
    35   * @author Paul Smith
    36   */
    37  public class LogPanelPreferenceModel implements Serializable {
    38      public static final String ISO8601 = "ISO8601";
    39      public static final Collection DATE_FORMATS;
    40
    41      private static final long serialVersionUID = 7526472295622776147L;
    42
    43      static {
    44          Collection list = new ArrayList();
    45
    46          Properties properties = SettingsManager.getInstance().getDefaultSettings();
    47
    48          for (Map.Entry<Object, Object> objectObjectEntry : properties.entrySet()) {
    49              Map.Entry<Object, Object> entry = objectObjectEntry;
    50
    51              if (entry.getKey().toString().startsWith("DateFormat")) {
    52                  list.add(entry.getValue());
    53              }
    54          }
    55
    56          DATE_FORMATS = Collections.unmodifiableCollection(list);
    57      }
    58
    59      private transient final PropertyChangeSupport propertySupport =
    60          new PropertyChangeSupport(this);
    61      private String dateFormatPattern = Constants.SIMPLE_TIME_PATTERN;
    62      private boolean levelIcons;
    63      private List allColumns = new ArrayList();
    64      private List visibleColumns = new ArrayList();
    65      private List visibleColumnOrder = new ArrayList();
    66      //set to true to match default 'detailPaneVisible' setting
    67      private boolean detailPaneVisible = true;
    68      private boolean toolTips;
    69      //default thumbnail bar tooltips to true
    70      private boolean thumbnailBarToolTips = true;
    71      private boolean scrollToBottom;
    72      private boolean logTreePanelVisible;
    73      private String loggerPrecision = "";
    74
    75      private Collection hiddenLoggers = new HashSet();
    76      private String timeZone;
    77      //default wrapMsg to true
    78      private boolean wrapMsg = true;
    79      private boolean highlightSearchMatchText;
    80      private String hiddenExpression;
    81      private String alwaysDisplayExpression;
    82      private String clearTableExpression;
    83      //default to cyclic mode off
    84      private boolean cyclic = false;
    85      private boolean showMillisDeltaAsGap;
    86      //default search results to visible
    87      private boolean searchResultsVisible = true;
    88
    89      /**
    90       * Returns an <b>unmodifiable</b> list of the columns.
    91       * <p>
    92       * The reason it is unmodifiable is to enforce the requirement that
    93       * the List is actually unique columns.  IT _could_ be a set,
    94       * but we need to maintain the order of insertion.
    95       *
    96       * @return
    97       */
    98      public List getColumns() {
    99          return Collections.unmodifiableList(allColumns);
    100     }
    101
    102     public void setCyclic(boolean cyclic) {
    103         this.cyclic = cyclic;
    104     }
    105
    106     public boolean isCyclic() {
    107         return cyclic;
    108     }
    109
    110     /**
    111      * Returns an <b>unmodifiable</b> list of the visible columns.
    112      * <p>
    113      * The reason it is unmodifiable is to enforce the requirement that
    114      * the List is actually unique columns.  IT _could_ be a set,
    115      * but we need to maintain the order of insertion.
    116      *
    117      * @return
    118      */
    119     public List getVisibleColumns() {
    120         return Collections.unmodifiableList(visibleColumns);
    121     }
    122
    123     public void clearColumns() {
    124         Object oldValue = this.allColumns;
    125         allColumns = new ArrayList();
    126         propertySupport.firePropertyChange("columns", oldValue, allColumns);
    127     }
    128
    129     private TableColumn findColumnByHeader(List list, String header) {
    130         for (Object aList : list) {
    131             TableColumn c = (TableColumn) aList;
    132             //columns may have changed - header may not exist
    133             if (c != null && c.getHeaderValue() != null && c.getHeaderValue().equals(header)) {
    134                 return c;
    135             }
    136         }
    137         return null;
    138     }
    139
    140     public void setVisibleColumnOrder(List visibleColumnOrder) {
    141         this.visibleColumnOrder = visibleColumnOrder;
    142     }
    143
    144     public List getVisibleColumnOrder() {
    145         return visibleColumnOrder;
    146     }
    147
    148     public boolean addColumn(TableColumn column) {
    149         if (findColumnByHeader(allColumns, column.getHeaderValue().toString()) != null) {
    150             return false;
    151         }
    152
    153         Object oldValue = allColumns;
    154         allColumns = new ArrayList(allColumns);
    155         allColumns.add(column);
    156
    157         propertySupport.firePropertyChange("columns", oldValue, allColumns);
    158         return true;
    159     }
    160
    161     private void setColumns(List columns) {
    162         Object oldValue = allColumns;
    163         allColumns = new ArrayList(columns);
    164         propertySupport.firePropertyChange("columns", oldValue, columns);
    165     }
    166
    167     /**
    168      * Returns the Date Pattern string for the alternate date formatter.
    169      *
    170      * @return date pattern
    171      */
    172     public final String getDateFormatPattern() {
    173         return dateFormatPattern;
    174     }
    175
    176     public final void setDefaultDatePatternFormat() {
    177         String oldVal = this.dateFormatPattern;
    178         this.dateFormatPattern = Constants.SIMPLE_TIME_PATTERN;
    179         propertySupport.firePropertyChange(
    180             "dateFormatPattern", oldVal, this.dateFormatPattern);
    181     }
    182
    183     /**
    184      * @param dateFormatPattern
    185      */
    186     public final void setDateFormatPattern(String dateFormatPattern) {
    187         String oldVal = this.dateFormatPattern;
    188         this.dateFormatPattern = dateFormatPattern;
    189         propertySupport.firePropertyChange(
    190             "dateFormatPattern", oldVal, this.dateFormatPattern);
    191     }
    192
    193     /**
    194      * @param listener
    195      */
    196     public synchronized void addPropertyChangeListener(
    197         PropertyChangeListener listener) {
    198         propertySupport.addPropertyChangeListener(listener);
    199     }
    200
    201     /**
    202      * @param propertyName
    203      * @param listener
    204      */
    205     public synchronized void addPropertyChangeListener(
    206         String propertyName, PropertyChangeListener listener) {
    207         propertySupport.addPropertyChangeListener(propertyName, listener);
    208     }
    209
    210     /**
    211      * @param listener
    212      */
    213     public synchronized void removePropertyChangeListener(
    214         PropertyChangeListener listener) {
    215         propertySupport.removePropertyChangeListener(listener);
    216     }
    217
    218     /**
    219      * @param propertyName
    220      * @param listener
    221      */
    222     public synchronized void removePropertyChangeListener(
    223         String propertyName, PropertyChangeListener listener) {
    224         propertySupport.removePropertyChangeListener(propertyName, listener);
    225     }
    226
    227     /**
    228      * Applies all the properties of another model to this model
    229      *
    230      * @param model the model to copy
    231      *              all the properties from
    232      */
    233     public void apply(LogPanelPreferenceModel model) {
    234         setCyclic(model.isCyclic());
    235         setLoggerPrecision(model.getLoggerPrecision());
    236         setDateFormatPattern(model.getDateFormatPattern());
    237         setLevelIcons(model.isLevelIcons());
    238         setWrapMessage(model.isWrapMessage());
    239         setHighlightSearchMatchText(model.isHighlightSearchMatchText());
    240         setTimeZone(model.getTimeZone());
    241         setToolTips(model.isToolTips());
    242         setThumbnailBarToolTips((model.isThumbnailBarToolTips()));
    243         setScrollToBottom(model.isScrollToBottom());
    244         setDetailPaneVisible(model.isDetailPaneVisible());
    245         setLogTreePanelVisible(model.isLogTreePanelVisible());
    246         setVisibleColumnOrder(model.getVisibleColumnOrder());
    247         setSearchResultsVisible(model.isSearchResultsVisible());
    248         // we have to copy the list, because getColumns() is unmodifiable
    249         setColumns(model.getColumns());
    250
    251         setVisibleColumns(model.getVisibleColumns());
    252         setHiddenLoggers(model.getHiddenLoggers());
    253         setHiddenExpression(model.getHiddenExpression());
    254         setAlwaysDisplayExpression(model.getAlwaysDisplayExpression());
    255         setShowMillisDeltaAsGap(model.isShowMillisDeltaAsGap());
    256         setClearTableExpression(model.getClearTableExpression());
    257     }
    258
    259     /**
    260      * Returns true if this the fast ISO8601DateFormat object
    261      * should be used instead of SimpleDateFormat
    262      *
    263      * @return use ISO8601 format flag
    264      */
    265     public boolean isUseISO8601Format() {
    266         return getDateFormatPattern().equals(ISO8601);
    267     }
    268
    269     /**
    270      * @return level icons flag
    271      */
    272     public boolean isLevelIcons() {
    273         return levelIcons;
    274     }
    275
    276     public boolean isWrapMessage() {
    277         return wrapMsg;
    278     }
    279
    280     public boolean isHighlightSearchMatchText() {
    281         return highlightSearchMatchText;
    282     }
    283
    284     /**
    285      * @param levelIcons
    286      */
    287     public void setLevelIcons(boolean levelIcons) {
    288         this.levelIcons = levelIcons;
    289         propertySupport.firePropertyChange("levelIcons", !levelIcons, levelIcons);
    290     }
    291
    292     public void setSearchResultsVisible(boolean searchResultsVisible) {
    293         boolean oldValue = this.searchResultsVisible;
    294         this.searchResultsVisible = searchResultsVisible;
    295         propertySupport.firePropertyChange("searchResultsVisible", oldValue, searchResultsVisible);
    296     }
    297
    298     public boolean isSearchResultsVisible() {
    299         return searchResultsVisible;
    300     }
    301
    302     /**
    303      * @param wrapMsg
    304      */
    305     public void setWrapMessage(boolean wrapMsg) {
    306         this.wrapMsg = wrapMsg;
    307         propertySupport.firePropertyChange("wrapMessage", !wrapMsg, wrapMsg);
    308     }
    309
    310     /**
    311      * @param highlightSearchMatchText
    312      */
    313     public void setHighlightSearchMatchText(boolean highlightSearchMatchText) {
    314         this.highlightSearchMatchText = highlightSearchMatchText;
    315         propertySupport.firePropertyChange("highlightSearchMatchText", !highlightSearchMatchText, highlightSearchMatchText);
    316     }
    317
    318     /**
    319      * @param loggerPrecision - an integer representing the number of packages to display,
    320      *                        or an empty string representing 'display all packages'
    321      */
    322     public void setLoggerPrecision(String loggerPrecision) {
    323         String oldVal = this.loggerPrecision;
    324         this.loggerPrecision = loggerPrecision;
    325         propertySupport.firePropertyChange("loggerPrecision", oldVal, this.loggerPrecision);
    326     }
    327
    328     /**
    329      * Returns the Logger precision.
    330      *
    331      * @return logger precision
    332      */
    333     public final String getLoggerPrecision() {
    334         return loggerPrecision;
    335     }
    336
    337     /**
    338      * Returns true if the named column should be made visible otherwise
    339      * false.
    340      *
    341      * @param column
    342      * @return column visible flag
    343      */
    344     public boolean isColumnVisible(TableColumn column) {
    345         return (findColumnByHeader(visibleColumns, column.getHeaderValue().toString()) != null);
    346     }
    347
    348     private void setVisibleColumns(List visibleColumns) {
    349         Object oldValue = new ArrayList();
    350         this.visibleColumns = new ArrayList(visibleColumns);
    351
    352         propertySupport.firePropertyChange("visibleColumns", oldValue, this.visibleColumns);
    353     }
    354
    355     public void setColumnVisible(String columnName, boolean isVisible) {
    356         boolean wasVisible = findColumnByHeader(visibleColumns, columnName) != null;
    357
    358         //because we're a list and not a set, ensure we keep at most
    359         //one entry for a tablecolumn
    360         Object col = findColumnByHeader(allColumns, columnName);
    361         if (isVisible && !wasVisible) {
    362             visibleColumns.add(col);
    363             visibleColumnOrder.add(col);
    364             propertySupport.firePropertyChange("visibleColumns", Boolean.valueOf(isVisible), Boolean.valueOf(wasVisible));
    365         }
    366         if (!isVisible && wasVisible) {
    367             visibleColumns.remove(col);
    368             visibleColumnOrder.remove(col);
    369             propertySupport.firePropertyChange("visibleColumns", Boolean.valueOf(isVisible), Boolean.valueOf(wasVisible));
    370         }
    371     }
    372
    373     /**
    374      * Toggles the state between visible, non-visible for a particular Column name
    375      *
    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     /**
    412      * @param scrollToBottom
    413      */
    414     public final void setScrollToBottom(boolean scrollToBottom) {
    415         boolean oldValue = this.scrollToBottom;
    416         this.scrollToBottom = scrollToBottom;
    417         propertySupport.firePropertyChange(
    418             "scrollToBottom", oldValue, this.scrollToBottom);
    419     }
    420
    421     /**
    422      * @param showMillisDeltaAsGap
    423      */
    424     public final void setShowMillisDeltaAsGap(boolean showMillisDeltaAsGap) {
    425         boolean oldValue = this.showMillisDeltaAsGap;
    426         this.showMillisDeltaAsGap = showMillisDeltaAsGap;
    427         propertySupport.firePropertyChange(
    428             "showMillisDeltaAsGap", oldValue, this.showMillisDeltaAsGap);
    429     }
    430
    431     public final void setThumbnailBarToolTips(boolean thumbnailBarToolTips) {
    432         boolean oldValue = this.thumbnailBarToolTips;
    433         this.thumbnailBarToolTips = thumbnailBarToolTips;
    434         propertySupport.firePropertyChange("thumbnailBarToolTips", oldValue, this.thumbnailBarToolTips);
    435     }
    436
    437     public final boolean isThumbnailBarToolTips() {
    438         return thumbnailBarToolTips;
    439     }
    440
    441     /**
    442      * @return tool tips enabled flag
    443      */
    444     public final boolean isToolTips() {
    445         return toolTips;
    446     }
    447
    448     /**
    449      * @param toolTips
    450      */
    451     public final void setToolTips(boolean toolTips) {
    452         boolean oldValue = this.toolTips;
    453         this.toolTips = toolTips;
    454         propertySupport.firePropertyChange("toolTips", oldValue, this.toolTips);
    455     }
    456
    457     /**
    458      * @return log tree panel visible flag
    459      */
    460     public final boolean isLogTreePanelVisible() {
    461         return logTreePanelVisible;
    462     }
    463
    464     /**
    465      * @param logTreePanelVisible
    466      */
    467     public final void setLogTreePanelVisible(boolean logTreePanelVisible) {
    468         boolean oldValue = this.logTreePanelVisible;
    469         this.logTreePanelVisible = logTreePanelVisible;
    470         propertySupport.firePropertyChange(
    471             "logTreePanelVisible", oldValue, this.logTreePanelVisible);
    472     }
    473
    474     /**
    475      * @return custom date format flag
    476      */
    477     public boolean isCustomDateFormat() {
    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 }