Source for java.text.DecimalFormatSymbols

   1: /* DecimalFormatSymbols.java -- Format symbols used by DecimalFormat
   2:    Copyright (C) 1999, 2000, 2001, 2004, 2007 Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10:  
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package java.text;
  40: 
  41: import gnu.java.locale.LocaleHelper;
  42: 
  43: import java.io.IOException;
  44: import java.io.ObjectInputStream;
  45: import java.io.Serializable;
  46: 
  47: import java.text.spi.DecimalFormatSymbolsProvider;
  48: 
  49: import java.util.Currency;
  50: import java.util.Locale;
  51: import java.util.MissingResourceException;
  52: import java.util.ResourceBundle;
  53: import java.util.ServiceLoader;
  54: 
  55: /**
  56:  * This class is a container for the symbols used by 
  57:  * <code>DecimalFormat</code> to format numbers and currency
  58:  * for a particular locale.  These are
  59:  * normally handled automatically, but an application can override
  60:  * values as desired using this class.
  61:  *
  62:  * @author Tom Tromey (tromey@cygnus.com)
  63:  * @author Aaron M. Renn (arenn@urbanophile.com)
  64:  * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
  65:  * @date February 24, 1999
  66:  * @see java.text.DecimalFormat
  67:  */
  68: /* Written using "Java Class Libraries", 2nd edition, plus online
  69:  * API docs for JDK 1.2 from http://www.javasoft.com.
  70:  * Status:  Believed complete and correct to 1.2.
  71:  */
  72: public class DecimalFormatSymbols implements Cloneable, Serializable
  73: {
  74:   public Object clone ()
  75:   {
  76:     try
  77:       {
  78:         return super.clone();
  79:       }
  80:     catch(CloneNotSupportedException e)
  81:       {
  82:     return null;
  83:       }
  84:   }
  85: 
  86:   /**
  87:    * This method initializes a new instance of
  88:    * <code>DecimalFormatSymbols</code> for the default locale.
  89:    * This constructor only obtains instances using the runtime's resources;
  90:    * to also include {@link java.text.spi.DateFormatSymbolsProvider} instances,
  91:    * call {@link #getInstance()} instead.
  92:    *
  93:    * @see #getInstance()
  94:    */
  95:   public DecimalFormatSymbols ()
  96:   {
  97:     this (Locale.getDefault());
  98:   }
  99: 
 100:   /**
 101:    * Retrieves a valid string, either using the supplied resource
 102:    * bundle or the default value.
 103:    *
 104:    * @param bundle the resource bundle to use to find the string.
 105:    * @param name key for the string in the resource bundle.
 106:    * @param def default value for the string.
 107:    */
 108:   private String safeGetString(ResourceBundle bundle,
 109:                                String name, String def)
 110:   {
 111:     if (bundle != null)
 112:       {
 113:     try
 114:       {
 115:         return bundle.getString(name);
 116:       }
 117:     catch (MissingResourceException x)
 118:       {
 119:       }
 120:       }
 121:     return def;
 122:   }
 123: 
 124:   private char safeGetChar(ResourceBundle bundle,
 125:                            String name, char def)
 126:   {
 127:     String r = null;
 128:     if (bundle != null)
 129:       {
 130:     try
 131:       {
 132:         r = bundle.getString(name);
 133:       }
 134:     catch (MissingResourceException x)
 135:       {
 136:       }
 137:       }
 138:     if (r == null || r.length() < 1)
 139:       return def;
 140:     return r.charAt(0);
 141:   }
 142: 
 143:   /**
 144:    * This method initializes a new instance of
 145:    * <code>DecimalFormatSymbols</code> for the specified locale.
 146:    * <strong>Note</strong>: if the locale does not have an associated
 147:    * <code>Currency</code> instance, the currency symbol and
 148:    * international currency symbol will be set to the strings "?"
 149:    * and "XXX" respectively.  This generally happens with language
 150:    * locales (those with no specified country), such as
 151:    * <code>Locale.ENGLISH</code>.  This constructor only obtains
 152:    * instances using the runtime's resources; to also include
 153:    * {@link java.text.spi.DecimalFormatSymbolsProvider} instances,
 154:    * call {@link #getInstance(java.util.Locale)} instead.
 155:    *
 156:    * @param loc The local to load symbols for.
 157:    * @throws NullPointerException if the locale is null.
 158:    * @see #getInstance(java.util.Locale)
 159:    */
 160:   public DecimalFormatSymbols (Locale loc)
 161:   {
 162:     ResourceBundle res;
 163: 
 164:     try
 165:       {
 166:     res = ResourceBundle.getBundle("gnu.java.locale.LocaleInformation",
 167:         loc, ClassLoader.getSystemClassLoader());
 168:       }
 169:     catch (MissingResourceException x)
 170:       {
 171:     res = null;
 172:       }
 173:     currency = Currency.getInstance("XXX");
 174:     currencySymbol = "?";
 175:     intlCurrencySymbol = "XXX";
 176:     try
 177:       {
 178:     Currency localeCurrency = Currency.getInstance(loc);
 179:     if (localeCurrency != null)
 180:       {
 181:         setCurrency(localeCurrency);
 182:       }
 183:       }
 184:     catch(IllegalArgumentException exception)
 185:       {
 186:     /* Locale has an invalid currency */
 187:       }
 188:     decimalSeparator = safeGetChar (res, "decimalSeparator", '.');
 189:     digit = safeGetChar (res, "digit", '#');
 190:     exponential = safeGetChar (res, "exponential", 'E');
 191:     groupingSeparator = safeGetChar (res, "groupingSeparator", ',');
 192:     infinity = safeGetString (res, "infinity", "\u221e");
 193:     try
 194:       {
 195:     monetarySeparator = safeGetChar (res, "monetarySeparator", '.');
 196:       }
 197:     catch (MissingResourceException x)
 198:       {
 199:     monetarySeparator = decimalSeparator;
 200:       }
 201:     minusSign = safeGetChar (res, "minusSign", '-');
 202:     NaN = safeGetString (res, "NaN", "\ufffd");
 203:     patternSeparator = safeGetChar (res, "patternSeparator", ';');
 204:     percent = safeGetChar (res, "percent", '%');
 205:     perMill = safeGetChar (res, "perMill", '\u2030');
 206:     zeroDigit = safeGetChar (res, "zeroDigit", '0');
 207:     locale = loc;
 208:   }
 209: 
 210:   /**
 211:    * This method this this object for equality against the specified object.
 212:    * This will be true if and only if the following criteria are met with
 213:    * regard to the specified object:
 214:    * <p>
 215:    * <ul>
 216:    * <li>It is not <code>null</code>.</li>
 217:    * <li>It is an instance of <code>DecimalFormatSymbols</code>.</li>
 218:    * <li>All of its symbols are identical to the symbols in this object.</li>
 219:    * </ul>
 220:    *
 221:    * @return <code>true</code> if the specified object is equal to this
 222:    * object, <code>false</code> otherwise.
 223:    */
 224:   public boolean equals (Object obj)
 225:   {
 226:     if (! (obj instanceof DecimalFormatSymbols))
 227:       return false;
 228:     DecimalFormatSymbols dfs = (DecimalFormatSymbols) obj;
 229:     return (currencySymbol.equals(dfs.currencySymbol)
 230:         && decimalSeparator == dfs.decimalSeparator
 231:         && digit == dfs.digit
 232:         && exponential == dfs.exponential
 233:         && groupingSeparator == dfs.groupingSeparator
 234:         && infinity.equals(dfs.infinity)
 235:         && intlCurrencySymbol.equals(dfs.intlCurrencySymbol)
 236:         && minusSign == dfs.minusSign
 237:         && monetarySeparator == dfs.monetarySeparator
 238:         && NaN.equals(dfs.NaN)
 239:         && patternSeparator == dfs.patternSeparator
 240:         && percent == dfs.percent
 241:         && perMill == dfs.perMill
 242:         && zeroDigit == dfs.zeroDigit);
 243:   }
 244: 
 245:   /**
 246:    * Returns the currency corresponding to the currency symbol stored
 247:    * in this instance of <code>DecimalFormatSymbols</code>.
 248:    *
 249:    * @return An instance of <code>Currency</code> which matches
 250:    *         the currency used, or null if there is no corresponding
 251:    *         instance.
 252:    */
 253:   public Currency getCurrency ()
 254:   {
 255:     return currency;
 256:   }
 257: 
 258:   /**
 259:    * This method returns the currency symbol in local format.  For example,
 260:    * "$" for Canadian dollars.
 261:    *
 262:    * @return The currency symbol in local format.
 263:    */
 264:   public String getCurrencySymbol ()
 265:   {
 266:     return currencySymbol;
 267:   }
 268: 
 269:   /**
 270:    * This method returns the character used as the decimal point.
 271:    *
 272:    * @return The character used as the decimal point.
 273:    */
 274:   public char getDecimalSeparator ()
 275:   {
 276:     return decimalSeparator;
 277:   }
 278: 
 279:   /**
 280:    * This method returns the character used to represent a digit in a
 281:    * format pattern string.
 282:    *
 283:    * @return The character used to represent a digit in a format
 284:    * pattern string. 
 285:    */
 286:   public char getDigit ()
 287:   {
 288:     return digit;
 289:   }
 290: 
 291:   /**
 292:    * This method returns the character used to represent the exponential
 293:    * format.  This is a GNU Classpath extension.
 294:    *
 295:    * @return the character used to represent an exponential in a format
 296:    *         pattern string.
 297:    */
 298:   char getExponential ()
 299:   {
 300:     return exponential;
 301:   }
 302: 
 303:   /**
 304:    * This method sets the character used to separate groups of digits.  For
 305:    * example, the United States uses a comma (,) to separate thousands in
 306:    * a number.
 307:    *
 308:    * @return The character used to separate groups of digits.
 309:    */
 310:   public char getGroupingSeparator ()
 311:   {
 312:     return groupingSeparator;
 313:   }
 314: 
 315:   /**
 316:    * This method returns the character used to represent infinity.
 317:    *
 318:    * @return The character used to represent infinity.
 319:    */
 320:   public String getInfinity ()
 321:   {
 322:     return infinity;
 323:   }
 324: 
 325:   /**
 326:    * This method returns the ISO 4217 currency code for
 327:    * the currency used.
 328:    *
 329:    * @return the ISO 4217 currency code.
 330:    */
 331:   public String getInternationalCurrencySymbol ()
 332:   {
 333:     return intlCurrencySymbol;
 334:   }
 335: 
 336:   /**
 337:    * This method returns the character used to represent the minus sign.
 338:    *
 339:    * @return The character used to represent the minus sign.
 340:    */
 341:   public char getMinusSign ()
 342:   {
 343:     return minusSign;
 344:   }
 345: 
 346:   /**
 347:    * This method returns the character used to represent the decimal
 348:    * point for currency values.
 349:    *
 350:    * @return The decimal point character used in currency values.
 351:    */
 352:   public char getMonetaryDecimalSeparator ()
 353:   {
 354:     return monetarySeparator;
 355:   }
 356: 
 357:   /**
 358:    * This method returns the string used to represent the NaN (not a number)
 359:    * value.
 360:    *
 361:    * @return The string used to represent NaN
 362:    */
 363:   public String getNaN ()
 364:   {
 365:     return NaN;
 366:   }
 367: 
 368:   /**
 369:    * This method returns the character used to separate positive and negative
 370:    * subpatterns in a format pattern.
 371:    *
 372:    * @return The character used to separate positive and negative subpatterns
 373:    * in a format pattern.
 374:    */
 375:   public char getPatternSeparator ()
 376:   {
 377:     return patternSeparator;
 378:   }
 379: 
 380:   /**
 381:    * This method returns the character used as the percent sign.
 382:    *
 383:    * @return The character used as the percent sign.
 384:    */
 385:   public char getPercent ()
 386:   {
 387:     return percent;
 388:   }
 389: 
 390:   /**
 391:    * This method returns the character used as the per mille character.
 392:    *
 393:    * @return The per mille character.
 394:    */
 395:   public char getPerMill ()
 396:   {
 397:     return perMill;
 398:   }
 399: 
 400:   /**
 401:    * This method returns the character used to represent the digit zero.
 402:    *
 403:    * @return The character used to represent the digit zero.
 404:    */
 405:   public char getZeroDigit ()
 406:   {
 407:     return zeroDigit;
 408:   }
 409: 
 410:   /**
 411:    * This method returns a hash value for this object.
 412:    *
 413:    * @return A hash value for this object.
 414:    */
 415:   public int hashCode ()
 416:   {
 417:     // Compute based on zero digit, grouping separator, and decimal
 418:     // separator -- JCL book.  This probably isn't a very good hash
 419:     // code.
 420:     return zeroDigit << 16 + groupingSeparator << 8 + decimalSeparator;
 421:   }
 422: 
 423:   /**
 424:    * This method sets the currency symbol and ISO 4217 currency
 425:    * code to the values obtained from the supplied currency.
 426:    *
 427:    * @param currency the currency from which to obtain the values.
 428:    * @throws NullPointerException if the currency is null.
 429:    */
 430:   public void setCurrency (Currency currency)
 431:   {
 432:     intlCurrencySymbol = currency.getCurrencyCode();
 433:     currencySymbol = currency.getSymbol();
 434:     this.currency = currency;
 435:   }
 436: 
 437:   /**
 438:    * This method sets the currency symbol to the specified value.
 439:    *
 440:    * @param currency The new currency symbol
 441:    */
 442:   public void setCurrencySymbol (String currency)
 443:   {
 444:     currencySymbol = currency;
 445:   }
 446: 
 447:   /**
 448:    * This method sets the decimal point character to the specified value.
 449:    *
 450:    * @param decimalSep The new decimal point character
 451:    */
 452:   public void setDecimalSeparator (char decimalSep)
 453:   {
 454:     decimalSeparator = decimalSep;
 455:   }
 456: 
 457:   /**
 458:    * This method sets the character used to represents a digit in a format
 459:    * string to the specified value.
 460:    *
 461:    * @param digit The character used to represent a digit in a format pattern.
 462:    */
 463:   public void setDigit (char digit)
 464:   {
 465:     this.digit = digit;
 466:   }
 467: 
 468:   /**
 469:    * This method sets the exponential character used in the format string to
 470:    * the specified value.  This is a GNU Classpath extension.
 471:    *
 472:    * @param exp the character used for the exponential in a format pattern.
 473:    */
 474:   void setExponential (char exp)
 475:   {
 476:     exponential = exp;
 477:   }
 478: 
 479:   /**
 480:    * This method sets the character used to separate groups of digits.
 481:    *
 482:    * @param groupSep The character used to separate groups of digits.
 483:    */
 484:   public void setGroupingSeparator (char groupSep)
 485:   {
 486:     groupingSeparator = groupSep;
 487:   }
 488: 
 489:   /**
 490:    * This method sets the string used to represents infinity.
 491:    *
 492:    * @param infinity The string used to represent infinity.
 493:    */
 494:   public void setInfinity (String infinity)
 495:   {
 496:     this.infinity = infinity;
 497:   }
 498: 
 499:   /**
 500:    * This method sets the international currency symbol to the
 501:    * specified value. If a valid <code>Currency</code> instance
 502:    * exists for the international currency code, then this is
 503:    * used for the currency attribute, and the currency symbol
 504:    * is set to the corresponding value from this instance.
 505:    * Otherwise, the currency attribute is set to null and the
 506:    * symbol is left unmodified. 
 507:    *
 508:    * @param currencyCode The new international currency symbol.
 509:    */
 510:   public void setInternationalCurrencySymbol (String currencyCode)
 511:   {
 512:     intlCurrencySymbol = currencyCode;
 513:     try
 514:       {
 515:     currency = Currency.getInstance(currencyCode);
 516:       }
 517:     catch (IllegalArgumentException exception)
 518:       {
 519:     currency = null;
 520:       }
 521:     if (currency != null)
 522:       {
 523:         setCurrencySymbol(currency.getSymbol(locale));
 524:       }
 525:   }
 526: 
 527:   /**
 528:    * This method sets the character used to represent the minus sign.
 529:    *
 530:    * @param minusSign The character used to represent the minus sign.
 531:    */
 532:   public void setMinusSign (char minusSign)
 533:   {
 534:     this.minusSign = minusSign;
 535:   }
 536: 
 537:   /**
 538:    * This method sets the character used for the decimal point in currency
 539:    * values.
 540:    *
 541:    * @param decimalSep The decimal point character used in currency values. 
 542:    */
 543:   public void setMonetaryDecimalSeparator (char decimalSep)
 544:   {
 545:     monetarySeparator = decimalSep;
 546:   }
 547: 
 548:   /**
 549:    * This method sets the string used to represent the NaN (not a
 550:    * number) value. 
 551:    *
 552:    * @param nan The string used to represent NaN
 553:    */
 554:   public void setNaN (String nan)
 555:   {
 556:     NaN = nan;
 557:   }
 558: 
 559:   /**
 560:    * This method sets the character used to separate positive and negative
 561:    * subpatterns in a format pattern.
 562:    *
 563:    * @param patternSep The character used to separate positive and
 564:    * negative subpatterns in a format pattern.
 565:    */
 566:   public void setPatternSeparator (char patternSep)
 567:   {
 568:     patternSeparator = patternSep;
 569:   }
 570: 
 571:   /**
 572:    * This method sets the character used as the percent sign.
 573:    *
 574:    * @param percent  The character used as the percent sign.
 575:    */
 576:   public void setPercent (char percent)
 577:   {
 578:     this.percent = percent;
 579:   }
 580: 
 581:   /**
 582:    * This method sets the character used as the per mille character.
 583:    *
 584:    * @param perMill The per mille character.
 585:    */
 586:   public void setPerMill (char perMill)
 587:   {
 588:     this.perMill = perMill;
 589:   }
 590: 
 591:   /**
 592:    * This method sets the character used to represent the digit zero.
 593:    *
 594:    * @param zeroDigit The character used to represent the digit zero.
 595:    */
 596:   public void setZeroDigit (char zeroDigit)
 597:   {
 598:     this.zeroDigit = zeroDigit;
 599:   }
 600: 
 601:   /**
 602:    * @serial A string used for the local currency
 603:    */
 604:   private String currencySymbol;
 605:   /**
 606:    * @serial The <code>char</code> used to separate decimals in a number.
 607:    */
 608:   private char decimalSeparator;
 609:   /**
 610:    * @serial This is the <code>char</code> used to represent a digit in
 611:    * a format specification.
 612:    */
 613:   private char digit;
 614:   /**
 615:    * @serial This is the <code>char</code> used to represent the exponent
 616:    * separator in exponential notation.
 617:    */
 618:   private char exponential;
 619:   /**
 620:    * @serial This separates groups of thousands in numbers.
 621:    */
 622:   private char groupingSeparator;
 623:   /**
 624:    * @serial This string represents infinity.
 625:    */
 626:   private String infinity;
 627:   /**
 628:    * @serial This string represents the local currency in an international
 629:    * context, eg, "C$" for Canadian dollars.
 630:    */
 631:   private String intlCurrencySymbol;
 632:   /**
 633:    * @serial This is the character used to represent the minus sign.
 634:    */
 635:   private char minusSign;
 636:   /**
 637:    * @serial This character is used to separate decimals when formatting
 638:    * currency values.
 639:    */
 640:   private char monetarySeparator;
 641:   /**
 642:    * @serial This string is used the represent the Java NaN value for
 643:    * "not a number".
 644:    */
 645:   private String NaN;
 646:   /**
 647:    * @serial This is the character used to separate positive and negative
 648:    * subpatterns in a format pattern.
 649:    */
 650:   private char patternSeparator;
 651:   /**
 652:    * @serial This is the percent symbols
 653:    */
 654:   private char percent;
 655:   /**
 656:    * @serial This character is used for the mille percent sign.
 657:    */
 658:   private char perMill;
 659:   /**
 660:    * @serial This value represents the type of object being de-serialized.
 661:    * 0 indicates a pre-Java 1.1.6 version, 1 indicates 1.1.6 or later.
 662:    * 0 indicates a pre-Java 1.1.6 version, 1 indicates 1.1.6 or later,
 663:    * 2 indicates 1.4 or later
 664:     */
 665:   private int serialVersionOnStream = 2;
 666:   /**
 667:    * @serial This is the character used to represent 0.
 668:    */
 669:   private char zeroDigit;
 670: 
 671:   /**
 672:    * @serial The locale of these currency symbols.
 673:    */
 674:   private Locale locale;
 675: 
 676:   /**
 677:    * The currency used for the symbols in this instance.
 678:    * This is stored temporarily for efficiency reasons,
 679:    * as well as to ensure that the correct instance
 680:    * is restored from the currency code.
 681:    *
 682:    * @serial Ignored.
 683:    */
 684:   private transient Currency currency;
 685: 
 686:   private static final long serialVersionUID = 5772796243397350300L;
 687: 
 688:   private void readObject(ObjectInputStream stream)
 689:     throws IOException, ClassNotFoundException
 690:   {
 691:     stream.defaultReadObject();
 692:     if (serialVersionOnStream < 1)
 693:       {
 694:         monetarySeparator = decimalSeparator;
 695:     exponential = 'E';
 696:       }
 697:     if (serialVersionOnStream < 2)
 698:     locale = Locale.getDefault();
 699: 
 700:     serialVersionOnStream = 2;
 701:   }
 702: 
 703:   /**
 704:    * Returns a {@link DecimalFormatSymbols} instance for the
 705:    * default locale obtained from either the runtime itself
 706:    * or one of the installed
 707:    * {@link java.text.spi.DecimalFormatSymbolsProvider} instances.
 708:    * This is equivalent to calling
 709:    * <code>getInstance(Locale.getDefault())</code>.
 710:    * 
 711:    * @return a {@link DecimalFormatSymbols} instance for the default
 712:    *         locale.
 713:    * @since 1.6
 714:    */
 715:   public static final DecimalFormatSymbols getInstance()
 716:   {
 717:     return getInstance(Locale.getDefault());
 718:   }
 719: 
 720:   /**
 721:    * Returns a {@link DecimalFormatSymbols} instance for the
 722:    * specified locale obtained from either the runtime itself
 723:    * or one of the installed
 724:    * {@link java.text.spi.DecimalFormatSymbolsProvider} instances.
 725:    * 
 726:    * @param locale the locale for which an instance should be
 727:    *               returned.
 728:    * @return a {@link DecimalFormatSymbols} instance for the specified
 729:    *         locale.
 730:    * @throws NullPointerException if <code>locale</code> is
 731:    *                              <code>null</code>.
 732:    * @since 1.6
 733:    */
 734:   public static final DecimalFormatSymbols getInstance(Locale locale)
 735:   {
 736:     try
 737:       {
 738:     if (!locale.equals(Locale.ROOT))
 739:       ResourceBundle.getBundle("gnu.java.locale.LocaleInformation",
 740:                    locale,
 741:                    ClassLoader.getSystemClassLoader());
 742:     return new DecimalFormatSymbols(locale);    
 743:       }
 744:     catch (MissingResourceException x)
 745:       {
 746:     /* This means runtime support for the locale
 747:      * is not available, so we check providers. */
 748:       }
 749:     for (DecimalFormatSymbolsProvider p :
 750:        ServiceLoader.load(DecimalFormatSymbolsProvider.class))
 751:       {
 752:     for (Locale loc : p.getAvailableLocales())
 753:       {
 754:         if (loc.equals(locale))
 755:           {
 756:         DecimalFormatSymbols syms = p.getInstance(locale);
 757:         if (syms != null)
 758:           return syms;
 759:         break;
 760:           }
 761:       }
 762:       }
 763:     return getInstance(LocaleHelper.getFallbackLocale(locale));
 764:   }
 765: 
 766: }