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     * @param leftTruncate
064     *            truncates to the left if true
065     */
066    public FormattingInfo(final boolean leftAlign, final int minLength, final int maxLength, final boolean leftTruncate) {
067        this.leftAlign = leftAlign;
068        this.minLength = minLength;
069        this.maxLength = maxLength;
070        this.leftTruncate = leftTruncate;
071    }
072
073    /**
074     * Gets default instance.
075     *
076     * @return default instance.
077     */
078    public static FormattingInfo getDefault() {
079        return DEFAULT;
080    }
081
082    /**
083     * Determine if left aligned.
084     *
085     * @return true if left aligned.
086     */
087    public boolean isLeftAligned() {
088        return leftAlign;
089    }
090
091    /**
092     * Determine if left truncated.
093     *
094     * @return true if left truncated.
095     */
096    public boolean isLeftTruncate() {
097                return leftTruncate;
098        }
099
100    /**
101     * Get minimum length.
102     *
103     * @return minimum length.
104     */
105    public int getMinLength() {
106        return minLength;
107    }
108
109    /**
110     * Get maximum length.
111     *
112     * @return maximum length.
113     */
114    public int getMaxLength() {
115        return maxLength;
116    }
117
118    /**
119     * Adjust the content of the buffer based on the specified lengths and alignment.
120     *
121     * @param fieldStart
122     *            start of field in buffer.
123     * @param buffer
124     *            buffer to be modified.
125     */
126    public void format(final int fieldStart, final StringBuilder buffer) {
127        final int rawLength = buffer.length() - fieldStart;
128
129        if (rawLength > maxLength) {
130                        if (leftTruncate) {
131                                buffer.delete(fieldStart, buffer.length() - maxLength);
132                        } else {
133                                buffer.delete(fieldStart + maxLength, fieldStart + buffer.length());
134                        }
135        } else if (rawLength < minLength) {
136            if (leftAlign) {
137                final int fieldEnd = buffer.length();
138                buffer.setLength(fieldStart + minLength);
139
140                for (int i = fieldEnd; i < buffer.length(); i++) {
141                    buffer.setCharAt(i, ' ');
142                }
143            } else {
144                int padLength = minLength - rawLength;
145
146                for (; padLength > SPACES.length; padLength -= SPACES.length) {
147                    buffer.insert(fieldStart, SPACES);
148                }
149
150                buffer.insert(fieldStart, SPACES, 0, padLength);
151            }
152        }
153    }
154
155    /**
156     * Returns a String suitable for debugging.
157     *
158     * @return a String suitable for debugging.
159     */
160    @Override
161    public String toString() {
162        final StringBuilder sb = new StringBuilder();
163        sb.append(super.toString());
164        sb.append("[leftAlign=");
165        sb.append(leftAlign);
166        sb.append(", maxLength=");
167        sb.append(maxLength);
168        sb.append(", minLength=");
169        sb.append(minLength);
170        sb.append(", leftTruncate=");
171        sb.append(leftTruncate);
172        sb.append(']');
173        return sb.toString();
174    }
175
176}