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.logging.log4j.core.pattern;
019
020/**
021 * Modifies the output of a pattern converter for a specified minimum and maximum width and alignment.
022 */
023public final class FormattingInfo {
024    /**
025     * Array of spaces.
026     */
027    private static final char[] SPACES = new char[] { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' };
028
029    /**
030     * Default instance.
031     */
032    private static final FormattingInfo DEFAULT = new FormattingInfo(false, 0, Integer.MAX_VALUE, true);
033
034    /**
035     * Minimum length.
036     */
037    private final int minLength;
038
039    /**
040     * Maximum length.
041     */
042    private final int maxLength;
043
044    /**
045     * Alignment.
046     */
047    private final boolean leftAlign;
048
049    /**
050     * Left vs. right-hand side truncation.
051     */
052    private final boolean leftTruncate;
053
054    /**
055     * Creates new instance.
056     *
057     * @param leftAlign
058     *            left align if true.
059     * @param minLength
060     *            minimum length.
061     * @param maxLength
062     *            maximum length.
063     */
064    public FormattingInfo(final boolean leftAlign, final int minLength, final int maxLength, final boolean leftTruncate) {
065        this.leftAlign = leftAlign;
066        this.minLength = minLength;
067        this.maxLength = maxLength;
068        this.leftTruncate = leftTruncate;
069    }
070
071    /**
072     * Gets default instance.
073     *
074     * @return default instance.
075     */
076    public static FormattingInfo getDefault() {
077        return DEFAULT;
078    }
079
080    /**
081     * Determine if left aligned.
082     *
083     * @return true if left aligned.
084     */
085    public boolean isLeftAligned() {
086        return leftAlign;
087    }
088
089    /**
090     * Determine if left truncated.
091     *
092     * @return true if left truncated.
093     */
094    public boolean isLeftTruncate() {
095                return leftTruncate;
096        }
097
098    /**
099     * Get minimum length.
100     *
101     * @return minimum length.
102     */
103    public int getMinLength() {
104        return minLength;
105    }
106
107    /**
108     * Get maximum length.
109     *
110     * @return maximum length.
111     */
112    public int getMaxLength() {
113        return maxLength;
114    }
115
116    /**
117     * Adjust the content of the buffer based on the specified lengths and alignment.
118     *
119     * @param fieldStart
120     *            start of field in buffer.
121     * @param buffer
122     *            buffer to be modified.
123     */
124    public void format(final int fieldStart, final StringBuilder buffer) {
125        final int rawLength = buffer.length() - fieldStart;
126
127        if (rawLength > maxLength) {
128                        if (leftTruncate) {
129                                buffer.delete(fieldStart, buffer.length() - maxLength);
130                        } else {
131                                buffer.delete(fieldStart + maxLength, fieldStart + buffer.length());
132                        }
133        } else if (rawLength < minLength) {
134            if (leftAlign) {
135                final int fieldEnd = buffer.length();
136                buffer.setLength(fieldStart + minLength);
137
138                for (int i = fieldEnd; i < buffer.length(); i++) {
139                    buffer.setCharAt(i, ' ');
140                }
141            } else {
142                int padLength = minLength - rawLength;
143
144                for (; padLength > SPACES.length; padLength -= SPACES.length) {
145                    buffer.insert(fieldStart, SPACES);
146                }
147
148                buffer.insert(fieldStart, SPACES, 0, padLength);
149            }
150        }
151    }
152
153    /**
154     * Returns a String suitable for debugging.
155     *
156     * @return a String suitable for debugging.
157     */
158    @Override
159    public String toString() {
160        final StringBuilder sb = new StringBuilder();
161        sb.append(super.toString());
162        sb.append("[leftAlign=");
163        sb.append(leftAlign);
164        sb.append(", maxLength=");
165        sb.append(maxLength);
166        sb.append(", minLength=");
167        sb.append(minLength);
168        sb.append(", leftTruncate=");
169        sb.append(leftTruncate);
170        sb.append(']');
171        return sb.toString();
172    }
173
174}