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