1 /** 2 * Logback: the generic, reliable, fast and flexible logging framework. 3 * 4 * Copyright (C) 2000-2009, QOS.ch 5 * 6 * This library is free software, you can redistribute it and/or modify it under 7 * the terms of the GNU Lesser General Public License as published by the Free 8 * Software Foundation. 9 */ 10 package ch.qos.logback.core.joran.spi; 11 12 import java.util.ArrayList; 13 import java.util.HashMap; 14 import java.util.List; 15 16 import ch.qos.logback.core.Context; 17 import ch.qos.logback.core.joran.action.Action; 18 import ch.qos.logback.core.spi.ContextAwareBase; 19 import ch.qos.logback.core.util.OptionHelper; 20 21 /** 22 * This class implements the {@link RuleStore} interface. It is the rule store 23 * implementation used by default in Joran. 24 * 25 * @author Ceki Gülcü 26 * 27 */ 28 public class SimpleRuleStore extends ContextAwareBase implements RuleStore { 29 30 // key: Pattern instance, value: ArrayList containing actions 31 HashMap<Pattern, List<Action>> rules = new HashMap<Pattern, List<Action>>(); 32 33 // public SimpleRuleStore() { 34 // } 35 36 public SimpleRuleStore(Context context) { 37 setContext(context); 38 } 39 40 /** 41 * Add a new rule, i.e. a pattern, action pair to the rule store. <p> Note 42 * that the added action's LoggerRepository will be set in the process. 43 */ 44 public void addRule(Pattern pattern, Action action) { 45 action.setContext(context); 46 47 List<Action> a4p = rules.get(pattern); 48 49 if (a4p == null) { 50 a4p = new ArrayList<Action>(); 51 rules.put(pattern, a4p); 52 } 53 54 a4p.add(action); 55 } 56 57 public void addRule(Pattern pattern, String actionClassName) { 58 Action action = null; 59 60 try { 61 action = (Action) OptionHelper.instantiateByClassName(actionClassName, 62 Action.class, context); 63 } catch (Exception e) { 64 addError("Could not instantiate class [" + actionClassName + "]", e); 65 } 66 if (action != null) { 67 addRule(pattern, action); 68 } 69 } 70 71 // exact match has highest priority 72 // if no exact match, check for tail match, i.e matches of type */x/y 73 // tail match for */x/y has higher priority than match for */x 74 // if no tail match, check for prefix match, i.e. matches for x/* 75 // match for x/y/* has higher priority than matches for x/* 76 77 public List matchActions(Pattern currentPattern) { 78 List actionList; 79 80 if ((actionList = rules.get(currentPattern)) != null) { 81 return actionList; 82 } else if ((actionList = tailMatch(currentPattern)) != null) { 83 return actionList; 84 } else if ((actionList = prefixMatch(currentPattern)) != null) { 85 // System.out.println(currentPattern + " prefixMatches "+actionList); 86 return actionList; 87 } else { 88 return null; 89 } 90 } 91 92 List tailMatch(Pattern currentPattern) { 93 int max = 0; 94 Pattern longestMatchingPattern = null; 95 96 for (Pattern p : rules.keySet()) { 97 98 if ((p.size() > 1) && p.get(0).equals("*")) { 99 int r = currentPattern.getTailMatchLength(p); 100 101 // System.out.println("tailMatch " +r); 102 if (r > max) { 103 // System.out.println("New longest tailMatch "+p); 104 max = r; 105 longestMatchingPattern = p; 106 } 107 } 108 } 109 110 if (longestMatchingPattern != null) { 111 return rules.get(longestMatchingPattern); 112 } else { 113 return null; 114 } 115 } 116 117 List prefixMatch(Pattern currentPattern) { 118 int max = 0; 119 Pattern longestMatchingPattern = null; 120 121 for (Pattern p : rules.keySet()) { 122 String last = p.peekLast(); 123 if ("*".equals(last)) { 124 int r = currentPattern.getPrefixMatchLength(p); 125 126 // System.out.println("r = "+ r + ", p= "+p); 127 128 // to qualify the match length must equal p's size omitting the '*' 129 if ((r == p.size() - 1) && (r > max)) { 130 // System.out.println("New longest prefixMatch "+p); 131 max = r; 132 longestMatchingPattern = p; 133 } 134 } 135 } 136 137 if (longestMatchingPattern != null) { 138 // System.out.println("prefixMatch will return" 139 // +rules.get(longestMatchingPattern)); 140 return rules.get(longestMatchingPattern); 141 } else { 142 return null; 143 } 144 } 145 146 public String toString() { 147 final String TAB = " "; 148 149 StringBuilder retValue = new StringBuilder(); 150 151 retValue.append("SimpleRuleStore ( ").append("rules = ").append(this.rules) 152 .append(TAB).append(" )"); 153 154 return retValue.toString(); 155 } 156 157 }