root/trunk/src/java/org/jcoderz/commons/logging/FixLengthFormat.java

Revision 1299, 9.7 kB (checked in by amandel, 3 years ago)
  • Log formatter ignores the category field but now outputs the last 9 characters of the thread name. In case of a ordinary log record the the name of the logger thread is used. This might be wrong in certain setups but is correct in many cases. The fawkeZ loggable records the thread name of the thread that created the loggable instance which is the correct thread name in all cases. #58
  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1/*
2 * $Id$
3 *
4 * Copyright 2006, The jCoderZ.org Project. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 *    * Redistributions of source code must retain the above copyright
11 *      notice, this list of conditions and the following disclaimer.
12 *    * Redistributions in binary form must reproduce the above
13 *      copyright notice, this list of conditions and the following
14 *      disclaimer in the documentation and/or other materials
15 *      provided with the distribution.
16 *    * Neither the name of the jCoderZ.org Project nor the names of
17 *      its contributors may be used to endorse or promote products
18 *      derived from this software without specific prior written
19 *      permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33package org.jcoderz.commons.logging;
34
35import java.io.ObjectStreamException;
36import java.io.Serializable;
37import java.nio.CharBuffer;
38import java.text.FieldPosition;
39import java.text.Format;
40import java.text.ParsePosition;
41import java.util.Arrays;
42
43/**
44 * This is used to format a String to a fixed length String. Strings, which are
45 * are longer than the configured length, are split after the appropriate number
46 * of chars; Strings which are shorter, are left padded with the configured
47 * padding char. When parsing a String, the configured number of chars is read
48 * from the source String and the padding char is left trimmed from the
49 * resulting String.
50 *
51 */
52public class FixLengthFormat
53      extends Format
54{
55   /**
56    * The string is left padded with the padding char to get the full sized
57    * string.
58    */
59   public static final Padding LEFT_PADDING = new Padding();
60
61   /**
62    * The string is right padded with the padding char to get the full sized
63    * string.
64    */
65   public static final Padding RIGHT_PADDING = new Padding();
66
67   /**
68    * The string is right padded with the padding char to get the full sized
69    * string or cut on the left side if it dues not fit the length.
70    */
71   public static final Padding LEFT_CUT_RIGHT_PADDING = new Padding();
72
73   private static final Padding[] PADDINGS = {LEFT_PADDING, RIGHT_PADDING,
74       LEFT_CUT_RIGHT_PADDING};
75
76   private static final long serialVersionUID = 3256720688978278194L;
77
78   private static final char DEFAULT_PADDING_CHAR = ' ';
79
80   private final char[] mAllPadding;
81
82   private final Padding mType;
83
84   /**
85    * This class implements a typesafe enumeration for the padding type.
86    *
87    */
88   private static final class Padding
89         implements Comparable, Serializable
90   {
91      private static final long serialVersionUID = 3258410642577831730L;
92
93      private static int sOrdinal = 0;
94      private final int mOrdinal;
95
96      private Padding ()
97      {
98         mOrdinal = sOrdinal++;
99      }
100
101      private Object readResolve ()
102            throws ObjectStreamException
103      {
104         return PADDINGS[mOrdinal];
105      }
106
107      /** {@inheritDoc} */
108      public int compareTo (Object o)
109      {
110         return mOrdinal - ((Padding) o).mOrdinal;
111      }
112   }
113
114   /**
115    * Generates an instance of this with the default padding character, which
116    * is a space.
117    *
118    * @param fixedLength all formatted strings will have this length, either
119    * they are cut or padded with spaces.
120    * @param type the type of padding, either {@linkplain #LEFT_PADDING} or
121    * {@linkplain #RIGHT_PADDING}
122    *
123    * @throws IllegalArgumentException if <code>fixedLength <= 0</code>
124    */
125   public FixLengthFormat (final int fixedLength, final Padding type)
126   {
127      this(fixedLength, type, DEFAULT_PADDING_CHAR);
128   }
129
130   /**
131    * Generates an instance of this with <code>paddingChar</code> as padding
132    * character.
133    *
134    * @param fixedLength all formatted strings will have this length, either
135    * they are cut or padded with <code>paddingChar</code>
136    * @param type the type of padding, either {@linkplain #LEFT_PADDING} or
137    * {@linkplain #RIGHT_PADDING}
138    * @param paddingChar the character to use for padding.
139    *
140    * @throws IllegalArgumentException if <code>fixedLength <= 0</code>
141    *
142    */
143   public FixLengthFormat (
144         final int fixedLength,
145         final Padding type,
146         final char paddingChar)
147   {
148      super();
149      if (fixedLength <= 0)
150      {
151         throw new IllegalArgumentException("Fixed length must be >= 0, but is "
152               + fixedLength);
153      }
154
155      mType = type;
156      mAllPadding = new char[fixedLength];
157      Arrays.fill(mAllPadding, paddingChar);
158   }
159
160   /**
161    * Parses the source string for a padded string from the position given by
162    * <code>pos</code>. It reads the configured number of chars and trims
163    * all chars equal to the padding character, either from left or from right,
164    * according to the configured type of this.
165    * If the given source string is not long enough, the index of
166    * <code>pos</code> is not modified, but the error index is set to its
167    * current index and null is returned.
168    *
169    * @see java.text.Format#parseObject(java.lang.String, java.text.ParsePosition)
170    *
171    * @param source the string to parse
172    * @param pos the parse position where to start parsing within
173    * <code>source</code>. This will be updated after parsing.
174    *
175    * @return null if not enough chars to read from <code>source</code>;
176    * else parsed String, one-side trimmed from padding char.
177    */
178   public Object parseObject (String source, ParsePosition pos)
179   {
180      String rc = null;
181
182      if (pos.getIndex() + mAllPadding.length > source.length())
183      {
184         pos.setErrorIndex(pos.getIndex());
185      }
186      else
187      {
188         final CharBuffer paddedString = CharBuffer.wrap(source,
189               pos.getIndex(), pos.getIndex() + mAllPadding.length);
190
191         if (paddedString.length() != mAllPadding.length)
192         {
193            pos.setErrorIndex(pos.getIndex());
194         }
195         else
196         {
197            rc = parse(paddedString, pos).toString();
198         }
199      }
200      return rc;
201   }
202
203   /**
204    * Formats a string to be of a certain length. If the string is longer than
205    * the configured length; it is cut and the first part being appended to the
206    * StringBuffer, if it is shorter, this call pads it with the configured
207    * char.
208    *
209    * @param obj the String to be formatted, must not be null.
210    * @param toAppendTo the StringBuffer to which to append the formatted String
211    * @param pos field position
212    *
213    * @return StringBuffer where the formatted object has been appended to.
214    *
215    * @see java.text.Format#format(java.lang.Object, java.lang.StringBuffer, java.text.FieldPosition)
216    */
217   public StringBuffer format (Object obj, StringBuffer toAppendTo,
218         FieldPosition pos)
219   {
220      if (obj == null)
221      {
222         throw new NullPointerException(
223               "Supplied object to format must not be null");
224      }
225      else if (! (obj instanceof String))
226      {
227         throw new IllegalArgumentException("Supplied object to be formatted "
228               + "must be a String but is "
229               + obj.getClass().getName() + ": " + obj);
230      }
231      else
232      {
233         pos.setBeginIndex(0);
234         pos.setEndIndex(0);
235         final String toBeFormatted = (String) obj;
236         final int len = toBeFormatted.length();
237         if (len > mAllPadding.length && mType == LEFT_CUT_RIGHT_PADDING)
238         {
239             toAppendTo.append(toBeFormatted.substring(
240                 len - mAllPadding.length));
241         }
242         else if (len > mAllPadding.length)
243         {
244            toAppendTo.append(toBeFormatted.substring(0, mAllPadding.length));
245         }
246         else if (len < mAllPadding.length)
247         {
248            if (mType == LEFT_PADDING)
249            {
250               toAppendTo.append(mAllPadding, 0, mAllPadding.length - len);
251               toAppendTo.append(toBeFormatted);
252            }
253            else
254            {
255               toAppendTo.append(toBeFormatted);
256               toAppendTo.append(mAllPadding, 0, mAllPadding.length - len);
257            }
258         }
259         else
260         {
261            toAppendTo.append(toBeFormatted);
262         }
263      }
264      return toAppendTo;
265   }
266
267   private CharSequence parse (
268         final CharBuffer paddedString,
269         final ParsePosition pos)
270   {
271      CharSequence rc = null;
272
273      pos.setIndex(pos.getIndex() + mAllPadding.length);
274
275      final char pad = mAllPadding[0];
276      if (mType == LEFT_PADDING)
277      {
278         int i = 0;
279         while ((i < mAllPadding.length)
280               && (paddedString.charAt(i) == pad))
281         {
282            ++i;
283         }
284         rc = paddedString.subSequence(i, mAllPadding.length);
285      }
286      else
287      {
288         int i = mAllPadding.length - 1;
289         while ((i >= 0) && (paddedString.charAt(i) == pad))
290         {
291            --i;
292         }
293         if (i < 0)
294         {
295            rc = "";
296         }
297         else
298         {
299            rc = paddedString.subSequence(0, i + 1);
300         }
301      }
302      return rc;
303   }
304}
Note: See TracBrowser for help on using the browser.