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  package org.apache.commons.lang3.text;
18  
19  import static java.util.FormattableFlags.LEFT_JUSTIFY;
20  
21  import java.util.Formattable;
22  import java.util.Formatter;
23  
24  import org.apache.commons.lang3.ObjectUtils;
25  import org.apache.commons.lang3.StringUtils;
26  import org.apache.commons.lang3.Validate;
27  
28  /**
29   * <p>Provides utilities for working with the {@code Formattable} interface.</p>
30   * 
31   * <p>The {@link Formattable} interface provides basic control over formatting
32   * when using a {@code Formatter}. It is primarily concerned with numeric precision
33   * and padding, and is not designed to allow generalised alternate formats.</p>
34   * 
35   * @since Lang 3.0
36   */
37  public class FormattableUtils {
38  
39      /**
40       * A format that simply outputs the value as a string.
41       */
42      private static final String SIMPLEST_FORMAT = "%s";
43  
44      /**
45       * <p>{@code FormattableUtils} instances should NOT be constructed in
46       * standard programming. Instead, the methods of the class should be invoked
47       * statically.</p>
48       * 
49       * <p>This constructor is public to permit tools that require a JavaBean
50       * instance to operate.</p>
51       */
52      public FormattableUtils() {
53          super();
54      }
55  
56      //-----------------------------------------------------------------------
57      /**
58       * Get the default formatted representation of the specified
59       * {@code Formattable}.
60       * 
61       * @param formattable  the instance to convert to a string, not null
62       * @return the resulting string, not null
63       */
64      public static String toString(final Formattable formattable) {
65          return String.format(SIMPLEST_FORMAT, formattable);
66      }
67  
68      /**
69       * Handles the common {@code Formattable} operations of truncate-pad-append,
70       * with no ellipsis on precision overflow, and padding width underflow with
71       * spaces.
72       * 
73       * @param seq  the string to handle, not null
74       * @param formatter  the destination formatter, not null
75       * @param flags  the flags for formatting, see {@code Formattable}
76       * @param width  the width of the output, see {@code Formattable}
77       * @param precision  the precision of the output, see {@code Formattable}
78       * @return the {@code formatter} instance, not null
79       */
80      public static Formatter append(final CharSequence seq, final Formatter formatter, final int flags, final int width,
81              final int precision) {
82          return append(seq, formatter, flags, width, precision, ' ', null);
83      }
84  
85      /**
86       * Handles the common {@link Formattable} operations of truncate-pad-append,
87       * with no ellipsis on precision overflow.
88       * 
89       * @param seq  the string to handle, not null
90       * @param formatter  the destination formatter, not null
91       * @param flags  the flags for formatting, see {@code Formattable}
92       * @param width  the width of the output, see {@code Formattable}
93       * @param precision  the precision of the output, see {@code Formattable}
94       * @param padChar  the pad character to use
95       * @return the {@code formatter} instance, not null
96       */
97      public static Formatter append(final CharSequence seq, final Formatter formatter, final int flags, final int width,
98              final int precision, final char padChar) {
99          return append(seq, formatter, flags, width, precision, padChar, null);
100     }
101 
102     /**
103      * Handles the common {@link Formattable} operations of truncate-pad-append,
104      * padding width underflow with spaces.
105      * 
106      * @param seq  the string to handle, not null
107      * @param formatter  the destination formatter, not null
108      * @param flags  the flags for formatting, see {@code Formattable}
109      * @param width  the width of the output, see {@code Formattable}
110      * @param precision  the precision of the output, see {@code Formattable}
111      * @param ellipsis  the ellipsis to use when precision dictates truncation, null or
112      *  empty causes a hard truncation
113      * @return the {@code formatter} instance, not null
114      */
115     public static Formatter append(final CharSequence seq, final Formatter formatter, final int flags, final int width,
116             final int precision, final CharSequence ellipsis) {
117         return append(seq, formatter, flags, width, precision, ' ', ellipsis);
118     }
119 
120     /**
121      * Handles the common {@link Formattable} operations of truncate-pad-append.
122      * 
123      * @param seq  the string to handle, not null
124      * @param formatter  the destination formatter, not null
125      * @param flags  the flags for formatting, see {@code Formattable}
126      * @param width  the width of the output, see {@code Formattable}
127      * @param precision  the precision of the output, see {@code Formattable}
128      * @param padChar  the pad character to use
129      * @param ellipsis  the ellipsis to use when precision dictates truncation, null or
130      *  empty causes a hard truncation
131      * @return the {@code formatter} instance, not null
132      */
133     public static Formatter append(final CharSequence seq, final Formatter formatter, final int flags, final int width,
134             final int precision, final char padChar, final CharSequence ellipsis) {
135         Validate.isTrue(ellipsis == null || precision < 0 || ellipsis.length() <= precision,
136                 "Specified ellipsis '%1$s' exceeds precision of %2$s", ellipsis, Integer.valueOf(precision));
137         final StringBuilder buf = new StringBuilder(seq);
138         if (precision >= 0 && precision < seq.length()) {
139             final CharSequence _ellipsis = ObjectUtils.defaultIfNull(ellipsis, StringUtils.EMPTY);
140             buf.replace(precision - _ellipsis.length(), seq.length(), _ellipsis.toString());
141         }
142         final boolean leftJustify = (flags & LEFT_JUSTIFY) == LEFT_JUSTIFY;
143         for (int i = buf.length(); i < width; i++) {
144             buf.insert(leftJustify ? i : 0, padChar);
145         }
146         formatter.format(buf.toString());
147         return formatter;
148     }
149 
150 }