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  package org.apache.log4j.chainsaw;
    18
    19  import javax.swing.*;
    20  import java.awt.*;
    21  import java.beans.PropertyChangeListener;
    22  import java.beans.PropertyChangeSupport;
    23  import java.util.ArrayList;
    24  import java.util.List;
    25  import java.util.Vector;
    26
    27  /**
    28   * Encapsulates the Chainsaw Application wide properties
    29   *
    30   * @author Paul Smith &lt;psmith@apache.org&gt;
    31   */
    32  public class ApplicationPreferenceModel {
    33
    34      private boolean showNoReceiverWarning = true;
    35      private boolean statusBar = true;
    36      private boolean toolbar = true;
    37      private boolean receivers = false; //setting this to true will cause the receivers panel to be displayed by default
    38      private boolean confirmExit = true;
    39      private boolean showSplash = true;
    40      private String lookAndFeelClassName = "";
    41      private int toolTipDisplayMillis = 4000;
    42      private int cyclicBufferSize = 50000;
    43      private String lastUsedVersion = "";
    44      private int responsiveness = 3;
    45      private Color searchBackgroundColor = ChainsawConstants.FIND_LOGGER_BACKGROUND;
    46      private Color searchForegroundColor = ChainsawConstants.FIND_LOGGER_FOREGROUND;
    47      private Color alternatingColorForegroundColor = ChainsawConstants.COLOR_ODD_ROW_FOREGROUND;
    48      private Color alternatingColorBackgroundColor = ChainsawConstants.COLOR_ODD_ROW_BACKGROUND;
    49
    50      private String identifierExpression = "PROP.hostname - PROP.application";
    51
    52      private transient final PropertyChangeSupport propertySupport =
    53          new PropertyChangeSupport(this);
    54
    55      private int tabPlacement = 3;
    56
    57      /**
    58       * If not 'empty', this property will be used as the URL to load log4j configuration at startup
    59       */
    60      private Vector<String> configurationURLs = new Vector<>();
    61
    62      private String configurationURL = "";
    63
    64      /**
    65       * Remember current config if provided via means other than configurationURL (command line arg, etc)
    66       */
    67      private transient String bypassConfigurationURL = null;
    68      /**
    69       * this means for Receivers that require optional jars that can't be delivered
    70       * by the Web start classloader, we need to be able to remove the SecurityManager in place
    71       */
    72      private boolean okToRemoveSecurityManager = false;
    73      private static final int CONFIGURATION_URL_ENTRY_COUNT = 10;
    74      private List defaultColumnNames = new ArrayList();
    75      private boolean defaultColumnsSet;
    76      private boolean bypassSearchColors = false;
    77
    78      /**
    79       * @param listener
    80       */
    81      public void addPropertyChangeListener(PropertyChangeListener listener) {
    82          propertySupport.addPropertyChangeListener(listener);
    83      }
    84
    85      /**
    86       * @param propertyName
    87       * @param listener
    88       */
    89      public void addPropertyChangeListener(String propertyName,
    90                                            PropertyChangeListener listener) {
    91          propertySupport.addPropertyChangeListener(propertyName, listener);
    92      }
    93
    94      /**
    95       * @param propertyName
    96       * @param oldValue
    97       * @param newValue
    98       */
    99      private void firePropertyChange(String propertyName, boolean oldValue,
    100                                     boolean newValue) {
    101         propertySupport.firePropertyChange(propertyName, oldValue, newValue);
    102     }
    103
    104     /**
    105      * @param propertyName
    106      * @param oldValue
    107      * @param newValue
    108      */
    109     private void firePropertyChange(String propertyName, int oldValue,
    110                                     int newValue) {
    111         propertySupport.firePropertyChange(propertyName, oldValue, newValue);
    112     }
    113
    114     /**
    115      * @param propertyName
    116      * @param oldValue
    117      * @param newValue
    118      */
    119     private void firePropertyChange(String propertyName, Object oldValue,
    120                                     Object newValue) {
    121         propertySupport.firePropertyChange(propertyName, oldValue, newValue);
    122     }
    123
    124     /**
    125      * @param propertyName
    126      * @return listeners flag
    127      */
    128     public boolean hasListeners(String propertyName) {
    129         return propertySupport.hasListeners(propertyName);
    130     }
    131
    132     /**
    133      * @param listener
    134      */
    135     public void removePropertyChangeListener(PropertyChangeListener listener) {
    136         propertySupport.removePropertyChangeListener(listener);
    137     }
    138
    139     /**
    140      * @return Returns the showNoReceiverWarning.
    141      */
    142     public final boolean isShowNoReceiverWarning() {
    143
    144         return showNoReceiverWarning;
    145     }
    146
    147     public final String getIdentifierExpression() {
    148         return identifierExpression;
    149     }
    150
    151     public final void setCyclicBufferSize(int newCyclicBufferSize) {
    152         int oldCyclicBufferSize = cyclicBufferSize;
    153         cyclicBufferSize = newCyclicBufferSize;
    154         firePropertyChange("cyclicBufferSize", oldCyclicBufferSize, newCyclicBufferSize);
    155     }
    156
    157     public final int getCyclicBufferSize() {
    158         return cyclicBufferSize;
    159     }
    160
    161     public final void setToolTipDisplayMillis(int newToolTipDisplayMillis) {
    162         int oldToolTipDisplayMillis = toolTipDisplayMillis;
    163         toolTipDisplayMillis = newToolTipDisplayMillis;
    164         firePropertyChange("toolTipDisplayMillis", oldToolTipDisplayMillis, newToolTipDisplayMillis);
    165     }
    166
    167     public final int getToolTipDisplayMillis() {
    168         return toolTipDisplayMillis;
    169     }
    170
    171     public final void setIdentifierExpression(String newIdentifierExpression) {
    172         String oldIdentifierExpression = identifierExpression;
    173         this.identifierExpression = newIdentifierExpression;
    174         firePropertyChange("identifierExpression", oldIdentifierExpression, newIdentifierExpression);
    175     }
    176
    177     /**
    178      * @param newShowNoReceiverWarning The showNoReceiverWarning to set.
    179      */
    180     public final void setShowNoReceiverWarning(boolean newShowNoReceiverWarning) {
    181         boolean oldShowNoReceiverWarning = showNoReceiverWarning;
    182         this.showNoReceiverWarning = newShowNoReceiverWarning;
    183         firePropertyChange("showNoReceiverWarning", oldShowNoReceiverWarning, newShowNoReceiverWarning);
    184     }
    185
    186
    187     /**
    188      * Takes another model and copies all the values into this model
    189      *
    190      * @param model
    191      */
    192     public void apply(ApplicationPreferenceModel model) {
    193         setIdentifierExpression(model.getIdentifierExpression());
    194         setShowNoReceiverWarning(model.isShowNoReceiverWarning() || (model.getConfigurationURL() == null || model.getConfigurationURL().trim().equals("")));
    195         setResponsiveness(model.getResponsiveness());
    196         setTabPlacement(model.getTabPlacement());
    197         setStatusBar(model.isStatusBar());
    198         setToolbar(model.isToolbar());
    199         setReceivers(model.isReceivers());
    200         if (model.getLookAndFeelClassName() != null && !model.getLookAndFeelClassName().trim().equals("")) {
    201             setLookAndFeelClassName(model.getLookAndFeelClassName());
    202         } else {
    203             //ensure current look and feel is selected
    204             setLookAndFeelClassName(UIManager.getLookAndFeel().getClass().getName());
    205         }
    206         setConfirmExit(model.isConfirmExit());
    207         setShowSplash(model.isShowSplash());
    208         setToolTipDisplayMillis(model.getToolTipDisplayMillis());
    209         setCyclicBufferSize(model.getCyclicBufferSize());
    210         Vector<String> configurationURLs = model.getConfigurationURLs();
    211         if (configurationURLs != null) {
    212             setConfigurationURLs(configurationURLs);
    213         }
    214         //only set current config URL if bypass is null
    215         if (model.getBypassConfigurationURL() == null) {
    216             setConfigurationURL(model.getConfigurationURL());
    217         }
    218         setLastUsedVersion(model.getLastUsedVersion());
    219         setOkToRemoveSecurityManager(model.isOkToRemoveSecurityManager());
    220         Color searchForeground = model.getSearchForegroundColor();
    221         Color searchBackground = model.getSearchBackgroundColor();
    222         if (searchForeground != null && searchBackground != null) {
    223             setSearchBackgroundColor(searchBackground);
    224             setSearchForegroundColor(searchForeground);
    225         }
    226
    227         Color alternatingForeground = model.getAlternatingColorForegroundColor();
    228         Color alternatingBackground = model.getAlternatingColorBackgroundColor();
    229         if (alternatingForeground != null && alternatingBackground != null) {
    230             setAlternatingBackgroundColor(alternatingBackground);
    231             setAlternatingForegroundColor(alternatingForeground);
    232         }
    233         if (model.isDefaultColumnsSet()) {
    234             setDefaultColumnNames(model.getDefaultColumnNames());
    235         }
    236         setBypassSearchColors(model.isBypassSearchColors());
    237     }
    238
    239     //use a lighter version of search color as the delta color
    240     public Color getDeltaColor() {
    241         float factor = 1.3F;
    242         Color search = getSearchBackgroundColor();
    243
    244         return new Color(boundColorValue((int) (search.getRed() * factor)),
    245             boundColorValue((int) (search.getGreen() * factor)),
    246             boundColorValue((int) (search.getBlue() * factor)));
    247     }
    248
    249     private int boundColorValue(int colorValue) {
    250         return Math.min(Math.max(0, colorValue), 255);
    251     }
    252
    253
    254     /**
    255      * @return Returns the responsiveness.
    256      */
    257     public final int getResponsiveness() {
    258         return responsiveness;
    259     }
    260
    261     /**
    262      * @param newValue The responsiveness to set.
    263      */
    264     public final void setResponsiveness(int newValue) {
    265         int oldvalue = responsiveness;
    266
    267         if (newValue >= 1000) {
    268             responsiveness = (newValue - 750) / 1000;
    269         } else {
    270             responsiveness = newValue;
    271         }
    272         firePropertyChange("responsiveness", oldvalue, responsiveness);
    273     }
    274
    275     /**
    276      * @param i
    277      */
    278     public void setTabPlacement(int i) {
    279         int oldValue = this.tabPlacement;
    280         this.tabPlacement = i;
    281         firePropertyChange("tabPlacement", oldValue, this.tabPlacement);
    282     }
    283
    284     /**
    285      * @return Returns the tabPlacement.
    286      */
    287     public final int getTabPlacement() {
    288         return tabPlacement;
    289     }
    290
    291     /**
    292      * @return Returns the statusBar.
    293      */
    294     public final boolean isStatusBar() {
    295         return statusBar;
    296     }
    297
    298     public Vector<String> getConfigurationURLs() {
    299         return configurationURLs;
    300     }
    301
    302     public void setConfigurationURLs(Vector<String> urls) {
    303         if (urls != null) {
    304             configurationURLs = urls;
    305         }
    306     }
    307
    308     /**
    309      * @param statusBar The statusBar to set.
    310      */
    311     public final void setStatusBar(boolean statusBar) {
    312         boolean oldValue = this.statusBar;
    313         this.statusBar = statusBar;
    314         firePropertyChange("statusBar", oldValue, this.statusBar);
    315     }
    316
    317     public void setAlternatingForegroundColor(Color alternatingColorForegroundColor) {
    318         this.alternatingColorForegroundColor = alternatingColorForegroundColor;
    319         firePropertyChange("alternatingColor", true, false);
    320     }
    321
    322     public void setAlternatingBackgroundColor(Color alternatingColorBackgroundColor) {
    323         this.alternatingColorBackgroundColor = alternatingColorBackgroundColor;
    324         firePropertyChange("alternatingColor", true, false);
    325     }
    326
    327     public void setSearchForegroundColor(Color searchForegroundColor) {
    328         this.searchForegroundColor = searchForegroundColor;
    329         firePropertyChange("searchColor", true, false);
    330     }
    331
    332     public void setSearchBackgroundColor(Color searchBackgroundColor) {
    333         this.searchBackgroundColor = searchBackgroundColor;
    334         firePropertyChange("searchColor", true, false);
    335     }
    336
    337     public Color getAlternatingColorBackgroundColor() {
    338         return alternatingColorBackgroundColor;
    339     }
    340
    341     public Color getAlternatingColorForegroundColor() {
    342         return alternatingColorForegroundColor;
    343     }
    344
    345     public Color getSearchBackgroundColor() {
    346         return searchBackgroundColor;
    347     }
    348
    349     public Color getSearchForegroundColor() {
    350         return searchForegroundColor;
    351     }
    352
    353     /**
    354      * @return Returns the receivers.
    355      */
    356     public final boolean isReceivers() {
    357         return receivers;
    358     }
    359
    360     /**
    361      * @param receivers The receivers to set.
    362      */
    363     public final void setReceivers(boolean receivers) {
    364         boolean oldValue = this.receivers;
    365         this.receivers = receivers;
    366         firePropertyChange("receivers", oldValue, this.receivers);
    367     }
    368
    369     /**
    370      * @return Returns the toolbar.
    371      */
    372     public final boolean isToolbar() {
    373         return toolbar;
    374     }
    375
    376     /**
    377      * @param toolbar The toolbar to set.
    378      */
    379     public final void setToolbar(boolean toolbar) {
    380         boolean oldValue = this.toolbar;
    381         this.toolbar = toolbar;
    382         firePropertyChange("toolbar", oldValue, this.toolbar);
    383     }
    384
    385     /**
    386      * @return Returns the lookAndFeelClassName.
    387      */
    388     public final String getLookAndFeelClassName() {
    389         return lookAndFeelClassName;
    390     }
    391
    392     /**
    393      * @param lookAndFeelClassName The lookAndFeelClassName to set.
    394      */
    395     public final void setLookAndFeelClassName(String lookAndFeelClassName) {
    396         String oldValue = this.lookAndFeelClassName;
    397         this.lookAndFeelClassName = lookAndFeelClassName;
    398         firePropertyChange("lookAndFeelClassName", oldValue, this.lookAndFeelClassName);
    399     }
    400
    401     /**
    402      * @return Returns the confirmExit.
    403      */
    404     public final boolean isConfirmExit() {
    405         return confirmExit;
    406     }
    407
    408     /**
    409      * @param confirmExit The confirmExit to set.
    410      */
    411     public final void setConfirmExit(boolean confirmExit) {
    412         boolean oldValue = this.confirmExit;
    413         this.confirmExit = confirmExit;
    414         firePropertyChange("confirmExit", oldValue, this.confirmExit);
    415     }
    416
    417     /**
    418      * @return Returns the showSplash.
    419      */
    420     public final boolean isShowSplash() {
    421         return showSplash;
    422     }
    423
    424     /**
    425      * @param showSplash The showSplash to set.
    426      */
    427     public final void setShowSplash(boolean showSplash) {
    428         boolean oldValue = this.showSplash;
    429         this.showSplash = showSplash;
    430         firePropertyChange("showSplash", oldValue, this.showSplash);
    431     }
    432
    433     /**
    434      * @return Returns the configurationURL.
    435      */
    436     public final String getConfigurationURL() {
    437         return this.configurationURL;
    438     }
    439
    440     public final String getBypassConfigurationURL() {
    441         return bypassConfigurationURL;
    442     }
    443
    444     /*
    445       Set to null to un-bypass
    446      */
    447     public void setBypassConfigurationURL(String bypassConfigurationURL) {
    448         //don't change configuration URL..configurationURL is persisted on app exit
    449         if (bypassConfigurationURL != null && bypassConfigurationURL.trim().equals("")) {
    450             this.bypassConfigurationURL = null;
    451         }
    452         this.bypassConfigurationURL = bypassConfigurationURL;
    453     }
    454
    455     /**
    456      * @param configurationURL The configurationURL to set.
    457      */
    458     public final void setConfigurationURL(String configurationURL) {
    459         //don't add empty entries, but allow the current configuration URL to be set to an empty string
    460         Object oldValue = this.bypassConfigurationURL != null ? this.bypassConfigurationURL : this.configurationURL;
    461         bypassConfigurationURL = null;
    462         if (configurationURL == null || configurationURL.trim().equals("")) {
    463             this.configurationURL = "";
    464             firePropertyChange("configurationURL", oldValue, this.configurationURL);
    465             return;
    466         }
    467         //add entry to MRU list
    468         if (!configurationURLs.contains(configurationURL)) {
    469             if (configurationURLs.size() == CONFIGURATION_URL_ENTRY_COUNT) {
    470                 configurationURLs.remove(CONFIGURATION_URL_ENTRY_COUNT - 1);
    471             }
    472             configurationURLs.add(0, configurationURL);
    473         }
    474         this.configurationURL = configurationURL;
    475         firePropertyChange("configurationURL", oldValue, this.configurationURL);
    476     }
    477
    478     /**
    479      * @return Returns the lastUsedVersion.
    480      */
    481     public final String getLastUsedVersion() {
    482         return this.lastUsedVersion;
    483     }
    484
    485     /**
    486      * @param lastUsedVersion The lastUsedVersion to set.
    487      */
    488     public final void setLastUsedVersion(String lastUsedVersion) {
    489         String oldValue = this.lastUsedVersion;
    490         this.lastUsedVersion = lastUsedVersion;
    491         firePropertyChange("lastUsedVersion", oldValue, this.lastUsedVersion);
    492     }
    493
    494     /**
    495      * @return ok to remove security manager flag
    496      */
    497     public final boolean isOkToRemoveSecurityManager() {
    498         return this.okToRemoveSecurityManager;
    499     }
    500
    501     /**
    502      * @param okToRemoveSecurityManager The okToRemoveSecurityManager to set.
    503      */
    504     public final void setOkToRemoveSecurityManager(boolean okToRemoveSecurityManager) {
    505         boolean oldValue = this.okToRemoveSecurityManager;
    506         this.okToRemoveSecurityManager = okToRemoveSecurityManager;
    507         firePropertyChange("okToRemoveSecurityManager", oldValue, this.okToRemoveSecurityManager);
    508     }
    509
    510     public void setDefaultColumnNames(List defaultColumnNames) {
    511         defaultColumnsSet = true;
    512         this.defaultColumnNames.clear();
    513         this.defaultColumnNames.addAll(defaultColumnNames);
    514     }
    515
    516     public boolean isDefaultColumnsSet() {
    517         return defaultColumnsSet;
    518     }
    519
    520     public List getDefaultColumnNames() {
    521         return defaultColumnNames;
    522     }
    523
    524     public void setBypassSearchColors(boolean bypassSearchColors) {
    525         this.bypassSearchColors = bypassSearchColors;
    526     }
    527
    528     public boolean isBypassSearchColors() {
    529         return bypassSearchColors;
    530     }
    531 }