FileDocCategorySizeDatePackage
FormatterImpl.javaAPI DocphoneME MR2 API (J2ME)11204Wed May 02 18:00:46 BST 2007com.sun.j2me.global

FormatterImpl.java

/*
 *   
 *
 * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version
 * 2 only, as published by the Free Software Foundation.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License version 2 for more details (a copy is
 * included at /legal/license.txt).
 * 
 * You should have received a copy of the GNU General Public License
 * version 2 along with this work; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 * 
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
 * Clara, CA 95054 or visit www.sun.com if you need additional
 * information or have any questions.
 */
package com.sun.j2me.global;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.Hashtable;
import javax.microedition.global.Formatter;
import javax.microedition.global.ResourceException;
import javax.microedition.global.UnsupportedLocaleException;
import com.sun.midp.log.Logging;
import com.sun.midp.log.LogChannels;

/**
 * This class actually realizes most of the methods of
 * {@link javax.microedition.global.Formatter}. Specifically, these are:
 * <ul>
 *   <li> {@link #formatDateTime(Calendar, int)}
 *   <li> {@link #formatCurrency(double)}
 *   <li> {@link #formatCurrency(double, String)}
 *   <li> {@link #formatNumber(double)}
 *   <li> {@link #formatNumber(double, int)}
 *   <li> {@link #formatNumber(long)}
 *   <li> {@link #formatPercentage(long number)}
 *   <li> {@link #formatPercentage(float, int)}
 * </ul>
 * <p>
 * This realization of <code>Formatter</code> is intended to be based on
 * some native functions for formatting support. Regarding this,
 * <code>FormatterImpl</code> uses locale index that points to its locale
 * instead of working with explicit locale code.
 */
public class FormatterImpl implements CommonFormatter {

    /**
     *  Current FormatterImpl locale index in the list of supported locales.
     */
    private int locale_index;

    /**
     * Constructs a <code>Formatter</code> implementation for the specified
     * locale.
     *
     * @param  locale  desired <code>FormatterImpl</code> locale
     * @throws UnsupportedLocaleException  The exception
     *      is thrown when locale isn't supported.
     */
    public FormatterImpl(String locale) throws UnsupportedLocaleException {
		locale_index = FormatAbstractionLayerImpl.getFormatLocaleIndex(locale);
		if (locale_index < 0) {
			throw new UnsupportedLocaleException("Locale \""
												 + locale +
												 "\" unsupported.");
		}
    }


    /**
     * Formats a date/time instance using locale-specific rules.
     * The <code>style</code> parameter determines the extent and style
     * of the result. <p>
     * If <code>dateTime</code> has an associated
     * <code>java.util.TimeZone</code>
     * object, <code>dateTime</code> MUST be interpreted as "wall time", not
     * universal time. The offset of that time zone MUST be reflected in the
     * formatted time.
     *
     * @param  dateTime         the date and time to format
     * @param  style            the formatting style to use
     * @return                  the date and/or time formatted as a string
     */
    public String formatDateTime(Calendar dateTime, int style) {
            return formatDateTime0(locale_index,
                                   dateTime.get(Calendar.YEAR), 
                                   dateTime.get(Calendar.MONTH) + 1, 
                                   dateTime.get(Calendar.DAY_OF_WEEK),
                                   dateTime.get(Calendar.DAY_OF_MONTH),
                                   dateTime.get(Calendar.HOUR_OF_DAY),
                                   dateTime.get(Calendar.MINUTE),
                                   dateTime.get(Calendar.SECOND),
                                   style);
    }

    private native String formatDateTime0(int locale,
                                          int year, int month,
                                          int dayOfWeek, int day,
                                          int hour, int minute, int secs,
                                          int style);


    /**
     * Formats a currency amount using locale-specific rules. This method
     * assumes that the amount is in the locale's currency. The result uses the
     * locale-specific decimal separator and may include grouping separators.
     * The number of decimals is also locale-specific. <p>
     *
     * This method does not perform any currency conversions based on exchange
     * rates.
     *x
     * @param  number  the currency amount to format
     * @return         the formatted currency amount
     */
    public String formatCurrency(double number) {
        return formatCurrency(number, null);
    }

    /**
     * Formats a currency amount using the locale-specific rules but using the
     * symbol of the specified currency. The currency is specified using its
     * ISO 4217 three-letter code, such as "USD", "EUR" or "GBP". If there is a
     * currency symbol attached to the ISO 4217 code in the implementation,
     * that symbol MUST be used instead of the locale's currency symbol. If the
     * implementation does not provide a currency symbol for a given ISO 4217
     * code, the code MUST be used as such. <p>
     *
     * The result uses the locale-specific decimal separator and may include
     * grouping separators. The number of decimals is also locale-specific. <p>
     *
     * This method does not perform any currency conversions based on exchange
     * rates.
     *
     * @param  number        the currency amount to format
     * @param  currencyCode  the ISO 4217 currency code to use
     * @return               formatted currency amount
     */
    public String formatCurrency(double number, String currencyCode) {
        if (Double.isNaN(number) || Double.isInfinite(number)) {
            return new Double(number).toString();
        }
        return formatCurrency0(locale_index, number, currencyCode);
    }

    private native String formatCurrency0(int locale, double number, String currency);


    /**
     * Formats a decimal number using locale-specific rules. The result
     * includes a locale-specific decimal separator and may include grouping
     * separators. <p>
     *
     * The symbols used for negative and positive infinity and NaN are
     * implementation-specific. Implementations MAY use the appropriate Unicode
     * character (U+221F INFINITY) if applicable.
     *
     * @param  number  the number to format
     * @return         formatted decimal number
     */
    public String formatNumber(double number) {
        if (Double.isNaN(number) || Double.isInfinite(number)) {
            return new Double(number).toString();
        }
        return formatNumber0(locale_index, number, -1);
    }


    /**
     * Formats a decimal number using locale-specific rules, with the specified
     * number of decimals. The result includes a locale-specific decimal
     * separator and may include grouping separators. <p>
     *
     * The number of decimals MUST be between 1 and 15. The formatted result
     * MUST have exactly the specified number of decimals, even if some of the
     * trailing digits are zeroes. <p>
     *
     * The symbols used for negative and positive infinity and NaN are
     * implementation-specific. Implementations MAY use the appropriate Unicode
     * character (U+221F INFINITY) if applicable.
     *
     * @param  number    the number to format
     * @param  decimals  number of decimals
     * @return           formatted decimal number
     */
    public String formatNumber(double number, int decimals) {
		if (decimals<=0 || decimals>15){
			throw new IllegalArgumentException("Wrong decimals parameter");
		}
        if (Double.isNaN(number) || Double.isInfinite(number)) {
            return new Double(number).toString();
        }
        return formatNumber0(locale_index, number, decimals);
    }


    /**
     * Formats an integer using locale-specific rules. The result may include
     * grouping separators.
     *
     * @param  number  the number to format
     * @return         formatted integer number
     */
    public String formatNumber(long number) {
        return formatNumber1(locale_index, number);
    }

    private native String formatNumber0(int locale, double number, int decimals);

	private native String formatNumber1(int locale, long number);

    /**
     * Formats an integral percentage value using locale-specific rules. This
     * method places the locale-specific percent sign at the correct position
     * in relation to the number, with the appropriate number of space
     * (possibly none) between the sign and the number. <p>
     *
     * A percentage is expressed as an integer value. Negative percentages are
     * allowed.
     *
     * @param  number  the number to format
     * @return         formatted percentage number
     */
    public String formatPercentage(long number) {
        return formatPercentage1(locale_index, number);
    }

    /**
     * Formats a percentage with the specified number of decimals using
     * locale-specific rules. This method places the locale-specific percent
     * sign at the correct position in relation to the number, with the
     * appropriate amount of space (possibly none) between the sign and the
     * number. <p>
     *
     * A percentage is expressed as a decimal number, with the value 0.0
     * interpreted as 0% and the value 1.0 as 100%. Percentages larger than
     * 100% are expressed as values greater than 1.0. Negative percentages are
     * allowed, and expressed as values smaller than 0.0. The percentage is
     * rounded to the specified number of decimals. <p>
     *
     * The number of decimals MUST be between 1 and 15. The formatted result
     * MUST have exactly the specified number of decimals, even if some of the
     * trailing digits are zeroes.
     *
     * @param  number    the percentage to format, expressed as a positive or
     *      negative number
     * @param  decimals  the number of decimals to use (1 <= decimals <=
     *      15)
     * @return           formatted percentage string
     */
    public String formatPercentage(float number, int decimals) {
		if (decimals<=0 || decimals>15){
			throw new IllegalArgumentException("Wrong decimals parameter");
		}
        if (Float.isNaN(number) || Float.isInfinite(number)) {
            return new Float(number).toString();
        }
        return formatPercentage0(locale_index, number, decimals);
    }

    private native String formatPercentage0(int locale_index, float number, int decimals);

	private native String formatPercentage1(int locale_index, long number);
}