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  package org.apache.log4j.chainsaw.color;
    19
    20  import org.apache.log4j.chainsaw.ChainsawConstants;
    21  import org.apache.log4j.chainsaw.prefs.SettingsManager;
    22  import org.apache.log4j.rule.ColorRule;
    23  import org.apache.log4j.rule.ExpressionRule;
    24  import org.apache.log4j.rule.Rule;
    25  import org.apache.log4j.spi.LoggingEvent;
    26
    27  import java.awt.*;
    28  import java.beans.PropertyChangeListener;
    29  import java.beans.PropertyChangeSupport;
    30  import java.io.*;
    31  import java.net.URLEncoder;
    32  import java.util.*;
    33  import java.util.List;
    34
    35
    36  /**
    37   * A colorizer supporting an ordered collection of ColorRules, including support for notification of
    38   * color rule changes via a propertyChangeListener and the 'colorrule' property.
    39   *
    40   * @author Scott Deboy &lt;sdeboy@apache.org&gt;
    41   */
    42  public class RuleColorizer implements Colorizer {
    43      private Map rules;
    44      private final PropertyChangeSupport colorChangeSupport =
    45          new PropertyChangeSupport(this);
    46      private Map defaultRules = new HashMap();
    47      private String currentRuleSet = ChainsawConstants.DEFAULT_COLOR_RULE_NAME;
    48      private Rule findRule;
    49      private Rule loggerRule;
    50
    51      private static final String COLORS_EXTENSION = ".colors";
    52
    53      private final Color WARN_DEFAULT_COLOR = new Color(255, 255, 153);
    54      private final Color FATAL_OR_ERROR_DEFAULT_COLOR = new Color(255, 153, 153);
    55      private final Color MARKER_DEFAULT_COLOR = new Color(153, 255, 153);
    56
    57      private final String DEFAULT_WARN_EXPRESSION = "level == WARN";
    58      private final String DEFAULT_FATAL_ERROR_EXCEPTION_EXPRESSION = "level == FATAL || level == ERROR || exception exists";
    59      private final String DEFAULT_MARKER_EXPRESSION = "prop.marker exists";
    60
    61      public RuleColorizer() {
    62          List rulesList = new ArrayList();
    63
    64          String expression = DEFAULT_FATAL_ERROR_EXCEPTION_EXPRESSION;
    65          rulesList.add(
    66              new ColorRule(
    67                  expression, ExpressionRule.getRule(expression), FATAL_OR_ERROR_DEFAULT_COLOR,
    68                  Color.black));
    69          expression = DEFAULT_WARN_EXPRESSION;
    70          rulesList.add(
    71              new ColorRule(
    72                  expression, ExpressionRule.getRule(expression), WARN_DEFAULT_COLOR,
    73                  Color.black));
    74
    75          expression = DEFAULT_MARKER_EXPRESSION;
    76          rulesList.add(
    77              new ColorRule(
    78                  expression, ExpressionRule.getRule(expression), MARKER_DEFAULT_COLOR,
    79                  Color.black));
    80
    81          defaultRules.put(currentRuleSet, rulesList);
    82          setRules(defaultRules);
    83      }
    84
    85      public void setLoggerRule(Rule loggerRule) {
    86          this.loggerRule = loggerRule;
    87          colorChangeSupport.firePropertyChange("colorrule", false, true);
    88      }
    89
    90      public void setFindRule(Rule findRule) {
    91          this.findRule = findRule;
    92          colorChangeSupport.firePropertyChange("colorrule", false, true);
    93      }
    94
    95      public Rule getFindRule() {
    96          return findRule;
    97      }
    98
    99      public Rule getLoggerRule() {
    100         return loggerRule;
    101     }
    102
    103     public void setRules(Map rules) {
    104         this.rules = rules;
    105         colorChangeSupport.firePropertyChange("colorrule", false, true);
    106     }
    107
    108     public Map getRules() {
    109         return rules;
    110     }
    111
    112     public List getCurrentRules() {
    113         return (List) rules.get(currentRuleSet);
    114     }
    115
    116     public void addRules(Map newRules) {
    117
    118         for (Object o : newRules.entrySet()) {
    119             Map.Entry entry = (Map.Entry) o;
    120
    121             if (rules.containsKey(entry.getKey())) {
    122                 ((List) rules.get(entry.getKey())).addAll((List) entry.getValue());
    123             } else {
    124                 rules.put(entry.getKey(), entry.getValue());
    125             }
    126         }
    127
    128         colorChangeSupport.firePropertyChange("colorrule", false, true);
    129     }
    130
    131     public void addRule(String ruleSetName, ColorRule rule) {
    132         if (rules.containsKey(ruleSetName)) {
    133             ((List) rules.get(ruleSetName)).add(rule);
    134         } else {
    135             List list = new ArrayList();
    136             list.add(rule);
    137             rules.put(ruleSetName, list);
    138         }
    139
    140         colorChangeSupport.firePropertyChange("colorrule", false, true);
    141     }
    142
    143     public void removeRule(String ruleSetName, String expression) {
    144         if (rules.containsKey(ruleSetName)) {
    145             List list = (List) rules.get(ruleSetName);
    146
    147             for (int i = 0; i < list.size(); i++) {
    148                 ColorRule rule = (ColorRule) list.get(i);
    149
    150                 if (rule.getExpression().equals(expression)) {
    151                     list.remove(rule);
    152
    153                     return;
    154                 }
    155             }
    156         }
    157     }
    158
    159     public void setCurrentRuleSet(String ruleSetName) {
    160         currentRuleSet = ruleSetName;
    161     }
    162
    163     public Color getBackgroundColor(LoggingEvent event) {
    164         if (rules.containsKey(currentRuleSet)) {
    165             List list = (List) rules.get(currentRuleSet);
    166
    167             for (Object aList : list) {
    168                 ColorRule rule = (ColorRule) aList;
    169
    170                 if ((rule.getBackgroundColor() != null) && (rule.evaluate(event, null))) {
    171                     return rule.getBackgroundColor();
    172                 }
    173             }
    174         }
    175
    176         return null;
    177     }
    178
    179     public Color getForegroundColor(LoggingEvent event) {
    180         if (rules.containsKey(currentRuleSet)) {
    181             List list = (List) rules.get(currentRuleSet);
    182
    183             for (Object aList : list) {
    184                 ColorRule rule = (ColorRule) aList;
    185
    186                 if ((rule.getForegroundColor() != null) && (rule.evaluate(event, null))) {
    187                     return rule.getForegroundColor();
    188                 }
    189             }
    190         }
    191
    192         return null;
    193     }
    194
    195     public void addPropertyChangeListener(PropertyChangeListener listener) {
    196         colorChangeSupport.addPropertyChangeListener(listener);
    197     }
    198
    199     public void removePropertyChangeListener(PropertyChangeListener listener) {
    200         colorChangeSupport.removePropertyChangeListener(listener);
    201     }
    202
    203     /**
    204      * @param propertyName
    205      * @param listener
    206      */
    207     public void addPropertyChangeListener(
    208         String propertyName, PropertyChangeListener listener) {
    209         colorChangeSupport.addPropertyChangeListener(propertyName, listener);
    210     }
    211
    212
    213     /**
    214      * Save panel color settings
    215      */
    216     public void saveColorSettings(String name) {
    217         ObjectOutputStream o = null;
    218         try {
    219             File f = new File(SettingsManager.getInstance().getSettingsDirectory(), URLEncoder.encode(name + COLORS_EXTENSION));
    220
    221             o = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(f)));
    222
    223             o.writeObject(getRules());
    224             o.flush();
    225         } catch (IOException ioe) {
    226             ioe.printStackTrace();
    227         } finally {
    228             try {
    229                 if (o != null) {
    230                     o.close();
    231                 }
    232             } catch (IOException ioe) {
    233                 ioe.printStackTrace();
    234             }
    235         }
    236     }
    237
    238     /**
    239      * Load panel color settings if they exist - otherwise, load default color settings
    240      */
    241     public void loadColorSettings(String name) {
    242         if (!doLoadColorSettings(name)) {
    243             doLoadColorSettings(ChainsawConstants.DEFAULT_COLOR_RULE_NAME);
    244         }
    245     }
    246
    247     private boolean doLoadColorSettings(String name) {
    248         //first attempt to load encoded file
    249         File f = new File(SettingsManager.getInstance().getSettingsDirectory(), URLEncoder.encode(name) + COLORS_EXTENSION);
    250
    251         if (f.exists()) {
    252             ObjectInputStream s = null;
    253
    254             try {
    255                 s = new ObjectInputStream(
    256                     new BufferedInputStream(new FileInputStream(f)));
    257
    258                 Map map = (Map) s.readObject();
    259                 setRules(map);
    260             } catch (EOFException eof) { //end of file - ignore..
    261             } catch (IOException ioe) {
    262                 ioe.printStackTrace();
    263                 //unable to load file - delete it
    264                 f.delete();
    265             } catch (ClassNotFoundException cnfe) {
    266                 cnfe.printStackTrace();
    267             } finally {
    268                 if (s != null) {
    269                     try {
    270                         s.close();
    271                     } catch (IOException ioe) {
    272                         ioe.printStackTrace();
    273                     }
    274                 }
    275             }
    276         }
    277         return f.exists();
    278     }
    279
    280     public Vector getDefaultColors() {
    281         Vector vec = new Vector();
    282
    283         vec.add(Color.white);
    284         vec.add(Color.black);
    285         //add default alternating color & search backgrounds (both foreground are black)
    286         vec.add(ChainsawConstants.COLOR_ODD_ROW_BACKGROUND);
    287         vec.add(ChainsawConstants.FIND_LOGGER_BACKGROUND);
    288
    289         vec.add(new Color(255, 255, 225));
    290         vec.add(new Color(255, 225, 255));
    291         vec.add(new Color(225, 255, 255));
    292         vec.add(new Color(255, 225, 225));
    293         vec.add(new Color(225, 255, 225));
    294         vec.add(new Color(225, 225, 255));
    295         vec.add(new Color(225, 225, 183));
    296         vec.add(new Color(225, 183, 225));
    297         vec.add(new Color(183, 225, 225));
    298         vec.add(new Color(183, 225, 183));
    299         vec.add(new Color(183, 183, 225));
    300         vec.add(new Color(232, 201, 169));
    301         vec.add(new Color(255, 255, 153));
    302         vec.add(new Color(255, 153, 153));
    303         vec.add(new Color(189, 156, 89));
    304         vec.add(new Color(255, 102, 102));
    305         vec.add(new Color(255, 177, 61));
    306         vec.add(new Color(61, 255, 61));
    307         vec.add(new Color(153, 153, 255));
    308         vec.add(new Color(255, 153, 255));
    309
    310         return vec;
    311     }
    312
    313 }