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 ce...@apache.org on 2005/02/01 15:46:21 UTC
cvs commit: logging-log4j/tests/src/java/org/apache/log4j/lbel EventEvaluationTest.java TokenStreamTest.java
ceki 2005/02/01 06:46:21
Modified: src/java/org/apache/log4j/lbel/comparator Comparator.java
StringComparator.java
src/java/org/apache/log4j/lbel Token.java Parser.java
TokenStream.java EventEvaluator.java
tests/src/java/org/apache/log4j/lbel
EventEvaluationTest.java TokenStreamTest.java
Log:
- Fixed problem with StreamTokenizer which would incorrectly drop backslash '\' characters in quoted literals.
This means that real world patterns can be processed.
For example, one can now write "'message ~ 'hello\s*world' "
Revision Changes Path
1.2 +8 -1 logging-log4j/src/java/org/apache/log4j/lbel/comparator/Comparator.java
Index: Comparator.java
===================================================================
RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/lbel/comparator/Comparator.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Comparator.java 27 Jan 2005 19:25:08 -0000 1.1
+++ Comparator.java 1 Feb 2005 14:46:21 -0000 1.2
@@ -28,5 +28,12 @@
*/
public interface Comparator {
- public boolean compare(LoggingEvent event);
+ /**
+ *
+ * @param event
+ * @return
+ * @throws NullPointerException thrown if the lef or right side is null and
+ * the comparison operator is other than equals not equals ('=' or '!=').
+ */
+ public boolean compare(LoggingEvent event) throws NullPointerException;
}
1.4 +82 -56 logging-log4j/src/java/org/apache/log4j/lbel/comparator/StringComparator.java
Index: StringComparator.java
===================================================================
RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/lbel/comparator/StringComparator.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- StringComparator.java 1 Feb 2005 10:39:27 -0000 1.3
+++ StringComparator.java 1 Feb 2005 14:46:21 -0000 1.4
@@ -1,14 +1,25 @@
/*
- * Created on Jan 27, 2005
+ * Copyright 1999,2004 The Apache Software Foundation.
*
- * To change the template for this generated file go to
- * Window>Preferences>Java>Code Generation>Code and Comments
+ * 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.lbel.comparator;
import org.apache.log4j.lbel.Operator;
import org.apache.log4j.lbel.ScanError;
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;
@@ -16,102 +27,117 @@
/**
- * Base class for string-based comparators.
- *
- * <p>Allowed comparison operators are 'CHILDOF', '=', '!=', '>', '>=', '<',
+ * Base class for string-based comparators.
+ *
+ * <p>Allowed comparison operators are 'CHILDOF', '=', '!=', '>', '>=', '<',
* '<=', '~' and '!~' where '~' stands for regular expression match.
- *
+ *
* @author <a href="http://www.qos.ch/log4j/">Ceki Gülcü</a>
* @author Scott Deboy
*/
-abstract public class StringComparator implements Comparator {
-
+public abstract class StringComparator implements Comparator {
Operator operator;
String rightSide;
String rightSideWithDotSuffix;
Pattern rightSidePattern;
Perl5Matcher matcher;
- /**
- * Derived classes supply the left side of the comparison based on the event.
- *
- * @param event
- * @return the left side of the expression
- */
- abstract protected String getLeftSide(LoggingEvent event);
-
- public StringComparator(Operator operator, String rightSide) throws ScanError {
+ public StringComparator(Operator operator, String rightSide)
+ throws ScanError {
this.operator = operator;
this.rightSide = rightSide;
-
-
- if(operator.isRegex()) {
+
+ if (operator.isRegex()) {
Perl5Compiler compiler = new Perl5Compiler();
matcher = new Perl5Matcher();
try {
rightSidePattern = compiler.compile(rightSide);
- } catch(MalformedPatternException mfpe) {
- throw new ScanError("Malformed pattern ["+rightSide+"]", mfpe);
+ } catch (MalformedPatternException mfpe) {
+ throw new ScanError("Malformed pattern [" + rightSide + "]", mfpe);
}
}
-
+
// if CHILDOF operator and rightSide does not end with a dot add one
- if(operator.getCode() == Operator.CHILDOF && !rightSide.endsWith(".")) {
+ if ((operator.getCode() == Operator.CHILDOF) && !rightSide.endsWith(".")) {
this.rightSideWithDotSuffix = rightSide + ".";
}
}
-
- public boolean compare(LoggingEvent event) {
-
+ /**
+ * Derived classes supply the left side of the comparison based on the event.
+ *
+ * @param event
+ * @return the left side of the expression
+ */
+ protected abstract String getLeftSide(LoggingEvent event);
+
+ public boolean compare(LoggingEvent event) throws NullPointerException {
String leftSide = getLeftSide(event);
-
- if(leftSide == null) {
- switch(operator.getCode()) {
- case Operator.EQUAL: return leftSide == rightSide;
- case Operator.NOT_EQUAL: return leftSide != rightSide;
- default: throw new NullPointerException("null leftside can only be used with == or != operators");
- }
-
+
+ if (leftSide == null) {
+ switch (operator.getCode()) {
+ case Operator.EQUAL:
+ return leftSide == rightSide;
+ case Operator.NOT_EQUAL:
+ return leftSide != rightSide;
+ default:
+ throw new NullPointerException(
+ "null leftside can only be used with == or != operators");
+ }
}
-
- if(operator.isRegex()) {
+
+ if (operator.isRegex()) {
boolean match = matcher.contains(leftSide, rightSidePattern);
- if(operator.getCode() == Operator.REGEX_MATCH) {
+ if (operator.getCode() == Operator.REGEX_MATCH) {
return match;
} else {
return !match;
}
}
- if(operator.getCode() == Operator.CHILDOF) {
- if(leftSide.equals(rightSide)) {
+ if (operator.getCode() == Operator.CHILDOF) {
+ if (leftSide.equals(rightSide)) {
return true;
} else {
return leftSide.startsWith(rightSideWithDotSuffix);
}
}
-
+
+ if (rightSide == null) {
+ switch (operator.getCode()) {
+ case Operator.EQUAL:
+ return leftSide == rightSide;
+ case Operator.NOT_EQUAL:
+ return leftSide != rightSide;
+ default:
+ throw new NullPointerException(
+ "null rightside can only be used with == or != operators");
+ }
+ }
int compResult = leftSide.compareTo(rightSide);
-
-
- switch(operator.getCode()) {
- case Operator.EQUAL: return compResult == 0;
- case Operator.NOT_EQUAL: return compResult != 0;
- case Operator.GREATER: return compResult > 0;
- case Operator.GREATER_OR_EQUAL: return compResult >= 0;
- case Operator.LESS: return compResult < 0;
- case Operator.LESS_OR_EQUAL: return compResult <= 0;
+
+ switch (operator.getCode()) {
+ case Operator.EQUAL:
+ return compResult == 0;
+ case Operator.NOT_EQUAL:
+ return compResult != 0;
+ case Operator.GREATER:
+ return compResult > 0;
+ case Operator.GREATER_OR_EQUAL:
+ return compResult >= 0;
+ case Operator.LESS:
+ return compResult < 0;
+ case Operator.LESS_OR_EQUAL:
+ return compResult <= 0;
}
-
- throw new IllegalStateException("Unreachable state reached, operator "+operator);
+
+ throw new IllegalStateException(
+ "Unreachable state reached, operator " + operator);
}
-
public String toString() {
String full = this.getClass().getName();
int i = full.lastIndexOf(".");
- return full.substring(i)+"("+operator+", "+rightSide+")";
+ return full.substring(i) + "(" + operator + ", " + rightSide + ")";
}
-
}
1.6 +1 -0 logging-log4j/src/java/org/apache/log4j/lbel/Token.java
Index: Token.java
===================================================================
RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/lbel/Token.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- Token.java 1 Feb 2005 10:41:46 -0000 1.5
+++ Token.java 1 Feb 2005 14:46:21 -0000 1.6
@@ -27,6 +27,7 @@
public static final int CLASS = 170;
public static final int METHOD = 180;
public static final int NULL = 190;
+ public static final int DOT = 200;
public static final int EOF = 1000;
1.10 +17 -1 logging-log4j/src/java/org/apache/log4j/lbel/Parser.java
Index: Parser.java
===================================================================
RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/lbel/Parser.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- Parser.java 1 Feb 2005 10:41:46 -0000 1.9
+++ Parser.java 1 Feb 2005 14:46:21 -0000 1.10
@@ -202,7 +202,8 @@
ts.next();
return new Node(Node.COMPARATOR, new TimestampComparator(operator, getLong()));
case Token.PROPERTY:
- String key = (String) token.getValue();
+ ts.next();
+ String key = (String) getPropertyKey();
ts.next();
operator = getOperator();
ts.next();
@@ -279,4 +280,19 @@
throw new ScanError("Expected a level stirng got "+levelStr);
}
}
+
+ String getPropertyKey() throws IOException, ScanError {
+ Token token = ts.getCurrent();
+ if(token.getType() == Token.DOT) {
+ ts.next();
+ Token token2 = ts.getCurrent();
+ if(token2.getType() == Token.LITERAL) {
+ return (String) token2.getValue();
+ } else {
+ throw new ScanError("Expected LITERAL but got "+token2);
+ }
+ } else {
+ throw new ScanError("Expected '.' but got "+token);
+ }
+ }
}
1.8 +59 -26 logging-log4j/src/java/org/apache/log4j/lbel/TokenStream.java
Index: TokenStream.java
===================================================================
RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/lbel/TokenStream.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- TokenStream.java 1 Feb 2005 10:41:46 -0000 1.7
+++ TokenStream.java 1 Feb 2005 14:46:21 -0000 1.8
@@ -44,6 +44,7 @@
keywordMap.put("method", new Token(Token.METHOD, "method"));
keywordMap.put("class", new Token(Token.CLASS, "class"));
keywordMap.put("thread", new Token(Token.THREAD, "thread"));
+ keywordMap.put("property", new Token(Token.PROPERTY, "property"));
keywordMap.put("date", new Token(Token.DATE, "date"));
keywordMap.put("null", new Token(Token.NULL, "null"));
}
@@ -51,11 +52,13 @@
StreamTokenizer tokenizer;
int token;
Token current;
-
+ Reader reader;
public TokenStream(Reader reader) {
+ this.reader = reader;
tokenizer = new StreamTokenizer(reader);
tokenizer.resetSyntax();
+
tokenizer.whitespaceChars(' ', ' ');
tokenizer.whitespaceChars('\t', '\t');
tokenizer.whitespaceChars('\n', '\n');
@@ -64,10 +67,15 @@
tokenizer.wordChars('a', 'z');
tokenizer.wordChars('A', 'Z');
tokenizer.wordChars('0', '9');
+
+
- tokenizer.quoteChar('"');
- tokenizer.quoteChar('\'');
- tokenizer.parseNumbers();
+ // StreamTokenizer does not correctly handle the '\' character within quotes
+ // tokenizer.quoteChar('"');
+ // tokenizer.quoteChar('\'');
+
+ tokenizer.parseNumbers();
+ tokenizer.ordinaryChar('.');
}
public Token getCurrent() {
@@ -90,22 +98,20 @@
case StreamTokenizer.TT_WORD:
String txt = tokenizer.sval;
String lowerCaseTxt = txt.toLowerCase();
-
- if(txt.startsWith("property.")) {
- current = extractPropertyToken(txt);
- } else {
- Token result = (Token) keywordMap.get(lowerCaseTxt);
- if(result != null) {
- current = result;
- } else {
- current = new Token(Token.LITERAL, tokenizer.sval);
- }
- }
+ Token result = (Token) keywordMap.get(lowerCaseTxt);
+ if(result != null) {
+ current = result;
+ } else {
+ current = new Token(Token.LITERAL, tokenizer.sval);
+ }
break;
case '"':
case '\'':
- current = new Token(Token.LITERAL, tokenizer.sval);
+ current = scanLiteral(token);
break;
+ case '.':
+ current = new Token(Token.DOT, ".");
+ break;
case '>':
token2 = tokenizer.nextToken();
if(token2 == '=') {
@@ -153,15 +159,42 @@
}
}
- Token extractPropertyToken(String txt) throws ScanError {
- int point = txt.indexOf('.');
- String key = txt.substring(point+1);
- // Is the key empty? (An empty key is the only thing that can go wrong at
- // this stage.
- if(key == null || key.length() == 0) {
- throw new ScanError("["+txt+"] has zero-legnth key.");
- } else {
- return new Token(Token.PROPERTY, key);
- }
+ Token scanLiteral(int startChar) {
+ StringBuffer buf = new StringBuffer();
+ try {
+ int in = 0;
+ while(in != -1) {
+ in = reader.read();
+ if(in == startChar) {
+ break;
+ } else {
+ switch(in) {
+ case '\n':
+ case '\r':
+ break; // ignore line breaks
+ default: buf.append((char) in);
+ }
+ }
+ }
+ } catch(IOException io) {
+ }
+
+ return new Token(Token.LITERAL, buf.toString());
}
+
+ // Token extractPropertyToken() throws ScanError {
+// int token = tokenizer.nextToken();
+// if(token == '.') {
+// }
+//
+// int point = txt.indexOf('.');
+// String key = txt.substring(point+1);
+// // Is the key empty? (An empty key is the only thing that can go wrong at
+// // this stage.
+// if(key == null || key.length() == 0) {
+// throw new ScanError("["+txt+"] has zero-legnth key.");
+// } else {
+// return new Token(Token.PROPERTY, key);
+// }
+ // }
}
1.3 +1 -1 logging-log4j/src/java/org/apache/log4j/lbel/EventEvaluator.java
Index: EventEvaluator.java
===================================================================
RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/lbel/EventEvaluator.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- EventEvaluator.java 1 Feb 2005 10:41:46 -0000 1.2
+++ EventEvaluator.java 1 Feb 2005 14:46:21 -0000 1.3
@@ -42,7 +42,7 @@
*
* @param event The event to evaluate
* @return true if there is a match, false otherwise.
- * @throws NullPointerException thrown if lefthand side is null
+ * @throws NullPointerException can be thrown in presence of null values
*/
boolean evaluate(LoggingEvent event) throws NullPointerException;
}
1.6 +14 -10 logging-log4j/tests/src/java/org/apache/log4j/lbel/EventEvaluationTest.java
Index: EventEvaluationTest.java
===================================================================
RCS file: /home/cvs/logging-log4j/tests/src/java/org/apache/log4j/lbel/EventEvaluationTest.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- EventEvaluationTest.java 1 Feb 2005 10:39:27 -0000 1.5
+++ EventEvaluationTest.java 1 Feb 2005 14:46:21 -0000 1.6
@@ -93,10 +93,11 @@
evaluator = new LBELEventEvaluator("message ~ 'h[a-z]* world'");
assertTrue(evaluator.evaluate(event));
- // the following test cannot be run because of a bug in the way
- // java.io.StreamTokenizer incorrectly interprets the '\' character within quotes
- // evaluator = new LBELEventEvaluator("message ~ 'h\\w* world'");
- //assertTrue(evaluator.evaluate(event));
+ evaluator = new LBELEventEvaluator("message ~ 'h\\w* world'");
+ assertTrue(evaluator.evaluate(event));
+
+ evaluator = new LBELEventEvaluator("message ~ 'hello\\sworld'");
+ assertTrue(evaluator.evaluate(event));
LBELEventEvaluator evaluator = new LBELEventEvaluator("message !~ 'x'");
assertTrue(evaluator.evaluate(event));
@@ -106,19 +107,19 @@
}
public void testLogger() throws Exception, ScanError {
- evaluator = new LBELEventEvaluator("logger = org.wombat");
+ evaluator = new LBELEventEvaluator("logger = 'org.wombat'");
assertTrue(evaluator.evaluate(event));
- evaluator = new LBELEventEvaluator("logger = org.wombat.x");
+ evaluator = new LBELEventEvaluator("logger = 'org.wombat.x'");
assertTrue(!evaluator.evaluate(event));
- evaluator = new LBELEventEvaluator("logger != org.wombat.x");
+ evaluator = new LBELEventEvaluator("logger != 'org.wombat.x'");
assertTrue(evaluator.evaluate(event));
- evaluator = new LBELEventEvaluator("logger < org.wombat.x");
+ evaluator = new LBELEventEvaluator("logger < 'org.wombat.x'");
assertTrue(evaluator.evaluate(event));
- evaluator = new LBELEventEvaluator("logger <= org.wombat.x");
+ evaluator = new LBELEventEvaluator("logger <= 'org.wombat.x'");
assertTrue(evaluator.evaluate(event));
evaluator = new LBELEventEvaluator("logger > org");
@@ -163,7 +164,7 @@
}
public void testClass() throws ScanError {
- evaluator = new LBELEventEvaluator("class = org.wombat");
+ evaluator = new LBELEventEvaluator("class = 'org.wombat'");
assertTrue(evaluator.evaluate(event));
evaluator = new LBELEventEvaluator("class > org");
@@ -180,6 +181,9 @@
evaluator = new LBELEventEvaluator("message != NULL");
assertTrue(!evaluator.evaluate(nullEvent));
+ evaluator = new LBELEventEvaluator("message != NULL");
+ assertTrue(evaluator.evaluate(event));
+
try {
evaluator = new LBELEventEvaluator("message > NULL");
assertTrue(evaluator.evaluate(nullEvent));
1.5 +24 -13 logging-log4j/tests/src/java/org/apache/log4j/lbel/TokenStreamTest.java
Index: TokenStreamTest.java
===================================================================
RCS file: /home/cvs/logging-log4j/tests/src/java/org/apache/log4j/lbel/TokenStreamTest.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- TokenStreamTest.java 31 Jan 2005 20:31:09 -0000 1.4
+++ TokenStreamTest.java 1 Feb 2005 14:46:21 -0000 1.5
@@ -241,28 +241,39 @@
ts.next(); t = ts.getCurrent();
assertEquals(Token.PROPERTY, t.getType());
+ ts.next(); t = ts.getCurrent();
+ assertEquals(Token.DOT, t.getType());
+ ts.next(); t = ts.getCurrent();
+ assertEquals(Token.LITERAL, t.getType());
assertEquals("x", t.getValue());
ts.next(); t = ts.getCurrent();
assertEquals(Token.PROPERTY, t.getType());
+ ts.next(); t = ts.getCurrent();
+ assertEquals(Token.DOT, t.getType());
+ ts.next(); t = ts.getCurrent();
+ assertEquals(Token.LITERAL, t.getType());
assertEquals("xyz", t.getValue());
+
+ ts.next(); t = ts.getCurrent();
+ assertEquals(Token.PROPERTY, t.getType());
+ ts.next(); t = ts.getCurrent();
+ assertEquals(Token.DOT, t.getType());
- try {
- ts.next();
- fail("A ScanError should have been thrown");
- } catch(ScanError e) {
- }
}
- public void testProperty2() throws IOException, ScanError {
- // TODO: add support for spaces in prooperty keys
+ public void testQuotedProperty() throws IOException, ScanError {
-// StringReader sr = new StringReader(" property.'toto a' etc");
-// TokenStream ts = new TokenStream(sr);
-//
-// ts.next(); t = ts.getCurrent();
-// assertEquals(Token.PROPERTY, t.getType());
-// assertEquals("toto a", t.getValue());
+ StringReader sr = new StringReader(" property.'toto a' etc");
+ TokenStream ts = new TokenStream(sr);
+
+ ts.next(); t = ts.getCurrent();
+ assertEquals(Token.PROPERTY, t.getType());
+ ts.next(); t = ts.getCurrent();
+ assertEquals(Token.DOT, t.getType());
+ ts.next(); t = ts.getCurrent();
+ assertEquals(Token.LITERAL, t.getType());
+ assertEquals("toto a", t.getValue());
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org