KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > protomatter > syslog > PerChannelPolicy


1 package com.protomatter.syslog;
2
3 /**
4  * {{{ The Protomatter Software License, Version 1.0
5  * derived from The Apache Software License, Version 1.1
6  *
7  * Copyright (c) 1998-2002 Nate Sammons. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution,
22  * if any, must include the following acknowledgment:
23  * "This product includes software developed for the
24  * Protomatter Software Project
25  * (http://protomatter.sourceforge.net/)."
26  * Alternately, this acknowledgment may appear in the software itself,
27  * if and wherever such third-party acknowledgments normally appear.
28  *
29  * 4. The names "Protomatter" and "Protomatter Software Project" must
30  * not be used to endorse or promote products derived from this
31  * software without prior written permission. For written
32  * permission, please contact support@protomatter.com.
33  *
34  * 5. Products derived from this software may not be called "Protomatter",
35  * nor may "Protomatter" appear in their name, without prior written
36  * permission of the Protomatter Software Project
37  * (support@protomatter.com).
38  *
39  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
40  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
41  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
42  * DISCLAIMED. IN NO EVENT SHALL THE PROTOMATTER SOFTWARE PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
45  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
46  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
47  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
48  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
49  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE. }}}
51  */

52
53 import java.util.*;
54 import java.text.MessageFormat JavaDoc;
55 import org.apache.oro.text.regex.*;
56
57 /**
58  * A policy that can make decision on a per-channel basis.
59  * It maintains a default log mask and channel list
60  * itself, but also has a list of "policy groups" that
61  * each have a log mask and channel list of their own
62  * in addition to a list of channel names that their
63  * mask and channel list applies to. If a message
64  * coming from a channel in one of those lists matches
65  * the mask and channel list, the message is logged. If
66  * not, but the message severity and channel match the
67  * default mask and channel list, it is also logged.
68  * Otherwise, the message is ignored.<P>
69  *
70  * This policy can be used to effectively say that
71  * messages from channels <TT>A</TT> and <TT>B</TT> should be logged
72  * if their severity is <TT>WARNING</TT> or greater, and that
73  * messages from channels <TT>C</TT> and <TT>D</TT> should be logged
74  * if their severity is <TT>INFO</TT> or greater and on a certain
75  * set of channels and that if all else fails, messages at
76  * or above the <TT>INFO</TT> level will be logged. It's
77  * very configurable.<P>
78  *
79  * Each "channel name" is actually a Perl5 regular expression,
80  * so you can match things like "<tt>com.protomatter.syslog.*</tt>"
81  * and other stuff. This functionality uses the
82  * <a HREF="http://jakarta.apache.org/oro/index.html">ORO regular expression package</a>,
83  * now part of the
84  * <a HREF="http://jakarta.apache.org">Apache Jakarta</a> project.<P>
85  *
86  * @see com.protomatter.syslog.xml.PerChannelPolicy_Helper XML configuration class
87  */

88 public class PerChannelPolicy
89 extends SimpleLogPolicy
90 {
91   private List groupList = new ArrayList();
92   private static Perl5Compiler patternCompiler = new Perl5Compiler();
93
94   /**
95    * Default constructor.
96    */

97   public PerChannelPolicy()
98   {
99     super();
100     removeAllChannels();
101     setLogMask(0);
102   }
103
104   /**
105    * Get the list of policy groups.
106    */

107   public List getGroupList()
108   {
109     return this.groupList;
110   }
111   /**
112    * Set the list of policy groups.
113    */

114   public void setGroupList(List list)
115   {
116     this.groupList = list;
117   }
118
119   /**
120    * Decide if the message should be logged. Each
121    * policy group is asked if it should be logged,
122    * and if none of them say yes, then we defer
123    * to our superclass. Each policy group maintains
124    * a channel list, log mask and a set of channel names
125    * -- to decide if it should log the message,
126    * the policy group first checks the message's
127    * severity and channel against its log mask
128    * and channel list. If it passes this test,
129    * the policy group checks to see if the
130    * channel name of the logger is in it's list.
131    */

132   public boolean shouldLog(SyslogMessage message)
133   {
134     // if any of the policy groups say yes, let it through
135
if (message.channel != null)
136     {
137       int size = groupList.size();
138       PolicyGroup group = null;
139       for (int i=0; i<size; i++)
140       {
141         group = (PolicyGroup)groupList.get(i);
142         if (group.shouldLog(message))
143           return true;
144       }
145     }
146
147     return false;
148   }
149
150   /**
151    * Get the list of policy groups.
152    */

153   public Iterator getPolicyGroups()
154   {
155     return this.groupList.iterator();
156   }
157
158   /**
159    * Add a policy group to our list.
160    */

161   public void addPolicyGroup(PolicyGroup group)
162   {
163     this.groupList.add(group);
164   }
165
166   /**
167    * Remove a policy group from our list.
168    */

169   public void removePolicyGroup(PolicyGroup group)
170   {
171     this.groupList.remove(group);
172   }
173
174   /**
175    * A policy within a policy -- this is exactly like
176    * the SimpleLogPolicy except that it also checks to
177    * see if the channel issuing the log message is
178    * in some set.
179    *
180    * @see PerChannelPolicy
181    */

182   public static class PolicyGroup
183   extends SimpleLogPolicy
184   {
185     private Set patternSet = new HashSet();
186     private Set channelNameSet = new HashSet();
187     private Pattern pattern = null;
188     private Object JavaDoc lock = new Object JavaDoc();
189     private Perl5Matcher patternMatcher = new Perl5Matcher();
190
191     /**
192      * Default constructor.
193      */

194     public PolicyGroup()
195     {
196       super();
197       removeAllChannels();
198       setLogMask(Syslog.DEBUG);
199     }
200
201     /**
202      * Get the set of channel names (exact matches) we're listing to.
203      */

204     public Iterator getChannelSet()
205     {
206       return this.channelNameSet.iterator();
207     }
208
209     /**
210      * Clear out the set of channel names
211      * we're listing to.
212      */

213     public void clearChannelSet()
214     {
215       this.channelNameSet = new HashSet();
216     }
217
218     /**
219      * Add a channelname to the set of channel names
220      * we're listening to.
221      */

222     public void addChannelName(String JavaDoc channelname)
223     {
224       this.channelNameSet.add(channelname);
225     }
226
227     /**
228      * Remove a channel name from the set of
229      * channel names we're listening to.
230      */

231     public void removeChannelName(String JavaDoc channelname)
232     {
233       this.channelNameSet.remove(channelname);
234     }
235
236     /**
237      * Get the set of channel patterns we're listing to.
238      */

239     public Iterator getPatternSet()
240     {
241       return this.patternSet.iterator();
242     }
243
244     /**
245      * Clear out the set of channel name patterns
246      * we're listing to.
247      */

248     public void clearPatternSet()
249     {
250       this.patternSet = new HashSet();
251       this.pattern = null;
252     }
253
254     /**
255      * Add a channelname to the set of channel name
256      * patterns we're listening to.
257      */

258     public void addChannelPattern(String JavaDoc channelname)
259     {
260       this.patternSet.add(channelname);
261       generatePattern();
262     }
263
264     /**
265      * Remove a channel name pattern from the set of
266      * channel name patterns we're listening to.
267      */

268     public void removeChannelPattern(String JavaDoc channelname)
269     {
270       this.patternSet.remove(channelname);
271       generatePattern();
272     }
273
274     /**
275      * Recompile the pattern each time something
276      * about the set of patterns changes.
277      */

278     private void generatePattern()
279     throws IllegalArgumentException JavaDoc
280     {
281       StringBuffer JavaDoc thePattern = new StringBuffer JavaDoc();
282       try
283       {
284         Iterator patterns = getPatternSet();
285         while (patterns.hasNext())
286         {
287           thePattern.append(patterns.next());
288           if (patterns.hasNext())
289             thePattern.append("|");
290         }
291         pattern = patternCompiler.compile(thePattern.toString());
292       }
293       catch (MalformedPatternException x)
294       {
295         throw new IllegalArgumentException JavaDoc(
296           MessageFormat.format(Syslog.getResources().getString(MessageConstants.INVALID_PATTERN_MESSAGE),
297           new Object JavaDoc[] { thePattern }));
298       }
299     }
300
301     /**
302      * Determine if the given message should be
303      * logged. The message severity and channel
304      * are first checked by our superclass, then
305      * we see if the logger channel name is in our
306      * set.
307      */

308     public boolean shouldLog(SyslogMessage m)
309     {
310       // passes the level test.
311
if (inMask(m.level, getLogMask()))
312       {
313         // exact matches...
314
if (channelNameSet.contains(m.channel))
315         {
316           return true;
317         }
318         else if (pattern != null) // pattern matches
319
{
320           synchronized (lock)
321           {
322             if (patternMatcher.contains(m.channel, pattern))
323             {
324               return true;
325             }
326           }
327         }
328       }
329
330       // if it's not in our list, we don't care about it.
331
return false;
332     }
333   }
334 }
335
Popular Tags