blob: aa197cf8fb4c19e69adf47a40bffb58032049b57 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.chainsaw.color;
import org.apache.log4j.chainsaw.ChainsawConstants;
import org.apache.log4j.chainsaw.prefs.SettingsManager;
import org.apache.log4j.rule.ColorRule;
import org.apache.log4j.rule.ExpressionRule;
import org.apache.log4j.rule.Rule;
import java.awt.*;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;
import java.util.List;
import org.apache.commons.configuration2.AbstractConfiguration;
import org.apache.log4j.chainsaw.logevents.ChainsawLoggingEvent;
/**
* A colorizer supporting an ordered collection of ColorRules, including support for notification of
* color rule changes via a propertyChangeListener and the 'colorrule' property.
*
* @author Scott Deboy <sdeboy@apache.org>
*/
public class RuleColorizer implements Colorizer {
private Map<String,List<ColorRule>> rules;
private final PropertyChangeSupport colorChangeSupport =
new PropertyChangeSupport(this);
private Map<String,List<ColorRule>> defaultRules = new HashMap<>();
private String currentRuleSet = ChainsawConstants.DEFAULT_COLOR_RULE_NAME;
private Rule findRule;
private Rule loggerRule;
private static final String COLORS_EXTENSION = ".colors";
private final Color WARN_DEFAULT_COLOR = new Color(255, 255, 153);
private final Color FATAL_OR_ERROR_DEFAULT_COLOR = new Color(255, 153, 153);
private final Color MARKER_DEFAULT_COLOR = new Color(153, 255, 153);
private final String DEFAULT_WARN_EXPRESSION = "level == WARN";
private final String DEFAULT_FATAL_ERROR_EXCEPTION_EXPRESSION = "level == FATAL || level == ERROR || exception exists";
private final String DEFAULT_MARKER_EXPRESSION = "prop.marker exists";
public RuleColorizer() {
List<ColorRule> rulesList = new ArrayList<>();
String expression = DEFAULT_FATAL_ERROR_EXCEPTION_EXPRESSION;
rulesList.add(
new ColorRule(
expression, ExpressionRule.getRule(expression), FATAL_OR_ERROR_DEFAULT_COLOR,
Color.black));
expression = DEFAULT_WARN_EXPRESSION;
rulesList.add(
new ColorRule(
expression, ExpressionRule.getRule(expression), WARN_DEFAULT_COLOR,
Color.black));
expression = DEFAULT_MARKER_EXPRESSION;
rulesList.add(
new ColorRule(
expression, ExpressionRule.getRule(expression), MARKER_DEFAULT_COLOR,
Color.black));
defaultRules.put(currentRuleSet, rulesList);
setRules(defaultRules);
}
public void setLoggerRule(Rule loggerRule) {
this.loggerRule = loggerRule;
colorChangeSupport.firePropertyChange("colorrule", false, true);
}
public void setFindRule(Rule findRule) {
this.findRule = findRule;
colorChangeSupport.firePropertyChange("colorrule", false, true);
}
public Rule getFindRule() {
return findRule;
}
public Rule getLoggerRule() {
return loggerRule;
}
public void setRules(Map<String,List<ColorRule>> rules) {
this.rules = rules;
colorChangeSupport.firePropertyChange("colorrule", false, true);
}
public Map<String,List<ColorRule>> getRules() {
return rules;
}
public List<ColorRule> getCurrentRules() {
return rules.get(currentRuleSet);
}
public void addRules(Map<String,List<ColorRule>> newRules) {
for (Map.Entry<String,List<ColorRule>> entry : newRules.entrySet()) {
if (rules.containsKey(entry.getKey())) {
rules.get(entry.getKey()).addAll( entry.getValue() );
} else {
rules.put(entry.getKey(), entry.getValue());
}
}
colorChangeSupport.firePropertyChange("colorrule", false, true);
}
public void addRule(String ruleSetName, ColorRule rule) {
if (rules.containsKey(ruleSetName)) {
rules.get(ruleSetName).add(rule);
} else {
List<ColorRule> list = new ArrayList<>();
list.add(rule);
rules.put(ruleSetName, list);
}
colorChangeSupport.firePropertyChange("colorrule", false, true);
}
public void removeRule(String ruleSetName, String expression) {
if (rules.containsKey(ruleSetName)) {
List<ColorRule> list = rules.get(ruleSetName);
for (int i = 0; i < list.size(); i++) {
ColorRule rule = list.get(i);
if (rule.getExpression().equals(expression)) {
list.remove(rule);
return;
}
}
}
}
public void setCurrentRuleSet(String ruleSetName) {
currentRuleSet = ruleSetName;
}
public Color getBackgroundColor(ChainsawLoggingEvent event) {
if (rules.containsKey(currentRuleSet)) {
List<ColorRule> list = rules.get(currentRuleSet);
for (ColorRule rule : list) {
if ((rule.getBackgroundColor() != null) && (rule.evaluate(event, null))) {
return rule.getBackgroundColor();
}
}
}
return null;
}
public Color getForegroundColor(ChainsawLoggingEvent event) {
if (rules.containsKey(currentRuleSet)) {
List<ColorRule> list = rules.get(currentRuleSet);
for (ColorRule rule : list) {
if ((rule.getForegroundColor() != null) && (rule.evaluate(event, null))) {
return rule.getForegroundColor();
}
}
}
return null;
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
colorChangeSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
colorChangeSupport.removePropertyChangeListener(listener);
}
/**
* @param propertyName
* @param listener
*/
public void addPropertyChangeListener(
String propertyName, PropertyChangeListener listener) {
colorChangeSupport.addPropertyChangeListener(propertyName, listener);
}
/**
* Save panel color settings
*/
public void saveColorSettings(String name) {
ObjectOutputStream o = null;
try {
File f = new File(SettingsManager.getInstance().getSettingsDirectory(), URLEncoder.encode(name + COLORS_EXTENSION));
o = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(f)));
o.writeObject(getRules());
o.flush();
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
try {
if (o != null) {
o.close();
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
/**
* Load panel color settings if they exist from the given configuration - otherwise, load default color settings
*/
public void loadColorSettings(String name){}
public void loadColorSettings(AbstractConfiguration configuration) {
// When we save/load the rule, we really need to load a map of rules
// There's no real good way to do this, so we will do this the somewhat
// dumb way and just load up to 32 color rules, since that seems like
// a good number
// This needs to be done for each rule set, so we first need to get a
// list of the rule sets
String[] ruleSets = configuration.getStringArray( "color.rulesets" );
if( ruleSets.length == 0 ){
// Default rule set is already defined
return;
}
/*
ColorRule(final String expression,
final Rule rule,
final Color backgroundColor,
final Color foregroundColor)
*/
// Map<String,List<ColorRule>> rules = new HashMap<>();
// for( String ruleSet : ruleSets ){
// String[] rulesForRuleSet = configuration.getStringArray( "color.rules." + ruleSet );
// for( String individualRule : rulesForRuleSet ){
//
// }
// }
//
// setRules(rules);
}
private boolean doLoadColorSettings(String name) {
//first attempt to load encoded file
File f = new File(SettingsManager.getInstance().getSettingsDirectory(), URLEncoder.encode(name) + COLORS_EXTENSION);
if (f.exists()) {
ObjectInputStream s = null;
try {
s = new ObjectInputStream(
new BufferedInputStream(new FileInputStream(f)));
Map map = (Map) s.readObject();
setRules(map);
} catch (EOFException eof) { //end of file - ignore..
} catch (IOException ioe) {
ioe.printStackTrace();
//unable to load file - delete it
f.delete();
} catch (ClassNotFoundException cnfe) {
cnfe.printStackTrace();
} finally {
if (s != null) {
try {
s.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
}
return f.exists();
}
public Vector getDefaultColors() {
Vector vec = new Vector();
vec.add(Color.white);
vec.add(Color.black);
//add default alternating color & search backgrounds (both foreground are black)
vec.add(ChainsawConstants.COLOR_ODD_ROW_BACKGROUND);
vec.add(ChainsawConstants.FIND_LOGGER_BACKGROUND);
vec.add(new Color(255, 255, 225));
vec.add(new Color(255, 225, 255));
vec.add(new Color(225, 255, 255));
vec.add(new Color(255, 225, 225));
vec.add(new Color(225, 255, 225));
vec.add(new Color(225, 225, 255));
vec.add(new Color(225, 225, 183));
vec.add(new Color(225, 183, 225));
vec.add(new Color(183, 225, 225));
vec.add(new Color(183, 225, 183));
vec.add(new Color(183, 183, 225));
vec.add(new Color(232, 201, 169));
vec.add(new Color(255, 255, 153));
vec.add(new Color(255, 153, 153));
vec.add(new Color(189, 156, 89));
vec.add(new Color(255, 102, 102));
vec.add(new Color(255, 177, 61));
vec.add(new Color(61, 255, 61));
vec.add(new Color(153, 153, 255));
vec.add(new Color(255, 153, 255));
return vec;
}
}