- /*
- * @(#)LocaleData.java 1.26 00/01/19
- *
- * Copyright 1996-2000 Sun Microsystems, Inc. All Rights Reserved.
- *
- * This software is the proprietary information of Sun Microsystems, Inc.
- * Use is subject to license terms.
- *
- */
-
- /*
- * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
- * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
- *
- * The original version of this source code and documentation
- * is copyrighted and owned by Taligent, Inc., a wholly-owned
- * subsidiary of IBM. These materials are provided under terms
- * of a License Agreement between Taligent and Sun. This technology
- * is protected by multiple US and International patents.
- *
- * This notice and attribution to Taligent may not be removed.
- * Taligent is a registered trademark of Taligent, Inc.
- *
- */
-
- package java.text.resources;
-
- import java.util.Locale;
- import java.util.ResourceBundle;
- import java.util.Hashtable;
- import java.util.Enumeration;
- import java.util.Vector;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.io.FileNotFoundException;
- import java.util.zip.ZipInputStream;
- import java.util.zip.ZipEntry;
-
- /**
- * This class used to be the base class for all of the LocaleElements classes. This has
- * been changed so that all of the LocaleElements classes descend from ListResourceBundle.
- * This class now exists only to allow a way to get the list of available resources. Even
- * this will be changing in the future.
- *
- * @author Asmus Freytag
- * @author Mark Davis
- * @version 1.26 01/19/00
- */
-
- public class LocaleData {
- /**
- * Returns a list of the installed locales.
- * @param key A resource tag. Currently, this parameter is ignored. The obvious
- * intent, however, is for getAvailableLocales() to return a list of only those
- * locales that contain a resource with the specified resource tag.
- *
- * <p>Before we implement this function this way, however, some thought should be
- * given to whether this is really the right thing to do. Because of the lookup
- * algorithm, a NumberFormat, for example, is "installed" for all locales. But if
- * we're trying to put up a list of NumberFormats to choose from, we may want to see
- * only a list of those locales that uniquely define a NumberFormat rather than
- * inheriting one from another locale. Thus, if fr and fr_CA uniquely define
- * NumberFormat data, but fr_BE doesn't, the user wouldn't see "French (Belgium)" in
- * the list and would go for "French (default)" instead. Of course, this means
- * "English (United States)" would not be in the list, since it is the default locale.
- * This might be okay, but might be confusing to some users.
- *
- * <p>In addition, the other functions that call getAvailableLocales() don't currently
- * all pass the right thing for "key," meaning that all of these functions should be
- * looked at before anything is done to this function.
- *
- * <p>We recommend that someone take some careful consideration of these issues before
- * modifying this function to pay attention to the "key" parameter. --rtg 1/26/98
- */
- public static Locale[] getAvailableLocales(String key)
- {
- Locale[] temp = new Locale[localeList.length];
- System.arraycopy(localeList, 0, temp, 0, localeList.length);
- return temp;
- }
-
- // ========== privates ==========
-
- private static Vector classPathSegments = new Vector();
- private static Locale[] localeList;
- private static final String PACKAGE = "java.text.resources";
- private static final String PREFIX = "LocaleElements_";
- private static final char ZIPSEPARATOR = '/';
-
- static {
- String classPath =
- (String) java.security.AccessController.doPrivileged(
- new sun.security.action.GetPropertyAction("sun.boot.class.path"));
- String s =
- (String) java.security.AccessController.doPrivileged(
- new sun.security.action.GetPropertyAction("java.class.path"));
-
- // Search combined system and application class path
- if (s != null && s.length() != 0) {
- classPath += File.pathSeparator + s;
- }
- while (classPath != null && classPath.length() != 0) {
- int i = classPath.lastIndexOf(java.io.File.pathSeparatorChar);
- String dir = classPath.substring(i + 1);
- if (i == -1) {
- classPath = null;
- } else {
- classPath = classPath.substring(0, i);
- }
- classPathSegments.insertElementAt(dir, 0);
- }
-
- String[] classList = (String[])
- java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction() {
- public Object run() {
- return getClassList(PACKAGE, PREFIX);
- }
- });
-
- int plen = PREFIX.length();
- localeList = new Locale[classList.length];
- for (int i = 0; i < classList.length; i++) {
- int p2 = 0;
- int p1 = classList[i].indexOf('_', plen);
- String lang = "";
- String region = "";
- String var = "";
-
- if (p1 == -1) {
- lang = classList[i].substring(plen);
- } else {
- lang = classList[i].substring(plen, p1);
- p2 = classList[i].indexOf('_', p1 + 1);
- if (p2 == -1) {
- region = classList[i].substring(p1 + 1);
- } else {
- region = classList[i].substring(p1 + 1, p2);
- if (p2 < classList[i].length())
- var = classList[i].substring(p2 + 1);
- }
- }
- localeList[i] = new Locale(lang, region, var);
- }
- }
-
- /**
- * Walk through CLASSPATH and find class list from a package.
- * The class names start with prefix string
- * @param package name, class name prefix
- * @return class list in an array of String
- */
- private static String[] getClassList(String pkgName, String prefix) {
- Vector listBuffer = new Vector();
- String packagePath = pkgName.replace('.', File.separatorChar)
- + File.separatorChar;
- String zipPackagePath = pkgName.replace('.', ZIPSEPARATOR)
- + ZIPSEPARATOR;
- for (int i = 0; i < classPathSegments.size(); i++){
- String onePath = (String) classPathSegments.elementAt(i);
- File f = new File(onePath);
- if (!f.exists())
- continue;
- if (f.isFile())
- scanFile(f, zipPackagePath, listBuffer, prefix);
- else if (f.isDirectory()) {
- String fullPath;
- if (onePath.endsWith(File.separator))
- fullPath = onePath + packagePath;
- else
- fullPath = onePath + File.separatorChar + packagePath;
- File dir = new File(fullPath);
- if (dir.exists() && dir.isDirectory())
- scanDir(dir, listBuffer, prefix);
- }
- }
- String[] classNames = new String[listBuffer.size()];
- listBuffer.copyInto(classNames);
- return classNames;
- }
-
- private static void addClass (String className, Vector listBuffer, String prefix) {
- if (className != null && className.startsWith(prefix)
- && !listBuffer.contains(className))
- listBuffer.addElement(className);
- }
-
- private static String midString(String str, String pre, String suf) {
- String midStr;
- if (str.startsWith(pre) && str.endsWith(suf))
- midStr = str.substring(pre.length(), str.length() - suf.length());
- else
- midStr = null;
- return midStr;
- }
-
- private static void scanDir(File dir, Vector listBuffer, String prefix) {
- String[] fileList = dir.list();
- for (int i = 0; i < fileList.length; i++) {
- addClass(midString(fileList[i], "", ".class"), listBuffer, prefix);
- }
- }
-
- private static void scanFile(File f, String packagePath, Vector listBuffer,
- String prefix) {
- try {
- ZipInputStream zipFile = new ZipInputStream(new FileInputStream(f));
- boolean gotThere = false;
- ZipEntry entry;
- while ((entry = zipFile.getNextEntry()) != null) {
- String eName = entry.getName();
- if (eName.startsWith(packagePath)) {
- gotThere = true;
- if (eName.endsWith(".class")) {
- addClass(midString(eName, packagePath, ".class"),
- listBuffer, prefix);
- }
- } else {
- if (gotThere) // Found the package, now we are leaving
- break;
- }
- }
- } catch (FileNotFoundException e) {
- System.out.println("file not found:" + e);
- } catch (IOException e) {
- System.out.println("file IO Exception:" + e);
- } catch (Exception e) {
- System.out.println("Exception:" + e);
- }
- }
- }