You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-dev@logging.apache.org by sd...@apache.org on 2003/10/23 11:18:12 UTC

cvs commit: jakarta-log4j/src/java/org/apache/log4j/chainsaw/rule OrOperator.java NotEqualsRule.java ExpressionRule.java RuleFactory.java NotRule.java AndRule.java EqualsRule.java LikeRule.java InFixToPostFix.java PartialTextMatchRule.java RuleTest.java

sdeboy      2003/10/23 02:18:12

  Modified:    src/java/org/apache/log4j/chainsaw/rule RuleTest.java
  Added:       src/java/org/apache/log4j/chainsaw/rule OrOperator.java
                        NotEqualsRule.java ExpressionRule.java
                        RuleFactory.java NotRule.java AndRule.java
                        EqualsRule.java LikeRule.java InFixToPostFix.java
                        PartialTextMatchRule.java
  Log:
  initial commit of a number of rules, including expression rule, logical rules and string-based rules
  
  Revision  Changes    Path
  1.9       +10 -377   jakarta-log4j/src/java/org/apache/log4j/chainsaw/rule/RuleTest.java
  
  Index: RuleTest.java
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j/src/java/org/apache/log4j/chainsaw/rule/RuleTest.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- RuleTest.java	26 Sep 2003 06:58:34 -0000	1.8
  +++ RuleTest.java	23 Oct 2003 09:18:12 -0000	1.9
  @@ -53,14 +53,8 @@
   import java.awt.GridLayout;
   import java.awt.event.ActionEvent;
   import java.util.ArrayList;
  -import java.util.Enumeration;
  -import java.util.HashMap;
   import java.util.Iterator;
   import java.util.List;
  -import java.util.Map;
  -import java.util.Stack;
  -import java.util.StringTokenizer;
  -import java.util.Vector;
   
   import javax.swing.AbstractAction;
   import javax.swing.JButton;
  @@ -75,14 +69,10 @@
   import org.apache.log4j.Logger;
   import org.apache.log4j.chainsaw.LoggingEventFieldResolver;
   import org.apache.log4j.spi.LoggingEvent;
  -import org.apache.oro.text.regex.MalformedPatternException;
  -import org.apache.oro.text.regex.Pattern;
  -import org.apache.oro.text.regex.Perl5Compiler;
  -import org.apache.oro.text.regex.Perl5Matcher;
   
   public class RuleTest extends JFrame {
   	/**
  -	 * Simple infix/postfix conversion and evaluation...work in progress..a ui test tool to work through expression building issues.
  +	 * UI for demonstrating infix/postfix conversion and expression rule evaluation...work in progress...
   	 *
   	 * Infix to postfix conversion routines and evaluation methods for boolean expressions.
   	 * See http://www.qiksearch.com/articles/cs/infix-postfix/
  @@ -93,6 +83,7 @@
   	 * @author Scott Deboy <sd...@apache.org>
   	 *
   	 */
  +    Rule rule;
   	public RuleTest(String booleanPostFixExpression, String inFixExpression) {
   		setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
   		getContentPane().setLayout(new BorderLayout());
  @@ -156,6 +147,7 @@
   				InFixToPostFix inFixConverter = new InFixToPostFix();
   				inFixResult.setText(
   					inFixConverter.convert(inFixTextField.getText()));
  +                rule = ExpressionRule.getRule(inFixResult.getText(), true);
   			}
   		});
   
  @@ -173,7 +165,6 @@
   				results.setText("");
   
   				Iterator iter = eventList.iterator();
  -				EvaluateBooleanPostFix evaluator = new EvaluateBooleanPostFix();
   
   				while (iter.hasNext()) {
   					LoggingEvent event = (LoggingEvent) iter.next();
  @@ -185,7 +176,7 @@
   							+ ", logger: "
   							+ event.getLoggerName()
   							+ " - result: "
  -							+ evaluator.evaluate(inFixResult.getText(), event));
  +							+ rule.evaluate(event));
   				}
   			}
   		});
  @@ -194,374 +185,16 @@
   		getContentPane().add(resultsPanel, BorderLayout.CENTER);
   	}
   
  +    private void setRule(Rule rule) {
  +        this.rule = rule;
  +    }
  +    
   	public static void main(String[] args) {
   		RuleTest test =
   			new RuleTest(
  -				"level debug ~= BLAH test == || logger logger1 == && ",
  -				"( ( level ~= debug ) || ( BLAH == test ) ) && logger  == logger1");
  +				"level deb ~=  blah test ==  ||  logger logger[1-3] like && ",
  +				"( ( level ~= deb ) || ( BLAH == test ) ) && logger like logger[1-3]");
   		test.pack();
   		test.setVisible(true);
  -	}
  -
  -	boolean convertToBoolean(String param) {
  -		boolean result = false;
  -
  -		if (param == null) {
  -			return result;
  -		}
  -
  -		try {
  -			result = Boolean.valueOf(param).booleanValue();
  -			System.out.println(
  -				"convert to boolean: " + param + "..result " + result);
  -		} catch (Exception e) {
  -			e.printStackTrace();
  -
  -			return result;
  -		}
  -
  -		return result;
  -	}
  -
  -	abstract class BooleanOperator {
  -		//the evaluate method usually uses the 2nd item on the stack first
  -		abstract boolean evaluate(Stack stack);
  -	}
  -
  -	abstract class EventOperator {
  -		//the evaluate method usually uses the 2nd item on the stack first
  -		abstract boolean evaluate(Stack stack, LoggingEvent event);
  -	}
  -
  -	class AndOperator extends BooleanOperator {
  -		boolean evaluate(Stack stack) {
  -			String firstParam = stack.pop().toString();
  -			String secondParam = stack.pop().toString();
  -			System.out.println("and op " + firstParam + ".." + secondParam);
  -
  -			boolean result =
  -				(convertToBoolean(firstParam) && convertToBoolean(secondParam));
  -			System.out.println("result is " + result);
  -
  -			return result;
  -		}
  -	}
  -
  -	class NotOperator extends BooleanOperator {
  -		boolean evaluate(Stack stack) {
  -			String firstParam = stack.pop().toString();
  -			System.out.println("not op " + firstParam + ".." + firstParam);
  -
  -			boolean result = !(convertToBoolean(firstParam));
  -			System.out.println("result is " + result);
  -
  -			return result;
  -		}
  -	}
  -
  -	class OrOperator extends BooleanOperator {
  -		boolean evaluate(Stack stack) {
  -			String firstParam = stack.pop().toString();
  -			String secondParam = stack.pop().toString();
  -			System.out.println("or op " + firstParam + ".." + secondParam);
  -
  -			boolean result =
  -				(convertToBoolean(firstParam) || convertToBoolean(secondParam));
  -			System.out.println("result is " + result);
  -
  -			return result;
  -		}
  -	}
  -
  -	class LikeOperator extends EventOperator {
  -		LoggingEventFieldResolver resolver =
  -			LoggingEventFieldResolver.getInstance();
  -
  -		boolean evaluate(Stack stack, LoggingEvent event) {
  -			Pattern pattern = null;
  -			Perl5Compiler compiler = new Perl5Compiler();
  -			Perl5Matcher matcher = new Perl5Matcher();
  -
  -            String firstParam = stack.pop().toString();
  -
  -            String secondParam = resolver.getValue(stack.pop().toString(), event).toString();
  -
  -			try {
  -				pattern =
  -					compiler.compile(
  -						firstParam,
  -						Perl5Compiler.CASE_INSENSITIVE_MASK);
  -			} catch (MalformedPatternException e) {
  -			}
  -
  -			System.out.println(firstParam + " like " + secondParam);
  -
  -			boolean result =
  -				(pattern != null && matcher.matches(secondParam, pattern));
  -
  -			System.out.println("result: " + result);
  -
  -			return result;
  -		}
  -	}
  -
  -	class PartialTextMatchOperator extends EventOperator {
  -		LoggingEventFieldResolver resolver =
  -			LoggingEventFieldResolver.getInstance();
  -
  -		boolean evaluate(Stack stack, LoggingEvent event) {
  -			String firstParam = stack.pop().toString();
  -			String secondParam =
  -				resolver.getValue(stack.pop().toString(), event).toString();
  -			System.out.println(
  -				"partial text match op " + firstParam + ".." + secondParam);
  -
  -			boolean result =
  -				(((secondParam != null) && (firstParam != null))
  -					&& (secondParam
  -						.toLowerCase()
  -						.indexOf(firstParam.toLowerCase())
  -						> -1));
  -			System.out.println("result is " + result);
  -
  -			return result;
  -		}
  -	}
  -
  -	class EqualsOperator extends EventOperator {
  -		LoggingEventFieldResolver resolver =
  -			LoggingEventFieldResolver.getInstance();
  -
  -		boolean evaluate(Stack stack, LoggingEvent event) {
  -			String firstParam = stack.pop().toString();
  -			String secondParam =
  -				resolver.getValue(stack.pop().toString(), event).toString();
  -			System.out.println("equals op " + firstParam + ".." + secondParam);
  -
  -			boolean result =
  -				((secondParam != null) && secondParam.equals(firstParam));
  -			System.out.println("result is " + result);
  -
  -			return result;
  -		}
  -	}
  -
  -	class NotEqualsOperator extends EventOperator {
  -		LoggingEventFieldResolver resolver =
  -			LoggingEventFieldResolver.getInstance();
  -
  -		boolean evaluate(Stack stack, LoggingEvent event) {
  -			String firstParam = stack.pop().toString();
  -			String secondParam =
  -				resolver.getValue(stack.pop().toString(), event).toString();
  -			System.out.println(
  -				"not equals op " + firstParam + ".." + secondParam);
  -
  -			boolean result =
  -				((secondParam != null)
  -					&& !(secondParam.equalsIgnoreCase(firstParam)));
  -			System.out.println("result is " + result);
  -
  -			return result;
  -		}
  -	}
  -
  -	/**
  -	 * Evaluate a boolean postfix expression.
  -	 *
  -	 */
  -	class EvaluateBooleanPostFix {
  -		private final Map booleanOperatorMap = new HashMap();
  -		private final Map eventOperatorMap = new HashMap();
  -		private final Stack stack = new Stack();
  -		String result = null;
  -
  -		EvaluateBooleanPostFix() {
  -			booleanOperatorMap.put("&&", new AndOperator());
  -			booleanOperatorMap.put("||", new OrOperator());
  -			booleanOperatorMap.put("!", new NotOperator());
  -			eventOperatorMap.put("!=", new NotEqualsOperator());
  -			eventOperatorMap.put("==", new EqualsOperator());
  -			eventOperatorMap.put("~=", new PartialTextMatchOperator());
  -            eventOperatorMap.put("like", new LikeOperator());
  -		}
  -
  -		String evaluate(String expression, LoggingEvent event) {
  -			String result = null;
  -			Enumeration tokenizer = new StringTokenizer(expression);
  -
  -			while (tokenizer.hasMoreElements()) {
  -				//examine each token
  -				String nextToken = ((String) tokenizer.nextElement()).toLowerCase();
  -
  -				//if a symbol is found, pop 2 off the stack, evaluate and push the result 
  -				if (booleanOperatorMap.containsKey(nextToken)) {
  -					BooleanOperator op =
  -						(BooleanOperator) booleanOperatorMap.get(nextToken);
  -
  -					//the operator is responsible for popping the stack
  -					stack.push(new Boolean(op.evaluate(stack)));
  -				} else if (eventOperatorMap.containsKey(nextToken)) {
  -					EventOperator op =
  -						(EventOperator) eventOperatorMap.get(nextToken);
  -					stack.push(new Boolean(op.evaluate(stack, event)));
  -				} else {
  -					//variables or constants are pushed onto the stack
  -					stack.push(nextToken);
  -				}
  -			}
  -
  -			if (stack.size() > 0) {
  -				result = stack.pop().toString();
  -			} else {
  -				result = "ERRROR";
  -			}
  -
  -			return result;
  -		}
  -	}
  -
  -	/**
  -	 * precedence: !, &, ^, |, &&, ||
  -	 * Convert an infix expression to postfix.  Supports parentheses, ||, &&, == and ~=
  -	 *
  -	 */
  -	public class InFixToPostFix {
  -		private final Map precedenceMap = new HashMap();
  -		private final List operators = new Vector();
  -
  -		public InFixToPostFix() {
  -			//boolean operators
  -			operators.add("!");
  -			operators.add("!=");
  -			operators.add("==");
  -			operators.add("~=");
  -			operators.add("||");
  -            operators.add("&&");
  -            operators.add("like");
  -
  -			operators.add("*");
  -			operators.add("+");
  -			operators.add("-");
  -
  -			//boolean precedence
  -			precedenceMap.put("!", new Integer(3));
  -			precedenceMap.put("!=", new Integer(3));
  -			precedenceMap.put("==", new Integer(3));
  -			precedenceMap.put("~=", new Integer(3));
  -            precedenceMap.put("like", new Integer(3));
  -
  -			precedenceMap.put("||", new Integer(2));
  -			precedenceMap.put("&&", new Integer(2));
  -
  -			precedenceMap.put("-", new Integer(2));
  -			precedenceMap.put("+", new Integer(2));
  -			precedenceMap.put("*", new Integer(3));
  -		}
  -
  -		public String convert(String expression) {
  -			return infixToPostFix(new StringTokenizer(expression));
  -		}
  -
  -		boolean isOperand(String symbol) {
  -            symbol = symbol.toLowerCase();
  -			return (!operators.contains(symbol));
  -		}
  -
  -		boolean precedes(String symbol1, String symbol2) {
  -            symbol1 = symbol1.toLowerCase();
  -            symbol2 = symbol2.toLowerCase();
  -			if (!precedenceMap.keySet().contains(symbol1)) {
  -				return false;
  -			}
  -
  -			if (!precedenceMap.keySet().contains(symbol2)) {
  -				return false;
  -			}
  -
  -			int index1 = ((Integer) precedenceMap.get(symbol1)).intValue();
  -			int index2 = ((Integer) precedenceMap.get(symbol2)).intValue();
  -
  -			boolean precedesResult = (index1 < index2);
  -			System.out.println(
  -				"SYMBOL1: "
  -					+ symbol1
  -					+ "SYMBOL2: "
  -					+ symbol2
  -					+ " index1: "
  -					+ index1
  -					+ " index2: "
  -					+ index2
  -					+ " precedesresult: "
  -					+ precedesResult);
  -
  -			return precedesResult;
  -		}
  -
  -		String infixToPostFix(StringTokenizer tokenizer) {
  -			String SPACE = " ";
  -			StringBuffer postfix = new StringBuffer();
  -
  -			Stack stack = new Stack();
  -			while (tokenizer.hasMoreTokens()) {
  -				String token = tokenizer.nextToken().toLowerCase();
  -				System.out.println("FOUND TOKEN " + token);
  -
  -				if ("(".equals(token)) {
  -					//recurse
  -					postfix.append(infixToPostFix(tokenizer));
  -					postfix.append(SPACE);
  -				} else if (")".equals(token)) {
  -					//exit recursion level
  -					while (stack.size() > 0) {
  -						postfix.append(stack.pop().toString());
  -						postfix.append(SPACE);
  -					}
  -
  -					return postfix.toString();
  -				} else if (isOperand(token)) {
  -					postfix.append(token);
  -					postfix.append(SPACE);
  -				} else {
  -					//operator..
  -					//peek the stack..if the top element has a lower precedence than token
  -					//(peeked + has lower precedence than token *), push token onto the stack
  -					//otherwise, pop top element off stack and add to postfix string
  -					//in a loop until lower precedence or empty..then push token
  -					if (stack.size() > 0) {
  -                        System.out.println("OPERATOR " + token + "..stack: " + stack);
  -						String peek = stack.peek().toString();
  -
  -						if (precedes(peek, token)) {
  -							stack.push(token);
  -						} else {
  -							boolean bypass = false;
  -
  -							do {
  -								if ((stack.size() > 0)
  -									&& !precedes(stack.peek().toString(),
  -										token)) {
  -									postfix.append(stack.pop().toString());
  -									postfix.append(SPACE);
  -								} else {
  -									bypass = true;
  -								}
  -							} while (!bypass);
  -
  -							stack.push(token);
  -						}
  -					} else {
  -						stack.push(token);
  -					}
  -				}
  -			}
  -
  -			while (stack.size() > 0) {
  -				postfix.append(stack.pop().toString());
  -				postfix.append(SPACE);
  -			}
  -
  -			return postfix.toString();
  -		}
   	}
   }
  
  
  
  1.1                  jakarta-log4j/src/java/org/apache/log4j/chainsaw/rule/OrOperator.java
  
  Index: OrOperator.java
  ===================================================================
  /*
   * ============================================================================
   *                   The Apache Software License, Version 1.1
   * ============================================================================
   *
   *    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without modifica-
   * tion, 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  by the  Apache Software Foundation  (http://www.apache.org/)."
   *    Alternately, this  acknowledgment may  appear in the software itself,  if
   *    and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "log4j" and  "Apache Software Foundation"  must not be used to
   *    endorse  or promote  products derived  from this  software without  prior
   *    written permission. For written permission, please contact
   *    apache@apache.org.
   *
   * 5. Products  derived from this software may not  be called "Apache", nor may
   *    "Apache" appear  in their name,  without prior written permission  of the
   *    Apache Software Foundation.
   *
   * 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
   * APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   * INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   * DING, 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.
   *
   * This software  consists of voluntary contributions made  by many individuals
   * on  behalf of the Apache Software  Foundation.  For more  information on the
   * Apache Software Foundation, please see <http://www.apache.org/>.
   *
   */
  
  package org.apache.log4j.chainsaw.rule;
  
  import org.apache.log4j.spi.LoggingEvent;
  
  import java.util.Stack;
  
  /**
   * A Rule class implementing logical or. 
   * 
   * @author Scott Deboy <sd...@apache.org>
   */
  class OrOperator extends AbstractRule {
    Rule firstParam;
    Rule secondParam;
  
    private OrOperator(Rule firstParam, Rule secondParam) {
      this.firstParam = firstParam;
      this.secondParam = secondParam;
    }
  
    static Rule getRule(Stack stack) {
      Rule p1 = (Rule) stack.pop();
      Rule p2 = (Rule) stack.pop();
      System.out.println("get or op " + p1 + ".." + p2);
  
      return new OrOperator(p1, p2);
    }
  
    public boolean evaluate(LoggingEvent event) {
      System.out.println("or op " + firstParam + ".." + secondParam);
  
      boolean result =
        (firstParam.evaluate(event) || secondParam.evaluate(event));
      System.out.println("result is " + result);
  
      return result;
    }
  }
  
  
  
  1.1                  jakarta-log4j/src/java/org/apache/log4j/chainsaw/rule/NotEqualsRule.java
  
  Index: NotEqualsRule.java
  ===================================================================
  /*
   * ============================================================================
   *                   The Apache Software License, Version 1.1
   * ============================================================================
   *
   *    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without modifica-
   * tion, 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  by the  Apache Software Foundation  (http://www.apache.org/)."
   *    Alternately, this  acknowledgment may  appear in the software itself,  if
   *    and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "log4j" and  "Apache Software Foundation"  must not be used to
   *    endorse  or promote  products derived  from this  software without  prior
   *    written permission. For written permission, please contact
   *    apache@apache.org.
   *
   * 5. Products  derived from this software may not  be called "Apache", nor may
   *    "Apache" appear  in their name,  without prior written permission  of the
   *    Apache Software Foundation.
   *
   * 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
   * APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   * INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   * DING, 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.
   *
   * This software  consists of voluntary contributions made  by many individuals
   * on  behalf of the Apache Software  Foundation.  For more  information on the
   * Apache Software Foundation, please see <http://www.apache.org/>.
   *
   */
  
  package org.apache.log4j.chainsaw.rule;
  
  import org.apache.log4j.chainsaw.LoggingEventFieldResolver;
  import org.apache.log4j.spi.LoggingEvent;
  
  import java.util.Stack;
  
  /**
   * A Rule class implementing not equals against two strings (case sensitive).
   * 
   * @author Scott Deboy <sd...@apache.org>
   */
  class NotEqualsRule extends AbstractRule {
    LoggingEventFieldResolver resolver = LoggingEventFieldResolver.getInstance();
    String firstParam;
    String secondParam;
  
    private NotEqualsRule(String firstParam, String secondParam) {
      this.firstParam = firstParam;
      this.secondParam = secondParam;
    }
  
    static Rule getRule(Stack stack) {
      String p1 = stack.pop().toString();
      String p2 = stack.pop().toString();
      System.out.println("get not equals op " + p1 + ".." + p2);
  
      return new NotEqualsRule(p1, p2);
    }
  
    public boolean evaluate(LoggingEvent event) {
      String p2 = resolver.getValue(secondParam, event).toString();
      System.out.println("not equals op " + firstParam + ".." + p2);
  
      boolean result = ((p2 != null) && !(p2.equals(firstParam)));
      System.out.println("result is " + result);
  
      return result;
    }
  }
  
  
  
  1.1                  jakarta-log4j/src/java/org/apache/log4j/chainsaw/rule/ExpressionRule.java
  
  Index: ExpressionRule.java
  ===================================================================
  /*
   * ============================================================================
   *                   The Apache Software License, Version 1.1
   * ============================================================================
   *
   *    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without modifica-
   * tion, 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  by the  Apache Software Foundation  (http://www.apache.org/)."
   *    Alternately, this  acknowledgment may  appear in the software itself,  if
   *    and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "log4j" and  "Apache Software Foundation"  must not be used to
   *    endorse  or promote  products derived  from this  software without  prior
   *    written permission. For written permission, please contact
   *    apache@apache.org.
   *
   * 5. Products  derived from this software may not  be called "Apache", nor may
   *    "Apache" appear  in their name,  without prior written permission  of the
   *    Apache Software Foundation.
   *
   * 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
   * APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   * INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   * DING, 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.
   *
   * This software  consists of voluntary contributions made  by many individuals
   * on  behalf of the Apache Software  Foundation.  For more  information on the
   * Apache Software Foundation, please see <http://www.apache.org/>.
   *
   */
  
  package org.apache.log4j.chainsaw.rule;
  
  import org.apache.log4j.spi.LoggingEvent;
  
  import java.util.Enumeration;
  import java.util.Iterator;
  import java.util.LinkedList;
  import java.util.List;
  import java.util.Stack;
  import java.util.StringTokenizer;
  
  /**
   * A Rule class supporting both infix and postfix expressions, accepting any rule which 
   * is supported by the <code>RuleFactory</code>.
   * 
   * NOTE: parsing is supported through the use of <code>StringTokenizer</code>, which means 
   * all tokens in the expression must be separated by spaces. 
   * 
   * @author Scott Deboy <sd...@apache.org>
   */
  
  public class ExpressionRule extends AbstractRule {
    private static InFixToPostFix convertor = new InFixToPostFix();
    private static PostFixExpressionCompiler compiler =
      new PostFixExpressionCompiler();
    List list = null;
    Stack stack = new Stack();
  
    private ExpressionRule(List list) {
      this.list = list;
    }
  
    static Rule getRule(String expression, boolean isPostFix) {
      if (!isPostFix) {
        expression = convertor.convert(expression);
      }
  
      return new ExpressionRule(compiler.compileExpression(expression));
    }
  
    public boolean evaluate(LoggingEvent event) {
      stack.clear();
  
      boolean result = false;
      Iterator iter = list.iterator();
  
      while (iter.hasNext()) {
        //examine each token
        Object nextItem = iter.next();
  
        //if a symbol is found, pop 2 off the stack, evaluate and push the result 
        if (nextItem instanceof Rule) {
          Rule r = (Rule) nextItem;
          stack.push(new Boolean(r.evaluate(event)));
        } else {
          //variables or constants are pushed onto the stack
          stack.push(nextItem);
        }
      }
  
      if (stack.size() > 0) {
        result = new Boolean(stack.pop().toString()).booleanValue();
      }
  
      return result;
    }
  }
  
  
  /**
   * Evaluate a boolean postfix expression.
   *
   */
  class PostFixExpressionCompiler {
  
    List compileExpression(String expression) {
      System.out.println("compiling expression: " + expression);
  
      List list = new LinkedList();
      Stack stack = new Stack();
      Enumeration tokenizer = new StringTokenizer(expression);
  
      while (tokenizer.hasMoreElements()) {
        //examine each token
        String nextToken = ((String) tokenizer.nextElement()).toLowerCase();
  
        //if a symbol is found, pop 2 off the stack, evaluate and push the result 
        if (RuleFactory.isRule(nextToken)) {
          Rule r = (Rule) RuleFactory.getRule(nextToken, stack);
          System.out.println("pushing rule " + r);
          stack.push(r);
        } else {
          System.out.println("pushing token " + nextToken);
  
          //variables or constants are pushed onto the stack
          stack.push(nextToken);
        }
      }
  
      while (!stack.isEmpty()) {
        list.add(stack.pop());
      }
  
      return list;
    }
  }
  
  
  
  1.1                  jakarta-log4j/src/java/org/apache/log4j/chainsaw/rule/RuleFactory.java
  
  Index: RuleFactory.java
  ===================================================================
  /*
   * ============================================================================
   *                   The Apache Software License, Version 1.1
   * ============================================================================
   *
   *    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without modifica-
   * tion, 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  by the  Apache Software Foundation  (http://www.apache.org/)."
   *    Alternately, this  acknowledgment may  appear in the software itself,  if
   *    and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "log4j" and  "Apache Software Foundation"  must not be used to
   *    endorse  or promote  products derived  from this  software without  prior
   *    written permission. For written permission, please contact
   *    apache@apache.org.
   *
   * 5. Products  derived from this software may not  be called "Apache", nor may
   *    "Apache" appear  in their name,  without prior written permission  of the
   *    Apache Software Foundation.
   *
   * 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
   * APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   * INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   * DING, 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.
   *
   * This software  consists of voluntary contributions made  by many individuals
   * on  behalf of the Apache Software  Foundation.  For more  information on the
   * Apache Software Foundation, please see <http://www.apache.org/>.
   *
   */
  
  package org.apache.log4j.chainsaw.rule;
  
  import java.util.Collection;
  import java.util.LinkedList;
  import java.util.Stack;
  
  /**
   * A Factory class which, given a string representation of the rule, and a context stack, will
   * return a Rule ready for evaluation against events. 
   * 
   * @author Scott Deboy <sd...@apache.org>
   */
  class RuleFactory {
    static final Collection rules = new LinkedList();
    private static final String AND_RULE = "&&";
    private static final String OR_RULE = "||";
    private static final String NOT_RULE = "!";
    private static final String NOT_EQUALS_RULE = "!=";
    private static final String EQUALS_RULE = "==";
    private static final String PARTIAL_TEXT_MATCH_RULE = "~=";
    private static final String LIKE_RULE = "like";
  
    static {
      rules.add(AND_RULE);
      rules.add(OR_RULE);
      rules.add(NOT_RULE);
      rules.add(NOT_EQUALS_RULE);
      rules.add(EQUALS_RULE);
      rules.add(PARTIAL_TEXT_MATCH_RULE);
      rules.add(LIKE_RULE);
    }
  
    static boolean isRule(String symbol) {
      return rules.contains(symbol.toLowerCase());
    }
  
    static Rule getRule(String symbol, Stack stack) {
      if (AND_RULE.equals(symbol)) {
        return AndRule.getRule(stack);
      }
  
      if (OR_RULE.equals(symbol)) {
        return OrOperator.getRule(stack);
      }
  
      if (NOT_RULE.equals(symbol)) {
        return NotRule.getRule(stack);
      }
  
      if (NOT_EQUALS_RULE.equals(symbol)) {
        return NotEqualsRule.getRule(stack);
      }
  
      if (EQUALS_RULE.equals(symbol)) {
        return EqualsRule.getRule(stack);
      }
  
      if (PARTIAL_TEXT_MATCH_RULE.equals(symbol)) {
        return PartialTextMatchRule.getRule(stack);
      }
  
      if (LIKE_RULE.equalsIgnoreCase(symbol)) {
        return LikeRule.getRule(stack);
      }
  
      return null;
    }
  }
  
  
  
  1.1                  jakarta-log4j/src/java/org/apache/log4j/chainsaw/rule/NotRule.java
  
  Index: NotRule.java
  ===================================================================
  /*
   * ============================================================================
   *                   The Apache Software License, Version 1.1
   * ============================================================================
   *
   *    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without modifica-
   * tion, 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  by the  Apache Software Foundation  (http://www.apache.org/)."
   *    Alternately, this  acknowledgment may  appear in the software itself,  if
   *    and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "log4j" and  "Apache Software Foundation"  must not be used to
   *    endorse  or promote  products derived  from this  software without  prior
   *    written permission. For written permission, please contact
   *    apache@apache.org.
   *
   * 5. Products  derived from this software may not  be called "Apache", nor may
   *    "Apache" appear  in their name,  without prior written permission  of the
   *    Apache Software Foundation.
   *
   * 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
   * APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   * INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   * DING, 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.
   *
   * This software  consists of voluntary contributions made  by many individuals
   * on  behalf of the Apache Software  Foundation.  For more  information on the
   * Apache Software Foundation, please see <http://www.apache.org/>.
   *
   */
  
  package org.apache.log4j.chainsaw.rule;
  
  import org.apache.log4j.spi.LoggingEvent;
  
  import java.util.Stack;
  
  /**
   * A Rule class implementing logical not. 
   * 
   * @author Scott Deboy <sd...@apache.org>
   */
  class NotRule extends AbstractRule {
    Rule firstParam;
  
    private NotRule(Rule firstParam) {
      this.firstParam = firstParam;
    }
  
    static Rule getRule(Stack stack) {
      Rule p1 = (Rule) stack.pop();
      System.out.println("get not op " + p1);
  
      return new NotRule(p1);
    }
  
    public boolean evaluate(LoggingEvent event) {
      System.out.println("not op " + firstParam + ".." + firstParam);
  
      boolean result = !(firstParam.evaluate(event));
      System.out.println("result is " + result);
  
      return result;
    }
  }
  
  
  
  1.1                  jakarta-log4j/src/java/org/apache/log4j/chainsaw/rule/AndRule.java
  
  Index: AndRule.java
  ===================================================================
  /*
   * ============================================================================
   *                   The Apache Software License, Version 1.1
   * ============================================================================
   *
   *    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without modifica-
   * tion, 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  by the  Apache Software Foundation  (http://www.apache.org/)."
   *    Alternately, this  acknowledgment may  appear in the software itself,  if
   *    and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "log4j" and  "Apache Software Foundation"  must not be used to
   *    endorse  or promote  products derived  from this  software without  prior
   *    written permission. For written permission, please contact
   *    apache@apache.org.
   *
   * 5. Products  derived from this software may not  be called "Apache", nor may
   *    "Apache" appear  in their name,  without prior written permission  of the
   *    Apache Software Foundation.
   *
   * 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
   * APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   * INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   * DING, 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.
   *
   * This software  consists of voluntary contributions made  by many individuals
   * on  behalf of the Apache Software  Foundation.  For more  information on the
   * Apache Software Foundation, please see <http://www.apache.org/>.
   *
   */
  
  package org.apache.log4j.chainsaw.rule;
  
  import org.apache.log4j.spi.LoggingEvent;
  
  import java.util.Stack;
  
  /**
   * A Rule class implementing a logical 'and'. 
   * 
   * @author Scott Deboy <sd...@apache.org>
   */
  class AndRule extends AbstractRule {
    Rule firstParam;
    Rule secondParam;
  
    private AndRule(Rule firstParam, Rule secondParam) {
      this.firstParam = firstParam;
      this.secondParam = secondParam;
    }
  
    static Rule getRule(Stack stack) {
      Rule p1 = (Rule) stack.pop();
      Rule p2 = (Rule) stack.pop();
      System.out.println("get and op " + p1 + ".." + p2);
  
      return new AndRule(p1, p2);
    }
  
    public boolean evaluate(LoggingEvent event) {
      System.out.println("and op " + firstParam + ".." + secondParam);
  
      boolean result =
        (firstParam.evaluate(event) && secondParam.evaluate(event));
      System.out.println("result is " + result);
  
      return result;
    }
  }
  
  
  
  1.1                  jakarta-log4j/src/java/org/apache/log4j/chainsaw/rule/EqualsRule.java
  
  Index: EqualsRule.java
  ===================================================================
  /*
   * ============================================================================
   *                   The Apache Software License, Version 1.1
   * ============================================================================
   *
   *    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without modifica-
   * tion, 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  by the  Apache Software Foundation  (http://www.apache.org/)."
   *    Alternately, this  acknowledgment may  appear in the software itself,  if
   *    and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "log4j" and  "Apache Software Foundation"  must not be used to
   *    endorse  or promote  products derived  from this  software without  prior
   *    written permission. For written permission, please contact
   *    apache@apache.org.
   *
   * 5. Products  derived from this software may not  be called "Apache", nor may
   *    "Apache" appear  in their name,  without prior written permission  of the
   *    Apache Software Foundation.
   *
   * 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
   * APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   * INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   * DING, 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.
   *
   * This software  consists of voluntary contributions made  by many individuals
   * on  behalf of the Apache Software  Foundation.  For more  information on the
   * Apache Software Foundation, please see <http://www.apache.org/>.
   *
   */
  
  package org.apache.log4j.chainsaw.rule;
  
  import org.apache.log4j.chainsaw.LoggingEventFieldResolver;
  import org.apache.log4j.spi.LoggingEvent;
  
  import java.util.Stack;
  
  /**
   * A Rule class implementing equals against two strings.  (Case-sensitive).
   * 
   * @author Scott Deboy <sd...@apache.org>
   */
  
  class EqualsRule extends AbstractRule {
    LoggingEventFieldResolver resolver = LoggingEventFieldResolver.getInstance();
    String firstParam;
    String secondParam;
  
    private EqualsRule(String firstParam, String secondParam) {
      this.firstParam = firstParam;
      this.secondParam = secondParam;
    }
  
    static Rule getRule(Stack stack) {
      String p1 = stack.pop().toString();
      String p2 = stack.pop().toString();
      System.out.println("get equals op " + p1 + ".." + p2);
  
      return new EqualsRule(p1, p2);
    }
  
    public boolean evaluate(LoggingEvent event) {
      String p2 = resolver.getValue(secondParam, event).toString();
      System.out.println("equals op " + firstParam + ".." + p2);
  
      boolean result = ((p2 != null) && p2.equals(firstParam));
      System.out.println("result is " + result);
  
      return result;
    }
  }
  
  
  
  1.1                  jakarta-log4j/src/java/org/apache/log4j/chainsaw/rule/LikeRule.java
  
  Index: LikeRule.java
  ===================================================================
  /*
   * ============================================================================
   *                   The Apache Software License, Version 1.1
   * ============================================================================
   *
   *    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without modifica-
   * tion, 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  by the  Apache Software Foundation  (http://www.apache.org/)."
   *    Alternately, this  acknowledgment may  appear in the software itself,  if
   *    and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "log4j" and  "Apache Software Foundation"  must not be used to
   *    endorse  or promote  products derived  from this  software without  prior
   *    written permission. For written permission, please contact
   *    apache@apache.org.
   *
   * 5. Products  derived from this software may not  be called "Apache", nor may
   *    "Apache" appear  in their name,  without prior written permission  of the
   *    Apache Software Foundation.
   *
   * 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
   * APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   * INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   * DING, 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.
   *
   * This software  consists of voluntary contributions made  by many individuals
   * on  behalf of the Apache Software  Foundation.  For more  information on the
   * Apache Software Foundation, please see <http://www.apache.org/>.
   *
   */
  
  package org.apache.log4j.chainsaw.rule;
  
  import org.apache.log4j.chainsaw.LoggingEventFieldResolver;
  import org.apache.log4j.spi.LoggingEvent;
  
  import org.apache.oro.text.regex.MalformedPatternException;
  import org.apache.oro.text.regex.Pattern;
  import org.apache.oro.text.regex.Perl5Compiler;
  import org.apache.oro.text.regex.Perl5Matcher;
  
  import java.util.Stack;
  
  /**
   * A Rule class providing support for ORO-based regular expression syntax. 
   * 
   * @author Scott Deboy <sd...@apache.org>
   */
  class LikeRule extends AbstractRule {
    LoggingEventFieldResolver resolver = LoggingEventFieldResolver.getInstance();
    Pattern pattern = null;
    Perl5Matcher matcher = new Perl5Matcher();
    String secondParam;
  
    private LikeRule(Pattern pattern, String secondParam) {
      this.pattern = pattern;
      this.secondParam = secondParam;
    }
  
    static Rule getRule(Stack stack) {
      String p1 = stack.pop().toString();
      String p2 = stack.pop().toString();
      Perl5Compiler compiler = new Perl5Compiler();
      Pattern pattern1 = null;
  
      try {
        pattern1 = compiler.compile(p1, Perl5Compiler.CASE_INSENSITIVE_MASK);
      } catch (MalformedPatternException e) {
      }
  
      return new LikeRule(pattern1, p2);
    }
  
    public boolean evaluate(LoggingEvent event) {
      String p2 = resolver.getValue(secondParam, event).toString();
      System.out.println(pattern + " like " + p2);
  
      boolean result = ((pattern != null) && matcher.matches(p2, pattern));
  
      System.out.println("result: " + result);
  
      return result;
    }
  }
  
  
  
  1.1                  jakarta-log4j/src/java/org/apache/log4j/chainsaw/rule/InFixToPostFix.java
  
  Index: InFixToPostFix.java
  ===================================================================
  /*
   * ============================================================================
   *                   The Apache Software License, Version 1.1
   * ============================================================================
   *
   *    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without modifica-
   * tion, 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  by the  Apache Software Foundation  (http://www.apache.org/)."
   *    Alternately, this  acknowledgment may  appear in the software itself,  if
   *    and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "log4j" and  "Apache Software Foundation"  must not be used to
   *    endorse  or promote  products derived  from this  software without  prior
   *    written permission. For written permission, please contact
   *    apache@apache.org.
   *
   * 5. Products  derived from this software may not  be called "Apache", nor may
   *    "Apache" appear  in their name,  without prior written permission  of the
   *    Apache Software Foundation.
   *
   * 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
   * APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   * INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   * DING, 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.
   *
   * This software  consists of voluntary contributions made  by many individuals
   * on  behalf of the Apache Software  Foundation.  For more  information on the
   * Apache Software Foundation, please see <http://www.apache.org/>.
   *
   */
  
  package org.apache.log4j.chainsaw.rule;
  
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  import java.util.Stack;
  import java.util.StringTokenizer;
  import java.util.Vector;
  
  /**
   * A helper class which converts infix expressions to postfix expressions
   * Currently grouping is supported, as well as all of the Rules supported by <code>RuleFactory</code>
   * 
   * NOTE: parsing is supported through the use of <code>StringTokenizer</code>, which means 
   * all tokens in the expression must be separated by spaces. 
   * 
   * @author Scott Deboy <sd...@apache.org>
   */
  
  class InFixToPostFix {
    private final Map precedenceMap = new HashMap();
    private final List operators = new Vector();
  
    public InFixToPostFix() {
      //boolean operators
      operators.add("!");
      operators.add("!=");
      operators.add("==");
      operators.add("~=");
      operators.add("||");
      operators.add("&&");
      operators.add("like");
  
      operators.add("*");
      operators.add("+");
      operators.add("-");
  
      //boolean precedence
      precedenceMap.put("!", new Integer(3));
      precedenceMap.put("!=", new Integer(3));
      precedenceMap.put("==", new Integer(3));
      precedenceMap.put("~=", new Integer(3));
      precedenceMap.put("like", new Integer(3));
  
      precedenceMap.put("||", new Integer(2));
      precedenceMap.put("&&", new Integer(2));
  
      precedenceMap.put("-", new Integer(2));
      precedenceMap.put("+", new Integer(2));
      precedenceMap.put("*", new Integer(3));
    }
  
    public String convert(String expression) {
      return infixToPostFix(new StringTokenizer(expression));
    }
  
    boolean isOperand(String symbol) {
      symbol = symbol.toLowerCase();
  
      return (!operators.contains(symbol));
    }
  
    boolean precedes(String symbol1, String symbol2) {
      symbol1 = symbol1.toLowerCase();
      symbol2 = symbol2.toLowerCase();
  
      if (!precedenceMap.keySet().contains(symbol1)) {
        return false;
      }
  
      if (!precedenceMap.keySet().contains(symbol2)) {
        return false;
      }
  
      int index1 = ((Integer) precedenceMap.get(symbol1)).intValue();
      int index2 = ((Integer) precedenceMap.get(symbol2)).intValue();
  
      boolean precedesResult = (index1 < index2);
      System.out.println(
        "SYMBOL1: " + symbol1 + "SYMBOL2: " + symbol2 + " index1: " + index1
        + " index2: " + index2 + " precedesresult: " + precedesResult);
  
      return precedesResult;
    }
  
    String infixToPostFix(StringTokenizer tokenizer) {
      String SPACE = " ";
      StringBuffer postfix = new StringBuffer();
  
      Stack stack = new Stack();
  
      while (tokenizer.hasMoreTokens()) {
        String token = tokenizer.nextToken().toLowerCase();
        System.out.println("FOUND TOKEN " + token);
  
        if ("(".equals(token)) {
          //recurse
          postfix.append(infixToPostFix(tokenizer));
          postfix.append(SPACE);
        } else if (")".equals(token)) {
          //exit recursion level
          while (stack.size() > 0) {
            postfix.append(stack.pop().toString());
            postfix.append(SPACE);
          }
  
          return postfix.toString();
        } else if (isOperand(token)) {
          postfix.append(token);
          postfix.append(SPACE);
        } else {
          //operator..
          //peek the stack..if the top element has a lower precedence than token
          //(peeked + has lower precedence than token *), push token onto the stack
          //otherwise, pop top element off stack and add to postfix string
          //in a loop until lower precedence or empty..then push token
          if (stack.size() > 0) {
            System.out.println("OPERATOR " + token + "..stack: " + stack);
  
            String peek = stack.peek().toString();
  
            if (precedes(peek, token)) {
              stack.push(token);
            } else {
              boolean bypass = false;
  
              do {
                if (
                  (stack.size() > 0)
                    && !precedes(stack.peek().toString(), token)) {
                  postfix.append(stack.pop().toString());
                  postfix.append(SPACE);
                } else {
                  bypass = true;
                }
              } while (!bypass);
  
              stack.push(token);
            }
          } else {
            stack.push(token);
          }
        }
      }
  
      while (stack.size() > 0) {
        postfix.append(stack.pop().toString());
        postfix.append(SPACE);
      }
  
      return postfix.toString();
    }
  }
  
  
  
  1.1                  jakarta-log4j/src/java/org/apache/log4j/chainsaw/rule/PartialTextMatchRule.java
  
  Index: PartialTextMatchRule.java
  ===================================================================
  /*
   * ============================================================================
   *                   The Apache Software License, Version 1.1
   * ============================================================================
   *
   *    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without modifica-
   * tion, 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  by the  Apache Software Foundation  (http://www.apache.org/)."
   *    Alternately, this  acknowledgment may  appear in the software itself,  if
   *    and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "log4j" and  "Apache Software Foundation"  must not be used to
   *    endorse  or promote  products derived  from this  software without  prior
   *    written permission. For written permission, please contact
   *    apache@apache.org.
   *
   * 5. Products  derived from this software may not  be called "Apache", nor may
   *    "Apache" appear  in their name,  without prior written permission  of the
   *    Apache Software Foundation.
   *
   * 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
   * APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   * INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   * DING, 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.
   *
   * This software  consists of voluntary contributions made  by many individuals
   * on  behalf of the Apache Software  Foundation.  For more  information on the
   * Apache Software Foundation, please see <http://www.apache.org/>.
   *
   */
  
  package org.apache.log4j.chainsaw.rule;
  
  import org.apache.log4j.chainsaw.LoggingEventFieldResolver;
  import org.apache.log4j.spi.LoggingEvent;
  
  import java.util.Stack;
  
  /**
   * A Rule class implementing case-insensitive partial-text matches against two strings. 
   * 
   * @author Scott Deboy <sd...@apache.org>
   */
  class PartialTextMatchRule extends AbstractRule {
    LoggingEventFieldResolver resolver = LoggingEventFieldResolver.getInstance();
    String firstParam;
    String secondParam;
  
    private PartialTextMatchRule(String firstParam, String secondParam) {
      this.firstParam = firstParam;
      this.secondParam = secondParam;
    }
  
    static Rule getRule(Stack stack) {
      String p1 = stack.pop().toString();
      String p2 = stack.pop().toString();
      System.out.println("get part text match op " + p1 + ".." + p2);
  
      return new PartialTextMatchRule(p1, p2);
    }
  
    public boolean evaluate(LoggingEvent event) {
      String p2 = resolver.getValue(secondParam, event).toString();
      System.out.println(
        "partial text match op " + firstParam + ".." + secondParam);
  
      boolean result =
        (((p2 != null) && (firstParam != null))
        && (p2.toLowerCase().indexOf(firstParam.toLowerCase()) > -1));
      System.out.println("result is " + result);
  
      return result;
    }
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: log4j-dev-help@jakarta.apache.org