View Javadoc

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 }