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&uuml;lc&uuml;
    * @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