diff options
author | tromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-07-16 01:27:14 +0000 |
---|---|---|
committer | tromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-07-16 01:27:14 +0000 |
commit | a63c2657c94913d72b3cd388730d61edcb09fc69 (patch) | |
tree | 8762d1f992e2f725a6bde1ff966ed6f1e5f4f823 /libjava/java/util | |
parent | 6484dceb0094998183c2f8d3c8c27c6f4e53b8a9 (diff) | |
download | gcc-a63c2657c94913d72b3cd388730d61edcb09fc69.tar.gz |
Major merge with Classpath.
Removed many duplicate files.
* HACKING: Updated.x
* classpath: Imported new directory.
* standard.omit: New file.
* Makefile.in, aclocal.m4, configure: Rebuilt.
* sources.am: New file.
* configure.ac: Run Classpath configure script. Moved code around
to support. Disable xlib AWT peers (temporarily).
* Makefile.am (SUBDIRS): Added 'classpath'
(JAVAC): Removed.
(AM_CPPFLAGS): Added more -I options.
(BOOTCLASSPATH): Simplified.
Completely redid how sources are built.
Include sources.am.
* include/Makefile.am (tool_include__HEADERS): Removed jni.h.
* include/jni.h: Removed (in Classpath).
* scripts/classes.pl: Updated to look at built classes.
* scripts/makemake.tcl: New file.
* testsuite/libjava.jni/jni.exp (gcj_jni_compile_c_to_so): Added
-I options.
(gcj_jni_invocation_compile_c_to_binary): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@102082 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/java/util')
96 files changed, 0 insertions, 40379 deletions
diff --git a/libjava/java/util/AbstractCollection.java b/libjava/java/util/AbstractCollection.java deleted file mode 100644 index 00ee23ebd43..00000000000 --- a/libjava/java/util/AbstractCollection.java +++ /dev/null @@ -1,470 +0,0 @@ -/* AbstractCollection.java -- Abstract implementation of most of Collection - Copyright (C) 1998, 2000, 2001, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -import java.lang.reflect.Array; - -/** - * A basic implementation of most of the methods in the Collection interface to - * make it easier to create a collection. To create an unmodifiable Collection, - * just subclass AbstractCollection and provide implementations of the - * iterator() and size() methods. The Iterator returned by iterator() need only - * provide implementations of hasNext() and next() (that is, it may throw an - * UnsupportedOperationException if remove() is called). To create a modifiable - * Collection, you must in addition provide an implementation of the - * add(Object) method and the Iterator returned by iterator() must provide an - * implementation of remove(). Other methods should be overridden if the - * backing data structure allows for a more efficient implementation. The - * precise implementation used by AbstractCollection is documented, so that - * subclasses can tell which methods could be implemented more efficiently. - * <p> - * - * The programmer should provide a no-argument constructor, and one that - * accepts another Collection, as recommended by the Collection interface. - * Unfortunately, there is no way to enforce this in Java. - * - * @author Original author unknown - * @author Bryce McKinlay - * @author Eric Blake (ebb9@email.byu.edu) - * @see Collection - * @see AbstractSet - * @see AbstractList - * @since 1.2 - * @status updated to 1.4 - */ -public abstract class AbstractCollection implements Collection -{ - /** - * The main constructor, for use by subclasses. - */ - protected AbstractCollection() - { - } - - /** - * Return an Iterator over this collection. The iterator must provide the - * hasNext and next methods and should in addition provide remove if the - * collection is modifiable. - * - * @return an iterator - */ - public abstract Iterator iterator(); - - /** - * Return the number of elements in this collection. If there are more than - * Integer.MAX_VALUE elements, return Integer.MAX_VALUE. - * - * @return the size - */ - public abstract int size(); - - /** - * Add an object to the collection (optional operation). This implementation - * always throws an UnsupportedOperationException - it should be - * overridden if the collection is to be modifiable. If the collection - * does not accept duplicates, simply return false. Collections may specify - * limitations on what may be added. - * - * @param o the object to add - * @return true if the add operation caused the Collection to change - * @throws UnsupportedOperationException if the add operation is not - * supported on this collection - * @throws NullPointerException if the collection does not support null - * @throws ClassCastException if the object is of the wrong type - * @throws IllegalArgumentException if some aspect of the object prevents - * it from being added - */ - public boolean add(Object o) - { - throw new UnsupportedOperationException(); - } - - /** - * Add all the elements of a given collection to this collection (optional - * operation). This implementation obtains an Iterator over the given - * collection and iterates over it, adding each element with the - * add(Object) method (thus this method will fail with an - * UnsupportedOperationException if the add method does). The behavior is - * unspecified if the specified collection is modified during the iteration, - * including the special case of trying addAll(this) on a non-empty - * collection. - * - * @param c the collection to add the elements of to this collection - * @return true if the add operation caused the Collection to change - * @throws UnsupportedOperationException if the add operation is not - * supported on this collection - * @throws NullPointerException if the specified collection is null - * @throws ClassCastException if the type of any element in c is - * not a valid type for addition. - * @throws IllegalArgumentException if some aspect of any element - * in c prevents it being added. - * @throws NullPointerException if any element in c is null and this - * collection doesn't allow null values. - * @see #add(Object) - */ - public boolean addAll(Collection c) - { - Iterator itr = c.iterator(); - boolean modified = false; - int pos = c.size(); - while (--pos >= 0) - modified |= add(itr.next()); - return modified; - } - - /** - * Remove all elements from the collection (optional operation). This - * implementation obtains an iterator over the collection and calls next - * and remove on it repeatedly (thus this method will fail with an - * UnsupportedOperationException if the Iterator's remove method does) - * until there are no more elements to remove. - * Many implementations will have a faster way of doing this. - * - * @throws UnsupportedOperationException if the Iterator returned by - * iterator does not provide an implementation of remove - * @see Iterator#remove() - */ - public void clear() - { - Iterator itr = iterator(); - int pos = size(); - while (--pos >= 0) - { - itr.next(); - itr.remove(); - } - } - - /** - * Test whether this collection contains a given object. That is, if the - * collection has an element e such that (o == null ? e == null : - * o.equals(e)). This implementation obtains an iterator over the collection - * and iterates over it, testing each element for equality with the given - * object. If it is equal, true is returned. Otherwise false is returned when - * the end of the collection is reached. - * - * @param o the object to remove from this collection - * @return true if this collection contains an object equal to o - */ - public boolean contains(Object o) - { - Iterator itr = iterator(); - int pos = size(); - while (--pos >= 0) - if (equals(o, itr.next())) - return true; - return false; - } - - /** - * Tests whether this collection contains all the elements in a given - * collection. This implementation iterates over the given collection, - * testing whether each element is contained in this collection. If any one - * is not, false is returned. Otherwise true is returned. - * - * @param c the collection to test against - * @return true if this collection contains all the elements in the given - * collection - * @throws NullPointerException if the given collection is null - * @see #contains(Object) - */ - public boolean containsAll(Collection c) - { - Iterator itr = c.iterator(); - int pos = c.size(); - while (--pos >= 0) - if (!contains(itr.next())) - return false; - return true; - } - - /** - * Test whether this collection is empty. This implementation returns - * size() == 0. - * - * @return true if this collection is empty. - * @see #size() - */ - public boolean isEmpty() - { - return size() == 0; - } - - /** - * Remove a single instance of an object from this collection (optional - * operation). That is, remove one element e such that - * <code>(o == null ? e == null : o.equals(e))</code>, if such an element - * exists. This implementation obtains an iterator over the collection - * and iterates over it, testing each element for equality with the given - * object. If it is equal, it is removed by the iterator's remove method - * (thus this method will fail with an UnsupportedOperationException if - * the Iterator's remove method does). After the first element has been - * removed, true is returned; if the end of the collection is reached, false - * is returned. - * - * @param o the object to remove from this collection - * @return true if the remove operation caused the Collection to change, or - * equivalently if the collection did contain o. - * @throws UnsupportedOperationException if this collection's Iterator - * does not support the remove method - * @see Iterator#remove() - */ - public boolean remove(Object o) - { - Iterator itr = iterator(); - int pos = size(); - while (--pos >= 0) - if (equals(o, itr.next())) - { - itr.remove(); - return true; - } - return false; - } - - /** - * Remove from this collection all its elements that are contained in a given - * collection (optional operation). This implementation iterates over this - * collection, and for each element tests if it is contained in the given - * collection. If so, it is removed by the Iterator's remove method (thus - * this method will fail with an UnsupportedOperationException if the - * Iterator's remove method does). - * - * @param c the collection to remove the elements of - * @return true if the remove operation caused the Collection to change - * @throws UnsupportedOperationException if this collection's Iterator - * does not support the remove method - * @throws NullPointerException if the collection, c, is null. - * @see Iterator#remove() - */ - public boolean removeAll(Collection c) - { - return removeAllInternal(c); - } - - /** - * Remove from this collection all its elements that are contained in a given - * collection (optional operation). This implementation iterates over this - * collection, and for each element tests if it is contained in the given - * collection. If so, it is removed by the Iterator's remove method (thus - * this method will fail with an UnsupportedOperationException if the - * Iterator's remove method does). This method is necessary for ArrayList, - * which cannot publicly override removeAll but can optimize this call. - * - * @param c the collection to remove the elements of - * @return true if the remove operation caused the Collection to change - * @throws UnsupportedOperationException if this collection's Iterator - * does not support the remove method - * @throws NullPointerException if the collection, c, is null. - * @see Iterator#remove() - */ - // Package visible for use throughout java.util. - boolean removeAllInternal(Collection c) - { - Iterator itr = iterator(); - boolean modified = false; - int pos = size(); - while (--pos >= 0) - if (c.contains(itr.next())) - { - itr.remove(); - modified = true; - } - return modified; - } - - /** - * Remove from this collection all its elements that are not contained in a - * given collection (optional operation). This implementation iterates over - * this collection, and for each element tests if it is contained in the - * given collection. If not, it is removed by the Iterator's remove method - * (thus this method will fail with an UnsupportedOperationException if - * the Iterator's remove method does). - * - * @param c the collection to retain the elements of - * @return true if the remove operation caused the Collection to change - * @throws UnsupportedOperationException if this collection's Iterator - * does not support the remove method - * @throws NullPointerException if the collection, c, is null. - * @see Iterator#remove() - */ - public boolean retainAll(Collection c) - { - return retainAllInternal(c); - } - - /** - * Remove from this collection all its elements that are not contained in a - * given collection (optional operation). This implementation iterates over - * this collection, and for each element tests if it is contained in the - * given collection. If not, it is removed by the Iterator's remove method - * (thus this method will fail with an UnsupportedOperationException if - * the Iterator's remove method does). This method is necessary for - * ArrayList, which cannot publicly override retainAll but can optimize - * this call. - * - * @param c the collection to retain the elements of - * @return true if the remove operation caused the Collection to change - * @throws UnsupportedOperationException if this collection's Iterator - * does not support the remove method - * @throws NullPointerException if the collection, c, is null. - * @see Iterator#remove() - */ - // Package visible for use throughout java.util. - boolean retainAllInternal(Collection c) - { - Iterator itr = iterator(); - boolean modified = false; - int pos = size(); - while (--pos >= 0) - if (!c.contains(itr.next())) - { - itr.remove(); - modified = true; - } - return modified; - } - - /** - * Return an array containing the elements of this collection. This - * implementation creates an Object array of size size() and then iterates - * over the collection, setting each element of the array from the value - * returned by the iterator. The returned array is safe, and is not backed - * by the collection. - * - * @return an array containing the elements of this collection - */ - public Object[] toArray() - { - Iterator itr = iterator(); - int size = size(); - Object[] a = new Object[size]; - for (int pos = 0; pos < size; pos++) - a[pos] = itr.next(); - return a; - } - - /** - * Copy the collection into a given array if it will fit, or into a - * dynamically created array of the same run-time type as the given array if - * not. If there is space remaining in the array, the first element after the - * end of the collection is set to null (this is only useful if the - * collection is known to contain no null elements, however). This - * implementation first tests whether the given array is large enough to hold - * all the elements of the collection. If not, the reflection API is used to - * allocate a new array of the same run-time type. Next an iterator is - * obtained over the collection and the elements are placed in the array as - * they are returned by the iterator. Finally the first spare element, if - * any, of the array is set to null, and the created array is returned. - * The returned array is safe; it is not backed by the collection. Note that - * null may not mark the last element, if the collection allows null - * elements. - * - * @param a the array to copy into, or of the correct run-time type - * @return the array that was produced - * @throws NullPointerException if the given array is null - * @throws ArrayStoreException if the type of the array precludes holding - * one of the elements of the Collection - */ - public Object[] toArray(Object[] a) - { - int size = size(); - if (a.length < size) - a = (Object[]) Array.newInstance(a.getClass().getComponentType(), - size); - else if (a.length > size) - a[size] = null; - - Iterator itr = iterator(); - for (int pos = 0; pos < size; pos++) - a[pos] = itr.next(); - - return a; - } - - /** - * Creates a String representation of the Collection. The string returned is - * of the form "[a, b, ...]" where a and b etc are the results of calling - * toString on the elements of the collection. This implementation obtains an - * Iterator over the Collection and adds each element to a StringBuffer as it - * is returned by the iterator. - * - * @return a String representation of the Collection - */ - public String toString() - { - Iterator itr = iterator(); - StringBuffer r = new StringBuffer("["); - for (int pos = size(); pos > 0; pos--) - { - r.append(itr.next()); - if (pos > 1) - r.append(", "); - } - r.append("]"); - return r.toString(); - } - - /** - * Compare two objects according to Collection semantics. - * - * @param o1 the first object - * @param o2 the second object - * @return o1 == null ? o2 == null : o1.equals(o2) - */ - // Package visible for use throughout java.util. - // It may be inlined since it is final. - static final boolean equals(Object o1, Object o2) - { - return o1 == null ? o2 == null : o1.equals(o2); - } - - /** - * Hash an object according to Collection semantics. - * - * @param o the object to hash - * @return o1 == null ? 0 : o1.hashCode() - */ - // Package visible for use throughout java.util. - // It may be inlined since it is final. - static final int hashCode(Object o) - { - return o == null ? 0 : o.hashCode(); - } -} diff --git a/libjava/java/util/AbstractList.java b/libjava/java/util/AbstractList.java deleted file mode 100644 index 8a9b6f10d7a..00000000000 --- a/libjava/java/util/AbstractList.java +++ /dev/null @@ -1,1225 +0,0 @@ -/* AbstractList.java -- Abstract implementation of most of List - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -/** - * A basic implementation of most of the methods in the List interface to make - * it easier to create a List based on a random-access data structure. If - * the list is sequential (such as a linked list), use AbstractSequentialList. - * To create an unmodifiable list, it is only necessary to override the - * size() and get(int) methods (this contrasts with all other abstract - * collection classes which require an iterator to be provided). To make the - * list modifiable, the set(int, Object) method should also be overridden, and - * to make the list resizable, the add(int, Object) and remove(int) methods - * should be overridden too. Other methods should be overridden if the - * backing data structure allows for a more efficient implementation. - * The precise implementation used by AbstractList is documented, so that - * subclasses can tell which methods could be implemented more efficiently. - * <p> - * - * As recommended by Collection and List, the subclass should provide at - * least a no-argument and a Collection constructor. This class is not - * synchronized. - * - * @author Original author unknown - * @author Bryce McKinlay - * @author Eric Blake (ebb9@email.byu.edu) - * @see Collection - * @see List - * @see AbstractSequentialList - * @see AbstractCollection - * @see ListIterator - * @since 1.2 - * @status updated to 1.4 - */ -public abstract class AbstractList extends AbstractCollection implements List -{ - /** - * A count of the number of structural modifications that have been made to - * the list (that is, insertions and removals). Structural modifications - * are ones which change the list size or affect how iterations would - * behave. This field is available for use by Iterator and ListIterator, - * in order to throw a {@link ConcurrentModificationException} in response - * to the next operation on the iterator. This <i>fail-fast</i> behavior - * saves the user from many subtle bugs otherwise possible from concurrent - * modification during iteration. - * <p> - * - * To make lists fail-fast, increment this field by just 1 in the - * <code>add(int, Object)</code> and <code>remove(int)</code> methods. - * Otherwise, this field may be ignored. - */ - protected transient int modCount; - - /** - * The main constructor, for use by subclasses. - */ - protected AbstractList() - { - } - - /** - * Returns the elements at the specified position in the list. - * - * @param index the element to return - * @return the element at that position - * @throws IndexOutOfBoundsException if index < 0 || index >= size() - */ - public abstract Object get(int index); - - /** - * Insert an element into the list at a given position (optional operation). - * This shifts all existing elements from that position to the end one - * index to the right. This version of add has no return, since it is - * assumed to always succeed if there is no exception. This implementation - * always throws UnsupportedOperationException, and must be overridden to - * make a modifiable List. If you want fail-fast iterators, be sure to - * increment modCount when overriding this. - * - * @param index the location to insert the item - * @param o the object to insert - * @throws UnsupportedOperationException if this list does not support the - * add operation - * @throws IndexOutOfBoundsException if index < 0 || index > size() - * @throws ClassCastException if o cannot be added to this list due to its - * type - * @throws IllegalArgumentException if o cannot be added to this list for - * some other reason - * @see #modCount - */ - public void add(int index, Object o) - { - throw new UnsupportedOperationException(); - } - - /** - * Add an element to the end of the list (optional operation). If the list - * imposes restraints on what can be inserted, such as no null elements, - * this should be documented. This implementation calls - * <code>add(size(), o);</code>, and will fail if that version does. - * - * @param o the object to add - * @return true, as defined by Collection for a modified list - * @throws UnsupportedOperationException if this list does not support the - * add operation - * @throws ClassCastException if o cannot be added to this list due to its - * type - * @throws IllegalArgumentException if o cannot be added to this list for - * some other reason - * @see #add(int, Object) - */ - public boolean add(Object o) - { - add(size(), o); - return true; - } - - /** - * Insert the contents of a collection into the list at a given position - * (optional operation). Shift all elements at that position to the right - * by the number of elements inserted. This operation is undefined if - * this list is modified during the operation (for example, if you try - * to insert a list into itself). This implementation uses the iterator of - * the collection, repeatedly calling add(int, Object); this will fail - * if add does. This can often be made more efficient. - * - * @param index the location to insert the collection - * @param c the collection to insert - * @return true if the list was modified by this action, that is, if c is - * non-empty - * @throws UnsupportedOperationException if this list does not support the - * addAll operation - * @throws IndexOutOfBoundsException if index < 0 || index > size() - * @throws ClassCastException if some element of c cannot be added to this - * list due to its type - * @throws IllegalArgumentException if some element of c cannot be added - * to this list for some other reason - * @throws NullPointerException if the specified collection is null - * @see #add(int, Object) - */ - public boolean addAll(int index, Collection c) - { - Iterator itr = c.iterator(); - int size = c.size(); - for (int pos = size; pos > 0; pos--) - add(index++, itr.next()); - return size > 0; - } - - /** - * Clear the list, such that a subsequent call to isEmpty() would return - * true (optional operation). This implementation calls - * <code>removeRange(0, size())</code>, so it will fail unless remove - * or removeRange is overridden. - * - * @throws UnsupportedOperationException if this list does not support the - * clear operation - * @see #remove(int) - * @see #removeRange(int, int) - */ - public void clear() - { - removeRange(0, size()); - } - - /** - * Test whether this list is equal to another object. A List is defined to be - * equal to an object if and only if that object is also a List, and the two - * lists have the same sequence. Two lists l1 and l2 are equal if and only - * if <code>l1.size() == l2.size()</code>, and for every integer n between 0 - * and <code>l1.size() - 1</code> inclusive, <code>l1.get(n) == null ? - * l2.get(n) == null : l1.get(n).equals(l2.get(n))</code>. - * <p> - * - * This implementation returns true if the object is this, or false if the - * object is not a List. Otherwise, it iterates over both lists (with - * iterator()), returning false if two elements compare false or one list - * is shorter, and true if the iteration completes successfully. - * - * @param o the object to test for equality with this list - * @return true if o is equal to this list - * @see Object#equals(Object) - * @see #hashCode() - */ - public boolean equals(Object o) - { - if (o == this) - return true; - if (! (o instanceof List)) - return false; - int size = size(); - if (size != ((List) o).size()) - return false; - - Iterator itr1 = iterator(); - Iterator itr2 = ((List) o).iterator(); - - while (--size >= 0) - if (! equals(itr1.next(), itr2.next())) - return false; - return true; - } - - /** - * Obtains a hash code for this list. In order to obey the general - * contract of the hashCode method of class Object, this value is - * calculated as follows: - * -<pre>hashCode = 1; -Iterator i = list.iterator(); -while (i.hasNext()) -{ - Object obj = i.next(); - hashCode = 31 * hashCode + (obj == null ? 0 : obj.hashCode()); -}</pre> - * - * This ensures that the general contract of Object.hashCode() is adhered to. - * - * @return the hash code of this list - * - * @see Object#hashCode() - * @see #equals(Object) - */ - public int hashCode() - { - int hashCode = 1; - Iterator itr = iterator(); - int pos = size(); - while (--pos >= 0) - hashCode = 31 * hashCode + hashCode(itr.next()); - return hashCode; - } - - /** - * Obtain the first index at which a given object is to be found in this - * list. This implementation follows a listIterator() until a match is found, - * or returns -1 if the list end is reached. - * - * @param o the object to search for - * @return the least integer n such that <code>o == null ? get(n) == null : - * o.equals(get(n))</code>, or -1 if there is no such index - */ - public int indexOf(Object o) - { - ListIterator itr = listIterator(); - int size = size(); - for (int pos = 0; pos < size; pos++) - if (equals(o, itr.next())) - return pos; - return -1; - } - - /** - * Obtain an Iterator over this list, whose sequence is the list order. - * This implementation uses size(), get(int), and remove(int) of the - * backing list, and does not support remove unless the list does. This - * implementation is fail-fast if you correctly maintain modCount. - * Also, this implementation is specified by Sun to be distinct from - * listIterator, although you could easily implement it as - * <code>return listIterator(0)</code>. - * - * @return an Iterator over the elements of this list, in order - * @see #modCount - */ - public Iterator iterator() - { - // Bah, Sun's implementation forbids using listIterator(0). - return new Iterator() - { - private int pos = 0; - private int size = size(); - private int last = -1; - private int knownMod = modCount; - - // This will get inlined, since it is private. - /** - * Checks for modifications made to the list from - * elsewhere while iteration is in progress. - * - * @throws ConcurrentModificationException if the - * list has been modified elsewhere. - */ - private void checkMod() - { - if (knownMod != modCount) - throw new ConcurrentModificationException(); - } - - /** - * Tests to see if there are any more objects to - * return. - * - * @return True if the end of the list has not yet been - * reached. - * @throws ConcurrentModificationException if the - * list has been modified elsewhere. - */ - public boolean hasNext() - { - checkMod(); - return pos < size; - } - - /** - * Retrieves the next object from the list. - * - * @return The next object. - * @throws NoSuchElementException if there are - * no more objects to retrieve. - * @throws ConcurrentModificationException if the - * list has been modified elsewhere. - */ - public Object next() - { - checkMod(); - if (pos == size) - throw new NoSuchElementException(); - last = pos; - return get(pos++); - } - - /** - * Removes the last object retrieved by <code>next()</code> - * from the list, if the list supports object removal. - * - * @throws ConcurrentModificationException if the list - * has been modified elsewhere. - * @throws IllegalStateException if the iterator is positioned - * before the start of the list or the last object has already - * been removed. - * @throws UnsupportedOperationException if the list does - * not support removing elements. - */ - public void remove() - { - checkMod(); - if (last < 0) - throw new IllegalStateException(); - AbstractList.this.remove(last); - pos--; - size--; - last = -1; - knownMod = modCount; - } - }; - } - - /** - * Obtain the last index at which a given object is to be found in this - * list. This implementation grabs listIterator(size()), then searches - * backwards for a match or returns -1. - * - * @return the greatest integer n such that <code>o == null ? get(n) == null - * : o.equals(get(n))</code>, or -1 if there is no such index - */ - public int lastIndexOf(Object o) - { - int pos = size(); - ListIterator itr = listIterator(pos); - while (--pos >= 0) - if (equals(o, itr.previous())) - return pos; - return -1; - } - - /** - * Obtain a ListIterator over this list, starting at the beginning. This - * implementation returns listIterator(0). - * - * @return a ListIterator over the elements of this list, in order, starting - * at the beginning - */ - public ListIterator listIterator() - { - return listIterator(0); - } - - /** - * Obtain a ListIterator over this list, starting at a given position. - * A first call to next() would return the same as get(index), and a - * first call to previous() would return the same as get(index - 1). - * <p> - * - * This implementation uses size(), get(int), set(int, Object), - * add(int, Object), and remove(int) of the backing list, and does not - * support remove, set, or add unless the list does. This implementation - * is fail-fast if you correctly maintain modCount. - * - * @param index the position, between 0 and size() inclusive, to begin the - * iteration from - * @return a ListIterator over the elements of this list, in order, starting - * at index - * @throws IndexOutOfBoundsException if index < 0 || index > size() - * @see #modCount - */ - public ListIterator listIterator(final int index) - { - if (index < 0 || index > size()) - throw new IndexOutOfBoundsException("Index: " + index + ", Size:" - + size()); - - return new ListIterator() - { - private int knownMod = modCount; - private int position = index; - private int lastReturned = -1; - private int size = size(); - - // This will get inlined, since it is private. - /** - * Checks for modifications made to the list from - * elsewhere while iteration is in progress. - * - * @throws ConcurrentModificationException if the - * list has been modified elsewhere. - */ - private void checkMod() - { - if (knownMod != modCount) - throw new ConcurrentModificationException(); - } - - /** - * Tests to see if there are any more objects to - * return. - * - * @return True if the end of the list has not yet been - * reached. - * @throws ConcurrentModificationException if the - * list has been modified elsewhere. - */ - public boolean hasNext() - { - checkMod(); - return position < size; - } - - /** - * Tests to see if there are objects prior to the - * current position in the list. - * - * @return True if objects exist prior to the current - * position of the iterator. - * @throws ConcurrentModificationException if the - * list has been modified elsewhere. - */ - public boolean hasPrevious() - { - checkMod(); - return position > 0; - } - - /** - * Retrieves the next object from the list. - * - * @return The next object. - * @throws NoSuchElementException if there are no - * more objects to retrieve. - * @throws ConcurrentModificationException if the - * list has been modified elsewhere. - */ - public Object next() - { - checkMod(); - if (position == size) - throw new NoSuchElementException(); - lastReturned = position; - return get(position++); - } - - /** - * Retrieves the previous object from the list. - * - * @return The next object. - * @throws NoSuchElementException if there are no - * previous objects to retrieve. - * @throws ConcurrentModificationException if the - * list has been modified elsewhere. - */ - public Object previous() - { - checkMod(); - if (position == 0) - throw new NoSuchElementException(); - lastReturned = --position; - return get(lastReturned); - } - - /** - * Returns the index of the next element in the - * list, which will be retrieved by <code>next()</code> - * - * @return The index of the next element. - * @throws ConcurrentModificationException if the list - * has been modified elsewhere. - */ - public int nextIndex() - { - checkMod(); - return position; - } - - /** - * Returns the index of the previous element in the - * list, which will be retrieved by <code>previous()</code> - * - * @return The index of the previous element. - * @throws ConcurrentModificationException if the list - * has been modified elsewhere. - */ - public int previousIndex() - { - checkMod(); - return position - 1; - } - - /** - * Removes the last object retrieved by <code>next()</code> - * or <code>previous()</code> from the list, if the list - * supports object removal. - * - * @throws IllegalStateException if the iterator is positioned - * before the start of the list or the last object has already - * been removed. - * @throws UnsupportedOperationException if the list does - * not support removing elements. - * @throws ConcurrentModificationException if the list - * has been modified elsewhere. - */ - public void remove() - { - checkMod(); - if (lastReturned < 0) - throw new IllegalStateException(); - AbstractList.this.remove(lastReturned); - size--; - position = lastReturned; - lastReturned = -1; - knownMod = modCount; - } - - /** - * Replaces the last object retrieved by <code>next()</code> - * or <code>previous</code> with o, if the list supports object - * replacement and an add or remove operation has not already - * been performed. - * - * @throws IllegalStateException if the iterator is positioned - * before the start of the list or the last object has already - * been removed. - * @throws UnsupportedOperationException if the list doesn't support - * the addition or removal of elements. - * @throws ClassCastException if the type of o is not a valid type - * for this list. - * @throws IllegalArgumentException if something else related to o - * prevents its addition. - * @throws ConcurrentModificationException if the list - * has been modified elsewhere. - */ - public void set(Object o) - { - checkMod(); - if (lastReturned < 0) - throw new IllegalStateException(); - AbstractList.this.set(lastReturned, o); - } - - /** - * Adds the supplied object before the element that would be returned - * by a call to <code>next()</code>, if the list supports addition. - * - * @param o The object to add to the list. - * @throws UnsupportedOperationException if the list doesn't support - * the addition of new elements. - * @throws ClassCastException if the type of o is not a valid type - * for this list. - * @throws IllegalArgumentException if something else related to o - * prevents its addition. - * @throws ConcurrentModificationException if the list - * has been modified elsewhere. - */ - public void add(Object o) - { - checkMod(); - AbstractList.this.add(position++, o); - size++; - lastReturned = -1; - knownMod = modCount; - } - }; - } - - /** - * Remove the element at a given position in this list (optional operation). - * Shifts all remaining elements to the left to fill the gap. This - * implementation always throws an UnsupportedOperationException. - * If you want fail-fast iterators, be sure to increment modCount when - * overriding this. - * - * @param index the position within the list of the object to remove - * @return the object that was removed - * @throws UnsupportedOperationException if this list does not support the - * remove operation - * @throws IndexOutOfBoundsException if index < 0 || index >= size() - * @see #modCount - */ - public Object remove(int index) - { - throw new UnsupportedOperationException(); - } - - /** - * Remove a subsection of the list. This is called by the clear and - * removeRange methods of the class which implements subList, which are - * difficult for subclasses to override directly. Therefore, this method - * should be overridden instead by the more efficient implementation, if one - * exists. Overriding this can reduce quadratic efforts to constant time - * in some cases! - * <p> - * - * This implementation first checks for illegal or out of range arguments. It - * then obtains a ListIterator over the list using listIterator(fromIndex). - * It then calls next() and remove() on this iterator repeatedly, toIndex - - * fromIndex times. - * - * @param fromIndex the index, inclusive, to remove from. - * @param toIndex the index, exclusive, to remove to. - * @throws UnsupportedOperationException if the list does - * not support removing elements. - */ - protected void removeRange(int fromIndex, int toIndex) - { - ListIterator itr = listIterator(fromIndex); - for (int index = fromIndex; index < toIndex; index++) - { - itr.next(); - itr.remove(); - } - } - - /** - * Replace an element of this list with another object (optional operation). - * This implementation always throws an UnsupportedOperationException. - * - * @param index the position within this list of the element to be replaced - * @param o the object to replace it with - * @return the object that was replaced - * @throws UnsupportedOperationException if this list does not support the - * set operation - * @throws IndexOutOfBoundsException if index < 0 || index >= size() - * @throws ClassCastException if o cannot be added to this list due to its - * type - * @throws IllegalArgumentException if o cannot be added to this list for - * some other reason - */ - public Object set(int index, Object o) - { - throw new UnsupportedOperationException(); - } - - /** - * Obtain a List view of a subsection of this list, from fromIndex - * (inclusive) to toIndex (exclusive). If the two indices are equal, the - * sublist is empty. The returned list should be modifiable if and only - * if this list is modifiable. Changes to the returned list should be - * reflected in this list. If this list is structurally modified in - * any way other than through the returned list, the result of any subsequent - * operations on the returned list is undefined. - * <p> - * - * This implementation returns a subclass of AbstractList. It stores, in - * private fields, the offset and size of the sublist, and the expected - * modCount of the backing list. If the backing list implements RandomAccess, - * the sublist will also. - * <p> - * - * The subclass's <code>set(int, Object)</code>, <code>get(int)</code>, - * <code>add(int, Object)</code>, <code>remove(int)</code>, - * <code>addAll(int, Collection)</code> and - * <code>removeRange(int, int)</code> methods all delegate to the - * corresponding methods on the backing abstract list, after - * bounds-checking the index and adjusting for the offset. The - * <code>addAll(Collection c)</code> method merely returns addAll(size, c). - * The <code>listIterator(int)</code> method returns a "wrapper object" - * over a list iterator on the backing list, which is created with the - * corresponding method on the backing list. The <code>iterator()</code> - * method merely returns listIterator(), and the <code>size()</code> method - * merely returns the subclass's size field. - * <p> - * - * All methods first check to see if the actual modCount of the backing - * list is equal to its expected value, and throw a - * ConcurrentModificationException if it is not. - * - * @param fromIndex the index that the returned list should start from - * (inclusive) - * @param toIndex the index that the returned list should go to (exclusive) - * @return a List backed by a subsection of this list - * @throws IndexOutOfBoundsException if fromIndex < 0 - * || toIndex > size() - * @throws IllegalArgumentException if fromIndex > toIndex - * @see ConcurrentModificationException - * @see RandomAccess - */ - public List subList(int fromIndex, int toIndex) - { - // This follows the specification of AbstractList, but is inconsistent - // with the one in List. Don't you love Sun's inconsistencies? - if (fromIndex > toIndex) - throw new IllegalArgumentException(fromIndex + " > " + toIndex); - if (fromIndex < 0 || toIndex > size()) - throw new IndexOutOfBoundsException(); - - if (this instanceof RandomAccess) - return new RandomAccessSubList(this, fromIndex, toIndex); - return new SubList(this, fromIndex, toIndex); - } - - /** - * This class follows the implementation requirements set forth in - * {@link AbstractList#subList(int, int)}. It matches Sun's implementation - * by using a non-public top-level class in the same package. - * - * @author Original author unknown - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static class SubList extends AbstractList - { - // Package visible, for use by iterator. - /** The original list. */ - final AbstractList backingList; - /** The index of the first element of the sublist. */ - final int offset; - /** The size of the sublist. */ - int size; - - /** - * Construct the sublist. - * - * @param backing the list this comes from - * @param fromIndex the lower bound, inclusive - * @param toIndex the upper bound, exclusive - */ - SubList(AbstractList backing, int fromIndex, int toIndex) - { - backingList = backing; - modCount = backing.modCount; - offset = fromIndex; - size = toIndex - fromIndex; - } - - /** - * This method checks the two modCount fields to ensure that there has - * not been a concurrent modification, returning if all is okay. - * - * @throws ConcurrentModificationException if the backing list has been - * modified externally to this sublist - */ - // This can be inlined. Package visible, for use by iterator. - void checkMod() - { - if (modCount != backingList.modCount) - throw new ConcurrentModificationException(); - } - - /** - * This method checks that a value is between 0 and size (inclusive). If - * it is not, an exception is thrown. - * - * @param index the value to check - * @throws IndexOutOfBoundsException if index < 0 || index > size() - */ - // This will get inlined, since it is private. - private void checkBoundsInclusive(int index) - { - if (index < 0 || index > size) - throw new IndexOutOfBoundsException("Index: " + index + ", Size:" - + size); - } - - /** - * This method checks that a value is between 0 (inclusive) and size - * (exclusive). If it is not, an exception is thrown. - * - * @param index the value to check - * @throws IndexOutOfBoundsException if index < 0 || index >= size() - */ - // This will get inlined, since it is private. - private void checkBoundsExclusive(int index) - { - if (index < 0 || index >= size) - throw new IndexOutOfBoundsException("Index: " + index + ", Size:" - + size); - } - - /** - * Specified by AbstractList.subList to return the private field size. - * - * @return the sublist size - * @throws ConcurrentModificationException if the backing list has been - * modified externally to this sublist - */ - public int size() - { - checkMod(); - return size; - } - - /** - * Specified by AbstractList.subList to delegate to the backing list. - * - * @param index the location to modify - * @param o the new value - * @return the old value - * @throws ConcurrentModificationException if the backing list has been - * modified externally to this sublist - * @throws UnsupportedOperationException if the backing list does not - * support the set operation - * @throws IndexOutOfBoundsException if index < 0 || index >= size() - * @throws ClassCastException if o cannot be added to the backing list due - * to its type - * @throws IllegalArgumentException if o cannot be added to the backing list - * for some other reason - */ - public Object set(int index, Object o) - { - checkMod(); - checkBoundsExclusive(index); - return backingList.set(index + offset, o); - } - - /** - * Specified by AbstractList.subList to delegate to the backing list. - * - * @param index the location to get from - * @return the object at that location - * @throws ConcurrentModificationException if the backing list has been - * modified externally to this sublist - * @throws IndexOutOfBoundsException if index < 0 || index >= size() - */ - public Object get(int index) - { - checkMod(); - checkBoundsExclusive(index); - return backingList.get(index + offset); - } - - /** - * Specified by AbstractList.subList to delegate to the backing list. - * - * @param index the index to insert at - * @param o the object to add - * @throws ConcurrentModificationException if the backing list has been - * modified externally to this sublist - * @throws IndexOutOfBoundsException if index < 0 || index > size() - * @throws UnsupportedOperationException if the backing list does not - * support the add operation. - * @throws ClassCastException if o cannot be added to the backing list due - * to its type. - * @throws IllegalArgumentException if o cannot be added to the backing - * list for some other reason. - */ - public void add(int index, Object o) - { - checkMod(); - checkBoundsInclusive(index); - backingList.add(index + offset, o); - size++; - modCount = backingList.modCount; - } - - /** - * Specified by AbstractList.subList to delegate to the backing list. - * - * @param index the index to remove - * @return the removed object - * @throws ConcurrentModificationException if the backing list has been - * modified externally to this sublist - * @throws IndexOutOfBoundsException if index < 0 || index >= size() - * @throws UnsupportedOperationException if the backing list does not - * support the remove operation - */ - public Object remove(int index) - { - checkMod(); - checkBoundsExclusive(index); - Object o = backingList.remove(index + offset); - size--; - modCount = backingList.modCount; - return o; - } - - /** - * Specified by AbstractList.subList to delegate to the backing list. - * This does no bounds checking, as it assumes it will only be called - * by trusted code like clear() which has already checked the bounds. - * - * @param fromIndex the lower bound, inclusive - * @param toIndex the upper bound, exclusive - * @throws ConcurrentModificationException if the backing list has been - * modified externally to this sublist - * @throws UnsupportedOperationException if the backing list does - * not support removing elements. - */ - protected void removeRange(int fromIndex, int toIndex) - { - checkMod(); - - backingList.removeRange(offset + fromIndex, offset + toIndex); - size -= toIndex - fromIndex; - modCount = backingList.modCount; - } - - /** - * Specified by AbstractList.subList to delegate to the backing list. - * - * @param index the location to insert at - * @param c the collection to insert - * @return true if this list was modified, in other words, c is non-empty - * @throws ConcurrentModificationException if the backing list has been - * modified externally to this sublist - * @throws IndexOutOfBoundsException if index < 0 || index > size() - * @throws UnsupportedOperationException if this list does not support the - * addAll operation - * @throws ClassCastException if some element of c cannot be added to this - * list due to its type - * @throws IllegalArgumentException if some element of c cannot be added - * to this list for some other reason - * @throws NullPointerException if the specified collection is null - */ - public boolean addAll(int index, Collection c) - { - checkMod(); - checkBoundsInclusive(index); - int csize = c.size(); - boolean result = backingList.addAll(offset + index, c); - size += csize; - modCount = backingList.modCount; - return result; - } - - /** - * Specified by AbstractList.subList to return addAll(size, c). - * - * @param c the collection to insert - * @return true if this list was modified, in other words, c is non-empty - * @throws ConcurrentModificationException if the backing list has been - * modified externally to this sublist - * @throws UnsupportedOperationException if this list does not support the - * addAll operation - * @throws ClassCastException if some element of c cannot be added to this - * list due to its type - * @throws IllegalArgumentException if some element of c cannot be added - * to this list for some other reason - * @throws NullPointerException if the specified collection is null - */ - public boolean addAll(Collection c) - { - return addAll(size, c); - } - - /** - * Specified by AbstractList.subList to return listIterator(). - * - * @return an iterator over the sublist - */ - public Iterator iterator() - { - return listIterator(); - } - - /** - * Specified by AbstractList.subList to return a wrapper around the - * backing list's iterator. - * - * @param index the start location of the iterator - * @return a list iterator over the sublist - * @throws ConcurrentModificationException if the backing list has been - * modified externally to this sublist - * @throws IndexOutOfBoundsException if the value is out of range - */ - public ListIterator listIterator(final int index) - { - checkMod(); - checkBoundsInclusive(index); - - return new ListIterator() - { - private final ListIterator i = backingList.listIterator(index + offset); - private int position = index; - - /** - * Tests to see if there are any more objects to - * return. - * - * @return True if the end of the list has not yet been - * reached. - * @throws ConcurrentModificationException if the - * list has been modified elsewhere. - */ - public boolean hasNext() - { - checkMod(); - return position < size; - } - - /** - * Tests to see if there are objects prior to the - * current position in the list. - * - * @return True if objects exist prior to the current - * position of the iterator. - * @throws ConcurrentModificationException if the - * list has been modified elsewhere. - */ - public boolean hasPrevious() - { - checkMod(); - return position > 0; - } - - /** - * Retrieves the next object from the list. - * - * @return The next object. - * @throws NoSuchElementException if there are no - * more objects to retrieve. - * @throws ConcurrentModificationException if the - * list has been modified elsewhere. - */ - public Object next() - { - if (position == size) - throw new NoSuchElementException(); - position++; - return i.next(); - } - - /** - * Retrieves the previous object from the list. - * - * @return The next object. - * @throws NoSuchElementException if there are no - * previous objects to retrieve. - * @throws ConcurrentModificationException if the - * list has been modified elsewhere. - */ - public Object previous() - { - if (position == 0) - throw new NoSuchElementException(); - position--; - return i.previous(); - } - - /** - * Returns the index of the next element in the - * list, which will be retrieved by <code>next()</code> - * - * @return The index of the next element. - * @throws ConcurrentModificationException if the - * list has been modified elsewhere. - */ - public int nextIndex() - { - return i.nextIndex() - offset; - } - - /** - * Returns the index of the previous element in the - * list, which will be retrieved by <code>previous()</code> - * - * @return The index of the previous element. - * @throws ConcurrentModificationException if the - * list has been modified elsewhere. - */ - public int previousIndex() - { - return i.previousIndex() - offset; - } - - /** - * Removes the last object retrieved by <code>next()</code> - * from the list, if the list supports object removal. - * - * @throws IllegalStateException if the iterator is positioned - * before the start of the list or the last object has already - * been removed. - * @throws UnsupportedOperationException if the list does - * not support removing elements. - */ - public void remove() - { - i.remove(); - size--; - position = nextIndex(); - modCount = backingList.modCount; - } - - - /** - * Replaces the last object retrieved by <code>next()</code> - * or <code>previous</code> with o, if the list supports object - * replacement and an add or remove operation has not already - * been performed. - * - * @throws IllegalStateException if the iterator is positioned - * before the start of the list or the last object has already - * been removed. - * @throws UnsupportedOperationException if the list doesn't support - * the addition or removal of elements. - * @throws ClassCastException if the type of o is not a valid type - * for this list. - * @throws IllegalArgumentException if something else related to o - * prevents its addition. - * @throws ConcurrentModificationException if the list - * has been modified elsewhere. - */ - public void set(Object o) - { - i.set(o); - } - - /** - * Adds the supplied object before the element that would be returned - * by a call to <code>next()</code>, if the list supports addition. - * - * @param o The object to add to the list. - * @throws UnsupportedOperationException if the list doesn't support - * the addition of new elements. - * @throws ClassCastException if the type of o is not a valid type - * for this list. - * @throws IllegalArgumentException if something else related to o - * prevents its addition. - * @throws ConcurrentModificationException if the list - * has been modified elsewhere. - */ - public void add(Object o) - { - i.add(o); - size++; - position++; - modCount = backingList.modCount; - } - - // Here is the reason why the various modCount fields are mostly - // ignored in this wrapper listIterator. - // If the backing listIterator is failfast, then the following holds: - // Using any other method on this list will call a corresponding - // method on the backing list *after* the backing listIterator - // is created, which will in turn cause a ConcurrentModException - // when this listIterator comes to use the backing one. So it is - // implicitly failfast. - // If the backing listIterator is NOT failfast, then the whole of - // this list isn't failfast, because the modCount field of the - // backing list is not valid. It would still be *possible* to - // make the iterator failfast wrt modifications of the sublist - // only, but somewhat pointless when the list can be changed under - // us. - // Either way, no explicit handling of modCount is needed. - // However modCount = backingList.modCount must be executed in add - // and remove, and size must also be updated in these two methods, - // since they do not go through the corresponding methods of the subList. - }; - } - } // class SubList - - /** - * This class is a RandomAccess version of SubList, as required by - * {@link AbstractList#subList(int, int)}. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class RandomAccessSubList extends SubList - implements RandomAccess - { - /** - * Construct the sublist. - * - * @param backing the list this comes from - * @param fromIndex the lower bound, inclusive - * @param toIndex the upper bound, exclusive - */ - RandomAccessSubList(AbstractList backing, int fromIndex, int toIndex) - { - super(backing, fromIndex, toIndex); - } - } // class RandomAccessSubList - -} // class AbstractList diff --git a/libjava/java/util/AbstractMap.java b/libjava/java/util/AbstractMap.java deleted file mode 100644 index 7cd6436a308..00000000000 --- a/libjava/java/util/AbstractMap.java +++ /dev/null @@ -1,749 +0,0 @@ -/* AbstractMap.java -- Abstract implementation of most of Map - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -/** - * An abstract implementation of Map to make it easier to create your own - * implementations. In order to create an unmodifiable Map, subclass - * AbstractMap and implement the <code>entrySet</code> (usually via an - * AbstractSet). To make it modifiable, also implement <code>put</code>, - * and have <code>entrySet().iterator()</code> support <code>remove</code>. - * <p> - * - * It is recommended that classes which extend this support at least the - * no-argument constructor, and a constructor which accepts another Map. - * Further methods in this class may be overridden if you have a more - * efficient implementation. - * - * @author Original author unknown - * @author Bryce McKinlay - * @author Eric Blake (ebb9@email.byu.edu) - * @see Map - * @see Collection - * @see HashMap - * @see LinkedHashMap - * @see TreeMap - * @see WeakHashMap - * @see IdentityHashMap - * @since 1.2 - * @status updated to 1.4 - */ -public abstract class AbstractMap implements Map -{ - /** An "enum" of iterator types. */ - // Package visible for use by subclasses. - static final int KEYS = 0, - VALUES = 1, - ENTRIES = 2; - - /** - * The cache for {@link #keySet()}. - */ - // Package visible for use by subclasses. - Set keys; - - /** - * The cache for {@link #values()}. - */ - // Package visible for use by subclasses. - Collection values; - - /** - * The main constructor, for use by subclasses. - */ - protected AbstractMap() - { - } - - /** - * Returns a set view of the mappings in this Map. Each element in the - * set must be an implementation of Map.Entry. The set is backed by - * the map, so that changes in one show up in the other. Modifications - * made while an iterator is in progress cause undefined behavior. If - * the set supports removal, these methods must be valid: - * <code>Iterator.remove</code>, <code>Set.remove</code>, - * <code>removeAll</code>, <code>retainAll</code>, and <code>clear</code>. - * Element addition is not supported via this set. - * - * @return the entry set - * @see Map.Entry - */ - public abstract Set entrySet(); - - /** - * Remove all entries from this Map (optional operation). This default - * implementation calls entrySet().clear(). NOTE: If the entry set does - * not permit clearing, then this will fail, too. Subclasses often - * override this for efficiency. Your implementation of entrySet() should - * not call <code>AbstractMap.clear</code> unless you want an infinite loop. - * - * @throws UnsupportedOperationException if <code>entrySet().clear()</code> - * does not support clearing. - * @see Set#clear() - */ - public void clear() - { - entrySet().clear(); - } - - /** - * Create a shallow copy of this Map, no keys or values are copied. The - * default implementation simply calls <code>super.clone()</code>. - * - * @return the shallow clone - * @throws CloneNotSupportedException if a subclass is not Cloneable - * @see Cloneable - * @see Object#clone() - */ - protected Object clone() throws CloneNotSupportedException - { - AbstractMap copy = (AbstractMap) super.clone(); - // Clear out the caches; they are stale. - copy.keys = null; - copy.values = null; - return copy; - } - - /** - * Returns true if this contains a mapping for the given key. This - * implementation does a linear search, O(n), over the - * <code>entrySet()</code>, returning <code>true</code> if a match - * is found, <code>false</code> if the iteration ends. Many subclasses - * can implement this more efficiently. - * - * @param key the key to search for - * @return true if the map contains the key - * @throws NullPointerException if key is <code>null</code> but the map - * does not permit null keys - * @see #containsValue(Object) - */ - public boolean containsKey(Object key) - { - Iterator entries = entrySet().iterator(); - int pos = size(); - while (--pos >= 0) - if (equals(key, ((Map.Entry) entries.next()).getKey())) - return true; - return false; - } - - /** - * Returns true if this contains at least one mapping with the given value. - * This implementation does a linear search, O(n), over the - * <code>entrySet()</code>, returning <code>true</code> if a match - * is found, <code>false</code> if the iteration ends. A match is - * defined as a value, v, where <code>(value == null ? v == null : - * value.equals(v))</code>. Subclasses are unlikely to implement - * this more efficiently. - * - * @param value the value to search for - * @return true if the map contains the value - * @see #containsKey(Object) - */ - public boolean containsValue(Object value) - { - Iterator entries = entrySet().iterator(); - int pos = size(); - while (--pos >= 0) - if (equals(value, ((Map.Entry) entries.next()).getValue())) - return true; - return false; - } - - /** - * Compares the specified object with this map for equality. Returns - * <code>true</code> if the other object is a Map with the same mappings, - * that is,<br> - * <code>o instanceof Map && entrySet().equals(((Map) o).entrySet();</code> - * - * @param o the object to be compared - * @return true if the object equals this map - * @see Set#equals(Object) - */ - public boolean equals(Object o) - { - return (o == this || - (o instanceof Map && - entrySet().equals(((Map) o).entrySet()))); - } - - /** - * Returns the value mapped by the given key. Returns <code>null</code> if - * there is no mapping. However, in Maps that accept null values, you - * must rely on <code>containsKey</code> to determine if a mapping exists. - * This iteration takes linear time, searching entrySet().iterator() of - * the key. Many implementations override this method. - * - * @param key the key to look up - * @return the value associated with the key, or null if key not in map - * @throws NullPointerException if this map does not accept null keys - * @see #containsKey(Object) - */ - public Object get(Object key) - { - Iterator entries = entrySet().iterator(); - int pos = size(); - while (--pos >= 0) - { - Map.Entry entry = (Map.Entry) entries.next(); - if (equals(key, entry.getKey())) - return entry.getValue(); - } - return null; - } - - /** - * Returns the hash code for this map. As defined in Map, this is the sum - * of all hashcodes for each Map.Entry object in entrySet, or basically - * entrySet().hashCode(). - * - * @return the hash code - * @see Map.Entry#hashCode() - * @see Set#hashCode() - */ - public int hashCode() - { - return entrySet().hashCode(); - } - - /** - * Returns true if the map contains no mappings. This is implemented by - * <code>size() == 0</code>. - * - * @return true if the map is empty - * @see #size() - */ - public boolean isEmpty() - { - return size() == 0; - } - - /** - * Returns a set view of this map's keys. The set is backed by the map, - * so changes in one show up in the other. Modifications while an iteration - * is in progress produce undefined behavior. The set supports removal - * if entrySet() does, but does not support element addition. - * <p> - * - * This implementation creates an AbstractSet, where the iterator wraps - * the entrySet iterator, size defers to the Map's size, and contains - * defers to the Map's containsKey. The set is created on first use, and - * returned on subsequent uses, although since no synchronization occurs, - * there is a slight possibility of creating two sets. - * - * @return a Set view of the keys - * @see Set#iterator() - * @see #size() - * @see #containsKey(Object) - * @see #values() - */ - public Set keySet() - { - if (keys == null) - keys = new AbstractSet() - { - /** - * Retrieves the number of keys in the backing map. - * - * @return The number of keys. - */ - public int size() - { - return AbstractMap.this.size(); - } - - /** - * Returns true if the backing map contains the - * supplied key. - * - * @param key The key to search for. - * @return True if the key was found, false otherwise. - */ - public boolean contains(Object key) - { - return containsKey(key); - } - - /** - * Returns an iterator which iterates over the keys - * in the backing map, using a wrapper around the - * iterator returned by <code>entrySet()</code>. - * - * @return An iterator over the keys. - */ - public Iterator iterator() - { - return new Iterator() - { - /** - * The iterator returned by <code>entrySet()</code>. - */ - private final Iterator map_iterator = entrySet().iterator(); - - /** - * Returns true if a call to <code>next()</code> will - * return another key. - * - * @return True if the iterator has not yet reached - * the last key. - */ - public boolean hasNext() - { - return map_iterator.hasNext(); - } - - /** - * Returns the key from the next entry retrieved - * by the underlying <code>entrySet()</code> iterator. - * - * @return The next key. - */ - public Object next() - { - return ((Map.Entry) map_iterator.next()).getKey(); - } - - /** - * Removes the map entry which has a key equal - * to that returned by the last call to - * <code>next()</code>. - * - * @throws UnsupportedOperationException if the - * map doesn't support removal. - */ - public void remove() - { - map_iterator.remove(); - } - }; - } - }; - return keys; - } - - /** - * Associates the given key to the given value (optional operation). If the - * map already contains the key, its value is replaced. This implementation - * simply throws an UnsupportedOperationException. Be aware that in a map - * that permits <code>null</code> values, a null return does not always - * imply that the mapping was created. - * - * @param key the key to map - * @param value the value to be mapped - * @return the previous value of the key, or null if there was no mapping - * @throws UnsupportedOperationException if the operation is not supported - * @throws ClassCastException if the key or value is of the wrong type - * @throws IllegalArgumentException if something about this key or value - * prevents it from existing in this map - * @throws NullPointerException if the map forbids null keys or values - * @see #containsKey(Object) - */ - public Object put(Object key, Object value) - { - throw new UnsupportedOperationException(); - } - - /** - * Copies all entries of the given map to this one (optional operation). If - * the map already contains a key, its value is replaced. This implementation - * simply iterates over the map's entrySet(), calling <code>put</code>, - * so it is not supported if puts are not. - * - * @param m the mapping to load into this map - * @throws UnsupportedOperationException if the operation is not supported - * by this map. - * @throws ClassCastException if a key or value is of the wrong type for - * adding to this map. - * @throws IllegalArgumentException if something about a key or value - * prevents it from existing in this map. - * @throws NullPointerException if the map forbids null keys or values. - * @throws NullPointerException if <code>m</code> is null. - * @see #put(Object, Object) - */ - public void putAll(Map m) - { - Iterator entries = m.entrySet().iterator(); - int pos = m.size(); - while (--pos >= 0) - { - Map.Entry entry = (Map.Entry) entries.next(); - put(entry.getKey(), entry.getValue()); - } - } - - /** - * Removes the mapping for this key if present (optional operation). This - * implementation iterates over the entrySet searching for a matching - * key, at which point it calls the iterator's <code>remove</code> method. - * It returns the result of <code>getValue()</code> on the entry, if found, - * or null if no entry is found. Note that maps which permit null values - * may also return null if the key was removed. If the entrySet does not - * support removal, this will also fail. This is O(n), so many - * implementations override it for efficiency. - * - * @param key the key to remove - * @return the value the key mapped to, or null if not present. - * Null may also be returned if null values are allowed - * in the map and the value of this mapping is null. - * @throws UnsupportedOperationException if deletion is unsupported - * @see Iterator#remove() - */ - public Object remove(Object key) - { - Iterator entries = entrySet().iterator(); - int pos = size(); - while (--pos >= 0) - { - Map.Entry entry = (Map.Entry) entries.next(); - if (equals(key, entry.getKey())) - { - // Must get the value before we remove it from iterator. - Object r = entry.getValue(); - entries.remove(); - return r; - } - } - return null; - } - - /** - * Returns the number of key-value mappings in the map. If there are more - * than Integer.MAX_VALUE mappings, return Integer.MAX_VALUE. This is - * implemented as <code>entrySet().size()</code>. - * - * @return the number of mappings - * @see Set#size() - */ - public int size() - { - return entrySet().size(); - } - - /** - * Returns a String representation of this map. This is a listing of the - * map entries (which are specified in Map.Entry as being - * <code>getKey() + "=" + getValue()</code>), separated by a comma and - * space (", "), and surrounded by braces ('{' and '}'). This implementation - * uses a StringBuffer and iterates over the entrySet to build the String. - * Note that this can fail with an exception if underlying keys or - * values complete abruptly in toString(). - * - * @return a String representation - * @see Map.Entry#toString() - */ - public String toString() - { - Iterator entries = entrySet().iterator(); - StringBuffer r = new StringBuffer("{"); - for (int pos = size(); pos > 0; pos--) - { - Map.Entry entry = (Map.Entry) entries.next(); - r.append(entry.getKey()); - r.append('='); - r.append(entry.getValue()); - if (pos > 1) - r.append(", "); - } - r.append("}"); - return r.toString(); - } - - /** - * Returns a collection or bag view of this map's values. The collection - * is backed by the map, so changes in one show up in the other. - * Modifications while an iteration is in progress produce undefined - * behavior. The collection supports removal if entrySet() does, but - * does not support element addition. - * <p> - * - * This implementation creates an AbstractCollection, where the iterator - * wraps the entrySet iterator, size defers to the Map's size, and contains - * defers to the Map's containsValue. The collection is created on first - * use, and returned on subsequent uses, although since no synchronization - * occurs, there is a slight possibility of creating two collections. - * - * @return a Collection view of the values - * @see Collection#iterator() - * @see #size() - * @see #containsValue(Object) - * @see #keySet() - */ - public Collection values() - { - if (values == null) - values = new AbstractCollection() - { - /** - * Returns the number of values stored in - * the backing map. - * - * @return The number of values. - */ - public int size() - { - return AbstractMap.this.size(); - } - - /** - * Returns true if the backing map contains - * the supplied value. - * - * @param value The value to search for. - * @return True if the value was found, false otherwise. - */ - public boolean contains(Object value) - { - return containsValue(value); - } - - /** - * Returns an iterator which iterates over the - * values in the backing map, by using a wrapper - * around the iterator returned by <code>entrySet()</code>. - * - * @return An iterator over the values. - */ - public Iterator iterator() - { - return new Iterator() - { - /** - * The iterator returned by <code>entrySet()</code>. - */ - private final Iterator map_iterator = entrySet().iterator(); - - /** - * Returns true if a call to <code>next()</call> will - * return another value. - * - * @return True if the iterator has not yet reached - * the last value. - */ - public boolean hasNext() - { - return map_iterator.hasNext(); - } - - /** - * Returns the value from the next entry retrieved - * by the underlying <code>entrySet()</code> iterator. - * - * @return The next value. - */ - public Object next() - { - return ((Map.Entry) map_iterator.next()).getValue(); - } - - /** - * Removes the map entry which has a key equal - * to that returned by the last call to - * <code>next()</code>. - * - * @throws UnsupportedOperationException if the - * map doesn't support removal. - */ - public void remove() - { - map_iterator.remove(); - } - }; - } - }; - return values; - } - - /** - * Compare two objects according to Collection semantics. - * - * @param o1 the first object - * @param o2 the second object - * @return o1 == null ? o2 == null : o1.equals(o2) - */ - // Package visible for use throughout java.util. - // It may be inlined since it is final. - static final boolean equals(Object o1, Object o2) - { - return o1 == null ? o2 == null : o1.equals(o2); - } - - /** - * Hash an object according to Collection semantics. - * - * @param o the object to hash - * @return o1 == null ? 0 : o1.hashCode() - */ - // Package visible for use throughout java.util. - // It may be inlined since it is final. - static final int hashCode(Object o) - { - return o == null ? 0 : o.hashCode(); - } - - /** - * A class which implements Map.Entry. It is shared by HashMap, TreeMap, - * Hashtable, and Collections. It is not specified by the JDK, but makes - * life much easier. - * - * @author Jon Zeppieri - * @author Eric Blake (ebb9@email.byu.edu) - */ - // XXX - FIXME Use fully qualified implements as gcj 3.1 workaround. - // Bug still exists in 3.4.1 - static class BasicMapEntry implements Map.Entry - { - /** - * The key. Package visible for direct manipulation. - */ - Object key; - - /** - * The value. Package visible for direct manipulation. - */ - Object value; - - /** - * Basic constructor initializes the fields. - * @param newKey the key - * @param newValue the value - */ - BasicMapEntry(Object newKey, Object newValue) - { - key = newKey; - value = newValue; - } - - /** - * Compares the specified object with this entry. Returns true only if - * the object is a mapping of identical key and value. In other words, - * this must be:<br> - * <pre>(o instanceof Map.Entry) - * && (getKey() == null ? ((HashMap) o).getKey() == null - * : getKey().equals(((HashMap) o).getKey())) - * && (getValue() == null ? ((HashMap) o).getValue() == null - * : getValue().equals(((HashMap) o).getValue()))</pre> - * - * @param o the object to compare - * @return <code>true</code> if it is equal - */ - public final boolean equals(Object o) - { - if (! (o instanceof Map.Entry)) - return false; - // Optimize for our own entries. - if (o instanceof BasicMapEntry) - { - BasicMapEntry e = (BasicMapEntry) o; - return (AbstractMap.equals(key, e.key) - && AbstractMap.equals(value, e.value)); - } - Map.Entry e = (Map.Entry) o; - return (AbstractMap.equals(key, e.getKey()) - && AbstractMap.equals(value, e.getValue())); - } - - /** - * Get the key corresponding to this entry. - * - * @return the key - */ - public final Object getKey() - { - return key; - } - - /** - * Get the value corresponding to this entry. If you already called - * Iterator.remove(), the behavior undefined, but in this case it works. - * - * @return the value - */ - public final Object getValue() - { - return value; - } - - /** - * Returns the hash code of the entry. This is defined as the exclusive-or - * of the hashcodes of the key and value (using 0 for null). In other - * words, this must be:<br> - * <pre>(getKey() == null ? 0 : getKey().hashCode()) - * ^ (getValue() == null ? 0 : getValue().hashCode())</pre> - * - * @return the hash code - */ - public final int hashCode() - { - return (AbstractMap.hashCode(key) ^ AbstractMap.hashCode(value)); - } - - /** - * Replaces the value with the specified object. This writes through - * to the map, unless you have already called Iterator.remove(). It - * may be overridden to restrict a null value. - * - * @param newVal the new value to store - * @return the old value - * @throws NullPointerException if the map forbids null values. - * @throws UnsupportedOperationException if the map doesn't support - * <code>put()</code>. - * @throws ClassCastException if the value is of a type unsupported - * by the map. - * @throws IllegalArgumentException if something else about this - * value prevents it being stored in the map. - */ - public Object setValue(Object newVal) - { - Object r = value; - value = newVal; - return r; - } - - /** - * This provides a string representation of the entry. It is of the form - * "key=value", where string concatenation is used on key and value. - * - * @return the string representation - */ - public final String toString() - { - return key + "=" + value; - } - } // class BasicMapEntry -} diff --git a/libjava/java/util/AbstractSequentialList.java b/libjava/java/util/AbstractSequentialList.java deleted file mode 100644 index 79583228d96..00000000000 --- a/libjava/java/util/AbstractSequentialList.java +++ /dev/null @@ -1,235 +0,0 @@ -/* AbstractSequentialList.java -- List implementation for sequential access - Copyright (C) 1998, 1999, 2000, 2001, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -/** - * Abstract superclass to make it easier to implement the List interface when - * backed by a sequential-access store, such as a linked list. For random - * access data, use AbstractList. This class implements the random access - * methods (<code>get</code>, <code>set</code>, <code>add</code>, and - * <code>remove</code>) atop the list iterator, opposite of AbstractList's - * approach of implementing the iterator atop random access. - * <p> - * - * To implement a list, you need an implementation for <code>size()</code> - * and <code>listIterator</code>. With just <code>hasNext</code>, - * <code>next</code>, <code>hasPrevious</code>, <code>previous</code>, - * <code>nextIndex</code>, and <code>previousIndex</code>, you have an - * unmodifiable list. For a modifiable one, add <code>set</code>, and for - * a variable-size list, add <code>add</code> and <code>remove</code>. - * <p> - * - * The programmer should provide a no-argument constructor, and one that - * accepts another Collection, as recommended by the Collection interface. - * Unfortunately, there is no way to enforce this in Java. - * - * @author Original author unknown - * @author Bryce McKinlay - * @author Eric Blake (ebb9@email.byu.edu) - * @see Collection - * @see List - * @see AbstractList - * @see AbstractCollection - * @see ListIterator - * @see LinkedList - * @since 1.2 - * @status updated to 1.4 - */ -public abstract class AbstractSequentialList extends AbstractList -{ - /** - * The main constructor, for use by subclasses. - */ - protected AbstractSequentialList() - { - } - - /** - * Returns a ListIterator over the list, starting from position index. - * Subclasses must provide an implementation of this method. - * - * @param index the starting position of the list - * @return the list iterator - * @throws IndexOutOfBoundsException if index < 0 || index > size() - */ - public abstract ListIterator listIterator(int index); - - /** - * Insert an element into the list at a given position (optional operation). - * This shifts all existing elements from that position to the end one - * index to the right. This version of add has no return, since it is - * assumed to always succeed if there is no exception. This iteration - * uses listIterator(index).add(o). - * - * @param index the location to insert the item - * @param o the object to insert - * @throws UnsupportedOperationException if this list does not support the - * add operation - * @throws IndexOutOfBoundsException if index < 0 || index > size() - * @throws ClassCastException if o cannot be added to this list due to its - * type - * @throws IllegalArgumentException if o cannot be added to this list for - * some other reason. - * @throws NullPointerException if o is null and the list does not permit - * the addition of null values. - */ - public void add(int index, Object o) - { - listIterator(index).add(o); - } - - /** - * Insert the contents of a collection into the list at a given position - * (optional operation). Shift all elements at that position to the right - * by the number of elements inserted. This operation is undefined if - * this list is modified during the operation (for example, if you try - * to insert a list into itself). - * <p> - * - * This implementation grabs listIterator(index), then proceeds to use add - * for each element returned by c's iterator. Sun's online specs are wrong, - * claiming that this also calls next(): listIterator.add() correctly - * skips the added element. - * - * @param index the location to insert the collection - * @param c the collection to insert - * @return true if the list was modified by this action, that is, if c is - * non-empty - * @throws UnsupportedOperationException if this list does not support the - * addAll operation - * @throws IndexOutOfBoundsException if index < 0 || index > size() - * @throws ClassCastException if some element of c cannot be added to this - * list due to its type - * @throws IllegalArgumentException if some element of c cannot be added - * to this list for some other reason - * @throws NullPointerException if the specified collection is null - * @throws NullPointerException if an object, o, in c is null and the list - * does not permit the addition of null values. - * @see #add(int, Object) - */ - public boolean addAll(int index, Collection c) - { - Iterator ci = c.iterator(); - int size = c.size(); - ListIterator i = listIterator(index); - for (int pos = size; pos > 0; pos--) - i.add(ci.next()); - return size > 0; - } - - /** - * Get the element at a given index in this list. This implementation - * returns listIterator(index).next(). - * - * @param index the index of the element to be returned - * @return the element at index index in this list - * @throws IndexOutOfBoundsException if index < 0 || index >= size() - */ - public Object get(int index) - { - // This is a legal listIterator position, but an illegal get. - if (index == size()) - throw new IndexOutOfBoundsException("Index: " + index + ", Size:" - + size()); - return listIterator(index).next(); - } - - /** - * Obtain an Iterator over this list, whose sequence is the list order. This - * implementation returns listIterator(). - * - * @return an Iterator over the elements of this list, in order - */ - public Iterator iterator() - { - return listIterator(); - } - - /** - * Remove the element at a given position in this list (optional operation). - * Shifts all remaining elements to the left to fill the gap. This - * implementation uses listIterator(index) and ListIterator.remove(). - * - * @param index the position within the list of the object to remove - * @return the object that was removed - * @throws UnsupportedOperationException if this list does not support the - * remove operation - * @throws IndexOutOfBoundsException if index < 0 || index >= size() - */ - public Object remove(int index) - { - // This is a legal listIterator position, but an illegal remove. - if (index == size()) - throw new IndexOutOfBoundsException("Index: " + index + ", Size:" - + size()); - ListIterator i = listIterator(index); - Object removed = i.next(); - i.remove(); - return removed; - } - - /** - * Replace an element of this list with another object (optional operation). - * This implementation uses listIterator(index) and ListIterator.set(o). - * - * @param index the position within this list of the element to be replaced - * @param o the object to replace it with - * @return the object that was replaced - * @throws UnsupportedOperationException if this list does not support the - * set operation - * @throws IndexOutOfBoundsException if index < 0 || index >= size() - * @throws ClassCastException if o cannot be added to this list due to its - * type - * @throws IllegalArgumentException if o cannot be added to this list for - * some other reason - * @throws NullPointerException if o is null and the list does not allow - * a value to be set to null. - */ - public Object set(int index, Object o) - { - // This is a legal listIterator position, but an illegal set. - if (index == size()) - throw new IndexOutOfBoundsException("Index: " + index + ", Size:" - + size()); - ListIterator i = listIterator(index); - Object old = i.next(); - i.set(o); - return old; - } -} diff --git a/libjava/java/util/AbstractSet.java b/libjava/java/util/AbstractSet.java deleted file mode 100644 index f0d7cb19908..00000000000 --- a/libjava/java/util/AbstractSet.java +++ /dev/null @@ -1,139 +0,0 @@ -/* AbstractSet.java -- Abstract implementation of most of Set - Copyright (C) 1998, 2000, 2001, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -/** - * An abstract implementation of Set to make it easier to create your own - * implementations. In order to create a Set, subclass AbstractSet and - * implement the same methods that are required for AbstractCollection - * (although these methods must of course meet the requirements that Set puts - * on them - specifically, no element may be in the set more than once). This - * class simply provides implementations of equals() and hashCode() to fulfil - * the requirements placed on them by the Set interface. - * - * @author Original author unknown - * @author Eric Blake (ebb9@email.byu.edu) - * @see Collection - * @see AbstractCollection - * @see Set - * @see HashSet - * @see TreeSet - * @see LinkedHashSet - * @since 1.2 - * @status updated to 1.4 - */ -public abstract class AbstractSet extends AbstractCollection implements Set -{ - /** - * The main constructor, for use by subclasses. - */ - protected AbstractSet() - { - } - - /** - * Tests whether the given object is equal to this Set. This implementation - * first checks whether this set <em>is</em> the given object, and returns - * true if so. Otherwise, if o is a Set and is the same size as this one, it - * returns the result of calling containsAll on the given Set. Otherwise, it - * returns false. - * - * @param o the Object to be tested for equality with this Set - * @return true if the given object is equal to this Set - */ - public boolean equals(Object o) - { - return (o == this || - (o instanceof Set && ((Set) o).size() == size() - && containsAll((Collection) o))); - } - - /** - * Returns a hash code for this Set. The hash code of a Set is the sum of the - * hash codes of all its elements, except that the hash code of null is - * defined to be zero. This implementation obtains an Iterator over the Set, - * and sums the results. - * - * @return a hash code for this Set - */ - public int hashCode() - { - Iterator itr = iterator(); - int hash = 0; - int pos = size(); - while (--pos >= 0) - hash += hashCode(itr.next()); - return hash; - } - - /** - * Removes from this set all elements in the given collection (optional - * operation). This implementation uses <code>size()</code> to determine - * the smaller collection. Then, if this set is smaller, it iterates - * over the set, calling Iterator.remove if the collection contains - * the element. If this set is larger, it iterates over the collection, - * calling Set.remove for all elements in the collection. Note that - * this operation will fail if a remove methods is not supported. - * - * @param c the collection of elements to remove - * @return true if the set was modified as a result - * @throws UnsupportedOperationException if remove is not supported - * @throws NullPointerException if the collection is null - * @see AbstractCollection#remove(Object) - * @see Collection#contains(Object) - * @see Iterator#remove() - */ - public boolean removeAll(Collection c) - { - int oldsize = size(); - int count = c.size(); - Iterator i; - if (oldsize < count) - { - for (i = iterator(), count = oldsize; count > 0; count--) - if (c.contains(i.next())) - i.remove(); - } - else - for (i = c.iterator(); count > 0; count--) - remove(i.next()); - return oldsize != size(); - } - -} diff --git a/libjava/java/util/ArrayList.java b/libjava/java/util/ArrayList.java deleted file mode 100644 index 82bcca8c3e0..00000000000 --- a/libjava/java/util/ArrayList.java +++ /dev/null @@ -1,591 +0,0 @@ -/* ArrayList.java -- JDK1.2's answer to Vector; this is an array-backed - implementation of the List interface - Copyright (C) 1998, 1999, 2000, 2001, 2004, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.lang.reflect.Array; - -/** - * An array-backed implementation of the List interface. This implements - * all optional list operations, and permits null elements, so that it is - * better than Vector, which it replaces. Random access is roughly constant - * time, and iteration is roughly linear time, so it is nice and fast, with - * less overhead than a LinkedList. - * <p> - * - * Each list has a capacity, and as the array reaches that capacity it - * is automatically transferred to a larger array. You also have access to - * ensureCapacity and trimToSize to control the backing array's size, avoiding - * reallocation or wasted memory. - * <p> - * - * ArrayList is not synchronized, so if you need multi-threaded access, - * consider using:<br> - * <code>List l = Collections.synchronizedList(new ArrayList(...));</code> - * <p> - * - * The iterators are <i>fail-fast</i>, meaning that any structural - * modification, except for <code>remove()</code> called on the iterator - * itself, cause the iterator to throw a - * {@link ConcurrentModificationException} rather than exhibit - * non-deterministic behavior. - * - * @author Jon A. Zeppieri - * @author Bryce McKinlay - * @author Eric Blake (ebb9@email.byu.edu) - * @see Collection - * @see List - * @see LinkedList - * @see Vector - * @see Collections#synchronizedList(List) - * @see AbstractList - * @status updated to 1.4 - */ -public class ArrayList extends AbstractList - implements List, RandomAccess, Cloneable, Serializable -{ - /** - * Compatible with JDK 1.2 - */ - private static final long serialVersionUID = 8683452581122892189L; - - /** - * The default capacity for new ArrayLists. - */ - private static final int DEFAULT_CAPACITY = 16; - - /** - * The number of elements in this list. - * @serial the list size - */ - private int size; - - /** - * Where the data is stored. - */ - private transient Object[] data; - - /** - * Construct a new ArrayList with the supplied initial capacity. - * - * @param capacity initial capacity of this ArrayList - * @throws IllegalArgumentException if capacity is negative - */ - public ArrayList(int capacity) - { - // Must explicitly check, to get correct exception. - if (capacity < 0) - throw new IllegalArgumentException(); - data = new Object[capacity]; - } - - /** - * Construct a new ArrayList with the default capacity (16). - */ - public ArrayList() - { - this(DEFAULT_CAPACITY); - } - - /** - * Construct a new ArrayList, and initialize it with the elements - * in the supplied Collection. The initial capacity is 110% of the - * Collection's size. - * - * @param c the collection whose elements will initialize this list - * @throws NullPointerException if c is null - */ - public ArrayList(Collection c) - { - this((int) (c.size() * 1.1f)); - addAll(c); - } - - /** - * Trims the capacity of this List to be equal to its size; - * a memory saver. - */ - public void trimToSize() - { - // Not a structural change from the perspective of iterators on this list, - // so don't update modCount. - if (size != data.length) - { - Object[] newData = new Object[size]; - System.arraycopy(data, 0, newData, 0, size); - data = newData; - } - } - - /** - * Guarantees that this list will have at least enough capacity to - * hold minCapacity elements. This implementation will grow the list to - * max(current * 2, minCapacity) if (minCapacity > current). The JCL says - * explictly that "this method increases its capacity to minCap", while - * the JDK 1.3 online docs specify that the list will grow to at least the - * size specified. - * - * @param minCapacity the minimum guaranteed capacity - */ - public void ensureCapacity(int minCapacity) - { - int current = data.length; - - if (minCapacity > current) - { - Object[] newData = new Object[Math.max(current * 2, minCapacity)]; - System.arraycopy(data, 0, newData, 0, size); - data = newData; - } - } - - /** - * Returns the number of elements in this list. - * - * @return the list size - */ - public int size() - { - return size; - } - - /** - * Checks if the list is empty. - * - * @return true if there are no elements - */ - public boolean isEmpty() - { - return size == 0; - } - - /** - * Returns true iff element is in this ArrayList. - * - * @param e the element whose inclusion in the List is being tested - * @return true if the list contains e - */ - public boolean contains(Object e) - { - return indexOf(e) != -1; - } - - /** - * Returns the lowest index at which element appears in this List, or - * -1 if it does not appear. - * - * @param e the element whose inclusion in the List is being tested - * @return the index where e was found - */ - public int indexOf(Object e) - { - for (int i = 0; i < size; i++) - if (equals(e, data[i])) - return i; - return -1; - } - - /** - * Returns the highest index at which element appears in this List, or - * -1 if it does not appear. - * - * @param e the element whose inclusion in the List is being tested - * @return the index where e was found - */ - public int lastIndexOf(Object e) - { - for (int i = size - 1; i >= 0; i--) - if (equals(e, data[i])) - return i; - return -1; - } - - /** - * Creates a shallow copy of this ArrayList (elements are not cloned). - * - * @return the cloned object - */ - public Object clone() - { - ArrayList clone = null; - try - { - clone = (ArrayList) super.clone(); - clone.data = (Object[]) data.clone(); - } - catch (CloneNotSupportedException e) - { - // Impossible to get here. - } - return clone; - } - - /** - * Returns an Object array containing all of the elements in this ArrayList. - * The array is independent of this list. - * - * @return an array representation of this list - */ - public Object[] toArray() - { - Object[] array = new Object[size]; - System.arraycopy(data, 0, array, 0, size); - return array; - } - - /** - * Returns an Array whose component type is the runtime component type of - * the passed-in Array. The returned Array is populated with all of the - * elements in this ArrayList. If the passed-in Array is not large enough - * to store all of the elements in this List, a new Array will be created - * and returned; if the passed-in Array is <i>larger</i> than the size - * of this List, then size() index will be set to null. - * - * @param a the passed-in Array - * @return an array representation of this list - * @throws ArrayStoreException if the runtime type of a does not allow - * an element in this list - * @throws NullPointerException if a is null - */ - public Object[] toArray(Object[] a) - { - if (a.length < size) - a = (Object[]) Array.newInstance(a.getClass().getComponentType(), - size); - else if (a.length > size) - a[size] = null; - System.arraycopy(data, 0, a, 0, size); - return a; - } - - /** - * Retrieves the element at the user-supplied index. - * - * @param index the index of the element we are fetching - * @throws IndexOutOfBoundsException if index < 0 || index >= size() - */ - public Object get(int index) - { - checkBoundExclusive(index); - return data[index]; - } - - /** - * Sets the element at the specified index. The new element, e, - * can be an object of any type or null. - * - * @param index the index at which the element is being set - * @param e the element to be set - * @return the element previously at the specified index - * @throws IndexOutOfBoundsException if index < 0 || index >= 0 - */ - public Object set(int index, Object e) - { - checkBoundExclusive(index); - Object result = data[index]; - data[index] = e; - return result; - } - - /** - * Appends the supplied element to the end of this list. - * The element, e, can be an object of any type or null. - * - * @param e the element to be appended to this list - * @return true, the add will always succeed - */ - public boolean add(Object e) - { - modCount++; - if (size == data.length) - ensureCapacity(size + 1); - data[size++] = e; - return true; - } - - /** - * Adds the supplied element at the specified index, shifting all - * elements currently at that index or higher one to the right. - * The element, e, can be an object of any type or null. - * - * @param index the index at which the element is being added - * @param e the item being added - * @throws IndexOutOfBoundsException if index < 0 || index > size() - */ - public void add(int index, Object e) - { - checkBoundInclusive(index); - modCount++; - if (size == data.length) - ensureCapacity(size + 1); - if (index != size) - System.arraycopy(data, index, data, index + 1, size - index); - data[index] = e; - size++; - } - - /** - * Removes the element at the user-supplied index. - * - * @param index the index of the element to be removed - * @return the removed Object - * @throws IndexOutOfBoundsException if index < 0 || index >= size() - */ - public Object remove(int index) - { - checkBoundExclusive(index); - Object r = data[index]; - modCount++; - if (index != --size) - System.arraycopy(data, index + 1, data, index, size - index); - // Aid for garbage collection by releasing this pointer. - data[size] = null; - return r; - } - - /** - * Removes all elements from this List - */ - public void clear() - { - if (size > 0) - { - modCount++; - // Allow for garbage collection. - Arrays.fill(data, 0, size, null); - size = 0; - } - } - - /** - * Add each element in the supplied Collection to this List. It is undefined - * what happens if you modify the list while this is taking place; for - * example, if the collection contains this list. c can contain objects - * of any type, as well as null values. - * - * @param c a Collection containing elements to be added to this List - * @return true if the list was modified, in other words c is not empty - * @throws NullPointerException if c is null - */ - public boolean addAll(Collection c) - { - return addAll(size, c); - } - - /** - * Add all elements in the supplied collection, inserting them beginning - * at the specified index. c can contain objects of any type, as well - * as null values. - * - * @param index the index at which the elements will be inserted - * @param c the Collection containing the elements to be inserted - * @throws IndexOutOfBoundsException if index < 0 || index > 0 - * @throws NullPointerException if c is null - */ - public boolean addAll(int index, Collection c) - { - checkBoundInclusive(index); - Iterator itr = c.iterator(); - int csize = c.size(); - - modCount++; - if (csize + size > data.length) - ensureCapacity(size + csize); - int end = index + csize; - if (size > 0 && index != size) - System.arraycopy(data, index, data, end, size - index); - size += csize; - for ( ; index < end; index++) - data[index] = itr.next(); - return csize > 0; - } - - /** - * Removes all elements in the half-open interval [fromIndex, toIndex). - * Does nothing when toIndex is equal to fromIndex. - * - * @param fromIndex the first index which will be removed - * @param toIndex one greater than the last index which will be removed - * @throws IndexOutOfBoundsException if fromIndex > toIndex - */ - protected void removeRange(int fromIndex, int toIndex) - { - int change = toIndex - fromIndex; - if (change > 0) - { - modCount++; - System.arraycopy(data, toIndex, data, fromIndex, size - toIndex); - size -= change; - } - else if (change < 0) - throw new IndexOutOfBoundsException(); - } - - /** - * Checks that the index is in the range of possible elements (inclusive). - * - * @param index the index to check - * @throws IndexOutOfBoundsException if index > size - */ - private void checkBoundInclusive(int index) - { - // Implementation note: we do not check for negative ranges here, since - // use of a negative index will cause an ArrayIndexOutOfBoundsException, - // a subclass of the required exception, with no effort on our part. - if (index > size) - throw new IndexOutOfBoundsException("Index: " + index + ", Size: " - + size); - } - - /** - * Checks that the index is in the range of existing elements (exclusive). - * - * @param index the index to check - * @throws IndexOutOfBoundsException if index >= size - */ - private void checkBoundExclusive(int index) - { - // Implementation note: we do not check for negative ranges here, since - // use of a negative index will cause an ArrayIndexOutOfBoundsException, - // a subclass of the required exception, with no effort on our part. - if (index >= size) - throw new IndexOutOfBoundsException("Index: " + index + ", Size: " - + size); - } - - /** - * Remove from this list all elements contained in the given collection. - * This is not public, due to Sun's API, but this performs in linear - * time while the default behavior of AbstractList would be quadratic. - * - * @param c the collection to filter out - * @return true if this list changed - * @throws NullPointerException if c is null - */ - boolean removeAllInternal(Collection c) - { - int i; - int j; - for (i = 0; i < size; i++) - if (c.contains(data[i])) - break; - if (i == size) - return false; - - modCount++; - for (j = i++; i < size; i++) - if (! c.contains(data[i])) - data[j++] = data[i]; - size -= i - j; - return true; - } - - /** - * Retain in this vector only the elements contained in the given collection. - * This is not public, due to Sun's API, but this performs in linear - * time while the default behavior of AbstractList would be quadratic. - * - * @param c the collection to filter by - * @return true if this vector changed - * @throws NullPointerException if c is null - * @since 1.2 - */ - boolean retainAllInternal(Collection c) - { - int i; - int j; - for (i = 0; i < size; i++) - if (! c.contains(data[i])) - break; - if (i == size) - return false; - - modCount++; - for (j = i++; i < size; i++) - if (c.contains(data[i])) - data[j++] = data[i]; - size -= i - j; - return true; - } - - /** - * Serializes this object to the given stream. - * - * @param out the stream to write to - * @throws IOException if the underlying stream fails - * @serialData the size field (int), the length of the backing array - * (int), followed by its elements (Objects) in proper order. - */ - private void writeObject(ObjectOutputStream s) throws IOException - { - // The 'size' field. - s.defaultWriteObject(); - // We serialize unused list entries to preserve capacity. - int len = data.length; - s.writeInt(len); - // it would be more efficient to just write "size" items, - // this need readObject read "size" items too. - for (int i = 0; i < size; i++) - s.writeObject(data[i]); - } - - /** - * Deserializes this object from the given stream. - * - * @param in the stream to read from - * @throws ClassNotFoundException if the underlying stream fails - * @throws IOException if the underlying stream fails - * @serialData the size field (int), the length of the backing array - * (int), followed by its elements (Objects) in proper order. - */ - private void readObject(ObjectInputStream s) - throws IOException, ClassNotFoundException - { - // the `size' field. - s.defaultReadObject(); - int capacity = s.readInt(); - data = new Object[capacity]; - for (int i = 0; i < size; i++) - data[i] = s.readObject(); - } -} diff --git a/libjava/java/util/Arrays.java b/libjava/java/util/Arrays.java deleted file mode 100644 index 15c1a5f33bf..00000000000 --- a/libjava/java/util/Arrays.java +++ /dev/null @@ -1,2510 +0,0 @@ -/* Arrays.java -- Utility class with methods to operate on arrays - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 - 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -import java.io.Serializable; -import java.lang.reflect.Array; - -/** - * This class contains various static utility methods performing operations on - * arrays, and a method to provide a List "view" of an array to facilitate - * using arrays with Collection-based APIs. All methods throw a - * {@link NullPointerException} if the parameter array is null. - * <p> - * - * Implementations may use their own algorithms, but must obey the general - * properties; for example, the sort must be stable and n*log(n) complexity. - * Sun's implementation of sort, and therefore ours, is a tuned quicksort, - * adapted from Jon L. Bentley and M. Douglas McIlroy's "Engineering a Sort - * Function", Software-Practice and Experience, Vol. 23(11) P. 1249-1265 - * (November 1993). This algorithm offers n*log(n) performance on many data - * sets that cause other quicksorts to degrade to quadratic performance. - * - * @author Original author unknown - * @author Bryce McKinlay - * @author Eric Blake (ebb9@email.byu.edu) - * @see Comparable - * @see Comparator - * @since 1.2 - * @status updated to 1.4 - */ -public class Arrays -{ - /** - * This class is non-instantiable. - */ - private Arrays() - { - } - - -// binarySearch - /** - * Perform a binary search of a byte array for a key. The array must be - * sorted (as by the sort() method) - if it is not, the behaviour of this - * method is undefined, and may be an infinite loop. If the array contains - * the key more than once, any one of them may be found. Note: although the - * specification allows for an infinite loop if the array is unsorted, it - * will not happen in this implementation. - * - * @param a the array to search (must be sorted) - * @param key the value to search for - * @return the index at which the key was found, or -n-1 if it was not - * found, where n is the index of the first value higher than key or - * a.length if there is no such value. - */ - public static int binarySearch(byte[] a, byte key) - { - int low = 0; - int hi = a.length - 1; - int mid = 0; - while (low <= hi) - { - mid = (low + hi) >> 1; - final byte d = a[mid]; - if (d == key) - return mid; - else if (d > key) - hi = mid - 1; - else - // This gets the insertion point right on the last loop. - low = ++mid; - } - return -mid - 1; - } - - /** - * Perform a binary search of a char array for a key. The array must be - * sorted (as by the sort() method) - if it is not, the behaviour of this - * method is undefined, and may be an infinite loop. If the array contains - * the key more than once, any one of them may be found. Note: although the - * specification allows for an infinite loop if the array is unsorted, it - * will not happen in this implementation. - * - * @param a the array to search (must be sorted) - * @param key the value to search for - * @return the index at which the key was found, or -n-1 if it was not - * found, where n is the index of the first value higher than key or - * a.length if there is no such value. - */ - public static int binarySearch(char[] a, char key) - { - int low = 0; - int hi = a.length - 1; - int mid = 0; - while (low <= hi) - { - mid = (low + hi) >> 1; - final char d = a[mid]; - if (d == key) - return mid; - else if (d > key) - hi = mid - 1; - else - // This gets the insertion point right on the last loop. - low = ++mid; - } - return -mid - 1; - } - - /** - * Perform a binary search of a short array for a key. The array must be - * sorted (as by the sort() method) - if it is not, the behaviour of this - * method is undefined, and may be an infinite loop. If the array contains - * the key more than once, any one of them may be found. Note: although the - * specification allows for an infinite loop if the array is unsorted, it - * will not happen in this implementation. - * - * @param a the array to search (must be sorted) - * @param key the value to search for - * @return the index at which the key was found, or -n-1 if it was not - * found, where n is the index of the first value higher than key or - * a.length if there is no such value. - */ - public static int binarySearch(short[] a, short key) - { - int low = 0; - int hi = a.length - 1; - int mid = 0; - while (low <= hi) - { - mid = (low + hi) >> 1; - final short d = a[mid]; - if (d == key) - return mid; - else if (d > key) - hi = mid - 1; - else - // This gets the insertion point right on the last loop. - low = ++mid; - } - return -mid - 1; - } - - /** - * Perform a binary search of an int array for a key. The array must be - * sorted (as by the sort() method) - if it is not, the behaviour of this - * method is undefined, and may be an infinite loop. If the array contains - * the key more than once, any one of them may be found. Note: although the - * specification allows for an infinite loop if the array is unsorted, it - * will not happen in this implementation. - * - * @param a the array to search (must be sorted) - * @param key the value to search for - * @return the index at which the key was found, or -n-1 if it was not - * found, where n is the index of the first value higher than key or - * a.length if there is no such value. - */ - public static int binarySearch(int[] a, int key) - { - int low = 0; - int hi = a.length - 1; - int mid = 0; - while (low <= hi) - { - mid = (low + hi) >> 1; - final int d = a[mid]; - if (d == key) - return mid; - else if (d > key) - hi = mid - 1; - else - // This gets the insertion point right on the last loop. - low = ++mid; - } - return -mid - 1; - } - - /** - * Perform a binary search of a long array for a key. The array must be - * sorted (as by the sort() method) - if it is not, the behaviour of this - * method is undefined, and may be an infinite loop. If the array contains - * the key more than once, any one of them may be found. Note: although the - * specification allows for an infinite loop if the array is unsorted, it - * will not happen in this implementation. - * - * @param a the array to search (must be sorted) - * @param key the value to search for - * @return the index at which the key was found, or -n-1 if it was not - * found, where n is the index of the first value higher than key or - * a.length if there is no such value. - */ - public static int binarySearch(long[] a, long key) - { - int low = 0; - int hi = a.length - 1; - int mid = 0; - while (low <= hi) - { - mid = (low + hi) >> 1; - final long d = a[mid]; - if (d == key) - return mid; - else if (d > key) - hi = mid - 1; - else - // This gets the insertion point right on the last loop. - low = ++mid; - } - return -mid - 1; - } - - /** - * Perform a binary search of a float array for a key. The array must be - * sorted (as by the sort() method) - if it is not, the behaviour of this - * method is undefined, and may be an infinite loop. If the array contains - * the key more than once, any one of them may be found. Note: although the - * specification allows for an infinite loop if the array is unsorted, it - * will not happen in this implementation. - * - * @param a the array to search (must be sorted) - * @param key the value to search for - * @return the index at which the key was found, or -n-1 if it was not - * found, where n is the index of the first value higher than key or - * a.length if there is no such value. - */ - public static int binarySearch(float[] a, float key) - { - // Must use Float.compare to take into account NaN, +-0. - int low = 0; - int hi = a.length - 1; - int mid = 0; - while (low <= hi) - { - mid = (low + hi) >> 1; - final int r = Float.compare(a[mid], key); - if (r == 0) - return mid; - else if (r > 0) - hi = mid - 1; - else - // This gets the insertion point right on the last loop - low = ++mid; - } - return -mid - 1; - } - - /** - * Perform a binary search of a double array for a key. The array must be - * sorted (as by the sort() method) - if it is not, the behaviour of this - * method is undefined, and may be an infinite loop. If the array contains - * the key more than once, any one of them may be found. Note: although the - * specification allows for an infinite loop if the array is unsorted, it - * will not happen in this implementation. - * - * @param a the array to search (must be sorted) - * @param key the value to search for - * @return the index at which the key was found, or -n-1 if it was not - * found, where n is the index of the first value higher than key or - * a.length if there is no such value. - */ - public static int binarySearch(double[] a, double key) - { - // Must use Double.compare to take into account NaN, +-0. - int low = 0; - int hi = a.length - 1; - int mid = 0; - while (low <= hi) - { - mid = (low + hi) >> 1; - final int r = Double.compare(a[mid], key); - if (r == 0) - return mid; - else if (r > 0) - hi = mid - 1; - else - // This gets the insertion point right on the last loop - low = ++mid; - } - return -mid - 1; - } - - /** - * Perform a binary search of an Object array for a key, using the natural - * ordering of the elements. The array must be sorted (as by the sort() - * method) - if it is not, the behaviour of this method is undefined, and may - * be an infinite loop. Further, the key must be comparable with every item - * in the array. If the array contains the key more than once, any one of - * them may be found. Note: although the specification allows for an infinite - * loop if the array is unsorted, it will not happen in this (JCL) - * implementation. - * - * @param a the array to search (must be sorted) - * @param key the value to search for - * @return the index at which the key was found, or -n-1 if it was not - * found, where n is the index of the first value higher than key or - * a.length if there is no such value. - * @throws ClassCastException if key could not be compared with one of the - * elements of a - * @throws NullPointerException if a null element in a is compared - */ - public static int binarySearch(Object[] a, Object key) - { - return binarySearch(a, key, null); - } - - /** - * Perform a binary search of an Object array for a key, using a supplied - * Comparator. The array must be sorted (as by the sort() method with the - * same Comparator) - if it is not, the behaviour of this method is - * undefined, and may be an infinite loop. Further, the key must be - * comparable with every item in the array. If the array contains the key - * more than once, any one of them may be found. Note: although the - * specification allows for an infinite loop if the array is unsorted, it - * will not happen in this (JCL) implementation. - * - * @param a the array to search (must be sorted) - * @param key the value to search for - * @param c the comparator by which the array is sorted; or null to - * use the elements' natural order - * @return the index at which the key was found, or -n-1 if it was not - * found, where n is the index of the first value higher than key or - * a.length if there is no such value. - * @throws ClassCastException if key could not be compared with one of the - * elements of a - * @throws NullPointerException if a null element is compared with natural - * ordering (only possible when c is null) - */ - public static int binarySearch(Object[] a, Object key, Comparator c) - { - int low = 0; - int hi = a.length - 1; - int mid = 0; - while (low <= hi) - { - mid = (low + hi) >> 1; - final int d = Collections.compare(key, a[mid], c); - if (d == 0) - return mid; - else if (d < 0) - hi = mid - 1; - else - // This gets the insertion point right on the last loop - low = ++mid; - } - return -mid - 1; - } - - -// equals - /** - * Compare two boolean arrays for equality. - * - * @param a1 the first array to compare - * @param a2 the second array to compare - * @return true if a1 and a2 are both null, or if a2 is of the same length - * as a1, and for each 0 <= i < a1.length, a1[i] == a2[i] - */ - public static boolean equals(boolean[] a1, boolean[] a2) - { - // Quick test which saves comparing elements of the same array, and also - // catches the case that both are null. - if (a1 == a2) - return true; - - if (null == a1 || null == a2) - return false; - - // If they're the same length, test each element - if (a1.length == a2.length) - { - int i = a1.length; - while (--i >= 0) - if (a1[i] != a2[i]) - return false; - return true; - } - return false; - } - - /** - * Compare two byte arrays for equality. - * - * @param a1 the first array to compare - * @param a2 the second array to compare - * @return true if a1 and a2 are both null, or if a2 is of the same length - * as a1, and for each 0 <= i < a1.length, a1[i] == a2[i] - */ - public static boolean equals(byte[] a1, byte[] a2) - { - // Quick test which saves comparing elements of the same array, and also - // catches the case that both are null. - if (a1 == a2) - return true; - - if (null == a1 || null == a2) - return false; - - // If they're the same length, test each element - if (a1.length == a2.length) - { - int i = a1.length; - while (--i >= 0) - if (a1[i] != a2[i]) - return false; - return true; - } - return false; - } - - /** - * Compare two char arrays for equality. - * - * @param a1 the first array to compare - * @param a2 the second array to compare - * @return true if a1 and a2 are both null, or if a2 is of the same length - * as a1, and for each 0 <= i < a1.length, a1[i] == a2[i] - */ - public static boolean equals(char[] a1, char[] a2) - { - // Quick test which saves comparing elements of the same array, and also - // catches the case that both are null. - if (a1 == a2) - return true; - - if (null == a1 || null == a2) - return false; - - // If they're the same length, test each element - if (a1.length == a2.length) - { - int i = a1.length; - while (--i >= 0) - if (a1[i] != a2[i]) - return false; - return true; - } - return false; - } - - /** - * Compare two short arrays for equality. - * - * @param a1 the first array to compare - * @param a2 the second array to compare - * @return true if a1 and a2 are both null, or if a2 is of the same length - * as a1, and for each 0 <= i < a1.length, a1[i] == a2[i] - */ - public static boolean equals(short[] a1, short[] a2) - { - // Quick test which saves comparing elements of the same array, and also - // catches the case that both are null. - if (a1 == a2) - return true; - - if (null == a1 || null == a2) - return false; - - // If they're the same length, test each element - if (a1.length == a2.length) - { - int i = a1.length; - while (--i >= 0) - if (a1[i] != a2[i]) - return false; - return true; - } - return false; - } - - /** - * Compare two int arrays for equality. - * - * @param a1 the first array to compare - * @param a2 the second array to compare - * @return true if a1 and a2 are both null, or if a2 is of the same length - * as a1, and for each 0 <= i < a1.length, a1[i] == a2[i] - */ - public static boolean equals(int[] a1, int[] a2) - { - // Quick test which saves comparing elements of the same array, and also - // catches the case that both are null. - if (a1 == a2) - return true; - - if (null == a1 || null == a2) - return false; - - // If they're the same length, test each element - if (a1.length == a2.length) - { - int i = a1.length; - while (--i >= 0) - if (a1[i] != a2[i]) - return false; - return true; - } - return false; - } - - /** - * Compare two long arrays for equality. - * - * @param a1 the first array to compare - * @param a2 the second array to compare - * @return true if a1 and a2 are both null, or if a2 is of the same length - * as a1, and for each 0 <= i < a1.length, a1[i] == a2[i] - */ - public static boolean equals(long[] a1, long[] a2) - { - // Quick test which saves comparing elements of the same array, and also - // catches the case that both are null. - if (a1 == a2) - return true; - - if (null == a1 || null == a2) - return false; - - // If they're the same length, test each element - if (a1.length == a2.length) - { - int i = a1.length; - while (--i >= 0) - if (a1[i] != a2[i]) - return false; - return true; - } - return false; - } - - /** - * Compare two float arrays for equality. - * - * @param a1 the first array to compare - * @param a2 the second array to compare - * @return true if a1 and a2 are both null, or if a2 is of the same length - * as a1, and for each 0 <= i < a1.length, a1[i] == a2[i] - */ - public static boolean equals(float[] a1, float[] a2) - { - // Quick test which saves comparing elements of the same array, and also - // catches the case that both are null. - if (a1 == a2) - return true; - - if (null == a1 || null == a2) - return false; - - // Must use Float.compare to take into account NaN, +-0. - // If they're the same length, test each element - if (a1.length == a2.length) - { - int i = a1.length; - while (--i >= 0) - if (Float.compare(a1[i], a2[i]) != 0) - return false; - return true; - } - return false; - } - - /** - * Compare two double arrays for equality. - * - * @param a1 the first array to compare - * @param a2 the second array to compare - * @return true if a1 and a2 are both null, or if a2 is of the same length - * as a1, and for each 0 <= i < a1.length, a1[i] == a2[i] - */ - public static boolean equals(double[] a1, double[] a2) - { - // Quick test which saves comparing elements of the same array, and also - // catches the case that both are null. - if (a1 == a2) - return true; - - if (null == a1 || null == a2) - return false; - - // Must use Double.compare to take into account NaN, +-0. - // If they're the same length, test each element - if (a1.length == a2.length) - { - int i = a1.length; - while (--i >= 0) - if (Double.compare(a1[i], a2[i]) != 0) - return false; - return true; - } - return false; - } - - /** - * Compare two Object arrays for equality. - * - * @param a1 the first array to compare - * @param a2 the second array to compare - * @return true if a1 and a2 are both null, or if a1 is of the same length - * as a2, and for each 0 <= i < a.length, a1[i] == null ? - * a2[i] == null : a1[i].equals(a2[i]). - */ - public static boolean equals(Object[] a1, Object[] a2) - { - // Quick test which saves comparing elements of the same array, and also - // catches the case that both are null. - if (a1 == a2) - return true; - - if (null == a1 || null == a2) - return false; - - // If they're the same length, test each element - if (a1.length == a2.length) - { - int i = a1.length; - while (--i >= 0) - if (! AbstractCollection.equals(a1[i], a2[i])) - return false; - return true; - } - return false; - } - - -// fill - /** - * Fill an array with a boolean value. - * - * @param a the array to fill - * @param val the value to fill it with - */ - public static void fill(boolean[] a, boolean val) - { - fill(a, 0, a.length, val); - } - - /** - * Fill a range of an array with a boolean value. - * - * @param a the array to fill - * @param fromIndex the index to fill from, inclusive - * @param toIndex the index to fill to, exclusive - * @param val the value to fill with - * @throws IllegalArgumentException if fromIndex > toIndex - * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 - * || toIndex > a.length - */ - public static void fill(boolean[] a, int fromIndex, int toIndex, boolean val) - { - if (fromIndex > toIndex) - throw new IllegalArgumentException(); - for (int i = fromIndex; i < toIndex; i++) - a[i] = val; - } - - /** - * Fill an array with a byte value. - * - * @param a the array to fill - * @param val the value to fill it with - */ - public static void fill(byte[] a, byte val) - { - fill(a, 0, a.length, val); - } - - /** - * Fill a range of an array with a byte value. - * - * @param a the array to fill - * @param fromIndex the index to fill from, inclusive - * @param toIndex the index to fill to, exclusive - * @param val the value to fill with - * @throws IllegalArgumentException if fromIndex > toIndex - * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 - * || toIndex > a.length - */ - public static void fill(byte[] a, int fromIndex, int toIndex, byte val) - { - if (fromIndex > toIndex) - throw new IllegalArgumentException(); - for (int i = fromIndex; i < toIndex; i++) - a[i] = val; - } - - /** - * Fill an array with a char value. - * - * @param a the array to fill - * @param val the value to fill it with - */ - public static void fill(char[] a, char val) - { - fill(a, 0, a.length, val); - } - - /** - * Fill a range of an array with a char value. - * - * @param a the array to fill - * @param fromIndex the index to fill from, inclusive - * @param toIndex the index to fill to, exclusive - * @param val the value to fill with - * @throws IllegalArgumentException if fromIndex > toIndex - * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 - * || toIndex > a.length - */ - public static void fill(char[] a, int fromIndex, int toIndex, char val) - { - if (fromIndex > toIndex) - throw new IllegalArgumentException(); - for (int i = fromIndex; i < toIndex; i++) - a[i] = val; - } - - /** - * Fill an array with a short value. - * - * @param a the array to fill - * @param val the value to fill it with - */ - public static void fill(short[] a, short val) - { - fill(a, 0, a.length, val); - } - - /** - * Fill a range of an array with a short value. - * - * @param a the array to fill - * @param fromIndex the index to fill from, inclusive - * @param toIndex the index to fill to, exclusive - * @param val the value to fill with - * @throws IllegalArgumentException if fromIndex > toIndex - * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 - * || toIndex > a.length - */ - public static void fill(short[] a, int fromIndex, int toIndex, short val) - { - if (fromIndex > toIndex) - throw new IllegalArgumentException(); - for (int i = fromIndex; i < toIndex; i++) - a[i] = val; - } - - /** - * Fill an array with an int value. - * - * @param a the array to fill - * @param val the value to fill it with - */ - public static void fill(int[] a, int val) - { - fill(a, 0, a.length, val); - } - - /** - * Fill a range of an array with an int value. - * - * @param a the array to fill - * @param fromIndex the index to fill from, inclusive - * @param toIndex the index to fill to, exclusive - * @param val the value to fill with - * @throws IllegalArgumentException if fromIndex > toIndex - * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 - * || toIndex > a.length - */ - public static void fill(int[] a, int fromIndex, int toIndex, int val) - { - if (fromIndex > toIndex) - throw new IllegalArgumentException(); - for (int i = fromIndex; i < toIndex; i++) - a[i] = val; - } - - /** - * Fill an array with a long value. - * - * @param a the array to fill - * @param val the value to fill it with - */ - public static void fill(long[] a, long val) - { - fill(a, 0, a.length, val); - } - - /** - * Fill a range of an array with a long value. - * - * @param a the array to fill - * @param fromIndex the index to fill from, inclusive - * @param toIndex the index to fill to, exclusive - * @param val the value to fill with - * @throws IllegalArgumentException if fromIndex > toIndex - * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 - * || toIndex > a.length - */ - public static void fill(long[] a, int fromIndex, int toIndex, long val) - { - if (fromIndex > toIndex) - throw new IllegalArgumentException(); - for (int i = fromIndex; i < toIndex; i++) - a[i] = val; - } - - /** - * Fill an array with a float value. - * - * @param a the array to fill - * @param val the value to fill it with - */ - public static void fill(float[] a, float val) - { - fill(a, 0, a.length, val); - } - - /** - * Fill a range of an array with a float value. - * - * @param a the array to fill - * @param fromIndex the index to fill from, inclusive - * @param toIndex the index to fill to, exclusive - * @param val the value to fill with - * @throws IllegalArgumentException if fromIndex > toIndex - * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 - * || toIndex > a.length - */ - public static void fill(float[] a, int fromIndex, int toIndex, float val) - { - if (fromIndex > toIndex) - throw new IllegalArgumentException(); - for (int i = fromIndex; i < toIndex; i++) - a[i] = val; - } - - /** - * Fill an array with a double value. - * - * @param a the array to fill - * @param val the value to fill it with - */ - public static void fill(double[] a, double val) - { - fill(a, 0, a.length, val); - } - - /** - * Fill a range of an array with a double value. - * - * @param a the array to fill - * @param fromIndex the index to fill from, inclusive - * @param toIndex the index to fill to, exclusive - * @param val the value to fill with - * @throws IllegalArgumentException if fromIndex > toIndex - * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 - * || toIndex > a.length - */ - public static void fill(double[] a, int fromIndex, int toIndex, double val) - { - if (fromIndex > toIndex) - throw new IllegalArgumentException(); - for (int i = fromIndex; i < toIndex; i++) - a[i] = val; - } - - /** - * Fill an array with an Object value. - * - * @param a the array to fill - * @param val the value to fill it with - * @throws ClassCastException if val is not an instance of the element - * type of a. - */ - public static void fill(Object[] a, Object val) - { - fill(a, 0, a.length, val); - } - - /** - * Fill a range of an array with an Object value. - * - * @param a the array to fill - * @param fromIndex the index to fill from, inclusive - * @param toIndex the index to fill to, exclusive - * @param val the value to fill with - * @throws ClassCastException if val is not an instance of the element - * type of a. - * @throws IllegalArgumentException if fromIndex > toIndex - * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 - * || toIndex > a.length - */ - public static void fill(Object[] a, int fromIndex, int toIndex, Object val) - { - if (fromIndex > toIndex) - throw new IllegalArgumentException(); - for (int i = fromIndex; i < toIndex; i++) - a[i] = val; - } - - -// sort - // Thanks to Paul Fisher (rao@gnu.org) for finding this quicksort algorithm - // as specified by Sun and porting it to Java. The algorithm is an optimised - // quicksort, as described in Jon L. Bentley and M. Douglas McIlroy's - // "Engineering a Sort Function", Software-Practice and Experience, Vol. - // 23(11) P. 1249-1265 (November 1993). This algorithm gives n*log(n) - // performance on many arrays that would take quadratic time with a standard - // quicksort. - - /** - * Performs a stable sort on the elements, arranging them according to their - * natural order. - * - * @param a the byte array to sort - */ - public static void sort(byte[] a) - { - qsort(a, 0, a.length); - } - - /** - * Performs a stable sort on the elements, arranging them according to their - * natural order. - * - * @param a the byte array to sort - * @param fromIndex the first index to sort (inclusive) - * @param toIndex the last index to sort (exclusive) - * @throws IllegalArgumentException if fromIndex > toIndex - * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 - * || toIndex > a.length - */ - public static void sort(byte[] a, int fromIndex, int toIndex) - { - if (fromIndex > toIndex) - throw new IllegalArgumentException(); - if (fromIndex < 0) - throw new ArrayIndexOutOfBoundsException(); - qsort(a, fromIndex, toIndex - fromIndex); - } - - /** - * Finds the index of the median of three array elements. - * - * @param a the first index - * @param b the second index - * @param c the third index - * @param d the array - * @return the index (a, b, or c) which has the middle value of the three - */ - private static int med3(int a, int b, int c, byte[] d) - { - return (d[a] < d[b] - ? (d[b] < d[c] ? b : d[a] < d[c] ? c : a) - : (d[b] > d[c] ? b : d[a] > d[c] ? c : a)); - } - - /** - * Swaps the elements at two locations of an array - * - * @param i the first index - * @param j the second index - * @param a the array - */ - private static void swap(int i, int j, byte[] a) - { - byte c = a[i]; - a[i] = a[j]; - a[j] = c; - } - - /** - * Swaps two ranges of an array. - * - * @param i the first range start - * @param j the second range start - * @param n the element count - * @param a the array - */ - private static void vecswap(int i, int j, int n, byte[] a) - { - for ( ; n > 0; i++, j++, n--) - swap(i, j, a); - } - - /** - * Performs a recursive modified quicksort. - * - * @param array the array to sort - * @param from the start index (inclusive) - * @param count the number of elements to sort - */ - private static void qsort(byte[] array, int from, int count) - { - // Use an insertion sort on small arrays. - if (count <= 7) - { - for (int i = from + 1; i < from + count; i++) - for (int j = i; j > from && array[j - 1] > array[j]; j--) - swap(j, j - 1, array); - return; - } - - // Determine a good median element. - int mid = count / 2; - int lo = from; - int hi = from + count - 1; - - if (count > 40) - { // big arrays, pseudomedian of 9 - int s = count / 8; - lo = med3(lo, lo + s, lo + 2 * s, array); - mid = med3(mid - s, mid, mid + s, array); - hi = med3(hi - 2 * s, hi - s, hi, array); - } - mid = med3(lo, mid, hi, array); - - int a, b, c, d; - int comp; - - // Pull the median element out of the fray, and use it as a pivot. - swap(from, mid, array); - a = b = from; - c = d = from + count - 1; - - // Repeatedly move b and c to each other, swapping elements so - // that all elements before index b are less than the pivot, and all - // elements after index c are greater than the pivot. a and b track - // the elements equal to the pivot. - while (true) - { - while (b <= c && (comp = array[b] - array[from]) <= 0) - { - if (comp == 0) - { - swap(a, b, array); - a++; - } - b++; - } - while (c >= b && (comp = array[c] - array[from]) >= 0) - { - if (comp == 0) - { - swap(c, d, array); - d--; - } - c--; - } - if (b > c) - break; - swap(b, c, array); - b++; - c--; - } - - // Swap pivot(s) back in place, the recurse on left and right sections. - hi = from + count; - int span; - span = Math.min(a - from, b - a); - vecswap(from, b - span, span, array); - - span = Math.min(d - c, hi - d - 1); - vecswap(b, hi - span, span, array); - - span = b - a; - if (span > 1) - qsort(array, from, span); - - span = d - c; - if (span > 1) - qsort(array, hi - span, span); - } - - /** - * Performs a stable sort on the elements, arranging them according to their - * natural order. - * - * @param a the char array to sort - */ - public static void sort(char[] a) - { - qsort(a, 0, a.length); - } - - /** - * Performs a stable sort on the elements, arranging them according to their - * natural order. - * - * @param a the char array to sort - * @param fromIndex the first index to sort (inclusive) - * @param toIndex the last index to sort (exclusive) - * @throws IllegalArgumentException if fromIndex > toIndex - * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 - * || toIndex > a.length - */ - public static void sort(char[] a, int fromIndex, int toIndex) - { - if (fromIndex > toIndex) - throw new IllegalArgumentException(); - if (fromIndex < 0) - throw new ArrayIndexOutOfBoundsException(); - qsort(a, fromIndex, toIndex - fromIndex); - } - - /** - * Finds the index of the median of three array elements. - * - * @param a the first index - * @param b the second index - * @param c the third index - * @param d the array - * @return the index (a, b, or c) which has the middle value of the three - */ - private static int med3(int a, int b, int c, char[] d) - { - return (d[a] < d[b] - ? (d[b] < d[c] ? b : d[a] < d[c] ? c : a) - : (d[b] > d[c] ? b : d[a] > d[c] ? c : a)); - } - - /** - * Swaps the elements at two locations of an array - * - * @param i the first index - * @param j the second index - * @param a the array - */ - private static void swap(int i, int j, char[] a) - { - char c = a[i]; - a[i] = a[j]; - a[j] = c; - } - - /** - * Swaps two ranges of an array. - * - * @param i the first range start - * @param j the second range start - * @param n the element count - * @param a the array - */ - private static void vecswap(int i, int j, int n, char[] a) - { - for ( ; n > 0; i++, j++, n--) - swap(i, j, a); - } - - /** - * Performs a recursive modified quicksort. - * - * @param array the array to sort - * @param from the start index (inclusive) - * @param count the number of elements to sort - */ - private static void qsort(char[] array, int from, int count) - { - // Use an insertion sort on small arrays. - if (count <= 7) - { - for (int i = from + 1; i < from + count; i++) - for (int j = i; j > from && array[j - 1] > array[j]; j--) - swap(j, j - 1, array); - return; - } - - // Determine a good median element. - int mid = count / 2; - int lo = from; - int hi = from + count - 1; - - if (count > 40) - { // big arrays, pseudomedian of 9 - int s = count / 8; - lo = med3(lo, lo + s, lo + 2 * s, array); - mid = med3(mid - s, mid, mid + s, array); - hi = med3(hi - 2 * s, hi - s, hi, array); - } - mid = med3(lo, mid, hi, array); - - int a, b, c, d; - int comp; - - // Pull the median element out of the fray, and use it as a pivot. - swap(from, mid, array); - a = b = from; - c = d = from + count - 1; - - // Repeatedly move b and c to each other, swapping elements so - // that all elements before index b are less than the pivot, and all - // elements after index c are greater than the pivot. a and b track - // the elements equal to the pivot. - while (true) - { - while (b <= c && (comp = array[b] - array[from]) <= 0) - { - if (comp == 0) - { - swap(a, b, array); - a++; - } - b++; - } - while (c >= b && (comp = array[c] - array[from]) >= 0) - { - if (comp == 0) - { - swap(c, d, array); - d--; - } - c--; - } - if (b > c) - break; - swap(b, c, array); - b++; - c--; - } - - // Swap pivot(s) back in place, the recurse on left and right sections. - hi = from + count; - int span; - span = Math.min(a - from, b - a); - vecswap(from, b - span, span, array); - - span = Math.min(d - c, hi - d - 1); - vecswap(b, hi - span, span, array); - - span = b - a; - if (span > 1) - qsort(array, from, span); - - span = d - c; - if (span > 1) - qsort(array, hi - span, span); - } - - /** - * Performs a stable sort on the elements, arranging them according to their - * natural order. - * - * @param a the short array to sort - */ - public static void sort(short[] a) - { - qsort(a, 0, a.length); - } - - /** - * Performs a stable sort on the elements, arranging them according to their - * natural order. - * - * @param a the short array to sort - * @param fromIndex the first index to sort (inclusive) - * @param toIndex the last index to sort (exclusive) - * @throws IllegalArgumentException if fromIndex > toIndex - * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 - * || toIndex > a.length - */ - public static void sort(short[] a, int fromIndex, int toIndex) - { - if (fromIndex > toIndex) - throw new IllegalArgumentException(); - if (fromIndex < 0) - throw new ArrayIndexOutOfBoundsException(); - qsort(a, fromIndex, toIndex - fromIndex); - } - - /** - * Finds the index of the median of three array elements. - * - * @param a the first index - * @param b the second index - * @param c the third index - * @param d the array - * @return the index (a, b, or c) which has the middle value of the three - */ - private static int med3(int a, int b, int c, short[] d) - { - return (d[a] < d[b] - ? (d[b] < d[c] ? b : d[a] < d[c] ? c : a) - : (d[b] > d[c] ? b : d[a] > d[c] ? c : a)); - } - - /** - * Swaps the elements at two locations of an array - * - * @param i the first index - * @param j the second index - * @param a the array - */ - private static void swap(int i, int j, short[] a) - { - short c = a[i]; - a[i] = a[j]; - a[j] = c; - } - - /** - * Swaps two ranges of an array. - * - * @param i the first range start - * @param j the second range start - * @param n the element count - * @param a the array - */ - private static void vecswap(int i, int j, int n, short[] a) - { - for ( ; n > 0; i++, j++, n--) - swap(i, j, a); - } - - /** - * Performs a recursive modified quicksort. - * - * @param array the array to sort - * @param from the start index (inclusive) - * @param count the number of elements to sort - */ - private static void qsort(short[] array, int from, int count) - { - // Use an insertion sort on small arrays. - if (count <= 7) - { - for (int i = from + 1; i < from + count; i++) - for (int j = i; j > from && array[j - 1] > array[j]; j--) - swap(j, j - 1, array); - return; - } - - // Determine a good median element. - int mid = count / 2; - int lo = from; - int hi = from + count - 1; - - if (count > 40) - { // big arrays, pseudomedian of 9 - int s = count / 8; - lo = med3(lo, lo + s, lo + 2 * s, array); - mid = med3(mid - s, mid, mid + s, array); - hi = med3(hi - 2 * s, hi - s, hi, array); - } - mid = med3(lo, mid, hi, array); - - int a, b, c, d; - int comp; - - // Pull the median element out of the fray, and use it as a pivot. - swap(from, mid, array); - a = b = from; - c = d = from + count - 1; - - // Repeatedly move b and c to each other, swapping elements so - // that all elements before index b are less than the pivot, and all - // elements after index c are greater than the pivot. a and b track - // the elements equal to the pivot. - while (true) - { - while (b <= c && (comp = array[b] - array[from]) <= 0) - { - if (comp == 0) - { - swap(a, b, array); - a++; - } - b++; - } - while (c >= b && (comp = array[c] - array[from]) >= 0) - { - if (comp == 0) - { - swap(c, d, array); - d--; - } - c--; - } - if (b > c) - break; - swap(b, c, array); - b++; - c--; - } - - // Swap pivot(s) back in place, the recurse on left and right sections. - hi = from + count; - int span; - span = Math.min(a - from, b - a); - vecswap(from, b - span, span, array); - - span = Math.min(d - c, hi - d - 1); - vecswap(b, hi - span, span, array); - - span = b - a; - if (span > 1) - qsort(array, from, span); - - span = d - c; - if (span > 1) - qsort(array, hi - span, span); - } - - /** - * Performs a stable sort on the elements, arranging them according to their - * natural order. - * - * @param a the int array to sort - */ - public static void sort(int[] a) - { - qsort(a, 0, a.length); - } - - /** - * Performs a stable sort on the elements, arranging them according to their - * natural order. - * - * @param a the int array to sort - * @param fromIndex the first index to sort (inclusive) - * @param toIndex the last index to sort (exclusive) - * @throws IllegalArgumentException if fromIndex > toIndex - * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 - * || toIndex > a.length - */ - public static void sort(int[] a, int fromIndex, int toIndex) - { - if (fromIndex > toIndex) - throw new IllegalArgumentException(); - if (fromIndex < 0) - throw new ArrayIndexOutOfBoundsException(); - qsort(a, fromIndex, toIndex - fromIndex); - } - - /** - * Finds the index of the median of three array elements. - * - * @param a the first index - * @param b the second index - * @param c the third index - * @param d the array - * @return the index (a, b, or c) which has the middle value of the three - */ - private static int med3(int a, int b, int c, int[] d) - { - return (d[a] < d[b] - ? (d[b] < d[c] ? b : d[a] < d[c] ? c : a) - : (d[b] > d[c] ? b : d[a] > d[c] ? c : a)); - } - - /** - * Swaps the elements at two locations of an array - * - * @param i the first index - * @param j the second index - * @param a the array - */ - private static void swap(int i, int j, int[] a) - { - int c = a[i]; - a[i] = a[j]; - a[j] = c; - } - - /** - * Swaps two ranges of an array. - * - * @param i the first range start - * @param j the second range start - * @param n the element count - * @param a the array - */ - private static void vecswap(int i, int j, int n, int[] a) - { - for ( ; n > 0; i++, j++, n--) - swap(i, j, a); - } - - /** - * Compares two integers in natural order, since a - b is inadequate. - * - * @param a the first int - * @param b the second int - * @return < 0, 0, or > 0 accorting to the comparison - */ - private static int compare(int a, int b) - { - return a < b ? -1 : a == b ? 0 : 1; - } - - /** - * Performs a recursive modified quicksort. - * - * @param array the array to sort - * @param from the start index (inclusive) - * @param count the number of elements to sort - */ - private static void qsort(int[] array, int from, int count) - { - // Use an insertion sort on small arrays. - if (count <= 7) - { - for (int i = from + 1; i < from + count; i++) - for (int j = i; j > from && array[j - 1] > array[j]; j--) - swap(j, j - 1, array); - return; - } - - // Determine a good median element. - int mid = count / 2; - int lo = from; - int hi = from + count - 1; - - if (count > 40) - { // big arrays, pseudomedian of 9 - int s = count / 8; - lo = med3(lo, lo + s, lo + 2 * s, array); - mid = med3(mid - s, mid, mid + s, array); - hi = med3(hi - 2 * s, hi - s, hi, array); - } - mid = med3(lo, mid, hi, array); - - int a, b, c, d; - int comp; - - // Pull the median element out of the fray, and use it as a pivot. - swap(from, mid, array); - a = b = from; - c = d = from + count - 1; - - // Repeatedly move b and c to each other, swapping elements so - // that all elements before index b are less than the pivot, and all - // elements after index c are greater than the pivot. a and b track - // the elements equal to the pivot. - while (true) - { - while (b <= c && (comp = compare(array[b], array[from])) <= 0) - { - if (comp == 0) - { - swap(a, b, array); - a++; - } - b++; - } - while (c >= b && (comp = compare(array[c], array[from])) >= 0) - { - if (comp == 0) - { - swap(c, d, array); - d--; - } - c--; - } - if (b > c) - break; - swap(b, c, array); - b++; - c--; - } - - // Swap pivot(s) back in place, the recurse on left and right sections. - hi = from + count; - int span; - span = Math.min(a - from, b - a); - vecswap(from, b - span, span, array); - - span = Math.min(d - c, hi - d - 1); - vecswap(b, hi - span, span, array); - - span = b - a; - if (span > 1) - qsort(array, from, span); - - span = d - c; - if (span > 1) - qsort(array, hi - span, span); - } - - /** - * Performs a stable sort on the elements, arranging them according to their - * natural order. - * - * @param a the long array to sort - */ - public static void sort(long[] a) - { - qsort(a, 0, a.length); - } - - /** - * Performs a stable sort on the elements, arranging them according to their - * natural order. - * - * @param a the long array to sort - * @param fromIndex the first index to sort (inclusive) - * @param toIndex the last index to sort (exclusive) - * @throws IllegalArgumentException if fromIndex > toIndex - * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 - * || toIndex > a.length - */ - public static void sort(long[] a, int fromIndex, int toIndex) - { - if (fromIndex > toIndex) - throw new IllegalArgumentException(); - if (fromIndex < 0) - throw new ArrayIndexOutOfBoundsException(); - qsort(a, fromIndex, toIndex - fromIndex); - } - - /** - * Finds the index of the median of three array elements. - * - * @param a the first index - * @param b the second index - * @param c the third index - * @param d the array - * @return the index (a, b, or c) which has the middle value of the three - */ - private static int med3(int a, int b, int c, long[] d) - { - return (d[a] < d[b] - ? (d[b] < d[c] ? b : d[a] < d[c] ? c : a) - : (d[b] > d[c] ? b : d[a] > d[c] ? c : a)); - } - - /** - * Swaps the elements at two locations of an array - * - * @param i the first index - * @param j the second index - * @param a the array - */ - private static void swap(int i, int j, long[] a) - { - long c = a[i]; - a[i] = a[j]; - a[j] = c; - } - - /** - * Swaps two ranges of an array. - * - * @param i the first range start - * @param j the second range start - * @param n the element count - * @param a the array - */ - private static void vecswap(int i, int j, int n, long[] a) - { - for ( ; n > 0; i++, j++, n--) - swap(i, j, a); - } - - /** - * Compares two longs in natural order, since a - b is inadequate. - * - * @param a the first long - * @param b the second long - * @return < 0, 0, or > 0 accorting to the comparison - */ - private static int compare(long a, long b) - { - return a < b ? -1 : a == b ? 0 : 1; - } - - /** - * Performs a recursive modified quicksort. - * - * @param array the array to sort - * @param from the start index (inclusive) - * @param count the number of elements to sort - */ - private static void qsort(long[] array, int from, int count) - { - // Use an insertion sort on small arrays. - if (count <= 7) - { - for (int i = from + 1; i < from + count; i++) - for (int j = i; j > from && array[j - 1] > array[j]; j--) - swap(j, j - 1, array); - return; - } - - // Determine a good median element. - int mid = count / 2; - int lo = from; - int hi = from + count - 1; - - if (count > 40) - { // big arrays, pseudomedian of 9 - int s = count / 8; - lo = med3(lo, lo + s, lo + 2 * s, array); - mid = med3(mid - s, mid, mid + s, array); - hi = med3(hi - 2 * s, hi - s, hi, array); - } - mid = med3(lo, mid, hi, array); - - int a, b, c, d; - int comp; - - // Pull the median element out of the fray, and use it as a pivot. - swap(from, mid, array); - a = b = from; - c = d = from + count - 1; - - // Repeatedly move b and c to each other, swapping elements so - // that all elements before index b are less than the pivot, and all - // elements after index c are greater than the pivot. a and b track - // the elements equal to the pivot. - while (true) - { - while (b <= c && (comp = compare(array[b], array[from])) <= 0) - { - if (comp == 0) - { - swap(a, b, array); - a++; - } - b++; - } - while (c >= b && (comp = compare(array[c], array[from])) >= 0) - { - if (comp == 0) - { - swap(c, d, array); - d--; - } - c--; - } - if (b > c) - break; - swap(b, c, array); - b++; - c--; - } - - // Swap pivot(s) back in place, the recurse on left and right sections. - hi = from + count; - int span; - span = Math.min(a - from, b - a); - vecswap(from, b - span, span, array); - - span = Math.min(d - c, hi - d - 1); - vecswap(b, hi - span, span, array); - - span = b - a; - if (span > 1) - qsort(array, from, span); - - span = d - c; - if (span > 1) - qsort(array, hi - span, span); - } - - /** - * Performs a stable sort on the elements, arranging them according to their - * natural order. - * - * @param a the float array to sort - */ - public static void sort(float[] a) - { - qsort(a, 0, a.length); - } - - /** - * Performs a stable sort on the elements, arranging them according to their - * natural order. - * - * @param a the float array to sort - * @param fromIndex the first index to sort (inclusive) - * @param toIndex the last index to sort (exclusive) - * @throws IllegalArgumentException if fromIndex > toIndex - * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 - * || toIndex > a.length - */ - public static void sort(float[] a, int fromIndex, int toIndex) - { - if (fromIndex > toIndex) - throw new IllegalArgumentException(); - if (fromIndex < 0) - throw new ArrayIndexOutOfBoundsException(); - qsort(a, fromIndex, toIndex - fromIndex); - } - - /** - * Finds the index of the median of three array elements. - * - * @param a the first index - * @param b the second index - * @param c the third index - * @param d the array - * @return the index (a, b, or c) which has the middle value of the three - */ - private static int med3(int a, int b, int c, float[] d) - { - return (Float.compare(d[a], d[b]) < 0 - ? (Float.compare(d[b], d[c]) < 0 ? b - : Float.compare(d[a], d[c]) < 0 ? c : a) - : (Float.compare(d[b], d[c]) > 0 ? b - : Float.compare(d[a], d[c]) > 0 ? c : a)); - } - - /** - * Swaps the elements at two locations of an array - * - * @param i the first index - * @param j the second index - * @param a the array - */ - private static void swap(int i, int j, float[] a) - { - float c = a[i]; - a[i] = a[j]; - a[j] = c; - } - - /** - * Swaps two ranges of an array. - * - * @param i the first range start - * @param j the second range start - * @param n the element count - * @param a the array - */ - private static void vecswap(int i, int j, int n, float[] a) - { - for ( ; n > 0; i++, j++, n--) - swap(i, j, a); - } - - /** - * Performs a recursive modified quicksort. - * - * @param array the array to sort - * @param from the start index (inclusive) - * @param count the number of elements to sort - */ - private static void qsort(float[] array, int from, int count) - { - // Use an insertion sort on small arrays. - if (count <= 7) - { - for (int i = from + 1; i < from + count; i++) - for (int j = i; - j > from && Float.compare(array[j - 1], array[j]) > 0; - j--) - { - swap(j, j - 1, array); - } - return; - } - - // Determine a good median element. - int mid = count / 2; - int lo = from; - int hi = from + count - 1; - - if (count > 40) - { // big arrays, pseudomedian of 9 - int s = count / 8; - lo = med3(lo, lo + s, lo + 2 * s, array); - mid = med3(mid - s, mid, mid + s, array); - hi = med3(hi - 2 * s, hi - s, hi, array); - } - mid = med3(lo, mid, hi, array); - - int a, b, c, d; - int comp; - - // Pull the median element out of the fray, and use it as a pivot. - swap(from, mid, array); - a = b = from; - c = d = from + count - 1; - - // Repeatedly move b and c to each other, swapping elements so - // that all elements before index b are less than the pivot, and all - // elements after index c are greater than the pivot. a and b track - // the elements equal to the pivot. - while (true) - { - while (b <= c && (comp = Float.compare(array[b], array[from])) <= 0) - { - if (comp == 0) - { - swap(a, b, array); - a++; - } - b++; - } - while (c >= b && (comp = Float.compare(array[c], array[from])) >= 0) - { - if (comp == 0) - { - swap(c, d, array); - d--; - } - c--; - } - if (b > c) - break; - swap(b, c, array); - b++; - c--; - } - - // Swap pivot(s) back in place, the recurse on left and right sections. - hi = from + count; - int span; - span = Math.min(a - from, b - a); - vecswap(from, b - span, span, array); - - span = Math.min(d - c, hi - d - 1); - vecswap(b, hi - span, span, array); - - span = b - a; - if (span > 1) - qsort(array, from, span); - - span = d - c; - if (span > 1) - qsort(array, hi - span, span); - } - - /** - * Performs a stable sort on the elements, arranging them according to their - * natural order. - * - * @param a the double array to sort - */ - public static void sort(double[] a) - { - qsort(a, 0, a.length); - } - - /** - * Performs a stable sort on the elements, arranging them according to their - * natural order. - * - * @param a the double array to sort - * @param fromIndex the first index to sort (inclusive) - * @param toIndex the last index to sort (exclusive) - * @throws IllegalArgumentException if fromIndex > toIndex - * @throws ArrayIndexOutOfBoundsException if fromIndex < 0 - * || toIndex > a.length - */ - public static void sort(double[] a, int fromIndex, int toIndex) - { - if (fromIndex > toIndex) - throw new IllegalArgumentException(); - if (fromIndex < 0) - throw new ArrayIndexOutOfBoundsException(); - qsort(a, fromIndex, toIndex - fromIndex); - } - - /** - * Finds the index of the median of three array elements. - * - * @param a the first index - * @param b the second index - * @param c the third index - * @param d the array - * @return the index (a, b, or c) which has the middle value of the three - */ - private static int med3(int a, int b, int c, double[] d) - { - return (Double.compare(d[a], d[b]) < 0 - ? (Double.compare(d[b], d[c]) < 0 ? b - : Double.compare(d[a], d[c]) < 0 ? c : a) - : (Double.compare(d[b], d[c]) > 0 ? b - : Double.compare(d[a], d[c]) > 0 ? c : a)); - } - - /** - * Swaps the elements at two locations of an array - * - * @param i the first index - * @param j the second index - * @param a the array - */ - private static void swap(int i, int j, double[] a) - { - double c = a[i]; - a[i] = a[j]; - a[j] = c; - } - - /** - * Swaps two ranges of an array. - * - * @param i the first range start - * @param j the second range start - * @param n the element count - * @param a the array - */ - private static void vecswap(int i, int j, int n, double[] a) - { - for ( ; n > 0; i++, j++, n--) - swap(i, j, a); - } - - /** - * Performs a recursive modified quicksort. - * - * @param array the array to sort - * @param from the start index (inclusive) - * @param count the number of elements to sort - */ - private static void qsort(double[] array, int from, int count) - { - // Use an insertion sort on small arrays. - if (count <= 7) - { - for (int i = from + 1; i < from + count; i++) - for (int j = i; - j > from && Double.compare(array[j - 1], array[j]) > 0; - j--) - { - swap(j, j - 1, array); - } - return; - } - - // Determine a good median element. - int mid = count / 2; - int lo = from; - int hi = from + count - 1; - - if (count > 40) - { // big arrays, pseudomedian of 9 - int s = count / 8; - lo = med3(lo, lo + s, lo + 2 * s, array); - mid = med3(mid - s, mid, mid + s, array); - hi = med3(hi - 2 * s, hi - s, hi, array); - } - mid = med3(lo, mid, hi, array); - - int a, b, c, d; - int comp; - - // Pull the median element out of the fray, and use it as a pivot. - swap(from, mid, array); - a = b = from; - c = d = from + count - 1; - - // Repeatedly move b and c to each other, swapping elements so - // that all elements before index b are less than the pivot, and all - // elements after index c are greater than the pivot. a and b track - // the elements equal to the pivot. - while (true) - { - while (b <= c && (comp = Double.compare(array[b], array[from])) <= 0) - { - if (comp == 0) - { - swap(a, b, array); - a++; - } - b++; - } - while (c >= b && (comp = Double.compare(array[c], array[from])) >= 0) - { - if (comp == 0) - { - swap(c, d, array); - d--; - } - c--; - } - if (b > c) - break; - swap(b, c, array); - b++; - c--; - } - - // Swap pivot(s) back in place, the recurse on left and right sections. - hi = from + count; - int span; - span = Math.min(a - from, b - a); - vecswap(from, b - span, span, array); - - span = Math.min(d - c, hi - d - 1); - vecswap(b, hi - span, span, array); - - span = b - a; - if (span > 1) - qsort(array, from, span); - - span = d - c; - if (span > 1) - qsort(array, hi - span, span); - } - - /** - * Sort an array of Objects according to their natural ordering. The sort is - * guaranteed to be stable, that is, equal elements will not be reordered. - * The sort algorithm is a mergesort with the merge omitted if the last - * element of one half comes before the first element of the other half. This - * algorithm gives guaranteed O(n*log(n)) time, at the expense of making a - * copy of the array. - * - * @param a the array to be sorted - * @throws ClassCastException if any two elements are not mutually - * comparable - * @throws NullPointerException if an element is null (since - * null.compareTo cannot work) - * @see Comparable - */ - public static void sort(Object[] a) - { - sort(a, 0, a.length, null); - } - - /** - * Sort an array of Objects according to a Comparator. The sort is - * guaranteed to be stable, that is, equal elements will not be reordered. - * The sort algorithm is a mergesort with the merge omitted if the last - * element of one half comes before the first element of the other half. This - * algorithm gives guaranteed O(n*log(n)) time, at the expense of making a - * copy of the array. - * - * @param a the array to be sorted - * @param c a Comparator to use in sorting the array; or null to indicate - * the elements' natural order - * @throws ClassCastException if any two elements are not mutually - * comparable by the Comparator provided - * @throws NullPointerException if a null element is compared with natural - * ordering (only possible when c is null) - */ - public static void sort(Object[] a, Comparator c) - { - sort(a, 0, a.length, c); - } - - /** - * Sort an array of Objects according to their natural ordering. The sort is - * guaranteed to be stable, that is, equal elements will not be reordered. - * The sort algorithm is a mergesort with the merge omitted if the last - * element of one half comes before the first element of the other half. This - * algorithm gives guaranteed O(n*log(n)) time, at the expense of making a - * copy of the array. - * - * @param a the array to be sorted - * @param fromIndex the index of the first element to be sorted - * @param toIndex the index of the last element to be sorted plus one - * @throws ClassCastException if any two elements are not mutually - * comparable - * @throws NullPointerException if an element is null (since - * null.compareTo cannot work) - * @throws ArrayIndexOutOfBoundsException if fromIndex and toIndex - * are not in range. - * @throws IllegalArgumentException if fromIndex > toIndex - */ - public static void sort(Object[] a, int fromIndex, int toIndex) - { - sort(a, fromIndex, toIndex, null); - } - - /** - * Sort an array of Objects according to a Comparator. The sort is - * guaranteed to be stable, that is, equal elements will not be reordered. - * The sort algorithm is a mergesort with the merge omitted if the last - * element of one half comes before the first element of the other half. This - * algorithm gives guaranteed O(n*log(n)) time, at the expense of making a - * copy of the array. - * - * @param a the array to be sorted - * @param fromIndex the index of the first element to be sorted - * @param toIndex the index of the last element to be sorted plus one - * @param c a Comparator to use in sorting the array; or null to indicate - * the elements' natural order - * @throws ClassCastException if any two elements are not mutually - * comparable by the Comparator provided - * @throws ArrayIndexOutOfBoundsException if fromIndex and toIndex - * are not in range. - * @throws IllegalArgumentException if fromIndex > toIndex - * @throws NullPointerException if a null element is compared with natural - * ordering (only possible when c is null) - */ - public static void sort(Object[] a, int fromIndex, int toIndex, Comparator c) - { - if (fromIndex > toIndex) - throw new IllegalArgumentException("fromIndex " + fromIndex - + " > toIndex " + toIndex); - if (fromIndex < 0) - throw new ArrayIndexOutOfBoundsException(); - - // In general, the code attempts to be simple rather than fast, the - // idea being that a good optimising JIT will be able to optimise it - // better than I can, and if I try it will make it more confusing for - // the JIT. First presort the array in chunks of length 6 with insertion - // sort. A mergesort would give too much overhead for this length. - for (int chunk = fromIndex; chunk < toIndex; chunk += 6) - { - int end = Math.min(chunk + 6, toIndex); - for (int i = chunk + 1; i < end; i++) - { - if (Collections.compare(a[i - 1], a[i], c) > 0) - { - // not already sorted - int j = i; - Object elem = a[j]; - do - { - a[j] = a[j - 1]; - j--; - } - while (j > chunk - && Collections.compare(a[j - 1], elem, c) > 0); - a[j] = elem; - } - } - } - - int len = toIndex - fromIndex; - // If length is smaller or equal 6 we are done. - if (len <= 6) - return; - - Object[] src = a; - Object[] dest = new Object[len]; - Object[] t = null; // t is used for swapping src and dest - - // The difference of the fromIndex of the src and dest array. - int srcDestDiff = -fromIndex; - - // The merges are done in this loop - for (int size = 6; size < len; size <<= 1) - { - for (int start = fromIndex; start < toIndex; start += size << 1) - { - // mid is the start of the second sublist; - // end the start of the next sublist (or end of array). - int mid = start + size; - int end = Math.min(toIndex, mid + size); - - // The second list is empty or the elements are already in - // order - no need to merge - if (mid >= end - || Collections.compare(src[mid - 1], src[mid], c) <= 0) - { - System.arraycopy(src, start, - dest, start + srcDestDiff, end - start); - - // The two halves just need swapping - no need to merge - } - else if (Collections.compare(src[start], src[end - 1], c) > 0) - { - System.arraycopy(src, start, - dest, end - size + srcDestDiff, size); - System.arraycopy(src, mid, - dest, start + srcDestDiff, end - mid); - - } - else - { - // Declare a lot of variables to save repeating - // calculations. Hopefully a decent JIT will put these - // in registers and make this fast - int p1 = start; - int p2 = mid; - int i = start + srcDestDiff; - - // The main merge loop; terminates as soon as either - // half is ended - while (p1 < mid && p2 < end) - { - dest[i++] = - src[(Collections.compare(src[p1], src[p2], c) <= 0 - ? p1++ : p2++)]; - } - - // Finish up by copying the remainder of whichever half - // wasn't finished. - if (p1 < mid) - System.arraycopy(src, p1, dest, i, mid - p1); - else - System.arraycopy(src, p2, dest, i, end - p2); - } - } - // swap src and dest ready for the next merge - t = src; - src = dest; - dest = t; - fromIndex += srcDestDiff; - toIndex += srcDestDiff; - srcDestDiff = -srcDestDiff; - } - - // make sure the result ends up back in the right place. Note - // that src and dest may have been swapped above, so src - // contains the sorted array. - if (src != a) - { - // Note that fromIndex == 0. - System.arraycopy(src, 0, a, srcDestDiff, toIndex); - } - } - - /** - * Returns a list "view" of the specified array. This method is intended to - * make it easy to use the Collections API with existing array-based APIs and - * programs. Changes in the list or the array show up in both places. The - * list does not support element addition or removal, but does permit - * value modification. The returned list implements both Serializable and - * RandomAccess. - * - * @param a the array to return a view of - * @return a fixed-size list, changes to which "write through" to the array - * @see Serializable - * @see RandomAccess - * @see Arrays.ArrayList - */ - public static List asList(final Object[] a) - { - return new Arrays.ArrayList(a); - } - - /** - * Inner class used by {@link #asList(Object[])} to provide a list interface - * to an array. The name, though it clashes with java.util.ArrayList, is - * Sun's choice for Serialization purposes. Element addition and removal - * is prohibited, but values can be modified. - * - * @author Eric Blake (ebb9@email.byu.edu) - * @status updated to 1.4 - */ - private static final class ArrayList extends AbstractList - implements Serializable, RandomAccess - { - // We override the necessary methods, plus others which will be much - // more efficient with direct iteration rather than relying on iterator(). - - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = -2764017481108945198L; - - /** - * The array we are viewing. - * @serial the array - */ - private final Object[] a; - - /** - * Construct a list view of the array. - * @param a the array to view - * @throws NullPointerException if a is null - */ - ArrayList(Object[] a) - { - // We have to explicitly check. - if (a == null) - throw new NullPointerException(); - this.a = a; - } - - /** - * Returns the object at the specified index in - * the array. - * - * @param index The index to retrieve an object from. - * @return The object at the array index specified. - */ - public Object get(int index) - { - return a[index]; - } - - /** - * Returns the size of the array. - * - * @return The size. - */ - public int size() - { - return a.length; - } - - /** - * Replaces the object at the specified index - * with the supplied element. - * - * @param index The index at which to place the new object. - * @param element The new object. - * @return The object replaced by this operation. - */ - public Object set(int index, Object element) - { - Object old = a[index]; - a[index] = element; - return old; - } - - /** - * Returns true if the array contains the - * supplied object. - * - * @param o The object to look for. - * @return True if the object was found. - */ - public boolean contains(Object o) - { - return lastIndexOf(o) >= 0; - } - - /** - * Returns the first index at which the - * object, o, occurs in the array. - * - * @param o The object to search for. - * @return The first relevant index. - */ - public int indexOf(Object o) - { - int size = a.length; - for (int i = 0; i < size; i++) - if (ArrayList.equals(o, a[i])) - return i; - return -1; - } - - /** - * Returns the last index at which the - * object, o, occurs in the array. - * - * @param o The object to search for. - * @return The last relevant index. - */ - public int lastIndexOf(Object o) - { - int i = a.length; - while (--i >= 0) - if (ArrayList.equals(o, a[i])) - return i; - return -1; - } - - /** - * Transforms the list into an array of - * objects, by simplying cloning the array - * wrapped by this list. - * - * @return A clone of the internal array. - */ - public Object[] toArray() - { - return (Object[]) a.clone(); - } - - /** - * Copies the objects from this list into - * the supplied array. The supplied array - * is shrunk or enlarged to the size of the - * internal array, and filled with its objects. - * - * @param array The array to fill with the objects in this list. - * @return The array containing the objects in this list, - * which may or may not be == to array. - */ - public Object[] toArray(Object[] array) - { - int size = a.length; - if (array.length < size) - array = (Object[]) - Array.newInstance(array.getClass().getComponentType(), size); - else if (array.length > size) - array[size] = null; - - System.arraycopy(a, 0, array, 0, size); - return array; - } - } -} diff --git a/libjava/java/util/BitSet.java b/libjava/java/util/BitSet.java deleted file mode 100644 index 891f185334c..00000000000 --- a/libjava/java/util/BitSet.java +++ /dev/null @@ -1,744 +0,0 @@ -/* BitSet.java -- A vector of bits. - Copyright (C) 1998, 1999, 2000, 2001, 2004, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package java.util; -import java.io.Serializable; - -/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3 - * hashCode algorithm taken from JDK 1.2 docs. - */ - -/** - * This class can be thought of in two ways. You can see it as a - * vector of bits or as a set of non-negative integers. The name - * <code>BitSet</code> is a bit misleading. - * - * It is implemented by a bit vector, but its equally possible to see - * it as set of non-negative integer; each integer in the set is - * represented by a set bit at the corresponding index. The size of - * this structure is determined by the highest integer in the set. - * - * You can union, intersect and build (symmetric) remainders, by - * invoking the logical operations and, or, andNot, resp. xor. - * - * This implementation is NOT synchronized against concurrent access from - * multiple threads. Specifically, if one thread is reading from a bitset - * while another thread is simultaneously modifying it, the results are - * undefined. - * - * @author Jochen Hoenicke - * @author Tom Tromey (tromey@cygnus.com) - * @author Eric Blake (ebb9@email.byu.edu) - * @status updated to 1.4 - */ -public class BitSet implements Cloneable, Serializable -{ - /** - * Compatible with JDK 1.0. - */ - private static final long serialVersionUID = 7997698588986878753L; - - /** - * A common mask. - */ - private static final int LONG_MASK = 0x3f; - - /** - * The actual bits. - * @serial the i'th bit is in bits[i/64] at position i%64 (where position - * 0 is the least significant). - */ - private long[] bits; - - /** - * Create a new empty bit set. All bits are initially false. - */ - public BitSet() - { - this(64); - } - - /** - * Create a new empty bit set, with a given size. This - * constructor reserves enough space to represent the integers - * from <code>0</code> to <code>nbits-1</code>. - * - * @param nbits the initial size of the bit set - * @throws NegativeArraySizeException if nbits < 0 - */ - public BitSet(int nbits) - { - if (nbits < 0) - throw new NegativeArraySizeException(); - - int length = nbits >>> 6; - if ((nbits & LONG_MASK) != 0) - ++length; - bits = new long[length]; - } - - /** - * Performs the logical AND operation on this bit set and the - * given <code>set</code>. This means it builds the intersection - * of the two sets. The result is stored into this bit set. - * - * @param set the second bit set - * @throws NullPointerException if set is null - */ - public void and(BitSet bs) - { - int max = Math.min(bits.length, bs.bits.length); - int i; - for (i = 0; i < max; ++i) - bits[i] &= bs.bits[i]; - while (i < bits.length) - bits[i++] = 0; - } - - /** - * Performs the logical AND operation on this bit set and the - * complement of the given <code>set</code>. This means it - * selects every element in the first set, that isn't in the - * second set. The result is stored into this bit set and is - * effectively the set difference of the two. - * - * @param set the second bit set - * @throws NullPointerException if set is null - * @since 1.2 - */ - public void andNot(BitSet bs) - { - int i = Math.min(bits.length, bs.bits.length); - while (--i >= 0) - bits[i] &= ~bs.bits[i]; - } - - /** - * Returns the number of bits set to true. - * - * @return the number of true bits - * @since 1.4 - */ - public int cardinality() - { - int card = 0; - for (int i = bits.length - 1; i >= 0; i--) - { - long a = bits[i]; - // Take care of common cases. - if (a == 0) - continue; - if (a == -1) - { - card += 64; - continue; - } - - // Successively collapse alternating bit groups into a sum. - a = ((a >> 1) & 0x5555555555555555L) + (a & 0x5555555555555555L); - a = ((a >> 2) & 0x3333333333333333L) + (a & 0x3333333333333333L); - int b = (int) ((a >>> 32) + a); - b = ((b >> 4) & 0x0f0f0f0f) + (b & 0x0f0f0f0f); - b = ((b >> 8) & 0x00ff00ff) + (b & 0x00ff00ff); - card += ((b >> 16) & 0x0000ffff) + (b & 0x0000ffff); - } - return card; - } - - /** - * Sets all bits in the set to false. - * - * @since 1.4 - */ - public void clear() - { - Arrays.fill(bits, 0); - } - - /** - * Removes the integer <code>bitIndex</code> from this set. That is - * the corresponding bit is cleared. If the index is not in the set, - * this method does nothing. - * - * @param bitIndex a non-negative integer - * @throws IndexOutOfBoundsException if bitIndex < 0 - */ - public void clear(int pos) - { - int offset = pos >> 6; - ensure(offset); - // ArrayIndexOutOfBoundsException subclasses IndexOutOfBoundsException, - // so we'll just let that be our exception. - bits[offset] &= ~(1L << pos); - } - - /** - * Sets the bits between from (inclusive) and to (exclusive) to false. - * - * @param from the start range (inclusive) - * @param to the end range (exclusive) - * @throws IndexOutOfBoundsException if from < 0 || to < 0 || - * from > to - * @since 1.4 - */ - public void clear(int from, int to) - { - if (from < 0 || from > to) - throw new IndexOutOfBoundsException(); - if (from == to) - return; - int lo_offset = from >>> 6; - int hi_offset = to >>> 6; - ensure(hi_offset); - if (lo_offset == hi_offset) - { - bits[hi_offset] &= ((1L << from) - 1) | (-1L << to); - return; - } - - bits[lo_offset] &= (1L << from) - 1; - bits[hi_offset] &= -1L << to; - for (int i = lo_offset + 1; i < hi_offset; i++) - bits[i] = 0; - } - - /** - * Create a clone of this bit set, that is an instance of the same - * class and contains the same elements. But it doesn't change when - * this bit set changes. - * - * @return the clone of this object. - */ - public Object clone() - { - try - { - BitSet bs = (BitSet) super.clone(); - bs.bits = (long[]) bits.clone(); - return bs; - } - catch (CloneNotSupportedException e) - { - // Impossible to get here. - return null; - } - } - - /** - * Returns true if the <code>obj</code> is a bit set that contains - * exactly the same elements as this bit set, otherwise false. - * - * @param obj the object to compare to - * @return true if obj equals this bit set - */ - public boolean equals(Object obj) - { - if (!(obj instanceof BitSet)) - return false; - BitSet bs = (BitSet) obj; - int max = Math.min(bits.length, bs.bits.length); - int i; - for (i = 0; i < max; ++i) - if (bits[i] != bs.bits[i]) - return false; - // If one is larger, check to make sure all extra bits are 0. - for (int j = i; j < bits.length; ++j) - if (bits[j] != 0) - return false; - for (int j = i; j < bs.bits.length; ++j) - if (bs.bits[j] != 0) - return false; - return true; - } - - /** - * Sets the bit at the index to the opposite value. - * - * @param index the index of the bit - * @throws IndexOutOfBoundsException if index is negative - * @since 1.4 - */ - public void flip(int index) - { - int offset = index >> 6; - ensure(offset); - // ArrayIndexOutOfBoundsException subclasses IndexOutOfBoundsException, - // so we'll just let that be our exception. - bits[offset] ^= 1L << index; - } - - /** - * Sets a range of bits to the opposite value. - * - * @param from the low index (inclusive) - * @param to the high index (exclusive) - * @throws IndexOutOfBoundsException if from > to || from < 0 || - * to < 0 - * @since 1.4 - */ - public void flip(int from, int to) - { - if (from < 0 || from > to) - throw new IndexOutOfBoundsException(); - if (from == to) - return; - int lo_offset = from >>> 6; - int hi_offset = to >>> 6; - ensure(hi_offset); - if (lo_offset == hi_offset) - { - bits[hi_offset] ^= (-1L << from) & ((1L << to) - 1); - return; - } - - bits[lo_offset] ^= -1L << from; - bits[hi_offset] ^= (1L << to) - 1; - for (int i = lo_offset + 1; i < hi_offset; i++) - bits[i] ^= -1; - } - - /** - * Returns true if the integer <code>bitIndex</code> is in this bit - * set, otherwise false. - * - * @param pos a non-negative integer - * @return the value of the bit at the specified index - * @throws IndexOutOfBoundsException if the index is negative - */ - public boolean get(int pos) - { - int offset = pos >> 6; - if (offset >= bits.length) - return false; - // ArrayIndexOutOfBoundsException subclasses IndexOutOfBoundsException, - // so we'll just let that be our exception. - return (bits[offset] & (1L << pos)) != 0; - } - - /** - * Returns a new <code>BitSet</code> composed of a range of bits from - * this one. - * - * @param from the low index (inclusive) - * @param to the high index (exclusive) - * @throws IndexOutOfBoundsException if from > to || from < 0 || - * to < 0 - * @since 1.4 - */ - public BitSet get(int from, int to) - { - if (from < 0 || from > to) - throw new IndexOutOfBoundsException(); - BitSet bs = new BitSet(to - from); - int lo_offset = from >>> 6; - if (lo_offset >= bits.length) - return bs; - - int lo_bit = from & LONG_MASK; - int hi_offset = to >>> 6; - if (lo_bit == 0) - { - int len = Math.min(hi_offset - lo_offset + 1, bits.length - lo_offset); - System.arraycopy(bits, lo_offset, bs.bits, 0, len); - if (hi_offset < bits.length) - bs.bits[hi_offset - lo_offset] &= (1L << to) - 1; - return bs; - } - - int len = Math.min(hi_offset, bits.length - 1); - int reverse = 64 - lo_bit; - int i; - for (i = 0; lo_offset < len; lo_offset++, i++) - bs.bits[i] = ((bits[lo_offset] >>> lo_bit) - | (bits[lo_offset + 1] << reverse)); - if ((to & LONG_MASK) > lo_bit) - bs.bits[i++] = bits[lo_offset] >>> lo_bit; - if (hi_offset < bits.length) - bs.bits[i - 1] &= (1L << (to - from)) - 1; - return bs; - } - - /** - * Returns a hash code value for this bit set. The hash code of - * two bit sets containing the same integers is identical. The algorithm - * used to compute it is as follows: - * - * Suppose the bits in the BitSet were to be stored in an array of - * long integers called <code>bits</code>, in such a manner that - * bit <code>k</code> is set in the BitSet (for non-negative values - * of <code>k</code>) if and only if - * - * <code>((k/64) < bits.length) - * && ((bits[k/64] & (1L << (bit % 64))) != 0) - * </code> - * - * Then the following definition of the hashCode method - * would be a correct implementation of the actual algorithm: - * - * -<pre>public int hashCode() -{ - long h = 1234; - for (int i = bits.length-1; i >= 0; i--) - { - h ^= bits[i] * (i + 1); - } - - return (int)((h >> 32) ^ h); -}</pre> - * - * Note that the hash code values changes, if the set is changed. - * - * @return the hash code value for this bit set. - */ - public int hashCode() - { - long h = 1234; - for (int i = bits.length; i > 0; ) - h ^= i * bits[--i]; - return (int) ((h >> 32) ^ h); - } - - /** - * Returns true if the specified BitSet and this one share at least one - * common true bit. - * - * @param set the set to check for intersection - * @return true if the sets intersect - * @throws NullPointerException if set is null - * @since 1.4 - */ - public boolean intersects(BitSet set) - { - int i = Math.min(bits.length, set.bits.length); - while (--i >= 0) - if ((bits[i] & set.bits[i]) != 0) - return true; - return false; - } - - /** - * Returns true if this set contains no true bits. - * - * @return true if all bits are false - * @since 1.4 - */ - public boolean isEmpty() - { - for (int i = bits.length - 1; i >= 0; i--) - if (bits[i] != 0) - return false; - return true; - } - - /** - * Returns the logical number of bits actually used by this bit - * set. It returns the index of the highest set bit plus one. - * Note that this method doesn't return the number of set bits. - * - * @return the index of the highest set bit plus one. - */ - public int length() - { - // Set i to highest index that contains a non-zero value. - int i; - for (i = bits.length - 1; i >= 0 && bits[i] == 0; --i) - ; - - // if i < 0 all bits are cleared. - if (i < 0) - return 0; - - // Now determine the exact length. - long b = bits[i]; - int len = (i + 1) * 64; - // b >= 0 checks if the highest bit is zero. - while (b >= 0) - { - --len; - b <<= 1; - } - - return len; - } - - /** - * Returns the index of the next false bit, from the specified bit - * (inclusive). - * - * @param from the start location - * @return the first false bit - * @throws IndexOutOfBoundsException if from is negative - * @since 1.4 - */ - public int nextClearBit(int from) - { - int offset = from >> 6; - long mask = 1L << from; - while (offset < bits.length) - { - // ArrayIndexOutOfBoundsException subclasses IndexOutOfBoundsException, - // so we'll just let that be our exception. - long h = bits[offset]; - do - { - if ((h & mask) == 0) - return from; - mask <<= 1; - from++; - } - while (mask != 0); - mask = 1; - offset++; - } - return from; - } - - /** - * Returns the index of the next true bit, from the specified bit - * (inclusive). If there is none, -1 is returned. You can iterate over - * all true bits with this loop:<br> - * -<pre>for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1)) -{ - // operate on i here -}</pre> - * - * @param from the start location - * @return the first true bit, or -1 - * @throws IndexOutOfBoundsException if from is negative - * @since 1.4 - */ - public int nextSetBit(int from) - { - int offset = from >> 6; - long mask = 1L << from; - while (offset < bits.length) - { - // ArrayIndexOutOfBoundsException subclasses IndexOutOfBoundsException, - // so we'll just let that be our exception. - long h = bits[offset]; - do - { - if ((h & mask) != 0) - return from; - mask <<= 1; - from++; - } - while (mask != 0); - mask = 1; - offset++; - } - return -1; - } - - /** - * Performs the logical OR operation on this bit set and the - * given <code>set</code>. This means it builds the union - * of the two sets. The result is stored into this bit set, which - * grows as necessary. - * - * @param bs the second bit set - * @throws NullPointerException if bs is null - */ - public void or(BitSet bs) - { - ensure(bs.bits.length - 1); - for (int i = bs.bits.length - 1; i >= 0; i--) - bits[i] |= bs.bits[i]; - } - - /** - * Add the integer <code>bitIndex</code> to this set. That is - * the corresponding bit is set to true. If the index was already in - * the set, this method does nothing. The size of this structure - * is automatically increased as necessary. - * - * @param pos a non-negative integer. - * @throws IndexOutOfBoundsException if pos is negative - */ - public void set(int pos) - { - int offset = pos >> 6; - ensure(offset); - // ArrayIndexOutOfBoundsException subclasses IndexOutOfBoundsException, - // so we'll just let that be our exception. - bits[offset] |= 1L << pos; - } - - /** - * Sets the bit at the given index to the specified value. The size of - * this structure is automatically increased as necessary. - * - * @param index the position to set - * @param value the value to set it to - * @throws IndexOutOfBoundsException if index is negative - * @since 1.4 - */ - public void set(int index, boolean value) - { - if (value) - set(index); - else - clear(index); - } - - /** - * Sets the bits between from (inclusive) and to (exclusive) to true. - * - * @param from the start range (inclusive) - * @param to the end range (exclusive) - * @throws IndexOutOfBoundsException if from < 0 || from > to || - * to < 0 - * @since 1.4 - */ - public void set(int from, int to) - { - if (from < 0 || from > to) - throw new IndexOutOfBoundsException(); - if (from == to) - return; - int lo_offset = from >>> 6; - int hi_offset = to >>> 6; - ensure(hi_offset); - if (lo_offset == hi_offset) - { - bits[hi_offset] |= (-1L << from) & ((1L << to) - 1); - return; - } - - bits[lo_offset] |= -1L << from; - bits[hi_offset] |= (1L << to) - 1; - for (int i = lo_offset + 1; i < hi_offset; i++) - bits[i] = -1; - } - - /** - * Sets the bits between from (inclusive) and to (exclusive) to the - * specified value. - * - * @param from the start range (inclusive) - * @param to the end range (exclusive) - * @param value the value to set it to - * @throws IndexOutOfBoundsException if from < 0 || from > to || - * to < 0 - * @since 1.4 - */ - public void set(int from, int to, boolean value) - { - if (value) - set(from, to); - else - clear(from, to); - } - - /** - * Returns the number of bits actually used by this bit set. Note - * that this method doesn't return the number of set bits, and that - * future requests for larger bits will make this automatically grow. - * - * @return the number of bits currently used. - */ - public int size() - { - return bits.length * 64; - } - - /** - * Returns the string representation of this bit set. This - * consists of a comma separated list of the integers in this set - * surrounded by curly braces. There is a space after each comma. - * A sample string is thus "{1, 3, 53}". - * @return the string representation. - */ - public String toString() - { - StringBuffer r = new StringBuffer("{"); - boolean first = true; - for (int i = 0; i < bits.length; ++i) - { - long bit = 1; - long word = bits[i]; - if (word == 0) - continue; - for (int j = 0; j < 64; ++j) - { - if ((word & bit) != 0) - { - if (! first) - r.append(", "); - r.append(64 * i + j); - first = false; - } - bit <<= 1; - } - } - return r.append("}").toString(); - } - - /** - * Performs the logical XOR operation on this bit set and the - * given <code>set</code>. This means it builds the symmetric - * remainder of the two sets (the elements that are in one set, - * but not in the other). The result is stored into this bit set, - * which grows as necessary. - * - * @param bs the second bit set - * @throws NullPointerException if bs is null - */ - public void xor(BitSet bs) - { - ensure(bs.bits.length - 1); - for (int i = bs.bits.length - 1; i >= 0; i--) - bits[i] ^= bs.bits[i]; - } - - /** - * Make sure the vector is big enough. - * - * @param lastElt the size needed for the bits array - */ - private void ensure(int lastElt) - { - if (lastElt >= bits.length) - { - long[] nd = new long[lastElt + 1]; - System.arraycopy(bits, 0, nd, 0, bits.length); - bits = nd; - } - } -} diff --git a/libjava/java/util/Collection.java b/libjava/java/util/Collection.java deleted file mode 100644 index 29e1b3786b4..00000000000 --- a/libjava/java/util/Collection.java +++ /dev/null @@ -1,288 +0,0 @@ -/* Collection.java -- Interface that represents a collection of objects - Copyright (C) 1998, 2001, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -/** - * Interface that represents a collection of objects. This interface is the - * root of the collection hierarchy, and does not provide any guarantees about - * the order of its elements or whether or not duplicate elements are - * permitted. - * <p> - * All methods of this interface that are defined to modify the collection are - * defined as <dfn>optional</dfn>. An optional operation may throw an - * UnsupportedOperationException if the data backing this collection does not - * support such a modification. This may mean that the data structure is - * immutable, or that it is read-only but may change ("unmodifiable"), or - * that it is modifiable but of fixed size (such as an array), or any number - * of other combinations. - * <p> - * A class that wishes to implement this interface should consider subclassing - * AbstractCollection, which provides basic implementations of most of the - * methods of this interface. Classes that are prepared to make guarantees - * about ordering or about absence of duplicate elements should consider - * implementing List or Set respectively, both of which are subinterfaces of - * Collection. - * <p> - * A general-purpose implementation of the Collection interface should in most - * cases provide at least two constructors: One which takes no arguments and - * creates an empty collection, and one which takes a Collection as an argument - * and returns a collection containing the same elements (that is, creates a - * copy of the argument using its own implementation). - * - * @author Original author unknown - * @author Eric Blake (ebb9@email.byu.edu) - * @see List - * @see Set - * @see Map - * @see SortedSet - * @see SortedMap - * @see HashSet - * @see TreeSet - * @see ArrayList - * @see LinkedList - * @see Vector - * @see Collections - * @see Arrays - * @see AbstractCollection - * @since 1.2 - * @status updated to 1.4 - */ -public interface Collection -{ - /** - * Add an element to this collection. - * - * @param o the object to add. - * @return true if the collection was modified as a result of this action. - * @throws UnsupportedOperationException if this collection does not - * support the add operation. - * @throws ClassCastException if o cannot be added to this collection due - * to its type. - * @throws NullPointerException if o is null and this collection doesn't - * support the addition of null values. - * @throws IllegalArgumentException if o cannot be added to this - * collection for some other reason. - */ - boolean add(Object o); - - /** - * Add the contents of a given collection to this collection. - * - * @param c the collection to add. - * @return true if the collection was modified as a result of this action. - * @throws UnsupportedOperationException if this collection does not - * support the addAll operation. - * @throws ClassCastException if some element of c cannot be added to this - * collection due to its type. - * @throws NullPointerException if some element of c is null and this - * collection does not support the addition of null values. - * @throws NullPointerException if c itself is null. - * @throws IllegalArgumentException if some element of c cannot be added - * to this collection for some other reason. - */ - boolean addAll(Collection c); - - /** - * Clear the collection, such that a subsequent call to isEmpty() would - * return true. - * - * @throws UnsupportedOperationException if this collection does not - * support the clear operation. - */ - void clear(); - - /** - * Test whether this collection contains a given object as one of its - * elements. - * - * @param o the element to look for. - * @return true if this collection contains at least one element e such that - * <code>o == null ? e == null : o.equals(e)</code>. - * @throws ClassCastException if the type of o is not a valid type for this - * collection. - * @throws NullPointerException if o is null and this collection doesn't - * support null values. - */ - boolean contains(Object o); - - /** - * Test whether this collection contains every element in a given collection. - * - * @param c the collection to test for. - * @return true if for every element o in c, contains(o) would return true. - * @throws ClassCastException if the type of any element in c is not a valid - * type for this collection. - * @throws NullPointerException if some element of c is null and this - * collection does not support null values. - * @throws NullPointerException if c itself is null. - */ - boolean containsAll(Collection c); - - /** - * Test whether this collection is equal to some object. The Collection - * interface does not explicitly require any behaviour from this method, and - * it may be left to the default implementation provided by Object. The Set - * and List interfaces do, however, require specific behaviour from this - * method. - * <p> - * If an implementation of Collection, which is not also an implementation of - * Set or List, should choose to implement this method, it should take care - * to obey the contract of the equals method of Object. In particular, care - * should be taken to return false when o is a Set or a List, in order to - * preserve the symmetry of the relation. - * - * @param o the object to compare to this collection. - * @return true if the o is equal to this collection. - */ - boolean equals(Object o); - - /** - * Obtain a hash code for this collection. The Collection interface does not - * explicitly require any behaviour from this method, and it may be left to - * the default implementation provided by Object. The Set and List interfaces - * do, however, require specific behaviour from this method. - * <p> - * If an implementation of Collection, which is not also an implementation of - * Set or List, should choose to implement this method, it should take care - * to obey the contract of the hashCode method of Object. Note that this - * method renders it impossible to correctly implement both Set and List, as - * the required implementations are mutually exclusive. - * - * @return a hash code for this collection. - */ - int hashCode(); - - /** - * Test whether this collection is empty, that is, if size() == 0. - * - * @return true if this collection contains no elements. - */ - boolean isEmpty(); - - /** - * Obtain an Iterator over this collection. - * - * @return an Iterator over the elements of this collection, in any order. - */ - Iterator iterator(); - - /** - * Remove a single occurrence of an object from this collection. That is, - * remove an element e, if one exists, such that <code>o == null ? e == null - * : o.equals(e)</code>. - * - * @param o the object to remove. - * @return true if the collection changed as a result of this call, that is, - * if the collection contained at least one occurrence of o. - * @throws UnsupportedOperationException if this collection does not - * support the remove operation. - * @throws ClassCastException if the type of o is not a valid type - * for this collection. - * @throws NullPointerException if o is null and the collection doesn't - * support null values. - */ - boolean remove(Object o); - - /** - * Remove all elements of a given collection from this collection. That is, - * remove every element e such that c.contains(e). - * - * @param c The collection of objects to be removed. - * @return true if this collection was modified as a result of this call. - * @throws UnsupportedOperationException if this collection does not - * support the removeAll operation. - * @throws ClassCastException if the type of any element in c is not a valid - * type for this collection. - * @throws NullPointerException if some element of c is null and this - * collection does not support removing null values. - * @throws NullPointerException if c itself is null. - */ - boolean removeAll(Collection c); - - /** - * Remove all elements of this collection that are not contained in a given - * collection. That is, remove every element e such that !c.contains(e). - * - * @param c The collection of objects to be retained. - * @return true if this collection was modified as a result of this call. - * @throws UnsupportedOperationException if this collection does not - * support the retainAll operation. - * @throws ClassCastException if the type of any element in c is not a valid - * type for this collection. - * @throws NullPointerException if some element of c is null and this - * collection does not support retaining null values. - * @throws NullPointerException if c itself is null. - */ - boolean retainAll(Collection c); - - /** - * Get the number of elements in this collection. - * - * @return the number of elements in the collection. - */ - int size(); - - /** - * Copy the current contents of this collection into an array. - * - * @return an array of type Object[] and length equal to the size of this - * collection, containing the elements currently in this collection, in - * any order. - */ - Object[] toArray(); - - /** - * Copy the current contents of this collection into an array. If the array - * passed as an argument has length less than the size of this collection, an - * array of the same run-time type as a, and length equal to the size of this - * collection, is allocated using Reflection. Otherwise, a itself is used. - * The elements of this collection are copied into it, and if there is space - * in the array, the following element is set to null. The resultant array is - * returned. - * Note: The fact that the following element is set to null is only useful - * if it is known that this collection does not contain any null elements. - * - * @param a the array to copy this collection into. - * @return an array containing the elements currently in this collection, in - * any order. - * @throws ArrayStoreException if the type of any element of the - * collection is not a subtype of the element type of a. - */ - Object[] toArray(Object[] a); -} diff --git a/libjava/java/util/Collections.java b/libjava/java/util/Collections.java deleted file mode 100644 index 64eb8da3585..00000000000 --- a/libjava/java/util/Collections.java +++ /dev/null @@ -1,5493 +0,0 @@ -/* Collections.java -- Utility class with methods to operate on collections - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005 - 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -import java.io.Serializable; - -/** - * Utility class consisting of static methods that operate on, or return - * Collections. Contains methods to sort, search, reverse, fill and shuffle - * Collections, methods to facilitate interoperability with legacy APIs that - * are unaware of collections, a method to return a list which consists of - * multiple copies of one element, and methods which "wrap" collections to give - * them extra properties, such as thread-safety and unmodifiability. - * <p> - * - * All methods which take a collection throw a {@link NullPointerException} if - * that collection is null. Algorithms which can change a collection may, but - * are not required, to throw the {@link UnsupportedOperationException} that - * the underlying collection would throw during an attempt at modification. - * For example, - * <code>Collections.singleton("").addAll(Collections.EMPTY_SET)</code> - * does not throw a exception, even though addAll is an unsupported operation - * on a singleton; the reason for this is that addAll did not attempt to - * modify the set. - * - * @author Original author unknown - * @author Eric Blake (ebb9@email.byu.edu) - * @see Collection - * @see Set - * @see List - * @see Map - * @see Arrays - * @since 1.2 - * @status updated to 1.4 - */ -public class Collections -{ - /** - * Constant used to decide cutoff for when a non-RandomAccess list should - * be treated as sequential-access. Basically, quadratic behavior is - * acceptable for small lists when the overhead is so small in the first - * place. I arbitrarily set it to 16, so it may need some tuning. - */ - private static final int LARGE_LIST_SIZE = 16; - - /** - * Determines if a list should be treated as a sequential-access one. - * Rather than the old method of JDK 1.3 of assuming only instanceof - * AbstractSequentialList should be sequential, this uses the new method - * of JDK 1.4 of assuming anything that does NOT implement RandomAccess - * and exceeds a large (unspecified) size should be sequential. - * - * @param l the list to check - * @return <code>true</code> if it should be treated as sequential-access - */ - private static boolean isSequential(List l) - { - return ! (l instanceof RandomAccess) && l.size() > LARGE_LIST_SIZE; - } - - /** - * This class is non-instantiable. - */ - private Collections() - { - } - - /** - * An immutable, serializable, empty Set. - * @see Serializable - */ - public static final Set EMPTY_SET = new EmptySet(); - - /** - * The implementation of {@link #EMPTY_SET}. This class name is required - * for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class EmptySet extends AbstractSet - implements Serializable - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 1582296315990362920L; - - /** - * A private constructor adds overhead. - */ - EmptySet() - { - } - - /** - * The size: always 0! - * @return 0. - */ - public int size() - { - return 0; - } - - /** - * Returns an iterator that does not iterate. - * @return A non-iterating iterator. - */ - // This is really cheating! I think it's perfectly valid, though. - public Iterator iterator() - { - return EMPTY_LIST.iterator(); - } - - // The remaining methods are optional, but provide a performance - // advantage by not allocating unnecessary iterators in AbstractSet. - /** - * The empty set never contains anything. - * @param o The object to search for. - * @return <code>false</code>. - */ - public boolean contains(Object o) - { - return false; - } - - /** - * This is true only if the given collection is also empty. - * @param c The collection of objects which are to be compared - * against the members of this set. - * @return <code>true</code> if c is empty. - */ - public boolean containsAll(Collection c) - { - return c.isEmpty(); - } - - /** - * Equal only if the other set is empty. - * @param o The object to compare with this set. - * @return <code>true</code> if o is an empty instance of <code>Set</code>. - */ - public boolean equals(Object o) - { - return o instanceof Set && ((Set) o).isEmpty(); - } - - /** - * The hashcode is always 0. - * @return 0. - */ - public int hashCode() - { - return 0; - } - - /** - * Always succeeds with a <code>false</code> result. - * @param o The object to remove. - * @return <code>false</code>. - */ - public boolean remove(Object o) - { - return false; - } - - /** - * Always succeeds with a <code>false</code> result. - * @param c The collection of objects which should - * all be removed from this set. - * @return <code>false</code>. - */ - public boolean removeAll(Collection c) - { - return false; - } - - /** - * Always succeeds with a <code>false</code> result. - * @param c The collection of objects which should - * all be retained within this set. - * @return <code>false</code>. - */ - public boolean retainAll(Collection c) - { - return false; - } - - /** - * The array is always empty. - * @return A new array with a size of 0. - */ - public Object[] toArray() - { - return new Object[0]; - } - - /** - * We don't even need to use reflection! - * @param a An existing array, which can be empty. - * @return The original array with any existing - * initial element set to null. - */ - public Object[] toArray(Object[] a) - { - if (a.length > 0) - a[0] = null; - return a; - } - - /** - * The string never changes. - * - * @return the string "[]". - */ - public String toString() - { - return "[]"; - } - } // class EmptySet - - /** - * An immutable, serializable, empty List, which implements RandomAccess. - * @see Serializable - * @see RandomAccess - */ - public static final List EMPTY_LIST = new EmptyList(); - - /** - * The implementation of {@link #EMPTY_LIST}. This class name is required - * for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class EmptyList extends AbstractList - implements Serializable, RandomAccess - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 8842843931221139166L; - - /** - * A private constructor adds overhead. - */ - EmptyList() - { - } - - /** - * The size is always 0. - * @return 0. - */ - public int size() - { - return 0; - } - - /** - * No matter the index, it is out of bounds. This - * method never returns, throwing an exception instead. - * - * @param index The index of the element to retrieve. - * @return the object at the specified index. - * @throws IndexOutofBoundsException as any given index - * is outside the bounds of an empty array. - */ - public Object get(int index) - { - throw new IndexOutOfBoundsException(); - } - - // The remaining methods are optional, but provide a performance - // advantage by not allocating unnecessary iterators in AbstractList. - /** - * Never contains anything. - * @param o The object to search for. - * @return <code>false</code>. - */ - public boolean contains(Object o) - { - return false; - } - - /** - * This is true only if the given collection is also empty. - * @param c The collection of objects, which should be compared - * against the members of this list. - * @return <code>true</code> if c is also empty. - */ - public boolean containsAll(Collection c) - { - return c.isEmpty(); - } - - /** - * Equal only if the other list is empty. - * @param o The object to compare against this list. - * @return <code>true</code> if o is also an empty instance of - * <code>List</code>. - */ - public boolean equals(Object o) - { - return o instanceof List && ((List) o).isEmpty(); - } - - /** - * The hashcode is always 1. - * @return 1. - */ - public int hashCode() - { - return 1; - } - - /** - * Returns -1. - * @param o The object to search for. - * @return -1. - */ - public int indexOf(Object o) - { - return -1; - } - - /** - * Returns -1. - * @param o The object to search for. - * @return -1. - */ - public int lastIndexOf(Object o) - { - return -1; - } - - /** - * Always succeeds with <code>false</code> result. - * @param o The object to remove. - * @return -1. - */ - public boolean remove(Object o) - { - return false; - } - - /** - * Always succeeds with <code>false</code> result. - * @param c The collection of objects which should - * all be removed from this list. - * @return <code>false</code>. - */ - public boolean removeAll(Collection c) - { - return false; - } - - /** - * Always succeeds with <code>false</code> result. - * @param c The collection of objects which should - * all be retained within this list. - * @return <code>false</code>. - */ - public boolean retainAll(Collection c) - { - return false; - } - - /** - * The array is always empty. - * @return A new array with a size of 0. - */ - public Object[] toArray() - { - return new Object[0]; - } - - /** - * We don't even need to use reflection! - * @param a An existing array, which can be empty. - * @return The original array with any existing - * initial element set to null. - */ - public Object[] toArray(Object[] a) - { - if (a.length > 0) - a[0] = null; - return a; - } - - /** - * The string never changes. - * - * @return the string "[]". - */ - public String toString() - { - return "[]"; - } - } // class EmptyList - - /** - * An immutable, serializable, empty Map. - * @see Serializable - */ - public static final Map EMPTY_MAP = new EmptyMap(); - - /** - * The implementation of {@link #EMPTY_MAP}. This class name is required - * for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class EmptyMap extends AbstractMap - implements Serializable - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 6428348081105594320L; - - /** - * A private constructor adds overhead. - */ - EmptyMap() - { - } - - /** - * There are no entries. - * @return The empty set. - */ - public Set entrySet() - { - return EMPTY_SET; - } - - // The remaining methods are optional, but provide a performance - // advantage by not allocating unnecessary iterators in AbstractMap. - /** - * No entries! - * @param key The key to search for. - * @return <code>false</code>. - */ - public boolean containsKey(Object key) - { - return false; - } - - /** - * No entries! - * @param value The value to search for. - * @return <code>false</code>. - */ - public boolean containsValue(Object value) - { - return false; - } - - /** - * Equal to all empty maps. - * @param o The object o to compare against this map. - * @return <code>true</code> if o is also an empty instance of - * <code>Map</code>. - */ - public boolean equals(Object o) - { - return o instanceof Map && ((Map) o).isEmpty(); - } - - /** - * No mappings, so this returns null. - * @param o The key of the object to retrieve. - * @return null. - */ - public Object get(Object o) - { - return null; - } - - /** - * The hashcode is always 0. - * @return 0. - */ - public int hashCode() - { - return 0; - } - - /** - * No entries. - * @return The empty set. - */ - public Set keySet() - { - return EMPTY_SET; - } - - /** - * Remove always succeeds, with null result. - * @param o The key of the mapping to remove. - * @return null, as there is never a mapping for o. - */ - public Object remove(Object o) - { - return null; - } - - /** - * Size is always 0. - * @return 0. - */ - public int size() - { - return 0; - } - - /** - * No entries. Technically, EMPTY_SET, while more specific than a general - * Collection, will work. Besides, that's what the JDK uses! - * @return The empty set. - */ - public Collection values() - { - return EMPTY_SET; - } - - /** - * The string never changes. - * - * @return the string "[]". - */ - public String toString() - { - return "[]"; - } - } // class EmptyMap - - - /** - * Compare two objects with or without a Comparator. If c is null, uses the - * natural ordering. Slightly slower than doing it inline if the JVM isn't - * clever, but worth it for removing a duplicate of the search code. - * Note: This code is also used in Arrays (for sort as well as search). - */ - static final int compare(Object o1, Object o2, Comparator c) - { - return c == null ? ((Comparable) o1).compareTo(o2) : c.compare(o1, o2); - } - - /** - * Perform a binary search of a List for a key, using the natural ordering of - * the elements. The list must be sorted (as by the sort() method) - if it is - * not, the behavior of this method is undefined, and may be an infinite - * loop. Further, the key must be comparable with every item in the list. If - * the list contains the key more than once, any one of them may be found. - * <p> - * - * This algorithm behaves in log(n) time for {@link RandomAccess} lists, - * and uses a linear search with O(n) link traversals and log(n) comparisons - * with {@link AbstractSequentialList} lists. Note: although the - * specification allows for an infinite loop if the list is unsorted, it will - * not happen in this (Classpath) implementation. - * - * @param l the list to search (must be sorted) - * @param key the value to search for - * @return the index at which the key was found, or -n-1 if it was not - * found, where n is the index of the first value higher than key or - * a.length if there is no such value - * @throws ClassCastException if key could not be compared with one of the - * elements of l - * @throws NullPointerException if a null element has compareTo called - * @see #sort(List) - */ - public static int binarySearch(List l, Object key) - { - return binarySearch(l, key, null); - } - - /** - * Perform a binary search of a List for a key, using a supplied Comparator. - * The list must be sorted (as by the sort() method with the same Comparator) - * - if it is not, the behavior of this method is undefined, and may be an - * infinite loop. Further, the key must be comparable with every item in the - * list. If the list contains the key more than once, any one of them may be - * found. If the comparator is null, the elements' natural ordering is used. - * <p> - * - * This algorithm behaves in log(n) time for {@link RandomAccess} lists, - * and uses a linear search with O(n) link traversals and log(n) comparisons - * with {@link AbstractSequentialList} lists. Note: although the - * specification allows for an infinite loop if the list is unsorted, it will - * not happen in this (Classpath) implementation. - * - * @param l the list to search (must be sorted) - * @param key the value to search for - * @param c the comparator by which the list is sorted - * @return the index at which the key was found, or -n-1 if it was not - * found, where n is the index of the first value higher than key or - * a.length if there is no such value - * @throws ClassCastException if key could not be compared with one of the - * elements of l - * @throws NullPointerException if a null element is compared with natural - * ordering (only possible when c is null) - * @see #sort(List, Comparator) - */ - public static int binarySearch(List l, Object key, Comparator c) - { - int pos = 0; - int low = 0; - int hi = l.size() - 1; - - // We use a linear search with log(n) comparisons using an iterator - // if the list is sequential-access. - if (isSequential(l)) - { - ListIterator itr = l.listIterator(); - int i = 0; - Object o = itr.next(); // Assumes list is not empty (see isSequential) - boolean forward = true; - while (low <= hi) - { - pos = (low + hi) >> 1; - if (i < pos) - { - if (!forward) - itr.next(); // Changing direction first. - for ( ; i != pos; i++, o = itr.next()); - forward = true; - } - else - { - if (forward) - itr.previous(); // Changing direction first. - for ( ; i != pos; i--, o = itr.previous()); - forward = false; - } - final int d = compare(key, o, c); - if (d == 0) - return pos; - else if (d < 0) - hi = pos - 1; - else - // This gets the insertion point right on the last loop - low = ++pos; - } - } - else - { - while (low <= hi) - { - pos = (low + hi) >> 1; - final int d = compare(key, l.get(pos), c); - if (d == 0) - return pos; - else if (d < 0) - hi = pos - 1; - else - // This gets the insertion point right on the last loop - low = ++pos; - } - } - - // If we failed to find it, we do the same whichever search we did. - return -pos - 1; - } - - /** - * Copy one list to another. If the destination list is longer than the - * source list, the remaining elements are unaffected. This method runs in - * linear time. - * - * @param dest the destination list - * @param source the source list - * @throws IndexOutOfBoundsException if the destination list is shorter - * than the source list (the destination will be unmodified) - * @throws UnsupportedOperationException if dest.listIterator() does not - * support the set operation - */ - public static void copy(List dest, List source) - { - int pos = source.size(); - if (dest.size() < pos) - throw new IndexOutOfBoundsException("Source does not fit in dest"); - - Iterator i1 = source.iterator(); - ListIterator i2 = dest.listIterator(); - - while (--pos >= 0) - { - i2.next(); - i2.set(i1.next()); - } - } - - /** - * Returns an Enumeration over a collection. This allows interoperability - * with legacy APIs that require an Enumeration as input. - * - * @param c the Collection to iterate over - * @return an Enumeration backed by an Iterator over c - */ - public static Enumeration enumeration(Collection c) - { - final Iterator i = c.iterator(); - return new Enumeration() - { - /** - * Returns <code>true</code> if there are more elements to - * be enumerated. - * - * @return The result of <code>hasNext()</code> - * called on the underlying iterator. - */ - public final boolean hasMoreElements() - { - return i.hasNext(); - } - - /** - * Returns the next element to be enumerated. - * - * @return The result of <code>next()</code> - * called on the underlying iterator. - */ - public final Object nextElement() - { - return i.next(); - } - }; - } - - /** - * Replace every element of a list with a given value. This method runs in - * linear time. - * - * @param l the list to fill. - * @param val the object to vill the list with. - * @throws UnsupportedOperationException if l.listIterator() does not - * support the set operation. - */ - public static void fill(List l, Object val) - { - ListIterator itr = l.listIterator(); - for (int i = l.size() - 1; i >= 0; --i) - { - itr.next(); - itr.set(val); - } - } - - /** - * Returns the starting index where the specified sublist first occurs - * in a larger list, or -1 if there is no matching position. If - * <code>target.size() > source.size()</code>, this returns -1, - * otherwise this implementation uses brute force, checking for - * <code>source.sublist(i, i + target.size()).equals(target)</code> - * for all possible i. - * - * @param source the list to search - * @param target the sublist to search for - * @return the index where found, or -1 - * @since 1.4 - */ - public static int indexOfSubList(List source, List target) - { - int ssize = source.size(); - for (int i = 0, j = target.size(); j <= ssize; i++, j++) - if (source.subList(i, j).equals(target)) - return i; - return -1; - } - - /** - * Returns the starting index where the specified sublist last occurs - * in a larger list, or -1 if there is no matching position. If - * <code>target.size() > source.size()</code>, this returns -1, - * otherwise this implementation uses brute force, checking for - * <code>source.sublist(i, i + target.size()).equals(target)</code> - * for all possible i. - * - * @param source the list to search - * @param target the sublist to search for - * @return the index where found, or -1 - * @since 1.4 - */ - public static int lastIndexOfSubList(List source, List target) - { - int ssize = source.size(); - for (int i = ssize - target.size(), j = ssize; i >= 0; i--, j--) - if (source.subList(i, j).equals(target)) - return i; - return -1; - } - - /** - * Returns an ArrayList holding the elements visited by a given - * Enumeration. This method exists for interoperability between legacy - * APIs and the new Collection API. - * - * @param e the enumeration to put in a list - * @return a list containing the enumeration elements - * @see ArrayList - * @since 1.4 - */ - public static ArrayList list(Enumeration e) - { - ArrayList l = new ArrayList(); - while (e.hasMoreElements()) - l.add(e.nextElement()); - return l; - } - - /** - * Find the maximum element in a Collection, according to the natural - * ordering of the elements. This implementation iterates over the - * Collection, so it works in linear time. - * - * @param c the Collection to find the maximum element of - * @return the maximum element of c - * @exception NoSuchElementException if c is empty - * @exception ClassCastException if elements in c are not mutually comparable - * @exception NullPointerException if null.compareTo is called - */ - public static Object max(Collection c) - { - return max(c, null); - } - - /** - * Find the maximum element in a Collection, according to a specified - * Comparator. This implementation iterates over the Collection, so it - * works in linear time. - * - * @param c the Collection to find the maximum element of - * @param order the Comparator to order the elements by, or null for natural - * ordering - * @return the maximum element of c - * @throws NoSuchElementException if c is empty - * @throws ClassCastException if elements in c are not mutually comparable - * @throws NullPointerException if null is compared by natural ordering - * (only possible when order is null) - */ - public static Object max(Collection c, Comparator order) - { - Iterator itr = c.iterator(); - Object max = itr.next(); // throws NoSuchElementException - int csize = c.size(); - for (int i = 1; i < csize; i++) - { - Object o = itr.next(); - if (compare(max, o, order) < 0) - max = o; - } - return max; - } - - /** - * Find the minimum element in a Collection, according to the natural - * ordering of the elements. This implementation iterates over the - * Collection, so it works in linear time. - * - * @param c the Collection to find the minimum element of - * @return the minimum element of c - * @throws NoSuchElementException if c is empty - * @throws ClassCastException if elements in c are not mutually comparable - * @throws NullPointerException if null.compareTo is called - */ - public static Object min(Collection c) - { - return min(c, null); - } - - /** - * Find the minimum element in a Collection, according to a specified - * Comparator. This implementation iterates over the Collection, so it - * works in linear time. - * - * @param c the Collection to find the minimum element of - * @param order the Comparator to order the elements by, or null for natural - * ordering - * @return the minimum element of c - * @throws NoSuchElementException if c is empty - * @throws ClassCastException if elements in c are not mutually comparable - * @throws NullPointerException if null is compared by natural ordering - * (only possible when order is null) - */ - public static Object min(Collection c, Comparator order) - { - Iterator itr = c.iterator(); - Object min = itr.next(); // throws NoSuchElementExcception - int csize = c.size(); - for (int i = 1; i < csize; i++) - { - Object o = itr.next(); - if (compare(min, o, order) > 0) - min = o; - } - return min; - } - - /** - * Creates an immutable list consisting of the same object repeated n times. - * The returned object is tiny, consisting of only a single reference to the - * object and a count of the number of elements. It is Serializable, and - * implements RandomAccess. You can use it in tandem with List.addAll for - * fast list construction. - * - * @param n the number of times to repeat the object - * @param o the object to repeat - * @return a List consisting of n copies of o - * @throws IllegalArgumentException if n < 0 - * @see List#addAll(Collection) - * @see Serializable - * @see RandomAccess - */ - public static List nCopies(final int n, final Object o) - { - return new CopiesList(n, o); - } - - /** - * The implementation of {@link #nCopies(int, Object)}. This class name - * is required for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class CopiesList extends AbstractList - implements Serializable, RandomAccess - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 2739099268398711800L; - - /** - * The count of elements in this list. - * @serial the list size - */ - private final int n; - - /** - * The repeated list element. - * @serial the list contents - */ - private final Object element; - - /** - * Constructs the list. - * - * @param n the count - * @param o the object - * @throws IllegalArgumentException if n < 0 - */ - CopiesList(int n, Object o) - { - if (n < 0) - throw new IllegalArgumentException(); - this.n = n; - element = o; - } - - /** - * The size is fixed. - * @return The size of the list. - */ - public int size() - { - return n; - } - - /** - * The same element is returned. - * @param index The index of the element to be returned (irrelevant - * as the list contains only copies of <code>element</code>). - * @return The element used by this list. - */ - public Object get(int index) - { - if (index < 0 || index >= n) - throw new IndexOutOfBoundsException(); - return element; - } - - // The remaining methods are optional, but provide a performance - // advantage by not allocating unnecessary iterators in AbstractList. - /** - * This list only contains one element. - * @param o The object to search for. - * @return <code>true</code> if o is the element used by this list. - */ - public boolean contains(Object o) - { - return n > 0 && equals(o, element); - } - - /** - * The index is either 0 or -1. - * @param o The object to find the index of. - * @return 0 if <code>o == element</code>, -1 if not. - */ - public int indexOf(Object o) - { - return (n > 0 && equals(o, element)) ? 0 : -1; - } - - /** - * The index is either n-1 or -1. - * @param o The object to find the last index of. - * @return The last index in the list if <code>o == element</code>, - * -1 if not. - */ - public int lastIndexOf(Object o) - { - return equals(o, element) ? n - 1 : -1; - } - - /** - * A subList is just another CopiesList. - * @param from The starting bound of the sublist. - * @param to The ending bound of the sublist. - * @return A list of copies containing <code>from - to</code> - * elements, all of which are equal to the element - * used by this list. - */ - public List subList(int from, int to) - { - if (from < 0 || to > n) - throw new IndexOutOfBoundsException(); - return new CopiesList(to - from, element); - } - - /** - * The array is easy. - * @return An array of size n filled with copies of - * the element used by this list. - */ - public Object[] toArray() - { - Object[] a = new Object[n]; - Arrays.fill(a, element); - return a; - } - - /** - * The string is easy to generate. - * @return A string representation of the list. - */ - public String toString() - { - StringBuffer r = new StringBuffer("{"); - for (int i = n - 1; --i > 0; ) - r.append(element).append(", "); - r.append(element).append("}"); - return r.toString(); - } - } // class CopiesList - - /** - * Replace all instances of one object with another in the specified list. - * The list does not change size. An element e is replaced if - * <code>oldval == null ? e == null : oldval.equals(e)</code>. - * - * @param list the list to iterate over - * @param oldval the element to replace - * @param newval the new value for the element - * @return <code>true</code> if a replacement occurred. - * @throws UnsupportedOperationException if the list iterator does not allow - * for the set operation - * @throws ClassCastException if newval is of a type which cannot be added - * to the list - * @throws IllegalArgumentException if some other aspect of newval stops - * it being added to the list - * @since 1.4 - */ - public static boolean replaceAll(List list, Object oldval, Object newval) - { - ListIterator itr = list.listIterator(); - boolean replace_occured = false; - for (int i = list.size(); --i >= 0; ) - if (AbstractCollection.equals(oldval, itr.next())) - { - itr.set(newval); - replace_occured = true; - } - return replace_occured; - } - - /** - * Reverse a given list. This method works in linear time. - * - * @param l the list to reverse - * @throws UnsupportedOperationException if l.listIterator() does not - * support the set operation - */ - public static void reverse(List l) - { - ListIterator i1 = l.listIterator(); - int pos1 = 1; - int pos2 = l.size(); - ListIterator i2 = l.listIterator(pos2); - while (pos1 < pos2) - { - Object o = i1.next(); - i1.set(i2.previous()); - i2.set(o); - ++pos1; - --pos2; - } - } - - /** - * Get a comparator that implements the reverse of natural ordering. In - * other words, this sorts Comparable objects opposite of how their - * compareTo method would sort. This makes it easy to sort into reverse - * order, by simply passing Collections.reverseOrder() to the sort method. - * The return value of this method is Serializable. - * - * @return a comparator that imposes reverse natural ordering - * @see Comparable - * @see Serializable - */ - public static Comparator reverseOrder() - { - return rcInstance; - } - - /** - * The object for {@link #reverseOrder()}. - */ - private static final ReverseComparator rcInstance = new ReverseComparator(); - - /** - * The implementation of {@link #reverseOrder()}. This class name - * is required for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class ReverseComparator - implements Comparator, Serializable - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 7207038068494060240L; - - /** - * A private constructor adds overhead. - */ - ReverseComparator() - { - } - - /** - * Compare two objects in reverse natural order. - * - * @param a the first object - * @param b the second object - * @return <, ==, or > 0 according to b.compareTo(a) - */ - public int compare(Object a, Object b) - { - return ((Comparable) b).compareTo(a); - } - } - - /** - * Rotate the elements in a list by a specified distance. After calling this - * method, the element now at index <code>i</code> was formerly at index - * <code>(i - distance) mod list.size()</code>. The list size is unchanged. - * <p> - * - * For example, suppose a list contains <code>[t, a, n, k, s]</code>. After - * either <code>Collections.rotate(l, 4)</code> or - * <code>Collections.rotate(l, -1)</code>, the new contents are - * <code>[s, t, a, n, k]</code>. This can be applied to sublists to rotate - * just a portion of the list. For example, to move element <code>a</code> - * forward two positions in the original example, use - * <code>Collections.rotate(l.subList(1, 3+1), -1)</code>, which will - * result in <code>[t, n, k, a, s]</code>. - * <p> - * - * If the list is small or implements {@link RandomAccess}, the - * implementation exchanges the first element to its destination, then the - * displaced element, and so on until a circuit has been completed. The - * process is repeated if needed on the second element, and so forth, until - * all elements have been swapped. For large non-random lists, the - * implementation breaks the list into two sublists at index - * <code>-distance mod size</code>, calls {@link #reverse(List)} on the - * pieces, then reverses the overall list. - * - * @param list the list to rotate - * @param distance the distance to rotate by; unrestricted in value - * @throws UnsupportedOperationException if the list does not support set - * @since 1.4 - */ - public static void rotate(List list, int distance) - { - int size = list.size(); - if (size == 0) - return; - distance %= size; - if (distance == 0) - return; - if (distance < 0) - distance += size; - - if (isSequential(list)) - { - reverse(list); - reverse(list.subList(0, distance)); - reverse(list.subList(distance, size)); - } - else - { - // Determine the least common multiple of distance and size, as there - // are (distance / LCM) loops to cycle through. - int a = size; - int lcm = distance; - int b = a % lcm; - while (b != 0) - { - a = lcm; - lcm = b; - b = a % lcm; - } - - // Now, make the swaps. We must take the remainder every time through - // the inner loop so that we don't overflow i to negative values. - while (--lcm >= 0) - { - Object o = list.get(lcm); - for (int i = lcm + distance; i != lcm; i = (i + distance) % size) - o = list.set(i, o); - list.set(lcm, o); - } - } - } - - /** - * Shuffle a list according to a default source of randomness. The algorithm - * used iterates backwards over the list, swapping each element with an - * element randomly selected from the elements in positions less than or - * equal to it (using r.nextInt(int)). - * <p> - * - * This algorithm would result in a perfectly fair shuffle (that is, each - * element would have an equal chance of ending up in any position) if r were - * a perfect source of randomness. In practice the results are merely very - * close to perfect. - * <p> - * - * This method operates in linear time. To do this on large lists which do - * not implement {@link RandomAccess}, a temporary array is used to acheive - * this speed, since it would be quadratic access otherwise. - * - * @param l the list to shuffle - * @throws UnsupportedOperationException if l.listIterator() does not - * support the set operation - */ - public static void shuffle(List l) - { - if (defaultRandom == null) - { - synchronized (Collections.class) - { - if (defaultRandom == null) - defaultRandom = new Random(); - } - } - shuffle(l, defaultRandom); - } - - /** - * Cache a single Random object for use by shuffle(List). This improves - * performance as well as ensuring that sequential calls to shuffle() will - * not result in the same shuffle order occurring: the resolution of - * System.currentTimeMillis() is not sufficient to guarantee a unique seed. - */ - private static Random defaultRandom = null; - - /** - * Shuffle a list according to a given source of randomness. The algorithm - * used iterates backwards over the list, swapping each element with an - * element randomly selected from the elements in positions less than or - * equal to it (using r.nextInt(int)). - * <p> - * - * This algorithm would result in a perfectly fair shuffle (that is, each - * element would have an equal chance of ending up in any position) if r were - * a perfect source of randomness. In practise (eg if r = new Random()) the - * results are merely very close to perfect. - * <p> - * - * This method operates in linear time. To do this on large lists which do - * not implement {@link RandomAccess}, a temporary array is used to acheive - * this speed, since it would be quadratic access otherwise. - * - * @param l the list to shuffle - * @param r the source of randomness to use for the shuffle - * @throws UnsupportedOperationException if l.listIterator() does not - * support the set operation - */ - public static void shuffle(List l, Random r) - { - int lsize = l.size(); - ListIterator i = l.listIterator(lsize); - boolean sequential = isSequential(l); - Object[] a = null; // stores a copy of the list for the sequential case - - if (sequential) - a = l.toArray(); - - for (int pos = lsize - 1; pos > 0; --pos) - { - // Obtain a random position to swap with. pos + 1 is used so that the - // range of the random number includes the current position. - int swap = r.nextInt(pos + 1); - - // Swap the desired element. - Object o; - if (sequential) - { - o = a[swap]; - a[swap] = i.previous(); - } - else - o = l.set(swap, i.previous()); - - i.set(o); - } - } - - - /** - * Obtain an immutable Set consisting of a single element. The return value - * of this method is Serializable. - * - * @param o the single element - * @return an immutable Set containing only o - * @see Serializable - */ - public static Set singleton(Object o) - { - return new SingletonSet(o); - } - - /** - * The implementation of {@link #singleton(Object)}. This class name - * is required for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class SingletonSet extends AbstractSet - implements Serializable - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 3193687207550431679L; - - - /** - * The single element; package visible for use in nested class. - * @serial the singleton - */ - final Object element; - - /** - * Construct a singleton. - * @param o the element - */ - SingletonSet(Object o) - { - element = o; - } - - /** - * The size: always 1! - * @return 1. - */ - public int size() - { - return 1; - } - - /** - * Returns an iterator over the lone element. - */ - public Iterator iterator() - { - return new Iterator() - { - /** - * Flag to indicate whether or not the element has - * been retrieved. - */ - private boolean hasNext = true; - - /** - * Returns <code>true</code> if elements still remain to be - * iterated through. - * - * @return <code>true</code> if the element has not yet been returned. - */ - public boolean hasNext() - { - return hasNext; - } - - /** - * Returns the element. - * - * @return The element used by this singleton. - * @throws NoSuchElementException if the object - * has already been retrieved. - */ - public Object next() - { - if (hasNext) - { - hasNext = false; - return element; - } - else - throw new NoSuchElementException(); - } - - /** - * Removes the element from the singleton. - * As this set is immutable, this will always - * throw an exception. - * - * @throws UnsupportedOperationException as the - * singleton set doesn't support - * <code>remove()</code>. - */ - public void remove() - { - throw new UnsupportedOperationException(); - } - }; - } - - // The remaining methods are optional, but provide a performance - // advantage by not allocating unnecessary iterators in AbstractSet. - /** - * The set only contains one element. - * - * @param o The object to search for. - * @return <code>true</code> if o == the element of the singleton. - */ - public boolean contains(Object o) - { - return equals(o, element); - } - - /** - * This is true if the other collection only contains the element. - * - * @param c A collection to compare against this singleton. - * @return <code>true</code> if c only contains either no elements or - * elements equal to the element in this singleton. - */ - public boolean containsAll(Collection c) - { - Iterator i = c.iterator(); - int pos = c.size(); - while (--pos >= 0) - if (! equals(i.next(), element)) - return false; - return true; - } - - /** - * The hash is just that of the element. - * - * @return The hashcode of the element. - */ - public int hashCode() - { - return hashCode(element); - } - - /** - * Returning an array is simple. - * - * @return An array containing the element. - */ - public Object[] toArray() - { - return new Object[] {element}; - } - - /** - * Obvious string. - * - * @return The string surrounded by enclosing - * square brackets. - */ - public String toString() - { - return "[" + element + "]"; - } - } // class SingletonSet - - /** - * Obtain an immutable List consisting of a single element. The return value - * of this method is Serializable, and implements RandomAccess. - * - * @param o the single element - * @return an immutable List containing only o - * @see Serializable - * @see RandomAccess - * @since 1.3 - */ - public static List singletonList(Object o) - { - return new SingletonList(o); - } - - /** - * The implementation of {@link #singletonList(Object)}. This class name - * is required for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class SingletonList extends AbstractList - implements Serializable, RandomAccess - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 3093736618740652951L; - - /** - * The single element. - * @serial the singleton - */ - private final Object element; - - /** - * Construct a singleton. - * @param o the element - */ - SingletonList(Object o) - { - element = o; - } - - /** - * The size: always 1! - * @return 1. - */ - public int size() - { - return 1; - } - - /** - * Only index 0 is valid. - * @param index The index of the element - * to retrieve. - * @return The singleton's element if the - * index is 0. - * @throws IndexOutOfBoundsException if - * index is not 0. - */ - public Object get(int index) - { - if (index == 0) - return element; - throw new IndexOutOfBoundsException(); - } - - // The remaining methods are optional, but provide a performance - // advantage by not allocating unnecessary iterators in AbstractList. - /** - * The set only contains one element. - * - * @param o The object to search for. - * @return <code>true</code> if o == the singleton element. - */ - public boolean contains(Object o) - { - return equals(o, element); - } - - /** - * This is true if the other collection only contains the element. - * - * @param c A collection to compare against this singleton. - * @return <code>true</code> if c only contains either no elements or - * elements equal to the element in this singleton. - */ - public boolean containsAll(Collection c) - { - Iterator i = c.iterator(); - int pos = c.size(); - while (--pos >= 0) - if (! equals(i.next(), element)) - return false; - return true; - } - - /** - * Speed up the hashcode computation. - * - * @return The hashcode of the list, based - * on the hashcode of the singleton element. - */ - public int hashCode() - { - return 31 + hashCode(element); - } - - /** - * Either the list has it or not. - * - * @param o The object to find the first index of. - * @return 0 if o is the singleton element, -1 if not. - */ - public int indexOf(Object o) - { - return equals(o, element) ? 0 : -1; - } - - /** - * Either the list has it or not. - * - * @param o The object to find the last index of. - * @return 0 if o is the singleton element, -1 if not. - */ - public int lastIndexOf(Object o) - { - return equals(o, element) ? 0 : -1; - } - - /** - * Sublists are limited in scope. - * - * @param from The starting bound for the sublist. - * @param to The ending bound for the sublist. - * @return Either an empty list if both bounds are - * 0 or 1, or this list if the bounds are 0 and 1. - * @throws IllegalArgumentException if <code>from > to</code> - * @throws IndexOutOfBoundsException if either bound is greater - * than 1. - */ - public List subList(int from, int to) - { - if (from == to && (to == 0 || to == 1)) - return EMPTY_LIST; - if (from == 0 && to == 1) - return this; - if (from > to) - throw new IllegalArgumentException(); - throw new IndexOutOfBoundsException(); - } - - /** - * Returning an array is simple. - * - * @return An array containing the element. - */ - public Object[] toArray() - { - return new Object[] {element}; - } - - /** - * Obvious string. - * - * @return The string surrounded by enclosing - * square brackets. - */ - public String toString() - { - return "[" + element + "]"; - } - } // class SingletonList - - /** - * Obtain an immutable Map consisting of a single key-value pair. - * The return value of this method is Serializable. - * - * @param key the single key - * @param value the single value - * @return an immutable Map containing only the single key-value pair - * @see Serializable - * @since 1.3 - */ - public static Map singletonMap(Object key, Object value) - { - return new SingletonMap(key, value); - } - - /** - * The implementation of {@link #singletonMap(Object)}. This class name - * is required for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class SingletonMap extends AbstractMap - implements Serializable - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = -6979724477215052911L; - - /** - * The single key. - * @serial the singleton key - */ - private final Object k; - - /** - * The corresponding value. - * @serial the singleton value - */ - private final Object v; - - /** - * Cache the entry set. - */ - private transient Set entries; - - /** - * Construct a singleton. - * @param key the key - * @param value the value - */ - SingletonMap(Object key, Object value) - { - k = key; - v = value; - } - - /** - * There is a single immutable entry. - * - * @return A singleton containing the map entry. - */ - public Set entrySet() - { - if (entries == null) - entries = singleton(new AbstractMap.BasicMapEntry(k, v) - { - /** - * Sets the value of the map entry to the supplied value. - * An exception is always thrown, as the map is immutable. - * - * @param o The new value. - * @return The old value. - * @throws UnsupportedOperationException as setting the value - * is not supported. - */ - public Object setValue(Object o) - { - throw new UnsupportedOperationException(); - } - }); - return entries; - } - - // The remaining methods are optional, but provide a performance - // advantage by not allocating unnecessary iterators in AbstractMap. - /** - * Single entry. - * - * @param key The key to look for. - * @return <code>true</code> if the key is the same as the one used by - * this map. - */ - public boolean containsKey(Object key) - { - return equals(key, k); - } - - /** - * Single entry. - * - * @param value The value to look for. - * @return <code>true</code> if the value is the same as the one used by - * this map. - */ - public boolean containsValue(Object value) - { - return equals(value, v); - } - - /** - * Single entry. - * - * @param key The key of the value to be retrieved. - * @return The singleton value if the key is the same as the - * singleton key, null otherwise. - */ - public Object get(Object key) - { - return equals(key, k) ? v : null; - } - - /** - * Calculate the hashcode directly. - * - * @return The hashcode computed from the singleton key - * and the singleton value. - */ - public int hashCode() - { - return hashCode(k) ^ hashCode(v); - } - - /** - * Return the keyset. - * - * @return A singleton containing the key. - */ - public Set keySet() - { - if (keys == null) - keys = singleton(k); - return keys; - } - - /** - * The size: always 1! - * - * @return 1. - */ - public int size() - { - return 1; - } - - /** - * Return the values. Technically, a singleton, while more specific than - * a general Collection, will work. Besides, that's what the JDK uses! - * - * @return A singleton containing the value. - */ - public Collection values() - { - if (values == null) - values = singleton(v); - return values; - } - - /** - * Obvious string. - * - * @return A string containing the string representations of the key - * and its associated value. - */ - public String toString() - { - return "{" + k + "=" + v + "}"; - } - } // class SingletonMap - - /** - * Sort a list according to the natural ordering of its elements. The list - * must be modifiable, but can be of fixed size. The sort algorithm is - * precisely that used by Arrays.sort(Object[]), which offers guaranteed - * nlog(n) performance. This implementation dumps the list into an array, - * sorts the array, and then iterates over the list setting each element from - * the array. - * - * @param l the List to sort - * @throws ClassCastException if some items are not mutually comparable - * @throws UnsupportedOperationException if the List is not modifiable - * @throws NullPointerException if some element is null - * @see Arrays#sort(Object[]) - */ - public static void sort(List l) - { - sort(l, null); - } - - /** - * Sort a list according to a specified Comparator. The list must be - * modifiable, but can be of fixed size. The sort algorithm is precisely that - * used by Arrays.sort(Object[], Comparator), which offers guaranteed - * nlog(n) performance. This implementation dumps the list into an array, - * sorts the array, and then iterates over the list setting each element from - * the array. - * - * @param l the List to sort - * @param c the Comparator specifying the ordering for the elements, or - * null for natural ordering - * @throws ClassCastException if c will not compare some pair of items - * @throws UnsupportedOperationException if the List is not modifiable - * @throws NullPointerException if null is compared by natural ordering - * (only possible when c is null) - * @see Arrays#sort(Object[], Comparator) - */ - public static void sort(List l, Comparator c) - { - Object[] a = l.toArray(); - Arrays.sort(a, c); - ListIterator i = l.listIterator(); - for (int pos = 0, alen = a.length; pos < alen; pos++) - { - i.next(); - i.set(a[pos]); - } - } - - /** - * Swaps the elements at the specified positions within the list. Equal - * positions have no effect. - * - * @param l the list to work on - * @param i the first index to swap - * @param j the second index - * @throws UnsupportedOperationException if list.set is not supported - * @throws IndexOutOfBoundsException if either i or j is < 0 or >= - * list.size() - * @since 1.4 - */ - public static void swap(List l, int i, int j) - { - l.set(i, l.set(j, l.get(i))); - } - - - /** - * Returns a synchronized (thread-safe) collection wrapper backed by the - * given collection. Notice that element access through the iterators - * is thread-safe, but if the collection can be structurally modified - * (adding or removing elements) then you should synchronize around the - * iteration to avoid non-deterministic behavior:<br> - * <pre> - * Collection c = Collections.synchronizedCollection(new Collection(...)); - * ... - * synchronized (c) - * { - * Iterator i = c.iterator(); - * while (i.hasNext()) - * foo(i.next()); - * } - * </pre><p> - * - * Since the collection might be a List or a Set, and those have incompatible - * equals and hashCode requirements, this relies on Object's implementation - * rather than passing those calls on to the wrapped collection. The returned - * Collection implements Serializable, but can only be serialized if - * the collection it wraps is likewise Serializable. - * - * @param c the collection to wrap - * @return a synchronized view of the collection - * @see Serializable - */ - public static Collection synchronizedCollection(Collection c) - { - return new SynchronizedCollection(c); - } - - /** - * The implementation of {@link #synchronizedCollection(Collection)}. This - * class name is required for compatibility with Sun's JDK serializability. - * Package visible, so that collections such as the one for - * Hashtable.values() can specify which object to synchronize on. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - static class SynchronizedCollection - implements Collection, Serializable - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 3053995032091335093L; - - /** - * The wrapped collection. Package visible for use by subclasses. - * @serial the real collection - */ - final Collection c; - - /** - * The object to synchronize on. When an instance is created via public - * methods, it will be this; but other uses like SynchronizedMap.values() - * must specify another mutex. Package visible for use by subclasses. - * @serial the lock - */ - final Object mutex; - - /** - * Wrap a given collection. - * @param c the collection to wrap - * @throws NullPointerException if c is null - */ - SynchronizedCollection(Collection c) - { - this.c = c; - mutex = this; - if (c == null) - throw new NullPointerException(); - } - - /** - * Called only by trusted code to specify the mutex as well as the - * collection. - * @param sync the mutex - * @param c the collection - */ - SynchronizedCollection(Object sync, Collection c) - { - this.c = c; - mutex = sync; - } - - /** - * Adds the object to the underlying collection, first - * obtaining a lock on the mutex. - * - * @param o The object to add. - * @return <code>true</code> if the collection was modified as a result - * of this action. - * @throws UnsupportedOperationException if this collection does not - * support the add operation. - * @throws ClassCastException if o cannot be added to this collection due - * to its type. - * @throws NullPointerException if o is null and this collection doesn't - * support the addition of null values. - * @throws IllegalArgumentException if o cannot be added to this - * collection for some other reason. - */ - public boolean add(Object o) - { - synchronized (mutex) - { - return c.add(o); - } - } - - /** - * Adds the objects in col to the underlying collection, first - * obtaining a lock on the mutex. - * - * @param col The collection to take the new objects from. - * @return <code>true</code> if the collection was modified as a result - * of this action. - * @throws UnsupportedOperationException if this collection does not - * support the addAll operation. - * @throws ClassCastException if some element of col cannot be added to this - * collection due to its type. - * @throws NullPointerException if some element of col is null and this - * collection does not support the addition of null values. - * @throws NullPointerException if col itself is null. - * @throws IllegalArgumentException if some element of col cannot be added - * to this collection for some other reason. - */ - public boolean addAll(Collection col) - { - synchronized (mutex) - { - return c.addAll(col); - } - } - - /** - * Removes all objects from the underlying collection, - * first obtaining a lock on the mutex. - * - * @throws UnsupportedOperationException if this collection does not - * support the clear operation. - */ - public void clear() - { - synchronized (mutex) - { - c.clear(); - } - } - - /** - * Checks for the existence of o within the underlying - * collection, first obtaining a lock on the mutex. - * - * @param o the element to look for. - * @return <code>true</code> if this collection contains at least one - * element e such that <code>o == null ? e == null : o.equals(e)</code>. - * @throws ClassCastException if the type of o is not a valid type for this - * collection. - * @throws NullPointerException if o is null and this collection doesn't - * support null values. - */ - public boolean contains(Object o) - { - synchronized (mutex) - { - return c.contains(o); - } - } - - /** - * Checks for the existence of each object in cl - * within the underlying collection, first obtaining - * a lock on the mutex. - * - * @param cl the collection to test for. - * @return <code>true</code> if for every element o in c, contains(o) - * would return <code>true</code>. - * @throws ClassCastException if the type of any element in cl is not a valid - * type for this collection. - * @throws NullPointerException if some element of cl is null and this - * collection does not support null values. - * @throws NullPointerException if cl itself is null. - */ - public boolean containsAll(Collection c1) - { - synchronized (mutex) - { - return c.containsAll(c1); - } - } - - /** - * Returns <code>true</code> if there are no objects in the underlying - * collection. A lock on the mutex is obtained before the - * check is performed. - * - * @return <code>true</code> if this collection contains no elements. - */ - public boolean isEmpty() - { - synchronized (mutex) - { - return c.isEmpty(); - } - } - - /** - * Returns a synchronized iterator wrapper around the underlying - * collection's iterator. A lock on the mutex is obtained before - * retrieving the collection's iterator. - * - * @return An iterator over the elements in the underlying collection, - * which returns each element in any order. - */ - public Iterator iterator() - { - synchronized (mutex) - { - return new SynchronizedIterator(mutex, c.iterator()); - } - } - - /** - * Removes the specified object from the underlying collection, - * first obtaining a lock on the mutex. - * - * @param o The object to remove. - * @return <code>true</code> if the collection changed as a result of this call, that is, - * if the collection contained at least one occurrence of o. - * @throws UnsupportedOperationException if this collection does not - * support the remove operation. - * @throws ClassCastException if the type of o is not a valid type - * for this collection. - * @throws NullPointerException if o is null and the collection doesn't - * support null values. - */ - public boolean remove(Object o) - { - synchronized (mutex) - { - return c.remove(o); - } - } - - /** - * Removes all elements, e, of the underlying - * collection for which <code>col.contains(e)</code> - * returns <code>true</code>. A lock on the mutex is obtained - * before the operation proceeds. - * - * @param col The collection of objects to be removed. - * @return <code>true</code> if this collection was modified as a result of this call. - * @throws UnsupportedOperationException if this collection does not - * support the removeAll operation. - * @throws ClassCastException if the type of any element in c is not a valid - * type for this collection. - * @throws NullPointerException if some element of c is null and this - * collection does not support removing null values. - * @throws NullPointerException if c itself is null. - */ - public boolean removeAll(Collection col) - { - synchronized (mutex) - { - return c.removeAll(col); - } - } - - /** - * Retains all elements, e, of the underlying - * collection for which <code>col.contains(e)</code> - * returns <code>true</code>. That is, every element that doesn't - * exist in col is removed. A lock on the mutex is obtained - * before the operation proceeds. - * - * @param col The collection of objects to be removed. - * @return <code>true</code> if this collection was modified as a result of this call. - * @throws UnsupportedOperationException if this collection does not - * support the removeAll operation. - * @throws ClassCastException if the type of any element in c is not a valid - * type for this collection. - * @throws NullPointerException if some element of c is null and this - * collection does not support removing null values. - * @throws NullPointerException if c itself is null. - */ - public boolean retainAll(Collection col) - { - synchronized (mutex) - { - return c.retainAll(col); - } - } - - /** - * Retrieves the size of the underlying collection. - * A lock on the mutex is obtained before the collection - * is accessed. - * - * @return The size of the collection. - */ - public int size() - { - synchronized (mutex) - { - return c.size(); - } - } - - /** - * Returns an array containing each object within the underlying - * collection. A lock is obtained on the mutex before the collection - * is accessed. - * - * @return An array of objects, matching the collection in size. The - * elements occur in any order. - */ - public Object[] toArray() - { - synchronized (mutex) - { - return c.toArray(); - } - } - - /** - * Copies the elements in the underlying collection to the supplied - * array. If <code>a.length < size()</code>, a new array of the - * same run-time type is created, with a size equal to that of - * the collection. If <code>a.length > size()</code>, then the - * elements from 0 to <code>size() - 1</code> contain the elements - * from this collection. The following element is set to null - * to indicate the end of the collection objects. However, this - * only makes a difference if null is not a permitted value within - * the collection. - * Before the copying takes place, a lock is obtained on the mutex. - * - * @param a An array to copy elements to. - * @return An array containing the elements of the underlying collection. - * @throws ArrayStoreException if the type of any element of the - * collection is not a subtype of the element type of a. - */ - public Object[] toArray(Object[] a) - { - synchronized (mutex) - { - return c.toArray(a); - } - } - - /** - * Returns a string representation of the underlying collection. - * A lock is obtained on the mutex before the string is created. - * - * @return A string representation of the collection. - */ - public String toString() - { - synchronized (mutex) - { - return c.toString(); - } - } - } // class SynchronizedCollection - - /** - * The implementation of the various iterator methods in the - * synchronized classes. These iterators must "sync" on the same object - * as the collection they iterate over. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static class SynchronizedIterator implements Iterator - { - /** - * The object to synchronize on. Package visible for use by subclass. - */ - final Object mutex; - - /** - * The wrapped iterator. - */ - private final Iterator i; - - /** - * Only trusted code creates a wrapper, with the specified sync. - * @param sync the mutex - * @param i the wrapped iterator - */ - SynchronizedIterator(Object sync, Iterator i) - { - this.i = i; - mutex = sync; - } - - /** - * Retrieves the next object in the underlying collection. - * A lock is obtained on the mutex before the collection is accessed. - * - * @return The next object in the collection. - * @throws NoSuchElementException if there are no more elements - */ - public Object next() - { - synchronized (mutex) - { - return i.next(); - } - } - - /** - * Returns <code>true</code> if objects can still be retrieved from the iterator - * using <code>next()</code>. A lock is obtained on the mutex before - * the collection is accessed. - * - * @return <code>true</code> if at least one element is still to be returned by - * <code>next()</code>. - */ - public boolean hasNext() - { - synchronized (mutex) - { - return i.hasNext(); - } - } - - /** - * Removes the object that was last returned by <code>next()</code> - * from the underlying collection. Only one call to this method is - * allowed per call to the <code>next()</code> method, and it does - * not affect the value that will be returned by <code>next()</code>. - * Thus, if element n was retrieved from the collection by - * <code>next()</code>, it is this element that gets removed. - * Regardless of whether this takes place or not, element n+1 is - * still returned on the subsequent <code>next()</code> call. - * - * @throws IllegalStateException if next has not yet been called or remove - * has already been called since the last call to next. - * @throws UnsupportedOperationException if this Iterator does not support - * the remove operation. - */ - public void remove() - { - synchronized (mutex) - { - i.remove(); - } - } - } // class SynchronizedIterator - - /** - * Returns a synchronized (thread-safe) list wrapper backed by the - * given list. Notice that element access through the iterators - * is thread-safe, but if the list can be structurally modified - * (adding or removing elements) then you should synchronize around the - * iteration to avoid non-deterministic behavior:<br> - * <pre> - * List l = Collections.synchronizedList(new List(...)); - * ... - * synchronized (l) - * { - * Iterator i = l.iterator(); - * while (i.hasNext()) - * foo(i.next()); - * } - * </pre><p> - * - * The returned List implements Serializable, but can only be serialized if - * the list it wraps is likewise Serializable. In addition, if the wrapped - * list implements RandomAccess, this does too. - * - * @param l the list to wrap - * @return a synchronized view of the list - * @see Serializable - * @see RandomAccess - */ - public static List synchronizedList(List l) - { - if (l instanceof RandomAccess) - return new SynchronizedRandomAccessList(l); - return new SynchronizedList(l); - } - - /** - * The implementation of {@link #synchronizedList(List)} for sequential - * lists. This class name is required for compatibility with Sun's JDK - * serializability. Package visible, so that lists such as Vector.subList() - * can specify which object to synchronize on. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - static class SynchronizedList extends SynchronizedCollection - implements List - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = -7754090372962971524L; - - /** - * The wrapped list; stored both here and in the superclass to avoid - * excessive casting. Package visible for use by subclass. - * @serial the wrapped list - */ - final List list; - - /** - * Wrap a given list. - * @param l the list to wrap - * @throws NullPointerException if l is null - */ - SynchronizedList(List l) - { - super(l); - list = l; - } - - /** - * Called only by trusted code to specify the mutex as well as the list. - * @param sync the mutex - * @param l the list - */ - SynchronizedList(Object sync, List l) - { - super(sync, l); - list = l; - } - - /** - * Insert an element into the underlying list at a given position (optional - * operation). This shifts all existing elements from that position to the - * end one index to the right. This version of add has no return, since it is - * assumed to always succeed if there is no exception. Before the - * addition takes place, a lock is obtained on the mutex. - * - * @param index the location to insert the item - * @param o the object to insert - * @throws UnsupportedOperationException if this list does not support the - * add operation - * @throws IndexOutOfBoundsException if index < 0 || index > size() - * @throws ClassCastException if o cannot be added to this list due to its - * type - * @throws IllegalArgumentException if o cannot be added to this list for - * some other reason - * @throws NullPointerException if o is null and this list doesn't support - * the addition of null values. - */ - public void add(int index, Object o) - { - synchronized (mutex) - { - list.add(index, o); - } - } - - /** - * Add an element to the end of the underlying list (optional operation). - * If the list imposes restraints on what can be inserted, such as no null - * elements, this should be documented. A lock is obtained on the mutex before - * any of the elements are added. - * - * @param o the object to add - * @return <code>true</code>, as defined by Collection for a modified list - * @throws UnsupportedOperationException if this list does not support the - * add operation - * @throws ClassCastException if o cannot be added to this list due to its - * type - * @throws IllegalArgumentException if o cannot be added to this list for - * some other reason - * @throws NullPointerException if o is null and this list doesn't support - * the addition of null values. - */ - public boolean addAll(int index, Collection c) - { - synchronized (mutex) - { - return list.addAll(index, c); - } - } - - /** - * Tests whether the underlying list is equal to the supplied object. - * The object is deemed to be equal if it is also a <code>List</code> - * of equal size and with the same elements (i.e. each element, e1, - * in list, l1, and each element, e2, in l2, must return <code>true</code> for - * <code>e1 == null ? e2 == null : e1.equals(e2)</code>. Before the - * comparison is made, a lock is obtained on the mutex. - * - * @param o The object to test for equality with the underlying list. - * @return <code>true</code> if o is equal to the underlying list under the above - * definition. - */ - public boolean equals(Object o) - { - synchronized (mutex) - { - return list.equals(o); - } - } - - /** - * Retrieves the object at the specified index. A lock - * is obtained on the mutex before the list is accessed. - * - * @param index the index of the element to be returned - * @return the element at index index in this list - * @throws IndexOutOfBoundsException if index < 0 || index >= size() - */ - public Object get(int index) - { - synchronized (mutex) - { - return list.get(index); - } - } - - /** - * Obtains a hashcode for the underlying list, first obtaining - * a lock on the mutex. The calculation of the hashcode is - * detailed in the documentation for the <code>List</code> - * interface. - * - * @return The hashcode of the underlying list. - * @see List#hashCode() - */ - public int hashCode() - { - synchronized (mutex) - { - return list.hashCode(); - } - } - - /** - * Obtain the first index at which a given object is to be found in the - * underlying list. A lock is obtained on the mutex before the list is - * accessed. - * - * @param o the object to search for - * @return the least integer n such that <code>o == null ? get(n) == null : - * o.equals(get(n))</code>, or -1 if there is no such index. - * @throws ClassCastException if the type of o is not a valid - * type for this list. - * @throws NullPointerException if o is null and this - * list does not support null values. - */ - - public int indexOf(Object o) - { - synchronized (mutex) - { - return list.indexOf(o); - } - } - - /** - * Obtain the last index at which a given object is to be found in this - * underlying list. A lock is obtained on the mutex before the list - * is accessed. - * - * @return the greatest integer n such that <code>o == null ? get(n) == null - * : o.equals(get(n))</code>, or -1 if there is no such index. - * @throws ClassCastException if the type of o is not a valid - * type for this list. - * @throws NullPointerException if o is null and this - * list does not support null values. - */ - public int lastIndexOf(Object o) - { - synchronized (mutex) - { - return list.lastIndexOf(o); - } - } - - /** - * Retrieves a synchronized wrapper around the underlying list's - * list iterator. A lock is obtained on the mutex before the - * list iterator is retrieved. - * - * @return A list iterator over the elements in the underlying list. - * The list iterator allows additional list-specific operations - * to be performed, in addition to those supplied by the - * standard iterator. - */ - public ListIterator listIterator() - { - synchronized (mutex) - { - return new SynchronizedListIterator(mutex, list.listIterator()); - } - } - - /** - * Retrieves a synchronized wrapper around the underlying list's - * list iterator. A lock is obtained on the mutex before the - * list iterator is retrieved. The iterator starts at the - * index supplied, leading to the element at that index being - * the first one returned by <code>next()</code>. Calling - * <code>previous()</code> from this initial position returns - * index - 1. - * - * @param index the position, between 0 and size() inclusive, to begin the - * iteration from - * @return A list iterator over the elements in the underlying list. - * The list iterator allows additional list-specific operations - * to be performed, in addition to those supplied by the - * standard iterator. - * @throws IndexOutOfBoundsException if index < 0 || index > size() - */ - public ListIterator listIterator(int index) - { - synchronized (mutex) - { - return new SynchronizedListIterator(mutex, list.listIterator(index)); - } - } - - /** - * Remove the element at a given position in the underlying list (optional - * operation). All remaining elements are shifted to the left to fill the gap. - * A lock on the mutex is obtained before the element is removed. - * - * @param index the position within the list of the object to remove - * @return the object that was removed - * @throws UnsupportedOperationException if this list does not support the - * remove operation - * @throws IndexOutOfBoundsException if index < 0 || index >= size() - */ - public Object remove(int index) - { - synchronized (mutex) - { - return list.remove(index); - } - } - - /** - * Replace an element of the underlying list with another object (optional - * operation). A lock is obtained on the mutex before the element is - * replaced. - * - * @param index the position within this list of the element to be replaced - * @param o the object to replace it with - * @return the object that was replaced - * @throws UnsupportedOperationException if this list does not support the - * set operation. - * @throws IndexOutOfBoundsException if index < 0 || index >= size() - * @throws ClassCastException if o cannot be added to this list due to its - * type - * @throws IllegalArgumentException if o cannot be added to this list for - * some other reason - * @throws NullPointerException if o is null and this - * list does not support null values. - */ - public Object set(int index, Object o) - { - synchronized (mutex) - { - return list.set(index, o); - } - } - - /** - * Obtain a List view of a subsection of the underlying list, from fromIndex - * (inclusive) to toIndex (exclusive). If the two indices are equal, the - * sublist is empty. The returned list should be modifiable if and only - * if this list is modifiable. Changes to the returned list should be - * reflected in this list. If this list is structurally modified in - * any way other than through the returned list, the result of any subsequent - * operations on the returned list is undefined. A lock is obtained - * on the mutex before the creation of the sublist. The returned list - * is also synchronized, using the same mutex. - * - * @param fromIndex the index that the returned list should start from - * (inclusive) - * @param toIndex the index that the returned list should go to (exclusive) - * @return a List backed by a subsection of this list - * @throws IndexOutOfBoundsException if fromIndex < 0 - * || toIndex > size() || fromIndex > toIndex - */ - public List subList(int fromIndex, int toIndex) - { - synchronized (mutex) - { - return new SynchronizedList(mutex, list.subList(fromIndex, toIndex)); - } - } - } // class SynchronizedList - - /** - * The implementation of {@link #synchronizedList(List)} for random-access - * lists. This class name is required for compatibility with Sun's JDK - * serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class SynchronizedRandomAccessList - extends SynchronizedList implements RandomAccess - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 1530674583602358482L; - - /** - * Wrap a given list. - * @param l the list to wrap - * @throws NullPointerException if l is null - */ - SynchronizedRandomAccessList(List l) - { - super(l); - } - - /** - * Called only by trusted code to specify the mutex as well as the - * collection. - * @param sync the mutex - * @param l the list - */ - SynchronizedRandomAccessList(Object sync, List l) - { - super(sync, l); - } - - /** - * Obtain a List view of a subsection of the underlying list, from fromIndex - * (inclusive) to toIndex (exclusive). If the two indices are equal, the - * sublist is empty. The returned list should be modifiable if and only - * if this list is modifiable. Changes to the returned list should be - * reflected in this list. If this list is structurally modified in - * any way other than through the returned list, the result of any subsequent - * operations on the returned list is undefined. A lock is obtained - * on the mutex before the creation of the sublist. The returned list - * is also synchronized, using the same mutex. Random accessibility - * is also extended to the new list. - * - * @param fromIndex the index that the returned list should start from - * (inclusive) - * @param toIndex the index that the returned list should go to (exclusive) - * @return a List backed by a subsection of this list - * @throws IndexOutOfBoundsException if fromIndex < 0 - * || toIndex > size() || fromIndex > toIndex - */ - public List subList(int fromIndex, int toIndex) - { - synchronized (mutex) - { - return new SynchronizedRandomAccessList(mutex, - list.subList(fromIndex, - toIndex)); - } - } - } // class SynchronizedRandomAccessList - - /** - * The implementation of {@link SynchronizedList#listIterator()}. This - * iterator must "sync" on the same object as the list it iterates over. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class SynchronizedListIterator - extends SynchronizedIterator implements ListIterator - { - /** - * The wrapped iterator, stored both here and in the superclass to - * avoid excessive casting. - */ - private final ListIterator li; - - /** - * Only trusted code creates a wrapper, with the specified sync. - * @param sync the mutex - * @param li the wrapped iterator - */ - SynchronizedListIterator(Object sync, ListIterator li) - { - super(sync, li); - this.li = li; - } - - /** - * Insert an element into the underlying list at the current position of - * the iterator (optional operation). The element is inserted in between - * the element that would be returned by <code>previous()</code> and the - * element that would be returned by <code>next()</code>. After the - * insertion, a subsequent call to next is unaffected, but - * a call to previous returns the item that was added. The values returned - * by nextIndex() and previousIndex() are incremented. A lock is obtained - * on the mutex before the addition takes place. - * - * @param o the object to insert into the list - * @throws ClassCastException if the object is of a type which cannot be added - * to this list. - * @throws IllegalArgumentException if some other aspect of the object stops - * it being added to this list. - * @throws UnsupportedOperationException if this ListIterator does not - * support the add operation. - */ - public void add(Object o) - { - synchronized (mutex) - { - li.add(o); - } - } - - /** - * Tests whether there are elements remaining in the underlying list - * in the reverse direction. In other words, <code>previous()</code> - * will not fail with a NoSuchElementException. A lock is obtained - * on the mutex before the check takes place. - * - * @return <code>true</code> if the list continues in the reverse direction - */ - public boolean hasPrevious() - { - synchronized (mutex) - { - return li.hasPrevious(); - } - } - - /** - * Find the index of the element that would be returned by a call to - * <code>next()</code>. If hasNext() returns <code>false</code>, this - * returns the list size. A lock is obtained on the mutex before the - * query takes place. - * - * @return the index of the element that would be returned by next() - */ - public int nextIndex() - { - synchronized (mutex) - { - return li.nextIndex(); - } - } - - /** - * Obtain the previous element from the underlying list. Repeated - * calls to previous may be used to iterate backwards over the entire list, - * or calls to next and previous may be used together to go forwards and - * backwards. Alternating calls to next and previous will return the same - * element. A lock is obtained on the mutex before the object is retrieved. - * - * @return the next element in the list in the reverse direction - * @throws NoSuchElementException if there are no more elements - */ - public Object previous() - { - synchronized (mutex) - { - return li.previous(); - } - } - - /** - * Find the index of the element that would be returned by a call to - * previous. If hasPrevious() returns <code>false</code>, this returns -1. - * A lock is obtained on the mutex before the query takes place. - * - * @return the index of the element that would be returned by previous() - */ - public int previousIndex() - { - synchronized (mutex) - { - return li.previousIndex(); - } - } - - /** - * Replace the element last returned by a call to <code>next()</code> or - * <code>previous()</code> with a given object (optional operation). This - * method may only be called if neither <code>add()</code> nor - * <code>remove()</code> have been called since the last call to - * <code>next()</code> or <code>previous</code>. A lock is obtained - * on the mutex before the list is modified. - * - * @param o the object to replace the element with - * @throws ClassCastException the object is of a type which cannot be added - * to this list - * @throws IllegalArgumentException some other aspect of the object stops - * it being added to this list - * @throws IllegalStateException if neither next or previous have been - * called, or if add or remove has been called since the last call - * to next or previous - * @throws UnsupportedOperationException if this ListIterator does not - * support the set operation - */ - public void set(Object o) - { - synchronized (mutex) - { - li.set(o); - } - } - } // class SynchronizedListIterator - - /** - * Returns a synchronized (thread-safe) map wrapper backed by the given - * map. Notice that element access through the collection views and their - * iterators are thread-safe, but if the map can be structurally modified - * (adding or removing elements) then you should synchronize around the - * iteration to avoid non-deterministic behavior:<br> - * <pre> - * Map m = Collections.synchronizedMap(new Map(...)); - * ... - * Set s = m.keySet(); // safe outside a synchronized block - * synchronized (m) // synch on m, not s - * { - * Iterator i = s.iterator(); - * while (i.hasNext()) - * foo(i.next()); - * } - * </pre><p> - * - * The returned Map implements Serializable, but can only be serialized if - * the map it wraps is likewise Serializable. - * - * @param m the map to wrap - * @return a synchronized view of the map - * @see Serializable - */ - public static Map synchronizedMap(Map m) - { - return new SynchronizedMap(m); - } - - /** - * The implementation of {@link #synchronizedMap(Map)}. This - * class name is required for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static class SynchronizedMap implements Map, Serializable - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 1978198479659022715L; - - /** - * The wrapped map. - * @serial the real map - */ - private final Map m; - - /** - * The object to synchronize on. When an instance is created via public - * methods, it will be this; but other uses like - * SynchronizedSortedMap.subMap() must specify another mutex. Package - * visible for use by subclass. - * @serial the lock - */ - final Object mutex; - - /** - * Cache the entry set. - */ - private transient Set entries; - - /** - * Cache the key set. - */ - private transient Set keys; - - /** - * Cache the value collection. - */ - private transient Collection values; - - /** - * Wrap a given map. - * @param m the map to wrap - * @throws NullPointerException if m is null - */ - SynchronizedMap(Map m) - { - this.m = m; - mutex = this; - if (m == null) - throw new NullPointerException(); - } - - /** - * Called only by trusted code to specify the mutex as well as the map. - * @param sync the mutex - * @param m the map - */ - SynchronizedMap(Object sync, Map m) - { - this.m = m; - mutex = sync; - } - - /** - * Clears all the entries from the underlying map. A lock is obtained - * on the mutex before the map is cleared. - * - * @throws UnsupportedOperationException if clear is not supported - */ - public void clear() - { - synchronized (mutex) - { - m.clear(); - } - } - - /** - * Returns <code>true</code> if the underlying map contains a entry for the given key. - * A lock is obtained on the mutex before the map is queried. - * - * @param key the key to search for. - * @return <code>true</code> if the underlying map contains the key. - * @throws ClassCastException if the key is of an inappropriate type. - * @throws NullPointerException if key is <code>null</code> but the map - * does not permit null keys. - */ - public boolean containsKey(Object key) - { - synchronized (mutex) - { - return m.containsKey(key); - } - } - - /** - * Returns <code>true</code> if the underlying map contains at least one entry with the - * given value. In other words, returns <code>true</code> if a value v exists where - * <code>(value == null ? v == null : value.equals(v))</code>. This usually - * requires linear time. A lock is obtained on the mutex before the map - * is queried. - * - * @param value the value to search for - * @return <code>true</code> if the map contains the value - * @throws ClassCastException if the type of the value is not a valid type - * for this map. - * @throws NullPointerException if the value is null and the map doesn't - * support null values. - */ - public boolean containsValue(Object value) - { - synchronized (mutex) - { - return m.containsValue(value); - } - } - - // This is one of the ickiest cases of nesting I've ever seen. It just - // means "return a SynchronizedSet, except that the iterator() method - // returns an SynchronizedIterator whose next() method returns a - // synchronized wrapper around its normal return value". - public Set entrySet() - { - // Define this here to spare some nesting. - class SynchronizedMapEntry implements Map.Entry - { - final Map.Entry e; - SynchronizedMapEntry(Object o) - { - e = (Map.Entry) o; - } - - /** - * Returns <code>true</code> if the object, o, implements <code>Map.Entry</code> - * with the same key and value as the underlying entry. A lock is - * obtained on the mutex before the comparison takes place. - * - * @param o The object to compare with this entry. - * @return <code>true</code> if o is equivalent to the underlying map entry. - */ - public boolean equals(Object o) - { - synchronized (mutex) - { - return e.equals(o); - } - } - - /** - * Returns the key used in the underlying map entry. A lock is obtained - * on the mutex before the key is retrieved. - * - * @return The key of the underlying map entry. - */ - public Object getKey() - { - synchronized (mutex) - { - return e.getKey(); - } - } - - /** - * Returns the value used in the underlying map entry. A lock is obtained - * on the mutex before the value is retrieved. - * - * @return The value of the underlying map entry. - */ - public Object getValue() - { - synchronized (mutex) - { - return e.getValue(); - } - } - - /** - * Computes the hash code for the underlying map entry. - * This computation is described in the documentation for the - * <code>Map</code> interface. A lock is obtained on the mutex - * before the underlying map is accessed. - * - * @return The hash code of the underlying map entry. - * @see Map#hashCode() - */ - public int hashCode() - { - synchronized (mutex) - { - return e.hashCode(); - } - } - - /** - * Replaces the value in the underlying map entry with the specified - * object (optional operation). A lock is obtained on the mutex - * before the map is altered. The map entry, in turn, will alter - * the underlying map object. The operation is undefined if the - * <code>remove()</code> method of the iterator has been called - * beforehand. - * - * @param value the new value to store - * @return the old value - * @throws UnsupportedOperationException if the operation is not supported. - * @throws ClassCastException if the value is of the wrong type. - * @throws IllegalArgumentException if something about the value - * prevents it from existing in this map. - * @throws NullPointerException if the map forbids null values. - */ - public Object setValue(Object value) - { - synchronized (mutex) - { - return e.setValue(value); - } - } - - /** - * Returns a textual representation of the underlying map entry. - * A lock is obtained on the mutex before the entry is accessed. - * - * @return The contents of the map entry in <code>String</code> form. - */ - public String toString() - { - synchronized (mutex) - { - return e.toString(); - } - } - } // class SynchronizedMapEntry - - // Now the actual code. - if (entries == null) - synchronized (mutex) - { - entries = new SynchronizedSet(mutex, m.entrySet()) - { - /** - * Returns an iterator over the set. The iterator has no specific order, - * unless further specified. A lock is obtained on the set's mutex - * before the iterator is created. The created iterator is also - * thread-safe. - * - * @return A synchronized set iterator. - */ - public Iterator iterator() - { - synchronized (super.mutex) - { - return new SynchronizedIterator(super.mutex, c.iterator()) - { - /** - * Retrieves the next map entry from the iterator. - * A lock is obtained on the iterator's mutex before - * the entry is created. The new map entry is enclosed in - * a thread-safe wrapper. - * - * @return A synchronized map entry. - */ - public Object next() - { - synchronized (super.mutex) - { - return new SynchronizedMapEntry(super.next()); - } - } - }; - } - } - }; - } - return entries; - } - - /** - * Returns <code>true</code> if the object, o, is also an instance - * of <code>Map</code> and contains an equivalent - * entry set to that of the underlying map. A lock - * is obtained on the mutex before the objects are - * compared. - * - * @param o The object to compare. - * @return <code>true</code> if o and the underlying map are equivalent. - */ - public boolean equals(Object o) - { - synchronized (mutex) - { - return m.equals(o); - } - } - - /** - * Returns the value associated with the given key, or null - * if no such mapping exists. An ambiguity exists with maps - * that accept null values as a return value of null could - * be due to a non-existent mapping or simply a null value - * for that key. To resolve this, <code>containsKey</code> - * should be used. A lock is obtained on the mutex before - * the value is retrieved from the underlying map. - * - * @param key The key of the required mapping. - * @return The value associated with the given key, or - * null if no such mapping exists. - * @throws ClassCastException if the key is an inappropriate type. - * @throws NullPointerException if this map does not accept null keys. - */ - public Object get(Object key) - { - synchronized (mutex) - { - return m.get(key); - } - } - - /** - * Calculates the hash code of the underlying map as the - * sum of the hash codes of all entries. A lock is obtained - * on the mutex before the hash code is computed. - * - * @return The hash code of the underlying map. - */ - public int hashCode() - { - synchronized (mutex) - { - return m.hashCode(); - } - } - - /** - * Returns <code>true</code> if the underlying map contains no entries. - * A lock is obtained on the mutex before the map is examined. - * - * @return <code>true</code> if the map is empty. - */ - public boolean isEmpty() - { - synchronized (mutex) - { - return m.isEmpty(); - } - } - - /** - * Returns a thread-safe set view of the keys in the underlying map. The - * set is backed by the map, so that changes in one show up in the other. - * Modifications made while an iterator is in progress cause undefined - * behavior. If the set supports removal, these methods remove the - * underlying mapping from the map: <code>Iterator.remove</code>, - * <code>Set.remove</code>, <code>removeAll</code>, <code>retainAll</code>, - * and <code>clear</code>. Element addition, via <code>add</code> or - * <code>addAll</code>, is not supported via this set. A lock is obtained - * on the mutex before the set is created. - * - * @return A synchronized set containing the keys of the underlying map. - */ - public Set keySet() - { - if (keys == null) - synchronized (mutex) - { - keys = new SynchronizedSet(mutex, m.keySet()); - } - return keys; - } - - /** - * Associates the given key to the given value (optional operation). If the - * underlying map already contains the key, its value is replaced. Be aware - * that in a map that permits <code>null</code> values, a null return does not - * always imply that the mapping was created. A lock is obtained on the mutex - * before the modification is made. - * - * @param key the key to map. - * @param value the value to be mapped. - * @return the previous value of the key, or null if there was no mapping - * @throws UnsupportedOperationException if the operation is not supported - * @throws ClassCastException if the key or value is of the wrong type - * @throws IllegalArgumentException if something about this key or value - * prevents it from existing in this map - * @throws NullPointerException if either the key or the value is null, - * and the map forbids null keys or values - * @see #containsKey(Object) - */ - public Object put(Object key, Object value) - { - synchronized (mutex) - { - return m.put(key, value); - } - } - - /** - * Copies all entries of the given map to the underlying one (optional - * operation). If the map already contains a key, its value is replaced. - * A lock is obtained on the mutex before the operation proceeds. - * - * @param m the mapping to load into this map - * @throws UnsupportedOperationException if the operation is not supported - * @throws ClassCastException if a key or value is of the wrong type - * @throws IllegalArgumentException if something about a key or value - * prevents it from existing in this map - * @throws NullPointerException if the map forbids null keys or values, or - * if <code>m</code> is null. - * @see #put(Object, Object) - */ - public void putAll(Map map) - { - synchronized (mutex) - { - m.putAll(map); - } - } - - /** - * Removes the mapping for the key, o, if present (optional operation). If - * the key is not present, this returns null. Note that maps which permit - * null values may also return null if the key was removed. A prior - * <code>containsKey()</code> check is required to avoid this ambiguity. - * Before the mapping is removed, a lock is obtained on the mutex. - * - * @param key the key to remove - * @return the value the key mapped to, or null if not present - * @throws UnsupportedOperationException if deletion is unsupported - * @throws NullPointerException if the key is null and this map doesn't - * support null keys. - * @throws ClassCastException if the type of the key is not a valid type - * for this map. - */ - public Object remove(Object o) - { - synchronized (mutex) - { - return m.remove(o); - } - } - - /** - * Retrieves the size of the underlying map. A lock - * is obtained on the mutex before access takes place. - * Maps with a size greater than <code>Integer.MAX_VALUE</code> - * return <code>Integer.MAX_VALUE</code> instead. - * - * @return The size of the underlying map. - */ - public int size() - { - synchronized (mutex) - { - return m.size(); - } - } - - /** - * Returns a textual representation of the underlying - * map. A lock is obtained on the mutex before the map - * is accessed. - * - * @return The map in <code>String</code> form. - */ - public String toString() - { - synchronized (mutex) - { - return m.toString(); - } - } - - /** - * Returns a synchronized collection view of the values in the underlying - * map. The collection is backed by the map, so that changes in one show up in - * the other. Modifications made while an iterator is in progress cause - * undefined behavior. If the collection supports removal, these methods - * remove the underlying mapping from the map: <code>Iterator.remove</code>, - * <code>Collection.remove</code>, <code>removeAll</code>, - * <code>retainAll</code>, and <code>clear</code>. Element addition, via - * <code>add</code> or <code>addAll</code>, is not supported via this - * collection. A lock is obtained on the mutex before the collection - * is created. - * - * @return the collection of all values in the underlying map. - */ - public Collection values() - { - if (values == null) - synchronized (mutex) - { - values = new SynchronizedCollection(mutex, m.values()); - } - return values; - } - } // class SynchronizedMap - - /** - * Returns a synchronized (thread-safe) set wrapper backed by the given - * set. Notice that element access through the iterator is thread-safe, but - * if the set can be structurally modified (adding or removing elements) - * then you should synchronize around the iteration to avoid - * non-deterministic behavior:<br> - * <pre> - * Set s = Collections.synchronizedSet(new Set(...)); - * ... - * synchronized (s) - * { - * Iterator i = s.iterator(); - * while (i.hasNext()) - * foo(i.next()); - * } - * </pre><p> - * - * The returned Set implements Serializable, but can only be serialized if - * the set it wraps is likewise Serializable. - * - * @param s the set to wrap - * @return a synchronized view of the set - * @see Serializable - */ - public static Set synchronizedSet(Set s) - { - return new SynchronizedSet(s); - } - - /** - * The implementation of {@link #synchronizedSet(Set)}. This class - * name is required for compatibility with Sun's JDK serializability. - * Package visible, so that sets such as Hashtable.keySet() - * can specify which object to synchronize on. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - static class SynchronizedSet extends SynchronizedCollection - implements Set - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 487447009682186044L; - - /** - * Wrap a given set. - * @param s the set to wrap - * @throws NullPointerException if s is null - */ - SynchronizedSet(Set s) - { - super(s); - } - - /** - * Called only by trusted code to specify the mutex as well as the set. - * @param sync the mutex - * @param s the set - */ - SynchronizedSet(Object sync, Set s) - { - super(sync, s); - } - - /** - * Returns <code>true</code> if the object, o, is a <code>Set</code> - * of the same size as the underlying set, and contains - * each element, e, which occurs in the underlying set. - * A lock is obtained on the mutex before the comparison - * takes place. - * - * @param o The object to compare against. - * @return <code>true</code> if o is an equivalent set. - */ - public boolean equals(Object o) - { - synchronized (mutex) - { - return c.equals(o); - } - } - - /** - * Computes the hash code for the underlying set as the - * sum of the hash code of all elements within the set. - * A lock is obtained on the mutex before the computation - * occurs. - * - * @return The hash code for the underlying set. - */ - public int hashCode() - { - synchronized (mutex) - { - return c.hashCode(); - } - } - } // class SynchronizedSet - - /** - * Returns a synchronized (thread-safe) sorted map wrapper backed by the - * given map. Notice that element access through the collection views, - * subviews, and their iterators are thread-safe, but if the map can be - * structurally modified (adding or removing elements) then you should - * synchronize around the iteration to avoid non-deterministic behavior:<br> - * <pre> - * SortedMap m = Collections.synchronizedSortedMap(new SortedMap(...)); - * ... - * Set s = m.keySet(); // safe outside a synchronized block - * SortedMap m2 = m.headMap(foo); // safe outside a synchronized block - * Set s2 = m2.keySet(); // safe outside a synchronized block - * synchronized (m) // synch on m, not m2, s or s2 - * { - * Iterator i = s.iterator(); - * while (i.hasNext()) - * foo(i.next()); - * i = s2.iterator(); - * while (i.hasNext()) - * bar(i.next()); - * } - * </pre><p> - * - * The returned SortedMap implements Serializable, but can only be - * serialized if the map it wraps is likewise Serializable. - * - * @param m the sorted map to wrap - * @return a synchronized view of the sorted map - * @see Serializable - */ - public static SortedMap synchronizedSortedMap(SortedMap m) - { - return new SynchronizedSortedMap(m); - } - - /** - * The implementation of {@link #synchronizedSortedMap(SortedMap)}. This - * class name is required for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class SynchronizedSortedMap extends SynchronizedMap - implements SortedMap - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = -8798146769416483793L; - - /** - * The wrapped map; stored both here and in the superclass to avoid - * excessive casting. - * @serial the wrapped map - */ - private final SortedMap sm; - - /** - * Wrap a given map. - * @param sm the map to wrap - * @throws NullPointerException if sm is null - */ - SynchronizedSortedMap(SortedMap sm) - { - super(sm); - this.sm = sm; - } - - /** - * Called only by trusted code to specify the mutex as well as the map. - * @param sync the mutex - * @param sm the map - */ - SynchronizedSortedMap(Object sync, SortedMap sm) - { - super(sync, sm); - this.sm = sm; - } - - /** - * Returns the comparator used in sorting the underlying map, or null if - * it is the keys' natural ordering. A lock is obtained on the mutex - * before the comparator is retrieved. - * - * @return the sorting comparator. - */ - public Comparator comparator() - { - synchronized (mutex) - { - return sm.comparator(); - } - } - - /** - * Returns the first, lowest sorted, key from the underlying map. - * A lock is obtained on the mutex before the map is accessed. - * - * @return the first key. - * @throws NoSuchElementException if this map is empty. - */ - public Object firstKey() - { - synchronized (mutex) - { - return sm.firstKey(); - } - } - - /** - * Returns a submap containing the keys from the first - * key (as returned by <code>firstKey()</code>) to - * the key before that specified. The submap supports all - * operations supported by the underlying map and all actions - * taking place on the submap are also reflected in the underlying - * map. A lock is obtained on the mutex prior to submap creation. - * This operation is equivalent to <code>subMap(firstKey(), toKey)</code>. - * The submap retains the thread-safe status of this map. - * - * @param toKey the exclusive upper range of the submap. - * @return a submap from <code>firstKey()</code> to the - * the key preceding toKey. - * @throws ClassCastException if toKey is not comparable to the underlying - * map's contents. - * @throws IllegalArgumentException if toKey is outside the map's range. - * @throws NullPointerException if toKey is null. but the map does not allow - * null keys. - */ - public SortedMap headMap(Object toKey) - { - synchronized (mutex) - { - return new SynchronizedSortedMap(mutex, sm.headMap(toKey)); - } - } - - /** - * Returns the last, highest sorted, key from the underlying map. - * A lock is obtained on the mutex before the map is accessed. - * - * @return the last key. - * @throws NoSuchElementException if this map is empty. - */ - public Object lastKey() - { - synchronized (mutex) - { - return sm.lastKey(); - } - } - - /** - * Returns a submap containing the keys from fromKey to - * the key before toKey. The submap supports all - * operations supported by the underlying map and all actions - * taking place on the submap are also reflected in the underlying - * map. A lock is obtained on the mutex prior to submap creation. - * The submap retains the thread-safe status of this map. - * - * @param fromKey the inclusive lower range of the submap. - * @param toKey the exclusive upper range of the submap. - * @return a submap from fromKey to the key preceding toKey. - * @throws ClassCastException if fromKey or toKey is not comparable - * to the underlying map's contents. - * @throws IllegalArgumentException if fromKey or toKey is outside the map's - * range. - * @throws NullPointerException if fromKey or toKey is null. but the map does - * not allow null keys. - */ - public SortedMap subMap(Object fromKey, Object toKey) - { - synchronized (mutex) - { - return new SynchronizedSortedMap(mutex, sm.subMap(fromKey, toKey)); - } - } - - /** - * Returns a submap containing all the keys from fromKey onwards. - * The submap supports all operations supported by the underlying - * map and all actions taking place on the submap are also reflected - * in the underlying map. A lock is obtained on the mutex prior to - * submap creation. The submap retains the thread-safe status of - * this map. - * - * @param fromKey the inclusive lower range of the submap. - * @return a submap from fromKey to <code>lastKey()</code>. - * @throws ClassCastException if fromKey is not comparable to the underlying - * map's contents. - * @throws IllegalArgumentException if fromKey is outside the map's range. - * @throws NullPointerException if fromKey is null. but the map does not allow - * null keys. - */ - public SortedMap tailMap(Object fromKey) - { - synchronized (mutex) - { - return new SynchronizedSortedMap(mutex, sm.tailMap(fromKey)); - } - } - } // class SynchronizedSortedMap - - /** - * Returns a synchronized (thread-safe) sorted set wrapper backed by the - * given set. Notice that element access through the iterator and through - * subviews are thread-safe, but if the set can be structurally modified - * (adding or removing elements) then you should synchronize around the - * iteration to avoid non-deterministic behavior:<br> - * <pre> - * SortedSet s = Collections.synchronizedSortedSet(new SortedSet(...)); - * ... - * SortedSet s2 = s.headSet(foo); // safe outside a synchronized block - * synchronized (s) // synch on s, not s2 - * { - * Iterator i = s2.iterator(); - * while (i.hasNext()) - * foo(i.next()); - * } - * </pre><p> - * - * The returned SortedSet implements Serializable, but can only be - * serialized if the set it wraps is likewise Serializable. - * - * @param s the sorted set to wrap - * @return a synchronized view of the sorted set - * @see Serializable - */ - public static SortedSet synchronizedSortedSet(SortedSet s) - { - return new SynchronizedSortedSet(s); - } - - /** - * The implementation of {@link #synchronizedSortedSet(SortedSet)}. This - * class name is required for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class SynchronizedSortedSet extends SynchronizedSet - implements SortedSet - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 8695801310862127406L; - - /** - * The wrapped set; stored both here and in the superclass to avoid - * excessive casting. - * @serial the wrapped set - */ - private final SortedSet ss; - - /** - * Wrap a given set. - * @param ss the set to wrap - * @throws NullPointerException if ss is null - */ - SynchronizedSortedSet(SortedSet ss) - { - super(ss); - this.ss = ss; - } - - /** - * Called only by trusted code to specify the mutex as well as the set. - * @param sync the mutex - * @param l the list - */ - SynchronizedSortedSet(Object sync, SortedSet ss) - { - super(sync, ss); - this.ss = ss; - } - - /** - * Returns the comparator used in sorting the underlying set, or null if - * it is the elements' natural ordering. A lock is obtained on the mutex - * before the comparator is retrieved. - * - * @return the sorting comparator. - */ - public Comparator comparator() - { - synchronized (mutex) - { - return ss.comparator(); - } - } - - /** - * Returns the first, lowest sorted, element from the underlying set. - * A lock is obtained on the mutex before the set is accessed. - * - * @return the first element. - * @throws NoSuchElementException if this set is empty. - */ - public Object first() - { - synchronized (mutex) - { - return ss.first(); - } - } - - /** - * Returns a subset containing the element from the first - * element (as returned by <code>first()</code>) to - * the element before that specified. The subset supports all - * operations supported by the underlying set and all actions - * taking place on the subset are also reflected in the underlying - * set. A lock is obtained on the mutex prior to subset creation. - * This operation is equivalent to <code>subSet(first(), toElement)</code>. - * The subset retains the thread-safe status of this set. - * - * @param toElement the exclusive upper range of the subset. - * @return a subset from <code>first()</code> to the - * the element preceding toElement. - * @throws ClassCastException if toElement is not comparable to the underlying - * set's contents. - * @throws IllegalArgumentException if toElement is outside the set's range. - * @throws NullPointerException if toElement is null. but the set does not allow - * null elements. - */ - public SortedSet headSet(Object toElement) - { - synchronized (mutex) - { - return new SynchronizedSortedSet(mutex, ss.headSet(toElement)); - } - } - - /** - * Returns the last, highest sorted, element from the underlying set. - * A lock is obtained on the mutex before the set is accessed. - * - * @return the last element. - * @throws NoSuchElementException if this set is empty. - */ - public Object last() - { - synchronized (mutex) - { - return ss.last(); - } - } - - /** - * Returns a subset containing the elements from fromElement to - * the element before toElement. The subset supports all - * operations supported by the underlying set and all actions - * taking place on the subset are also reflected in the underlying - * set. A lock is obtained on the mutex prior to subset creation. - * The subset retains the thread-safe status of this set. - * - * @param fromElement the inclusive lower range of the subset. - * @param toElement the exclusive upper range of the subset. - * @return a subset from fromElement to the element preceding toElement. - * @throws ClassCastException if fromElement or toElement is not comparable - * to the underlying set's contents. - * @throws IllegalArgumentException if fromElement or toElement is outside the set's - * range. - * @throws NullPointerException if fromElement or toElement is null. but the set does - * not allow null elements. - */ - public SortedSet subSet(Object fromElement, Object toElement) - { - synchronized (mutex) - { - return new SynchronizedSortedSet(mutex, - ss.subSet(fromElement, toElement)); - } - } - - /** - * Returns a subset containing all the elements from fromElement onwards. - * The subset supports all operations supported by the underlying - * set and all actions taking place on the subset are also reflected - * in the underlying set. A lock is obtained on the mutex prior to - * subset creation. The subset retains the thread-safe status of - * this set. - * - * @param fromElement the inclusive lower range of the subset. - * @return a subset from fromElement to <code>last()</code>. - * @throws ClassCastException if fromElement is not comparable to the underlying - * set's contents. - * @throws IllegalArgumentException if fromElement is outside the set's range. - * @throws NullPointerException if fromElement is null. but the set does not allow - * null elements. - */ - public SortedSet tailSet(Object fromElement) - { - synchronized (mutex) - { - return new SynchronizedSortedSet(mutex, ss.tailSet(fromElement)); - } - } - } // class SynchronizedSortedSet - - - /** - * Returns an unmodifiable view of the given collection. This allows - * "read-only" access, although changes in the backing collection show up - * in this view. Attempts to modify the collection directly or via iterators - * will fail with {@link UnsupportedOperationException}. Although this view - * prevents changes to the structure of the collection and its elements, the values - * referenced by the objects in the collection can still be modified. - * <p> - * - * Since the collection might be a List or a Set, and those have incompatible - * equals and hashCode requirements, this relies on Object's implementation - * rather than passing those calls on to the wrapped collection. The returned - * Collection implements Serializable, but can only be serialized if - * the collection it wraps is likewise Serializable. - * - * @param c the collection to wrap - * @return a read-only view of the collection - * @see Serializable - */ - public static Collection unmodifiableCollection(Collection c) - { - return new UnmodifiableCollection(c); - } - - /** - * The implementation of {@link #unmodifiableCollection(Collection)}. This - * class name is required for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static class UnmodifiableCollection - implements Collection, Serializable - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 1820017752578914078L; - - /** - * The wrapped collection. Package visible for use by subclasses. - * @serial the real collection - */ - final Collection c; - - /** - * Wrap a given collection. - * @param c the collection to wrap - * @throws NullPointerException if c is null - */ - UnmodifiableCollection(Collection c) - { - this.c = c; - if (c == null) - throw new NullPointerException(); - } - - /** - * Blocks the addition of elements to the underlying collection. - * This method never returns, throwing an exception instead. - * - * @param o the object to add. - * @return <code>true</code> if the collection was modified as a result of this action. - * @throws UnsupportedOperationException as an unmodifiable collection does not - * support the add operation. - */ - public boolean add(Object o) - { - throw new UnsupportedOperationException(); - } - - /** - * Blocks the addition of a collection of elements to the underlying - * collection. This method never returns, throwing an exception instead. - * - * @param c the collection to add. - * @return <code>true</code> if the collection was modified as a result of this action. - * @throws UnsupportedOperationException as an unmodifiable collection does not - * support the <code>addAll</code> operation. - */ - public boolean addAll(Collection c) - { - throw new UnsupportedOperationException(); - } - - /** - * Blocks the clearing of the underlying collection. This method never - * returns, throwing an exception instead. - * - * @throws UnsupportedOperationException as an unmodifiable collection does - * not support the <code>clear()</code> operation. - */ - public void clear() - { - throw new UnsupportedOperationException(); - } - - /** - * Test whether the underlying collection contains a given object as one of its - * elements. - * - * @param o the element to look for. - * @return <code>true</code> if the underlying collection contains at least - * one element e such that - * <code>o == null ? e == null : o.equals(e)</code>. - * @throws ClassCastException if the type of o is not a valid type for the - * underlying collection. - * @throws NullPointerException if o is null and the underlying collection - * doesn't support null values. - */ - public boolean contains(Object o) - { - return c.contains(o); - } - - /** - * Test whether the underlying collection contains every element in a given - * collection. - * - * @param c the collection to test for. - * @return <code>true</code> if for every element o in c, contains(o) would - * return <code>true</code>. - * @throws ClassCastException if the type of any element in c is not a valid - * type for the underlying collection. - * @throws NullPointerException if some element of c is null and the underlying - * collection does not support null values. - * @throws NullPointerException if c itself is null. - */ - public boolean containsAll(Collection c1) - { - return c.containsAll(c1); - } - - /** - * Tests whether the underlying collection is empty, that is, - * if size() == 0. - * - * @return <code>true</code> if this collection contains no elements. - */ - public boolean isEmpty() - { - return c.isEmpty(); - } - - /** - * Obtain an Iterator over the underlying collection, which maintains - * its unmodifiable nature. - * - * @return an UnmodifiableIterator over the elements of the underlying - * collection, in any order. - */ - public Iterator iterator() - { - return new UnmodifiableIterator(c.iterator()); - } - - /** - * Blocks the removal of an object from the underlying collection. - * This method never returns, throwing an exception instead. - * - * @param o The object to remove. - * @return <code>true</code> if the object was removed (i.e. the underlying - * collection returned 1 or more instances of o). - * @throws UnsupportedOperationException as an unmodifiable collection - * does not support the <code>remove()</code> operation. - */ - public boolean remove(Object o) - { - throw new UnsupportedOperationException(); - } - - /** - * Blocks the removal of a collection of objects from the underlying - * collection. This method never returns, throwing an exception - * instead. - * - * @param c The collection of objects to remove. - * @return <code>true</code> if the collection was modified. - * @throws UnsupportedOperationException as an unmodifiable collection - * does not support the <code>removeAll()</code> operation. - */ - public boolean removeAll(Collection c) - { - throw new UnsupportedOperationException(); - } - - /** - * Blocks the removal of all elements from the underlying collection, - * except those in the supplied collection. This method never returns, - * throwing an exception instead. - * - * @param c The collection of objects to retain. - * @return <code>true</code> if the collection was modified. - * @throws UnsupportedOperationException as an unmodifiable collection - * does not support the <code>retainAll()</code> operation. - */ - public boolean retainAll(Collection c) - { - throw new UnsupportedOperationException(); - } - - /** - * Retrieves the number of elements in the underlying collection. - * - * @return the number of elements in the collection. - */ - public int size() - { - return c.size(); - } - - /** - * Copy the current contents of the underlying collection into an array. - * - * @return an array of type Object[] with a length equal to the size of the - * underlying collection and containing the elements currently in - * the underlying collection, in any order. - */ - public Object[] toArray() - { - return c.toArray(); - } - - /** - * Copy the current contents of the underlying collection into an array. If - * the array passed as an argument has length less than the size of the - * underlying collection, an array of the same run-time type as a, with a length - * equal to the size of the underlying collection, is allocated using reflection. - * Otherwise, a itself is used. The elements of the underlying collection are - * copied into it, and if there is space in the array, the following element is - * set to null. The resultant array is returned. - * Note: The fact that the following element is set to null is only useful - * if it is known that this collection does not contain any null elements. - * - * @param a the array to copy this collection into. - * @return an array containing the elements currently in the underlying - * collection, in any order. - * @throws ArrayStoreException if the type of any element of the - * collection is not a subtype of the element type of a. - */ - public Object[] toArray(Object[] a) - { - return c.toArray(a); - } - - /** - * A textual representation of the unmodifiable collection. - * - * @return The unmodifiable collection in the form of a <code>String</code>. - */ - public String toString() - { - return c.toString(); - } - } // class UnmodifiableCollection - - /** - * The implementation of the various iterator methods in the - * unmodifiable classes. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static class UnmodifiableIterator implements Iterator - { - /** - * The wrapped iterator. - */ - private final Iterator i; - - /** - * Only trusted code creates a wrapper. - * @param i the wrapped iterator - */ - UnmodifiableIterator(Iterator i) - { - this.i = i; - } - - /** - * Obtains the next element in the underlying collection. - * - * @return the next element in the collection. - * @throws NoSuchElementException if there are no more elements. - */ - public Object next() - { - return i.next(); - } - /** - * Tests whether there are still elements to be retrieved from the - * underlying collection by <code>next()</code>. When this method - * returns <code>true</code>, an exception will not be thrown on calling - * <code>next()</code>. - * - * @return <code>true</code> if there is at least one more element in the underlying - * collection. - */ - public boolean hasNext() - { - return i.hasNext(); - } - - /** - * Blocks the removal of elements from the underlying collection by the - * iterator. - * - * @throws UnsupportedOperationException as an unmodifiable collection - * does not support the removal of elements by its iterator. - */ - public void remove() - { - throw new UnsupportedOperationException(); - } - } // class UnmodifiableIterator - - /** - * Returns an unmodifiable view of the given list. This allows - * "read-only" access, although changes in the backing list show up - * in this view. Attempts to modify the list directly, via iterators, or - * via sublists, will fail with {@link UnsupportedOperationException}. - * Although this view prevents changes to the structure of the list and - * its elements, the values referenced by the objects in the list can - * still be modified. - * <p> - * - * The returned List implements Serializable, but can only be serialized if - * the list it wraps is likewise Serializable. In addition, if the wrapped - * list implements RandomAccess, this does too. - * - * @param l the list to wrap - * @return a read-only view of the list - * @see Serializable - * @see RandomAccess - */ - public static List unmodifiableList(List l) - { - if (l instanceof RandomAccess) - return new UnmodifiableRandomAccessList(l); - return new UnmodifiableList(l); - } - - /** - * The implementation of {@link #unmodifiableList(List)} for sequential - * lists. This class name is required for compatibility with Sun's JDK - * serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static class UnmodifiableList extends UnmodifiableCollection - implements List - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = -283967356065247728L; - - - /** - * The wrapped list; stored both here and in the superclass to avoid - * excessive casting. Package visible for use by subclass. - * @serial the wrapped list - */ - final List list; - - /** - * Wrap a given list. - * @param l the list to wrap - * @throws NullPointerException if l is null - */ - UnmodifiableList(List l) - { - super(l); - list = l; - } - - /** - * Blocks the addition of an element to the underlying - * list at a specific index. This method never returns, - * throwing an exception instead. - * - * @param index The index at which to place the new element. - * @param o the object to add. - * @throws UnsupportedOperationException as an unmodifiable - * list doesn't support the <code>add()</code> operation. - */ - public void add(int index, Object o) - { - throw new UnsupportedOperationException(); - } - - /** - * Blocks the addition of a collection of elements to the - * underlying list at a specific index. This method never - * returns, throwing an exception instead. - * - * @param index The index at which to place the new element. - * @param c the collections of objects to add. - * @throws UnsupportedOperationException as an unmodifiable - * list doesn't support the <code>addAll()</code> operation. - */ - public boolean addAll(int index, Collection c) - { - throw new UnsupportedOperationException(); - } - - /** - * Returns <code>true</code> if the object, o, is an instance of - * <code>List</code> with the same size and elements - * as the underlying list. - * - * @param o The object to compare. - * @return <code>true</code> if o is equivalent to the underlying list. - */ - public boolean equals(Object o) - { - return list.equals(o); - } - - /** - * Retrieves the element at a given index in the underlying list. - * - * @param index the index of the element to be returned - * @return the element at index index in this list - * @throws IndexOutOfBoundsException if index < 0 || index >= size() - */ - public Object get(int index) - { - return list.get(index); - } - - /** - * Computes the hash code for the underlying list. - * The exact computation is described in the documentation - * of the <code>List</code> interface. - * - * @return The hash code of the underlying list. - * @see List#hashCode() - */ - public int hashCode() - { - return list.hashCode(); - } - - /** - * Obtain the first index at which a given object is to be found in the - * underlying list. - * - * @param o the object to search for - * @return the least integer n such that <code>o == null ? get(n) == null : - * o.equals(get(n))</code>, or -1 if there is no such index. - * @throws ClassCastException if the type of o is not a valid - * type for the underlying list. - * @throws NullPointerException if o is null and the underlying - * list does not support null values. - */ - public int indexOf(Object o) - { - return list.indexOf(o); - } - - /** - * Obtain the last index at which a given object is to be found in the - * underlying list. - * - * @return the greatest integer n such that <code>o == null ? get(n) == null - * : o.equals(get(n))</code>, or -1 if there is no such index. - * @throws ClassCastException if the type of o is not a valid - * type for the underlying list. - * @throws NullPointerException if o is null and the underlying - * list does not support null values. - */ - public int lastIndexOf(Object o) - { - return list.lastIndexOf(o); - } - - /** - * Obtains a list iterator over the underlying list, starting at the beginning - * and maintaining the unmodifiable nature of this list. - * - * @return a <code>UnmodifiableListIterator</code> over the elements of the - * underlying list, in order, starting at the beginning. - */ - public ListIterator listIterator() - { - return new UnmodifiableListIterator(list.listIterator()); - } - - /** - * Obtains a list iterator over the underlying list, starting at the specified - * index and maintaining the unmodifiable nature of this list. An initial call - * to <code>next()</code> will retrieve the element at the specified index, - * and an initial call to <code>previous()</code> will retrieve the element - * at index - 1. - * - * - * @param index the position, between 0 and size() inclusive, to begin the - * iteration from. - * @return a <code>UnmodifiableListIterator</code> over the elements of the - * underlying list, in order, starting at the specified index. - * @throws IndexOutOfBoundsException if index < 0 || index > size() - */ - public ListIterator listIterator(int index) - { - return new UnmodifiableListIterator(list.listIterator(index)); - } - - /** - * Blocks the removal of the element at the specified index. - * This method never returns, throwing an exception instead. - * - * @param index The index of the element to remove. - * @return the removed element. - * @throws UnsupportedOperationException as an unmodifiable - * list does not support the <code>remove()</code> - * operation. - */ - public Object remove(int index) - { - throw new UnsupportedOperationException(); - } - - /** - * Blocks the replacement of the element at the specified index. - * This method never returns, throwing an exception instead. - * - * @param index The index of the element to replace. - * @param o The new object to place at the specified index. - * @return the replaced element. - * @throws UnsupportedOperationException as an unmodifiable - * list does not support the <code>set()</code> - * operation. - */ - public Object set(int index, Object o) - { - throw new UnsupportedOperationException(); - } - - /** - * Obtain a List view of a subsection of the underlying list, from - * fromIndex (inclusive) to toIndex (exclusive). If the two indices - * are equal, the sublist is empty. The returned list will be - * unmodifiable, like this list. Changes to the elements of the - * returned list will be reflected in the underlying list. No structural - * modifications can take place in either list. - * - * @param fromIndex the index that the returned list should start from - * (inclusive). - * @param toIndex the index that the returned list should go to (exclusive). - * @return a List backed by a subsection of the underlying list. - * @throws IndexOutOfBoundsException if fromIndex < 0 - * || toIndex > size() || fromIndex > toIndex. - */ - public List subList(int fromIndex, int toIndex) - { - return unmodifiableList(list.subList(fromIndex, toIndex)); - } - } // class UnmodifiableList - - /** - * The implementation of {@link #unmodifiableList(List)} for random-access - * lists. This class name is required for compatibility with Sun's JDK - * serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class UnmodifiableRandomAccessList - extends UnmodifiableList implements RandomAccess - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = -2542308836966382001L; - - /** - * Wrap a given list. - * @param l the list to wrap - * @throws NullPointerException if l is null - */ - UnmodifiableRandomAccessList(List l) - { - super(l); - } - } // class UnmodifiableRandomAccessList - - /** - * The implementation of {@link UnmodifiableList#listIterator()}. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class UnmodifiableListIterator - extends UnmodifiableIterator implements ListIterator - { - /** - * The wrapped iterator, stored both here and in the superclass to - * avoid excessive casting. - */ - private final ListIterator li; - - /** - * Only trusted code creates a wrapper. - * @param li the wrapped iterator - */ - UnmodifiableListIterator(ListIterator li) - { - super(li); - this.li = li; - } - - /** - * Blocks the addition of an object to the list underlying this iterator. - * This method never returns, throwing an exception instead. - * - * @param o The object to add. - * @throws UnsupportedOperationException as the iterator of an unmodifiable - * list does not support the <code>add()</code> operation. - */ - public void add(Object o) - { - throw new UnsupportedOperationException(); - } - - /** - * Tests whether there are still elements to be retrieved from the - * underlying collection by <code>previous()</code>. When this method - * returns <code>true</code>, an exception will not be thrown on calling - * <code>previous()</code>. - * - * @return <code>true</code> if there is at least one more element prior to the - * current position in the underlying list. - */ - public boolean hasPrevious() - { - return li.hasPrevious(); - } - - /** - * Find the index of the element that would be returned by a call to next. - * If <code>hasNext()</code> returns <code>false</code>, this returns the list size. - * - * @return the index of the element that would be returned by - * <code>next()</code>. - */ - public int nextIndex() - { - return li.nextIndex(); - } - - /** - * Obtains the previous element in the underlying list. - * - * @return the previous element in the list. - * @throws NoSuchElementException if there are no more prior elements. - */ - public Object previous() - { - return li.previous(); - } - - /** - * Find the index of the element that would be returned by a call to - * previous. If <code>hasPrevious()</code> returns <code>false</code>, - * this returns -1. - * - * @return the index of the element that would be returned by - * <code>previous()</code>. - */ - public int previousIndex() - { - return li.previousIndex(); - } - - /** - * Blocks the replacement of an element in the list underlying this - * iterator. This method never returns, throwing an exception instead. - * - * @param o The new object to replace the existing one. - * @throws UnsupportedOperationException as the iterator of an unmodifiable - * list does not support the <code>set()</code> operation. - */ - public void set(Object o) - { - throw new UnsupportedOperationException(); - } - } // class UnmodifiableListIterator - - /** - * Returns an unmodifiable view of the given map. This allows "read-only" - * access, although changes in the backing map show up in this view. - * Attempts to modify the map directly, or via collection views or their - * iterators will fail with {@link UnsupportedOperationException}. - * Although this view prevents changes to the structure of the map and its - * entries, the values referenced by the objects in the map can still be - * modified. - * <p> - * - * The returned Map implements Serializable, but can only be serialized if - * the map it wraps is likewise Serializable. - * - * @param m the map to wrap - * @return a read-only view of the map - * @see Serializable - */ - public static Map unmodifiableMap(Map m) - { - return new UnmodifiableMap(m); - } - - /** - * The implementation of {@link #unmodifiableMap(Map)}. This - * class name is required for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static class UnmodifiableMap implements Map, Serializable - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = -1034234728574286014L; - - /** - * The wrapped map. - * @serial the real map - */ - private final Map m; - - /** - * Cache the entry set. - */ - private transient Set entries; - - /** - * Cache the key set. - */ - private transient Set keys; - - /** - * Cache the value collection. - */ - private transient Collection values; - - /** - * Wrap a given map. - * @param m the map to wrap - * @throws NullPointerException if m is null - */ - UnmodifiableMap(Map m) - { - this.m = m; - if (m == null) - throw new NullPointerException(); - } - - /** - * Blocks the clearing of entries from the underlying map. - * This method never returns, throwing an exception instead. - * - * @throws UnsupportedOperationException as an unmodifiable - * map does not support the <code>clear()</code> operation. - */ - public void clear() - { - throw new UnsupportedOperationException(); - } - - /** - * Returns <code>true</code> if the underlying map contains a mapping for - * the given key. - * - * @param key the key to search for - * @return <code>true</code> if the map contains the key - * @throws ClassCastException if the key is of an inappropriate type - * @throws NullPointerException if key is <code>null</code> but the map - * does not permit null keys - */ - public boolean containsKey(Object key) - { - return m.containsKey(key); - } - - /** - * Returns <code>true</code> if the underlying map contains at least one mapping with - * the given value. In other words, it returns <code>true</code> if a value v exists where - * <code>(value == null ? v == null : value.equals(v))</code>. This usually - * requires linear time. - * - * @param value the value to search for - * @return <code>true</code> if the map contains the value - * @throws ClassCastException if the type of the value is not a valid type - * for this map. - * @throws NullPointerException if the value is null and the map doesn't - * support null values. - */ - public boolean containsValue(Object value) - { - return m.containsValue(value); - } - - /** - * Returns a unmodifiable set view of the entries in the underlying map. - * Each element in the set is a unmodifiable variant of <code>Map.Entry</code>. - * The set is backed by the map, so that changes in one show up in the other. - * Modifications made while an iterator is in progress cause undefined - * behavior. These modifications are again limited to the values of - * the objects. - * - * @return the unmodifiable set view of all mapping entries. - * @see Map.Entry - */ - public Set entrySet() - { - if (entries == null) - entries = new UnmodifiableEntrySet(m.entrySet()); - return entries; - } - - /** - * The implementation of {@link UnmodifiableMap#entrySet()}. This class - * name is required for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class UnmodifiableEntrySet extends UnmodifiableSet - implements Serializable - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 7854390611657943733L; - - /** - * Wrap a given set. - * @param s the set to wrap - */ - UnmodifiableEntrySet(Set s) - { - super(s); - } - - // The iterator must return unmodifiable map entries. - public Iterator iterator() - { - return new UnmodifiableIterator(c.iterator()) - { - /** - * Obtains the next element from the underlying set of - * map entries. - * - * @return the next element in the collection. - * @throws NoSuchElementException if there are no more elements. - */ - public Object next() - { - final Map.Entry e = (Map.Entry) super.next(); - return new Map.Entry() - { - /** - * Returns <code>true</code> if the object, o, is also a map entry with an - * identical key and value. - * - * @param o the object to compare. - * @return <code>true</code> if o is an equivalent map entry. - */ - public boolean equals(Object o) - { - return e.equals(o); - } - - /** - * Returns the key of this map entry. - * - * @return the key. - */ - public Object getKey() - { - return e.getKey(); - } - - /** - * Returns the value of this map entry. - * - * @return the value. - */ - public Object getValue() - { - return e.getValue(); - } - - /** - * Computes the hash code of this map entry. - * The computation is described in the <code>Map</code> - * interface documentation. - * - * @return the hash code of this entry. - * @see Map#hashCode() - */ - public int hashCode() - { - return e.hashCode(); - } - - /** - * Blocks the alteration of the value of this map entry. - * This method never returns, throwing an exception instead. - * - * @param value The new value. - * @throws UnsupportedOperationException as an unmodifiable - * map entry does not support the <code>setValue()</code> - * operation. - */ - public Object setValue(Object value) - { - throw new UnsupportedOperationException(); - } - - /** - * Returns a textual representation of the map entry. - * - * @return The map entry as a <code>String</code>. - */ - public String toString() - { - return e.toString(); - } - }; - } - }; - } - } // class UnmodifiableEntrySet - - /** - * Returns <code>true</code> if the object, o, is also an instance - * of <code>Map</code> with an equal set of map entries. - * - * @param o The object to compare. - * @return <code>true</code> if o is an equivalent map. - */ - public boolean equals(Object o) - { - return m.equals(o); - } - - /** - * Returns the value associated with the supplied key or - * null if no such mapping exists. An ambiguity can occur - * if null values are accepted by the underlying map. - * In this case, <code>containsKey()</code> can be used - * to separate the two possible cases of a null result. - * - * @param key The key to look up. - * @return the value associated with the key, or null if key not in map. - * @throws ClassCastException if the key is an inappropriate type. - * @throws NullPointerException if this map does not accept null keys. - * @see #containsKey(Object) - */ - public Object get(Object key) - { - return m.get(key); - } - - /** - * Blocks the addition of a new entry to the underlying map. - * This method never returns, throwing an exception instead. - * - * @param key The new key. - * @param value The new value. - * @return the previous value of the key, or null if there was no mapping. - * @throws UnsupportedOperationException as an unmodifiable - * map does not support the <code>put()</code> operation. - */ - public Object put(Object key, Object value) - { - throw new UnsupportedOperationException(); - } - - /** - * Computes the hash code for the underlying map, as the sum - * of the hash codes of all entries. - * - * @return The hash code of the underlying map. - * @see Map.Entry#hashCode() - */ - public int hashCode() - { - return m.hashCode(); - } - - /** - * Returns <code>true</code> if the underlying map contains no entries. - * - * @return <code>true</code> if the map is empty. - */ - public boolean isEmpty() - { - return m.isEmpty(); - } - - /** - * Returns a unmodifiable set view of the keys in the underlying map. - * The set is backed by the map, so that changes in one show up in the other. - * Modifications made while an iterator is in progress cause undefined - * behavior. These modifications are again limited to the values of - * the keys. - * - * @return the set view of all keys. - */ - public Set keySet() - { - if (keys == null) - keys = new UnmodifiableSet(m.keySet()); - return keys; - } - - /** - * Blocks the addition of the entries in the supplied map. - * This method never returns, throwing an exception instead. - * - * @param m The map, the entries of which should be added - * to the underlying map. - * @throws UnsupportedOperationException as an unmodifiable - * map does not support the <code>putAll</code> operation. - */ - public void putAll(Map m) - { - throw new UnsupportedOperationException(); - } - - /** - * Blocks the removal of an entry from the map. - * This method never returns, throwing an exception instead. - * - * @param o The key of the entry to remove. - * @return The value the key was associated with, or null - * if no such mapping existed. Null is also returned - * if the removed entry had a null key. - * @throws UnsupportedOperationException as an unmodifiable - * map does not support the <code>remove</code> operation. - */ - public Object remove(Object o) - { - throw new UnsupportedOperationException(); - } - - - /** - * Returns the number of key-value mappings in the underlying map. - * If there are more than Integer.MAX_VALUE mappings, Integer.MAX_VALUE - * is returned. - * - * @return the number of mappings. - */ - public int size() - { - return m.size(); - } - - /** - * Returns a textual representation of the map. - * - * @return The map in the form of a <code>String</code>. - */ - public String toString() - { - return m.toString(); - } - - /** - * Returns a unmodifiable collection view of the values in the underlying map. - * The collection is backed by the map, so that changes in one show up in the other. - * Modifications made while an iterator is in progress cause undefined - * behavior. These modifications are again limited to the values of - * the keys. - * - * @return the collection view of all values. - */ - public Collection values() - { - if (values == null) - values = new UnmodifiableCollection(m.values()); - return values; - } - } // class UnmodifiableMap - - /** - * Returns an unmodifiable view of the given set. This allows - * "read-only" access, although changes in the backing set show up - * in this view. Attempts to modify the set directly or via iterators - * will fail with {@link UnsupportedOperationException}. - * Although this view prevents changes to the structure of the set and its - * entries, the values referenced by the objects in the set can still be - * modified. - * <p> - * - * The returned Set implements Serializable, but can only be serialized if - * the set it wraps is likewise Serializable. - * - * @param s the set to wrap - * @return a read-only view of the set - * @see Serializable - */ - public static Set unmodifiableSet(Set s) - { - return new UnmodifiableSet(s); - } - - /** - * The implementation of {@link #unmodifiableSet(Set)}. This class - * name is required for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static class UnmodifiableSet extends UnmodifiableCollection - implements Set - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = -9215047833775013803L; - - /** - * Wrap a given set. - * @param s the set to wrap - * @throws NullPointerException if s is null - */ - UnmodifiableSet(Set s) - { - super(s); - } - - /** - * Returns <code>true</code> if the object, o, is also an instance of - * <code>Set</code> of the same size and with the same entries. - * - * @return <code>true</code> if o is an equivalent set. - */ - public boolean equals(Object o) - { - return c.equals(o); - } - - /** - * Computes the hash code of this set, as the sum of the - * hash codes of all elements within the set. - * - * @return the hash code of the set. - */ - public int hashCode() - { - return c.hashCode(); - } - } // class UnmodifiableSet - - /** - * Returns an unmodifiable view of the given sorted map. This allows - * "read-only" access, although changes in the backing map show up in this - * view. Attempts to modify the map directly, via subviews, via collection - * views, or iterators, will fail with {@link UnsupportedOperationException}. - * Although this view prevents changes to the structure of the map and its - * entries, the values referenced by the objects in the map can still be - * modified. - * <p> - * - * The returned SortedMap implements Serializable, but can only be - * serialized if the map it wraps is likewise Serializable. - * - * @param m the map to wrap - * @return a read-only view of the map - * @see Serializable - */ - public static SortedMap unmodifiableSortedMap(SortedMap m) - { - return new UnmodifiableSortedMap(m); - } - - /** - * The implementation of {@link #unmodifiableSortedMap(SortedMap)}. This - * class name is required for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static class UnmodifiableSortedMap extends UnmodifiableMap - implements SortedMap - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = -8806743815996713206L; - - /** - * The wrapped map; stored both here and in the superclass to avoid - * excessive casting. - * @serial the wrapped map - */ - private final SortedMap sm; - - /** - * Wrap a given map. - * @param sm the map to wrap - * @throws NullPointerException if sm is null - */ - UnmodifiableSortedMap(SortedMap sm) - { - super(sm); - this.sm = sm; - } - - /** - * Returns the comparator used in sorting the underlying map, - * or null if it is the keys' natural ordering. - * - * @return the sorting comparator. - */ - public Comparator comparator() - { - return sm.comparator(); - } - - /** - * Returns the first (lowest sorted) key in the map. - * - * @return the first key. - * @throws NoSuchElementException if this map is empty. - */ - public Object firstKey() - { - return sm.firstKey(); - } - - /** - * Returns a unmodifiable view of the portion of the map strictly less - * than toKey. The view is backed by the underlying map, so changes in - * one show up in the other. The submap supports all optional operations - * of the original. This operation is equivalent to - * <code>subMap(firstKey(), toKey)</code>. - * <p> - * - * The returned map throws an IllegalArgumentException any time a key is - * used which is out of the range of toKey. Note that the endpoint, toKey, - * is not included; if you want this value to be included, pass its successor - * object in to toKey. For example, for Integers, you could request - * <code>headMap(new Integer(limit.intValue() + 1))</code>. - * - * @param toKey the exclusive upper range of the submap. - * @return the submap. - * @throws ClassCastException if toKey is not comparable to the map contents. - * @throws IllegalArgumentException if this is a subMap, and toKey is out - * of range. - * @throws NullPointerException if toKey is null but the map does not allow - * null keys. - */ - public SortedMap headMap(Object toKey) - { - return new UnmodifiableSortedMap(sm.headMap(toKey)); - } - - /** - * Returns the last (highest sorted) key in the map. - * - * @return the last key. - * @throws NoSuchElementException if this map is empty. - */ - public Object lastKey() - { - return sm.lastKey(); - } - - /** - * Returns a unmodifiable view of the portion of the map greater than or - * equal to fromKey, and strictly less than toKey. The view is backed by - * the underlying map, so changes in one show up in the other. The submap - * supports all optional operations of the original. - * <p> - * - * The returned map throws an IllegalArgumentException any time a key is - * used which is out of the range of fromKey and toKey. Note that the - * lower endpoint is included, but the upper is not; if you want to - * change the inclusion or exclusion of an endpoint, pass its successor - * object in instead. For example, for Integers, you could request - * <code>subMap(new Integer(lowlimit.intValue() + 1), - * new Integer(highlimit.intValue() + 1))</code> to reverse - * the inclusiveness of both endpoints. - * - * @param fromKey the inclusive lower range of the submap. - * @param toKey the exclusive upper range of the submap. - * @return the submap. - * @throws ClassCastException if fromKey or toKey is not comparable to - * the map contents. - * @throws IllegalArgumentException if this is a subMap, and fromKey or - * toKey is out of range. - * @throws NullPointerException if fromKey or toKey is null but the map - * does not allow null keys. - */ - public SortedMap subMap(Object fromKey, Object toKey) - { - return new UnmodifiableSortedMap(sm.subMap(fromKey, toKey)); - } - - /** - * Returns a unmodifiable view of the portion of the map greater than or - * equal to fromKey. The view is backed by the underlying map, so changes - * in one show up in the other. The submap supports all optional operations - * of the original. - * <p> - * - * The returned map throws an IllegalArgumentException any time a key is - * used which is out of the range of fromKey. Note that the endpoint, fromKey, is - * included; if you do not want this value to be included, pass its successor object in - * to fromKey. For example, for Integers, you could request - * <code>tailMap(new Integer(limit.intValue() + 1))</code>. - * - * @param fromKey the inclusive lower range of the submap - * @return the submap - * @throws ClassCastException if fromKey is not comparable to the map - * contents - * @throws IllegalArgumentException if this is a subMap, and fromKey is out - * of range - * @throws NullPointerException if fromKey is null but the map does not allow - * null keys - */ - public SortedMap tailMap(Object fromKey) - { - return new UnmodifiableSortedMap(sm.tailMap(fromKey)); - } - } // class UnmodifiableSortedMap - - /** - * Returns an unmodifiable view of the given sorted set. This allows - * "read-only" access, although changes in the backing set show up - * in this view. Attempts to modify the set directly, via subsets, or via - * iterators, will fail with {@link UnsupportedOperationException}. - * Although this view prevents changes to the structure of the set and its - * entries, the values referenced by the objects in the set can still be - * modified. - * <p> - * - * The returns SortedSet implements Serializable, but can only be - * serialized if the set it wraps is likewise Serializable. - * - * @param s the set to wrap - * @return a read-only view of the set - * @see Serializable - */ - public static SortedSet unmodifiableSortedSet(SortedSet s) - { - return new UnmodifiableSortedSet(s); - } - - /** - * The implementation of {@link #synchronizedSortedMap(SortedMap)}. This - * class name is required for compatibility with Sun's JDK serializability. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static class UnmodifiableSortedSet extends UnmodifiableSet - implements SortedSet - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = -4929149591599911165L; - - /** - * The wrapped set; stored both here and in the superclass to avoid - * excessive casting. - * @serial the wrapped set - */ - private SortedSet ss; - - /** - * Wrap a given set. - * @param ss the set to wrap - * @throws NullPointerException if ss is null - */ - UnmodifiableSortedSet(SortedSet ss) - { - super(ss); - this.ss = ss; - } - - /** - * Returns the comparator used in sorting the underlying set, - * or null if it is the elements' natural ordering. - * - * @return the sorting comparator - */ - public Comparator comparator() - { - return ss.comparator(); - } - - /** - * Returns the first (lowest sorted) element in the underlying - * set. - * - * @return the first element. - * @throws NoSuchElementException if the set is empty. - */ - public Object first() - { - return ss.first(); - } - - /** - * Returns a unmodifiable view of the portion of the set strictly - * less than toElement. The view is backed by the underlying set, - * so changes in one show up in the other. The subset supports - * all optional operations of the original. This operation - * is equivalent to <code>subSet(first(), toElement)</code>. - * <p> - * - * The returned set throws an IllegalArgumentException any time an element is - * used which is out of the range of toElement. Note that the endpoint, toElement, - * is not included; if you want this value included, pass its successor object in to - * toElement. For example, for Integers, you could request - * <code>headSet(new Integer(limit.intValue() + 1))</code>. - * - * @param toElement the exclusive upper range of the subset - * @return the subset. - * @throws ClassCastException if toElement is not comparable to the set - * contents. - * @throws IllegalArgumentException if this is a subSet, and toElement is out - * of range. - * @throws NullPointerException if toElement is null but the set does not - * allow null elements. - */ - public SortedSet headSet(Object toElement) - { - return new UnmodifiableSortedSet(ss.headSet(toElement)); - } - - /** - * Returns the last (highest sorted) element in the underlying - * set. - * - * @return the last element. - * @throws NoSuchElementException if the set is empty. - */ - public Object last() - { - return ss.last(); - } - - /** - * Returns a unmodifiable view of the portion of the set greater than or - * equal to fromElement, and strictly less than toElement. The view is backed by - * the underlying set, so changes in one show up in the other. The subset - * supports all optional operations of the original. - * <p> - * - * The returned set throws an IllegalArgumentException any time an element is - * used which is out of the range of fromElement and toElement. Note that the - * lower endpoint is included, but the upper is not; if you want to - * change the inclusion or exclusion of an endpoint, pass its successor - * object in instead. For example, for Integers, you can request - * <code>subSet(new Integer(lowlimit.intValue() + 1), - * new Integer(highlimit.intValue() + 1))</code> to reverse - * the inclusiveness of both endpoints. - * - * @param fromElement the inclusive lower range of the subset. - * @param toElement the exclusive upper range of the subset. - * @return the subset. - * @throws ClassCastException if fromElement or toElement is not comparable - * to the set contents. - * @throws IllegalArgumentException if this is a subSet, and fromElement or - * toElement is out of range. - * @throws NullPointerException if fromElement or toElement is null but the - * set does not allow null elements. - */ - public SortedSet subSet(Object fromElement, Object toElement) - { - return new UnmodifiableSortedSet(ss.subSet(fromElement, toElement)); - } - - /** - * Returns a unmodifiable view of the portion of the set greater than or equal to - * fromElement. The view is backed by the underlying set, so changes in one show up - * in the other. The subset supports all optional operations of the original. - * <p> - * - * The returned set throws an IllegalArgumentException any time an element is - * used which is out of the range of fromElement. Note that the endpoint, - * fromElement, is included; if you do not want this value to be included, pass its - * successor object in to fromElement. For example, for Integers, you could request - * <code>tailSet(new Integer(limit.intValue() + 1))</code>. - * - * @param fromElement the inclusive lower range of the subset - * @return the subset. - * @throws ClassCastException if fromElement is not comparable to the set - * contents. - * @throws IllegalArgumentException if this is a subSet, and fromElement is - * out of range. - * @throws NullPointerException if fromElement is null but the set does not - * allow null elements. - */ - public SortedSet tailSet(Object fromElement) - { - return new UnmodifiableSortedSet(ss.tailSet(fromElement)); - } - } // class UnmodifiableSortedSet -} // class Collections diff --git a/libjava/java/util/Comparator.java b/libjava/java/util/Comparator.java deleted file mode 100644 index 386bdc1d6a2..00000000000 --- a/libjava/java/util/Comparator.java +++ /dev/null @@ -1,119 +0,0 @@ -/* Comparator.java -- Interface for objects that specify an ordering - Copyright (C) 1998, 2001, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -/** - * Interface for objects that specify an ordering between objects. The ordering - * should be <em>total</em>, such that any two objects of the correct type - * can be compared, and the comparison is reflexive, anti-symmetric, and - * transitive. It is also recommended that the comparator be <em>consistent - * with equals</em>, although this is not a strict requirement. A relation - * is consistent with equals if these two statements always have the same - * results (if no exceptions occur):<br> - * <code>compare((Object) e1, (Object) e2) == 0</code> and - * <code>e1.equals((Object) e2)</code><br> - * Comparators that violate consistency with equals may cause strange behavior - * in sorted lists and sets. For example, a case-sensitive dictionary order - * comparison of Strings is consistent with equals, but if it is - * case-insensitive it is not, because "abc" and "ABC" compare as equal even - * though "abc".equals("ABC") returns false. - * <P> - * In general, Comparators should be Serializable, because when they are passed - * to Serializable data structures such as SortedMap or SortedSet, the entire - * data structure will only serialize correctly if the comparator is - * Serializable. - * - * @author Original author unknown - * @author Eric Blake (ebb9@email.byu.edu) - * @see Comparable - * @see TreeMap - * @see TreeSet - * @see SortedMap - * @see SortedSet - * @see Arrays#sort(Object[], Comparator) - * @see java.io.Serializable - * @since 1.2 - * @status updated to 1.4 - */ -public interface Comparator -{ - /** - * Return an integer that is negative, zero or positive depending on whether - * the first argument is less than, equal to or greater than the second - * according to this ordering. This method should obey the following - * contract: - * <ul> - * <li>if compare(a, b) < 0 then compare(b, a) > 0</li> - * <li>if compare(a, b) throws an exception, so does compare(b, a)</li> - * <li>if compare(a, b) < 0 and compare(b, c) < 0 then compare(a, c) - * < 0</li> - * <li>if compare(a, b) == 0 then compare(a, c) and compare(b, c) must - * have the same sign</li> - * </ul> - * To be consistent with equals, the following additional constraint is - * in place: - * <ul> - * <li>if a.equals(b) or both a and b are null, then - * compare(a, b) == 0.</li> - * </ul><p> - * - * Although it is permissible for a comparator to provide an order - * inconsistent with equals, that should be documented. - * - * @param o1 the first object - * @param o2 the second object - * @return the comparison - * @throws ClassCastException if the elements are not of types that can be - * compared by this ordering. - */ - int compare(Object o1, Object o2); - - /** - * Return true if the object is equal to this object. To be - * considered equal, the argument object must satisfy the constraints - * of <code>Object.equals()</code>, be a Comparator, and impose the - * same ordering as this Comparator. The default implementation - * inherited from Object is usually adequate. - * - * @param obj The object - * @return true if it is a Comparator that imposes the same order - * @see Object#equals(Object) - */ - boolean equals(Object obj); -} diff --git a/libjava/java/util/ConcurrentModificationException.java b/libjava/java/util/ConcurrentModificationException.java deleted file mode 100644 index 3d7ae108415..00000000000 --- a/libjava/java/util/ConcurrentModificationException.java +++ /dev/null @@ -1,92 +0,0 @@ -/* ConcurrentModificationException.java -- Data structure concurrently modified - Copyright (C) 1998, 1999, 2001, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -/* 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. - */ - -/** - * 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. Notice that this can occur - * even in single-threaded designs, if you call methods out of order. - * - * @author Warren Levy (warrenl@cygnus.com) - * @author Eric Blake (ebb9@email.byu.edu) - * @see Collection - * @see Iterator - * @see ListIterator - * @see Vector - * @see LinkedList - * @see HashSet - * @see Hashtable - * @see TreeMap - * @see AbstractList - * @since 1.2 - * @status updated to 1.4 - */ -public class ConcurrentModificationException extends RuntimeException -{ - /** - * Compatible with JDK 1.2. - */ - private static final long serialVersionUID = -3666751008965953603L; - - /** - * Constructs a ConcurrentModificationException with no detail message. - */ - public ConcurrentModificationException() - { - } - - /** - * Constructs a ConcurrentModificationException with a detail message. - * - * @param detail the detail message for the exception - */ - public ConcurrentModificationException(String detail) - { - super(detail); - } -} diff --git a/libjava/java/util/Dictionary.java b/libjava/java/util/Dictionary.java deleted file mode 100644 index 0d44ab67de1..00000000000 --- a/libjava/java/util/Dictionary.java +++ /dev/null @@ -1,136 +0,0 @@ -/* Dictionary.java -- an abstract (and essentially worthless) - class which is Hashtable's superclass - Copyright (C) 1998, 2001, 2002 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -/** - * A Dictionary maps keys to values; <i>how</i> it does that is - * implementation-specific. - * - * This is an abstract class which has really gone by the wayside. - * People at Javasoft are probably embarrassed by it. At this point, - * it might as well be an interface rather than a class, but it remains - * this poor, laughable skeleton for the sake of backwards compatibility. - * At any rate, this was what came before the {@link Map} interface - * in the Collections framework. - * - * @author Jon Zeppieri - * @author Eric Blake (ebb9@email.byu.edu) - * @see Map - * @see Hashtable - * @since 1.0 - * @status updated to 1.4 - */ -public abstract class Dictionary -{ - // WARNING: Dictionary is a CORE class in the bootstrap cycle. See the - // comments in vm/reference/java/lang/Runtime for implications of this fact. - - /** - * Sole constructor (often called implicitly). - */ - public Dictionary() - { - } - - /** - * Returns an Enumeration of the values in this Dictionary. - * - * @return an Enumeration of the values - * @see #keys() - */ - public abstract Enumeration elements(); - - /** - * Returns the value associated with the supplied key, or null - * if no such value exists. Since Dictionaries are not allowed null keys - * or elements, a null result always means the key is not present. - * - * @param key the key to use to fetch the value - * @return the mapped value - * @throws NullPointerException if key is null - * @see #put(Object, Object) - */ - public abstract Object get(Object key); - - /** - * Returns true when there are no elements in this Dictionary. - * - * @return <code>size() == 0</code> - */ - public abstract boolean isEmpty(); - - /** - * Returns an Enumeration of the keys in this Dictionary - * - * @return an Enumeration of the keys - * @see #elements() - */ - public abstract Enumeration keys(); - - /** - * Inserts a new value into this Dictionary, located by the - * supplied key. Dictionary does not support null keys or values, so - * a null return can safely be interpreted as adding a new key. - * - * @param key the key which locates the value - * @param value the value to put into the Dictionary - * @return the previous value of the key, or null if there was none - * @throws NullPointerException if key or value is null - * @see #get(Object) - */ - public abstract Object put(Object key, Object value); - - /** - * Removes from the Dictionary the value located by the given key. A null - * return safely means that the key was not mapped in the Dictionary. - * - * @param key the key used to locate the value to be removed - * @return the value associated with the removed key - * @throws NullPointerException if key is null - */ - public abstract Object remove(Object key); - - /** - * Returns the number of values currently in this Dictionary. - * - * @return the number of keys in the Dictionary - */ - public abstract int size(); -} // class Dictionary diff --git a/libjava/java/util/EmptyStackException.java b/libjava/java/util/EmptyStackException.java deleted file mode 100644 index e8b4509ee5c..00000000000 --- a/libjava/java/util/EmptyStackException.java +++ /dev/null @@ -1,69 +0,0 @@ -/* EmptyStackException.java -- Attempt to pop from an empty stack - Copyright (C) 1998, 1999, 2001, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -/* 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. - */ - -/** - * 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) - * @author Eric Blake (ebb9@email.byu.edu) - * @see Stack - * @since 1.0 - * @status updated to 1.4 - */ -public class EmptyStackException extends RuntimeException -{ - /** - * Compatible with JDK 1.0. - */ - private static final long serialVersionUID = 5084686378493302095L; - - /** - * Constructs an EmptyStackException with no detail message. - */ - public EmptyStackException() - { - } -} diff --git a/libjava/java/util/Enumeration.java b/libjava/java/util/Enumeration.java deleted file mode 100644 index 1365bbb2f0f..00000000000 --- a/libjava/java/util/Enumeration.java +++ /dev/null @@ -1,81 +0,0 @@ -/* Enumeration.java -- Interface for enumerating lists of objects - Copyright (C) 1998, 1999, 2001, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package java.util; - -/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3 - * "The Java Language Specification", ISBN 0-201-63451-1. - * Status: Believed complete and correct - */ - -/** - * Interface for lists of objects that can be returned in sequence. Successive - * objects are obtained by the nextElement method. - * <p> - * As of Java 1.2, the Iterator interface provides the same functionality, but - * with shorter method names and a new optional method to remove items from the - * list. If writing for 1.2, consider using Iterator instead. Enumerations over - * the new collections classes, for use with legacy APIs that require them, can - * be obtained by the enumeration method in class Collections. - * - * @author Warren Levy (warrenl@cygnus.com) - * @author Eric Blake (ebb9@email.byu.edu) - * @see Iterator - * @see Hashtable - * @see Vector - * @since 1.0 - * @status updated to 1.4 - */ -public interface Enumeration -{ - /** - * Tests whether there are elements remaining in the enumeration. - * - * @return true if there is at least one more element in the enumeration, - * that is, if the next call to nextElement will not throw a - * NoSuchElementException. - */ - boolean hasMoreElements(); - - /** - * Obtain the next element in the enumeration. - * - * @return the next element in the enumeration - * @throws NoSuchElementException if there are no more elements - */ - Object nextElement(); -} diff --git a/libjava/java/util/EventListener.java b/libjava/java/util/EventListener.java deleted file mode 100644 index c9a1795f900..00000000000 --- a/libjava/java/util/EventListener.java +++ /dev/null @@ -1,54 +0,0 @@ -/* EventListener.java -- tagging interface for all event listeners - Copyright (C) 1998, 1999, 2001, 2002, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -/** - * Empty interface that is implemented by classes that need to receive - * events. Subinterfaces define methods that can be called to fire an - * event notification. Normally the name of these subinterfaces end in - * <code>Listener</code> and all method described by the subinterface - * take as argument an subclass of <code>EventObject</code>. - * - * @author Tom Tromey (tromey@cygnus.com) - * @see EventObject - * @status updated to 1.4 - */ -public interface EventListener -{ -} diff --git a/libjava/java/util/EventListenerProxy.java b/libjava/java/util/EventListenerProxy.java deleted file mode 100644 index 245c5ffb458..00000000000 --- a/libjava/java/util/EventListenerProxy.java +++ /dev/null @@ -1,75 +0,0 @@ -/* EventListenerProxy.java -- abstract wrapper for event listeners - Copyright (C) 2002, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -/** - * An abstract wrapper for event listeners. This allows subclasses to - * attach additional parameters to an existing event listener to create - * a new one. Subclasses are expected to add methods to set and retrieve - * any attached properties. - * - * @author Eric Blake (ebb9@email.byu.edu) - * @since 1.4 - * @status updated to 1.4 - */ -public abstract class EventListenerProxy implements EventListener -{ - /** The listener that this proxy wraps. */ - private final EventListener listener; - - /** - * Construct a proxy event listener, given an existing one to augment. - * - * @param listener the listener to wrap - */ - public EventListenerProxy(EventListener listener) - { - this.listener = listener; - } - - /** - * Return the wrapped event listener. - * - * @return the listener associated with this proxy - */ - public EventListener getListener() - { - return listener; - } -} // class EventListenerProxy diff --git a/libjava/java/util/EventObject.java b/libjava/java/util/EventObject.java deleted file mode 100644 index 7ced18aa4ba..00000000000 --- a/libjava/java/util/EventObject.java +++ /dev/null @@ -1,101 +0,0 @@ -/* EventObject.java -- represents an event on an object - Copyright (C) 1999, 2000, 2002, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -import java.io.Serializable; - -/** - * Represents Events fired by Objects. - * - * @author Eric Blake (ebb9@email.byu.edu) - * @see EventListener - * @since 1.1 - * @status updated to 1.4 - */ -public class EventObject implements Serializable -{ - /** - * Compatible with JDK 1.1+. - */ - private static final long serialVersionUID = 5516075349620653480L; - - /** - * The source object; in other words, the object which this event takes - * place on. - */ - protected transient Object source; - - /** - * Constructs an EventObject with the specified source. - * - * @param source the source of the event - * @throws IllegalArgumentException if source is null (This is not - * specified, but matches the behavior of the JDK) - */ - public EventObject(Object source) - { - // This check for null is stupid, if you ask me, since source is - // protected and non-final, so a subclass can set it to null later on. - if (source == null) - throw new IllegalArgumentException(); - this.source = source; - } - - /** - * Returns the source of the event. - * - * @return the event source - */ - public Object getSource() - { - return source; - } - - /** - * Converts the event to a String. The format is not specified, but by - * observation, the JDK uses: - * <code>getClass().getName() + "[source=" + source + "]";</code>. - * - * @return String representation of the Event - */ - public String toString() - { - return getClass().getName() + "[source=" + source + "]"; - } -} // class EventObject diff --git a/libjava/java/util/HashMap.java b/libjava/java/util/HashMap.java deleted file mode 100644 index 5ca9cf6d500..00000000000 --- a/libjava/java/util/HashMap.java +++ /dev/null @@ -1,906 +0,0 @@ -/* HashMap.java -- a class providing a basic hashtable data structure, - mapping Object --> Object - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; - -// NOTE: This implementation is very similar to that of Hashtable. If you fix -// a bug in here, chances are you should make a similar change to the Hashtable -// code. - -// NOTE: This implementation has some nasty coding style in order to -// support LinkedHashMap, which extends this. - -/** - * This class provides a hashtable-backed implementation of the - * Map interface. - * <p> - * - * It uses a hash-bucket approach; that is, hash collisions are handled - * by linking the new node off of the pre-existing node (or list of - * nodes). In this manner, techniques such as linear probing (which - * can cause primary clustering) and rehashing (which does not fit very - * well with Java's method of precomputing hash codes) are avoided. - * <p> - * - * Under ideal circumstances (no collisions), HashMap offers O(1) - * performance on most operations (<code>containsValue()</code> is, - * of course, O(n)). In the worst case (all keys map to the same - * hash code -- very unlikely), most operations are O(n). - * <p> - * - * HashMap is part of the JDK1.2 Collections API. It differs from - * Hashtable in that it accepts the null key and null values, and it - * does not support "Enumeration views." Also, it is not synchronized; - * if you plan to use it in multiple threads, consider using:<br> - * <code>Map m = Collections.synchronizedMap(new HashMap(...));</code> - * <p> - * - * The iterators are <i>fail-fast</i>, meaning that any structural - * modification, except for <code>remove()</code> called on the iterator - * itself, cause the iterator to throw a - * <code>ConcurrentModificationException</code> rather than exhibit - * non-deterministic behavior. - * - * @author Jon Zeppieri - * @author Jochen Hoenicke - * @author Bryce McKinlay - * @author Eric Blake (ebb9@email.byu.edu) - * @see Object#hashCode() - * @see Collection - * @see Map - * @see TreeMap - * @see LinkedHashMap - * @see IdentityHashMap - * @see Hashtable - * @since 1.2 - * @status updated to 1.4 - */ -public class HashMap extends AbstractMap - implements Map, Cloneable, Serializable -{ - /** - * Default number of buckets. This is the value the JDK 1.3 uses. Some - * early documentation specified this value as 101. That is incorrect. - * Package visible for use by HashSet. - */ - static final int DEFAULT_CAPACITY = 11; - - /** - * The default load factor; this is explicitly specified by the spec. - * Package visible for use by HashSet. - */ - static final float DEFAULT_LOAD_FACTOR = 0.75f; - - /** - * Compatible with JDK 1.2. - */ - private static final long serialVersionUID = 362498820763181265L; - - /** - * The rounded product of the capacity and the load factor; when the number - * of elements exceeds the threshold, the HashMap calls - * <code>rehash()</code>. - * @serial the threshold for rehashing - */ - private int threshold; - - /** - * Load factor of this HashMap: used in computing the threshold. - * Package visible for use by HashSet. - * @serial the load factor - */ - final float loadFactor; - - /** - * Array containing the actual key-value mappings. - * Package visible for use by nested and subclasses. - */ - transient HashEntry[] buckets; - - /** - * Counts the number of modifications this HashMap has undergone, used - * by Iterators to know when to throw ConcurrentModificationExceptions. - * Package visible for use by nested and subclasses. - */ - transient int modCount; - - /** - * The size of this HashMap: denotes the number of key-value pairs. - * Package visible for use by nested and subclasses. - */ - transient int size; - - /** - * The cache for {@link #entrySet()}. - */ - private transient Set entries; - - /** - * Class to represent an entry in the hash table. Holds a single key-value - * pair. Package visible for use by subclass. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - static class HashEntry extends AbstractMap.BasicMapEntry - { - /** - * The next entry in the linked list. Package visible for use by subclass. - */ - HashEntry next; - - /** - * Simple constructor. - * @param key the key - * @param value the value - */ - HashEntry(Object key, Object value) - { - super(key, value); - } - - /** - * Called when this entry is accessed via {@link #put(Object, Object)}. - * This version does nothing, but in LinkedHashMap, it must do some - * bookkeeping for access-traversal mode. - */ - void access() - { - } - - /** - * Called when this entry is removed from the map. This version simply - * returns the value, but in LinkedHashMap, it must also do bookkeeping. - * - * @return the value of this key as it is removed - */ - Object cleanup() - { - return value; - } - } - - /** - * Construct a new HashMap with the default capacity (11) and the default - * load factor (0.75). - */ - public HashMap() - { - this(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR); - } - - /** - * Construct a new HashMap from the given Map, with initial capacity - * the greater of the size of <code>m</code> or the default of 11. - * <p> - * - * Every element in Map m will be put into this new HashMap. - * - * @param m a Map whose key / value pairs will be put into the new HashMap. - * <b>NOTE: key / value pairs are not cloned in this constructor.</b> - * @throws NullPointerException if m is null - */ - public HashMap(Map m) - { - this(Math.max(m.size() * 2, DEFAULT_CAPACITY), DEFAULT_LOAD_FACTOR); - putAll(m); - } - - /** - * Construct a new HashMap with a specific inital capacity and - * default load factor of 0.75. - * - * @param initialCapacity the initial capacity of this HashMap (>=0) - * @throws IllegalArgumentException if (initialCapacity < 0) - */ - public HashMap(int initialCapacity) - { - this(initialCapacity, DEFAULT_LOAD_FACTOR); - } - - /** - * Construct a new HashMap with a specific inital capacity and load factor. - * - * @param initialCapacity the initial capacity (>=0) - * @param loadFactor the load factor (> 0, not NaN) - * @throws IllegalArgumentException if (initialCapacity < 0) || - * ! (loadFactor > 0.0) - */ - public HashMap(int initialCapacity, float loadFactor) - { - if (initialCapacity < 0) - throw new IllegalArgumentException("Illegal Capacity: " - + initialCapacity); - if (! (loadFactor > 0)) // check for NaN too - throw new IllegalArgumentException("Illegal Load: " + loadFactor); - - if (initialCapacity == 0) - initialCapacity = 1; - buckets = new HashEntry[initialCapacity]; - this.loadFactor = loadFactor; - threshold = (int) (initialCapacity * loadFactor); - } - - /** - * Returns the number of kay-value mappings currently in this Map. - * - * @return the size - */ - public int size() - { - return size; - } - - /** - * Returns true if there are no key-value mappings currently in this Map. - * - * @return <code>size() == 0</code> - */ - public boolean isEmpty() - { - return size == 0; - } - - /** - * Return the value in this HashMap associated with the supplied key, - * or <code>null</code> if the key maps to nothing. NOTE: Since the value - * could also be null, you must use containsKey to see if this key - * actually maps to something. - * - * @param key the key for which to fetch an associated value - * @return what the key maps to, if present - * @see #put(Object, Object) - * @see #containsKey(Object) - */ - public Object get(Object key) - { - int idx = hash(key); - HashEntry e = buckets[idx]; - while (e != null) - { - if (equals(key, e.key)) - return e.value; - e = e.next; - } - return null; - } - - /** - * Returns true if the supplied object <code>equals()</code> a key - * in this HashMap. - * - * @param key the key to search for in this HashMap - * @return true if the key is in the table - * @see #containsValue(Object) - */ - public boolean containsKey(Object key) - { - int idx = hash(key); - HashEntry e = buckets[idx]; - while (e != null) - { - if (equals(key, e.key)) - return true; - e = e.next; - } - return false; - } - - /** - * Puts the supplied value into the Map, mapped by the supplied key. - * The value may be retrieved by any object which <code>equals()</code> - * this key. NOTE: Since the prior value could also be null, you must - * first use containsKey if you want to see if you are replacing the - * key's mapping. - * - * @param key the key used to locate the value - * @param value the value to be stored in the HashMap - * @return the prior mapping of the key, or null if there was none - * @see #get(Object) - * @see Object#equals(Object) - */ - public Object put(Object key, Object value) - { - int idx = hash(key); - HashEntry e = buckets[idx]; - - while (e != null) - { - if (equals(key, e.key)) - { - e.access(); // Must call this for bookkeeping in LinkedHashMap. - Object r = e.value; - e.value = value; - return r; - } - else - e = e.next; - } - - // At this point, we know we need to add a new entry. - modCount++; - if (++size > threshold) - { - rehash(); - // Need a new hash value to suit the bigger table. - idx = hash(key); - } - - // LinkedHashMap cannot override put(), hence this call. - addEntry(key, value, idx, true); - return null; - } - - /** - * Copies all elements of the given map into this hashtable. If this table - * already has a mapping for a key, the new mapping replaces the current - * one. - * - * @param m the map to be hashed into this - */ - public void putAll(Map m) - { - Iterator itr = m.entrySet().iterator(); - while (itr.hasNext()) - { - Map.Entry e = (Map.Entry) itr.next(); - // Optimize in case the Entry is one of our own. - if (e instanceof AbstractMap.BasicMapEntry) - { - AbstractMap.BasicMapEntry entry = (AbstractMap.BasicMapEntry) e; - put(entry.key, entry.value); - } - else - put(e.getKey(), e.getValue()); - } - } - - /** - * Removes from the HashMap and returns the value which is mapped by the - * supplied key. If the key maps to nothing, then the HashMap remains - * unchanged, and <code>null</code> is returned. NOTE: Since the value - * could also be null, you must use containsKey to see if you are - * actually removing a mapping. - * - * @param key the key used to locate the value to remove - * @return whatever the key mapped to, if present - */ - public Object remove(Object key) - { - int idx = hash(key); - HashEntry e = buckets[idx]; - HashEntry last = null; - - while (e != null) - { - if (equals(key, e.key)) - { - modCount++; - if (last == null) - buckets[idx] = e.next; - else - last.next = e.next; - size--; - // Method call necessary for LinkedHashMap to work correctly. - return e.cleanup(); - } - last = e; - e = e.next; - } - return null; - } - - /** - * Clears the Map so it has no keys. This is O(1). - */ - public void clear() - { - if (size != 0) - { - modCount++; - Arrays.fill(buckets, null); - size = 0; - } - } - - /** - * Returns true if this HashMap contains a value <code>o</code>, such that - * <code>o.equals(value)</code>. - * - * @param value the value to search for in this HashMap - * @return true if at least one key maps to the value - * @see containsKey(Object) - */ - public boolean containsValue(Object value) - { - for (int i = buckets.length - 1; i >= 0; i--) - { - HashEntry e = buckets[i]; - while (e != null) - { - if (equals(value, e.value)) - return true; - e = e.next; - } - } - return false; - } - - /** - * Returns a shallow clone of this HashMap. The Map itself is cloned, - * but its contents are not. This is O(n). - * - * @return the clone - */ - public Object clone() - { - HashMap copy = null; - try - { - copy = (HashMap) super.clone(); - } - catch (CloneNotSupportedException x) - { - // This is impossible. - } - copy.buckets = new HashEntry[buckets.length]; - copy.putAllInternal(this); - // Clear the entry cache. AbstractMap.clone() does the others. - copy.entries = null; - return copy; - } - - /** - * Returns a "set view" of this HashMap's keys. The set is backed by the - * HashMap, so changes in one show up in the other. The set supports - * element removal, but not element addition. - * - * @return a set view of the keys - * @see #values() - * @see #entrySet() - */ - public Set keySet() - { - if (keys == null) - // Create an AbstractSet with custom implementations of those methods - // that can be overridden easily and efficiently. - keys = new AbstractSet() - { - public int size() - { - return size; - } - - public Iterator iterator() - { - // Cannot create the iterator directly, because of LinkedHashMap. - return HashMap.this.iterator(KEYS); - } - - public void clear() - { - HashMap.this.clear(); - } - - public boolean contains(Object o) - { - return containsKey(o); - } - - public boolean remove(Object o) - { - // Test against the size of the HashMap to determine if anything - // really got removed. This is necessary because the return value - // of HashMap.remove() is ambiguous in the null case. - int oldsize = size; - HashMap.this.remove(o); - return oldsize != size; - } - }; - return keys; - } - - /** - * Returns a "collection view" (or "bag view") of this HashMap's values. - * The collection is backed by the HashMap, so changes in one show up - * in the other. The collection supports element removal, but not element - * addition. - * - * @return a bag view of the values - * @see #keySet() - * @see #entrySet() - */ - public Collection values() - { - if (values == null) - // We don't bother overriding many of the optional methods, as doing so - // wouldn't provide any significant performance advantage. - values = new AbstractCollection() - { - public int size() - { - return size; - } - - public Iterator iterator() - { - // Cannot create the iterator directly, because of LinkedHashMap. - return HashMap.this.iterator(VALUES); - } - - public void clear() - { - HashMap.this.clear(); - } - }; - return values; - } - - /** - * Returns a "set view" of this HashMap's entries. The set is backed by - * the HashMap, so changes in one show up in the other. The set supports - * element removal, but not element addition.<p> - * - * Note that the iterators for all three views, from keySet(), entrySet(), - * and values(), traverse the HashMap in the same sequence. - * - * @return a set view of the entries - * @see #keySet() - * @see #values() - * @see Map.Entry - */ - public Set entrySet() - { - if (entries == null) - // Create an AbstractSet with custom implementations of those methods - // that can be overridden easily and efficiently. - entries = new AbstractSet() - { - public int size() - { - return size; - } - - public Iterator iterator() - { - // Cannot create the iterator directly, because of LinkedHashMap. - return HashMap.this.iterator(ENTRIES); - } - - public void clear() - { - HashMap.this.clear(); - } - - public boolean contains(Object o) - { - return getEntry(o) != null; - } - - public boolean remove(Object o) - { - HashEntry e = getEntry(o); - if (e != null) - { - HashMap.this.remove(e.key); - return true; - } - return false; - } - }; - return entries; - } - - /** - * Helper method for put, that creates and adds a new Entry. This is - * overridden in LinkedHashMap for bookkeeping purposes. - * - * @param key the key of the new Entry - * @param value the value - * @param idx the index in buckets where the new Entry belongs - * @param callRemove whether to call the removeEldestEntry method - * @see #put(Object, Object) - */ - void addEntry(Object key, Object value, int idx, boolean callRemove) - { - HashEntry e = new HashEntry(key, value); - e.next = buckets[idx]; - buckets[idx] = e; - } - - /** - * Helper method for entrySet(), which matches both key and value - * simultaneously. - * - * @param o the entry to match - * @return the matching entry, if found, or null - * @see #entrySet() - */ - // Package visible, for use in nested classes. - final HashEntry getEntry(Object o) - { - if (! (o instanceof Map.Entry)) - return null; - Map.Entry me = (Map.Entry) o; - Object key = me.getKey(); - int idx = hash(key); - HashEntry e = buckets[idx]; - while (e != null) - { - if (equals(e.key, key)) - return equals(e.value, me.getValue()) ? e : null; - e = e.next; - } - return null; - } - - /** - * Helper method that returns an index in the buckets array for `key' - * based on its hashCode(). Package visible for use by subclasses. - * - * @param key the key - * @return the bucket number - */ - final int hash(Object key) - { - return key == null ? 0 : Math.abs(key.hashCode() % buckets.length); - } - - /** - * Generates a parameterized iterator. Must be overrideable, since - * LinkedHashMap iterates in a different order. - * - * @param type {@link #KEYS}, {@link #VALUES}, or {@link #ENTRIES} - * @return the appropriate iterator - */ - Iterator iterator(int type) - { - return new HashIterator(type); - } - - /** - * A simplified, more efficient internal implementation of putAll(). clone() - * should not call putAll or put, in order to be compatible with the JDK - * implementation with respect to subclasses. - * - * @param m the map to initialize this from - */ - void putAllInternal(Map m) - { - Iterator itr = m.entrySet().iterator(); - size = 0; - while (itr.hasNext()) - { - size++; - Map.Entry e = (Map.Entry) itr.next(); - Object key = e.getKey(); - int idx = hash(key); - addEntry(key, e.getValue(), idx, false); - } - } - - /** - * Increases the size of the HashMap and rehashes all keys to new - * array indices; this is called when the addition of a new value - * would cause size() > threshold. Note that the existing Entry - * objects are reused in the new hash table. - * - * <p>This is not specified, but the new size is twice the current size - * plus one; this number is not always prime, unfortunately. - */ - private void rehash() - { - HashEntry[] oldBuckets = buckets; - - int newcapacity = (buckets.length * 2) + 1; - threshold = (int) (newcapacity * loadFactor); - buckets = new HashEntry[newcapacity]; - - for (int i = oldBuckets.length - 1; i >= 0; i--) - { - HashEntry e = oldBuckets[i]; - while (e != null) - { - int idx = hash(e.key); - HashEntry dest = buckets[idx]; - HashEntry next = e.next; - e.next = buckets[idx]; - buckets[idx] = e; - e = next; - } - } - } - - /** - * Serializes this object to the given stream. - * - * @param s the stream to write to - * @throws IOException if the underlying stream fails - * @serialData the <i>capacity</i>(int) that is the length of the - * bucket array, the <i>size</i>(int) of the hash map - * are emitted first. They are followed by size entries, - * each consisting of a key (Object) and a value (Object). - */ - private void writeObject(ObjectOutputStream s) throws IOException - { - // Write the threshold and loadFactor fields. - s.defaultWriteObject(); - - s.writeInt(buckets.length); - s.writeInt(size); - // Avoid creating a wasted Set by creating the iterator directly. - Iterator it = iterator(ENTRIES); - while (it.hasNext()) - { - HashEntry entry = (HashEntry) it.next(); - s.writeObject(entry.key); - s.writeObject(entry.value); - } - } - - /** - * Deserializes this object from the given stream. - * - * @param s the stream to read from - * @throws ClassNotFoundException if the underlying stream fails - * @throws IOException if the underlying stream fails - * @serialData the <i>capacity</i>(int) that is the length of the - * bucket array, the <i>size</i>(int) of the hash map - * are emitted first. They are followed by size entries, - * each consisting of a key (Object) and a value (Object). - */ - private void readObject(ObjectInputStream s) - throws IOException, ClassNotFoundException - { - // Read the threshold and loadFactor fields. - s.defaultReadObject(); - - // Read and use capacity, followed by key/value pairs. - buckets = new HashEntry[s.readInt()]; - int len = s.readInt(); - size = len; - while (len-- > 0) - { - Object key = s.readObject(); - addEntry(key, s.readObject(), hash(key), false); - } - } - - /** - * Iterate over HashMap's entries. - * This implementation is parameterized to give a sequential view of - * keys, values, or entries. - * - * @author Jon Zeppieri - */ - private final class HashIterator implements Iterator - { - /** - * The type of this Iterator: {@link #KEYS}, {@link #VALUES}, - * or {@link #ENTRIES}. - */ - private final int type; - /** - * The number of modifications to the backing HashMap that we know about. - */ - private int knownMod = modCount; - /** The number of elements remaining to be returned by next(). */ - private int count = size; - /** Current index in the physical hash table. */ - private int idx = buckets.length; - /** The last Entry returned by a next() call. */ - private HashEntry last; - /** - * The next entry that should be returned by next(). It is set to something - * if we're iterating through a bucket that contains multiple linked - * entries. It is null if next() needs to find a new bucket. - */ - private HashEntry next; - - /** - * Construct a new HashIterator with the supplied type. - * @param type {@link #KEYS}, {@link #VALUES}, or {@link #ENTRIES} - */ - HashIterator(int type) - { - this.type = type; - } - - /** - * Returns true if the Iterator has more elements. - * @return true if there are more elements - * @throws ConcurrentModificationException if the HashMap was modified - */ - public boolean hasNext() - { - if (knownMod != modCount) - throw new ConcurrentModificationException(); - return count > 0; - } - - /** - * Returns the next element in the Iterator's sequential view. - * @return the next element - * @throws ConcurrentModificationException if the HashMap was modified - * @throws NoSuchElementException if there is none - */ - public Object next() - { - if (knownMod != modCount) - throw new ConcurrentModificationException(); - if (count == 0) - throw new NoSuchElementException(); - count--; - HashEntry e = next; - - while (e == null) - e = buckets[--idx]; - - next = e.next; - last = e; - if (type == VALUES) - return e.value; - if (type == KEYS) - return e.key; - return e; - } - - /** - * Removes from the backing HashMap the last element which was fetched - * with the <code>next()</code> method. - * @throws ConcurrentModificationException if the HashMap was modified - * @throws IllegalStateException if called when there is no last element - */ - public void remove() - { - if (knownMod != modCount) - throw new ConcurrentModificationException(); - if (last == null) - throw new IllegalStateException(); - - HashMap.this.remove(last.key); - last = null; - knownMod++; - } - } -} diff --git a/libjava/java/util/HashSet.java b/libjava/java/util/HashSet.java deleted file mode 100644 index 681d5bb1b07..00000000000 --- a/libjava/java/util/HashSet.java +++ /dev/null @@ -1,293 +0,0 @@ -/* HashSet.java -- a class providing a HashMap-backed Set - Copyright (C) 1998, 1999, 2001, 2004, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; - -/** - * This class provides a HashMap-backed implementation of the Set interface. - * <p> - * - * Most operations are O(1), assuming no hash collisions. In the worst - * case (where all hashes collide), operations are O(n). Setting the - * initial capacity too low will force many resizing operations, but - * setting the initial capacity too high (or loadfactor too low) leads - * to wasted memory and slower iteration. - * <p> - * - * HashSet accepts the null key and null values. It is not synchronized, - * so if you need multi-threaded access, consider using:<br> - * <code>Set s = Collections.synchronizedSet(new HashSet(...));</code> - * <p> - * - * The iterators are <i>fail-fast</i>, meaning that any structural - * modification, except for <code>remove()</code> called on the iterator - * itself, cause the iterator to throw a - * {@link ConcurrentModificationException} rather than exhibit - * non-deterministic behavior. - * - * @author Jon Zeppieri - * @author Eric Blake (ebb9@email.byu.edu) - * @see Collection - * @see Set - * @see TreeSet - * @see Collections#synchronizedSet(Set) - * @see HashMap - * @see LinkedHashSet - * @since 1.2 - * @status updated to 1.4 - */ -public class HashSet extends AbstractSet - implements Set, Cloneable, Serializable -{ - /** - * Compatible with JDK 1.2. - */ - private static final long serialVersionUID = -5024744406713321676L; - - /** - * The HashMap which backs this Set. - */ - private transient HashMap map; - - /** - * Construct a new, empty HashSet whose backing HashMap has the default - * capacity (11) and loadFacor (0.75). - */ - public HashSet() - { - this(HashMap.DEFAULT_CAPACITY, HashMap.DEFAULT_LOAD_FACTOR); - } - - /** - * Construct a new, empty HashSet whose backing HashMap has the supplied - * capacity and the default load factor (0.75). - * - * @param initialCapacity the initial capacity of the backing HashMap - * @throws IllegalArgumentException if the capacity is negative - */ - public HashSet(int initialCapacity) - { - this(initialCapacity, HashMap.DEFAULT_LOAD_FACTOR); - } - - /** - * Construct a new, empty HashSet whose backing HashMap has the supplied - * capacity and load factor. - * - * @param initialCapacity the initial capacity of the backing HashMap - * @param loadFactor the load factor of the backing HashMap - * @throws IllegalArgumentException if either argument is negative, or - * if loadFactor is POSITIVE_INFINITY or NaN - */ - public HashSet(int initialCapacity, float loadFactor) - { - map = init(initialCapacity, loadFactor); - } - - /** - * Construct a new HashSet with the same elements as are in the supplied - * collection (eliminating any duplicates, of course). The backing storage - * has twice the size of the collection, or the default size of 11, - * whichever is greater; and the default load factor (0.75). - * - * @param c a collection of initial set elements - * @throws NullPointerException if c is null - */ - public HashSet(Collection c) - { - this(Math.max(2 * c.size(), HashMap.DEFAULT_CAPACITY)); - addAll(c); - } - - /** - * Adds the given Object to the set if it is not already in the Set. - * This set permits a null element. - * - * @param o the Object to add to this Set - * @return true if the set did not already contain o - */ - public boolean add(Object o) - { - return map.put(o, "") == null; - } - - /** - * Empties this Set of all elements; this takes constant time. - */ - public void clear() - { - map.clear(); - } - - /** - * Returns a shallow copy of this Set. The Set itself is cloned; its - * elements are not. - * - * @return a shallow clone of the set - */ - public Object clone() - { - HashSet copy = null; - try - { - copy = (HashSet) super.clone(); - } - catch (CloneNotSupportedException x) - { - // Impossible to get here. - } - copy.map = (HashMap) map.clone(); - return copy; - } - - /** - * Returns true if the supplied element is in this Set. - * - * @param o the Object to look for - * @return true if it is in the set - */ - public boolean contains(Object o) - { - return map.containsKey(o); - } - - /** - * Returns true if this set has no elements in it. - * - * @return <code>size() == 0</code>. - */ - public boolean isEmpty() - { - return map.size == 0; - } - - /** - * Returns an Iterator over the elements of this Set, which visits the - * elements in no particular order. For this class, the Iterator allows - * removal of elements. The iterator is fail-fast, and will throw a - * ConcurrentModificationException if the set is modified externally. - * - * @return a set iterator - * @see ConcurrentModificationException - */ - public Iterator iterator() - { - // Avoid creating intermediate keySet() object by using non-public API. - return map.iterator(HashMap.KEYS); - } - - /** - * Removes the supplied Object from this Set if it is in the Set. - * - * @param o the object to remove - * @return true if an element was removed - */ - public boolean remove(Object o) - { - return (map.remove(o) != null); - } - - /** - * Returns the number of elements in this Set (its cardinality). - * - * @return the size of the set - */ - public int size() - { - return map.size; - } - - /** - * Helper method which initializes the backing Map. Overridden by - * LinkedHashSet for correct semantics. - * - * @param capacity the initial capacity - * @param load the initial load factor - * @return the backing HashMap - */ - HashMap init(int capacity, float load) - { - return new HashMap(capacity, load); - } - - /** - * Serializes this object to the given stream. - * - * @param s the stream to write to - * @throws IOException if the underlying stream fails - * @serialData the <i>capacity</i> (int) and <i>loadFactor</i> (float) - * of the backing store, followed by the set size (int), - * then a listing of its elements (Object) in no order - */ - private void writeObject(ObjectOutputStream s) throws IOException - { - s.defaultWriteObject(); - // Avoid creating intermediate keySet() object by using non-public API. - Iterator it = map.iterator(HashMap.KEYS); - s.writeInt(map.buckets.length); - s.writeFloat(map.loadFactor); - s.writeInt(map.size); - while (it.hasNext()) - s.writeObject(it.next()); - } - - /** - * Deserializes this object from the given stream. - * - * @param s the stream to read from - * @throws ClassNotFoundException if the underlying stream fails - * @throws IOException if the underlying stream fails - * @serialData the <i>capacity</i> (int) and <i>loadFactor</i> (float) - * of the backing store, followed by the set size (int), - * then a listing of its elements (Object) in no order - */ - private void readObject(ObjectInputStream s) - throws IOException, ClassNotFoundException - { - s.defaultReadObject(); - - map = init(s.readInt(), s.readFloat()); - for (int size = s.readInt(); size > 0; size--) - map.put(s.readObject(), ""); - } -} diff --git a/libjava/java/util/Hashtable.java b/libjava/java/util/Hashtable.java deleted file mode 100644 index 78d5fa10c69..00000000000 --- a/libjava/java/util/Hashtable.java +++ /dev/null @@ -1,1151 +0,0 @@ -/* Hashtable.java -- a class providing a basic hashtable data structure, - mapping Object --> Object - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package java.util; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; - -// NOTE: This implementation is very similar to that of HashMap. If you fix -// a bug in here, chances are you should make a similar change to the HashMap -// code. - -/** - * A class which implements a hashtable data structure. - * <p> - * - * This implementation of Hashtable uses a hash-bucket approach. That is: - * linear probing and rehashing is avoided; instead, each hashed value maps - * to a simple linked-list which, in the best case, only has one node. - * Assuming a large enough table, low enough load factor, and / or well - * implemented hashCode() methods, Hashtable should provide O(1) - * insertion, deletion, and searching of keys. Hashtable is O(n) in - * the worst case for all of these (if all keys hash to the same bucket). - * <p> - * - * This is a JDK-1.2 compliant implementation of Hashtable. As such, it - * belongs, partially, to the Collections framework (in that it implements - * Map). For backwards compatibility, it inherits from the obsolete and - * utterly useless Dictionary class. - * <p> - * - * Being a hybrid of old and new, Hashtable has methods which provide redundant - * capability, but with subtle and even crucial differences. - * For example, one can iterate over various aspects of a Hashtable with - * either an Iterator (which is the JDK-1.2 way of doing things) or with an - * Enumeration. The latter can end up in an undefined state if the Hashtable - * changes while the Enumeration is open. - * <p> - * - * Unlike HashMap, Hashtable does not accept `null' as a key value. Also, - * all accesses are synchronized: in a single thread environment, this is - * expensive, but in a multi-thread environment, this saves you the effort - * of extra synchronization. However, the old-style enumerators are not - * synchronized, because they can lead to unspecified behavior even if - * they were synchronized. You have been warned. - * <p> - * - * The iterators are <i>fail-fast</i>, meaning that any structural - * modification, except for <code>remove()</code> called on the iterator - * itself, cause the iterator to throw a - * <code>ConcurrentModificationException</code> rather than exhibit - * non-deterministic behavior. - * - * @author Jon Zeppieri - * @author Warren Levy - * @author Bryce McKinlay - * @author Eric Blake (ebb9@email.byu.edu) - * @see HashMap - * @see TreeMap - * @see IdentityHashMap - * @see LinkedHashMap - * @since 1.0 - * @status updated to 1.4 - */ -public class Hashtable extends Dictionary - implements Map, Cloneable, Serializable -{ - // WARNING: Hashtable is a CORE class in the bootstrap cycle. See the - // comments in vm/reference/java/lang/Runtime for implications of this fact. - - /** Default number of buckets. This is the value the JDK 1.3 uses. Some - * early documentation specified this value as 101. That is incorrect. - */ - private static final int DEFAULT_CAPACITY = 11; - - /** An "enum" of iterator types. */ - // Package visible for use by nested classes. - static final int KEYS = 0, - VALUES = 1, - ENTRIES = 2; - - /** - * The default load factor; this is explicitly specified by the spec. - */ - private static final float DEFAULT_LOAD_FACTOR = 0.75f; - - /** - * Compatible with JDK 1.0+. - */ - private static final long serialVersionUID = 1421746759512286392L; - - /** - * The rounded product of the capacity and the load factor; when the number - * of elements exceeds the threshold, the Hashtable calls - * <code>rehash()</code>. - * @serial - */ - private int threshold; - - /** - * Load factor of this Hashtable: used in computing the threshold. - * @serial - */ - private final float loadFactor; - - /** - * Array containing the actual key-value mappings. - */ - // Package visible for use by nested classes. - transient HashEntry[] buckets; - - /** - * Counts the number of modifications this Hashtable has undergone, used - * by Iterators to know when to throw ConcurrentModificationExceptions. - */ - // Package visible for use by nested classes. - transient int modCount; - - /** - * The size of this Hashtable: denotes the number of key-value pairs. - */ - // Package visible for use by nested classes. - transient int size; - - /** - * The cache for {@link #keySet()}. - */ - private transient Set keys; - - /** - * The cache for {@link #values()}. - */ - private transient Collection values; - - /** - * The cache for {@link #entrySet()}. - */ - private transient Set entries; - - /** - * Class to represent an entry in the hash table. Holds a single key-value - * pair. A Hashtable Entry is identical to a HashMap Entry, except that - * `null' is not allowed for keys and values. - */ - private static final class HashEntry extends AbstractMap.BasicMapEntry - { - /** The next entry in the linked list. */ - HashEntry next; - - /** - * Simple constructor. - * @param key the key, already guaranteed non-null - * @param value the value, already guaranteed non-null - */ - HashEntry(Object key, Object value) - { - super(key, value); - } - - /** - * Resets the value. - * @param newValue the new value - * @return the prior value - * @throws NullPointerException if <code>newVal</code> is null - */ - public Object setValue(Object newVal) - { - if (newVal == null) - throw new NullPointerException(); - return super.setValue(newVal); - } - } - - /** - * Construct a new Hashtable with the default capacity (11) and the default - * load factor (0.75). - */ - public Hashtable() - { - this(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR); - } - - /** - * Construct a new Hashtable from the given Map, with initial capacity - * the greater of the size of <code>m</code> or the default of 11. - * <p> - * - * Every element in Map m will be put into this new Hashtable. - * - * @param m a Map whose key / value pairs will be put into - * the new Hashtable. <b>NOTE: key / value pairs - * are not cloned in this constructor.</b> - * @throws NullPointerException if m is null, or if m contains a mapping - * to or from `null'. - * @since 1.2 - */ - public Hashtable(Map m) - { - this(Math.max(m.size() * 2, DEFAULT_CAPACITY), DEFAULT_LOAD_FACTOR); - putAll(m); - } - - /** - * Construct a new Hashtable with a specific inital capacity and - * default load factor of 0.75. - * - * @param initialCapacity the initial capacity of this Hashtable (>= 0) - * @throws IllegalArgumentException if (initialCapacity < 0) - */ - public Hashtable(int initialCapacity) - { - this(initialCapacity, DEFAULT_LOAD_FACTOR); - } - - /** - * Construct a new Hashtable with a specific initial capacity and - * load factor. - * - * @param initialCapacity the initial capacity (>= 0) - * @param loadFactor the load factor (> 0, not NaN) - * @throws IllegalArgumentException if (initialCapacity < 0) || - * ! (loadFactor > 0.0) - */ - public Hashtable(int initialCapacity, float loadFactor) - { - if (initialCapacity < 0) - throw new IllegalArgumentException("Illegal Capacity: " - + initialCapacity); - if (! (loadFactor > 0)) // check for NaN too - throw new IllegalArgumentException("Illegal Load: " + loadFactor); - - if (initialCapacity == 0) - initialCapacity = 1; - buckets = new HashEntry[initialCapacity]; - this.loadFactor = loadFactor; - threshold = (int) (initialCapacity * loadFactor); - } - - /** - * Returns the number of key-value mappings currently in this hashtable. - * @return the size - */ - public synchronized int size() - { - return size; - } - - /** - * Returns true if there are no key-value mappings currently in this table. - * @return <code>size() == 0</code> - */ - public synchronized boolean isEmpty() - { - return size == 0; - } - - /** - * Return an enumeration of the keys of this table. There's no point - * in synchronizing this, as you have already been warned that the - * enumeration is not specified to be thread-safe. - * - * @return the keys - * @see #elements() - * @see #keySet() - */ - public Enumeration keys() - { - return new Enumerator(KEYS); - } - - /** - * Return an enumeration of the values of this table. There's no point - * in synchronizing this, as you have already been warned that the - * enumeration is not specified to be thread-safe. - * - * @return the values - * @see #keys() - * @see #values() - */ - public Enumeration elements() - { - return new Enumerator(VALUES); - } - - /** - * Returns true if this Hashtable contains a value <code>o</code>, - * such that <code>o.equals(value)</code>. This is the same as - * <code>containsValue()</code>, and is O(n). - * <p> - * - * @param value the value to search for in this Hashtable - * @return true if at least one key maps to the value - * @throws NullPointerException if <code>value</code> is null - * @see #containsValue(Object) - * @see #containsKey(Object) - */ - public synchronized boolean contains(Object value) - { - for (int i = buckets.length - 1; i >= 0; i--) - { - HashEntry e = buckets[i]; - while (e != null) - { - if (value.equals(e.value)) - return true; - e = e.next; - } - } - - // Must throw on null argument even if the table is empty - if (value == null) - throw new NullPointerException(); - - return false; - } - - /** - * Returns true if this Hashtable contains a value <code>o</code>, such that - * <code>o.equals(value)</code>. This is the new API for the old - * <code>contains()</code>. - * - * @param value the value to search for in this Hashtable - * @return true if at least one key maps to the value - * @see #contains(Object) - * @see #containsKey(Object) - * @throws NullPointerException if <code>value</code> is null - * @since 1.2 - */ - public boolean containsValue(Object value) - { - // Delegate to older method to make sure code overriding it continues - // to work. - return contains(value); - } - - /** - * Returns true if the supplied object <code>equals()</code> a key - * in this Hashtable. - * - * @param key the key to search for in this Hashtable - * @return true if the key is in the table - * @throws NullPointerException if key is null - * @see #containsValue(Object) - */ - public synchronized boolean containsKey(Object key) - { - int idx = hash(key); - HashEntry e = buckets[idx]; - while (e != null) - { - if (key.equals(e.key)) - return true; - e = e.next; - } - return false; - } - - /** - * Return the value in this Hashtable associated with the supplied key, - * or <code>null</code> if the key maps to nothing. - * - * @param key the key for which to fetch an associated value - * @return what the key maps to, if present - * @throws NullPointerException if key is null - * @see #put(Object, Object) - * @see #containsKey(Object) - */ - public synchronized Object get(Object key) - { - int idx = hash(key); - HashEntry e = buckets[idx]; - while (e != null) - { - if (key.equals(e.key)) - return e.value; - e = e.next; - } - return null; - } - - /** - * Puts the supplied value into the Map, mapped by the supplied key. - * Neither parameter may be null. The value may be retrieved by any - * object which <code>equals()</code> this key. - * - * @param key the key used to locate the value - * @param value the value to be stored in the table - * @return the prior mapping of the key, or null if there was none - * @throws NullPointerException if key or value is null - * @see #get(Object) - * @see Object#equals(Object) - */ - public synchronized Object put(Object key, Object value) - { - int idx = hash(key); - HashEntry e = buckets[idx]; - - // Check if value is null since it is not permitted. - if (value == null) - throw new NullPointerException(); - - while (e != null) - { - if (key.equals(e.key)) - { - // Bypass e.setValue, since we already know value is non-null. - Object r = e.value; - e.value = value; - return r; - } - else - { - e = e.next; - } - } - - // At this point, we know we need to add a new entry. - modCount++; - if (++size > threshold) - { - rehash(); - // Need a new hash value to suit the bigger table. - idx = hash(key); - } - - e = new HashEntry(key, value); - - e.next = buckets[idx]; - buckets[idx] = e; - - return null; - } - - /** - * Removes from the table and returns the value which is mapped by the - * supplied key. If the key maps to nothing, then the table remains - * unchanged, and <code>null</code> is returned. - * - * @param key the key used to locate the value to remove - * @return whatever the key mapped to, if present - */ - public synchronized Object remove(Object key) - { - int idx = hash(key); - HashEntry e = buckets[idx]; - HashEntry last = null; - - while (e != null) - { - if (key.equals(e.key)) - { - modCount++; - if (last == null) - buckets[idx] = e.next; - else - last.next = e.next; - size--; - return e.value; - } - last = e; - e = e.next; - } - return null; - } - - /** - * Copies all elements of the given map into this hashtable. However, no - * mapping can contain null as key or value. If this table already has - * a mapping for a key, the new mapping replaces the current one. - * - * @param m the map to be hashed into this - * @throws NullPointerException if m is null, or contains null keys or values - */ - public synchronized void putAll(Map m) - { - Iterator itr = m.entrySet().iterator(); - - while (itr.hasNext()) - { - Map.Entry e = (Map.Entry) itr.next(); - // Optimize in case the Entry is one of our own. - if (e instanceof AbstractMap.BasicMapEntry) - { - AbstractMap.BasicMapEntry entry = (AbstractMap.BasicMapEntry) e; - put(entry.key, entry.value); - } - else - { - put(e.getKey(), e.getValue()); - } - } - } - - /** - * Clears the hashtable so it has no keys. This is O(1). - */ - public synchronized void clear() - { - if (size > 0) - { - modCount++; - Arrays.fill(buckets, null); - size = 0; - } - } - - /** - * Returns a shallow clone of this Hashtable. The Map itself is cloned, - * but its contents are not. This is O(n). - * - * @return the clone - */ - public synchronized Object clone() - { - Hashtable copy = null; - try - { - copy = (Hashtable) super.clone(); - } - catch (CloneNotSupportedException x) - { - // This is impossible. - } - copy.buckets = new HashEntry[buckets.length]; - copy.putAllInternal(this); - // Clear the caches. - copy.keys = null; - copy.values = null; - copy.entries = null; - return copy; - } - - /** - * Converts this Hashtable to a String, surrounded by braces, and with - * key/value pairs listed with an equals sign between, separated by a - * comma and space. For example, <code>"{a=1, b=2}"</code>.<p> - * - * NOTE: if the <code>toString()</code> method of any key or value - * throws an exception, this will fail for the same reason. - * - * @return the string representation - */ - public synchronized String toString() - { - // Since we are already synchronized, and entrySet().iterator() - // would repeatedly re-lock/release the monitor, we directly use the - // unsynchronized HashIterator instead. - Iterator entries = new HashIterator(ENTRIES); - StringBuffer r = new StringBuffer("{"); - for (int pos = size; pos > 0; pos--) - { - r.append(entries.next()); - if (pos > 1) - r.append(", "); - } - r.append("}"); - return r.toString(); - } - - /** - * Returns a "set view" of this Hashtable's keys. The set is backed by - * the hashtable, so changes in one show up in the other. The set supports - * element removal, but not element addition. The set is properly - * synchronized on the original hashtable. Sun has not documented the - * proper interaction of null with this set, but has inconsistent behavior - * in the JDK. Therefore, in this implementation, contains, remove, - * containsAll, retainAll, removeAll, and equals just ignore a null key - * rather than throwing a {@link NullPointerException}. - * - * @return a set view of the keys - * @see #values() - * @see #entrySet() - * @since 1.2 - */ - public Set keySet() - { - if (keys == null) - { - // Create a synchronized AbstractSet with custom implementations of - // those methods that can be overridden easily and efficiently. - Set r = new AbstractSet() - { - public int size() - { - return size; - } - - public Iterator iterator() - { - return new HashIterator(KEYS); - } - - public void clear() - { - Hashtable.this.clear(); - } - - public boolean contains(Object o) - { - if (o == null) - return false; - return containsKey(o); - } - - public boolean remove(Object o) - { - return Hashtable.this.remove(o) != null; - } - }; - // We must specify the correct object to synchronize upon, hence the - // use of a non-public API - keys = new Collections.SynchronizedSet(this, r); - } - return keys; - } - - /** - * Returns a "collection view" (or "bag view") of this Hashtable's values. - * The collection is backed by the hashtable, so changes in one show up - * in the other. The collection supports element removal, but not element - * addition. The collection is properly synchronized on the original - * hashtable. Sun has not documented the proper interaction of null with - * this set, but has inconsistent behavior in the JDK. Therefore, in this - * implementation, contains, remove, containsAll, retainAll, removeAll, and - * equals just ignore a null value rather than throwing a - * {@link NullPointerException}. - * - * @return a bag view of the values - * @see #keySet() - * @see #entrySet() - * @since 1.2 - */ - public Collection values() - { - if (values == null) - { - // We don't bother overriding many of the optional methods, as doing so - // wouldn't provide any significant performance advantage. - Collection r = new AbstractCollection() - { - public int size() - { - return size; - } - - public Iterator iterator() - { - return new HashIterator(VALUES); - } - - public void clear() - { - Hashtable.this.clear(); - } - }; - // We must specify the correct object to synchronize upon, hence the - // use of a non-public API - values = new Collections.SynchronizedCollection(this, r); - } - return values; - } - - /** - * Returns a "set view" of this Hashtable's entries. The set is backed by - * the hashtable, so changes in one show up in the other. The set supports - * element removal, but not element addition. The set is properly - * synchronized on the original hashtable. Sun has not documented the - * proper interaction of null with this set, but has inconsistent behavior - * in the JDK. Therefore, in this implementation, contains, remove, - * containsAll, retainAll, removeAll, and equals just ignore a null entry, - * or an entry with a null key or value, rather than throwing a - * {@link NullPointerException}. However, calling entry.setValue(null) - * will fail. - * <p> - * - * Note that the iterators for all three views, from keySet(), entrySet(), - * and values(), traverse the hashtable in the same sequence. - * - * @return a set view of the entries - * @see #keySet() - * @see #values() - * @see Map.Entry - * @since 1.2 - */ - public Set entrySet() - { - if (entries == null) - { - // Create an AbstractSet with custom implementations of those methods - // that can be overridden easily and efficiently. - Set r = new AbstractSet() - { - public int size() - { - return size; - } - - public Iterator iterator() - { - return new HashIterator(ENTRIES); - } - - public void clear() - { - Hashtable.this.clear(); - } - - public boolean contains(Object o) - { - return getEntry(o) != null; - } - - public boolean remove(Object o) - { - HashEntry e = getEntry(o); - if (e != null) - { - Hashtable.this.remove(e.key); - return true; - } - return false; - } - }; - // We must specify the correct object to synchronize upon, hence the - // use of a non-public API - entries = new Collections.SynchronizedSet(this, r); - } - return entries; - } - - /** - * Returns true if this Hashtable equals the supplied Object <code>o</code>. - * As specified by Map, this is: - * <code> - * (o instanceof Map) && entrySet().equals(((Map) o).entrySet()); - * </code> - * - * @param o the object to compare to - * @return true if o is an equal map - * @since 1.2 - */ - public boolean equals(Object o) - { - // no need to synchronize, entrySet().equals() does that - if (o == this) - return true; - if (!(o instanceof Map)) - return false; - - return entrySet().equals(((Map) o).entrySet()); - } - - /** - * Returns the hashCode for this Hashtable. As specified by Map, this is - * the sum of the hashCodes of all of its Map.Entry objects - * - * @return the sum of the hashcodes of the entries - * @since 1.2 - */ - public synchronized int hashCode() - { - // Since we are already synchronized, and entrySet().iterator() - // would repeatedly re-lock/release the monitor, we directly use the - // unsynchronized HashIterator instead. - Iterator itr = new HashIterator(ENTRIES); - int hashcode = 0; - for (int pos = size; pos > 0; pos--) - hashcode += itr.next().hashCode(); - - return hashcode; - } - - /** - * Helper method that returns an index in the buckets array for `key' - * based on its hashCode(). - * - * @param key the key - * @return the bucket number - * @throws NullPointerException if key is null - */ - private int hash(Object key) - { - // Note: Inline Math.abs here, for less method overhead, and to avoid - // a bootstrap dependency, since Math relies on native methods. - int hash = key.hashCode() % buckets.length; - return hash < 0 ? -hash : hash; - } - - /** - * Helper method for entrySet(), which matches both key and value - * simultaneously. Ignores null, as mentioned in entrySet(). - * - * @param o the entry to match - * @return the matching entry, if found, or null - * @see #entrySet() - */ - // Package visible, for use in nested classes. - HashEntry getEntry(Object o) - { - if (! (o instanceof Map.Entry)) - return null; - Object key = ((Map.Entry) o).getKey(); - if (key == null) - return null; - - int idx = hash(key); - HashEntry e = buckets[idx]; - while (e != null) - { - if (o.equals(e)) - return e; - e = e.next; - } - return null; - } - - /** - * A simplified, more efficient internal implementation of putAll(). clone() - * should not call putAll or put, in order to be compatible with the JDK - * implementation with respect to subclasses. - * - * @param m the map to initialize this from - */ - void putAllInternal(Map m) - { - Iterator itr = m.entrySet().iterator(); - size = 0; - - while (itr.hasNext()) - { - size++; - Map.Entry e = (Map.Entry) itr.next(); - Object key = e.getKey(); - int idx = hash(key); - HashEntry he = new HashEntry(key, e.getValue()); - he.next = buckets[idx]; - buckets[idx] = he; - } - } - - /** - * Increases the size of the Hashtable and rehashes all keys to new array - * indices; this is called when the addition of a new value would cause - * size() > threshold. Note that the existing Entry objects are reused in - * the new hash table. - * <p> - * - * This is not specified, but the new size is twice the current size plus - * one; this number is not always prime, unfortunately. This implementation - * is not synchronized, as it is only invoked from synchronized methods. - */ - protected void rehash() - { - HashEntry[] oldBuckets = buckets; - - int newcapacity = (buckets.length * 2) + 1; - threshold = (int) (newcapacity * loadFactor); - buckets = new HashEntry[newcapacity]; - - for (int i = oldBuckets.length - 1; i >= 0; i--) - { - HashEntry e = oldBuckets[i]; - while (e != null) - { - int idx = hash(e.key); - HashEntry dest = buckets[idx]; - - if (dest != null) - { - while (dest.next != null) - dest = dest.next; - dest.next = e; - } - else - { - buckets[idx] = e; - } - - HashEntry next = e.next; - e.next = null; - e = next; - } - } - } - - /** - * Serializes this object to the given stream. - * - * @param s the stream to write to - * @throws IOException if the underlying stream fails - * @serialData the <i>capacity</i> (int) that is the length of the - * bucket array, the <i>size</i> (int) of the hash map - * are emitted first. They are followed by size entries, - * each consisting of a key (Object) and a value (Object). - */ - private synchronized void writeObject(ObjectOutputStream s) - throws IOException - { - // Write the threshold and loadFactor fields. - s.defaultWriteObject(); - - s.writeInt(buckets.length); - s.writeInt(size); - // Since we are already synchronized, and entrySet().iterator() - // would repeatedly re-lock/release the monitor, we directly use the - // unsynchronized HashIterator instead. - Iterator it = new HashIterator(ENTRIES); - while (it.hasNext()) - { - HashEntry entry = (HashEntry) it.next(); - s.writeObject(entry.key); - s.writeObject(entry.value); - } - } - - /** - * Deserializes this object from the given stream. - * - * @param s the stream to read from - * @throws ClassNotFoundException if the underlying stream fails - * @throws IOException if the underlying stream fails - * @serialData the <i>capacity</i> (int) that is the length of the - * bucket array, the <i>size</i> (int) of the hash map - * are emitted first. They are followed by size entries, - * each consisting of a key (Object) and a value (Object). - */ - private void readObject(ObjectInputStream s) - throws IOException, ClassNotFoundException - { - // Read the threshold and loadFactor fields. - s.defaultReadObject(); - - // Read and use capacity. - buckets = new HashEntry[s.readInt()]; - int len = s.readInt(); - - // Read and use key/value pairs. - // TODO: should we be defensive programmers, and check for illegal nulls? - while (--len >= 0) - put(s.readObject(), s.readObject()); - } - - /** - * A class which implements the Iterator interface and is used for - * iterating over Hashtables. - * This implementation is parameterized to give a sequential view of - * keys, values, or entries; it also allows the removal of elements, - * as per the Javasoft spec. Note that it is not synchronized; this is - * a performance enhancer since it is never exposed externally and is - * only used within synchronized blocks above. - * - * @author Jon Zeppieri - */ - private final class HashIterator implements Iterator - { - /** - * The type of this Iterator: {@link #KEYS}, {@link #VALUES}, - * or {@link #ENTRIES}. - */ - final int type; - /** - * The number of modifications to the backing Hashtable that we know about. - */ - int knownMod = modCount; - /** The number of elements remaining to be returned by next(). */ - int count = size; - /** Current index in the physical hash table. */ - int idx = buckets.length; - /** The last Entry returned by a next() call. */ - HashEntry last; - /** - * The next entry that should be returned by next(). It is set to something - * if we're iterating through a bucket that contains multiple linked - * entries. It is null if next() needs to find a new bucket. - */ - HashEntry next; - - /** - * Construct a new HashIterator with the supplied type. - * @param type {@link #KEYS}, {@link #VALUES}, or {@link #ENTRIES} - */ - HashIterator(int type) - { - this.type = type; - } - - /** - * Returns true if the Iterator has more elements. - * @return true if there are more elements - * @throws ConcurrentModificationException if the hashtable was modified - */ - public boolean hasNext() - { - if (knownMod != modCount) - throw new ConcurrentModificationException(); - return count > 0; - } - - /** - * Returns the next element in the Iterator's sequential view. - * @return the next element - * @throws ConcurrentModificationException if the hashtable was modified - * @throws NoSuchElementException if there is none - */ - public Object next() - { - if (knownMod != modCount) - throw new ConcurrentModificationException(); - if (count == 0) - throw new NoSuchElementException(); - count--; - HashEntry e = next; - - while (e == null) - e = buckets[--idx]; - - next = e.next; - last = e; - if (type == VALUES) - return e.value; - if (type == KEYS) - return e.key; - return e; - } - - /** - * Removes from the backing Hashtable the last element which was fetched - * with the <code>next()</code> method. - * @throws ConcurrentModificationException if the hashtable was modified - * @throws IllegalStateException if called when there is no last element - */ - public void remove() - { - if (knownMod != modCount) - throw new ConcurrentModificationException(); - if (last == null) - throw new IllegalStateException(); - - Hashtable.this.remove(last.key); - last = null; - knownMod++; - } - } // class HashIterator - - - /** - * Enumeration view of this Hashtable, providing sequential access to its - * elements; this implementation is parameterized to provide access either - * to the keys or to the values in the Hashtable. - * - * <b>NOTE</b>: Enumeration is not safe if new elements are put in the table - * as this could cause a rehash and we'd completely lose our place. Even - * without a rehash, it is undetermined if a new element added would - * appear in the enumeration. The spec says nothing about this, but - * the "Java Class Libraries" book infers that modifications to the - * hashtable during enumeration causes indeterminate results. Don't do it! - * - * @author Jon Zeppieri - */ - private final class Enumerator implements Enumeration - { - /** - * The type of this Iterator: {@link #KEYS} or {@link #VALUES}. - */ - final int type; - /** The number of elements remaining to be returned by next(). */ - int count = size; - /** Current index in the physical hash table. */ - int idx = buckets.length; - /** - * Entry which will be returned by the next nextElement() call. It is - * set if we are iterating through a bucket with multiple entries, or null - * if we must look in the next bucket. - */ - HashEntry next; - - /** - * Construct the enumeration. - * @param type either {@link #KEYS} or {@link #VALUES}. - */ - Enumerator(int type) - { - this.type = type; - } - - /** - * Checks whether more elements remain in the enumeration. - * @return true if nextElement() will not fail. - */ - public boolean hasMoreElements() - { - return count > 0; - } - - /** - * Returns the next element. - * @return the next element - * @throws NoSuchElementException if there is none. - */ - public Object nextElement() - { - if (count == 0) - throw new NoSuchElementException("Hashtable Enumerator"); - count--; - HashEntry e = next; - - while (e == null) - e = buckets[--idx]; - - next = e.next; - return type == VALUES ? e.value : e.key; - } - } // class Enumerator -} // class Hashtable diff --git a/libjava/java/util/IdentityHashMap.java b/libjava/java/util/IdentityHashMap.java deleted file mode 100644 index 6369fac691b..00000000000 --- a/libjava/java/util/IdentityHashMap.java +++ /dev/null @@ -1,935 +0,0 @@ -/* IdentityHashMap.java -- a class providing a hashtable data structure, - mapping Object --> Object, which uses object identity for hashing. - Copyright (C) 2001, 2002, 2004, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package java.util; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; - -/** - * This class provides a hashtable-backed implementation of the - * Map interface, but uses object identity to do its hashing. In fact, - * it uses object identity for comparing values, as well. It uses a - * linear-probe hash table, which may have faster performance - * than the chaining employed by HashMap. - * <p> - * - * <em>WARNING: This is not a general purpose map. Because it uses - * System.identityHashCode and ==, instead of hashCode and equals, for - * comparison, it violated Map's general contract, and may cause - * undefined behavior when compared to other maps which are not - * IdentityHashMaps. This is designed only for the rare cases when - * identity semantics are needed.</em> An example use is - * topology-preserving graph transformations, such as deep cloning, - * or as proxy object mapping such as in debugging. - * <p> - * - * This map permits <code>null</code> keys and values, and does not - * guarantee that elements will stay in the same order over time. The - * basic operations (<code>get</code> and <code>put</code>) take - * constant time, provided System.identityHashCode is decent. You can - * tune the behavior by specifying the expected maximum size. As more - * elements are added, the map may need to allocate a larger table, - * which can be expensive. - * <p> - * - * This implementation is unsynchronized. If you want multi-thread - * access to be consistent, you must synchronize it, perhaps by using - * <code>Collections.synchronizedMap(new IdentityHashMap(...));</code>. - * The iterators are <i>fail-fast</i>, meaning that a structural modification - * made to the map outside of an iterator's remove method cause the - * iterator, and in the case of the entrySet, the Map.Entry, to - * fail with a {@link ConcurrentModificationException}. - * - * @author Tom Tromey (tromey@redhat.com) - * @author Eric Blake (ebb9@email.byu.edu) - * @see System#identityHashCode(Object) - * @see Collection - * @see Map - * @see HashMap - * @see TreeMap - * @see LinkedHashMap - * @see WeakHashMap - * @since 1.4 - * @status updated to 1.4 - */ -public class IdentityHashMap extends AbstractMap - implements Map, Serializable, Cloneable -{ - /** The default capacity. */ - private static final int DEFAULT_CAPACITY = 21; - - /** - * This object is used to mark deleted items. Package visible for use by - * nested classes. - */ - static final Object tombstone = new Object(); - - /** - * This object is used to mark empty slots. We need this because - * using null is ambiguous. Package visible for use by nested classes. - */ - static final Object emptyslot = new Object(); - - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 8188218128353913216L; - - /** - * The number of mappings in the table. Package visible for use by nested - * classes. - * @serial - */ - int size; - - /** - * The table itself. Package visible for use by nested classes. - */ - transient Object[] table; - - /** - * The number of structural modifications made so far. Package visible for - * use by nested classes. - */ - transient int modCount; - - /** - * The cache for {@link #entrySet()}. - */ - private transient Set entries; - - /** - * The threshold for rehashing, which is 75% of (table.length / 2). - */ - private transient int threshold; - - /** - * Create a new IdentityHashMap with the default capacity (21 entries). - */ - public IdentityHashMap() - { - this(DEFAULT_CAPACITY); - } - - /** - * Create a new IdentityHashMap with the indicated number of - * entries. If the number of elements added to this hash map - * exceeds this maximum, the map will grow itself; however, that - * incurs a performance penalty. - * - * @param max initial size - * @throws IllegalArgumentException if max is negative - */ - public IdentityHashMap(int max) - { - if (max < 0) - throw new IllegalArgumentException(); - // Need at least two slots, or hash() will break. - if (max < 2) - max = 2; - table = new Object[max << 1]; - Arrays.fill(table, emptyslot); - threshold = (max >> 2) * 3; - } - - /** - * Create a new IdentityHashMap whose contents are taken from the - * given Map. - * - * @param m The map whose elements are to be put in this map - * @throws NullPointerException if m is null - */ - public IdentityHashMap(Map m) - { - this(Math.max(m.size() << 1, DEFAULT_CAPACITY)); - putAll(m); - } - - /** - * Remove all mappings from this map. - */ - public void clear() - { - if (size != 0) - { - modCount++; - Arrays.fill(table, emptyslot); - size = 0; - } - } - - /** - * Creates a shallow copy where keys and values are not cloned. - */ - public Object clone() - { - try - { - IdentityHashMap copy = (IdentityHashMap) super.clone(); - copy.table = (Object[]) table.clone(); - copy.entries = null; // invalidate the cache - return copy; - } - catch (CloneNotSupportedException e) - { - // Can't happen. - return null; - } - } - - /** - * Tests whether the specified key is in this map. Unlike normal Maps, - * this test uses <code>entry == key</code> instead of - * <code>entry == null ? key == null : entry.equals(key)</code>. - * - * @param key the key to look for - * @return true if the key is contained in the map - * @see #containsValue(Object) - * @see #get(Object) - */ - public boolean containsKey(Object key) - { - return key == table[hash(key)]; - } - - /** - * Returns true if this HashMap contains the value. Unlike normal maps, - * this test uses <code>entry == value</code> instead of - * <code>entry == null ? value == null : entry.equals(value)</code>. - * - * @param value the value to search for in this HashMap - * @return true if at least one key maps to the value - * @see #containsKey(Object) - */ - public boolean containsValue(Object value) - { - for (int i = table.length - 1; i > 0; i -= 2) - if (table[i] == value) - return true; - return false; - } - - /** - * Returns a "set view" of this Map's entries. The set is backed by - * the Map, so changes in one show up in the other. The set supports - * element removal, but not element addition. - * <p> - * - * <em>The semantics of this set, and of its contained entries, are - * different from the contract of Set and Map.Entry in order to make - * IdentityHashMap work. This means that while you can compare these - * objects between IdentityHashMaps, comparing them with regular sets - * or entries is likely to have undefined behavior.</em> The entries - * in this set are reference-based, rather than the normal object - * equality. Therefore, <code>e1.equals(e2)</code> returns - * <code>e1.getKey() == e2.getKey() && e1.getValue() == e2.getValue()</code>, - * and <code>e.hashCode()</code> returns - * <code>System.identityHashCode(e.getKey()) ^ - * System.identityHashCode(e.getValue())</code>. - * <p> - * - * Note that the iterators for all three views, from keySet(), entrySet(), - * and values(), traverse the Map in the same sequence. - * - * @return a set view of the entries - * @see #keySet() - * @see #values() - * @see Map.Entry - */ - public Set entrySet() - { - if (entries == null) - entries = new AbstractSet() - { - public int size() - { - return size; - } - - public Iterator iterator() - { - return new IdentityIterator(ENTRIES); - } - - public void clear() - { - IdentityHashMap.this.clear(); - } - - public boolean contains(Object o) - { - if (! (o instanceof Map.Entry)) - return false; - Map.Entry m = (Map.Entry) o; - return m.getValue() == table[hash(m.getKey()) + 1]; - } - - public int hashCode() - { - return IdentityHashMap.this.hashCode(); - } - - public boolean remove(Object o) - { - if (! (o instanceof Map.Entry)) - return false; - Object key = ((Map.Entry) o).getKey(); - int h = hash(key); - if (table[h] == key) - { - size--; - modCount++; - table[h] = tombstone; - table[h + 1] = tombstone; - return true; - } - return false; - } - }; - return entries; - } - - /** - * Compares two maps for equality. This returns true only if both maps - * have the same reference-identity comparisons. While this returns - * <code>this.entrySet().equals(m.entrySet())</code> as specified by Map, - * this will not work with normal maps, since the entry set compares - * with == instead of .equals. - * - * @param o the object to compare to - * @return true if it is equal - */ - public boolean equals(Object o) - { - // Why did Sun specify this one? The superclass does the right thing. - return super.equals(o); - } - - /** - * Return the value in this Map associated with the supplied key, or - * <code>null</code> if the key maps to nothing. - * - * <p>NOTE: Since the value could also be null, you must use - * containsKey to see if this key actually maps to something. - * Unlike normal maps, this tests for the key with <code>entry == - * key</code> instead of <code>entry == null ? key == null : - * entry.equals(key)</code>. - * - * @param key the key for which to fetch an associated value - * @return what the key maps to, if present - * @see #put(Object, Object) - * @see #containsKey(Object) - */ - public Object get(Object key) - { - int h = hash(key); - return table[h] == key ? table[h + 1] : null; - } - - /** - * Returns the hashcode of this map. This guarantees that two - * IdentityHashMaps that compare with equals() will have the same hash code, - * but may break with comparison to normal maps since it uses - * System.identityHashCode() instead of hashCode(). - * - * @return the hash code - */ - public int hashCode() - { - int hash = 0; - for (int i = table.length - 2; i >= 0; i -= 2) - { - Object key = table[i]; - if (key == emptyslot || key == tombstone) - continue; - hash += (System.identityHashCode(key) - ^ System.identityHashCode(table[i + 1])); - } - return hash; - } - - /** - * Returns true if there are no key-value mappings currently in this Map - * @return <code>size() == 0</code> - */ - public boolean isEmpty() - { - return size == 0; - } - - /** - * Returns a "set view" of this Map's keys. The set is backed by the - * Map, so changes in one show up in the other. The set supports - * element removal, but not element addition. - * <p> - * - * <em>The semantics of this set are different from the contract of Set - * in order to make IdentityHashMap work. This means that while you can - * compare these objects between IdentityHashMaps, comparing them with - * regular sets is likely to have undefined behavior.</em> The hashCode - * of the set is the sum of the identity hash codes, instead of the - * regular hashCodes, and equality is determined by reference instead - * of by the equals method. - * <p> - * - * @return a set view of the keys - * @see #values() - * @see #entrySet() - */ - public Set keySet() - { - if (keys == null) - keys = new AbstractSet() - { - public int size() - { - return size; - } - - public Iterator iterator() - { - return new IdentityIterator(KEYS); - } - - public void clear() - { - IdentityHashMap.this.clear(); - } - - public boolean contains(Object o) - { - return containsKey(o); - } - - public int hashCode() - { - int hash = 0; - for (int i = table.length - 2; i >= 0; i -= 2) - { - Object key = table[i]; - if (key == emptyslot || key == tombstone) - continue; - hash += System.identityHashCode(key); - } - return hash; - - } - - public boolean remove(Object o) - { - int h = hash(o); - if (table[h] == o) - { - size--; - modCount++; - table[h] = tombstone; - table[h + 1] = tombstone; - return true; - } - return false; - } - }; - return keys; - } - - /** - * Puts the supplied value into the Map, mapped by the supplied key. - * The value may be retrieved by any object which <code>equals()</code> - * this key. NOTE: Since the prior value could also be null, you must - * first use containsKey if you want to see if you are replacing the - * key's mapping. Unlike normal maps, this tests for the key - * with <code>entry == key</code> instead of - * <code>entry == null ? key == null : entry.equals(key)</code>. - * - * @param key the key used to locate the value - * @param value the value to be stored in the HashMap - * @return the prior mapping of the key, or null if there was none - * @see #get(Object) - */ - public Object put(Object key, Object value) - { - // Rehash if the load factor is too high. - if (size > threshold) - { - Object[] old = table; - // This isn't necessarily prime, but it is an odd number of key/value - // slots, which has a higher probability of fewer collisions. - table = new Object[(old.length * 2) + 2]; - Arrays.fill(table, emptyslot); - size = 0; - threshold = (table.length >>> 3) * 3; - - for (int i = old.length - 2; i >= 0; i -= 2) - { - Object oldkey = old[i]; - if (oldkey != tombstone && oldkey != emptyslot) - // Just use put. This isn't very efficient, but it is ok. - put(oldkey, old[i + 1]); - } - } - - int h = hash(key); - if (table[h] == key) - { - Object r = table[h + 1]; - table[h + 1] = value; - return r; - } - - // At this point, we add a new mapping. - modCount++; - size++; - table[h] = key; - table[h + 1] = value; - return null; - } - - /** - * Copies all of the mappings from the specified map to this. If a key - * is already in this map, its value is replaced. - * - * @param m the map to copy - * @throws NullPointerException if m is null - */ - public void putAll(Map m) - { - // Why did Sun specify this one? The superclass does the right thing. - super.putAll(m); - } - - /** - * Removes from the HashMap and returns the value which is mapped by - * the supplied key. If the key maps to nothing, then the HashMap - * remains unchanged, and <code>null</code> is returned. - * - * NOTE: Since the value could also be null, you must use - * containsKey to see if you are actually removing a mapping. - * Unlike normal maps, this tests for the key with <code>entry == - * key</code> instead of <code>entry == null ? key == null : - * entry.equals(key)</code>. - * - * @param key the key used to locate the value to remove - * @return whatever the key mapped to, if present - */ - public Object remove(Object key) - { - int h = hash(key); - if (table[h] == key) - { - modCount++; - size--; - Object r = table[h + 1]; - table[h] = tombstone; - table[h + 1] = tombstone; - return r; - } - return null; - } - - /** - * Returns the number of kay-value mappings currently in this Map - * @return the size - */ - public int size() - { - return size; - } - - /** - * Returns a "collection view" (or "bag view") of this Map's values. - * The collection is backed by the Map, so changes in one show up - * in the other. The collection supports element removal, but not element - * addition. - * <p> - * - * <em>The semantics of this set are different from the contract of - * Collection in order to make IdentityHashMap work. This means that - * while you can compare these objects between IdentityHashMaps, comparing - * them with regular sets is likely to have undefined behavior.</em> - * Likewise, contains and remove go by == instead of equals(). - * <p> - * - * @return a bag view of the values - * @see #keySet() - * @see #entrySet() - */ - public Collection values() - { - if (values == null) - values = new AbstractCollection() - { - public int size() - { - return size; - } - - public Iterator iterator() - { - return new IdentityIterator(VALUES); - } - - public void clear() - { - IdentityHashMap.this.clear(); - } - - public boolean remove(Object o) - { - for (int i = table.length - 1; i > 0; i -= 2) - if (table[i] == o) - { - modCount++; - table[i - 1] = tombstone; - table[i] = tombstone; - size--; - return true; - } - return false; - } - }; - return values; - } - - /** - * Helper method which computes the hash code, then traverses the table - * until it finds the key, or the spot where the key would go. - * - * @param key the key to check - * @return the index where the key belongs - * @see #IdentityHashMap(int) - * @see #put(Object, Object) - */ - // Package visible for use by nested classes. - int hash(Object key) - { - // Implementation note: it is feasible for the table to have no - // emptyslots, if it is full with entries and tombstones, so we must - // remember where we started. If we encounter the key or an emptyslot, - // we are done. If we encounter a tombstone, the key may still be in - // the array. If we don't encounter the key, we use the first emptyslot - // or tombstone we encountered as the location where the key would go. - // By requiring at least 2 key/value slots, and rehashing at 75% - // capacity, we guarantee that there will always be either an emptyslot - // or a tombstone somewhere in the table. - int h = Math.abs(System.identityHashCode(key) % (table.length >> 1)) << 1; - int del = -1; - int save = h; - - do - { - if (table[h] == key) - return h; - if (table[h] == emptyslot) - break; - if (table[h] == tombstone && del < 0) - del = h; - h -= 2; - if (h < 0) - h = table.length - 2; - } - while (h != save); - - return del < 0 ? h : del; - } - - /** - * This class allows parameterized iteration over IdentityHashMaps. Based - * on its construction, it returns the key or value of a mapping, or - * creates the appropriate Map.Entry object with the correct fail-fast - * semantics and identity comparisons. - * - * @author Tom Tromey (tromey@redhat.com) - * @author Eric Blake (ebb9@email.byu.edu) - */ - private class IdentityIterator implements Iterator - { - /** - * The type of this Iterator: {@link #KEYS}, {@link #VALUES}, - * or {@link #ENTRIES}. - */ - final int type; - /** The number of modifications to the backing Map that we know about. */ - int knownMod = modCount; - /** The number of elements remaining to be returned by next(). */ - int count = size; - /** Location in the table. */ - int loc = table.length; - - /** - * Construct a new Iterator with the supplied type. - * @param type {@link #KEYS}, {@link #VALUES}, or {@link #ENTRIES} - */ - IdentityIterator(int type) - { - this.type = type; - } - - /** - * Returns true if the Iterator has more elements. - * @return true if there are more elements - * @throws ConcurrentModificationException if the Map was modified - */ - public boolean hasNext() - { - if (knownMod != modCount) - throw new ConcurrentModificationException(); - return count > 0; - } - - /** - * Returns the next element in the Iterator's sequential view. - * @return the next element - * @throws ConcurrentModificationException if the Map was modified - * @throws NoSuchElementException if there is none - */ - public Object next() - { - if (knownMod != modCount) - throw new ConcurrentModificationException(); - if (count == 0) - throw new NoSuchElementException(); - count--; - - Object key; - do - { - loc -= 2; - key = table[loc]; - } - while (key == emptyslot || key == tombstone); - - return type == KEYS ? key : (type == VALUES ? table[loc + 1] - : new IdentityEntry(loc)); - } - - /** - * Removes from the backing Map the last element which was fetched - * with the <code>next()</code> method. - * - * @throws ConcurrentModificationException if the Map was modified - * @throws IllegalStateException if called when there is no last element - */ - public void remove() - { - if (knownMod != modCount) - throw new ConcurrentModificationException(); - if (loc == table.length || table[loc] == tombstone) - throw new IllegalStateException(); - modCount++; - size--; - table[loc] = tombstone; - table[loc + 1] = tombstone; - knownMod++; - } - } // class IdentityIterator - - /** - * This class provides Map.Entry objects for IdentityHashMaps. The entry - * is fail-fast, and will throw a ConcurrentModificationException if - * the underlying map is modified, or if remove is called on the iterator - * that generated this object. It is identity based, so it violates - * the general contract of Map.Entry, and is probably unsuitable for - * comparison to normal maps; but it works among other IdentityHashMaps. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private final class IdentityEntry implements Map.Entry - { - /** The location of this entry. */ - final int loc; - /** The number of modifications to the backing Map that we know about. */ - final int knownMod = modCount; - - /** - * Constructs the Entry. - * - * @param loc the location of this entry in table - */ - IdentityEntry(int loc) - { - this.loc = loc; - } - - /** - * Compares the specified object with this entry, using identity - * semantics. Note that this can lead to undefined results with - * Entry objects created by normal maps. - * - * @param o the object to compare - * @return true if it is equal - * @throws ConcurrentModificationException if the entry was invalidated - * by modifying the Map or calling Iterator.remove() - */ - public boolean equals(Object o) - { - if (knownMod != modCount || table[loc] == tombstone) - throw new ConcurrentModificationException(); - if (! (o instanceof Map.Entry)) - return false; - Map.Entry e = (Map.Entry) o; - return table[loc] == e.getKey() && table[loc + 1] == e.getValue(); - } - - /** - * Returns the key of this entry. - * - * @return the key - * @throws ConcurrentModificationException if the entry was invalidated - * by modifying the Map or calling Iterator.remove() - */ - public Object getKey() - { - if (knownMod != modCount || table[loc] == tombstone) - throw new ConcurrentModificationException(); - return table[loc]; - } - - /** - * Returns the value of this entry. - * - * @return the value - * @throws ConcurrentModificationException if the entry was invalidated - * by modifying the Map or calling Iterator.remove() - */ - public Object getValue() - { - if (knownMod != modCount || table[loc] == tombstone) - throw new ConcurrentModificationException(); - return table[loc + 1]; - } - - /** - * Returns the hashcode of the entry, using identity semantics. - * Note that this can lead to undefined results with Entry objects - * created by normal maps. - * - * @return the hash code - * @throws ConcurrentModificationException if the entry was invalidated - * by modifying the Map or calling Iterator.remove() - */ - public int hashCode() - { - if (knownMod != modCount || table[loc] == tombstone) - throw new ConcurrentModificationException(); - return (System.identityHashCode(table[loc]) - ^ System.identityHashCode(table[loc + 1])); - } - - /** - * Replaces the value of this mapping, and returns the old value. - * - * @param value the new value - * @return the old value - * @throws ConcurrentModificationException if the entry was invalidated - * by modifying the Map or calling Iterator.remove() - */ - public Object setValue(Object value) - { - if (knownMod != modCount || table[loc] == tombstone) - throw new ConcurrentModificationException(); - Object r = table[loc + 1]; - table[loc + 1] = value; - return r; - } - - /** - * This provides a string representation of the entry. It is of the form - * "key=value", where string concatenation is used on key and value. - * - * @return the string representation - * @throws ConcurrentModificationException if the entry was invalidated - * by modifying the Map or calling Iterator.remove() - */ - public String toString() - { - if (knownMod != modCount || table[loc] == tombstone) - throw new ConcurrentModificationException(); - return table[loc] + "=" + table[loc + 1]; - } - } // class IdentityEntry - - /** - * Reads the object from a serial stream. - * - * @param s the stream to read from - * @throws ClassNotFoundException if the underlying stream fails - * @throws IOException if the underlying stream fails - * @serialData expects the size (int), followed by that many key (Object) - * and value (Object) pairs, with the pairs in no particular - * order - */ - private void readObject(ObjectInputStream s) - throws IOException, ClassNotFoundException - { - s.defaultReadObject(); - - int num = s.readInt(); - table = new Object[Math.max(num << 1, DEFAULT_CAPACITY) << 1]; - // Read key/value pairs. - while (--num >= 0) - put(s.readObject(), s.readObject()); - } - - /** - * Writes the object to a serial stream. - * - * @param s the stream to write to - * @throws IOException if the underlying stream fails - * @serialData outputs the size (int), followed by that many key (Object) - * and value (Object) pairs, with the pairs in no particular - * order - */ - private void writeObject(ObjectOutputStream s) - throws IOException - { - s.defaultWriteObject(); - s.writeInt(size); - for (int i = table.length - 2; i >= 0; i -= 2) - { - Object key = table[i]; - if (key != tombstone && key != emptyslot) - { - s.writeObject(key); - s.writeObject(table[i + 1]); - } - } - } -} diff --git a/libjava/java/util/Iterator.java b/libjava/java/util/Iterator.java deleted file mode 100644 index 31ecff8a257..00000000000 --- a/libjava/java/util/Iterator.java +++ /dev/null @@ -1,87 +0,0 @@ -/* Iterator.java -- Interface for iterating over collections - Copyright (C) 1998, 2001, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -/** - * An object which iterates over a collection. An Iterator is used to return - * the items once only, in sequence, by successive calls to the next method. - * It is also possible to remove elements from the underlying collection by - * using the optional remove method. Iterator is intended as a replacement - * for the Enumeration interface of previous versions of Java, which did not - * have the remove method and had less conveniently named methods. - * - * @author Original author unknown - * @author Eric Blake (ebb9@email.byu.edu) - * @see Collection - * @see ListIterator - * @see Enumeration - * @since 1.2 - * @status updated to 1.4 - */ -public interface Iterator -{ - /** - * Tests whether there are elements remaining in the collection. In other - * words, calling <code>next()</code> will not throw an exception. - * - * @return true if there is at least one more element in the collection - */ - boolean hasNext(); - - /** - * Obtain the next element in the collection. - * - * @return the next element in the collection - * @throws NoSuchElementException if there are no more elements - */ - Object next(); - - /** - * Remove from the underlying collection the last element returned by next - * (optional operation). This method can be called only once after each - * call to <code>next()</code>. It does not affect what will be returned - * by subsequent calls to next. - * - * @throws IllegalStateException if next has not yet been called or remove - * has already been called since the last call to next. - * @throws UnsupportedOperationException if this Iterator does not support - * the remove operation. - */ - void remove(); -} diff --git a/libjava/java/util/LinkedHashMap.java b/libjava/java/util/LinkedHashMap.java deleted file mode 100644 index 8e895a9e0d8..00000000000 --- a/libjava/java/util/LinkedHashMap.java +++ /dev/null @@ -1,501 +0,0 @@ -/* LinkedHashMap.java -- a class providing hashtable data structure, - mapping Object --> Object, with linked list traversal - Copyright (C) 2001, 2002, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -/** - * This class provides a hashtable-backed implementation of the - * Map interface, with predictable traversal order. - * <p> - * - * It uses a hash-bucket approach; that is, hash collisions are handled - * by linking the new node off of the pre-existing node (or list of - * nodes). In this manner, techniques such as linear probing (which - * can cause primary clustering) and rehashing (which does not fit very - * well with Java's method of precomputing hash codes) are avoided. In - * addition, this maintains a doubly-linked list which tracks either - * insertion or access order. - * <p> - * - * In insertion order, calling <code>put</code> adds the key to the end of - * traversal, unless the key was already in the map; changing traversal order - * requires removing and reinserting a key. On the other hand, in access - * order, all calls to <code>put</code> and <code>get</code> cause the - * accessed key to move to the end of the traversal list. Note that any - * accesses to the map's contents via its collection views and iterators do - * not affect the map's traversal order, since the collection views do not - * call <code>put</code> or <code>get</code>. - * <p> - * - * One of the nice features of tracking insertion order is that you can - * copy a hashtable, and regardless of the implementation of the original, - * produce the same results when iterating over the copy. This is possible - * without needing the overhead of <code>TreeMap</code>. - * <p> - * - * When using this {@link #LinkedHashMap(int, float, boolean) constructor}, - * you can build an access-order mapping. This can be used to implement LRU - * caches, for example. By overriding {@link #removeEldestEntry(Map.Entry)}, - * you can also control the removal of the oldest entry, and thereby do - * things like keep the map at a fixed size. - * <p> - * - * Under ideal circumstances (no collisions), LinkedHashMap offers O(1) - * performance on most operations (<code>containsValue()</code> is, - * of course, O(n)). In the worst case (all keys map to the same - * hash code -- very unlikely), most operations are O(n). Traversal is - * faster than in HashMap (proportional to the map size, and not the space - * allocated for the map), but other operations may be slower because of the - * overhead of the maintaining the traversal order list. - * <p> - * - * LinkedHashMap accepts the null key and null values. It is not - * synchronized, so if you need multi-threaded access, consider using:<br> - * <code>Map m = Collections.synchronizedMap(new LinkedHashMap(...));</code> - * <p> - * - * The iterators are <i>fail-fast</i>, meaning that any structural - * modification, except for <code>remove()</code> called on the iterator - * itself, cause the iterator to throw a - * {@link ConcurrentModificationException} rather than exhibit - * non-deterministic behavior. - * - * @author Eric Blake (ebb9@email.byu.edu) - * @see Object#hashCode() - * @see Collection - * @see Map - * @see HashMap - * @see TreeMap - * @see Hashtable - * @since 1.4 - * @status updated to 1.4 - */ -public class LinkedHashMap extends HashMap -{ - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 3801124242820219131L; - - /** - * The oldest Entry to begin iteration at. - */ - transient LinkedHashEntry root; - - /** - * The iteration order of this linked hash map: <code>true</code> for - * access-order, <code>false</code> for insertion-order. - * - * @serial true for access order traversal - */ - final boolean accessOrder; - - /** - * Class to represent an entry in the hash table. Holds a single key-value - * pair and the doubly-linked insertion order list. - */ - class LinkedHashEntry extends HashEntry - { - /** - * The predecessor in the iteration list. If this entry is the root - * (eldest), pred points to the newest entry. - */ - LinkedHashEntry pred; - - /** The successor in the iteration list, null if this is the newest. */ - LinkedHashEntry succ; - - /** - * Simple constructor. - * - * @param key the key - * @param value the value - */ - LinkedHashEntry(Object key, Object value) - { - super(key, value); - if (root == null) - { - root = this; - pred = this; - } - else - { - pred = root.pred; - pred.succ = this; - root.pred = this; - } - } - - /** - * Called when this entry is accessed via put or get. This version does - * the necessary bookkeeping to keep the doubly-linked list in order, - * after moving this element to the newest position in access order. - */ - void access() - { - if (accessOrder && succ != null) - { - modCount++; - if (this == root) - { - root = succ; - pred.succ = this; - succ = null; - } - else - { - pred.succ = succ; - succ.pred = pred; - succ = null; - pred = root.pred; - pred.succ = this; - root.pred = this; - } - } - } - - /** - * Called when this entry is removed from the map. This version does - * the necessary bookkeeping to keep the doubly-linked list in order. - * - * @return the value of this key as it is removed - */ - Object cleanup() - { - if (this == root) - { - root = succ; - if (succ != null) - succ.pred = pred; - } - else if (succ == null) - { - pred.succ = null; - root.pred = pred; - } - else - { - pred.succ = succ; - succ.pred = pred; - } - return value; - } - } // class LinkedHashEntry - - /** - * Construct a new insertion-ordered LinkedHashMap with the default - * capacity (11) and the default load factor (0.75). - */ - public LinkedHashMap() - { - super(); - accessOrder = false; - } - - /** - * Construct a new insertion-ordered LinkedHashMap from the given Map, - * with initial capacity the greater of the size of <code>m</code> or - * the default of 11. - * <p> - * - * Every element in Map m will be put into this new HashMap, in the - * order of m's iterator. - * - * @param m a Map whose key / value pairs will be put into - * the new HashMap. <b>NOTE: key / value pairs - * are not cloned in this constructor.</b> - * @throws NullPointerException if m is null - */ - public LinkedHashMap(Map m) - { - super(m); - accessOrder = false; - } - - /** - * Construct a new insertion-ordered LinkedHashMap with a specific - * inital capacity and default load factor of 0.75. - * - * @param initialCapacity the initial capacity of this HashMap (>= 0) - * @throws IllegalArgumentException if (initialCapacity < 0) - */ - public LinkedHashMap(int initialCapacity) - { - super(initialCapacity); - accessOrder = false; - } - - /** - * Construct a new insertion-orderd LinkedHashMap with a specific - * inital capacity and load factor. - * - * @param initialCapacity the initial capacity (>= 0) - * @param loadFactor the load factor (> 0, not NaN) - * @throws IllegalArgumentException if (initialCapacity < 0) || - * ! (loadFactor > 0.0) - */ - public LinkedHashMap(int initialCapacity, float loadFactor) - { - super(initialCapacity, loadFactor); - accessOrder = false; - } - - /** - * Construct a new LinkedHashMap with a specific inital capacity, load - * factor, and ordering mode. - * - * @param initialCapacity the initial capacity (>=0) - * @param loadFactor the load factor (>0, not NaN) - * @param accessOrder true for access-order, false for insertion-order - * @throws IllegalArgumentException if (initialCapacity < 0) || - * ! (loadFactor > 0.0) - */ - public LinkedHashMap(int initialCapacity, float loadFactor, - boolean accessOrder) - { - super(initialCapacity, loadFactor); - this.accessOrder = accessOrder; - } - - /** - * Clears the Map so it has no keys. This is O(1). - */ - public void clear() - { - super.clear(); - root = null; - } - - /** - * Returns <code>true</code> if this HashMap contains a value - * <code>o</code>, such that <code>o.equals(value)</code>. - * - * @param value the value to search for in this HashMap - * @return <code>true</code> if at least one key maps to the value - */ - public boolean containsValue(Object value) - { - LinkedHashEntry e = root; - while (e != null) - { - if (equals(value, e.value)) - return true; - e = e.succ; - } - return false; - } - - /** - * Return the value in this Map associated with the supplied key, - * or <code>null</code> if the key maps to nothing. If this is an - * access-ordered Map and the key is found, this performs structural - * modification, moving the key to the newest end of the list. NOTE: - * Since the value could also be null, you must use containsKey to - * see if this key actually maps to something. - * - * @param key the key for which to fetch an associated value - * @return what the key maps to, if present - * @see #put(Object, Object) - * @see #containsKey(Object) - */ - public Object get(Object key) - { - int idx = hash(key); - HashEntry e = buckets[idx]; - while (e != null) - { - if (equals(key, e.key)) - { - e.access(); - return e.value; - } - e = e.next; - } - return null; - } - - /** - * Returns <code>true</code> if this map should remove the eldest entry. - * This method is invoked by all calls to <code>put</code> and - * <code>putAll</code> which place a new entry in the map, providing - * the implementer an opportunity to remove the eldest entry any time - * a new one is added. This can be used to save memory usage of the - * hashtable, as well as emulating a cache, by deleting stale entries. - * <p> - * - * For example, to keep the Map limited to 100 entries, override as follows: - * <pre> - * private static final int MAX_ENTRIES = 100; - * protected boolean removeEldestEntry(Map.Entry eldest) - * { - * return size() > MAX_ENTRIES; - * } - * </pre><p> - * - * Typically, this method does not modify the map, but just uses the - * return value as an indication to <code>put</code> whether to proceed. - * However, if you override it to modify the map, you must return false - * (indicating that <code>put</code> should leave the modified map alone), - * or you face unspecified behavior. Remember that in access-order mode, - * even calling <code>get</code> is a structural modification, but using - * the collections views (such as <code>keySet</code>) is not. - * <p> - * - * This method is called after the eldest entry has been inserted, so - * if <code>put</code> was called on a previously empty map, the eldest - * entry is the one you just put in! The default implementation just - * returns <code>false</code>, so that this map always behaves like - * a normal one with unbounded growth. - * - * @param eldest the eldest element which would be removed if this - * returns true. For an access-order map, this is the least - * recently accessed; for an insertion-order map, this is the - * earliest element inserted. - * @return true if <code>eldest</code> should be removed - */ - protected boolean removeEldestEntry(Map.Entry eldest) - { - return false; - } - - /** - * Helper method called by <code>put</code>, which creates and adds a - * new Entry, followed by performing bookkeeping (like removeEldestEntry). - * - * @param key the key of the new Entry - * @param value the value - * @param idx the index in buckets where the new Entry belongs - * @param callRemove whether to call the removeEldestEntry method - * @see #put(Object, Object) - * @see #removeEldestEntry(Map.Entry) - * @see LinkedHashEntry#LinkedHashEntry(Object, Object) - */ - void addEntry(Object key, Object value, int idx, boolean callRemove) - { - LinkedHashEntry e = new LinkedHashEntry(key, value); - e.next = buckets[idx]; - buckets[idx] = e; - if (callRemove && removeEldestEntry(root)) - remove(root.key); - } - - /** - * Helper method, called by clone() to reset the doubly-linked list. - * - * @param m the map to add entries from - * @see #clone() - */ - void putAllInternal(Map m) - { - root = null; - super.putAllInternal(m); - } - - /** - * Generates a parameterized iterator. This allows traversal to follow - * the doubly-linked list instead of the random bin order of HashMap. - * - * @param type {@link #KEYS}, {@link #VALUES}, or {@link #ENTRIES} - * @return the appropriate iterator - */ - Iterator iterator(final int type) - { - return new Iterator() - { - /** The current Entry. */ - LinkedHashEntry current = root; - - /** The previous Entry returned by next(). */ - LinkedHashEntry last; - - /** The number of known modifications to the backing Map. */ - int knownMod = modCount; - - /** - * Returns true if the Iterator has more elements. - * - * @return true if there are more elements - * @throws ConcurrentModificationException if the HashMap was modified - */ - public boolean hasNext() - { - if (knownMod != modCount) - throw new ConcurrentModificationException(); - return current != null; - } - - /** - * Returns the next element in the Iterator's sequential view. - * - * @return the next element - * @throws ConcurrentModificationException if the HashMap was modified - * @throws NoSuchElementException if there is none - */ - public Object next() - { - if (knownMod != modCount) - throw new ConcurrentModificationException(); - if (current == null) - throw new NoSuchElementException(); - last = current; - current = current.succ; - return type == VALUES ? last.value : type == KEYS ? last.key : last; - } - - /** - * Removes from the backing HashMap the last element which was fetched - * with the <code>next()</code> method. - * - * @throws ConcurrentModificationException if the HashMap was modified - * @throws IllegalStateException if called when there is no last element - */ - public void remove() - { - if (knownMod != modCount) - throw new ConcurrentModificationException(); - if (last == null) - throw new IllegalStateException(); - LinkedHashMap.this.remove(last.key); - last = null; - knownMod++; - } - }; - } -} // class LinkedHashMap diff --git a/libjava/java/util/LinkedHashSet.java b/libjava/java/util/LinkedHashSet.java deleted file mode 100644 index 6c68195c3bd..00000000000 --- a/libjava/java/util/LinkedHashSet.java +++ /dev/null @@ -1,160 +0,0 @@ -/* LinkedHashSet.java -- a set backed by a LinkedHashMap, for linked - list traversal. - Copyright (C) 2001, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -import java.io.Serializable; - -/** - * This class provides a hashtable-backed implementation of the - * Set interface, with predictable traversal order. - * <p> - * - * It uses a hash-bucket approach; that is, hash collisions are handled - * by linking the new node off of the pre-existing node (or list of - * nodes). In this manner, techniques such as linear probing (which - * can cause primary clustering) and rehashing (which does not fit very - * well with Java's method of precomputing hash codes) are avoided. In - * addition, this maintains a doubly-linked list which tracks insertion - * order. Note that the insertion order is not modified if an - * <code>add</code> simply reinserts an element in the set. - * <p> - * - * One of the nice features of tracking insertion order is that you can - * copy a set, and regardless of the implementation of the original, - * produce the same results when iterating over the copy. This is possible - * without needing the overhead of <code>TreeSet</code>. - * <p> - * - * Under ideal circumstances (no collisions), LinkedHashSet offers O(1) - * performance on most operations. In the worst case (all elements map - * to the same hash code -- very unlikely), most operations are O(n). - * <p> - * - * LinkedHashSet accepts the null entry. It is not synchronized, so if - * you need multi-threaded access, consider using:<br> - * <code>Set s = Collections.synchronizedSet(new LinkedHashSet(...));</code> - * <p> - * - * The iterators are <i>fail-fast</i>, meaning that any structural - * modification, except for <code>remove()</code> called on the iterator - * itself, cause the iterator to throw a - * {@link ConcurrentModificationException} rather than exhibit - * non-deterministic behavior. - * - * @author Eric Blake (ebb9@email.byu.edu) - * @see Object#hashCode() - * @see Collection - * @see Set - * @see HashSet - * @see TreeSet - * @see Collections#synchronizedSet(Set) - * @since 1.4 - * @status updated to 1.4 - */ -public class LinkedHashSet extends HashSet - implements Set, Cloneable, Serializable -{ - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = -2851667679971038690L; - - /** - * Construct a new, empty HashSet whose backing HashMap has the default - * capacity (11) and loadFacor (0.75). - */ - public LinkedHashSet() - { - super(); - } - - /** - * Construct a new, empty HashSet whose backing HashMap has the supplied - * capacity and the default load factor (0.75). - * - * @param initialCapacity the initial capacity of the backing HashMap - * @throws IllegalArgumentException if the capacity is negative - */ - public LinkedHashSet(int initialCapacity) - { - super(initialCapacity); - } - - /** - * Construct a new, empty HashSet whose backing HashMap has the supplied - * capacity and load factor. - * - * @param initialCapacity the initial capacity of the backing HashMap - * @param loadFactor the load factor of the backing HashMap - * @throws IllegalArgumentException if either argument is negative, or - * if loadFactor is POSITIVE_INFINITY or NaN - */ - public LinkedHashSet(int initialCapacity, float loadFactor) - { - super(initialCapacity, loadFactor); - } - - /** - * Construct a new HashSet with the same elements as are in the supplied - * collection (eliminating any duplicates, of course). The backing storage - * has twice the size of the collection, or the default size of 11, - * whichever is greater; and the default load factor (0.75). - * - * @param c a collection of initial set elements - * @throws NullPointerException if c is null - */ - public LinkedHashSet(Collection c) - { - super(c); - } - - /** - * Helper method which initializes the backing Map. - * - * @param capacity the initial capacity - * @param load the initial load factor - * @return the backing HashMap - */ - HashMap init(int capacity, float load) - { - return new LinkedHashMap(capacity, load); - } - -} diff --git a/libjava/java/util/LinkedList.java b/libjava/java/util/LinkedList.java deleted file mode 100644 index f611050df1d..00000000000 --- a/libjava/java/util/LinkedList.java +++ /dev/null @@ -1,958 +0,0 @@ -/* LinkedList.java -- Linked list implementation of the List interface - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.lang.reflect.Array; - -/** - * Linked list implementation of the List interface. In addition to the - * methods of the List interface, this class provides access to the first - * and last list elements in O(1) time for easy stack, queue, or double-ended - * queue (deque) creation. The list is doubly-linked, with traversal to a - * given index starting from the end closest to the element.<p> - * - * LinkedList is not synchronized, so if you need multi-threaded access, - * consider using:<br> - * <code>List l = Collections.synchronizedList(new LinkedList(...));</code> - * <p> - * - * The iterators are <i>fail-fast</i>, meaning that any structural - * modification, except for <code>remove()</code> called on the iterator - * itself, cause the iterator to throw a - * {@link ConcurrentModificationException} rather than exhibit - * non-deterministic behavior. - * - * @author Original author unknown - * @author Bryce McKinlay - * @author Eric Blake (ebb9@email.byu.edu) - * @see List - * @see ArrayList - * @see Vector - * @see Collections#synchronizedList(List) - * @since 1.2 - * @status missing javadoc, but complete to 1.4 - */ -public class LinkedList extends AbstractSequentialList - implements List, Cloneable, Serializable -{ - /** - * Compatible with JDK 1.2. - */ - private static final long serialVersionUID = 876323262645176354L; - - /** - * The first element in the list. - */ - transient Entry first; - - /** - * The last element in the list. - */ - transient Entry last; - - /** - * The current length of the list. - */ - transient int size = 0; - - /** - * Class to represent an entry in the list. Holds a single element. - */ - private static final class Entry - { - /** The element in the list. */ - Object data; - - /** The next list entry, null if this is last. */ - Entry next; - - /** The previous list entry, null if this is first. */ - Entry previous; - - /** - * Construct an entry. - * @param data the list element - */ - Entry(Object data) - { - this.data = data; - } - } // class Entry - - /** - * Obtain the Entry at a given position in a list. This method of course - * takes linear time, but it is intelligent enough to take the shorter of the - * paths to get to the Entry required. This implies that the first or last - * entry in the list is obtained in constant time, which is a very desirable - * property. - * For speed and flexibility, range checking is not done in this method: - * Incorrect values will be returned if (n < 0) or (n >= size). - * - * @param n the number of the entry to get - * @return the entry at position n - */ - // Package visible for use in nested classes. - Entry getEntry(int n) - { - Entry e; - if (n < size / 2) - { - e = first; - // n less than size/2, iterate from start - while (n-- > 0) - e = e.next; - } - else - { - e = last; - // n greater than size/2, iterate from end - while (++n < size) - e = e.previous; - } - return e; - } - - /** - * Remove an entry from the list. This will adjust size and deal with - * `first' and `last' appropriatly. - * - * @param e the entry to remove - */ - // Package visible for use in nested classes. - void removeEntry(Entry e) - { - modCount++; - size--; - if (size == 0) - first = last = null; - else - { - if (e == first) - { - first = e.next; - e.next.previous = null; - } - else if (e == last) - { - last = e.previous; - e.previous.next = null; - } - else - { - e.next.previous = e.previous; - e.previous.next = e.next; - } - } - } - - /** - * Checks that the index is in the range of possible elements (inclusive). - * - * @param index the index to check - * @throws IndexOutOfBoundsException if index < 0 || index > size - */ - private void checkBoundsInclusive(int index) - { - if (index < 0 || index > size) - throw new IndexOutOfBoundsException("Index: " + index + ", Size:" - + size); - } - - /** - * Checks that the index is in the range of existing elements (exclusive). - * - * @param index the index to check - * @throws IndexOutOfBoundsException if index < 0 || index >= size - */ - private void checkBoundsExclusive(int index) - { - if (index < 0 || index >= size) - throw new IndexOutOfBoundsException("Index: " + index + ", Size:" - + size); - } - - /** - * Create an empty linked list. - */ - public LinkedList() - { - } - - /** - * Create a linked list containing the elements, in order, of a given - * collection. - * - * @param c the collection to populate this list from - * @throws NullPointerException if c is null - */ - public LinkedList(Collection c) - { - addAll(c); - } - - /** - * Returns the first element in the list. - * - * @return the first list element - * @throws NoSuchElementException if the list is empty - */ - public Object getFirst() - { - if (size == 0) - throw new NoSuchElementException(); - return first.data; - } - - /** - * Returns the last element in the list. - * - * @return the last list element - * @throws NoSuchElementException if the list is empty - */ - public Object getLast() - { - if (size == 0) - throw new NoSuchElementException(); - return last.data; - } - - /** - * Remove and return the first element in the list. - * - * @return the former first element in the list - * @throws NoSuchElementException if the list is empty - */ - public Object removeFirst() - { - if (size == 0) - throw new NoSuchElementException(); - modCount++; - size--; - Object r = first.data; - - if (first.next != null) - first.next.previous = null; - else - last = null; - - first = first.next; - - return r; - } - - /** - * Remove and return the last element in the list. - * - * @return the former last element in the list - * @throws NoSuchElementException if the list is empty - */ - public Object removeLast() - { - if (size == 0) - throw new NoSuchElementException(); - modCount++; - size--; - Object r = last.data; - - if (last.previous != null) - last.previous.next = null; - else - first = null; - - last = last.previous; - - return r; - } - - /** - * Insert an element at the first of the list. - * - * @param o the element to insert - */ - public void addFirst(Object o) - { - Entry e = new Entry(o); - - modCount++; - if (size == 0) - first = last = e; - else - { - e.next = first; - first.previous = e; - first = e; - } - size++; - } - - /** - * Insert an element at the last of the list. - * - * @param o the element to insert - */ - public void addLast(Object o) - { - addLastEntry(new Entry(o)); - } - - /** - * Inserts an element at the end of the list. - * - * @param e the entry to add - */ - private void addLastEntry(Entry e) - { - modCount++; - if (size == 0) - first = last = e; - else - { - e.previous = last; - last.next = e; - last = e; - } - size++; - } - - /** - * Returns true if the list contains the given object. Comparison is done by - * <code>o == null ? e = null : o.equals(e)</code>. - * - * @param o the element to look for - * @return true if it is found - */ - public boolean contains(Object o) - { - Entry e = first; - while (e != null) - { - if (equals(o, e.data)) - return true; - e = e.next; - } - return false; - } - - /** - * Returns the size of the list. - * - * @return the list size - */ - public int size() - { - return size; - } - - /** - * Adds an element to the end of the list. - * - * @param e the entry to add - * @return true, as it always succeeds - */ - public boolean add(Object o) - { - addLastEntry(new Entry(o)); - return true; - } - - /** - * Removes the entry at the lowest index in the list that matches the given - * object, comparing by <code>o == null ? e = null : o.equals(e)</code>. - * - * @param o the object to remove - * @return true if an instance of the object was removed - */ - public boolean remove(Object o) - { - Entry e = first; - while (e != null) - { - if (equals(o, e.data)) - { - removeEntry(e); - return true; - } - e = e.next; - } - return false; - } - - /** - * Append the elements of the collection in iteration order to the end of - * this list. If this list is modified externally (for example, if this - * list is the collection), behavior is unspecified. - * - * @param c the collection to append - * @return true if the list was modified - * @throws NullPointerException if c is null - */ - public boolean addAll(Collection c) - { - return addAll(size, c); - } - - /** - * Insert the elements of the collection in iteration order at the given - * index of this list. If this list is modified externally (for example, - * if this list is the collection), behavior is unspecified. - * - * @param c the collection to append - * @return true if the list was modified - * @throws NullPointerException if c is null - * @throws IndexOutOfBoundsException if index < 0 || index > size() - */ - public boolean addAll(int index, Collection c) - { - checkBoundsInclusive(index); - int csize = c.size(); - - if (csize == 0) - return false; - - Iterator itr = c.iterator(); - - // Get the entries just before and after index. If index is at the start - // of the list, BEFORE is null. If index is at the end of the list, AFTER - // is null. If the list is empty, both are null. - Entry after = null; - Entry before = null; - if (index != size) - { - after = getEntry(index); - before = after.previous; - } - else - before = last; - - // Create the first new entry. We do not yet set the link from `before' - // to the first entry, in order to deal with the case where (c == this). - // [Actually, we don't have to handle this case to fufill the - // contract for addAll(), but Sun's implementation appears to.] - Entry e = new Entry(itr.next()); - e.previous = before; - Entry prev = e; - Entry firstNew = e; - - // Create and link all the remaining entries. - for (int pos = 1; pos < csize; pos++) - { - e = new Entry(itr.next()); - e.previous = prev; - prev.next = e; - prev = e; - } - - // Link the new chain of entries into the list. - modCount++; - size += csize; - prev.next = after; - if (after != null) - after.previous = e; - else - last = e; - - if (before != null) - before.next = firstNew; - else - first = firstNew; - return true; - } - - /** - * Remove all elements from this list. - */ - public void clear() - { - if (size > 0) - { - modCount++; - first = null; - last = null; - size = 0; - } - } - - /** - * Return the element at index. - * - * @param index the place to look - * @return the element at index - * @throws IndexOutOfBoundsException if index < 0 || index >= size() - */ - public Object get(int index) - { - checkBoundsExclusive(index); - return getEntry(index).data; - } - - /** - * Replace the element at the given location in the list. - * - * @param index which index to change - * @param o the new element - * @return the prior element - * @throws IndexOutOfBoundsException if index < 0 || index >= size() - */ - public Object set(int index, Object o) - { - checkBoundsExclusive(index); - Entry e = getEntry(index); - Object old = e.data; - e.data = o; - return old; - } - - /** - * Inserts an element in the given position in the list. - * - * @param index where to insert the element - * @param o the element to insert - * @throws IndexOutOfBoundsException if index < 0 || index > size() - */ - public void add(int index, Object o) - { - checkBoundsInclusive(index); - Entry e = new Entry(o); - - if (index < size) - { - modCount++; - Entry after = getEntry(index); - e.next = after; - e.previous = after.previous; - if (after.previous == null) - first = e; - else - after.previous.next = e; - after.previous = e; - size++; - } - else - addLastEntry(e); - } - - /** - * Removes the element at the given position from the list. - * - * @param index the location of the element to remove - * @return the removed element - * @throws IndexOutOfBoundsException if index < 0 || index > size() - */ - public Object remove(int index) - { - checkBoundsExclusive(index); - Entry e = getEntry(index); - removeEntry(e); - return e.data; - } - - /** - * Returns the first index where the element is located in the list, or -1. - * - * @param o the element to look for - * @return its position, or -1 if not found - */ - public int indexOf(Object o) - { - int index = 0; - Entry e = first; - while (e != null) - { - if (equals(o, e.data)) - return index; - index++; - e = e.next; - } - return -1; - } - - /** - * Returns the last index where the element is located in the list, or -1. - * - * @param o the element to look for - * @return its position, or -1 if not found - */ - public int lastIndexOf(Object o) - { - int index = size - 1; - Entry e = last; - while (e != null) - { - if (equals(o, e.data)) - return index; - index--; - e = e.previous; - } - return -1; - } - - /** - * Obtain a ListIterator over this list, starting at a given index. The - * ListIterator returned by this method supports the add, remove and set - * methods. - * - * @param index the index of the element to be returned by the first call to - * next(), or size() to be initially positioned at the end of the list - * @throws IndexOutOfBoundsException if index < 0 || index > size() - */ - public ListIterator listIterator(int index) - { - checkBoundsInclusive(index); - return new LinkedListItr(index); - } - - /** - * Create a shallow copy of this LinkedList (the elements are not cloned). - * - * @return an object of the same class as this object, containing the - * same elements in the same order - */ - public Object clone() - { - LinkedList copy = null; - try - { - copy = (LinkedList) super.clone(); - } - catch (CloneNotSupportedException ex) - { - } - copy.clear(); - copy.addAll(this); - return copy; - } - - /** - * Returns an array which contains the elements of the list in order. - * - * @return an array containing the list elements - */ - public Object[] toArray() - { - Object[] array = new Object[size]; - Entry e = first; - for (int i = 0; i < size; i++) - { - array[i] = e.data; - e = e.next; - } - return array; - } - - /** - * Returns an Array whose component type is the runtime component type of - * the passed-in Array. The returned Array is populated with all of the - * elements in this LinkedList. If the passed-in Array is not large enough - * to store all of the elements in this List, a new Array will be created - * and returned; if the passed-in Array is <i>larger</i> than the size - * of this List, then size() index will be set to null. - * - * @param a the passed-in Array - * @return an array representation of this list - * @throws ArrayStoreException if the runtime type of a does not allow - * an element in this list - * @throws NullPointerException if a is null - */ - public Object[] toArray(Object[] a) - { - if (a.length < size) - a = (Object[]) Array.newInstance(a.getClass().getComponentType(), size); - else if (a.length > size) - a[size] = null; - Entry e = first; - for (int i = 0; i < size; i++) - { - a[i] = e.data; - e = e.next; - } - return a; - } - - /** - * Serializes this object to the given stream. - * - * @param s the stream to write to - * @throws IOException if the underlying stream fails - * @serialData the size of the list (int), followed by all the elements - * (Object) in proper order - */ - private void writeObject(ObjectOutputStream s) throws IOException - { - s.defaultWriteObject(); - s.writeInt(size); - Entry e = first; - while (e != null) - { - s.writeObject(e.data); - e = e.next; - } - } - - /** - * Deserializes this object from the given stream. - * - * @param s the stream to read from - * @throws ClassNotFoundException if the underlying stream fails - * @throws IOException if the underlying stream fails - * @serialData the size of the list (int), followed by all the elements - * (Object) in proper order - */ - private void readObject(ObjectInputStream s) - throws IOException, ClassNotFoundException - { - s.defaultReadObject(); - int i = s.readInt(); - while (--i >= 0) - addLastEntry(new Entry(s.readObject())); - } - - /** - * A ListIterator over the list. This class keeps track of its - * position in the list and the two list entries it is between. - * - * @author Original author unknown - * @author Eric Blake (ebb9@email.byu.edu) - */ - private final class LinkedListItr implements ListIterator - { - /** Number of modifications we know about. */ - private int knownMod = modCount; - - /** Entry that will be returned by next(). */ - private Entry next; - - /** Entry that will be returned by previous(). */ - private Entry previous; - - /** Entry that will be affected by remove() or set(). */ - private Entry lastReturned; - - /** Index of `next'. */ - private int position; - - /** - * Initialize the iterator. - * - * @param index the initial index - */ - LinkedListItr(int index) - { - if (index == size) - { - next = null; - previous = last; - } - else - { - next = getEntry(index); - previous = next.previous; - } - position = index; - } - - /** - * Checks for iterator consistency. - * - * @throws ConcurrentModificationException if the list was modified - */ - private void checkMod() - { - if (knownMod != modCount) - throw new ConcurrentModificationException(); - } - - /** - * Returns the index of the next element. - * - * @return the next index - * @throws ConcurrentModificationException if the list was modified - */ - public int nextIndex() - { - checkMod(); - return position; - } - - /** - * Returns the index of the previous element. - * - * @return the previous index - * @throws ConcurrentModificationException if the list was modified - */ - public int previousIndex() - { - checkMod(); - return position - 1; - } - - /** - * Returns true if more elements exist via next. - * - * @return true if next will succeed - * @throws ConcurrentModificationException if the list was modified - */ - public boolean hasNext() - { - checkMod(); - return (next != null); - } - - /** - * Returns true if more elements exist via previous. - * - * @return true if previous will succeed - * @throws ConcurrentModificationException if the list was modified - */ - public boolean hasPrevious() - { - checkMod(); - return (previous != null); - } - - /** - * Returns the next element. - * - * @return the next element - * @throws ConcurrentModificationException if the list was modified - * @throws NoSuchElementException if there is no next - */ - public Object next() - { - checkMod(); - if (next == null) - throw new NoSuchElementException(); - position++; - lastReturned = previous = next; - next = lastReturned.next; - return lastReturned.data; - } - - /** - * Returns the previous element. - * - * @return the previous element - * @throws ConcurrentModificationException if the list was modified - * @throws NoSuchElementException if there is no previous - */ - public Object previous() - { - checkMod(); - if (previous == null) - throw new NoSuchElementException(); - position--; - lastReturned = next = previous; - previous = lastReturned.previous; - return lastReturned.data; - } - - /** - * Remove the most recently returned element from the list. - * - * @throws ConcurrentModificationException if the list was modified - * @throws IllegalStateException if there was no last element - */ - public void remove() - { - checkMod(); - if (lastReturned == null) - throw new IllegalStateException(); - - // Adjust the position to before the removed element, if the element - // being removed is behind the cursor. - if (lastReturned == previous) - position--; - - next = lastReturned.next; - previous = lastReturned.previous; - removeEntry(lastReturned); - knownMod++; - - lastReturned = null; - } - - /** - * Adds an element between the previous and next, and advance to the next. - * - * @param o the element to add - * @throws ConcurrentModificationException if the list was modified - */ - public void add(Object o) - { - checkMod(); - modCount++; - knownMod++; - size++; - position++; - Entry e = new Entry(o); - e.previous = previous; - e.next = next; - - if (previous != null) - previous.next = e; - else - first = e; - - if (next != null) - next.previous = e; - else - last = e; - - previous = e; - lastReturned = null; - } - - /** - * Changes the contents of the element most recently returned. - * - * @param o the new element - * @throws ConcurrentModificationException if the list was modified - * @throws IllegalStateException if there was no last element - */ - public void set(Object o) - { - checkMod(); - if (lastReturned == null) - throw new IllegalStateException(); - lastReturned.data = o; - } - } // class LinkedListItr -} diff --git a/libjava/java/util/List.java b/libjava/java/util/List.java deleted file mode 100644 index 445811292ac..00000000000 --- a/libjava/java/util/List.java +++ /dev/null @@ -1,451 +0,0 @@ -/* List.java -- An ordered collection which allows indexed access - Copyright (C) 1998, 2001, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -/** - * An ordered collection (also known as a list). This collection allows - * access to elements by position, as well as control on where elements - * are inserted. Unlike sets, duplicate elements are permitted by this - * general contract (if a subclass forbids duplicates, this should be - * documented). - * <p> - * - * List places additional requirements on <code>iterator</code>, - * <code>add</code>, <code>remove</code>, <code>equals</code>, and - * <code>hashCode</code>, in addition to requiring more methods. List - * indexing is 0-based (like arrays), although some implementations may - * require time proportional to the index to obtain an arbitrary element. - * The List interface is incompatible with Set; you cannot implement both - * simultaneously. - * <p> - * - * Lists also provide a <code>ListIterator</code> which allows bidirectional - * traversal and other features atop regular iterators. Lists can be - * searched for arbitrary elements, and allow easy insertion and removal - * of multiple elements in one method call. - * <p> - * - * Note: While lists may contain themselves as elements, this leads to - * undefined (usually infinite recursive) behavior for some methods like - * hashCode or equals. - * - * @author Original author unknown - * @author Eric Blake (ebb9@email.byu.edu) - * @see Collection - * @see Set - * @see ArrayList - * @see LinkedList - * @see Vector - * @see Arrays#asList(Object[]) - * @see Collections#nCopies(int, Object) - * @see Collections#EMPTY_LIST - * @see AbstractList - * @see AbstractSequentialList - * @since 1.2 - * @status updated to 1.4 - */ -public interface List extends Collection -{ - /** - * Insert an element into the list at a given position (optional operation). - * This shifts all existing elements from that position to the end one - * index to the right. This version of add has no return, since it is - * assumed to always succeed if there is no exception. - * - * @param index the location to insert the item - * @param o the object to insert - * @throws UnsupportedOperationException if this list does not support the - * add operation - * @throws IndexOutOfBoundsException if index < 0 || index > size() - * @throws ClassCastException if o cannot be added to this list due to its - * type - * @throws IllegalArgumentException if o cannot be added to this list for - * some other reason - * @throws NullPointerException if o is null and this list doesn't support - * the addition of null values. - */ - void add(int index, Object o); - - /** - * Add an element to the end of the list (optional operation). If the list - * imposes restraints on what can be inserted, such as no null elements, - * this should be documented. - * - * @param o the object to add - * @return true, as defined by Collection for a modified list - * @throws UnsupportedOperationException if this list does not support the - * add operation - * @throws ClassCastException if o cannot be added to this list due to its - * type - * @throws IllegalArgumentException if o cannot be added to this list for - * some other reason - * @throws NullPointerException if o is null and this list doesn't support - * the addition of null values. - */ - boolean add(Object o); - - /** - * Insert the contents of a collection into the list at a given position - * (optional operation). Shift all elements at that position to the right - * by the number of elements inserted. This operation is undefined if - * this list is modified during the operation (for example, if you try - * to insert a list into itself). - * - * @param index the location to insert the collection - * @param c the collection to insert - * @return true if the list was modified by this action, that is, if c is - * non-empty - * @throws UnsupportedOperationException if this list does not support the - * addAll operation - * @throws IndexOutOfBoundsException if index < 0 || index > size() - * @throws ClassCastException if some element of c cannot be added to this - * list due to its type - * @throws IllegalArgumentException if some element of c cannot be added - * to this list for some other reason - * @throws NullPointerException if some element of c is null and this list - * doesn't support the addition of null values. - * @throws NullPointerException if the specified collection is null - * @see #add(int, Object) - */ - boolean addAll(int index, Collection c); - - /** - * Add the contents of a collection to the end of the list (optional - * operation). This operation is undefined if this list is modified - * during the operation (for example, if you try to insert a list into - * itself). - * - * @param c the collection to add - * @return true if the list was modified by this action, that is, if c is - * non-empty - * @throws UnsupportedOperationException if this list does not support the - * addAll operation - * @throws ClassCastException if some element of c cannot be added to this - * list due to its type - * @throws IllegalArgumentException if some element of c cannot be added - * to this list for some other reason - * @throws NullPointerException if the specified collection is null - * @throws NullPointerException if some element of c is null and this list - * doesn't support the addition of null values. - * @see #add(Object) - */ - boolean addAll(Collection c); - - /** - * Clear the list, such that a subsequent call to isEmpty() would return - * true (optional operation). - * - * @throws UnsupportedOperationException if this list does not support the - * clear operation - */ - void clear(); - - /** - * Test whether this list contains a given object as one of its elements. - * This is defined as the existence of an element e such that - * <code>o == null ? e == null : o.equals(e)</code>. - * - * @param o the element to look for - * @return true if this list contains the element - * @throws ClassCastException if the type of o is not a valid type - * for this list. - * @throws NullPointerException if o is null and the list doesn't - * support null values. - */ - boolean contains(Object o); - - /** - * Test whether this list contains every element in a given collection. - * - * @param c the collection to test for - * @return true if for every element o in c, contains(o) would return true - * @throws NullPointerException if the collection is null - * @throws ClassCastException if the type of any element in c is not a valid - * type for this list. - * @throws NullPointerException if some element of c is null and this - * list does not support null values. - * @see #contains(Object) - */ - boolean containsAll(Collection c); - - /** - * Test whether this list is equal to another object. A List is defined to be - * equal to an object if and only if that object is also a List, and the two - * lists have the same sequence. Two lists l1 and l2 are equal if and only - * if <code>l1.size() == l2.size()</code>, and for every integer n between 0 - * and <code>l1.size() - 1</code> inclusive, <code>l1.get(n) == null ? - * l2.get(n) == null : l1.get(n).equals(l2.get(n))</code>. - * - * @param o the object to test for equality with this list - * @return true if o is equal to this list - * @see Object#equals(Object) - * @see #hashCode() - */ - boolean equals(Object o); - - /** - * Get the element at a given index in this list. - * - * @param index the index of the element to be returned - * @return the element at index index in this list - * @throws IndexOutOfBoundsException if index < 0 || index >= size() - */ - Object get(int index); - - /** - * Obtains a hash code for this list. In order to obey the general - * contract of the hashCode method of class Object, this value is - * calculated as follows: - * -<p><pre>hashCode = 1; -Iterator i = list.iterator(); -while (i.hasNext()) -{ - Object obj = i.next(); - hashCode = 31 * hashCode + (obj == null ? 0 : obj.hashCode()); -}</pre> - * - * <p>This ensures that the general contract of Object.hashCode() - * is adhered to. - * - * @return the hash code of this list - * @see Object#hashCode() - * @see #equals(Object) - */ - int hashCode(); - - /** - * Obtain the first index at which a given object is to be found in this - * list. - * - * @param o the object to search for - * @return the least integer n such that <code>o == null ? get(n) == null : - * o.equals(get(n))</code>, or -1 if there is no such index. - * @throws ClassCastException if the type of o is not a valid - * type for this list. - * @throws NullPointerException if o is null and this - * list does not support null values. - */ - int indexOf(Object o); - - /** - * Test whether this list is empty, that is, if size() == 0. - * - * @return true if this list contains no elements - */ - boolean isEmpty(); - - /** - * Obtain an Iterator over this list, whose sequence is the list order. - * - * @return an Iterator over the elements of this list, in order - */ - Iterator iterator(); - - /** - * Obtain the last index at which a given object is to be found in this - * list. - * - * @return the greatest integer n such that <code>o == null ? get(n) == null - * : o.equals(get(n))</code>, or -1 if there is no such index. - * @throws ClassCastException if the type of o is not a valid - * type for this list. - * @throws NullPointerException if o is null and this - * list does not support null values. - */ - int lastIndexOf(Object o); - - /** - * Obtain a ListIterator over this list, starting at the beginning. - * - * @return a ListIterator over the elements of this list, in order, starting - * at the beginning - */ - ListIterator listIterator(); - - /** - * Obtain a ListIterator over this list, starting at a given position. - * A first call to next() would return the same as get(index), and a - * first call to previous() would return the same as get(index - 1). - * - * @param index the position, between 0 and size() inclusive, to begin the - * iteration from - * @return a ListIterator over the elements of this list, in order, starting - * at index - * @throws IndexOutOfBoundsException if index < 0 || index > size() - */ - ListIterator listIterator(int index); - - /** - * Remove the element at a given position in this list (optional operation). - * Shifts all remaining elements to the left to fill the gap. - * - * @param index the position within the list of the object to remove - * @return the object that was removed - * @throws UnsupportedOperationException if this list does not support the - * remove operation - * @throws IndexOutOfBoundsException if index < 0 || index >= size() - */ - Object remove(int index); - - /** - * Remove the first occurence of an object from this list (optional - * operation). That is, remove the first element e such that - * <code>o == null ? e == null : o.equals(e)</code>. - * - * @param o the object to remove - * @return true if the list changed as a result of this call, that is, if - * the list contained at least one occurrence of o - * @throws UnsupportedOperationException if this list does not support the - * remove operation - * @throws ClassCastException if the type of o is not a valid - * type for this list. - * @throws NullPointerException if o is null and this - * list does not support removing null values. - */ - boolean remove(Object o); - - /** - * Remove all elements of a given collection from this list (optional - * operation). That is, remove every element e such that c.contains(e). - * - * @param c the collection to filter out - * @return true if this list was modified as a result of this call - * @throws UnsupportedOperationException if this list does not support the - * removeAll operation - * @throws NullPointerException if the collection is null - * @throws ClassCastException if the type of any element in c is not a valid - * type for this list. - * @throws NullPointerException if some element of c is null and this - * list does not support removing null values. - * @see #remove(Object) - * @see #contains(Object) - */ - boolean removeAll(Collection c); - - /** - * Remove all elements of this list that are not contained in a given - * collection (optional operation). That is, remove every element e such - * that !c.contains(e). - * - * @param c the collection to retain - * @return true if this list was modified as a result of this call - * @throws UnsupportedOperationException if this list does not support the - * retainAll operation - * @throws NullPointerException if the collection is null - * @throws ClassCastException if the type of any element in c is not a valid - * type for this list. - * @throws NullPointerException if some element of c is null and this - * list does not support retaining null values. - * @see #remove(Object) - * @see #contains(Object) - */ - boolean retainAll(Collection c); - - /** - * Replace an element of this list with another object (optional operation). - * - * @param index the position within this list of the element to be replaced - * @param o the object to replace it with - * @return the object that was replaced - * @throws UnsupportedOperationException if this list does not support the - * set operation - * @throws IndexOutOfBoundsException if index < 0 || index >= size() - * @throws ClassCastException if o cannot be added to this list due to its - * type - * @throws IllegalArgumentException if o cannot be added to this list for - * some other reason - * @throws NullPointerException if o is null and this - * list does not support null values. - */ - Object set(int index, Object o); - - /** - * Get the number of elements in this list. If the list contains more - * than Integer.MAX_VALUE elements, return Integer.MAX_VALUE. - * - * @return the number of elements in the list - */ - int size(); - - /** - * Obtain a List view of a subsection of this list, from fromIndex - * (inclusive) to toIndex (exclusive). If the two indices are equal, the - * sublist is empty. The returned list should be modifiable if and only - * if this list is modifiable. Changes to the returned list should be - * reflected in this list. If this list is structurally modified in - * any way other than through the returned list, the result of any subsequent - * operations on the returned list is undefined. - * - * @param fromIndex the index that the returned list should start from - * (inclusive) - * @param toIndex the index that the returned list should go to (exclusive) - * @return a List backed by a subsection of this list - * @throws IndexOutOfBoundsException if fromIndex < 0 - * || toIndex > size() || fromIndex > toIndex - */ - List subList(int fromIndex, int toIndex); - - /** - * Copy the current contents of this list into an array. - * - * @return an array of type Object[] and length equal to the length of this - * list, containing the elements currently in this list, in order - */ - Object[] toArray(); - - /** - * Copy the current contents of this list into an array. If the array passed - * as an argument has length less than that of this list, an array of the - * same run-time type as a, and length equal to the length of this list, is - * allocated using Reflection. Otherwise, a itself is used. The elements of - * this list are copied into it, and if there is space in the array, the - * following element is set to null. The resultant array is returned. - * Note: The fact that the following element is set to null is only useful - * if it is known that this list does not contain any null elements. - * - * @param a the array to copy this list into - * @return an array containing the elements currently in this list, in - * order - * @throws ArrayStoreException if the type of any element of the - * collection is not a subtype of the element type of a - * @throws NullPointerException if the specified array is null - */ - Object[] toArray(Object[] a); -} diff --git a/libjava/java/util/ListIterator.java b/libjava/java/util/ListIterator.java deleted file mode 100644 index 5e17108c991..00000000000 --- a/libjava/java/util/ListIterator.java +++ /dev/null @@ -1,170 +0,0 @@ -/* ListIterator.java -- Extended Iterator for iterating over ordered lists - Copyright (C) 1998, 1999, 2001, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -/** - * An extended version of Iterator to support the extra features of Lists. The - * elements may be accessed in forward or reverse order, elements may be - * replaced as well as removed, and new elements may be inserted, during the - * traversal of the list. - * <p> - * - * A list with n elements provides n+1 iterator positions (the front, the end, - * or between two elements). Note that <code>remove</code> and <code>set</code> - * operate on the last element returned, whether it was by <code>next</code> - * or <code>previous</code>. - * - * @author Original author unknown - * @author Eric Blake (ebb9@email.byu.edu) - * @see Collection - * @see List - * @see Iterator - * @see Enumeration - * @since 1.2 - * @status updated to 1.4 - */ -public interface ListIterator extends Iterator -{ - /** - * Tests whether there are elements remaining in the list in the forward - * direction. In other words, next() will not fail with a - * NoSuchElementException. - * - * @return true if the list continues in the forward direction - */ - boolean hasNext(); - - /** - * Tests whether there are elements remaining in the list in the reverse - * direction. In other words, previous() will not fail with a - * NoSuchElementException. - * - * @return true if the list continues in the reverse direction - */ - boolean hasPrevious(); - - /** - * Obtain the next element in the list in the forward direction. Repeated - * calls to next may be used to iterate over the entire list, or calls to - * next and previous may be used together to go forwards and backwards. - * Alternating calls to next and previous will return the same element. - * - * @return the next element in the list in the forward direction - * @throws NoSuchElementException if there are no more elements - */ - Object next(); - - /** - * Obtain the next element in the list in the reverse direction. Repeated - * calls to previous may be used to iterate backwards over the entire list, - * or calls to next and previous may be used together to go forwards and - * backwards. Alternating calls to next and previous will return the same - * element. - * - * @return the next element in the list in the reverse direction - * @throws NoSuchElementException if there are no more elements - */ - Object previous(); - - /** - * Find the index of the element that would be returned by a call to next. - * If hasNext() returns false, this returns the list size. - * - * @return the index of the element that would be returned by next() - */ - int nextIndex(); - - /** - * Find the index of the element that would be returned by a call to - * previous. If hasPrevious() returns false, this returns -1. - * - * @return the index of the element that would be returned by previous() - */ - int previousIndex(); - - /** - * Insert an element into the list at the current position of the iterator - * (optional operation). The element is inserted in between the element that - * would be returned by previous and the element that would be returned by - * next. After the insertion, a subsequent call to next is unaffected, but - * a call to previous returns the item that was added. The values returned - * by nextIndex() and previousIndex() are incremented. - * - * @param o the object to insert into the list - * @throws ClassCastException if the object is of a type which cannot be added - * to this list. - * @throws IllegalArgumentException if some other aspect of the object stops - * it being added to this list. - * @throws UnsupportedOperationException if this ListIterator does not - * support the add operation. - */ - void add(Object o); - - /** - * Remove from the list the element last returned by a call to next or - * previous (optional operation). This method may only be called if neither - * add nor remove have been called since the last call to next or previous. - * - * @throws IllegalStateException if neither next or previous have been - * called, or if add or remove has been called since the last call - * to next or previous - * @throws UnsupportedOperationException if this ListIterator does not - * support the remove operation - */ - void remove(); - - /** - * Replace the element last returned by a call to next or previous with a - * given object (optional operation). This method may only be called if - * neither add nor remove have been called since the last call to next or - * previous. - * - * @param o the object to replace the element with - * @throws ClassCastException the object is of a type which cannot be added - * to this list - * @throws IllegalArgumentException some other aspect of the object stops - * it being added to this list - * @throws IllegalStateException if neither next or previous have been - * called, or if add or remove has been called since the last call - * to next or previous - * @throws UnsupportedOperationException if this ListIterator does not - * support the set operation - */ - void set(Object o); -} diff --git a/libjava/java/util/ListResourceBundle.java b/libjava/java/util/ListResourceBundle.java deleted file mode 100644 index 2bc51c3b013..00000000000 --- a/libjava/java/util/ListResourceBundle.java +++ /dev/null @@ -1,140 +0,0 @@ -/* ListResourceBundle -- a resource bundle build around a list - Copyright (C) 1998, 1999, 2001, 2002, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -/** - * 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. - * - * <p>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, and they are - * case-sensitive. For example: - * -<br><pre>public class MyResources - extends ListResourceBundle -{ - public Object[][] getContents() - { - return contents; - } - - static final Object[][] contents = - { - // LOCALIZED STRINGS - {"s1", "The disk \"{1}\" contains {0}."}, // MessageFormat pattern - {"s2", "1"}, // location of {0} in pattern - {"s3", "My Disk"}, // sample disk name - {"s4", "no files"}, // first ChoiceFormat choice - {"s5", "one file"}, // second ChoiceFormat choice - {"s6", "{0,number} files"} // third ChoiceFormat choice - {"s7", "3 Mar 96"}, // sample date - {"s8", new Dimension(1,5)} // real object, not just string - // END OF LOCALIZED MATERIAL - }; -}</pre> - * - * @author Jochen Hoenicke - * @author Eric Blake (ebb9@email.byu.edu) - * @see Locale - * @see PropertyResourceBundle - * @since 1.1 - * @status updated to 1.4 - */ -public abstract class ListResourceBundle extends ResourceBundle -{ - /** - * The constructor. It does nothing special. - */ - public ListResourceBundle() - { - } - - /** - * Gets a resource for a given key. This is called by <code>getObject</code>. - * - * @param key the key of the resource - * @return the resource for the key, or null if it doesn't exist - */ - public final Object handleGetObject(String key) - { - Object[][] contents = getContents(); - int i = contents.length; - while (--i >= 0) - 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() - { - // We make a new Set that holds all the keys, then return an enumeration - // for that. This prevents modifications from ruining the enumeration, - // as well as ignoring duplicates. - final Object[][] contents = getContents(); - Set s = new HashSet(); - int i = contents.length; - while (--i >= 0) - s.add(contents[i][0]); - ResourceBundle bundle = parent; - // Eliminate tail recursion. - while (bundle != null) - { - Enumeration e = bundle.getKeys(); - while (e.hasMoreElements()) - s.add(e.nextElement()); - bundle = bundle.parent; - } - return Collections.enumeration(s); - } - - /** - * Gets the key/value list. You must override this method, and should not - * provide duplicate keys or null entries. - * - * @return a two dimensional list of String key / Object resouce pairs - */ - protected abstract Object[][] getContents(); -} // class ListResourceBundle diff --git a/libjava/java/util/Map.java b/libjava/java/util/Map.java deleted file mode 100644 index 256e98899f6..00000000000 --- a/libjava/java/util/Map.java +++ /dev/null @@ -1,338 +0,0 @@ -/* Map.java: interface Map -- An object that maps keys to values - interface Map.Entry -- an Entry in a Map - Copyright (C) 1998, 2001, 2004, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -/** - * An object that maps keys onto values. Keys cannot be duplicated. This - * interface replaces the obsolete {@link Dictionary} abstract class. - * <p> - * - * The map has three collection views, which are backed by the map - * (modifications on one show up on the other): a set of keys, a collection - * of values, and a set of key-value mappings. Some maps have a guaranteed - * order, but not all do. - * <p> - * - * Note: Be careful about using mutable keys. Behavior is unspecified if - * a key's comparison behavior is changed after the fact. As a corollary - * to this rule, don't use a Map as one of its own keys or values, as it makes - * hashCode and equals have undefined behavior. - * <p> - * - * All maps are recommended to provide a no argument constructor, which builds - * an empty map, and one that accepts a Map parameter and copies the mappings - * (usually by putAll), to create an equivalent map. Unfortunately, Java - * cannot enforce these suggestions. - * <p> - * - * The map may be unmodifiable, in which case unsupported operations will - * throw an UnsupportedOperationException. Note that some operations may be - * safe, such as putAll(m) where m is empty, even if the operation would - * normally fail with a non-empty argument. - * - * @author Original author unknown - * @author Eric Blake (ebb9@email.byu.edu) - * @see HashMap - * @see TreeMap - * @see Hashtable - * @see SortedMap - * @see Collection - * @see Set - * @since 1.2 - * @status updated to 1.4 - */ -public interface Map -{ - /** - * Remove all entries from this Map (optional operation). - * - * @throws UnsupportedOperationException if clear is not supported - */ - void clear(); - - /** - * Returns true if this contains a mapping for the given key. - * - * @param key the key to search for - * @return true if the map contains the key - * @throws ClassCastException if the key is of an inappropriate type - * @throws NullPointerException if key is <code>null</code> but the map - * does not permit null keys - */ - boolean containsKey(Object key); - - /** - * Returns true if this contains at least one mapping with the given value. - * In other words, returns true if a value v exists where - * <code>(value == null ? v == null : value.equals(v))</code>. This usually - * requires linear time. - * - * @param value the value to search for - * @return true if the map contains the value - * @throws ClassCastException if the type of the value is not a valid type - * for this map. - * @throws NullPointerException if the value is null and the map doesn't - * support null values. - */ - boolean containsValue(Object value); - - /** - * Returns a set view of the mappings in this Map. Each element in the - * set is a Map.Entry. The set is backed by the map, so that changes in - * one show up in the other. Modifications made while an iterator is - * in progress cause undefined behavior. If the set supports removal, - * these methods remove the underlying mapping from the map: - * <code>Iterator.remove</code>, <code>Set.remove</code>, - * <code>removeAll</code>, <code>retainAll</code>, and <code>clear</code>. - * Element addition, via <code>add</code> or <code>addAll</code>, is - * not supported via this set. - * - * @return the set view of all mapping entries - * @see Map.Entry - */ - Set entrySet(); - - /** - * Compares the specified object with this map for equality. Returns - * <code>true</code> if the other object is a Map with the same mappings, - * that is,<br> - * <code>o instanceof Map && entrySet().equals(((Map) o).entrySet();</code> - * This allows comparison of maps, regardless of implementation. - * - * @param o the object to be compared - * @return true if the object equals this map - * @see Set#equals(Object) - */ - boolean equals(Object o); - - /** - * Returns the value mapped by the given key. Returns <code>null</code> if - * there is no mapping. However, in Maps that accept null values, you - * must rely on <code>containsKey</code> to determine if a mapping exists. - * - * @param key the key to look up - * @return the value associated with the key, or null if key not in map - * @throws ClassCastException if the key is an inappropriate type - * @throws NullPointerException if this map does not accept null keys - * @see #containsKey(Object) - */ - Object get(Object key); - - /** - * Associates the given key to the given value (optional operation). If the - * map already contains the key, its value is replaced. Be aware that in - * a map that permits <code>null</code> values, a null return does not - * always imply that the mapping was created. - * - * @param key the key to map - * @param value the value to be mapped - * @return the previous value of the key, or null if there was no mapping - * @throws UnsupportedOperationException if the operation is not supported - * @throws ClassCastException if the key or value is of the wrong type - * @throws IllegalArgumentException if something about this key or value - * prevents it from existing in this map - * @throws NullPointerException if either the key or the value is null, - * and the map forbids null keys or values - * @see #containsKey(Object) - */ - Object put(Object key, Object value); - - /** - * Returns the hash code for this map. This is the sum of all hashcodes - * for each Map.Entry object in entrySet. This allows comparison of maps, - * regardless of implementation, and satisfies the contract of - * Object.hashCode. - * - * @return the hash code - * @see Map.Entry#hashCode() - */ - int hashCode(); - - /** - * Returns true if the map contains no mappings. - * - * @return true if the map is empty - */ - boolean isEmpty(); - - /** - * Returns a set view of the keys in this Map. The set is backed by the - * map, so that changes in one show up in the other. Modifications made - * while an iterator is in progress cause undefined behavior. If the set - * supports removal, these methods remove the underlying mapping from - * the map: <code>Iterator.remove</code>, <code>Set.remove</code>, - * <code>removeAll</code>, <code>retainAll</code>, and <code>clear</code>. - * Element addition, via <code>add</code> or <code>addAll</code>, is - * not supported via this set. - * - * @return the set view of all keys - */ - Set keySet(); - - /** - * Copies all entries of the given map to this one (optional operation). If - * the map already contains a key, its value is replaced. - * - * @param m the mapping to load into this map - * @throws UnsupportedOperationException if the operation is not supported - * @throws ClassCastException if a key or value is of the wrong type - * @throws IllegalArgumentException if something about a key or value - * prevents it from existing in this map - * @throws NullPointerException if the map forbids null keys or values, or - * if <code>m</code> is null. - * @see #put(Object, Object) - */ - void putAll(Map m); - - /** - * Removes the mapping for this key if present (optional operation). If - * the key is not present, this returns null. Note that maps which permit - * null values may also return null if the key was removed. - * - * @param key the key to remove - * @return the value the key mapped to, or null if not present. - * @throws UnsupportedOperationException if deletion is unsupported - * @throws NullPointerException if the key is null and this map doesn't - * support null keys. - * @throws ClassCastException if the type of the key is not a valid type - * for this map. - */ - Object remove(Object key); - - /** - * Returns the number of key-value mappings in the map. If there are more - * than Integer.MAX_VALUE mappings, return Integer.MAX_VALUE. - * - * @return the number of mappings - */ - int size(); - - /** - * Returns a collection (or bag) view of the values in this Map. The - * collection is backed by the map, so that changes in one show up in - * the other. Modifications made while an iterator is in progress cause - * undefined behavior. If the collection supports removal, these methods - * remove the underlying mapping from the map: <code>Iterator.remove</code>, - * <code>Collection.remove</code>, <code>removeAll</code>, - * <code>retainAll</code>, and <code>clear</code>. Element addition, via - * <code>add</code> or <code>addAll</code>, is not supported via this - * collection. - * - * @return the collection view of all values - */ - Collection values(); - - /** - * A map entry (key-value pair). The Map.entrySet() method returns a set - * view of these objects; there is no other valid way to come across them. - * These objects are only valid for the duration of an iteration; in other - * words, if you mess with one after modifying the map, you are asking - * for undefined behavior. - * - * @author Original author unknown - * @author Eric Blake (ebb9@email.byu.edu) - * @see Map - * @see Map#entrySet() - * @since 1.2 - * @status updated to 1.4 - */ - interface Entry - { - /** - * Get the key corresponding to this entry. - * - * @return the key - */ - Object getKey(); - - /** - * Get the value corresponding to this entry. If you already called - * Iterator.remove(), this is undefined. - * - * @return the value - */ - Object getValue(); - - /** - * Replaces the value with the specified object (optional operation). - * This writes through to the map, and is undefined if you already - * called Iterator.remove(). - * - * @param value the new value to store - * @return the old value - * @throws UnsupportedOperationException if the operation is not supported - * @throws ClassCastException if the value is of the wrong type - * @throws IllegalArgumentException if something about the value - * prevents it from existing in this map - * @throws NullPointerException if the map forbids null values - */ - Object setValue(Object value); - - - /** - * Returns the hash code of the entry. This is defined as the - * exclusive-or of the hashcodes of the key and value (using 0 for - * <code>null</code>). In other words, this must be: - * -<p><pre>(getKey() == null ? 0 : getKey().hashCode()) -^ (getValue() == null ? 0 : getValue().hashCode())</pre> - * - * @return the hash code - */ - int hashCode(); - - /** - * Compares the specified object with this entry. Returns true only if - * the object is a mapping of identical key and value. In other words, - * this must be: - * -<p><pre>(o instanceof Map.Entry) -&& (getKey() == null ? ((HashMap) o).getKey() == null - : getKey().equals(((HashMap) o).getKey())) -&& (getValue() == null ? ((HashMap) o).getValue() == null - : getValue().equals(((HashMap) o).getValue()))</pre> - * - * @param o the object to compare - * - * @return <code>true</code> if it is equal - */ - boolean equals(Object o); - } -} diff --git a/libjava/java/util/MissingResourceException.java b/libjava/java/util/MissingResourceException.java deleted file mode 100644 index 26640de90df..00000000000 --- a/libjava/java/util/MissingResourceException.java +++ /dev/null @@ -1,105 +0,0 @@ -/* MissingResourceException.java -- thrown for a missing resource - Copyright (C) 1998, 1999, 2001, 2002, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -/** - * This exception is thrown when a resource is missing. - * - * @author Jochen Hoenicke - * @author Warren Levy (warrenl@cygnus.com) - * @see ResourceBundle - * @since 1.1 - * @status updated to 1.4 - */ -public class MissingResourceException extends RuntimeException -{ - /** - * Compatible with JDK 1.1+. - */ - private static final long serialVersionUID = -4876345176062000401L; - - /** - * The name of the resource bundle requested by user. - * - * @serial the class name of the resource bundle - */ - private final String className; - - /** - * The key of the resource in the bundle requested by user. - * - * @serial the name of the resouce - */ - private final String key; - - /** - * 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(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; - } -} diff --git a/libjava/java/util/NoSuchElementException.java b/libjava/java/util/NoSuchElementException.java deleted file mode 100644 index 5e1a2176d62..00000000000 --- a/libjava/java/util/NoSuchElementException.java +++ /dev/null @@ -1,88 +0,0 @@ -/* NoSuchElementException.java -- Attempt to access element that does not exist - Copyright (C) 1998, 1999, 2001, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -/* 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. - */ - -/** - * 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. It is also - * thrown by Vector and Stack when attempting to access the first or last - * element of an empty collection. - * - * @author Warren Levy (warrenl@cygnus.com) - * @author Eric Blake (ebb9@email.byu.edu) - * @see Enumeration - * @see Iterator - * @see ListIterator - * @see Enumeration#nextElement() - * @see Iterator#next() - * @see ListIterator#previous() - * @since 1.0 - * @status updated to 1.4 - */ -public class NoSuchElementException extends RuntimeException -{ - /** - * Compatible with JDK 1.0. - */ - private static final long serialVersionUID = 6769829250639411880L; - - /** - * Constructs a NoSuchElementException with no detail message. - */ - public NoSuchElementException() - { - } - - /** - * Constructs a NoSuchElementException with a detail message. - * - * @param detail the detail message for the exception - */ - public NoSuchElementException(String detail) - { - super(detail); - } -} diff --git a/libjava/java/util/Observable.java b/libjava/java/util/Observable.java deleted file mode 100644 index 4c2cddb5496..00000000000 --- a/libjava/java/util/Observable.java +++ /dev/null @@ -1,180 +0,0 @@ -/* Observable.java -- an object to be observed - Copyright (C) 1999, 2000, 2001, 2002, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -/** - * This class represents an object which is observable. Other objects may - * register their intent to be notified when this object changes; and when - * this object does change, it will trigger the <code>update</code> method - * of each observer. - * - * Note that the <code>notifyObservers()</code> method of this class is - * unrelated to the <code>notify()</code> of Object. - * - * @author Warren Levy (warrenl@cygnus.com) - * @author Eric Blake (ebb9@email.byu.edu) - * @see Observer - * @status updated to 1.4 - */ -public class Observable -{ - /** Tracks whether this object has changed. */ - private boolean changed; - - /* List of the Observers registered as interested in this Observable. */ - private LinkedHashSet observers; - - /** - * Constructs an Observable with zero Observers. - */ - public Observable() - { - observers = new LinkedHashSet(); - } - - /** - * Adds an Observer. If the observer was already added this method does - * nothing. - * - * @param observer Observer to add - * @throws NullPointerException if observer is null - */ - public synchronized void addObserver(Observer observer) - { - observers.add(observer); - } - - /** - * Reset this Observable's state to unchanged. This is called automatically - * by <code>notifyObservers</code> once all observers have been notified. - * - * @see #notifyObservers() - */ - protected synchronized void clearChanged() - { - changed = false; - } - - /** - * Returns the number of observers for this object. - * - * @return number of Observers for this - */ - public synchronized int countObservers() - { - return observers.size(); - } - - /** - * Deletes an Observer of this Observable. - * - * @param victim Observer to delete - */ - public synchronized void deleteObserver(Observer victim) - { - observers.remove(victim); - } - - /** - * Deletes all Observers of this Observable. - */ - public synchronized void deleteObservers() - { - observers.clear(); - } - - /** - * True if <code>setChanged</code> has been called more recently than - * <code>clearChanged</code>. - * - * @return whether or not this Observable has changed - */ - public synchronized boolean hasChanged() - { - return changed; - } - - /** - * If the Observable has actually changed then tell all Observers about it, - * then reset state to unchanged. - * - * @see #notifyObservers(Object) - * @see Observer#update(Observable, Object) - */ - public void notifyObservers() - { - notifyObservers(null); - } - - /** - * If the Observable has actually changed then tell all Observers about it, - * then reset state to unchanged. Note that though the order of - * notification is unspecified in subclasses, in Observable it is in the - * order of registration. - * - * @param obj argument to Observer's update method - * @see Observer#update(Observable, Object) - */ - public void notifyObservers(Object obj) - { - if (! hasChanged()) - return; - // Create clone inside monitor, as that is relatively fast and still - // important to keep threadsafe, but update observers outside of the - // lock since update() can call arbitrary code. - Set s; - synchronized (this) - { - s = (Set) observers.clone(); - } - int i = s.size(); - Iterator iter = s.iterator(); - while (--i >= 0) - ((Observer) iter.next()).update(this, obj); - clearChanged(); - } - - /** - * Marks this Observable as having changed. - */ - protected synchronized void setChanged() - { - changed = true; - } -} diff --git a/libjava/java/util/Observer.java b/libjava/java/util/Observer.java deleted file mode 100644 index c59a0ca6c68..00000000000 --- a/libjava/java/util/Observer.java +++ /dev/null @@ -1,60 +0,0 @@ -/* Observer.java -- an object that will be informed of changes in an Observable - Copyright (C) 1998, 1999, 2001, 2002, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -/** - * Interface that is implemented when a class wants to be informed of changes - * in Observable objects. - * - * @author Warren Levy (warrenl@cygnus.com) - * @see Observable - * @status updated to 1.4 - */ -public interface Observer -{ - /** - * This method is called whenever the observable object changes, and has - * called <code>notifyObservers</code>. The Observable object can pass - * arbitrary information in the second parameter. - * - * @param observable the Observable object that changed - * @param arg arbitrary information, usually relating to the change - */ - void update(Observable observable, Object arg); -} diff --git a/libjava/java/util/Properties.java b/libjava/java/util/Properties.java deleted file mode 100644 index dd442fc396f..00000000000 --- a/libjava/java/util/Properties.java +++ /dev/null @@ -1,574 +0,0 @@ -/* Properties.java -- a set of persistent properties - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.PrintStream; -import java.io.PrintWriter; - -/** - * A set of persistent properties, which can be saved or loaded from a stream. - * A property list may also contain defaults, searched if the main list - * does not contain a property for a given key. - * - * 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 character - * <code>\</code><code>u00e4</code> is the german umlaut) - * - * -<pre>s1=3 -s2=MeineDisk -s3=3. M\<code></code>u00e4rz 96 -s4=Die Diskette ''{1}'' enth\<code></code>u00e4lt {0} in {2}. -s5=0 -s6=keine Dateien -s7=1 -s8=eine Datei -s9=2 -s10={0,number} Dateien -s11=Das Formatieren schlug fehl mit folgender Exception: {0} -s12=FEHLER -s13=Ergebnis -s14=Dialog -s15=Auswahlkriterium -s16=1,3</pre> - * - * <p>Although this is a sub class of a hash table, you should never - * insert anything other than strings to this property, or several - * methods, that need string keys and values, will fail. To ensure - * this, you should use the <code>get/setProperty</code> method instead - * of <code>get/put</code>. - * - * Properties are saved in ISO 8859-1 encoding, using Unicode escapes with - * a single <code>u</code> for any character which cannot be represented. - * - * @author Jochen Hoenicke - * @author Eric Blake (ebb9@email.byu.edu) - * @see PropertyResourceBundle - * @status updated to 1.4 - */ -public class Properties extends Hashtable -{ - // WARNING: Properties is a CORE class in the bootstrap cycle. See the - // comments in vm/reference/java/lang/Runtime for implications of this fact. - - /** - * The property list that contains default values for any keys not - * in this property list. - * - * @serial the default properties - */ - protected Properties defaults; - - /** - * Compatible with JDK 1.0+. - */ - private static final long serialVersionUID = 4112578634029874840L; - - /** - * Creates a new empty property list with no default values. - */ - public Properties() - { - } - - /** - * Create a new empty property list with the specified default values. - * - * @param defaults a Properties object containing the default values - */ - public Properties(Properties defaults) - { - this.defaults = defaults; - } - - /** - * Adds the given key/value pair to this properties. This calls - * the hashtable method put. - * - * @param key the key for this property - * @param value the value for this property - * @return The old value for the given key - * @see #getProperty(String) - * @since 1.2 - */ - public Object setProperty(String key, String value) - { - return put(key, value); - } - - /** - * Reads a property list from an input stream. The stream should - * have the following format: <br> - * - * An empty line or a line starting with <code>#</code> or - * <code>!</code> is ignored. An backslash (<code>\</code>) at the - * end of the line makes the line continueing on the next line - * (but make sure there is no whitespace after the backslash). - * Otherwise, each line describes a key/value pair. <br> - * - * The chars up to the first whitespace, = or : are the key. You - * can include this caracters in the key, if you precede them with - * a backslash (<code>\</code>). The key is followed by optional - * whitespaces, optionally one <code>=</code> or <code>:</code>, - * and optionally some more whitespaces. The rest of the line is - * the resource belonging to the key. <br> - * - * Escape sequences <code>\t, \n, \r, \\, \", \', \!, \#, \ </code>(a - * space), and unicode characters with the - * <code>\\u</code><em>xxxx</em> notation are detected, and - * converted to the corresponding single character. <br> - * - * -<pre># This is a comment -key = value -k\:5 \ a string starting with space and ending with newline\n -# This is a multiline specification; note that the value contains -# no white space. -weekdays: Sunday,Monday,Tuesday,Wednesday,\\ - Thursday,Friday,Saturday -# The safest way to include a space at the end of a value: -label = Name:\\u0020</pre> - * - * @param in the input stream - * @throws IOException if an error occurred when reading the input - * @throws NullPointerException if in is null - */ - public void load(InputStream inStream) throws IOException - { - // The spec says that the file must be encoded using ISO-8859-1. - BufferedReader reader = - new BufferedReader(new InputStreamReader(inStream, "ISO-8859-1")); - String line; - - while ((line = reader.readLine()) != null) - { - char c = 0; - int pos = 0; - // Leading whitespaces must be deleted first. - while (pos < line.length() - && Character.isWhitespace(c = line.charAt(pos))) - pos++; - - // If empty line or begins with a comment character, skip this line. - if ((line.length() - pos) == 0 - || line.charAt(pos) == '#' || line.charAt(pos) == '!') - continue; - - // The characters up to the next Whitespace, ':', or '=' - // describe the key. But look for escape sequences. - StringBuffer key = new StringBuffer(); - while (pos < line.length() - && ! Character.isWhitespace(c = line.charAt(pos++)) - && c != '=' && c != ':') - { - if (c == '\\') - { - if (pos == line.length()) - { - // The line continues on the next line. - line = reader.readLine(); - pos = 0; - while (pos < line.length() - && Character.isWhitespace(c = line.charAt(pos))) - pos++; - } - else - { - c = line.charAt(pos++); - switch (c) - { - case 'n': - key.append('\n'); - break; - case 't': - key.append('\t'); - break; - case 'r': - key.append('\r'); - break; - case 'u': - if (pos + 4 <= line.length()) - { - char uni = (char) Integer.parseInt - (line.substring(pos, pos + 4), 16); - key.append(uni); - pos += 4; - } // else throw exception? - break; - default: - key.append(c); - break; - } - } - } - else - key.append(c); - } - - boolean isDelim = (c == ':' || c == '='); - while (pos < line.length() - && Character.isWhitespace(c = line.charAt(pos))) - pos++; - - if (! isDelim && (c == ':' || c == '=')) - { - pos++; - while (pos < line.length() - && Character.isWhitespace(c = line.charAt(pos))) - pos++; - } - - StringBuffer element = new StringBuffer(line.length() - pos); - while (pos < line.length()) - { - c = line.charAt(pos++); - if (c == '\\') - { - if (pos == line.length()) - { - // The line continues on the next line. - line = reader.readLine(); - - // We might have seen a backslash at the end of - // the file. The JDK ignores the backslash in - // this case, so we follow for compatibility. - if (line == null) - break; - - pos = 0; - while (pos < line.length() - && Character.isWhitespace(c = line.charAt(pos))) - pos++; - element.ensureCapacity(line.length() - pos + - element.length()); - } - else - { - c = line.charAt(pos++); - switch (c) - { - case 'n': - element.append('\n'); - break; - case 't': - element.append('\t'); - break; - case 'r': - element.append('\r'); - break; - case 'u': - if (pos + 4 <= line.length()) - { - char uni = (char) Integer.parseInt - (line.substring(pos, pos + 4), 16); - element.append(uni); - pos += 4; - } // else throw exception? - break; - default: - element.append(c); - break; - } - } - } - else - element.append(c); - } - put(key.toString(), element.toString()); - } - } - - /** - * Calls <code>store(OutputStream out, String header)</code> and - * ignores the IOException that may be thrown. - * - * @param out the stream to write to - * @param header a description of the property list - * @throws ClassCastException if this property contains any key or - * value that are not strings - * @deprecated use {@link #store(OutputStream, String)} instead - */ - public void save(OutputStream out, String header) - { - try - { - store(out, header); - } - catch (IOException ex) - { - } - } - - /** - * Writes the key/value pairs to the given output stream, in a format - * suitable for <code>load</code>.<br> - * - * If header is not null, this method writes a comment containing - * the header as first line to the stream. The next line (or first - * line if header is null) contains a comment with the current date. - * Afterwards the key/value pairs are written to the stream in the - * following format.<br> - * - * Each line has the form <code>key = value</code>. Newlines, - * Returns and tabs are written as <code>\n,\t,\r</code> resp. - * The characters <code>\, !, #, =</code> and <code>:</code> are - * preceeded by a backslash. Spaces are preceded with a backslash, - * if and only if they are at the beginning of the key. Characters - * that are not in the ascii range 33 to 127 are written in the - * <code>\</code><code>u</code>xxxx Form.<br> - * - * Following the listing, the output stream is flushed but left open. - * - * @param out the output stream - * @param header the header written in the first line, may be null - * @throws ClassCastException if this property contains any key or - * value that isn't a string - * @throws IOException if writing to the stream fails - * @throws NullPointerException if out is null - * @since 1.2 - */ - public void store(OutputStream out, String header) throws IOException - { - // The spec says that the file must be encoded using ISO-8859-1. - PrintWriter writer - = new PrintWriter(new OutputStreamWriter(out, "ISO-8859-1")); - if (header != null) - writer.println("#" + header); - writer.println ("#" + Calendar.getInstance ().getTime ()); - - Iterator iter = entrySet ().iterator (); - int i = size (); - StringBuffer s = new StringBuffer (); // Reuse the same buffer. - while (--i >= 0) - { - Map.Entry entry = (Map.Entry) iter.next (); - formatForOutput ((String) entry.getKey (), s, true); - s.append ('='); - formatForOutput ((String) entry.getValue (), s, false); - writer.println (s); - } - - writer.flush (); - } - - /** - * Gets the property with the specified key in this property list. - * If the key is not found, the default property list is searched. - * If the property is not found in the default, null is returned. - * - * @param key The key for this property - * @return the value for the given key, or null if not found - * @throws ClassCastException if this property contains any key or - * value that isn't a string - * @see #defaults - * @see #setProperty(String, String) - * @see #getProperty(String, String) - */ - public String getProperty(String key) - { - return getProperty(key, null); - } - - /** - * Gets the property with the specified key in this property list. If - * the key is not found, the default property list is searched. If the - * property is not found in the default, the specified defaultValue is - * returned. - * - * @param key The key for this property - * @param defaultValue A default value - * @return The value for the given key - * @throws ClassCastException if this property contains any key or - * value that isn't a string - * @see #defaults - * @see #setProperty(String, String) - */ - public String getProperty(String key, String defaultValue) - { - Properties prop = this; - // Eliminate tail recursion. - do - { - String value = (String) prop.get(key); - if (value != null) - return value; - prop = prop.defaults; - } - while (prop != null); - return defaultValue; - } - - /** - * Returns an enumeration of all keys in this property list, including - * the keys in the default property list. - * - * @return an Enumeration of all defined keys - */ - public Enumeration propertyNames() - { - // We make a new Set that holds all the keys, then return an enumeration - // for that. This prevents modifications from ruining the enumeration, - // as well as ignoring duplicates. - Properties prop = this; - Set s = new HashSet(); - // Eliminate tail recursion. - do - { - s.addAll(prop.keySet()); - prop = prop.defaults; - } - while (prop != null); - return Collections.enumeration(s); - } - - /** - * Prints the key/value pairs to the given print stream. This is - * mainly useful for debugging purposes. - * - * @param out the print stream, where the key/value pairs are written to - * @throws ClassCastException if this property contains a key or a - * value that isn't a string - * @see #list(PrintWriter) - */ - public void list(PrintStream out) - { - PrintWriter writer = new PrintWriter (out); - list (writer); - } - - /** - * Prints the key/value pairs to the given print writer. This is - * mainly useful for debugging purposes. - * - * @param out the print writer where the key/value pairs are written to - * @throws ClassCastException if this property contains a key or a - * value that isn't a string - * @see #list(PrintStream) - * @since 1.1 - */ - public void list(PrintWriter out) - { - out.println ("-- listing properties --"); - - Iterator iter = entrySet ().iterator (); - int i = size (); - while (--i >= 0) - { - Map.Entry entry = (Map.Entry) iter.next (); - out.print ((String) entry.getKey () + "="); - - // JDK 1.3/1.4 restrict the printed value, but not the key, - // to 40 characters, including the truncating ellipsis. - String s = (String ) entry.getValue (); - if (s != null && s.length () > 40) - out.println (s.substring (0, 37) + "..."); - else - out.println (s); - } - out.flush (); - } - - /** - * Formats a key or value for output in a properties file. - * See store for a description of the format. - * - * @param str the string to format - * @param buffer the buffer to add it to - * @param key true if all ' ' must be escaped for the key, false if only - * leading spaces must be escaped for the value - * @see #store(OutputStream, String) - */ - private void formatForOutput(String str, StringBuffer buffer, boolean key) - { - if (key) - { - buffer.setLength(0); - buffer.ensureCapacity(str.length()); - } - else - buffer.ensureCapacity(buffer.length() + str.length()); - boolean head = true; - int size = str.length(); - for (int i = 0; i < size; i++) - { - char c = str.charAt(i); - switch (c) - { - case '\n': - buffer.append("\\n"); - break; - case '\r': - buffer.append("\\r"); - break; - case '\t': - buffer.append("\\t"); - break; - case ' ': - buffer.append(head ? "\\ " : " "); - break; - case '\\': - case '!': - case '#': - case '=': - case ':': - buffer.append('\\').append(c); - break; - default: - if (c < ' ' || c > '~') - { - String hex = Integer.toHexString(c); - buffer.append("\\u0000".substring(0, 6 - hex.length())); - buffer.append(hex); - } - else - buffer.append(c); - } - if (c != ' ') - head = key; - } - } -} // class Properties diff --git a/libjava/java/util/PropertyPermission.java b/libjava/java/util/PropertyPermission.java deleted file mode 100644 index d1bdbd1d058..00000000000 --- a/libjava/java/util/PropertyPermission.java +++ /dev/null @@ -1,271 +0,0 @@ -/* PropertyPermission.java -- permission to get and set System properties - Copyright (C) 1999, 2000, 2002, 2004, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.ObjectStreamField; -import java.security.BasicPermission; -import java.security.Permission; -import java.security.PermissionCollection; - -/** - * This class represents the permission to access and modify a property.<br> - * - * The name is the name of the property, e.g. xxx. You can also - * use an asterisk "*" as described in BasicPermission.<br> - * - * The action string is a comma-separated list of keywords. There are - * two possible actions: - * <dl> - * <dt>read</dt> - * <dd>Allows to read the property via <code>System.getProperty</code>.</dd> - * <dt>write</dt> - * <dd>Allows to write the property via <code>System.setProperty</code>.</dd> - * </dl> - * - * The action string is case insensitive (it is converted to lower case). - * - * @see Permission - * @see BasicPermission - * @see SecurityManager - * @author Jochen Hoenicke - * @since 1.2 - * @status updated to 1.4 - */ -public final class PropertyPermission extends BasicPermission -{ - /** - * PropertyPermission uses a more efficient representation than the - * serialized form; this documents the difference. - * - * @serialField action String the action string - */ - private static final ObjectStreamField[] serialPersistentFields = - { - new ObjectStreamField("action", String.class) - }; - - /** - * Compatible with JDK 1.2+. - */ - private static final long serialVersionUID = 885438825399942851L; - - /** Permission to read. */ - private static final int READ = 1; - /** Permission to write. */ - private static final int WRITE = 2; - - /** The set of actions permitted. */ - // Package visible for use by PropertyPermissionCollection. - transient int actions; - - /** - * The String forms of the actions permitted. - */ - private static final String actionStrings[] = - { - "", "read", "write", "read,write" - }; - - /** - * Constructs a PropertyPermission with the specified property. Possible - * actions are read and write, comma-separated and case-insensitive. - * - * @param name the name of the property - * @param actions the action string - * @throws NullPointerException if name is null - * @throws IllegalArgumentException if name string contains an - * illegal wildcard or actions string contains an illegal action - * (this includes a null actions string) - */ - public PropertyPermission(String name, String actions) - { - super(name); - if (actions == null) - throw new IllegalArgumentException(); - setActions(actions); - } - - /** - * Parse the action string and convert actions from external to internal - * form. This will set the internal actions field. - * - * @param str the action string - * @throws IllegalArgumentException if actions string contains an - * illegal action - */ - private void setActions(String str) - { - // Initialising the class java.util.Locale ... - // tries to initialise the Locale.defaultLocale static - // which calls System.getProperty, - // which calls SecurityManager.checkPropertiesAccess, - // which creates a PropertyPermission with action "read,write", - // which calls setActions("read,write"). - // If we now were to call toLowerCase on 'str', - // this would call Locale.getDefault() which returns null - // because Locale.defaultLocale hasn't been set yet - // then toLowerCase will fail with a null pointer exception. - // - // The solution is to take a punt on 'str' being lower case, and - // test accordingly. If that fails, we convert 'str' to lower case - // and try the tests again. - if ("read".equals(str)) - actions = READ; - else if ("write".equals(str)) - actions = WRITE; - else if ("read,write".equals(str) || "write,read".equals(str)) - actions = READ | WRITE; - else - { - String lstr = str.toLowerCase(); - if ("read".equals(lstr)) - actions = READ; - else if ("write".equals(lstr)) - actions = WRITE; - else if ("read,write".equals(lstr) || "write,read".equals(lstr)) - actions = READ | WRITE; - else - throw new IllegalArgumentException("illegal action " + str); - } - } - - /** - * Reads an object from the stream. This converts the external to the - * internal representation. - * - * @param s the stream to read from - * @throws IOException if the stream fails - * @throws ClassNotFoundException if reserialization fails - */ - private void readObject(ObjectInputStream s) - throws IOException, ClassNotFoundException - { - ObjectInputStream.GetField fields = s.readFields(); - setActions((String) fields.get("actions", null)); - } - - /** - * Writes an object to the stream. This converts the internal to the - * external representation. - * - * @param s the stram to write to - * @throws IOException if the stream fails - */ - private void writeObject(ObjectOutputStream s) throws IOException - { - ObjectOutputStream.PutField fields = s.putFields(); - fields.put("actions", getActions()); - s.writeFields(); - } - - /** - * Check if this permission implies p. This returns true iff all of - * the following conditions are true: - * <ul> - * <li> p is a PropertyPermission </li> - * <li> this.getName() implies p.getName(), - * e.g. <code>java.*</code> implies <code>java.home</code> </li> - * <li> this.getActions is a subset of p.getActions </li> - * </ul> - * - * @param p the permission to check - * @return true if this permission implies p - */ - public boolean implies(Permission p) - { - // BasicPermission checks for name and type. - if (super.implies(p)) - { - // We have to check the actions. - PropertyPermission pp = (PropertyPermission) p; - return (pp.actions & ~actions) == 0; - } - return false; - } - - /** - * Check to see whether this object is the same as another - * PropertyPermission object; this is true if it has the same name and - * actions. - * - * @param obj the other object - * @return true if the two are equivalent - */ - public boolean equals(Object obj) - { - return super.equals(obj) && actions == ((PropertyPermission) obj).actions; - } - - /** - * Returns the hash code for this permission. It is equivalent to - * <code>getName().hashCode()</code>. - * - * @return the hash code - */ - public int hashCode() - { - return super.hashCode(); - } - - /** - * Returns the action string. Note that this may differ from the string - * given at the constructor: The actions are converted to lowercase and - * may be reordered. - * - * @return one of "read", "write", or "read,write" - */ - public String getActions() - { - return actionStrings[actions]; - } - - /** - * Returns a permission collection suitable to take - * PropertyPermission objects. - * - * @return a new empty PermissionCollection - */ - public PermissionCollection newPermissionCollection() - { - return new PropertyPermissionCollection(); - } -} diff --git a/libjava/java/util/PropertyPermissionCollection.java b/libjava/java/util/PropertyPermissionCollection.java deleted file mode 100644 index c95fa4e66bf..00000000000 --- a/libjava/java/util/PropertyPermissionCollection.java +++ /dev/null @@ -1,166 +0,0 @@ -/* PropertyPermissionCollection.java -- a collection of PropertyPermissions - Copyright (C) 2002, 2004, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -import java.security.Permission; -import java.security.PermissionCollection; - -/** - * This class provides the implementation for - * <code>PropertyPermission.newPermissionCollection()</code>. It only accepts - * PropertyPermissions, and correctly implements <code>implies</code>. It - * is synchronized, as specified in the superclass. - * - * @author Eric Blake (ebb9@email.byu.edu) - * @status an undocumented class, but this matches Sun's serialization - */ -class PropertyPermissionCollection extends PermissionCollection -{ - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 7015263904581634791L; - - /** - * The permissions. - * - * @serial the table of permissions in the collection - */ - private final Hashtable permissions = new Hashtable(); - - /** - * A flag to detect if "*" is in the collection. - * - * @serial true if "*" is in the collection - */ - private boolean all_allowed; - - /** - * Adds a PropertyPermission to this collection. - * - * @param permission the permission to add - * @throws IllegalArgumentException if permission is not a PropertyPermission - * @throws SecurityException if collection is read-only - */ - public void add(Permission permission) - { - if (isReadOnly()) - throw new SecurityException("readonly"); - if (! (permission instanceof PropertyPermission)) - throw new IllegalArgumentException(); - PropertyPermission pp = (PropertyPermission) permission; - String name = pp.getName(); - if (name.equals("*")) - all_allowed = true; - PropertyPermission old = (PropertyPermission) permissions.get(name); - if (old != null) - { - if ((pp.actions | old.actions) == old.actions) - pp = old; // Old implies pp. - else if ((pp.actions | old.actions) != pp.actions) - // Here pp doesn't imply old; the only case left is both actions. - pp = new PropertyPermission(name, "read,write"); - } - permissions.put(name, pp); - } - - /** - * Returns true if this collection implies the given permission. This even - * returns true for this case: - * - * <pre> - * collection.add(new PropertyPermission("a.*", "read")); - * collection.add(new PropertyPermission("a.b.*", "write")); - * collection.implies(new PropertyPermission("a.b.c", "read,write")); - * </pre> - * - * @param permission the permission to check - * @return true if it is implied by this - */ - public boolean implies(Permission permission) - { - if (! (permission instanceof PropertyPermission)) - return false; - PropertyPermission toImply = (PropertyPermission) permission; - int actions = toImply.actions; - - if (all_allowed) - { - int all_actions = ((PropertyPermission) permissions.get("*")).actions; - actions &= ~all_actions; - if (actions == 0) - return true; - } - - String name = toImply.getName(); - if (name.equals("*")) - return false; - - int prefixLength = name.length(); - if (name.endsWith("*")) - prefixLength -= 2; - - while (true) - { - PropertyPermission forName = - (PropertyPermission) permissions.get(name); - if (forName != null) - { - actions &= ~forName.actions; - if (actions == 0) - return true; - } - - prefixLength = name.lastIndexOf('.', prefixLength - 1); - if (prefixLength < 0) - return false; - name = name.substring(0, prefixLength + 1) + '*'; - } - } - - /** - * Enumerate over the collection. - * - * @return an enumeration of the collection contents - */ - public Enumeration elements() - { - return permissions.elements(); - } -} diff --git a/libjava/java/util/PropertyResourceBundle.java b/libjava/java/util/PropertyResourceBundle.java deleted file mode 100644 index 86318654719..00000000000 --- a/libjava/java/util/PropertyResourceBundle.java +++ /dev/null @@ -1,152 +0,0 @@ -/* PropertyResourceBundle -- a resource bundle built from a Property file - Copyright (C) 1998, 1999, 2001, 2002 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -import java.io.IOException; -import java.io.InputStream; - -/** - * 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 will be chosen. 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> - * - * 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</code> is the - * german umlaut) - * - * -<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> - * - * @author Jochen Hoenicke - * @see ResourceBundle - * @see ListResourceBundle - * @see Properties#load() - * @since 1.1 - * @status updated to 1.4 - */ -public class PropertyResourceBundle extends ResourceBundle -{ - /** The properties file this bundle is based on. */ - private Properties properties; - - /** - * Creates a new property resource bundle. - * - * @param stream an input stream, where the resources are read from - * @throws NullPointerException if stream is null - * @throws IOException if reading the stream fails - */ - public PropertyResourceBundle(InputStream stream) throws 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 exist - */ - public 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(); - // We make a new Set that holds all the keys, then return an enumeration - // for that. This prevents modifications from ruining the enumeration, - // as well as ignoring duplicates. - Set s = new HashSet(); - Enumeration e = properties.propertyNames(); - while (e.hasMoreElements()) - s.add(e.nextElement()); - ResourceBundle bundle = parent; - // Eliminate tail recursion. - do - { - e = bundle.getKeys(); - while (e.hasMoreElements()) - s.add(e.nextElement()); - bundle = bundle.parent; - } - while (bundle != null); - return Collections.enumeration(s); - } -} // class PropertyResourceBundle diff --git a/libjava/java/util/Random.java b/libjava/java/util/Random.java deleted file mode 100644 index bc005075140..00000000000 --- a/libjava/java/util/Random.java +++ /dev/null @@ -1,429 +0,0 @@ -/* Random.java -- a pseudo-random number generator - Copyright (C) 1998, 1999, 2000, 2001, 2002 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -import java.io.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. It is a 48-bit seed, - * linear congruential formula. - * - * 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 - * @author Eric Blake (ebb9@email.byu.edu) - * @status updated to 1.4 - */ -public class Random implements Serializable -{ - /** - * 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. - * - * @serial whether nextNextGaussian is available - * @see #nextGaussian() - * @see #nextNextGaussian - */ - private boolean haveNextNextGaussian; - - /** - * The next nextGaussian, when available. This is used by nextGaussian, - * which generates two gaussian numbers by one call, and returns the - * second on the second call. - * - * @serial the second gaussian of a pair - * @see #nextGaussian() - * @see #haveNextNextGaussian - */ - private double nextNextGaussian; - - /** - * The seed. This is the number set by setSeed and which is used - * in next. - * - * @serial the internal state of this generator - * @see #next() - */ - private long seed; - - /** - * Compatible with JDK 1.0+. - */ - private static final long serialVersionUID = 3905348978240129619L; - - /** - * Creates a new pseudorandom number generator. The seed is initialized - * to the current time, as if by - * <code>setSeed(System.currentTimeMillis());</code>. - * - * @see System#currentTimeMillis() - */ - public Random() - { - this(System.currentTimeMillis()); - } - - /** - * Creates a new pseudorandom number generator, starting with the - * specified seed, using <code>setSeed(seed);</code>. - * - * @param seed the initial seed - */ - public Random(long seed) - { - setSeed(seed); - } - - /** - * 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> - * - * @param seed the new seed - */ - 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, in the range 1..32 - * @return the next pseudorandom value - * @since 1.1 - */ - protected synchronized int next(int bits) - { - 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 - * @throws NullPointerException if bytes is null - * @since 1.1 - */ - public void nextBytes(byte[] bytes) - { - 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(31); - val = bits % n; - } - while(bits - val + (n-1) < 0); - - return val; -}</pre> - * - * <p>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 - * @throws IllegalArgumentException if the given upper bound is negative - * @return the next pseudorandom value - * @since 1.2 - */ - 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(31); - 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 - * @since 1.2 - */ - public boolean nextBoolean() - { - return next(1) != 0; - } - - /** - * Generates the next pseudorandom float uniformly distributed - * between 0.0f (inclusive) and 1.0f (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.0 (inclusive) and 1.0 (exclusive). The - * implementation is as follows. - * -<pre>public double nextDouble() -{ - return (((long) next(26) << 27) + next(27)) / (double)(1L << 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> - * - * <p>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; - } - 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; - } -} diff --git a/libjava/java/util/RandomAccess.java b/libjava/java/util/RandomAccess.java deleted file mode 100644 index 054266a1c74..00000000000 --- a/libjava/java/util/RandomAccess.java +++ /dev/null @@ -1,64 +0,0 @@ -/* RandomAccess.java -- A tagging interface that lists can use to tailor - operations to the correct algorithm - Copyright (C) 2001, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -/** - * Marker interface used to inform <code>List</code> implementations that - * they support fast (usually constant time) random access. This allows - * generic list algorithms to tailor their behavior based on the list - * type. - * <p> - * - * For example, some sorts are n*log(n) on an array, but decay to quadratic - * time on a linked list. As a rule of thumb, this interface should be - * used is this loop:<br> - * <code>for (int i = 0, n = list.size(); i < n; i++) list.get(i);</code> - * <br>runs faster than this loop:<br> - * <code>for (Iterator i = list.iterator(); i.hasNext(); ) i.next();</code> - * - * @author Eric Blake (ebb9@email.byu.edu) - * @see List - * @since 1.4 - * @status updated to 1.4 - */ -public interface RandomAccess -{ - // Tagging interface only. -} diff --git a/libjava/java/util/Set.java b/libjava/java/util/Set.java deleted file mode 100644 index 839959e620c..00000000000 --- a/libjava/java/util/Set.java +++ /dev/null @@ -1,264 +0,0 @@ -/* Set.java -- A collection that prohibits duplicates - Copyright (C) 1998, 2001, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -/** - * A collection that contains no duplicates. In other words, for two set - * elements e1 and e2, <code>e1.equals(e2)</code> returns false. There - * are additional stipulations on <code>add</code>, <code>equals</code> - * and <code>hashCode</code>, as well as the requirements that constructors - * do not permit duplicate elements. The Set interface is incompatible with - * List; you cannot implement both simultaneously. - * <p> - * - * Note: Be careful about using mutable objects in sets. In particular, - * if a mutable object changes to become equal to another set element, you - * have violated the contract. As a special case of this, a Set is not - * allowed to be an element of itself, without risking undefined behavior. - * - * @author Original author unknown - * @author Eric Blake (ebb9@email.byu.edu) - * @see Collection - * @see List - * @see SortedSet - * @see HashSet - * @see TreeSet - * @see LinkedHashSet - * @see AbstractSet - * @see Collections#singleton(Object) - * @see Collections#EMPTY_SET - * @since 1.2 - * @status updated to 1.4 - */ -public interface Set extends Collection -{ - /** - * Adds the specified element to the set if it is not already present - * (optional operation). In particular, the comparison algorithm is - * <code>o == null ? e == null : o.equals(e)</code>. Sets need not permit - * all values, and may document what exceptions will be thrown if - * a value is not permitted. - * - * @param o the object to add - * @return true if the object was not previously in the set - * @throws UnsupportedOperationException if this operation is not allowed - * @throws ClassCastException if the class of o prevents it from being added - * @throws IllegalArgumentException if some aspect of o prevents it from - * being added - * @throws NullPointerException if null is not permitted in this set - */ - boolean add(Object o); - - /** - * Adds all of the elements of the given collection to this set (optional - * operation). If the argument is also a Set, this returns the mathematical - * <i>union</i> of the two. The behavior is unspecified if the set is - * modified while this is taking place. - * - * @param c the collection to add - * @return true if the set changed as a result - * @throws UnsupportedOperationException if this operation is not allowed - * @throws ClassCastException if the class of an element prevents it from - * being added - * @throws IllegalArgumentException if something about an element prevents - * it from being added - * @throws NullPointerException if null is not permitted in this set, or - * if the argument c is null - * @see #add(Object) - */ - boolean addAll(Collection c); - - /** - * Removes all elements from this set (optional operation). This set will - * be empty afterwords, unless an exception occurs. - * - * @throws UnsupportedOperationException if this operation is not allowed - */ - void clear(); - - /** - * Returns true if the set contains the specified element. In other words, - * this looks for <code>o == null ? e == null : o.equals(e)</code>. - * - * @param o the object to look for - * @return true if it is found in the set - * @throws ClassCastException if the type of o is not a valid type - * for this set. - * @throws NullPointerException if o is null and this set doesn't - * support null values. - */ - boolean contains(Object o); - - /** - * Returns true if this set contains all elements in the specified - * collection. If the argument is also a set, this is the <i>subset</i> - * relationship. - * - * @param c the collection to check membership in - * @return true if all elements in this set are in c - * @throws NullPointerException if c is null - * @throws ClassCastException if the type of any element in c is not - * a valid type for this set. - * @throws NullPointerException if some element of c is null and this - * set doesn't support null values. - * @see #contains(Object) - */ - boolean containsAll(Collection c); - - /** - * Compares the specified object to this for equality. For sets, the object - * must be a set, the two must have the same size, and every element in - * one must be in the other. - * - * @param o the object to compare to - * @return true if it is an equal set - */ - boolean equals(Object o); - - /** - * Returns the hash code for this set. In order to satisfy the contract of - * equals, this is the sum of the hashcode of all elements in the set. - * - * @return the sum of the hashcodes of all set elements - * @see #equals(Object) - */ - int hashCode(); - - /** - * Returns true if the set contains no elements. - * - * @return true if the set is empty - */ - boolean isEmpty(); - - /** - * Returns an iterator over the set. The iterator has no specific order, - * unless further specified. - * - * @return a set iterator - */ - Iterator iterator(); - - /** - * Removes the specified element from this set (optional operation). If - * an element e exists, <code>o == null ? e == null : o.equals(e)</code>, - * it is removed from the set. - * - * @param o the object to remove - * @return true if the set changed (an object was removed) - * @throws UnsupportedOperationException if this operation is not allowed - * @throws ClassCastException if the type of o is not a valid type - * for this set. - * @throws NullPointerException if o is null and this set doesn't allow - * the removal of a null value. - */ - boolean remove(Object o); - - /** - * Removes from this set all elements contained in the specified collection - * (optional operation). If the argument is a set, this returns the - * <i>asymmetric set difference</i> of the two sets. - * - * @param c the collection to remove from this set - * @return true if this set changed as a result - * @throws UnsupportedOperationException if this operation is not allowed - * @throws NullPointerException if c is null - * @throws ClassCastException if the type of any element in c is not - * a valid type for this set. - * @throws NullPointerException if some element of c is null and this - * set doesn't support removing null values. - * @see #remove(Object) - */ - boolean removeAll(Collection c); - - /** - * Retains only the elements in this set that are also in the specified - * collection (optional operation). If the argument is also a set, this - * performs the <i>intersection</i> of the two sets. - * - * @param c the collection to keep - * @return true if this set was modified - * @throws UnsupportedOperationException if this operation is not allowed - * @throws NullPointerException if c is null - * @throws ClassCastException if the type of any element in c is not - * a valid type for this set. - * @throws NullPointerException if some element of c is null and this - * set doesn't support retaining null values. - * @see #remove(Object) - */ - boolean retainAll(Collection c); - - /** - * Returns the number of elements in the set. If there are more - * than Integer.MAX_VALUE mappings, return Integer.MAX_VALUE. This is - * the <i>cardinality</i> of the set. - * - * @return the number of elements - */ - int size(); - - /** - * Returns an array containing the elements of this set. If the set - * makes a guarantee about iteration order, the array has the same - * order. The array is distinct from the set; modifying one does not - * affect the other. - * - * @return an array of this set's elements - * @see #toArray(Object[]) - */ - Object[] toArray(); - - /** - * Returns an array containing the elements of this set, of the same runtime - * type of the argument. If the given set is large enough, it is reused, - * and null is inserted in the first unused slot. Otherwise, reflection - * is used to build a new array. If the set makes a guarantee about iteration - * order, the array has the same order. The array is distinct from the set; - * modifying one does not affect the other. - * - * @param a the array to determine the return type; if it is big enough - * it is used and returned - * @return an array holding the elements of the set - * @throws ArrayStoreException if the runtime type of a is not a supertype - * of all elements in the set - * @throws NullPointerException if a is null - * @see #toArray() - */ - Object[] toArray(Object[] a); -} diff --git a/libjava/java/util/SortedMap.java b/libjava/java/util/SortedMap.java deleted file mode 100644 index acfbd0d3639..00000000000 --- a/libjava/java/util/SortedMap.java +++ /dev/null @@ -1,173 +0,0 @@ -/* SortedMap.java -- A map that makes guarantees about the order of its keys - Copyright (C) 1998, 2001, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -/** - * A map which guarantees its key's iteration order. The entries in the - * map are related by the <i>natural ordering</i> of the keys if they - * are Comparable, or by the provided Comparator. Additional operations - * take advantage of the sorted nature of the map. - * <p> - * - * All keys entered in the map must be mutually comparable; in other words, - * <code>k1.compareTo(k2)</code> or <code>comparator.compare(k1, k2)</code> - * must not throw a ClassCastException. The ordering must be <i>consistent - * with equals</i> (see {@link Comparator} for this definition), if the - * map is to obey the general contract of the Map interface. If not, - * the results are well-defined, but probably not what you wanted. - * <p> - * - * It is recommended that all implementing classes provide four constructors: - * 1) one that takes no arguments and builds an empty map sorted by natural - * order of the keys; 2) one that takes a Comparator for the sorting order; - * 3) one that takes a Map and sorts according to the natural order of its - * keys; and 4) one that takes a SortedMap and sorts by the same comparator. - * Unfortunately, the Java language does not provide a way to enforce this. - * - * @author Original author unknown - * @author Eric Blake (ebb9@email.byu.edu) - * @see Map - * @see TreeMap - * @see SortedSet - * @see Comparable - * @see Comparator - * @see Collection - * @see ClassCastException - * @since 1.2 - * @status updated to 1.4 - */ -public interface SortedMap extends Map -{ - /** - * Returns the comparator used in sorting this map, or null if it is - * the keys' natural ordering. - * - * @return the sorting comparator - */ - Comparator comparator(); - - /** - * Returns the first (lowest sorted) key in the map. - * - * @return the first key - * @throws NoSuchElementException if this map is empty. - */ - Object firstKey(); - - /** - * Returns a view of the portion of the map strictly less than toKey. The - * view is backed by this map, so changes in one show up in the other. - * The submap supports all optional operations of the original. - * <p> - * - * The returned map throws an IllegalArgumentException any time a key is - * used which is out of the range of toKey. Note that the endpoint, toKey, - * is not included; if you want this value to be included, pass its successor - * object in to toKey. For example, for Integers, you could request - * <code>headMap(new Integer(limit.intValue() + 1))</code>. - * - * @param toKey the exclusive upper range of the submap - * @return the submap - * @throws ClassCastException if toKey is not comparable to the map contents - * @throws IllegalArgumentException if this is a subMap, and toKey is out - * of range - * @throws NullPointerException if toKey is null but the map does not allow - * null keys - */ - SortedMap headMap(Object toKey); - - /** - * Returns the last (highest sorted) key in the map. - * - * @return the last key - * @throws NoSuchElementException if this map is empty. - */ - Object lastKey(); - - /** - * Returns a view of the portion of the map greater than or equal to - * fromKey, and strictly less than toKey. The view is backed by this map, - * so changes in one show up in the other. The submap supports all - * optional operations of the original. - * <p> - * - * The returned map throws an IllegalArgumentException any time a key is - * used which is out of the range of fromKey and toKey. Note that the - * lower endpoint is included, but the upper is not; if you want to - * change the inclusion or exclusion of an endpoint, pass its successor - * object in instead. For example, for Integers, you could request - * <code>subMap(new Integer(lowlimit.intValue() + 1), - * new Integer(highlimit.intValue() + 1))</code> to reverse - * the inclusiveness of both endpoints. - * - * @param fromKey the inclusive lower range of the submap - * @param toKey the exclusive upper range of the submap - * @return the submap - * @throws ClassCastException if fromKey or toKey is not comparable to - * the map contents - * @throws IllegalArgumentException if this is a subMap, and fromKey or - * toKey is out of range - * @throws NullPointerException if fromKey or toKey is null but the map - * does not allow null keys - */ - SortedMap subMap(Object fromKey, Object toKey); - - /** - * Returns a view of the portion of the map greater than or equal to - * fromKey. The view is backed by this map, so changes in one show up - * in the other. The submap supports all optional operations of the original. - * <p> - * - * The returned map throws an IllegalArgumentException any time a key is - * used which is out of the range of fromKey. Note that the endpoint, fromKey, is - * included; if you do not want this value to be included, pass its successor object in - * to fromKey. For example, for Integers, you could request - * <code>tailMap(new Integer(limit.intValue() + 1))</code>. - * - * @param fromKey the inclusive lower range of the submap - * @return the submap - * @throws ClassCastException if fromKey is not comparable to the map - * contents - * @throws IllegalArgumentException if this is a subMap, and fromKey is out - * of range - * @throws NullPointerException if fromKey is null but the map does not allow - * null keys - */ - SortedMap tailMap(Object fromKey); -} diff --git a/libjava/java/util/SortedSet.java b/libjava/java/util/SortedSet.java deleted file mode 100644 index 48a24a8e0f9..00000000000 --- a/libjava/java/util/SortedSet.java +++ /dev/null @@ -1,176 +0,0 @@ -/* SortedSet.java -- A set that makes guarantees about the order of its - elements - Copyright (C) 1998, 2001, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -/** - * A set which guarantees its iteration order. The elements in the set - * are related by the <i>natural ordering</i> if they are Comparable, or - * by the provided Comparator. Additional operations take advantage of - * the sorted nature of the set. - * <p> - * - * All elements entered in the set must be mutually comparable; in other words, - * <code>k1.compareTo(k2)</code> or <code>comparator.compare(k1, k2)</code> - * must not throw a ClassCastException. The ordering must be <i>consistent - * with equals</i> (see {@link Comparator} for this definition), if the - * set is to obey the general contract of the Set interface. If not, - * the results are well-defined, but probably not what you wanted. - * <p> - * - * It is recommended that all implementing classes provide four constructors: - * 1) one that takes no arguments and builds an empty set sorted by natural - * order of the elements; 2) one that takes a Comparator for the sorting order; - * 3) one that takes a Set and sorts according to the natural order of its - * elements; and 4) one that takes a SortedSet and sorts by the same - * comparator. Unfortunately, the Java language does not provide a way to - * enforce this. - * - * @author Original author unknown - * @author Eric Blake (ebb9@email.byu.edu) - * @see Set - * @see TreeSet - * @see SortedMap - * @see Collection - * @see Comparable - * @see Comparator - * @see ClassCastException - * @since 1.2 - * @status updated to 1.4 - */ -public interface SortedSet extends Set -{ - /** - * Returns the comparator used in sorting this set, or null if it is - * the elements' natural ordering. - * - * @return the sorting comparator - */ - Comparator comparator(); - - /** - * Returns the first (lowest sorted) element in the set. - * - * @return the first element - * @throws NoSuchElementException if the set is empty. - */ - Object first(); - - /** - * Returns a view of the portion of the set strictly less than toElement. The - * view is backed by this set, so changes in one show up in the other. - * The subset supports all optional operations of the original. - * <p> - * - * The returned set throws an IllegalArgumentException any time an element is - * used which is out of the range of toElement. Note that the endpoint, toElement, - * is not included; if you want this value included, pass its successor object in to - * toElement. For example, for Integers, you could request - * <code>headSet(new Integer(limit.intValue() + 1))</code>. - * - * @param toElement the exclusive upper range of the subset - * @return the subset - * @throws ClassCastException if toElement is not comparable to the set - * contents - * @throws IllegalArgumentException if this is a subSet, and toElement is out - * of range - * @throws NullPointerException if toElement is null but the set does not - * allow null elements - */ - SortedSet headSet(Object toElement); - - /** - * Returns the last (highest sorted) element in the set. - * - * @return the last element - * @throws NoSuchElementException if the set is empty. - */ - Object last(); - - /** - * Returns a view of the portion of the set greater than or equal to - * fromElement, and strictly less than toElement. The view is backed by - * this set, so changes in one show up in the other. The subset supports all - * optional operations of the original. - * <p> - * - * The returned set throws an IllegalArgumentException any time an element is - * used which is out of the range of fromElement and toElement. Note that the - * lower endpoint is included, but the upper is not; if you want to - * change the inclusion or exclusion of an endpoint, pass its successor - * object in instead. For example, for Integers, you can request - * <code>subSet(new Integer(lowlimit.intValue() + 1), - * new Integer(highlimit.intValue() + 1))</code> to reverse - * the inclusiveness of both endpoints. - * - * @param fromElement the inclusive lower range of the subset - * @param toElement the exclusive upper range of the subset - * @return the subset - * @throws ClassCastException if fromElement or toElement is not comparable - * to the set contents - * @throws IllegalArgumentException if this is a subSet, and fromElement or - * toElement is out of range - * @throws NullPointerException if fromElement or toElement is null but the - * set does not allow null elements - */ - SortedSet subSet(Object fromElement, Object toElement); - - /** - * Returns a view of the portion of the set greater than or equal to - * fromElement. The view is backed by this set, so changes in one show up - * in the other. The subset supports all optional operations of the original. - * <p> - * - * The returned set throws an IllegalArgumentException any time an element is - * used which is out of the range of fromElement. Note that the endpoint, - * fromElement, is included; if you do not want this value to be included, pass its - * successor object in to fromElement. For example, for Integers, you could request - * <code>tailSet(new Integer(limit.intValue() + 1))</code>. - * - * @param fromElement the inclusive lower range of the subset - * @return the subset - * @throws ClassCastException if fromElement is not comparable to the set - * contents - * @throws IllegalArgumentException if this is a subSet, and fromElement is - * out of range - * @throws NullPointerException if fromElement is null but the set does not - * allow null elements - */ - SortedSet tailSet(Object fromElement); -} diff --git a/libjava/java/util/Stack.java b/libjava/java/util/Stack.java deleted file mode 100644 index 730ce177cd1..00000000000 --- a/libjava/java/util/Stack.java +++ /dev/null @@ -1,158 +0,0 @@ -/* Stack.java - Class that provides a Last In First Out (LIFO) - datatype, known more commonly as a Stack - Copyright (C) 1998, 1999, 2001, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -/* 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 - -/** - * Stack provides a Last In First Out (LIFO) data type, commonly known - * as a Stack. Stack itself extends Vector and provides the additional - * methods for stack manipulation (push, pop, peek). You can also seek for - * the 1-based position of an element on the stack. - * - * @author Warren Levy (warrenl@cygnus.com) - * @author Eric Blake (ebb9@email.byu.edu) - * @see List - * @see AbstractList - * @see LinkedList - * @since 1.0 - * @status updated to 1.4 - */ -public class Stack extends Vector -{ - // We could use Vector methods internally for the following methods, - // but have used Vector fields directly for efficiency (i.e. this - // often reduces out duplicate bounds checking). - - /** - * Compatible with JDK 1.0+. - */ - private static final long serialVersionUID = 1224463164541339165L; - - /** - * This constructor creates a new Stack, initially empty - */ - public Stack() - { - } - - /** - * Pushes an Object onto the top of the stack. This method is effectively - * the same as addElement(item). - * - * @param item the Object to push onto the stack - * @return the Object pushed onto the stack - * @see Vector#addElement(Object) - */ - public Object push(Object item) - { - // When growing the Stack, use the Vector routines in case more - // memory is needed. - // Note: spec indicates that this method *always* returns obj passed in! - - addElement(item); - return item; - } - - /** - * Pops an item from the stack and returns it. The item popped is - * removed from the Stack. - * - * @return the Object popped from the stack - * @throws EmptyStackException if the stack is empty - */ - public synchronized Object pop() - { - if (elementCount == 0) - throw new EmptyStackException(); - - modCount++; - Object obj = elementData[--elementCount]; - - // Set topmost element to null to assist the gc in cleanup. - elementData[elementCount] = null; - return obj; - } - - /** - * Returns the top Object on the stack without removing it. - * - * @return the top Object on the stack - * @throws EmptyStackException if the stack is empty - */ - public synchronized Object peek() - { - if (elementCount == 0) - throw new EmptyStackException(); - - return elementData[elementCount - 1]; - } - - /** - * Tests if the stack is empty. - * - * @return true if the stack contains no items, false otherwise - */ - public synchronized boolean empty() - { - return elementCount == 0; - } - - /** - * Returns the position of an Object on the stack, with the top - * most Object being at position 1, and each Object deeper in the - * stack at depth + 1. - * - * @param o The object to search for - * @return The 1 based depth of the Object, or -1 if the Object - * is not on the stack - */ - public synchronized int search(Object o) - { - int i = elementCount; - while (--i >= 0) - if (equals(o, elementData[i])) - return elementCount - i; - return -1; - } -} diff --git a/libjava/java/util/StringTokenizer.java b/libjava/java/util/StringTokenizer.java deleted file mode 100644 index dcc192c855a..00000000000 --- a/libjava/java/util/StringTokenizer.java +++ /dev/null @@ -1,268 +0,0 @@ -/* StringTokenizer -- breaks a String into tokens - Copyright (C) 1998, 1999, 2001, 2002, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -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. This is much simpler than {@link java.io.StreamTokenizer}. - * - * <p>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 candidates for being returned. - * - * <p>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) - * @see java.io.StreamTokenizer - * @status updated to 1.4 - */ -public class StringTokenizer implements Enumeration -{ - // WARNING: StringTokenizer is a CORE class in the bootstrap cycle. See the - // comments in vm/reference/java/lang/Runtime for implications of this fact. - - /** - * The position in the str, where we currently are. - */ - private int pos; - - /** - * The string that should be split into tokens. - */ - private final String str; - - /** - * The length of the string. - */ - private final int len; - - /** - * The string containing the delimiter characters. - */ - private String delim; - - /** - * Tells, if we should return the delimiters. - */ - private final boolean retDelims; - - /** - * Creates a new StringTokenizer for the string <code>str</code>, - * that should split on the default delimiter set (space, tab, - * newline, return and formfeed), and which doesn't return the - * delimiters. - * - * @param str The string to split - * @throws NullPointerException if str is null - */ - public StringTokenizer(String str) - { - this(str, " \t\n\r\f", false); - } - - /** - * 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 - * @throws NullPointerException if either argument is null - */ - public StringTokenizer(String str, String delim) - { - this(str, delim, false); - } - - /** - * 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 - * @throws NullPointerException if str or delim is null - */ - public StringTokenizer(String str, String delim, boolean returnDelims) - { - len = str.length(); - this.str = str; - // The toString() hack causes the NullPointerException. - this.delim = delim.toString(); - this.retDelims = returnDelims; - this.pos = 0; - } - - /** - * Tells if there are more tokens. - * - * @return true if the next call of nextToken() will succeed - */ - public boolean hasMoreTokens() - { - if (! retDelims) - { - while (pos < len && delim.indexOf(str.charAt(pos)) >= 0) - pos++; - } - return pos < len; - } - - /** - * 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 - * @throws NoSuchElementException if there are no more tokens - * @throws NullPointerException if delim is null - */ - public String nextToken(String delim) throws NoSuchElementException - { - this.delim = delim; - return nextToken(); - } - - /** - * Returns the nextToken of the string. - * - * @return the next token with respect to the current delimiter characters - * @throws NoSuchElementException if there are no more tokens - */ - public String nextToken() throws NoSuchElementException - { - if (pos < len && delim.indexOf(str.charAt(pos)) >= 0) - { - if (retDelims) - return str.substring(pos, ++pos); - while (++pos < len && delim.indexOf(str.charAt(pos)) >= 0); - } - if (pos < len) - { - int start = pos; - while (++pos < len && delim.indexOf(str.charAt(pos)) < 0); - - 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() will succeed - * @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 current delimiter characters - * @throws 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 tmpPos = pos; - - // Note for efficiency, we count up the delimiters rather than check - // retDelims every time we encounter one. That way, we can - // just do the conditional once at the end of the method - while (tmpPos < len) - { - if (delim.indexOf(str.charAt(tmpPos++)) >= 0) - { - if (tokenFound) - { - // Got to the end of a token - count++; - tokenFound = false; - } - delimiterCount++; // Increment for this delimiter - } - else - { - tokenFound = true; - // Get to the end of the token - while (tmpPos < len - && delim.indexOf(str.charAt(tmpPos)) < 0) - ++tmpPos; - } - } - - // Make sure to count the last token - if (tokenFound) - count++; - - // if counting delmiters add them into the token count - return retDelims ? count + delimiterCount : count; - } -} // class StringTokenizer diff --git a/libjava/java/util/TimeZone.java b/libjava/java/util/TimeZone.java deleted file mode 100644 index 6850043f2b4..00000000000 --- a/libjava/java/util/TimeZone.java +++ /dev/null @@ -1,1331 +0,0 @@ -/* java.util.TimeZone - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 - 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.text.DateFormatSymbols; - -/** - * This class represents a time zone offset and handles daylight savings. - * - * You can get the default time zone with <code>getDefault</code>. - * This represents the time zone where program is running. - * - * Another way to create a time zone is <code>getTimeZone</code>, where - * you can give an identifier as parameter. For instance, the identifier - * of the Central European Time zone is "CET". - * - * With the <code>getAvailableIDs</code> method, you can get all the - * supported time zone identifiers. - * - * @see Calendar - * @see SimpleTimeZone - * @author Jochen Hoenicke - */ -public abstract class TimeZone implements java.io.Serializable, Cloneable -{ - - /** - * Constant used to indicate that a short timezone abbreviation should - * be returned, such as "EST" - */ - public static final int SHORT = 0; - - /** - * Constant used to indicate that a long timezone name should be - * returned, such as "Eastern Standard Time". - */ - public static final int LONG = 1; - - /** - * The time zone identifier, e.g. PST. - */ - private String ID; - - /** - * The default time zone, as returned by getDefault. - */ - private static TimeZone defaultZone0; - - /** - * Tries to get the default TimeZone for this system if not already - * set. It will call <code>getDefaultTimeZone(String)</code> with - * the result of <code>System.getProperty("user.timezone")</code>. - * If that fails it calls <code>VMTimeZone.getDefaultTimeZoneId()</code>. - * If that also fails GMT is returned. - */ - private static synchronized TimeZone defaultZone() - { - /* Look up default timezone */ - if (defaultZone0 == null) - { - defaultZone0 = (TimeZone) AccessController.doPrivileged - (new PrivilegedAction() - { - public Object run() - { - TimeZone zone = null; - - // Prefer System property user.timezone. - String tzid = System.getProperty("user.timezone"); - if (tzid != null && !tzid.equals("")) - zone = getDefaultTimeZone(tzid); - - // Try platfom specific way. - if (zone == null) - zone = VMTimeZone.getDefaultTimeZoneId(); - - // Fall back on GMT. - if (zone == null) - zone = (TimeZone) timezones().get("GMT"); - - return zone; - } - }); - } - - return defaultZone0; - } - - private static final long serialVersionUID = 3581463369166924961L; - - /** - * HashMap for timezones by ID. - */ - private static HashMap timezones0; - /* initialize this static field lazily to overhead if - * it is not needed: - */ - // Package-private to avoid a trampoline. - static synchronized HashMap timezones() - { - if (timezones0 == null) - { - HashMap timezones = new HashMap(); - timezones0 = timezones; - - TimeZone tz; - // Automatically generated by scripts/timezones.pl - // XXX - Should we read this data from a file? - tz = new SimpleTimeZone(-11000 * 3600, "MIT"); - timezones0.put("MIT", tz); - timezones0.put("Pacific/Apia", tz); - timezones0.put("Pacific/Midway", tz); - timezones0.put("Pacific/Niue", tz); - timezones0.put("Pacific/Pago_Pago", tz); - tz = new SimpleTimeZone - (-10000 * 3600, "America/Adak", - Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("America/Adak", tz); - tz = new SimpleTimeZone(-10000 * 3600, "HST"); - timezones0.put("HST", tz); - timezones0.put("Pacific/Fakaofo", tz); - timezones0.put("Pacific/Honolulu", tz); - timezones0.put("Pacific/Johnston", tz); - timezones0.put("Pacific/Rarotonga", tz); - timezones0.put("Pacific/Tahiti", tz); - tz = new SimpleTimeZone(-9500 * 3600, "Pacific/Marquesas"); - timezones0.put("Pacific/Marquesas", tz); - tz = new SimpleTimeZone - (-9000 * 3600, "AST", - Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("AST", tz); - timezones0.put("America/Anchorage", tz); - timezones0.put("America/Juneau", tz); - timezones0.put("America/Nome", tz); - timezones0.put("America/Yakutat", tz); - tz = new SimpleTimeZone(-9000 * 3600, "Pacific/Gambier"); - timezones0.put("Pacific/Gambier", tz); - tz = new SimpleTimeZone - (-8000 * 3600, "PST", - Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("PST", tz); - timezones0.put("PST8PDT", tz); - timezones0.put("America/Dawson", tz); - timezones0.put("America/Los_Angeles", tz); - timezones0.put("America/Tijuana", tz); - timezones0.put("America/Vancouver", tz); - timezones0.put("America/Whitehorse", tz); - timezones0.put("US/Pacific-New", tz); - tz = new SimpleTimeZone(-8000 * 3600, "Pacific/Pitcairn"); - timezones0.put("Pacific/Pitcairn", tz); - tz = new SimpleTimeZone - (-7000 * 3600, "MST", - Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("MST", tz); - timezones0.put("MST7MDT", tz); - timezones0.put("America/Boise", tz); - timezones0.put("America/Chihuahua", tz); - timezones0.put("America/Denver", tz); - timezones0.put("America/Edmonton", tz); - timezones0.put("America/Inuvik", tz); - timezones0.put("America/Mazatlan", tz); - timezones0.put("America/Shiprock", tz); - timezones0.put("America/Yellowknife", tz); - tz = new SimpleTimeZone(-7000 * 3600, "MST7"); - timezones0.put("MST7", tz); - timezones0.put("PNT", tz); - timezones0.put("America/Dawson_Creek", tz); - timezones0.put("America/Hermosillo", tz); - timezones0.put("America/Phoenix", tz); - tz = new SimpleTimeZone - (-6000 * 3600, "CST", - Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("CST", tz); - timezones0.put("CST6CDT", tz); - timezones0.put("America/Cambridge_Bay", tz); - timezones0.put("America/Cancun", tz); - timezones0.put("America/Chicago", tz); - timezones0.put("America/Menominee", tz); - timezones0.put("America/Merida", tz); - timezones0.put("America/Mexico_City", tz); - timezones0.put("America/Monterrey", tz); - timezones0.put("America/Rainy_River", tz); - timezones0.put("America/Winnipeg", tz); - tz = new SimpleTimeZone(-6000 * 3600, "America/Belize"); - timezones0.put("America/Belize", tz); - timezones0.put("America/Costa_Rica", tz); - timezones0.put("America/El_Salvador", tz); - timezones0.put("America/Guatemala", tz); - timezones0.put("America/Managua", tz); - timezones0.put("America/Regina", tz); - timezones0.put("America/Swift_Current", tz); - timezones0.put("America/Tegucigalpa", tz); - timezones0.put("Pacific/Galapagos", tz); - tz = new SimpleTimeZone - (-6000 * 3600, "Pacific/Easter", - Calendar.OCTOBER, 9, -Calendar.SUNDAY, 0 * 3600, - Calendar.MARCH, 9, -Calendar.SUNDAY, 0 * 3600); - timezones0.put("Pacific/Easter", tz); - tz = new SimpleTimeZone - (-5000 * 3600, "America/Grand_Turk", - Calendar.APRIL, 1, Calendar.SUNDAY, 0 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600); - timezones0.put("America/Grand_Turk", tz); - timezones0.put("America/Havana", tz); - tz = new SimpleTimeZone(-5000 * 3600, "EST5"); - timezones0.put("EST5", tz); - timezones0.put("IET", tz); - timezones0.put("America/Bogota", tz); - timezones0.put("America/Cayman", tz); - timezones0.put("America/Eirunepe", tz); - timezones0.put("America/Guayaquil", tz); - timezones0.put("America/Indiana/Indianapolis", tz); - timezones0.put("America/Indiana/Knox", tz); - timezones0.put("America/Indiana/Marengo", tz); - timezones0.put("America/Indiana/Vevay", tz); - timezones0.put("America/Indianapolis", tz); - timezones0.put("America/Iqaluit", tz); - timezones0.put("America/Jamaica", tz); - timezones0.put("America/Lima", tz); - timezones0.put("America/Panama", tz); - timezones0.put("America/Pangnirtung", tz); - timezones0.put("America/Port-au-Prince", tz); - timezones0.put("America/Porto_Acre", tz); - timezones0.put("America/Rankin_Inlet", tz); - tz = new SimpleTimeZone - (-5000 * 3600, "EST", - Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("EST", tz); - timezones0.put("EST5EDT", tz); - timezones0.put("America/Detroit", tz); - timezones0.put("America/Kentucky/Louisville", tz); - timezones0.put("America/Kentucky/Monticello", tz); - timezones0.put("America/Louisville", tz); - timezones0.put("America/Montreal", tz); - timezones0.put("America/Nassau", tz); - timezones0.put("America/New_York", tz); - timezones0.put("America/Nipigon", tz); - timezones0.put("America/Thunder_Bay", tz); - tz = new SimpleTimeZone(-4000 * 3600, "PRT"); - timezones0.put("PRT", tz); - timezones0.put("America/Anguilla", tz); - timezones0.put("America/Antigua", tz); - timezones0.put("America/Aruba", tz); - timezones0.put("America/Barbados", tz); - timezones0.put("America/Boa_Vista", tz); - timezones0.put("America/Caracas", tz); - timezones0.put("America/Curacao", tz); - timezones0.put("America/Dominica", tz); - timezones0.put("America/Grenada", tz); - timezones0.put("America/Guadeloupe", tz); - timezones0.put("America/Guyana", tz); - timezones0.put("America/La_Paz", tz); - timezones0.put("America/Manaus", tz); - timezones0.put("America/Martinique", tz); - timezones0.put("America/Montserrat", tz); - timezones0.put("America/Port_of_Spain", tz); - timezones0.put("America/Porto_Velho", tz); - timezones0.put("America/Puerto_Rico", tz); - timezones0.put("America/Santo_Domingo", tz); - timezones0.put("America/St_Kitts", tz); - timezones0.put("America/St_Lucia", tz); - timezones0.put("America/St_Thomas", tz); - timezones0.put("America/St_Vincent", tz); - timezones0.put("America/Tortola", tz); - tz = new SimpleTimeZone - (-4000 * 3600, "America/Asuncion", - Calendar.OCTOBER, 1, Calendar.SUNDAY, 0 * 3600, - Calendar.FEBRUARY, -1, Calendar.SUNDAY, 0 * 3600); - timezones0.put("America/Asuncion", tz); - tz = new SimpleTimeZone - (-4000 * 3600, "America/Cuiaba", - Calendar.OCTOBER, 2, Calendar.SUNDAY, 0 * 3600, - Calendar.FEBRUARY, 3, Calendar.SUNDAY, 0 * 3600); - timezones0.put("America/Cuiaba", tz); - tz = new SimpleTimeZone - (-4000 * 3600, "America/Goose_Bay", - Calendar.APRIL, 1, Calendar.SUNDAY, 60000, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 60000); - timezones0.put("America/Goose_Bay", tz); - tz = new SimpleTimeZone - (-4000 * 3600, "America/Glace_Bay", - Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("America/Glace_Bay", tz); - timezones0.put("America/Halifax", tz); - timezones0.put("America/Thule", tz); - timezones0.put("Atlantic/Bermuda", tz); - tz = new SimpleTimeZone - (-4000 * 3600, "America/Santiago", - Calendar.OCTOBER, 9, -Calendar.SUNDAY, 0 * 3600, - Calendar.MARCH, 9, -Calendar.SUNDAY, 0 * 3600); - timezones0.put("America/Santiago", tz); - timezones0.put("Antarctica/Palmer", tz); - tz = new SimpleTimeZone - (-4000 * 3600, "Atlantic/Stanley", - Calendar.SEPTEMBER, 2, Calendar.SUNDAY, 0 * 3600, - Calendar.APRIL, 16, -Calendar.SUNDAY, 0 * 3600); - timezones0.put("Atlantic/Stanley", tz); - tz = new SimpleTimeZone - (-3500 * 3600, "CNT", - Calendar.APRIL, 1, Calendar.SUNDAY, 60000, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 60000); - timezones0.put("CNT", tz); - timezones0.put("America/St_Johns", tz); - tz = new SimpleTimeZone - (-3000 * 3600, "America/Araguaina", - Calendar.OCTOBER, 2, Calendar.SUNDAY, 0 * 3600, - Calendar.FEBRUARY, 3, Calendar.SUNDAY, 0 * 3600); - timezones0.put("America/Araguaina", tz); - timezones0.put("America/Sao_Paulo", tz); - tz = new SimpleTimeZone(-3000 * 3600, "AGT"); - timezones0.put("AGT", tz); - timezones0.put("America/Belem", tz); - timezones0.put("America/Buenos_Aires", tz); - timezones0.put("America/Catamarca", tz); - timezones0.put("America/Cayenne", tz); - timezones0.put("America/Cordoba", tz); - timezones0.put("America/Fortaleza", tz); - timezones0.put("America/Jujuy", tz); - timezones0.put("America/Maceio", tz); - timezones0.put("America/Mendoza", tz); - timezones0.put("America/Montevideo", tz); - timezones0.put("America/Paramaribo", tz); - timezones0.put("America/Recife", tz); - timezones0.put("America/Rosario", tz); - tz = new SimpleTimeZone - (-3000 * 3600, "America/Godthab", - Calendar.MARCH, 30, -Calendar.SATURDAY, 22000 * 3600, - Calendar.OCTOBER, 30, -Calendar.SATURDAY, 22000 * 3600); - timezones0.put("America/Godthab", tz); - tz = new SimpleTimeZone - (-3000 * 3600, "America/Miquelon", - Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("America/Miquelon", tz); - tz = new SimpleTimeZone(-2000 * 3600, "America/Noronha"); - timezones0.put("America/Noronha", tz); - timezones0.put("Atlantic/South_Georgia", tz); - tz = new SimpleTimeZone - (-1000 * 3600, "America/Scoresbysund", - Calendar.MARCH, -1, Calendar.SUNDAY, 0 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600); - timezones0.put("America/Scoresbysund", tz); - timezones0.put("Atlantic/Azores", tz); - tz = new SimpleTimeZone(-1000 * 3600, "Atlantic/Cape_Verde"); - timezones0.put("Atlantic/Cape_Verde", tz); - timezones0.put("Atlantic/Jan_Mayen", tz); - tz = new SimpleTimeZone(0 * 3600, "GMT"); - timezones0.put("GMT", tz); - timezones0.put("UTC", tz); - timezones0.put("Africa/Abidjan", tz); - timezones0.put("Africa/Accra", tz); - timezones0.put("Africa/Bamako", tz); - timezones0.put("Africa/Banjul", tz); - timezones0.put("Africa/Bissau", tz); - timezones0.put("Africa/Casablanca", tz); - timezones0.put("Africa/Conakry", tz); - timezones0.put("Africa/Dakar", tz); - timezones0.put("Africa/El_Aaiun", tz); - timezones0.put("Africa/Freetown", tz); - timezones0.put("Africa/Lome", tz); - timezones0.put("Africa/Monrovia", tz); - timezones0.put("Africa/Nouakchott", tz); - timezones0.put("Africa/Ouagadougou", tz); - timezones0.put("Africa/Sao_Tome", tz); - timezones0.put("Africa/Timbuktu", tz); - timezones0.put("Atlantic/Reykjavik", tz); - timezones0.put("Atlantic/St_Helena", tz); - timezones0.put("Europe/Belfast", tz); - timezones0.put("Europe/Dublin", tz); - timezones0.put("Europe/London", tz); - tz = new SimpleTimeZone - (0 * 3600, "WET", - Calendar.MARCH, -1, Calendar.SUNDAY, 1000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 1000 * 3600); - timezones0.put("WET", tz); - timezones0.put("Atlantic/Canary", tz); - timezones0.put("Atlantic/Faeroe", tz); - timezones0.put("Atlantic/Madeira", tz); - timezones0.put("Europe/Lisbon", tz); - tz = new SimpleTimeZone(1000 * 3600, "Africa/Algiers"); - timezones0.put("Africa/Algiers", tz); - timezones0.put("Africa/Bangui", tz); - timezones0.put("Africa/Brazzaville", tz); - timezones0.put("Africa/Douala", tz); - timezones0.put("Africa/Kinshasa", tz); - timezones0.put("Africa/Lagos", tz); - timezones0.put("Africa/Libreville", tz); - timezones0.put("Africa/Luanda", tz); - timezones0.put("Africa/Malabo", tz); - timezones0.put("Africa/Ndjamena", tz); - timezones0.put("Africa/Niamey", tz); - timezones0.put("Africa/Porto-Novo", tz); - timezones0.put("Africa/Tunis", tz); - tz = new SimpleTimeZone - (1000 * 3600, "Africa/Windhoek", - Calendar.SEPTEMBER, 1, Calendar.SUNDAY, 2000 * 3600, - Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("Africa/Windhoek", tz); - tz = new SimpleTimeZone - (1000 * 3600, "CET", - Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("CET", tz); - timezones0.put("CEST", tz); - timezones0.put("ECT", tz); - timezones0.put("MET", tz); - timezones0.put("Africa/Ceuta", tz); - timezones0.put("Arctic/Longyearbyen", tz); - timezones0.put("Europe/Amsterdam", tz); - timezones0.put("Europe/Andorra", tz); - timezones0.put("Europe/Belgrade", tz); - timezones0.put("Europe/Berlin", tz); - timezones0.put("Europe/Bratislava", tz); - timezones0.put("Europe/Brussels", tz); - timezones0.put("Europe/Budapest", tz); - timezones0.put("Europe/Copenhagen", tz); - timezones0.put("Europe/Gibraltar", tz); - timezones0.put("Europe/Ljubljana", tz); - timezones0.put("Europe/Luxembourg", tz); - timezones0.put("Europe/Madrid", tz); - timezones0.put("Europe/Malta", tz); - timezones0.put("Europe/Monaco", tz); - timezones0.put("Europe/Oslo", tz); - timezones0.put("Europe/Paris", tz); - timezones0.put("Europe/Prague", tz); - timezones0.put("Europe/Rome", tz); - timezones0.put("Europe/San_Marino", tz); - timezones0.put("Europe/Sarajevo", tz); - timezones0.put("Europe/Skopje", tz); - timezones0.put("Europe/Stockholm", tz); - timezones0.put("Europe/Tirane", tz); - timezones0.put("Europe/Vaduz", tz); - timezones0.put("Europe/Vatican", tz); - timezones0.put("Europe/Vienna", tz); - timezones0.put("Europe/Warsaw", tz); - timezones0.put("Europe/Zagreb", tz); - timezones0.put("Europe/Zurich", tz); - tz = new SimpleTimeZone - (2000 * 3600, "ART", - Calendar.APRIL, -1, Calendar.FRIDAY, 0 * 3600, - Calendar.SEPTEMBER, -1, Calendar.THURSDAY, 23000 * 3600); - timezones0.put("ART", tz); - timezones0.put("Africa/Cairo", tz); - tz = new SimpleTimeZone(2000 * 3600, "CAT"); - timezones0.put("CAT", tz); - timezones0.put("Africa/Blantyre", tz); - timezones0.put("Africa/Bujumbura", tz); - timezones0.put("Africa/Gaborone", tz); - timezones0.put("Africa/Harare", tz); - timezones0.put("Africa/Johannesburg", tz); - timezones0.put("Africa/Kigali", tz); - timezones0.put("Africa/Lubumbashi", tz); - timezones0.put("Africa/Lusaka", tz); - timezones0.put("Africa/Maputo", tz); - timezones0.put("Africa/Maseru", tz); - timezones0.put("Africa/Mbabane", tz); - timezones0.put("Africa/Tripoli", tz); - timezones0.put("Europe/Riga", tz); - timezones0.put("Europe/Tallinn", tz); - timezones0.put("Europe/Vilnius", tz); - tz = new SimpleTimeZone - (2000 * 3600, "Asia/Amman", - Calendar.MARCH, -1, Calendar.THURSDAY, 0 * 3600, - Calendar.SEPTEMBER, -1, Calendar.THURSDAY, 0 * 3600); - timezones0.put("Asia/Amman", tz); - tz = new SimpleTimeZone - (2000 * 3600, "Asia/Beirut", - Calendar.MARCH, -1, Calendar.SUNDAY, 0 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600); - timezones0.put("Asia/Beirut", tz); - tz = new SimpleTimeZone - (2000 * 3600, "Asia/Damascus", - Calendar.APRIL, 1, 0, 0 * 3600, - Calendar.OCTOBER, 1, 0, 0 * 3600); - timezones0.put("Asia/Damascus", tz); - tz = new SimpleTimeZone - (2000 * 3600, "Asia/Gaza", - Calendar.APRIL, 3, Calendar.FRIDAY, 0 * 3600, - Calendar.OCTOBER, 3, Calendar.FRIDAY, 0 * 3600); - timezones0.put("Asia/Gaza", tz); - tz = new SimpleTimeZone - (2000 * 3600, "Asia/Jerusalem", - Calendar.APRIL, 1, 0, 1000 * 3600, - Calendar.OCTOBER, 1, 0, 1000 * 3600); - timezones0.put("Asia/Jerusalem", tz); - tz = new SimpleTimeZone - (2000 * 3600, "EET", - Calendar.MARCH, -1, Calendar.SUNDAY, 3000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600); - timezones0.put("EET", tz); - timezones0.put("Asia/Istanbul", tz); - timezones0.put("Asia/Nicosia", tz); - timezones0.put("Europe/Athens", tz); - timezones0.put("Europe/Bucharest", tz); - timezones0.put("Europe/Chisinau", tz); - timezones0.put("Europe/Helsinki", tz); - timezones0.put("Europe/Istanbul", tz); - timezones0.put("Europe/Kiev", tz); - timezones0.put("Europe/Nicosia", tz); - timezones0.put("Europe/Simferopol", tz); - timezones0.put("Europe/Sofia", tz); - timezones0.put("Europe/Uzhgorod", tz); - timezones0.put("Europe/Zaporozhye", tz); - tz = new SimpleTimeZone - (2000 * 3600, "Europe/Kaliningrad", - Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("Europe/Kaliningrad", tz); - timezones0.put("Europe/Minsk", tz); - tz = new SimpleTimeZone - (3000 * 3600, "Asia/Baghdad", - Calendar.APRIL, 1, 0, 3000 * 3600, - Calendar.OCTOBER, 1, 0, 3000 * 3600); - timezones0.put("Asia/Baghdad", tz); - tz = new SimpleTimeZone - (3000 * 3600, "Europe/Moscow", - Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("Europe/Moscow", tz); - timezones0.put("Europe/Tiraspol", tz); - tz = new SimpleTimeZone(3000 * 3600, "EAT"); - timezones0.put("EAT", tz); - timezones0.put("Africa/Addis_Ababa", tz); - timezones0.put("Africa/Asmera", tz); - timezones0.put("Africa/Dar_es_Salaam", tz); - timezones0.put("Africa/Djibouti", tz); - timezones0.put("Africa/Kampala", tz); - timezones0.put("Africa/Khartoum", tz); - timezones0.put("Africa/Mogadishu", tz); - timezones0.put("Africa/Nairobi", tz); - timezones0.put("Antarctica/Syowa", tz); - timezones0.put("Asia/Aden", tz); - timezones0.put("Asia/Bahrain", tz); - timezones0.put("Asia/Kuwait", tz); - timezones0.put("Asia/Qatar", tz); - timezones0.put("Asia/Riyadh", tz); - timezones0.put("Indian/Antananarivo", tz); - timezones0.put("Indian/Comoro", tz); - timezones0.put("Indian/Mayotte", tz); - tz = new SimpleTimeZone(3500 * 3600, "Asia/Tehran"); - timezones0.put("Asia/Tehran", tz); - tz = new SimpleTimeZone - (4000 * 3600, "Asia/Baku", - Calendar.MARCH, -1, Calendar.SUNDAY, 1000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 1000 * 3600); - timezones0.put("Asia/Baku", tz); - tz = new SimpleTimeZone - (4000 * 3600, "Asia/Aqtau", - Calendar.MARCH, -1, Calendar.SUNDAY, 0 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600); - timezones0.put("Asia/Aqtau", tz); - timezones0.put("Asia/Tbilisi", tz); - tz = new SimpleTimeZone - (4000 * 3600, "Asia/Yerevan", - Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("Asia/Yerevan", tz); - timezones0.put("Europe/Samara", tz); - tz = new SimpleTimeZone(4000 * 3600, "NET"); - timezones0.put("NET", tz); - timezones0.put("Asia/Dubai", tz); - timezones0.put("Asia/Muscat", tz); - timezones0.put("Indian/Mahe", tz); - timezones0.put("Indian/Mauritius", tz); - timezones0.put("Indian/Reunion", tz); - tz = new SimpleTimeZone(4500 * 3600, "Asia/Kabul"); - timezones0.put("Asia/Kabul", tz); - tz = new SimpleTimeZone - (5000 * 3600, "Asia/Aqtobe", - Calendar.MARCH, -1, Calendar.SUNDAY, 0 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600); - timezones0.put("Asia/Aqtobe", tz); - tz = new SimpleTimeZone - (5000 * 3600, "Asia/Bishkek", - Calendar.MARCH, -1, Calendar.SUNDAY, 2500 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 2500 * 3600); - timezones0.put("Asia/Bishkek", tz); - tz = new SimpleTimeZone - (5000 * 3600, "Asia/Yekaterinburg", - Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("Asia/Yekaterinburg", tz); - tz = new SimpleTimeZone(5000 * 3600, "PLT"); - timezones0.put("PLT", tz); - timezones0.put("Asia/Ashgabat", tz); - timezones0.put("Asia/Dushanbe", tz); - timezones0.put("Asia/Karachi", tz); - timezones0.put("Asia/Samarkand", tz); - timezones0.put("Asia/Tashkent", tz); - timezones0.put("Indian/Chagos", tz); - timezones0.put("Indian/Kerguelen", tz); - timezones0.put("Indian/Maldives", tz); - tz = new SimpleTimeZone(5500 * 3600, "IST"); - timezones0.put("IST", tz); - timezones0.put("Asia/Calcutta", tz); - tz = new SimpleTimeZone(5750 * 3600, "Asia/Katmandu"); - timezones0.put("Asia/Katmandu", tz); - tz = new SimpleTimeZone(6000 * 3600, "BST"); - timezones0.put("BST", tz); - timezones0.put("Antarctica/Mawson", tz); - timezones0.put("Asia/Colombo", tz); - timezones0.put("Asia/Dhaka", tz); - timezones0.put("Asia/Thimphu", tz); - tz = new SimpleTimeZone - (6000 * 3600, "Asia/Almaty", - Calendar.MARCH, -1, Calendar.SUNDAY, 0 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600); - timezones0.put("Asia/Almaty", tz); - tz = new SimpleTimeZone - (6000 * 3600, "Asia/Novosibirsk", - Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("Asia/Novosibirsk", tz); - timezones0.put("Asia/Omsk", tz); - tz = new SimpleTimeZone(6500 * 3600, "Asia/Rangoon"); - timezones0.put("Asia/Rangoon", tz); - timezones0.put("Indian/Cocos", tz); - tz = new SimpleTimeZone(7000 * 3600, "VST"); - timezones0.put("VST", tz); - timezones0.put("Antarctica/Davis", tz); - timezones0.put("Asia/Bangkok", tz); - timezones0.put("Asia/Hovd", tz); - timezones0.put("Asia/Jakarta", tz); - timezones0.put("Asia/Phnom_Penh", tz); - timezones0.put("Asia/Saigon", tz); - timezones0.put("Asia/Vientiane", tz); - timezones0.put("Indian/Christmas", tz); - tz = new SimpleTimeZone - (7000 * 3600, "Asia/Krasnoyarsk", - Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("Asia/Krasnoyarsk", tz); - tz = new SimpleTimeZone(8000 * 3600, "CTT"); - timezones0.put("CTT", tz); - timezones0.put("Antarctica/Casey", tz); - timezones0.put("Asia/Brunei", tz); - timezones0.put("Asia/Chungking", tz); - timezones0.put("Asia/Harbin", tz); - timezones0.put("Asia/Hong_Kong", tz); - timezones0.put("Asia/Kashgar", tz); - timezones0.put("Asia/Kuala_Lumpur", tz); - timezones0.put("Asia/Kuching", tz); - timezones0.put("Asia/Macao", tz); - timezones0.put("Asia/Manila", tz); - timezones0.put("Asia/Shanghai", tz); - timezones0.put("Asia/Singapore", tz); - timezones0.put("Asia/Taipei", tz); - timezones0.put("Asia/Ujung_Pandang", tz); - timezones0.put("Asia/Ulaanbaatar", tz); - timezones0.put("Asia/Urumqi", tz); - timezones0.put("Australia/Perth", tz); - tz = new SimpleTimeZone - (8000 * 3600, "Asia/Irkutsk", - Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("Asia/Irkutsk", tz); - tz = new SimpleTimeZone(9000 * 3600, "JST"); - timezones0.put("JST", tz); - timezones0.put("Asia/Dili", tz); - timezones0.put("Asia/Jayapura", tz); - timezones0.put("Asia/Pyongyang", tz); - timezones0.put("Asia/Seoul", tz); - timezones0.put("Asia/Tokyo", tz); - timezones0.put("Pacific/Palau", tz); - tz = new SimpleTimeZone - (9000 * 3600, "Asia/Yakutsk", - Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("Asia/Yakutsk", tz); - tz = new SimpleTimeZone - (9500 * 3600, "Australia/Adelaide", - Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600, - Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("Australia/Adelaide", tz); - timezones0.put("Australia/Broken_Hill", tz); - tz = new SimpleTimeZone(9500 * 3600, "ACT"); - timezones0.put("ACT", tz); - timezones0.put("Australia/Darwin", tz); - tz = new SimpleTimeZone(10000 * 3600, "Antarctica/DumontDUrville"); - timezones0.put("Antarctica/DumontDUrville", tz); - timezones0.put("Australia/Brisbane", tz); - timezones0.put("Australia/Lindeman", tz); - timezones0.put("Pacific/Guam", tz); - timezones0.put("Pacific/Port_Moresby", tz); - timezones0.put("Pacific/Saipan", tz); - timezones0.put("Pacific/Truk", tz); - timezones0.put("Pacific/Yap", tz); - tz = new SimpleTimeZone - (10000 * 3600, "Asia/Vladivostok", - Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("Asia/Vladivostok", tz); - tz = new SimpleTimeZone - (10000 * 3600, "Australia/Hobart", - Calendar.OCTOBER, 1, Calendar.SUNDAY, 2000 * 3600, - Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("Australia/Hobart", tz); - tz = new SimpleTimeZone - (10000 * 3600, "AET", - Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600, - Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("AET", tz); - timezones0.put("Australia/Melbourne", tz); - timezones0.put("Australia/Sydney", tz); - tz = new SimpleTimeZone - (10500 * 3600, "Australia/Lord_Howe", - Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600, - Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, 500 * 3600); - timezones0.put("Australia/Lord_Howe", tz); - tz = new SimpleTimeZone - (11000 * 3600, "Asia/Magadan", - Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("Asia/Magadan", tz); - tz = new SimpleTimeZone(11000 * 3600, "SST"); - timezones0.put("SST", tz); - timezones0.put("Pacific/Efate", tz); - timezones0.put("Pacific/Guadalcanal", tz); - timezones0.put("Pacific/Kosrae", tz); - timezones0.put("Pacific/Noumea", tz); - timezones0.put("Pacific/Ponape", tz); - tz = new SimpleTimeZone(11500 * 3600, "Pacific/Norfolk"); - timezones0.put("Pacific/Norfolk", tz); - tz = new SimpleTimeZone - (12000 * 3600, "NST", - Calendar.OCTOBER, 1, Calendar.SUNDAY, 2000 * 3600, - Calendar.MARCH, 3, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("NST", tz); - timezones0.put("Antarctica/McMurdo", tz); - timezones0.put("Antarctica/South_Pole", tz); - timezones0.put("Pacific/Auckland", tz); - tz = new SimpleTimeZone - (12000 * 3600, "Asia/Anadyr", - Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("Asia/Anadyr", tz); - timezones0.put("Asia/Kamchatka", tz); - tz = new SimpleTimeZone(12000 * 3600, "Pacific/Fiji"); - timezones0.put("Pacific/Fiji", tz); - timezones0.put("Pacific/Funafuti", tz); - timezones0.put("Pacific/Kwajalein", tz); - timezones0.put("Pacific/Majuro", tz); - timezones0.put("Pacific/Nauru", tz); - timezones0.put("Pacific/Tarawa", tz); - timezones0.put("Pacific/Wake", tz); - timezones0.put("Pacific/Wallis", tz); - tz = new SimpleTimeZone - (12750 * 3600, "Pacific/Chatham", - Calendar.OCTOBER, 1, Calendar.SUNDAY, 2750 * 3600, - Calendar.MARCH, 3, Calendar.SUNDAY, 2750 * 3600); - timezones0.put("Pacific/Chatham", tz); - tz = new SimpleTimeZone(13000 * 3600, "Pacific/Enderbury"); - timezones0.put("Pacific/Enderbury", tz); - timezones0.put("Pacific/Tongatapu", tz); - tz = new SimpleTimeZone(14000 * 3600, "Pacific/Kiritimati"); - timezones0.put("Pacific/Kiritimati", tz); - } - return timezones0; - } - - /** - * Maps a time zone name (with optional GMT offset and daylight time - * zone name) to one of the known time zones. This method called - * with the result of <code>System.getProperty("user.timezone")</code> - * or <code>getDefaultTimeZoneId()</code>. Note that giving one of - * the standard tz data names from ftp://elsie.nci.nih.gov/pub/ is - * preferred. The time zone name can be given as follows: - * <code>(standard zone name)[(GMT offset)[(daylight time zone name)]]</code> - * <p> - * If only a (standard zone name) is given (no numbers in the - * String) then it gets mapped directly to the TimeZone with that - * name, if that fails null is returned. - * <p> - * A GMT offset is the offset to add to the local time to get GMT. - * If a (GMT offset) is included (either in seconds or hours) then - * an attempt is made to find a TimeZone name matching both the name - * and the offset (that doesn't observe daylight time, if the - * timezone observes daylight time then you must include a daylight - * time zone name after the offset), if that fails then a TimeZone - * with the given GMT offset is returned (whether or not the - * TimeZone observes daylight time is ignored), if that also fails - * the GMT TimeZone is returned. - * <p> - * If the String ends with (GMT offset)(daylight time zone name) - * then an attempt is made to find a TimeZone with the given name and - * GMT offset that also observes (the daylight time zone name is not - * currently used in any other way), if that fails a TimeZone with - * the given GMT offset that observes daylight time is returned, if - * that also fails the GMT TimeZone is returned. - * <p> - * Examples: In Chicago, the time zone id could be "CST6CDT", but - * the preferred name would be "America/Chicago". In Indianapolis - * (which does not have Daylight Savings Time) the string could be - * "EST5", but the preferred name would be "America/Indianapolis". - * The standard time zone name for The Netherlands is "Europe/Amsterdam", - * but can also be given as "CET-1CEST". - */ - static TimeZone getDefaultTimeZone(String sysTimeZoneId) - { - // First find start of GMT offset info and any Daylight zone name. - int startGMToffset = 0; - int sysTimeZoneIdLength = sysTimeZoneId.length(); - for (int i = 0; i < sysTimeZoneIdLength && startGMToffset == 0; i++) - { - char c = sysTimeZoneId.charAt(i); - if (Character.isDigit(c)) - startGMToffset = i; - else if ((c == '+' || c == '-') - && i + 1 < sysTimeZoneIdLength - && Character.isDigit(sysTimeZoneId.charAt(i + 1))) - startGMToffset = i; - } - - String tzBasename; - if (startGMToffset == 0) - tzBasename = sysTimeZoneId; - else - tzBasename = sysTimeZoneId.substring (0, startGMToffset); - - int startDaylightZoneName = 0; - for (int i = sysTimeZoneIdLength - 1; - i >= 0 && !Character.isDigit(sysTimeZoneId.charAt(i)); --i) - startDaylightZoneName = i; - - boolean useDaylightTime = startDaylightZoneName > 0; - - // Integer.parseInt() doesn't handle leading +. - if (sysTimeZoneId.charAt(startGMToffset) == '+') - startGMToffset++; - - int gmtOffset = 0; - if (startGMToffset > 0) - { - gmtOffset = Integer.parseInt - (startDaylightZoneName == 0 - ? sysTimeZoneId.substring(startGMToffset) - : sysTimeZoneId.substring(startGMToffset, - startDaylightZoneName)); - - // Offset could be in hours or seconds. Convert to millis. - // The offset is given as the time to add to local time to get GMT - // we need the time to add to GMT to get localtime. - if (Math.abs(gmtOffset) < 24) - gmtOffset *= 60 * 60; - gmtOffset *= -1000; - } - - // Try to be optimistic and get the timezone that matches the base name. - // If we only have the base name then just accept this timezone. - // Otherwise check the gmtOffset and day light attributes. - TimeZone tz = (TimeZone) timezones().get(tzBasename); - if (tz != null - && (tzBasename == sysTimeZoneId - || (tz.getRawOffset() == gmtOffset - && tz.useDaylightTime() == useDaylightTime))) - return tz; - - // Maybe there is one with the daylight zone name? - if (useDaylightTime) - { - String daylightZoneName; - daylightZoneName = sysTimeZoneId.substring(startDaylightZoneName); - if (!daylightZoneName.equals(tzBasename)) - { - tz = (TimeZone) timezones().get(tzBasename); - if (tz != null - && tz.getRawOffset() == gmtOffset - && tz.useDaylightTime()) - return tz; - } - } - - // If no match, see if a valid timezone has similar attributes as this - // and then use it instead. We take the first one that looks OKish. - if (startGMToffset > 0) - { - String[] ids = getAvailableIDs(gmtOffset); - for (int i = 0; i < ids.length; i++) - { - tz = (TimeZone) timezones().get(ids[i]); - if (tz.useDaylightTime() == useDaylightTime) - return tz; - } - } - - return null; - } - - /** - * Gets the time zone offset, for current date, modified in case of - * daylight savings. This is the offset to add to UTC to get the local - * time. - * @param era the era of the given date - * @param year the year of the given date - * @param month the month of the given date, 0 for January. - * @param day the day of month - * @param dayOfWeek the day of week - * @param milliseconds the millis in the day (in local standard time) - * @return the time zone offset in milliseconds. - */ - public abstract int getOffset(int era, int year, int month, - int day, int dayOfWeek, int milliseconds); - - /** - * Get the time zone offset for the specified date, modified in case of - * daylight savings. This is the offset to add to UTC to get the local - * time. - * @param date the date represented in millisecends - * since January 1, 1970 00:00:00 GMT. - * @since 1.4 - */ - public int getOffset(long date) - { - return (inDaylightTime(new Date(date)) - ? getRawOffset() + getDSTSavings() - : getRawOffset()); - } - - /** - * Gets the time zone offset, ignoring daylight savings. This is - * the offset to add to UTC to get the local time. - * @return the time zone offset in milliseconds. - */ - public abstract int getRawOffset(); - - /** - * Sets the time zone offset, ignoring daylight savings. This is - * the offset to add to UTC to get the local time. - * @param offsetMillis the time zone offset to GMT. - */ - public abstract void setRawOffset(int offsetMillis); - - /** - * Gets the identifier of this time zone. For instance, PST for - * Pacific Standard Time. - * @returns the ID of this time zone. - */ - public String getID() - { - return ID; - } - - /** - * Sets the identifier of this time zone. For instance, PST for - * Pacific Standard Time. - * @param id the new time zone ID. - * @throws NullPointerException if <code>id</code> is <code>null</code> - */ - public void setID(String id) - { - if (id == null) - throw new NullPointerException(); - - this.ID = id; - } - - /** - * This method returns a string name of the time zone suitable - * for displaying to the user. The string returned will be the long - * description of the timezone in the current locale. The name - * displayed will assume daylight savings time is not in effect. - * - * @return The name of the time zone. - */ - public final String getDisplayName() - { - return (getDisplayName(false, LONG, Locale.getDefault())); - } - - /** - * This method returns a string name of the time zone suitable - * for displaying to the user. The string returned will be the long - * description of the timezone in the specified locale. The name - * displayed will assume daylight savings time is not in effect. - * - * @param locale The locale for this timezone name. - * - * @return The name of the time zone. - */ - public final String getDisplayName(Locale locale) - { - return (getDisplayName(false, LONG, locale)); - } - - /** - * This method returns a string name of the time zone suitable - * for displaying to the user. The string returned will be of the - * specified type in the current locale. - * - * @param dst Whether or not daylight savings time is in effect. - * @param style <code>LONG</code> for a long name, <code>SHORT</code> for - * a short abbreviation. - * - * @return The name of the time zone. - */ - public final String getDisplayName(boolean dst, int style) - { - return (getDisplayName(dst, style, Locale.getDefault())); - } - - - /** - * This method returns a string name of the time zone suitable - * for displaying to the user. The string returned will be of the - * specified type in the specified locale. - * - * @param dst Whether or not daylight savings time is in effect. - * @param style <code>LONG</code> for a long name, <code>SHORT</code> for - * a short abbreviation. - * @param locale The locale for this timezone name. - * - * @return The name of the time zone. - */ - public String getDisplayName(boolean dst, int style, Locale locale) - { - DateFormatSymbols dfs; - try - { - dfs = new DateFormatSymbols(locale); - - // The format of the value returned is defined by us. - String[][]zoneinfo = dfs.getZoneStrings(); - for (int i = 0; i < zoneinfo.length; i++) - { - if (zoneinfo[i][0].equals(getID())) - { - if (!dst) - { - if (style == SHORT) - return (zoneinfo[i][2]); - else - return (zoneinfo[i][1]); - } - else - { - if (style == SHORT) - return (zoneinfo[i][4]); - else - return (zoneinfo[i][3]); - } - } - } - } - catch (MissingResourceException e) - { - } - - return getDefaultDisplayName(dst); - } - - private String getDefaultDisplayName(boolean dst) - { - int offset = getRawOffset(); - if (dst && this instanceof SimpleTimeZone) - { - // ugly, but this is a design failure of the API: - // getDisplayName takes a dst parameter even though - // TimeZone knows nothing about daylight saving offsets. - offset += ((SimpleTimeZone) this).getDSTSavings(); - } - - StringBuffer sb = new StringBuffer(9); - sb.append("GMT"); - - offset = offset / (1000 * 60); - int hours = Math.abs(offset) / 60; - int minutes = Math.abs(offset) % 60; - - if (minutes != 0 || hours != 0) - { - sb.append(offset >= 0 ? '+' : '-'); - sb.append((char) ('0' + hours / 10)); - sb.append((char) ('0' + hours % 10)); - sb.append(':'); - sb.append((char) ('0' + minutes / 10)); - sb.append((char) ('0' + minutes % 10)); - } - - return sb.toString(); - } - - /** - * Returns true, if this time zone uses Daylight Savings Time. - */ - public abstract boolean useDaylightTime(); - - /** - * Returns true, if the given date is in Daylight Savings Time in this - * time zone. - * @param date the given Date. - */ - public abstract boolean inDaylightTime(Date date); - - /** - * Gets the daylight savings offset. This is a positive offset in - * milliseconds with respect to standard time. Typically this - * is one hour, but for some time zones this may be half an our. - * <p>The default implementation returns 3600000 milliseconds - * (one hour) if the time zone uses daylight savings time - * (as specified by {@link #useDaylightTime()}), otherwise - * it returns 0. - * @return the daylight savings offset in milliseconds. - * @since 1.4 - */ - public int getDSTSavings () - { - return useDaylightTime () ? 3600000 : 0; - } - - /** - * Gets the TimeZone for the given ID. - * @param ID the time zone identifier. - * @return The time zone for the identifier or GMT, if no such time - * zone exists. - */ - // FIXME: XXX: JCL indicates this and other methods are synchronized. - public static TimeZone getTimeZone(String ID) - { - // First check timezones hash - TimeZone tz = (TimeZone) timezones().get(ID); - if (tz != null) - { - if (tz.getID().equals(ID)) - return tz; - - // We always return a timezone with the requested ID. - // This is the same behaviour as with JDK1.2. - tz = (TimeZone) tz.clone(); - tz.setID(ID); - // We also save the alias, so that we return the same - // object again if getTimeZone is called with the same - // alias. - timezones().put(ID, tz); - return tz; - } - - // See if the ID is really a GMT offset form. - // Note that GMT is in the table so we know it is different. - if (ID.startsWith("GMT")) - { - int pos = 3; - int offset_direction = 1; - - if (ID.charAt(pos) == '-') - { - offset_direction = -1; - pos++; - } - else if (ID.charAt(pos) == '+') - { - pos++; - } - - try - { - int hour, minute; - - String offset_str = ID.substring(pos); - int idx = offset_str.indexOf(":"); - if (idx != -1) - { - hour = Integer.parseInt(offset_str.substring(0, idx)); - minute = Integer.parseInt(offset_str.substring(idx + 1)); - } - else - { - int offset_length = offset_str.length(); - if (offset_length <= 2) - { - // Only hour - hour = Integer.parseInt(offset_str); - minute = 0; - } - else - { - // hour and minute, not separated by colon - hour = Integer.parseInt - (offset_str.substring(0, offset_length - 2)); - minute = Integer.parseInt - (offset_str.substring(offset_length - 2)); - } - } - - return new SimpleTimeZone((hour * (60 * 60 * 1000) + - minute * (60 * 1000)) - * offset_direction, ID); - } - catch (NumberFormatException e) - { - } - } - - // Finally, return GMT per spec - return getTimeZone("GMT"); - } - - /** - * Gets the available IDs according to the given time zone - * offset. - * @param rawOffset the given time zone GMT offset. - * @return An array of IDs, where the time zone has the specified GMT - * offset. For example <code>{"Phoenix", "Denver"}</code>, since both have - * GMT-07:00, but differ in daylight savings behaviour. - */ - public static String[] getAvailableIDs(int rawOffset) - { - int count = 0; - Iterator iter = timezones().entrySet().iterator(); - while (iter.hasNext()) - { - // Don't iterate the values, since we want to count - // doubled values (aliases) - Map.Entry entry = (Map.Entry) iter.next(); - if (((TimeZone) entry.getValue()).getRawOffset() == rawOffset) - count++; - } - - String[] ids = new String[count]; - count = 0; - iter = timezones().entrySet().iterator(); - while (iter.hasNext()) - { - Map.Entry entry = (Map.Entry) iter.next(); - if (((TimeZone) entry.getValue()).getRawOffset() == rawOffset) - ids[count++] = (String) entry.getKey(); - } - return ids; - } - - /** - * Gets all available IDs. - * @return An array of all supported IDs. - */ - public static String[] getAvailableIDs() - { - return (String[]) - timezones().keySet().toArray(new String[timezones().size()]); - } - - /** - * Returns the time zone under which the host is running. This - * can be changed with setDefault. - * - * @return A clone of the current default time zone for this host. - * @see #setDefault - */ - public static TimeZone getDefault() - { - return (TimeZone) defaultZone().clone(); - } - - public static void setDefault(TimeZone zone) - { - // Hmmmm. No Security checks? - defaultZone0 = zone; - } - - /** - * Test if the other time zone uses the same rule and only - * possibly differs in ID. This implementation for this particular - * class will return true if the raw offsets are identical. Subclasses - * should override this method if they use daylight savings. - * @return true if this zone has the same raw offset - */ - public boolean hasSameRules(TimeZone other) - { - return other.getRawOffset() == getRawOffset(); - } - - /** - * Returns a clone of this object. I can't imagine, why this is - * useful for a time zone. - */ - public Object clone() - { - try - { - return super.clone(); - } - catch (CloneNotSupportedException ex) - { - return null; - } - } -} diff --git a/libjava/java/util/Timer.java b/libjava/java/util/Timer.java deleted file mode 100644 index 715f06cf641..00000000000 --- a/libjava/java/util/Timer.java +++ /dev/null @@ -1,615 +0,0 @@ -/* Timer.java -- Timer that runs TimerTasks at a later time. - Copyright (C) 2000, 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package java.util; - -/** - * Timer that can run TimerTasks at a later time. - * TimerTasks can be scheduled for one time execution at some time in the - * future. They can be scheduled to be rescheduled at a time period after the - * task was last executed. Or they can be scheduled to be executed repeatedly - * at a fixed rate. - * <p> - * The normal scheduling will result in a more or less even delay in time - * between successive executions, but the executions could drift in time if - * the task (or other tasks) takes a long time to execute. Fixed delay - * scheduling guarantees more or less that the task will be executed at a - * specific time, but if there is ever a delay in execution then the period - * between successive executions will be shorter. The first method of - * repeated scheduling is preferred for repeated tasks in response to user - * interaction, the second method of repeated scheduling is preferred for tasks - * that act like alarms. - * <p> - * The Timer keeps a binary heap as a task priority queue which means that - * scheduling and serving of a task in a queue of n tasks costs O(log n). - * - * @see TimerTask - * @since 1.3 - * @author Mark Wielaard (mark@klomp.org) - */ -public class Timer -{ - /** - * Priority Task Queue. - * TimerTasks are kept in a binary heap. - * The scheduler calls sleep() on the queue when it has nothing to do or - * has to wait. A sleeping scheduler can be notified by calling interrupt() - * which is automatically called by the enqueue(), cancel() and - * timerFinalized() methods. - */ - private static final class TaskQueue - { - /** Default size of this queue */ - private static final int DEFAULT_SIZE = 32; - - /** Whether to return null when there is nothing in the queue */ - private boolean nullOnEmpty; - - /** - * The heap containing all the scheduled TimerTasks - * sorted by the TimerTask.scheduled field. - * Null when the stop() method has been called. - */ - private TimerTask heap[]; - - /** - * The actual number of elements in the heap - * Can be less then heap.length. - * Note that heap[0] is used as a sentinel. - */ - private int elements; - - /** - * Creates a TaskQueue of default size without any elements in it. - */ - public TaskQueue() - { - heap = new TimerTask[DEFAULT_SIZE]; - elements = 0; - nullOnEmpty = false; - } - - /** - * Adds a TimerTask at the end of the heap. - * Grows the heap if necessary by doubling the heap in size. - */ - private void add(TimerTask task) - { - elements++; - if (elements == heap.length) - { - TimerTask new_heap[] = new TimerTask[heap.length * 2]; - System.arraycopy(heap, 0, new_heap, 0, heap.length); - heap = new_heap; - } - heap[elements] = task; - } - - /** - * Removes the last element from the heap. - * Shrinks the heap in half if - * elements+DEFAULT_SIZE/2 <= heap.length/4. - */ - private void remove() - { - // clear the entry first - heap[elements] = null; - elements--; - if (elements + DEFAULT_SIZE / 2 <= (heap.length / 4)) - { - TimerTask new_heap[] = new TimerTask[heap.length / 2]; - System.arraycopy(heap, 0, new_heap, 0, elements + 1); - heap = new_heap; - } - } - - /** - * Adds a task to the queue and puts it at the correct place - * in the heap. - */ - public synchronized void enqueue(TimerTask task) - { - // Check if it is legal to add another element - if (heap == null) - { - throw new IllegalStateException - ("cannot enqueue when stop() has been called on queue"); - } - - heap[0] = task; // sentinel - add(task); // put the new task at the end - // Now push the task up in the heap until it has reached its place - int child = elements; - int parent = child / 2; - while (heap[parent].scheduled > task.scheduled) - { - heap[child] = heap[parent]; - child = parent; - parent = child / 2; - } - // This is the correct place for the new task - heap[child] = task; - heap[0] = null; // clear sentinel - // Maybe sched() is waiting for a new element - this.notify(); - } - - /** - * Returns the top element of the queue. - * Can return null when no task is in the queue. - */ - private TimerTask top() - { - if (elements == 0) - { - return null; - } - else - { - return heap[1]; - } - } - - /** - * Returns the top task in the Queue. - * Removes the element from the heap and reorders the heap first. - * Can return null when there is nothing in the queue. - */ - public synchronized TimerTask serve() - { - // The task to return - TimerTask task = null; - - while (task == null) - { - // Get the next task - task = top(); - - // return null when asked to stop - // or if asked to return null when the queue is empty - if ((heap == null) || (task == null && nullOnEmpty)) - { - return null; - } - - // Do we have a task? - if (task != null) - { - // The time to wait until the task should be served - long time = task.scheduled - System.currentTimeMillis(); - if (time > 0) - { - // This task should not yet be served - // So wait until this task is ready - // or something else happens to the queue - task = null; // set to null to make sure we call top() - try - { - this.wait(time); - } - catch (InterruptedException _) - { - } - } - } - else - { - // wait until a task is added - // or something else happens to the queue - try - { - this.wait(); - } - catch (InterruptedException _) - { - } - } - } - - // reconstruct the heap - TimerTask lastTask = heap[elements]; - remove(); - - // drop lastTask at the beginning and move it down the heap - int parent = 1; - int child = 2; - heap[1] = lastTask; - while (child <= elements) - { - if (child < elements) - { - if (heap[child].scheduled > heap[child + 1].scheduled) - { - child++; - } - } - - if (lastTask.scheduled <= heap[child].scheduled) - break; // found the correct place (the parent) - done - - heap[parent] = heap[child]; - parent = child; - child = parent * 2; - } - - // this is the correct new place for the lastTask - heap[parent] = lastTask; - - // return the task - return task; - } - - /** - * When nullOnEmpty is true the serve() method will return null when - * there are no tasks in the queue, otherwise it will wait until - * a new element is added to the queue. It is used to indicate to - * the scheduler that no new tasks will ever be added to the queue. - */ - public synchronized void setNullOnEmpty(boolean nullOnEmpty) - { - this.nullOnEmpty = nullOnEmpty; - this.notify(); - } - - /** - * When this method is called the current and all future calls to - * serve() will return null. It is used to indicate to the Scheduler - * that it should stop executing since no more tasks will come. - */ - public synchronized void stop() - { - this.heap = null; - this.elements = 0; - this.notify(); - } - - } // TaskQueue - - /** - * The scheduler that executes all the tasks on a particular TaskQueue, - * reschedules any repeating tasks and that waits when no task has to be - * executed immediatly. Stops running when canceled or when the parent - * Timer has been finalized and no more tasks have to be executed. - */ - private static final class Scheduler implements Runnable - { - // The priority queue containing all the TimerTasks. - private TaskQueue queue; - - /** - * Creates a new Scheduler that will schedule the tasks on the - * given TaskQueue. - */ - public Scheduler(TaskQueue queue) - { - this.queue = queue; - } - - public void run() - { - TimerTask task; - while ((task = queue.serve()) != null) - { - // If this task has not been canceled - if (task.scheduled >= 0) - { - - // Mark execution time - task.lastExecutionTime = task.scheduled; - - // Repeatable task? - if (task.period < 0) - { - // Last time this task is executed - task.scheduled = -1; - } - - // Run the task - try - { - task.run(); - } - catch (ThreadDeath death) - { - // If an exception escapes, the Timer becomes invalid. - queue.stop(); - throw death; - } - catch (Throwable t) - { - // If an exception escapes, the Timer becomes invalid. - queue.stop(); - } - } - - // Calculate next time and possibly re-enqueue. - if (task.scheduled >= 0) - { - if (task.fixed) - { - task.scheduled += task.period; - } - else - { - task.scheduled = task.period + System.currentTimeMillis(); - } - - try - { - queue.enqueue(task); - } - catch (IllegalStateException ise) - { - // Ignore. Apparently the Timer queue has been stopped. - } - } - } - } - } // Scheduler - - // Number of Timers created. - // Used for creating nice Thread names. - private static int nr; - - // The queue that all the tasks are put in. - // Given to the scheduler - private TaskQueue queue; - - // The Scheduler that does all the real work - private Scheduler scheduler; - - // Used to run the scheduler. - // Also used to checked if the Thread is still running by calling - // thread.isAlive(). Sometimes a Thread is suddenly killed by the system - // (if it belonged to an Applet). - private Thread thread; - - // When cancelled we don't accept any more TimerTasks. - private boolean canceled; - - /** - * Creates a new Timer with a non daemon Thread as Scheduler, with normal - * priority and a default name. - */ - public Timer() - { - this(false); - } - - /** - * Creates a new Timer with a daemon Thread as scheduler if daemon is true, - * with normal priority and a default name. - */ - public Timer(boolean daemon) - { - this(daemon, Thread.NORM_PRIORITY); - } - - /** - * Creates a new Timer with a daemon Thread as scheduler if daemon is true, - * with the priority given and a default name. - */ - private Timer(boolean daemon, int priority) - { - this(daemon, priority, "Timer-" + (++nr)); - } - - /** - * Creates a new Timer with a daemon Thread as scheduler if daemon is true, - * with the priority and name given.E - */ - private Timer(boolean daemon, int priority, String name) - { - canceled = false; - queue = new TaskQueue(); - scheduler = new Scheduler(queue); - thread = new Thread(scheduler, name); - thread.setDaemon(daemon); - thread.setPriority(priority); - thread.start(); - } - - /** - * Cancels the execution of the scheduler. If a task is executing it will - * normally finish execution, but no other tasks will be executed and no - * more tasks can be scheduled. - */ - public void cancel() - { - canceled = true; - queue.stop(); - } - - /** - * Schedules the task at Time time, repeating every period - * milliseconds if period is positive and at a fixed rate if fixed is true. - * - * @exception IllegalArgumentException if time is negative - * @exception IllegalStateException if the task was already scheduled or - * canceled or this Timer is canceled or the scheduler thread has died - */ - private void schedule(TimerTask task, long time, long period, boolean fixed) - { - if (time < 0) - throw new IllegalArgumentException("negative time"); - - if (task.scheduled == 0 && task.lastExecutionTime == -1) - { - task.scheduled = time; - task.period = period; - task.fixed = fixed; - } - else - { - throw new IllegalStateException - ("task was already scheduled or canceled"); - } - - if (!this.canceled && this.thread != null) - { - queue.enqueue(task); - } - else - { - throw new IllegalStateException - ("timer was canceled or scheduler thread has died"); - } - } - - private static void positiveDelay(long delay) - { - if (delay < 0) - { - throw new IllegalArgumentException("delay is negative"); - } - } - - private static void positivePeriod(long period) - { - if (period < 0) - { - throw new IllegalArgumentException("period is negative"); - } - } - - /** - * Schedules the task at the specified data for one time execution. - * - * @exception IllegalArgumentException if date.getTime() is negative - * @exception IllegalStateException if the task was already scheduled or - * canceled or this Timer is canceled or the scheduler thread has died - */ - public void schedule(TimerTask task, Date date) - { - long time = date.getTime(); - schedule(task, time, -1, false); - } - - /** - * Schedules the task at the specified date and reschedules the task every - * period milliseconds after the last execution of the task finishes until - * this timer or the task is canceled. - * - * @exception IllegalArgumentException if period or date.getTime() is - * negative - * @exception IllegalStateException if the task was already scheduled or - * canceled or this Timer is canceled or the scheduler thread has died - */ - public void schedule(TimerTask task, Date date, long period) - { - positivePeriod(period); - long time = date.getTime(); - schedule(task, time, period, false); - } - - /** - * Schedules the task after the specified delay milliseconds for one time - * execution. - * - * @exception IllegalArgumentException if delay or - * System.currentTimeMillis + delay is negative - * @exception IllegalStateException if the task was already scheduled or - * canceled or this Timer is canceled or the scheduler thread has died - */ - public void schedule(TimerTask task, long delay) - { - positiveDelay(delay); - long time = System.currentTimeMillis() + delay; - schedule(task, time, -1, false); - } - - /** - * Schedules the task after the delay milliseconds and reschedules the - * task every period milliseconds after the last execution of the task - * finishes until this timer or the task is canceled. - * - * @exception IllegalArgumentException if delay or period is negative - * @exception IllegalStateException if the task was already scheduled or - * canceled or this Timer is canceled or the scheduler thread has died - */ - public void schedule(TimerTask task, long delay, long period) - { - positiveDelay(delay); - positivePeriod(period); - long time = System.currentTimeMillis() + delay; - schedule(task, time, period, false); - } - - /** - * Schedules the task at the specified date and reschedules the task at a - * fixed rate every period milliseconds until this timer or the task is - * canceled. - * - * @exception IllegalArgumentException if period or date.getTime() is - * negative - * @exception IllegalStateException if the task was already scheduled or - * canceled or this Timer is canceled or the scheduler thread has died - */ - public void scheduleAtFixedRate(TimerTask task, Date date, long period) - { - positivePeriod(period); - long time = date.getTime(); - schedule(task, time, period, true); - } - - /** - * Schedules the task after the delay milliseconds and reschedules the task - * at a fixed rate every period milliseconds until this timer or the task - * is canceled. - * - * @exception IllegalArgumentException if delay or - * System.currentTimeMillis + delay is negative - * @exception IllegalStateException if the task was already scheduled or - * canceled or this Timer is canceled or the scheduler thread has died - */ - public void scheduleAtFixedRate(TimerTask task, long delay, long period) - { - positiveDelay(delay); - positivePeriod(period); - long time = System.currentTimeMillis() + delay; - schedule(task, time, period, true); - } - - /** - * Tells the scheduler that the Timer task died - * so there will be no more new tasks scheduled. - */ - protected void finalize() throws Throwable - { - queue.setNullOnEmpty(true); - } -} diff --git a/libjava/java/util/TimerTask.java b/libjava/java/util/TimerTask.java deleted file mode 100644 index b03118ad0fe..00000000000 --- a/libjava/java/util/TimerTask.java +++ /dev/null @@ -1,145 +0,0 @@ -/* TimerTask.java -- Task that can be run at a later time if given to a Timer. - Copyright (C) 2000 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package java.util; - -/** - * Task that can be run at a later time if given to a Timer. - * The TimerTask must implement a run method that will be called by the - * Timer when the task is scheduled for execution. The task can check when - * it should have been scheduled and cancel itself when no longer needed. - * <p> - * Example: - * <pre> - * Timer timer = new Timer(); - * TimerTask task = new TimerTask() { - * public void run() { - * if (this.scheduledExecutionTime() < System.currentTimeMillis() + 500) - * // Do something - * else - * // Complain: We are more then half a second late! - * if (someStopCondition) - * this.cancel(); // This was our last execution - * }; - * timer.scheduleAtFixedRate(task, 1000, 1000); // schedule every second - * </pre> - * <p> - * Note that a TimerTask object is a one shot object and can only given once - * to a Timer. (The Timer will use the TimerTask object for bookkeeping, - * in this implementation). - * <p> - * This class also implements <code>Runnable</code> to make it possible to - * give a TimerTask directly as a target to a <code>Thread</code>. - * - * @see Timer - * @since 1.3 - * @author Mark Wielaard (mark@klomp.org) - */ -public abstract class TimerTask implements Runnable -{ - /** - * If positive the next time this task should be run. - * If negative this TimerTask is canceled or executed for the last time. - */ - long scheduled; - - /** - * If positive the last time this task was run. - * If negative this TimerTask has not yet been scheduled. - */ - long lastExecutionTime; - - /** - * If positive the number of milliseconds between runs of this task. - * If -1 this task doesn't have to be run more then once. - */ - long period; - - /** - * If true the next time this task should be run is relative to - * the last scheduled time, otherwise it can drift in time. - */ - boolean fixed; - - /** - * Creates a TimerTask and marks it as not yet scheduled. - */ - protected TimerTask() - { - this.scheduled = 0; - this.lastExecutionTime = -1; - } - - /** - * Marks the task as canceled and prevents any further execution. - * Returns true if the task was scheduled for any execution in the future - * and this cancel operation prevents that execution from happening. - * <p> - * A task that has been canceled can never be scheduled again. - * <p> - * In this implementation the TimerTask it is possible that the Timer does - * keep a reference to the TimerTask until the first time the TimerTask - * is actually scheduled. But the reference will disappear immediatly when - * cancel is called from within the TimerTask run method. - */ - public boolean cancel() - { - boolean prevented_execution = (this.scheduled >= 0); - this.scheduled = -1; - return prevented_execution; - } - - /** - * Method that is called when this task is scheduled for execution. - */ - public abstract void run(); - - /** - * Returns the last time this task was scheduled or (when called by the - * task from the run method) the time the current execution of the task - * was scheduled. When the task has not yet run the return value is - * undefined. - * <p> - * Can be used (when the task is scheduled at fixed rate) to see the - * difference between the requested schedule time and the actual time - * that can be found with <code>System.currentTimeMillis()</code>. - */ - public long scheduledExecutionTime() - { - return lastExecutionTime; - } -} diff --git a/libjava/java/util/TooManyListenersException.java b/libjava/java/util/TooManyListenersException.java deleted file mode 100644 index 92ad772f2bb..00000000000 --- a/libjava/java/util/TooManyListenersException.java +++ /dev/null @@ -1,78 +0,0 @@ -/* TooManyListenersException.java -- thrown when a unicast event can't accept - another Listener - Copyright (C) 1998, 1999, 2001, 2002, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -/** - * 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. - * - * @author Jochen Hoenicke - * @author Warren Levy (warrenl@cygnus.com) - * @see EventListener - * @see EventObject - * @since 1.1 - * @status updated to 1.4 - */ -public class TooManyListenersException extends Exception -{ - /** - * Compatible with JDK 1.1+. - */ - private static final long serialVersionUID = 5074640544770687831L; - - /** - * Constructs a TooManyListenersException with no detail message. - */ - public TooManyListenersException() - { - } - - /** - * Constructs a TooManyListenersException with a detail message. - * - * @param detail the detail message - */ - public TooManyListenersException(String detail) - { - super(detail); - } -} diff --git a/libjava/java/util/TreeMap.java b/libjava/java/util/TreeMap.java deleted file mode 100644 index bddf97d9a33..00000000000 --- a/libjava/java/util/TreeMap.java +++ /dev/null @@ -1,1781 +0,0 @@ -/* TreeMap.java -- a class providing a basic Red-Black Tree data structure, - mapping Object --> Object - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; - -/** - * This class provides a red-black tree implementation of the SortedMap - * interface. Elements in the Map will be sorted by either a user-provided - * Comparator object, or by the natural ordering of the keys. - * - * The algorithms are adopted from Corman, Leiserson, and Rivest's - * <i>Introduction to Algorithms.</i> TreeMap guarantees O(log n) - * insertion and deletion of elements. That being said, there is a large - * enough constant coefficient in front of that "log n" (overhead involved - * in keeping the tree balanced), that TreeMap may not be the best choice - * for small collections. If something is already sorted, you may want to - * just use a LinkedHashMap to maintain the order while providing O(1) access. - * - * TreeMap is a part of the JDK1.2 Collections API. Null keys are allowed - * only if a Comparator is used which can deal with them; natural ordering - * cannot cope with null. Null values are always allowed. Note that the - * ordering must be <i>consistent with equals</i> to correctly implement - * the Map interface. If this condition is violated, the map is still - * well-behaved, but you may have suprising results when comparing it to - * other maps.<p> - * - * This implementation is not synchronized. If you need to share this between - * multiple threads, do something like:<br> - * <code>SortedMap m - * = Collections.synchronizedSortedMap(new TreeMap(...));</code><p> - * - * The iterators are <i>fail-fast</i>, meaning that any structural - * modification, except for <code>remove()</code> called on the iterator - * itself, cause the iterator to throw a - * <code>ConcurrentModificationException</code> rather than exhibit - * non-deterministic behavior. - * - * @author Jon Zeppieri - * @author Bryce McKinlay - * @author Eric Blake (ebb9@email.byu.edu) - * @see Map - * @see HashMap - * @see Hashtable - * @see LinkedHashMap - * @see Comparable - * @see Comparator - * @see Collection - * @see Collections#synchronizedSortedMap(SortedMap) - * @since 1.2 - * @status updated to 1.4 - */ -public class TreeMap extends AbstractMap - implements SortedMap, Cloneable, Serializable -{ - // Implementation note: - // A red-black tree is a binary search tree with the additional properties - // that all paths to a leaf node visit the same number of black nodes, - // and no red node has red children. To avoid some null-pointer checks, - // we use the special node nil which is always black, has no relatives, - // and has key and value of null (but is not equal to a mapping of null). - - /** - * Compatible with JDK 1.2. - */ - private static final long serialVersionUID = 919286545866124006L; - - /** - * Color status of a node. Package visible for use by nested classes. - */ - static final int RED = -1, - BLACK = 1; - - /** - * Sentinal node, used to avoid null checks for corner cases and make the - * delete rebalance code simpler. The rebalance code must never assign - * the parent, left, or right of nil, but may safely reassign the color - * to be black. This object must never be used as a key in a TreeMap, or - * it will break bounds checking of a SubMap. - */ - static final Node nil = new Node(null, null, BLACK); - static - { - // Nil is self-referential, so we must initialize it after creation. - nil.parent = nil; - nil.left = nil; - nil.right = nil; - } - - /** - * The root node of this TreeMap. - */ - private transient Node root; - - /** - * The size of this TreeMap. Package visible for use by nested classes. - */ - transient int size; - - /** - * The cache for {@link #entrySet()}. - */ - private transient Set entries; - - /** - * Counts the number of modifications this TreeMap has undergone, used - * by Iterators to know when to throw ConcurrentModificationExceptions. - * Package visible for use by nested classes. - */ - transient int modCount; - - /** - * This TreeMap's comparator, or null for natural ordering. - * Package visible for use by nested classes. - * @serial the comparator ordering this tree, or null - */ - final Comparator comparator; - - /** - * Class to represent an entry in the tree. Holds a single key-value pair, - * plus pointers to parent and child nodes. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class Node extends AbstractMap.BasicMapEntry - { - // All fields package visible for use by nested classes. - /** The color of this node. */ - int color; - - /** The left child node. */ - Node left = nil; - /** The right child node. */ - Node right = nil; - /** The parent node. */ - Node parent = nil; - - /** - * Simple constructor. - * @param key the key - * @param value the value - */ - Node(Object key, Object value, int color) - { - super(key, value); - this.color = color; - } - } - - /** - * Instantiate a new TreeMap with no elements, using the keys' natural - * ordering to sort. All entries in the map must have a key which implements - * Comparable, and which are <i>mutually comparable</i>, otherwise map - * operations may throw a {@link ClassCastException}. Attempts to use - * a null key will throw a {@link NullPointerException}. - * - * @see Comparable - */ - public TreeMap() - { - this((Comparator) null); - } - - /** - * Instantiate a new TreeMap with no elements, using the provided comparator - * to sort. All entries in the map must have keys which are mutually - * comparable by the Comparator, otherwise map operations may throw a - * {@link ClassCastException}. - * - * @param comparator the sort order for the keys of this map, or null - * for the natural order - */ - public TreeMap(Comparator c) - { - comparator = c; - fabricateTree(0); - } - - /** - * Instantiate a new TreeMap, initializing it with all of the elements in - * the provided Map. The elements will be sorted using the natural - * ordering of the keys. This algorithm runs in n*log(n) time. All entries - * in the map must have keys which implement Comparable and are mutually - * comparable, otherwise map operations may throw a - * {@link ClassCastException}. - * - * @param map a Map, whose entries will be put into this TreeMap - * @throws ClassCastException if the keys in the provided Map are not - * comparable - * @throws NullPointerException if map is null - * @see Comparable - */ - public TreeMap(Map map) - { - this((Comparator) null); - putAll(map); - } - - /** - * Instantiate a new TreeMap, initializing it with all of the elements in - * the provided SortedMap. The elements will be sorted using the same - * comparator as in the provided SortedMap. This runs in linear time. - * - * @param sm a SortedMap, whose entries will be put into this TreeMap - * @throws NullPointerException if sm is null - */ - public TreeMap(SortedMap sm) - { - this(sm.comparator()); - int pos = sm.size(); - Iterator itr = sm.entrySet().iterator(); - - fabricateTree(pos); - Node node = firstNode(); - - while (--pos >= 0) - { - Map.Entry me = (Map.Entry) itr.next(); - node.key = me.getKey(); - node.value = me.getValue(); - node = successor(node); - } - } - - /** - * Clears the Map so it has no keys. This is O(1). - */ - public void clear() - { - if (size > 0) - { - modCount++; - root = nil; - size = 0; - } - } - - /** - * Returns a shallow clone of this TreeMap. The Map itself is cloned, - * but its contents are not. - * - * @return the clone - */ - public Object clone() - { - TreeMap copy = null; - try - { - copy = (TreeMap) super.clone(); - } - catch (CloneNotSupportedException x) - { - } - copy.entries = null; - copy.fabricateTree(size); - - Node node = firstNode(); - Node cnode = copy.firstNode(); - - while (node != nil) - { - cnode.key = node.key; - cnode.value = node.value; - node = successor(node); - cnode = copy.successor(cnode); - } - return copy; - } - - /** - * Return the comparator used to sort this map, or null if it is by - * natural order. - * - * @return the map's comparator - */ - public Comparator comparator() - { - return comparator; - } - - /** - * Returns true if the map contains a mapping for the given key. - * - * @param key the key to look for - * @return true if the key has a mapping - * @throws ClassCastException if key is not comparable to map elements - * @throws NullPointerException if key is null and the comparator is not - * tolerant of nulls - */ - public boolean containsKey(Object key) - { - return getNode(key) != nil; - } - - /** - * Returns true if the map contains at least one mapping to the given value. - * This requires linear time. - * - * @param value the value to look for - * @return true if the value appears in a mapping - */ - public boolean containsValue(Object value) - { - Node node = firstNode(); - while (node != nil) - { - if (equals(value, node.value)) - return true; - node = successor(node); - } - return false; - } - - /** - * Returns a "set view" of this TreeMap's entries. The set is backed by - * the TreeMap, so changes in one show up in the other. The set supports - * element removal, but not element addition.<p> - * - * Note that the iterators for all three views, from keySet(), entrySet(), - * and values(), traverse the TreeMap in sorted sequence. - * - * @return a set view of the entries - * @see #keySet() - * @see #values() - * @see Map.Entry - */ - public Set entrySet() - { - if (entries == null) - // Create an AbstractSet with custom implementations of those methods - // that can be overriden easily and efficiently. - entries = new AbstractSet() - { - public int size() - { - return size; - } - - public Iterator iterator() - { - return new TreeIterator(ENTRIES); - } - - public void clear() - { - TreeMap.this.clear(); - } - - public boolean contains(Object o) - { - if (! (o instanceof Map.Entry)) - return false; - Map.Entry me = (Map.Entry) o; - Node n = getNode(me.getKey()); - return n != nil && AbstractSet.equals(me.getValue(), n.value); - } - - public boolean remove(Object o) - { - if (! (o instanceof Map.Entry)) - return false; - Map.Entry me = (Map.Entry) o; - Node n = getNode(me.getKey()); - if (n != nil && AbstractSet.equals(me.getValue(), n.value)) - { - removeNode(n); - return true; - } - return false; - } - }; - return entries; - } - - /** - * Returns the first (lowest) key in the map. - * - * @return the first key - * @throws NoSuchElementException if the map is empty - */ - public Object firstKey() - { - if (root == nil) - throw new NoSuchElementException(); - return firstNode().key; - } - - /** - * Return the value in this TreeMap associated with the supplied key, - * or <code>null</code> if the key maps to nothing. NOTE: Since the value - * could also be null, you must use containsKey to see if this key - * actually maps to something. - * - * @param key the key for which to fetch an associated value - * @return what the key maps to, if present - * @throws ClassCastException if key is not comparable to elements in the map - * @throws NullPointerException if key is null but the comparator does not - * tolerate nulls - * @see #put(Object, Object) - * @see #containsKey(Object) - */ - public Object get(Object key) - { - // Exploit fact that nil.value == null. - return getNode(key).value; - } - - /** - * Returns a view of this Map including all entries with keys less than - * <code>toKey</code>. The returned map is backed by the original, so changes - * in one appear in the other. The submap will throw an - * {@link IllegalArgumentException} for any attempt to access or add an - * element beyond the specified cutoff. The returned map does not include - * the endpoint; if you want inclusion, pass the successor element. - * - * @param toKey the (exclusive) cutoff point - * @return a view of the map less than the cutoff - * @throws ClassCastException if <code>toKey</code> is not compatible with - * the comparator (or is not Comparable, for natural ordering) - * @throws NullPointerException if toKey is null, but the comparator does not - * tolerate null elements - */ - public SortedMap headMap(Object toKey) - { - return new SubMap(nil, toKey); - } - - /** - * Returns a "set view" of this TreeMap's keys. The set is backed by the - * TreeMap, so changes in one show up in the other. The set supports - * element removal, but not element addition. - * - * @return a set view of the keys - * @see #values() - * @see #entrySet() - */ - public Set keySet() - { - if (keys == null) - // Create an AbstractSet with custom implementations of those methods - // that can be overriden easily and efficiently. - keys = new AbstractSet() - { - public int size() - { - return size; - } - - public Iterator iterator() - { - return new TreeIterator(KEYS); - } - - public void clear() - { - TreeMap.this.clear(); - } - - public boolean contains(Object o) - { - return containsKey(o); - } - - public boolean remove(Object key) - { - Node n = getNode(key); - if (n == nil) - return false; - removeNode(n); - return true; - } - }; - return keys; - } - - /** - * Returns the last (highest) key in the map. - * - * @return the last key - * @throws NoSuchElementException if the map is empty - */ - public Object lastKey() - { - if (root == nil) - throw new NoSuchElementException("empty"); - return lastNode().key; - } - - /** - * Puts the supplied value into the Map, mapped by the supplied key. - * The value may be retrieved by any object which <code>equals()</code> - * this key. NOTE: Since the prior value could also be null, you must - * first use containsKey if you want to see if you are replacing the - * key's mapping. - * - * @param key the key used to locate the value - * @param value the value to be stored in the Map - * @return the prior mapping of the key, or null if there was none - * @throws ClassCastException if key is not comparable to current map keys - * @throws NullPointerException if key is null, but the comparator does - * not tolerate nulls - * @see #get(Object) - * @see Object#equals(Object) - */ - public Object put(Object key, Object value) - { - Node current = root; - Node parent = nil; - int comparison = 0; - - // Find new node's parent. - while (current != nil) - { - parent = current; - comparison = compare(key, current.key); - if (comparison > 0) - current = current.right; - else if (comparison < 0) - current = current.left; - else // Key already in tree. - return current.setValue(value); - } - - // Set up new node. - Node n = new Node(key, value, RED); - n.parent = parent; - - // Insert node in tree. - modCount++; - size++; - if (parent == nil) - { - // Special case inserting into an empty tree. - root = n; - return null; - } - if (comparison > 0) - parent.right = n; - else - parent.left = n; - - // Rebalance after insert. - insertFixup(n); - return null; - } - - /** - * Copies all elements of the given map into this TreeMap. If this map - * already has a mapping for a key, the new mapping replaces the current - * one. - * - * @param m the map to be added - * @throws ClassCastException if a key in m is not comparable with keys - * in the map - * @throws NullPointerException if a key in m is null, and the comparator - * does not tolerate nulls - */ - public void putAll(Map m) - { - Iterator itr = m.entrySet().iterator(); - int pos = m.size(); - while (--pos >= 0) - { - Map.Entry e = (Map.Entry) itr.next(); - put(e.getKey(), e.getValue()); - } - } - - /** - * Removes from the TreeMap and returns the value which is mapped by the - * supplied key. If the key maps to nothing, then the TreeMap remains - * unchanged, and <code>null</code> is returned. NOTE: Since the value - * could also be null, you must use containsKey to see if you are - * actually removing a mapping. - * - * @param key the key used to locate the value to remove - * @return whatever the key mapped to, if present - * @throws ClassCastException if key is not comparable to current map keys - * @throws NullPointerException if key is null, but the comparator does - * not tolerate nulls - */ - public Object remove(Object key) - { - Node n = getNode(key); - if (n == nil) - return null; - // Note: removeNode can alter the contents of n, so save value now. - Object result = n.value; - removeNode(n); - return result; - } - - /** - * Returns the number of key-value mappings currently in this Map. - * - * @return the size - */ - public int size() - { - return size; - } - - /** - * Returns a view of this Map including all entries with keys greater or - * equal to <code>fromKey</code> and less than <code>toKey</code> (a - * half-open interval). The returned map is backed by the original, so - * changes in one appear in the other. The submap will throw an - * {@link IllegalArgumentException} for any attempt to access or add an - * element beyond the specified cutoffs. The returned map includes the low - * endpoint but not the high; if you want to reverse this behavior on - * either end, pass in the successor element. - * - * @param fromKey the (inclusive) low cutoff point - * @param toKey the (exclusive) high cutoff point - * @return a view of the map between the cutoffs - * @throws ClassCastException if either cutoff is not compatible with - * the comparator (or is not Comparable, for natural ordering) - * @throws NullPointerException if fromKey or toKey is null, but the - * comparator does not tolerate null elements - * @throws IllegalArgumentException if fromKey is greater than toKey - */ - public SortedMap subMap(Object fromKey, Object toKey) - { - return new SubMap(fromKey, toKey); - } - - /** - * Returns a view of this Map including all entries with keys greater or - * equal to <code>fromKey</code>. The returned map is backed by the - * original, so changes in one appear in the other. The submap will throw an - * {@link IllegalArgumentException} for any attempt to access or add an - * element beyond the specified cutoff. The returned map includes the - * endpoint; if you want to exclude it, pass in the successor element. - * - * @param fromKey the (inclusive) low cutoff point - * @return a view of the map above the cutoff - * @throws ClassCastException if <code>fromKey</code> is not compatible with - * the comparator (or is not Comparable, for natural ordering) - * @throws NullPointerException if fromKey is null, but the comparator - * does not tolerate null elements - */ - public SortedMap tailMap(Object fromKey) - { - return new SubMap(fromKey, nil); - } - - /** - * Returns a "collection view" (or "bag view") of this TreeMap's values. - * The collection is backed by the TreeMap, so changes in one show up - * in the other. The collection supports element removal, but not element - * addition. - * - * @return a bag view of the values - * @see #keySet() - * @see #entrySet() - */ - public Collection values() - { - if (values == null) - // We don't bother overriding many of the optional methods, as doing so - // wouldn't provide any significant performance advantage. - values = new AbstractCollection() - { - public int size() - { - return size; - } - - public Iterator iterator() - { - return new TreeIterator(VALUES); - } - - public void clear() - { - TreeMap.this.clear(); - } - }; - return values; - } - - /** - * Compares two elements by the set comparator, or by natural ordering. - * Package visible for use by nested classes. - * - * @param o1 the first object - * @param o2 the second object - * @throws ClassCastException if o1 and o2 are not mutually comparable, - * or are not Comparable with natural ordering - * @throws NullPointerException if o1 or o2 is null with natural ordering - */ - final int compare(Object o1, Object o2) - { - return (comparator == null - ? ((Comparable) o1).compareTo(o2) - : comparator.compare(o1, o2)); - } - - /** - * Maintain red-black balance after deleting a node. - * - * @param node the child of the node just deleted, possibly nil - * @param parent the parent of the node just deleted, never nil - */ - private void deleteFixup(Node node, Node parent) - { - // if (parent == nil) - // throw new InternalError(); - // If a black node has been removed, we need to rebalance to avoid - // violating the "same number of black nodes on any path" rule. If - // node is red, we can simply recolor it black and all is well. - while (node != root && node.color == BLACK) - { - if (node == parent.left) - { - // Rebalance left side. - Node sibling = parent.right; - // if (sibling == nil) - // throw new InternalError(); - if (sibling.color == RED) - { - // Case 1: Sibling is red. - // Recolor sibling and parent, and rotate parent left. - sibling.color = BLACK; - parent.color = RED; - rotateLeft(parent); - sibling = parent.right; - } - - if (sibling.left.color == BLACK && sibling.right.color == BLACK) - { - // Case 2: Sibling has no red children. - // Recolor sibling, and move to parent. - sibling.color = RED; - node = parent; - parent = parent.parent; - } - else - { - if (sibling.right.color == BLACK) - { - // Case 3: Sibling has red left child. - // Recolor sibling and left child, rotate sibling right. - sibling.left.color = BLACK; - sibling.color = RED; - rotateRight(sibling); - sibling = parent.right; - } - // Case 4: Sibling has red right child. Recolor sibling, - // right child, and parent, and rotate parent left. - sibling.color = parent.color; - parent.color = BLACK; - sibling.right.color = BLACK; - rotateLeft(parent); - node = root; // Finished. - } - } - else - { - // Symmetric "mirror" of left-side case. - Node sibling = parent.left; - // if (sibling == nil) - // throw new InternalError(); - if (sibling.color == RED) - { - // Case 1: Sibling is red. - // Recolor sibling and parent, and rotate parent right. - sibling.color = BLACK; - parent.color = RED; - rotateRight(parent); - sibling = parent.left; - } - - if (sibling.right.color == BLACK && sibling.left.color == BLACK) - { - // Case 2: Sibling has no red children. - // Recolor sibling, and move to parent. - sibling.color = RED; - node = parent; - parent = parent.parent; - } - else - { - if (sibling.left.color == BLACK) - { - // Case 3: Sibling has red right child. - // Recolor sibling and right child, rotate sibling left. - sibling.right.color = BLACK; - sibling.color = RED; - rotateLeft(sibling); - sibling = parent.left; - } - // Case 4: Sibling has red left child. Recolor sibling, - // left child, and parent, and rotate parent right. - sibling.color = parent.color; - parent.color = BLACK; - sibling.left.color = BLACK; - rotateRight(parent); - node = root; // Finished. - } - } - } - node.color = BLACK; - } - - /** - * Construct a perfectly balanced tree consisting of n "blank" nodes. This - * permits a tree to be generated from pre-sorted input in linear time. - * - * @param count the number of blank nodes, non-negative - */ - private void fabricateTree(final int count) - { - if (count == 0) - { - root = nil; - size = 0; - return; - } - - // We color every row of nodes black, except for the overflow nodes. - // I believe that this is the optimal arrangement. We construct the tree - // in place by temporarily linking each node to the next node in the row, - // then updating those links to the children when working on the next row. - - // Make the root node. - root = new Node(null, null, BLACK); - size = count; - Node row = root; - int rowsize; - - // Fill each row that is completely full of nodes. - for (rowsize = 2; rowsize + rowsize <= count; rowsize <<= 1) - { - Node parent = row; - Node last = null; - for (int i = 0; i < rowsize; i += 2) - { - Node left = new Node(null, null, BLACK); - Node right = new Node(null, null, BLACK); - left.parent = parent; - left.right = right; - right.parent = parent; - parent.left = left; - Node next = parent.right; - parent.right = right; - parent = next; - if (last != null) - last.right = left; - last = right; - } - row = row.left; - } - - // Now do the partial final row in red. - int overflow = count - rowsize; - Node parent = row; - int i; - for (i = 0; i < overflow; i += 2) - { - Node left = new Node(null, null, RED); - Node right = new Node(null, null, RED); - left.parent = parent; - right.parent = parent; - parent.left = left; - Node next = parent.right; - parent.right = right; - parent = next; - } - // Add a lone left node if necessary. - if (i - overflow == 0) - { - Node left = new Node(null, null, RED); - left.parent = parent; - parent.left = left; - parent = parent.right; - left.parent.right = nil; - } - // Unlink the remaining nodes of the previous row. - while (parent != nil) - { - Node next = parent.right; - parent.right = nil; - parent = next; - } - } - - /** - * Returns the first sorted node in the map, or nil if empty. Package - * visible for use by nested classes. - * - * @return the first node - */ - final Node firstNode() - { - // Exploit fact that nil.left == nil. - Node node = root; - while (node.left != nil) - node = node.left; - return node; - } - - /** - * Return the TreeMap.Node associated with key, or the nil node if no such - * node exists in the tree. Package visible for use by nested classes. - * - * @param key the key to search for - * @return the node where the key is found, or nil - */ - final Node getNode(Object key) - { - Node current = root; - while (current != nil) - { - int comparison = compare(key, current.key); - if (comparison > 0) - current = current.right; - else if (comparison < 0) - current = current.left; - else - return current; - } - return current; - } - - /** - * Find the "highest" node which is < key. If key is nil, return last - * node. Package visible for use by nested classes. - * - * @param key the upper bound, exclusive - * @return the previous node - */ - final Node highestLessThan(Object key) - { - if (key == nil) - return lastNode(); - - Node last = nil; - Node current = root; - int comparison = 0; - - while (current != nil) - { - last = current; - comparison = compare(key, current.key); - if (comparison > 0) - current = current.right; - else if (comparison < 0) - current = current.left; - else // Exact match. - return predecessor(last); - } - return comparison <= 0 ? predecessor(last) : last; - } - - /** - * Maintain red-black balance after inserting a new node. - * - * @param n the newly inserted node - */ - private void insertFixup(Node n) - { - // Only need to rebalance when parent is a RED node, and while at least - // 2 levels deep into the tree (ie: node has a grandparent). Remember - // that nil.color == BLACK. - while (n.parent.color == RED && n.parent.parent != nil) - { - if (n.parent == n.parent.parent.left) - { - Node uncle = n.parent.parent.right; - // Uncle may be nil, in which case it is BLACK. - if (uncle.color == RED) - { - // Case 1. Uncle is RED: Change colors of parent, uncle, - // and grandparent, and move n to grandparent. - n.parent.color = BLACK; - uncle.color = BLACK; - uncle.parent.color = RED; - n = uncle.parent; - } - else - { - if (n == n.parent.right) - { - // Case 2. Uncle is BLACK and x is right child. - // Move n to parent, and rotate n left. - n = n.parent; - rotateLeft(n); - } - // Case 3. Uncle is BLACK and x is left child. - // Recolor parent, grandparent, and rotate grandparent right. - n.parent.color = BLACK; - n.parent.parent.color = RED; - rotateRight(n.parent.parent); - } - } - else - { - // Mirror image of above code. - Node uncle = n.parent.parent.left; - // Uncle may be nil, in which case it is BLACK. - if (uncle.color == RED) - { - // Case 1. Uncle is RED: Change colors of parent, uncle, - // and grandparent, and move n to grandparent. - n.parent.color = BLACK; - uncle.color = BLACK; - uncle.parent.color = RED; - n = uncle.parent; - } - else - { - if (n == n.parent.left) - { - // Case 2. Uncle is BLACK and x is left child. - // Move n to parent, and rotate n right. - n = n.parent; - rotateRight(n); - } - // Case 3. Uncle is BLACK and x is right child. - // Recolor parent, grandparent, and rotate grandparent left. - n.parent.color = BLACK; - n.parent.parent.color = RED; - rotateLeft(n.parent.parent); - } - } - } - root.color = BLACK; - } - - /** - * Returns the last sorted node in the map, or nil if empty. - * - * @return the last node - */ - private Node lastNode() - { - // Exploit fact that nil.right == nil. - Node node = root; - while (node.right != nil) - node = node.right; - return node; - } - - /** - * Find the "lowest" node which is >= key. If key is nil, return either - * nil or the first node, depending on the parameter first. - * Package visible for use by nested classes. - * - * @param key the lower bound, inclusive - * @param first true to return the first element instead of nil for nil key - * @return the next node - */ - final Node lowestGreaterThan(Object key, boolean first) - { - if (key == nil) - return first ? firstNode() : nil; - - Node last = nil; - Node current = root; - int comparison = 0; - - while (current != nil) - { - last = current; - comparison = compare(key, current.key); - if (comparison > 0) - current = current.right; - else if (comparison < 0) - current = current.left; - else - return current; - } - return comparison > 0 ? successor(last) : last; - } - - /** - * Return the node preceding the given one, or nil if there isn't one. - * - * @param node the current node, not nil - * @return the prior node in sorted order - */ - private Node predecessor(Node node) - { - if (node.left != nil) - { - node = node.left; - while (node.right != nil) - node = node.right; - return node; - } - - Node parent = node.parent; - // Exploit fact that nil.left == nil and node is non-nil. - while (node == parent.left) - { - node = parent; - parent = node.parent; - } - return parent; - } - - /** - * Construct a tree from sorted keys in linear time. Package visible for - * use by TreeSet. - * - * @param s the stream to read from - * @param count the number of keys to read - * @param readValue true to read values, false to insert "" as the value - * @throws ClassNotFoundException if the underlying stream fails - * @throws IOException if the underlying stream fails - * @see #readObject(ObjectInputStream) - * @see TreeSet#readObject(ObjectInputStream) - */ - final void putFromObjStream(ObjectInputStream s, int count, - boolean readValues) - throws IOException, ClassNotFoundException - { - fabricateTree(count); - Node node = firstNode(); - - while (--count >= 0) - { - node.key = s.readObject(); - node.value = readValues ? s.readObject() : ""; - node = successor(node); - } - } - - /** - * Construct a tree from sorted keys in linear time, with values of "". - * Package visible for use by TreeSet. - * - * @param keys the iterator over the sorted keys - * @param count the number of nodes to insert - * @see TreeSet#TreeSet(SortedSet) - */ - final void putKeysLinear(Iterator keys, int count) - { - fabricateTree(count); - Node node = firstNode(); - - while (--count >= 0) - { - node.key = keys.next(); - node.value = ""; - node = successor(node); - } - } - - /** - * Deserializes this object from the given stream. - * - * @param s the stream to read from - * @throws ClassNotFoundException if the underlying stream fails - * @throws IOException if the underlying stream fails - * @serialData the <i>size</i> (int), followed by key (Object) and value - * (Object) pairs in sorted order - */ - private void readObject(ObjectInputStream s) - throws IOException, ClassNotFoundException - { - s.defaultReadObject(); - int size = s.readInt(); - putFromObjStream(s, size, true); - } - - /** - * Remove node from tree. This will increment modCount and decrement size. - * Node must exist in the tree. Package visible for use by nested classes. - * - * @param node the node to remove - */ - final void removeNode(Node node) - { - Node splice; - Node child; - - modCount++; - size--; - - // Find splice, the node at the position to actually remove from the tree. - if (node.left == nil) - { - // Node to be deleted has 0 or 1 children. - splice = node; - child = node.right; - } - else if (node.right == nil) - { - // Node to be deleted has 1 child. - splice = node; - child = node.left; - } - else - { - // Node has 2 children. Splice is node's predecessor, and we swap - // its contents into node. - splice = node.left; - while (splice.right != nil) - splice = splice.right; - child = splice.left; - node.key = splice.key; - node.value = splice.value; - } - - // Unlink splice from the tree. - Node parent = splice.parent; - if (child != nil) - child.parent = parent; - if (parent == nil) - { - // Special case for 0 or 1 node remaining. - root = child; - return; - } - if (splice == parent.left) - parent.left = child; - else - parent.right = child; - - if (splice.color == BLACK) - deleteFixup(child, parent); - } - - /** - * Rotate node n to the left. - * - * @param node the node to rotate - */ - private void rotateLeft(Node node) - { - Node child = node.right; - // if (node == nil || child == nil) - // throw new InternalError(); - - // Establish node.right link. - node.right = child.left; - if (child.left != nil) - child.left.parent = node; - - // Establish child->parent link. - child.parent = node.parent; - if (node.parent != nil) - { - if (node == node.parent.left) - node.parent.left = child; - else - node.parent.right = child; - } - else - root = child; - - // Link n and child. - child.left = node; - node.parent = child; - } - - /** - * Rotate node n to the right. - * - * @param node the node to rotate - */ - private void rotateRight(Node node) - { - Node child = node.left; - // if (node == nil || child == nil) - // throw new InternalError(); - - // Establish node.left link. - node.left = child.right; - if (child.right != nil) - child.right.parent = node; - - // Establish child->parent link. - child.parent = node.parent; - if (node.parent != nil) - { - if (node == node.parent.right) - node.parent.right = child; - else - node.parent.left = child; - } - else - root = child; - - // Link n and child. - child.right = node; - node.parent = child; - } - - /** - * Return the node following the given one, or nil if there isn't one. - * Package visible for use by nested classes. - * - * @param node the current node, not nil - * @return the next node in sorted order - */ - final Node successor(Node node) - { - if (node.right != nil) - { - node = node.right; - while (node.left != nil) - node = node.left; - return node; - } - - Node parent = node.parent; - // Exploit fact that nil.right == nil and node is non-nil. - while (node == parent.right) - { - node = parent; - parent = parent.parent; - } - return parent; - } - - /** - * Serializes this object to the given stream. - * - * @param s the stream to write to - * @throws IOException if the underlying stream fails - * @serialData the <i>size</i> (int), followed by key (Object) and value - * (Object) pairs in sorted order - */ - private void writeObject(ObjectOutputStream s) throws IOException - { - s.defaultWriteObject(); - - Node node = firstNode(); - s.writeInt(size); - while (node != nil) - { - s.writeObject(node.key); - s.writeObject(node.value); - node = successor(node); - } - } - - /** - * Iterate over TreeMap's entries. This implementation is parameterized - * to give a sequential view of keys, values, or entries. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private final class TreeIterator implements Iterator - { - /** - * The type of this Iterator: {@link #KEYS}, {@link #VALUES}, - * or {@link #ENTRIES}. - */ - private final int type; - /** The number of modifications to the backing Map that we know about. */ - private int knownMod = modCount; - /** The last Entry returned by a next() call. */ - private Node last; - /** The next entry that should be returned by next(). */ - private Node next; - /** - * The last node visible to this iterator. This is used when iterating - * on a SubMap. - */ - private final Node max; - - /** - * Construct a new TreeIterator with the supplied type. - * @param type {@link #KEYS}, {@link #VALUES}, or {@link #ENTRIES} - */ - TreeIterator(int type) - { - // FIXME gcj cannot handle this. Bug java/4695 - // this(type, firstNode(), nil); - this.type = type; - this.next = firstNode(); - this.max = nil; - } - - /** - * Construct a new TreeIterator with the supplied type. Iteration will - * be from "first" (inclusive) to "max" (exclusive). - * - * @param type {@link #KEYS}, {@link #VALUES}, or {@link #ENTRIES} - * @param first where to start iteration, nil for empty iterator - * @param max the cutoff for iteration, nil for all remaining nodes - */ - TreeIterator(int type, Node first, Node max) - { - this.type = type; - this.next = first; - this.max = max; - } - - /** - * Returns true if the Iterator has more elements. - * @return true if there are more elements - * @throws ConcurrentModificationException if the TreeMap was modified - */ - public boolean hasNext() - { - if (knownMod != modCount) - throw new ConcurrentModificationException(); - return next != max; - } - - /** - * Returns the next element in the Iterator's sequential view. - * @return the next element - * @throws ConcurrentModificationException if the TreeMap was modified - * @throws NoSuchElementException if there is none - */ - public Object next() - { - if (knownMod != modCount) - throw new ConcurrentModificationException(); - if (next == max) - throw new NoSuchElementException(); - last = next; - next = successor(last); - - if (type == VALUES) - return last.value; - else if (type == KEYS) - return last.key; - return last; - } - - /** - * Removes from the backing TreeMap the last element which was fetched - * with the <code>next()</code> method. - * @throws ConcurrentModificationException if the TreeMap was modified - * @throws IllegalStateException if called when there is no last element - */ - public void remove() - { - if (last == null) - throw new IllegalStateException(); - if (knownMod != modCount) - throw new ConcurrentModificationException(); - - removeNode(last); - last = null; - knownMod++; - } - } // class TreeIterator - - /** - * Implementation of {@link #subMap(Object, Object)} and other map - * ranges. This class provides a view of a portion of the original backing - * map, and throws {@link IllegalArgumentException} for attempts to - * access beyond that range. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private final class SubMap extends AbstractMap implements SortedMap - { - /** - * The lower range of this view, inclusive, or nil for unbounded. - * Package visible for use by nested classes. - */ - final Object minKey; - - /** - * The upper range of this view, exclusive, or nil for unbounded. - * Package visible for use by nested classes. - */ - final Object maxKey; - - /** - * The cache for {@link #entrySet()}. - */ - private Set entries; - - /** - * Create a SubMap representing the elements between minKey (inclusive) - * and maxKey (exclusive). If minKey is nil, SubMap has no lower bound - * (headMap). If maxKey is nil, the SubMap has no upper bound (tailMap). - * - * @param minKey the lower bound - * @param maxKey the upper bound - * @throws IllegalArgumentException if minKey > maxKey - */ - SubMap(Object minKey, Object maxKey) - { - if (minKey != nil && maxKey != nil && compare(minKey, maxKey) > 0) - throw new IllegalArgumentException("fromKey > toKey"); - this.minKey = minKey; - this.maxKey = maxKey; - } - - /** - * Check if "key" is in within the range bounds for this SubMap. The - * lower ("from") SubMap range is inclusive, and the upper ("to") bound - * is exclusive. Package visible for use by nested classes. - * - * @param key the key to check - * @return true if the key is in range - */ - boolean keyInRange(Object key) - { - return ((minKey == nil || compare(key, minKey) >= 0) - && (maxKey == nil || compare(key, maxKey) < 0)); - } - - public void clear() - { - Node next = lowestGreaterThan(minKey, true); - Node max = lowestGreaterThan(maxKey, false); - while (next != max) - { - Node current = next; - next = successor(current); - removeNode(current); - } - } - - public Comparator comparator() - { - return comparator; - } - - public boolean containsKey(Object key) - { - return keyInRange(key) && TreeMap.this.containsKey(key); - } - - public boolean containsValue(Object value) - { - Node node = lowestGreaterThan(minKey, true); - Node max = lowestGreaterThan(maxKey, false); - while (node != max) - { - if (equals(value, node.getValue())) - return true; - node = successor(node); - } - return false; - } - - public Set entrySet() - { - if (entries == null) - // Create an AbstractSet with custom implementations of those methods - // that can be overriden easily and efficiently. - entries = new AbstractSet() - { - public int size() - { - return SubMap.this.size(); - } - - public Iterator iterator() - { - Node first = lowestGreaterThan(minKey, true); - Node max = lowestGreaterThan(maxKey, false); - return new TreeIterator(ENTRIES, first, max); - } - - public void clear() - { - SubMap.this.clear(); - } - - public boolean contains(Object o) - { - if (! (o instanceof Map.Entry)) - return false; - Map.Entry me = (Map.Entry) o; - Object key = me.getKey(); - if (! keyInRange(key)) - return false; - Node n = getNode(key); - return n != nil && AbstractSet.equals(me.getValue(), n.value); - } - - public boolean remove(Object o) - { - if (! (o instanceof Map.Entry)) - return false; - Map.Entry me = (Map.Entry) o; - Object key = me.getKey(); - if (! keyInRange(key)) - return false; - Node n = getNode(key); - if (n != nil && AbstractSet.equals(me.getValue(), n.value)) - { - removeNode(n); - return true; - } - return false; - } - }; - return entries; - } - - public Object firstKey() - { - Node node = lowestGreaterThan(minKey, true); - if (node == nil || ! keyInRange(node.key)) - throw new NoSuchElementException(); - return node.key; - } - - public Object get(Object key) - { - if (keyInRange(key)) - return TreeMap.this.get(key); - return null; - } - - public SortedMap headMap(Object toKey) - { - if (! keyInRange(toKey)) - throw new IllegalArgumentException("key outside range"); - return new SubMap(minKey, toKey); - } - - public Set keySet() - { - if (this.keys == null) - // Create an AbstractSet with custom implementations of those methods - // that can be overriden easily and efficiently. - this.keys = new AbstractSet() - { - public int size() - { - return SubMap.this.size(); - } - - public Iterator iterator() - { - Node first = lowestGreaterThan(minKey, true); - Node max = lowestGreaterThan(maxKey, false); - return new TreeIterator(KEYS, first, max); - } - - public void clear() - { - SubMap.this.clear(); - } - - public boolean contains(Object o) - { - if (! keyInRange(o)) - return false; - return getNode(o) != nil; - } - - public boolean remove(Object o) - { - if (! keyInRange(o)) - return false; - Node n = getNode(o); - if (n != nil) - { - removeNode(n); - return true; - } - return false; - } - }; - return this.keys; - } - - public Object lastKey() - { - Node node = highestLessThan(maxKey); - if (node == nil || ! keyInRange(node.key)) - throw new NoSuchElementException(); - return node.key; - } - - public Object put(Object key, Object value) - { - if (! keyInRange(key)) - throw new IllegalArgumentException("Key outside range"); - return TreeMap.this.put(key, value); - } - - public Object remove(Object key) - { - if (keyInRange(key)) - return TreeMap.this.remove(key); - return null; - } - - public int size() - { - Node node = lowestGreaterThan(minKey, true); - Node max = lowestGreaterThan(maxKey, false); - int count = 0; - while (node != max) - { - count++; - node = successor(node); - } - return count; - } - - public SortedMap subMap(Object fromKey, Object toKey) - { - if (! keyInRange(fromKey) || ! keyInRange(toKey)) - throw new IllegalArgumentException("key outside range"); - return new SubMap(fromKey, toKey); - } - - public SortedMap tailMap(Object fromKey) - { - if (! keyInRange(fromKey)) - throw new IllegalArgumentException("key outside range"); - return new SubMap(fromKey, maxKey); - } - - public Collection values() - { - if (this.values == null) - // Create an AbstractCollection with custom implementations of those - // methods that can be overriden easily and efficiently. - this.values = new AbstractCollection() - { - public int size() - { - return SubMap.this.size(); - } - - public Iterator iterator() - { - Node first = lowestGreaterThan(minKey, true); - Node max = lowestGreaterThan(maxKey, false); - return new TreeIterator(VALUES, first, max); - } - - public void clear() - { - SubMap.this.clear(); - } - }; - return this.values; - } - } // class SubMap -} // class TreeMap diff --git a/libjava/java/util/TreeSet.java b/libjava/java/util/TreeSet.java deleted file mode 100644 index 34cb39acc07..00000000000 --- a/libjava/java/util/TreeSet.java +++ /dev/null @@ -1,416 +0,0 @@ -/* TreeSet.java -- a class providing a TreeMap-backed SortedSet - Copyright (C) 1999, 2000, 2001, 2004, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; - -/** - * This class provides a TreeMap-backed implementation of the SortedSet - * interface. The elements will be sorted according to their <i>natural - * order</i>, or according to the provided <code>Comparator</code>.<p> - * - * Most operations are O(log n), but there is so much overhead that this - * makes small sets expensive. Note that the ordering must be <i>consistent - * with equals</i> to correctly implement the Set interface. If this - * condition is violated, the set is still well-behaved, but you may have - * suprising results when comparing it to other sets.<p> - * - * This implementation is not synchronized. If you need to share this between - * multiple threads, do something like:<br> - * <code>SortedSet s - * = Collections.synchronizedSortedSet(new TreeSet(...));</code><p> - * - * The iterators are <i>fail-fast</i>, meaning that any structural - * modification, except for <code>remove()</code> called on the iterator - * itself, cause the iterator to throw a - * <code>ConcurrentModificationException</code> rather than exhibit - * non-deterministic behavior. - * - * @author Jon Zeppieri - * @author Bryce McKinlay - * @author Eric Blake (ebb9@email.byu.edu) - * @see Collection - * @see Set - * @see HashSet - * @see LinkedHashSet - * @see Comparable - * @see Comparator - * @see Collections#synchronizedSortedSet(SortedSet) - * @see TreeMap - * @since 1.2 - * @status updated to 1.4 - */ -public class TreeSet extends AbstractSet - implements SortedSet, Cloneable, Serializable -{ - /** - * Compatible with JDK 1.2. - */ - private static final long serialVersionUID = -2479143000061671589L; - - /** - * The SortedMap which backs this Set. - */ - // Not final because of readObject. This will always be one of TreeMap or - // TreeMap.SubMap, which both extend AbstractMap. - private transient SortedMap map; - - /** - * Construct a new TreeSet whose backing TreeMap using the "natural" - * ordering of keys. Elements that are not mutually comparable will cause - * ClassCastExceptions down the road. - * - * @see Comparable - */ - public TreeSet() - { - map = new TreeMap(); - } - - /** - * Construct a new TreeSet whose backing TreeMap uses the supplied - * Comparator. Elements that are not mutually comparable will cause - * ClassCastExceptions down the road. - * - * @param comparator the Comparator this Set will use - */ - public TreeSet(Comparator comparator) - { - map = new TreeMap(comparator); - } - - /** - * Construct a new TreeSet whose backing TreeMap uses the "natural" - * orering of the keys and which contains all of the elements in the - * supplied Collection. This runs in n*log(n) time. - * - * @param collection the new Set will be initialized with all - * of the elements in this Collection - * @throws ClassCastException if the elements of the collection are not - * comparable - * @throws NullPointerException if the collection is null - * @see Comparable - */ - public TreeSet(Collection collection) - { - map = new TreeMap(); - addAll(collection); - } - - /** - * Construct a new TreeSet, using the same key ordering as the supplied - * SortedSet and containing all of the elements in the supplied SortedSet. - * This constructor runs in linear time. - * - * @param sortedSet the new TreeSet will use this SortedSet's comparator - * and will initialize itself with all its elements - * @throws NullPointerException if sortedSet is null - */ - public TreeSet(SortedSet sortedSet) - { - map = new TreeMap(sortedSet.comparator()); - Iterator itr = sortedSet.iterator(); - ((TreeMap) map).putKeysLinear(itr, sortedSet.size()); - } - - /** - * This private constructor is used to implement the subSet() calls around - * a backing TreeMap.SubMap. - * - * @param backingMap the submap - */ - private TreeSet(SortedMap backingMap) - { - map = backingMap; - } - - /** - * Adds the spplied Object to the Set if it is not already in the Set; - * returns true if the element is added, false otherwise. - * - * @param obj the Object to be added to this Set - * @throws ClassCastException if the element cannot be compared with objects - * already in the set - */ - public boolean add(Object obj) - { - return map.put(obj, "") == null; - } - - /** - * Adds all of the elements in the supplied Collection to this TreeSet. - * - * @param c The collection to add - * @return true if the Set is altered, false otherwise - * @throws NullPointerException if c is null - * @throws ClassCastException if an element in c cannot be compared with - * objects already in the set - */ - public boolean addAll(Collection c) - { - boolean result = false; - int pos = c.size(); - Iterator itr = c.iterator(); - while (--pos >= 0) - result |= (map.put(itr.next(), "") == null); - return result; - } - - /** - * Removes all elements in this Set. - */ - public void clear() - { - map.clear(); - } - - /** - * Returns a shallow copy of this Set. The elements are not cloned. - * - * @return the cloned set - */ - public Object clone() - { - TreeSet copy = null; - try - { - copy = (TreeSet) super.clone(); - // Map may be either TreeMap or TreeMap.SubMap, hence the ugly casts. - copy.map = (SortedMap) ((AbstractMap) map).clone(); - } - catch (CloneNotSupportedException x) - { - // Impossible result. - } - return copy; - } - - /** - * Returns this Set's comparator. - * - * @return the comparator, or null if the set uses natural ordering - */ - public Comparator comparator() - { - return map.comparator(); - } - - /** - * Returns true if this Set contains the supplied Object, false otherwise. - * - * @param obj the Object to check for - * @return true if it is in the set - * @throws ClassCastException if obj cannot be compared with objects - * already in the set - */ - public boolean contains(Object obj) - { - return map.containsKey(obj); - } - - /** - * Returns the first (by order) element in this Set. - * - * @return the first element - * @throws NoSuchElementException if the set is empty - */ - public Object first() - { - return map.firstKey(); - } - - /** - * Returns a view of this Set including all elements less than - * <code>to</code>. The returned set is backed by the original, so changes - * in one appear in the other. The subset will throw an - * {@link IllegalArgumentException} for any attempt to access or add an - * element beyond the specified cutoff. The returned set does not include - * the endpoint; if you want inclusion, pass the successor element. - * - * @param to the (exclusive) cutoff point - * @return a view of the set less than the cutoff - * @throws ClassCastException if <code>to</code> is not compatible with - * the comparator (or is not Comparable, for natural ordering) - * @throws NullPointerException if to is null, but the comparator does not - * tolerate null elements - */ - public SortedSet headSet(Object to) - { - return new TreeSet(map.headMap(to)); - } - - /** - * Returns true if this Set has size 0, false otherwise. - * - * @return true if the set is empty - */ - public boolean isEmpty() - { - return map.isEmpty(); - } - - /** - * Returns in Iterator over the elements in this TreeSet, which traverses - * in ascending order. - * - * @return an iterator - */ - public Iterator iterator() - { - return map.keySet().iterator(); - } - - /** - * Returns the last (by order) element in this Set. - * - * @return the last element - * @throws NoSuchElementException if the set is empty - */ - public Object last() - { - return map.lastKey(); - } - - /** - * If the supplied Object is in this Set, it is removed, and true is - * returned; otherwise, false is returned. - * - * @param obj the Object to remove from this Set - * @return true if the set was modified - * @throws ClassCastException if obj cannot be compared to set elements - */ - public boolean remove(Object obj) - { - return map.remove(obj) != null; - } - - /** - * Returns the number of elements in this Set - * - * @return the set size - */ - public int size() - { - return map.size(); - } - - /** - * Returns a view of this Set including all elements greater or equal to - * <code>from</code> and less than <code>to</code> (a half-open interval). - * The returned set is backed by the original, so changes in one appear in - * the other. The subset will throw an {@link IllegalArgumentException} - * for any attempt to access or add an element beyond the specified cutoffs. - * The returned set includes the low endpoint but not the high; if you want - * to reverse this behavior on either end, pass in the successor element. - * - * @param from the (inclusive) low cutoff point - * @param to the (exclusive) high cutoff point - * @return a view of the set between the cutoffs - * @throws ClassCastException if either cutoff is not compatible with - * the comparator (or is not Comparable, for natural ordering) - * @throws NullPointerException if from or to is null, but the comparator - * does not tolerate null elements - * @throws IllegalArgumentException if from is greater than to - */ - public SortedSet subSet(Object from, Object to) - { - return new TreeSet(map.subMap(from, to)); - } - - /** - * Returns a view of this Set including all elements greater or equal to - * <code>from</code>. The returned set is backed by the original, so - * changes in one appear in the other. The subset will throw an - * {@link IllegalArgumentException} for any attempt to access or add an - * element beyond the specified cutoff. The returned set includes the - * endpoint; if you want to exclude it, pass in the successor element. - * - * @param from the (inclusive) low cutoff point - * @return a view of the set above the cutoff - * @throws ClassCastException if <code>from</code> is not compatible with - * the comparator (or is not Comparable, for natural ordering) - * @throws NullPointerException if from is null, but the comparator - * does not tolerate null elements - */ - public SortedSet tailSet(Object from) - { - return new TreeSet(map.tailMap(from)); - } - - /** - * Serializes this object to the given stream. - * - * @param s the stream to write to - * @throws IOException if the underlying stream fails - * @serialData the <i>comparator</i> (Object), followed by the set size - * (int), the the elements in sorted order (Object) - */ - private void writeObject(ObjectOutputStream s) throws IOException - { - s.defaultWriteObject(); - Iterator itr = map.keySet().iterator(); - int pos = map.size(); - s.writeObject(map.comparator()); - s.writeInt(pos); - while (--pos >= 0) - s.writeObject(itr.next()); - } - - /** - * Deserializes this object from the given stream. - * - * @param s the stream to read from - * @throws ClassNotFoundException if the underlying stream fails - * @throws IOException if the underlying stream fails - * @serialData the <i>comparator</i> (Object), followed by the set size - * (int), the the elements in sorted order (Object) - */ - private void readObject(ObjectInputStream s) - throws IOException, ClassNotFoundException - { - s.defaultReadObject(); - Comparator comparator = (Comparator) s.readObject(); - int size = s.readInt(); - map = new TreeMap(comparator); - ((TreeMap) map).putFromObjStream(s, size, false); - } -} diff --git a/libjava/java/util/Vector.java b/libjava/java/util/Vector.java deleted file mode 100644 index e26d7aaa4dd..00000000000 --- a/libjava/java/util/Vector.java +++ /dev/null @@ -1,931 +0,0 @@ -/* Vector.java -- Class that provides growable arrays. - Copyright (C) 1998, 1999, 2000, 2001, 2004, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; -import java.io.IOException; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.lang.reflect.Array; - -/** - * The <code>Vector</code> classes implements growable arrays of Objects. - * You can access elements in a Vector with an index, just as you - * can in a built in array, but Vectors can grow and shrink to accommodate - * more or fewer objects.<p> - * - * Vectors try to mantain efficiency in growing by having a - * <code>capacityIncrement</code> that can be specified at instantiation. - * When a Vector can no longer hold a new Object, it grows by the amount - * in <code>capacityIncrement</code>. If this value is 0, the vector doubles in - * size.<p> - * - * Vector implements the JDK 1.2 List interface, and is therefore a fully - * compliant Collection object. The iterators are fail-fast - if external - * code structurally modifies the vector, any operation on the iterator will - * then throw a {@link ConcurrentModificationException}. The Vector class is - * fully synchronized, but the iterators are not. So, when iterating over a - * vector, be sure to synchronize on the vector itself. If you don't want the - * expense of synchronization, use ArrayList instead. On the other hand, the - * Enumeration of elements() is not thread-safe, nor is it fail-fast; so it - * can lead to undefined behavior even in a single thread if you modify the - * vector during iteration.<p> - * - * Note: Some methods, especially those specified by List, specify throwing - * {@link IndexOutOfBoundsException}, but it is easier to implement by - * throwing the subclass {@link ArrayIndexOutOfBoundsException}. Others - * directly specify this subclass. - * - * @author Scott G. Miller - * @author Bryce McKinlay - * @author Eric Blake (ebb9@email.byu.edu) - * @see Collection - * @see List - * @see ArrayList - * @see LinkedList - * @since 1.0 - * @status updated to 1.4 - */ -public class Vector extends AbstractList - implements List, RandomAccess, Cloneable, Serializable -{ - /** - * Compatible with JDK 1.0+. - */ - private static final long serialVersionUID = -2767605614048989439L; - - /** - * The internal array used to hold members of a Vector. The elements are - * in positions 0 through elementCount - 1, and all remaining slots are null. - * @serial the elements - */ - protected Object[] elementData; - - /** - * The number of elements currently in the vector, also returned by - * {@link #size}. - * @serial the size - */ - protected int elementCount; - - /** - * The amount the Vector's internal array should be increased in size when - * a new element is added that exceeds the current size of the array, - * or when {@link #ensureCapacity} is called. If <= 0, the vector just - * doubles in size. - * @serial the amount to grow the vector by - */ - protected int capacityIncrement; - - /** - * Constructs an empty vector with an initial size of 10, and - * a capacity increment of 0 - */ - public Vector() - { - this(10, 0); - } - - /** - * Constructs a vector containing the contents of Collection, in the - * order given by the collection. - * - * @param c collection of elements to add to the new vector - * @throws NullPointerException if c is null - * @since 1.2 - */ - public Vector(Collection c) - { - elementCount = c.size(); - elementData = c.toArray(new Object[elementCount]); - } - - /** - * Constructs a Vector with the initial capacity and capacity - * increment specified. - * - * @param initialCapacity the initial size of the Vector's internal array - * @param capacityIncrement the amount the internal array should be - * increased by when necessary, 0 to double the size - * @throws IllegalArgumentException if initialCapacity < 0 - */ - public Vector(int initialCapacity, int capacityIncrement) - { - if (initialCapacity < 0) - throw new IllegalArgumentException(); - elementData = new Object[initialCapacity]; - this.capacityIncrement = capacityIncrement; - } - - /** - * Constructs a Vector with the initial capacity specified, and a capacity - * increment of 0 (double in size). - * - * @param initialCapacity the initial size of the Vector's internal array - * @throws IllegalArgumentException if initialCapacity < 0 - */ - public Vector(int initialCapacity) - { - this(initialCapacity, 0); - } - - /** - * Copies the contents of a provided array into the Vector. If the - * array is too large to fit in the Vector, an IndexOutOfBoundsException - * is thrown without modifying the array. Old elements in the Vector are - * overwritten by the new elements. - * - * @param a target array for the copy - * @throws IndexOutOfBoundsException the array is not large enough - * @throws NullPointerException the array is null - * @see #toArray(Object[]) - */ - public synchronized void copyInto(Object[] a) - { - System.arraycopy(elementData, 0, a, 0, elementCount); - } - - /** - * Trims the Vector down to size. If the internal data array is larger - * than the number of Objects its holding, a new array is constructed - * that precisely holds the elements. Otherwise this does nothing. - */ - public synchronized void trimToSize() - { - // Don't bother checking for the case where size() == the capacity of the - // vector since that is a much less likely case; it's more efficient to - // not do the check and lose a bit of performance in that infrequent case - - Object[] newArray = new Object[elementCount]; - System.arraycopy(elementData, 0, newArray, 0, elementCount); - elementData = newArray; - } - - /** - * Ensures that <code>minCapacity</code> elements can fit within this Vector. - * If <code>elementData</code> is too small, it is expanded as follows: - * If the <code>elementCount + capacityIncrement</code> is adequate, that - * is the new size. If <code>capacityIncrement</code> is non-zero, the - * candidate size is double the current. If that is not enough, the new - * size is <code>minCapacity</code>. - * - * @param minCapacity the desired minimum capacity, negative values ignored - */ - public synchronized void ensureCapacity(int minCapacity) - { - if (elementData.length >= minCapacity) - return; - - int newCapacity; - if (capacityIncrement <= 0) - newCapacity = elementData.length * 2; - else - newCapacity = elementData.length + capacityIncrement; - - Object[] newArray = new Object[Math.max(newCapacity, minCapacity)]; - - System.arraycopy(elementData, 0, newArray, 0, elementCount); - elementData = newArray; - } - - /** - * Explicitly sets the size of the vector (but not necessarily the size of - * the internal data array). If the new size is smaller than the old one, - * old values that don't fit are lost. If the new size is larger than the - * old one, the vector is padded with null entries. - * - * @param newSize The new size of the internal array - * @throws ArrayIndexOutOfBoundsException if the new size is negative - */ - public synchronized void setSize(int newSize) - { - // Don't bother checking for the case where size() == the capacity of the - // vector since that is a much less likely case; it's more efficient to - // not do the check and lose a bit of performance in that infrequent case - modCount++; - ensureCapacity(newSize); - if (newSize < elementCount) - Arrays.fill(elementData, newSize, elementCount, null); - elementCount = newSize; - } - - /** - * Returns the size of the internal data array (not the amount of elements - * contained in the Vector). - * - * @return capacity of the internal data array - */ - public synchronized int capacity() - { - return elementData.length; - } - - /** - * Returns the number of elements stored in this Vector. - * - * @return the number of elements in this Vector - */ - public synchronized int size() - { - return elementCount; - } - - /** - * Returns true if this Vector is empty, false otherwise - * - * @return true if the Vector is empty, false otherwise - */ - public synchronized boolean isEmpty() - { - return elementCount == 0; - } - - /** - * Returns an Enumeration of the elements of this Vector. The enumeration - * visits the elements in increasing index order, but is NOT thread-safe. - * - * @return an Enumeration - * @see #iterator() - */ - // No need to synchronize as the Enumeration is not thread-safe! - public Enumeration elements() - { - return new Enumeration() - { - private int i = 0; - - public boolean hasMoreElements() - { - return i < elementCount; - } - - public Object nextElement() - { - if (i >= elementCount) - throw new NoSuchElementException(); - return elementData[i++]; - } - }; - } - - /** - * Returns true when <code>elem</code> is contained in this Vector. - * - * @param elem the element to check - * @return true if the object is contained in this Vector, false otherwise - */ - public boolean contains(Object elem) - { - return indexOf(elem, 0) >= 0; - } - - /** - * Returns the first occurrence of <code>elem</code> in the Vector, or -1 if - * <code>elem</code> is not found. - * - * @param elem the object to search for - * @return the index of the first occurrence, or -1 if not found - */ - public int indexOf(Object elem) - { - return indexOf(elem, 0); - } - - /** - * Searches the vector starting at <code>index</code> for object - * <code>elem</code> and returns the index of the first occurrence of this - * Object. If the object is not found, or index is larger than the size - * of the vector, -1 is returned. - * - * @param e the Object to search for - * @param index start searching at this index - * @return the index of the next occurrence, or -1 if it is not found - * @throws IndexOutOfBoundsException if index < 0 - */ - public synchronized int indexOf(Object e, int index) - { - for (int i = index; i < elementCount; i++) - if (equals(e, elementData[i])) - return i; - return -1; - } - - /** - * Returns the last index of <code>elem</code> within this Vector, or -1 - * if the object is not within the Vector. - * - * @param elem the object to search for - * @return the last index of the object, or -1 if not found - */ - public int lastIndexOf(Object elem) - { - return lastIndexOf(elem, elementCount - 1); - } - - /** - * Returns the index of the first occurrence of <code>elem</code>, when - * searching backwards from <code>index</code>. If the object does not - * occur in this Vector, or index is less than 0, -1 is returned. - * - * @param e the object to search for - * @param index the index to start searching in reverse from - * @return the index of the Object if found, -1 otherwise - * @throws IndexOutOfBoundsException if index >= size() - */ - public synchronized int lastIndexOf(Object e, int index) - { - checkBoundExclusive(index); - for (int i = index; i >= 0; i--) - if (equals(e, elementData[i])) - return i; - return -1; - } - - /** - * Returns the Object stored at <code>index</code>. - * - * @param index the index of the Object to retrieve - * @return the object at <code>index</code> - * @throws ArrayIndexOutOfBoundsException index < 0 || index >= size() - * @see #get(int) - */ - public synchronized Object elementAt(int index) - { - checkBoundExclusive(index); - return elementData[index]; - } - - /** - * Returns the first element (index 0) in the Vector. - * - * @return the first Object in the Vector - * @throws NoSuchElementException the Vector is empty - */ - public synchronized Object firstElement() - { - if (elementCount == 0) - throw new NoSuchElementException(); - - return elementData[0]; - } - - /** - * Returns the last element in the Vector. - * - * @return the last Object in the Vector - * @throws NoSuchElementException the Vector is empty - */ - public synchronized Object lastElement() - { - if (elementCount == 0) - throw new NoSuchElementException(); - - return elementData[elementCount - 1]; - } - - /** - * Changes the element at <code>index</code> to be <code>obj</code> - * - * @param obj the object to store - * @param index the position in the Vector to store the object - * @throws ArrayIndexOutOfBoundsException the index is out of range - * @see #set(int, Object) - */ - public void setElementAt(Object obj, int index) - { - set(index, obj); - } - - /** - * Removes the element at <code>index</code>, and shifts all elements at - * positions greater than index to their index - 1. - * - * @param index the index of the element to remove - * @throws ArrayIndexOutOfBoundsException index < 0 || index >= size(); - * @see #remove(int) - */ - public void removeElementAt(int index) - { - remove(index); - } - - /** - * Inserts a new element into the Vector at <code>index</code>. Any elements - * at or greater than index are shifted up one position. - * - * @param obj the object to insert - * @param index the index at which the object is inserted - * @throws ArrayIndexOutOfBoundsException index < 0 || index > size() - * @see #add(int, Object) - */ - public synchronized void insertElementAt(Object obj, int index) - { - checkBoundInclusive(index); - if (elementCount == elementData.length) - ensureCapacity(elementCount + 1); - modCount++; - System.arraycopy(elementData, index, elementData, index + 1, - elementCount - index); - elementCount++; - elementData[index] = obj; - } - - /** - * Adds an element to the Vector at the end of the Vector. The vector - * is increased by ensureCapacity(size() + 1) if needed. - * - * @param obj the object to add to the Vector - */ - public synchronized void addElement(Object obj) - { - if (elementCount == elementData.length) - ensureCapacity(elementCount + 1); - modCount++; - elementData[elementCount++] = obj; - } - - /** - * Removes the first (the lowestindex) occurance of the given object from - * the Vector. If such a remove was performed (the object was found), true - * is returned. If there was no such object, false is returned. - * - * @param obj the object to remove from the Vector - * @return true if the Object was in the Vector, false otherwise - * @see #remove(Object) - */ - public synchronized boolean removeElement(Object obj) - { - int idx = indexOf(obj, 0); - if (idx >= 0) - { - remove(idx); - return true; - } - return false; - } - - /** - * Removes all elements from the Vector. Note that this does not - * resize the internal data array. - * - * @see #clear() - */ - public synchronized void removeAllElements() - { - if (elementCount == 0) - return; - - modCount++; - Arrays.fill(elementData, 0, elementCount, null); - elementCount = 0; - } - - /** - * Creates a new Vector with the same contents as this one. The clone is - * shallow; elements are not cloned. - * - * @return the clone of this vector - */ - public synchronized Object clone() - { - try - { - Vector clone = (Vector) super.clone(); - clone.elementData = (Object[]) elementData.clone(); - return clone; - } - catch (CloneNotSupportedException ex) - { - // Impossible to get here. - throw new InternalError(ex.toString()); - } - } - - /** - * Returns an Object array with the contents of this Vector, in the order - * they are stored within this Vector. Note that the Object array returned - * is not the internal data array, and that it holds only the elements - * within the Vector. This is similar to creating a new Object[] with the - * size of this Vector, then calling Vector.copyInto(yourArray). - * - * @return an Object[] containing the contents of this Vector in order - * @since 1.2 - */ - public synchronized Object[] toArray() - { - Object[] newArray = new Object[elementCount]; - copyInto(newArray); - return newArray; - } - - /** - * Returns an array containing the contents of this Vector. - * If the provided array is large enough, the contents are copied - * into that array, and a null is placed in the position size(). - * In this manner, you can obtain the size of a Vector by the position - * of the null element, if you know the vector does not itself contain - * null entries. If the array is not large enough, reflection is used - * to create a bigger one of the same runtime type. - * - * @param a an array to copy the Vector into if large enough - * @return an array with the contents of this Vector in order - * @throws ArrayStoreException the runtime type of the provided array - * cannot hold the elements of the Vector - * @throws NullPointerException if <code>a</code> is null - * @since 1.2 - */ - public synchronized Object[] toArray(Object[] a) - { - if (a.length < elementCount) - a = (Object[]) Array.newInstance(a.getClass().getComponentType(), - elementCount); - else if (a.length > elementCount) - a[elementCount] = null; - System.arraycopy(elementData, 0, a, 0, elementCount); - return a; - } - - /** - * Returns the element at position <code>index</code>. - * - * @param index the position from which an element will be retrieved - * @return the element at that position - * @throws ArrayIndexOutOfBoundsException index < 0 || index >= size() - * @since 1.2 - */ - public Object get(int index) - { - return elementAt(index); - } - - /** - * Puts <code>element</code> into the Vector at position <code>index</code> - * and returns the Object that previously occupied that position. - * - * @param index the index within the Vector to place the Object - * @param element the Object to store in the Vector - * @return the previous object at the specified index - * @throws ArrayIndexOutOfBoundsException index < 0 || index >= size() - * @since 1.2 - */ - public synchronized Object set(int index, Object element) - { - checkBoundExclusive(index); - Object temp = elementData[index]; - elementData[index] = element; - return temp; - } - - /** - * Adds an object to the Vector. - * - * @param o the element to add to the Vector - * @return true, as specified by List - * @since 1.2 - */ - public boolean add(Object o) - { - addElement(o); - return true; - } - - /** - * Removes the given Object from the Vector. If it exists, true - * is returned, if not, false is returned. - * - * @param o the object to remove from the Vector - * @return true if the Object existed in the Vector, false otherwise - * @since 1.2 - */ - public boolean remove(Object o) - { - return removeElement(o); - } - - /** - * Adds an object at the specified index. Elements at or above - * index are shifted up one position. - * - * @param index the index at which to add the element - * @param element the element to add to the Vector - * @throws ArrayIndexOutOfBoundsException index < 0 || index > size() - * @since 1.2 - */ - public void add(int index, Object element) - { - insertElementAt(element, index); - } - - /** - * Removes the element at the specified index, and returns it. - * - * @param index the position from which to remove the element - * @return the object removed - * @throws ArrayIndexOutOfBoundsException index < 0 || index >= size() - * @since 1.2 - */ - public synchronized Object remove(int index) - { - checkBoundExclusive(index); - Object temp = elementData[index]; - modCount++; - elementCount--; - if (index < elementCount) - System.arraycopy(elementData, index + 1, elementData, index, - elementCount - index); - elementData[elementCount] = null; - return temp; - } - - /** - * Clears all elements in the Vector and sets its size to 0. - */ - public void clear() - { - removeAllElements(); - } - - /** - * Returns true if this Vector contains all the elements in c. - * - * @param c the collection to compare to - * @return true if this vector contains all elements of c - * @throws NullPointerException if c is null - * @since 1.2 - */ - public synchronized boolean containsAll(Collection c) - { - // Here just for the sychronization. - return super.containsAll(c); - } - - /** - * Appends all elements of the given collection to the end of this Vector. - * Behavior is undefined if the collection is modified during this operation - * (for example, if this == c). - * - * @param c the collection to append - * @return true if this vector changed, in other words c was not empty - * @throws NullPointerException if c is null - * @since 1.2 - */ - public synchronized boolean addAll(Collection c) - { - return addAll(elementCount, c); - } - - /** - * Remove from this vector all elements contained in the given collection. - * - * @param c the collection to filter out - * @return true if this vector changed - * @throws NullPointerException if c is null - * @since 1.2 - */ - public synchronized boolean removeAll(Collection c) - { - if (c == null) - throw new NullPointerException(); - - int i; - int j; - for (i = 0; i < elementCount; i++) - if (c.contains(elementData[i])) - break; - if (i == elementCount) - return false; - - modCount++; - for (j = i++; i < elementCount; i++) - if (! c.contains(elementData[i])) - elementData[j++] = elementData[i]; - elementCount -= i - j; - return true; - } - - /** - * Retain in this vector only the elements contained in the given collection. - * - * @param c the collection to filter by - * @return true if this vector changed - * @throws NullPointerException if c is null - * @since 1.2 - */ - public synchronized boolean retainAll(Collection c) - { - if (c == null) - throw new NullPointerException(); - - int i; - int j; - for (i = 0; i < elementCount; i++) - if (! c.contains(elementData[i])) - break; - if (i == elementCount) - return false; - - modCount++; - for (j = i++; i < elementCount; i++) - if (c.contains(elementData[i])) - elementData[j++] = elementData[i]; - elementCount -= i - j; - return true; - } - - /** - * Inserts all elements of the given collection at the given index of - * this Vector. Behavior is undefined if the collection is modified during - * this operation (for example, if this == c). - * - * @param c the collection to append - * @return true if this vector changed, in other words c was not empty - * @throws NullPointerException if c is null - * @throws ArrayIndexOutOfBoundsException index < 0 || index > size() - * @since 1.2 - */ - public synchronized boolean addAll(int index, Collection c) - { - checkBoundInclusive(index); - Iterator itr = c.iterator(); - int csize = c.size(); - - modCount++; - ensureCapacity(elementCount + csize); - int end = index + csize; - if (elementCount > 0 && index != elementCount) - System.arraycopy(elementData, index, - elementData, end, elementCount - index); - elementCount += csize; - for ( ; index < end; index++) - elementData[index] = itr.next(); - return (csize > 0); - } - - /** - * Compares this to the given object. - * - * @param o the object to compare to - * @return true if the two are equal - * @since 1.2 - */ - public synchronized boolean equals(Object o) - { - // Here just for the sychronization. - return super.equals(o); - } - - /** - * Computes the hashcode of this object. - * - * @return the hashcode - * @since 1.2 - */ - public synchronized int hashCode() - { - // Here just for the sychronization. - return super.hashCode(); - } - - /** - * Returns a string representation of this Vector in the form - * "[element0, element1, ... elementN]". - * - * @return the String representation of this Vector - */ - public synchronized String toString() - { - // Here just for the sychronization. - return super.toString(); - } - - /** - * Obtain a List view of a subsection of this list, from fromIndex - * (inclusive) to toIndex (exclusive). If the two indices are equal, the - * sublist is empty. The returned list is modifiable, and changes in one - * reflect in the other. If this list is structurally modified in - * any way other than through the returned list, the result of any subsequent - * operations on the returned list is undefined. - * <p> - * - * @param fromIndex the index that the returned list should start from - * (inclusive) - * @param toIndex the index that the returned list should go to (exclusive) - * @return a List backed by a subsection of this vector - * @throws IndexOutOfBoundsException if fromIndex < 0 - * || toIndex > size() - * @throws IllegalArgumentException if fromIndex > toIndex - * @see ConcurrentModificationException - * @since 1.2 - */ - public synchronized List subList(int fromIndex, int toIndex) - { - List sub = super.subList(fromIndex, toIndex); - // We must specify the correct object to synchronize upon, hence the - // use of a non-public API - return new Collections.SynchronizedList(this, sub); - } - - /** - * Removes a range of elements from this list. - * Does nothing when toIndex is equal to fromIndex. - * - * @param fromIndex the index to start deleting from (inclusive) - * @param toIndex the index to delete up to (exclusive) - * @throws IndexOutOfBoundsException if fromIndex > toIndex - */ - // This does not need to be synchronized, because it is only called through - // clear() of a sublist, and clear() had already synchronized. - protected void removeRange(int fromIndex, int toIndex) - { - int change = toIndex - fromIndex; - if (change > 0) - { - modCount++; - System.arraycopy(elementData, toIndex, elementData, fromIndex, - elementCount - toIndex); - int save = elementCount; - elementCount -= change; - Arrays.fill(elementData, elementCount, save, null); - } - else if (change < 0) - throw new IndexOutOfBoundsException(); - } - - /** - * Checks that the index is in the range of possible elements (inclusive). - * - * @param index the index to check - * @throws ArrayIndexOutOfBoundsException if index > size - */ - private void checkBoundInclusive(int index) - { - // Implementation note: we do not check for negative ranges here, since - // use of a negative index will cause an ArrayIndexOutOfBoundsException - // with no effort on our part. - if (index > elementCount) - throw new ArrayIndexOutOfBoundsException(index + " > " + elementCount); - } - - /** - * Checks that the index is in the range of existing elements (exclusive). - * - * @param index the index to check - * @throws ArrayIndexOutOfBoundsException if index >= size - */ - private void checkBoundExclusive(int index) - { - // Implementation note: we do not check for negative ranges here, since - // use of a negative index will cause an ArrayIndexOutOfBoundsException - // with no effort on our part. - if (index >= elementCount) - throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount); - } - - /** - * Serializes this object to the given stream. - * - * @param s the stream to write to - * @throws IOException if the underlying stream fails - * @serialData just calls default write function - */ - private synchronized void writeObject(ObjectOutputStream s) - throws IOException - { - s.defaultWriteObject(); - } - -} diff --git a/libjava/java/util/WeakHashMap.java b/libjava/java/util/WeakHashMap.java deleted file mode 100644 index 7593f7e330e..00000000000 --- a/libjava/java/util/WeakHashMap.java +++ /dev/null @@ -1,881 +0,0 @@ -/* WeakHashMap -- a hashtable that keeps only weak references - to its keys, allowing the virtual machine to reclaim them - Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - -import java.lang.ref.ReferenceQueue; -import java.lang.ref.WeakReference; - -/** - * A weak hash map has only weak references to the key. This means that it - * allows the key to be garbage collected if it is not used otherwise. If - * this happens, the entry will eventually disappear from the map, - * asynchronously. - * - * <p>A weak hash map makes most sense when the keys doesn't override the - * <code>equals</code> method: If there is no other reference to the - * key nobody can ever look up the key in this table and so the entry - * can be removed. This table also works when the <code>equals</code> - * method is overloaded, such as String keys, but you should be prepared - * to deal with some entries disappearing spontaneously. - * - * <p>Other strange behaviors to be aware of: The size of this map may - * spontaneously shrink (even if you use a synchronized map and synchronize - * it); it behaves as if another thread removes entries from this table - * without synchronization. The entry set returned by <code>entrySet</code> - * has similar phenomenons: The size may spontaneously shrink, or an - * entry, that was in the set before, suddenly disappears. - * - * <p>A weak hash map is not meant for caches; use a normal map, with - * soft references as values instead, or try {@link LinkedHashMap}. - * - * <p>The weak hash map supports null values and null keys. The null key - * is never deleted from the map (except explictly of course). The - * performance of the methods are similar to that of a hash map. - * - * <p>The value objects are strongly referenced by this table. So if a - * value object maintains a strong reference to the key (either direct - * or indirect) the key will never be removed from this map. According - * to Sun, this problem may be fixed in a future release. It is not - * possible to do it with the jdk 1.2 reference model, though. - * - * @author Jochen Hoenicke - * @author Eric Blake (ebb9@email.byu.edu) - * - * @see HashMap - * @see WeakReference - * @see LinkedHashMap - * @since 1.2 - * @status updated to 1.4 - */ -public class WeakHashMap extends AbstractMap implements Map -{ - // WARNING: WeakHashMap is a CORE class in the bootstrap cycle. See the - // comments in vm/reference/java/lang/Runtime for implications of this fact. - - /** - * The default capacity for an instance of HashMap. - * Sun's documentation mildly suggests that this (11) is the correct - * value. - */ - private static final int DEFAULT_CAPACITY = 11; - - /** - * The default load factor of a HashMap. - */ - private static final float DEFAULT_LOAD_FACTOR = 0.75F; - - /** - * This is used instead of the key value <i>null</i>. It is needed - * to distinguish between an null key and a removed key. - */ - // Package visible for use by nested classes. - static final Object NULL_KEY = new Object() - { - /** - * Sets the hashCode to 0, since that's what null would map to. - * @return the hash code 0 - */ - public int hashCode() - { - return 0; - } - - /** - * Compares this key to the given object. Normally, an object should - * NEVER compare equal to null, but since we don't publicize NULL_VALUE, - * it saves bytecode to do so here. - * @return true iff o is this or null - */ - public boolean equals(Object o) - { - return null == o || this == o; - } - }; - - /** - * The reference queue where our buckets (which are WeakReferences) are - * registered to. - */ - private final ReferenceQueue queue; - - /** - * The number of entries in this hash map. - */ - // Package visible for use by nested classes. - int size; - - /** - * The load factor of this WeakHashMap. This is the maximum ratio of - * size versus number of buckets. If size grows the number of buckets - * must grow, too. - */ - private float loadFactor; - - /** - * The rounded product of the capacity (i.e. number of buckets) and - * the load factor. When the number of elements exceeds the - * threshold, the HashMap calls <code>rehash()</code>. - */ - private int threshold; - - /** - * The number of structural modifications. This is used by - * iterators, to see if they should fail. This doesn't count - * the silent key removals, when a weak reference is cleared - * by the garbage collection. Instead the iterators must make - * sure to have strong references to the entries they rely on. - */ - // Package visible for use by nested classes. - int modCount; - - /** - * The entry set. There is only one instance per hashmap, namely - * theEntrySet. Note that the entry set may silently shrink, just - * like the WeakHashMap. - */ - private final class WeakEntrySet extends AbstractSet - { - /** - * Non-private constructor to reduce bytecode emitted. - */ - WeakEntrySet() - { - } - - /** - * Returns the size of this set. - * - * @return the set size - */ - public int size() - { - return size; - } - - /** - * Returns an iterator for all entries. - * - * @return an Entry iterator - */ - public Iterator iterator() - { - return new Iterator() - { - /** - * The entry that was returned by the last - * <code>next()</code> call. This is also the entry whose - * bucket should be removed by the <code>remove</code> call. <br> - * - * It is null, if the <code>next</code> method wasn't - * called yet, or if the entry was already removed. <br> - * - * Remembering this entry here will also prevent it from - * being removed under us, since the entry strongly refers - * to the key. - */ - WeakBucket.WeakEntry lastEntry; - - /** - * The entry that will be returned by the next - * <code>next()</code> call. It is <code>null</code> if there - * is no further entry. <br> - * - * Remembering this entry here will also prevent it from - * being removed under us, since the entry strongly refers - * to the key. - */ - WeakBucket.WeakEntry nextEntry = findNext(null); - - /** - * The known number of modification to the list, if it differs - * from the real number, we throw an exception. - */ - int knownMod = modCount; - - /** - * Check the known number of modification to the number of - * modifications of the table. If it differs from the real - * number, we throw an exception. - * @throws ConcurrentModificationException if the number - * of modifications doesn't match. - */ - private void checkMod() - { - // This method will get inlined. - cleanQueue(); - if (knownMod != modCount) - throw new ConcurrentModificationException(); - } - - /** - * Get a strong reference to the next entry after - * lastBucket. - * @param lastEntry the previous bucket, or null if we should - * get the first entry. - * @return the next entry. - */ - private WeakBucket.WeakEntry findNext(WeakBucket.WeakEntry lastEntry) - { - int slot; - WeakBucket nextBucket; - if (lastEntry != null) - { - nextBucket = lastEntry.getBucket().next; - slot = lastEntry.getBucket().slot; - } - else - { - nextBucket = buckets[0]; - slot = 0; - } - - while (true) - { - while (nextBucket != null) - { - WeakBucket.WeakEntry entry = nextBucket.getEntry(); - if (entry != null) - // This is the next entry. - return entry; - - // Entry was cleared, try next. - nextBucket = nextBucket.next; - } - - slot++; - if (slot == buckets.length) - // No more buckets, we are through. - return null; - - nextBucket = buckets[slot]; - } - } - - /** - * Checks if there are more entries. - * @return true, iff there are more elements. - * @throws ConcurrentModificationException if the hash map was - * modified. - */ - public boolean hasNext() - { - checkMod(); - return nextEntry != null; - } - - /** - * Returns the next entry. - * @return the next entry. - * @throws ConcurrentModificationException if the hash map was - * modified. - * @throws NoSuchElementException if there is no entry. - */ - public Object next() - { - checkMod(); - if (nextEntry == null) - throw new NoSuchElementException(); - lastEntry = nextEntry; - nextEntry = findNext(lastEntry); - return lastEntry; - } - - /** - * Removes the last returned entry from this set. This will - * also remove the bucket of the underlying weak hash map. - * @throws ConcurrentModificationException if the hash map was - * modified. - * @throws IllegalStateException if <code>next()</code> was - * never called or the element was already removed. - */ - public void remove() - { - checkMod(); - if (lastEntry == null) - throw new IllegalStateException(); - modCount++; - internalRemove(lastEntry.getBucket()); - lastEntry = null; - knownMod++; - } - }; - } - } - - /** - * A bucket is a weak reference to the key, that contains a strong - * reference to the value, a pointer to the next bucket and its slot - * number. <br> - * - * It would be cleaner to have a WeakReference as field, instead of - * extending it, but if a weak reference gets cleared, we only get - * the weak reference (by queue.poll) and wouldn't know where to - * look for this reference in the hashtable, to remove that entry. - * - * @author Jochen Hoenicke - */ - private static class WeakBucket extends WeakReference - { - /** - * The value of this entry. The key is stored in the weak - * reference that we extend. - */ - Object value; - - /** - * The next bucket describing another entry that uses the same - * slot. - */ - WeakBucket next; - - /** - * The slot of this entry. This should be - * <code>Math.abs(key.hashCode() % buckets.length)</code>. - * - * But since the key may be silently removed we have to remember - * the slot number. - * - * If this bucket was removed the slot is -1. This marker will - * prevent the bucket from being removed twice. - */ - int slot; - - /** - * Creates a new bucket for the given key/value pair and the specified - * slot. - * @param key the key - * @param queue the queue the weak reference belongs to - * @param value the value - * @param slot the slot. This must match the slot where this bucket - * will be enqueued. - */ - public WeakBucket(Object key, ReferenceQueue queue, Object value, - int slot) - { - super(key, queue); - this.value = value; - this.slot = slot; - } - - /** - * This class gives the <code>Entry</code> representation of the - * current bucket. It also keeps a strong reference to the - * key; bad things may happen otherwise. - */ - class WeakEntry implements Map.Entry - { - /** - * The strong ref to the key. - */ - Object key; - - /** - * Creates a new entry for the key. - * @param key the key - */ - public WeakEntry(Object key) - { - this.key = key; - } - - /** - * Returns the underlying bucket. - * @return the owning bucket - */ - public WeakBucket getBucket() - { - return WeakBucket.this; - } - - /** - * Returns the key. - * @return the key - */ - public Object getKey() - { - return key == NULL_KEY ? null : key; - } - - /** - * Returns the value. - * @return the value - */ - public Object getValue() - { - return value; - } - - /** - * This changes the value. This change takes place in - * the underlying hash map. - * @param newVal the new value - * @return the old value - */ - public Object setValue(Object newVal) - { - Object oldVal = value; - value = newVal; - return oldVal; - } - - /** - * The hashCode as specified in the Entry interface. - * @return the hash code - */ - public int hashCode() - { - return key.hashCode() ^ WeakHashMap.hashCode(value); - } - - /** - * The equals method as specified in the Entry interface. - * @param o the object to compare to - * @return true iff o represents the same key/value pair - */ - public boolean equals(Object o) - { - if (o instanceof Map.Entry) - { - Map.Entry e = (Map.Entry) o; - return key.equals(e.getKey()) - && WeakHashMap.equals(value, e.getValue()); - } - return false; - } - - public String toString() - { - return key + "=" + value; - } - } - - /** - * This returns the entry stored in this bucket, or null, if the - * bucket got cleared in the mean time. - * @return the Entry for this bucket, if it exists - */ - WeakEntry getEntry() - { - final Object key = this.get(); - if (key == null) - return null; - return new WeakEntry(key); - } - } - - /** - * The entry set returned by <code>entrySet()</code>. - */ - private final WeakEntrySet theEntrySet; - - /** - * The hash buckets. These are linked lists. Package visible for use in - * nested classes. - */ - WeakBucket[] buckets; - - /** - * Creates a new weak hash map with default load factor and default - * capacity. - */ - public WeakHashMap() - { - this(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR); - } - - /** - * Creates a new weak hash map with default load factor and the given - * capacity. - * @param initialCapacity the initial capacity - * @throws IllegalArgumentException if initialCapacity is negative - */ - public WeakHashMap(int initialCapacity) - { - this(initialCapacity, DEFAULT_LOAD_FACTOR); - } - - /** - * Creates a new weak hash map with the given initial capacity and - * load factor. - * @param initialCapacity the initial capacity. - * @param loadFactor the load factor (see class description of HashMap). - * @throws IllegalArgumentException if initialCapacity is negative, or - * loadFactor is non-positive - */ - public WeakHashMap(int initialCapacity, float loadFactor) - { - // Check loadFactor for NaN as well. - if (initialCapacity < 0 || ! (loadFactor > 0)) - throw new IllegalArgumentException(); - if (initialCapacity == 0) - initialCapacity = 1; - this.loadFactor = loadFactor; - threshold = (int) (initialCapacity * loadFactor); - theEntrySet = new WeakEntrySet(); - queue = new ReferenceQueue(); - buckets = new WeakBucket[initialCapacity]; - } - - /** - * Construct a new WeakHashMap with the same mappings as the given map. - * The WeakHashMap has a default load factor of 0.75. - * - * @param m the map to copy - * @throws NullPointerException if m is null - * @since 1.3 - */ - public WeakHashMap(Map m) - { - this(m.size(), DEFAULT_LOAD_FACTOR); - putAll(m); - } - - /** - * Simply hashes a non-null Object to its array index. - * @param key the key to hash - * @return its slot number - */ - private int hash(Object key) - { - return Math.abs(key.hashCode() % buckets.length); - } - - /** - * Cleans the reference queue. This will poll all references (which - * are WeakBuckets) from the queue and remove them from this map. - * This will not change modCount, even if it modifies the map. The - * iterators have to make sure that nothing bad happens. <br> - * - * Currently the iterator maintains a strong reference to the key, so - * that is no problem. - */ - // Package visible for use by nested classes. - void cleanQueue() - { - Object bucket = queue.poll(); - while (bucket != null) - { - internalRemove((WeakBucket) bucket); - bucket = queue.poll(); - } - } - - /** - * Rehashes this hashtable. This will be called by the - * <code>add()</code> method if the size grows beyond the threshold. - * It will grow the bucket size at least by factor two and allocates - * new buckets. - */ - private void rehash() - { - WeakBucket[] oldBuckets = buckets; - int newsize = buckets.length * 2 + 1; // XXX should be prime. - threshold = (int) (newsize * loadFactor); - buckets = new WeakBucket[newsize]; - - // Now we have to insert the buckets again. - for (int i = 0; i < oldBuckets.length; i++) - { - WeakBucket bucket = oldBuckets[i]; - WeakBucket nextBucket; - while (bucket != null) - { - nextBucket = bucket.next; - - Object key = bucket.get(); - if (key == null) - { - // This bucket should be removed; it is probably - // already on the reference queue. We don't insert it - // at all, and mark it as cleared. - bucket.slot = -1; - size--; - } - else - { - // Add this bucket to its new slot. - int slot = hash(key); - bucket.slot = slot; - bucket.next = buckets[slot]; - buckets[slot] = bucket; - } - bucket = nextBucket; - } - } - } - - /** - * Finds the entry corresponding to key. Since it returns an Entry - * it will also prevent the key from being removed under us. - * @param key the key, may be null - * @return The WeakBucket.WeakEntry or null, if the key wasn't found. - */ - private WeakBucket.WeakEntry internalGet(Object key) - { - if (key == null) - key = NULL_KEY; - int slot = hash(key); - WeakBucket bucket = buckets[slot]; - while (bucket != null) - { - WeakBucket.WeakEntry entry = bucket.getEntry(); - if (entry != null && key.equals(entry.key)) - return entry; - - bucket = bucket.next; - } - return null; - } - - /** - * Adds a new key/value pair to the hash map. - * @param key the key. This mustn't exists in the map. It may be null. - * @param value the value. - */ - private void internalAdd(Object key, Object value) - { - if (key == null) - key = NULL_KEY; - int slot = hash(key); - WeakBucket bucket = new WeakBucket(key, queue, value, slot); - bucket.next = buckets[slot]; - buckets[slot] = bucket; - size++; - } - - /** - * Removes a bucket from this hash map, if it wasn't removed before - * (e.g. one time through rehashing and one time through reference queue). - * Package visible for use in nested classes. - * - * @param bucket the bucket to remove. - */ - void internalRemove(WeakBucket bucket) - { - int slot = bucket.slot; - if (slot == -1) - // This bucket was already removed. - return; - - // Mark the bucket as removed. This is necessary, since the - // bucket may be enqueued later by the garbage collection, and - // internalRemove will be called a second time. - bucket.slot = -1; - if (buckets[slot] == bucket) - buckets[slot] = bucket.next; - else - { - WeakBucket prev = buckets[slot]; - /* This may throw a NullPointerException. It shouldn't but if - * a race condition occurred (two threads removing the same - * bucket at the same time) it may happen. <br> - * But with race condition many much worse things may happen - * anyway. - */ - while (prev.next != bucket) - prev = prev.next; - prev.next = bucket.next; - } - size--; - } - - /** - * Returns the size of this hash map. Note that the size() may shrink - * spontaneously, if the some of the keys were only weakly reachable. - * @return the number of entries in this hash map. - */ - public int size() - { - cleanQueue(); - return size; - } - - /** - * Tells if the map is empty. Note that the result may change - * spontanously, if all of the keys were only weakly reachable. - * @return true, iff the map is empty. - */ - public boolean isEmpty() - { - cleanQueue(); - return size == 0; - } - - /** - * Tells if the map contains the given key. Note that the result - * may change spontanously, if the key was only weakly - * reachable. - * @param key the key to look for - * @return true, iff the map contains an entry for the given key. - */ - public boolean containsKey(Object key) - { - cleanQueue(); - return internalGet(key) != null; - } - - /** - * Gets the value the key is mapped to. - * @return the value the key was mapped to. It returns null if - * the key wasn't in this map, or if the mapped value was - * explicitly set to null. - */ - public Object get(Object key) - { - cleanQueue(); - WeakBucket.WeakEntry entry = internalGet(key); - return entry == null ? null : entry.getValue(); - } - - /** - * Adds a new key/value mapping to this map. - * @param key the key, may be null - * @param value the value, may be null - * @return the value the key was mapped to previously. It returns - * null if the key wasn't in this map, or if the mapped value - * was explicitly set to null. - */ - public Object put(Object key, Object value) - { - cleanQueue(); - WeakBucket.WeakEntry entry = internalGet(key); - if (entry != null) - return entry.setValue(value); - - modCount++; - if (size >= threshold) - rehash(); - - internalAdd(key, value); - return null; - } - - /** - * Removes the key and the corresponding value from this map. - * @param key the key. This may be null. - * @return the value the key was mapped to previously. It returns - * null if the key wasn't in this map, or if the mapped value was - * explicitly set to null. - */ - public Object remove(Object key) - { - cleanQueue(); - WeakBucket.WeakEntry entry = internalGet(key); - if (entry == null) - return null; - - modCount++; - internalRemove(entry.getBucket()); - return entry.getValue(); - } - - /** - * Returns a set representation of the entries in this map. This - * set will not have strong references to the keys, so they can be - * silently removed. The returned set has therefore the same - * strange behaviour (shrinking size(), disappearing entries) as - * this weak hash map. - * @return a set representation of the entries. - */ - public Set entrySet() - { - cleanQueue(); - return theEntrySet; - } - - /** - * Clears all entries from this map. - */ - public void clear() - { - super.clear(); - } - - /** - * Returns true if the map contains at least one key which points to - * the specified object as a value. Note that the result - * may change spontanously, if its key was only weakly reachable. - * @param value the value to search for - * @return true if it is found in the set. - */ - public boolean containsValue(Object value) - { - cleanQueue(); - return super.containsValue(value); - } - - /** - * Returns a set representation of the keys in this map. This - * set will not have strong references to the keys, so they can be - * silently removed. The returned set has therefore the same - * strange behaviour (shrinking size(), disappearing entries) as - * this weak hash map. - * @return a set representation of the keys. - */ - public Set keySet() - { - cleanQueue(); - return super.keySet(); - } - - /** - * Puts all of the mappings from the given map into this one. If the - * key already exists in this map, its value is replaced. - * @param m the map to copy in - */ - public void putAll(Map m) - { - super.putAll(m); - } - - /** - * Returns a collection representation of the values in this map. This - * collection will not have strong references to the keys, so mappings - * can be silently removed. The returned collection has therefore the same - * strange behaviour (shrinking size(), disappearing entries) as - * this weak hash map. - * @return a collection representation of the values. - */ - public Collection values() - { - cleanQueue(); - return super.values(); - } -} // class WeakHashMap diff --git a/libjava/java/util/jar/Attributes.java b/libjava/java/util/jar/Attributes.java deleted file mode 100644 index 4db2c72e75b..00000000000 --- a/libjava/java/util/jar/Attributes.java +++ /dev/null @@ -1,630 +0,0 @@ -/* Attributes.java -- Represents attribute name/value pairs from a Manifest - Copyright (C) 2000, 2002, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package java.util.jar; - -import java.util.Collection; -import java.util.Hashtable; -import java.util.Map; -import java.util.Set; - -/** - * Represents attribute name/value pairs from a Manifest as a Map. - * The names of an attribute are represented by the - * <code>Attributes.Name</code> class and should confirm to the restrictions - * described in that class. Note that the Map interface that Attributes - * implements allows you to put names and values into the attribute that don't - * follow these restriction (and are not really Atrribute.Names, but if you do - * that it might cause undefined behaviour later). - * <p> - * If you use the constants defined in the inner class Name then you can be - * sure that you always access the right attribute names. This makes - * manipulating the Attributes more or less type safe. - * <p> - * Most of the methods are wrappers to implement the Map interface. The really - * useful and often used methods are <code>getValue(Name)</code> and - * <code>getValue(String)</code>. If you actually want to set attributes you - * may want to use the <code>putValue(String, String)</code> method - * (sorry there is no public type safe <code>putValue(Name, String)</code> - * method). - * - * @see java.util.jar.Attributes.Name - * @author Mark Wielaard (mark@klomp.org) - */ -public class Attributes implements Cloneable, Map -{ - - // Fields - - /** - * The map that holds all the attribute name/value pairs. In this - * implementation it is actually a Hashtable, but that can be different in - * other implementations. - */ - protected Map map; - - // Inner class - - /** - * Represents a name of a Manifest Attribute. Defines a couple of well - * know names for the general main attributes, stand alone application - * attributes, applet attributes, extension identification attributes, - * package versioning and sealing attributes, file contents attributes, - * bean objects attribute and signing attributes. See the - * - * <p>The characters of a Name must obey the following restrictions:</p> - * - * <ul> - * <li>Must contain at least one character</li> - * <li>The first character must be alphanumeric (a-z, A-Z, 0-9)</li> - * <li>All other characters must be alphanumeric, a '-' or a '_'</li> - * </ul> - * - * <p>When comparing Names (with <code>equals</code>) all characters are - * converted to lowercase. But you can get the original case sensitive - * string with the <code>toString()</code> method.</p> - * - * <p>Most important attributes have a constant defined in this - * class. Some other attributes used in Manifest files are: - * <ul> - * <li> "Created-By" - General main attribute, tool and version - * that created this Manifest file.</li> - * <li> "Java-Bean" - Bean objects attribute, whether the entry is a Bean. - * Value is either "true" or "false".</li> - * <li> "Magic" - Signing attribute, application specific signing attribute. - * Must be understood by the manifest parser when present to validate the - * jar (entry).</li> - * </ul> - * - * @since 1.2 - * @author Mark Wielaard (mark@klomp.org) - */ - public static class Name - { - // General Main Attributes - - /** - * General main attribute - - * the version of this Manifest file. - */ - public static final Name MANIFEST_VERSION = new Name("Manifest-Version"); - - /** - * General main attribute - - * the version of the jar file signature. - */ - public static final Name SIGNATURE_VERSION - = new Name("Signature-Version"); - - /** - * General main attribute - - * (relative) file paths of the libraries/classpaths that the Classes in - * this jar file depend on. Paths are separated by spaces. - */ - public static final Name CLASS_PATH = new Name("Class-Path"); - - /** - * Stand alone application attribute - - * the entry (without the .class ending) that is the main - * class of this jar file. - */ - public static final Name MAIN_CLASS = new Name("Main-Class"); - - /** - * Applet attribute - - * a list of extension libraries that the applet in this - * jar file depends on. - * For every named extension there should be some Attributes in the - * Manifest manifest file with the following Names: - * <ul> - * <li> <extension>-Extension-Name: - * unique name of the extension</li> - * <li> <extension>-Specification-Version: - * minimum specification version</li> - * <li> <extension>-Implementation-Version: - * minimum implementation version</li> - * <li> <extension>-Implementation-Vendor-Id: - * unique id of implementation vendor</li> - * <li> <extension>-Implementation-URL: - * where the latest version of the extension library can be found</li> - * </ul> - */ - public static final Name EXTENSION_LIST = new Name("Extension-List"); - - /** - * Extension identification attribute - - * the name if the extension library contained in the jar. - */ - public static final Name EXTENSION_NAME = new Name("Extension-Name"); - - /** - * Extension identification attribute - - * synonym for <code>EXTENSTION_NAME</code>. - */ - public static final Name EXTENSION_INSTALLATION = EXTENSION_NAME; - - // Package versioning and sealing attributes - - /** - * Package versioning - - * name of extension library contained in this jar. - */ - public static final Name IMPLEMENTATION_TITLE - = new Name("Implementation-Title"); - - /** - * Package versioning - - * version of the extension library contained in this jar. - */ - public static final Name IMPLEMENTATION_VERSION - = new Name("Implementation-Version"); - - /** - * Package versioning - - * name of extension library creator contained in this jar. - */ - public static final Name IMPLEMENTATION_VENDOR - = new Name("Implementation-Vendor"); - - /** - * Package versioning - - * unique id of extension library creator. - */ - public static final Name IMPLEMENTATION_VENDOR_ID - = new Name("Implementation-Vendor-Id"); - - /** - * Package versioning - - * location where this implementation can be downloaded. - */ - public static final Name IMPLEMENTATION_URL - = new Name("Implementation-URL"); - - /** - * Package versioning - - * title of the specification contained in this jar. - */ - public static final Name SPECIFICATION_TITLE - = new Name("Specification-Title"); - - /** - * Package versioning - - * version of the specification contained in this jar. - */ - public static final Name SPECIFICATION_VERSION - = new Name("Specification-Version"); - - /** - * Package versioning - - * organisation that maintains the specification contains in this - * jar. - */ - public static final Name SPECIFICATION_VENDOR - = new Name("Specification-Vendor"); - - /** - * Package sealing - - * whether (all) package(s) is(/are) sealed. Value is either "true" - * or "false". - */ - public static final Name SEALED = new Name("Sealed"); - - /** - * File contents attribute - - * Mime type and subtype for the jar entry. - */ - public static final Name CONTENT_TYPE = new Name("Content-Type"); - - /** The (lowercase) String representation of this Name */ - private final String name; - - /** The original String given to the constructor */ - private final String origName; - - // Constructor - - /** - * Creates a new Name from the given String. - * Throws an IllegalArgumentException if the given String is empty or - * contains any illegal Name characters. - * - * @param name the name of the new Name - * @exception IllegalArgumentException if name isn't a valid String - * representation of a Name - * @exception NullPointerException if name is null - */ - public Name(String name) throws IllegalArgumentException, - NullPointerException - { - // name must not be null - // this will throw a NullPointerException if it is - char chars[] = name.toCharArray(); - - // there must be at least one character - if (chars.length == 0) - throw new - IllegalArgumentException - ("There must be at least one character in a name"); - - // first character must be alphanum - char c = chars[0]; - if (!((c >= 'a' && c <= 'z') || - (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'))) - throw new - IllegalArgumentException("First character must be alphanum"); - - // all other characters must be alphanums, '-' or '_' - for (int i = 1; i < chars.length; i++) - { - c = chars[i]; - if (!((c >= 'a' && c <= 'z') || - (c >= 'A' && c <= 'Z') || - (c >= '0' && c <= '9') || (c == '-') || (c == '_'))) - throw new - IllegalArgumentException - ("Characters must be alphanums, '-' or '_'"); - } - - // Still here? Then convert to lower case and be done. - // Store the original name for toString(); - this.origName = name; - this.name = name.toLowerCase(); - } - - /** - * Returns the hash code of the (lowercase) String representation of - * this Name. - */ - public int hashCode() - { - return name.hashCode(); - } - - /** - * Checks if another object is equal to this Name object. - * Another object is equal to this Name object if it is an instance of - * Name and the (lowercase) string representation of the name is equal. - */ - public boolean equals(Object o) - { - // Quick and dirty check - if (name == o) - return true; - - try - { - // Note that the constructor already converts the strings to - // lowercase. - String otherName = ((Name) o).name; - return name.equals(otherName); - } - catch (ClassCastException cce) - { - return false; - } - catch (NullPointerException npe) - { - return false; - } - } - - /** - * Returns the string representation of this Name as given to the - * constructor (not neccesarily the lower case representation). - */ - public String toString() - { - return origName; - } - } - - // Constructors - - /** - * Creates an empty Attributes map. - */ - public Attributes() - { - map = new Hashtable(); - } - - /** - * Creates an empty Attributes map with the given initial size. - * @param size the initial size of the underlying map - */ - public Attributes(int size) - { - map = new Hashtable(size); - } - - /** - * Creates an Attributes map with the initial values taken from another - * Attributes map. - * @param attr Attributes map to take the initial values from - */ - public Attributes(Attributes attr) - { - map = new Hashtable(attr.map); - } - - // Methods - - /** - * Gets the value of an attribute name given as a String. - * - * @param name a String describing the Name to look for - * @return the value gotten from the map of null when not found - */ - public String getValue(String name) - { - return (String) get(new Name(name)); - } - - /** - * Gets the value of the given attribute name. - * - * @param name the Name to look for - * @return the value gotten from the map of null when not found - */ - public String getValue(Name name) - { - return (String) get(name); - } - - /** - * Stores an attribute name (represented by a String) and value in this - * Attributes map. - * When the (case insensitive string) name already exists the value is - * replaced and the old value is returned. - * - * @param name a (case insensitive) String representation of the attribite - * name to add/replace - * @param value the (new) value of the attribute name - * @returns the old value of the attribute name or null if it didn't exist - * yet - */ - public String putValue(String name, String value) - { - return putValue(new Name(name), value); - } - - /** - * Stores an attribute name (represented by a String) and value in this - * Attributes map. - * When the name already exists the value is replaced and the old value - * is returned. - * <p> - * I don't know why there is no public method with this signature. I think - * there should be one. - * - * @param name the attribite name to add/replace - * @param value the (new) value of the attribute name - * @returns the old value of the attribute name or null if it didn't exist - * yet - */ - String putValue(Name name, String value) - { - return (String) put(name, value); - } - - // Methods from Cloneable interface - - /** - * Return a clone of this attribute map. - */ - public Object clone() - { - return new Attributes(this); - } - - // Methods from Map interface - - /** - * Removes all attributes. - */ - public void clear() - { - map.clear(); - } - - /** - * Checks to see if there is an attribute with the specified name. - * XXX - what if the object is a String? - * - * @param attrName the name of the attribute to check - * @return true if there is an attribute with the specified name, false - * otherwise - */ - public boolean containsKey(Object attrName) - { - return map.containsKey(attrName); - } - - /** - * Checks to see if there is an attribute name with the specified value. - * - * @param attrValue the value of a attribute to check - * @return true if there is an attribute name with the specified value, - * false otherwise - */ - public boolean containsValue(Object attrValue) - { - return map.containsValue(attrValue); - } - - /** - * Gives a Set of attribute name and values pairs as MapEntries. - * @see java.util.Map.Entry - * @see java.util.Map#entrySet() - * - * @return a set of attribute name value pairs - */ - public Set entrySet() - { - return map.entrySet(); - } - - /** - * Checks to see if two Attributes are equal. The supplied object must be - * a real instance of Attributes and contain the same attribute name/value - * pairs. - * - * @param o another Attribute object which should be checked for equality - * @return true if the object is an instance of Attributes and contains the - * same name/value pairs, false otherwise - */ - public boolean equals(Object o) - { - // quick and dirty check - if (this == o) - return true; - - try - { - return map.equals(((Attributes) o).map); - } - catch (ClassCastException cce) - { - return false; - } - catch (NullPointerException npe) - { - return false; - } - } - - /** - * Gets the value of a specified attribute name. - * XXX - what if the object is a String? - * - * @param attrName the name of the attribute we want the value of - * @return the value of the specified attribute name or null when there is - * no such attribute name - */ - public Object get(Object attrName) - { - return map.get(attrName); - } - - /** - * Returns the hashcode of the attribute name/value map. - */ - public int hashCode() - { - return map.hashCode(); - } - - /** - * Returns true if there are no attributes set, false otherwise. - */ - public boolean isEmpty() - { - return map.isEmpty(); - } - - /** - * Gives a Set of all the values of defined attribute names. - */ - public Set keySet() - { - return map.keySet(); - } - - /** - * Adds or replaces a attribute name/value pair. - * XXX - What if the name is a string? What if the name is neither a Name - * nor a String? What if the value is not a string? - * - * @param name the name of the attribute - * @param value the (new) value of the attribute - * @return the old value of the attribute or null when there was no old - * attribute with this name - */ - public Object put(Object name, Object value) - { - return map.put(name, value); - } - - /** - * Adds or replaces all attribute name/value pairs from another - * Attributes object to this one. The supplied Map must be an instance of - * Attributes. - * - * @param attr the Attributes object to merge with this one - * @exception ClassCastException if the supplied map is not an instance of - * Attributes - */ - public void putAll(Map attr) - { - if (!(attr instanceof Attributes)) - { - throw new - ClassCastException("Supplied Map is not an instance of Attributes"); - } - map.putAll(attr); - } - - /** - * Remove a attribute name/value pair. - * XXX - What if the name is a String? - * - * @param name the name of the attribute name/value pair to remove - * @return the old value of the attribute or null if the attribute didn't - * exist - */ - public Object remove(Object name) - { - return map.remove(name); - } - - /** - * Returns the number of defined attribute name/value pairs. - */ - public int size() - { - return map.size(); - } - - /** - * Returns all the values of the defined attribute name/value pairs as a - * Collection. - */ - public Collection values() - { - return map.values(); - } -} diff --git a/libjava/java/util/jar/JarEntry.java b/libjava/java/util/jar/JarEntry.java deleted file mode 100644 index 722a283bba3..00000000000 --- a/libjava/java/util/jar/JarEntry.java +++ /dev/null @@ -1,165 +0,0 @@ -/* JarEntry.java - Represents an entry in a jar file - Copyright (C) 2000 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package java.util.jar; - -import java.io.IOException; -import java.security.cert.Certificate; -import java.util.zip.ZipEntry; - -/** - * Extension to a ZipEntry that contains manifest attributes and certificates. - * Both the Atrributes and the Certificates can be null when not set. - * Note that the <code>getCertificates()</code> method only returns a - * valid value after all of the data of the entry has been read. - * <p> - * There are no public methods to set the attributes or certificate of an - * Entru. Only JarEntries created by the classes in <code>java.util.jar</code> - * will have these properties set. - * - * @since 1.2 - * @author Mark Wielaard (mark@klomp.org) - */ - -public class JarEntry extends ZipEntry -{ - // (Package local) fields - - Attributes attr; - Certificate certs[]; - - // Constructors - - /** - * Creates a new JarEntry with the specified name and no attributes or - * or certificates. Calls <code>super(name)</code> so all other (zip)entry - * fields are null or -1. - * - * @param name the name of the new jar entry - * @exception NullPointerException when the supplied name is null - * @exception IllegalArgumentException when the supplied name is longer - * than 65535 bytes - */ - public JarEntry(String name) throws NullPointerException, - IllegalArgumentException - { - super(name); - attr = null; - certs = null; - } - - /** - * Creates a new JarEntry with the specified ZipEntry as template for - * all properties of the entry. Both attributes and certificates will be - * null. - * - * @param entry the ZipEntry whose fields should be copied - */ - public JarEntry(ZipEntry entry) - { - super(entry); - attr = null; - certs = null; - } - - /** - * Creates a new JarEntry with the specified JarEntry as template for - * all properties of the entry. - * - * @param entry the jarEntry whose fields should be copied - */ - public JarEntry(JarEntry entry) - { - super(entry); - try - { - attr = entry.getAttributes(); - } - catch (IOException _) - { - } - certs = entry.getCertificates(); - } - - // Methods - - /** - * Returns a copy of the Attributes set for this entry. - * When no Attributes are set in the manifest null is returned. - * - * @return a copy of the Attributes set for this entry - * @exception IOException This will never be thrown. It is here for - * binary compatibility. - */ - public Attributes getAttributes() throws IOException - { - if (attr != null) - { - return (Attributes) attr.clone(); - } - else - { - return null; - } - } - - /** - * Returns a copy of the certificates set for this entry. - * When no certificates are set or when not all data of this entry has - * been read null is returned. - * <p> - * To make sure that this call returns a valid value you must read all - * data from the JarInputStream for this entry. - * When you don't need the data for an entry but want to know the - * certificates that are set for the entry then you can skip all data by - * calling <code>skip(entry.getSize())</code> on the JarInputStream for - * the entry. - * - * @return a copy of the certificates set for this entry - */ - public Certificate[] getCertificates() - { - if (certs != null) - { - return (Certificate[])certs.clone(); - } - else - { - return null; - } - } -} diff --git a/libjava/java/util/jar/JarException.java b/libjava/java/util/jar/JarException.java deleted file mode 100644 index d6f0634fe71..00000000000 --- a/libjava/java/util/jar/JarException.java +++ /dev/null @@ -1,77 +0,0 @@ -/* JarException.java -- thrown to indicate an problem with a jar file - Copyright (C) 2000, 2002 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package java.util.jar; - -import java.util.zip.ZipException; - -/** - * This exception is thrown to indicate an problem with a jar file. - * Note that none of the methods in the java.util.jar package actually declare - * to throw this exception, most just declare that they throw an IOException - * which is super class of JarException. - * - * @author Mark Wielaard (mark@klomp.org) - * @since 1.2 - */ -public class JarException extends ZipException -{ - /** - * Compatible with JDK 1.2+. - */ - private static final long serialVersionUID = 7159778400963954473L; - - /** - * Create a new JarException without a descriptive error message. - */ - public JarException() - { - } - - /** - * Create a new JarException with a descriptive error message indicating - * what went wrong. This message can later be retrieved by calling the - * <code>getMessage()</code> method. - * - * @param message The descriptive error message - * @see #getMessage() - */ - public JarException(String message) - { - super(message); - } -} diff --git a/libjava/java/util/jar/JarFile.java b/libjava/java/util/jar/JarFile.java deleted file mode 100644 index 3550ad8e0fb..00000000000 --- a/libjava/java/util/jar/JarFile.java +++ /dev/null @@ -1,1058 +0,0 @@ -/* JarFile.java - Representation of a jar file - Copyright (C) 2000, 2003, 2004 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util.jar; - -import gnu.java.io.Base64InputStream; -import gnu.java.security.OID; -import gnu.java.security.pkcs.PKCS7SignedData; -import gnu.java.security.pkcs.SignerInfo; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.security.InvalidKeyException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.Signature; -import java.security.SignatureException; -import java.security.cert.CRLException; -import java.security.cert.Certificate; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.util.Arrays; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.zip.ZipEntry; -import java.util.zip.ZipException; -import java.util.zip.ZipFile; - -/** - * Representation of a jar file. - * <p> - * Note that this class is not a subclass of java.io.File but a subclass of - * java.util.zip.ZipFile and you can only read JarFiles with it (although - * there are constructors that take a File object). - * - * @since 1.2 - * @author Mark Wielaard (mark@klomp.org) - * @author Casey Marshall (csm@gnu.org) wrote the certificate and entry - * verification code. - */ -public class JarFile extends ZipFile -{ - // Fields - - /** The name of the manifest entry: META-INF/MANIFEST.MF */ - public static final String MANIFEST_NAME = "META-INF/MANIFEST.MF"; - - /** The META-INF directory entry. */ - private static final String META_INF = "META-INF/"; - - /** The suffix for PKCS7 DSA signature entries. */ - private static final String PKCS7_DSA_SUFFIX = ".DSA"; - - /** The suffix for PKCS7 RSA signature entries. */ - private static final String PKCS7_RSA_SUFFIX = ".RSA"; - - /** The suffix for digest attributes. */ - private static final String DIGEST_KEY_SUFFIX = "-Digest"; - - /** The suffix for signature files. */ - private static final String SF_SUFFIX = ".SF"; - - // Signature OIDs. - private static final OID MD2_OID = new OID("1.2.840.113549.2.2"); - private static final OID MD4_OID = new OID("1.2.840.113549.2.4"); - private static final OID MD5_OID = new OID("1.2.840.113549.2.5"); - private static final OID SHA1_OID = new OID("1.3.14.3.2.26"); - private static final OID DSA_ENCRYPTION_OID = new OID("1.2.840.10040.4.1"); - private static final OID RSA_ENCRYPTION_OID = new OID("1.2.840.113549.1.1.1"); - - /** - * The manifest of this file, if any, otherwise null. - * Read when first needed. - */ - private Manifest manifest; - - /** Whether to verify the manifest and all entries. */ - boolean verify; - - /** Whether the has already been loaded. */ - private boolean manifestRead = false; - - /** Whether the signature files have been loaded. */ - boolean signaturesRead = false; - - /** - * A map between entry names and booleans, signaling whether or - * not that entry has been verified. - * Only be accessed with lock on this JarFile*/ - HashMap verified = new HashMap(); - - /** - * A mapping from entry name to certificates, if any. - * Only accessed with lock on this JarFile. - */ - HashMap entryCerts; - - static boolean DEBUG = false; - static void debug(Object msg) - { - System.err.print(JarFile.class.getName()); - System.err.print(" >>> "); - System.err.println(msg); - } - - // Constructors - - /** - * Creates a new JarFile. All jar entries are verified (when a Manifest file - * for this JarFile exists). You need to actually open and read the complete - * jar entry (with <code>getInputStream()</code>) to check its signature. - * - * @param fileName the name of the file to open - * @exception FileNotFoundException if the fileName cannot be found - * @exception IOException if another IO exception occurs while reading - */ - public JarFile(String fileName) throws FileNotFoundException, IOException - { - this(fileName, true); - } - - /** - * Creates a new JarFile. If verify is true then all jar entries are - * verified (when a Manifest file for this JarFile exists). You need to - * actually open and read the complete jar entry - * (with <code>getInputStream()</code>) to check its signature. - * - * @param fileName the name of the file to open - * @param verify checks manifest and entries when true and a manifest - * exists, when false no checks are made - * @exception FileNotFoundException if the fileName cannot be found - * @exception IOException if another IO exception occurs while reading - */ - public JarFile(String fileName, boolean verify) throws - FileNotFoundException, IOException - { - super(fileName); - if (verify) - { - manifest = readManifest(); - verify(); - } - } - - /** - * Creates a new JarFile. All jar entries are verified (when a Manifest file - * for this JarFile exists). You need to actually open and read the complete - * jar entry (with <code>getInputStream()</code>) to check its signature. - * - * @param file the file to open as a jar file - * @exception FileNotFoundException if the file does not exits - * @exception IOException if another IO exception occurs while reading - */ - public JarFile(File file) throws FileNotFoundException, IOException - { - this(file, true); - } - - /** - * Creates a new JarFile. If verify is true then all jar entries are - * verified (when a Manifest file for this JarFile exists). You need to - * actually open and read the complete jar entry - * (with <code>getInputStream()</code>) to check its signature. - * - * @param file the file to open to open as a jar file - * @param verify checks manifest and entries when true and a manifest - * exists, when false no checks are made - * @exception FileNotFoundException if file does not exist - * @exception IOException if another IO exception occurs while reading - */ - public JarFile(File file, boolean verify) throws FileNotFoundException, - IOException - { - super(file); - if (verify) - { - manifest = readManifest(); - verify(); - } - } - - /** - * Creates a new JarFile with the indicated mode. If verify is true then - * all jar entries are verified (when a Manifest file for this JarFile - * exists). You need to actually open and read the complete jar entry - * (with <code>getInputStream()</code>) to check its signature. - * manifest and if the manifest exists and verify is true verfies it. - * - * @param file the file to open to open as a jar file - * @param verify checks manifest and entries when true and a manifest - * exists, when false no checks are made - * @param mode either ZipFile.OPEN_READ or - * (ZipFile.OPEN_READ | ZipFile.OPEN_DELETE) - * @exception FileNotFoundException if the file does not exist - * @exception IOException if another IO exception occurs while reading - * @exception IllegalArgumentException when given an illegal mode - * - * @since 1.3 - */ - public JarFile(File file, boolean verify, int mode) throws - FileNotFoundException, IOException, IllegalArgumentException - { - super(file, mode); - if (verify) - { - manifest = readManifest(); - verify(); - } - } - - // Methods - - /** - * XXX - should verify the manifest file - */ - private void verify() - { - // only check if manifest is not null - if (manifest == null) - { - verify = false; - return; - } - - verify = true; - // XXX - verify manifest - } - - /** - * Parses and returns the manifest if it exists, otherwise returns null. - */ - private Manifest readManifest() - { - try - { - ZipEntry manEntry = super.getEntry(MANIFEST_NAME); - if (manEntry != null) - { - InputStream in = super.getInputStream(manEntry); - manifestRead = true; - return new Manifest(in); - } - else - { - manifestRead = true; - return null; - } - } - catch (IOException ioe) - { - manifestRead = true; - return null; - } - } - - /** - * Returns a enumeration of all the entries in the JarFile. - * Note that also the Jar META-INF entries are returned. - * - * @exception IllegalStateException when the JarFile is already closed - */ - public Enumeration entries() throws IllegalStateException - { - return new JarEnumeration(super.entries(), this); - } - - /** - * Wraps a given Zip Entries Enumeration. For every zip entry a - * JarEntry is created and the corresponding Attributes are looked up. - */ - private static class JarEnumeration implements Enumeration - { - - private final Enumeration entries; - private final JarFile jarfile; - - JarEnumeration(Enumeration e, JarFile f) - { - entries = e; - jarfile = f; - } - - public boolean hasMoreElements() - { - return entries.hasMoreElements(); - } - - public Object nextElement() - { - ZipEntry zip = (ZipEntry) entries.nextElement(); - JarEntry jar = new JarEntry(zip); - Manifest manifest; - try - { - manifest = jarfile.getManifest(); - } - catch (IOException ioe) - { - manifest = null; - } - - if (manifest != null) - { - jar.attr = manifest.getAttributes(jar.getName()); - } - - synchronized(jarfile) - { - if (!jarfile.signaturesRead) - try - { - jarfile.readSignatures(); - } - catch (IOException ioe) - { - if (JarFile.DEBUG) - { - JarFile.debug(ioe); - ioe.printStackTrace(); - } - jarfile.signaturesRead = true; // fudge it. - } - - // Include the certificates only if we have asserted that the - // signatures are valid. This means the certificates will not be - // available if the entry hasn't been read yet. - if (jarfile.entryCerts != null - && jarfile.verified.get(zip.getName()) == Boolean.TRUE) - { - Set certs = (Set) jarfile.entryCerts.get(jar.getName()); - if (certs != null) - jar.certs = (Certificate[]) - certs.toArray(new Certificate[certs.size()]); - } - } - return jar; - } - } - - /** - * XXX - * It actually returns a JarEntry not a zipEntry - * @param name XXX - */ - public synchronized ZipEntry getEntry(String name) - { - ZipEntry entry = super.getEntry(name); - if (entry != null) - { - JarEntry jarEntry = new JarEntry(entry); - Manifest manifest; - try - { - manifest = getManifest(); - } - catch (IOException ioe) - { - manifest = null; - } - - if (manifest != null) - { - jarEntry.attr = manifest.getAttributes(name); - } - - if (!signaturesRead) - try - { - readSignatures(); - } - catch (IOException ioe) - { - if (DEBUG) - { - debug(ioe); - ioe.printStackTrace(); - } - signaturesRead = true; - } - // See the comments in the JarEnumeration for why we do this - // check. - if (DEBUG) - debug("entryCerts=" + entryCerts + " verified " + name - + " ? " + verified.get(name)); - if (entryCerts != null && verified.get(name) == Boolean.TRUE) - { - Set certs = (Set) entryCerts.get(name); - if (certs != null) - jarEntry.certs = (Certificate[]) - certs.toArray(new Certificate[certs.size()]); - } - return jarEntry; - } - return null; - } - - /** - * Returns an input stream for the given entry. If configured to - * verify entries, the input stream returned will verify them while - * the stream is read, but only on the first time. - * - * @param entry The entry to get the input stream for. - * @exception ZipException XXX - * @exception IOException XXX - */ - public synchronized InputStream getInputStream(ZipEntry entry) throws - ZipException, IOException - { - // If we haven't verified the hash, do it now. - if (!verified.containsKey(entry.getName()) && verify) - { - if (DEBUG) - debug("reading and verifying " + entry); - return new EntryInputStream(entry, super.getInputStream(entry), this); - } - else - { - if (DEBUG) - debug("reading already verified entry " + entry); - if (verify && verified.get(entry.getName()) == Boolean.FALSE) - throw new ZipException("digest for " + entry + " is invalid"); - return super.getInputStream(entry); - } - } - - /** - * Returns the JarEntry that belongs to the name if such an entry - * exists in the JarFile. Returns null otherwise - * Convenience method that just casts the result from <code>getEntry</code> - * to a JarEntry. - * - * @param name the jar entry name to look up - * @return the JarEntry if it exists, null otherwise - */ - public JarEntry getJarEntry(String name) - { - return (JarEntry) getEntry(name); - } - - /** - * Returns the manifest for this JarFile or null when the JarFile does not - * contain a manifest file. - */ - public synchronized Manifest getManifest() throws IOException - { - if (!manifestRead) - manifest = readManifest(); - - return manifest; - } - - // Only called with lock on this JarFile. - private void readSignatures() throws IOException - { - Map pkcs7Dsa = new HashMap(); - Map pkcs7Rsa = new HashMap(); - Map sigFiles = new HashMap(); - - // Phase 1: Read all signature files. These contain the user - // certificates as well as the signatures themselves. - for (Enumeration e = super.entries(); e.hasMoreElements(); ) - { - ZipEntry ze = (ZipEntry) e.nextElement(); - String name = ze.getName(); - if (name.startsWith(META_INF)) - { - String alias = name.substring(META_INF.length()); - if (alias.lastIndexOf('.') >= 0) - alias = alias.substring(0, alias.lastIndexOf('.')); - - if (name.endsWith(PKCS7_DSA_SUFFIX) || name.endsWith(PKCS7_RSA_SUFFIX)) - { - if (DEBUG) - debug("reading PKCS7 info from " + name + ", alias=" + alias); - PKCS7SignedData sig = null; - try - { - sig = new PKCS7SignedData(super.getInputStream(ze)); - } - catch (CertificateException ce) - { - IOException ioe = new IOException("certificate parsing error"); - ioe.initCause(ce); - throw ioe; - } - catch (CRLException crle) - { - IOException ioe = new IOException("CRL parsing error"); - ioe.initCause(crle); - throw ioe; - } - if (name.endsWith(PKCS7_DSA_SUFFIX)) - pkcs7Dsa.put(alias, sig); - else if (name.endsWith(PKCS7_RSA_SUFFIX)) - pkcs7Rsa.put(alias, sig); - } - else if (name.endsWith(SF_SUFFIX)) - { - if (DEBUG) - debug("reading signature file for " + alias + ": " + name); - Manifest sf = new Manifest(super.getInputStream(ze)); - sigFiles.put(alias, sf); - if (DEBUG) - debug("result: " + sf); - } - } - } - - // Phase 2: verify the signatures on any signature files. - Set validCerts = new HashSet(); - Map entryCerts = new HashMap(); - for (Iterator it = sigFiles.entrySet().iterator(); it.hasNext(); ) - { - int valid = 0; - Map.Entry e = (Map.Entry) it.next(); - String alias = (String) e.getKey(); - - PKCS7SignedData sig = (PKCS7SignedData) pkcs7Dsa.get(alias); - if (sig != null) - { - Certificate[] certs = sig.getCertificates(); - Set signerInfos = sig.getSignerInfos(); - for (Iterator it2 = signerInfos.iterator(); it2.hasNext(); ) - verify(certs, (SignerInfo) it2.next(), alias, validCerts); - } - - sig = (PKCS7SignedData) pkcs7Rsa.get(alias); - if (sig != null) - { - Certificate[] certs = sig.getCertificates(); - Set signerInfos = sig.getSignerInfos(); - for (Iterator it2 = signerInfos.iterator(); it2.hasNext(); ) - verify(certs, (SignerInfo) it2.next(), alias, validCerts); - } - - // It isn't a signature for anything. Punt it. - if (validCerts.isEmpty()) - { - it.remove(); - continue; - } - - entryCerts.put(e.getValue(), new HashSet(validCerts)); - validCerts.clear(); - } - - // Phase 3: verify the signature file signatures against the manifest, - // mapping the entry name to the target certificates. - this.entryCerts = new HashMap(); - for (Iterator it = entryCerts.entrySet().iterator(); it.hasNext(); ) - { - Map.Entry e = (Map.Entry) it.next(); - Manifest sigfile = (Manifest) e.getKey(); - Map entries = sigfile.getEntries(); - Set certificates = (Set) e.getValue(); - - for (Iterator it2 = entries.entrySet().iterator(); it2.hasNext(); ) - { - Map.Entry e2 = (Map.Entry) it2.next(); - String entryname = String.valueOf(e2.getKey()); - Attributes attr = (Attributes) e2.getValue(); - if (verifyHashes(entryname, attr)) - { - if (DEBUG) - debug("entry " + entryname + " has certificates " + certificates); - Set s = (Set) this.entryCerts.get(entryname); - if (s != null) - s.addAll(certificates); - else - this.entryCerts.put(entryname, new HashSet(certificates)); - } - } - } - - signaturesRead = true; - } - - /** - * Tell if the given signer info is over the given alias's signature file, - * given one of the certificates specified. - */ - private void verify(Certificate[] certs, SignerInfo signerInfo, - String alias, Set validCerts) - { - Signature sig = null; - try - { - OID alg = signerInfo.getDigestEncryptionAlgorithmId(); - if (alg.equals(DSA_ENCRYPTION_OID)) - { - if (!signerInfo.getDigestAlgorithmId().equals(SHA1_OID)) - return; - sig = Signature.getInstance("SHA1withDSA"); - } - else if (alg.equals(RSA_ENCRYPTION_OID)) - { - OID hash = signerInfo.getDigestAlgorithmId(); - if (hash.equals(MD2_OID)) - sig = Signature.getInstance("md2WithRsaEncryption"); - else if (hash.equals(MD4_OID)) - sig = Signature.getInstance("md4WithRsaEncryption"); - else if (hash.equals(MD5_OID)) - sig = Signature.getInstance("md5WithRsaEncryption"); - else if (hash.equals(SHA1_OID)) - sig = Signature.getInstance("sha1WithRsaEncryption"); - else - return; - } - else - { - if (DEBUG) - debug("unsupported signature algorithm: " + alg); - return; - } - } - catch (NoSuchAlgorithmException nsae) - { - if (DEBUG) - { - debug(nsae); - nsae.printStackTrace(); - } - return; - } - ZipEntry sigFileEntry = super.getEntry(META_INF + alias + SF_SUFFIX); - if (sigFileEntry == null) - return; - for (int i = 0; i < certs.length; i++) - { - if (!(certs[i] instanceof X509Certificate)) - continue; - X509Certificate cert = (X509Certificate) certs[i]; - if (!cert.getIssuerX500Principal().equals(signerInfo.getIssuer()) || - !cert.getSerialNumber().equals(signerInfo.getSerialNumber())) - continue; - try - { - sig.initVerify(cert.getPublicKey()); - InputStream in = super.getInputStream(sigFileEntry); - if (in == null) - continue; - byte[] buf = new byte[1024]; - int len = 0; - while ((len = in.read(buf)) != -1) - sig.update(buf, 0, len); - if (sig.verify(signerInfo.getEncryptedDigest())) - { - if (DEBUG) - debug("signature for " + cert.getSubjectDN() + " is good"); - validCerts.add(cert); - } - } - catch (IOException ioe) - { - continue; - } - catch (InvalidKeyException ike) - { - continue; - } - catch (SignatureException se) - { - continue; - } - } - } - - /** - * Verifies that the digest(s) in a signature file were, in fact, made - * over the manifest entry for ENTRY. - * - * @param entry The entry name. - * @param attr The attributes from the signature file to verify. - */ - private boolean verifyHashes(String entry, Attributes attr) - { - int verified = 0; - - // The bytes for ENTRY's manifest entry, which are signed in the - // signature file. - byte[] entryBytes = null; - try - { - ZipEntry e = super.getEntry(entry); - if (e == null) - { - if (DEBUG) - debug("verifyHashes: no entry '" + entry + "'"); - return false; - } - entryBytes = readManifestEntry(e); - } - catch (IOException ioe) - { - if (DEBUG) - { - debug(ioe); - ioe.printStackTrace(); - } - return false; - } - - for (Iterator it = attr.entrySet().iterator(); it.hasNext(); ) - { - Map.Entry e = (Map.Entry) it.next(); - String key = String.valueOf(e.getKey()); - if (!key.endsWith(DIGEST_KEY_SUFFIX)) - continue; - String alg = key.substring(0, key.length() - DIGEST_KEY_SUFFIX.length()); - try - { - byte[] hash = Base64InputStream.decode((String) e.getValue()); - MessageDigest md = MessageDigest.getInstance(alg); - md.update(entryBytes); - byte[] hash2 = md.digest(); - if (DEBUG) - debug("verifying SF entry " + entry + " alg: " + md.getAlgorithm() - + " expect=" + new java.math.BigInteger(hash).toString(16) - + " comp=" + new java.math.BigInteger(hash2).toString(16)); - if (!Arrays.equals(hash, hash2)) - return false; - verified++; - } - catch (IOException ioe) - { - if (DEBUG) - { - debug(ioe); - ioe.printStackTrace(); - } - return false; - } - catch (NoSuchAlgorithmException nsae) - { - if (DEBUG) - { - debug(nsae); - nsae.printStackTrace(); - } - return false; - } - } - - // We have to find at least one valid digest. - return verified > 0; - } - - /** - * Read the raw bytes that comprise a manifest entry. We can't use the - * Manifest object itself, because that loses information (such as line - * endings, and order of entries). - */ - private byte[] readManifestEntry(ZipEntry entry) throws IOException - { - InputStream in = super.getInputStream(super.getEntry(MANIFEST_NAME)); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - byte[] target = ("Name: " + entry.getName()).getBytes(); - int t = 0, c, prev = -1, state = 0, l = -1; - - while ((c = in.read()) != -1) - { -// if (DEBUG) -// debug("read " -// + (c == '\n' ? "\\n" : (c == '\r' ? "\\r" : String.valueOf((char) c))) -// + " state=" + state + " prev=" -// + (prev == '\n' ? "\\n" : (prev == '\r' ? "\\r" : String.valueOf((char) prev))) -// + " t=" + t + (t < target.length ? (" target[t]=" + (char) target[t]) : "") -// + " l=" + l); - switch (state) - { - - // Step 1: read until we find the "target" bytes: the start - // of the entry we need to read. - case 0: - if (((byte) c) != target[t]) - t = 0; - else - { - t++; - if (t == target.length) - { - out.write(target); - state = 1; - } - } - break; - - // Step 2: assert that there is a newline character after - // the "target" bytes. - case 1: - if (c != '\n' && c != '\r') - { - out.reset(); - t = 0; - state = 0; - } - else - { - out.write(c); - state = 2; - } - break; - - // Step 3: read this whole entry, until we reach an empty - // line. - case 2: - if (c == '\n') - { - out.write(c); - // NL always terminates a line. - if (l == 0 || (l == 1 && prev == '\r')) - return out.toByteArray(); - l = 0; - } - else - { - // Here we see a blank line terminated by a CR, - // followed by the next entry. Technically, `c' should - // always be 'N' at this point. - if (l == 1 && prev == '\r') - return out.toByteArray(); - out.write(c); - l++; - } - prev = c; - break; - - default: - throw new RuntimeException("this statement should be unreachable"); - } - } - - // The last entry, with a single CR terminating the line. - if (state == 2 && prev == '\r' && l == 0) - return out.toByteArray(); - - // We should not reach this point, we didn't find the entry (or, possibly, - // it is the last entry and is malformed). - throw new IOException("could not find " + entry + " in manifest"); - } - - /** - * A utility class that verifies jar entries as they are read. - */ - private static class EntryInputStream extends FilterInputStream - { - private final JarFile jarfile; - private final long length; - private long pos; - private final ZipEntry entry; - private final byte[][] hashes; - private final MessageDigest[] md; - private boolean checked; - - EntryInputStream(final ZipEntry entry, - final InputStream in, - final JarFile jar) - throws IOException - { - super(in); - this.entry = entry; - this.jarfile = jar; - - length = entry.getSize(); - pos = 0; - checked = false; - - Attributes attr; - Manifest manifest = jarfile.getManifest(); - if (manifest != null) - attr = manifest.getAttributes(entry.getName()); - else - attr = null; - if (DEBUG) - debug("verifying entry " + entry + " attr=" + attr); - if (attr == null) - { - hashes = new byte[0][]; - md = new MessageDigest[0]; - } - else - { - List hashes = new LinkedList(); - List md = new LinkedList(); - for (Iterator it = attr.entrySet().iterator(); it.hasNext(); ) - { - Map.Entry e = (Map.Entry) it.next(); - String key = String.valueOf(e.getKey()); - if (key == null) - continue; - if (!key.endsWith(DIGEST_KEY_SUFFIX)) - continue; - hashes.add(Base64InputStream.decode((String) e.getValue())); - try - { - md.add(MessageDigest.getInstance - (key.substring(0, key.length() - DIGEST_KEY_SUFFIX.length()))); - } - catch (NoSuchAlgorithmException nsae) - { - IOException ioe = new IOException("no such message digest: " + key); - ioe.initCause(nsae); - throw ioe; - } - } - if (DEBUG) - debug("digests=" + md); - this.hashes = (byte[][]) hashes.toArray(new byte[hashes.size()][]); - this.md = (MessageDigest[]) md.toArray(new MessageDigest[md.size()]); - } - } - - public boolean markSupported() - { - return false; - } - - public void mark(int readLimit) - { - } - - public void reset() - { - } - - public int read() throws IOException - { - int b = super.read(); - if (b == -1) - { - eof(); - return -1; - } - for (int i = 0; i < md.length; i++) - md[i].update((byte) b); - pos++; - if (length > 0 && pos >= length) - eof(); - return b; - } - - public int read(byte[] buf, int off, int len) throws IOException - { - int count = super.read(buf, off, (int) Math.min(len, (length != 0 - ? length - pos - : Integer.MAX_VALUE))); - if (count == -1 || (length > 0 && pos >= length)) - { - eof(); - return -1; - } - for (int i = 0; i < md.length; i++) - md[i].update(buf, off, count); - pos += count; - if (length != 0 && pos >= length) - eof(); - return count; - } - - public int read(byte[] buf) throws IOException - { - return read(buf, 0, buf.length); - } - - public long skip(long bytes) throws IOException - { - byte[] b = new byte[1024]; - long amount = 0; - while (amount < bytes) - { - int l = read(b, 0, (int) Math.min(b.length, bytes - amount)); - if (l == -1) - break; - amount += l; - } - return amount; - } - - private void eof() throws IOException - { - if (checked) - return; - checked = true; - for (int i = 0; i < md.length; i++) - { - byte[] hash = md[i].digest(); - if (DEBUG) - debug("verifying " + md[i].getAlgorithm() + " expect=" - + new java.math.BigInteger(hashes[i]).toString(16) - + " comp=" + new java.math.BigInteger(hash).toString(16)); - if (!Arrays.equals(hash, hashes[i])) - { - synchronized(jarfile) - { - if (DEBUG) - debug(entry + " could NOT be verified"); - jarfile.verified.put(entry.getName(), Boolean.FALSE); - } - return; - // XXX ??? what do we do here? - // throw new ZipException("message digest mismatch"); - } - } - - synchronized(jarfile) - { - if (DEBUG) - debug(entry + " has been VERIFIED"); - jarfile.verified.put(entry.getName(), Boolean.TRUE); - } - } - } -} diff --git a/libjava/java/util/jar/JarInputStream.java b/libjava/java/util/jar/JarInputStream.java deleted file mode 100644 index 1788af6add5..00000000000 --- a/libjava/java/util/jar/JarInputStream.java +++ /dev/null @@ -1,200 +0,0 @@ -/* JarInputStream.java - InputStream for reading jar files - Copyright (C) 2000, 2004 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package java.util.jar; - -import java.io.IOException; -import java.io.InputStream; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -/** - * InputStream for reading jar files. - * XXX - verification of the signatures in the Manifest file is not yet - * implemented. - * - * @since 1.2 - * @author Mark Wielaard (mark@klomp.org) - */ - -public class JarInputStream extends ZipInputStream -{ - // Fields - - /** The manifest for this file or null when there was no manifest. */ - private Manifest manifest; - - /** The first real JarEntry for this file. Used by readManifest() to store - an entry that isn't the manifest but that should be returned by - getNextEntry next time it is called. Null when no firstEntry was read - while searching for the manifest entry, or when it has already been - returned by getNextEntry(). */ - private JarEntry firstEntry; - - // Constructors - - /** - * Creates a new JarInputStream and tries to read the manifest. - * If such a manifest is present the JarInputStream tries to verify all - * the entry signatures while reading. - * - * @param in InputStream to read the jar from - * @exception IOException when an error occurs when opening or reading - */ - public JarInputStream(InputStream in) throws IOException - { - this(in, true); - } - - /** - * Creates a new JarInputStream and tries to read the manifest. - * If such a manifest is present and verify is true, the JarInputStream - * tries to verify all the entry signatures while reading. - * - * @param in InputStream to read the jar from - * @param verify whether or not to verify the manifest entries - * @exception IOException when an error occurs when opening or reading - */ - public JarInputStream(InputStream in, boolean verify) throws IOException - { - super(in); - readManifest(verify); - } - - // Methods - - /** - * Set the manifest if found. Skips all entries that start with "META-INF/" - * - * @param verify when true (and a Manifest is found) checks the Manifest, - * when false no check is performed - * @exception IOException if an error occurs while reading - */ - private void readManifest(boolean verify) throws IOException - { - firstEntry = (JarEntry) super.getNextEntry(); - while ((firstEntry != null) && - firstEntry.getName().startsWith("META-INF/")) - { - if (firstEntry.getName().equals(JarFile.MANIFEST_NAME)) - { - manifest = new Manifest(this); - } - firstEntry = (JarEntry) super.getNextEntry(); - } - - if (verify) - { - // XXX - } - } - - /** - * Creates a JarEntry for a particular name and consults the manifest - * for the Attributes of the entry. - * Used by <code>ZipEntry.getNextEntry()</code> - * - * @param name the name of the new entry - */ - protected ZipEntry createZipEntry(String name) - { - ZipEntry zipEntry = super.createZipEntry(name); - JarEntry jarEntry = new JarEntry(zipEntry); - if (manifest != null) - { - jarEntry.attr = manifest.getAttributes(name); - } - return jarEntry; - } - - /** - * Returns the Manifest for the jar file or null if there was no Manifest. - */ - public Manifest getManifest() - { - return manifest; - } - - /** - * Returns the next entry or null when there are no more entries. - * Does actually return a JarEntry, if you don't want to cast it yourself - * use <code>getNextJarEntry()</code>. Does not return any entries found - * at the beginning of the ZipFile that are special - * (those that start with "META-INF/"). - * - * @exception IOException if an IO error occurs when reading the entry - */ - public ZipEntry getNextEntry() throws IOException - { - ZipEntry entry; - if (firstEntry != null) - { - entry = firstEntry; - firstEntry = null; - } - else - { - entry = super.getNextEntry(); - } - return entry; - } - - /** - * Returns the next jar entry or null when there are no more entries. - * - * @exception IOException if an IO error occurs when reading the entry - */ - public JarEntry getNextJarEntry() throws IOException - { - return (JarEntry) getNextEntry(); - } - - /** - * XXX - * - * @param buf XXX - * @param off XXX - * @param len XXX - * @return XXX - * @exception IOException XXX - */ - public int read(byte[]buf, int off, int len) throws IOException - { - // XXX if (verify) {} - return super.read(buf, off, len); - } -} diff --git a/libjava/java/util/jar/JarOutputStream.java b/libjava/java/util/jar/JarOutputStream.java deleted file mode 100644 index 2c8c2f08d8f..00000000000 --- a/libjava/java/util/jar/JarOutputStream.java +++ /dev/null @@ -1,113 +0,0 @@ -/* JarOutputStream.java - OutputStream for writing jar files - Copyright (C) 2000, 2004 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package java.util.jar; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; - -/** - * OutputStream for writing jar files. - * A special ZipOutputStream that can take JarEntries and can have a optional - * Manifest as first entry. - * - * @author Mark Wielaard (mark@klomp.org) - */ - -public class JarOutputStream extends ZipOutputStream -{ - // Constructors - - /** - * Creates a new JarOutputStream without a manifest entry. - * - * @param out the stream to create the new jar on - * @exception IOException if something unexpected happend - */ - public JarOutputStream(OutputStream out) throws IOException - { - this(out, null); - } - - /** - * Creates a new JarOutputStream with a manifest entry. - * The manifest will be the first entry in the jar. - * - * @param out the stream to create the new jar on - * @param man the manifest that should be put in the jar file or null - * for no manifest entry - * @exception IOException if something unexpected happend - */ - public JarOutputStream(OutputStream out, Manifest man) throws IOException - { - super(out); - if (man != null) - writeManifest(man); - } - - // Methods - - /** - * Writes the manifest to a new JarEntry in this JarOutputStream with as - * name JarFile.MANIFEST_NAME. - * - * @param manifest the non null manifest to be written - * @exception IOException if something unexpected happend - */ - private void writeManifest(Manifest manifest) throws IOException - { - // Create a new Jar Entry for the Manifest - JarEntry entry = new JarEntry(JarFile.MANIFEST_NAME); - putNextEntry(entry); - manifest.write(this); - closeEntry(); - } - - /** - * Prepares the JarOutputStream for writing the next entry. - * This implementation just calls <code>super.putNextEntre()</code>. - * - * @param entry The information for the next entry - * @exception IOException when some unexpected I/O exception occurred - */ - public void putNextEntry(ZipEntry entry) throws IOException - { - super.putNextEntry(entry); // XXX - } -} diff --git a/libjava/java/util/jar/Manifest.java b/libjava/java/util/jar/Manifest.java deleted file mode 100644 index fdc76ff97ee..00000000000 --- a/libjava/java/util/jar/Manifest.java +++ /dev/null @@ -1,472 +0,0 @@ -/* Manifest.java -- Reads, writes and manipulaties jar manifest files - Copyright (C) 2000, 2004 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package java.util.jar; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.Map; - -/** - * Reads, writes and manipulaties jar manifest files. - * XXX - * - * @since 1.2 - * @author Mark Wielaard (mark@klomp.org) - */ -public class Manifest implements Cloneable -{ - // Fields - - /** The main attributes of the manifest (jar file). */ - private final Attributes mainAttr; - - /** A map of atrributes for all entries described in this Manifest. */ - private final Map entries; - - // Constructors - - /** - * Creates a new empty Manifest. - */ - public Manifest() - { - mainAttr = new Attributes(); - entries = new Hashtable(); - } - - /** - * Creates a Manifest from the supplied input stream. - * - * @see read(Inputstream) - * @see write(OutputStream) - * - * @param InputStream the input stream to read the manifest from - * @exception IOException when an i/o exception occurs or the input stream - * does not describe a valid manifest - */ - public Manifest(InputStream in) throws IOException - { - this(); - read(in); - } - - /** - * Creates a Manifest from another Manifest. - * Makes a deep copy of the main attributes, but a shallow copy of - * the other entries. This means that you can freely add, change or remove - * the main attributes or the entries of the new manifest without effecting - * the original manifest, but adding, changing or removing attributes from - * a particular entry also changes the attributes of that entry in the - * original manifest. - * - * @see clone() - * @param man the Manifest to copy from - */ - public Manifest(Manifest man) - { - mainAttr = new Attributes(man.getMainAttributes()); - entries = new Hashtable(man.getEntries()); - } - - // Methods - - /** - * Gets the main attributes of this Manifest. - */ - public Attributes getMainAttributes() - { - return mainAttr; - } - - /** - * Gets a map of entry Strings to Attributes for all the entries described - * in this manifest. Adding, changing or removing from this entries map - * changes the entries of this manifest. - */ - public Map getEntries() - { - return entries; - } - - /** - * Returns the Attributes associated with the Entry. - * <p> - * Implemented as: - * <code>return (Attributes)getEntries().get(entryName)</code> - * - * @param entryName the name of the entry to look up - * @return the attributes associated with the entry or null when none - */ - public Attributes getAttributes(String entryName) - { - return (Attributes) getEntries().get(entryName); - } - - /** - * Clears the main attributes and removes all the entries from the - * manifest. - */ - public void clear() - { - mainAttr.clear(); - entries.clear(); - } - - /** - * XXX - */ - public void read(InputStream in) throws IOException - { - BufferedReader br = - new BufferedReader(new InputStreamReader(in, "8859_1")); - read_main_section(getMainAttributes(), br); - read_individual_sections(getEntries(), br); - } - - // Private Static methods for reading the Manifest file from BufferedReader - - private static void read_main_section(Attributes attr, - BufferedReader br) throws IOException - { - // According to the spec we should actually call read_version_info() here. - read_attributes(attr, br); - // Explicitly set Manifest-Version attribute if not set in Main - // attributes of Manifest. - if (attr.getValue(Attributes.Name.MANIFEST_VERSION) == null) - attr.putValue(Attributes.Name.MANIFEST_VERSION, "0.0"); - } - - /** - * Pedantic method that requires the next attribute in the Manifest to be - * the "Manifest-Version". This follows the Manifest spec closely but - * reject some jar Manifest files out in the wild. - */ - private static void read_version_info(Attributes attr, - BufferedReader br) throws IOException - { - String version_header = Attributes.Name.MANIFEST_VERSION.toString(); - try - { - String value = expect_header(version_header, br); - attr.putValue(Attributes.Name.MANIFEST_VERSION, value); - } - catch (IOException ioe) - { - throw new JarException("Manifest should start with a " + - version_header + ": " + ioe.getMessage()); - } - } - - private static String expect_header(String header, BufferedReader br) - throws IOException - { - String s = br.readLine(); - if (s == null) - { - throw new JarException("unexpected end of file"); - } - return expect_header(header, br, s); - } - - private static String expect_header(String header, BufferedReader br, - String s) throws IOException - { - try - { - String name = s.substring(0, header.length() + 1); - if (name.equalsIgnoreCase(header + ":")) - { - String value_start = s.substring(header.length() + 2); - return read_header_value(value_start, br); - } - } - catch (IndexOutOfBoundsException iobe) - { - } - // If we arrive here, something went wrong - throw new JarException("unexpected '" + s + "'"); - } - - private static String read_header_value(String s, BufferedReader br) - throws IOException - { - boolean try_next = true; - while (try_next) - { - // Lets see if there is something on the next line - br.mark(1); - if (br.read() == ' ') - { - s += br.readLine(); - } - else - { - br.reset(); - try_next = false; - } - } - return s; - } - - private static void read_attributes(Attributes attr, - BufferedReader br) throws IOException - { - String s = br.readLine(); - while (s != null && (!s.equals(""))) - { - read_attribute(attr, s, br); - s = br.readLine(); - } - } - - private static void read_attribute(Attributes attr, String s, - BufferedReader br) throws IOException - { - try - { - int colon = s.indexOf(": "); - String name = s.substring(0, colon); - String value_start = s.substring(colon + 2); - String value = read_header_value(value_start, br); - attr.putValue(name, value); - } - catch (IndexOutOfBoundsException iobe) - { - throw new JarException("Manifest contains a bad header: " + s); - } - } - - private static void read_individual_sections(Map entries, - BufferedReader br) throws - IOException - { - String s = br.readLine(); - while (s != null && (!s.equals(""))) - { - Attributes attr = read_section_name(s, br, entries); - read_attributes(attr, br); - s = br.readLine(); - } - } - - private static Attributes read_section_name(String s, BufferedReader br, - Map entries) throws JarException - { - try - { - String name = expect_header("Name", br, s); - Attributes attr = new Attributes(); - entries.put(name, attr); - return attr; - } - catch (IOException ioe) - { - throw new JarException - ("Section should start with a Name header: " + ioe.getMessage()); - } - } - - /** - * XXX - */ - public void write(OutputStream out) throws IOException - { - PrintWriter pw = - new PrintWriter(new - BufferedWriter(new OutputStreamWriter(out, "8859_1"))); - write_main_section(getMainAttributes(), pw); - pw.println(); - write_individual_sections(getEntries(), pw); - if (pw.checkError()) - { - throw new JarException("Error while writing manifest"); - } - } - - // Private Static functions for writing the Manifest file to a PrintWriter - - private static void write_main_section(Attributes attr, - PrintWriter pw) throws JarException - { - write_version_info(attr, pw); - write_main_attributes(attr, pw); - } - - private static void write_version_info(Attributes attr, PrintWriter pw) - { - // First check if there is already a version attribute set - String version = attr.getValue(Attributes.Name.MANIFEST_VERSION); - if (version == null) - { - version = "1.0"; - } - write_header(Attributes.Name.MANIFEST_VERSION.toString(), version, pw); - } - - private static void write_header(String name, String value, PrintWriter pw) - { - pw.print(name + ": "); - - int last = 68 - name.length(); - if (last > value.length()) - { - pw.println(value); - } - else - { - pw.println(value.substring(0, last)); - } - while (last < value.length()) - { - pw.print(" "); - int end = (last + 69); - if (end > value.length()) - { - pw.println(value.substring(last)); - } - else - { - pw.println(value.substring(last, end)); - } - last = end; - } - } - - private static void write_main_attributes(Attributes attr, PrintWriter pw) - throws JarException - { - Iterator it = attr.entrySet().iterator(); - while (it.hasNext()) - { - Map.Entry entry = (Map.Entry) it.next(); - // Don't print the manifest version again - if (!Attributes.Name.MANIFEST_VERSION.equals(entry.getKey())) - { - write_attribute_entry(entry, pw); - } - } - } - - private static void write_attribute_entry(Map.Entry entry, PrintWriter pw) - throws JarException - { - String name = entry.getKey().toString(); - String value = entry.getValue().toString(); - - if (name.equalsIgnoreCase("Name")) - { - throw new JarException("Attributes cannot be called 'Name'"); - } - if (name.startsWith("From")) - { - throw new - JarException("Header cannot start with the four letters 'From'" + - name); - } - write_header(name, value, pw); - } - - private static void write_individual_sections(Map entries, PrintWriter pw) - throws JarException - { - - Iterator it = entries.entrySet().iterator(); - while (it.hasNext()) - { - Map.Entry entry = (Map.Entry) it.next(); - write_header("Name", entry.getKey().toString(), pw); - write_entry_attributes((Attributes) entry.getValue(), pw); - pw.println(); - } - } - - private static void write_entry_attributes(Attributes attr, PrintWriter pw) - throws JarException - { - Iterator it = attr.entrySet().iterator(); - while (it.hasNext()) - { - Map.Entry entry = (Map.Entry) it.next(); - write_attribute_entry(entry, pw); - } - } - - /** - * Makes a deep copy of the main attributes, but a shallow copy of - * the other entries. This means that you can freely add, change or remove - * the main attributes or the entries of the new manifest without effecting - * the original manifest, but adding, changing or removing attributes from - * a particular entry also changes the attributes of that entry in the - * original manifest. Calls <CODE>new Manifest(this)</CODE>. - */ - public Object clone() - { - return new Manifest(this); - } - - /** - * Checks if another object is equal to this Manifest object. - * Another Object is equal to this Manifest object if it is an instance of - * Manifest and the main attributes and the entries of the other manifest - * are equal to this one. - */ - public boolean equals(Object o) - { - return (o instanceof Manifest) && - (mainAttr.equals(((Manifest) o).mainAttr)) && - (entries.equals(((Manifest) o).entries)); - } - - /** - * Calculates the hash code of the manifest. Implemented by a xor of the - * hash code of the main attributes with the hash code of the entries map. - */ - public int hashCode() - { - return mainAttr.hashCode() ^ entries.hashCode(); - } - -} diff --git a/libjava/java/util/logging/ConsoleHandler.java b/libjava/java/util/logging/ConsoleHandler.java deleted file mode 100644 index 3cf4bca3354..00000000000 --- a/libjava/java/util/logging/ConsoleHandler.java +++ /dev/null @@ -1,125 +0,0 @@ -/* ConsoleHandler.java -- a class for publishing log messages to System.err - Copyright (C) 2002, 2004 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util.logging; - -/** - * A <code>ConsoleHandler</code> publishes log records to - * <code>System.err</code>. - * - * <p><strong>Configuration:</strong> Values of the subsequent - * <code>LogManager</code> properties are taken into consideration - * when a <code>ConsoleHandler</code> is initialized. - * If a property is not defined, or if it has an invalid - * value, a default is taken without an exception being thrown. - * - * <ul> - * - * <li><code>java.util.logging.ConsoleHandler.level</code> - specifies - * the initial severity level threshold. Default value: - * <code>Level.INFO</code>.</li> - * - * <li><code>java.util.logging.ConsoleHandler.filter</code> - specifies - * the name of a Filter class. Default value: No Filter.</li> - * - * <li><code>java.util.logging.ConsoleHandler.formatter</code> - specifies - * the name of a Formatter class. Default value: - * <code>java.util.logging.SimpleFormatter</code>.</li> - * - * <li><code>java.util.logging.ConsoleHandler.encoding</code> - specifies - * the name of the character encoding. Default value: - * the default platform encoding.</li> - * - * </ul> - * - * @author Sascha Brawer (brawer@acm.org) - */ -public class ConsoleHandler - extends StreamHandler -{ - /** - * Constructs a <code>StreamHandler</code> that publishes - * log records to <code>System.err</code>. The initial - * configuration is determined by the <code>LogManager</code> - * properties described above. - */ - public ConsoleHandler() - { - super(System.err, "java.util.logging.ConsoleHandler", Level.INFO, - /* formatter */ null, SimpleFormatter.class); - } - - - /** - * Forces any data that may have been buffered to the underlying - * output device, but does <i>not</i> close <code>System.err</code>. - * - * <p>In case of an I/O failure, the <code>ErrorManager</code> - * of this <code>ConsoleHandler</code> will be informed, but the caller - * of this method will not receive an exception. - */ - public void close() - { - flush(); - } - - - /** - * Publishes a <code>LogRecord</code> to the console, provided the - * record passes all tests for being loggable. - * - * <p>Most applications do not need to call this method directly. - * Instead, they will use use a <code>Logger</code>, which will - * create LogRecords and distribute them to registered handlers. - * - * <p>In case of an I/O failure, the <code>ErrorManager</code> - * of this <code>SocketHandler</code> will be informed, but the caller - * of this method will not receive an exception. - * - * <p>The GNU implementation of <code>ConsoleHandler.publish</code> - * calls flush() for every request to publish a record, so - * they appear immediately on the console. - * - * @param record the log event to be published. - */ - public void publish(LogRecord record) - { - super.publish(record); - flush(); - } -} diff --git a/libjava/java/util/logging/ErrorManager.java b/libjava/java/util/logging/ErrorManager.java deleted file mode 100644 index 57c079fe25b..00000000000 --- a/libjava/java/util/logging/ErrorManager.java +++ /dev/null @@ -1,194 +0,0 @@ -/* ErrorManager.java -- - A class for dealing with errors that a Handler encounters - during logging - Copyright (C) 2002, 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util.logging; - -/** - * An <code>ErrorManager</code> deals with errors that a <code>Handler</code> - * encounters while logging. - * - * @see Handler#setErrorManager(ErrorManager) - * - * @author Sascha Brawer (brawer@acm.org) - */ -public class ErrorManager -{ - /* The values have been taken from Sun's public J2SE 1.4 API - * documentation. - * See http://java.sun.com/j2se/1.4/docs/api/constant-values.html - */ - - /** - * Indicates that there was a failure that does not readily - * fall into any of the other categories. - */ - public static final int GENERIC_FAILURE = 0; - - - /** - * Indicates that there was a problem upon writing to - * an output stream. - */ - public static final int WRITE_FAILURE = 1; - - - /** - * Indicates that there was a problem upon flushing - * an output stream. - */ - public static final int FLUSH_FAILURE = 2; - - - /** - * Indicates that there was a problem upon closing - * an output stream. - */ - public static final int CLOSE_FAILURE = 3; - - - /** - * Indicates that there was a problem upon opening - * an output stream. - */ - public static final int OPEN_FAILURE = 4; - - - /** - * Indicates that there was a problem upon formatting - * the message of a log record. - */ - public static final int FORMAT_FAILURE = 5; - - - /** - * Indicates whether the {@link #error} method of this ErrorManager - * has ever been used. - * - * Declared volatile in order to correctly support the - * double-checked locking idiom (once the revised Java Memory Model - * gets adopted); see Classpath bug #2944. - */ - private volatile boolean everUsed = false; - - - public ErrorManager() - { - } - - - /** - * Reports an error that occured upon logging. The default implementation - * emits the very first error to System.err, ignoring subsequent errors. - * - * @param message a message describing the error, or <code>null</code> if - * there is no suitable description. - * - * @param ex an exception, or <code>null</code> if the error is not - * related to an exception. - * - * @param errorCode one of the defined error codes, for example - * <code>ErrorManager.CLOSE_FAILURE</code>. - */ - public void error(String message, Exception ex, int errorCode) - { - if (everUsed) - return; - - synchronized (this) - { - /* The double check is intentional. If the first check was - * omitted, the monitor would have to be entered every time - * error() method was called. If the second check was - * omitted, the code below could be executed by multiple - * threads simultaneously. - * - * This is the 'double-checked locking' idiom, which is broken - * with the current version of the Java memory model. However, - * we assume that JVMs will have adopted a revised version of - * the Java Memory Model by the time GNU Classpath gains - * widespread acceptance. See Classpath bug #2944. - */ - if (everUsed) - return; - - everUsed = true; - } - - String codeMsg; - switch (errorCode) - { - case GENERIC_FAILURE: - codeMsg = "GENERIC_FAILURE"; - break; - - case WRITE_FAILURE: - codeMsg = "WRITE_FAILURE"; - break; - - case FLUSH_FAILURE: - codeMsg = "FLUSH_FAILURE"; - break; - - case CLOSE_FAILURE: - codeMsg = "CLOSE_FAILURE"; - break; - - case OPEN_FAILURE: - codeMsg = "OPEN_FAILURE"; - break; - - case FORMAT_FAILURE: - codeMsg = "FORMAT_FAILURE"; - break; - - default: - codeMsg = String.valueOf(errorCode); - break; - } - - System.err.println("Error upon logging: " + codeMsg); - if ((message != null) && (message.length() > 0)) - System.err.println(message); - - if (ex != null) - ex.printStackTrace(); - } -} - diff --git a/libjava/java/util/logging/FileHandler.java b/libjava/java/util/logging/FileHandler.java deleted file mode 100644 index a948ba389f4..00000000000 --- a/libjava/java/util/logging/FileHandler.java +++ /dev/null @@ -1,506 +0,0 @@ -/* FileHandler.java -- a class for publishing log messages to log files - Copyright (C) 2002, 2003, 2004, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util.logging; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; - -/** - * A <code>FileHandler</code> publishes log records to a set of log - * files. A maximum file size can be specified; as soon as a log file - * reaches the size limit, it is closed and the next file in the set - * is taken. - * - * <p><strong>Configuration:</strong> Values of the subsequent - * <code>LogManager</code> properties are taken into consideration - * when a <code>FileHandler</code> is initialized. If a property is - * not defined, or if it has an invalid value, a default is taken - * without an exception being thrown. - * - * <ul> - * - * <li><code>java.util.FileHandler.level</code> - specifies - * the initial severity level threshold. Default value: - * <code>Level.ALL</code>.</li> - * - * <li><code>java.util.FileHandler.filter</code> - specifies - * the name of a Filter class. Default value: No Filter.</li> - * - * <li><code>java.util.FileHandler.formatter</code> - specifies - * the name of a Formatter class. Default value: - * <code>java.util.logging.XMLFormatter</code>.</li> - * - * <li><code>java.util.FileHandler.encoding</code> - specifies - * the name of the character encoding. Default value: - * the default platform encoding.</li> - * - * <li><code>java.util.FileHandler.limit</code> - specifies the number - * of bytes a log file is approximately allowed to reach before it - * is closed and the handler switches to the next file in the - * rotating set. A value of zero means that files can grow - * without limit. Default value: 0 (unlimited growth).</li> - * - * <li><code>java.util.FileHandler.count</code> - specifies the number - * of log files through which this handler cycles. Default value: - * 1.</li> - * - * <li><code>java.util.FileHandler.pattern</code> - specifies a - * pattern for the location and name of the produced log files. - * See the section on <a href="#filePatterns">file name - * patterns</a> for details. Default value: - * <code>"%h/java%u.log"</code>.</li> - * - * <li><code>java.util.FileHandler.append</code> - specifies - * whether the handler will append log records to existing - * files, or whether the handler will clear log files - * upon switching to them. Default value: <code>false</code>, - * indicating that files will be cleared.</li> - * - * </ul> - * - * <p><a name="filePatterns"><strong>File Name Patterns:</strong></a> - * The name and location and log files are specified with pattern - * strings. The handler will replace the following character sequences - * when opening log files: - * - * <p><ul> - * <li><code>/</code> - replaced by the platform-specific path name - * separator. This value is taken from the system property - * <code>file.separator</code>.</li> - * - * <li><code>%t</code> - replaced by the platform-specific location of - * the directory intended for temporary files. This value is - * taken from the system property <code>java.io.tmpdir</code>.</li> - * - * <li><code>%h</code> - replaced by the location of the home - * directory of the current user. This value is taken from the - * system property <code>file.separator</code>.</li> - * - * <li><code>%g</code> - replaced by a generation number for - * distinguisthing the individual items in the rotating set - * of log files. The generation number cycles through the - * sequence 0, 1, ..., <code>count</code> - 1.</li> - * - * <li><code>%u</code> - replaced by a unique number for - * distinguisthing the output files of several concurrently - * running processes. The <code>FileHandler</code> starts - * with 0 when it tries to open a log file. If the file - * cannot be opened because it is currently in use, - * the unique number is incremented by one and opening - * is tried again. These steps are repeated until the - * opening operation succeeds. - * - * <p>FIXME: Is the following correct? Please review. The unique - * number is determined for each log file individually when it is - * opened upon switching to the next file. Therefore, it is not - * correct to assume that all log files in a rotating set bear the - * same unique number. - * - * <p>FIXME: The Javadoc for the Sun reference implementation - * says: "Note that the use of unique ids to avoid conflicts is - * only guaranteed to work reliably when using a local disk file - * system." Why? This needs to be mentioned as well, in case - * the reviewers decide the statement is true. Otherwise, - * file a bug report with Sun.</li> - * - * <li><code>%%</code> - replaced by a single percent sign.</li> - * </ul> - * - * <p>If the pattern string does not contain <code>%g</code> and - * <code>count</code> is greater than one, the handler will append - * the string <code>.%g</code> to the specified pattern. - * - * <p>If the handler attempts to open a log file, this log file - * is being used at the time of the attempt, and the pattern string - * does not contain <code>%u</code>, the handler will append - * the string <code>.%u</code> to the specified pattern. This - * step is performed after any generation number has been - * appended. - * - * <p><em>Examples for the GNU platform:</em> - * - * <p><ul> - * - * <li><code>%h/java%u.log</code> will lead to a single log file - * <code>/home/janet/java0.log</code>, assuming <code>count</code> - * equals 1, the user's home directory is - * <code>/home/janet</code>, and the attempt to open the file - * succeeds.</li> - * - * <li><code>%h/java%u.log</code> will lead to three log files - * <code>/home/janet/java0.log.0</code>, - * <code>/home/janet/java0.log.1</code>, and - * <code>/home/janet/java0.log.2</code>, - * assuming <code>count</code> equals 3, the user's home - * directory is <code>/home/janet</code>, and all attempts - * to open files succeed.</li> - * - * <li><code>%h/java%u.log</code> will lead to three log files - * <code>/home/janet/java0.log.0</code>, - * <code>/home/janet/java1.log.1</code>, and - * <code>/home/janet/java0.log.2</code>, - * assuming <code>count</code> equals 3, the user's home - * directory is <code>/home/janet</code>, and the attempt - * to open <code>/home/janet/java0.log.1</code> fails.</li> - * - * </ul> - * - * @author Sascha Brawer (brawer@acm.org) - */ -public class FileHandler - extends StreamHandler -{ - /** - * The number of bytes a log file is approximately allowed to reach - * before it is closed and the handler switches to the next file in - * the rotating set. A value of zero means that files can grow - * without limit. - */ - private final int limit; - - - /** - * The number of log files through which this handler cycles. - */ - private final int count; - - - /** - * The pattern for the location and name of the produced log files. - * See the section on <a href="#filePatterns">file name patterns</a> - * for details. - */ - private final String pattern; - - - /** - * Indicates whether the handler will append log records to existing - * files (<code>true</code>), or whether the handler will clear log files - * upon switching to them (<code>false</code>). - */ - private final boolean append; - - - /** - * Constructs a <code>FileHandler</code>, taking all property values - * from the current {@link LogManager LogManager} configuration. - * - * @throws java.io.IOException FIXME: The Sun Javadoc says: "if - * there are IO problems opening the files." This conflicts - * with the general principle that configuration errors do - * not prohibit construction. Needs review. - * - * @throws SecurityException if a security manager exists and - * the caller is not granted the permission to control - * the logging infrastructure. - */ - public FileHandler() - throws IOException, SecurityException - { - this(/* pattern: use configiguration */ null, - - LogManager.getIntProperty("java.util.logging.FileHandler.limit", - /* default */ 0), - - LogManager.getIntProperty("java.util.logging.FileHandler.count", - /* default */ 1), - - LogManager.getBooleanProperty("java.util.logging.FileHandler.append", - /* default */ false)); - } - - - /* FIXME: Javadoc missing. */ - public FileHandler(String pattern) - throws IOException, SecurityException - { - this(pattern, - /* limit */ 0, - /* count */ 1, - /* append */ false); - } - - - /* FIXME: Javadoc missing. */ - public FileHandler(String pattern, boolean append) - throws IOException, SecurityException - { - this(pattern, - /* limit */ 0, - /* count */ 1, - append); - } - - - /* FIXME: Javadoc missing. */ - public FileHandler(String pattern, int limit, int count) - throws IOException, SecurityException - { - this(pattern, limit, count, - LogManager.getBooleanProperty( - "java.util.logging.FileHandler.append", - /* default */ false)); - } - - - /** - * Constructs a <code>FileHandler</code> given the pattern for the - * location and name of the produced log files, the size limit, the - * number of log files thorough which the handler will rotate, and - * the <code>append</code> property. All other property values are - * taken from the current {@link LogManager LogManager} - * configuration. - * - * @param pattern The pattern for the location and name of the - * produced log files. See the section on <a - * href="#filePatterns">file name patterns</a> for details. - * If <code>pattern</code> is <code>null</code>, the value is - * taken from the {@link LogManager LogManager} configuration - * property - * <code>java.util.logging.FileHandler.pattern</code>. - * However, this is a pecularity of the GNU implementation, - * and Sun's API specification does not mention what behavior - * is to be expected for <code>null</code>. Therefore, - * applications should not rely on this feature. - * - * @param limit specifies the number of bytes a log file is - * approximately allowed to reach before it is closed and the - * handler switches to the next file in the rotating set. A - * value of zero means that files can grow without limit. - * - * @param count specifies the number of log files through which this - * handler cycles. - * - * @param append specifies whether the handler will append log - * records to existing files (<code>true</code>), or whether the - * handler will clear log files upon switching to them - * (<code>false</code>). - * - * @throws java.io.IOException FIXME: The Sun Javadoc says: "if - * there are IO problems opening the files." This conflicts - * with the general principle that configuration errors do - * not prohibit construction. Needs review. - * - * @throws SecurityException if a security manager exists and - * the caller is not granted the permission to control - * the logging infrastructure. - * <p>FIXME: This seems in contrast to all other handler - * constructors -- verify this by running tests against - * the Sun reference implementation. - */ - public FileHandler(String pattern, - int limit, - int count, - boolean append) - throws IOException, SecurityException - { - super(createFileStream(pattern, limit, count, append, - /* generation */ 0), - "java.util.logging.FileHandler", - /* default level */ Level.ALL, - /* formatter */ null, - /* default formatter */ XMLFormatter.class); - - if ((limit <0) || (count < 1)) - throw new IllegalArgumentException(); - - this.pattern = pattern; - this.limit = limit; - this.count = count; - this.append = append; - } - - - /* FIXME: Javadoc missing. */ - private static java.io.OutputStream createFileStream(String pattern, - int limit, - int count, - boolean append, - int generation) - { - String path; - int unique = 0; - - /* Throws a SecurityException if the caller does not have - * LoggingPermission("control"). - */ - LogManager.getLogManager().checkAccess(); - - /* Default value from the java.util.logging.FileHandler.pattern - * LogManager configuration property. - */ - if (pattern == null) - pattern = LogManager.getLogManager().getProperty( - "java.util.logging.FileHandler.pattern"); - if (pattern == null) - pattern = "%h/java%u.log"; - - do - { - path = replaceFileNameEscapes(pattern, generation, unique, count); - - try - { - File file = new File(path); - if (file.createNewFile()) - return new FileOutputStream(path, append); - } - catch (Exception ex) - { - ex.printStackTrace(); - } - - unique = unique + 1; - if (pattern.indexOf("%u") < 0) - pattern = pattern + ".%u"; - } - while (true); - } - - - /** - * Replaces the substrings <code>"/"</code> by the value of the - * system property <code>"file.separator"</code>, <code>"%t"</code> - * by the value of the system property - * <code>"java.io.tmpdir"</code>, <code>"%h"</code> by the value of - * the system property <code>"user.home"</code>, <code>"%g"</code> - * by the value of <code>generation</code>, <code>"%u"</code> by the - * value of <code>uniqueNumber</code>, and <code>"%%"</code> by a - * single percent character. If <code>pattern</code> does - * <em>not</em> contain the sequence <code>"%g"</code>, - * the value of <code>generation</code> will be appended to - * the result. - * - * @throws NullPointerException if one of the system properties - * <code>"file.separator"</code>, - * <code>"java.io.tmpdir"</code>, or - * <code>"user.home"</code> has no value and the - * corresponding escape sequence appears in - * <code>pattern</code>. - */ - private static String replaceFileNameEscapes(String pattern, - int generation, - int uniqueNumber, - int count) - { - StringBuffer buf = new StringBuffer(pattern); - String replaceWith; - boolean foundGeneration = false; - - int pos = 0; - do - { - // Uncomment the next line for finding bugs. - // System.out.println(buf.substring(0,pos) + '|' + buf.substring(pos)); - - if (buf.charAt(pos) == '/') - { - /* The same value is also provided by java.io.File.separator. */ - replaceWith = System.getProperty("file.separator"); - buf.replace(pos, pos + 1, replaceWith); - pos = pos + replaceWith.length() - 1; - continue; - } - - if (buf.charAt(pos) == '%') - { - switch (buf.charAt(pos + 1)) - { - case 't': - replaceWith = System.getProperty("java.io.tmpdir"); - break; - - case 'h': - replaceWith = System.getProperty("user.home"); - break; - - case 'g': - replaceWith = Integer.toString(generation); - foundGeneration = true; - break; - - case 'u': - replaceWith = Integer.toString(uniqueNumber); - break; - - case '%': - replaceWith = "%"; - break; - - default: - replaceWith = "??"; - break; // FIXME: Throw exception? - } - - buf.replace(pos, pos + 2, replaceWith); - pos = pos + replaceWith.length() - 1; - continue; - } - } - while (++pos < buf.length() - 1); - - if (!foundGeneration && (count > 1)) - { - buf.append('.'); - buf.append(generation); - } - - return buf.toString(); - } - - - /* FIXME: Javadoc missing, implementation incomplete. */ - public void publish(LogRecord record) - { - super.publish(record); - - /* FIXME: Decide when to switch over. How do we get to - * the number of bytes published so far? Two possibilities: - * 1. File.length, 2. have metering wrapper around - * output stream counting the number of written bytes. - */ - - /* FIXME: Switch over if needed! This implementation always - * writes into a single file, i.e. behaves as if limit - * always was zero. So, the implementation is somewhat - * functional but incomplete. - */ - } -} diff --git a/libjava/java/util/logging/Filter.java b/libjava/java/util/logging/Filter.java deleted file mode 100644 index ec4597670d5..00000000000 --- a/libjava/java/util/logging/Filter.java +++ /dev/null @@ -1,64 +0,0 @@ -/* Filter.java -- an interface for filters that decide whether a - LogRecord should be published or discarded - Copyright (C) 2002, 2004 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util.logging; - -/** - * By implementing the <code>Filter</code> interface, applications - * can control what is being logged based on arbitrary properties, - * not just the severity level. Both <code>Handler</code> and - * <code>Logger</code> allow to register Filters whose - * <code>isLoggable</code> method will be called when a - * <code>LogRecord</code> has passed the test based on the - * severity level. - * - * @author Sascha Brawer (brawer@acm.org) - */ -public interface Filter -{ - /** - * Determines whether a LogRecord should be published or discarded. - * - * @param record the <code>LogRecord</code> to be inspected. - * - * @return <code>true</code> if the record should be published, - * <code>false</code> if it should be discarded. - */ - boolean isLoggable(LogRecord record); -} diff --git a/libjava/java/util/logging/Formatter.java b/libjava/java/util/logging/Formatter.java deleted file mode 100644 index ee747b0b978..00000000000 --- a/libjava/java/util/logging/Formatter.java +++ /dev/null @@ -1,171 +0,0 @@ -/* Formatter.java -- - A class for formatting log messages by localizing message texts - and performing substitution of parameters - Copyright (C) 2002, 2004 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util.logging; - -import java.text.MessageFormat; -import java.util.ResourceBundle; - -/** - * A <code>Formatter</code> supports handlers by localizing - * message texts and by subsituting parameter values for their - * placeholders. - * - * @author Sascha Brawer (brawer@acm.org) - */ -public abstract class Formatter -{ - /** - * Constructs a new Formatter. - */ - protected Formatter() - { - } - - - /** - * Formats a LogRecord into a string. Usually called by handlers - * which need a string for a log record, for example to append - * a record to a log file or to transmit a record over the network. - * - * @param record the log record for which a string form is requested. - */ - public abstract String format(LogRecord record); - - - /** - * Returns a string that handlers are supposed to emit before - * the first log record. The base implementation returns an - * empty string, but subclasses such as {@link XMLFormatter} - * override this method in order to provide a suitable header. - * - * @return a string for the header. - * - * @param handler the handler which will prepend the returned - * string in front of the first log record. This method - * may inspect certain properties of the handler, for - * example its encoding, in order to construct the header. - */ - public String getHead(Handler handler) - { - return ""; - } - - - /** - * Returns a string that handlers are supposed to emit after - * the last log record. The base implementation returns an - * empty string, but subclasses such as {@link XMLFormatter} - * override this method in order to provide a suitable tail. - * - * @return a string for the header. - * - * @param handler the handler which will append the returned - * string after the last log record. This method - * may inspect certain properties of the handler - * in order to construct the tail. - */ - public String getTail(Handler handler) - { - return ""; - } - - - /** - * Formats the message part of a log record. - * - * <p>First, the Formatter localizes the record message to the - * default locale by looking up the message in the record's - * localization resource bundle. If this step fails because there - * is no resource bundle associated with the record, or because the - * record message is not a key in the bundle, the raw message is - * used instead. - * - * <p>Second, the Formatter substitutes appropriate strings for - * the message parameters. If the record returns a non-empty - * array for <code>getParameters()</code> and the localized - * message string contains the character sequence "{0", the - * formatter uses <code>java.text.MessageFormat</code> to format - * the message. Otherwise, no parameter substitution is performed. - * - * @param record the log record to be localized and formatted. - * - * @return the localized message text where parameters have been - * substituted by suitable strings. - * - * @throws NullPointerException if <code>record</code> - * is <code>null</code>. - */ - public String formatMessage(LogRecord record) - { - String msg; - ResourceBundle bundle; - Object[] params; - - /* This will throw a NullPointerExceptionif record is null. */ - msg = record.getMessage(); - if (msg == null) - msg = ""; - - /* Try to localize the message. */ - bundle = record.getResourceBundle(); - if (bundle != null) - { - try - { - msg = bundle.getString(msg); - } - catch (java.util.MissingResourceException _) - { - } - } - - /* Format the message if there are parameters. */ - params = record.getParameters(); - if ((params != null) - && (params.length > 0) - && (msg.indexOf("{0") >= 0)) - { - msg = MessageFormat.format(msg, params); - } - - return msg; - } -} diff --git a/libjava/java/util/logging/Handler.java b/libjava/java/util/logging/Handler.java deleted file mode 100644 index c3227d6f531..00000000000 --- a/libjava/java/util/logging/Handler.java +++ /dev/null @@ -1,386 +0,0 @@ -/* Handler.java -- a class for publishing log messages - Copyright (C) 2002, 2004 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util.logging; - -import java.io.UnsupportedEncodingException; - -/** - * A <code>Handler</code> publishes <code>LogRecords</code> to - * a sink, for example a file, the console or a network socket. - * There are different subclasses of <code>Handler</code> - * to deal with different kinds of sinks. - * - * <p>FIXME: Are handlers thread-safe, or is the assumption that only - * loggers are, and a handler can belong only to one single logger? If - * the latter, should we enforce it? (Spec not clear). In any - * case, it needs documentation. - * - * @author Sascha Brawer (brawer@acm.org) - */ -public abstract class Handler -{ - Formatter formatter; - Filter filter; - Level level; - ErrorManager errorManager; - String encoding; - - /** - * Constructs a Handler with a logging severity level of - * <code>Level.ALL</code>, no formatter, no filter, and - * an instance of <code>ErrorManager</code> managing errors. - * - * <p><strong>Specification Note:</strong> The specification of the - * Java<sup>TM</sup> Logging API does not mention which character - * encoding is to be used by freshly constructed Handlers. The GNU - * implementation uses the default platform encoding, but other - * Java implementations might behave differently. - * - * <p><strong>Specification Note:</strong> While a freshly constructed - * Handler is required to have <em>no filter</em> according to the - * specification, <code>null</code> is not a valid parameter for - * <code>Handler.setFormatter</code>. Therefore, the following - * code will throw a <code>java.lang.NullPointerException</code>: - * - * <p><pre>Handler h = new MyConcreteSubclassOfHandler(); -h.setFormatter(h.getFormatter());</pre> - * - * It seems strange that a freshly constructed Handler is not - * supposed to provide a Formatter, but this is what the specification - * says. - */ - protected Handler() - { - level = Level.ALL; - } - - - /** - * Publishes a <code>LogRecord</code> to an appropriate sink, - * provided the record passes all tests for being loggable. The - * <code>Handler</code> will localize the message of the log - * record and substitute any message parameters. - * - * <p>Most applications do not need to call this method directly. - * Instead, they will use use a {@link Logger}, which will - * create LogRecords and distribute them to registered handlers. - * - * <p>In case of an I/O failure, the <code>ErrorManager</code> - * of this <code>Handler</code> will be informed, but the caller - * of this method will not receive an exception. - * - * @param record the log event to be published. - */ - public abstract void publish(LogRecord record); - - - /** - * Forces any data that may have been buffered to the underlying - * output device. - * - * <p>In case of an I/O failure, the <code>ErrorManager</code> - * of this <code>Handler</code> will be informed, but the caller - * of this method will not receive an exception. - */ - public abstract void flush(); - - - /** - * Closes this <code>Handler</code> after having flushed - * the buffers. As soon as <code>close</code> has been called, - * a <code>Handler</code> should not be used anymore. Attempts - * to publish log records, to flush buffers, or to modify the - * <code>Handler</code> in any other way may throw runtime - * exceptions after calling <code>close</code>. - * - * <p>In case of an I/O failure, the <code>ErrorManager</code> - * of this <code>Handler</code> will be informed, but the caller - * of this method will not receive an exception. - * - * @throws SecurityException if a security manager exists and - * the caller is not granted the permission to control - * the logging infrastructure. - */ - public abstract void close() - throws SecurityException; - - - /** - * Returns the <code>Formatter</code> which will be used to - * localize the text of log messages and to substitute - * message parameters. A <code>Handler</code> is encouraged, - * but not required to actually use an assigned - * <code>Formatter</code>. - * - * @return the <code>Formatter</code> being used, or - * <code>null</code> if this <code>Handler</code> - * does not use formatters and no formatter has - * ever been set by calling <code>setFormatter</code>. - */ - public Formatter getFormatter() - { - return formatter; - } - - - /** - * Sets the <code>Formatter</code> which will be used to - * localize the text of log messages and to substitute - * message parameters. A <code>Handler</code> is encouraged, - * but not required to actually use an assigned - * <code>Formatter</code>. - * - * @param formatter the new <code>Formatter</code> to use. - * - * @throws SecurityException if a security manager exists and - * the caller is not granted the permission to control - * the logging infrastructure. - * - * @throws NullPointerException if <code>formatter</code> is - * <code>null</code>. - */ - public void setFormatter(Formatter formatter) - throws SecurityException - { - LogManager.getLogManager().checkAccess(); - - /* Throws a NullPointerException if formatter is null. */ - formatter.getClass(); - - this.formatter = formatter; - } - - - /** - * Returns the character encoding which this handler uses for publishing - * log records. - * - * @param encoding the name of a character encoding, or <code>null</code> - * for the default platform encoding. - */ - public String getEncoding() - { - return encoding; - } - - - /** - * Sets the character encoding which this handler uses for publishing - * log records. The encoding of a <code>Handler</code> must be - * set before any log records have been published. - * - * @param encoding the name of a character encoding, or <code>null</code> - * for the default encoding. - * - * @exception SecurityException if a security manager exists and - * the caller is not granted the permission to control - * the logging infrastructure. - * - */ - public void setEncoding(String encoding) - throws SecurityException, UnsupportedEncodingException - { - /* Should any developer ever change this implementation, they are - * advised to have a look at StreamHandler.setEncoding(String), - * which overrides this method without calling super.setEncoding. - */ - LogManager.getLogManager().checkAccess(); - - /* Simple check for supported encodings. This is more expensive - * than it could be, but this method is overwritten by StreamHandler - * anyway. - */ - if (encoding != null) - new String(new byte[0], encoding); - - this.encoding = encoding; - } - - - /** - * Returns the <code>Filter</code> that currently controls which - * log records are being published by this <code>Handler</code>. - * - * @return the currently active <code>Filter</code>, or - * <code>null</code> if no filter has been associated. - * In the latter case, log records are filtered purely - * based on their severity level. - */ - public Filter getFilter() - { - return filter; - } - - - /** - * Sets the <code>Filter</code> for controlling which - * log records will be published by this <code>Handler</code>. - * - * @return the <code>Filter</code> to use, or - * <code>null</code> to filter log records purely based - * on their severity level. - */ - public void setFilter(Filter filter) - throws SecurityException - { - LogManager.getLogManager().checkAccess(); - this.filter = filter; - } - - - /** - * Returns the <code>ErrorManager</code> that currently deals - * with errors originating from this Handler. - * - * @exception SecurityException if a security manager exists and - * the caller is not granted the permission to control - * the logging infrastructure. - */ - public ErrorManager getErrorManager() - { - LogManager.getLogManager().checkAccess(); - - /* Developers wanting to change the subsequent code should - * have a look at Handler.reportError -- it also can create - * an ErrorManager, but does so without checking permissions - * to control the logging infrastructure. - */ - if (errorManager == null) - errorManager = new ErrorManager(); - - return errorManager; - } - - - public void setErrorManager(ErrorManager manager) - { - LogManager.getLogManager().checkAccess(); - - /* Make sure manager is not null. */ - manager.getClass(); - - this.errorManager = manager; - } - - - protected void reportError(String message, Exception ex, int code) - { - if (errorManager == null) - errorManager = new ErrorManager(); - - errorManager.error(message, ex, code); - } - - - /** - * Returns the severity level threshold for this <code>Handler</code> - * All log records with a lower severity level will be discarded; - * a log record of the same or a higher level will be published - * unless an installed <code>Filter</code> decides to discard it. - * - * @return the severity level below which all log messages - * will be discarded. - */ - public Level getLevel() - { - return level; - } - - - /** - * Sets the severity level threshold for this <code>Handler</code>. - * All log records with a lower severity level will be discarded; - * a log record of the same or a higher level will be published - * unless an installed <code>Filter</code> decides to discard it. - * - * @param level the severity level below which all log messages - * will be discarded. - * - * @exception SecurityException if a security manager exists and - * the caller is not granted the permission to control - * the logging infrastructure. - * - * @exception NullPointerException if <code>level</code> is - * <code>null</code>. - */ - public void setLevel(Level level) - { - LogManager.getLogManager().checkAccess(); - - /* Throw NullPointerException if level is null. */ - level.getClass(); - this.level = level; - } - - - /** - * Checks whether a <code>LogRecord</code> would be logged - * if it was passed to this <code>Handler</code> for publication. - * - * <p>The <code>Handler</code> implementation considers a record as - * loggable if its level is greater than or equal to the severity - * level threshold. In a second step, if a {@link Filter} has - * been installed, its {@link Filter#isLoggable(LogRecord) isLoggable} - * method is invoked. Subclasses of <code>Handler</code> can override - * this method to impose their own constraints. - * - * @param record the <code>LogRecord</code> to be checked. - * - * @return <code>true</code> if <code>record</code> would - * be published by {@link #publish(LogRecord) publish}, - * <code>false</code> if it would be discarded. - * - * @see #setLevel(Level) - * @see #setFilter(Filter) - * @see Filter#isLoggable(LogRecord) - * - * @throws NullPointerException if <code>record</code> - * is <code>null</code>. - */ - public boolean isLoggable(LogRecord record) - { - if (record.getLevel().intValue() < level.intValue()) - return false; - - if (filter != null) - return filter.isLoggable(record); - else - return true; - } -} diff --git a/libjava/java/util/logging/Level.java b/libjava/java/util/logging/Level.java deleted file mode 100644 index 2c400dc3a90..00000000000 --- a/libjava/java/util/logging/Level.java +++ /dev/null @@ -1,414 +0,0 @@ -/* Level.java -- a class for indicating logging levels - Copyright (C) 2002, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util.logging; - -import java.io.Serializable; -import java.util.ResourceBundle; - -/** - * A class for indicating logging levels. A number of commonly used - * levels is pre-defined (such as <code>java.util.logging.Level.INFO</code>), - * and applications should utilize those whenever possible. For specialized - * purposes, however, applications can sub-class Level in order to define - * custom logging levels. - * - * @author Sascha Brawer (brawer@acm.org) - */ -public class Level implements Serializable -{ - /* The integer values are the same as in the Sun J2SE 1.4. - * They have been obtained with a test program. In J2SE 1.4.1, - * Sun has amended the API documentation; these values are now - * publicly documented. - */ - - /** - * The <code>OFF</code> level is used as a threshold for filtering - * log records, meaning that no message should be logged. - * - * @see Logger#setLevel(java.util.logging.Level) - */ - public static final Level OFF = new Level ("OFF", Integer.MAX_VALUE); - - /** - * Log records whose level is <code>SEVERE</code> indicate a serious - * failure that prevents normal program execution. Messages at this - * level should be understandable to an inexperienced, non-technical - * end user. Ideally, they explain in simple words what actions the - * user can take in order to resolve the problem. - */ - public static final Level SEVERE = new Level ("SEVERE", 1000); - - - /** - * Log records whose level is <code>WARNING</code> indicate a - * potential problem that does not prevent normal program execution. - * Messages at this level should be understandable to an - * inexperienced, non-technical end user. Ideally, they explain in - * simple words what actions the user can take in order to resolve - * the problem. - */ - public static final Level WARNING = new Level ("WARNING", 900); - - - /** - * Log records whose level is <code>INFO</code> are used in purely - * informational situations that do not constitute serious errors or - * potential problems. In the default logging configuration, INFO - * messages will be written to the system console. For this reason, - * the INFO level should be used only for messages that are - * important to end users and system administrators. Messages at - * this level should be understandable to an inexperienced, - * non-technical user. - */ - public static final Level INFO = new Level ("INFO", 800); - - - /** - * Log records whose level is <code>CONFIG</code> are used for - * describing the static configuration, for example the windowing - * environment, the operating system version, etc. - */ - public static final Level CONFIG = new Level ("CONFIG", 700); - - - /** - * Log records whose level is <code>FINE</code> are typically used - * for messages that are relevant for developers using - * the component generating log messages. Examples include minor, - * recoverable failures, or possible inefficiencies. - */ - public static final Level FINE = new Level ("FINE", 500); - - - /** - * Log records whose level is <code>FINER</code> are intended for - * rather detailed tracing, for example entering a method, returning - * from a method, or throwing an exception. - */ - public static final Level FINER = new Level ("FINER", 400); - - - /** - * Log records whose level is <code>FINEST</code> are used for - * highly detailed tracing, for example to indicate that a certain - * point inside the body of a method has been reached. - */ - public static final Level FINEST = new Level ("FINEST", 300); - - - /** - * The <code>ALL</code> level is used as a threshold for filtering - * log records, meaning that every message should be logged. - * - * @see Logger#setLevel(java.util.logging.Level) - */ - public static final Level ALL = new Level ("ALL", Integer.MIN_VALUE); - - - private static final Level[] knownLevels = { - ALL, FINEST, FINER, FINE, CONFIG, INFO, WARNING, SEVERE, OFF - }; - - - /** - * The name of the Level without localizing it, for example - * "WARNING". - */ - private String name; - - - /** - * The integer value of this <code>Level</code>. - */ - private int value; - - - /** - * The name of the resource bundle used for localizing the level - * name, or <code>null</code> if the name does not undergo - * localization. - */ - private String resourceBundleName; - - - /** - * Creates a logging level given a name and an integer value. - * It rarely is necessary to create custom levels, - * as most applications should be well served with one of the - * standard levels such as <code>Level.CONFIG</code>, - * <code>Level.INFO</code>, or <code>Level.FINE</code>. - * - * @param name the name of the level. - * - * @param value the integer value of the level. Please note - * that the Java<small><sup>TM</sup></small> - * Logging API does not specify integer - * values for standard levels (such as - * Level.FINE). Therefore, a custom - * level should pass an integer value that - * is calculated at run-time, e.g. - * <code>(Level.FINE.intValue() + Level.CONFIG.intValue()) - * / 2</code> for a level between FINE and CONFIG. - */ - protected Level(String name, int value) - { - this(name, value, null); - } - - - /** - * Create a logging level given a name, an integer value and a name - * of a resource bundle for localizing the level name. It rarely - * is necessary to create custom levels, as most applications - * should be well served with one of the standard levels such as - * <code>Level.CONFIG</code>, <code>Level.INFO</code>, or - * <code>Level.FINE</code>. - * - * @param name the name of the level. - * - * @param value the integer value of the level. Please note - * that the Java<small><sup>TM</sup></small> - * Logging API does not specify integer - * values for standard levels (such as - * Level.FINE). Therefore, a custom - * level should pass an integer value that - * is calculated at run-time, e.g. - * <code>(Level.FINE.intValue() + Level.CONFIG.intValue()) - * / 2</code> for a level between FINE and CONFIG. - * - * @param resourceBundleName the name of a resource bundle - * for localizing the level name, or <code>null</code> - * if the name does not need to be localized. - */ - protected Level(String name, int value, String resourceBundleName) - { - this.name = name; - this.value = value; - this.resourceBundleName = resourceBundleName; - } - - - static final long serialVersionUID = -8176160795706313070L; - - - /** - * Checks whether the Level has the same intValue as one of the - * pre-defined levels. If so, the pre-defined level object is - * returned. - * - * <br/>Since the resource bundle name is not taken into - * consideration, it is possible to resolve Level objects that have - * been de-serialized by another implementation, even if the other - * implementation uses a different resource bundle for localizing - * the names of pre-defined levels. - */ - private Object readResolve() - { - for (int i = 0; i < knownLevels.length; i++) - if (value == knownLevels[i].intValue()) - return knownLevels[i]; - - return this; - } - - - /** - * Returns the name of the resource bundle used for localizing the - * level name. - * - * @return the name of the resource bundle used for localizing the - * level name, or <code>null</code> if the name does not undergo - * localization. - */ - public String getResourceBundleName() - { - return resourceBundleName; - } - - - /** - * Returns the name of the Level without localizing it, for example - * "WARNING". - */ - public String getName() - { - return name; - } - - - /** - * Returns the name of the Level after localizing it, for example - * "WARNUNG". - */ - public String getLocalizedName() - { - String localizedName = null; - - if (resourceBundleName != null) - { - try - { - ResourceBundle b = ResourceBundle.getBundle(resourceBundleName); - localizedName = b.getString(name); - } - catch (Exception _) - { - } - } - - if (localizedName != null) - return localizedName; - else - return name; - } - - - /** - * Returns the name of the Level without localizing it, for example - * "WARNING". - */ - public final String toString() - { - return getName(); - } - - - /** - * Returns the integer value of the Level. - */ - public final int intValue() - { - return value; - } - - - /** - * Returns one of the standard Levels given either its name or its - * integer value. Custom subclasses of Level will not be returned - * by this method. - * - * @throws IllegalArgumentException if <code>name</code> is neither - * the name nor the integer value of one of the pre-defined standard - * logging levels. - * - * @throws NullPointerException if <code>name</code> is null. - * - */ - public static Level parse(String name) - throws IllegalArgumentException - { - /* This will throw a NullPointerException if name is null, - * as required by the API specification. - */ - name = name.intern(); - - for (int i = 0; i < knownLevels.length; i++) - { - if (name == knownLevels[i].name) - return knownLevels[i]; - } - - try - { - int num = Integer.parseInt(name); - for (int i = 0; i < knownLevels.length; i++) - if (num == knownLevels[i].value) - return knownLevels[i]; - } - catch (NumberFormatException _) - { - } - - String msg = "Not the name of a standard logging level: \"" + name + "\""; - throw new IllegalArgumentException(msg); - } - - - /** - * Checks whether this Level's integer value is equal to that of - * another object. - * - * @return <code>true</code> if <code>other</code> is an instance of - * <code>java.util.logging.Level</code> and has the same integer - * value, <code>false</code> otherwise. - */ - public boolean equals(Object other) - { - if (!(other instanceof Level)) - return false; - - return value == ((Level) other).value; - } - - - /** - * Returns a hash code for this Level which is based on its numeric - * value. - */ - public int hashCode() - { - return value; - } - - - /** - * Determines whether or not this Level is one of the standard - * levels specified in the Logging API. - * - * <p>This method is package-private because it is not part - * of the logging API specification. However, an XMLFormatter - * is supposed to emit the numeric value for a custom log - * level, but the name for a pre-defined level. It seems - * cleaner to put this method to Level than to write some - * procedural code for XMLFormatter. - * - * @return <code>true</code> if this Level is a standard level, - * <code>false</code> otherwise. - */ - final boolean isStandardLevel() - { - for (int i = 0; i < knownLevels.length; i++) - if (knownLevels[i] == this) - return true; - - return false; - } -} - diff --git a/libjava/java/util/logging/LogRecord.java b/libjava/java/util/logging/LogRecord.java deleted file mode 100644 index af7f2058dbe..00000000000 --- a/libjava/java/util/logging/LogRecord.java +++ /dev/null @@ -1,672 +0,0 @@ -/* LogRecord.java -- - A class for the state associated with individual logging events - Copyright (C) 2002, 2003, 2004 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util.logging; - -import java.util.ResourceBundle; - - -/** - * A <code>LogRecord</code> contains the state for an individual - * event to be logged. - * - * <p>As soon as a LogRecord instance has been handed over to the - * logging framework, applications should not manipulate it anymore. - * - * @author Sascha Brawer (brawer@acm.org) - */ -public class LogRecord - implements java.io.Serializable -{ - /** - * The severity level of this <code>LogRecord</code>. - */ - private Level level; - - - /** - * The sequence number of this <code>LogRecord</code>. - */ - private long sequenceNumber; - - - /** - * The name of the class that issued the logging request, or - * <code>null</code> if this information could not be obtained. - */ - private String sourceClassName; - - - /** - * The name of the method that issued the logging request, or - * <code>null</code> if this information could not be obtained. - */ - private String sourceMethodName; - - - /** - * The message for this <code>LogRecord</code> before - * any localization or formatting. - */ - private String message; - - - /** - * An identifier for the thread in which this <code>LogRecord</code> - * was created. The identifier is not necessarily related to any - * thread identifiers used by the operating system. - */ - private int threadID; - - - /** - * The time when this <code>LogRecord</code> was created, - * in milliseconds since the beginning of January 1, 1970. - */ - private long millis; - - - /** - * The Throwable associated with this <code>LogRecord</code>, or - * <code>null</code> if the logged event is not related to an - * exception or error. - */ - private Throwable thrown; - - - /** - * The name of the logger where this <code>LogRecord</code> has - * originated, or <code>null</code> if this <code>LogRecord</code> - * does not originate from a <code>Logger</code>. - */ - private String loggerName; - - - /** - * The name of the resource bundle used for localizing log messages, - * or <code>null</code> if no bundle has been specified. - */ - private String resourceBundleName; - - private transient Object[] parameters; - - private transient ResourceBundle bundle; - - - /** - * Constructs a <code>LogRecord</code> given a severity level and - * an unlocalized message text. In addition, the sequence number, - * creation time (as returned by <code>getMillis()</code>) and - * thread ID are assigned. All other properties are set to - * <code>null</code>. - * - * @param level the severity level, for example <code>Level.WARNING</code>. - * - * @param message the message text (which will be used as key - * for looking up the localized message text - * if a resource bundle has been associated). - */ - public LogRecord(Level level, String message) - { - this.level = level; - this.message = message; - this.millis = System.currentTimeMillis(); - - /* A subclass of java.lang.Thread could override hashCode(), - * in which case the result would not be guaranteed anymore - * to be unique among all threads. While System.identityHashCode - * is not necessarily unique either, it at least cannot be - * overridden by user code. However, is might be a good idea - * to use something better for generating thread IDs. - */ - this.threadID = System.identityHashCode(Thread.currentThread()); - - sequenceNumber = allocateSeqNum(); - } - - - /** - * Determined with the serialver tool of the Sun J2SE 1.4. - */ - static final long serialVersionUID = 5372048053134512534L; - - private void readObject(java.io.ObjectInputStream in) - throws java.io.IOException, java.lang.ClassNotFoundException - { - in.defaultReadObject(); - - /* We assume that future versions will be downwards compatible, - * so we can ignore the versions. - */ - byte majorVersion = in.readByte(); - byte minorVersion = in.readByte(); - - int numParams = in.readInt(); - if (numParams >= 0) - { - parameters = new Object[numParams]; - for (int i = 0; i < numParams; i++) - parameters[i] = in.readObject(); - } - } - - - /** - * @serialData The default fields, followed by a major byte version - * number, followed by a minor byte version number, followed by - * information about the log record parameters. If - * <code>parameters</code> is <code>null</code>, the integer -1 is - * written, otherwise the length of the <code>parameters</code> - * array (which can be zero), followed by the result of calling - * {@link Object#toString() toString()} on the parameter (or - * <code>null</code> if the parameter is <code>null</code>). - * - * <p><strong>Specification Note:</strong> The Javadoc for the - * Sun reference implementation does not specify the version - * number. FIXME: Reverse-engineer the JDK and file a bug - * report with Sun, asking for amendment of the specification. - */ - private void writeObject(java.io.ObjectOutputStream out) - throws java.io.IOException - { - out.defaultWriteObject(); - - /* Major, minor version number: The Javadoc for J2SE1.4 does not - * specify the values. - */ - out.writeByte(0); - out.writeByte(0); - - if (parameters == null) - out.writeInt(-1); - else - { - out.writeInt(parameters.length); - for (int i = 0; i < parameters.length; i++) - { - if (parameters[i] == null) - out.writeObject(null); - else - out.writeObject(parameters[i].toString()); - } - } - } - - - /** - * Returns the name of the logger where this <code>LogRecord</code> - * has originated. - * - * @return the name of the source {@link Logger}, or - * <code>null</code> if this <code>LogRecord</code> - * does not originate from a <code>Logger</code>. - */ - public String getLoggerName() - { - return loggerName; - } - - - /** - * Sets the name of the logger where this <code>LogRecord</code> - * has originated. - * - * <p>As soon as a <code>LogRecord</code> has been handed over - * to the logging framework, applications should not modify it - * anymore. Therefore, this method should only be called on - * freshly constructed LogRecords. - * - * @param name the name of the source logger, or <code>null</code> to - * indicate that this <code>LogRecord</code> does not - * originate from a <code>Logger</code>. - */ - public void setLoggerName(String name) - { - loggerName = name; - } - - - /** - * Returns the resource bundle that is used when the message - * of this <code>LogRecord</code> needs to be localized. - * - * @return the resource bundle used for localization, - * or <code>null</code> if this message does not need - * to be localized. - */ - public ResourceBundle getResourceBundle() - { - return bundle; - } - - - /** - * Sets the resource bundle that is used when the message - * of this <code>LogRecord</code> needs to be localized. - * - * <p>As soon as a <code>LogRecord</code> has been handed over - * to the logging framework, applications should not modify it - * anymore. Therefore, this method should only be called on - * freshly constructed LogRecords. - * - * @param bundle the resource bundle to be used, or - * <code>null</code> to indicate that this - * message does not need to be localized. - */ - public void setResourceBundle(ResourceBundle bundle) - { - this.bundle = bundle; - - /* FIXME: Is there a way to infer the name - * of a resource bundle from a ResourceBundle object? - */ - this.resourceBundleName = null; - } - - - /** - * Returns the name of the resource bundle that is used when the - * message of this <code>LogRecord</code> needs to be localized. - * - * @return the name of the resource bundle used for localization, - * or <code>null</code> if this message does not need - * to be localized. - */ - public String getResourceBundleName() - { - return resourceBundleName; - } - - - /** - * Sets the name of the resource bundle that is used when the - * message of this <code>LogRecord</code> needs to be localized. - * - * <p>As soon as a <code>LogRecord</code> has been handed over - * to the logging framework, applications should not modify it - * anymore. Therefore, this method should only be called on - * freshly constructed LogRecords. - * - * @param name the name of the resource bundle to be used, or - * <code>null</code> to indicate that this message - * does not need to be localized. - */ - public void setResourceBundleName(String name) - { - resourceBundleName = name; - bundle = null; - - try - { - if (resourceBundleName != null) - bundle = ResourceBundle.getBundle(resourceBundleName); - } - catch (java.util.MissingResourceException _) - { - } - } - - - /** - * Returns the level of the LogRecord. - * - * <p>Applications should be aware of the possibility that the - * result is not necessarily one of the standard logging levels, - * since the logging framework allows to create custom subclasses - * of <code>java.util.logging.Level</code>. Therefore, filters - * should perform checks like <code>theRecord.getLevel().intValue() - * == Level.INFO.intValue()</code> instead of <code>theRecord.getLevel() - * == Level.INFO</code>. - */ - public Level getLevel() - { - return level; - } - - - /** - * Sets the severity level of this <code>LogRecord</code> to a new - * value. - * - * <p>As soon as a <code>LogRecord</code> has been handed over - * to the logging framework, applications should not modify it - * anymore. Therefore, this method should only be called on - * freshly constructed LogRecords. - * - * @param level the new severity level, for example - * <code>Level.WARNING</code>. - */ - public void setLevel(Level level) - { - this.level = level; - } - - - /** - * The last used sequence number for any LogRecord. - */ - private static long lastSeqNum; - - - /** - * Allocates a sequence number for a new LogRecord. This class - * method is only called by the LogRecord constructor. - */ - private static synchronized long allocateSeqNum() - { - lastSeqNum += 1; - return lastSeqNum; - } - - - /** - * Returns the sequence number of this <code>LogRecord</code>. - */ - public long getSequenceNumber() - { - return sequenceNumber; - } - - - /** - * Sets the sequence number of this <code>LogRecord</code> to a new - * value. - * - * <p>As soon as a <code>LogRecord</code> has been handed over - * to the logging framework, applications should not modify it - * anymore. Therefore, this method should only be called on - * freshly constructed LogRecords. - * - * @param seqNum the new sequence number. - */ - public void setSequenceNumber(long seqNum) - { - this.sequenceNumber = seqNum; - } - - - /** - * Returns the name of the class where the event being logged - * has had its origin. This information can be passed as - * parameter to some logging calls, and in certain cases, the - * logging framework tries to determine an approximation - * (which may or may not be accurate). - * - * @return the name of the class that issued the logging request, - * or <code>null</code> if this information could not - * be obtained. - */ - public String getSourceClassName() - { - if (sourceClassName != null) - return sourceClassName; - - /* FIXME: Should infer this information from the call stack. */ - return null; - } - - - /** - * Sets the name of the class where the event being logged - * has had its origin. - * - * <p>As soon as a <code>LogRecord</code> has been handed over - * to the logging framework, applications should not modify it - * anymore. Therefore, this method should only be called on - * freshly constructed LogRecords. - * - * @param sourceClassName the name of the class that issued the - * logging request, or <code>null</code> to indicate that - * this information could not be obtained. - */ - public void setSourceClassName(String sourceClassName) - { - this.sourceClassName = sourceClassName; - } - - - /** - * Returns the name of the method where the event being logged - * has had its origin. This information can be passed as - * parameter to some logging calls, and in certain cases, the - * logging framework tries to determine an approximation - * (which may or may not be accurate). - * - * @return the name of the method that issued the logging request, - * or <code>null</code> if this information could not - * be obtained. - */ - public String getSourceMethodName() - { - if (sourceMethodName != null) - return sourceMethodName; - - /* FIXME: Should infer this information from the call stack. */ - return null; - } - - - /** - * Sets the name of the method where the event being logged - * has had its origin. - * - * <p>As soon as a <code>LogRecord</code> has been handed over - * to the logging framework, applications should not modify it - * anymore. Therefore, this method should only be called on - * freshly constructed LogRecords. - * - * @param sourceMethodName the name of the method that issued the - * logging request, or <code>null</code> to indicate that - * this information could not be obtained. - */ - public void setSourceMethodName(String sourceMethodName) - { - this.sourceMethodName = sourceMethodName; - } - - - /** - * Returns the message for this <code>LogRecord</code> before - * any localization or parameter substitution. - * - * <p>A {@link Logger} will try to localize the message - * if a resource bundle has been associated with this - * <code>LogRecord</code>. In this case, the logger will call - * <code>getMessage()</code> and use the result as the key - * for looking up the localized message in the bundle. - * If no bundle has been associated, or if the result of - * <code>getMessage()</code> is not a valid key in the - * bundle, the logger will use the raw message text as - * returned by this method. - * - * @return the message text, or <code>null</code> if there - * is no message text. - */ - public String getMessage() - { - return message; - } - - - /** - * Sets the message for this <code>LogRecord</code>. - * - * <p>A <code>Logger</code> will try to localize the message - * if a resource bundle has been associated with this - * <code>LogRecord</code>. In this case, the logger will call - * <code>getMessage()</code> and use the result as the key - * for looking up the localized message in the bundle. - * If no bundle has been associated, or if the result of - * <code>getMessage()</code> is not a valid key in the - * bundle, the logger will use the raw message text as - * returned by this method. - * - * <p>It is possible to set the message to either an empty String or - * <code>null</code>, although this does not make the the message - * very helpful to human users. - * - * @param message the message text (which will be used as key - * for looking up the localized message text - * if a resource bundle has been associated). - */ - public void setMessage(String message) - { - this.message = message; - } - - - /** - * Returns the parameters to the log message. - * - * @return the parameters to the message, or <code>null</code> if - * the message has no parameters. - */ - public Object[] getParameters() - { - return parameters; - } - - - /** - * Sets the parameters to the log message. - * - * <p>As soon as a <code>LogRecord</code> has been handed over - * to the logging framework, applications should not modify it - * anymore. Therefore, this method should only be called on - * freshly constructed LogRecords. - * - * @param parameters the parameters to the message, or <code>null</code> - * to indicate that the message has no parameters. - */ - public void setParameters(Object[] parameters) - { - this.parameters = parameters; - } - - - /** - * Returns an identifier for the thread in which this - * <code>LogRecord</code> was created. The identifier is not - * necessarily related to any thread identifiers used by the - * operating system. - * - * @return an identifier for the source thread. - */ - public int getThreadID() - { - return threadID; - } - - - /** - * Sets the identifier indicating in which thread this - * <code>LogRecord</code> was created. The identifier is not - * necessarily related to any thread identifiers used by the - * operating system. - * - * <p>As soon as a <code>LogRecord</code> has been handed over - * to the logging framework, applications should not modify it - * anymore. Therefore, this method should only be called on - * freshly constructed LogRecords. - * - * @param threadID the identifier for the source thread. - */ - public void setThreadID(int threadID) - { - this.threadID = threadID; - } - - - /** - * Returns the time when this <code>LogRecord</code> was created. - * - * @return the time of creation in milliseconds since the beginning - * of January 1, 1970. - */ - public long getMillis() - { - return millis; - } - - - /** - * Sets the time when this <code>LogRecord</code> was created. - * - * <p>As soon as a <code>LogRecord</code> has been handed over - * to the logging framework, applications should not modify it - * anymore. Therefore, this method should only be called on - * freshly constructed LogRecords. - * - * @param millis the time of creation in milliseconds since the - * beginning of January 1, 1970. - */ - public void setMillis(long millis) - { - this.millis = millis; - } - - - /** - * Returns the Throwable associated with this <code>LogRecord</code>, - * or <code>null</code> if the logged event is not related to an exception - * or error. - */ - public Throwable getThrown() - { - return thrown; - } - - - /** - * Associates this <code>LogRecord</code> with an exception or error. - * - * <p>As soon as a <code>LogRecord</code> has been handed over - * to the logging framework, applications should not modify it - * anymore. Therefore, this method should only be called on - * freshly constructed LogRecords. - * - * @param thrown the exception or error to associate with, or - * <code>null</code> if this <code>LogRecord</code> - * should be made unrelated to an exception or error. - */ - public void setThrown(Throwable thrown) - { - this.thrown = thrown; - } -} diff --git a/libjava/java/util/logging/LoggingPermission.java b/libjava/java/util/logging/LoggingPermission.java deleted file mode 100644 index c7a2255ecea..00000000000 --- a/libjava/java/util/logging/LoggingPermission.java +++ /dev/null @@ -1,73 +0,0 @@ -/* LoggingPermission.java -- a class for logging permissions. - Copyright (C) 2002 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util.logging; - -public final class LoggingPermission - extends java.security.BasicPermission -{ - /** - * Creates a new LoggingPermission. - * - * @param name the name of the permission, which must be "control". - * - * @param actions the list of actions for the permission, which - * must be either <code>null</code> or an empty - * string. - * - * @exception IllegalArgumentException if <code>name</code> - * is not "control", or <code>actions</code> is - * neither <code>null</code> nor empty. - */ - public LoggingPermission(String name, String actions) - { - super("control", ""); - - if (!"control".equals(name)) - { - throw new IllegalArgumentException( - "name of LoggingPermission must be \"control\""); - } - - if ((actions != null) && (actions.length() != 0)) - { - throw new IllegalArgumentException( - "actions of LoggingPermissions must be null or empty"); - } - } -} diff --git a/libjava/java/util/logging/MemoryHandler.java b/libjava/java/util/logging/MemoryHandler.java deleted file mode 100644 index ffa589f1668..00000000000 --- a/libjava/java/util/logging/MemoryHandler.java +++ /dev/null @@ -1,345 +0,0 @@ -/* MemoryHandler.java -- a class for buffering log messages in a memory buffer - Copyright (C) 2002, 2004 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package java.util.logging; - -/** - * A <code>MemoryHandler</code> maintains a circular buffer of - * log records. - * - * <p><strong>Configuration:</strong> Values of the subsequent - * <code>LogManager</code> properties are taken into consideration - * when a <code>MemoryHandler</code> is initialized. - * If a property is not defined, or if it has an invalid - * value, a default is taken without an exception being thrown. - * - * <ul> - * <li><code>java.util.MemoryHandler.level</code> - specifies - * the initial severity level threshold. Default value: - * <code>Level.ALL</code>.</li> - * <li><code>java.util.MemoryHandler.filter</code> - specifies - * the name of a Filter class. Default value: No Filter.</li> - * <li><code>java.util.MemoryHandler.size</code> - specifies the - * maximum number of log records that are kept in the circular - * buffer. Default value: 1000.</li> - * <li><code>java.util.MemoryHandler.push</code> - specifies the - * <code>pushLevel</code>. Default value: - * <code>Level.SEVERE</code>.</li> - * <li><code>java.util.MemoryHandler.target</code> - specifies the - * name of a subclass of {@link Handler} that will be used as the - * target handler. There is no default value for this property; - * if it is not set, the no-argument MemoryHandler constructor - * will throw an exception.</li> - * </ul> - * - * @author Sascha Brawer (brawer@acm.org) - */ -public class MemoryHandler - extends Handler -{ - /** - * The storage area used for buffering the unpushed log records in - * memory. - */ - private final LogRecord[] buffer; - - - /** - * The current position in the circular buffer. For a new - * MemoryHandler, or immediately after {@link #push()} was called, - * the value of this variable is zero. Each call to {@link - * #publish(LogRecord)} will store the published LogRecord into - * <code>buffer[position]</code> before position is incremented by - * one. If position becomes greater than the size of the buffer, it - * is reset to zero. - */ - private int position; - - - /** - * The number of log records which have been published, but not - * pushed yet to the target handler. - */ - private int numPublished; - - - /** - * The push level threshold for this <code>Handler</code>. When a - * record is published whose severity level is greater than or equal - * to the <code>pushLevel</code> of this <code>MemoryHandler</code>, - * the {@link #push()} method will be invoked for pushing the buffer - * contents to the target <code>Handler</code>. - */ - private Level pushLevel; - - - /** - * The Handler to which log records are forwarded for actual - * publication. - */ - private final Handler target; - - - /** - * Constructs a <code>MemoryHandler</code> for keeping a circular - * buffer of LogRecords; the initial configuration is determined by - * the <code>LogManager</code> properties described above. - */ - public MemoryHandler() - { - this((Handler) LogManager.getInstanceProperty( - "java.util.logging.MemoryHandler.target", - Handler.class, /* default */ null), - LogManager.getIntPropertyClamped( - "java.util.logging.MemoryHandler.size", - /* default */ 1000, - /* minimum value */ 1, - /* maximum value */ Integer.MAX_VALUE), - LogManager.getLevelProperty( - "java.util.logging.MemoryHandler.push", - /* default push level */ Level.SEVERE)); - } - - - /** - * Constructs a <code>MemoryHandler</code> for keeping a circular - * buffer of LogRecords, given some parameters. The values of the - * other parameters are taken from LogManager properties, as - * described above. - * - * @param target the target handler that will receive those - * log records that are passed on for publication. - * - * @param size the number of log records that are kept in the buffer. - * The value must be a at least one. - * - * @param pushLevel the push level threshold for this - * <code>MemoryHandler</code>. When a record is published whose - * severity level is greater than or equal to - * <code>pushLevel</code>, the {@link #push()} method will be - * invoked in order to push the bufffer contents to - * <code>target</code>. - * - * @throws java.lang.IllegalArgumentException if <code>size</code> - * is negative or zero. The GNU implementation also throws - * an IllegalArgumentException if <code>target</code> or - * <code>pushLevel</code> are <code>null</code>, but the - * API specification does not prescribe what should happen - * in those cases. - */ - public MemoryHandler(Handler target, int size, Level pushLevel) - { - if ((target == null) || (size <= 0) || (pushLevel == null)) - throw new IllegalArgumentException(); - - buffer = new LogRecord[size]; - this.pushLevel = pushLevel; - this.target = target; - - setLevel(LogManager.getLevelProperty( - "java.util.logging.MemoryHandler.level", - /* default value */ Level.ALL)); - - setFilter((Filter) LogManager.getInstanceProperty( - "java.util.logging.MemoryHandler.filter", - /* must be instance of */ Filter.class, - /* default value */ null)); - } - - - /** - * Stores a <code>LogRecord</code> in a fixed-size circular buffer, - * provided the record passes all tests for being loggable. If the - * buffer is full, the oldest record will be discarded. - * - * <p>If the record has a severity level which is greater than or - * equal to the <code>pushLevel</code> of this - * <code>MemoryHandler</code>, the {@link #push()} method will be - * invoked for pushing the buffer contents to the target - * <code>Handler</code>. - * - * <p>Most applications do not need to call this method directly. - * Instead, they will use use a {@link Logger}, which will create - * LogRecords and distribute them to registered handlers. - * - * @param record the log event to be published. - */ - public void publish(LogRecord record) - { - if (!isLoggable(record)) - return; - - buffer[position] = record; - position = (position + 1) % buffer.length; - numPublished = numPublished + 1; - - if (record.getLevel().intValue() >= pushLevel.intValue()) - push(); - } - - - /** - * Pushes the contents of the memory buffer to the target - * <code>Handler</code> and clears the buffer. Note that - * the target handler will discard those records that do - * not satisfy its own severity level threshold, or that are - * not considered loggable by an installed {@link Filter}. - * - * <p>In case of an I/O failure, the {@link ErrorManager} of the - * target <code>Handler</code> will be notified, but the caller of - * this method will not receive an exception. - */ - public void push() - { - int i; - - if (numPublished < buffer.length) - { - for (i = 0; i < position; i++) - target.publish(buffer[i]); - } - else - { - for (i = position; i < buffer.length; i++) - target.publish(buffer[i]); - for (i = 0; i < position; i++) - target.publish(buffer[i]); - } - - numPublished = 0; - position = 0; - } - - - /** - * Forces any data that may have been buffered by the target - * <code>Handler</code> to the underlying output device, but - * does <em>not</em> push the contents of the circular memory - * buffer to the target handler. - * - * <p>In case of an I/O failure, the {@link ErrorManager} of the - * target <code>Handler</code> will be notified, but the caller of - * this method will not receive an exception. - * - * @see #push() - */ - public void flush() - { - target.flush(); - } - - - /** - * Closes this <code>MemoryHandler</code> and its associated target - * handler, discarding the contents of the memory buffer. However, - * any data that may have been buffered by the target - * <code>Handler</code> is forced to the underlying output device. - * - * <p>As soon as <code>close</code> has been called, - * a <code>Handler</code> should not be used anymore. Attempts - * to publish log records, to flush buffers, or to modify the - * <code>Handler</code> in any other way may throw runtime - * exceptions after calling <code>close</code>.</p> - * - * <p>In case of an I/O failure, the <code>ErrorManager</code> of - * the associated target <code>Handler</code> will be informed, but - * the caller of this method will not receive an exception.</p> - * - * @throws SecurityException if a security manager exists and - * the caller is not granted the permission to control - * the logging infrastructure. - * - * @see #push() - */ - public void close() - throws SecurityException - { - push(); - - /* This will check for LoggingPermission("control"). If the - * current security context does not grant this permission, - * push() has been executed, but this does not impose a - * security risk. - */ - target.close(); - } - - - - /** - * Returns the push level threshold for this <code>Handler</code>. - * When a record is published whose severity level is greater - * than or equal to the <code>pushLevel</code> of this - * <code>MemoryHandler</code>, the {@link #push()} method will be - * invoked for pushing the buffer contents to the target - * <code>Handler</code>. - * - * @return the push level threshold for automatic pushing. - */ - public Level getPushLevel() - { - return pushLevel; - } - - - /** - * Sets the push level threshold for this <code>Handler</code>. - * When a record is published whose severity level is greater - * than or equal to the <code>pushLevel</code> of this - * <code>MemoryHandler</code>, the {@link #push()} method will be - * invoked for pushing the buffer contents to the target - * <code>Handler</code>. - * - * @param pushLevel the push level threshold for automatic pushing. - * - * @exception SecurityException if a security manager exists and - * the caller is not granted the permission to control - * the logging infrastructure. - * - * @exception NullPointerException if <code>pushLevel</code> is - * <code>null</code>. - */ - public void setPushLevel(Level pushLevel) - { - LogManager.getLogManager().checkAccess(); - - /* Throws a NullPointerException if pushLevel is null. */ - pushLevel.getClass(); - - this.pushLevel = pushLevel; - } -} diff --git a/libjava/java/util/logging/SimpleFormatter.java b/libjava/java/util/logging/SimpleFormatter.java deleted file mode 100644 index f7a442792f9..00000000000 --- a/libjava/java/util/logging/SimpleFormatter.java +++ /dev/null @@ -1,119 +0,0 @@ -/* SimpleFormatter.java -- - A class for formatting log records into short human-readable messages - Copyright (C) 2002, 2004 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util.logging; - -import java.text.DateFormat; -import java.util.Date; - -/** - * A <code>SimpleFormatter</code> formats log records into - * short human-readable messages, typically one or two lines. - * - * @author Sascha Brawer (brawer@acm.org) - */ -public class SimpleFormatter - extends Formatter -{ - /** - * Constructs a SimpleFormatter. - */ - public SimpleFormatter() - { - } - - - /** - * An instance of a DateFormatter that is used for formatting - * the time of a log record into a human-readable string, - * according to the rules of the current locale. The value - * is set after the first invocation of format, since it is - * common that a JVM will instantiate a SimpleFormatter without - * ever using it. - */ - private DateFormat dateFormat; - - /** - * The character sequence that is used to separate lines in the - * generated stream. Somewhat surprisingly, the Sun J2SE 1.4 - * reference implementation always uses UNIX line endings, even on - * platforms that have different line ending conventions (i.e., - * DOS). The GNU implementation does not replicate this bug. - * - * @see Sun bug parade, bug #4462871, - * "java.util.logging.SimpleFormatter uses hard-coded line separator". - */ - static final String lineSep = System.getProperty("line.separator"); - - - /** - * Formats a log record into a String. - * - * @param the log record to be formatted. - * - * @return a short human-readable message, typically one or two - * lines. Lines are separated using the default platform line - * separator. - * - * @throws NullPointerException if <code>record</code> - * is <code>null</code>. - */ - public String format(LogRecord record) - { - StringBuffer buf = new StringBuffer(180); - - if (dateFormat == null) - dateFormat = DateFormat.getDateTimeInstance(); - - buf.append(dateFormat.format(new Date(record.getMillis()))); - buf.append(' '); - buf.append(record.getSourceClassName()); - buf.append(' '); - buf.append(record.getSourceMethodName()); - buf.append(lineSep); - - buf.append(record.getLevel()); - buf.append(": "); - buf.append(formatMessage(record)); - - buf.append(lineSep); - - return buf.toString(); - } -} diff --git a/libjava/java/util/logging/SocketHandler.java b/libjava/java/util/logging/SocketHandler.java deleted file mode 100644 index 002dfdbbe5e..00000000000 --- a/libjava/java/util/logging/SocketHandler.java +++ /dev/null @@ -1,221 +0,0 @@ -/* SocketHandler.java -- a class for publishing log messages to network sockets - Copyright (C) 2002 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util.logging; - - -/** - * A <code>SocketHandler</code> publishes log records to - * a TCP/IP socket. - * - * <p><strong>Configuration:</strong> Values of the subsequent - * <code>LogManager</code> properties are taken into consideration - * when a <code>SocketHandler</code> is initialized. - * If a property is not defined, or if it has an invalid - * value, a default is taken without an exception being thrown. - * - * <ul> - * - * <li><code>java.util.SocketHandler.level</code> - specifies - * the initial severity level threshold. Default value: - * <code>Level.ALL</code>.</li> - * - * <li><code>java.util.SocketHandler.filter</code> - specifies - * the name of a Filter class. Default value: No Filter.</li> - * - * <li><code>java.util.SocketHandler.formatter</code> - specifies - * the name of a Formatter class. Default value: - * <code>java.util.logging.XMLFormatter</code>.</li> - * - * <li><code>java.util.SocketHandler.encoding</code> - specifies - * the name of the character encoding. Default value: - * the default platform encoding.</li> - * - * <li><code>java.util.SocketHandler.host</code> - specifies - * the name of the host to which records are published. - * There is no default value for this property; if it is - * not set, the SocketHandler constructor will throw - * an exception.</li> - * - * <li><code>java.util.SocketHandler.port</code> - specifies - * the TCP/IP port to which records are published. - * There is no default value for this property; if it is - * not set, the SocketHandler constructor will throw - * an exception.</li> - * - * </ul> - * - * @author Sascha Brawer (brawer@acm.org) - */ -public class SocketHandler - extends StreamHandler -{ - /** - * Constructs a <code>SocketHandler</code> that publishes log - * records to a TCP/IP socket. Tthe initial configuration is - * determined by the <code>LogManager</code> properties described - * above. - * - * @throws java.io.IOException if the connection to the specified - * network host and port cannot be established. - * - * @throws java.lang.IllegalArgumentException if either the - * <code>java.util.logging.SocketHandler.host</code> - * or <code>java.util.logging.SocketHandler.port</code> - * LogManager properties is not defined, or specifies - * an invalid value. - */ - public SocketHandler() - throws java.io.IOException - { - this(LogManager.getLogManager().getProperty("java.util.logging.SocketHandler.host"), - getPortNumber()); - } - - - /** - * Constructs a <code>SocketHandler</code> that publishes log - * records to a TCP/IP socket. With the exception of the internet - * host and port, the initial configuration is determined by the - * <code>LogManager</code> properties described above. - * - * @param host the Internet host to which log records will be - * forwarded. - * - * @param port the port at the host which will accept a request - * for a TCP/IP connection. - * - * @throws java.io.IOException if the connection to the specified - * network host and port cannot be established. - * - * @throws java.lang.IllegalArgumentException if either - * <code>host</code> or <code>port</code> specify - * an invalid value. - */ - public SocketHandler(String host, int port) - throws java.io.IOException - { - super(createSocket(host, port), - "java.util.logging.SocketHandler", - /* default level */ Level.ALL, - /* formatter */ null, - /* default formatter */ XMLFormatter.class); - } - - - /** - * Retrieves the port number from the java.util.logging.SocketHandler.port - * LogManager property. - * - * @throws IllegalArgumentException if the property is not defined or - * does not specify an integer value. - */ - private static int getPortNumber() - { - try { - return Integer.parseInt(LogManager.getLogManager().getProperty("java.util.logging.SocketHandler.port")); - } catch (Exception ex) { - throw new IllegalArgumentException(); - } - } - - - /** - * Creates an OutputStream for publishing log records to an Internet - * host and port. This private method is a helper for use by the - * constructor of SocketHandler. - * - * @param host the Internet host to which log records will be - * forwarded. - * - * @param port the port at the host which will accept a request - * for a TCP/IP connection. - * - * @throws java.io.IOException if the connection to the specified - * network host and port cannot be established. - * - * @throws java.lang.IllegalArgumentException if either - * <code>host</code> or <code>port</code> specify - * an invalid value. - */ - private static java.io.OutputStream createSocket(String host, int port) - throws java.io.IOException, java.lang.IllegalArgumentException - { - java.net.Socket socket; - - if ((host == null) || (port < 1)) - throw new IllegalArgumentException(); - - socket = new java.net.Socket(host, port); - - socket.shutdownInput(); - - /* The architecture of the logging framework provides replaceable - * formatters. Because these formatters perform their task by - * returning one single String for each LogRecord to be formatted, - * there is no need to buffer. - */ - socket.setTcpNoDelay(true); - - return socket.getOutputStream(); - } - - - /** - * Publishes a <code>LogRecord</code> to the network socket, - * provided the record passes all tests for being loggable. - * In addition, all data that may have been buffered will - * be forced to the network stream. - * - * <p>Most applications do not need to call this method directly. - * Instead, they will use a {@link Logger} instance, which will - * create LogRecords and distribute them to registered handlers. - * - * <p>In case of an I/O failure, the <code>ErrorManager</code> - * of this <code>SocketHandler</code> will be informed, but the caller - * of this method will not receive an exception. - * - * @param record the log event to be published. - */ - public void publish(LogRecord record) - { - super.publish(record); - flush(); - } -} - diff --git a/libjava/java/util/logging/StreamHandler.java b/libjava/java/util/logging/StreamHandler.java deleted file mode 100644 index 5c35c1e481d..00000000000 --- a/libjava/java/util/logging/StreamHandler.java +++ /dev/null @@ -1,521 +0,0 @@ -/* StreamHandler.java -- - A class for publishing log messages to instances of java.io.OutputStream - Copyright (C) 2002 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util.logging; - -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.UnsupportedEncodingException; -import java.io.Writer; - -/** - * A <code>StreamHandler</code> publishes <code>LogRecords</code> to - * a instances of <code>java.io.OutputStream</code>. - * - * @author Sascha Brawer (brawer@acm.org) - */ -public class StreamHandler - extends Handler -{ - private OutputStream out; - private Writer writer; - - - /** - * Indicates the current state of this StreamHandler. The value - * should be one of STATE_FRESH, STATE_PUBLISHED, or STATE_CLOSED. - */ - private int streamState = STATE_FRESH; - - - /** - * streamState having this value indicates that the StreamHandler - * has been created, but the publish(LogRecord) method has not been - * called yet. If the StreamHandler has been constructed without an - * OutputStream, writer will be null, otherwise it is set to a - * freshly created OutputStreamWriter. - */ - private static final int STATE_FRESH = 0; - - - /** - * streamState having this value indicates that the publish(LocRecord) - * method has been called at least once. - */ - private static final int STATE_PUBLISHED = 1; - - - /** - * streamState having this value indicates that the close() method - * has been called. - */ - private static final int STATE_CLOSED = 2; - - - /** - * Creates a <code>StreamHandler</code> without an output stream. - * Subclasses can later use {@link - * #setOutputStream(java.io.OutputStream)} to associate an output - * stream with this StreamHandler. - */ - public StreamHandler() - { - this(null, null); - } - - - /** - * Creates a <code>StreamHandler</code> that formats log messages - * with the specified Formatter and publishes them to the specified - * output stream. - * - * @param out the output stream to which the formatted log messages - * are published. - * - * @param formatter the <code>Formatter</code> that will be used - * to format log messages. - */ - public StreamHandler(OutputStream out, Formatter formatter) - { - this(out, "java.util.logging.StreamHandler", Level.INFO, - formatter, SimpleFormatter.class); - } - - - StreamHandler( - OutputStream out, - String propertyPrefix, - Level defaultLevel, - Formatter formatter, Class defaultFormatterClass) - { - this.level = LogManager.getLevelProperty(propertyPrefix + ".level", - defaultLevel); - - this.filter = (Filter) LogManager.getInstanceProperty( - propertyPrefix + ".filter", - /* must be instance of */ Filter.class, - /* default: new instance of */ null); - - if (formatter != null) - this.formatter = formatter; - else - this.formatter = (Formatter) LogManager.getInstanceProperty( - propertyPrefix + ".formatter", - /* must be instance of */ Formatter.class, - /* default: new instance of */ defaultFormatterClass); - - try - { - String enc = LogManager.getLogManager().getProperty(propertyPrefix - + ".encoding"); - - /* make sure enc actually is a valid encoding */ - if ((enc != null) && (enc.length() > 0)) - new String(new byte[0], enc); - - this.encoding = enc; - } - catch (Exception _) - { - } - - if (out != null) - { - try - { - changeWriter(out, getEncoding()); - } - catch (UnsupportedEncodingException uex) - { - /* This should never happen, since the validity of the encoding - * name has been checked above. - */ - throw new RuntimeException(uex.getMessage()); - } - } - } - - - private void checkOpen() - { - if (streamState == STATE_CLOSED) - throw new IllegalStateException(this.toString() + " has been closed"); - } - - private void checkFresh() - { - checkOpen(); - if (streamState != STATE_FRESH) - throw new IllegalStateException("some log records have been published to " + this); - } - - - private void changeWriter(OutputStream out, String encoding) - throws UnsupportedEncodingException - { - OutputStreamWriter writer; - - /* The logging API says that a null encoding means the default - * platform encoding. However, java.io.OutputStreamWriter needs - * another constructor for the default platform encoding, - * passing null would throw an exception. - */ - if (encoding == null) - writer = new OutputStreamWriter(out); - else - writer = new OutputStreamWriter(out, encoding); - - /* Closing the stream has side effects -- do this only after - * creating a new writer has been successful. - */ - if ((streamState != STATE_FRESH) || (this.writer != null)) - close(); - - this.writer = writer; - this.out = out; - this.encoding = encoding; - streamState = STATE_FRESH; - } - - - /** - * Sets the character encoding which this handler uses for publishing - * log records. The encoding of a <code>StreamHandler</code> must be - * set before any log records have been published. - * - * @param encoding the name of a character encoding, or <code>null</code> - * for the default encoding. - * - * @throws SecurityException if a security manager exists and - * the caller is not granted the permission to control the - * the logging infrastructure. - * - * @exception IllegalStateException if any log records have been - * published to this <code>StreamHandler</code> before. Please - * be aware that this is a pecularity of the GNU implementation. - * While the API specification indicates that it is an error - * if the encoding is set after records have been published, - * it does not mandate any specific behavior for that case. - */ - public void setEncoding(String encoding) - throws SecurityException, UnsupportedEncodingException - { - /* The inherited implementation first checks whether the invoking - * code indeed has the permission to control the logging infra- - * structure, and throws a SecurityException if this was not the - * case. - * - * Next, it verifies that the encoding is supported and throws - * an UnsupportedEncodingExcpetion otherwise. Finally, it remembers - * the name of the encoding. - */ - super.setEncoding(encoding); - - checkFresh(); - - /* If out is null, setEncoding is being called before an output - * stream has been set. In that case, we need to check that the - * encoding is valid, and remember it if this is the case. Since - * this is exactly what the inherited implementation of - * Handler.setEncoding does, we can delegate. - */ - if (out != null) - { - /* The logging API says that a null encoding means the default - * platform encoding. However, java.io.OutputStreamWriter needs - * another constructor for the default platform encoding, passing - * null would throw an exception. - */ - if (encoding == null) - writer = new OutputStreamWriter(out); - else - writer = new OutputStreamWriter(out, encoding); - } - } - - - /** - * Changes the output stream to which this handler publishes - * logging records. - * - * @throws SecurityException if a security manager exists and - * the caller is not granted the permission to control - * the logging infrastructure. - * - * @throws NullPointerException if <code>out</code> - * is <code>null</code>. - */ - protected void setOutputStream(OutputStream out) - throws SecurityException - { - LogManager.getLogManager().checkAccess(); - - /* Throw a NullPointerException if out is null. */ - out.getClass(); - - try - { - changeWriter(out, getEncoding()); - } - catch (UnsupportedEncodingException ex) - { - /* This seems quite unlikely to happen, unless the underlying - * implementation of java.io.OutputStreamWriter changes its - * mind (at runtime) about the set of supported character - * encodings. - */ - throw new RuntimeException(ex.getMessage()); - } - } - - - /** - * Publishes a <code>LogRecord</code> to the associated output - * stream, provided the record passes all tests for being loggable. - * The <code>StreamHandler</code> will localize the message of the - * log record and substitute any message parameters. - * - * <p>Most applications do not need to call this method directly. - * Instead, they will use use a {@link Logger}, which will create - * LogRecords and distribute them to registered handlers. - * - * <p>In case of an I/O failure, the <code>ErrorManager</code> - * of this <code>Handler</code> will be informed, but the caller - * of this method will not receive an exception. - * - * <p>If a log record is being published to a - * <code>StreamHandler</code> that has been closed earlier, the Sun - * J2SE 1.4 reference can be observed to silently ignore the - * call. The GNU implementation, however, intentionally behaves - * differently by informing the <code>ErrorManager</code> associated - * with this <code>StreamHandler</code>. Since the condition - * indicates a programming error, the programmer should be - * informed. It also seems extremely unlikely that any application - * would depend on the exact behavior in this rather obscure, - * erroneous case -- especially since the API specification does not - * prescribe what is supposed to happen. - * - * @param record the log event to be published. - */ - public void publish(LogRecord record) - { - String formattedMessage; - - if (!isLoggable(record)) - return; - - if (streamState == STATE_FRESH) - { - try - { - writer.write(formatter.getHead(this)); - } - catch (java.io.IOException ex) - { - reportError(null, ex, ErrorManager.WRITE_FAILURE); - return; - } - catch (Exception ex) - { - reportError(null, ex, ErrorManager.GENERIC_FAILURE); - return; - } - - streamState = STATE_PUBLISHED; - } - - try - { - formattedMessage = formatter.format(record); - } - catch (Exception ex) - { - reportError(null, ex, ErrorManager.FORMAT_FAILURE); - return; - } - - try - { - writer.write(formattedMessage); - } - catch (Exception ex) - { - reportError(null, ex, ErrorManager.WRITE_FAILURE); - } - } - - - /** - * Checks whether or not a <code>LogRecord</code> would be logged - * if it was passed to this <code>StreamHandler</code> for publication. - * - * <p>The <code>StreamHandler</code> implementation first checks - * whether a writer is present and the handler's level is greater - * than or equal to the severity level threshold. In a second step, - * if a {@link Filter} has been installed, its {@link - * Filter#isLoggable(LogRecord) isLoggable} method is - * invoked. Subclasses of <code>StreamHandler</code> can override - * this method to impose their own constraints. - * - * @param record the <code>LogRecord</code> to be checked. - * - * @return <code>true</code> if <code>record</code> would - * be published by {@link #publish(LogRecord) publish}, - * <code>false</code> if it would be discarded. - * - * @see #setLevel(Level) - * @see #setFilter(Filter) - * @see Filter#isLoggable(LogRecord) - * - * @throws NullPointerException if <code>record</code> is - * <code>null</code>. */ - public boolean isLoggable(LogRecord record) - { - return (writer != null) && super.isLoggable(record); - } - - - /** - * Forces any data that may have been buffered to the underlying - * output device. - * - * <p>In case of an I/O failure, the <code>ErrorManager</code> - * of this <code>Handler</code> will be informed, but the caller - * of this method will not receive an exception. - * - * <p>If a <code>StreamHandler</code> that has been closed earlier - * is closed a second time, the Sun J2SE 1.4 reference can be - * observed to silently ignore the call. The GNU implementation, - * however, intentionally behaves differently by informing the - * <code>ErrorManager</code> associated with this - * <code>StreamHandler</code>. Since the condition indicates a - * programming error, the programmer should be informed. It also - * seems extremely unlikely that any application would depend on the - * exact behavior in this rather obscure, erroneous case -- - * especially since the API specification does not prescribe what is - * supposed to happen. - */ - public void flush() - { - try - { - checkOpen(); - if (writer != null) - writer.flush(); - } - catch (Exception ex) - { - reportError(null, ex, ErrorManager.FLUSH_FAILURE); - } - } - - - /** - * Closes this <code>StreamHandler</code> after having forced any - * data that may have been buffered to the underlying output - * device. - * - * <p>As soon as <code>close</code> has been called, - * a <code>Handler</code> should not be used anymore. Attempts - * to publish log records, to flush buffers, or to modify the - * <code>Handler</code> in any other way may throw runtime - * exceptions after calling <code>close</code>.</p> - * - * <p>In case of an I/O failure, the <code>ErrorManager</code> - * of this <code>Handler</code> will be informed, but the caller - * of this method will not receive an exception.</p> - * - * <p>If a <code>StreamHandler</code> that has been closed earlier - * is closed a second time, the Sun J2SE 1.4 reference can be - * observed to silently ignore the call. The GNU implementation, - * however, intentionally behaves differently by informing the - * <code>ErrorManager</code> associated with this - * <code>StreamHandler</code>. Since the condition indicates a - * programming error, the programmer should be informed. It also - * seems extremely unlikely that any application would depend on the - * exact behavior in this rather obscure, erroneous case -- - * especially since the API specification does not prescribe what is - * supposed to happen. - * - * @throws SecurityException if a security manager exists and - * the caller is not granted the permission to control - * the logging infrastructure. - */ - public void close() - throws SecurityException - { - LogManager.getLogManager().checkAccess(); - - try - { - /* Although flush also calls checkOpen, it catches - * any exceptions and reports them to the ErrorManager - * as flush failures. However, we want to report - * a closed stream as a close failure, not as a - * flush failure here. Therefore, we call checkOpen() - * before flush(). - */ - checkOpen(); - flush(); - - if (writer != null) - { - if (formatter != null) - { - /* Even if the StreamHandler has never published a record, - * it emits head and tail upon closing. An earlier version - * of the GNU Classpath implementation did not emitted - * anything. However, this had caused XML log files to be - * entirely empty instead of containing no log records. - */ - if (streamState == STATE_FRESH) - writer.write(formatter.getHead(this)); - if (streamState != STATE_CLOSED) - writer.write(formatter.getTail(this)); - } - streamState = STATE_CLOSED; - writer.close(); - } - } - catch (Exception ex) - { - reportError(null, ex, ErrorManager.CLOSE_FAILURE); - } - } -} diff --git a/libjava/java/util/logging/XMLFormatter.java b/libjava/java/util/logging/XMLFormatter.java deleted file mode 100644 index 4dd63281727..00000000000 --- a/libjava/java/util/logging/XMLFormatter.java +++ /dev/null @@ -1,387 +0,0 @@ -/* XMLFormatter.java -- - A class for formatting log messages into a standard XML format - Copyright (C) 2002, 2004 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util.logging; - -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.ResourceBundle; - -/** - * An <code>XMLFormatter</code> formats LogRecords into - * a standard XML format. - * - * @author Sascha Brawer (brawer@acm.org) - */ -public class XMLFormatter - extends Formatter -{ - /** - * Constructs a new XMLFormatter. - */ - public XMLFormatter() - { - } - - - /** - * The character sequence that is used to separate lines in the - * generated XML stream. Somewhat surprisingly, the Sun J2SE 1.4 - * reference implementation always uses UNIX line endings, even on - * platforms that have different line ending conventions (i.e., - * DOS). The GNU Classpath implementation does not replicates this - * bug. - * - * See also the Sun bug parade, bug #4462871, - * "java.util.logging.SimpleFormatter uses hard-coded line separator". - */ - private static final String lineSep = SimpleFormatter.lineSep; - - - /** - * A DateFormat for emitting time in the ISO 8601 format. - * Since the API specification of SimpleDateFormat does not talk - * about its thread-safety, we cannot share a singleton instance. - */ - private final SimpleDateFormat iso8601 - = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); - - - /** - * Appends a line consisting of indentation, opening element tag, - * element content, closing element tag and line separator to - * a StringBuffer, provided that the element content is - * actually existing. - * - * @param buf the StringBuffer to which the line will be appended. - * - * @param indent the indentation level. - * - * @param tag the element tag name, for instance <code>method</code>. - * - * @param content the element content, or <code>null</code> to - * have no output whatsoever appended to <code>buf</code>. - */ - private static void appendTag(StringBuffer buf, int indent, - String tag, String content) - { - int i; - - if (content == null) - return; - - for (i = 0; i < indent * 2; i++) - buf.append(' '); - - buf.append("<"); - buf.append(tag); - buf.append('>'); - - /* Append the content, but escape for XML by replacing - * '&', '<', '>' and all non-ASCII characters with - * appropriate escape sequences. - * The Sun J2SE 1.4 reference implementation does not - * escape non-ASCII characters. This is a bug in their - * implementation which has been reported in the Java - * bug parade as bug number (FIXME: Insert number here). - */ - for (i = 0; i < content.length(); i++) - { - char c = content.charAt(i); - switch (c) - { - case '&': - buf.append("&"); - break; - - case '<': - buf.append("<"); - break; - - case '>': - buf.append(">"); - break; - - default: - if (((c >= 0x20) && (c <= 0x7e)) - || (c == /* line feed */ 10) - || (c == /* carriage return */ 13)) - buf.append(c); - else - { - buf.append("&#"); - buf.append((int) c); - buf.append(';'); - } - break; - } /* switch (c) */ - } /* for i */ - - buf.append("</"); - buf.append(tag); - buf.append(">"); - buf.append(lineSep); - } - - - /** - * Appends a line consisting of indentation, opening element tag, - * numeric element content, closing element tag and line separator - * to a StringBuffer. - * - * @param buf the StringBuffer to which the line will be appended. - * - * @param indent the indentation level. - * - * @param tag the element tag name, for instance <code>method</code>. - * - * @param content the element content. - */ - private static void appendTag(StringBuffer buf, int indent, - String tag, long content) - { - appendTag(buf, indent, tag, Long.toString(content)); - } - - - public String format(LogRecord record) - { - StringBuffer buf = new StringBuffer(400); - Level level = record.getLevel(); - long millis = record.getMillis(); - Object[] params = record.getParameters(); - ResourceBundle bundle = record.getResourceBundle(); - String message; - - buf.append("<record>"); - buf.append(lineSep); - - - appendTag(buf, 1, "date", iso8601.format(new Date(millis))); - appendTag(buf, 1, "millis", record.getMillis()); - appendTag(buf, 1, "sequence", record.getSequenceNumber()); - appendTag(buf, 1, "logger", record.getLoggerName()); - - if (level.isStandardLevel()) - appendTag(buf, 1, "level", level.toString()); - else - appendTag(buf, 1, "level", level.intValue()); - - appendTag(buf, 1, "class", record.getSourceClassName()); - appendTag(buf, 1, "method", record.getSourceMethodName()); - appendTag(buf, 1, "thread", record.getThreadID()); - - /* The Sun J2SE 1.4 reference implementation does not emit the - * message in localized form. This is in violation of the API - * specification. The GNU Classpath implementation intentionally - * replicates the buggy behavior of the Sun implementation, as - * different log files might be a big nuisance to users. - */ - try - { - record.setResourceBundle(null); - message = formatMessage(record); - } - finally - { - record.setResourceBundle(bundle); - } - appendTag(buf, 1, "message", message); - - /* The Sun J2SE 1.4 reference implementation does not - * emit key, catalog and param tags. This is in violation - * of the API specification. The Classpath implementation - * intentionally replicates the buggy behavior of the - * Sun implementation, as different log files might be - * a big nuisance to users. - * - * FIXME: File a bug report with Sun. Insert bug number here. - * - * - * key = record.getMessage(); - * if (key == null) - * key = ""; - * - * if ((bundle != null) && !key.equals(message)) - * { - * appendTag(buf, 1, "key", key); - * appendTag(buf, 1, "catalog", record.getResourceBundleName()); - * } - * - * if (params != null) - * { - * for (int i = 0; i < params.length; i++) - * appendTag(buf, 1, "param", params[i].toString()); - * } - */ - - /* FIXME: We have no way to obtain the stacktrace before free JVMs - * support the corresponding method in java.lang.Throwable. Well, - * it would be possible to parse the output of printStackTrace, - * but this would be pretty kludgy. Instead, we postpose the - * implementation until Throwable has made progress. - */ - Throwable thrown = record.getThrown(); - if (thrown != null) - { - buf.append(" <exception>"); - buf.append(lineSep); - - /* The API specification is not clear about what exactly - * goes into the XML record for a thrown exception: It - * could be the result of getMessage(), getLocalizedMessage(), - * or toString(). Therefore, it was necessary to write a - * Mauve testlet and run it with the Sun J2SE 1.4 reference - * implementation. It turned out that the we need to call - * toString(). - * - * FIXME: File a bug report with Sun, asking for clearer - * specs. - */ - appendTag(buf, 2, "message", thrown.toString()); - - /* FIXME: The Logging DTD specifies: - * - * <!ELEMENT exception (message?, frame+)> - * - * However, java.lang.Throwable.getStackTrace() is - * allowed to return an empty array. So, what frame should - * be emitted for an empty stack trace? We probably - * should file a bug report with Sun, asking for the DTD - * to be changed. - */ - - buf.append(" </exception>"); - buf.append(lineSep); - } - - - buf.append("</record>"); - buf.append(lineSep); - - return buf.toString(); - } - - - /** - * Returns a string that handlers are supposed to emit before - * the first log record. The base implementation returns an - * empty string, but subclasses such as {@link XMLFormatter} - * override this method in order to provide a suitable header. - * - * @return a string for the header. - * - * @param handler the handler which will prepend the returned - * string in front of the first log record. This method - * will inspect certain properties of the handler, for - * example its encoding, in order to construct the header. - */ - public String getHead(Handler h) - { - StringBuffer buf; - String encoding; - - buf = new StringBuffer(80); - buf.append("<?xml version=\"1.0\" encoding=\""); - - encoding = h.getEncoding(); - - /* file.encoding is a system property with the Sun JVM, indicating - * the platform-default file encoding. Unfortunately, the API - * specification for java.lang.System.getProperties() does not - * list this property. - */ - if (encoding == null) - encoding = System.getProperty("file.encoding"); - - /* Since file.encoding is not listed with the API specification of - * java.lang.System.getProperties(), there might be some VMs that - * do not define this system property. Therefore, we use UTF-8 as - * a reasonable default. Please note that if the platform encoding - * uses the same codepoints as US-ASCII for the US-ASCII character - * set (e.g, 65 for A), it does not matter whether we emit the - * wrong encoding into the XML header -- the GNU Classpath will - * emit XML escape sequences like Ӓ for any non-ASCII - * character. Virtually all character encodings use the same code - * points as US-ASCII for ASCII characters. Probably, EBCDIC is - * the only exception. - */ - if (encoding == null) - encoding = "UTF-8"; - - /* On Windows XP localized for Swiss German (this is one of - * my [Sascha Brawer's] test machines), the default encoding - * has the canonical name "windows-1252". The "historical" name - * of this encoding is "Cp1252" (see the Javadoc for the class - * java.nio.charset.Charset for the distinction). Now, that class - * does have a method for mapping historical to canonical encoding - * names. However, if we used it here, we would be come dependent - * on java.nio.*, which was only introduced with J2SE 1.4. - * Thus, we do this little hack here. As soon as Classpath supports - * java.nio.charset.CharSet, this hack should be replaced by - * code that correctly canonicalizes the encoding name. - */ - if ((encoding.length() > 2) && encoding.startsWith("Cp")) - encoding = "windows-" + encoding.substring(2); - - buf.append(encoding); - - buf.append("\" standalone=\"no\"?>"); - buf.append(lineSep); - - /* SYSTEM is not a fully qualified URL so that validating - * XML parsers do not need to connect to the Internet in - * order to read in a log file. See also the Sun Bug Parade, - * bug #4372790, "Logging APIs: need to use relative URL for XML - * doctype". - */ - buf.append("<!DOCTYPE log SYSTEM \"logger.dtd\">"); - buf.append(lineSep); - buf.append("<log>"); - buf.append(lineSep); - - return buf.toString(); - } - - - public String getTail(Handler h) - { - return "</log>" + lineSep; - } -} diff --git a/libjava/java/util/prefs/AbstractPreferences.java b/libjava/java/util/prefs/AbstractPreferences.java deleted file mode 100644 index 1c40ea8a92f..00000000000 --- a/libjava/java/util/prefs/AbstractPreferences.java +++ /dev/null @@ -1,1272 +0,0 @@ -/* AbstractPreferences -- Partial implementation of a Preference node - Copyright (C) 2001, 2003, 2004 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util.prefs; - -import gnu.java.util.prefs.NodeWriter; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.HashMap; -import java.util.Iterator; -import java.util.TreeSet; - -/** - * Partial implementation of a Preference node. - * - * @since 1.4 - * @author Mark Wielaard (mark@klomp.org) - */ -public abstract class AbstractPreferences extends Preferences { - - // protected fields - - /** - * Object used to lock this preference node. Any thread only locks nodes - * downwards when it has the lock on the current node. No method should - * synchronize on the lock of any of its parent nodes while holding the - * lock on the current node. - */ - protected final Object lock = new Object(); - - /** - * Set to true in the contructor if the node did not exist in the backing - * store when this preference node object was created. Should be set in - * the contructor of a subclass. Defaults to false. Used to fire node - * changed events. - */ - protected boolean newNode = false; - - // private fields - - /** - * The parent preferences node or null when this is the root node. - */ - private final AbstractPreferences parent; - - /** - * The name of this node. - * Only when this is a root node (parent == null) the name is empty. - * It has a maximum of 80 characters and cannot contain any '/' characters. - */ - private final String name; - - /** True when this node has been remove, false otherwise. */ - private boolean removed = false; - - /** - * Holds all the child names and nodes of this node that have been - * accessed by earlier <code>getChild()</code> or <code>childSpi()</code> - * invocations and that have not been removed. - */ - private HashMap childCache = new HashMap(); - - // constructor - - /** - * Creates a new AbstractPreferences node with the given parent and name. - * - * @param parent the parent of this node or null when this is the root node - * @param name the name of this node, can not be null, only 80 characters - * maximum, must be empty when parent is null and cannot - * contain any '/' characters - * @exception IllegalArgumentException when name is null, greater then 80 - * characters, not the empty string but parent is null or - * contains a '/' character - */ - protected AbstractPreferences(AbstractPreferences parent, String name) { - if ( (name == null) // name should be given - || (name.length() > MAX_NAME_LENGTH) // 80 characters max - || (parent == null && name.length() != 0) // root has no name - || (parent != null && name.length() == 0) // all other nodes do - || (name.indexOf('/') != -1)) // must not contain '/' - throw new IllegalArgumentException("Illegal name argument '" - + name - + "' (parent is " - + (parent == null ? "" : "not ") - + "null)"); - this.parent = parent; - this.name = name; - } - - // identification methods - - /** - * Returns the absolute path name of this preference node. - * The absolute path name of a node is the path name of its parent node - * plus a '/' plus its own name. If the node is the root node and has no - * parent then its path name is "" and its absolute path name is "/". - */ - public String absolutePath() { - if (parent == null) - return "/"; - else - return parent.path() + '/' + name; - } - - /** - * Private helper method for absolutePath. Returns the empty string for a - * root node and otherwise the parentPath of its parent plus a '/'. - */ - private String path() { - if (parent == null) - return ""; - else - return parent.path() + '/' + name; - } - - /** - * Returns true if this node comes from the user preferences tree, false - * if it comes from the system preferences tree. - */ - public boolean isUserNode() { - AbstractPreferences root = this; - while (root.parent != null) - root = root.parent; - return root == Preferences.userRoot(); - } - - /** - * Returns the name of this preferences node. The name of the node cannot - * be null, can be mostly 80 characters and cannot contain any '/' - * characters. The root node has as name "". - */ - public String name() { - return name; - } - - /** - * Returns the String given by - * <code> - * (isUserNode() ? "User":"System") + " Preference Node: " + absolutePath() - * </code> - */ - public String toString() { - return (isUserNode() ? "User":"System") - + " Preference Node: " - + absolutePath(); - } - - /** - * Returns all known unremoved children of this node. - * - * @return All known unremoved children of this node - */ - protected final AbstractPreferences[] cachedChildren() - { - return (AbstractPreferences[]) childCache.values().toArray(); - } - - /** - * Returns all the direct sub nodes of this preferences node. - * Needs access to the backing store to give a meaningfull answer. - * <p> - * This implementation locks this node, checks if the node has not yet - * been removed and throws an <code>IllegalStateException</code> when it - * has been. Then it creates a new <code>TreeSet</code> and adds any - * already cached child nodes names. To get any uncached names it calls - * <code>childrenNamesSpi()</code> and adds the result to the set. Finally - * it calls <code>toArray()</code> on the created set. When the call to - * <code>childrenNamesSpi</code> thows an <code>BackingStoreException</code> - * this method will not catch that exception but propagate the exception - * to the caller. - * - * @exception BackingStoreException when the backing store cannot be - * reached - * @exception IllegalStateException when this node has been removed - */ - public String[] childrenNames() throws BackingStoreException { - synchronized(lock) { - if (isRemoved()) - throw new IllegalStateException("Node removed"); - - TreeSet childrenNames = new TreeSet(); - - // First get all cached node names - childrenNames.addAll(childCache.keySet()); - - // Then add any others - String names[] = childrenNamesSpi(); - for (int i = 0; i < names.length; i++) { - childrenNames.add(names[i]); - } - - // And return the array of names - String[] children = new String[childrenNames.size()]; - childrenNames.toArray(children); - return children; - - } - } - - /** - * Returns a sub node of this preferences node if the given path is - * relative (does not start with a '/') or a sub node of the root - * if the path is absolute (does start with a '/'). - * <p> - * This method first locks this node and checks if the node has not been - * removed, if it has been removed it throws an exception. Then if the - * path is relative (does not start with a '/') it checks if the path is - * legal (does not end with a '/' and has no consecutive '/' characters). - * Then it recursively gets a name from the path, gets the child node - * from the child-cache of this node or calls the <code>childSpi()</code> - * method to create a new child sub node. This is done recursively on the - * newly created sub node with the rest of the path till the path is empty. - * If the path is absolute (starts with a '/') the lock on this node is - * droped and this method is called on the root of the preferences tree - * with as argument the complete path minus the first '/'. - * - * @exception IllegalStateException if this node has been removed - * @exception IllegalArgumentException if the path contains two or more - * consecutive '/' characters, ends with a '/' charactor and is not the - * string "/" (indicating the root node) or any name on the path is more - * then 80 characters long - */ - public Preferences node(String path) { - synchronized(lock) { - if (isRemoved()) - throw new IllegalStateException("Node removed"); - - // Is it a relative path? - if (!path.startsWith("/")) { - - // Check if it is a valid path - if (path.indexOf("//") != -1 || path.endsWith("/")) - throw new IllegalArgumentException(path); - - return getNode(path); - } - } - - // path started with a '/' so it is absolute - // we drop the lock and start from the root (omitting the first '/') - Preferences root = isUserNode() ? userRoot() : systemRoot(); - return root.node(path.substring(1)); - - } - - /** - * Private helper method for <code>node()</code>. Called with this node - * locked. Returns this node when path is the empty string, if it is not - * empty the next node name is taken from the path (all chars till the - * next '/' or end of path string) and the node is either taken from the - * child-cache of this node or the <code>childSpi()</code> method is called - * on this node with the name as argument. Then this method is called - * recursively on the just constructed child node with the rest of the - * path. - * - * @param path should not end with a '/' character and should not contain - * consecutive '/' characters - * @exception IllegalArgumentException if path begins with a name that is - * larger then 80 characters. - */ - private Preferences getNode(String path) { - // if mark is dom then goto end - - // Empty String "" indicates this node - if (path.length() == 0) - return this; - - // Calculate child name and rest of path - String childName; - String childPath; - int nextSlash = path.indexOf('/'); - if (nextSlash == -1) { - childName = path; - childPath = ""; - } else { - childName = path.substring(0, nextSlash); - childPath = path.substring(nextSlash+1); - } - - // Get the child node - AbstractPreferences child; - child = (AbstractPreferences)childCache.get(childName); - if (child == null) { - - if (childName.length() > MAX_NAME_LENGTH) - throw new IllegalArgumentException(childName); - - // Not in childCache yet so create a new sub node - child = childSpi(childName); - // XXX - check if node is new - childCache.put(childName, child); - } - - // Lock the child and go down - synchronized(child.lock) { - return child.getNode(childPath); - } - } - - /** - * Returns true if the node that the path points to exists in memory or - * in the backing store. Otherwise it returns false or an exception is - * thrown. When this node is removed the only valid parameter is the - * empty string (indicating this node), the return value in that case - * will be false. - * - * @exception BackingStoreException when the backing store cannot be - * reached - * @exception IllegalStateException if this node has been removed - * and the path is not the empty string (indicating this node) - * @exception IllegalArgumentException if the path contains two or more - * consecutive '/' characters, ends with a '/' charactor and is not the - * string "/" (indicating the root node) or any name on the path is more - * then 80 characters long - */ - public boolean nodeExists(String path) throws BackingStoreException { - synchronized(lock) { - if (isRemoved() && path.length() != 0) - throw new IllegalStateException("Node removed"); - - // Is it a relative path? - if (!path.startsWith("/")) { - - // Check if it is a valid path - if (path.indexOf("//") != -1 || path.endsWith("/")) - throw new IllegalArgumentException(path); - - return existsNode(path); - } - } - - // path started with a '/' so it is absolute - // we drop the lock and start from the root (omitting the first '/') - Preferences root = isUserNode() ? userRoot() : systemRoot(); - return root.nodeExists(path.substring(1)); - - } - - private boolean existsNode(String path) throws BackingStoreException { - - // Empty String "" indicates this node - if (path.length() == 0) - return(!isRemoved()); - - // Calculate child name and rest of path - String childName; - String childPath; - int nextSlash = path.indexOf('/'); - if (nextSlash == -1) { - childName = path; - childPath = ""; - } else { - childName = path.substring(0, nextSlash); - childPath = path.substring(nextSlash+1); - } - - // Get the child node - AbstractPreferences child; - child = (AbstractPreferences)childCache.get(childName); - if (child == null) { - - if (childName.length() > MAX_NAME_LENGTH) - throw new IllegalArgumentException(childName); - - // Not in childCache yet so create a new sub node - child = getChild(childName); - - if (child == null) - return false; - - childCache.put(childName, child); - } - - // Lock the child and go down - synchronized(child.lock) { - return child.existsNode(childPath); - } - } - - /** - * Returns the child sub node if it exists in the backing store or null - * if it does not exist. Called (indirectly) by <code>nodeExists()</code> - * when a child node name can not be found in the cache. - * <p> - * Gets the lock on this node, calls <code>childrenNamesSpi()</code> to - * get an array of all (possibly uncached) children and compares the - * given name with the names in the array. If the name is found in the - * array <code>childSpi()</code> is called to get an instance, otherwise - * null is returned. - * - * @exception BackingStoreException when the backing store cannot be - * reached - */ - protected AbstractPreferences getChild(String name) - throws BackingStoreException - { - synchronized(lock) { - // Get all the names (not yet in the cache) - String[] names = childrenNamesSpi(); - for (int i=0; i < names.length; i++) - if (name.equals(names[i])) - return childSpi(name); - - // No child with that name found - return null; - } - } - - /** - * Returns true if this node has been removed with the - * <code>removeNode()</code> method, false otherwise. - * <p> - * Gets the lock on this node and then returns a boolean field set by - * <code>removeNode</code> methods. - */ - protected boolean isRemoved() { - synchronized(lock) { - return removed; - } - } - - /** - * Returns the parent preferences node of this node or null if this is - * the root of the preferences tree. - * <p> - * Gets the lock on this node, checks that the node has not been removed - * and returns the parent given to the constructor. - * - * @exception IllegalStateException if this node has been removed - */ - public Preferences parent() { - synchronized(lock) { - if (isRemoved()) - throw new IllegalStateException("Node removed"); - - return parent; - } - } - - // export methods - - /** - * XXX - */ - public void exportNode(OutputStream os) - throws BackingStoreException, - IOException - { - NodeWriter nodeWriter = new NodeWriter(this, os); - nodeWriter.writePrefs(); - } - - /** - * XXX - */ - public void exportSubtree(OutputStream os) - throws BackingStoreException, - IOException - { - NodeWriter nodeWriter = new NodeWriter(this, os); - nodeWriter.writePrefsTree(); - } - - // preference entry manipulation methods - - /** - * Returns an (possibly empty) array with all the keys of the preference - * entries of this node. - * <p> - * This method locks this node and checks if the node has not been - * removed, if it has been removed it throws an exception, then it returns - * the result of calling <code>keysSpi()</code>. - * - * @exception BackingStoreException when the backing store cannot be - * reached - * @exception IllegalStateException if this node has been removed - */ - public String[] keys() throws BackingStoreException { - synchronized(lock) { - if (isRemoved()) - throw new IllegalStateException("Node removed"); - - return keysSpi(); - } - } - - - /** - * Returns the value associated with the key in this preferences node. If - * the default value of the key cannot be found in the preferences node - * entries or something goes wrong with the backing store the supplied - * default value is returned. - * <p> - * Checks that key is not null and not larger then 80 characters, - * locks this node, and checks that the node has not been removed. - * Then it calls <code>keySpi()</code> and returns - * the result of that method or the given default value if it returned - * null or throwed an exception. - * - * @exception IllegalArgumentException if key is larger then 80 characters - * @exception IllegalStateException if this node has been removed - * @exception NullPointerException if key is null - */ - public String get(String key, String defaultVal) { - if (key.length() > MAX_KEY_LENGTH) - throw new IllegalArgumentException(key); - - synchronized(lock) { - if (isRemoved()) - throw new IllegalStateException("Node removed"); - - String value; - try { - value = getSpi(key); - } catch (ThreadDeath death) { - throw death; - } catch (Throwable t) { - value = null; - } - - if (value != null) { - return value; - } else { - return defaultVal; - } - } - } - - /** - * Convenience method for getting the given entry as a boolean. - * When the string representation of the requested entry is either - * "true" or "false" (ignoring case) then that value is returned, - * otherwise the given default boolean value is returned. - * - * @exception IllegalArgumentException if key is larger then 80 characters - * @exception IllegalStateException if this node has been removed - * @exception NullPointerException if key is null - */ - public boolean getBoolean(String key, boolean defaultVal) { - String value = get(key, null); - - if ("true".equalsIgnoreCase(value)) - return true; - - if ("false".equalsIgnoreCase(value)) - return false; - - return defaultVal; - } - - /** - * Convenience method for getting the given entry as a byte array. - * When the string representation of the requested entry is a valid - * Base64 encoded string (without any other characters, such as newlines) - * then the decoded Base64 string is returned as byte array, - * otherwise the given default byte array value is returned. - * - * @exception IllegalArgumentException if key is larger then 80 characters - * @exception IllegalStateException if this node has been removed - * @exception NullPointerException if key is null - */ - public byte[] getByteArray(String key, byte[] defaultVal) { - String value = get(key, null); - - byte[] b = null; - if (value != null) { - b = decode64(value); - } - - if (b != null) - return b; - else - return defaultVal; - } - - /** - * Helper method for decoding a Base64 string as an byte array. - * Returns null on encoding error. This method does not allow any other - * characters present in the string then the 65 special base64 chars. - */ - private static byte[] decode64(String s) { - ByteArrayOutputStream bs = new ByteArrayOutputStream((s.length()/4)*3); - char[] c = new char[s.length()]; - s.getChars(0, s.length(), c, 0); - - // Convert from base64 chars - int endchar = -1; - for(int j = 0; j < c.length && endchar == -1; j++) { - if (c[j] >= 'A' && c[j] <= 'Z') { - c[j] -= 'A'; - } else if (c[j] >= 'a' && c[j] <= 'z') { - c[j] = (char) (c[j] + 26 - 'a'); - } else if (c[j] >= '0' && c[j] <= '9') { - c[j] = (char) (c[j] + 52 - '0'); - } else if (c[j] == '+') { - c[j] = 62; - } else if (c[j] == '/') { - c[j] = 63; - } else if (c[j] == '=') { - endchar = j; - } else { - return null; // encoding exception - } - } - - int remaining = endchar == -1 ? c.length : endchar; - int i = 0; - while (remaining > 0) { - // Four input chars (6 bits) are decoded as three bytes as - // 000000 001111 111122 222222 - - byte b0 = (byte) (c[i] << 2); - if (remaining >= 2) { - b0 += (c[i+1] & 0x30) >> 4; - } - bs.write(b0); - - if (remaining >= 3) { - byte b1 = (byte) ((c[i+1] & 0x0F) << 4); - b1 += (byte) ((c[i+2] & 0x3C) >> 2); - bs.write(b1); - } - - if (remaining >= 4) { - byte b2 = (byte) ((c[i+2] & 0x03) << 6); - b2 += c[i+3]; - bs.write(b2); - } - - i += 4; - remaining -= 4; - } - - return bs.toByteArray(); - } - - /** - * Convenience method for getting the given entry as a double. - * When the string representation of the requested entry can be decoded - * with <code>Double.parseDouble()</code> then that double is returned, - * otherwise the given default double value is returned. - * - * @exception IllegalArgumentException if key is larger then 80 characters - * @exception IllegalStateException if this node has been removed - * @exception NullPointerException if key is null - */ - public double getDouble(String key, double defaultVal) { - String value = get(key, null); - - if (value != null) { - try { - return Double.parseDouble(value); - } catch (NumberFormatException nfe) { /* ignore */ } - } - - return defaultVal; - } - - /** - * Convenience method for getting the given entry as a float. - * When the string representation of the requested entry can be decoded - * with <code>Float.parseFloat()</code> then that float is returned, - * otherwise the given default float value is returned. - * - * @exception IllegalArgumentException if key is larger then 80 characters - * @exception IllegalStateException if this node has been removed - * @exception NullPointerException if key is null - */ - public float getFloat(String key, float defaultVal) { - String value = get(key, null); - - if (value != null) { - try { - return Float.parseFloat(value); - } catch (NumberFormatException nfe) { /* ignore */ } - } - - return defaultVal; - } - - /** - * Convenience method for getting the given entry as an integer. - * When the string representation of the requested entry can be decoded - * with <code>Integer.parseInt()</code> then that integer is returned, - * otherwise the given default integer value is returned. - * - * @exception IllegalArgumentException if key is larger then 80 characters - * @exception IllegalStateException if this node has been removed - * @exception NullPointerException if key is null - */ - public int getInt(String key, int defaultVal) { - String value = get(key, null); - - if (value != null) { - try { - return Integer.parseInt(value); - } catch (NumberFormatException nfe) { /* ignore */ } - } - - return defaultVal; - } - - /** - * Convenience method for getting the given entry as a long. - * When the string representation of the requested entry can be decoded - * with <code>Long.parseLong()</code> then that long is returned, - * otherwise the given default long value is returned. - * - * @exception IllegalArgumentException if key is larger then 80 characters - * @exception IllegalStateException if this node has been removed - * @exception NullPointerException if key is null - */ - public long getLong(String key, long defaultVal) { - String value = get(key, null); - - if (value != null) { - try { - return Long.parseLong(value); - } catch (NumberFormatException nfe) { /* ignore */ } - } - - return defaultVal; - } - - /** - * Sets the value of the given preferences entry for this node. - * Key and value cannot be null, the key cannot exceed 80 characters - * and the value cannot exceed 8192 characters. - * <p> - * The result will be immediatly visible in this VM, but may not be - * immediatly written to the backing store. - * <p> - * Checks that key and value are valid, locks this node, and checks that - * the node has not been removed. Then it calls <code>putSpi()</code>. - * - * @exception NullPointerException if either key or value are null - * @exception IllegalArgumentException if either key or value are to large - * @exception IllegalStateException when this node has been removed - */ - public void put(String key, String value) { - if (key.length() > MAX_KEY_LENGTH - || value.length() > MAX_VALUE_LENGTH) - throw new IllegalArgumentException("key (" - + key.length() + ")" - + " or value (" - + value.length() + ")" - + " to large"); - synchronized(lock) { - if (isRemoved()) - throw new IllegalStateException("Node removed"); - - putSpi(key, value); - - // XXX - fire events - } - - } - - /** - * Convenience method for setting the given entry as a boolean. - * The boolean is converted with <code>Boolean.toString(value)</code> - * and then stored in the preference entry as that string. - * - * @exception NullPointerException if key is null - * @exception IllegalArgumentException if the key length is to large - * @exception IllegalStateException when this node has been removed - */ - public void putBoolean(String key, boolean value) { - put(key, String.valueOf(value)); - // XXX - Use when using 1.4 compatible Boolean - // put(key, Boolean.toString(value)); - } - - /** - * Convenience method for setting the given entry as an array of bytes. - * The byte array is converted to a Base64 encoded string - * and then stored in the preference entry as that string. - * <p> - * Note that a byte array encoded as a Base64 string will be about 1.3 - * times larger then the original length of the byte array, which means - * that the byte array may not be larger about 6 KB. - * - * @exception NullPointerException if either key or value are null - * @exception IllegalArgumentException if either key or value are to large - * @exception IllegalStateException when this node has been removed - */ - public void putByteArray(String key, byte[] value) { - put(key, encode64(value)); - } - - /** - * Helper method for encoding an array of bytes as a Base64 String. - */ - private static String encode64(byte[] b) { - StringBuffer sb = new StringBuffer((b.length/3)*4); - - int i = 0; - int remaining = b.length; - char c[] = new char[4]; - while (remaining > 0) { - // Three input bytes are encoded as four chars (6 bits) as - // 00000011 11112222 22333333 - - c[0] = (char) ((b[i] & 0xFC) >> 2); - c[1] = (char) ((b[i] & 0x03) << 4); - if (remaining >= 2) { - c[1] += (char) ((b[i+1] & 0xF0) >> 4); - c[2] = (char) ((b[i+1] & 0x0F) << 2); - if (remaining >= 3) { - c[2] += (char) ((b[i+2] & 0xC0) >> 6); - c[3] = (char) (b[i+2] & 0x3F); - } else { - c[3] = 64; - } - } else { - c[2] = 64; - c[3] = 64; - } - - // Convert to base64 chars - for(int j = 0; j < 4; j++) { - if (c[j] < 26) { - c[j] += 'A'; - } else if (c[j] < 52) { - c[j] = (char) (c[j] - 26 + 'a'); - } else if (c[j] < 62) { - c[j] = (char) (c[j] - 52 + '0'); - } else if (c[j] == 62) { - c[j] = '+'; - } else if (c[j] == 63) { - c[j] = '/'; - } else { - c[j] = '='; - } - } - - sb.append(c); - i += 3; - remaining -= 3; - } - - return sb.toString(); - } - - /** - * Convenience method for setting the given entry as a double. - * The double is converted with <code>Double.toString(double)</code> - * and then stored in the preference entry as that string. - * - * @exception NullPointerException if the key is null - * @exception IllegalArgumentException if the key length is to large - * @exception IllegalStateException when this node has been removed - */ - public void putDouble(String key, double value) { - put(key, Double.toString(value)); - } - - /** - * Convenience method for setting the given entry as a float. - * The float is converted with <code>Float.toString(float)</code> - * and then stored in the preference entry as that string. - * - * @exception NullPointerException if the key is null - * @exception IllegalArgumentException if the key length is to large - * @exception IllegalStateException when this node has been removed - */ - public void putFloat(String key, float value) { - put(key, Float.toString(value)); - } - - /** - * Convenience method for setting the given entry as an integer. - * The integer is converted with <code>Integer.toString(int)</code> - * and then stored in the preference entry as that string. - * - * @exception NullPointerException if the key is null - * @exception IllegalArgumentException if the key length is to large - * @exception IllegalStateException when this node has been removed - */ - public void putInt(String key, int value) { - put(key, Integer.toString(value)); - } - - /** - * Convenience method for setting the given entry as a long. - * The long is converted with <code>Long.toString(long)</code> - * and then stored in the preference entry as that string. - * - * @exception NullPointerException if the key is null - * @exception IllegalArgumentException if the key length is to large - * @exception IllegalStateException when this node has been removed - */ - public void putLong(String key, long value) { - put(key, Long.toString(value)); - } - - /** - * Removes the preferences entry from this preferences node. - * <p> - * The result will be immediatly visible in this VM, but may not be - * immediatly written to the backing store. - * <p> - * This implementation checks that the key is not larger then 80 - * characters, gets the lock of this node, checks that the node has - * not been removed and calls <code>removeSpi</code> with the given key. - * - * @exception NullPointerException if the key is null - * @exception IllegalArgumentException if the key length is to large - * @exception IllegalStateException when this node has been removed - */ - public void remove(String key) { - if (key.length() > MAX_KEY_LENGTH) - throw new IllegalArgumentException(key); - - synchronized(lock) { - if (isRemoved()) - throw new IllegalStateException("Node removed"); - - removeSpi(key); - } - } - - /** - * Removes all entries from this preferences node. May need access to the - * backing store to get and clear all entries. - * <p> - * The result will be immediatly visible in this VM, but may not be - * immediatly written to the backing store. - * <p> - * This implementation locks this node, checks that the node has not been - * removed and calls <code>keys()</code> to get a complete array of keys - * for this node. For every key found <code>removeSpi()</code> is called. - * - * @exception BackingStoreException when the backing store cannot be - * reached - * @exception IllegalStateException if this node has been removed - */ - public void clear() throws BackingStoreException { - synchronized(lock) { - if (isRemoved()) - throw new IllegalStateException("Node Removed"); - - String[] keys = keys(); - for (int i = 0; i < keys.length; i++) { - removeSpi(keys[i]); - } - } - } - - /** - * Writes all preference changes on this and any subnode that have not - * yet been written to the backing store. This has no effect on the - * preference entries in this VM, but it makes sure that all changes - * are visible to other programs (other VMs might need to call the - * <code>sync()</code> method to actually see the changes to the backing - * store. - * <p> - * Locks this node, calls the <code>flushSpi()</code> method, gets all - * the (cached - already existing in this VM) subnodes and then calls - * <code>flushSpi()</code> on every subnode with this node unlocked and - * only that particular subnode locked. - * - * @exception BackingStoreException when the backing store cannot be - * reached - */ - public void flush() throws BackingStoreException { - flushNode(false); - } - - /** - * Writes and reads all preference changes to and from this and any - * subnodes. This makes sure that all local changes are written to the - * backing store and that all changes to the backing store are visible - * in this preference node (and all subnodes). - * <p> - * Checks that this node is not removed, locks this node, calls the - * <code>syncSpi()</code> method, gets all the subnodes and then calls - * <code>syncSpi()</code> on every subnode with this node unlocked and - * only that particular subnode locked. - * - * @exception BackingStoreException when the backing store cannot be - * reached - * @exception IllegalStateException if this node has been removed - */ - public void sync() throws BackingStoreException { - flushNode(true); - } - - - /** - * Private helper method that locks this node and calls either - * <code>flushSpi()</code> if <code>sync</code> is false, or - * <code>flushSpi()</code> if <code>sync</code> is true. Then it gets all - * the currently cached subnodes. For every subnode it calls this method - * recursively with this node no longer locked. - * <p> - * Called by either <code>flush()</code> or <code>sync()</code> - */ - private void flushNode(boolean sync) throws BackingStoreException { - String[] keys = null; - synchronized(lock) { - if (sync) { - syncSpi(); - } else { - flushSpi(); - } - keys = (String[]) childCache.keySet().toArray(); - } - - if (keys != null) { - for (int i = 0; i < keys.length; i++) { - // Have to lock this node again to access the childCache - AbstractPreferences subNode; - synchronized(this) { - subNode = (AbstractPreferences) childCache.get(keys[i]); - } - - // The child could already have been removed from the cache - if (subNode != null) { - subNode.flushNode(sync); - } - } - } - } - - /** - * Removes this and all subnodes from the backing store and clears all - * entries. After removal this instance will not be useable (except for - * a few methods that don't throw a <code>InvalidStateException</code>), - * even when a new node with the same path name is created this instance - * will not be usable again. - * <p> - * Checks that this is not a root node. If not it locks the parent node, - * then locks this node and checks that the node has not yet been removed. - * Then it makes sure that all subnodes of this node are in the child cache, - * by calling <code>childSpi()</code> on any children not yet in the cache. - * Then for all children it locks the subnode and removes it. After all - * subnodes have been purged the child cache is cleared, this nodes removed - * flag is set and any listeners are called. Finally this node is removed - * from the child cache of the parent node. - * - * @exception BackingStoreException when the backing store cannot be - * reached - * @exception IllegalStateException if this node has already been removed - * @exception UnsupportedOperationException if this is a root node - */ - public void removeNode() throws BackingStoreException { - // Check if it is a root node - if (parent == null) - throw new UnsupportedOperationException("Cannot remove root node"); - - synchronized(parent) { - synchronized(this) { - if (isRemoved()) - throw new IllegalStateException("Node Removed"); - - purge(); - } - parent.childCache.remove(name); - } - } - - /** - * Private helper method used to completely remove this node. - * Called by <code>removeNode</code> with the parent node and this node - * locked. - * <p> - * Makes sure that all subnodes of this node are in the child cache, - * by calling <code>childSpi()</code> on any children not yet in the - * cache. Then for all children it locks the subnode and calls this method - * on that node. After all subnodes have been purged the child cache is - * cleared, this nodes removed flag is set and any listeners are called. - */ - private void purge() throws BackingStoreException - { - // Make sure all children have an AbstractPreferences node in cache - String children[] = childrenNamesSpi(); - for (int i = 0; i < children.length; i++) { - if (childCache.get(children[i]) == null) - childCache.put(children[i], childSpi(children[i])); - } - - // purge all children - Iterator i = childCache.values().iterator(); - while (i.hasNext()) { - AbstractPreferences node = (AbstractPreferences) i.next(); - synchronized(node) { - node.purge(); - } - } - - // Cache is empty now - childCache.clear(); - - // remove this node - removeNodeSpi(); - removed = true; - - // XXX - check for listeners - } - - // listener methods - - /** - * XXX - */ - public void addNodeChangeListener(NodeChangeListener listener) { - // XXX - } - - public void addPreferenceChangeListener(PreferenceChangeListener listener) { - // XXX - } - - public void removeNodeChangeListener(NodeChangeListener listener) { - // XXX - } - - public void removePreferenceChangeListener - (PreferenceChangeListener listener) - { - // XXX - } - - // abstract spi methods - - /** - * Returns the names of the sub nodes of this preference node. - * This method only has to return any not yet cached child names, - * but may return all names if that is easier. It must not return - * null when there are no children, it has to return an empty array - * in that case. Since this method must consult the backing store to - * get all the sub node names it may throw a BackingStoreException. - * <p> - * Called by <code>childrenNames()</code> with this node locked. - */ - protected abstract String[] childrenNamesSpi() throws BackingStoreException; - - /** - * Returns a child note with the given name. - * This method is called by the <code>node()</code> method (indirectly - * through the <code>getNode()</code> helper method) with this node locked - * if a sub node with this name does not already exist in the child cache. - * If the child node did not aleady exist in the backing store the boolean - * field <code>newNode</code> of the returned node should be set. - * <p> - * Note that this method should even return a non-null child node if the - * backing store is not available since it may not throw a - * <code>BackingStoreException</code>. - */ - protected abstract AbstractPreferences childSpi(String name); - - /** - * Returns an (possibly empty) array with all the keys of the preference - * entries of this node. - * <p> - * Called by <code>keys()</code> with this node locked if this node has - * not been removed. May throw an exception when the backing store cannot - * be accessed. - * - * @exception BackingStoreException when the backing store cannot be - * reached - */ - protected abstract String[] keysSpi() throws BackingStoreException; - - /** - * Returns the value associated with the key in this preferences node or - * null when the key does not exist in this preferences node. - * <p> - * Called by <code>key()</code> with this node locked after checking that - * key is valid, not null and that the node has not been removed. - * <code>key()</code> will catch any exceptions that this method throws. - */ - protected abstract String getSpi(String key); - - /** - * Sets the value of the given preferences entry for this node. - * The implementation is not required to propagate the change to the - * backing store immediatly. It may not throw an exception when it tries - * to write to the backing store and that operation fails, the failure - * should be registered so a later invocation of <code>flush()</code> - * or <code>sync()</code> can signal the failure. - * <p> - * Called by <code>put()</code> with this node locked after checking that - * key and value are valid and non-null. - */ - protected abstract void putSpi(String key, String value); - - /** - * Removes the given key entry from this preferences node. - * The implementation is not required to propagate the change to the - * backing store immediatly. It may not throw an exception when it tries - * to write to the backing store and that operation fails, the failure - * should be registered so a later invocation of <code>flush()</code> - * or <code>sync()</code> can signal the failure. - * <p> - * Called by <code>remove()</code> with this node locked after checking - * that the key is valid and non-null. - */ - protected abstract void removeSpi(String key); - - /** - * Writes all entries of this preferences node that have not yet been - * written to the backing store and possibly creates this node in the - * backing store, if it does not yet exist. Should only write changes to - * this node and not write changes to any subnodes. - * Note that the node can be already removed in this VM. To check if - * that is the case the implementation can call <code>isRemoved()</code>. - * <p> - * Called (indirectly) by <code>flush()</code> with this node locked. - */ - protected abstract void flushSpi() throws BackingStoreException; - - /** - * Writes all entries of this preferences node that have not yet been - * written to the backing store and reads any entries that have changed - * in the backing store but that are not yet visible in this VM. - * Should only sync this node and not change any of the subnodes. - * Note that the node can be already removed in this VM. To check if - * that is the case the implementation can call <code>isRemoved()</code>. - * <p> - * Called (indirectly) by <code>sync()</code> with this node locked. - */ - protected abstract void syncSpi() throws BackingStoreException; - - /** - * Clears this node from this VM and removes it from the backing store. - * After this method has been called the node is marked as removed. - * <p> - * Called (indirectly) by <code>removeNode()</code> with this node locked - * after all the sub nodes of this node have already been removed. - */ - protected abstract void removeNodeSpi() throws BackingStoreException; -} diff --git a/libjava/java/util/prefs/BackingStoreException.java b/libjava/java/util/prefs/BackingStoreException.java deleted file mode 100644 index 0ba358a5688..00000000000 --- a/libjava/java/util/prefs/BackingStoreException.java +++ /dev/null @@ -1,104 +0,0 @@ -/* BackingStoreException.java - chained exception thrown when backing store - fails - Copyright (C) 2001, 2002, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package java.util.prefs; - -import java.io.NotSerializableException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; - -/** - * Chained exception thrown when backing store fails. This exception is - * only thrown from methods that actually have to access the backing store, - * such as <code>clear(), keys(), childrenNames(), nodeExists(), removeNode(), - * flush(), sync(), exportNode(), exportSubTree()</code>; normal operations - * do not throw BackingStoreExceptions. - * - * <p>Note that although this class inherits the Serializable interface, an - * attempt to serialize will fail with a <code>NotSerializableException</code>. - * - * @author Mark Wielaard (mark@klomp.org) - * @since 1.4 - * @status updated to 1.4 - */ -public class BackingStoreException extends Exception -{ - static final long serialVersionUID = 859796500401108469L; - - /** - * Creates a new exception with a descriptive message. - * - * @param message the message - */ - public BackingStoreException(String message) - { - super(message); - } - - /** - * Create a new exception with the given cause. - * - * @param cause the cause - */ - public BackingStoreException(Throwable cause) - { - super(cause); - } - - /** - * This class should not be serialized. - * - * @param o the output stream - */ - private void writeObject(ObjectOutputStream o) throws NotSerializableException - { - throw new NotSerializableException - ("java.util.prefs.BackingStoreException"); - } - - /** - * This class should not be serialized. - * - * @param i the input stream - */ - private void readObject(ObjectInputStream i) throws NotSerializableException - { - throw new NotSerializableException - ("java.util.prefs.BackingStoreException"); - } -} diff --git a/libjava/java/util/prefs/InvalidPreferencesFormatException.java b/libjava/java/util/prefs/InvalidPreferencesFormatException.java deleted file mode 100644 index f929b56f68e..00000000000 --- a/libjava/java/util/prefs/InvalidPreferencesFormatException.java +++ /dev/null @@ -1,116 +0,0 @@ -/* InvalidPreferencesFormatException - indicates reading prefs from stream - failed - Copyright (C) 2001, 2002, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package java.util.prefs; - -import java.io.NotSerializableException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; - -/** - * Indicates reading prefs from stream failed. Thrown by the - * <code>importPreferences()</code> method when the supplied input stream - * could not be read because it was not in the correct XML format. - * - * <p>Note that although this class inherits the Serializable interface, an - * attempt to serialize will fail with a <code>NotSerializableException</code>. - * </p> - * - * @author Mark Wielaard (mark@klomp.org) - * @see Preferences - * @since 1.4 - * @status updated to 1.4 - */ -public class InvalidPreferencesFormatException extends Exception -{ - static final long serialVersionUID = -791715184232119669L; - - /** - * Creates a new exception with a descriptive message. The cause remains - * uninitialized. - * - * @param message the message - */ - public InvalidPreferencesFormatException(String message) - { - super(message); - } - - /** - * Creates a new exception with the given cause. - * - * @param cause the cause - */ - public InvalidPreferencesFormatException(Throwable cause) - { - super(cause); - } - - /** - * Creates a new exception with a descriptive message and a cause. - * - * @param message the message - * @param cause the cause - */ - public InvalidPreferencesFormatException(String message, Throwable cause) - { - super(message, cause); - } - - /** - * This class should not be serialized. - * - * @param o the output stream - */ - private void writeObject(ObjectOutputStream o) throws NotSerializableException - { - throw new NotSerializableException - ("java.util.prefs.InvalidPreferencesFormatException"); - } - - /** - * This class should not be serialized. - * - * @param i the input stream - */ - private void readObject(ObjectInputStream i) throws NotSerializableException - { - throw new NotSerializableException - ("java.util.prefs.InvalidPreferencesFormatException"); - } -} diff --git a/libjava/java/util/prefs/NodeChangeEvent.java b/libjava/java/util/prefs/NodeChangeEvent.java deleted file mode 100644 index 89986db88b3..00000000000 --- a/libjava/java/util/prefs/NodeChangeEvent.java +++ /dev/null @@ -1,91 +0,0 @@ -/* NodeChangeEvent - ObjectEvent fired when a Preference node is added/removed - Copyright (C) 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package java.util.prefs; - -import java.util.EventObject; - -/** - * ObjectEvent fired when a Preference node is added/removed. - * This event is only generated when a new subnode is added or a subnode is - * removed from a preference node. Changes in the entries of a preference node - * are indicated with a <code>PreferenceChangeEvent</code>. - * - * @since 1.4 - * @author Mark Wielaard (mark@klomp.org) - */ -public class NodeChangeEvent extends EventObject { - - private static final long serialVersionUID =8068949086596572957L; - - /** - * The sub node that was added or removed. - * Defined transient just like <code>EventObject.source</code> since - * this object should be serializable, but Preferences is in general not - * serializable. - */ - private final transient Preferences child; - - /** - * Creates a new NodeChangeEvent. - * - * @param parentNode The source preference node from which a subnode was - * added or removed - * @param childNode The preference node that was added or removed - */ - public NodeChangeEvent(Preferences parentNode, Preferences childNode) { - super(parentNode); - child = childNode; - } - - /** - * Returns the source parent preference node from which a subnode was - * added or removed. - */ - public Preferences getParent() { - return (Preferences) source; - } - - /** - * Returns the child preference subnode that was added or removed. - * To see wether it is still a valid preference node one has to call - * <code>event.getChild().nodeExists("")</code>. - */ - public Preferences getChild() { - return child; - } -} diff --git a/libjava/java/util/prefs/NodeChangeListener.java b/libjava/java/util/prefs/NodeChangeListener.java deleted file mode 100644 index 19664c6652d..00000000000 --- a/libjava/java/util/prefs/NodeChangeListener.java +++ /dev/null @@ -1,64 +0,0 @@ -/* NodeChangeListener - EventListener for Preferences node addition/removal - Copyright (C) 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package java.util.prefs; - -import java.util.EventListener; - -/** - * EventListener for Preferences node addition/removal. - * <p> - * Note that these events are only generated for the addition and removal - * of sub nodes from the preference node. Entry changes in the preference - * node can be monitored with a <code>PreferenceChangeListener</code>. - * - * @since 1.4 - * @author Mark Wielaard (mark@klomp.org) - */ -public interface NodeChangeListener extends EventListener { - - /** - * Fired when a sub node is added to the preference node. - */ - void childAdded(NodeChangeEvent event); - - /** - * Fired when a sub node is removed from the preference node. - */ - void childRemoved(NodeChangeEvent event); - -} diff --git a/libjava/java/util/prefs/PreferenceChangeEvent.java b/libjava/java/util/prefs/PreferenceChangeEvent.java deleted file mode 100644 index fe371f15e4e..00000000000 --- a/libjava/java/util/prefs/PreferenceChangeEvent.java +++ /dev/null @@ -1,105 +0,0 @@ -/* PreferenceChangeEvent - ObjectEvent fired when a Preferences entry changes - Copyright (C) 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package java.util.prefs; - -import java.util.EventObject; - -/** - * ObjectEvent fired when a Preferences entry changes. - * This event is generated when a entry is added, changed or removed. - * When an entry is removed then <code>getNewValue</code> will return null. - * <p> - * Preference change events are only generated for entries in one particular - * preference node. Notification of subnode addition/removal is given by a - * <code>NodeChangeEvent</code>. - * - * @since 1.4 - * @author Mark Wielaard (mark@klomp.org) - */ -public class PreferenceChangeEvent extends EventObject { - - private static final long serialVersionUID = 793724513368024975L; - - /** - * The key of the changed entry. - */ - private final String key; - - /** - * The new value of the changed entry, or null when the entry was removed. - */ - private final String newValue; - - /** - * Creates a new PreferenceChangeEvent. - * - * @param node The source preference node for which an entry was added, - * changed or removed - * @param key The key of the entry that was added, changed or removed - * @param value The new value of the entry that was added or changed, or - * null when the entry was removed - */ - public PreferenceChangeEvent(Preferences node, String key, String value) { - super(node); - this.key = key; - this.newValue = value; - } - - /** - * Returns the source Preference node from which an entry was added, - * changed or removed. - */ - public Preferences getNode() { - return (Preferences) source; - } - - /** - * Returns the key of the entry that was added, changed or removed. - */ - public String getKey() { - return key; - } - - /** - * Returns the new value of the entry that was added or changed, or - * returns null when the entry was removed. - */ - public String getNewValue() { - return newValue; - } -} diff --git a/libjava/java/util/prefs/PreferenceChangeListener.java b/libjava/java/util/prefs/PreferenceChangeListener.java deleted file mode 100644 index adff3582079..00000000000 --- a/libjava/java/util/prefs/PreferenceChangeListener.java +++ /dev/null @@ -1,60 +0,0 @@ -/* PreferenceChangeListener - EventListener for Preferences entry changes - Copyright (C) 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package java.util.prefs; - -import java.util.EventListener; - -/** - * EventListener for Preferences entry addition, change or removal. - * <p> - * Preference change events are only generated for entries in one particular - * preference node. Notification of subnode addition/removal can be monitored - * with a <code>NodeChangeListener</code>. - * - * @since 1.4 - * @author Mark Wielaard (mark@klomp.org) - */ -public interface PreferenceChangeListener extends EventListener { - - /** - * Fired when a entry has been added, changed or removed from the - * preference node. - */ - void preferenceChange(PreferenceChangeEvent event); - -} diff --git a/libjava/java/util/prefs/Preferences.java b/libjava/java/util/prefs/Preferences.java deleted file mode 100644 index c407ae6127a..00000000000 --- a/libjava/java/util/prefs/Preferences.java +++ /dev/null @@ -1,668 +0,0 @@ -/* Preferences -- Preference node containing key value entries and subnodes - Copyright (C) 2001, 2004, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package java.util.prefs; - -import gnu.java.util.prefs.NodeReader; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.security.AccessController; -import java.security.Permission; -import java.security.PrivilegedAction; - -/** - * Preference node containing key value entries and subnodes. - * <p> - * There are two preference node trees, a system tree which can be accessed - * by calling <code>systemRoot()</code> containing system preferences usefull - * for all users, and a user tree that can be accessed by calling - * <code>userRoot()</code> containing preferences that can differ between - * different users. How different users are identified is implementation - * depended. It can be determined by Thread, Access Control Context or Subject. - * <p> - * This implementation uses the "java.util.prefs.PreferencesFactory" system - * property to find a class that implement <code>PreferencesFactory</code> - * and initialized that class (if it has a public no arguments contructor) - * to get at the actual system or user root. If the system property is not set, - * or the class cannot be initialized it uses the default implementation - * <code>gnu.java.util.prefs.FileBasedFactory</code>. - * <p> - * Besides the two static method above to get the roots of the system and user - * preference node trees there are also two convenience methods to access the - * default preference node for a particular package an object is in. These are - * <code>userNodeForPackage()</code> and <code>systemNodeForPackage()</code>. - * Both methods take an Object as an argument so accessing preferences values - * can be as easy as calling <code>Preferences.userNodeForPackage(this)</code>. - * <p> - * Note that if a security manager is installed all static methods check for - * <code>RuntimePermission("preferences")</code>. But if this permission is - * given to the code then it can access and change all (user) preference nodes - * and entries. So you should be carefull not to store to sensitive information - * or make security decissions based on preference values since there is no - * more fine grained control over what preference values can be changed once - * code has been given the correct runtime permission. - * <p> - * XXX - * - * @since 1.4 - * @author Mark Wielaard (mark@klomp.org) - */ -public abstract class Preferences { - - // Static Fields - - /** - * Default PreferencesFactory class used when the system property - * "java.util.prefs.PreferencesFactory" is not set. - * <p> - * XXX - Currently set to MemoryBasedFactory, should be changed - * when FileBasedPreferences backend works. - */ - private static final String defaultFactoryClass - = "gnu.java.util.prefs.MemoryBasedFactory"; - - /** Permission needed to access system or user root. */ - private static final Permission prefsPermission - = new RuntimePermission("preferences"); - - /** - * The preferences factory object that supplies the system and user root. - * Set and returned by the getFactory() method. - */ - private static PreferencesFactory factory; - - /** Maximum node name length. 80 characters. */ - public static final int MAX_NAME_LENGTH = 80; - - /** Maximum entry key length. 80 characters. */ - public static final int MAX_KEY_LENGTH = 80; - - /** Maximum entry value length. 8192 characters. */ - public static final int MAX_VALUE_LENGTH = 8192; - - // Constructors - - /** - * Creates a new Preferences node. Can only be used by subclasses. - * Empty implementation. - */ - protected Preferences() {} - - // Static methods - - /** - * Returns the system preferences root node containing usefull preferences - * for all users. It is save to cache this value since it should always - * return the same preference node. - * - * @return the root system preference node - * @exception SecurityException when a security manager is installed and - * the caller does not have <code>RuntimePermission("preferences")</code>. - */ - public static Preferences systemRoot() throws SecurityException { - // Get the preferences factory and check for permission - PreferencesFactory factory = getFactory(); - - return factory.systemRoot(); - } - - /** - * Returns the user preferences root node containing preferences for the - * the current user. How different users are identified is implementation - * depended. It can be determined by Thread, Access Control Context or - * Subject. - * - * @return the root user preference node - * @exception SecurityException when a security manager is installed and - * the caller does not have <code>RuntimePermission("preferences")</code>. - */ - public static Preferences userRoot() throws SecurityException { - // Get the preferences factory and check for permission - PreferencesFactory factory = getFactory(); - return factory.userRoot(); - } - - /** - * Private helper method for <code>systemRoot()</code> and - * <code>userRoot()</code>. Checks security permission and instantiates the - * correct factory if it has not yet been set. - * <p> - * When the preferences factory has not yet been set this method first - * tries to get the system propery "java.util.prefs.PreferencesFactory" - * and tries to initializes that class. If the system property is not set - * or initialization fails it returns an instance of the default factory - * <code>gnu.java.util.prefs.FileBasedPreferencesFactory</code>. - * - * @return the preferences factory to use - * @exception SecurityException when a security manager is installed and - * the caller does not have <code>RuntimePermission("preferences")</code>. - */ - private static PreferencesFactory getFactory() throws SecurityException { - - // First check for permission - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(prefsPermission); - } - - // Get the factory - if (factory == null) { - // Caller might not have enough permissions - factory = (PreferencesFactory) AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { - PreferencesFactory pf = null; - String className = System.getProperty - ("java.util.prefs.PreferencesFactory"); - if (className != null) { - try { - Class fc = Class.forName(className); - Object o = fc.newInstance(); - pf = (PreferencesFactory) o; - } catch (ClassNotFoundException cnfe) - {/*ignore*/} - catch (InstantiationException ie) - {/*ignore*/} - catch (IllegalAccessException iae) - {/*ignore*/} - catch (ClassCastException cce) - {/*ignore*/} - } - return pf; - } - }); - - // Still no factory? Use our default. - if (factory == null) - { - try - { - Class cls = Class.forName (defaultFactoryClass); - factory = (PreferencesFactory) cls.newInstance(); - } - catch (Exception e) - { - throw new RuntimeException ("Couldn't load default factory" - + " '"+ defaultFactoryClass +"'"); - // XXX - when using 1.4 compatible throwables add cause - } - } - - } - - return factory; - } - - /** - * Returns the system preferences node for the package of an object. - * The package node name of the object is determined by dropping the - * class name of the object of the fully quallified class name and - * replacing all '.' to '/' in the package name. If the class of the - * object has no package then the package node name is "<unnamed>". - * The returened node is <code>systemRoot().node(packageNodeName)</code>. - * - * @param o Object whose default system preference node is requested - * @returns system preferences node that should be used by object o - * @exception SecurityException when a security manager is installed and - * the caller does not have <code>RuntimePermission("preferences")</code>. - */ - public static Preferences systemNodeForPackage(Class c) - throws SecurityException - { - return nodeForPackage(c, systemRoot()); - } - - /** - * Returns the user preferences node for the package of an object. - * The package node name of the object is determined by dropping the - * class name of the object of the fully quallified class name and - * replacing all '.' to '/' in the package name. If the class of the - * object has no package then the package node name is "<unnamed>". - * The returened node is <code>userRoot().node(packageNodeName)</code>. - * - * @param o Object whose default user preference node is requested - * @returns user preferences node that should be used by object o - * @exception SecurityException when a security manager is installed and - * the caller does not have <code>RuntimePermission("preferences")</code>. - */ - public static Preferences userNodeForPackage(Class c) - throws SecurityException - { - return nodeForPackage(c, userRoot()); - } - - /** - * Private helper method for <code>systemNodeForPackage()</code> and - * <code>userNodeForPackage()</code>. Given the correct system or user - * root it returns the correct Preference node for the package node name - * of the given object. - */ - private static Preferences nodeForPackage(Class c, Preferences root) { - // Get the package path - String className = c.getName(); - String packagePath; - int index = className.lastIndexOf('.'); - if(index == -1) { - packagePath = "<unnamed>"; - } else { - packagePath = className.substring(0,index).replace('.','/'); - } - - return root.node(packagePath); - } - - /** - * XXX - */ - public static void importPreferences(InputStream is) - throws InvalidPreferencesFormatException, - IOException - { - PreferencesFactory factory = getFactory(); - NodeReader reader = new NodeReader(is, factory); - reader.importPreferences(); - } - - // abstract methods (identification) - - /** - * Returns the absolute path name of this preference node. - * The absolute path name of a node is the path name of its parent node - * plus a '/' plus its own name. If the node is the root node and has no - * parent then its name is "" and its absolute path name is "/". - */ - public abstract String absolutePath(); - - /** - * Returns true if this node comes from the user preferences tree, false - * if it comes from the system preferences tree. - */ - public abstract boolean isUserNode(); - - /** - * Returns the name of this preferences node. The name of the node cannot - * be null, can be mostly 80 characters and cannot contain any '/' - * characters. The root node has as name "". - */ - public abstract String name(); - - /** - * Returns the String given by - * <code> - * (isUserNode() ? "User":"System") + " Preference Node: " + absolutePath() - * </code> - */ - public abstract String toString(); - - // abstract methods (navigation) - - /** - * Returns all the direct sub nodes of this preferences node. - * Needs access to the backing store to give a meaningfull answer. - * - * @exception BackingStoreException when the backing store cannot be - * reached - * @exception IllegalStateException when this node has been removed - */ - public abstract String[] childrenNames() throws BackingStoreException; - - /** - * Returns a sub node of this preferences node if the given path is - * relative (does not start with a '/') or a sub node of the root - * if the path is absolute (does start with a '/'). - * - * @exception IllegalStateException if this node has been removed - * @exception IllegalArgumentException if the path contains two or more - * consecutive '/' characters, ends with a '/' charactor and is not the - * string "/" (indicating the root node) or any name on the path is more - * then 80 characters long - */ - public abstract Preferences node(String path); - - /** - * Returns true if the node that the path points to exists in memory or - * in the backing store. Otherwise it returns false or an exception is - * thrown. When this node is removed the only valid parameter is the - * empty string (indicating this node), the return value in that case - * will be false. - * - * @exception BackingStoreException when the backing store cannot be - * reached - * @exception IllegalStateException if this node has been removed - * and the path is not the empty string (indicating this node) - * @exception IllegalArgumentException if the path contains two or more - * consecutive '/' characters, ends with a '/' charactor and is not the - * string "/" (indicating the root node) or any name on the path is more - * then 80 characters long - */ - public abstract boolean nodeExists(String path) - throws BackingStoreException; - - /** - * Returns the parent preferences node of this node or null if this is - * the root of the preferences tree. - * - * @exception IllegalStateException if this node has been removed - */ - public abstract Preferences parent(); - - // abstract methods (export) - - /** - * XXX - */ - public abstract void exportNode(OutputStream os) - throws BackingStoreException, - IOException; - - /** - * XXX - */ - public abstract void exportSubtree(OutputStream os) - throws BackingStoreException, - IOException; - - // abstract methods (preference entry manipulation) - - /** - * Returns an (possibly empty) array with all the keys of the preference - * entries of this node. - * - * @exception BackingStoreException when the backing store cannot be - * reached - * @exception IllegalStateException if this node has been removed - */ - public abstract String[] keys() throws BackingStoreException; - - /** - * Returns the value associated with the key in this preferences node. If - * the default value of the key cannot be found in the preferences node - * entries or something goes wrong with the backing store the supplied - * default value is returned. - * - * @exception IllegalArgumentException if key is larger then 80 characters - * @exception IllegalStateException if this node has been removed - * @exception NullPointerException if key is null - */ - public abstract String get(String key, String defaultVal); - - /** - * Convenience method for getting the given entry as a boolean. - * When the string representation of the requested entry is either - * "true" or "false" (ignoring case) then that value is returned, - * otherwise the given default boolean value is returned. - * - * @exception IllegalArgumentException if key is larger then 80 characters - * @exception IllegalStateException if this node has been removed - * @exception NullPointerException if key is null - */ - public abstract boolean getBoolean(String key, boolean defaultVal); - - /** - * Convenience method for getting the given entry as a byte array. - * When the string representation of the requested entry is a valid - * Base64 encoded string (without any other characters, such as newlines) - * then the decoded Base64 string is returned as byte array, - * otherwise the given default byte array value is returned. - * - * @exception IllegalArgumentException if key is larger then 80 characters - * @exception IllegalStateException if this node has been removed - * @exception NullPointerException if key is null - */ - public abstract byte[] getByteArray(String key, byte[] defaultVal); - - /** - * Convenience method for getting the given entry as a double. - * When the string representation of the requested entry can be decoded - * with <code>Double.parseDouble()</code> then that double is returned, - * otherwise the given default double value is returned. - * - * @exception IllegalArgumentException if key is larger then 80 characters - * @exception IllegalStateException if this node has been removed - * @exception NullPointerException if key is null - */ - public abstract double getDouble(String key, double defaultVal); - - /** - * Convenience method for getting the given entry as a float. - * When the string representation of the requested entry can be decoded - * with <code>Float.parseFloat()</code> then that float is returned, - * otherwise the given default float value is returned. - * - * @exception IllegalArgumentException if key is larger then 80 characters - * @exception IllegalStateException if this node has been removed - * @exception NullPointerException if key is null - */ - public abstract float getFloat(String key, float defaultVal); - - /** - * Convenience method for getting the given entry as an integer. - * When the string representation of the requested entry can be decoded - * with <code>Integer.parseInt()</code> then that integer is returned, - * otherwise the given default integer value is returned. - * - * @exception IllegalArgumentException if key is larger then 80 characters - * @exception IllegalStateException if this node has been removed - * @exception NullPointerException if key is null - */ - public abstract int getInt(String key, int defaultVal); - - /** - * Convenience method for getting the given entry as a long. - * When the string representation of the requested entry can be decoded - * with <code>Long.parseLong()</code> then that long is returned, - * otherwise the given default long value is returned. - * - * @exception IllegalArgumentException if key is larger then 80 characters - * @exception IllegalStateException if this node has been removed - * @exception NullPointerException if key is null - */ - public abstract long getLong(String key, long defaultVal); - - /** - * Sets the value of the given preferences entry for this node. - * Key and value cannot be null, the key cannot exceed 80 characters - * and the value cannot exceed 8192 characters. - * <p> - * The result will be immediatly visible in this VM, but may not be - * immediatly written to the backing store. - * - * @exception NullPointerException if either key or value are null - * @exception IllegalArgumentException if either key or value are to large - * @exception IllegalStateException when this node has been removed - */ - public abstract void put(String key, String value); - - /** - * Convenience method for setting the given entry as a boolean. - * The boolean is converted with <code>Boolean.toString(value)</code> - * and then stored in the preference entry as that string. - * - * @exception NullPointerException if key is null - * @exception IllegalArgumentException if the key length is to large - * @exception IllegalStateException when this node has been removed - */ - public abstract void putBoolean(String key, boolean value); - - /** - * Convenience method for setting the given entry as an array of bytes. - * The byte array is converted to a Base64 encoded string - * and then stored in the preference entry as that string. - * <p> - * Note that a byte array encoded as a Base64 string will be about 1.3 - * times larger then the original length of the byte array, which means - * that the byte array may not be larger about 6 KB. - * - * @exception NullPointerException if either key or value are null - * @exception IllegalArgumentException if either key or value are to large - * @exception IllegalStateException when this node has been removed - */ - public abstract void putByteArray(String key, byte[] value); - - /** - * Convenience method for setting the given entry as a double. - * The double is converted with <code>Double.toString(double)</code> - * and then stored in the preference entry as that string. - * - * @exception NullPointerException if the key is null - * @exception IllegalArgumentException if the key length is to large - * @exception IllegalStateException when this node has been removed - */ - public abstract void putDouble(String key, double value); - - /** - * Convenience method for setting the given entry as a float. - * The float is converted with <code>Float.toString(float)</code> - * and then stored in the preference entry as that string. - * - * @exception NullPointerException if the key is null - * @exception IllegalArgumentException if the key length is to large - * @exception IllegalStateException when this node has been removed - */ - public abstract void putFloat(String key, float value); - - /** - * Convenience method for setting the given entry as an integer. - * The integer is converted with <code>Integer.toString(int)</code> - * and then stored in the preference entry as that string. - * - * @exception NullPointerException if the key is null - * @exception IllegalArgumentException if the key length is to large - * @exception IllegalStateException when this node has been removed - */ - public abstract void putInt(String key, int value); - - /** - * Convenience method for setting the given entry as a long. - * The long is converted with <code>Long.toString(long)</code> - * and then stored in the preference entry as that string. - * - * @exception NullPointerException if the key is null - * @exception IllegalArgumentException if the key length is to large - * @exception IllegalStateException when this node has been removed - */ - public abstract void putLong(String key, long value); - - /** - * Removes the preferences entry from this preferences node. - * <p> - * The result will be immediatly visible in this VM, but may not be - * immediatly written to the backing store. - * - * @exception NullPointerException if the key is null - * @exception IllegalArgumentException if the key length is to large - * @exception IllegalStateException when this node has been removed - */ - public abstract void remove(String key); - - // abstract methods (preference node manipulation) - - /** - * Removes all entries from this preferences node. May need access to the - * backing store to get and clear all entries. - * <p> - * The result will be immediatly visible in this VM, but may not be - * immediatly written to the backing store. - * - * @exception BackingStoreException when the backing store cannot be - * reached - * @exception IllegalStateException if this node has been removed - */ - public abstract void clear() throws BackingStoreException; - - /** - * Writes all preference changes on this and any subnode that have not - * yet been written to the backing store. This has no effect on the - * preference entries in this VM, but it makes sure that all changes - * are visible to other programs (other VMs might need to call the - * <code>sync()</code> method to actually see the changes to the backing - * store. - * - * @exception BackingStoreException when the backing store cannot be - * reached - * @exception IllegalStateException if this node has been removed - */ - public abstract void flush() throws BackingStoreException; - - /** - * Writes and reads all preference changes to and from this and any - * subnodes. This makes sure that all local changes are written to the - * backing store and that all changes to the backing store are visible - * in this preference node (and all subnodes). - * - * @exception BackingStoreException when the backing store cannot be - * reached - * @exception IllegalStateException if this node has been removed - */ - public abstract void sync() throws BackingStoreException; - - /** - * Removes this and all subnodes from the backing store and clears all - * entries. After removal this instance will not be useable (except for - * a few methods that don't throw a <code>InvalidStateException</code>), - * even when a new node with the same path name is created this instance - * will not be usable again. The root (system or user) may never be removed. - * <p> - * Note that according to the specification an implementation may delay - * removal of the node from the backing store till the <code>flush()</code> - * method is called. But the <code>flush()</code> method may throw a - * <code>IllegalStateException</code> when the node has been removed. - * So most implementations will actually remove the node and any subnodes - * from the backing store immediatly. - * - * @exception BackingStoreException when the backing store cannot be - * reached - * @exception IllegalStateException if this node has already been removed - * @exception UnsupportedOperationException if this is a root node - */ - public abstract void removeNode() throws BackingStoreException; - - // abstract methods (listeners) - - public abstract void addNodeChangeListener(NodeChangeListener listener); - - public abstract void addPreferenceChangeListener - (PreferenceChangeListener listener); - - public abstract void removeNodeChangeListener(NodeChangeListener listener); - - public abstract void removePreferenceChangeListener - (PreferenceChangeListener listener); -} - diff --git a/libjava/java/util/prefs/PreferencesFactory.java b/libjava/java/util/prefs/PreferencesFactory.java deleted file mode 100644 index f4fe7e37ffe..00000000000 --- a/libjava/java/util/prefs/PreferencesFactory.java +++ /dev/null @@ -1,65 +0,0 @@ -/* PreferencesFactory - Preferences system and user root factory interface - Copyright (C) 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util.prefs; - -/** - * Preferences system and user root factory interface. Defines how to get - * to the system and user root preferences objects. Should be implemented by - * new preferences backends. - * - * @since 1.4 - * @author Mark Wielaard (mark@klomp.org) - */ -public interface PreferencesFactory { - - /** - * Returns the system root preferences node. Should always return the - * same object. - */ - Preferences systemRoot(); - - /** - * Returns the user root preferences node. May return different objects - * depending on the user that called this method. The user may for example - * be determined by the current Thread or the Subject associated with the - * current AccessControllContext. - */ - Preferences userRoot(); - -} diff --git a/libjava/java/util/regex/Matcher.java b/libjava/java/util/regex/Matcher.java deleted file mode 100644 index bd97ace54a8..00000000000 --- a/libjava/java/util/regex/Matcher.java +++ /dev/null @@ -1,301 +0,0 @@ -/* Matcher.java -- Instance of a regular expression applied to a char sequence. - Copyright (C) 2002, 2004 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util.regex; - -import gnu.regexp.REMatch; - -/** - * Instance of a regular expression applied to a char sequence. - * - * @since 1.4 - */ -public final class Matcher -{ - private Pattern pattern; - private CharSequence input; - private int position; - private int appendPosition; - private REMatch match; - - Matcher(Pattern pattern, CharSequence input) - { - this.pattern = pattern; - this.input = input; - } - - /** - * @param sb The target string buffer - * @param replacement The replacement string - * - * @exception IllegalStateException If no match has yet been attempted, - * or if the previous match operation failed - * @exception IndexOutOfBoundsException If the replacement string refers - * to a capturing group that does not exist in the pattern - */ - public Matcher appendReplacement (StringBuffer sb, String replacement) - throws IllegalStateException - { - assertMatchOp(); - sb.append(input.subSequence(appendPosition, - match.getStartIndex()).toString()); - sb.append(match.substituteInto(replacement)); - appendPosition = match.getEndIndex(); - return this; - } - - /** - * @param sb The target string buffer - */ - public StringBuffer appendTail (StringBuffer sb) - { - sb.append(input.subSequence(appendPosition, input.length()).toString()); - return sb; - } - - /** - * @exception IllegalStateException If no match has yet been attempted, - * or if the previous match operation failed - */ - public int end () - throws IllegalStateException - { - assertMatchOp(); - return match.getEndIndex(); - } - - /** - * @param group The index of a capturing group in this matcher's pattern - * - * @exception IllegalStateException If no match has yet been attempted, - * or if the previous match operation failed - * @exception IndexOutOfBoundsException If the replacement string refers - * to a capturing group that does not exist in the pattern - */ - public int end (int group) - throws IllegalStateException - { - assertMatchOp(); - return match.getEndIndex(group); - } - - public boolean find () - { - boolean first = (match == null); - match = pattern.getRE().getMatch(input, position); - if (match != null) - { - int endIndex = match.getEndIndex(); - // Are we stuck at the same position? - if (!first && endIndex == position) - { - match = null; - // Not at the end of the input yet? - if (position < input.length() - 1) - { - position++; - return find(position); - } - else - return false; - } - position = endIndex; - return true; - } - return false; - } - - /** - * @param start The index to start the new pattern matching - * - * @exception IndexOutOfBoundsException If the replacement string refers - * to a capturing group that does not exist in the pattern - */ - public boolean find (int start) - { - match = pattern.getRE().getMatch(input, start); - if (match != null) - { - position = match.getEndIndex(); - return true; - } - return false; - } - - /** - * @exception IllegalStateException If no match has yet been attempted, - * or if the previous match operation failed - */ - public String group () - { - assertMatchOp(); - return match.toString(); - } - - /** - * @param group The index of a capturing group in this matcher's pattern - * - * @exception IllegalStateException If no match has yet been attempted, - * or if the previous match operation failed - * @exception IndexOutOfBoundsException If the replacement string refers - * to a capturing group that does not exist in the pattern - */ - public String group (int group) - throws IllegalStateException - { - assertMatchOp(); - return match.toString(group); - } - - /** - * @param replacement The replacement string - */ - public String replaceFirst (String replacement) - { - reset(); - // Semantics might not quite match - return pattern.getRE().substitute(input, replacement, position); - } - - /** - * @param replacement The replacement string - */ - public String replaceAll (String replacement) - { - reset(); - return pattern.getRE().substituteAll(input, replacement, position); - } - - public int groupCount () - { - return pattern.getRE().getNumSubs(); - } - - public boolean lookingAt () - { - match = pattern.getRE().getMatch(input, 0); - if (match != null) - { - if (match.getStartIndex() == 0) - { - position = match.getEndIndex(); - return true; - } - match = null; - } - return false; - } - - /** - * Attempts to match the entire input sequence against the pattern. - * - * If the match succeeds then more information can be obtained via the - * start, end, and group methods. - * - * @see #start - * @see #end - * @see #group - */ - public boolean matches () - { - if (lookingAt()) - { - if (position == input.length()) - return true; - match = null; - } - return false; - } - - /** - * Returns the Pattern that is interpreted by this Matcher - */ - public Pattern pattern () - { - return pattern; - } - - public Matcher reset () - { - position = 0; - match = null; - return this; - } - - /** - * @param input The new input character sequence - */ - public Matcher reset (CharSequence input) - { - this.input = input; - return reset(); - } - - /** - * @param group The index of a capturing group in this matcher's pattern - * - * @exception IllegalStateException If no match has yet been attempted, - * or if the previous match operation failed - */ - public int start () - throws IllegalStateException - { - assertMatchOp(); - return match.getStartIndex(); - } - - /** - * @param group The index of a capturing group in this matcher's pattern - * - * @exception IllegalStateException If no match has yet been attempted, - * or if the previous match operation failed - * @exception IndexOutOfBoundsException If the replacement string refers - * to a capturing group that does not exist in the pattern - */ - public int start (int group) - throws IllegalStateException - { - assertMatchOp(); - return match.getStartIndex(group); - } - - private void assertMatchOp() - { - if (match == null) throw new IllegalStateException(); - } -} diff --git a/libjava/java/util/regex/Pattern.java b/libjava/java/util/regex/Pattern.java deleted file mode 100644 index ddd0c257800..00000000000 --- a/libjava/java/util/regex/Pattern.java +++ /dev/null @@ -1,253 +0,0 @@ -/* Pattern.java -- Compiled regular expression ready to be applied. - Copyright (C) 2002, 2004 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package java.util.regex; - -import gnu.regexp.RE; -import gnu.regexp.REException; -import gnu.regexp.RESyntax; - -import java.io.Serializable; -import java.util.ArrayList; - - -/** - * Compiled regular expression ready to be applied. - * - * @since 1.4 - */ -public final class Pattern implements Serializable -{ - private static final long serialVersionUID = 5073258162644648461L; - - public static final int CANON_EQ = 128; - public static final int CASE_INSENSITIVE = 2; - public static final int COMMENTS = 4; - public static final int DOTALL = 32; - public static final int MULTILINE = 8; - public static final int UNICODE_CASE = 64; - public static final int UNIX_LINES = 1; - - private final String regex; - private final int flags; - - private final RE re; - - private Pattern (String regex, int flags) - throws PatternSyntaxException - { - this.regex = regex; - this.flags = flags; - - int gnuFlags = 0; - if ((flags & CASE_INSENSITIVE) != 0) - gnuFlags |= RE.REG_ICASE; - if ((flags & MULTILINE) != 0) - gnuFlags |= RE.REG_MULTILINE; - if ((flags & DOTALL) != 0) - gnuFlags |= RE.REG_DOT_NEWLINE; - // not yet supported: - // if ((flags & UNICODE_CASE) != 0) gnuFlags = - // if ((flags & CANON_EQ) != 0) gnuFlags = - - RESyntax syntax = RESyntax.RE_SYNTAX_JAVA_1_4; - if ((flags & UNIX_LINES) != 0) - { - // Use a syntax set with \n for linefeeds? - syntax = new RESyntax(syntax); - syntax.setLineSeparator("\n"); - } - - if ((flags & COMMENTS) != 0) - { - // Use a syntax with support for comments? - } - - try - { - this.re = new RE(regex, gnuFlags, syntax); - } - catch (REException e) - { - throw new PatternSyntaxException(e.getMessage(), - regex, e.getPosition()); - } - } - - // package private accessor method - RE getRE() - { - return re; - } - - /** - * @param regex The regular expression - * - * @exception PatternSyntaxException If the expression's syntax is invalid - */ - public static Pattern compile (String regex) - throws PatternSyntaxException - { - return compile(regex, 0); - } - - /** - * @param regex The regular expression - * @param flags The match flags, a bit mask - * - * @exception PatternSyntaxException If the expression's syntax is invalid - * @exception IllegalArgumentException If bit values other than those - * corresponding to the defined match flags are set in flags - */ - public static Pattern compile (String regex, int flags) - throws PatternSyntaxException - { - // FIXME: check which flags are really accepted - if ((flags & ~0xEF) != 0) - throw new IllegalArgumentException (); - - return new Pattern (regex, flags); - } - - public int flags () - { - return this.flags; - } - - /** - * @param regex The regular expression - * @param input The character sequence to be matched - * - * @exception PatternSyntaxException If the expression's syntax is invalid - */ - public static boolean matches (String regex, CharSequence input) - { - return compile(regex).matcher(input).matches(); - } - - /** - * @param input The character sequence to be matched - */ - public Matcher matcher (CharSequence input) - { - return new Matcher(this, input); - } - - /** - * @param input The character sequence to be matched - */ - public String[] split (CharSequence input) - { - return split(input, 0); - } - - /** - * @param input The character sequence to be matched - * @param limit The result threshold - */ - public String[] split (CharSequence input, int limit) - { - Matcher matcher = new Matcher(this, input); - ArrayList list = new ArrayList(); - int empties = 0; - int count = 0; - int start = 0; - int end; - boolean matched; - - while (matched = matcher.find() && (limit <= 0 || count < limit - 1)) - { - ++count; - end = matcher.start(); - if (start == end) - empties++; - else - { - while (empties > 0) - { - list.add(""); - empties--; - } - - String text = input.subSequence(start, end).toString(); - list.add(text); - } - start = matcher.end(); - } - - // We matched nothing. - if (!matched && count == 0) - return new String[] { input.toString() }; - - // Is the last token empty? - boolean emptyLast = (start == input.length()); - - // Can/Must we add empties or an extra last token at the end? - if (list.size() < limit || limit < 0 || (limit == 0 && !emptyLast)) - { - if (limit > list.size()) - { - int max = limit - list.size(); - empties = (empties > max) ? max : empties; - } - while (empties > 0) - { - list.add(""); - empties--; - } - } - - // last token at end - if (limit != 0 || (limit == 0 && !emptyLast)) - { - String t = input.subSequence(start, input.length()).toString(); - if ("".equals(t) && limit == 0) - ; // Don't add. - else - list.add(t); - } - - String[] output = new String [list.size()]; - list.toArray(output); - return output; - } - - public String pattern () - { - return regex; - } -} diff --git a/libjava/java/util/regex/PatternSyntaxException.java b/libjava/java/util/regex/PatternSyntaxException.java deleted file mode 100644 index 0c80e119c37..00000000000 --- a/libjava/java/util/regex/PatternSyntaxException.java +++ /dev/null @@ -1,132 +0,0 @@ -/* PatternSyntaxException - Indicates illegal pattern for regular expression. - Copyright (C) 2002 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package java.util.regex; - -/** - * Indicates illegal pattern for regular expression. - * Includes state to inspect the pattern and what and where the expression - * was not valid regular expression. - */ -public class PatternSyntaxException extends IllegalArgumentException -{ - private static final long serialVersionUID = -3864639126226059218L; - - /** - * Human readable escription of the syntax error. - */ - private final String desc; - - /** - * The original pattern that contained the syntax error. - */ - private final String pattern; - - /** - * Index of the first character in the String that was probably invalid, - * or -1 when unknown. - */ - private final int index; - - /** - * Creates a new PatternSyntaxException. - * - * @param description Human readable escription of the syntax error. - * @param pattern The original pattern that contained the syntax error. - * @param index Index of the first character in the String that was - * probably invalid, or -1 when unknown. - */ - public PatternSyntaxException(String description, - String pattern, - int index) - { - super(description); - this.desc = description; - this.pattern = pattern; - this.index = index; - } - - /** - * Returns a human readable escription of the syntax error. - */ - public String getDescription() - { - return desc; - } - - /** - * Returns the original pattern that contained the syntax error. - */ - public String getPattern() - { - return pattern; - } - - /** - * Returns the index of the first character in the String that was probably - * invalid, or -1 when unknown. - */ - public int getIndex() - { - return index; - } - - /** - * Returns a string containing a line with the description, a line with - * the original pattern and a line indicating with a ^ which character is - * probably the first invalid character in the pattern if the index is not - * negative. - */ - public String getMessage() - { - String lineSep = System.getProperty("line.separator"); - StringBuffer sb = new StringBuffer(desc); - sb.append(lineSep); - sb.append('\t'); - sb.append(pattern); - if (index != -1) - { - sb.append(lineSep); - sb.append('\t'); - for (int i=0; i<index; i++) - sb.append(' '); - sb.append('^'); - } - return sb.toString(); - } - -} diff --git a/libjava/java/util/zip/Adler32.java b/libjava/java/util/zip/Adler32.java deleted file mode 100644 index 7c411384057..00000000000 --- a/libjava/java/util/zip/Adler32.java +++ /dev/null @@ -1,205 +0,0 @@ -/* Adler32.java - Computes Adler32 data checksum of a data stream - Copyright (C) 1999, 2000, 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package java.util.zip; - -/* - * Written using on-line Java Platform 1.2 API Specification, as well - * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998). - * The actual Adler32 algorithm is taken from RFC 1950. - * Status: Believed complete and correct. - */ - -/** - * Computes Adler32 checksum for a stream of data. An Adler32 - * checksum is not as reliable as a CRC32 checksum, but a lot faster to - * compute. - *<p> - * The specification for Adler32 may be found in RFC 1950. - * (ZLIB Compressed Data Format Specification version 3.3) - *<p> - *<p> - * From that document: - *<p> - * "ADLER32 (Adler-32 checksum) - * This contains a checksum value of the uncompressed data - * (excluding any dictionary data) computed according to Adler-32 - * algorithm. This algorithm is a 32-bit extension and improvement - * of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073 - * standard. - *<p> - * Adler-32 is composed of two sums accumulated per byte: s1 is - * the sum of all bytes, s2 is the sum of all s1 values. Both sums - * are done modulo 65521. s1 is initialized to 1, s2 to zero. The - * Adler-32 checksum is stored as s2*65536 + s1 in most- - * significant-byte first (network) order." - *<p> - * "8.2. The Adler-32 algorithm - *<p> - * The Adler-32 algorithm is much faster than the CRC32 algorithm yet - * still provides an extremely low probability of undetected errors. - *<p> - * The modulo on unsigned long accumulators can be delayed for 5552 - * bytes, so the modulo operation time is negligible. If the bytes - * are a, b, c, the second sum is 3a + 2b + c + 3, and so is position - * and order sensitive, unlike the first sum, which is just a - * checksum. That 65521 is prime is important to avoid a possible - * large class of two-byte errors that leave the check unchanged. - * (The Fletcher checksum uses 255, which is not prime and which also - * makes the Fletcher check insensitive to single byte changes 0 <-> - * 255.) - *<p> - * The sum s1 is initialized to 1 instead of zero to make the length - * of the sequence part of s2, so that the length does not have to be - * checked separately. (Any sequence of zeroes has a Fletcher - * checksum of zero.)" - * - * @author John Leuner, Per Bothner - * @since JDK 1.1 - * - * @see InflaterInputStream - * @see DeflaterOutputStream - */ -public class Adler32 implements Checksum -{ - - /** largest prime smaller than 65536 */ - private static final int BASE = 65521; - - private int checksum; //we do all in int. - - //Note that java doesn't have unsigned integers, - //so we have to be careful with what arithmetic - //we do. We return the checksum as a long to - //avoid sign confusion. - - /** - * Creates a new instance of the <code>Adler32</code> class. - * The checksum starts off with a value of 1. - */ - public Adler32 () - { - reset(); - } - - /** - * Resets the Adler32 checksum to the initial value. - */ - public void reset () - { - checksum = 1; //Initialize to 1 - } - - /** - * Updates the checksum with the byte b. - * - * @param bval the data value to add. The high byte of the int is ignored. - */ - public void update (int bval) - { - //We could make a length 1 byte array and call update again, but I - //would rather not have that overhead - int s1 = checksum & 0xffff; - int s2 = checksum >>> 16; - - s1 = (s1 + (bval & 0xFF)) % BASE; - s2 = (s1 + s2) % BASE; - - checksum = (s2 << 16) + s1; - } - - /** - * Updates the checksum with the bytes taken from the array. - * - * @param buffer an array of bytes - */ - public void update (byte[] buffer) - { - update(buffer, 0, buffer.length); - } - - /** - * Updates the checksum with the bytes taken from the array. - * - * @param buf an array of bytes - * @param off the start of the data used for this update - * @param len the number of bytes to use for this update - */ - public void update (byte[] buf, int off, int len) - { - //(By Per Bothner) - int s1 = checksum & 0xffff; - int s2 = checksum >>> 16; - - while (len > 0) - { - // We can defer the modulo operation: - // s1 maximally grows from 65521 to 65521 + 255 * 3800 - // s2 maximally grows by 3800 * median(s1) = 2090079800 < 2^31 - int n = 3800; - if (n > len) - n = len; - len -= n; - while (--n >= 0) - { - s1 = s1 + (buf[off++] & 0xFF); - s2 = s2 + s1; - } - s1 %= BASE; - s2 %= BASE; - } - - /*Old implementation, borrowed from somewhere: - int n; - - while (len-- > 0) { - - s1 = (s1 + (bs[offset++] & 0xff)) % BASE; - s2 = (s2 + s1) % BASE; - }*/ - - checksum = (s2 << 16) | s1; - } - - /** - * Returns the Adler32 data checksum computed so far. - */ - public long getValue() - { - return (long) checksum & 0xffffffffL; - } -} diff --git a/libjava/java/util/zip/CRC32.java b/libjava/java/util/zip/CRC32.java deleted file mode 100644 index 1c2b3973852..00000000000 --- a/libjava/java/util/zip/CRC32.java +++ /dev/null @@ -1,132 +0,0 @@ -/* CRC32.java - Computes CRC32 data checksum of a data stream - Copyright (C) 1999. 2000, 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package java.util.zip; - -/* - * Written using on-line Java Platform 1.2 API Specification, as well - * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998). - * The actual CRC32 algorithm is taken from RFC 1952. - * Status: Believed complete and correct. - */ - -/** - * Computes CRC32 data checksum of a data stream. - * The actual CRC32 algorithm is described in RFC 1952 - * (GZIP file format specification version 4.3). - * Can be used to get the CRC32 over a stream if used with checked input/output - * streams. - * - * @see InflaterInputStream - * @see DeflaterOutputStream - * - * @author Per Bothner - * @date April 1, 1999. - */ -public class CRC32 implements Checksum -{ - /** The crc data checksum so far. */ - private int crc = 0; - - /** The fast CRC table. Computed once when the CRC32 class is loaded. */ - private static int[] crc_table = make_crc_table(); - - /** Make the table for a fast CRC. */ - private static int[] make_crc_table () - { - int[] crc_table = new int[256]; - for (int n = 0; n < 256; n++) - { - int c = n; - for (int k = 8; --k >= 0; ) - { - if ((c & 1) != 0) - c = 0xedb88320 ^ (c >>> 1); - else - c = c >>> 1; - } - crc_table[n] = c; - } - return crc_table; - } - - /** - * Returns the CRC32 data checksum computed so far. - */ - public long getValue () - { - return (long) crc & 0xffffffffL; - } - - /** - * Resets the CRC32 data checksum as if no update was ever called. - */ - public void reset () { crc = 0; } - - /** - * Updates the checksum with the int bval. - * - * @param bval (the byte is taken as the lower 8 bits of bval) - */ - - public void update (int bval) - { - int c = ~crc; - c = crc_table[(c ^ bval) & 0xff] ^ (c >>> 8); - crc = ~c; - } - - /** - * Adds the byte array to the data checksum. - * - * @param buf the buffer which contains the data - * @param off the offset in the buffer where the data starts - * @param len the length of the data - */ - public void update (byte[] buf, int off, int len) - { - int c = ~crc; - while (--len >= 0) - c = crc_table[(c ^ buf[off++]) & 0xff] ^ (c >>> 8); - crc = ~c; - } - - /** - * Adds the complete byte array to the data checksum. - */ - public void update (byte[] buf) { update(buf, 0, buf.length); } -} diff --git a/libjava/java/util/zip/CheckedInputStream.java b/libjava/java/util/zip/CheckedInputStream.java deleted file mode 100644 index d743fbb2447..00000000000 --- a/libjava/java/util/zip/CheckedInputStream.java +++ /dev/null @@ -1,135 +0,0 @@ -/* CheckedInputStream.java - Compute checksum of data being read - Copyright (C) 1999, 2000, 2004 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util.zip; - -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; - -/* Written using on-line Java Platform 1.2 API Specification - * and JCL book. - * Believed complete and correct. - */ - -/** - * InputStream that computes a checksum of the data being read using a - * supplied Checksum object. - * - * @see Checksum - * - * @author Tom Tromey - * @date May 17, 1999 - */ -public class CheckedInputStream extends FilterInputStream -{ - /** - * Creates a new CheckInputStream on top of the supplied OutputStream - * using the supplied Checksum. - */ - public CheckedInputStream (InputStream in, Checksum sum) - { - super (in); - this.sum = sum; - } - - /** - * Returns the Checksum object used. To get the data checksum computed so - * far call <code>getChecksum.getValue()</code>. - */ - public Checksum getChecksum () - { - return sum; - } - - /** - * Reads one byte, updates the checksum and returns the read byte - * (or -1 when the end of file was reached). - */ - public int read () throws IOException - { - int x = in.read(); - if (x != -1) - sum.update(x); - return x; - } - - /** - * Reads at most len bytes in the supplied buffer and updates the checksum - * with it. Returns the number of bytes actually read or -1 when the end - * of file was reached. - */ - public int read (byte[] buf, int off, int len) throws IOException - { - int r = in.read(buf, off, len); - if (r != -1) - sum.update(buf, off, r); - return r; - } - - /** - * Skips n bytes by reading them in a temporary buffer and updating the - * the checksum with that buffer. Returns the actual number of bytes skiped - * which can be less then requested when the end of file is reached. - */ - public long skip (long n) throws IOException - { - if (n == 0) - return 0; - - int min = (int) Math.min(n, 1024); - byte[] buf = new byte[min]; - - long s = 0; - while (n > 0) - { - int r = in.read(buf, 0, min); - if (r == -1) - break; - n -= r; - s += r; - min = (int) Math.min(n, 1024); - sum.update(buf, 0, r); - } - - return s; - } - - /** The checksum object. */ - private Checksum sum; -} diff --git a/libjava/java/util/zip/CheckedOutputStream.java b/libjava/java/util/zip/CheckedOutputStream.java deleted file mode 100644 index a3c19292fae..00000000000 --- a/libjava/java/util/zip/CheckedOutputStream.java +++ /dev/null @@ -1,100 +0,0 @@ -/* CheckedOutputStream.java - Compute checksum of data being written. - Copyright (C) 1999, 2000 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util.zip; - -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -/* Written using on-line Java Platform 1.2 API Specification - * and JCL book. - * Believed complete and correct. - */ - -/** - * OutputStream that computes a checksum of data being written using a - * supplied Checksum object. - * - * @see Checksum - * - * @author Tom Tromey - * @date May 17, 1999 - */ -public class CheckedOutputStream extends FilterOutputStream -{ - /** - * Creates a new CheckInputStream on top of the supplied OutputStream - * using the supplied Checksum. - */ - public CheckedOutputStream (OutputStream out, Checksum cksum) - { - super (out); - this.sum = cksum; - } - - /** - * Returns the Checksum object used. To get the data checksum computed so - * far call <code>getChecksum.getValue()</code>. - */ - public Checksum getChecksum () - { - return sum; - } - - /** - * Writes one byte to the OutputStream and updates the Checksum. - */ - public void write (int bval) throws IOException - { - out.write(bval); - sum.update(bval); - } - - /** - * Writes the byte array to the OutputStream and updates the Checksum. - */ - public void write (byte[] buf, int off, int len) throws IOException - { - out.write(buf, off, len); - sum.update(buf, off, len); - } - - /** The checksum object. */ - private Checksum sum; -} diff --git a/libjava/java/util/zip/Checksum.java b/libjava/java/util/zip/Checksum.java deleted file mode 100644 index 3342ba3a609..00000000000 --- a/libjava/java/util/zip/Checksum.java +++ /dev/null @@ -1,86 +0,0 @@ -/* Checksum.java - Interface to compute a data checksum - Copyright (C) 1999, 2000, 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package java.util.zip; - -/* - * Written using on-line Java Platform 1.2 API Specification, as well - * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998). - * Status: Believed complete and correct. - */ - -/** - * Interface to compute a data checksum used by checked input/output streams. - * A data checksum can be updated by one byte or with a byte array. After each - * update the value of the current checksum can be returned by calling - * <code>getValue</code>. The complete checksum object can also be reset - * so it can be used again with new data. - * - * @see CheckedInputStream - * @see CheckedOutputStream - * - * @author Per Bothner - * @author Jochen Hoenicke - */ -public interface Checksum -{ - /** - * Returns the data checksum computed so far. - */ - long getValue(); - - /** - * Resets the data checksum as if no update was ever called. - */ - void reset(); - - /** - * Adds one byte to the data checksum. - * - * @param bval the data value to add. The high byte of the int is ignored. - */ - void update (int bval); - - /** - * Adds the byte array to the data checksum. - * - * @param buf the buffer which contains the data - * @param off the offset in the buffer where the data starts - * @param len the length of the data - */ - void update (byte[] buf, int off, int len); -} diff --git a/libjava/java/util/zip/DataFormatException.java b/libjava/java/util/zip/DataFormatException.java deleted file mode 100644 index dc5b10dec90..00000000000 --- a/libjava/java/util/zip/DataFormatException.java +++ /dev/null @@ -1,71 +0,0 @@ -/* DataformatException.java -- thrown when compressed data is corrupt - Copyright (C) 1999, 2000, 2001, 2002 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package java.util.zip; - -/** - * Exception thrown when compressed data is corrupt. - * - * @author Tom Tromey - * @author John Leuner - * @since 1.1 - * @status updated to 1.4 - */ -public class DataFormatException extends Exception -{ - /** - * Compatible with JDK 1.1+. - */ - private static final long serialVersionUID = 2219632870893641452L; - - /** - * Create an exception without a message. - */ - public DataFormatException() - { - } - - /** - * Create an exception with a message. - * - * @param msg the message - */ - public DataFormatException(String msg) - { - super(msg); - } -} diff --git a/libjava/java/util/zip/ZipConstants.java b/libjava/java/util/zip/ZipConstants.java deleted file mode 100644 index 952a44def4c..00000000000 --- a/libjava/java/util/zip/ZipConstants.java +++ /dev/null @@ -1,97 +0,0 @@ -/* java.util.zip.ZipConstants - Copyright (C) 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package java.util.zip; - -interface ZipConstants -{ - /* The local file header */ - int LOCHDR = 30; - int LOCSIG = 'P'|('K'<<8)|(3<<16)|(4<<24); - - int LOCVER = 4; - int LOCFLG = 6; - int LOCHOW = 8; - int LOCTIM = 10; - int LOCCRC = 14; - int LOCSIZ = 18; - int LOCLEN = 22; - int LOCNAM = 26; - int LOCEXT = 28; - - /* The Data descriptor */ - int EXTSIG = 'P'|('K'<<8)|(7<<16)|(8<<24); - int EXTHDR = 16; - - int EXTCRC = 4; - int EXTSIZ = 8; - int EXTLEN = 12; - - /* The central directory file header */ - int CENSIG = 'P'|('K'<<8)|(1<<16)|(2<<24); - int CENHDR = 46; - - int CENVEM = 4; - int CENVER = 6; - int CENFLG = 8; - int CENHOW = 10; - int CENTIM = 12; - int CENCRC = 16; - int CENSIZ = 20; - int CENLEN = 24; - int CENNAM = 28; - int CENEXT = 30; - int CENCOM = 32; - int CENDSK = 34; - int CENATT = 36; - int CENATX = 38; - int CENOFF = 42; - - /* The entries in the end of central directory */ - int ENDSIG = 'P'|('K'<<8)|(5<<16)|(6<<24); - int ENDHDR = 22; - - /* The following two fields are missing in SUN JDK */ - int ENDNRD = 4; - int ENDDCD = 6; - int ENDSUB = 8; - int ENDTOT = 10; - int ENDSIZ = 12; - int ENDOFF = 16; - int ENDCOM = 20; -} - diff --git a/libjava/java/util/zip/ZipException.java b/libjava/java/util/zip/ZipException.java deleted file mode 100644 index c5bfc1e7c39..00000000000 --- a/libjava/java/util/zip/ZipException.java +++ /dev/null @@ -1,72 +0,0 @@ -/* ZipException.java - exception representing a zip related error - Copyright (C) 1998, 1999, 2000, 2001, 2002 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package java.util.zip; - -import java.io.IOException; - -/** - * Thrown during the creation or input of a zip file. - * - * @author Jochen Hoenicke - * @author Per Bothner - * @status updated to 1.4 - */ -public class ZipException extends IOException -{ - /** - * Compatible with JDK 1.0+. - */ - private static final long serialVersionUID = 8000196834066748623L; - - /** - * Create an exception without a message. - */ - public ZipException() - { - } - - /** - * Create an exception with a message. - * - * @param msg the message - */ - public ZipException (String msg) - { - super(msg); - } -} diff --git a/libjava/java/util/zip/ZipInputStream.java b/libjava/java/util/zip/ZipInputStream.java deleted file mode 100644 index 5732523238e..00000000000 --- a/libjava/java/util/zip/ZipInputStream.java +++ /dev/null @@ -1,371 +0,0 @@ -/* ZipInputStream.java -- - Copyright (C) 2001, 2002, 2003, 2004 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util.zip; - -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; - -/** - * This is a FilterInputStream that reads the files in an zip archive - * one after another. It has a special method to get the zip entry of - * the next file. The zip entry contains information about the file name - * size, compressed size, CRC, etc. - * - * It includes support for STORED and DEFLATED entries. - * - * @author Jochen Hoenicke - */ -public class ZipInputStream extends InflaterInputStream implements ZipConstants -{ - private CRC32 crc = new CRC32(); - private ZipEntry entry = null; - - private int csize; - private int size; - private int method; - private int flags; - private int avail; - private boolean entryAtEOF; - - /** - * Creates a new Zip input stream, reading a zip archive. - */ - public ZipInputStream(InputStream in) - { - super(in, new Inflater(true)); - } - - private void fillBuf() throws IOException - { - avail = len = in.read(buf, 0, buf.length); - } - - private int readBuf(byte[] out, int offset, int length) throws IOException - { - if (avail <= 0) - { - fillBuf(); - if (avail <= 0) - return -1; - } - if (length > avail) - length = avail; - System.arraycopy(buf, len - avail, out, offset, length); - avail -= length; - return length; - } - - private void readFully(byte[] out) throws IOException - { - int off = 0; - int len = out.length; - while (len > 0) - { - int count = readBuf(out, off, len); - if (count == -1) - throw new EOFException(); - off += count; - len -= count; - } - } - - private int readLeByte() throws IOException - { - if (avail <= 0) - { - fillBuf(); - if (avail <= 0) - throw new ZipException("EOF in header"); - } - return buf[len - avail--] & 0xff; - } - - /** - * Read an unsigned short in little endian byte order. - */ - private int readLeShort() throws IOException - { - return readLeByte() | (readLeByte() << 8); - } - - /** - * Read an int in little endian byte order. - */ - private int readLeInt() throws IOException - { - return readLeShort() | (readLeShort() << 16); - } - - /** - * Open the next entry from the zip archive, and return its description. - * If the previous entry wasn't closed, this method will close it. - */ - public ZipEntry getNextEntry() throws IOException - { - if (crc == null) - throw new IOException("Stream closed."); - if (entry != null) - closeEntry(); - - int header = readLeInt(); - if (header == CENSIG) - { - /* Central Header reached. */ - close(); - return null; - } - if (header != LOCSIG) - throw new ZipException("Wrong Local header signature: " - + Integer.toHexString(header)); - /* skip version */ - readLeShort(); - flags = readLeShort(); - method = readLeShort(); - int dostime = readLeInt(); - int crc = readLeInt(); - csize = readLeInt(); - size = readLeInt(); - int nameLen = readLeShort(); - int extraLen = readLeShort(); - - if (method == ZipOutputStream.STORED && csize != size) - throw new ZipException("Stored, but compressed != uncompressed"); - - - byte[] buffer = new byte[nameLen]; - readFully(buffer); - String name = new String(buffer); - - entry = createZipEntry(name); - entryAtEOF = false; - entry.setMethod(method); - if ((flags & 8) == 0) - { - entry.setCrc(crc & 0xffffffffL); - entry.setSize(size & 0xffffffffL); - entry.setCompressedSize(csize & 0xffffffffL); - } - entry.setDOSTime(dostime); - if (extraLen > 0) - { - byte[] extra = new byte[extraLen]; - readFully(extra); - entry.setExtra(extra); - } - - if (method == ZipOutputStream.DEFLATED && avail > 0) - { - System.arraycopy(buf, len - avail, buf, 0, avail); - len = avail; - avail = 0; - inf.setInput(buf, 0, len); - } - return entry; - } - - private void readDataDescr() throws IOException - { - if (readLeInt() != EXTSIG) - throw new ZipException("Data descriptor signature not found"); - entry.setCrc(readLeInt() & 0xffffffffL); - csize = readLeInt(); - size = readLeInt(); - entry.setSize(size & 0xffffffffL); - entry.setCompressedSize(csize & 0xffffffffL); - } - - /** - * Closes the current zip entry and moves to the next one. - */ - public void closeEntry() throws IOException - { - if (crc == null) - throw new IOException("Stream closed."); - if (entry == null) - return; - - if (method == ZipOutputStream.DEFLATED) - { - if ((flags & 8) != 0) - { - /* We don't know how much we must skip, read until end. */ - byte[] tmp = new byte[2048]; - while (read(tmp) > 0) - ; - /* read will close this entry */ - return; - } - csize -= inf.getTotalIn(); - avail = inf.getRemaining(); - } - - if (avail > csize && csize >= 0) - avail -= csize; - else - { - csize -= avail; - avail = 0; - while (csize != 0) - { - long skipped = in.skip(csize & 0xffffffffL); - if (skipped <= 0) - throw new ZipException("zip archive ends early."); - csize -= skipped; - } - } - - size = 0; - crc.reset(); - if (method == ZipOutputStream.DEFLATED) - inf.reset(); - entry = null; - entryAtEOF = true; - } - - public int available() throws IOException - { - return entryAtEOF ? 0 : 1; - } - - /** - * Reads a byte from the current zip entry. - * @return the byte or -1 on EOF. - * @exception IOException if a i/o error occured. - * @exception ZipException if the deflated stream is corrupted. - */ - public int read() throws IOException - { - byte[] b = new byte[1]; - if (read(b, 0, 1) <= 0) - return -1; - return b[0] & 0xff; - } - - /** - * Reads a block of bytes from the current zip entry. - * @return the number of bytes read (may be smaller, even before - * EOF), or -1 on EOF. - * @exception IOException if a i/o error occured. - * @exception ZipException if the deflated stream is corrupted. - */ - public int read(byte[] b, int off, int len) throws IOException - { - if (len == 0) - return 0; - if (crc == null) - throw new IOException("Stream closed."); - if (entry == null) - return -1; - boolean finished = false; - switch (method) - { - case ZipOutputStream.DEFLATED: - len = super.read(b, off, len); - if (len < 0) - { - if (!inf.finished()) - throw new ZipException("Inflater not finished!?"); - avail = inf.getRemaining(); - if ((flags & 8) != 0) - readDataDescr(); - - if (inf.getTotalIn() != csize - || inf.getTotalOut() != size) - throw new ZipException("size mismatch: "+csize+";"+size+" <-> "+inf.getTotalIn()+";"+inf.getTotalOut()); - inf.reset(); - finished = true; - } - break; - - case ZipOutputStream.STORED: - - if (len > csize && csize >= 0) - len = csize; - - len = readBuf(b, off, len); - if (len > 0) - { - csize -= len; - size -= len; - } - - if (csize == 0) - finished = true; - else if (len < 0) - throw new ZipException("EOF in stored block"); - break; - } - - if (len > 0) - crc.update(b, off, len); - - if (finished) - { - if ((crc.getValue() & 0xffffffffL) != entry.getCrc()) - throw new ZipException("CRC mismatch"); - crc.reset(); - entry = null; - entryAtEOF = true; - } - return len; - } - - /** - * Closes the zip file. - * @exception IOException if a i/o error occured. - */ - public void close() throws IOException - { - super.close(); - crc = null; - entry = null; - entryAtEOF = true; - } - - /** - * Creates a new zip entry for the given name. This is equivalent - * to new ZipEntry(name). - * @param name the name of the zip entry. - */ - protected ZipEntry createZipEntry(String name) - { - return new ZipEntry(name); - } -} diff --git a/libjava/java/util/zip/ZipOutputStream.java b/libjava/java/util/zip/ZipOutputStream.java deleted file mode 100644 index 5699ff046f5..00000000000 --- a/libjava/java/util/zip/ZipOutputStream.java +++ /dev/null @@ -1,399 +0,0 @@ -/* ZipOutputStream.java -- - Copyright (C) 2001, 2004 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., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util.zip; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.Enumeration; -import java.util.Vector; - -/** - * This is a FilterOutputStream that writes the files into a zip - * archive one after another. It has a special method to start a new - * zip entry. The zip entries contains information about the file name - * size, compressed size, CRC, etc. - * - * It includes support for STORED and DEFLATED entries. - * - * This class is not thread safe. - * - * @author Jochen Hoenicke - */ -public class ZipOutputStream extends DeflaterOutputStream implements ZipConstants -{ - private Vector entries = new Vector(); - private CRC32 crc = new CRC32(); - private ZipEntry curEntry = null; - - private int curMethod; - private int size; - private int offset = 0; - - private byte[] zipComment = new byte[0]; - private int defaultMethod = DEFLATED; - - /** - * Our Zip version is hard coded to 1.0 resp. 2.0 - */ - private static final int ZIP_STORED_VERSION = 10; - private static final int ZIP_DEFLATED_VERSION = 20; - - /** - * Compression method. This method doesn't compress at all. - */ - public static final int STORED = 0; - - /** - * Compression method. This method uses the Deflater. - */ - public static final int DEFLATED = 8; - - /** - * Creates a new Zip output stream, writing a zip archive. - * @param out the output stream to which the zip archive is written. - */ - public ZipOutputStream(OutputStream out) - { - super(out, new Deflater(Deflater.DEFAULT_COMPRESSION, true)); - } - - /** - * Set the zip file comment. - * @param comment the comment. - * @exception IllegalArgumentException if encoding of comment is - * longer than 0xffff bytes. - */ - public void setComment(String comment) - { - byte[] commentBytes; - commentBytes = comment.getBytes(); - if (commentBytes.length > 0xffff) - throw new IllegalArgumentException("Comment too long."); - zipComment = commentBytes; - } - - /** - * Sets default compression method. If the Zip entry specifies - * another method its method takes precedence. - * @param method the method. - * @exception IllegalArgumentException if method is not supported. - * @see #STORED - * @see #DEFLATED - */ - public void setMethod(int method) - { - if (method != STORED && method != DEFLATED) - throw new IllegalArgumentException("Method not supported."); - defaultMethod = method; - } - - /** - * Sets default compression level. The new level will be activated - * immediately. - * @exception IllegalArgumentException if level is not supported. - * @see Deflater - */ - public void setLevel(int level) - { - def.setLevel(level); - } - - /** - * Write an unsigned short in little endian byte order. - */ - private void writeLeShort(int value) throws IOException - { - out.write(value & 0xff); - out.write((value >> 8) & 0xff); - } - - /** - * Write an int in little endian byte order. - */ - private void writeLeInt(int value) throws IOException - { - writeLeShort(value); - writeLeShort(value >> 16); - } - - /** - * Starts a new Zip entry. It automatically closes the previous - * entry if present. If the compression method is stored, the entry - * must have a valid size and crc, otherwise all elements (except - * name) are optional, but must be correct if present. If the time - * is not set in the entry, the current time is used. - * @param entry the entry. - * @exception IOException if an I/O error occured. - * @exception ZipException if stream was finished. - */ - public void putNextEntry(ZipEntry entry) throws IOException - { - if (entries == null) - throw new ZipException("ZipOutputStream was finished"); - - int method = entry.getMethod(); - int flags = 0; - if (method == -1) - method = defaultMethod; - - if (method == STORED) - { - if (entry.getCompressedSize() >= 0) - { - if (entry.getSize() < 0) - entry.setSize(entry.getCompressedSize()); - else if (entry.getSize() != entry.getCompressedSize()) - throw new ZipException - ("Method STORED, but compressed size != size"); - } - else - entry.setCompressedSize(entry.getSize()); - - if (entry.getSize() < 0) - throw new ZipException("Method STORED, but size not set"); - if (entry.getCrc() < 0) - throw new ZipException("Method STORED, but crc not set"); - } - else if (method == DEFLATED) - { - if (entry.getCompressedSize() < 0 - || entry.getSize() < 0 || entry.getCrc() < 0) - flags |= 8; - } - - if (curEntry != null) - closeEntry(); - - if (entry.getTime() < 0) - entry.setTime(System.currentTimeMillis()); - - entry.flags = flags; - entry.offset = offset; - entry.setMethod(method); - curMethod = method; - /* Write the local file header */ - writeLeInt(LOCSIG); - writeLeShort(method == STORED - ? ZIP_STORED_VERSION : ZIP_DEFLATED_VERSION); - writeLeShort(flags); - writeLeShort(method); - writeLeInt(entry.getDOSTime()); - if ((flags & 8) == 0) - { - writeLeInt((int)entry.getCrc()); - writeLeInt((int)entry.getCompressedSize()); - writeLeInt((int)entry.getSize()); - } - else - { - writeLeInt(0); - writeLeInt(0); - writeLeInt(0); - } - byte[] name = entry.getName().getBytes(); - if (name.length > 0xffff) - throw new ZipException("Name too long."); - byte[] extra = entry.getExtra(); - if (extra == null) - extra = new byte[0]; - writeLeShort(name.length); - writeLeShort(extra.length); - out.write(name); - out.write(extra); - - offset += LOCHDR + name.length + extra.length; - - /* Activate the entry. */ - - curEntry = entry; - crc.reset(); - if (method == DEFLATED) - def.reset(); - size = 0; - } - - /** - * Closes the current entry. - * @exception IOException if an I/O error occured. - * @exception ZipException if no entry is active. - */ - public void closeEntry() throws IOException - { - if (curEntry == null) - throw new ZipException("No open entry"); - - /* First finish the deflater, if appropriate */ - if (curMethod == DEFLATED) - super.finish(); - - int csize = curMethod == DEFLATED ? def.getTotalOut() : size; - - if (curEntry.getSize() < 0) - curEntry.setSize(size); - else if (curEntry.getSize() != size) - throw new ZipException("size was "+size - +", but I expected "+curEntry.getSize()); - - if (curEntry.getCompressedSize() < 0) - curEntry.setCompressedSize(csize); - else if (curEntry.getCompressedSize() != csize) - throw new ZipException("compressed size was "+csize - +", but I expected "+curEntry.getSize()); - - if (curEntry.getCrc() < 0) - curEntry.setCrc(crc.getValue()); - else if (curEntry.getCrc() != crc.getValue()) - throw new ZipException("crc was " + Long.toHexString(crc.getValue()) - + ", but I expected " - + Long.toHexString(curEntry.getCrc())); - - offset += csize; - - /* Now write the data descriptor entry if needed. */ - if (curMethod == DEFLATED && (curEntry.flags & 8) != 0) - { - writeLeInt(EXTSIG); - writeLeInt((int)curEntry.getCrc()); - writeLeInt((int)curEntry.getCompressedSize()); - writeLeInt((int)curEntry.getSize()); - offset += EXTHDR; - } - - entries.addElement(curEntry); - curEntry = null; - } - - /** - * Writes the given buffer to the current entry. - * @exception IOException if an I/O error occured. - * @exception ZipException if no entry is active. - */ - public void write(byte[] b, int off, int len) throws IOException - { - if (curEntry == null) - throw new ZipException("No open entry."); - - switch (curMethod) - { - case DEFLATED: - super.write(b, off, len); - break; - - case STORED: - out.write(b, off, len); - break; - } - - crc.update(b, off, len); - size += len; - } - - /** - * Finishes the stream. This will write the central directory at the - * end of the zip file and flush the stream. - * @exception IOException if an I/O error occured. - */ - public void finish() throws IOException - { - if (entries == null) - return; - if (curEntry != null) - closeEntry(); - - int numEntries = 0; - int sizeEntries = 0; - - Enumeration e = entries.elements(); - while (e.hasMoreElements()) - { - ZipEntry entry = (ZipEntry) e.nextElement(); - - int method = entry.getMethod(); - writeLeInt(CENSIG); - writeLeShort(method == STORED - ? ZIP_STORED_VERSION : ZIP_DEFLATED_VERSION); - writeLeShort(method == STORED - ? ZIP_STORED_VERSION : ZIP_DEFLATED_VERSION); - writeLeShort(entry.flags); - writeLeShort(method); - writeLeInt(entry.getDOSTime()); - writeLeInt((int)entry.getCrc()); - writeLeInt((int)entry.getCompressedSize()); - writeLeInt((int)entry.getSize()); - - byte[] name = entry.getName().getBytes(); - if (name.length > 0xffff) - throw new ZipException("Name too long."); - byte[] extra = entry.getExtra(); - if (extra == null) - extra = new byte[0]; - String strComment = entry.getComment(); - byte[] comment = strComment != null - ? strComment.getBytes() : new byte[0]; - if (comment.length > 0xffff) - throw new ZipException("Comment too long."); - - writeLeShort(name.length); - writeLeShort(extra.length); - writeLeShort(comment.length); - writeLeShort(0); /* disk number */ - writeLeShort(0); /* internal file attr */ - writeLeInt(0); /* external file attr */ - writeLeInt(entry.offset); - - out.write(name); - out.write(extra); - out.write(comment); - numEntries++; - sizeEntries += CENHDR + name.length + extra.length + comment.length; - } - - writeLeInt(ENDSIG); - writeLeShort(0); /* disk number */ - writeLeShort(0); /* disk with start of central dir */ - writeLeShort(numEntries); - writeLeShort(numEntries); - writeLeInt(sizeEntries); - writeLeInt(offset); - writeLeShort(zipComment.length); - out.write(zipComment); - out.flush(); - entries = null; - } -} |