All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.joda.money.format.MoneyFormatter Maven / Gradle / Ivy

There is a newer version: 2.0.0
Show newest version
/*
 *  Copyright 2009-present, Stephen Colebourne
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.joda.money.format;

import java.io.IOException;
import java.io.Serializable;
import java.util.Locale;

import org.joda.money.BigMoney;
import org.joda.money.BigMoneyProvider;
import org.joda.money.Money;

/**
 * Formats instances of money to and from a String.
 * 

* Instances of {@code MoneyFormatter} can be created by * {@code MoneyFormatterBuilder}. *

* This class is immutable and thread-safe. */ public final class MoneyFormatter implements Serializable { /** * Serialization version. */ private static final long serialVersionUID = 2385346258L; /** * The locale to use. */ private final Locale locale; /** * The printer/parser. */ private final MultiPrinterParser printerParser; //----------------------------------------------------------------------- /** * Validates that the object specified is not null * * @param object the object to check, null throws exception * @param message the message to use in the exception, not null * @throws NullPointerException if the input value is null */ static void checkNotNull(Object object, String message) { if (object == null) { throw new NullPointerException(message); } } //----------------------------------------------------------------------- /** * Constructor, creating a new formatter. * * @param locale the locale to use, not null * @param printers the printers, not null * @param parsers the parsers, not null */ MoneyFormatter(Locale locale, MoneyPrinter[] printers, MoneyParser[] parsers) { MoneyFormatter.checkNotNull(locale, "Locale must not be null"); MoneyFormatter.checkNotNull(printers, "Printers must not be null"); MoneyFormatter.checkNotNull(parsers, "Parsers must not be null"); if (printers.length != parsers.length) { throw new IllegalArgumentException("Printers and parsers must match"); } this.locale = locale; this.printerParser = new MultiPrinterParser(printers, parsers); } /** * Constructor, creating a new formatter. * * @param locale the locale to use, not null * @param printerParser the printer/parser, not null */ private MoneyFormatter(Locale locale, MultiPrinterParser printerParser) { MoneyFormatter.checkNotNull(locale, "Locale must not be null"); MoneyFormatter.checkNotNull(printerParser, "PrinterParser must not be null"); this.locale = locale; this.printerParser = printerParser; } //----------------------------------------------------------------------- /** * Gets the printer/parser. * * @return the printer/parser, never null */ MultiPrinterParser getPrinterParser() { return printerParser; } //----------------------------------------------------------------------- /** * Gets the locale to use. * * @return the locale, never null */ public Locale getLocale() { return locale; } /** * Returns a copy of this instance with the specified locale. *

* Changing the locale may change the style of output depending on how the * formatter has been configured. * * @param locale the locale, not null * @return the new instance, never null */ public MoneyFormatter withLocale(Locale locale) { checkNotNull(locale, "Locale must not be null"); return new MoneyFormatter(locale, printerParser); } //----------------------------------------------------------------------- /** * Checks whether this formatter can print. *

* If the formatter cannot print, an UnsupportedOperationException will * be thrown from the print methods. * * @return true if the formatter can print */ public boolean isPrinter() { return printerParser.isPrinter(); } /** * Checks whether this formatter can parse. *

* If the formatter cannot parse, an UnsupportedOperationException will * be thrown from the parse methods. * * @return true if the formatter can parse */ public boolean isParser() { return printerParser.isParser(); } //----------------------------------------------------------------------- /** * Prints a monetary value to a {@code String}. * * @param moneyProvider the money to print, not null * @return the string printed using the settings of this formatter * @throws UnsupportedOperationException if the formatter is unable to print * @throws MoneyFormatException if there is a problem while printing */ public String print(BigMoneyProvider moneyProvider) { StringBuilder buf = new StringBuilder(); print(buf, moneyProvider); return buf.toString(); } /** * Prints a monetary value to an {@code Appendable} converting * any {@code IOException} to a {@code MoneyFormatException}. *

* Example implementations of {@code Appendable} are {@code StringBuilder}, * {@code StringBuffer} or {@code Writer}. Note that {@code StringBuilder} * and {@code StringBuffer} never throw an {@code IOException}. * * @param appendable the appendable to add to, not null * @param moneyProvider the money to print, not null * @throws UnsupportedOperationException if the formatter is unable to print * @throws MoneyFormatException if there is a problem while printing */ public void print(Appendable appendable, BigMoneyProvider moneyProvider) { try { printIO(appendable, moneyProvider); } catch (IOException ex) { throw new MoneyFormatException(ex.getMessage(), ex); } } /** * Prints a monetary value to an {@code Appendable} potentially * throwing an {@code IOException}. *

* Example implementations of {@code Appendable} are {@code StringBuilder}, * {@code StringBuffer} or {@code Writer}. Note that {@code StringBuilder} * and {@code StringBuffer} never throw an {@code IOException}. * * @param appendable the appendable to add to, not null * @param moneyProvider the money to print, not null * @throws UnsupportedOperationException if the formatter is unable to print * @throws MoneyFormatException if there is a problem while printing * @throws IOException if an IO error occurs */ public void printIO(Appendable appendable, BigMoneyProvider moneyProvider) throws IOException { checkNotNull(moneyProvider, "BigMoneyProvider must not be null"); if (isPrinter() == false) { throw new UnsupportedOperationException("MoneyFomatter has not been configured to be able to print"); } BigMoney money = BigMoney.of(moneyProvider); MoneyPrintContext context = new MoneyPrintContext(locale); printerParser.print(context, appendable, money); } //----------------------------------------------------------------------- /** * Fully parses the text into a {@code BigMoney}. *

* The parse must complete normally and parse the entire text (currency and amount). * If the parse completes without reading the entire length of the text, an exception is thrown. * If any other problem occurs during parsing, an exception is thrown. * * @param text the text to parse, not null * @return the parsed monetary value, never null * @throws UnsupportedOperationException if the formatter is unable to parse * @throws MoneyFormatException if there is a problem while parsing */ public BigMoney parseBigMoney(CharSequence text) { checkNotNull(text, "Text must not be null"); MoneyParseContext result = parse(text, 0); if (result.isError() || result.isFullyParsed() == false || result.isComplete() == false) { String str = (text.length() > 64 ? text.subSequence(0, 64).toString() + "..." : text.toString()); if (result.isError()) { throw new MoneyFormatException("Text could not be parsed at index " + result.getErrorIndex() + ": " + str); } else if (result.isFullyParsed() == false) { throw new MoneyFormatException("Unparsed text found at index " + result.getIndex() + ": " + str); } else { throw new MoneyFormatException("Parsing did not find both currency and amount: " + str); } } return result.toBigMoney(); } /** * Fully parses the text into a {@code Money} requiring that the parsed * amount has the correct number of decimal places. *

* The parse must complete normally and parse the entire text (currency and amount). * If the parse completes without reading the entire length of the text, an exception is thrown. * If any other problem occurs during parsing, an exception is thrown. * * @param text the text to parse, not null * @return the parsed monetary value, never null * @throws UnsupportedOperationException if the formatter is unable to parse * @throws MoneyFormatException if there is a problem while parsing * @throws ArithmeticException if the scale of the parsed money exceeds the scale of the currency */ public Money parseMoney(CharSequence text) { return parseBigMoney(text).toMoney(); } /** * Parses the text extracting monetary information. *

* This method parses the input providing low-level access to the parsing state. * The resulting context contains the parsed text, indicator of error, position * following the parse and the parsed currency and amount. * Together, these provide enough information for higher level APIs to use. * * @param text the text to parse, not null * @param startIndex the start index to parse from * @return the parsed monetary value, null only if the parse results in an error * @throws IndexOutOfBoundsException if the start index is invalid * @throws UnsupportedOperationException if this formatter cannot parse */ public MoneyParseContext parse(CharSequence text, int startIndex) { checkNotNull(text, "Text must not be null"); if (startIndex < 0 || startIndex > text.length()) { throw new StringIndexOutOfBoundsException("Invalid start index: " + startIndex); } if (isParser() == false) { throw new UnsupportedOperationException("MoneyFomatter has not been configured to be able to parse"); } MoneyParseContext context = new MoneyParseContext(locale, text, startIndex); printerParser.parse(context); return context; } //----------------------------------------------------------------------- /** * Gets a string summary of the formatter. * * @return a string summarising the formatter, never null */ @Override public String toString() { return printerParser.toString(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy