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    *      https://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  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  
23  package org.hipparchus.fraction;
24  
25  import java.io.Serializable;
26  import java.text.FieldPosition;
27  import java.text.NumberFormat;
28  import java.text.ParsePosition;
29  import java.util.Locale;
30  
31  import org.hipparchus.exception.LocalizedCoreFormats;
32  import org.hipparchus.util.MathUtils;
33  
34  /**
35   * Common part shared by both {@link FractionFormat} and {@link BigFractionFormat}.
36   */
37  abstract class AbstractFormat extends NumberFormat implements Serializable {
38  
39      /** Serializable version identifier. */
40      private static final long serialVersionUID = 20160323L;
41  
42      /** The format used for the denominator. */
43      private final NumberFormat denominatorFormat;
44  
45      /** The format used for the numerator. */
46      private final NumberFormat numeratorFormat;
47  
48      /**
49       * Create an improper formatting instance with the default number format
50       * for the numerator and denominator.
51       */
52      protected AbstractFormat() {
53          this(getDefaultNumberFormat());
54      }
55  
56      /**
57       * Create an improper formatting instance with a custom number format for
58       * both the numerator and denominator.
59       * @param format the custom format for both the numerator and denominator.
60       * @throws org.hipparchus.exception.NullArgumentException if the provided format is null.
61       */
62      protected AbstractFormat(final NumberFormat format) {
63          this(format, (NumberFormat) format.clone());
64      }
65  
66      /**
67       * Create an improper formatting instance with a custom number format for
68       * the numerator and a custom number format for the denominator.
69       * @param numeratorFormat the custom format for the numerator.
70       * @param denominatorFormat the custom format for the denominator.
71       * @throws org.hipparchus.exception.NullArgumentException if either provided format is null.
72       */
73      protected AbstractFormat(final NumberFormat numeratorFormat,
74                               final NumberFormat denominatorFormat) {
75          MathUtils.checkNotNull(numeratorFormat, LocalizedCoreFormats.NUMERATOR_FORMAT);
76          MathUtils.checkNotNull(denominatorFormat, LocalizedCoreFormats.DENOMINATOR_FORMAT);
77  
78          this.numeratorFormat   = numeratorFormat;
79          this.denominatorFormat = denominatorFormat;
80      }
81  
82      /**
83       * Create a default number format.  The default number format is based on
84       * {@link NumberFormat#getNumberInstance(java.util.Locale)}. The only
85       * customization is the maximum number of BigFraction digits, which is set to 0.
86       * @return the default number format.
87       */
88      protected static NumberFormat getDefaultNumberFormat() {
89          return getDefaultNumberFormat(Locale.getDefault());
90      }
91  
92      /**
93       * Create a default number format.  The default number format is based on
94       * {@link NumberFormat#getNumberInstance(java.util.Locale)}. The only
95       * customization is the maximum number of BigFraction digits, which is set to 0.
96       * @param locale the specific locale used by the format.
97       * @return the default number format specific to the given locale.
98       */
99      protected static NumberFormat getDefaultNumberFormat(final Locale locale) {
100         final NumberFormat nf = NumberFormat.getNumberInstance(locale);
101         nf.setMaximumFractionDigits(0);
102         nf.setParseIntegerOnly(true);
103         return nf;
104     }
105 
106     /**
107      * Access the denominator format.
108      * @return the denominator format.
109      */
110     public NumberFormat getDenominatorFormat() {
111         return denominatorFormat;
112     }
113 
114     /**
115      * Access the numerator format.
116      * @return the numerator format.
117      */
118     public NumberFormat getNumeratorFormat() {
119         return numeratorFormat;
120     }
121 
122     /**
123      * Parses <code>source</code> until a non-whitespace character is found.
124      * @param source the string to parse
125      * @param pos input/output parsing parameter.  On output, <code>pos</code>
126      *        holds the index of the next non-whitespace character.
127      */
128     protected static void parseAndIgnoreWhitespace(final String source,
129                                                    final ParsePosition pos) {
130         parseNextCharacter(source, pos);
131         pos.setIndex(pos.getIndex() - 1);
132     }
133 
134     /**
135      * Parses <code>source</code> until a non-whitespace character is found.
136      * @param source the string to parse
137      * @param pos input/output parsing parameter.
138      * @return the first non-whitespace character.
139      */
140     protected static char parseNextCharacter(final String source,
141                                              final ParsePosition pos) {
142          int index = pos.getIndex();
143          final int n = source.length();
144          char ret = 0;
145 
146          if (index < n) {
147              char c;
148              do {
149                  c = source.charAt(index++);
150              } while (Character.isWhitespace(c) && index < n);
151              pos.setIndex(index);
152 
153              if (index < n) {
154                  ret = c;
155              }
156          }
157 
158          return ret;
159     }
160 
161     /**
162      * Formats a double value as a fraction and appends the result to a StringBuffer.
163      *
164      * @param value the double value to format
165      * @param buffer StringBuffer to append to
166      * @param position On input: an alignment field, if desired. On output: the
167      *            offsets of the alignment field
168      * @return a reference to the appended buffer
169      * @see #format(Object, StringBuffer, FieldPosition)
170      */
171     @Override
172     public StringBuffer format(final double value,
173                                final StringBuffer buffer, final FieldPosition position) {
174         return format(Double.valueOf(value), buffer, position);
175     }
176 
177 
178     /**
179      * Formats a long value as a fraction and appends the result to a StringBuffer.
180      *
181      * @param value the long value to format
182      * @param buffer StringBuffer to append to
183      * @param position On input: an alignment field, if desired. On output: the
184      *            offsets of the alignment field
185      * @return a reference to the appended buffer
186      * @see #format(Object, StringBuffer, FieldPosition)
187      */
188     @Override
189     public StringBuffer format(final long value,
190                                final StringBuffer buffer, final FieldPosition position) {
191         return format(Long.valueOf(value), buffer, position);
192     }
193 
194 }