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