Return-Path: X-Original-To: apmail-incubator-callback-commits-archive@minotaur.apache.org Delivered-To: apmail-incubator-callback-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id F03D1D296 for ; Wed, 19 Sep 2012 18:09:06 +0000 (UTC) Received: (qmail 60295 invoked by uid 500); 19 Sep 2012 18:09:06 -0000 Delivered-To: apmail-incubator-callback-commits-archive@incubator.apache.org Received: (qmail 60264 invoked by uid 500); 19 Sep 2012 18:09:06 -0000 Mailing-List: contact callback-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: callback-dev@incubator.apache.org Delivered-To: mailing list callback-commits@incubator.apache.org Received: (qmail 60255 invoked by uid 99); 19 Sep 2012 18:09:06 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 19 Sep 2012 18:09:06 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 8743438066; Wed, 19 Sep 2012 18:09:06 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: macdonst@apache.org To: callback-commits@incubator.apache.org X-Mailer: ASF-Git Admin Mailer Subject: android commit: CB-1469: Add Globalization Plug-in for Android Message-Id: <20120919180906.8743438066@tyr.zones.apache.org> Date: Wed, 19 Sep 2012 18:09:06 +0000 (UTC) Updated Branches: refs/heads/master f71e66495 -> 631245742 CB-1469: Add Globalization Plug-in for Android Project: http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/commit/63124574 Tree: http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/tree/63124574 Diff: http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/diff/63124574 Branch: refs/heads/master Commit: 6312457425a0833564a4726998dac79729479b91 Parents: f71e664 Author: Simon MacDonald Authored: Wed Sep 19 14:08:52 2012 -0400 Committer: Simon MacDonald Committed: Wed Sep 19 14:08:52 2012 -0400 ---------------------------------------------------------------------- framework/assets/js/cordova.android.js | 547 ++++++++++++++- framework/res/xml/config.xml | 1 + .../src/org/apache/cordova/Globalization.java | 560 +++++++++++++++ .../src/org/apache/cordova/GlobalizationError.java | 72 ++ 4 files changed, 1178 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/blob/63124574/framework/assets/js/cordova.android.js ---------------------------------------------------------------------- diff --git a/framework/assets/js/cordova.android.js b/framework/assets/js/cordova.android.js index 7a7806e..7f9a826 100644 --- a/framework/assets/js/cordova.android.js +++ b/framework/assets/js/cordova.android.js @@ -1,6 +1,6 @@ -// commit d30179b30152b9383a80637e609cf2d785e1aa3e +// commit 65b59c7e484a9e5227fa7b4de8e784a8466b2ef5 -// File generated at :: Tue Sep 18 2012 11:34:26 GMT-0400 (EDT) +// File generated at :: Wed Sep 19 2012 13:58:04 GMT-0400 (EDT) /* Licensed to the Apache Software Foundation (ASF) under one @@ -729,6 +729,9 @@ module.exports = { geolocation: { path: 'cordova/plugin/geolocation' }, + globalization: { + path: 'cordova/plugin/globalization' + }, network: { children: { connection: { @@ -844,6 +847,9 @@ module.exports = { Flags: { path: 'cordova/plugin/Flags' }, + GlobalizationError: { + path: 'cordova/plugin/GlobalizationError' + }, LocalFileSystem: { path: 'cordova/plugin/LocalFileSystem' }, @@ -3118,6 +3124,22 @@ module.exports = Flags; }); +// file: lib/common/plugin/GlobalizationError.js +define("cordova/plugin/GlobalizationError", function(require, exports, module) { +var GlobalizationError = function(code, message) { + this.code = code || null; + this.message = message || ''; +}; + +// Globalization error codes +GlobalizationError.UNKNOWN_ERROR = 0; +GlobalizationError.FORMATTING_ERROR = 1; +GlobalizationError.PARSING_ERROR = 2; +GlobalizationError.PATTERN_ERROR = 3; + +module.exports = GlobalizationError; +}); + // file: lib/common/plugin/LocalFileSystem.js define("cordova/plugin/LocalFileSystem", function(require, exports, module) { @@ -5205,6 +5227,527 @@ module.exports = geolocation; }); +// file: lib/common/plugin/globalization.js +define("cordova/plugin/globalization", function(require, exports, module) { +var exec = require('cordova/exec'), + GlobalizationError = require('cordova/plugin/GlobalizationError'); + +var globalization = { + +getPreferredLanguage:function(successCB, failureCB) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.getPreferredLanguage Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.getPreferredLanguage Error: failureCB is not a function"); + return; + } + + exec(successCB, failureCB, "Globalization","getPreferredLanguage", []); +}, + +/** +* Returns the string identifier for the client's current locale setting. +* It returns the locale identifier string to the successCB callback with a +* properties object as a parameter. If there is an error getting the locale, +* then the errorCB callback is invoked. +* +* @param {Function} successCB +* @param {Function} errorCB +* +* @return Object.value {String}: The locale identifier +* +* @error GlobalizationError.UNKNOWN_ERROR +* +* Example +* globalization.getLocaleName(function (locale) {alert('locale:' + locale.value + '\n');}, +* function () {}); +*/ +getLocaleName:function(successCB, failureCB) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.getLocaleName Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.getLocaleName Error: failureCB is not a function"); + return; + } + exec(successCB, failureCB, "Globalization","getLocaleName", []); +}, + + +/** +* Returns a date formatted as a string according to the client's user preferences and +* calendar using the time zone of the client. It returns the formatted date string to the +* successCB callback with a properties object as a parameter. If there is an error +* formatting the date, then the errorCB callback is invoked. +* +* The defaults are: formatLenght="short" and selector="date and time" +* +* @param {Date} date +* @param {Function} successCB +* @param {Function} errorCB +* @param {Object} options {optional} +* formatLength {String}: 'short', 'medium', 'long', or 'full' +* selector {String}: 'date', 'time', or 'date and time' +* +* @return Object.value {String}: The localized date string +* +* @error GlobalizationError.FORMATTING_ERROR +* +* Example +* globalization.dateToString(new Date(), +* function (date) {alert('date:' + date.value + '\n');}, +* function (errorCode) {alert(errorCode);}, +* {formatLength:'short'}); +*/ +dateToString:function(date, successCB, failureCB, options) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.dateToString Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.dateToString Error: failureCB is not a function"); + return; + } + + + if (date instanceof Date){ + var dateValue; + dateValue = date.valueOf(); + exec(successCB, failureCB, "Globalization", "dateToString", [{"date": dateValue, "options": options}]); + } + else { + console.log("Globalization.dateToString Error: date is not a Date object"); + } +}, + + +/** +* 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. It returns the date to the successCB +* callback with a properties object as a parameter. If there is an error +* parsing the date string, then the errorCB callback is invoked. +* +* The defaults are: formatLength="short" and selector="date and time" +* +* @param {String} dateString +* @param {Function} successCB +* @param {Function} errorCB +* @param {Object} options {optional} +* formatLength {String}: 'short', 'medium', 'long', or 'full' +* selector {String}: 'date', 'time', or 'date and time' +* +* @return 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 +* +* @error GlobalizationError.PARSING_ERROR +* +* Example +* globalization.stringToDate('4/11/2011', +* function (date) { alert('Month:' + date.month + '\n' + +* 'Day:' + date.day + '\n' + +* 'Year:' + date.year + '\n');}, +* function (errorCode) {alert(errorCode);}, +* {selector:'date'}); +*/ +stringToDate:function(dateString, successCB, failureCB, options) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.stringToDate Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.stringToDate Error: failureCB is not a function"); + return; + } + if (typeof dateString == "string"){ + exec(successCB, failureCB, "Globalization", "stringToDate", [{"dateString": dateString, "options": options}]); + } + else { + console.log("Globalization.stringToDate Error: dateString is not a string"); + } +}, + + +/** +* Returns a pattern string for formatting and parsing dates according to the client's +* user preferences. It returns the pattern to the successCB callback with a +* properties object as a parameter. If there is an error obtaining the pattern, +* then the errorCB callback is invoked. +* +* The defaults are: formatLength="short" and selector="date and time" +* +* @param {Function} successCB +* @param {Function} errorCB +* @param {Object} options {optional} +* formatLength {String}: 'short', 'medium', 'long', or 'full' +* selector {String}: 'date', 'time', or 'date and time' +* +* @return 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 zone 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. +* +* @error GlobalizationError.PATTERN_ERROR +* +* Example +* globalization.getDatePattern( +* function (date) {alert('pattern:' + date.pattern + '\n');}, +* function () {}, +* {formatLength:'short'}); +*/ +getDatePattern:function(successCB, failureCB, options) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.getDatePattern Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.getDatePattern Error: failureCB is not a function"); + return; + } + + exec(successCB, failureCB, "Globalization", "getDatePattern", [{"options": options}]); +}, + + +/** +* Returns an array of either the names of the months or days of the week +* according to the client's user preferences and calendar. It returns the array of names to the +* successCB callback with a properties object as a parameter. If there is an error obtaining the +* names, then the errorCB callback is invoked. +* +* The defaults are: type="wide" and item="months" +* +* @param {Function} successCB +* @param {Function} errorCB +* @param {Object} options {optional} +* type {String}: 'narrow' or 'wide' +* item {String}: 'months', or 'days' +* +* @return Object.value {Array{String}}: The array of names starting from either +* the first month in the year or the +* first day of the week. +* @error GlobalizationError.UNKNOWN_ERROR +* +* Example +* globalization.getDateNames(function (names) { +* for(var i = 0; i < names.value.length; i++) { +* alert('Month:' + names.value[i] + '\n');}}, +* function () {}); +*/ +getDateNames:function(successCB, failureCB, options) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.getDateNames Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.getDateNames Error: failureCB is not a function"); + return; + } + exec(successCB, failureCB, "Globalization", "getDateNames", [{"options": options}]); +}, + +/** +* Returns whether daylight savings time is in effect for a given date using the client's +* time zone and calendar. It returns whether or not daylight savings time is in effect +* to the successCB callback with a properties object as a parameter. If there is an error +* reading the date, then the errorCB callback is invoked. +* +* @param {Date} date +* @param {Function} successCB +* @param {Function} errorCB +* +* @return Object.dst {Boolean}: The value "true" indicates that daylight savings time is +* in effect for the given date and "false" indicate that it is not. +* +* @error GlobalizationError.UNKNOWN_ERROR +* +* Example +* globalization.isDayLightSavingsTime(new Date(), +* function (date) {alert('dst:' + date.dst + '\n');} +* function () {}); +*/ +isDayLightSavingsTime:function(date, successCB, failureCB) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.isDayLightSavingsTime Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.isDayLightSavingsTime Error: failureCB is not a function"); + return; + } + + + if (date instanceof Date){ + var dateValue; + dateValue = date.valueOf(); + exec(successCB, failureCB, "Globalization", "isDayLightSavingsTime", [{"date": dateValue}]); + } + else { + console.log("Globalization.isDayLightSavingsTime Error: date is not a Date object"); + } + +}, + +/** +* 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. +* It returns the day to the successCB callback with a properties object as a parameter. +* If there is an error obtaining the pattern, then the errorCB callback is invoked. +* +* @param {Function} successCB +* @param {Function} errorCB +* +* @return Object.value {Number}: The number of the first day of the week. +* +* @error GlobalizationError.UNKNOWN_ERROR +* +* Example +* globalization.getFirstDayOfWeek(function (day) +* { alert('Day:' + day.value + '\n');}, +* function () {}); +*/ +getFirstDayOfWeek:function(successCB, failureCB) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.getFirstDayOfWeek Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.getFirstDayOfWeek Error: failureCB is not a function"); + return; + } + + exec(successCB, failureCB, "Globalization", "getFirstDayOfWeek", []); +}, + + +/** +* Returns a number formatted as a string according to the client's user preferences. +* It returns the formatted number string to the successCB callback with a properties object as a +* parameter. If there is an error formatting the number, then the errorCB callback is invoked. +* +* The defaults are: type="decimal" +* +* @param {Number} number +* @param {Function} successCB +* @param {Function} errorCB +* @param {Object} options {optional} +* type {String}: 'decimal', "percent", or 'currency' +* +* @return Object.value {String}: The formatted number string. +* +* @error GlobalizationError.FORMATTING_ERROR +* +* Example +* globalization.numberToString(3.25, +* function (number) {alert('number:' + number.value + '\n');}, +* function () {}, +* {type:'decimal'}); +*/ +numberToString:function(number, successCB, failureCB, options) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.numberToString Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.numberToString Error: failureCB is not a function"); + return; + } + + if(typeof number == "number") { + exec(successCB, failureCB, "Globalization", "numberToString", [{"number": number, "options": options}]); + } + else { + console.log("Globalization.numberToString Error: number is not a number"); + } +}, + +/** +* Parses a number formatted as a string according to the client's user preferences and +* returns the corresponding number. It returns the number to the successCB callback with a +* properties object as a parameter. If there is an error parsing the number string, then +* the errorCB callback is invoked. +* +* The defaults are: type="decimal" +* +* @param {String} numberString +* @param {Function} successCB +* @param {Function} errorCB +* @param {Object} options {optional} +* type {String}: 'decimal', "percent", or 'currency' +* +* @return Object.value {Number}: The parsed number. +* +* @error GlobalizationError.PARSING_ERROR +* +* Example +* globalization.stringToNumber('1234.56', +* function (number) {alert('Number:' + number.value + '\n');}, +* function () { alert('Error parsing number');}); +*/ +stringToNumber:function(numberString, successCB, failureCB, options) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.stringToNumber Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.stringToNumber Error: failureCB is not a function"); + return; + } + + if(typeof numberString == "string") { + exec(successCB, failureCB, "Globalization", "stringToNumber", [{"numberString": numberString, "options": options}]); + } + else { + console.log("Globalization.stringToNumber Error: numberString is not a string"); + } +}, + +/** +* Returns a pattern string for formatting and parsing numbers according to the client's user +* preferences. It returns the pattern to the successCB callback with a properties object as a +* parameter. If there is an error obtaining the pattern, then the errorCB callback is invoked. +* +* The defaults are: type="decimal" +* +* @param {Function} successCB +* @param {Function} errorCB +* @param {Object} options {optional} +* type {String}: 'decimal', "percent", or 'currency' +* +* @return 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. +* +* @error GlobalizationError.PATTERN_ERROR +* +* Example +* globalization.getNumberPattern( +* function (pattern) {alert('Pattern:' + pattern.pattern + '\n');}, +* function () {}); +*/ +getNumberPattern:function(successCB, failureCB, options) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.getNumberPattern Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.getNumberPattern Error: failureCB is not a function"); + return; + } + + exec(successCB, failureCB, "Globalization", "getNumberPattern", [{"options": options}]); +}, + +/** +* Returns a pattern string for formatting and parsing currency values according to the client's +* user preferences and ISO 4217 currency code. It returns the pattern to the successCB callback with a +* properties object as a parameter. If there is an error obtaining the pattern, then the errorCB +* callback is invoked. +* +* @param {String} currencyCode +* @param {Function} successCB +* @param {Function} errorCB +* +* @return 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. +* +* @error GlobalizationError.FORMATTING_ERROR +* +* Example +* globalization.getCurrencyPattern('EUR', +* function (currency) {alert('Pattern:' + currency.pattern + '\n');} +* function () {}); +*/ +getCurrencyPattern:function(currencyCode, successCB, failureCB) { + // successCallback required + if (typeof successCB != "function") { + console.log("Globalization.getCurrencyPattern Error: successCB is not a function"); + return; + } + + // errorCallback required + if (typeof failureCB != "function") { + console.log("Globalization.getCurrencyPattern Error: failureCB is not a function"); + return; + } + + if(typeof currencyCode == "string") { + exec(successCB, failureCB, "Globalization", "getCurrencyPattern", [{"currencyCode": currencyCode}]); + } + else { + console.log("Globalization.getCurrencyPattern Error: currencyCode is not a currency code"); + } +} + +}; + +module.exports = globalization; + +}); + // file: lib/common/plugin/logger.js define("cordova/plugin/logger", function(require, exports, module) { http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/blob/63124574/framework/res/xml/config.xml ---------------------------------------------------------------------- diff --git a/framework/res/xml/config.xml b/framework/res/xml/config.xml index 4a6fffc..1117f8d 100644 --- a/framework/res/xml/config.xml +++ b/framework/res/xml/config.xml @@ -51,6 +51,7 @@ + http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/blob/63124574/framework/src/org/apache/cordova/Globalization.java ---------------------------------------------------------------------- diff --git a/framework/src/org/apache/cordova/Globalization.java b/framework/src/org/apache/cordova/Globalization.java new file mode 100644 index 0000000..1c2a13c --- /dev/null +++ b/framework/src/org/apache/cordova/Globalization.java @@ -0,0 +1,560 @@ +package org.apache.cordova; + +import java.text.DateFormat; +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collections; +import java.util.Comparator; +import java.util.Currency; +import java.util.Date; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.TimeZone; + +import org.apache.cordova.api.Plugin; +import org.apache.cordova.api.PluginResult; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import android.text.format.Time; + +/** + * + */ +public class Globalization extends Plugin { + //GlobalizationCommand Plugin Actions + public static final String GETLOCALENAME = "getLocaleName"; + public static final String DATETOSTRING = "dateToString"; + public static final String STRINGTODATE = "stringToDate"; + public static final String GETDATEPATTERN = "getDatePattern"; + public static final String GETDATENAMES = "getDateNames"; + public static final String ISDAYLIGHTSAVINGSTIME = "isDayLightSavingsTime"; + public static final String GETFIRSTDAYOFWEEK = "getFirstDayOfWeek"; + public static final String NUMBERTOSTRING = "numberToString"; + public static final String STRINGTONUMBER = "stringToNumber"; + public static final String GETNUMBERPATTERN = "getNumberPattern"; + public static final String GETCURRENCYPATTERN = "getCurrencyPattern"; + public static final String GETPREFERREDLANGUAGE = "getPreferredLanguage"; + + //GlobalizationCommand Option Parameters + public static final String OPTIONS = "options"; + public static final String FORMATLENGTH = "formatLength"; + //public static final String SHORT = "short"; //default for dateToString format + public static final String MEDIUM = "medium"; + public static final String LONG = "long"; + public static final String FULL = "full"; + public static final String SELECTOR = "selector"; + //public static final String DATEANDTIME = "date and time"; //default for dateToString + public static final String DATE = "date"; + public static final String TIME = "time"; + public static final String DATESTRING = "dateString"; + public static final String TYPE = "type"; + public static final String ITEM = "item"; + public static final String NARROW = "narrow"; + public static final String WIDE = "wide"; + public static final String MONTHS = "months"; + public static final String DAYS = "days"; + //public static final String DECMIAL = "wide"; //default for numberToString + public static final String NUMBER = "number"; + public static final String NUMBERSTRING = "numberString"; + public static final String PERCENT = "percent"; + public static final String CURRENCY = "currency"; + public static final String CURRENCYCODE = "currencyCode"; + + @Override + public PluginResult execute(String action, JSONArray data, String callbackId) { + PluginResult.Status status = PluginResult.Status.OK; + JSONObject obj = new JSONObject(); + + try{ + if (action.equals(GETLOCALENAME)){ + obj = getLocaleName(); + return new PluginResult(status, obj); + }else if (action.equals(GETPREFERREDLANGUAGE)){ + obj = getPreferredLanguage(); + return new PluginResult(status, obj); + } else if (action.equalsIgnoreCase(DATETOSTRING)) { + obj = getDateToString(data); + return new PluginResult(PluginResult.Status.OK, obj); + }else if(action.equalsIgnoreCase(STRINGTODATE)){ + obj = getStringtoDate(data); + return new PluginResult(PluginResult.Status.OK, obj); + }else if(action.equalsIgnoreCase(GETDATEPATTERN)){ + obj = getDatePattern(data); + return new PluginResult(PluginResult.Status.OK, obj); + }else if(action.equalsIgnoreCase(GETDATENAMES)){ + obj = getDateNames(data); + return new PluginResult(PluginResult.Status.OK, obj); + }else if(action.equalsIgnoreCase(ISDAYLIGHTSAVINGSTIME)){ + obj = getIsDayLightSavingsTime(data); + return new PluginResult(PluginResult.Status.OK, obj); + }else if(action.equalsIgnoreCase(GETFIRSTDAYOFWEEK)){ + obj = getFirstDayOfWeek(data); + return new PluginResult(PluginResult.Status.OK, obj); + }else if(action.equalsIgnoreCase(NUMBERTOSTRING)){ + obj = getNumberToString(data); + return new PluginResult(PluginResult.Status.OK, obj); + }else if(action.equalsIgnoreCase(STRINGTONUMBER)){ + obj = getStringToNumber(data); + return new PluginResult(PluginResult.Status.OK, obj); + }else if(action.equalsIgnoreCase(GETNUMBERPATTERN)){ + obj = getNumberPattern(data); + return new PluginResult(PluginResult.Status.OK, obj); + }else if(action.equalsIgnoreCase(GETCURRENCYPATTERN)){ + obj = getCurrencyPattern(data); + return new PluginResult(PluginResult.Status.OK, obj); + } + }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.INVALID_ACTION); + } + /* + * @Description: 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{ + obj.put("value",Locale.getDefault().toString());//get the locale from the Android Device + return obj; + }catch(Exception e){ + throw new GlobalizationError(GlobalizationError.UNKNOWN_ERROR); + } + } + /* + * @Description: Returns the string identifier for the client's current language + * + * @Return: JSONObject + * Object.value {String}: The language identifier + * + * @throws: GlobalizationError.UNKNOWN_ERROR + */ + private JSONObject getPreferredLanguage() throws GlobalizationError { + JSONObject obj = new JSONObject(); + try { + obj.put("value", Locale.getDefault().getDisplayLanguage().toString()); + return obj; + } catch (Exception e) { + throw new GlobalizationError(GlobalizationError.UNKNOWN_ERROR); + } + } + /* + * @Description: 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)options.getJSONObject(0).get(DATE)); + + //get formatting pattern from android device (Will only have device specific formatting for short form of date) or options supplied + JSONObject datePattern = getDatePattern(options); + SimpleDateFormat fmt = new SimpleDateFormat(datePattern.getString("pattern")); + + //return formatted date + return obj.put("value",fmt.format(date)); + }catch(Exception ge){ + throw new GlobalizationError(GlobalizationError.FORMATTING_ERROR); + } + } + + /* + * @Description: 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(); + Date date; + try{ + //get format pattern from android device (Will only have device specific formatting for short form of date) or options supplied + DateFormat fmt = new SimpleDateFormat(getDatePattern(options).getString("pattern")); + + //attempt parsing string based on user preferences + date = fmt.parse(options.getJSONObject(0).get(DATESTRING).toString()); + + //set Android Time object + Time time = new Time(); + time.set(date.getTime()); + + //return properties; + obj.put("year", time.year); + obj.put("month", time.month); + obj.put("day", time.monthDay); + obj.put("hour", time.hour); + obj.put("minute", time.minute); + obj.put("second", time.second); + obj.put("millisecond", new Long(0)); + return obj; + }catch(Exception ge){ + throw new GlobalizationError(GlobalizationError.PARSING_ERROR); + } + } + + /* + * @Description: 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 zone 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{ + SimpleDateFormat fmtDate = (SimpleDateFormat)android.text.format.DateFormat.getDateFormat(this.cordova.getActivity()); //default user preference for date + SimpleDateFormat fmtTime = (SimpleDateFormat)android.text.format.DateFormat.getTimeFormat(this.cordova.getActivity()); //default user preference for time + + String fmt = fmtDate.toLocalizedPattern() + " " + fmtTime.toLocalizedPattern(); //default SHORT date/time format. ex. dd/MM/yyyy h:mm a + + //get Date value + options (if available) + if (options.getJSONObject(0).length() > 1){ + //options were included + + //get formatLength option + if (!((JSONObject)options.getJSONObject(0).get(OPTIONS)).isNull(FORMATLENGTH)){ + String fmtOpt = (String)((JSONObject)options.getJSONObject(0).get(OPTIONS)).get(FORMATLENGTH); + if (fmtOpt.equalsIgnoreCase(MEDIUM)){//medium + fmtDate = (SimpleDateFormat)android.text.format.DateFormat.getMediumDateFormat(this.cordova.getActivity()); + }else if (fmtOpt.equalsIgnoreCase(LONG) || fmtOpt.equalsIgnoreCase(FULL)){ //long/full + fmtDate = (SimpleDateFormat)android.text.format.DateFormat.getLongDateFormat(this.cordova.getActivity()); + } + } + + //return pattern type + fmt = fmtDate.toLocalizedPattern() + " " + fmtTime.toLocalizedPattern(); + if (!((JSONObject)options.getJSONObject(0).get(OPTIONS)).isNull(SELECTOR)){ + String selOpt = (String)((JSONObject)options.getJSONObject(0).get(OPTIONS)).get(SELECTOR); + if (selOpt.equalsIgnoreCase(DATE)){ + fmt = fmtDate.toLocalizedPattern(); + }else if (selOpt.equalsIgnoreCase(TIME)){ + fmt = fmtTime.toLocalizedPattern(); + } + } + } + + //TimeZone from users device + //TimeZone tz = Calendar.getInstance(Locale.getDefault()).getTimeZone(); //substitute method + TimeZone tz = TimeZone.getTimeZone(Time.getCurrentTimezone()); + + obj.put("pattern", fmt); + obj.put("timezone", tz.getDisplayName(tz.inDaylightTime(Calendar.getInstance().getTime()),TimeZone.SHORT)); + obj.put("utc_offset", tz.getRawOffset()/1000); + obj.put("dst_offset", tz.getDSTSavings()/1000); + return obj; + + }catch(Exception ge){ + throw new GlobalizationError(GlobalizationError.PATTERN_ERROR); + } + } + + /* + * @Description: 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(); + //String[] value; + JSONArray value = new JSONArray(); + List namesList = new ArrayList(); + final Map namesMap; // final needed for sorting with anonymous comparator + 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(OPTIONS)).isNull(TYPE)){ + String t = (String)((JSONObject)options.getJSONObject(0).get(OPTIONS)).get(TYPE); + if (t.equalsIgnoreCase(NARROW)){type++;} //DateUtils.LENGTH_MEDIUM + } + //get item if available + if (!((JSONObject)options.getJSONObject(0).get(OPTIONS)).isNull(ITEM)){ + String t = (String)((JSONObject)options.getJSONObject(0).get(OPTIONS)).get(ITEM); + if (t.equalsIgnoreCase(DAYS)){item += 10;} //Days of week start at 1 + } + } + //determine return value + int method = item + type; + if (method == 1) { //months and narrow + namesMap = Calendar.getInstance().getDisplayNames(Calendar.MONTH, Calendar.SHORT, Locale.getDefault()); + } else if (method == 10) { //days and wide + namesMap = Calendar.getInstance().getDisplayNames(Calendar.DAY_OF_WEEK, Calendar.LONG, Locale.getDefault()); + } else if (method == 11) { //days and narrow + namesMap = Calendar.getInstance().getDisplayNames(Calendar.DAY_OF_WEEK, Calendar.SHORT, Locale.getDefault()); + } else { //default: months and wide + namesMap = Calendar.getInstance().getDisplayNames(Calendar.MONTH, Calendar.LONG, Locale.getDefault()); + } + + // save names as a list + for(String name : namesMap.keySet()) { + namesList.add(name); + } + + // sort the list according to values in namesMap + Collections.sort(namesList, new Comparator() { + public int compare(String arg0, String arg1) { + return namesMap.get(arg0).compareTo(namesMap.get(arg1)); + } + }); + + // convert nameList into JSONArray of String objects + for (int i = 0; i < namesList.size(); i ++){ + value.put(namesList.get(i)); + } + + //return array of names + return obj.put("value", value); + }catch(Exception ge){ + throw new GlobalizationError(GlobalizationError.UNKNOWN_ERROR); + } + } + + /* + * @Description: 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" indicate that it is not. * + * + * @throws: GlobalizationError.UNKNOWN_ERROR + */ + private JSONObject getIsDayLightSavingsTime(JSONArray options) throws GlobalizationError{ + JSONObject obj = new JSONObject(); + boolean dst = false; + try{ + Date date = new Date((Long)options.getJSONObject(0).get(DATE)); + //TimeZone tz = Calendar.getInstance(Locale.getDefault()).getTimeZone(); + TimeZone tz = TimeZone.getTimeZone(Time.getCurrentTimezone()); + dst = tz.inDaylightTime(date); //get daylight savings data from date object and user timezone settings + + return obj.put("dst",dst); + }catch(Exception ge){ + throw new GlobalizationError(GlobalizationError.UNKNOWN_ERROR); + } + } + + /* + * @Description: 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{ + int value = Calendar.getInstance(Locale.getDefault()).getFirstDayOfWeek(); //get first day of week based on user locale settings + return obj.put("value", value); + }catch(Exception ge){ + throw new GlobalizationError(GlobalizationError.UNKNOWN_ERROR); + } + } + + /* + * @Description: 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{ + DecimalFormat fmt = getNumberFormatInstance(options);//returns Decimal/Currency/Percent instance + value = fmt.format(options.getJSONObject(0).get(NUMBER)); + return obj.put("value", value); + }catch(Exception ge){ + throw new GlobalizationError(GlobalizationError.FORMATTING_ERROR); + } + } + + /* + * @Description: 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(); + Number value; + try{ + DecimalFormat fmt = getNumberFormatInstance(options); //returns Decimal/Currency/Percent instance + value = fmt.parse((String)options.getJSONObject(0).get(NUMBERSTRING)); + return obj.put("value", value); + }catch(Exception ge){ + throw new GlobalizationError(GlobalizationError.PARSING_ERROR); + } + } + + /* + * @Description: 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{ + //uses java.text.DecimalFormat to format value + DecimalFormat fmt = (DecimalFormat) DecimalFormat.getInstance(Locale.getDefault()); //default format + String symbol = String.valueOf(fmt.getDecimalFormatSymbols().getDecimalSeparator()); + //get Date value + options (if available) + if (options.getJSONObject(0).length() > 0){ + //options were included + if (!((JSONObject)options.getJSONObject(0).get(OPTIONS)).isNull(TYPE)){ + String fmtOpt = (String)((JSONObject)options.getJSONObject(0).get(OPTIONS)).get(TYPE); + if (fmtOpt.equalsIgnoreCase(CURRENCY)){ + fmt = (DecimalFormat) DecimalFormat.getCurrencyInstance(Locale.getDefault()); + symbol = fmt.getDecimalFormatSymbols().getCurrencySymbol(); + }else if(fmtOpt.equalsIgnoreCase(PERCENT)){ + fmt = (DecimalFormat) DecimalFormat.getPercentInstance(Locale.getDefault()); + symbol = String.valueOf(fmt.getDecimalFormatSymbols().getPercent()); + } + } + } + + //return properties + obj.put("pattern", fmt.toPattern()); + obj.put("symbol", symbol); + obj.put("fraction", fmt.getMinimumFractionDigits()); + obj.put("rounding", new Integer(0)); + obj.put("positive", fmt.getPositivePrefix()); + obj.put("negative", fmt.getNegativePrefix()); + obj.put("decimal", String.valueOf(fmt.getDecimalFormatSymbols().getDecimalSeparator())); + obj.put("grouping", String.valueOf(fmt.getDecimalFormatSymbols().getGroupingSeparator())); + + return obj; + }catch(Exception ge){ + throw new GlobalizationError(GlobalizationError.PATTERN_ERROR); + } + } + + /* + * @Description: 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{ + //get ISO 4217 currency code + String code = options.getJSONObject(0).getString(CURRENCYCODE); + + //uses java.text.DecimalFormat to format value + DecimalFormat fmt = (DecimalFormat) DecimalFormat.getCurrencyInstance(Locale.getDefault()); + + //set currency format + Currency currency = Currency.getInstance(code); + fmt.setCurrency(currency); + + //return properties + obj.put("pattern", fmt.toPattern()); + obj.put("code", currency.getCurrencyCode()); + obj.put("fraction", fmt.getMinimumFractionDigits()); + obj.put("rounding", new Integer(0)); + obj.put("decimal", String.valueOf(fmt.getDecimalFormatSymbols().getDecimalSeparator())); + obj.put("grouping", String.valueOf(fmt.getDecimalFormatSymbols().getGroupingSeparator())); + + return obj; + }catch(Exception ge){ + throw new GlobalizationError(GlobalizationError.FORMATTING_ERROR); + } + } + + /* + * @Description: Parses a JSONArray from user options and returns the correct Instance of Decimal/Percent/Currency. + * @Return: DecimalFormat : The Instance to use. + * + * @throws: JSONException + */ + private DecimalFormat getNumberFormatInstance(JSONArray options) throws JSONException{ + DecimalFormat fmt = (DecimalFormat)DecimalFormat.getInstance(Locale.getDefault()); //default format + try{ + if (options.getJSONObject(0).length() > 1){ + //options were included + if (!((JSONObject)options.getJSONObject(0).get(OPTIONS)).isNull(TYPE)){ + String fmtOpt = (String)((JSONObject)options.getJSONObject(0).get(OPTIONS)).get(TYPE); + if (fmtOpt.equalsIgnoreCase(CURRENCY)){ + fmt = (DecimalFormat)DecimalFormat.getCurrencyInstance(Locale.getDefault()); + }else if(fmtOpt.equalsIgnoreCase(PERCENT)){ + fmt = (DecimalFormat)DecimalFormat.getPercentInstance(Locale.getDefault()); + } + } + } + + }catch (JSONException je){} + return fmt; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-cordova-android/blob/63124574/framework/src/org/apache/cordova/GlobalizationError.java ---------------------------------------------------------------------- diff --git a/framework/src/org/apache/cordova/GlobalizationError.java b/framework/src/org/apache/cordova/GlobalizationError.java new file mode 100644 index 0000000..c831845 --- /dev/null +++ b/framework/src/org/apache/cordova/GlobalizationError.java @@ -0,0 +1,72 @@ +package org.apache.cordova; + +/** + * @description Exception class representing defined Globalization error codes + * @Globalization error codes: + * GlobalizationError.UNKNOWN_ERROR = 0; + * GlobalizationError.FORMATTING_ERROR = 1; + * GlobalizationError.PARSING_ERROR = 2; + * GlobalizationError.PATTERN_ERROR = 3; + */ +public class GlobalizationError extends Exception{ + /** + * + */ + private static final long serialVersionUID = 1L; + public static final String UNKNOWN_ERROR = "UNKNOWN_ERROR"; + public static final String FORMATTING_ERROR = "FORMATTING_ERROR"; + public static final String PARSING_ERROR = "PARSING_ERROR"; + public static final String PATTERN_ERROR = "PATTERN_ERROR"; + + int error = 0; //default unknown error thrown + /** + * Default constructor + */ + public GlobalizationError() {} + /** + * Create an exception returning an error code + * + * @param s + */ + public GlobalizationError(String s) { + if (s.equalsIgnoreCase(FORMATTING_ERROR)){ + error = 1; + }else if (s.equalsIgnoreCase(PARSING_ERROR)){ + error = 2; + }else if (s.equalsIgnoreCase(PATTERN_ERROR)){ + error = 3; + } + } + /** + * get error string based on error code + * + * @param String msg + */ + public String getErrorString(){ + String msg = ""; + switch (error){ + case 0: + msg = UNKNOWN_ERROR; + break; + case 1: + msg = FORMATTING_ERROR; + break; + case 2: + msg = PARSING_ERROR; + break; + case 3: + msg = PATTERN_ERROR; + break; + } + return msg; + } + /** + * get error code + * + * @param String msg + */ + public int getErrorCode(){ + return error; + } + +} \ No newline at end of file