001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 * 
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 * 
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.apache.log4j.helpers;
019
020import org.apache.log4j.spi.LoggingEvent;
021
022/**
023
024   <p>PatternConverter is an abtract class that provides the
025   formatting functionality that derived classes need.
026
027   <p>Conversion specifiers in a conversion patterns are parsed to
028   individual PatternConverters. Each of which is responsible for
029   converting a logging event in a converter specific manner.
030
031   @author <a href="mailto:cakalijp@Maritz.com">James P. Cakalic</a>
032   @author Ceki G&uuml;lc&uuml;
033
034   @since 0.8.2
035 */
036public abstract class PatternConverter {
037  public PatternConverter next;
038  int min = -1;
039  int max = 0x7FFFFFFF;
040  boolean leftAlign = false;
041
042  protected
043  PatternConverter() {  }
044  
045  protected
046  PatternConverter(FormattingInfo fi) {
047    min = fi.min;
048    max = fi.max;
049    leftAlign = fi.leftAlign;
050  }
051
052  /**
053     Derived pattern converters must override this method in order to
054     convert conversion specifiers in the correct way.
055  */
056  abstract
057  protected
058  String convert(LoggingEvent event);
059
060  /**
061     A template method for formatting in a converter specific way.
062   */
063  public
064  void format(StringBuffer sbuf, LoggingEvent e) {
065    String s = convert(e);
066
067    if(s == null) {
068      if(0 < min)
069        spacePad(sbuf, min);
070      return;
071    }
072
073    int len = s.length();
074
075    if(len > max)
076      sbuf.append(s.substring(len-max));
077    else if(len < min) {
078      if(leftAlign) {   
079        sbuf.append(s);
080        spacePad(sbuf, min-len);
081      }
082      else {
083        spacePad(sbuf, min-len);
084        sbuf.append(s);
085      }
086    }
087    else
088      sbuf.append(s);
089  }     
090
091  static String[] SPACES = {" ", "  ", "    ", "        ", //1,2,4,8 spaces
092                            "                ", // 16 spaces
093                            "                                " }; // 32 spaces
094
095  /**
096     Fast space padding method.
097  */
098  public
099  void spacePad(StringBuffer sbuf, int length) {
100    while(length >= 32) {
101      sbuf.append(SPACES[5]);
102      length -= 32;
103    }
104    
105    for(int i = 4; i >= 0; i--) {       
106      if((length & (1<<i)) != 0) {
107        sbuf.append(SPACES[i]);
108      }
109    }
110  }
111}