/*
*
*
* 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;
/**
* This class provides general helper methods related with locale manipulation.
*/
public class LocaleHelpers {
/**
* Checks whether given locale is valid or not according to
* JSR 238 specification, i.e. is in form of
* <language>-<country>-<variant>.
* Restrictions apply to length and
* validity of characters of language part, country part and separators.
* No checking of variant is performed.
*
* @param locale locale code
* @return <code>true</code> if locale is valid,
* <code>false</code> otherwise
*/
public static boolean isValidLocale(String locale) {
if (locale == null) {
// Null locale is acceptable according to MIDP 2.0.
return true;
}
int len = locale.length();
if (len == 0) {
return true;
}
if (len < 2) {
// Language part, if present, must be 2 characters long.
return false;
}
char ch = locale.charAt(0);
if (ch < 'a' || ch > 'z') {
return false;
}
ch = locale.charAt(1);
if (ch < 'a' || ch > 'z') {
return false;
}
if (len > 2) {
if (len < 5 || len == 6) {
// Country part, if present, must be 2 characters long.
return false;
}
ch = locale.charAt(2);
if (ch != '-' && ch != '_') {
return false;
}
ch = locale.charAt(3);
if (ch < 'A' || ch > 'Z') {
return false;
}
ch = locale.charAt(4);
if (ch < 'A' || ch > 'Z') {
return false;
}
if (len > 6) {
ch = locale.charAt(5);
if (ch != '-' && ch != '_') {
return false;
}
}
}
return true;
}
/**
* Replaces characters (expected dashes or underscores) on appropriate
* positions of locale code by dashes. The resulting locale name is likely
* to conform with MIDP 2.0 specification.
*
* @param locale locale code
* @return corrected locale code, or <code>null</code> in case of invalid
* format of given locale
*/
public static String normalizeLocale(String locale) {
if (locale == null) {
return null;
}
int len = locale.length();
if (len > 3) {
locale = locale.substring(0, 2) + '-' + locale.substring(3);
if (len > 6) {
locale = locale.substring(0, 5) + '-' + locale.substring(6);
}
}
return locale;
}
/**
* Returns parent for the given locale. Parent locale is obtained by removing
* the last component of locale code, which is in form:
* <language>-<country>-<variant>. Parent locale for
* <language> is empty string.
*
* @param locale the locale to obtain parent of.
* @return parent locale or <code>null</code> if locale doesn't have
* parent (if locale is already <code>null</code> or empty string.
*/
public static String getParentLocale(String locale) {
if (locale == null) {
return null;
}
int len = locale.length();
if (len == 0) {
return null;
}
if (len > 6) {
return locale.substring(0, 5);
}
if (len > 3) {
return locale.substring(0, 2);
}
return "";
}
/**
* Get an index of the given locale in array of locales returned from any
* of <code>getSupportedLocales</code> methods (e.g.
* {@link javax.microedition.global.ResourceManager#getSupportedLocales}).
*
* @param locale the locale to search for
* @param locales array of locales to search in
* @return locale index in the given array, or <code>-1</code> if the
* array doesn't contain the specified locale
*/
public static int indexInSupportedLocales(String locale,
String[] locales) {
if (locale == null || locales == null || locales.length == 0) {
return -1;
}
for (int i = 0; i < locales.length; i++) {
if (locale.equals(locales[i])) {
return i;
}
}
return -1;
}
private static String extractElement(String input) {
String trimmed = input.trim();
int length = trimmed.length();
if ((length >= 2) && (trimmed.charAt(0) == '"') &&
(trimmed.charAt(length - 1) == '"')) {
return trimmed.substring(1, length - 1);
}
return trimmed;
}
/**
* Splits the given string into parts according to the given separator. It
* stops parsing the string after the first <code>limit</code> parts are
* extracted. If <code>limit</code> equals <code>-1</code> all parts are
* extracted.
*
* @param input the input string
* @param separator the separator
* @param limit the maximum number of parts or <code>-1</code> if no maximum
* is given
* @return the extracted parts as an array of strings
*/
public static String[] splitString(String input, String separator,
int limit) {
int index = input.indexOf(separator);
int count = 1;
// get the count of elements
while (index >= 0) {
++count;
index = input.indexOf(separator, index + 1);
}
if ((limit != -1) && (count > limit)) {
count = limit;
}
// create array for elements
String[] elements = new String[count];
splitString(elements, input, separator, limit);
return elements;
}
/**
* Splits the given string into parts according to the given separator. It
* stops parsing the string after the first <code>limit</code> parts are
* extracted. If <code>limit</code> equals <code>-1</code> all parts are
* extracted.
*
* @param elements an array of strings where to put the results to
* @param input the input string
* @param separator the separator
* @param limit the maximum number of parts or <code>-1</code> if no maximum
* is given
* @return the number of extracted parts
*/
public static int splitString(String[] elements, String input,
String separator, int limit) {
int lastIndex = -1;
int index = input.indexOf(separator);
int count = 0;
if ((limit == -1) || (limit > elements.length)) {
limit = elements.length;
}
if (limit == 0) {
return 0;
}
while (index >= 0) {
elements[count++] = extractElement(input.substring(lastIndex + 1,
index));
if (count == limit) {
return count;
}
lastIndex = index;
index = input.indexOf(separator, lastIndex + 1);
}
elements[count++] = extractElement(input.substring(lastIndex + 1,
input.length()));
return count;
}
/**
* Creates an array of <code>short</code> values from a given
* <code>byte</code> array. Every two sequential one-byte values are
* packed into one <code>short</code> value. <p>
* Caution: initial array must have even length.
*
* @param source original array of bytes
* @return new array of shorts
*/
public static short[] byteArrayToShortArray(byte[] source) {
short[] output = new short[source.length >> 1];
for (int i = 0, j = 0; i < source.length; i += 2, ++j) {
output[j] = (short)(((source[i] & 0xff) << 8) |
source[i + 1] & 0xff);
}
return output;
}
/**
* Creates an array of <code>int</code> values from a given
* <code>byte</code> array. Every four sequential one-byte values are
* packed into one <code>int</code> value. <p>
* Caution: initial array's length must be a multiple of 4.
*
* @param source original array of bytes
* @return new array of ints
*/
public static int[] byteArrayToIntArray(byte[] source) {
int[] output = new int[source.length >> 2];
for (int i = 0, j = 0; i < source.length; i += 4, ++j) {
output[j] = ((source[i] & 0xff) << 24) |
((source[i + 1] & 0xff) << 16) |
((source[i + 2] & 0xff) << 8) |
source[i + 3] & 0xff;
}
return output;
}
}
|