AbstractFormat.java

  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.  * This is not the original file distributed by the Apache Software Foundation
  19.  * It has been modified by the Hipparchus project
  20.  */

  21. package org.hipparchus.fraction;

  22. import java.io.Serializable;
  23. import java.text.FieldPosition;
  24. import java.text.NumberFormat;
  25. import java.text.ParsePosition;
  26. import java.util.Locale;

  27. import org.hipparchus.exception.LocalizedCoreFormats;
  28. import org.hipparchus.util.MathUtils;

  29. /**
  30.  * Common part shared by both {@link FractionFormat} and {@link BigFractionFormat}.
  31.  */
  32. abstract class AbstractFormat extends NumberFormat implements Serializable {

  33.     /** Serializable version identifier. */
  34.     private static final long serialVersionUID = 20160323L;

  35.     /** The format used for the denominator. */
  36.     private final NumberFormat denominatorFormat;

  37.     /** The format used for the numerator. */
  38.     private final NumberFormat numeratorFormat;

  39.     /**
  40.      * Create an improper formatting instance with the default number format
  41.      * for the numerator and denominator.
  42.      */
  43.     protected AbstractFormat() {
  44.         this(getDefaultNumberFormat());
  45.     }

  46.     /**
  47.      * Create an improper formatting instance with a custom number format for
  48.      * both the numerator and denominator.
  49.      * @param format the custom format for both the numerator and denominator.
  50.      * @throws org.hipparchus.exception.NullArgumentException if the provided format is null.
  51.      */
  52.     protected AbstractFormat(final NumberFormat format) {
  53.         this(format, (NumberFormat) format.clone());
  54.     }

  55.     /**
  56.      * Create an improper formatting instance with a custom number format for
  57.      * the numerator and a custom number format for the denominator.
  58.      * @param numeratorFormat the custom format for the numerator.
  59.      * @param denominatorFormat the custom format for the denominator.
  60.      * @throws org.hipparchus.exception.NullArgumentException if either provided format is null.
  61.      */
  62.     protected AbstractFormat(final NumberFormat numeratorFormat,
  63.                              final NumberFormat denominatorFormat) {
  64.         MathUtils.checkNotNull(numeratorFormat, LocalizedCoreFormats.NUMERATOR_FORMAT);
  65.         MathUtils.checkNotNull(denominatorFormat, LocalizedCoreFormats.DENOMINATOR_FORMAT);

  66.         this.numeratorFormat   = numeratorFormat;
  67.         this.denominatorFormat = denominatorFormat;
  68.     }

  69.     /**
  70.      * Create a default number format.  The default number format is based on
  71.      * {@link NumberFormat#getNumberInstance(java.util.Locale)}. The only
  72.      * customization is the maximum number of BigFraction digits, which is set to 0.
  73.      * @return the default number format.
  74.      */
  75.     protected static NumberFormat getDefaultNumberFormat() {
  76.         return getDefaultNumberFormat(Locale.getDefault());
  77.     }

  78.     /**
  79.      * Create a default number format.  The default number format is based on
  80.      * {@link NumberFormat#getNumberInstance(java.util.Locale)}. The only
  81.      * customization is the maximum number of BigFraction digits, which is set to 0.
  82.      * @param locale the specific locale used by the format.
  83.      * @return the default number format specific to the given locale.
  84.      */
  85.     protected static NumberFormat getDefaultNumberFormat(final Locale locale) {
  86.         final NumberFormat nf = NumberFormat.getNumberInstance(locale); // NOPMD - explicit class necessary to avoid infinite recursion
  87.         nf.setMaximumFractionDigits(0);
  88.         nf.setParseIntegerOnly(true);
  89.         return nf;
  90.     }

  91.     /**
  92.      * Access the denominator format.
  93.      * @return the denominator format.
  94.      */
  95.     public NumberFormat getDenominatorFormat() {
  96.         return denominatorFormat;
  97.     }

  98.     /**
  99.      * Access the numerator format.
  100.      * @return the numerator format.
  101.      */
  102.     public NumberFormat getNumeratorFormat() {
  103.         return numeratorFormat;
  104.     }

  105.     /**
  106.      * Parses <code>source</code> until a non-whitespace character is found.
  107.      * @param source the string to parse
  108.      * @param pos input/output parsing parameter.  On output, <code>pos</code>
  109.      *        holds the index of the next non-whitespace character.
  110.      */
  111.     protected static void parseAndIgnoreWhitespace(final String source,
  112.                                                    final ParsePosition pos) {
  113.         parseNextCharacter(source, pos);
  114.         pos.setIndex(pos.getIndex() - 1);
  115.     }

  116.     /**
  117.      * Parses <code>source</code> until a non-whitespace character is found.
  118.      * @param source the string to parse
  119.      * @param pos input/output parsing parameter.
  120.      * @return the first non-whitespace character.
  121.      */
  122.     protected static char parseNextCharacter(final String source,
  123.                                              final ParsePosition pos) {
  124.          int index = pos.getIndex();
  125.          final int n = source.length();
  126.          char ret = 0;

  127.          if (index < n) {
  128.              char c;
  129.              do {
  130.                  c = source.charAt(index++);
  131.              } while (Character.isWhitespace(c) && index < n);
  132.              pos.setIndex(index);

  133.              if (index < n) {
  134.                  ret = c;
  135.              }
  136.          }

  137.          return ret;
  138.     }

  139.     /**
  140.      * Formats a double value as a fraction and appends the result to a StringBuffer.
  141.      *
  142.      * @param value the double value to format
  143.      * @param buffer StringBuffer to append to
  144.      * @param position On input: an alignment field, if desired. On output: the
  145.      *            offsets of the alignment field
  146.      * @return a reference to the appended buffer
  147.      * @see #format(Object, StringBuffer, FieldPosition)
  148.      */
  149.     @Override
  150.     public StringBuffer format(final double value,
  151.                                final StringBuffer buffer, final FieldPosition position) {
  152.         return format(Double.valueOf(value), buffer, position); // NOPMD
  153.     }


  154.     /**
  155.      * Formats a long value as a fraction and appends the result to a StringBuffer.
  156.      *
  157.      * @param value the long value to format
  158.      * @param buffer StringBuffer to append to
  159.      * @param position On input: an alignment field, if desired. On output: the
  160.      *            offsets of the alignment field
  161.      * @return a reference to the appended buffer
  162.      * @see #format(Object, StringBuffer, FieldPosition)
  163.      */
  164.     @Override
  165.     public StringBuffer format(final long value,
  166.                                final StringBuffer buffer, final FieldPosition position) {
  167.         return format(Long.valueOf(value), buffer, position); // NOPMD
  168.     }

  169. }