JDK14PerClassPolicy.java :  » Development » protomatter » com » protomatter » syslog » Java Open Source

Java Open Source » Development » protomatter 
protomatter » com » protomatter » syslog » JDK14PerClassPolicy.java
package com.protomatter.syslog;

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

import java.util.*;
import java.util.regex.*;
import java.text.MessageFormat;

/**
 *  A policy that can make decision on a per-class basis.
 *  It maintains a default log mask and channel list
 *  itself, but also has a list of "policy groups" that
 *  each have a log mask and channel list of their own
 *  in addition to a list of class names that their
 *  mask and channel list applies to.  If a message
 *  coming from a class in one of those lists matches
 *  the mask and channel list, the message is logged. If
 *  not, but the message severity and channel match the
 *  default mask and channel list, it is also logged.
 *  Otherwise, the message is ignored.<P>
 *
 *  This policy can be used to effectively say that
 *  messages from classes <TT>A</TT> and <TT>B</TT> should be logged
 *  if their severity is <TT>WARNING</TT> or greater, and that
 *  messages from classes <TT>C</TT> and <TT>D</TT> should be logged
 *  if their severity is <TT>INFO</TT> or greater and on a certain
 *  set of channels and that if all else fails, messages at
 *  or above the <TT>INFO</TT> level will be logged.  It's
 *  very configurable.<P>
 *
 *  Each "class name" is actually a regular expression,
 *  so you can match things like "<tt>com.protomatter.syslog.*</tt>"
 *  and other stuff.  This functionality uses the
 *  <TT>java.util.regex</TT> package from JDK 1.4.
 *
 *  @see com.protomatter.syslog.xml.JDK14PerClassPolicy_Helper XML configuration class
 */
public class JDK14PerClassPolicy
extends SimpleLogPolicy
{
  private List groupList = new ArrayList();

  /**
   *  Default constructor.
   */
  public JDK14PerClassPolicy()
  {
    super();
  }

  /**
   *  Get the list of policy groups.
   */
  public List getGroupList()
  {
    return this.groupList;
  }
  /**
   *  Set the list of policy groups.
   */
  public void setGroupList(List list)
  {
    this.groupList = list;
  }

  /**
   *  Decide if the message should be logged.  Each
   *  policy group is asked if it should be logged,
   *  and if none of them say yes, then we defer
   *  to our superclass.  Each policy group maintains
   *  a channel list, log mask and a set of class names
   *  -- to decide if it should log the message,
   *  the policy group first checks the message's
   *  severity and channel against its log mask
   *  and channel list.  If it passes this test,
   *  the policy group checks to see if the
   *  class name of the caller is in it's list.
   */
  public boolean shouldLog(SyslogMessage message)
  {
    // if any of the policy groups say yes, let it through
    if (message.loggerClassname != null)
    {
      int size = groupList.size();
      PolicyGroup group = null;
      for (int i=0; i<size; i++)
      {
        group = (PolicyGroup)groupList.get(i);
        if (group.shouldLog(message))
          return true;
      }
    }

    // otherwise, defer to the superclass, which
    // knows about channels and log masks.
    return super.shouldLog(message);
  }

  /**
   *  Get the list of policy groups.
   */
  public Iterator getPolicyGroups()
  {
    return this.groupList.iterator();
  }

  /**
   *  Add a policy group to our list.
   */
  public void addPolicyGroup(PolicyGroup group)
  {
    this.groupList.add(group);
  }

  /**
   *  Remove a policy group from our list.
   */
  public void removePolicyGroup(PolicyGroup group)
  {
    this.groupList.remove(group);
  }

  /**
   *  A policy within a policy -- this is exactly like
   *  the SimpleLogPolicy except that it also checks to
   *  see if the class issuing the log message is
   *  in some set.
   *
   *  @see JDK14PerClassPolicy
   */
  public static class PolicyGroup
  extends SimpleLogPolicy
  {
    private Set patternSet = new HashSet();
    private Set classNameSet = new HashSet();
    private Pattern pattern = null;

    /**
     *  Default constructor.
     */
    public PolicyGroup()
    {
      super();
    }

    /**
     *  Get the set of class names (exact matches) we're listing to.
     */
    public Iterator getClassSet()
    {
      return this.classNameSet.iterator();
    }

    /**
     *  Clear out the set of class names
     *  we're listing to.
     */
    public void clearClassSet()
    {
      this.classNameSet = new HashSet();
    }

    /**
     *  Add a classname to the set of class names
     *  we're listening to.
     */
    public void addClass(String classname)
    {
      this.classNameSet.add(classname);
    }

    /**
     *  Remove a class name from the set of
     *  class names we're listening to.
     */
    public void removeClass(String classname)
    {
      this.classNameSet.remove(classname);
    }

    /**
     *  Get the set of class patterns we're listing to.
     */
    public Iterator getPatternSet()
    {
      return this.patternSet.iterator();
    }

    /**
     *  Clear out the set of class name patterns
     *  we're listing to.
     */
    public void clearPatternSet()
    {
      this.patternSet = new HashSet();
      this.pattern = null;
    }

    /**
     *  Add a classname to the set of class name
     *  patterns we're listening to.
     */
    public void addClassPattern(String classname)
    {
      this.patternSet.add(classname);
      generatePattern();
    }

    /**
     *  Remove a class name pattern from the set of
     *  class name patterns we're listening to.
     */
    public void removeClassPattern(String classname)
    {
      this.patternSet.remove(classname);
      generatePattern();
    }

    /**
     *  Recompile the pattern each time something
     *  about the set of patterns changes.
     */
    private void generatePattern()
    throws IllegalArgumentException
    {
      StringBuffer thePattern = new StringBuffer();
      try
      {
        Iterator patterns = getPatternSet();
        while (patterns.hasNext())
        {
          thePattern.append(patterns.next());
          if (patterns.hasNext())
            thePattern.append("|");
        }
        pattern = Pattern.compile(thePattern.toString());
      }
      catch (PatternSyntaxException x)
      {
        throw new IllegalArgumentException(
          MessageFormat.format(Syslog.getResources().getString(MessageConstants.INVALID_PATTERN_MESSAGE),
          new Object[] { thePattern }));
      }
    }

    /**
     *  Determine if the given message should be
     *  logged.  The message severity and channel
     *  are first checked by our superclass, then
     *  we see if the caller class name is in our
     *  set.
     */
    public boolean shouldLog(SyslogMessage m)
    {
      // passes the channel/level test.
      if (super.shouldLog(m))
      {
        // exact matches...
        if (classNameSet.contains(m.loggerClassname))
        {
          return true;
        }
        else if (pattern != null) // pattern matches
        {
          return pattern.matcher(m.loggerClassname).matches();
        }
      }

      // if it's not in our list, we don't care about it.
      return false;
    }
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.