< prev index next >

src/java.base/share/classes/java/text/ChoiceFormat.java

Print this page


   1 /*
   2  * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 155  *
 156  * <p>
 157  * Choice formats are not synchronized.
 158  * It is recommended to create separate format instances for each thread.
 159  * If multiple threads access a format concurrently, it must be synchronized
 160  * externally.
 161  *
 162  *
 163  * @see          DecimalFormat
 164  * @see          MessageFormat
 165  * @author       Mark Davis
 166  */
 167 public class ChoiceFormat extends NumberFormat {
 168 
 169     // Proclaim serial compatibility with 1.1 FCS
 170     private static final long serialVersionUID = 1795184449645032964L;
 171 
 172     /**
 173      * Sets the pattern.
 174      * @param newPattern See the class description.


 175      */
 176     public void applyPattern(String newPattern) {
 177         StringBuffer[] segments = new StringBuffer[2];
 178         for (int i = 0; i < segments.length; ++i) {
 179             segments[i] = new StringBuffer();
 180         }
 181         double[] newChoiceLimits = new double[30];
 182         String[] newChoiceFormats = new String[30];
 183         int count = 0;
 184         int part = 0;
 185         double startValue = 0;
 186         double oldStartValue = Double.NaN;
 187         boolean inQuote = false;
 188         for (int i = 0; i < newPattern.length(); ++i) {
 189             char ch = newPattern.charAt(i);
 190             if (ch=='\'') {
 191                 // Check for "''" indicating a literal quote
 192                 if ((i+1)<newPattern.length() && newPattern.charAt(i+1)==ch) {
 193                     segments[part].append(ch);
 194                     ++i;


 292                 || text.indexOf('\u2264') >= 0
 293                 || text.indexOf('|') >= 0;
 294             if (needQuote) result.append('\'');
 295             if (text.indexOf('\'') < 0) result.append(text);
 296             else {
 297                 for (int j=0; j<text.length(); ++j) {
 298                     char c = text.charAt(j);
 299                     result.append(c);
 300                     if (c == '\'') result.append(c);
 301                 }
 302             }
 303             if (needQuote) result.append('\'');
 304         }
 305         return result.toString();
 306     }
 307 
 308     /**
 309      * Constructs with limits and corresponding formats based on the pattern.
 310      *
 311      * @param newPattern the new pattern string


 312      * @see #applyPattern
 313      */
 314     public ChoiceFormat(String newPattern)  {
 315         applyPattern(newPattern);
 316     }
 317 
 318     /**
 319      * Constructs with the limits and the corresponding formats.
 320      *
 321      * @param limits limits in ascending order
 322      * @param formats corresponding format strings


 323      * @see #setChoices
 324      */
 325     public ChoiceFormat(double[] limits, String[] formats) {
 326         setChoices(limits, formats);
 327     }
 328 
 329     /**
 330      * Set the choices to be used in formatting.
 331      * @param limits contains the top value that you want
 332      * parsed with that format, and should be in ascending sorted order. When
 333      * formatting X, the choice will be the i, where
 334      * limit[i] &le; X {@literal <} limit[i+1].
 335      * If the limit array is not in ascending order, the results of formatting
 336      * will be incorrect.
 337      * @param formats are the formats you want to use for each limit.
 338      * They can be either Format objects or Strings.
 339      * When formatting with object Y,
 340      * if the object is a NumberFormat, then ((NumberFormat) Y).format(X)
 341      * is called. Otherwise Y.toString() is called.


 342      */
 343     public void setChoices(double[] limits, String formats[]) {
 344         if (limits.length != formats.length) {
 345             throw new IllegalArgumentException(
 346                 "Array and limit arrays must be of the same length.");
 347         }
 348         choiceLimits = Arrays.copyOf(limits, limits.length);
 349         choiceFormats = Arrays.copyOf(formats, formats.length);
 350     }
 351 
 352     /**
 353      * Get the limits passed in the constructor.
 354      * @return the limits.
 355      */
 356     public double[] getLimits() {
 357         double[] newLimits = Arrays.copyOf(choiceLimits, choiceLimits.length);
 358         return newLimits;
 359     }
 360 
 361     /**


 369 
 370     // Overrides
 371 
 372     /**
 373      * Specialization of format. This method really calls
 374      * <code>format(double, StringBuffer, FieldPosition)</code>
 375      * thus the range of longs that are supported is only equal to
 376      * the range that can be stored by double. This will never be
 377      * a practical limitation.
 378      */
 379     public StringBuffer format(long number, StringBuffer toAppendTo,
 380                                FieldPosition status) {
 381         return format((double)number, toAppendTo, status);
 382     }
 383 
 384     /**
 385      * Returns pattern with formatted double.
 386      * @param number number to be formatted and substituted.
 387      * @param toAppendTo where text is appended.
 388      * @param status ignore no useful status is returned.


 389      */
 390    public StringBuffer format(double number, StringBuffer toAppendTo,
 391                                FieldPosition status) {
 392         // find the number
 393         int i;
 394         for (i = 0; i < choiceLimits.length; ++i) {
 395             if (!(number >= choiceLimits[i])) {
 396                 // same as number < choiceLimits, except catchs NaN
 397                 break;
 398             }
 399         }
 400         --i;
 401         if (i < 0) i = 0;
 402         // return either a formatted number, or a string
 403         return toAppendTo.append(choiceFormats[i]);
 404     }
 405 
 406     /**
 407      * Parses a Number from the input text.
 408      * @param text the source text.
 409      * @param status an input-output parameter.  On input, the
 410      * status.index field indicates the first character of the
 411      * source text that should be parsed.  On exit, if no error
 412      * occurred, status.index is set to the first unparsed character
 413      * in the source text.  On exit, if an error did occur,
 414      * status.index is unchanged and status.errorIndex is set to the
 415      * first index of the character that caused the parse to fail.
 416      * @return A Number representing the value of the number parsed.



 417      */
 418     public Number parse(String text, ParsePosition status) {
 419         // find the best number (defined as the one with the longest parse)
 420         int start = status.index;
 421         int furthest = start;
 422         double bestNumber = Double.NaN;
 423         double tempNumber = 0.0;
 424         for (int i = 0; i < choiceFormats.length; ++i) {
 425             String tempString = choiceFormats[i];
 426             if (text.regionMatches(start, tempString, 0, tempString.length())) {
 427                 status.index = start + tempString.length();
 428                 tempNumber = choiceLimits[i];
 429                 if (status.index > furthest) {
 430                     furthest = status.index;
 431                     bestNumber = tempNumber;
 432                     if (furthest == text.length()) break;
 433                 }
 434             }
 435         }
 436         status.index = furthest;


   1 /*
   2  * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 155  *
 156  * <p>
 157  * Choice formats are not synchronized.
 158  * It is recommended to create separate format instances for each thread.
 159  * If multiple threads access a format concurrently, it must be synchronized
 160  * externally.
 161  *
 162  *
 163  * @see          DecimalFormat
 164  * @see          MessageFormat
 165  * @author       Mark Davis
 166  */
 167 public class ChoiceFormat extends NumberFormat {
 168 
 169     // Proclaim serial compatibility with 1.1 FCS
 170     private static final long serialVersionUID = 1795184449645032964L;
 171 
 172     /**
 173      * Sets the pattern.
 174      * @param newPattern See the class description.
 175      * @exception NullPointerException if {@code newPattern}
 176      *            is {@code null}
 177      */
 178     public void applyPattern(String newPattern) {
 179         StringBuffer[] segments = new StringBuffer[2];
 180         for (int i = 0; i < segments.length; ++i) {
 181             segments[i] = new StringBuffer();
 182         }
 183         double[] newChoiceLimits = new double[30];
 184         String[] newChoiceFormats = new String[30];
 185         int count = 0;
 186         int part = 0;
 187         double startValue = 0;
 188         double oldStartValue = Double.NaN;
 189         boolean inQuote = false;
 190         for (int i = 0; i < newPattern.length(); ++i) {
 191             char ch = newPattern.charAt(i);
 192             if (ch=='\'') {
 193                 // Check for "''" indicating a literal quote
 194                 if ((i+1)<newPattern.length() && newPattern.charAt(i+1)==ch) {
 195                     segments[part].append(ch);
 196                     ++i;


 294                 || text.indexOf('\u2264') >= 0
 295                 || text.indexOf('|') >= 0;
 296             if (needQuote) result.append('\'');
 297             if (text.indexOf('\'') < 0) result.append(text);
 298             else {
 299                 for (int j=0; j<text.length(); ++j) {
 300                     char c = text.charAt(j);
 301                     result.append(c);
 302                     if (c == '\'') result.append(c);
 303                 }
 304             }
 305             if (needQuote) result.append('\'');
 306         }
 307         return result.toString();
 308     }
 309 
 310     /**
 311      * Constructs with limits and corresponding formats based on the pattern.
 312      *
 313      * @param newPattern the new pattern string
 314      * @exception NullPointerExcpetion if {@code newPattern} is
 315      *            {@code null}
 316      * @see #applyPattern
 317      */
 318     public ChoiceFormat(String newPattern)  {
 319         applyPattern(newPattern);
 320     }
 321 
 322     /**
 323      * Constructs with the limits and the corresponding formats.
 324      *
 325      * @param limits limits in ascending order
 326      * @param formats corresponding format strings
 327      * @exception NullPointerException if {@code limits} or {@code formats}
 328      *            is {@code null}
 329      * @see #setChoices
 330      */
 331     public ChoiceFormat(double[] limits, String[] formats) {
 332         setChoices(limits, formats);
 333     }
 334 
 335     /**
 336      * Set the choices to be used in formatting.
 337      * @param limits contains the top value that you want
 338      * parsed with that format, and should be in ascending sorted order. When
 339      * formatting X, the choice will be the i, where
 340      * limit[i] &le; X {@literal <} limit[i+1].
 341      * If the limit array is not in ascending order, the results of formatting
 342      * will be incorrect.
 343      * @param formats are the formats you want to use for each limit.
 344      * They can be either Format objects or Strings.
 345      * When formatting with object Y,
 346      * if the object is a NumberFormat, then ((NumberFormat) Y).format(X)
 347      * is called. Otherwise Y.toString() is called.
 348      * @exception NullPointerException if {@code limits} or
 349      *            {@code formats} is {@code null}
 350      */
 351     public void setChoices(double[] limits, String formats[]) {
 352         if (limits.length != formats.length) {
 353             throw new IllegalArgumentException(
 354                 "Array and limit arrays must be of the same length.");
 355         }
 356         choiceLimits = Arrays.copyOf(limits, limits.length);
 357         choiceFormats = Arrays.copyOf(formats, formats.length);
 358     }
 359 
 360     /**
 361      * Get the limits passed in the constructor.
 362      * @return the limits.
 363      */
 364     public double[] getLimits() {
 365         double[] newLimits = Arrays.copyOf(choiceLimits, choiceLimits.length);
 366         return newLimits;
 367     }
 368 
 369     /**


 377 
 378     // Overrides
 379 
 380     /**
 381      * Specialization of format. This method really calls
 382      * <code>format(double, StringBuffer, FieldPosition)</code>
 383      * thus the range of longs that are supported is only equal to
 384      * the range that can be stored by double. This will never be
 385      * a practical limitation.
 386      */
 387     public StringBuffer format(long number, StringBuffer toAppendTo,
 388                                FieldPosition status) {
 389         return format((double)number, toAppendTo, status);
 390     }
 391 
 392     /**
 393      * Returns pattern with formatted double.
 394      * @param number number to be formatted and substituted.
 395      * @param toAppendTo where text is appended.
 396      * @param status ignore no useful status is returned.
 397      * @exception NullPointerException if {@code toAppendTo}
 398      *            is {@code null}
 399      */
 400    public StringBuffer format(double number, StringBuffer toAppendTo,
 401                                FieldPosition status) {
 402         // find the number
 403         int i;
 404         for (i = 0; i < choiceLimits.length; ++i) {
 405             if (!(number >= choiceLimits[i])) {
 406                 // same as number < choiceLimits, except catchs NaN
 407                 break;
 408             }
 409         }
 410         --i;
 411         if (i < 0) i = 0;
 412         // return either a formatted number, or a string
 413         return toAppendTo.append(choiceFormats[i]);
 414     }
 415 
 416     /**
 417      * Parses a Number from the input text.
 418      * @param text the source text.
 419      * @param status an input-output parameter.  On input, the
 420      * status.index field indicates the first character of the
 421      * source text that should be parsed.  On exit, if no error
 422      * occurred, status.index is set to the first unparsed character
 423      * in the source text.  On exit, if an error did occur,
 424      * status.index is unchanged and status.errorIndex is set to the
 425      * first index of the character that caused the parse to fail.
 426      * @return A Number representing the value of the number parsed.
 427      * @exception NullPointerException if {@code status} is {@code null}
 428      *            or if {@code text} is {@code null} and the list of
 429      *            choice strings is not empty.
 430      */
 431     public Number parse(String text, ParsePosition status) {
 432         // find the best number (defined as the one with the longest parse)
 433         int start = status.index;
 434         int furthest = start;
 435         double bestNumber = Double.NaN;
 436         double tempNumber = 0.0;
 437         for (int i = 0; i < choiceFormats.length; ++i) {
 438             String tempString = choiceFormats[i];
 439             if (text.regionMatches(start, tempString, 0, tempString.length())) {
 440                 status.index = start + tempString.length();
 441                 tempNumber = choiceLimits[i];
 442                 if (status.index > furthest) {
 443                     furthest = status.index;
 444                     bestNumber = tempNumber;
 445                     if (furthest == text.length()) break;
 446                 }
 447             }
 448         }
 449         status.index = furthest;


< prev index next >