Coverage Report - org.apache.commons.math.fraction.ProperFractionFormat

Classes in this File Line Coverage Branch Coverage Complexity
ProperFractionFormat
84% 
100% 
3.143

 1  
 /*
 2  
  * Copyright 2005 The Apache Software Foundation.
 3  
  *
 4  
  * Licensed under the Apache License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  *      http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package org.apache.commons.math.fraction;
 17  
 
 18  
 import java.text.FieldPosition;
 19  
 import java.text.NumberFormat;
 20  
 import java.text.ParsePosition;
 21  
 
 22  
 import org.apache.commons.math.util.MathUtils;
 23  
 
 24  
 /**
 25  
  * Formats a Fraction number in proper format.  The number format for each of
 26  
  * the whole number, numerator and, denominator can be configured.
 27  
  * 
 28  
  * @since 1.1
 29  
  * @version $Revision$ $Date: 2005-05-21 22:25:44 -0700 (Sat, 21 May 2005) $
 30  
  */
 31  
 public class ProperFractionFormat extends FractionFormat {
 32  
     
 33  
     /** Serializable version identifier */
 34  
     static final long serialVersionUID = -6337346779577272307L;
 35  
     
 36  
     /** The format used for the whole number. */
 37  
     private NumberFormat wholeFormat;
 38  
 
 39  
     /**
 40  
      * Create a proper formatting instance with the default number format for
 41  
      * the whole, numerator, and denominator.  
 42  
      */
 43  
     public ProperFractionFormat() {
 44  0
         this(getDefaultNumberFormat());
 45  0
     }
 46  
     
 47  
     /**
 48  
      * Create a proper formatting instance with a custom number format for the
 49  
      * whole, numerator, and denominator.
 50  
      * @param format the custom format for the whole, numerator, and
 51  
      *        denominator.
 52  
      */
 53  
     public ProperFractionFormat(NumberFormat format) {
 54  30
         this(format, (NumberFormat)format.clone(), (NumberFormat)format.clone());
 55  30
     }
 56  
     
 57  
     /**
 58  
      * Create a proper formatting instance with a custom number format for each
 59  
      * of the whole, numerator, and denominator.
 60  
      * @param wholeFormat the custom format for the whole.
 61  
      * @param numeratorFormat the custom format for the numerator.
 62  
      * @param denominatorFormat the custom format for the denominator.
 63  
      */
 64  
     public ProperFractionFormat(NumberFormat wholeFormat,
 65  
             NumberFormat numeratorFormat,
 66  
             NumberFormat denominatorFormat)
 67  
     {
 68  30
         super(numeratorFormat, denominatorFormat);
 69  30
         setWholeFormat(wholeFormat);
 70  30
     }
 71  
     
 72  
     /**
 73  
      * Formats a {@link Fraction} object to produce a string.  The fraction
 74  
      * is output in proper format.
 75  
      *
 76  
      * @param fraction the object to format.
 77  
      * @param toAppendTo where the text is to be appended
 78  
      * @param pos On input: an alignment field, if desired. On output: the
 79  
      *            offsets of the alignment field
 80  
      * @return the value passed in as toAppendTo.
 81  
      */
 82  
     public StringBuffer format(Fraction fraction, StringBuffer toAppendTo,
 83  
             FieldPosition pos) {
 84  
         
 85  10
         pos.setBeginIndex(0);
 86  10
         pos.setEndIndex(0);
 87  
 
 88  10
         int num = fraction.getNumerator();
 89  10
         int den = fraction.getDenominator();
 90  10
         int whole = num / den;
 91  10
         num = num % den;
 92  
         
 93  10
         if (whole != 0) {
 94  4
             getWholeFormat().format(whole, toAppendTo, pos);
 95  4
             toAppendTo.append(' ');
 96  4
             num = Math.abs(num);
 97  
         }
 98  10
         getNumeratorFormat().format(num, toAppendTo, pos);
 99  10
         toAppendTo.append(" / ");
 100  10
         getDenominatorFormat().format(den, toAppendTo,
 101  
             pos);
 102  
         
 103  10
         return toAppendTo;
 104  
     }
 105  
 
 106  
     /**
 107  
      * Access the whole format.
 108  
      * @return the whole format.
 109  
      */
 110  
     public NumberFormat getWholeFormat() {
 111  16
         return wholeFormat;
 112  
     }
 113  
     
 114  
     /**
 115  
      * Parses a string to produce a {@link Fraction} object.  This method
 116  
      * expects the string to be formatted as a proper fraction.
 117  
      * @param source the string to parse
 118  
      * @param pos input/ouput parsing parameter.
 119  
      * @return the parsed {@link Fraction} object.
 120  
      */
 121  
     public Fraction parse(String source, ParsePosition pos) {
 122  
         // try to parse improper fraction
 123  16
         Fraction ret = super.parse(source, pos);
 124  16
         if (ret != null) {
 125  8
             return ret;
 126  
         }
 127  
         
 128  8
         int initialIndex = pos.getIndex();
 129  
 
 130  
         // parse whitespace
 131  8
         parseAndIgnoreWhitespace(source, pos);
 132  
 
 133  
         // parse whole
 134  8
         Number whole = getWholeFormat().parse(source, pos);
 135  8
         if (whole == null) {
 136  
             // invalid integer number
 137  
             // set index back to initial, error index should already be set
 138  
             // character examined.
 139  2
             pos.setIndex(initialIndex);
 140  2
             return null;
 141  
         }
 142  
 
 143  
         // parse whitespace
 144  6
         parseAndIgnoreWhitespace(source, pos);
 145  
         
 146  
         // parse numerator
 147  6
         Number num = getNumeratorFormat().parse(source, pos);
 148  6
         if (num == null) {
 149  
             // invalid integer number
 150  
             // set index back to initial, error index should already be set
 151  
             // character examined.
 152  2
             pos.setIndex(initialIndex);
 153  2
             return null;
 154  
         }
 155  
 
 156  
         // parse '/'
 157  4
         int startIndex = pos.getIndex();
 158  4
         char c = parseNextCharacter(source, pos);
 159  4
         switch (c) {
 160  
         case 0 :
 161  
             // no '/'
 162  
             // return num as a fraction
 163  0
             return new Fraction(num.intValue(), 1);
 164  
         case '/' :
 165  
             // found '/', continue parsing denominator
 166  4
             break;
 167  
         default :
 168  
             // invalid '/'
 169  
             // set index back to initial, error index should be the last
 170  
             // character examined.
 171  0
             pos.setIndex(initialIndex);
 172  0
             pos.setErrorIndex(startIndex);
 173  0
             return null;
 174  
         }
 175  
 
 176  
         // parse whitespace
 177  4
         parseAndIgnoreWhitespace(source, pos);
 178  
 
 179  
         // parse denominator
 180  4
         Number den = getDenominatorFormat().parse(source, pos);
 181  4
         if (den == null) {
 182  
             // invalid integer number
 183  
             // set index back to initial, error index should already be set
 184  
             // character examined.
 185  0
             pos.setIndex(initialIndex);
 186  0
             return null;
 187  
         }
 188  
 
 189  4
         int w = whole.intValue();
 190  4
         int n = num.intValue();
 191  4
         int d = den.intValue();
 192  4
         return new Fraction(((Math.abs(w) * d) + n) * MathUtils.sign(w), d);
 193  
     }
 194  
     
 195  
     /**
 196  
      * Modify the whole format.
 197  
      * @param format The new whole format value.
 198  
      * @throws IllegalArgumentException if <code>format</code> is
 199  
      *         <code>null</code>.
 200  
      */
 201  
     public void setWholeFormat(NumberFormat format) {
 202  34
         if (format == null) {
 203  0
             throw new IllegalArgumentException(
 204  
                 "whole format can not be null.");
 205  
         }
 206  34
         this.wholeFormat = format;
 207  34
     }
 208  
 }