2001-08-31 Tom Tromey <tromey@redhat.com>
+ * Makefile.in: Rebuilt.
+ * Makefile.am (ordinary_java_source_files): Removed
+ EnumerationChain, added DoubleEnumeration.
+ (nat_source_files): Added natResourceBundle.cc.
+ * java/util/natResourceBundle.cc: New file.
+ * gnu/java/util/DoubleEnumeration.java: New file.
+ * gnu/gcj/util/EnumerationChain.java: Removed.
+ * java/beans/VetoableChangeSupport.java: Merged with Classpath.
+ * java/util/ResourceBundle.java: Merged with Classpath.
+ * java/util/StringTokenizer.java: Merged with Classpath.
+ * java/util/Locale.java: Merged with Classpath.
+ * java/util/Random.java: Merged with Classpath.
+ * java/util/PropertyResourceBundle.java: Merged with Classpath.
+ * java/util/ListResourceBundle.java: Merged with Classpath.
+ * java/util/ConcurrentModificationException.java: Re-merged with
+ Classpath.
+ * java/util/EmptyStackException.java: Likewise.
+ * java/util/MissingResourceException.java: Likewise.
+ * java/util/NoSuchElementException.java: Likewise.
+ * java/util/TooManyListenersException.java: Likewise.
+
* java/io/ByteArrayOutputStream.java: Re-merged with Classpath.
* java/io/OptionalDataException.java: Merged with Classpath.
gnu/gcj/text/LocaleData_en_US.java \
gnu/gcj/text/SentenceBreakIterator.java \
gnu/gcj/text/WordBreakIterator.java \
-gnu/gcj/util/EnumerationChain.java \
gnu/java/io/ClassLoaderObjectInputStream.java \
gnu/java/io/NullOutputStream.java \
gnu/java/io/ObjectIdentityWrapper.java \
gnu/java/security/provider/Gnu.java \
gnu/java/security/provider/SHA.java \
gnu/java/security/provider/SHA1PRNG.java \
+gnu/java/util/DoubleEnumeration.java \
java/lang/ref/PhantomReference.java \
java/lang/ref/Reference.java \
java/lang/ref/ReferenceQueue.java \
java/net/natPlainDatagramSocketImpl.cc \
java/net/natPlainSocketImpl.cc \
java/text/natCollator.cc \
+java/util/natResourceBundle.cc \
java/util/zip/natDeflater.cc \
java/util/zip/natInflater.cc
gnu/gcj/text/LocaleData_en_US.java \
gnu/gcj/text/SentenceBreakIterator.java \
gnu/gcj/text/WordBreakIterator.java \
-gnu/gcj/util/EnumerationChain.java \
gnu/java/io/ClassLoaderObjectInputStream.java \
gnu/java/io/NullOutputStream.java \
gnu/java/io/ObjectIdentityWrapper.java \
gnu/java/security/provider/Gnu.java \
gnu/java/security/provider/SHA.java \
gnu/java/security/provider/SHA1PRNG.java \
+gnu/java/util/DoubleEnumeration.java \
java/lang/ref/PhantomReference.java \
java/lang/ref/Reference.java \
java/lang/ref/ReferenceQueue.java \
java/net/natPlainDatagramSocketImpl.cc \
java/net/natPlainSocketImpl.cc \
java/text/natCollator.cc \
+java/util/natResourceBundle.cc \
java/util/zip/natDeflater.cc \
java/util/zip/natInflater.cc
java/lang/reflect/natField.lo java/lang/reflect/natMethod.lo \
java/net/natInetAddress.lo java/net/natPlainDatagramSocketImpl.lo \
java/net/natPlainSocketImpl.lo java/text/natCollator.lo \
-java/util/zip/natDeflater.lo java/util/zip/natInflater.lo
+java/util/natResourceBundle.lo java/util/zip/natDeflater.lo \
+java/util/zip/natInflater.lo
libgcjx_la_OBJECTS = gnu/gcj/xlib/natClip.lo \
gnu/gcj/xlib/natColormap.lo gnu/gcj/xlib/natDisplay.lo \
gnu/gcj/xlib/natDrawable.lo gnu/gcj/xlib/natFont.lo \
.deps/gnu/gcj/text/LocaleData_en.P \
.deps/gnu/gcj/text/LocaleData_en_US.P \
.deps/gnu/gcj/text/SentenceBreakIterator.P \
-.deps/gnu/gcj/text/WordBreakIterator.P \
-.deps/gnu/gcj/util/EnumerationChain.P .deps/gnu/gcj/xlib/Clip.P \
+.deps/gnu/gcj/text/WordBreakIterator.P .deps/gnu/gcj/xlib/Clip.P \
.deps/gnu/gcj/xlib/Colormap.P .deps/gnu/gcj/xlib/Display.P \
.deps/gnu/gcj/xlib/Drawable.P .deps/gnu/gcj/xlib/Font.P \
.deps/gnu/gcj/xlib/GC.P .deps/gnu/gcj/xlib/Pixmap.P \
.deps/gnu/java/security/provider/DefaultPolicy.P \
.deps/gnu/java/security/provider/Gnu.P \
.deps/gnu/java/security/provider/SHA.P \
-.deps/gnu/java/security/provider/SHA1PRNG.P .deps/interpret.P \
+.deps/gnu/java/security/provider/SHA1PRNG.P \
+.deps/gnu/java/util/DoubleEnumeration.P .deps/interpret.P \
.deps/java/applet/Applet.P .deps/java/applet/AppletContext.P \
.deps/java/applet/AppletStub.P .deps/java/applet/AudioClip.P \
.deps/java/awt/AWTError.P .deps/java/awt/AWTEvent.P \
.deps/java/util/jar/JarEntry.P .deps/java/util/jar/JarException.P \
.deps/java/util/jar/JarFile.P .deps/java/util/jar/JarInputStream.P \
.deps/java/util/jar/JarOutputStream.P .deps/java/util/jar/Manifest.P \
-.deps/java/util/zip/Adler32.P .deps/java/util/zip/CRC32.P \
-.deps/java/util/zip/CheckedInputStream.P \
+.deps/java/util/natResourceBundle.P .deps/java/util/zip/Adler32.P \
+.deps/java/util/zip/CRC32.P .deps/java/util/zip/CheckedInputStream.P \
.deps/java/util/zip/CheckedOutputStream.P \
.deps/java/util/zip/Checksum.P \
.deps/java/util/zip/DataFormatException.P \
+++ /dev/null
-/* Copyright (C) 1999 Free Software Foundation
-
- This file is part of libgcj.
-
-This software is copyrighted work licensed under the terms of the
-Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
-details. */
-
-package gnu.gcj.util;
-
-import java.util.Enumeration;
-import java.util.NoSuchElementException;
-
-public class EnumerationChain implements Enumeration
-{
- private Enumeration first_;
- private Enumeration second_;
-
- public EnumerationChain (Enumeration first, Enumeration second)
- {
- if (first == null
- || second == null)
- throw new NullPointerException();
-
- first_ = first;
- second_ = second;
- }
-
- public synchronized boolean hasMoreElements()
- {
- if (first_ == null)
- return false;
- else
- return first_.hasMoreElements();
- }
-
- public synchronized Object nextElement() throws NoSuchElementException
- {
- while (first_ != null)
- {
- if (! first_.hasMoreElements())
- {
- first_ = second_;
- second_ = null;
- }
- else
- return first_.nextElement();
- }
-
- throw new NoSuchElementException();
- }
-}
--- /dev/null
+/* gnu.java.util.DoubleEnumeration
+ Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
+
+package gnu.java.util;
+
+import java.io.*;
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
+
+
+/**
+ * This is a helper class that combines two Enumerations.
+ * It returns the elements of the first Enumeration until it has
+ * no more elements and then returns the elements of the second
+ * Enumeration.<br>
+ *
+ * In the default case:
+ * <pre>
+ * doubleEnum = new DoubleEnumeration(enum1, enum2);
+ * while (doubleEnum.hasMoreElements()) {
+ * Object o = doubleEnum.nextElement();
+ * do_something(o);
+ * }
+ * </pre>
+ * it calls hasMoreElements of the Enumerations as few times as
+ * possible.
+ * The references to the Enumerations are cleared as soon as they have no
+ * more elements to help garbage collecting.
+ *
+ * @author Jochen Hoenicke
+ * @author Mark Wielaard (mark@klomp.org)
+ */
+public class DoubleEnumeration implements Enumeration
+{
+ /**
+ * This is true as long as one of the enumerations has more
+ * elements.
+ * Only valid when hasChecked is true.
+ * Set in <code>hasMoreElements()</code>
+ */
+ private boolean hasMore;
+ /**
+ * This is true, if it is sure that hasMore indicates wether there are
+ * more elements.
+ * Set to true in <code>hasMoreElements()</code>.
+ * Set to false in <code>getNextElement()</code>.
+ */
+ private boolean hasChecked;
+ /**
+ * The first enumeration.
+ */
+ private Enumeration e1;
+ /**
+ * The second enumeration.
+ */
+ private Enumeration e2;
+
+ /**
+ * Creates a new Enumeration combining the given two enumerations.
+ * The enumerations mustn't be accessed by other classes.
+ */
+ public DoubleEnumeration(Enumeration e1, Enumeration e2)
+ {
+ this.e1 = e1;
+ this.e2 = e2;
+ hasChecked = false;
+ }
+
+ /**
+ * Returns true, if at least one of the two enumerations has more
+ * elements.
+ */
+ public boolean hasMoreElements()
+ {
+ if (hasChecked)
+ return hasMore;
+
+ hasMore = (e1 != null && e1.hasMoreElements());
+
+ if (!hasMore) {
+ e1 = e2;
+ e2 = null;
+ hasMore = (e1 != null && e1.hasMoreElements());
+ }
+
+ hasChecked = true;
+ return hasMore;
+ }
+
+ /**
+ * Returns the next element. This returns the next element of the
+ * first enumeration, if it has more elements, otherwise the next
+ * element of the second enumeration. If both enumeration don't have
+ * any elements it throws a <code>NoSuchElementException</code>.
+ */
+ public Object nextElement()
+ {
+ if (!hasMoreElements())
+ throw new NoSuchElementException();
+ else {
+ hasChecked = false;
+ return e1.nextElement();
+ }
+ }
+}
-/*
- * java.beans.VetoableChangeSupport: part of the Java Class Libraries project.
- * Copyright (C) 1998, 2000 Free Software Foundation
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
+/* java.beans.VetoableChangeSupport
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
package java.beans;
import java.util.Hashtable;
-/* Copyright (C) 1998, 1999 Free Software Foundation
+/* ConcurrentModificationException.java -- Data structure concurrently modified
+ Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
- This file is part of libgcj.
-This software is copyrighted work licensed under the terms of the
-Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
-details. */
-
package java.util;
-
-/**
- * @author Warren Levy <warrenl@cygnus.com>
- * @date September 2, 1998.
- */
+
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
* "The Java Language Specification", ISBN 0-201-63451-1
* plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
* Status: Believed complete and correct.
*/
-
-/* Added in JDK 1.2 */
+
+/**
+ * Exception that is thrown by the collections classes when it is detected that
+ * a modification has been made to a data structure when this is not allowed,
+ * such as when a collection is structurally modified while an Iterator is
+ * operating over it. In cases where this can be detected, a
+ * ConcurrentModificationException will be thrown. An Iterator that detects this
+ * condition is referred to as fail-fast.
+ *
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 2, 1998.
+ * @since 1.2
+ */
public class ConcurrentModificationException extends RuntimeException
{
+ private static final long serialVersionUID = -3666751008965953603L;
+
+ /**
+ * Constructs a ConcurrentModificationException with no detail message.
+ */
public ConcurrentModificationException()
{
super();
}
- public ConcurrentModificationException(String msg)
+ /**
+ * Constructs a ConcurrentModificationException with a detail message.
+ *
+ * @param detail the detail message for the exception
+ */
+ public ConcurrentModificationException(String detail)
{
- super(msg);
+ super(detail);
}
}
-/* Copyright (C) 1998, 1999 Free Software Foundation
+/* EmptyStackException.java -- Attempt to pop from an empty stack
+ Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
- This file is part of libgcj.
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
-This software is copyrighted work licensed under the terms of the
-Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
-details. */
package java.util;
-
-/**
- * @author Warren Levy <warrenl@cygnus.com>
- * @date September 2, 1998.
- */
+
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
* "The Java Language Specification", ISBN 0-201-63451-1
* plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
* Status: Believed complete and correct.
*/
-
+
+/**
+ * This exception is thrown by the Stack class when an attempt is made to pop
+ * or otherwise access elements from an empty stack.
+ *
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 2, 1998.
+ */
public class EmptyStackException extends RuntimeException
{
+ private static final long serialVersionUID = 5084686378493302095L;
+
+ /**
+ * Constructs an EmptyStackException with no detail message.
+ */
public EmptyStackException()
{
super();
-/* Copyright (C) 1998, 1999 Free Software Foundation
+/* java.util.ListResourceBundle
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
- This file is part of libgcj.
+This file is part of GNU Classpath.
-This software is copyrighted work licensed under the terms of the
-Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
-details. */
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
-package java.util;
-
-/**
- * @author Anthony Green <green@cygnus.com>
- * @date November 26, 1998.
- */
-
-/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3,
- * and "The Java Language Specification", ISBN 0-201-63451-1. */
+GNU Classpath 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 for more details.
-public abstract class ListResourceBundle extends ResourceBundle
-{
- public final Object handleGetObject(String key)
- {
- Object a[][] = getContents();
-
- for (int i = 0; i < a.length; i++)
- {
- if (key.compareTo((String) a[i][0]) == 0)
- return a[i][1];
- }
- throw new MissingResourceException("can't find handle",
- getClass().getName(),
- key);
- }
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
- public Enumeration getKeys()
- {
- Object a[][] = getContents();
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
- Vector keys = new Vector(a.length);
- for (int i = 0; i < a.length; i++)
- keys.addElement(a[i][0]);
+package java.util;
- return keys.elements();
- }
+/**
+ * A <code>ListResouceBundle</code> provides an easy way, to create
+ * your own resource bundle. It is an abstract class that you can
+ * subclass. You should then overwrite the getContents method, that
+ * provides a key/value list.
+ * <br>
+ * The key/value list is a two dimensional list of Object. The first
+ * dimension ranges over the resources. The second dimension ranges
+ * from zero (key) to one (value). The keys must be of type String.
+ * <br>
+ * XXX Example!
+ *
+ * @see Locale
+ * @see PropertyResourceBundle
+ * @author Jochen Hoenicke */
+public abstract class ListResourceBundle extends ResourceBundle
+{
+ /**
+ * The constructor. It does nothing special.
+ */
+ public ListResourceBundle()
+ {
+ }
+ /**
+ * Gets the key/value list. You must override this method.
+ * @return a two dimensional list of Objects. The first dimension
+ * ranges over the objects, and the second dimension ranges from
+ * zero (key) to one (value).
+ */
protected abstract Object[][] getContents();
- public ListResourceBundle()
+ /**
+ * Override this method to provide the resource for a keys. This gets
+ * called by <code>getObject</code>.
+ * @param key The key of the resource.
+ * @return The resource for the key or null if it doesn't exists.
+ */
+ protected Object handleGetObject(String key)
+ {
+ Object[][] contents = getContents();
+ for (int i = 0; i < contents.length; i++)
+ {
+ if (key.equals(contents[i][0]))
+ return contents[i][1];
+ }
+ return null;
+ }
+
+ /**
+ * This method should return all keys for which a resource exists.
+ * @return An enumeration of the keys.
+ */
+ public Enumeration getKeys()
+ {
+ final Object[][] contents = getContents();
+
+ return new Enumeration()
{
- }
+ int i = 0;
+ public boolean hasMoreElements()
+ {
+ return i < contents.length;
+ }
+ public Object nextElement()
+ {
+ return contents[i++][0];
+ }
+ };
+ }
}
-/* Copyright (C) 1998, 1999, 2000 Free Software Foundation
-
- This file is part of libgcj.
-
-This software is copyrighted work licensed under the terms of the
-Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
-details. */
+/* java.util.Locale
+ Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
package java.util;
/**
- * @author Per Bothner <bothner@cygnus.com>
- * @date October 24, 1998.
- */
-
-/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3,
- * and "The Java Language Specification", ISBN 0-201-63451-1.
- * Status: None of the getDisplayXXX or getISO3XXX methods are implemented.
+ * Locales represent a specific country and culture.
+ * <br><br>
+ * Classes which can be passed a Locale object tailor their information
+ * for a given locale. For instance, currency number formatting is
+ * handled differently for the USA and France.
+ * <br><br>
+ * Locales are made up of a language code, a country code, and an optional
+ * set of variant strings.
+ * <br><br>
+ * Language codes are represented by
+ * <a href="http://www.indigo.ie/egt/standards/iso639/iso639-1-en.html">ISO 639:1988</a>
+ * w/ additions from ISO 639/RA Newsletter No. 1/1989
+ * and a decision of the Advisory Committee of ISO/TC39 on
+ * August 8, 1997.
+ * <br><br>
+ * Country codes are represented by
+ * <a href="ftp://ftp.ripe.net/iso3166-countrycodes">ISO 3166</a>.
+ * <br><br>
+ * Variant strings are vendor and browser specific. Standard variant
+ * strings include "POSIX" for POSIX, "WIN" for MS-Windows, and "MAC" for
+ * Macintosh. When there is more than one variant string, they must
+ * be separated by an underscore (U+005F).
+ * <br><br>
+ * The default locale is determined by the values of the system properties
+ * user.language, user.region, and user.variant.
+ * @see ResourceBundle
+ * @see java.text.Format
+ * @see java.text.NumberFormat
+ * @see java.text.Collator
+ * @author Jochen Hoenicke
+ * @author Paul Fisher
*/
public final class Locale implements java.io.Serializable, Cloneable
{
- // The fields are as specified in Sun's "Serialized Form"
- // in the JDK 1.2 beta 4 API specification.
- private String country;
- private int hashcode;
+ /**
+ * Locale which represents the English language.
+ */
+ public static final Locale ENGLISH = new Locale("en", "");
+ /**
+ * Locale which represents the English language.
+ */
+ public static final Locale FRENCH = new Locale("fr", "");
+ /**
+ * Locale which represents the German language.
+ */
+ public static final Locale GERMAN = new Locale("de", "");
+ /**
+ * Locale which represents the Italian language.
+ */
+ public static final Locale ITALIAN = new Locale("it", "");
+ /**
+ * Locale which represents the Japanese language.
+ */
+ public static final Locale JAPANESE = new Locale("ja", "");
+ /**
+ * Locale which represents the Korean language.
+ */
+ public static final Locale KOREAN = new Locale("ko", "");
+ /**
+ * Locale which represents the Chinese language.
+ */
+ public static final Locale CHINESE = new Locale("zh", "");
+ /**
+ * Locale which represents the Chinese language as used in China.
+ */
+ public static final Locale SIMPLIFIED_CHINESE = new Locale("zh", "CN");
+ /**
+ * Locale which represents the Chinese language as used in Taiwan.
+ * Same as TAIWAN Locale.
+ */
+ public static final Locale TRADITIONAL_CHINESE = new Locale("zh", "TW");
+ /**
+ * Locale which represents France.
+ */
+ public static final Locale FRANCE = new Locale("fr", "FR");
+ /**
+ * Locale which represents Germany.
+ */
+ public static final Locale GERMANY = new Locale("de", "DE");
+ /**
+ * Locale which represents Italy.
+ */
+ public static final Locale ITALY = new Locale("it", "IT");
+ /**
+ * Locale which represents Japan.
+ */
+ public static final Locale JAPAN = new Locale("ja", "JP");
+ /**
+ * Locale which represents Korea.
+ */
+ public static final Locale KOREA = new Locale("ko", "KR");
+ /**
+ * Locale which represents China.
+ * Same as SIMPLIFIED_CHINESE Locale.
+ */
+ public static final Locale CHINA = SIMPLIFIED_CHINESE;
+ /**
+ * Locale which represents the People's Republic of China.
+ * Same as CHINA Locale.
+ */
+ public static final Locale PRC = CHINA;
+ /**
+ * Locale which represents Taiwan.
+ * Same as TRADITIONAL_CHINESE Locale.
+ */
+ public static final Locale TAIWAN = TRADITIONAL_CHINESE;
+ /**
+ * Locale which represents the United Kingdom.
+ */
+ public static final Locale UK = new Locale("en", "GB");
+ /**
+ * Locale which represents the United States.
+ */
+ public static final Locale US = new Locale("en", "US");
+ /**
+ * Locale which represents the English speaking portion of Canada.
+ */
+ public static final Locale CANADA = new Locale("en", "CA");
+ /**
+ * Locale which represents the French speaking portion of Canada.
+ */
+ public static final Locale CANADA_FRENCH = new Locale("fr", "CA");
+
+ /**
+ * We are compatible to sun's Locale.
+ */
+ static final long serialVersionUID = 9149081749638150636L;
+
+ /**
+ * The language code, as returned by getLanguage().
+ * @serial
+ */
private String language;
+ /**
+ * The country code, as returned by getCountry().
+ * @serial
+ */
+ private String country;
+ /**
+ * The variant code, as returned by getVariant().
+ * @serial
+ */
private String variant;
- private static Locale defaultLocale;
- private static final long serialVersionUID = 9149081749638150636L;
-
- // These are as specified in the JDK 1.2 AP documentation
-
-
- // LANGUAGE constants ... country-neutral
- public static final Locale CHINESE = new Locale ("zh", "");
- public static final Locale ENGLISH = new Locale ("en", "");
- public static final Locale FRENCH = new Locale ("fr", "");
- public static final Locale GERMAN = new Locale ("de", "");
- public static final Locale ITALIAN = new Locale ("it", "");
- public static final Locale JAPANESE = new Locale ("ja", "");
- public static final Locale KOREAN = new Locale ("ko", "");
-
- // COUNTRY constants ... countries can be multi-lingual
- public static final Locale CANADA = new Locale ("en", "CA");
- public static final Locale CANADA_FRENCH = new Locale ("fr", "CA");
- public static final Locale FRANCE = new Locale ("fr", "FR");
- public static final Locale GERMANY = new Locale ("de", "DE");
- public static final Locale ITALY = new Locale ("it", "IT");
- public static final Locale JAPAN = new Locale ("ja", "JP");
- public static final Locale KOREA = new Locale ("ko", "KR");
- public static final Locale UK = new Locale ("en", "GB");
- public static final Locale US = new Locale ("en", "US");
-
- // Chinese has multiple scripts and political bodies
- public static final Locale SIMPLIFIED_CHINESE = new Locale ("zh", "CN");
- public static final Locale TRADITIONAL_CHINESE = new Locale ("zh", "TW");
- public static final Locale PRC = SIMPLIFIED_CHINESE;
- public static final Locale TAIWAN = TRADITIONAL_CHINESE;
- public static final Locale CHINA = PRC;
+ /**
+ * This is the cached hashcode. When writing to stream, we write -1.
+ * @serial
+ */
+ private int hashcode;
+
+ /**
+ * Convert old iso639 codes to the new ones.
+ */
+ private String convertLanguage(String language)
+ {
+ if (language.equals(""))
+ return language;
+
+ language = language.toLowerCase();
+ int index = "iw,in,ji".indexOf(language);
+ if (index != -1)
+ return "he,id,yi".substring(index, index + 2);
+ return language;
+ }
+
+ /**
+ * Creates a new locale for the given language and country.
+ * @param language lowercase two-letter ISO-639 A2 language code.
+ * @param country uppercase two-letter ISO-3166 A2 contry code.
+ * @param variant vendor and browser specific.
+ */
+ public Locale(String language, String country, String variant)
+ {
+ this.language = convertLanguage(language);
+ this.country = country.toUpperCase();
+ this.variant = variant.toUpperCase();
+ this.hashcode = (this.language.hashCode() ^ this.country.hashCode()
+ ^ this.variant.hashCode());
+ }
- public Locale (String languageCode, String countryCode)
+ /**
+ * Creates a new locale for the given language and country.
+ * @param language lowercase two-letter ISO-639 A2 language code.
+ * @param country uppercase two-letter ISO-3166 A2 country code.
+ */
+ public Locale(String language, String country)
{
- this (languageCode, countryCode, "");
+ this(language, country, "");
}
- public Locale (String languageCode, String countryCode,
- String variantCode)
+ private static Locale defaultLocale =
+ new Locale(System.getProperty("user.language", ""),
+ System.getProperty("user.region", ""),
+ System.getProperty("user.variant", ""));
+
+ /**
+ * Returns the default Locale. The default locale is generally
+ * once set on start up and then never changed. Normally you
+ * should use this locale for everywhere you need a locale.
+ * The initial setting matches the default locale, the user has
+ * chosen.
+ */
+ public static Locale getDefault()
{
- language = languageCode.toLowerCase();
- country = countryCode.toUpperCase();
- variant = variantCode.toUpperCase();
- hashcode = (languageCode.hashCode()
- ^ countryCode.hashCode()
- ^ variantCode.hashCode());
+ return defaultLocale;
}
- public Object clone ()
+ /**
+ * Changes the default locale. Normally only called on program
+ * start up. Note that this doesn't change the locale for other
+ * programs.
+ */
+ public static void setDefault(Locale newLocale)
{
- return (Object) new Locale (language, country, variant);
+ defaultLocale = newLocale;
}
- public boolean equals (Object obj)
+ /**
+ * Returns the list of available locales.
+ */
+ public static Locale[] getAvailableLocales()
+ {
+ /* I only return those for which localized language
+ * or country information exists.
+ * XXX - remove hard coded list.
+ */
+ return new Locale[]
{
- if (! (obj instanceof Locale))
- return false;
- Locale loc = (Locale) obj;
- return (language.equals(loc.language)
- && country.equals(loc.country)
- && variant.equals(loc.variant));
- }
+ ENGLISH, FRENCH, GERMAN, new Locale("ga", "")
+ };
+ }
- public String getCountry ()
+ /**
+ * Returns a list of all 2-letter uppercase country codes as defined
+ * in ISO 3166
+ */
+ public static String[] getISOCountries()
{
- return country;
+ return new String[]
+ {
+ "AF", "AL", "DZ", "AS", "AD", "AO", "AI", "AQ", "AG",
+ "AR", "AM", "AW", "AU", "AT", "AZ", "BS", "BH", "BD",
+ "BB", "BY", "BE", "BZ", "BJ", "BM", "BT", "BO", "BA",
+ "BW", "BV", "BR", "IO", "BN", "BG", "BF", "BI", "KH",
+ "CM", "CA", "CV", "KY", "CF", "TD", "CL", "CN", "CX",
+ "CC", "CO", "KM", "CG", "CK", "CR", "CI", "HR", "CU",
+ "CY", "CZ", "DK", "DJ", "DM", "DO", "TP", "EC", "EG",
+ "SV", "GQ", "ER", "EE", "ET", "FK", "FO", "FJ", "FI",
+ "FR", "FX", "GF", "PF", "TF", "GA", "GM", "GE", "DE",
+ "GH", "GI", "GR", "GL", "GD", "GP", "GU", "GT", "GN",
+ "GW", "GY", "HT", "HM", "HN", "HK", "HU", "IS", "IN",
+ "ID", "IR", "IQ", "IE", "IL", "IT", "JM", "JP", "JO",
+ "KZ", "KE", "KI", "KP", "KR", "KW", "KG", "LA", "LV",
+ "LB", "LS", "LR", "LY", "LI", "LT", "LU", "MO", "MK",
+ "MG", "MW", "MY", "MV", "ML", "MT", "MH", "MQ", "MR",
+ "MU", "YT", "MX", "FM", "MD", "MC", "MN", "MS", "MA",
+ "MZ", "MM", "NA", "NR", "NP", "NL", "AN", "NC", "NZ",
+ "NI", "NE", "NG", "NU", "NF", "MP", "NO", "OM", "PK",
+ "PW", "PA", "PG", "PY", "PE", "PH", "PN", "PL", "PT",
+ "PR", "QA", "RE", "RO", "RU", "RW", "KN", "LC", "VC",
+ "WS", "SM", "ST", "SA", "SN", "SC", "SL", "SG", "SK",
+ "SI", "SB", "SO", "ZA", "GS", "ES", "LK", "SH", "PM",
+ "SD", "SR", "SJ", "SZ", "SE", "CH", "SY", "TW", "TJ",
+ "TZ", "TH", "TG", "TK", "TO", "TT", "TN", "TR", "TM",
+ "TC", "TV", "UG", "UA", "AE", "GB", "US", "UM", "UY",
+ "UZ", "VU", "VA", "VE", "VN", "VG", "VI", "WF", "EH",
+ "YE", "YU", "ZR", "ZM", "ZW"};
}
- public String getLanguage ()
+ /**
+ * Returns a list of all 2-letter lowercase language codes as defined
+ * in ISO 639 (both old and new variant).
+ */
+ public static String[] getISOLanguages()
+ {
+ return new String[]
+ {
+ "aa", "ab", "af", "am", "ar", "as", "ay", "az", "ba",
+ "be", "bg", "bh", "bi", "bn", "bo", "br", "ca", "co",
+ "cs", "cy", "da", "de", "dz", "el", "en", "eo", "es",
+ "et", "eu", "fa", "fi", "fj", "fo", "fr", "fy", "ga",
+ "gd", "gl", "gn", "gu", "ha", "iw", "he", "hi", "hr",
+ "hu", "hy", "ia", "in", "id", "ie", "ik", "is", "it",
+ "iu", "ja", "jw", "ka", "kk", "kl", "km", "kn", "ko",
+ "ks", "ku", "ky", "la", "ln", "lo", "lt", "lv", "mg",
+ "mi", "mk", "ml", "mn", "mo", "mr", "ms", "mt", "my",
+ "na", "ne", "nl", "no", "oc", "om", "or", "pa", "pl",
+ "ps", "pt", "qu", "rm", "rn", "ro", "ru", "rw", "sa",
+ "sd", "sg", "sh", "si", "sk", "sl", "sm", "sn", "so",
+ "sq", "sr", "ss", "st", "su", "sv", "sw", "ta", "te",
+ "tg", "th", "ti", "tk", "tl", "tn", "to", "tr", "ts",
+ "tt", "tw", "ug", "uk", "ur", "uz", "vi", "vo", "wo",
+ "xh", "ji", "yi", "yo", "za", "zh", "zu"};
+ }
+
+ /**
+ * Returns the language code of this locale.
+ * @return language code portion of this locale, or an empty String if
+ * none exists
+ */
+ public String getLanguage()
{
return language;
}
- public String getVariant ()
+ /**
+ * Returns the country code of this locale.
+ * @return country code portion of this locale, or an empty String if
+ * none exists
+ */
+ public String getCountry()
+ {
+ return country;
+ }
+
+ /**
+ * Returns the variant code of this locale.
+ */
+ public String getVariant()
{
return variant;
}
- public int hashCode ()
+ /**
+ * Gets the string representation of the current locale. This
+ * consists of the language, the country, and the variant,
+ * separated by an underscore. If one of this three component is
+ * missing the underscore will also disappear.
+ * @return the string representation of this Locale.
+ */
+ public final String toString()
{
- return hashcode;
+ StringBuffer result = new StringBuffer(language);
+ String underscore = "";
+ if (language.length() != 0)
+ underscore = "_";
+ if (country.length() != 0)
+ {
+ result.append(underscore);
+ result.append(country);
+ underscore = "_";
+ }
+ if (variant.length() != 0)
+ {
+ result.append(underscore);
+ result.append(variant);
+ }
+ return result.toString();
+ }
+
+ /**
+ * Returns the three-letter ISO language abbrevation of this locale.
+ * @exception MissingResourceException if the three-letter code is not
+ * known.
+ */
+ public String getISO3Language() throws MissingResourceException
+ {
+ int index =
+ ("aa,ab,af,am,ar,as,ay,az,ba,be,bg,bh,bi,bn,bo,br,ca,co,cs,cy," +
+ "da,de,dz,el,en,eo,es,et,eu,fa,fi,fj,fo,fr,fy,ga,gd,gl,gn,gu," +
+ "gv,ha,hi,hr,hu,hy,ia,ie,ik,id,is,it,iu,he,ja,yi,jw,ka,kk,kl," +
+ "km,kn,ko,ks,ku,kw,ky,la,lb,ln,lo,lt,lv,mg,mi,mk,ml,mn,mo,mr," +
+ "ms,mt,my,na,ne,nl,no,oc,om,or,pa,pl,ps,pt,qu,rm,rn,ro,ru,rw," +
+ "sa,sd,se,sg,sh,si,sk,sl,sm,sn,so,sq,sr,ss,st,su,sv,sw,ta,te," +
+ "tg,th,ti,tk,tl,tn,to,tr,ts,tt,tw,ug,uk,ur,uz,vi,vo,wo,xh,yo," +
+ "za,zh,zu,").indexOf(language + ",");
+
+ if (index == -1 || language.length() != 2)
+ throw new MissingResourceException
+ ("Can't find ISO3 language for " + language,
+ "java.util.Locale", language);
+
+ /* Don't read this aloud. This are the three letter language codes
+ */
+ return
+ ("aarabkaframharaasmaymazebakbelbulbihbisbenbodbrecatcoscescym" +
+ "dandeudzoellengepospaesteusfasfinfijfaofrafrygaigdhglggrnguj" +
+ "maxhauhinhrvhunhyeinaileipkindislitaikuhebjpnyidjawkatkazkal" +
+ "khmkankorkaskurcorkirlatltzlinlaolitlavmlgmrimkdmalmonmolmar" +
+ "msamltmyanaunepnldnorociormoripanpolpusporquerohrunronruskin" +
+ "sansndsmisagsrpsinslkslvsmosnasomsqisrpsswsotsunsweswatamtel" +
+ "tgkthatirtuktgltsntonturtsotattwiuigukrurduzbvievolwolxhoyor" +
+ "zhazhozul").substring(index, index + 3);
}
- private static synchronized Locale setDefault()
+ /**
+ * Returns the three-letter ISO country abbrevation of the locale.
+ * @exception MissingResourceException if the three-letter code is not
+ * known.
+ */
+ public String getISO3Country() throws MissingResourceException
{
- if (defaultLocale != null)
- return defaultLocale;
- String language = System.getProperty("user.language");
- String country = System.getProperty("user.region");
- defaultLocale = new Locale (language == null ? "en" : language,
- country == null ? "" : country);
- return defaultLocale;
+ int index =
+ ("AF,AL,DZ,AS,AD,AO,AI,AQ,AG,AR,AM,AW,AU,AT,AZ,BS,BH,BD,BB,BY,BE," +
+ "BZ,BJ,BM,BT,BO,BA,BW,BV,BR,IO,BN,BG,BF,BI,KH,CM,CA,CV,KY,CF,TD," +
+ "CL,CN,CX,CC,CO,KM,CG,CD,CK,CR,CI,HR,CU,CY,CZ,DK,DJ,DM,DO,TP,EC," +
+ "EG,SV,GQ,ER,EE,ET,FK,FO,FJ,FI,FR,FX,GF,PF,TF,GA,GM,GE,DE,GH,GI," +
+ "GR,GL,GD,GP,GU,GT,GN,GW,GY,HT,HM,VA,HN,HK,HU,IS,IN,ID,IR,IQ,IE," +
+ "IL,IT,JM,JP,JO,KZ,KE,KI,KP,KR,KW,KG,LA,LV,LB,LS,LR,LY,LI,LT,LU," +
+ "MO,MK,MG,MW,MY,MV,ML,MT,MH,MQ,MR,MU,YT,MX,FM,MD,MC,MN,MS,MA,MZ," +
+ "MM,NA,NR,NP,NL,AN,NC,NZ,NI,NE,NG,NU,NF,MP,NO,OM,PK,PW,PA,PG,PY," +
+ "PE,PH,PN,PL,PT,PR,QA,RE,RO,RU,RW,KN,LC,VC,WS,SM,ST,SA,SN,SC,SL," +
+ "SG,SK,SI,SB,SO,ZA,GS,ES,LK,SH,PM,SD,SR,SJ,SZ,SE,CH,SY,TW,TJ,TZ," +
+ "TH,TG,TK,TO,TT,TN,TR,TM,TC,TV,UG,UA,AE,GB,US,UM,UY,UZ,VU,VE,VN," +
+ "VG,VI,WF,EH,YE,YU,ZM,ZW,").indexOf(country + ",");
+
+ if (index == -1 || language.length() != 2)
+ throw new MissingResourceException
+ ("Can't find ISO3 country for " + country,
+ "java.util.Locale", country);
+
+ /* Don't read this aloud. This are the three letter country codes
+ */
+ return
+ ("AFGALBDZAASMANDAGOAIAATAATGARGARMABWAUSAUTAZEBHSBHRBGDBRBBLRBEL" +
+ "BLZBENBMUBTNBOLBIHBWABVTBRAIOTBRNBGRBFABDIKHMCMRCANCPVCYMCAFTCD" +
+ "CHLCHNCXRCCKCOLCOMCOGCODCOKCRICIVHRVCUBCYPCZEDNKDJIDMADOMTMPECU" +
+ "EGYSLVGNQERIESTETHFLKFROFJIFINFRAFXXGUFPYFATFGABGMBGEODEUGHAGIB" +
+ "GRCGRLGRDGLPGUMGTMGINGNBGUYHTIHMDVATHNDHKGHUNISLINDIDNIRNIRQIRL" +
+ "ISRITAJAMJPNJORKAZKENKIRPRKKORKWTKGZLAOLVALBNLSOLBRLBYLIELTULUX" +
+ "MACMKDMDGMWIMYSMDVMLIMLTMHLMTQMRTMUSMYTMEXFSMMDAMCOMNGMSRMARMOZ" +
+ "MMRNAMNRUNPLNLDANTNCLNZLNICNERNGANIUNFKMNPNOROMNPAKPLWPANPNGPRY" +
+ "PERPHLPCNPOLPRTPRIQATREUROMRUSRWAKNALCAVCTWSMSMRSTPSAUSENSYCSLE" +
+ "SGPSVKSVNSLBSOMZAFSGSESPLKASHNSPMSDNSURSJMSWZSWECHESYRTWNTJKTZA" +
+ "THATGOTKLTONTTOTUNTURTKMTCATUVUGAUKRAREGBRUSAUMIURYUZBVUTVENVNM" +
+ "VGBVIRWLFESHYEMYUGZMBZWE").substring(index, index + 3);
}
- public static Locale getDefault ()
+ /**
+ * Gets the country name suitable for display to the user, formatted
+ * for the default locale. This has the same effect as
+ * <pre>
+ * getDisplayLanguage(Locale.getDefault());
+ * </pre>
+ *
+ * @return the language name of this locale localized to the
+ * default locale. If the localized is not found, the ISO code
+ * is returned.
+ */
+ public String getDisplayLanguage()
{
- return defaultLocale == null ? setDefault() : defaultLocale;
+ return getDisplayLanguage(getDefault());
}
- public static void setDefault (Locale newLocale)
+ /**
+ * Gets the language name suitable for display to the user, formatted
+ * for a specified locale.
+ * @param locale locale to use for formatting
+ * @return the language name of this locale localized to the
+ * given locale. If the localized is not found, the ISO code
+ * is returned.
+ */
+ public String getDisplayLanguage(Locale locale)
{
- defaultLocale = newLocale;
+ try
+ {
+ ResourceBundle bundle
+ = ResourceBundle.getBundle("gnu.java.locale.iso639", locale);
+ return bundle.getString(language);
+ }
+ catch (MissingResourceException ex)
+ {
+ return language;
+ }
+ }
+
+ /**
+ * Returns the country name of this locale localized to the
+ * default locale. If the localized is not found, the ISO code
+ * is returned. This has the same effect as
+ * <pre>
+ * getDisplayCountry(Locale.getDefault());
+ * </pre>
+ */
+ public String getDisplayCountry()
+ {
+ return getDisplayCountry(getDefault());
}
- public String toString ()
+ /**
+ * Gets the country name suitable for display to the user, formatted
+ * for a specified locale.
+ *
+ * @param locale locale to use for formatting
+ * @return the country name of this locale localized to the given
+ * locale. If the localized is not found, the ISO country code is
+ * returned. */
+ public String getDisplayCountry(Locale locale)
{
- StringBuffer result = new StringBuffer(20);
- result.append(language);
- if (country.length() > 0)
+ try
{
- result.append('_');
- result.append(country);
- if (variant.length() > 0)
- {
- result.append('_');
- result.append(variant);
- }
+ ResourceBundle bundle =
+ ResourceBundle.getBundle("gnu.java.locale.iso3166", locale);
+ return bundle.getString(country);
+ }
+ catch (MissingResourceException ex)
+ {
+ return country;
}
+ }
+
+ /**
+ * Returns the variant name of this locale localized to the
+ * default locale. If the localized is not found, the variant code
+ * itself is returned. This has the same effect as
+ * <pre>
+ * getDisplayVariant(Locale.getDefault());
+ * </pre>
+ */
+ public String getDisplayVariant()
+ {
+ return getDisplayVariant(getDefault());
+ }
+
+ /**
+ * Returns the variant name of this locale localized to the
+ * given locale. If the localized is not found, the variant code
+ * itself is returned.
+ */
+ public String getDisplayVariant(Locale locale)
+ {
+ /*XXX - load a bundle? */
+ return variant;
+ }
+
+ /**
+ * Gets all local components suitable for display to the user, formatted
+ * for the default locale. For the language component, getDisplayLanguage
+ * is called. For the country component, getDisplayCountry is called.
+ * For the variant set component, getDisplayVariant is called.
+ * <br><br>
+ * The returned String will be one of the following forms:<br>
+ * <pre>
+ * language (country, variant)
+ * language (country)
+ * language (variant)
+ * country (variant)
+ * language
+ * country
+ * variant
+ * </pre>
+ * @return String version of this locale, suitable for display to the
+ * user.
+ */
+ public String getDisplayName()
+ {
+ return getDisplayName(getDefault());
+ }
+
+ /**
+ * Gets all local components suitable for display to the user, formatted
+ * for a specified locale. For the language component,
+ * getDisplayLanguage(Locale) is called. For the country component,
+ * getDisplayCountry(Locale) is called. For the variant set component,
+ * getDisplayVariant(Locale) is called.
+ * <br><br>
+ * The returned String will be one of the following forms:<br>
+ * <pre>
+ * language (country, variant)
+ * language (country)
+ * language (variant)
+ * country (variant)
+ * language
+ * country
+ * variant
+ * </pre>
+ *
+ * @param locale locale to use for formatting
+ *
+ * @return String version of this locale, suitable for display to the
+ * user.
+ */
+ public String getDisplayName(Locale locale)
+ {
+ StringBuffer result = new StringBuffer();
+ int count = 0;
+ String[] delimiters = {"", " (", ","};
+
+ if (language.length() != 0)
+ {
+ result.append(delimiters[count++]);
+ result.append(getDisplayLanguage(locale));
+ }
+
+ if (country.length() != 0)
+ {
+ result.append(delimiters[count++]);
+ result.append(getDisplayCountry(locale));
+ }
+
+ if (variant.length() != 0)
+ {
+ result.append(delimiters[count++]);
+ result.append(getDisplayVariant(locale));
+ }
+
+ if (count > 1)
+ result.append(")");
+
return result.toString();
}
- /**
+ /**
+ * Does the same as <code>Object.clone()</code> but does not throw
+ * an <code>CloneNotSupportedException</code>. Why anyone would
+ * use this method is a secret to me, since this class is
+ * immutable.
+ */
+ public Object clone()
+ {
+ try
+ {
+ return super.clone();
+ }
+ catch (CloneNotSupportedException ex)
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Return the hash code for this locale. The hashcode is the logical
+ * xor of the hash codes of the language, the country and the variant.
+ * The hash code is precomputed, since <code>Locale</code>s are often
+ * used in hash tables.
+ */
+ public synchronized int hashCode()
+ {
+ // This method is synchronized because writeObject() might reset
+ // the hashcode.
+ return hashcode;
+ }
+
+ /**
+ * Compares two locales.
+ * @param obj the other locale.
+ * @return true, if obj is a Locale with the same language, country, and
+ * variant code as this locale, otherwise false.
+ */
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ return true;
+ if (!(obj instanceof Locale))
+ return false;
+ Locale l = (Locale) obj;
+ return (language.equals(l.language)
+ && country.equals(l.country)
+ && variant.equals(l.variant));
+ }
+
+ /**
* @serialdata According to jdk1.2 the hashcode should always be
* written as -1;
*/
- private void writeObject(java.io.ObjectOutputStream output)
+ private synchronized void writeObject(java.io.ObjectOutputStream output)
throws java.io.IOException
{
int tmpHashcode = hashcode;
-/* Copyright (C) 1998, 1999 Free Software Foundation
+/* java.util.MissingResourceException
+ Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
- This file is part of libgcj.
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
-This software is copyrighted work licensed under the terms of the
-Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
-details. */
package java.util;
-
-/**
- * @author Warren Levy <warrenl@cygnus.com>
- * @date September 2, 1998.
- */
+
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
* "The Java Language Specification", ISBN 0-201-63451-1
* plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
* Status: Believed complete and correct.
*/
-
+
+/**
+ * This exception is thrown when a resource is missing.
+ *
+ * @see ResourceBundle
+ * @author Jochen Hoenicke
+ * @author Warren Levy <warrenl@cygnus.com>
+ */
public class MissingResourceException extends RuntimeException
{
+ private static final long serialVersionUID = -4876345176062000401L;
+
+ /**
+ * The name of the resource bundle requested by user.
+ */
private String className;
+
+ /**
+ * The key of the resource in the bundle requested by user.
+ */
private String key;
- public MissingResourceException(String msg, String cName, String k)
+ /**
+ * Creates a new exception, with the specified parameters.
+ * @param s the detail message.
+ * @param className the name of the resource bundle.
+ * @param key the key of the missing resource.
+ */
+ public MissingResourceException(String s, String className, String key)
{
- super(msg);
- className = cName;
- key = k;
+ super(s);
+ this.className = className;
+ this.key = key;
}
+ /**
+ * Gets the name of the resource bundle, for which a resource is missing.
+ * @return the name of the resource bundle.
+ */
public String getClassName()
{
return className;
}
+ /**
+ * Gets the key of the resource that is missing bundle, this is an empty
+ * string if the whole resource bundle is missing.
+ * @return the name of the resource bundle.
+ */
public String getKey()
{
return key;
}
}
-
-/* Copyright (C) 1998, 1999 Free Software Foundation
+/* NoSuchElementException.java -- Attempt to access element that does not exist
+ Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
- This file is part of libgcj.
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
-This software is copyrighted work licensed under the terms of the
-Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
-details. */
package java.util;
-
-/**
- * @author Warren Levy <warrenl@cygnus.com>
- * @date September 2, 1998.
- */
+
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
* "The Java Language Specification", ISBN 0-201-63451-1
* plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
* Status: Believed complete and correct.
*/
-
+
+/**
+ * Exception thrown when an attempt is made to access an element that does not
+ * exist. This exception is thrown by the Enumeration, Iterator and ListIterator
+ * classes if the nextElement, next or previous method goes beyond the end of
+ * the list of elements that are being accessed.
+ *
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date September 2, 1998.
+ */
public class NoSuchElementException extends RuntimeException
{
+ private static final long serialVersionUID = 6769829250639411880L;
+
+ /**
+ * Constructs a NoSuchElementException with no detail message.
+ */
public NoSuchElementException()
{
super();
}
- public NoSuchElementException(String msg)
+ /**
+ * Constructs a NoSuchElementException with a detail message.
+ *
+ * @param detail the detail message for the exception
+ */
+ public NoSuchElementException(String detail)
{
- super(msg);
+ super(detail);
}
}
-/* Copyright (C) 1999 Free Software Foundation
+/* java.util.PropertyResourceBundle
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
- This file is part of libgcj.
+This file is part of GNU Classpath.
-This software is copyrighted work licensed under the terms of the
-Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
-details. */
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
-package java.util;
+GNU Classpath 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 for more details.
-import java.io.InputStream;
-import java.io.IOException;
-import gnu.gcj.util.EnumerationChain;
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
-/**
- * @author Anthony Green <green@cygnus.com>
- * @date April 29, 1999.
- */
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
-/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3,
- * and "The Java Language Specification", ISBN 0-201-63451-1. */
+package java.util;
+
+import gnu.java.util.DoubleEnumeration;
+
+/**
+ * This class is a concrete <code>ResourceBundle</code> that gets it
+ * resources from a property file. This implies that the resources are
+ * strings. For more information about resource bundles see the class
+ * <code>ResourceBundle</code>.
+ *
+ * You should not use this class directly, or subclass it, but you get
+ * an object of this class automatically when you call
+ * <code>ResourceBundle.getBundle()</code> and there is a properties
+ * file.
+ *
+ * If there is also a class for this resource and the same locale, the
+ * class does win.
+ *
+ * The properties file should have the name of the resource bundle,
+ * appended with the locale (e.g. <code>_de</code) and the extension
+ * <code>.properties</code>. The file should have the same format
+ * as for <code>Properties.load()</code>
+ *
+ * XXX- move this to properties.
+ * The file should have the following
+ * format: An empty line or a line starting with <code>#</code> is
+ * ignored. An backslash (<code>\</code>) at the end of the line
+ * makes the line continueing on the next line. Otherwise, each line
+ * describes a key/value pair. The chars up to the first whitespace,
+ * = or : are the key. The key is followed by one or more
+ * whitespaces, <code>=</code> or <code>:</code>. The rest of the
+ * line is the resource belonging to the key. You can give unicode
+ * characters with the <code>\\uxxxx</code> notation, where
+ * <code>xxxx</code> is the hex encoding of the 16 bit unicode char
+ * number.
+ *
+ * An example of a properties file for the german language is given
+ * here. This extends the example given in ListResourceBundle.
+ * Create a file MyResource_de.properties with the following contents
+ * and put it in the CLASSPATH. (The char <code>\u00e4<char> is the
+ * german ä)
+ *
+ * <pre>
+ * s1=3
+ * s2=MeineDisk
+ * s3=3. M\u00e4rz 96
+ * s4=Die Diskette ''{1}'' enth\u00e4lt {0} in {2}.
+ * s5=0
+ * s6=keine Dateien
+ * s7=1
+ * s8=eine Datei
+ * s9=2
+ * s10={0,number} Dateien
+ * s11=Die Formatierung warf eine Exception: {0}
+ * s12=FEHLER
+ * s13=Ergebnis
+ * s14=Dialog
+ * s15=Auswahlkriterium
+ * s16=1,3
+ * </pre>
+ *
+ * @see ResourceBundle
+ * @see ListResourceBundle
+ * @see Properties#load()
+ * @author Jochen Hoenicke */
public class PropertyResourceBundle extends ResourceBundle
{
- private Properties properties;
+ Properties properties;
+
+ /**
+ * Creates a new property resource bundle.
+ * @param stream An input stream, where the resources are read from.
+ */
+ public PropertyResourceBundle(java.io.InputStream stream)
+ throws java.io.IOException
+ {
+ properties = new Properties();
+ properties.load(stream);
+ }
- public PropertyResourceBundle (InputStream pstream) throws IOException
- {
- // Initialize and load our Properties.
- properties = new Properties();
- properties.load(pstream);
- }
+ /**
+ * Called by <code>getObject</code> when a resource is needed. This
+ * returns the resource given by the key.
+ * @param key The key of the resource.
+ * @return The resource for the key or null if it doesn't exists.
+ */
+ protected Object handleGetObject(String key)
+ {
+ return properties.getProperty(key);
+ }
+ /**
+ * This method should return all keys for which a resource exists.
+ * @return An enumeration of the keys.
+ */
public Enumeration getKeys()
- {
- if (parent == null)
- return properties.propertyNames();
- else
- return new EnumerationChain (properties.propertyNames(),
- parent.getKeys ());
- }
-
- public Object handleGetObject (String key)
- {
- return properties.getProperty(key);
- }
-}
+ {
+ // We must also return the keys of our parent.
+ if (parent != null)
+ {
+ return new DoubleEnumeration(properties.propertyNames(),
+ parent.getKeys());
+ }
+ return properties.propertyNames();
+ }
+}
-/* Copyright (C) 1998, 1999 Free Software Foundation
+/* java.util.Random
+ Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
- This file is part of libgcj.
+This file is part of GNU Classpath.
-This software is copyrighted work licensed under the terms of the
-Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
-details. */
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
-package java.util;
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
-import java.io.Serializable;
+
+package java.util;
/**
- * @author Warren Levy <warrenl@cygnus.com>
- * @date August 25, 1998.
- */
-/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
- * "The Java Language Specification", ISBN 0-201-63451-1
- * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
- * Status: Believed complete and correct
- */
-
-/* This class is completely specified by the spec to ensure absolute
- * portability between all implementations of Java
- */
-public class Random implements Serializable
+ * This class generates pseudorandom numbers. It uses the same
+ * algorithm as the original JDK-class, so that your programs behave
+ * exactly the same way, if started with the same seed.
+ *
+ * The algorithm is described in <em>The Art of Computer Programming,
+ * Volume 2</em> by Donald Knuth in Section 3.2.1.
+ *
+ * If two instances of this class are created with the same seed and
+ * the same calls to these classes are made, they behave exactly the
+ * same way. This should be even true for foreign implementations
+ * (like this), so every port must use the same algorithm as described
+ * here.
+ *
+ * If you want to implement your own pseudorandom algorithm, you
+ * should extend this class and overload the <code>next()</code> and
+ * <code>setSeed(long)</code> method. In that case the above
+ * paragraph doesn't apply to you.
+ *
+ * This class shouldn't be used for security sensitive purposes (like
+ * generating passwords or encryption keys. See <code>SecureRandom</code>
+ * in package <code>java.security</code> for this purpose.
+ *
+ * For simple random doubles between 0.0 and 1.0, you may consider using
+ * Math.random instead.
+ *
+ * @see java.security.SecureRandom
+ * @see Math#random()
+ * @author Jochen Hoenicke */
+public class Random implements java.io.Serializable
{
- /* Used by next() to hold the state of the pseudorandom number generator */
- private long seed;
-
- /* Used by nextGaussian() to hold a precomputed value */
- /* to be delivered by that method the next time it is called */
+ /**
+ * True if the next nextGaussian is available. This is used by
+ * nextGaussian, which generates two gaussian numbers by one call,
+ * and returns the second on the second call.
+ * @see #nextGaussian. */
+ private boolean haveNextNextGaussian;
+ /**
+ * The next nextGaussian if available. This is used by nextGaussian,
+ * which generates two gaussian numbers by one call, and returns the
+ * second on the second call.
+ * @see #nextGaussian.
+ */
private double nextNextGaussian;
-
- /* Used by nextGaussian() to keep track of whether it is has precomputed */
- /* and stashed away the next value to be delivered by that method */
- private boolean haveNextNextGaussian = false;
+ /**
+ * The seed. This is the number set by setSeed and which is used
+ * in next.
+ * @see #next
+ */
+ private long seed;
private static final long serialVersionUID = 3905348978240129619L;
+ /**
+ * Creates a new pseudorandom number generator. The seed is initialized
+ * to the current time as follows.
+ * <pre>
+ * setSeed(System.currentTimeMillis());
+ * </pre>
+ * @see System#currentTimeMillis()
+ */
public Random()
{
- this(System.currentTimeMillis());
+ setSeed(System.currentTimeMillis());
}
+ /**
+ * Creates a new pseudorandom number generator, starting with the
+ * specified seed. This does:
+ * <pre>
+ * setSeed(seed);
+ * </pre>
+ * @param seed the initial seed.
+ */
public Random(long seed)
{
setSeed(seed);
}
- protected synchronized int next(int bits)
- {
- seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
- return (int)(seed >>> (48 - bits));
- }
-
- // JDK1.2
- public boolean nextBoolean()
- {
- return next(1) != 0;
- }
-
- /* The method nextBytes() is not fully specified in the published specs.
- * At first I implemented it simply via:
- * for (int i = 0; i < buf.length; i++)
- * buf[i] = (byte)next(8);
- * but a simple test did not yield the same results as the std implementation.
- * There seemed to be a relationship where each i byte above was at pos 4*i+3
- * in the std. For efficiency, by reducing calls to the expensive math
- * routines, the std probably was calling next(32) once rather than next(8)
- * 4 times. Changing the algorithm to the one below based on that assumption
- * then yielded identical results to the std.
+ /**
+ * Sets the seed for this pseudorandom number generator. As described
+ * above, two instances of the same random class, starting with the
+ * same seed, should produce the same results, if the same methods
+ * are called. The implementation for java.util.Random is:
+ * <pre>
+ * public synchronized void setSeed(long seed) {
+ * this.seed = (seed ^ 0x5DEECE66DL) & ((1L << 48) - 1);
+ * haveNextNextGaussian = false;
+ * }
+ * </pre>
*/
- public void nextBytes(byte[] buf)
- {
- int randInt = 0;
-
- for (int i = 0; i < buf.length; i++)
- {
- int shift = (i % 4) * 8;
- if (shift == 0)
- randInt = next(32);
- buf[i] = (byte) (randInt >> shift);
- }
- }
-
- public double nextDouble()
+ public synchronized void setSeed(long seed)
{
- return (((long)next(26) << 27) + next(27)) / (double)(1L << 53);
+ this.seed = (seed ^ 0x5DEECE66DL) & ((1L << 48) - 1);
+ haveNextNextGaussian = false;
}
- public float nextFloat()
+ /**
+ * Generates the next pseudorandom number. This returns
+ * an int value whose <code>bits</code> low order bits are
+ * independent chosen random bits (0 and 1 are equally likely).
+ * The implementation for java.util.Random is:
+ * <pre>
+ * protected synchronized int next(int bits) {
+ * seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
+ * return (int) (seed >>> (48 - bits));
+ * }
+ * </pre>
+ * @param bits the number of random bits to generate. Must be in range
+ * 1..32.
+ * @return the next pseudorandom value.
+ * @since JDK1.1
+ */
+ protected synchronized int next(int bits)
+ /*{ require { 1 <= bits && bits <=32 ::
+ "bits "+bits+" not in range [1..32]" } } */
{
- return next(24) / ((float)(1 << 24));
+ seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
+ return (int) (seed >>> (48 - bits));
}
- public synchronized double nextGaussian()
+ /**
+ * Fills an array of bytes with random numbers. All possible values
+ * are (approximately) equally likely.
+ * The JDK documentation gives no implementation, but it seems to be:
+ * <pre>
+ * public void nextBytes(byte[] bytes) {
+ * for (int i=0; i< bytes.length; i+=4) {
+ * int random = next(32);
+ * for (int j=0; i+j< bytes.length && j<4; j++)
+ * bytes[i+j] = (byte) (random & 0xff)
+ * random >>= 8;
+ * }
+ * }
+ * }
+ * </pre>
+ * @param bytes The byte array that should be filled.
+ * @since JDK1.1
+ */
+ public void nextBytes(byte[] bytes)
+ /*{ require { bytes != null :: "bytes is null"; } } */
{
- if (haveNextNextGaussian)
+ int random;
+ /* Do a little bit unrolling of the above algorithm. */
+ int max = bytes.length & ~0x3;
+ for (int i = 0; i < max; i += 4)
{
- haveNextNextGaussian = false;
- return nextNextGaussian;
+ random = next(32);
+ bytes[i] = (byte) random;
+ bytes[i + 1] = (byte) (random >> 8);
+ bytes[i + 2] = (byte) (random >> 16);
+ bytes[i + 3] = (byte) (random >> 24);
}
- else
+ if (max < bytes.length)
{
- double v1, v2, s;
- do
- {
- v1 = 2 * nextDouble() - 1; // between -1.0 and 1.0
- v2 = 2 * nextDouble() - 1; // between -1.0 and 1.0
- s = v1 * v1 + v2 * v2;
- } while (s >= 1);
- double norm = Math.sqrt(-2 * Math.log(s)/s);
- nextNextGaussian = v2 * norm;
- haveNextNextGaussian = true;
- return v1 * norm;
+ random = next(32);
+ for (int j = max; j < bytes.length; j++)
+ {
+ bytes[j] = (byte) random;
+ random >>= 8;
+ }
}
}
+ /**
+ * Generates the next pseudorandom number. This returns
+ * an int value whose 32 bits are independent chosen random bits
+ * (0 and 1 are equally likely). The implementation for
+ * java.util.Random is:
+ * <pre>
+ * public int nextInt() {
+ * return next(32);
+ * }
+ * </pre>
+ *
+ * @return the next pseudorandom value. */
public int nextInt()
{
return next(32);
}
- // JDK1.2
+ /**
+ * Generates the next pseudorandom number. This returns
+ * a value between 0(inclusive) and <code>n</code>(exclusive), and
+ * each value has the same likelihodd (1/<code>n</code>).
+ * (0 and 1 are equally likely). The implementation for
+ * java.util.Random is:
+ * <pre>
+ * public int nextInt(int n) {
+ * if (n<=0)
+ * throw new IllegalArgumentException("n must be positive");
+ * if ((n & -n) == n) // i.e., n is a power of 2
+ * return (int)((n * (long)next(31)) >> 31);
+ * int bits, val;
+ * do {
+ * bits = next(32);
+ * val = bits % n;
+ * } while(bits - val + (n-1) < 0);
+ * return val;
+ * }
+ * </pre>
+ * This algorithm would return every value with exactly the same
+ * probability, if the next()-method would be a perfect random number
+ * generator.
+ *
+ * The loop at the bottom only accepts a value, if the random
+ * number was between 0 and the highest number less then 1<<31,
+ * which is divisible by n. The probability for this is high for small
+ * n, and the worst case is 1/2 (for n=(1<<30)+1).
+ *
+ * The special treatment for n = power of 2, selects the high bits of
+ * the random number (the loop at the bottom would select the low order
+ * bits). This is done, because the low order bits of linear congruential
+ * number generators (like the one used in this class) are known to be
+ * ``less random'' than the high order bits.
+ *
+ * @param n the upper bound.
+ * @exception IllegalArgumentException if the given upper bound is negative
+ * @return the next pseudorandom value.
+ */
public int nextInt(int n)
+ /*{ require { n > 0 :: "n must be positive"; } } */
{
if (n <= 0)
throw new IllegalArgumentException("n must be positive");
-
+ if ((n & -n) == n) // i.e., n is a power of 2
+ return (int) ((n * (long) next(31)) >> 31);
int bits, val;
do
{
- bits = next(31);
- val = bits % n;
- } while (bits - val + (n-1) < 0);
+ bits = next(32);
+ val = bits % n;
+ }
+ while (bits - val + (n - 1) < 0);
return val;
}
+ /**
+ * Generates the next pseudorandom long number. All bits of this
+ * long are independently chosen and 0 and 1 have equal likelihood.
+ * The implementation for java.util.Random is:
+ * <pre>
+ * public long nextLong() {
+ * return ((long)next(32) << 32) + next(32);
+ * }
+ * </pre>
+ * @return the next pseudorandom value.
+ */
public long nextLong()
{
- return ((long)next(32) << 32) + next(32);
+ return ((long) next(32) << 32) + next(32);
}
- public synchronized void setSeed(long seed)
+ /**
+ * Generates the next pseudorandom boolean. True and false have
+ * the same probability. The implementation is:
+ * <pre>
+ * public boolean nextBoolean() {
+ * return next(1) != 0;
+ * }
+ * </pre>
+ * @return the next pseudorandom boolean.
+ */
+ public boolean nextBoolean()
{
- this.seed = (seed ^ 0x5DEECE66DL) & ((1L << 48) - 1);
- haveNextNextGaussian = false;
+ return next(1) != 0;
+ }
+
+ /**
+ * Generates the next pseudorandom float uniformly distributed
+ * between 0.0f (inclusive) and 1.0 (exclusive). The
+ * implementation is as follows.
+ * <pre>
+ * public float nextFloat() {
+ * return next(24) / ((float)(1 << 24));
+ * }
+ * </pre>
+ * @return the next pseudorandom float. */
+ public float nextFloat()
+ {
+ return next(24) / ((float) (1 << 24));
+ }
+
+ /**
+ * Generates the next pseudorandom double uniformly distributed
+ * between 0.0f (inclusive) and 1.0 (exclusive). The
+ * implementation is as follows.
+ * <pre>
+ * public double nextDouble() {
+ * return (((long)next(26) << 27) + next(27)) / (double)(1 << 53);
+ * }
+ * </pre>
+ * @return the next pseudorandom double. */
+ public double nextDouble()
+ {
+ return (((long) next(26) << 27) + next(27)) / (double) (1L << 53);
+ }
+
+ /**
+ * Generates the next pseudorandom, Gaussian (normally) distributed
+ * double value, with mean 0.0 and standard deviation 1.0.
+ * The algorithm is as follows.
+ * <pre>
+ * public synchronized double nextGaussian() {
+ * if (haveNextNextGaussian) {
+ * haveNextNextGaussian = false;
+ * return nextNextGaussian;
+ * } else {
+ * double v1, v2, s;
+ * do {
+ * v1 = 2 * nextDouble() - 1; // between -1.0 and 1.0
+ * v2 = 2 * nextDouble() - 1; // between -1.0 and 1.0
+ * s = v1 * v1 + v2 * v2;
+ * } while (s >= 1);
+ * double norm = Math.sqrt(-2 * Math.log(s)/s);
+ * nextNextGaussian = v2 * norm;
+ * haveNextNextGaussian = true;
+ * return v1 * norm;
+ * }
+ * }
+ * </pre>
+ * This is described in section 3.4.1 of <em>The Art of Computer
+ * Programming, Volume 2</em> by Donald Knuth.
+ *
+ * @return the next pseudorandom Gaussian distributed double.
+ */
+ public synchronized double nextGaussian()
+ {
+ if (haveNextNextGaussian)
+ {
+ haveNextNextGaussian = false;
+ return nextNextGaussian;
+ }
+ else
+ {
+ double v1, v2, s;
+ do
+ {
+ v1 = 2 * nextDouble() - 1; // between -1.0 and 1.0
+ v2 = 2 * nextDouble() - 1; // between -1.0 and 1.0
+ s = v1 * v1 + v2 * v2;
+ }
+ while (s >= 1);
+ double norm = Math.sqrt(-2 * Math.log(s) / s);
+ nextNextGaussian = v2 * norm;
+ haveNextNextGaussian = true;
+ return v1 * norm;
+ }
}
}
-/* Copyright (C) 1998, 1999, 2000 Free Software Foundation
+/* java.util.ResourceBundle
+ Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
- This file is part of libgcj.
+This file is part of GNU Classpath.
-This software is copyrighted work licensed under the terms of the
-Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
-details. */
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
-package java.util;
+GNU Classpath 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 for more details.
-import java.io.InputStream;
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
-/**
- * @author Anthony Green <green@cygnus.com>
- * @date November 26, 1998.
- */
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
-/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3,
- * and "The Java Language Specification", ISBN 0-201-63451-1. */
+package java.util;
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
+
+/**
+ * A resource bundle contains locale-specific data. If you need
+ * localized data, you can load a resource bundle that matches the
+ * locale with <code>getBundle</code>. Now you can get your object by
+ * calling <code>getObject</code> or <code>getString</code> on that
+ * bundle.
+ * <br>
+ * When a bundle is demanded for a specific locale, the ResourceBundle
+ * is searched in following order (<i>def. language code<i> stands for
+ * the two letter ISO language code of the default locale (see
+ * <code>Locale.getDefault()</code>).
+ * <pre>
+ * baseName_<i>language code</i>_<i>country code</i>_<i>variant</i>
+ * baseName_<i>language code</i>_<i>country code</i>
+ * baseName_<i>language code</i>
+ * baseName_<i>def. language code</i>_<i>def. country code</i>_<i>def. variant</i>
+ * baseName_<i>def. language code</i>_<i>def. country code</i>
+ * baseName_<i>def. language code</i>
+ * baseName
+ * </pre>
+ *
+ * A bundle is backed up, by less specific bundle (omiting variant,
+ * country or language). But it is not backed up by the default
+ * language locale.
+ * <br>
+ * If you provide a bundle for a given locale, say
+ * <code>Bundle_en_UK_POSIX</code>, you must also provide a bundle for
+ * all sub locales, ie. <code>Bundle_en_UK</code>, <code>Bundle_en</code>, and
+ * <code>Bundle</code>.
+ * <br>
+ * When a bundle is searched, we look first for a class with
+ * the given name and if that is not found for a file with
+ * <code>.properties</code> extension in the classpath. The name
+ * must be a fully qualified classname (with dots as path separators).
+ * <br>
+ * (Note: This implementation always backs up the class with a
+ * properties file if that is existing, but you shouldn't rely on
+ * this, if you want to be compatible to the standard JDK.)
+ *
+ * @see Locale
+ * @see PropertyResourceBundle
+ * @author Jochen Hoenicke */
public abstract class ResourceBundle
{
+ /**
+ * The parent bundle. This is consulted when you call getObject
+ * and there is no such resource in the current bundle. This
+ * field may be null.
+ */
protected ResourceBundle parent;
- // This is used to cache resource bundles.
- private static Hashtable resource_cache = new Hashtable ();
-
- public ResourceBundle ()
- {
- }
-
- public Locale getLocale()
+ /**
+ * The locale of this resource bundle. You can read this with
+ * <code>getLocale</code> and it is automatically set in
+ * <code>getBundle</code>.
+ */
+ private Locale locale;
+
+ /**
+ * The constructor. It does nothing special.
+ */
+ public ResourceBundle()
{
- // FIXME: Stub added for this missing method because it is needed for AWT.
- return null;
}
- public final String getString (String key) throws MissingResourceException
- {
- return (String) getObject(key);
- }
+ /**
+ * Get a String from this resource bundle. Since most localized
+ * Objects are Strings, this method provides a convenient way to get
+ * them without casting.
+ * @param key the name of the resource.
+ * @exception MissingResourceException
+ * if that particular object could not be found in this bundle nor
+ * the parent bundle.
+ */
+ public final String getString(String key) throws MissingResourceException
+ {
+ return (String) getObject(key);
+ }
- public final String[] getStringArray (String key)
+ /**
+ * Get an array of Strings from this resource bundle. This method
+ * provides a convenient way to get it without casting.
+ * @param key the name of the resource.
+ * @exception MissingResourceException
+ * if that particular object could not be found in this bundle nor
+ * the parent bundle.
+ */
+ public final String[] getStringArray(String key)
throws MissingResourceException
- {
- return (String[]) getObject(key);
- }
+ {
+ return (String[]) getObject(key);
+ }
+ /**
+ * Get an object from this resource bundle.
+ * @param key the name of the resource.
+ * @exception MissingResourceException
+ * if that particular object could not be found in this bundle nor
+ * the parent bundle.
+ */
public final Object getObject(String key) throws MissingResourceException
- {
- Object result;
+ {
+ for (ResourceBundle bundle = this; bundle != null; bundle = bundle.parent)
+ {
+ try
+ {
+ Object o = bundle.handleGetObject(key);
+ if (o != null)
+ return o;
+ }
+ catch (MissingResourceException ex)
+ {
+ }
+ }
+ throw new MissingResourceException
+ ("Key not found", getClass().getName(), key);
+ }
- try
- {
- return handleGetObject (key);
- }
- catch (MissingResourceException ex)
- {
- if (parent != null)
- return parent.getObject(key);
- else
- throw ex;
- }
- }
+ /**
+ * This method returns an array with the classes of the calling
+ * methods. The zeroth entry is the class that called this method
+ * (should always be ResourceBundle), the first contains the class
+ * that called the caller (i.e. the class that called getBundle).
+ *
+ * Implementation note: This depends on the fact, that getBundle
+ * doesn't get inlined, but since it calls a private method, it
+ * isn't inlineable.
+ *
+ * @return an array containing the classes for the callers.
+ */
+ private static native Class[] getClassContext();
+
+ /**
+ * Get the appropriate ResourceBundle for the default locale.
+ * @param baseName the name of the ResourceBundle. This should be
+ * a name of a Class or a properties-File. See the class
+ * description for details.
+ * @return the desired resource bundle
+ * @exception MissingResourceException
+ * if the resource bundle couldn't be found. */
+ public static final ResourceBundle getBundle(String baseName)
+ throws MissingResourceException
+ {
+ return getBundle(baseName, Locale.getDefault(),
+ getClassContext()[1].getClassLoader());
+ }
- public static final ResourceBundle getBundle(String baseName)
+ /**
+ * Get the appropriate ResourceBundle for the given locale.
+ * @param baseName the name of the ResourceBundle. This should be
+ * a name of a Class or a properties-File. See the class
+ * description for details.
+ * @param locale A locale.
+ * @return the desired resource bundle
+ * @exception MissingResourceException
+ * if the resource bundle couldn't be found.
+ */
+ public static final ResourceBundle getBundle(String baseName,
+ Locale locale)
throws MissingResourceException
- {
- return getBundle(baseName, Locale.getDefault());
- }
+ {
+ return getBundle(baseName, locale, getClassContext()[1].getClassLoader());
+ }
- // Start searching with the name bundleName. Continue searching by
- // stripping off the '_' delimited tails until the search name is
- // the same as stopHere.
- private static final ResourceBundle trySomeGetBundle (String bundleName,
- String stopHere,
- ClassLoader loader)
+ /**
+ * The resource bundle cache. This is a two-level hash map: The key
+ * is the class loader, the value is a new HashMap. The key of this
+ * second hash map is the localized name, the value is a soft
+ * references to the resource bundle. */
+ private static Map resourceBundleCache = new HashMap();
+
+ /**
+ * Tries to load a class or a property file with the specified name.
+ * @param name the name.
+ * @param locale the locale, that must be used exactly.
+ * @param classloader the classloader.
+ * @param bundle the back up (parent) bundle
+ * @return the resource bundle if that could be loaded, otherwise
+ * <code>bundle</code>.
+ */
+ private static final ResourceBundle tryBundle(String localizedName,
+ Locale locale,
+ ClassLoader classloader,
+ ResourceBundle bundle,
+ HashMap cache)
+ {
{
- Class rbc;
- ResourceBundle needs_parent = null, r, result = null;
-
- while (true)
+ // First look into the cache.
+ // XXX We should remove cleared references from the cache.
+ Reference ref = (Reference) cache.get(localizedName);
+ if (ref != null)
{
- try
- {
- rbc = Class.forName(bundleName, true, loader);
- r = null;
- try
- {
- r = (ResourceBundle) rbc.newInstance();
- }
- catch (IllegalAccessException ex)
- {
- // Fall through
- }
- catch (InstantiationException ex)
- {
- // Fall through
- }
- if (r != null)
- {
- if (result == null)
- result = r;
- if (needs_parent != null)
- {
- // We've been through the loop one or more times
- // already. Set the parent and keep going.
- needs_parent.setParent(r);
- }
- needs_parent = r;
- }
- }
- catch (ClassNotFoundException ex)
- {
- // Fall through.
- }
-
- // Look for a properties file.
- InputStream i = loader.getResourceAsStream (bundleName.replace ('.',
- '/')
- + ".properties");
- if (i != null)
- {
- try
- {
- return new PropertyResourceBundle (i);
- }
- catch (java.io.IOException e)
- {
- // The docs don't appear to define what happens in
- // this case, but it seems like continuing the
- // search is a reasonable thing to do.
- }
- }
-
- if (bundleName.equals(stopHere))
- return result;
- else
- {
- int last = bundleName.lastIndexOf('_');
-
- // No more underscores?
- if (last == -1)
- return result;
-
- // Loop around, testing this new shorter name.
- bundleName = bundleName.substring(0, last);
- }
+ ResourceBundle rb = (ResourceBundle) ref.get();
+ if (rb != null)
+ // rb should already have the right parent, except if
+ // something very strange happened.
+ return rb;
}
}
- // Search for bundles, but stop at baseName_language (if required).
- // This is synchronized so that the cache works correctly.
- private static final synchronized ResourceBundle
- partialGetBundle (String baseName, Locale locale, boolean langStop,
- ClassLoader loader)
- {
- ResourceBundle rb;
-
- // Explicitly invoke locale.toString() to force a
- // NullPointerException when required.
- String bundleName = baseName + "_" + locale.toString();
-
- // Check the cache.
- Object obj = resource_cache.get(bundleName);
- if (obj != null)
- return (ResourceBundle) obj;
-
- String stopHere = (baseName
- + (langStop ? ("_" + locale.getLanguage()) : ""));
-
-
- rb = trySomeGetBundle(bundleName, stopHere, loader);
- if (rb != null)
- resource_cache.put(bundleName, rb);
-
- return rb;
- }
+ try
+ {
+ java.io.InputStream is;
+ if (classloader == null)
+ is = ClassLoader.getSystemResourceAsStream
+ (localizedName.replace('.', '/') + ".properties");
+ else
+ is = classloader.getResourceAsStream
+ (localizedName.replace('.', '/') + ".properties");
+ if (is != null)
+ {
+ ResourceBundle rb = new PropertyResourceBundle(is);
+ rb.parent = bundle;
+ rb.locale = locale;
+ bundle = rb;
+ }
+ }
+ catch (java.io.IOException ex)
+ {
+ }
+
+ try
+ {
+ Class rbClass;
+ if (classloader == null)
+ rbClass = Class.forName(localizedName);
+ else
+ rbClass = classloader.loadClass(localizedName);
+ ResourceBundle rb = (ResourceBundle) rbClass.newInstance();
+ rb.parent = bundle;
+ rb.locale = locale;
+ bundle = rb;
+ }
+ catch (ClassNotFoundException ex)
+ {
+ }
+ catch (IllegalAccessException ex)
+ {
+ }
+ catch (InstantiationException ex)
+ {
+ // ignore them all
+ // XXX should we also ignore ClassCastException?
+ }
+
+ // Put the bundle in the cache
+ if (bundle != null)
+ cache.put(localizedName, new SoftReference(bundle));
+
+ return bundle;
+ }
- public static final ResourceBundle getBundle (String baseName,
- Locale locale)
+ /**
+ * Tries to load a the bundle for a given locale, also loads the backup
+ * locales with the same language.
+ *
+ * @param name the name.
+ * @param locale the locale, that must be used exactly.
+ * @param classloader the classloader.
+ * @param bundle the back up (parent) bundle
+ * @return the resource bundle if that could be loaded, otherwise
+ * <code>bundle</code>.
+ */
+ private static final ResourceBundle tryLocalBundle(String baseName,
+ Locale locale,
+ ClassLoader classloader,
+ ResourceBundle bundle,
+ HashMap cache)
{
- return getBundle (baseName, locale, ClassLoader.getSystemClassLoader ());
+ if (locale.getLanguage().length() > 0)
+ {
+ String name = baseName + "_" + locale.getLanguage();
+
+ if (locale.getCountry().length() != 0)
+ {
+ bundle = tryBundle(name,
+ new Locale(locale.getLanguage(), ""),
+ classloader, bundle, cache);
+
+ name += "_" + locale.getCountry();
+
+ if (locale.getVariant().length() != 0)
+ {
+ bundle = tryBundle(name,
+ new Locale(locale.getLanguage(),
+ locale.getCountry()),
+ classloader, bundle, cache);
+
+ name += "_" + locale.getVariant();
+ }
+ }
+ bundle = tryBundle(name, locale, classloader, bundle, cache);
+ }
+ return bundle;
}
- public static final ResourceBundle getBundle (String baseName,
- Locale locale,
- ClassLoader loader)
+ /**
+ * Get the appropriate ResourceBundle for the given locale.
+ * @param baseName the name of the ResourceBundle. This should be
+ * a name of a Class or a properties file. See the class
+ * description for details.
+ * @param locale A locale.
+ * @param classloader a ClassLoader.
+ * @return the desired resource bundle
+ * @exception MissingResourceException
+ * if the resource bundle couldn't be found.
+ */
+ // This method is synchronized so that the cache is properly
+ // handled.
+ public static final synchronized ResourceBundle getBundle(String baseName,
+ Locale locale,
+ ClassLoader classLoader)
throws MissingResourceException
- {
- ResourceBundle rb;
- Class rbc;
-
- if (baseName == null)
- throw new NullPointerException ();
-
- rb = partialGetBundle(baseName, locale, false, loader);
- if (rb != null)
- return rb;
-
- // Finally, try the default locale.
- if (! locale.equals(Locale.getDefault()))
- {
- rb = partialGetBundle(baseName, Locale.getDefault(), true, loader);
- if (rb != null)
- return rb;
- }
+ {
+ // This implementation searches the bundle in the reverse direction
+ // and builds the parent chain on the fly.
+
+ HashMap cache = (HashMap) resourceBundleCache.get(classLoader);
+ if (cache == null)
+ {
+ cache = new HashMap();
+ resourceBundleCache.put(classLoader, cache);
+ }
+ else
+ {
+ // Fast path: If baseName + "_" + locale is in cache use it.
+ String name = baseName + "_" + locale.toString();
+ Reference ref = (Reference) cache.get(name);
+ if (ref != null)
+ {
+ ResourceBundle rb = (ResourceBundle) ref.get();
+ if (rb != null)
+ // rb should already have the right parent, except if
+ // something very strange happened.
+ return rb;
+ }
+ }
+
+ ResourceBundle baseBundle = tryBundle(baseName, new Locale("", ""),
+ classLoader, null, cache);
+ if (baseBundle == null)
+ // JDK says, that if one provides a bundle base_en_UK, one
+ // must also provide the bundles base_en and base.
+ // This implies that if there is no bundle for base, there
+ // is no bundle at all.
+ throw new MissingResourceException("Bundle not found", baseName, "");
+
+ // Now use the default locale.
+ ResourceBundle bundle = tryLocalBundle(baseName, locale,
+ classLoader, baseBundle, cache);
+ if (bundle == baseBundle && !locale.equals(Locale.getDefault()))
+ {
+ bundle = tryLocalBundle(baseName, Locale.getDefault(),
+ classLoader, baseBundle, cache);
+ }
+ return bundle;
+ }
- throw new MissingResourceException("can't load bundle",
- baseName,
- "bundle");
- }
+ /**
+ * Return the actual locale of this bundle. You can use it after
+ * calling getBundle, to know if the bundle for the desired locale
+ * was loaded or if the fall back was used.
+ */
+ public Locale getLocale()
+ {
+ return locale;
+ }
+ /**
+ * Set the parent of this bundle. This is consulted when you call
+ * getObject and there is no such resource in the current bundle.
+ * @param parent the parent of this bundle.
+ */
protected void setParent(ResourceBundle parent)
- {
- this.parent = parent;
- }
+ {
+ // Shall we ignore the old parent?
+ this.parent = parent;
+ }
- protected abstract Object handleGetObject(String key)
+ /**
+ * Override this method to provide the resource for a keys. This gets
+ * called by <code>getObject</code>. If you don't have a resource
+ * for the given key, you should return null instead throwing a
+ * MissingResourceException. You don't have to ask the parent,
+ * getObject() already does this.
+ *
+ * @param key The key of the resource.
+ * @return The resource for the key, or null if not in bundle.
+ * @exception MissingResourceException
+ * you shouldn't throw this.
+ */
+ protected abstract Object handleGetObject(String key)
throws MissingResourceException;
+ /**
+ * This method should return all keys for which a resource exists.
+ * @return An enumeration of the keys.
+ */
public abstract Enumeration getKeys();
}
-/* Copyright (C) 1998, 1999 Free Software Foundation
+/* java.util.StringTokenizer
+ Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
- This file is part of libgcj.
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
-This software is copyrighted work licensed under the terms of the
-Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
-details. */
package java.util;
/**
+ * This class splits a string into tokens. The caller can set on which
+ * delimiters the string should be split and if the delimiters should be
+ * returned.
+ *
+ * You may change the delimiter set on the fly by calling
+ * nextToken(String). But the semantic is quite difficult; it even
+ * depends on calling <code>hasMoreTokens()</code>. You should call
+ * <code>hasMoreTokens()</code> before, otherwise the old delimiters
+ * after the last token are returned.
+ *
+ * If you want to get the delimiters, you have to use the three argument
+ * constructor. The delimiters are returned as token consisting of a
+ * single character.
+ *
+ * @author Jochen Hoenicke
* @author Warren Levy <warrenl@cygnus.com>
- * @date August 24, 1998.
- */
-/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
- * "The Java Language Specification", ISBN 0-201-63451-1
- * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
- * Status: Believed complete and correct
*/
-
public class StringTokenizer implements Enumeration
{
- /* String to be parsed */
- private String inputString;
+ /**
+ * The position in the str, where we currently are.
+ */
+ private int pos;
+ /**
+ * The string that should be split into tokens.
+ */
+ private String str;
+ /**
+ * The string containing the delimiter characters.
+ */
+ private String delim;
+ /**
+ * Tells, if we should return the delimiters.
+ */
+ private boolean retDelims;
+
+ /*{
+ invariant {
+ pos >= 0 :: "position is negative";
+ pos <= str.length() :: "position is out of string";
+ str != null :: "String is null";
+ delim != null :: "Delimiters are null";
+ }
+ } */
+
+ /**
+ * Creates a new StringTokenizer for the string <code>str</code>,
+ * that should split on the default delimiter set (space, tap,
+ * newline, return and formfeed), and which doesn't return the
+ * delimiters.
+ * @param str The string to split.
+ */
+ public StringTokenizer(String str)
+ /*{ require { str != null :: "str must not be null"; } } */
+ {
+ this(str, " \t\n\r\f", false);
+ }
- /* String to be parsed put into a char array for efficient access */
- private char[] chArray;
+ /**
+ * Create a new StringTokenizer, that splits the given string on
+ * the given delimiter characters. It doesn't return the delimiter
+ * characters.
+ *
+ * @param str The string to split.
+ * @param delim A string containing all delimiter characters.
+ */
+ public StringTokenizer(String str, String delim)
+ /*{ require { str != null :: "str must not be null";
+ delim != null :: "delim must not be null"; } } */
+ {
+ this(str, delim, false);
+ }
- /* Set of delimiter characters for separating tokens */
- private String delimiters;
+ /**
+ * Create a new StringTokenizer, that splits the given string on
+ * the given delimiter characters. If you set
+ * <code>returnDelims</code> to <code>true</code>, the delimiter
+ * characters are returned as tokens of their own. The delimiter
+ * tokens always consist of a single character.
+ *
+ * @param str The string to split.
+ * @param delim A string containing all delimiter characters.
+ * @param returnDelims Tells, if you want to get the delimiters.
+ */
+ public StringTokenizer(String str, String delim, boolean returnDelims)
+ /*{ require { str != null :: "str must not be null";
+ delim != null :: "delim must not be null"; } } */
+ {
+ this.str = str;
+ this.delim = delim;
+ this.retDelims = returnDelims;
+ this.pos = 0;
+ }
- /* Whether delimiters in this instance are treated as tokens themselves */
- private boolean returnDelimiters;
+ /**
+ * Tells if there are more tokens.
+ * @return True, if the next call of nextToken() succeeds, false otherwise.
+ */
+ public boolean hasMoreTokens()
+ {
+ if (!retDelims)
+ {
+ while (pos < str.length() && delim.indexOf(str.charAt(pos)) > -1)
+ {
+ pos++;
+ }
+ }
+ return pos < str.length();
+ }
- /* Index into the input string to start parsing for the next token */
- private int inputStringIndex;
+ /**
+ * Returns the nextToken, changing the delimiter set to the given
+ * <code>delim</code>. The change of the delimiter set is
+ * permanent, ie. the next call of nextToken(), uses the same
+ * delimiter set.
+ * @param delim a string containing the new delimiter characters.
+ * @return the next token with respect to the new delimiter characters.
+ * @exception NoSuchElementException if there are no more tokens.
+ */
+ public String nextToken(String delim) throws NoSuchElementException
+ /*{ require { hasMoreTokens() :: "no more Tokens available";
+ ensure { $return != null && $return.length() > 0; } } */
+ {
+ this.delim = delim;
+ return nextToken();
+ }
- public StringTokenizer(String str)
+ /**
+ * Returns the nextToken of the string.
+ * @param delim a string containing the new delimiter characters.
+ * @return the next token with respect to the new delimiter characters.
+ * @exception NoSuchElementException if there are no more tokens.
+ */
+ public String nextToken() throws NoSuchElementException
+ /*{ require { hasMoreTokens() :: "no more Tokens available";
+ ensure { $return != null && $return.length() > 0; } } */
{
- this(str, " \t\n\r", false);
+ if (pos < str.length() && delim.indexOf(str.charAt(pos)) > -1)
+ {
+ if (retDelims)
+ return str.substring(pos, ++pos);
+
+ while (++pos < str.length() && delim.indexOf(str.charAt(pos)) > -1)
+ {
+ /* empty */
+ }
+ }
+ if (pos < str.length())
+ {
+ int start = pos;
+ while (++pos < str.length() && delim.indexOf(str.charAt(pos)) == -1)
+ {
+ /* empty */
+ }
+ return str.substring(start, pos);
+ }
+ throw new NoSuchElementException();
}
- public StringTokenizer(String str, String delims)
+ /**
+ * This does the same as hasMoreTokens. This is the
+ * <code>Enumeration</code interface method.
+ * @return True, if the next call of nextElement() succeeds, false
+ * otherwise.
+ * @see #hasMoreTokens
+ */
+ public boolean hasMoreElements()
{
- this(str, delims, false);
+ return hasMoreTokens();
}
- public StringTokenizer(String str, String delims, boolean retDelim)
+ /**
+ * This does the same as nextTokens. This is the
+ * <code>Enumeration</code interface method.
+ * @return the next token with respect to the new delimiter characters.
+ * @exception NoSuchElementException if there are no more tokens.
+ * @see #nextToken
+ */
+ public Object nextElement() throws NoSuchElementException
{
- inputString = str;
- delimiters = delims;
- returnDelimiters = retDelim;
- inputStringIndex = 0;
-
- // Work on a copy of the remaining string in a char array
- // to gain efficiency of using primitives
- chArray = new char[inputString.length()];
- inputString.getChars(0, inputString.length(), chArray, 0);
+ return nextToken();
}
+ /**
+ * This counts the number of remaining tokens in the string, with
+ * respect to the current delimiter set.
+ * @return the number of times <code>nextTokens()</code> will
+ * succeed.
+ * @see #nextToken
+ */
public int countTokens()
{
int count = 0;
int delimiterCount = 0;
boolean tokenFound = false; // Set when a non-delimiter is found
- int offset = inputStringIndex;
+ int tmpPos = pos;
// Note for efficiency, we count up the delimiters rather than check
- // returnDelimiters every time we encounter one. That way, we can
+ // retDelims every time we encounter one. That way, we can
// just do the conditional once at the end of the method
- while (offset < chArray.length)
+ while (tmpPos < str.length())
{
- if (isDelimiter(chArray[offset++]))
+ if (delim.indexOf(str.charAt(tmpPos++)) > -1)
{
if (tokenFound)
{
tokenFound = true;
// Get to the end of the token
- while (offset < chArray.length && !isDelimiter(chArray[offset]))
- offset++;
+ while (tmpPos < str.length()
+ && delim.indexOf(str.charAt(tmpPos)) == -1)
+ ++tmpPos;
}
}
count++;
// if counting delmiters add them into the token count
- return returnDelimiters ? count + delimiterCount : count;
- }
-
- public boolean hasMoreElements()
- {
- return hasMoreTokens();
- }
-
- public boolean hasMoreTokens()
- {
- int offset = inputStringIndex;
-
- while (offset < chArray.length)
- if (!isDelimiter(chArray[offset++]) || returnDelimiters)
- {
- // update the current position with the start of the next token
- inputStringIndex = --offset;
-
- return true;
- }
-
- return false;
- }
-
- public Object nextElement()
- {
- return nextToken();
- }
-
- public String nextToken()
- {
- int offset = inputStringIndex;
- int startSubstr = -1;
-
- // Make sure we have more chars left to parse
- // and then find the start of the next token
- while (offset < chArray.length && startSubstr < 0)
- {
- // Find the start of the token; skipping initial delimiters
- if (!isDelimiter(chArray[offset++]))
- startSubstr = offset - 1;
- else if (returnDelimiters)
- {
- // The single char delimiter is treated as a token
- inputStringIndex = offset; // update the current position
-
- return inputString.substring(offset - 1, inputStringIndex);
- }
- }
-
- // Now look for the end of the token
- while (offset < chArray.length)
- {
- if (isDelimiter(chArray[offset++]))
- {
- // Found the end of token
- inputStringIndex = offset - 1; // update the current position
-
- return inputString.substring(startSubstr, inputStringIndex);
- }
- }
-
- // Got to the end of the string without finding the start of a token
- if (startSubstr < 0)
- throw new NoSuchElementException();
-
- // Got to the end of the string before a delimiter
- inputStringIndex = offset; // update the current position
-
- return inputString.substring(startSubstr, inputStringIndex);
- }
-
- public String nextToken(String delims)
- {
- // First replace with new set of delimiters
- delimiters = delims;
-
- return nextToken();
- }
-
- // This private method could be inlined but the other methods are
- // more readable this way, so we'll take the hit on efficiency.
- private boolean isDelimiter(char ch)
- {
- return delimiters.indexOf(ch, 0) >= 0;
+ return retDelims ? count + delimiterCount : count;
}
}
-/* Copyright (C) 1998, 1999 Free Software Foundation
+/* java.util.TooManyListenersException
+ Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
- This file is part of libgcj.
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
-This software is copyrighted work licensed under the terms of the
-Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
-details. */
package java.util;
-
-/**
- * @author Warren Levy <warrenl@cygnus.com>
- * @date September 2, 1998.
- */
+
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
* "The Java Language Specification", ISBN 0-201-63451-1
* plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
* Status: Believed complete and correct.
*/
-
+
+/**
+ * This exception is part of the java event model. It is thrown if an
+ * event listener is added via the addXyzEventListener method, but the
+ * object doesn't support any more listeners, e.g. it only supports a
+ * single event listener.
+ *
+ * @see EventListener
+ * @see EventObject
+ * @author Jochen Hoenicke
+ * @author Warren Levy <warrenl@cygnus.com>
+ */
+
public class TooManyListenersException extends Exception
{
+ private static final long serialVersionUID = 5074640544770687831L;
+
+ /**
+ * Constructs a TooManyListenersException with no detail message.
+ */
public TooManyListenersException()
{
- super();
}
- public TooManyListenersException(String msg)
+ /**
+ * Constructs a TooManyListenersException with a detail message.
+ * @param detail the detail message.
+ */
+ public TooManyListenersException(String detail)
{
- super(msg);
+ super(detail);
}
}
--- /dev/null
+// natResourceBundle.cc - Native code for ResourceBundle class.
+
+/* Copyright (C) 2001 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java/util/ResourceBundle.h>
+#include <java/lang/Class.h>
+#include <java/lang/ClassLoader.h>
+
+JArray<jclass> *
+java::util::ResourceBundle::getClassContext ()
+{
+ // FIXME: we currently lack the capability to correctly implement
+ // this method. So we fake it by telling ResourceBundle that we
+ // only have the system class loader.
+ jobjectArray a = JvNewObjectArray (2, &java::lang::Class::class$, NULL);
+ jobject *elts = elements (a);
+ elts[0] = java::lang::ClassLoader::getSystemClassLoader ();
+ elts[1] = elts[0];
+
+ return reinterpret_cast< JArray<jclass> *> (a);
+}