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
9
* http://www.apache.org/licenses/LICENSE-2.0
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.
17
package org.apache.commons.math.util;
19
import java.text.FieldPosition;
20
import java.text.Format;
21
import java.text.NumberFormat;
22
import java.text.ParsePosition;
23
import java.util.Locale;
26
* Base class for formatters of composite objects (complex numbers, vectors ...).
28
* @author Apache Software Foundation
29
* @version $Revision: 705231 $ $Date: 2008-10-16 08:49:13 -0400 (Thu, 16 Oct 2008) $
31
public abstract class CompositeFormat extends Format {
33
/** Serializable version identifier. */
34
private static final long serialVersionUID = 5358685519349262494L;
37
* Create a default number format. The default number format is based on
38
* {@link NumberFormat#getInstance()} with the only customizing that the
39
* maximum number of fraction digits is set to 2.
40
* @return the default number format.
42
protected static NumberFormat getDefaultNumberFormat() {
43
return getDefaultNumberFormat(Locale.getDefault());
47
* Create a default number format. The default number format is based on
48
* {@link NumberFormat#getInstance(java.util.Locale)} with the only
49
* customizing that the maximum number of fraction digits is set to 2.
50
* @param locale the specific locale used by the format.
51
* @return the default number format specific to the given locale.
53
protected static NumberFormat getDefaultNumberFormat(final Locale locale) {
54
final NumberFormat nf = NumberFormat.getInstance(locale);
55
nf.setMaximumFractionDigits(2);
60
* Parses <code>source</code> until a non-whitespace character is found.
62
* @param source the string to parse
63
* @param pos input/ouput parsing parameter. On output, <code>pos</code>
64
* holds the index of the next non-whitespace character.
66
protected void parseAndIgnoreWhitespace(final String source,
67
final ParsePosition pos) {
68
parseNextCharacter(source, pos);
69
pos.setIndex(pos.getIndex() - 1);
73
* Parses <code>source</code> until a non-whitespace character is found.
75
* @param source the string to parse
76
* @param pos input/ouput parsing parameter.
77
* @return the first non-whitespace character.
79
protected char parseNextCharacter(final String source,
80
final ParsePosition pos) {
81
int index = pos.getIndex();
82
final int n = source.length();
88
c = source.charAt(index++);
89
} while (Character.isWhitespace(c) && index < n);
101
* Parses <code>source</code> for special double values. These values
102
* include Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY.
104
* @param source the string to parse
105
* @param value the special value to parse.
106
* @param pos input/ouput parsing parameter.
107
* @return the special number.
109
private Number parseNumber(final String source, final double value,
110
final ParsePosition pos) {
113
StringBuffer sb = new StringBuffer();
118
final int n = sb.length();
119
final int startIndex = pos.getIndex();
120
final int endIndex = startIndex + n;
121
if (endIndex < source.length()) {
122
if (source.substring(startIndex, endIndex).compareTo(sb.toString()) == 0) {
123
ret = Double.valueOf(value);
124
pos.setIndex(endIndex);
132
* Parses <code>source</code> for a number. This method can parse normal,
133
* numeric values as well as special values. These special values include
134
* Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY.
136
* @param source the string to parse
137
* @param format the number format used to parse normal, numeric values.
138
* @param pos input/ouput parsing parameter.
139
* @return the parsed number.
141
protected Number parseNumber(final String source, final NumberFormat format,
142
final ParsePosition pos) {
143
final int startIndex = pos.getIndex();
144
Number number = format.parse(source, pos);
145
final int endIndex = pos.getIndex();
147
// check for error parsing number
148
if (startIndex == endIndex) {
149
// try parsing special numbers
150
final double[] special = {
151
Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY
153
for (int i = 0; i < special.length; ++i) {
154
number = parseNumber(source, special[i], pos);
155
if (number != null) {
165
* Parse <code>source</code> for an expected fixed string.
166
* @param source the string to parse
167
* @param expected expected string
168
* @param pos input/ouput parsing parameter.
169
* @return true if the expected string was there
171
protected boolean parseFixedstring(final String source, final String expected,
172
final ParsePosition pos) {
174
final int startIndex = pos.getIndex();
175
final int endIndex = startIndex + expected.length();
176
if ((startIndex >= source.length()) ||
177
(endIndex > source.length()) ||
178
(source.substring(startIndex, endIndex).compareTo(expected) != 0)) {
179
// set index back to start, error index should be the start index
180
pos.setIndex(startIndex);
181
pos.setErrorIndex(startIndex);
185
// the string was here
186
pos.setIndex(endIndex);
192
* Formats a double value to produce a string. In general, the value is
193
* formatted using the formatting rules of <code>format</code>. There are
194
* three exceptions to this:
196
* <li>NaN is formatted as '(NaN)'</li>
197
* <li>Positive infinity is formatted as '(Infinity)'</li>
198
* <li>Negative infinity is formatted as '(-Infinity)'</li>
201
* @param value the double to format.
202
* @param format the format used.
203
* @param toAppendTo where the text is to be appended
204
* @param pos On input: an alignment field, if desired. On output: the
205
* offsets of the alignment field
206
* @return the value passed in as toAppendTo.
208
protected StringBuffer formatDouble(final double value, final NumberFormat format,
209
final StringBuffer toAppendTo,
210
final FieldPosition pos) {
211
if( Double.isNaN(value) || Double.isInfinite(value) ) {
212
toAppendTo.append('(');
213
toAppendTo.append(value);
214
toAppendTo.append(')');
216
format.format(value, toAppendTo, pos);
b'\\ No newline at end of file'