You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4cxx-dev@logging.apache.org by ca...@apache.org on 2005/06/01 21:23:14 UTC

cvs commit: logging-log4cxx/include/log4cxx/filter Makefile.am andfilter.h denyallfilter.h expressionfilter.h levelmatchfilter.h levelrangefilter.h locationinfofilter.h mapfilter.h propertyfilter.h reflectionfilter.h stringmatchfilter.h

carnold     2005/06/01 12:23:14

  Added:       include/log4cxx/filter Makefile.am andfilter.h
                        denyallfilter.h expressionfilter.h
                        levelmatchfilter.h levelrangefilter.h
                        locationinfofilter.h mapfilter.h propertyfilter.h
                        reflectionfilter.h stringmatchfilter.h
  Log:
  LOGCXX-52: Migrate log4j 1.3 RollingFileAppender
  
  Revision  Changes    Path
  1.1                  logging-log4cxx/include/log4cxx/filter/Makefile.am
  
  Index: Makefile.am
  ===================================================================
  filterincdir = $(includedir)/log4cxx/filter
  filterinc_HEADERS= $(top_srcdir)/include/log4cxx/filter/*.h
  
  
  
  
  1.1                  logging-log4cxx/include/log4cxx/filter/andfilter.h
  
  Index: andfilter.h
  ===================================================================
  /*
   * Copyright 1999,2004 The Apache Software Foundation.
   * 
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.log4j.filter;
  
  import org.apache.log4j.spi.Filter;
  import org.apache.log4j.spi.LoggingEvent;
  
  
  /**
   * A filter that 'and's the results of any number of contained filters together.
   * 
   * For the filter to process events, all contained filters must return Filter.ACCEPT.
   * 
   * If the contained filters do not return Filter.ACCEPT, Filter.NEUTRAL is returned.
   * 
   * If acceptOnMatch is set to true, Filter.ACCEPT is returned.
   * If acceptOnMatch is set to false, Filter.DENY is returned.
   * 
   * Here is an example config that will accept only events that contain BOTH
   * a DEBUG level AND 'test' in the message:
   * 
   *<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
   * <filter class="org.apache.log4j.filter.AndFilter">
   *  <filter class="org.apache.log4j.filter.LevelMatchFilter">
   *        <param name="levelToMatch" value="DEBUG" />
   *        <param name="acceptOnMatch" value="true" />
   *  </filter>
   *  <filter class="org.apache.log4j.filter.StringMatchFilter">
   *        <param name="stringToMatch" value="test" />
   *        <param name="acceptOnMatch" value="true" />
   *  </filter>
   *  <param name="acceptOnMatch" value="false"/>
   * </filter>
   * <filter class="org.apache.log4j.filter.DenyAllFilter"/>
   *<layout class="org.apache.log4j.SimpleLayout"/>
   *</appender>
   * 
   * To accept all events EXCEPT those events that contain a 
   * DEBUG level and 'test' in the message: 
   * change the AndFilter's acceptOnMatch param to false and remove the DenyAllFilter
   * 
   * NOTE: If you are defining a filter that is only relying on logging event content 
   * (no external or filter-managed state), you could opt instead
   * to use an ExpressionFilter with one of the following expressions:
   * 
   * LEVEL == DEBUG && MSG ~= 'test'
   * or
   * ! ( LEVEL == DEBUG && MSG ~= 'test' )
   *  
   * @author Scott Deboy sdeboy@apache.org
   */
  public class AndFilter extends Filter {
    Filter headFilter = null;
    Filter tailFilter = null;
    boolean acceptOnMatch = true;
    
    public void activateOptions() {
    }
  
    public void addFilter(Filter filter) {
      System.out.println("add"+filter);
      if (headFilter == null) {
        headFilter = filter;
        tailFilter = filter;
      } else {
        tailFilter.setNext(filter);
      }
    }
    
    public void setAcceptOnMatch(boolean acceptOnMatch) {
      this.acceptOnMatch = acceptOnMatch;
    }
    /**
     * If this event does not already contain location information, 
     * evaluate the event against the expression.
     * 
     * If the expression evaluates to true, generate a LocationInfo instance 
     * by creating an exception and set this LocationInfo on the event.
     * 
     * Returns {@link Filter#NEUTRAL}
     */
    public int decide(LoggingEvent event) {
      boolean accepted = true;
      Filter f = headFilter;
      while (f != null) {
        accepted = accepted && (Filter.ACCEPT == f.decide(event));
        f = f.getNext();
      }
      if (accepted) {
        if(acceptOnMatch) {
          return Filter.ACCEPT;
        }
         return Filter.DENY;
      }
      return Filter.NEUTRAL;
    }
  }
  
  
  
  1.1                  logging-log4cxx/include/log4cxx/filter/denyallfilter.h
  
  Index: denyallfilter.h
  ===================================================================
  /*
   * Copyright 2003,2004 The Apache Software Foundation.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  #ifndef _LOG4CXX_FILTER_DENY_ALL_FILTER_H
  #define _LOG4CXX_FILTER_DENY_ALL_FILTER_H
  
  #include <log4cxx/spi/filter.h>
  
  namespace log4cxx
  {
          namespace filter
          {
                  /**
                  This filter drops all logging events.
                  <p>You can add this filter to the end of a filter chain to
                  switch from the default "accept all unless instructed otherwise"
                  filtering behaviour to a "deny all unless instructed otherwise"
                  behaviour.
                  */
                  class DenyAllFilter;
                  typedef helpers::ObjectPtrT<DenyAllFilter> DenyAllFilterPtr;
  
                  class LOG4CXX_EXPORT DenyAllFilter : public spi::Filter
                  {
                  public:
                          DenyAllFilter() : spi::Filter() {
                          }
  
                          typedef spi::Filter BASE_CLASS;
                          DECLARE_LOG4CXX_OBJECT(DenyAllFilter)
                          BEGIN_LOG4CXX_CAST_MAP()
                                  LOG4CXX_CAST_ENTRY(DenyAllFilter)
                                  LOG4CXX_CAST_ENTRY_CHAIN(BASE_CLASS)
                          END_LOG4CXX_CAST_MAP()
  
                          /**
                          Always returns the integer constant {@link spi::Filter#DENY DENY}
                          regardless of the {@link spi::LoggingEvent LoggingEvent} parameter.
                          @param event The LoggingEvent to filter.
                          @return Always returns {@link spi::Filter#DENY DENY}.
                          */
                          FilterDecision decide(const spi::LoggingEventPtr& event) const
                                  { return spi::Filter::DENY; }
                  }; // class DenyAllFilter
          }  // namespace filter
  } // namespace log4cxx
  
  #endif // _LOG4CXX_FILTER_DENY_ALL_FILTER_H
  
  
  
  1.1                  logging-log4cxx/include/log4cxx/filter/expressionfilter.h
  
  Index: expressionfilter.h
  ===================================================================
  /*
   * Copyright 1999,2004 The Apache Software Foundation.
   * 
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.log4j.filter;
  
  import org.apache.log4j.rule.ExpressionRule;
  import org.apache.log4j.rule.Rule;
  import org.apache.log4j.spi.Filter;
  import org.apache.log4j.spi.LoggingEvent;
  
  
  /**
   *A filter supporting complex expressions - supports both infix and postfix 
   * expressions (infix expressions must first be converted to postfix prior 
   * to processing).
   *
   * <p>See <code>org.apache.log4j.chainsaw.LoggingEventFieldResolver.java</code> 
   * for the correct names for logging event fields used when building expressions.
   *
   * <p>See <org.apache.log4j.chainsaw.rule</code> package for a list of available
   * rules which can be applied using the expression syntax.
   *
   * <p>See <code>org.apache.log4j.chainsaw.RuleFactory</code> for the symbols 
   * used to activate the corresponding rules.
   *
   *NOTE:  Grouping using parentheses is supported - all tokens must be separated by spaces, and
   *operands which contain spaces are not yet supported.
   *
   *Example:
   *
   *In order to build a filter that displays all messages with infomsg-45 or infomsg-44 in the message,
   *as well as all messages with a level of WARN or higher, build an expression using 
   *the LikeRule (supports ORO-based regular expressions) and the InequalityRule. 
   * <b> ( MSG LIKE infomsg-4[4,5] ) && ( LEVEL >= WARN ) </b>
   *  
   *Three options are required:
   *  <b>Expression</b> - the expression to match
   *  <b>ConvertInFixToPostFix</b> - convert from infix to posfix (default true)
   *  <b>AcceptOnMatch</b> - true or false (default true)
   *
   * Meaning of <b>AcceptToMatch</b>:
   * If there is a match between the value of the
   * Expression option and the {@link LoggingEvent} and AcceptOnMatch is true,
   * the {@link #decide} method returns {@link Filter#ACCEPT}.
   *
   * If there is a match between the value of the
   * Expression option and the {@link LoggingEvent} and AcceptOnMatch is false,
   * {@link Filter#DENY} is returned.
   *
   * If there is no match, {@link Filter#NEUTRAL} is returned.
   *
   * @author Scott Deboy sdeboy@apache.org
   */
  public class ExpressionFilter extends Filter {
    boolean acceptOnMatch = true;
    boolean convertInFixToPostFix = true;
    String expression;
    Rule expressionRule;
  
    public void activateOptions() {
      expressionRule =
        ExpressionRule.getRule(expression, !convertInFixToPostFix);
    }
  
    public void setExpression(String expression) {
      this.expression = expression;
    }
  
    public String getExpression() {
      return expression;
    }
  
    public void setConvertInFixToPostFix(boolean convertInFixToPostFix) {
      this.convertInFixToPostFix = convertInFixToPostFix;
    }
  
    public boolean getConvertInFixToPostFix() {
      return convertInFixToPostFix;
    }
  
    public void setAcceptOnMatch(boolean acceptOnMatch) {
      this.acceptOnMatch = acceptOnMatch;
    }
  
    public boolean getAcceptOnMatch() {
      return acceptOnMatch;
    }
  
    /**
       Returns {@link Filter#NEUTRAL} is there is no string match.
     */
    public int decide(LoggingEvent event) {
      if (expressionRule.evaluate(event)) {
        return (acceptOnMatch?Filter.ACCEPT:Filter.DENY);
      }
      return Filter.NEUTRAL;
    }
  }
  
  
  
  1.1                  logging-log4cxx/include/log4cxx/filter/levelmatchfilter.h
  
  Index: levelmatchfilter.h
  ===================================================================
  /*
   * Copyright 2003,2004 The Apache Software Foundation.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  #ifndef _LOG4CXX_FILTER_LEVEL_MATCH_FILTER_H
  #define _LOG4CXX_FILTER_LEVEL_MATCH_FILTER_H
  
  #include <log4cxx/spi/filter.h>
  #include <log4cxx/level.h>
  
  namespace log4cxx
  {
          class Level;
  
          namespace filter
          {
                  /**
                  This is a very simple filter based on level matching.
  
                  <p>The filter admits two options <b>LevelToMatch</b> and
                  <b>AcceptOnMatch</b>. If there is an exact match between the value
                  of the <b>LevelToMatch</b> option and the level of the {@link
                  spi::LoggingEvent LoggingEvent}, then the #decide method returns {@link
                  spi::Filter#ACCEPT ACCEPT} in case the <b>AcceptOnMatch</b>
                  option value is set to <code>true</code>, if it is <code>false</code>
                  then {@link spi::Filter#DENY DENY} is returned. If there is no match,
                  {@link spi::Filter#NEUTRAL NEUTRAL} is returned.
                  */
                  class LevelMatchFilter;
                  typedef helpers::ObjectPtrT<LevelMatchFilter> LevelMatchFilterPtr;
  
                  class LOG4CXX_EXPORT LevelMatchFilter : public spi::Filter
                  {
                  private:
                          bool acceptOnMatch;
                          LevelPtr levelToMatch;
  
                  public:
                          typedef spi::Filter BASE_CLASS;
                          DECLARE_LOG4CXX_OBJECT(LevelMatchFilter)
                          BEGIN_LOG4CXX_CAST_MAP()
                                  LOG4CXX_CAST_ENTRY(LevelMatchFilter)
                                  LOG4CXX_CAST_ENTRY_CHAIN(BASE_CLASS)
                          END_LOG4CXX_CAST_MAP()
  
                          LevelMatchFilter();
  
                          /**
                          Set options
                          */
                          virtual void setOption(const LogString& option,
                                  const LogString& value);
  
                          void setLevelToMatch(const LogString& levelToMatch);
  
                          const LogString& getLevelToMatch() const;
  
                          inline void setAcceptOnMatch(bool acceptOnMatch)
                                  { this->acceptOnMatch = acceptOnMatch; }
  
                          inline bool getAcceptOnMatch() const
                                  { return acceptOnMatch; }
  
                          /**
                          Return the decision of this filter.
  
                          Returns {@link spi::Filter#NEUTRAL NEUTRAL} if the
                          <b>LevelToMatch</b> option is not set or if there is not match.
                          Otherwise, if there is a match, then the returned decision is
                          {@link spi::Filter#ACCEPT ACCEPT} if the <b>AcceptOnMatch</b>
                          property is set to <code>true</code>. The returned decision is
                          {@link spi::Filter#DENY DENY} if the
                          <b>AcceptOnMatch</b> property is set to false.
                          */
                          FilterDecision decide(const spi::LoggingEventPtr& event) const;
                  }; // class LevelMatchFilter
          }  // namespace filter
  } // namespace log4cxx
  
  #endif // _LOG4CXX_FILTER_STRING_MATCH_FILTER_H
  
  
  
  1.1                  logging-log4cxx/include/log4cxx/filter/levelrangefilter.h
  
  Index: levelrangefilter.h
  ===================================================================
  /*
   * Copyright 2003,2004 The Apache Software Foundation.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  #ifndef _LOG4CXX_FILTER_LEVEL_RANGE_FILTER_H
  #define _LOG4CXX_FILTER_LEVEL_RANGE_FILTER_H
  
  #include <log4cxx/spi/filter.h>
  #include <log4cxx/level.h>
  
  namespace log4cxx
  {
          namespace filter
          {
                  /**
                  This is a very simple filter based on level matching, which can be
                  used to reject messages with priorities outside a certain range.
  
                  <p>The filter admits three options <b>LevelMin</b>, <b>LevelMax</b>
                  and <b>AcceptOnMatch</b>.
  
                  <p>If the level of the {@link spi::LoggingEvent LoggingEvent} is not
                  between Min and Max (inclusive), then {@link spi::Filter#DENY DENY}
                  is returned.
  
                  <p> If the Logging event level is within the specified range, then if
                  <b>AcceptOnMatch</b> is true, {@link spi::Filter#ACCEPT ACCEPT} is
                  returned, and if <b>AcceptOnMatch</b> is false,
                  {@link spi::Filter#NEUTRAL NEUTRAL} is returned.
  
                  <p>If <code>LevelMin</code>w is not defined, then there is no
                  minimum acceptable level (ie a level is never rejected for
                  being too "low"/unimportant).  If <code>LevelMax</code> is not
                  defined, then there is no maximum acceptable level (ie a
                  level is never rejected for beeing too "high"/important).
  
                  <p>Refer to the {@link
                  AppenderSkeleton#setThreshold setThreshold} method
                  available to <code>all</code> appenders extending
                  AppenderSkeleton for a more convenient way to
                  filter out events by level.
                  */
                  class LevelRangeFilter;
                  typedef helpers::ObjectPtrT<LevelRangeFilter> LevelRangeFilterPtr;
  
                  class LOG4CXX_EXPORT LevelRangeFilter : public spi::Filter
                  {
                  private:
                          /**
                          Do we return ACCEPT when a match occurs. Default is
                          <code>false</code>, so that later filters get run by default
                          */
                          bool acceptOnMatch;
                          LevelPtr levelMin;
                          LevelPtr levelMax;
  
                  public:
                          typedef spi::Filter BASE_CLASS;
                          DECLARE_LOG4CXX_OBJECT(LevelRangeFilter)
                          BEGIN_LOG4CXX_CAST_MAP()
                                  LOG4CXX_CAST_ENTRY(LevelRangeFilter)
                                  LOG4CXX_CAST_ENTRY_CHAIN(BASE_CLASS)
                          END_LOG4CXX_CAST_MAP()
  
                          LevelRangeFilter();
  
                          /**
                          Set options
                          */
                          virtual void setOption(const LogString& option,
                                  const LogString& value);
  
                          /**
                          Set the <code>LevelMin</code> option.
                          */
                          void setLevelMin(const LevelPtr& levelMin)
                                  { this->levelMin = levelMin; }
  
                          /**
                          Get the value of the <code>LevelMin</code> option.
                          */
                          const LevelPtr& getLevelMin() const
                                  { return levelMin; }
  
                          /**
                          Set the <code>LevelMax</code> option.
                          */
                          void setLevelMax(const LevelPtr& levelMax)
                                  { this->levelMax = levelMax; }
  
                          /**
                          Get the value of the <code>LevelMax</code> option.
                          */
                          const LevelPtr& getLevelMax() const
                                  { return levelMax; }
  
                          /**
                          Set the <code>AcceptOnMatch</code> option.
                          */
                          inline void setAcceptOnMatch(bool acceptOnMatch)
                                  { this->acceptOnMatch = acceptOnMatch; }
  
                          /**
                          Get the value of the <code>AcceptOnMatch</code> option.
                          */
                          inline bool getAcceptOnMatch() const
                                  { return acceptOnMatch; }
  
                          /**
                          Return the decision of this filter.
  
                          Returns {@link spi::Filter#NEUTRAL NEUTRAL} if the
                          <b>LevelToMatch</b> option is not set or if there is not match.
                          Otherwise, if there is a match, then the returned decision is
                          {@link spi::Filter#ACCEPT ACCEPT} if the
                          <b>AcceptOnMatch</b> property is set to <code>true</code>. The
                          returned decision is {@link spi::Filter#DENY DENY} if the
                          <b>AcceptOnMatch</b> property is set to false.
                          */
                          FilterDecision decide(const spi::LoggingEventPtr& event) const;
                  }; // class LevelMatchFilter
          }  // namespace filter
  } // namespace log4cxx
  
  #endif // _LOG4CXX_FILTER_LEVEL_RANGE_FILTER_H
  
  
  
  1.1                  logging-log4cxx/include/log4cxx/filter/locationinfofilter.h
  
  Index: locationinfofilter.h
  ===================================================================
  /*
   * Copyright 1999,2004 The Apache Software Foundation.
   * 
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.log4j.filter;
  
  import org.apache.log4j.rule.ExpressionRule;
  import org.apache.log4j.rule.Rule;
  import org.apache.log4j.spi.Filter;
  import org.apache.log4j.spi.LoggingEvent;
  import org.apache.log4j.spi.location.LocationInfo;
  
  
  /**
   * Location information is usually specified at the appender level - all events associated 
   * with an appender either create and parse stack traces or they do not.  This is
   * an expensive operation and in some cases not needed for all events associated with
   * an appender.
   * 
   * This filter creates event-level location information only if the provided expression evaluates to true.
   * 
   * For information on expression syntax, see org.apache.log4j.rule.ExpressionRule
   * 
   * @author Scott Deboy sdeboy@apache.org
   */
  public class LocationInfoFilter extends Filter {
    boolean convertInFixToPostFix = true;
    String expression;
    Rule expressionRule;
    //HACK: Category is the last of the internal layers - pass this in as the class name
    //in order for parsing to work correctly
    private String className = "org.apache.log4j.Category";
  
    public void activateOptions() {
      expressionRule =
        ExpressionRule.getRule(expression, !convertInFixToPostFix);
    }
  
    public void setExpression(String expression) {
      this.expression = expression;
    }
  
    public String getExpression() {
      return expression;
    }
  
    public void setConvertInFixToPostFix(boolean convertInFixToPostFix) {
      this.convertInFixToPostFix = convertInFixToPostFix;
    }
  
    public boolean getConvertInFixToPostFix() {
      return convertInFixToPostFix;
    }
  
    /**
     * If this event does not already contain location information, 
     * evaluate the event against the expression.
     * 
     * If the expression evaluates to true, generate a LocationInfo instance 
     * by creating an exception and set this LocationInfo on the event.
     * 
     * Returns {@link Filter#NEUTRAL}
     */
    public int decide(LoggingEvent event) {
      if (!event.locationInformationExists()) {
        if (expressionRule.evaluate(event)) {
  	      Throwable t = new Exception();
  	      event.setLocationInformation(new LocationInfo(t, className));
        }
      }
      return Filter.NEUTRAL;
    }
  }
  
  
  
  1.1                  logging-log4cxx/include/log4cxx/filter/mapfilter.h
  
  Index: mapfilter.h
  ===================================================================
  /*
   * Copyright 1999,2004 The Apache Software Foundation.
   * 
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.log4j.filter;
  
  import java.util.Hashtable;
  import java.util.Iterator;
  import java.util.Map;
  import org.apache.log4j.spi.Filter;
  import org.apache.log4j.spi.LoggingEvent;
  
  public class MapFilter extends Filter {
  
  	/**
  	 * NOTE: This filter modifies logging events by adding properties to the event.
  	 * 
  	 * The object passed in as the event message must implement java.util.Map.
     * 
     * This filter converts the event message (a Map) into properties on the event.
     * 
     * If the map holds an entry with a key of "message", the value of the entry is used
     * as the rendered message.
     * 
  	 * @since 1.3
  	 */
  	public int decide(LoggingEvent event) {
  		Map properties = event.getProperties();
  		Hashtable eventProps = null;
  		if (properties == null) {
  			eventProps = new Hashtable();
  		} else {
  			eventProps = new Hashtable(properties);
  		}
  	
  		if (event.getMessage() instanceof Map) {
  			for (Iterator iter = ((Map)event.getMessage()).entrySet().iterator();iter.hasNext();) {
          Map.Entry entry = (Map.Entry)iter.next();
  				if ("message".equalsIgnoreCase(entry.getKey().toString())) {
  					event.setRenderedMessage(entry.getValue().toString());
  				} else {
  					eventProps.put(entry.getKey(), entry.getValue());
  				}
  			}
  			event.setProperties(eventProps);
  		}
  		return Filter.NEUTRAL;
  	}
  }
  
  
  
  1.1                  logging-log4cxx/include/log4cxx/filter/propertyfilter.h
  
  Index: propertyfilter.h
  ===================================================================
  /*
   * Copyright 1999,2004 The Apache Software Foundation.
   * 
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.log4j.filter;
  
  import java.util.Hashtable;
  import java.util.Iterator;
  import java.util.Map;
  import java.util.StringTokenizer;
  
  import org.apache.log4j.spi.Filter;
  import org.apache.log4j.spi.LoggingEvent;
  
  /**
   * NOTE: This filter modifies logging events by adding properties to the event.
   * 
   * The 'properties' param is converted to event properties, which are 
   * set on every event processed by the filter.
   * 
   * Individual properties are only set if they do not already exist on the 
   * logging event (will not override existing properties).
   * 
   * This class relies on the convention that property name/value pairs are 
   * equals-symbol delimited, and each name/value pair is comma-delimited
   * 
   * Example properties param:
   * somename=somevalue,anothername=anothervalue,thirdname=third value
   * 
   * @since 1.3
   */
  public class PropertyFilter extends Filter {
  	private Hashtable properties;
  	public void setProperties(String props) {
  		properties = parseProperties(props);
  	}
  	
  	public int decide(LoggingEvent event) {
  		Map eventProps = event.getProperties();
  		if (eventProps == null) {
  			event.setProperties(new Hashtable(properties));
  		} else {
  		    //only add properties that don't already exist
  		    for (Iterator iter = properties.keySet().iterator();iter.hasNext();) {
  		        Object key = iter.next();
  		        if (!(eventProps.containsKey(key))) {
  		            eventProps.put(key, properties.get(key));
  		        }
  		    }
  		}
  		return Filter.NEUTRAL;
  	}
  	
  	private Hashtable parseProperties(String props) {
  		Hashtable hashTable = new Hashtable();
  		StringTokenizer pairs = new StringTokenizer(props, ",");
  		while (pairs.hasMoreTokens()) {
  			StringTokenizer entry = new StringTokenizer(pairs.nextToken(), "=");
  			hashTable.put(entry.nextElement().toString().trim(), entry.nextElement().toString().trim());
  		}
  		return hashTable;
  	}
  }
  
  
  
  1.1                  logging-log4cxx/include/log4cxx/filter/reflectionfilter.h
  
  Index: reflectionfilter.h
  ===================================================================
  /*
   * Copyright 1999,2004 The Apache Software Foundation.
   * 
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.log4j.filter;
  
  import java.beans.IntrospectionException;
  import java.beans.Introspector;
  import java.beans.PropertyDescriptor;
  import java.lang.reflect.InvocationTargetException;
  import java.util.Hashtable;
  import java.util.Map;
  
  import org.apache.log4j.spi.Filter;
  import org.apache.log4j.spi.LoggingEvent;
  
  public class ReflectionFilter extends Filter {
  
  	/**
  	 * NOTE: This filter modifies logging events by adding   
  	 * properties to the event.
  	 * 
  	 * The object passed in as the message must provide a message via toString 
  	 * or provide a 'message' property, which will be set as the rendered message.
  	 * 
  	 * This ReflectionFilter uses the JavaBeans BeanInfo and PropertyDescriptor mechanisms to discover 
  	 * readMethods available on the 'message' object provided by the event.
  	 *  
  	 * For each method available on the object via the BeanInfo PropertyDescriptors, the method is executed
  	 * and a property is added to the event, using the results of the method call as the value 
  	 * and the method name as the key.
  	 * 
  	 * @since 1.3
  	 */
  	public int decide(LoggingEvent event) {
  		Map properties = event.getProperties();
  		Hashtable eventProps = null;
  		if (properties == null) {
  			eventProps = new Hashtable();
  		} else {
  			eventProps = new Hashtable(properties);
  		}
  	
  		//ignore strings and the object class properties
  		if (!(event.getMessage() instanceof String)) {
  			PropertyDescriptor[] props;
  			try {
  				props = Introspector.getBeanInfo(event.getMessage().getClass(), Object.class).getPropertyDescriptors();
  				for (int i=0;i<props.length;i++) {
  					if ("message".equalsIgnoreCase(props[i].getName())) {
  						event.setRenderedMessage(props[i].getReadMethod().invoke(event.getMessage(), null).toString());
  					} else {
  						eventProps.put(props[i].getName(), props[i].getReadMethod().invoke(event.getMessage(), null).toString());
  					}
  				}
  				event.setProperties(eventProps);
  			} catch (IntrospectionException e) {
  				e.printStackTrace();
  			} catch (IllegalArgumentException e1) {
  				e1.printStackTrace();
  			} catch (IllegalAccessException e1) {
  				e1.printStackTrace();
  			} catch (InvocationTargetException e1) {
  				e1.printStackTrace();
  			}
  		}
  		return Filter.NEUTRAL;
  	}
  }
  
  
  
  1.1                  logging-log4cxx/include/log4cxx/filter/stringmatchfilter.h
  
  Index: stringmatchfilter.h
  ===================================================================
  /*
   * Copyright 2003,2004 The Apache Software Foundation.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  #ifndef _LOG4CXX_FILTER_STRING_MATCH_FILTER_H
  #define _LOG4CXX_FILTER_STRING_MATCH_FILTER_H
  
  #include <log4cxx/spi/filter.h>
  
  namespace log4cxx
  {
          namespace filter
          {
                  /**
                  This is a very simple filter based on string matching.
  
                  <p>The filter admits two options <b>StringToMatch</b> and
                  <b>AcceptOnMatch</b>. If there is a match between the value of the
                  StringToMatch option and the message of the {@link spi::LoggingEvent
                  LoggingEvent}, then the #decide method returns
                  {@link spi::Filter#ACCEPT ACCEPT} if the <b>AcceptOnMatch</b> option
                  value is true, if it is false then {@link spi::Filter#DENY DENY} is
                  returned. If there is no match, {@link spi::Filter#NEUTRAL NEUTRAL}
                  is returned.
  
                  <p>See configuration files <a
                  href="../xml/doc-files/test6.xml">test6.xml</a>, <a
                  href="../xml/doc-files/test7.xml">test7.xml</a>, <a
                  href="../xml/doc-files/test8.xml">test8.xml</a>, <a
                  href="../xml/doc-files/test9.xml">test9.xml</a>, and <a
                  href="../xml/doc-files/test10.xml">test10.xml</a> for examples of
                  seeting up a <code>StringMatchFilter</code>.
                  */
  
                  class StringMatchFilter;
                  typedef helpers::ObjectPtrT<StringMatchFilter> StringMatchFilterPtr;
  
                  class LOG4CXX_EXPORT StringMatchFilter : public spi::Filter
                  {
                  private:
                          bool acceptOnMatch;
                          LogString stringToMatch;
  
                  public:
                          typedef spi::Filter BASE_CLASS;
                          DECLARE_LOG4CXX_OBJECT(StringMatchFilter)
                          BEGIN_LOG4CXX_CAST_MAP()
                                  LOG4CXX_CAST_ENTRY(StringMatchFilter)
                                  LOG4CXX_CAST_ENTRY_CHAIN(BASE_CLASS)
                          END_LOG4CXX_CAST_MAP()
  
                          StringMatchFilter();
  
                          /**
                          Set options
                          */
                          virtual void setOption(const LogString& option,
                                  const LogString& value);
  
                          inline void setStringToMatch(const LogString& stringToMatch)
                                  { this->stringToMatch.assign(stringToMatch); }
  
                          inline const LogString& getStringToMatch() const
                                  { return stringToMatch; }
  
                          inline void setAcceptOnMatch(bool acceptOnMatch)
                                  { this->acceptOnMatch = acceptOnMatch; }
  
                          inline bool getAcceptOnMatch() const
                                  { return acceptOnMatch; }
  
                          /**
                          Returns {@link spi::Filter#NEUTRAL NEUTRAL}
                          is there is no string match.
                          */
                          FilterDecision decide(const spi::LoggingEventPtr& event) const;
                 }; // class StringMatchFilter
          }  // namespace filter
  } // namespace log4cxx
  
  #endif // _LOG4CXX_FILTER_STRING_MATCH_FILTER_H