1dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond/* 2dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Licensed to the Apache Software Foundation (ASF) under one or more 3dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * contributor license agreements. See the NOTICE file distributed with 4dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * this work for additional information regarding copyright ownership. 5dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The ASF licenses this file to You under the Apache License, Version 2.0 6dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * (the "License"); you may not use this file except in compliance with 7dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the License. You may obtain a copy of the License at 8dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 9dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * http://www.apache.org/licenses/LICENSE-2.0 10dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 11dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Unless required by applicable law or agreed to in writing, software 12dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * distributed under the License is distributed on an "AS IS" BASIS, 13dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * See the License for the specific language governing permissions and 15dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * limitations under the License. 16dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 17dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 18dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondpackage org.apache.commons.math.fraction; 19dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 20dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport java.text.FieldPosition; 21dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport java.text.NumberFormat; 22dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport java.text.ParseException; 23dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport java.text.ParsePosition; 24dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport java.util.Locale; 25dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 26dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.ConvergenceException; 27dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.MathRuntimeException; 28dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.exception.util.LocalizedFormats; 29dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 30dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond/** 31dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Formats a Fraction number in proper format or improper format. The number 32dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * format for each of the whole number, numerator and, denominator can be 33dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * configured. 34dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 35dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 1.1 36dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @version $Revision: 983921 $ $Date: 2010-08-10 12:46:06 +0200 (mar. 10 août 2010) $ 37dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 38dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondpublic class FractionFormat extends AbstractFormat { 39dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 40dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Serializable version identifier */ 41dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static final long serialVersionUID = 3008655719530972611L; 42dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 43dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 44dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Create an improper formatting instance with the default number format 45dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * for the numerator and denominator. 46dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 47dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public FractionFormat() { 48dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 49dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 50dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 51dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Create an improper formatting instance with a custom number format for 52dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * both the numerator and denominator. 53dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param format the custom format for both the numerator and denominator. 54dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 55dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public FractionFormat(final NumberFormat format) { 56dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond super(format); 57dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 58dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 59dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 60dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Create an improper formatting instance with a custom number format for 61dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the numerator and a custom number format for the denominator. 62dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param numeratorFormat the custom format for the numerator. 63dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param denominatorFormat the custom format for the denominator. 64dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 65dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public FractionFormat(final NumberFormat numeratorFormat, 66dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final NumberFormat denominatorFormat) { 67dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond super(numeratorFormat, denominatorFormat); 68dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 69dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 70dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 71dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Get the set of locales for which complex formats are available. This 72dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * is the same set as the {@link NumberFormat} set. 73dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return available complex format locales. 74dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 75dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static Locale[] getAvailableLocales() { 76dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return NumberFormat.getAvailableLocales(); 77dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 78dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 79dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 80dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * This static method calls formatFraction() on a default instance of 81dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * FractionFormat. 82dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 83dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param f Fraction object to format 84dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return A formatted fraction in proper form. 85dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 86dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static String formatFraction(Fraction f) { 87dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return getImproperInstance().format(f); 88dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 89dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 90dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 91dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Returns the default complex format for the current locale. 92dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the default complex format. 93dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 94dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static FractionFormat getImproperInstance() { 95dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return getImproperInstance(Locale.getDefault()); 96dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 97dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 98dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 99dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Returns the default complex format for the given locale. 100dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param locale the specific locale used by the format. 101dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the complex format specific to the given locale. 102dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 103dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static FractionFormat getImproperInstance(final Locale locale) { 104dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return new FractionFormat(getDefaultNumberFormat(locale)); 105dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 106dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 107dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 108dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Returns the default complex format for the current locale. 109dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the default complex format. 110dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 111dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static FractionFormat getProperInstance() { 112dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return getProperInstance(Locale.getDefault()); 113dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 114dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 115dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 116dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Returns the default complex format for the given locale. 117dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param locale the specific locale used by the format. 118dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the complex format specific to the given locale. 119dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 120dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public static FractionFormat getProperInstance(final Locale locale) { 121dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return new ProperFractionFormat(getDefaultNumberFormat(locale)); 122dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 123dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 124dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 125dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Create a default number format. The default number format is based on 126dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * {@link NumberFormat#getNumberInstance(java.util.Locale)} with the only 127dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * customizing is the maximum number of fraction digits, which is set to 0. 128dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the default number format. 129dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 130dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected static NumberFormat getDefaultNumberFormat() { 131dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return getDefaultNumberFormat(Locale.getDefault()); 132dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 133dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 134dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 135dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Formats a {@link Fraction} object to produce a string. The fraction is 136dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * output in improper format. 137dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 138dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param fraction the object to format. 139dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param toAppendTo where the text is to be appended 140dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param pos On input: an alignment field, if desired. On output: the 141dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * offsets of the alignment field 142dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the value passed in as toAppendTo. 143dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 144dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public StringBuffer format(final Fraction fraction, 145dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final StringBuffer toAppendTo, final FieldPosition pos) { 146dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 147dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond pos.setBeginIndex(0); 148dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond pos.setEndIndex(0); 149dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 150dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond getNumeratorFormat().format(fraction.getNumerator(), toAppendTo, pos); 151dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond toAppendTo.append(" / "); 152dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond getDenominatorFormat().format(fraction.getDenominator(), toAppendTo, 153dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond pos); 154dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 155dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return toAppendTo; 156dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 157dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 158dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 159dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Formats an object and appends the result to a StringBuffer. <code>obj</code> must be either a 160dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * {@link Fraction} object or a {@link Number} object. Any other type of 161dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * object will result in an {@link IllegalArgumentException} being thrown. 162dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 163dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param obj the object to format. 164dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param toAppendTo where the text is to be appended 165dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param pos On input: an alignment field, if desired. On output: the 166dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * offsets of the alignment field 167dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the value passed in as toAppendTo. 168dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @see java.text.Format#format(java.lang.Object, java.lang.StringBuffer, java.text.FieldPosition) 169dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws IllegalArgumentException is <code>obj</code> is not a valid type. 170dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 171dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond @Override 172dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public StringBuffer format(final Object obj, 173dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final StringBuffer toAppendTo, final FieldPosition pos) { 174dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond StringBuffer ret = null; 175dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 176dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (obj instanceof Fraction) { 177dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ret = format((Fraction) obj, toAppendTo, pos); 178dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else if (obj instanceof Number) { 179dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond try { 180dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ret = format(new Fraction(((Number) obj).doubleValue()), 181dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond toAppendTo, pos); 182dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } catch (ConvergenceException ex) { 183dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw MathRuntimeException.createIllegalArgumentException( 184dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond LocalizedFormats.CANNOT_CONVERT_OBJECT_TO_FRACTION, 185dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ex.getLocalizedMessage()); 186dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 187dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 188dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw MathRuntimeException.createIllegalArgumentException( 189dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond LocalizedFormats.CANNOT_FORMAT_OBJECT_TO_FRACTION); 190dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 191dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 192dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return ret; 193dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 194dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 195dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 196dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Parses a string to produce a {@link Fraction} object. 197dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param source the string to parse 198dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the parsed {@link Fraction} object. 199dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @exception ParseException if the beginning of the specified string 200dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * cannot be parsed. 201dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 202dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond @Override 203dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public Fraction parse(final String source) throws ParseException { 204dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final ParsePosition parsePosition = new ParsePosition(0); 205dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final Fraction result = parse(source, parsePosition); 206dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (parsePosition.getIndex() == 0) { 207dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw MathRuntimeException.createParseException( 208dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond parsePosition.getErrorIndex(), 209dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond LocalizedFormats.UNPARSEABLE_FRACTION_NUMBER, source); 210dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 211dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return result; 212dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 213dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 214dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 215dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Parses a string to produce a {@link Fraction} object. This method 216dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * expects the string to be formatted as an improper fraction. 217dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param source the string to parse 218dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param pos input/ouput parsing parameter. 219dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the parsed {@link Fraction} object. 220dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 221dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond @Override 222dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public Fraction parse(final String source, final ParsePosition pos) { 223dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final int initialIndex = pos.getIndex(); 224dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 225dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // parse whitespace 226dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond parseAndIgnoreWhitespace(source, pos); 227dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 228dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // parse numerator 229dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final Number num = getNumeratorFormat().parse(source, pos); 230dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (num == null) { 231dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // invalid integer number 232dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // set index back to initial, error index should already be set 233dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // character examined. 234dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond pos.setIndex(initialIndex); 235dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return null; 236dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 237dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 238dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // parse '/' 239dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final int startIndex = pos.getIndex(); 240dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final char c = parseNextCharacter(source, pos); 241dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond switch (c) { 242dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond case 0 : 243dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // no '/' 244dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // return num as a fraction 245dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return new Fraction(num.intValue(), 1); 246dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond case '/' : 247dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // found '/', continue parsing denominator 248dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond break; 249dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond default : 250dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // invalid '/' 251dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // set index back to initial, error index should be the last 252dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // character examined. 253dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond pos.setIndex(initialIndex); 254dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond pos.setErrorIndex(startIndex); 255dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return null; 256dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 257dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 258dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // parse whitespace 259dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond parseAndIgnoreWhitespace(source, pos); 260dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 261dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // parse denominator 262dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final Number den = getDenominatorFormat().parse(source, pos); 263dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (den == null) { 264dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // invalid integer number 265dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // set index back to initial, error index should already be set 266dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // character examined. 267dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond pos.setIndex(initialIndex); 268dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return null; 269dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 270dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 271dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return new Fraction(num.intValue(), den.intValue()); 272dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 273dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 274dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond} 275