View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache license, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License. You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the license for the specific language governing permissions and
15   * limitations under the license.
16   */
17  
18  package org.apache.logging.log4j.core.pattern;
19  
20  import org.apache.logging.log4j.util.PerformanceSensitive;
21  
22  /**
23   * Modifies the output of a pattern converter for a specified minimum and maximum width and alignment.
24   */
25  @PerformanceSensitive("allocation")
26  public final class FormattingInfo {
27      /**
28       * Array of spaces.
29       */
30      private static final char[] SPACES = new char[] { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' };
31  
32      /**
33       * Array of zeros.
34       */
35      private static final char[] ZEROS = new char[] { '0', '0', '0', '0', '0', '0', '0', '0' };
36  
37      /**
38       * Default instance.
39       */
40      private static final FormattingInfo DEFAULT = new FormattingInfo(false, 0, Integer.MAX_VALUE, true);
41  
42      /**
43       * Minimum length.
44       */
45      private final int minLength;
46  
47      /**
48       * Maximum length.
49       */
50      private final int maxLength;
51  
52      /**
53       * Alignment.
54       */
55      private final boolean leftAlign;
56  
57      /**
58       * Left vs. right-hand side truncation.
59       */
60      private final boolean leftTruncate;
61  
62      /**
63       * Use zero-padding instead whitespace padding
64       */
65      private final boolean zeroPad;
66  
67      /**
68       * Creates new instance.
69       *
70       * @param leftAlign
71       *            left align if true.
72       * @param minLength
73       *            minimum length.
74       * @param maxLength
75       *            maximum length.
76       * @param leftTruncate
77       *            truncates to the left if true
78       */
79      public FormattingInfo(final boolean leftAlign, final int minLength, final int maxLength, final boolean leftTruncate) {
80          this(leftAlign, minLength, maxLength, leftTruncate, false);
81      }
82  
83      /**
84       * Creates new instance.
85       *
86       * @param leftAlign
87       *            left align if true.
88       * @param minLength
89       *            minimum length.
90       * @param maxLength
91       *            maximum length.
92       * @param leftTruncate
93       *            truncates to the left if true
94       * @param zeroPad
95       *            use zero-padding instead of whitespace-padding
96       */
97      public FormattingInfo(final boolean leftAlign, final int minLength, final int maxLength, final boolean leftTruncate, final boolean zeroPad) {
98          this.leftAlign = leftAlign;
99          this.minLength = minLength;
100         this.maxLength = maxLength;
101         this.leftTruncate = leftTruncate;
102         this.zeroPad = zeroPad;
103     }
104 
105     /**
106      * Gets default instance.
107      *
108      * @return default instance.
109      */
110     public static FormattingInfo getDefault() {
111         return DEFAULT;
112     }
113 
114     /**
115      * Determine if left aligned.
116      *
117      * @return true if left aligned.
118      */
119     public boolean isLeftAligned() {
120         return leftAlign;
121     }
122 
123     /**
124      * Determine if left truncated.
125      *
126      * @return true if left truncated.
127      */
128     public boolean isLeftTruncate() {
129 		return leftTruncate;
130 	}
131 
132     /**
133      * Determine if zero-padded.
134      *
135      * @return true if zero-padded.
136      */
137     public boolean isZeroPad() {
138         return zeroPad;
139     }
140 
141     /**
142      * Get minimum length.
143      *
144      * @return minimum length.
145      */
146     public int getMinLength() {
147         return minLength;
148     }
149 
150     /**
151      * Get maximum length.
152      *
153      * @return maximum length.
154      */
155     public int getMaxLength() {
156         return maxLength;
157     }
158 
159     /**
160      * Adjust the content of the buffer based on the specified lengths and alignment.
161      *
162      * @param fieldStart
163      *            start of field in buffer.
164      * @param buffer
165      *            buffer to be modified.
166      */
167     public void format(final int fieldStart, final StringBuilder buffer) {
168         final int rawLength = buffer.length() - fieldStart;
169 
170         if (rawLength > maxLength) {
171 			if (leftTruncate) {
172 				buffer.delete(fieldStart, buffer.length() - maxLength);
173 			} else {
174 				buffer.delete(fieldStart + maxLength, fieldStart + buffer.length());
175 			}
176         } else if (rawLength < minLength) {
177             if (leftAlign) {
178                 final int fieldEnd = buffer.length();
179                 buffer.setLength(fieldStart + minLength);
180 
181                 for (int i = fieldEnd; i < buffer.length(); i++) {
182                     buffer.setCharAt(i, ' ');
183                 }
184             } else {
185                 int padLength = minLength - rawLength;
186 
187                 final char[] paddingArray= zeroPad ? ZEROS : SPACES;
188 
189                 for (; padLength > paddingArray.length; padLength -= paddingArray.length) {
190                     buffer.insert(fieldStart, paddingArray);
191                 }
192 
193                 buffer.insert(fieldStart, paddingArray, 0, padLength);
194             }
195         }
196     }
197 
198     /**
199      * Returns a String suitable for debugging.
200      *
201      * @return a String suitable for debugging.
202      */
203     @Override
204     public String toString() {
205         final StringBuilder sb = new StringBuilder();
206         sb.append(super.toString());
207         sb.append("[leftAlign=");
208         sb.append(leftAlign);
209         sb.append(", maxLength=");
210         sb.append(maxLength);
211         sb.append(", minLength=");
212         sb.append(minLength);
213         sb.append(", leftTruncate=");
214         sb.append(leftTruncate);
215         sb.append(", zeroPad=");
216         sb.append(zeroPad);
217         sb.append(']');
218         return sb.toString();
219     }
220 
221 }