Makefile.in: Rebuilt.

* 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.

From-SVN: r45335
This commit is contained in:
Tom Tromey 2001-08-31 21:31:20 +00:00 committed by Tom Tromey
parent fb9282f91f
commit 7a95ae6b51
18 changed files with 2271 additions and 779 deletions

View File

@ -1,5 +1,26 @@
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.

View File

@ -1128,7 +1128,6 @@ gnu/gcj/text/LocaleData_en.java \
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 \
@ -1143,6 +1142,7 @@ gnu/java/security/provider/DefaultPolicy.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 \
@ -1492,6 +1492,7 @@ java/net/natInetAddress.cc \
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

View File

@ -878,7 +878,6 @@ gnu/gcj/text/LocaleData_en.java \
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 \
@ -893,6 +892,7 @@ gnu/java/security/provider/DefaultPolicy.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 \
@ -1241,6 +1241,7 @@ java/net/natInetAddress.cc \
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
@ -1388,7 +1389,8 @@ java/lang/reflect/natArray.lo java/lang/reflect/natConstructor.lo \
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 \
@ -1493,8 +1495,7 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.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 \
@ -1560,7 +1561,8 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.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 \
@ -2062,8 +2064,8 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.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 \

View File

@ -1,52 +0,0 @@
/* 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();
}
}

View File

@ -0,0 +1,128 @@
/* 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();
}
}
}

View File

@ -1,22 +1,28 @@
/*
* 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;

View File

@ -1,33 +1,69 @@
/* 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);
}
}

View File

@ -1,25 +1,52 @@
/* 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();

View File

@ -1,52 +1,100 @@
/* 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.
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 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. */
public abstract class ListResourceBundle extends ResourceBundle
* 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
{
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);
}
public Enumeration getKeys()
{
Object a[][] = getContents();
Vector keys = new Vector(a.length);
for (int i = 0; i < a.length; i++)
keys.addElement(a[i][0]);
return keys.elements();
}
/**
* 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];
}
};
}
}

View File

@ -1,157 +1,687 @@
/* 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;
private String language;
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;
/**
* 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;
public static final Locale CHINA = PRC;
/**
* 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");
public Locale (String languageCode, String countryCode)
/**
* 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;
/**
* 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)
{
this (languageCode, countryCode, "");
}
if (language.equals(""))
return language;
public Locale (String languageCode, String countryCode,
String variantCode)
{
language = languageCode.toLowerCase();
country = countryCode.toUpperCase();
variant = variantCode.toUpperCase();
hashcode = (languageCode.hashCode()
^ countryCode.hashCode()
^ variantCode.hashCode());
}
public Object clone ()
{
return (Object) new Locale (language, country, variant);
}
public boolean equals (Object obj)
{
if (! (obj instanceof Locale))
return false;
Locale loc = (Locale) obj;
return (language.equals(loc.language)
&& country.equals(loc.country)
&& variant.equals(loc.variant));
}
public String getCountry ()
{
return country;
}
public String getLanguage ()
{
language = language.toLowerCase();
int index = "iw,in,ji".indexOf(language);
if (index != -1)
return "he,id,yi".substring(index, index + 2);
return language;
}
public String getVariant ()
/**
* 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)
{
return 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 int hashCode ()
/**
* 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)
{
return hashcode;
this(language, country, "");
}
private static synchronized Locale setDefault()
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()
{
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;
}
public static Locale getDefault ()
{
return defaultLocale == null ? setDefault() : defaultLocale;
}
public static void setDefault (Locale newLocale)
/**
* 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)
{
defaultLocale = newLocale;
}
public String toString ()
/**
* Returns the list of available locales.
*/
public static Locale[] getAvailableLocales()
{
StringBuffer result = new StringBuffer(20);
result.append(language);
if (country.length() > 0)
/* I only return those for which localized language
* or country information exists.
* XXX - remove hard coded list.
*/
return new Locale[]
{
ENGLISH, FRENCH, GERMAN, new Locale("ga", "")
};
}
/**
* Returns a list of all 2-letter uppercase country codes as defined
* in ISO 3166
*/
public static String[] getISOCountries()
{
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"};
}
/**
* 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;
}
/**
* 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;
}
/**
* 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()
{
StringBuffer result = new StringBuffer(language);
String underscore = "";
if (language.length() != 0)
underscore = "_";
if (country.length() != 0)
{
result.append('_');
result.append(underscore);
result.append(country);
if (variant.length() > 0)
{
result.append('_');
result.append(variant);
}
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);
}
/**
* 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
{
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);
}
/**
* 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 getDisplayLanguage(getDefault());
}
/**
* 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)
{
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());
}
/**
* 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)
{
try
{
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;

View File

@ -1,43 +1,88 @@
/* 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;
}
}

View File

@ -1,32 +1,66 @@
/* 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);
}
}

View File

@ -1,47 +1,133 @@
/* 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.
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;
import java.io.InputStream;
import java.io.IOException;
import gnu.gcj.util.EnumerationChain;
import gnu.java.util.DoubleEnumeration;
/**
* @author Anthony Green <green@cygnus.com>
* @date April 29, 1999.
*/
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3,
* and "The Java Language Specification", ISBN 0-201-63451-1. */
* 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 &auml;)
*
* <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;
public PropertyResourceBundle (InputStream pstream) throws IOException
{
// Initialize and load our Properties.
properties = new Properties();
properties.load(pstream);
}
/**
* 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);
}
/**
* 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();
}
}

View File

@ -1,150 +1,379 @@
/* 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.
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;
import java.io.Serializable;
/**
* @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()
{
return (((long)next(26) << 27) + next(27)) / (double)(1L << 53);
}
public float nextFloat()
{
return next(24) / ((float)(1 << 24));
}
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;
}
}
public int nextInt()
{
return next(32);
}
// JDK1.2
public int nextInt(int n)
{
if (n <= 0)
throw new IllegalArgumentException("n must be positive");
int bits, val;
do
{
bits = next(31);
val = bits % n;
} while (bits - val + (n-1) < 0);
return val;
}
public long nextLong()
{
return ((long)next(32) << 32) + next(32);
}
public synchronized void setSeed(long seed)
{
this.seed = (seed ^ 0x5DEECE66DL) & ((1L << 48) - 1);
haveNextNextGaussian = false;
}
/**
* 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]" } } */
{
seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
return (int) (seed >>> (48 - bits));
}
/**
* 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"; } } */
{
int random;
/* Do a little bit unrolling of the above algorithm. */
int max = bytes.length & ~0x3;
for (int i = 0; i < max; i += 4)
{
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);
}
if (max < bytes.length)
{
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);
}
/**
* 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(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);
}
/**
* 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()
{
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;
}
}
}

View File

@ -1,223 +1,431 @@
/* 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.
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;
import java.io.InputStream;
import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
/**
* @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. */
* 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 ();
/**
* 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;
public ResourceBundle ()
{
}
public Locale getLocale()
/**
* 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;
try
{
return handleGetObject (key);
}
catch (MissingResourceException ex)
{
if (parent != null)
return parent.getObject(key);
else
throw ex;
}
}
public static final ResourceBundle getBundle(String baseName)
throws MissingResourceException
{
return getBundle(baseName, Locale.getDefault());
}
// 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)
{
Class rbc;
ResourceBundle needs_parent = null, r, result = null;
while (true)
{
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);
}
}
}
// 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;
}
public static final ResourceBundle getBundle (String baseName,
Locale locale)
{
return getBundle (baseName, locale, ClassLoader.getSystemClassLoader ());
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);
}
public static final ResourceBundle getBundle (String baseName,
Locale locale,
ClassLoader loader)
/**
* 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());
}
/**
* 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, getClassContext()[1].getClassLoader());
}
/**
* 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)
{
{
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()))
// First look into the cache.
// XXX We should remove cleared references from the cache.
Reference ref = (Reference) cache.get(localizedName);
if (ref != null)
{
rb = partialGetBundle(baseName, Locale.getDefault(), true, loader);
ResourceBundle rb = (ResourceBundle) ref.get();
if (rb != null)
// rb should already have the right parent, except if
// something very strange happened.
return rb;
}
throw new MissingResourceException("can't load bundle",
baseName,
"bundle");
}
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;
}
/**
* 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)
{
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;
}
/**
* 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
{
// 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;
}
/**
* 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();
}

View File

@ -1,76 +1,236 @@
/* 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;
/* String to be parsed put into a char array for efficient access */
private char[] chArray;
/* Set of delimiter characters for separating tokens */
private String delimiters;
/* Whether delimiters in this instance are treated as tokens themselves */
private boolean returnDelimiters;
/* Index into the input string to start parsing for the next token */
private int inputStringIndex;
/*{
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", false);
this(str, " \t\n\r\f", false);
}
public StringTokenizer(String str, String delims)
/**
* 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, delims, false);
this(str, delim, false);
}
public StringTokenizer(String str, String delims, boolean retDelim)
/**
* 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"; } } */
{
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);
this.str = str;
this.delim = delim;
this.retDelims = returnDelims;
this.pos = 0;
}
/**
* 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();
}
/**
* 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();
}
/**
* 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; } } */
{
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();
}
/**
* 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()
{
return hasMoreTokens();
}
/**
* 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
{
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)
{
@ -86,8 +246,9 @@ public class StringTokenizer implements Enumeration
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;
}
}
@ -96,90 +257,6 @@ public class StringTokenizer implements Enumeration
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;
}
}

View File

@ -1,32 +1,67 @@
/* 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);
}
}

View File

@ -0,0 +1,31 @@
// 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);
}