mirror of
https://github.com/purplecabbage/phonegap-plugins.git
synced 2026-04-24 03:00:11 -04:00
532 lines
22 KiB
Java
532 lines
22 KiB
Java
/*
|
|
* PhoneGap is available under *either* the terms of the modified BSD license *or* the
|
|
* MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
|
|
*
|
|
* Copyright (c) 2011, IBM Corporation
|
|
*/
|
|
package com.phonegap.plugins.globalization;
|
|
|
|
import com.phonegap.json4j.JSONArray;
|
|
import com.phonegap.json4j.JSONObject;
|
|
|
|
import com.phonegap.api.Plugin;
|
|
import com.phonegap.api.PluginResult;
|
|
|
|
import net.rim.device.api.i18n.Locale;
|
|
import net.rim.device.api.i18n.SimpleDateFormat;
|
|
import net.rim.device.api.util.TimeZoneUtilities;
|
|
import javax.microedition.global.Formatter;
|
|
|
|
import java.util.Date;
|
|
import java.util.Calendar;
|
|
import java.util.TimeZone;
|
|
import java.lang.Long;
|
|
|
|
public class Globalization extends Plugin {
|
|
|
|
/**
|
|
* Executes the requested action and returns a PluginResult.
|
|
*
|
|
* @param action
|
|
* The action to execute.
|
|
* @param data
|
|
* JSONArry of arguments for the action.
|
|
* @param callbackId
|
|
* The callback ID to be invoked upon action completion
|
|
* @return A PluginResult object with a status and message.
|
|
*/
|
|
public PluginResult execute(String action, JSONArray data, String callbackId) {
|
|
JSONObject obj = new JSONObject();
|
|
|
|
try {
|
|
if (action.equals(Resources.GETLOCALENAME)) {
|
|
obj = getLocaleName();
|
|
} else if (action.equalsIgnoreCase(Resources.DATETOSTRING)) {
|
|
obj = getDateToString(data);
|
|
} else if (action.equalsIgnoreCase(Resources.STRINGTODATE)) {
|
|
obj = getStringToDate(data);
|
|
} else if (action.equalsIgnoreCase(Resources.GETDATEPATTERN)) {
|
|
obj = getDatePattern(data);
|
|
} else if (action.equalsIgnoreCase(Resources.GETDATENAMES)) {
|
|
obj = getDateNames(data);
|
|
} else if (action.equalsIgnoreCase(Resources.ISDAYLIGHTSAVINGSTIME)) {
|
|
obj = getIsDayLightSavingsTime(data);
|
|
} else if (action.equalsIgnoreCase(Resources.GETFIRSTDAYOFWEEK)) {
|
|
obj = getFirstDayOfWeek(data);
|
|
} else if (action.equalsIgnoreCase(Resources.NUMBERTOSTRING)) {
|
|
obj = getNumberToString(data);
|
|
} else if (action.equalsIgnoreCase(Resources.STRINGTONUMBER)) {
|
|
obj = getStringToNumber(data);
|
|
} else if (action.equalsIgnoreCase(Resources.GETNUMBERPATTERN)) {
|
|
obj = getNumberPattern(data);
|
|
} else if (action.equalsIgnoreCase(Resources.GETCURRENCYPATTERN)) {
|
|
obj = getCurrencyPattern(data);
|
|
} else {
|
|
return new PluginResult(PluginResult.Status.INVALID_ACTION);
|
|
}
|
|
} catch (GlobalizationError ge) {
|
|
return new PluginResult(PluginResult.Status.ERROR,
|
|
ge.getErrorCode());
|
|
} catch (Exception e) {
|
|
return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
|
|
}
|
|
|
|
return new PluginResult(PluginResult.Status.OK, obj);
|
|
}
|
|
|
|
/*
|
|
* Returns the string identifier for the client's current locale setting.
|
|
*
|
|
* @return JSONObject Object.value {String}: The locale identifier
|
|
*
|
|
* @throws GlobalizationError.UNKNOWN_ERROR
|
|
*/
|
|
private JSONObject getLocaleName() throws GlobalizationError {
|
|
JSONObject obj = new JSONObject();
|
|
try {
|
|
return obj.put("value", Locale.getDefault().toString());
|
|
} catch (Exception e) {
|
|
throw new GlobalizationError(GlobalizationError.UNKNOWN_ERROR);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Returns a date formatted as a string according to the client's user
|
|
* preferences and calendar using the time zone of the client.
|
|
*
|
|
* @return JSONObject Object.value {String}: The localized date string
|
|
*
|
|
* @throws GlobalizationError.FORMATTING_ERROR
|
|
*/
|
|
private JSONObject getDateToString(JSONArray options)
|
|
throws GlobalizationError {
|
|
JSONObject obj = new JSONObject();
|
|
try {
|
|
Date date = new Date(Long.parseLong(options.getJSONObject(0)
|
|
.get(Resources.DATE).toString()));
|
|
// get formatting pattern from BB device
|
|
SimpleDateFormat fmt = new SimpleDateFormat(
|
|
Util.getBlackBerryDatePattern(options));
|
|
|
|
// return formatted date
|
|
return obj.put("value", fmt.format(date));
|
|
} catch (Exception ge) {
|
|
throw new GlobalizationError(GlobalizationError.FORMATTING_ERROR);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Parses a date formatted as a string according to the
|
|
* client's user preferences and calendar using the time zone of the client
|
|
* and returns the corresponding date object
|
|
*
|
|
* @return JSONObject
|
|
* Object.year {Number}: The four digit year
|
|
* Object.month {Number}: The month from (0 - 11)
|
|
* Object.day {Number}: The day from (1 - 31)
|
|
* Object.hour {Number}: The hour from (0 - 23)
|
|
* Object.minute {Number}: The minute from (0 - 59)
|
|
* Object.second {Number}: The second from (0 - 59)
|
|
* Object.millisecond {Number}: The milliseconds (from 0 - 999),
|
|
* not available on all platforms
|
|
*
|
|
* @throws GlobalizationError.PARSING_ERROR
|
|
*/
|
|
private JSONObject getStringToDate(JSONArray options)
|
|
throws GlobalizationError {
|
|
JSONObject obj = new JSONObject();
|
|
try {
|
|
// get formatting pattern from BB device
|
|
SimpleDateFormat fmt = new SimpleDateFormat(
|
|
Util.getBlackBerryDatePattern(options));
|
|
|
|
// Manually parse string based on user preferences or Locale default
|
|
String userDate = options.getJSONObject(0)
|
|
.get(Resources.DATESTRING).toString().trim();
|
|
|
|
Calendar date = Util.dateParserBB(userDate, fmt.toPattern());
|
|
if (date == null) { // date was unparsable
|
|
throw new Exception();
|
|
}
|
|
|
|
// return properties;
|
|
obj.put("year", date.get(Calendar.YEAR));
|
|
obj.put("month", date.get(Calendar.MONTH)); // returns 0-11
|
|
obj.put("day", date.get(Calendar.DAY_OF_MONTH));
|
|
obj.put("hour", date.get(Calendar.HOUR));
|
|
obj.put("minute", date.get(Calendar.MINUTE));
|
|
obj.put("second", date.get(Calendar.SECOND));
|
|
obj.put("millisecond", date.get(Calendar.MILLISECOND));
|
|
return obj;
|
|
} catch (Exception ge) {
|
|
throw new GlobalizationError(GlobalizationError.PARSING_ERROR);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Returns a pattern string for formatting and parsing dates
|
|
* according to the client's user preferences.
|
|
*
|
|
* @return JSONObject
|
|
* Object.pattern {String}: The date and time pattern for
|
|
* formatting and parsing dates. The
|
|
* patterns follow Unicode Technical Standard #35
|
|
* http://unicode.org/reports/tr35/tr35-4.html
|
|
* Object.timezone {String}: The abbreviated name of the
|
|
* time zone on the client
|
|
* Object.utc_offset {Number}: The current difference in seconds
|
|
* between the client's time zon and
|
|
* coordinated universal time.
|
|
* Object.dst_offset {Number}: The current daylight saving time
|
|
* offset in seconds between the client's
|
|
* non-daylight saving's time zone and the
|
|
* client's daylight saving's time zone.
|
|
*
|
|
* @throws GlobalizationError.PATTERN_ERROR
|
|
*/
|
|
private JSONObject getDatePattern(JSONArray options)
|
|
throws GlobalizationError {
|
|
JSONObject obj = new JSONObject();
|
|
try {
|
|
// TimeZone from users device
|
|
TimeZone tz = Calendar.getInstance().getTimeZone();
|
|
|
|
// Daylight
|
|
boolean daylight = tz.useDaylightTime();
|
|
|
|
// set dst_offset
|
|
int dst_offset = 0; // defaulted to zero
|
|
if (daylight) {
|
|
Calendar c = Calendar.getInstance();
|
|
dst_offset = (tz.getOffset(1, c.get(Calendar.YEAR),
|
|
c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH),
|
|
c.get(Calendar.DAY_OF_WEEK),
|
|
c.get(Calendar.MILLISECOND))) / 1000;
|
|
}
|
|
|
|
obj.put("pattern", Util.getBlackBerryDatePattern(options));
|
|
obj.put("timezone", TimeZoneUtilities.getDisplayName(tz,
|
|
TimeZoneUtilities.SHORT));
|
|
obj.put("utc_offset", tz.getRawOffset() / 1000);
|
|
obj.put("dst_offset", dst_offset);
|
|
return obj;
|
|
} catch (Exception ge) {
|
|
throw new GlobalizationError(GlobalizationError.PATTERN_ERROR);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Returns an array of either the names of the months or days of the week
|
|
* according to the client's user preferences and calendar
|
|
*
|
|
* @return JSONObject
|
|
* Object.value {Array{String}}: The array of names starting from
|
|
* either the first month in the year or the first
|
|
* day of the week.
|
|
*
|
|
* @throws GlobalizationError.UNKNOWN_ERROR
|
|
*/
|
|
private JSONObject getDateNames(JSONArray options)
|
|
throws GlobalizationError {
|
|
JSONObject obj = new JSONObject();
|
|
JSONArray value = new JSONArray();
|
|
try {
|
|
int type = 0; // default wide
|
|
int item = 0; // default months
|
|
|
|
// get options if available
|
|
if (options.getJSONObject(0).length() > 0) {
|
|
// get type if available
|
|
if (!((JSONObject) options.getJSONObject(0).get(
|
|
Resources.OPTIONS)).isNull(Resources.TYPE)) {
|
|
String t = (String) ((JSONObject) options.getJSONObject(0)
|
|
.get(Resources.OPTIONS)).get(Resources.TYPE);
|
|
if (t.equalsIgnoreCase(Resources.NARROW)) {
|
|
type++;
|
|
} // DateUtils.LENGTH_MEDIUM
|
|
}
|
|
// get item if available
|
|
if (!((JSONObject) options.getJSONObject(0).get(
|
|
Resources.OPTIONS)).isNull(Resources.ITEM)) {
|
|
String t = (String) ((JSONObject) options.getJSONObject(0)
|
|
.get(Resources.OPTIONS)).get(Resources.ITEM);
|
|
if (t.equalsIgnoreCase(Resources.DAYS)) {
|
|
item += 10;
|
|
} // Days of week start at 1
|
|
}
|
|
}
|
|
// determine return value
|
|
|
|
int method = item + type;
|
|
if (method == 1) {
|
|
value = Util.getDateNameString(Resources.MONTHS, "MMM");
|
|
}// months and narrow
|
|
else if (method == 10) {
|
|
value = Util.getDateNameString(Resources.DAYS, "EEEE");
|
|
}// days and wide
|
|
else if (method == 11) {
|
|
value = Util.getDateNameString(Resources.DAYS, "EEE");
|
|
}// days and narrow
|
|
else {
|
|
value = Util.getDateNameString(Resources.MONTHS, "MMMM");
|
|
}// default: months and wide
|
|
|
|
if (value == null) {
|
|
throw new Exception();
|
|
}
|
|
|
|
// return array of names
|
|
return obj.put("value", value);
|
|
} catch (Exception ge) {
|
|
throw new GlobalizationError(GlobalizationError.UNKNOWN_ERROR);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Returns whether daylight savings time is in effect for a
|
|
* given date using the client's time zone and calendar.
|
|
*
|
|
* @return JSONObject
|
|
* Object.dst {Boolean}: The value "true" indicates that daylight
|
|
* savings time is in effect for the given date
|
|
* and "false" indicates that it is not.
|
|
*
|
|
* @throws GlobalizationError.UNKNOWN_ERROR
|
|
*
|
|
* Note: Functionality to determine if date is within day light savings
|
|
* time is not available in this API version
|
|
*/
|
|
private JSONObject getIsDayLightSavingsTime(JSONArray options)
|
|
throws GlobalizationError {
|
|
throw new GlobalizationError(GlobalizationError.UNKNOWN_ERROR);
|
|
}
|
|
|
|
/*
|
|
* Returns the first day of the week according to the client's user
|
|
* preferences and calendar. The days of the week are numbered starting from
|
|
* 1 where 1 is considered to be Sunday.
|
|
*
|
|
* @return JSONObject Object.value {Number}: The number of the first day of
|
|
* the week.
|
|
*
|
|
* @throws GlobalizationError.UNKNOWN_ERROR
|
|
*/
|
|
private JSONObject getFirstDayOfWeek(JSONArray options)
|
|
throws GlobalizationError {
|
|
JSONObject obj = new JSONObject();
|
|
try {
|
|
JSONObject result = Util.getLocaleData(Locale.getDefault()
|
|
.toString());
|
|
|
|
if (result == null || result.length() <= 0) {
|
|
throw new Exception();
|
|
}
|
|
return obj.put("value", Integer.valueOf(result
|
|
.getString(Resources.JSON_FIRISTDAYOFWEEK)));
|
|
} catch (Exception e) {
|
|
throw new GlobalizationError(GlobalizationError.UNKNOWN_ERROR);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Returns a number formatted as a string according to the
|
|
* client's user preferences.
|
|
*
|
|
* @return JSONObject
|
|
* Object.value {String}: The formatted number string.
|
|
*
|
|
* @throws GlobalizationError.FORMATTING_ERROR
|
|
*/
|
|
private JSONObject getNumberToString(JSONArray options)
|
|
throws GlobalizationError {
|
|
JSONObject obj = new JSONObject();
|
|
String value;
|
|
try {
|
|
// Initialize formatter
|
|
Formatter fmt = new Formatter(Locale.getDefault().toString());
|
|
|
|
// obtain user supplied number
|
|
double num = Double.parseDouble(options.getJSONObject(0)
|
|
.get(Resources.NUMBER).toString());
|
|
// format based on options if available
|
|
value = fmt.formatNumber(num);
|
|
if (options.getJSONObject(0).length() > 1) {
|
|
// options were included
|
|
if (!((JSONObject) options.getJSONObject(0).get(
|
|
Resources.OPTIONS)).isNull(Resources.TYPE)) {
|
|
String fmtOpt = (String) ((JSONObject) options
|
|
.getJSONObject(0).get(Resources.OPTIONS))
|
|
.get(Resources.TYPE);
|
|
if (fmtOpt.equalsIgnoreCase(Resources.CURRENCY)) {
|
|
value = fmt.formatCurrency(num);
|
|
} else if (fmtOpt.equalsIgnoreCase(Resources.PERCENT)) {
|
|
// convert double to long
|
|
// used 1 decimal places as a default
|
|
value = fmt.formatPercentage((float) num, 1);
|
|
}
|
|
}
|
|
}
|
|
return obj.put("value", value);
|
|
} catch (Exception ge) {
|
|
throw new GlobalizationError(GlobalizationError.FORMATTING_ERROR);
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
* Parses a number formatted as a string according to the
|
|
* client's user preferences and returns the corresponding number.
|
|
*
|
|
* @return JSONObject
|
|
* Object.value {Number}: The parsed number.
|
|
*
|
|
* @throws GlobalizationError.PARSING_ERROR
|
|
*/
|
|
private JSONObject getStringToNumber(JSONArray options)
|
|
throws GlobalizationError {
|
|
JSONObject obj = new JSONObject();
|
|
double value = 0;
|
|
try {
|
|
// format based on options if available
|
|
String num = options.getJSONObject(0).get(Resources.NUMBERSTRING)
|
|
.toString().trim();
|
|
if (options.getJSONObject(0).length() > 1) {
|
|
// options were included
|
|
if (!((JSONObject) options.getJSONObject(0).get(
|
|
Resources.OPTIONS)).isNull(Resources.TYPE)) {
|
|
String fmtOpt = (String) ((JSONObject) options
|
|
.getJSONObject(0).get(Resources.OPTIONS))
|
|
.get(Resources.TYPE);
|
|
// remove unwanted symbols
|
|
if (fmtOpt.equalsIgnoreCase(Resources.CURRENCY)) {
|
|
value = (Double.parseDouble(Util.removeSymbols(num)));
|
|
} else if (fmtOpt.equalsIgnoreCase(Resources.PERCENT)) {
|
|
value = (Double.parseDouble(Util.removeSymbols(num)) / 100);
|
|
}
|
|
}
|
|
} else {
|
|
value = Double.parseDouble(num); // decimal default
|
|
}
|
|
|
|
return obj.put("value", value);
|
|
} catch (Exception ge) {
|
|
throw new GlobalizationError(GlobalizationError.PARSING_ERROR);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Returns a pattern string for formatting and parsing numbers
|
|
* according to the client's user preferences.
|
|
*
|
|
* @return JSONObject
|
|
* Object.pattern {String}: The number pattern for formatting
|
|
* and parsing numbers. The patterns follow
|
|
* Unicode Technical Standard #35.
|
|
* http://unicode.org/reports/tr35/tr35-4.html
|
|
* Object.symbol {String}: The symbol to be used when
|
|
* formatting and parsing e.g., percent or
|
|
* currency symbol.
|
|
* Object.fraction {Number}: The number of fractional digits
|
|
* to use when parsing and formatting numbers.
|
|
* Object.rounding {Number}: The rounding increment to use
|
|
* when parsing and formatting.
|
|
* Object.positive {String}: The symbol to use for positive
|
|
* numbers when parsing and formatting.
|
|
* Object.negative: {String}: The symbol to use for negative
|
|
* numbers when parsing and formatting.
|
|
* Object.decimal: {String}: The decimal symbol to use for
|
|
* parsing and formatting.
|
|
* Object.grouping: {String}: The grouping symbol to use
|
|
* for parsing and formatting.
|
|
*
|
|
* @throws GlobalizationError.PATTERN_ERROR
|
|
*/
|
|
private JSONObject getNumberPattern(JSONArray options)
|
|
throws GlobalizationError {
|
|
JSONObject obj = new JSONObject();
|
|
try {
|
|
JSONObject result = Util.getLocaleData(Locale.getDefault()
|
|
.toString());
|
|
|
|
String symbol = Resources.JSON_DECIMALSYMBOL;
|
|
// get Date value + options (if available)
|
|
if (options.getJSONObject(0).length() > 0) {
|
|
// options were included
|
|
if (!((JSONObject) options.getJSONObject(0).get(
|
|
Resources.OPTIONS)).isNull(Resources.TYPE)) {
|
|
String fmtOpt = (String) ((JSONObject) options
|
|
.getJSONObject(0).get(Resources.OPTIONS))
|
|
.get(Resources.TYPE);
|
|
if (fmtOpt.equalsIgnoreCase(Resources.CURRENCY)) {
|
|
symbol = Resources.JSON_CURRENCYSYMBOL;
|
|
} else if (fmtOpt.equalsIgnoreCase(Resources.PERCENT)) {
|
|
symbol = Resources.JSON_PERCENTSYMBOL;
|
|
}
|
|
}
|
|
}
|
|
|
|
// return properties
|
|
obj.put("pattern", result.getString(Resources.JSON_PATTERN));
|
|
obj.put("symbol", result.getString(symbol));
|
|
obj.put("fraction",
|
|
Integer.valueOf(result.getString(Resources.JSON_FRACTION)));
|
|
obj.put("rounding",
|
|
Integer.valueOf(result.getString(Resources.JSON_ROUNDING)));
|
|
obj.put("positive", result.getString(Resources.JSON_POSITIVE));
|
|
obj.put("negative", result.getString(Resources.JSON_NEGATIVE));
|
|
obj.put("decimal", result.getString(Resources.JSON_DECIMALSYMBOL));
|
|
obj.put("grouping", result.getString(Resources.JSON_GROUPING));
|
|
return obj;
|
|
} catch (Exception ge) {
|
|
throw new GlobalizationError(GlobalizationError.PATTERN_ERROR);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Returns a pattern string for formatting and parsing
|
|
* currency values according to the client's user preferences and ISO 4217
|
|
* currency code.
|
|
*
|
|
* @return JSONObject =
|
|
* Object.pattern {String}: The currency pattern for formatting
|
|
* and parsing currency values. The patterns
|
|
* follow Unicode Technical Standard #35
|
|
* http://unicode.org/reports/tr35/tr35-4.html
|
|
* Object.code {String}: The ISO 4217 currency code for the
|
|
* pattern.
|
|
* Object.fraction {Number}: The number of fractional digits
|
|
* to use when parsing and formatting currency.
|
|
* Object.rounding {Number}: The rounding increment to use
|
|
* when parsing and formatting.
|
|
* Object.decimal: {String}: The decimal symbol to use for
|
|
* parsing and formatting.
|
|
* Object.grouping: {String}: The grouping symbol to use
|
|
* for parsing and formatting.
|
|
*
|
|
* @throws GlobalizationError.FORMATTING_ERROR
|
|
*/
|
|
private JSONObject getCurrencyPattern(JSONArray options)
|
|
throws GlobalizationError {
|
|
JSONObject obj = new JSONObject();
|
|
try {
|
|
JSONObject result = Util.getCurrencyData(Locale.getDefault()
|
|
.toString(),
|
|
options.getJSONObject(0).getString(Resources.CURRENCYCODE));
|
|
|
|
// return properties
|
|
obj.put("pattern", result.getString(Resources.JSON_CURRENCYPATTERN));
|
|
obj.put("code", result.getString(Resources.JSON_CURRENCYCODE));
|
|
obj.put("fraction", Integer.valueOf(result
|
|
.getString(Resources.JSON_CURRENCYFRACTION)));
|
|
obj.put("rounding", Integer.valueOf(result
|
|
.getString(Resources.JSON_CURRENCYROUNDING)));
|
|
obj.put("decimal", result.getString(Resources.JSON_CURRENCYDECIMAL));
|
|
obj.put("grouping",
|
|
result.getString(Resources.JSON_CURRENCYGROUPING));
|
|
return obj;
|
|
} catch (Exception ge) {
|
|
throw new GlobalizationError(GlobalizationError.FORMATTING_ERROR);
|
|
}
|
|
}
|
|
}
|