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 * <p>
017 * Formats instances of {@code MonetaryAmount} to a {@link String} or an {@link Appendable}.
018 * </p>
019 * <p>
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 * </p>
028 * <p>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 * <p>
034 * <blockquote>
035 * <p>
036 * <pre>
037 * MonetaryAmountFormat f = MonetaryFormats.getInstance(loc);
038 * f.setStyle(f.getStyle().toBuilder().setPattern(&quot;###.##;(###.##)&quot;).build());
039 * </pre>
040 * <p>
041 * </blockquote>
042 * <p>
043 * <h4>Special Values</h4>
044 * <p>
045 * <p>
046 * Negative zero (<code>"-0"</code>) should always parse to
047 * <ul>
048 * <li><code>0</code></li>
049 * </ul>
050 * <p>
051 * <h4><a name="synchronization">Synchronization</a></h4>
052 * <p>
053 * <p>
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 * <p>
058 * <h4>Example</h4>
059 * <p>
060 * <blockquote>
061 * <p>
062 * <pre>
063 * <strong>// Print out a number using the localized number, currency,
064 * // for each locale</strong>
065 * Locale[] locales = MonetaryFormats.getAvailableLocales();
066 * MonetaryAmount amount = ...;
067 * MonetaryAmountFormat form;
068 *     System.out.println("FORMAT");
069 *     for (int i = 0; i < locales.length; ++i) {
070 *         if (locales[i].getCountry().length() == 0) {
071 *            continue; // Skip language-only locales
072 *         }
073 *         System.out.print(locales[i].getDisplayName());
074 *         form = MonetaryFormats.getInstance(locales[i]);
075 *         System.out.print(": " + form.getStyle().getPattern());
076 *         String myAmount = form.format(amount);
077 *         System.out.print(" -> " + myAmount);
078 *         try {
079 *             System.out.println(" -> " + form.parse(form.format(myAmount)));
080 *         } catch (ParseException e) {}
081 *     }
082 * }
083 * </pre>
084 * <p>
085 * </blockquote>
086 */
087public abstract class BaseMonetaryAmountFormat implements MonetaryAmountFormat{
088
089    /**
090     * Formats the given {@link javax.money.MonetaryAmount} to a String.
091     *
092     * @param amount the amount to format, not {@code null}
093     * @return the string printed using the settings of this formatter
094     * @throws UnsupportedOperationException if the formatter is unable to print
095     */
096    public String format(MonetaryAmount amount){
097        StringBuilder b = new StringBuilder();
098        try{
099            print(b, amount);
100        }
101        catch(IOException e){
102            throw new IllegalStateException("Formatting error.", e);
103        }
104        return b.toString();
105    }
106
107}