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 ca...@apache.org on 2005/03/08 00:50:27 UTC
cvs commit: logging-log4j/tests/witness/pattern patternLayout.14
carnold 2005/03/07 15:50:27
Modified: src/java/org/apache/log4j/pattern
ClassNamePatternConverter.java
LoggerPatternConverter.java
NamedPatternConverter.java PatternParser.java
tests/src/java/org/apache/log4j PatternLayoutTest.java
tests/src/java/org/apache/log4j/pattern
PatternParserTest.java
tests/witness/pattern patternLayout.14
Added: src/java/org/apache/log4j/pattern NameAbbreviator.java
tests/input/pattern patternLayout14.properties
tests/src/java/org/apache/log4j/pattern
NameAbbreviatorTest.java
Log:
Bug 33888: Enhanced abbreviation syntax for logger and class name
Revision Changes Path
1.10 +19 -17 logging-log4j/src/java/org/apache/log4j/pattern/ClassNamePatternConverter.java
Index: ClassNamePatternConverter.java
===================================================================
RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/pattern/ClassNamePatternConverter.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- ClassNamePatternConverter.java 20 Nov 2004 11:27:19 -0000 1.9
+++ ClassNamePatternConverter.java 7 Mar 2005 23:50:27 -0000 1.10
@@ -1,12 +1,12 @@
/*
- * Copyright 1999,2004 The Apache Software Foundation.
- *
+ * Copyright 1999,2005 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.
@@ -19,35 +19,37 @@
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.location.LocationInfo;
+
/**
- * Most of the work is done in the parent class {@link
+ * Most of the work is done in the parent class {@link
* org.apache.log4j.pattern.NamedPatternConverter NamedPatternConverter}.
* This class is only responsible of returning the full name name of the caller
- * class.
- *
+ * class.
+ *
* @author Ceki Gülcü
*/
public class ClassNamePatternConverter extends NamedPatternConverter {
- static private final String NAME = "Class Name";
- static private final String STYLE_CLASS = NAME.toLowerCase();
+ private static final String NAME = "Class Name";
+ private static final String STYLE_CLASS = NAME.toLowerCase();
public ClassNamePatternConverter() {
super();
}
-
- String getFullyQualifiedName(LoggingEvent event) {
+
+ protected String getFullyQualifiedName(LoggingEvent event) {
LocationInfo li = event.getLocationInformation();
- if(li == null) {
+
+ if (li == null) {
return LocationInfo.NA;
} else {
- return li.getClassName();
+ return li.getClassName();
}
- }
-
+ }
+
public String getName() {
- return NAME;
+ return NAME;
}
-
+
public String getStyleClass(LoggingEvent e) {
return STYLE_CLASS;
}
1.6 +13 -14 logging-log4j/src/java/org/apache/log4j/pattern/LoggerPatternConverter.java
Index: LoggerPatternConverter.java
===================================================================
RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/pattern/LoggerPatternConverter.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- LoggerPatternConverter.java 16 Sep 2004 19:18:58 -0000 1.5
+++ LoggerPatternConverter.java 7 Mar 2005 23:50:27 -0000 1.6
@@ -1,12 +1,12 @@
/*
- * Copyright 1999,2004 The Apache Software Foundation.
- *
+ * Copyright 1999,2005 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.
@@ -18,30 +18,29 @@
import org.apache.log4j.spi.LoggingEvent;
+
/**
- *
- *
+ *
+ *
* @author Ceki Gülcü
*/
public class LoggerPatternConverter extends NamedPatternConverter {
// We assume that each PatternConveter instance is unique within a layout,
// which is unique within an appender. We further assume that callas to the
// appender method are serialized (per appender).
-
public LoggerPatternConverter() {
super();
}
- String getFullyQualifiedName(LoggingEvent event) {
- return event.getLoggerName();
- }
-
+ protected String getFullyQualifiedName(LoggingEvent event) {
+ return event.getLoggerName();
+ }
+
public String getName() {
- return "Logger";
+ return "Logger";
}
-
+
public String getStyleClass(LoggingEvent e) {
return "logger";
}
-
}
1.7 +42 -66 logging-log4j/src/java/org/apache/log4j/pattern/NamedPatternConverter.java
Index: NamedPatternConverter.java
===================================================================
RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/pattern/NamedPatternConverter.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- NamedPatternConverter.java 6 Jan 2005 19:27:03 -0000 1.6
+++ NamedPatternConverter.java 7 Mar 2005 23:50:27 -0000 1.7
@@ -1,12 +1,12 @@
/*
- * Copyright 1999,2004 The Apache Software Foundation.
- *
+ * Copyright 1999,2005 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.
@@ -16,87 +16,63 @@
package org.apache.log4j.pattern;
-import java.util.List;
-
import org.apache.log4j.spi.LoggingEvent;
+import java.util.List;
+
/**
- *
+ *
* Base class for other pattern converters which can return only parts of their name.
- *
+ *
* @author Ceki Gülcü
+ * @author Curt Arnold
*/
-abstract class NamedPatternConverter extends PatternConverter {
-
+public abstract class NamedPatternConverter extends PatternConverter {
// We assume that each PatternConveter instance is unique within a layout,
// which is unique within an appender. We further assume that callas to the
// appender method are serialized (per appender).
- StringBuffer buf;
- int precision;
+ private final StringBuffer buf = new StringBuffer(32);
+ private NameAbbreviator abbreviator =
+ NameAbbreviator.getDefaultAbbreviator();
- public NamedPatternConverter() {
- super();
- this.buf = new StringBuffer(32);
+ protected NamedPatternConverter() {
}
- abstract String getFullyQualifiedName(LoggingEvent event);
-
- public void setOptions(List optionList) {
- if(optionList == null || optionList.size() == 0) {
- return;
- }
-
- String option = (String) optionList.get(0);
-
- /**
- The option is expected to be in decimal and positive. In case of
- error, zero is returned. */
- int r = 0;
-
- if (option != null) {
- try {
- precision = Integer.parseInt(option);
- //System.out.println("Precision is "+precision);
- if (precision <= 0) {
- getLogger().error(
- "Precision option (" + option + ") isn't a positive integer.");
- precision = 0;
- }
- } catch (NumberFormatException e) {
- getLogger().error(
- "Category option \"" + option + "\" not a decimal integer.", e);
- }
+ /**
+ * Gets fully qualified name from event.
+ * @param event event, will not be null.
+ * @return name, must not be null.
+ */
+ protected abstract String getFullyQualifiedName(final LoggingEvent event);
+
+ /**
+ * Sets converter options.
+ *
+ * NamedPatternConverter interprets the first parameter as an
+ * abbreviation specification.
+ *
+ * @param optionList option list.
+ */
+ public void setOptions(final List optionList) {
+ if ((optionList != null) && (optionList.size() > 0)) {
+ String option = (String) optionList.get(0);
+ abbreviator = NameAbbreviator.getAbbreviator(option);
}
}
- public StringBuffer convert(LoggingEvent event) {
+ /**
+ * Convert event.
+ *
+ * @param event event, may not be null.
+ * @return string buffer used in conversion.
+ */
+ public StringBuffer convert(final LoggingEvent event) {
buf.setLength(0);
String n = getFullyQualifiedName(event);
- if (precision <= 0) {
- buf.append(n);
- } else {
- int len = n.length();
-
- // We substract 1 from 'len' when assigning to 'end' to avoid out of
- // bounds exception in return r.substring(end+1, len). This can happen if
- // precision is 1 and the category name ends with a dot.
- int end = len - 1;
-
- for (int i = precision; i > 0; i--) {
- end = n.lastIndexOf('.', end - 1);
-
- if (end == -1) {
- // not enough dot characters. The whole string should be returned
- return buf.append(n);
- }
- }
-
- // The end variable should point to the left-most dot character to
- // the right of which all character should be returned.
- buf.append(n.substring(end + 1, len));
- }
+ abbreviator.abbreviate(buf, n);
+
return buf;
}
}
1.23 +162 -128 logging-log4j/src/java/org/apache/log4j/pattern/PatternParser.java
Index: PatternParser.java
===================================================================
RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/pattern/PatternParser.java,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- PatternParser.java 8 Jan 2005 14:05:28 -0000 1.22
+++ PatternParser.java 7 Mar 2005 23:50:27 -0000 1.23
@@ -1,12 +1,12 @@
/*
- * Copyright 1999,2004 The Apache Software Foundation.
- *
+ * Copyright 1999,2005 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.
@@ -20,10 +20,10 @@
import org.apache.log4j.spi.ComponentBase;
import org.apache.log4j.spi.LoggerRepository;
+import java.util.ArrayList;
import java.util.HashMap;
-import java.util.Map;
import java.util.List;
-import java.util.ArrayList;
+import java.util.Map;
// Contributors: Nelson Minar <(n...@monkey.org>
@@ -31,19 +31,20 @@
// Reinhard Deschler <re...@web.de>
/**
- * Most of the work of the {@link org.apache.log4j.PatternLayout} class
- * is delegated to the PatternParser class.
- * <p>It is this class that parses conversion patterns and creates
+ * Most of the work of the {@link org.apache.log4j.PatternLayout} class
+ * is delegated to the PatternParser class.
+ * <p>It is this class that parses conversion patterns and creates
* a chained list of {@link OptionConverter OptionConverters}.
- *
+ *
* @author James P. Cakalic
* @author Ceki Gülcü
* @author Anders Kristensen
* @author Paul Smith
+ * @author Curt Arnold
*
* @since 0.8.2
*/
-public class PatternParser extends ComponentBase {
+public final class PatternParser extends ComponentBase {
private static final char ESCAPE_CHAR = '%';
private static final int LITERAL_STATE = 0;
private static final int CONVERTER_STATE = 1;
@@ -51,78 +52,81 @@
private static final int DOT_STATE = 3;
private static final int MIN_STATE = 4;
private static final int MAX_STATE = 5;
-
- static Map globalRulesRegistry;
+ private static Map globalRulesRegistry;
static {
// We set the global rules in the static initializer of PatternParser class
globalRulesRegistry = new HashMap(17);
- globalRulesRegistry.put("c", LoggerPatternConverter.class.getName());
- globalRulesRegistry.put("logger", LoggerPatternConverter.class.getName());
-
- globalRulesRegistry.put("C", ClassNamePatternConverter.class.getName());
- globalRulesRegistry.put("class", ClassNamePatternConverter.class.getName());
-
- globalRulesRegistry.put("d", DatePatternConverter.class.getName());
- globalRulesRegistry.put("date", DatePatternConverter.class.getName());
-
- globalRulesRegistry.put("F", FileLocationPatternConverter.class.getName());
- globalRulesRegistry.put("file", FileLocationPatternConverter.class.getName());
-
- globalRulesRegistry.put("l", FullLocationPatternConverter.class.getName());
+ globalRulesRegistry.put("c", LoggerPatternConverter.class);
+ globalRulesRegistry.put("logger", LoggerPatternConverter.class);
+
+ globalRulesRegistry.put("C", ClassNamePatternConverter.class);
+ globalRulesRegistry.put("class", ClassNamePatternConverter.class);
+
+ globalRulesRegistry.put("d", DatePatternConverter.class);
+ globalRulesRegistry.put("date", DatePatternConverter.class);
+
+ globalRulesRegistry.put("F", FileLocationPatternConverter.class);
+ globalRulesRegistry.put("file", FileLocationPatternConverter.class);
+
+ globalRulesRegistry.put("l", FullLocationPatternConverter.class);
+
+ globalRulesRegistry.put("L", LineLocationPatternConverter.class);
+ globalRulesRegistry.put("line", LineLocationPatternConverter.class);
+
+ globalRulesRegistry.put("m", MessagePatternConverter.class);
+ globalRulesRegistry.put("message", MessagePatternConverter.class);
- globalRulesRegistry.put("L", LineLocationPatternConverter.class.getName());
- globalRulesRegistry.put("line", LineLocationPatternConverter.class.getName());
+ globalRulesRegistry.put("n", LineSeparatorPatternConverter.class);
- globalRulesRegistry.put("m", MessagePatternConverter.class.getName());
- globalRulesRegistry.put("message", MessagePatternConverter.class.getName());
+ globalRulesRegistry.put("M", MethodLocationPatternConverter.class);
+ globalRulesRegistry.put("method", MethodLocationPatternConverter.class);
- globalRulesRegistry.put("n", LineSeparatorPatternConverter.class.getName());
+ globalRulesRegistry.put("p", LevelPatternConverter.class);
+ globalRulesRegistry.put("level", LevelPatternConverter.class);
+ globalRulesRegistry.put("r", RelativeTimePatternConverter.class);
+ globalRulesRegistry.put("relative", RelativeTimePatternConverter.class);
+
+ globalRulesRegistry.put("t", ThreadPatternConverter.class);
+ globalRulesRegistry.put("thread", ThreadPatternConverter.class);
+
+ globalRulesRegistry.put("x", NDCPatternConverter.class);
+ globalRulesRegistry.put("ndc", NDCPatternConverter.class);
+
+ globalRulesRegistry.put("X", PropertiesPatternConverter.class);
+ globalRulesRegistry.put("properties", PropertiesPatternConverter.class);
+
+ globalRulesRegistry.put("sn", SequenceNumberPatternConverter.class);
globalRulesRegistry.put(
- "M", MethodLocationPatternConverter.class.getName());
+ "sequenceNumber", SequenceNumberPatternConverter.class);
+
globalRulesRegistry.put(
- "method", MethodLocationPatternConverter.class.getName());
+ "throwable", ThrowableInformationPatternConverter.class);
+ }
+
+ private int state;
+ private StringBuffer currentLiteral = new StringBuffer(32);
+ private int patternLength;
+ private int i;
+ private PatternConverter head;
+ private PatternConverter tail;
+ private FormattingInfo formattingInfo = new FormattingInfo();
+ private String pattern;
- globalRulesRegistry.put("p", LevelPatternConverter.class.getName());
- globalRulesRegistry.put("level", LevelPatternConverter.class.getName());
-
- globalRulesRegistry.put("r", RelativeTimePatternConverter.class.getName());
- globalRulesRegistry.put("relative", RelativeTimePatternConverter.class.getName());
-
- globalRulesRegistry.put("t", ThreadPatternConverter.class.getName());
- globalRulesRegistry.put("thread", ThreadPatternConverter.class.getName());
-
- globalRulesRegistry.put("x", NDCPatternConverter.class.getName());
- globalRulesRegistry.put("ndc", NDCPatternConverter.class.getName());
-
- globalRulesRegistry.put("X", PropertiesPatternConverter.class.getName());
- globalRulesRegistry.put("properties", PropertiesPatternConverter.class.getName());
-
- globalRulesRegistry.put("sn", SequenceNumberPatternConverter.class.getName());
- globalRulesRegistry.put("sequenceNumber", SequenceNumberPatternConverter.class.getName());
-
- globalRulesRegistry.put("throwable", ThrowableInformationPatternConverter.class.getName());
-
- }
-
- int state;
- protected StringBuffer currentLiteral = new StringBuffer(32);
- protected int patternLength;
- protected int i;
- PatternConverter head;
- PatternConverter tail;
- protected FormattingInfo formattingInfo = new FormattingInfo();
- protected String pattern;
-
/**
* Additional rules for this particular instance.
* key: the conversion word (as String)
- * value: the pattern converter class (as String)
+ * value: the pattern converter class (as String)
*/
- Map converterRegistry;
+ private Map converterRegistry;
+
+ public PatternParser(
+ final String pattern, final LoggerRepository repository) {
+ if (pattern == null) {
+ throw new NullPointerException("pattern");
+ }
- public PatternParser(String pattern, LoggerRepository repository) {
this.pattern = pattern;
this.repository = repository;
patternLength = pattern.length();
@@ -147,25 +151,24 @@
* start of a unicode identifier, the value null is returned.
*
*/
- protected String extractConverter(char lastChar) {
-
+ private String extractConverter(char lastChar) {
// When this method is called, lastChar points to the first character of the
// conersion word. For example:
// For "%hello" lastChar = 'h'
// For "%-5hello" lastChar = 'h'
-
- //System.out.println("lastchar is "+lastChar);
-
- if(!Character.isUnicodeIdentifierStart(lastChar)) {
+ //System.out.println("lastchar is "+lastChar);
+ if (!Character.isUnicodeIdentifierStart(lastChar)) {
return null;
- }
-
+ }
+
StringBuffer convBuf = new StringBuffer(16);
- convBuf.append(lastChar);
-
- while ((i < patternLength)
- && Character.isUnicodeIdentifierPart(pattern.charAt(i))) {
+ convBuf.append(lastChar);
+
+ while (
+ (i < patternLength)
+ && Character.isUnicodeIdentifierPart(pattern.charAt(i))) {
convBuf.append(pattern.charAt(i));
+
//System.out.println("conv buffer is now ["+convBuf+"].");
i++;
}
@@ -176,15 +179,17 @@
/**
* Returns the option, null if not in the expected format.
*/
- protected List extractOptions() {
+ private List extractOptions() {
ArrayList options = null;
+
while ((i < patternLength) && (pattern.charAt(i) == '{')) {
int end = pattern.indexOf('}', i);
if (end > i) {
if (options == null) {
- options = new ArrayList();
+ options = new ArrayList();
}
+
String r = pattern.substring(i + 1, end);
options.add(r);
i = end + 1;
@@ -319,68 +324,88 @@
return head;
}
- String findConverterClass(String converterId) {
- if(converterId == null) {
+ /**
+ * Creates a new pattern converter.
+ * @param converterId converter identifier.
+ * @param formattingInfo formatting info.
+ * @param options options.
+ * @return pattern converter, may be null.
+ */
+ private PatternConverter createConverter(
+ final String converterId, final FormattingInfo formattingInfo,
+ final List options) {
+ PatternConverter converter = null;
+
+ if (converterId == null) {
getLogger().warn("converterId is null");
- }
-
- if (converterRegistry != null) {
- String r = (String) converterRegistry.get(converterId);
+ } else {
+ if (converterRegistry != null) {
+ String r = (String) converterRegistry.get(converterId);
+
+ if (r != null) {
+ converter =
+ (PatternConverter) OptionConverter.instantiateByClassName(
+ r, PatternConverter.class, null);
+ }
+ }
- if (r != null) {
- return r;
+ Class converterClass = (Class) globalRulesRegistry.get(converterId);
+
+ if (converterClass != null) {
+ try {
+ converter = (PatternConverter) converterClass.newInstance();
+ } catch (Exception ex) {
+ getLogger().error("Error creating converter for " + converterId, ex);
+ }
}
}
-
- String r = (String) globalRulesRegistry.get(converterId);
- if (r != null) {
- return r;
- }
- return null;
+ if (converter != null) {
+ converter.setFormattingInfo(formattingInfo);
+ converter.setOptions(options);
+ }
+
+ return converter;
}
/**
* When finalizeConverter is called 'c' is the current conversion caracter
* and i points to the character following 'c'.
*/
- protected void finalizeConverter(char c) {
- PatternConverter pc = null;
-
+ private void finalizeConverter(char c) {
String converterId = extractConverter(c);
- //System.out.println("converter ID[" + converterId + "]");
- //System.out.println("c is [" + c + "]");
- String className = (String) findConverterClass(converterId);
-
- //System.out.println("converter class [" + className + "]");
-
List options = extractOptions();
- //System.out.println("Option is [" + option + "]");
- if (className != null) {
- pc = (PatternConverter) OptionConverter.instantiateByClassName(
- className, PatternConverter.class, null);
-
- // setting the logger repository is an important configuration step.
- pc.setLoggerRepository(this.repository);
-
- // formattingInfo variable is an instance variable, occasionally reset
- // and used over and over again
- pc.setFormattingInfo(formattingInfo);
- pc.setOptions(options);
- currentLiteral.setLength(0);
- } else {
- getLogger().error(
- "Unexpected char [" + c + "] at position " + i
- + " in conversion patterrn.");
- pc = new LiteralPatternConverter(currentLiteral.toString());
- currentLiteral.setLength(0);
+ PatternConverter pc =
+ createConverter(converterId, formattingInfo, options);
+
+ if (pc == null) {
+ StringBuffer msg;
+
+ if ((converterId == null) || (converterId.length() == 0)) {
+ msg =
+ new StringBuffer("Empty conversion specifier starting at position ");
+ } else {
+ msg = new StringBuffer("Unrecognized conversion specifier [");
+ msg.append(converterId);
+ msg.append("] starting at position ");
+ }
+
+ msg.append(Integer.toString(i));
+ msg.append(" in conversion pattern.");
+ getLogger().error(msg.toString());
+ pc = new LiteralPatternConverter(currentLiteral.toString());
}
+
+ // setting the logger repository is an important configuration step.
+ pc.setLoggerRepository(this.repository);
+
+ currentLiteral.setLength(0);
addConverter(pc);
}
- protected void addConverter(PatternConverter pc) {
+ private void addConverter(final PatternConverter pc) {
currentLiteral.setLength(0);
// Add the pattern converter to the list.
@@ -395,16 +420,25 @@
/**
* Returns the converter registry for this PatternParser instance.
+ * @return map of custom pattern converters, may be null.
*/
public Map getConverterRegistry() {
- return converterRegistry;
+ if (converterRegistry == null) {
+ return null;
+ }
+
+ return new HashMap(converterRegistry);
}
/**
* Set the converter registry for this PatternParser instance.
+ * @param converterRegistry map of format specifiers to class names, may be null.
*/
- public void setConverterRegistry(Map converterRegistry) {
- this.converterRegistry = converterRegistry;
+ public void setConverterRegistry(final Map converterRegistry) {
+ if (converterRegistry == null) {
+ this.converterRegistry = null;
+ } else {
+ this.converterRegistry = new HashMap(converterRegistry);
+ }
}
-
}
1.1 logging-log4j/src/java/org/apache/log4j/pattern/NameAbbreviator.java
Index: NameAbbreviator.java
===================================================================
/*
* Copyright 1999,2005 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.pattern;
import java.util.ArrayList;
import java.util.List;
/**
* NameAbbreviator generates abbreviated logger and class names.
*
* @author Curt Arnold
* @since 1.3
*/
public abstract class NameAbbreviator {
/**
* Default (no abbreviation) abbreviator.
*/
private static final NameAbbreviator defaultAbbreviator =
new NOPAbbreviator();
/**
* Gets an abbreviator.
*
*
* @param pattern abbreviation pattern.
* @return abbreviator, will not be null.
*/
public static NameAbbreviator getAbbreviator(final String pattern) {
if (pattern.length() > 0) {
// if pattern is just spaces and numbers then
// use MaxElementAbbreviator
String trimmed = pattern.trim();
if (trimmed.length() == 0) {
return defaultAbbreviator;
}
int i = 0;
for (
;
(i < trimmed.length()) && (trimmed.charAt(i) >= '0')
&& (trimmed.charAt(i) <= '9'); i++)
;
//
// if all blanks and digits
//
if (i == trimmed.length()) {
return new MaxElementAbbreviator(Integer.parseInt(trimmed));
}
ArrayList fragments = new ArrayList(5);
char ellipsis;
int charCount;
int pos = 0;
while ((pos < trimmed.length()) && (pos >= 0)) {
int ellipsisPos = pos;
if (trimmed.charAt(pos) == '*') {
charCount = Integer.MAX_VALUE;
ellipsisPos++;
} else {
if ((trimmed.charAt(pos) >= '0') && (trimmed.charAt(pos) <= '9')) {
charCount = trimmed.charAt(pos) - '0';
ellipsisPos++;
} else {
charCount = 0;
}
}
ellipsis = '\0';
if (ellipsisPos < trimmed.length()) {
ellipsis = trimmed.charAt(ellipsisPos);
if (ellipsis == '.') {
ellipsis = '\0';
}
}
fragments.add(new PatternAbbreviatorFragment(charCount, ellipsis));
pos = trimmed.indexOf(".", pos);
if (pos == -1) {
break;
}
pos++;
}
return new PatternAbbreviator(fragments);
}
//
// no matching abbreviation, return defaultAbbreviator
//
return defaultAbbreviator;
}
/**
* Gets default abbreviator.
*
* @return default abbreviator.
*/
public static NameAbbreviator getDefaultAbbreviator() {
return defaultAbbreviator;
}
/**
* Appends abbreviated name to StringBuffer.
*
*
* @param buf buffer, may not be null.
* @param name name, may not be null.
*
*/
public abstract void abbreviate(final StringBuffer buf, String name);
/**
* Abbreviator that simply appends full name to buffer.
*/
private static class NOPAbbreviator extends NameAbbreviator {
public NOPAbbreviator() {
}
public void abbreviate(final StringBuffer buf, String name) {
buf.append(name);
}
}
/**
* Abbreviator that drops starting path elements.
*/
private static class MaxElementAbbreviator extends NameAbbreviator {
private final int count;
/**
* Create new instance.
* @param count maximum number of path elements to output.
*/
public MaxElementAbbreviator(final int count) {
this.count = count;
}
/**
* Abbreviate name.
* @param buf buffer to append abbreviation.
* @param name name to abbreviate.
*/
public void abbreviate(final StringBuffer buf, String name) {
int len = name.length();
// We substract 1 from 'len' when assigning to 'end' to avoid out of
// bounds exception in return r.substring(end+1, len). This can happen if
// precision is 1 and the category name ends with a dot.
int end = len - 1;
for (int i = count; i > 0; i--) {
end = name.lastIndexOf('.', end - 1);
if (end == -1) {
// not enough dot characters. The whole string should be returned
buf.append(name);
return;
}
}
// The end variable should point to the left-most dot character to
// the right of which all character should be returned.
buf.append(name.substring(end + 1, len));
}
}
/**
* Fragment of an pattern abbreviator.
*
*/
private static class PatternAbbreviatorFragment {
/**
* Count of initial characters of element to output.
*/
private final int charCount;
/**
* Character used to represent dropped characters.
* '\0' indicates no representation of dropped characters.
*/
private final char ellipsis;
/**
* Creates a PatternAbbreviatorFragment.
* @param charCount number of initial characters to preserve.
* @param ellipsis character to represent elimination of characters,
* '\0' if no ellipsis is desired.
*/
public PatternAbbreviatorFragment(
final int charCount, final char ellipsis) {
this.charCount = charCount;
this.ellipsis = ellipsis;
}
/**
* Abbreviate element of name.
* @param buf buffer to receive element.
* @param name name.
* @param startPos starting index of name element.
* @return starting index of next element.
*/
public int abbreviate(
final StringBuffer buf, final String name, final int startPos) {
int nextDot = name.indexOf(".", startPos);
if (nextDot != -1) {
if ((nextDot - startPos) > charCount) {
if (charCount > 0) {
buf.append(name.substring(startPos, startPos + charCount));
}
if (ellipsis != '\0') {
buf.append(ellipsis);
}
buf.append('.');
} else {
buf.append(name.substring(startPos, nextDot + 1));
}
return nextDot + 1;
}
buf.append(name.substring(startPos));
return name.length();
}
}
/**
* Pattern abbreviator.
*
*
*/
private static class PatternAbbreviator extends NameAbbreviator {
/**
* Element abbreviation patterns.
*/
private final PatternAbbreviatorFragment[] fragments;
/**
* Create PatternAbbreviator.
*
* @param fragments element abbreviation patterns.
*/
public PatternAbbreviator(List fragments) {
if (fragments.size() == 0) {
throw new IllegalArgumentException(
"fragments must have at least one element");
}
this.fragments = new PatternAbbreviatorFragment[fragments.size()];
fragments.toArray(this.fragments);
}
/**
* Abbreviate name.
* @param buf buffer that abbreviated name is appended.
* @param name name.
*/
public void abbreviate(final StringBuffer buf, final String name) {
//
// all non-terminal patterns are executed once
//
int pos = 0;
for (int i = 0; (i < (fragments.length - 1)) && (pos < name.length());
i++) {
pos = fragments[i].abbreviate(buf, name, pos);
}
//
// last pattern in executed repeatedly
//
PatternAbbreviatorFragment terminalFragment =
fragments[fragments.length - 1];
while (pos < name.length()) {
pos = terminalFragment.abbreviate(buf, name, pos);
}
}
}
}
1.4 +4 -4 logging-log4j/tests/input/pattern/patternLayout14.properties
1.9 +19 -0 logging-log4j/tests/src/java/org/apache/log4j/PatternLayoutTest.java
Index: PatternLayoutTest.java
===================================================================
RCS file: /home/cvs/logging-log4j/tests/src/java/org/apache/log4j/PatternLayoutTest.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- PatternLayoutTest.java 28 Dec 2004 23:08:12 -0000 1.8
+++ PatternLayoutTest.java 7 Mar 2005 23:50:27 -0000 1.9
@@ -287,6 +287,25 @@
assertTrue(Compare.compare(FILTERED, "witness/pattern/patternLayout.13"));
}
+ /**
+ * Test of class abbreviation.
+ *
+ * @throws Exception
+ */
+ public void test14() throws Exception {
+ PropertyConfigurator.configure("input/pattern/patternLayout14.properties");
+ common();
+
+ Transformer.transform(
+ TEMP, FILTERED,
+ new Filter[] {
+ new LineNumberFilter(), new SunReflectFilter(),
+ new JunitTestRunnerFilter()
+ });
+ assertTrue(Compare.compare(FILTERED, "witness/pattern/patternLayout.14"));
+ }
+
+
public void testMDC1() throws Exception {
PropertyConfigurator.configure("input/pattern/patternLayout.mdc.1.properties");
MDC.put("key1", "va11");
1.9 +8 -6 logging-log4j/tests/src/java/org/apache/log4j/pattern/PatternParserTest.java
Index: PatternParserTest.java
===================================================================
RCS file: /home/cvs/logging-log4j/tests/src/java/org/apache/log4j/pattern/PatternParserTest.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- PatternParserTest.java 4 Jan 2005 19:42:10 -0000 1.8
+++ PatternParserTest.java 7 Mar 2005 23:50:27 -0000 1.9
@@ -17,6 +17,8 @@
package org.apache.log4j.pattern;
import junit.framework.TestCase;
+import junit.framework.Test;
+import junit.framework.TestSuite;
import org.apache.log4j.Layout;
import org.apache.log4j.Level;
@@ -166,10 +168,10 @@
}
-// public static Test suite() {
-// TestSuite suite = new TestSuite();
-// suite.addTest(new PatternParserTest("testBasic2"));
-//
-// return suite;
-// }
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTestSuite(PatternParserTest.class);
+ suite.addTestSuite(NameAbbreviatorTest.class);
+ return suite;
+ }
}
1.1 logging-log4j/tests/src/java/org/apache/log4j/pattern/NameAbbreviatorTest.java
Index: NameAbbreviatorTest.java
===================================================================
/*
* Copyright 1999,2005 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.pattern;
import junit.framework.TestCase;
/**
* Tests for NameAbbrevator.
*
* @author Curt Arnold
* @since 1.3
*
*/
public class NameAbbreviatorTest extends TestCase {
/**
* Create a new instance.
*
* @param name test name
*/
public NameAbbreviatorTest(final String name) {
super(name);
}
/**
* Check that getDefaultAbbreviator does not return null.
*
*/
public void testGetDefault() {
NameAbbreviator abbrev = NameAbbreviator.getDefaultAbbreviator();
assertNotNull(abbrev);
}
/**
* Check that "0" drops all name content.
*
*/
public void testZero() {
NameAbbreviator abbrev = NameAbbreviator.getAbbreviator("0");
StringBuffer buf = new StringBuffer("DEBUG - ");
abbrev.abbreviate(buf, "org.example.foo.bar");
assertEquals("DEBUG - ", buf.toString());
}
/**
* Check that getAbbreviator(" ") returns default abbreviator.
*
*/
public void testBlank() {
NameAbbreviator abbrev = NameAbbreviator.getAbbreviator(" ");
NameAbbreviator defaultAbbrev = NameAbbreviator.getDefaultAbbreviator();
assertTrue(abbrev == defaultAbbrev);
}
/**
* Check that getAbbreviator("1").abbreviate() drops all but the final name element.
*
*/
public void testOne() {
NameAbbreviator abbrev = NameAbbreviator.getAbbreviator("1");
StringBuffer buf = new StringBuffer("DEBUG - ");
abbrev.abbreviate(buf, "org.example.foo.bar");
assertEquals("DEBUG - bar", buf.toString());
buf.setLength(0);
buf.append("DEBUG - ");
abbrev.abbreviate(buf, "bar");
assertEquals("DEBUG - bar", buf.toString());
buf.setLength(0);
buf.append("DEBUG - ");
abbrev.abbreviate(buf, "");
assertEquals("DEBUG - ", buf.toString());
}
/**
* Check that blanks are trimmed in evaluating abbreviation pattern.
*/
public void testBlankOne() {
NameAbbreviator abbrev = NameAbbreviator.getAbbreviator(" 1 ");
StringBuffer buf = new StringBuffer("DEBUG - ");
abbrev.abbreviate(buf, "org.example.foo.bar");
assertEquals("DEBUG - bar", buf.toString());
buf.setLength(0);
buf.append("DEBUG - ");
abbrev.abbreviate(buf, "bar");
assertEquals("DEBUG - bar", buf.toString());
buf.setLength(0);
buf.append("DEBUG - ");
abbrev.abbreviate(buf, "");
assertEquals("DEBUG - ", buf.toString());
}
/**
* Check that getAbbreviator("2").abbreviate drops all but the last two elements.
*
*/
public void testTwo() {
NameAbbreviator abbrev = NameAbbreviator.getAbbreviator("2");
StringBuffer buf = new StringBuffer("DEBUG - ");
abbrev.abbreviate(buf, "org.example.foo.bar");
assertEquals("DEBUG - foo.bar", buf.toString());
buf.setLength(0);
buf.append("DEBUG - ");
abbrev.abbreviate(buf, "foo.bar");
assertEquals("DEBUG - foo.bar", buf.toString());
buf.setLength(0);
buf.append("DEBUG - ");
abbrev.abbreviate(buf, "bar");
assertEquals("DEBUG - bar", buf.toString());
}
/**
* Check that getAbbreviator("1.").abbreviate abbreviates non-final elements
* to one character.
*
*/
public void testOneDot() {
NameAbbreviator abbrev = NameAbbreviator.getAbbreviator("1.");
StringBuffer buf = new StringBuffer("DEBUG - ");
abbrev.abbreviate(buf, "org.example.foo.bar");
assertEquals("DEBUG - o.e.f.bar", buf.toString());
buf.setLength(0);
buf.append("DEBUG - ");
abbrev.abbreviate(buf, "org.example.foo.");
assertEquals("DEBUG - o.e.f.", buf.toString());
buf.setLength(0);
buf.append("DEBUG - ");
abbrev.abbreviate(buf, "foo.bar");
assertEquals("DEBUG - f.bar", buf.toString());
buf.setLength(0);
buf.append("DEBUG - ");
abbrev.abbreviate(buf, "bar");
assertEquals("DEBUG - bar", buf.toString());
buf.setLength(0);
buf.append("DEBUG - ");
abbrev.abbreviate(buf, "");
assertEquals("DEBUG - ", buf.toString());
buf.setLength(0);
buf.append("DEBUG - ");
abbrev.abbreviate(buf, ".");
assertEquals("DEBUG - .", buf.toString());
}
/**
* Check that getAbbreviator("1~.").abbreviate abbreviates non-final elements
* to one character and a tilde.
*
*/
public void testOneTildeDot() {
NameAbbreviator abbrev = NameAbbreviator.getAbbreviator("1~.");
StringBuffer buf = new StringBuffer("DEBUG - ");
abbrev.abbreviate(buf, "org.example.foo.bar");
assertEquals("DEBUG - o~.e~.f~.bar", buf.toString());
buf.setLength(0);
buf.append("DEBUG - ");
abbrev.abbreviate(buf, "org.example.foo.");
assertEquals("DEBUG - o~.e~.f~.", buf.toString());
buf.setLength(0);
buf.append("DEBUG - ");
abbrev.abbreviate(buf, "foo.bar");
assertEquals("DEBUG - f~.bar", buf.toString());
buf.setLength(0);
buf.append("DEBUG - ");
abbrev.abbreviate(buf, "bar");
assertEquals("DEBUG - bar", buf.toString());
buf.setLength(0);
buf.append("DEBUG - ");
abbrev.abbreviate(buf, "");
assertEquals("DEBUG - ", buf.toString());
buf.setLength(0);
buf.append("DEBUG - ");
abbrev.abbreviate(buf, ".");
assertEquals("DEBUG - .", buf.toString());
buf.setLength(0);
buf.append("DEBUG - ");
abbrev.abbreviate(buf, "o.e.f.bar");
assertEquals("DEBUG - o.e.f.bar", buf.toString());
}
/**
* Check that getAbbreviator("1.*.2").abbreviate drops all but the first
* character from the first element, uses all of the second element and
* drops all but the first two characters of the rest of the non-final elements.
*
*/
public void testMulti() {
NameAbbreviator abbrev = NameAbbreviator.getAbbreviator("1.*.2");
StringBuffer buf = new StringBuffer("DEBUG - ");
abbrev.abbreviate(buf, "org.example.foo.bar");
assertEquals("DEBUG - o.example.fo.bar", buf.toString());
buf.setLength(0);
buf.append("DEBUG - ");
abbrev.abbreviate(buf, "org.example.foo.");
assertEquals("DEBUG - o.example.fo.", buf.toString());
buf.setLength(0);
buf.append("DEBUG - ");
abbrev.abbreviate(buf, "foo.bar");
assertEquals("DEBUG - f.bar", buf.toString());
buf.setLength(0);
buf.append("DEBUG - ");
abbrev.abbreviate(buf, "bar");
assertEquals("DEBUG - bar", buf.toString());
buf.setLength(0);
buf.append("DEBUG - ");
abbrev.abbreviate(buf, "");
assertEquals("DEBUG - ", buf.toString());
buf.setLength(0);
buf.append("DEBUG - ");
abbrev.abbreviate(buf, ".");
assertEquals("DEBUG - .", buf.toString());
}
}
1.2 +15 -15 logging-log4j/tests/witness/pattern/patternLayout.14
Index: patternLayout.14
===================================================================
RCS file: /home/cvs/logging-log4j/tests/witness/pattern/patternLayout.14,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- patternLayout.14 20 Nov 2004 12:58:23 -0000 1.1
+++ patternLayout.14 7 Mar 2005 23:50:27 -0000 1.2
@@ -1,14 +1,14 @@
-DEBUG 1 - Message 0
-DEBUG 2 - Message 0
- INFO 3 - Message 1
- INFO 4 - Message 1
- WARN 5 - Message 2
- WARN 6 - Message 2
-ERROR 7 - Message 3
-ERROR 8 - Message 3
-FATAL 9 - Message 4
-FATAL 10 - Message 4
-DEBUG 11 - Message 5
+DEBUG [main] o.a.l.PatternLayoutTest: Message 0
+DEBUG [main] root: Message 0
+INFO [main] o.a.l.PatternLayoutTest: Message 1
+INFO [main] root: Message 1
+WARN [main] o.a.l.PatternLayoutTest: Message 2
+WARN [main] root: Message 2
+ERROR [main] o.a.l.PatternLayoutTest: Message 3
+ERROR [main] root: Message 3
+FATAL [main] o.a.l.PatternLayoutTest: Message 4
+FATAL [main] root: Message 4
+DEBUG [main] o.a.l.PatternLayoutTest: Message 5
java.lang.Exception: Just testing
at org.apache.log4j.PatternLayoutTest.common(X)
at org.apache.log4j.PatternLayoutTest.test14(X)
@@ -21,7 +21,7 @@
at junit.framework.TestCase.run(X)
at junit.framework.TestSuite.runTest(X)
at junit.framework.TestSuite.run(X)
- INFO 12 - Message 6
+INFO [main] o.a.l.PatternLayoutTest: Message 6
java.lang.Exception: Just testing
at org.apache.log4j.PatternLayoutTest.common(X)
at org.apache.log4j.PatternLayoutTest.test14(X)
@@ -34,7 +34,7 @@
at junit.framework.TestCase.run(X)
at junit.framework.TestSuite.runTest(X)
at junit.framework.TestSuite.run(X)
- WARN 13 - Message 7
+WARN [main] o.a.l.PatternLayoutTest: Message 7
java.lang.Exception: Just testing
at org.apache.log4j.PatternLayoutTest.common(X)
at org.apache.log4j.PatternLayoutTest.test14(X)
@@ -47,7 +47,7 @@
at junit.framework.TestCase.run(X)
at junit.framework.TestSuite.runTest(X)
at junit.framework.TestSuite.run(X)
-ERROR 14 - Message 8
+ERROR [main] o.a.l.PatternLayoutTest: Message 8
java.lang.Exception: Just testing
at org.apache.log4j.PatternLayoutTest.common(X)
at org.apache.log4j.PatternLayoutTest.test14(X)
@@ -60,7 +60,7 @@
at junit.framework.TestCase.run(X)
at junit.framework.TestSuite.runTest(X)
at junit.framework.TestSuite.run(X)
-FATAL 15 - Message 9
+FATAL [main] o.a.l.PatternLayoutTest: Message 9
java.lang.Exception: Just testing
at org.apache.log4j.PatternLayoutTest.common(X)
at org.apache.log4j.PatternLayoutTest.test14(X)
---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org