001/*
002 * CREDIT SUISSE IS WILLING TO LICENSE THIS SPECIFICATION TO YOU ONLY UPON THE CONDITION THAT YOU
003 * ACCEPT ALL OF THE TERMS CONTAINED IN THIS AGREEMENT. PLEASE READ THE TERMS AND CONDITIONS OF THIS
004 * AGREEMENT CAREFULLY. BY DOWNLOADING THIS SPECIFICATION, YOU ACCEPT THE TERMS AND CONDITIONS OF
005 * THE AGREEMENT. IF YOU ARE NOT WILLING TO BE BOUND BY IT, SELECT THE "DECLINE" BUTTON AT THE
006 * BOTTOM OF THIS PAGE. Specification: JSR-354 Money and Currency API ("Specification") Copyright
007 * (c) 2012-2013, Credit Suisse All rights reserved.
008 */
009package org.javamoney.moneta.spi.base;
010
011import javax.money.MonetaryAmount;
012import javax.money.format.MonetaryAmountFormat;
013import java.io.IOException;
014
015/**
016 *
017 * Formats instances of {@code MonetaryAmount} to a {@link String} or an {@link Appendable}.
018 *
019 *
020 * To obtain a <code>MonetaryAmountFormat</code> for a specific locale, including the default
021 * locale, call {@link javax.money.format.MonetaryFormats#getAmountFormat(java.util.Locale, String...)}.
022 *
023 * More complex formatting scenarios can be implemented by registering instances of {@link javax.money.spi
024 * .MonetaryAmountFormatProviderSpi}.
025 * The spi implementation creates new instances of {@link BaseMonetaryAmountFormat} based on the
026 * <i>styleId</i> and <i> (arbitrary) attributes</i> passed within the {@link javax.money.format.AmountFormatContext}.
027 *
028 * In general, do prefer
029 * accessing <code>MonetaryAmountFormat</code> instances from the {@link javax.money.format.MonetaryFormats} singleton,
030 * instead of instantiating implementations directly, since the <code>MonetaryFormats</code> factory
031 * method may return different subclasses or may implement contextual behaviour (in a EE context).
032 * If you need to customize the format object, do something like this:
033 *
034 * <blockquote>
035 *
036 * <pre>
037 * MonetaryAmountFormat f = MonetaryFormats.getInstance(loc);
038 * f.setStyle(f.getStyle().toBuilder().setPattern(&quot;###.##;(###.##)&quot;).build());
039 * </pre>
040 *
041 * </blockquote>
042 *
043 * <b>Special Values</b>
044 *
045 *
046 * Negative zero (<code>"-0"</code>) should always parse to
047 * <ul>
048 * <li><code>0</code></li>
049 * </ul>
050 *
051 * <b><a name="synchronization">Synchronization</a></b>
052 *
053 *
054 * Instances of this class are not required to be thread-safe. It is recommended to of separate
055 * format instances for each thread. If multiple threads access a format concurrently, it must be
056 * synchronized externally.
057 *
058 * <b>Example</b>
059 *
060 * {@code
061 * // Print out a number using the localized number, currency,
062 * // for each locale</strong>
063 * Locale[] locales = MonetaryFormats.getAvailableLocales();
064 * MonetaryAmount amount = ...;
065 * MonetaryAmountFormat form;
066 *     System.out.println("FORMAT");
067 *     for (int i = 0; i < locales.length; ++i) {
068 *         if (locales[i].getCountry().length() == 0) {
069 *            continue; // Skip language-only locales
070 *         }
071 *         System.out.print(locales[i].getDisplayName());
072 *         form = MonetaryFormats.getInstance(locales[i]);
073 *         System.out.print(": " + form.getStyle().getPattern());
074 *         String myAmount = form.format(amount);
075 *         System.out.print(" -> " + myAmount);
076 *         try {
077 *             System.out.println(" -> " + form.parse(form.format(myAmount)));
078 *         } catch (ParseException e) {}
079 *     }
080 * }
081 * }
082 */
083public abstract class BaseMonetaryAmountFormat implements MonetaryAmountFormat{
084
085    /**
086     * Formats the given {@link javax.money.MonetaryAmount} to a String.
087     *
088     * @param amount the amount to format, not {@code null}
089     * @return the string printed using the settings of this formatter
090     * @throws UnsupportedOperationException if the formatter is unable to print
091     */
092    public String format(MonetaryAmount amount){
093        StringBuilder b = new StringBuilder();
094        try{
095            print(b, amount);
096        }
097        catch(IOException e){
098            throw new IllegalStateException("Formatting error.", e);
099        }
100        return b.toString();
101    }
102
103}