/**
* LOGBack: the generic, reliable, fast and flexible logging framework.
*
* Copyright (C) 1999-2006, QOS.ch
*
* This library is free software, you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation.
*/
package ch.qos.logback.core.joran.spi;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import ch.qos.logback.core.Context;
import ch.qos.logback.core.joran.action.Action;
import ch.qos.logback.core.spi.ContextAwareBase;
import ch.qos.logback.core.util.OptionHelper;
public class SimpleRuleStore extends ContextAwareBase implements RuleStore {
// key: Pattern instance, value: ArrayList containing actions
HashMap<Pattern, List<Action>> rules = new HashMap<Pattern, List<Action>>();
// public SimpleRuleStore() {
// }
public SimpleRuleStore(Context context) {
setContext(context);
}
/**
* Add a new rule, i.e. a pattern, action pair to the rule store.
* <p>
* Note that the added action's LoggerRepository will be set in the
* process.
*/
public void addRule(Pattern pattern, Action action) {
action.setContext(context);
List<Action> a4p = rules.get(pattern);
if (a4p == null) {
a4p = new ArrayList<Action>();
rules.put(pattern, a4p);
}
a4p.add(action);
}
public void addRule(Pattern pattern, String actionClassName) {
Action action = null;
try {
action = (Action) OptionHelper.instantiateByClassName(
actionClassName, Action.class);
} catch(Exception e) {
addError("Could not instantiate class ["+actionClassName+"]", e);
}
if(action != null) {
addRule(pattern, action);
}
}
// exact match has highest priority
// if no exact match, check for tail match, i.e matches of type */x/y
// tail match for */x/y has higher priority than match for */x
// if no tail match, check for prefix match, i.e. matches for x/*
// match for x/y/* has higher priority than matches for x/*
public List matchActions(Pattern currentPattern) {
//System.out.println("pattern to search for:" + pattern + ", hashcode: " + pattern.hashCode());
//System.out.println("rules:" + rules);
List actionList;
if ((actionList = rules.get(currentPattern)) != null) {
return actionList;
} else if ( (actionList = tailMatch(currentPattern)) != null){
return actionList;
} else if ((actionList = prefixMatch(currentPattern)) != null) {
//System.out.println(currentPattern + " prefixMatches "+actionList);
return actionList;
} else {
return null;
}
}
List tailMatch(Pattern currentPattern) {
int max = 0;
Pattern longestMatchingPattern = null;
for (Pattern p: rules.keySet()) {
if ((p.size() > 1) && p.get(0).equals("*")) {
int r = currentPattern.getTailMatchLength(p);
//System.out.println("tailMatch " +r);
if (r > max) {
//System.out.println("New longest tailMatch "+p);
max = r;
longestMatchingPattern = p;
}
}
}
if (longestMatchingPattern != null) {
return rules.get(longestMatchingPattern);
} else {
return null;
}
}
List prefixMatch(Pattern currentPattern) {
int max = 0;
Pattern longestMatchingPattern = null;
for (Pattern p: rules.keySet()) {
String last = p.peekLast();
if("*".equals(last)) {
int r = currentPattern.getPrefixMatchLength(p);
//System.out.println("r = "+ r + ", p= "+p);
// to qualify the match length must equal p's size omitting the '*'
if ((r == p.size()-1) && (r > max)) {
//System.out.println("New longest prefixMatch "+p);
max = r;
longestMatchingPattern = p;
}
}
}
if (longestMatchingPattern != null) {
//System.out.println("prefixMatch will return" +rules.get(longestMatchingPattern));
return rules.get(longestMatchingPattern);
} else {
return null;
}
}
public String toString() {
final String TAB = " ";
StringBuilder retValue = new StringBuilder();
retValue.append("SimpleRuleStore ( ")
.append("rules = ").append(this.rules).append(TAB)
.append(" )");
return retValue.toString();
}
}