diff options
Diffstat (limited to 'libjava/classpath/java/util')
162 files changed, 0 insertions, 73200 deletions
diff --git a/libjava/classpath/java/util/.cvsignore b/libjava/classpath/java/util/.cvsignore deleted file mode 100644 index d41ae8d..0000000 --- a/libjava/classpath/java/util/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -LocaleData.java diff --git a/libjava/classpath/java/util/AbstractCollection.java b/libjava/classpath/java/util/AbstractCollection.java deleted file mode 100644 index d3406c2..0000000 --- a/libjava/classpath/java/util/AbstractCollection.java +++ /dev/null @@ -1,482 +0,0 @@ -/* AbstractCollection.java -- Abstract implementation of most of Collection - Copyright (C) 1998, 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 gnu.java.lang.CPStringBuilder; - -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) - * @author Tom Tromey (tromey@redhat.com) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @see Collection - * @see AbstractSet - * @see AbstractList - * @since 1.2 - * @status updated to 1.4 - */ -public abstract class AbstractCollection<E> - implements Collection<E>, Iterable<E> -{ - /** - * 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<E> 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(E 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<? extends E> c) - { - Iterator<? extends E> 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<E> 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<E> 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<E> 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<E> 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<E> 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<E> 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 <T> T[] toArray(T[] a) - { - int size = size(); - if (a.length < size) - a = (T[]) Array.newInstance(a.getClass().getComponentType(), - size); - else if (a.length > size) - a[size] = null; - - Iterator<E> itr = iterator(); - for (int pos = 0; pos < size; pos++) - a[pos] = (T) (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. "<this>" is inserted when the collection - * contains itself (only works for direct containment, not for collections - * inside collections). - * - * @return a String representation of the Collection - */ - public String toString() - { - Iterator itr = iterator(); - CPStringBuilder r = new CPStringBuilder("["); - boolean hasNext = itr.hasNext(); - while (hasNext) - { - Object o = itr.next(); - if (o == this) - r.append("<this>"); - else - r.append(o); - hasNext = itr.hasNext(); - if (hasNext) - 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/classpath/java/util/AbstractList.java b/libjava/classpath/java/util/AbstractList.java deleted file mode 100644 index 13ee28a..0000000 --- a/libjava/classpath/java/util/AbstractList.java +++ /dev/null @@ -1,1204 +0,0 @@ -/* AbstractList.java -- Abstract implementation of most of List - 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; - -/** - * 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<E> - extends AbstractCollection<E> - implements List<E> -{ - /** - * 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 E 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, E 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(E 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<? extends E> c) - { - Iterator<? extends E> 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<E> 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<E> 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<E> 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<E> iterator() - { - // Bah, Sun's implementation forbids using listIterator(0). - return new Iterator<E>() - { - 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. - */ - public boolean hasNext() - { - 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 E 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<E> 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<E> 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<E> listIterator(final int index) - { - if (index < 0 || index > size()) - throw new IndexOutOfBoundsException("Index: " + index + ", Size:" - + size()); - - return new ListIterator<E>() - { - 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. - */ - public boolean hasNext() - { - 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. - */ - public boolean hasPrevious() - { - 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 E 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 E 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. - */ - public int nextIndex() - { - 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. - */ - public int previousIndex() - { - 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(E 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(E 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 E 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<E> 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 E set(int index, E 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<E> 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<E>(this, fromIndex, toIndex); - return new SubList<E>(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<E> extends AbstractList<E> - { - // Package visible, for use by iterator. - /** The original list. */ - final AbstractList<E> 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<E> 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 E set(int index, E 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 E 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, E 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 E remove(int index) - { - checkMod(); - checkBoundsExclusive(index); - E 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<? extends E> 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<? extends E> c) - { - return addAll(size, c); - } - - /** - * Specified by AbstractList.subList to return listIterator(). - * - * @return an iterator over the sublist - */ - public Iterator<E> 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<E> listIterator(final int index) - { - checkMod(); - checkBoundsInclusive(index); - - return new ListIterator<E>() - { - private final ListIterator<E> 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. - */ - public boolean hasNext() - { - 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. - */ - public boolean hasPrevious() - { - 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 E 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 E 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. - */ - 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. - */ - 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(E 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(E 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<E> extends SubList<E> - 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<E> backing, int fromIndex, int toIndex) - { - super(backing, fromIndex, toIndex); - } - } // class RandomAccessSubList - -} // class AbstractList diff --git a/libjava/classpath/java/util/AbstractMap.java b/libjava/classpath/java/util/AbstractMap.java deleted file mode 100644 index e0e3571..0000000 --- a/libjava/classpath/java/util/AbstractMap.java +++ /dev/null @@ -1,819 +0,0 @@ -/* AbstractMap.java -- Abstract implementation of most of Map - 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 gnu.java.lang.CPStringBuilder; - -import java.io.Serializable; - -/** - * 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<K, V> implements Map<K, V> -{ - /** - * A class containing an immutable key and value. The - * implementation of {@link Entry#setValue(V)} for this class - * simply throws an {@link UnsupportedOperationException}, - * thus preventing changes being made. This is useful when - * a static thread-safe view of a map is required. - * - * @since 1.6 - */ - public static class SimpleImmutableEntry<K, V> - implements Entry<K, V>, Serializable - { - /** - * Compatible with JDK 1.6 - */ - private static final long serialVersionUID = 7138329143949025153L; - - K key; - V value; - - public SimpleImmutableEntry(K key, V value) - { - this.key = key; - this.value = value; - } - - public SimpleImmutableEntry(Entry<? extends K, ? extends V> entry) - { - this(entry.getKey(), entry.getValue()); - } - - public K getKey() - { - return key; - } - - public V getValue() - { - return value; - } - - public V setValue(V value) - { - throw new UnsupportedOperationException("setValue not supported on immutable entry"); - } - } - -/** 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<K> keys; - - /** - * The cache for {@link #values()}. - */ - // Package visible for use by subclasses. - Collection<V> 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<Map.Entry<K, V>> 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<K, V> copy = (AbstractMap<K, V>) 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<Map.Entry<K, V>> entries = entrySet().iterator(); - int pos = size(); - while (--pos >= 0) - if (equals(key, 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<Map.Entry<K, V>> entries = entrySet().iterator(); - int pos = size(); - while (--pos >= 0) - if (equals(value, 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<K, V>) 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 V get(Object key) - { - Iterator<Map.Entry<K, V>> entries = entrySet().iterator(); - int pos = size(); - while (--pos >= 0) - { - Map.Entry<K, V> 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<K> keySet() - { - if (keys == null) - keys = new AbstractSet<K>() - { - /** - * 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<K> iterator() - { - return new Iterator<K>() - { - /** - * The iterator returned by <code>entrySet()</code>. - */ - private final Iterator<Map.Entry<K, V>> 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 K next() - { - return 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 V put(K key, V 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<? extends K, ? extends V> m) - { - // FIXME: bogus circumlocution. - Iterator entries2 = m.entrySet().iterator(); - Iterator<Map.Entry<? extends K, ? extends V>> entries - = (Iterator<Map.Entry<? extends K, ? extends V>>) entries2; - int pos = m.size(); - while (--pos >= 0) - { - Map.Entry<? extends K, ? extends V> 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 V remove(Object key) - { - Iterator<Map.Entry<K, V>> entries = entrySet().iterator(); - int pos = size(); - while (--pos >= 0) - { - Map.Entry<K, V> entry = entries.next(); - if (equals(key, entry.getKey())) - { - // Must get the value before we remove it from iterator. - V 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<Map.Entry<K, V>> entries = entrySet().iterator(); - CPStringBuilder r = new CPStringBuilder("{"); - for (int pos = size(); pos > 0; pos--) - { - Map.Entry<K, V> 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<V> values() - { - if (values == null) - values = new AbstractCollection<V>() - { - /** - * 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<V> iterator() - { - return new Iterator<V>() - { - /** - * The iterator returned by <code>entrySet()</code>. - */ - private final Iterator<Map.Entry<K, V>> 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 V next() - { - return 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 == o2 || (o1 != 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 == o2 || (o1 != 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) - * - * @since 1.6 - */ - public static class SimpleEntry<K, V> implements Entry<K, V>, Serializable - { - - /** - * Compatible with JDK 1.6 - */ - private static final long serialVersionUID = -8499721149061103585L; - - /** - * The key. Package visible for direct manipulation. - */ - K key; - - /** - * The value. Package visible for direct manipulation. - */ - V value; - - /** - * Basic constructor initializes the fields. - * @param newKey the key - * @param newValue the value - */ - public SimpleEntry(K newKey, V newValue) - { - key = newKey; - value = newValue; - } - - public SimpleEntry(Entry<? extends K, ? extends V> entry) - { - this(entry.getKey(), entry.getValue()); - } - - /** - * 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 boolean equals(Object o) - { - if (! (o instanceof Map.Entry)) - return false; - // Optimize for our own entries. - if (o instanceof SimpleEntry) - { - SimpleEntry e = (SimpleEntry) 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 K 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 V 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 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 V setValue(V newVal) - { - V 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 String toString() - { - return key + "=" + value; - } - } // class SimpleEntry - - -} diff --git a/libjava/classpath/java/util/AbstractSequentialList.java b/libjava/classpath/java/util/AbstractSequentialList.java deleted file mode 100644 index 81b0714..0000000 --- a/libjava/classpath/java/util/AbstractSequentialList.java +++ /dev/null @@ -1,235 +0,0 @@ -/* AbstractSequentialList.java -- List implementation for sequential access - 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; - -/** - * 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<E> extends AbstractList<E> -{ - /** - * 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<E> 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, E 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<? extends E> c) - { - Iterator<? extends E> ci = c.iterator(); - int size = c.size(); - ListIterator<E> 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 E 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<E> 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 E remove(int index) - { - // This is a legal listIterator position, but an illegal remove. - if (index == size()) - throw new IndexOutOfBoundsException("Index: " + index + ", Size:" - + size()); - ListIterator<E> i = listIterator(index); - E 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 E set(int index, E o) - { - // This is a legal listIterator position, but an illegal set. - if (index == size()) - throw new IndexOutOfBoundsException("Index: " + index + ", Size:" - + size()); - ListIterator<E> i = listIterator(index); - E old = i.next(); - i.set(o); - return old; - } -} diff --git a/libjava/classpath/java/util/AbstractSet.java b/libjava/classpath/java/util/AbstractSet.java deleted file mode 100644 index af1e4d1..0000000 --- a/libjava/classpath/java/util/AbstractSet.java +++ /dev/null @@ -1,146 +0,0 @@ -/* AbstractSet.java -- Abstract implementation of most of Set - Copyright (C) 1998, 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; - -/** - * 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<E> - extends AbstractCollection<E> - implements Set<E> -{ - /** - * 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<E> 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(); - if (oldsize < count) - { - Iterator<E> i; - for (i = iterator(), count = oldsize; count > 0; count--) - { - if (c.contains(i.next())) - i.remove(); - } - } - else - { - Iterator<?> i; - for (i = c.iterator(); count > 0; count--) - remove(i.next()); - } - return oldsize != size(); - } -} diff --git a/libjava/classpath/java/util/ArrayList.java b/libjava/classpath/java/util/ArrayList.java deleted file mode 100644 index 0da2193..0000000 --- a/libjava/classpath/java/util/ArrayList.java +++ /dev/null @@ -1,603 +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<E> extends AbstractList<E> - implements List<E>, 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 = 10; - - /** - * The number of elements in this list. - * @serial the list size - */ - private int size; - - /** - * Where the data is stored. - */ - private transient E[] 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 = (E[]) 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<? extends E> 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) - { - E[] newData = (E[]) 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) - { - E[] newData = (E[]) 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<E> clone = null; - try - { - clone = (ArrayList<E>) super.clone(); - clone.data = (E[]) 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() - { - E[] array = (E[]) 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 <T> T[] toArray(T[] a) - { - if (a.length < size) - a = (T[]) 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 E 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 E set(int index, E e) - { - checkBoundExclusive(index); - E 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(E 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, E 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 E remove(int index) - { - checkBoundExclusive(index); - E 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<? extends E> 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<? extends E> c) - { - checkBoundInclusive(index); - Iterator<? extends E> 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) - raiseBoundsError(index); - } - - /** - * 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) - raiseBoundsError(index); - } - - /** - * Raise the ArrayIndexOfOutBoundsException. - * - * @param index the index of the access - * @throws IndexOutOfBoundsException unconditionally - */ - private void raiseBoundsError(int index) - { - // Implementaion note: put in a separate method to make the JITs job easier - // (separate common from uncommon code at method boundaries when trivial to - // do so). - 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 s 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 s 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 = (E[]) new Object[capacity]; - for (int i = 0; i < size; i++) - data[i] = (E) s.readObject(); - } -} diff --git a/libjava/classpath/java/util/Arrays.java b/libjava/classpath/java/util/Arrays.java deleted file mode 100644 index dad55c4..0000000 --- a/libjava/classpath/java/util/Arrays.java +++ /dev/null @@ -1,4034 +0,0 @@ -/* Arrays.java -- Utility class with methods to operate on arrays - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, - 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 gnu.java.lang.CPStringBuilder; - -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) - { - if (a.length == 0) - return -1; - return binarySearch(a, 0, a.length - 1, key); - } - - /** - * Perform a binary search of a range of a byte array for a key. The range - * must be sorted (as by the <code>sort(byte[], int, int)</code> 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 low the lowest index to search from. - * @param hi the highest index to search to. - * @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 IllegalArgumentException if <code>low > hi</code> - * @throws ArrayIndexOutOfBoundsException if <code>low < 0</code> or - * <code>hi > a.length</code>. - */ - public static int binarySearch(byte[] a, int low, int hi, byte key) - { - if (low > hi) - throw new IllegalArgumentException("The start index is higher than " + - "the finish index."); - if (low < 0 || hi > a.length) - throw new ArrayIndexOutOfBoundsException("One of the indices is out " + - "of bounds."); - 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) - { - if (a.length == 0) - return -1; - return binarySearch(a, 0, a.length - 1, key); - } - - /** - * Perform a binary search of a range of a char array for a key. The range - * must be sorted (as by the <code>sort(char[], int, int)</code> 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 low the lowest index to search from. - * @param hi the highest index to search to. - * @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 IllegalArgumentException if <code>low > hi</code> - * @throws ArrayIndexOutOfBoundsException if <code>low < 0</code> or - * <code>hi > a.length</code>. - */ - public static int binarySearch(char[] a, int low, int hi, char key) - { - if (low > hi) - throw new IllegalArgumentException("The start index is higher than " + - "the finish index."); - if (low < 0 || hi > a.length) - throw new ArrayIndexOutOfBoundsException("One of the indices is out " + - "of bounds."); - 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) - { - if (a.length == 0) - return -1; - return binarySearch(a, 0, a.length - 1, key); - } - - /** - * Perform a binary search of a range of a short array for a key. The range - * must be sorted (as by the <code>sort(short[], int, int)</code> 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 low the lowest index to search from. - * @param hi the highest index to search to. - * @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 IllegalArgumentException if <code>low > hi</code> - * @throws ArrayIndexOutOfBoundsException if <code>low < 0</code> or - * <code>hi > a.length</code>. - */ - public static int binarySearch(short[] a, int low, int hi, short key) - { - if (low > hi) - throw new IllegalArgumentException("The start index is higher than " + - "the finish index."); - if (low < 0 || hi > a.length) - throw new ArrayIndexOutOfBoundsException("One of the indices is out " + - "of bounds."); - 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) - { - if (a.length == 0) - return -1; - return binarySearch(a, 0, a.length - 1, key); - } - - /** - * Perform a binary search of a range of an integer array for a key. The range - * must be sorted (as by the <code>sort(int[], int, int)</code> 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 low the lowest index to search from. - * @param hi the highest index to search to. - * @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 IllegalArgumentException if <code>low > hi</code> - * @throws ArrayIndexOutOfBoundsException if <code>low < 0</code> or - * <code>hi > a.length</code>. - */ - public static int binarySearch(int[] a, int low, int hi, int key) - { - if (low > hi) - throw new IllegalArgumentException("The start index is higher than " + - "the finish index."); - if (low < 0 || hi > a.length) - throw new ArrayIndexOutOfBoundsException("One of the indices is out " + - "of bounds."); - 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) - { - if (a.length == 0) - return -1; - return binarySearch(a, 0, a.length - 1, key); - } - - /** - * Perform a binary search of a range of a long array for a key. The range - * must be sorted (as by the <code>sort(long[], int, int)</code> 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 low the lowest index to search from. - * @param hi the highest index to search to. - * @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 IllegalArgumentException if <code>low > hi</code> - * @throws ArrayIndexOutOfBoundsException if <code>low < 0</code> or - * <code>hi > a.length</code>. - */ - public static int binarySearch(long[] a, int low, int hi, long key) - { - if (low > hi) - throw new IllegalArgumentException("The start index is higher than " + - "the finish index."); - if (low < 0 || hi > a.length) - throw new ArrayIndexOutOfBoundsException("One of the indices is out " + - "of bounds."); - 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) - { - if (a.length == 0) - return -1; - return binarySearch(a, 0, a.length - 1, key); - } - - /** - * Perform a binary search of a range of a float array for a key. The range - * must be sorted (as by the <code>sort(float[], int, int)</code> 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 low the lowest index to search from. - * @param hi the highest index to search to. - * @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 IllegalArgumentException if <code>low > hi</code> - * @throws ArrayIndexOutOfBoundsException if <code>low < 0</code> or - * <code>hi > a.length</code>. - */ - public static int binarySearch(float[] a, int low, int hi, float key) - { - if (low > hi) - throw new IllegalArgumentException("The start index is higher than " + - "the finish index."); - if (low < 0 || hi > a.length) - throw new ArrayIndexOutOfBoundsException("One of the indices is out " + - "of bounds."); - // Must use Float.compare to take into account NaN, +-0. - 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) - { - if (a.length == 0) - return -1; - return binarySearch(a, 0, a.length - 1, key); - } - - /** - * Perform a binary search of a range of a double array for a key. The range - * must be sorted (as by the <code>sort(double[], int, int)</code> 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 low the lowest index to search from. - * @param hi the highest index to search to. - * @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 IllegalArgumentException if <code>low > hi</code> - * @throws ArrayIndexOutOfBoundsException if <code>low < 0</code> or - * <code>hi > a.length</code>. - */ - public static int binarySearch(double[] a, int low, int hi, double key) - { - if (low > hi) - throw new IllegalArgumentException("The start index is higher than " + - "the finish index."); - if (low < 0 || hi > a.length) - throw new ArrayIndexOutOfBoundsException("One of the indices is out " + - "of bounds."); - // Must use Double.compare to take into account NaN, +-0. - 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) - { - if (a.length == 0) - return -1; - return binarySearch(a, key, null); - } - - /** - * Perform a binary search of a range of an Object array for a key. The range - * must be sorted (as by the <code>sort(Object[], int, int)</code> 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 low the lowest index to search from. - * @param hi the highest index to search to. - * @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(Object[] a, int low, int hi, Object key) - { - return binarySearch(a, low, hi, 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 <T> int binarySearch(T[] a, T key, Comparator<? super T> c) - { - if (a.length == 0) - return -1; - return binarySearch(a, 0, a.length - 1, key, c); - } - - /** - * Perform a binary search of a range of an Object array for a key using - * a {@link Comparator}. The range must be sorted (as by the - * <code>sort(Object[], int, int)</code> 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 low the lowest index to search from. - * @param hi the highest index to search to. - * @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 IllegalArgumentException if <code>low > hi</code> - * @throws ArrayIndexOutOfBoundsException if <code>low < 0</code> or - * <code>hi > a.length</code>. - */ - public static <T> int binarySearch(T[] a, int low, int hi, T key, - Comparator<? super T> c) - { - if (low > hi) - throw new IllegalArgumentException("The start index is higher than " + - "the finish index."); - if (low < 0 || hi > a.length) - throw new ArrayIndexOutOfBoundsException("One of the indices is out " + - "of bounds."); - int mid = 0; - while (low <= hi) - { - mid = (low + hi) >>> 1; - // NOTE: Please keep the order of a[mid] and key. Although - // not required by the specs, the RI has it in this order as - // well, and real programs (erroneously) depend on it. - final int d = Collections.compare(a[mid], key, 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 = from + 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 = from + 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 = from + 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 = from + 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 = from + 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 = from + 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 = from + 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 <T> void sort(T[] a, Comparator<? super T> 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 <T> void sort(T[] a, int fromIndex, int toIndex, - Comparator<? super T> 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; - T 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; - - T[] src = a; - T[] dest = (T[]) new Object[len]; - T[] 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 (<code>null</code> not permitted) - * @return a fixed-size list, changes to which "write through" to the array - * - * @throws NullPointerException if <code>a</code> is <code>null</code>. - * @see Serializable - * @see RandomAccess - * @see Arrays.ArrayList - */ - public static <T> List<T> asList(final T... a) - { - return new Arrays.ArrayList(a); - } - - /** - * Returns the hashcode of an array of long numbers. If two arrays - * are equal, according to <code>equals()</code>, they should have the - * same hashcode. The hashcode returned by the method is equal to that - * obtained by the corresponding <code>List</code> object. This has the same - * data, but represents longs in their wrapper class, <code>Long</code>. - * For <code>null</code>, 0 is returned. - * - * @param v an array of long numbers for which the hash code should be - * computed. - * @return the hash code of the array, or 0 if null was given. - * @since 1.5 - */ - public static int hashCode(long[] v) - { - if (v == null) - return 0; - int result = 1; - for (int i = 0; i < v.length; ++i) - { - int elt = (int) (v[i] ^ (v[i] >>> 32)); - result = 31 * result + elt; - } - return result; - } - - /** - * Returns the hashcode of an array of integer numbers. If two arrays - * are equal, according to <code>equals()</code>, they should have the - * same hashcode. The hashcode returned by the method is equal to that - * obtained by the corresponding <code>List</code> object. This has the same - * data, but represents ints in their wrapper class, <code>Integer</code>. - * For <code>null</code>, 0 is returned. - * - * @param v an array of integer numbers for which the hash code should be - * computed. - * @return the hash code of the array, or 0 if null was given. - * @since 1.5 - */ - public static int hashCode(int[] v) - { - if (v == null) - return 0; - int result = 1; - for (int i = 0; i < v.length; ++i) - result = 31 * result + v[i]; - return result; - } - - /** - * Returns the hashcode of an array of short numbers. If two arrays - * are equal, according to <code>equals()</code>, they should have the - * same hashcode. The hashcode returned by the method is equal to that - * obtained by the corresponding <code>List</code> object. This has the same - * data, but represents shorts in their wrapper class, <code>Short</code>. - * For <code>null</code>, 0 is returned. - * - * @param v an array of short numbers for which the hash code should be - * computed. - * @return the hash code of the array, or 0 if null was given. - * @since 1.5 - */ - public static int hashCode(short[] v) - { - if (v == null) - return 0; - int result = 1; - for (int i = 0; i < v.length; ++i) - result = 31 * result + v[i]; - return result; - } - - /** - * Returns the hashcode of an array of characters. If two arrays - * are equal, according to <code>equals()</code>, they should have the - * same hashcode. The hashcode returned by the method is equal to that - * obtained by the corresponding <code>List</code> object. This has the same - * data, but represents chars in their wrapper class, <code>Character</code>. - * For <code>null</code>, 0 is returned. - * - * @param v an array of characters for which the hash code should be - * computed. - * @return the hash code of the array, or 0 if null was given. - * @since 1.5 - */ - public static int hashCode(char[] v) - { - if (v == null) - return 0; - int result = 1; - for (int i = 0; i < v.length; ++i) - result = 31 * result + v[i]; - return result; - } - - /** - * Returns the hashcode of an array of bytes. If two arrays - * are equal, according to <code>equals()</code>, they should have the - * same hashcode. The hashcode returned by the method is equal to that - * obtained by the corresponding <code>List</code> object. This has the same - * data, but represents bytes in their wrapper class, <code>Byte</code>. - * For <code>null</code>, 0 is returned. - * - * @param v an array of bytes for which the hash code should be - * computed. - * @return the hash code of the array, or 0 if null was given. - * @since 1.5 - */ - public static int hashCode(byte[] v) - { - if (v == null) - return 0; - int result = 1; - for (int i = 0; i < v.length; ++i) - result = 31 * result + v[i]; - return result; - } - - /** - * Returns the hashcode of an array of booleans. If two arrays - * are equal, according to <code>equals()</code>, they should have the - * same hashcode. The hashcode returned by the method is equal to that - * obtained by the corresponding <code>List</code> object. This has the same - * data, but represents booleans in their wrapper class, - * <code>Boolean</code>. For <code>null</code>, 0 is returned. - * - * @param v an array of booleans for which the hash code should be - * computed. - * @return the hash code of the array, or 0 if null was given. - * @since 1.5 - */ - public static int hashCode(boolean[] v) - { - if (v == null) - return 0; - int result = 1; - for (int i = 0; i < v.length; ++i) - result = 31 * result + (v[i] ? 1231 : 1237); - return result; - } - - /** - * Returns the hashcode of an array of floats. If two arrays - * are equal, according to <code>equals()</code>, they should have the - * same hashcode. The hashcode returned by the method is equal to that - * obtained by the corresponding <code>List</code> object. This has the same - * data, but represents floats in their wrapper class, <code>Float</code>. - * For <code>null</code>, 0 is returned. - * - * @param v an array of floats for which the hash code should be - * computed. - * @return the hash code of the array, or 0 if null was given. - * @since 1.5 - */ - public static int hashCode(float[] v) - { - if (v == null) - return 0; - int result = 1; - for (int i = 0; i < v.length; ++i) - result = 31 * result + Float.floatToIntBits(v[i]); - return result; - } - - /** - * Returns the hashcode of an array of doubles. If two arrays - * are equal, according to <code>equals()</code>, they should have the - * same hashcode. The hashcode returned by the method is equal to that - * obtained by the corresponding <code>List</code> object. This has the same - * data, but represents doubles in their wrapper class, <code>Double</code>. - * For <code>null</code>, 0 is returned. - * - * @param v an array of doubles for which the hash code should be - * computed. - * @return the hash code of the array, or 0 if null was given. - * @since 1.5 - */ - public static int hashCode(double[] v) - { - if (v == null) - return 0; - int result = 1; - for (int i = 0; i < v.length; ++i) - { - long l = Double.doubleToLongBits(v[i]); - int elt = (int) (l ^ (l >>> 32)); - result = 31 * result + elt; - } - return result; - } - - /** - * Returns the hashcode of an array of objects. If two arrays - * are equal, according to <code>equals()</code>, they should have the - * same hashcode. The hashcode returned by the method is equal to that - * obtained by the corresponding <code>List</code> object. - * For <code>null</code>, 0 is returned. - * - * @param v an array of integer numbers for which the hash code should be - * computed. - * @return the hash code of the array, or 0 if null was given. - * @since 1.5 - */ - public static int hashCode(Object[] v) - { - if (v == null) - return 0; - int result = 1; - for (int i = 0; i < v.length; ++i) - { - int elt = v[i] == null ? 0 : v[i].hashCode(); - result = 31 * result + elt; - } - return result; - } - - public static int deepHashCode(Object[] v) - { - if (v == null) - return 0; - int result = 1; - for (int i = 0; i < v.length; ++i) - { - int elt; - if (v[i] == null) - elt = 0; - else if (v[i] instanceof boolean[]) - elt = hashCode((boolean[]) v[i]); - else if (v[i] instanceof byte[]) - elt = hashCode((byte[]) v[i]); - else if (v[i] instanceof char[]) - elt = hashCode((char[]) v[i]); - else if (v[i] instanceof short[]) - elt = hashCode((short[]) v[i]); - else if (v[i] instanceof int[]) - elt = hashCode((int[]) v[i]); - else if (v[i] instanceof long[]) - elt = hashCode((long[]) v[i]); - else if (v[i] instanceof float[]) - elt = hashCode((float[]) v[i]); - else if (v[i] instanceof double[]) - elt = hashCode((double[]) v[i]); - else if (v[i] instanceof Object[]) - elt = hashCode((Object[]) v[i]); - else - elt = v[i].hashCode(); - result = 31 * result + elt; - } - return result; - } - - /** @since 1.5 */ - public static boolean deepEquals(Object[] v1, Object[] v2) - { - if (v1 == null) - return v2 == null; - if (v2 == null || v1.length != v2.length) - return false; - - for (int i = 0; i < v1.length; ++i) - { - Object e1 = v1[i]; - Object e2 = v2[i]; - - if (e1 == e2) - continue; - if (e1 == null || e2 == null) - return false; - - boolean check; - if (e1 instanceof boolean[] && e2 instanceof boolean[]) - check = equals((boolean[]) e1, (boolean[]) e2); - else if (e1 instanceof byte[] && e2 instanceof byte[]) - check = equals((byte[]) e1, (byte[]) e2); - else if (e1 instanceof char[] && e2 instanceof char[]) - check = equals((char[]) e1, (char[]) e2); - else if (e1 instanceof short[] && e2 instanceof short[]) - check = equals((short[]) e1, (short[]) e2); - else if (e1 instanceof int[] && e2 instanceof int[]) - check = equals((int[]) e1, (int[]) e2); - else if (e1 instanceof long[] && e2 instanceof long[]) - check = equals((long[]) e1, (long[]) e2); - else if (e1 instanceof float[] && e2 instanceof float[]) - check = equals((float[]) e1, (float[]) e2); - else if (e1 instanceof double[] && e2 instanceof double[]) - check = equals((double[]) e1, (double[]) e2); - else if (e1 instanceof Object[] && e2 instanceof Object[]) - check = equals((Object[]) e1, (Object[]) e2); - else - check = e1.equals(e2); - if (! check) - return false; - } - - return true; - } - - /** - * Returns a String representation of the argument array. Returns "null" - * if <code>a</code> is null. - * @param v the array to represent - * @return a String representing this array - * @since 1.5 - */ - public static String toString(boolean[] v) - { - if (v == null) - return "null"; - CPStringBuilder b = new CPStringBuilder("["); - for (int i = 0; i < v.length; ++i) - { - if (i > 0) - b.append(", "); - b.append(v[i]); - } - b.append("]"); - return b.toString(); - } - - /** - * Returns a String representation of the argument array. Returns "null" - * if <code>a</code> is null. - * @param v the array to represent - * @return a String representing this array - * @since 1.5 - */ - public static String toString(byte[] v) - { - if (v == null) - return "null"; - CPStringBuilder b = new CPStringBuilder("["); - for (int i = 0; i < v.length; ++i) - { - if (i > 0) - b.append(", "); - b.append(v[i]); - } - b.append("]"); - return b.toString(); - } - - /** - * Returns a String representation of the argument array. Returns "null" - * if <code>a</code> is null. - * @param v the array to represent - * @return a String representing this array - * @since 1.5 - */ - public static String toString(char[] v) - { - if (v == null) - return "null"; - CPStringBuilder b = new CPStringBuilder("["); - for (int i = 0; i < v.length; ++i) - { - if (i > 0) - b.append(", "); - b.append(v[i]); - } - b.append("]"); - return b.toString(); - } - - /** - * Returns a String representation of the argument array. Returns "null" - * if <code>a</code> is null. - * @param v the array to represent - * @return a String representing this array - * @since 1.5 - */ - public static String toString(short[] v) - { - if (v == null) - return "null"; - CPStringBuilder b = new CPStringBuilder("["); - for (int i = 0; i < v.length; ++i) - { - if (i > 0) - b.append(", "); - b.append(v[i]); - } - b.append("]"); - return b.toString(); - } - - /** - * Returns a String representation of the argument array. Returns "null" - * if <code>a</code> is null. - * @param v the array to represent - * @return a String representing this array - * @since 1.5 - */ - public static String toString(int[] v) - { - if (v == null) - return "null"; - CPStringBuilder b = new CPStringBuilder("["); - for (int i = 0; i < v.length; ++i) - { - if (i > 0) - b.append(", "); - b.append(v[i]); - } - b.append("]"); - return b.toString(); - } - - /** - * Returns a String representation of the argument array. Returns "null" - * if <code>a</code> is null. - * @param v the array to represent - * @return a String representing this array - * @since 1.5 - */ - public static String toString(long[] v) - { - if (v == null) - return "null"; - CPStringBuilder b = new CPStringBuilder("["); - for (int i = 0; i < v.length; ++i) - { - if (i > 0) - b.append(", "); - b.append(v[i]); - } - b.append("]"); - return b.toString(); - } - - /** - * Returns a String representation of the argument array. Returns "null" - * if <code>a</code> is null. - * @param v the array to represent - * @return a String representing this array - * @since 1.5 - */ - public static String toString(float[] v) - { - if (v == null) - return "null"; - CPStringBuilder b = new CPStringBuilder("["); - for (int i = 0; i < v.length; ++i) - { - if (i > 0) - b.append(", "); - b.append(v[i]); - } - b.append("]"); - return b.toString(); - } - - /** - * Returns a String representation of the argument array. Returns "null" - * if <code>a</code> is null. - * @param v the array to represent - * @return a String representing this array - * @since 1.5 - */ - public static String toString(double[] v) - { - if (v == null) - return "null"; - CPStringBuilder b = new CPStringBuilder("["); - for (int i = 0; i < v.length; ++i) - { - if (i > 0) - b.append(", "); - b.append(v[i]); - } - b.append("]"); - return b.toString(); - } - - /** - * Returns a String representation of the argument array. Returns "null" - * if <code>a</code> is null. - * @param v the array to represent - * @return a String representing this array - * @since 1.5 - */ - public static String toString(Object[] v) - { - if (v == null) - return "null"; - CPStringBuilder b = new CPStringBuilder("["); - for (int i = 0; i < v.length; ++i) - { - if (i > 0) - b.append(", "); - b.append(v[i]); - } - b.append("]"); - return b.toString(); - } - - private static void deepToString(Object[] v, CPStringBuilder b, HashSet seen) - { - b.append("["); - for (int i = 0; i < v.length; ++i) - { - if (i > 0) - b.append(", "); - Object elt = v[i]; - if (elt == null) - b.append("null"); - else if (elt instanceof boolean[]) - b.append(toString((boolean[]) elt)); - else if (elt instanceof byte[]) - b.append(toString((byte[]) elt)); - else if (elt instanceof char[]) - b.append(toString((char[]) elt)); - else if (elt instanceof short[]) - b.append(toString((short[]) elt)); - else if (elt instanceof int[]) - b.append(toString((int[]) elt)); - else if (elt instanceof long[]) - b.append(toString((long[]) elt)); - else if (elt instanceof float[]) - b.append(toString((float[]) elt)); - else if (elt instanceof double[]) - b.append(toString((double[]) elt)); - else if (elt instanceof Object[]) - { - Object[] os = (Object[]) elt; - if (seen.contains(os)) - b.append("[...]"); - else - { - seen.add(os); - deepToString(os, b, seen); - } - } - else - b.append(elt); - } - b.append("]"); - } - - /** @since 1.5 */ - public static String deepToString(Object[] v) - { - if (v == null) - return "null"; - HashSet seen = new HashSet(); - CPStringBuilder b = new CPStringBuilder(); - deepToString(v, b, seen); - return b.toString(); - } - - /** - * 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<E> extends AbstractList<E> - 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 E[] a; - - /** - * Construct a list view of the array. - * @param a the array to view - * @throws NullPointerException if a is null - */ - ArrayList(E[] 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 E 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 E set(int index, E element) - { - E 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 <T> T[] toArray(T[] array) - { - int size = a.length; - if (array.length < size) - array = (T[]) Array.newInstance(array.getClass().getComponentType(), - size); - else if (array.length > size) - array[size] = null; - - System.arraycopy(a, 0, array, 0, size); - return array; - } - } - - /** - * Returns a copy of the supplied array, truncating or padding as - * necessary with <code>false</code> to obtain the specified length. - * Indices that are valid for both arrays will return the same value. - * Indices that only exist in the returned array (due to the new length - * being greater than the original length) will return <code>false</code>. - * This is equivalent to calling - * <code>copyOfRange(original, 0, newLength)</code>. - * - * @param original the original array to be copied. - * @param newLength the length of the returned array. - * @return a copy of the original array, truncated or padded with - * <code>false</code> to obtain the required length. - * @throws NegativeArraySizeException if <code>newLength</code> is negative. - * @throws NullPointerException if <code>original</code> is <code>null</code>. - * @since 1.6 - * @see #copyOfRange(boolean[],int,int) - */ - public static boolean[] copyOf(boolean[] original, int newLength) - { - if (newLength < 0) - throw new NegativeArraySizeException("The array size is negative."); - return copyOfRange(original, 0, newLength); - } - - /** - * Copies the specified range of the supplied array to a new - * array, padding as necessary with <code>false</code> - * if <code>to</code> is greater than the length of the original - * array. <code>from</code> must be in the range zero to - * <code>original.length</code> and can not be greater than - * <code>to</code>. The initial element of the - * returned array will be equal to <code>original[from]</code>, - * except where <code>from</code> is equal to <code>to</code> - * (where a zero-length array will be returned) or <code> - * <code>from</code> is equal to <code>original.length</code> - * (where an array padded with <code>false</code> will be - * returned). The returned array is always of length - * <code>to - from</code>. - * - * @param original the array from which to copy. - * @param from the initial index of the range, inclusive. - * @param to the final index of the range, exclusive. - * @return a copy of the specified range, with padding to - * obtain the required length. - * @throws ArrayIndexOutOfBoundsException if <code>from < 0</code> - * or <code>from > original.length</code> - * @throws IllegalArgumentException if <code>from > to</code> - * @throws NullPointerException if <code>original</code> is <code>null</code>. - * @since 1.6 - * @see #copyOf(boolean[],int) - */ - public static boolean[] copyOfRange(boolean[] original, int from, int to) - { - if (from > to) - throw new IllegalArgumentException("The initial index is after " + - "the final index."); - boolean[] newArray = new boolean[to - from]; - if (to > original.length) - { - System.arraycopy(original, from, newArray, 0, - original.length - from); - fill(newArray, original.length, newArray.length, false); - } - else - System.arraycopy(original, from, newArray, 0, to - from); - return newArray; - } - - /** - * Returns a copy of the supplied array, truncating or padding as - * necessary with <code>(byte)0</code> to obtain the specified length. - * Indices that are valid for both arrays will return the same value. - * Indices that only exist in the returned array (due to the new length - * being greater than the original length) will return <code>(byte)0</code>. - * This is equivalent to calling - * <code>copyOfRange(original, 0, newLength)</code>. - * - * @param original the original array to be copied. - * @param newLength the length of the returned array. - * @return a copy of the original array, truncated or padded with - * <code>(byte)0</code> to obtain the required length. - * @throws NegativeArraySizeException if <code>newLength</code> is negative. - * @throws NullPointerException if <code>original</code> is <code>null</code>. - * @since 1.6 - * @see #copyOfRange(byte[],int,int) - */ - public static byte[] copyOf(byte[] original, int newLength) - { - if (newLength < 0) - throw new NegativeArraySizeException("The array size is negative."); - return copyOfRange(original, 0, newLength); - } - - /** - * Copies the specified range of the supplied array to a new - * array, padding as necessary with <code>(byte)0</code> - * if <code>to</code> is greater than the length of the original - * array. <code>from</code> must be in the range zero to - * <code>original.length</code> and can not be greater than - * <code>to</code>. The initial element of the - * returned array will be equal to <code>original[from]</code>, - * except where <code>from</code> is equal to <code>to</code> - * (where a zero-length array will be returned) or <code> - * <code>from</code> is equal to <code>original.length</code> - * (where an array padded with <code>(byte)0</code> will be - * returned). The returned array is always of length - * <code>to - from</code>. - * - * @param original the array from which to copy. - * @param from the initial index of the range, inclusive. - * @param to the final index of the range, exclusive. - * @return a copy of the specified range, with padding to - * obtain the required length. - * @throws ArrayIndexOutOfBoundsException if <code>from < 0</code> - * or <code>from > original.length</code> - * @throws IllegalArgumentException if <code>from > to</code> - * @throws NullPointerException if <code>original</code> is <code>null</code>. - * @since 1.6 - * @see #copyOf(byte[],int) - */ - public static byte[] copyOfRange(byte[] original, int from, int to) - { - if (from > to) - throw new IllegalArgumentException("The initial index is after " + - "the final index."); - byte[] newArray = new byte[to - from]; - if (to > original.length) - { - System.arraycopy(original, from, newArray, 0, - original.length - from); - fill(newArray, original.length, newArray.length, (byte)0); - } - else - System.arraycopy(original, from, newArray, 0, to - from); - return newArray; - } - - /** - * Returns a copy of the supplied array, truncating or padding as - * necessary with <code>'\0'</code> to obtain the specified length. - * Indices that are valid for both arrays will return the same value. - * Indices that only exist in the returned array (due to the new length - * being greater than the original length) will return <code>'\0'</code>. - * This is equivalent to calling - * <code>copyOfRange(original, 0, newLength)</code>. - * - * @param original the original array to be copied. - * @param newLength the length of the returned array. - * @return a copy of the original array, truncated or padded with - * <code>'\0'</code> to obtain the required length. - * @throws NegativeArraySizeException if <code>newLength</code> is negative. - * @throws NullPointerException if <code>original</code> is <code>null</code>. - * @since 1.6 - * @see #copyOfRange(char[],int,int) - */ - public static char[] copyOf(char[] original, int newLength) - { - if (newLength < 0) - throw new NegativeArraySizeException("The array size is negative."); - return copyOfRange(original, 0, newLength); - } - - /** - * Copies the specified range of the supplied array to a new - * array, padding as necessary with <code>'\0'</code> - * if <code>to</code> is greater than the length of the original - * array. <code>from</code> must be in the range zero to - * <code>original.length</code> and can not be greater than - * <code>to</code>. The initial element of the - * returned array will be equal to <code>original[from]</code>, - * except where <code>from</code> is equal to <code>to</code> - * (where a zero-length array will be returned) or <code> - * <code>from</code> is equal to <code>original.length</code> - * (where an array padded with <code>'\0'</code> will be - * returned). The returned array is always of length - * <code>to - from</code>. - * - * @param original the array from which to copy. - * @param from the initial index of the range, inclusive. - * @param to the final index of the range, exclusive. - * @return a copy of the specified range, with padding to - * obtain the required length. - * @throws ArrayIndexOutOfBoundsException if <code>from < 0</code> - * or <code>from > original.length</code> - * @throws IllegalArgumentException if <code>from > to</code> - * @throws NullPointerException if <code>original</code> is <code>null</code>. - * @since 1.6 - * @see #copyOf(char[],int) - */ - public static char[] copyOfRange(char[] original, int from, int to) - { - if (from > to) - throw new IllegalArgumentException("The initial index is after " + - "the final index."); - char[] newArray = new char[to - from]; - if (to > original.length) - { - System.arraycopy(original, from, newArray, 0, - original.length - from); - fill(newArray, original.length, newArray.length, '\0'); - } - else - System.arraycopy(original, from, newArray, 0, to - from); - return newArray; - } - - /** - * Returns a copy of the supplied array, truncating or padding as - * necessary with <code>0d</code> to obtain the specified length. - * Indices that are valid for both arrays will return the same value. - * Indices that only exist in the returned array (due to the new length - * being greater than the original length) will return <code>0d</code>. - * This is equivalent to calling - * <code>copyOfRange(original, 0, newLength)</code>. - * - * @param original the original array to be copied. - * @param newLength the length of the returned array. - * @return a copy of the original array, truncated or padded with - * <code>0d</code> to obtain the required length. - * @throws NegativeArraySizeException if <code>newLength</code> is negative. - * @throws NullPointerException if <code>original</code> is <code>null</code>. - * @since 1.6 - * @see #copyOfRange(double[],int,int) - */ - public static double[] copyOf(double[] original, int newLength) - { - if (newLength < 0) - throw new NegativeArraySizeException("The array size is negative."); - return copyOfRange(original, 0, newLength); - } - - /** - * Copies the specified range of the supplied array to a new - * array, padding as necessary with <code>0d</code> - * if <code>to</code> is greater than the length of the original - * array. <code>from</code> must be in the range zero to - * <code>original.length</code> and can not be greater than - * <code>to</code>. The initial element of the - * returned array will be equal to <code>original[from]</code>, - * except where <code>from</code> is equal to <code>to</code> - * (where a zero-length array will be returned) or <code> - * <code>from</code> is equal to <code>original.length</code> - * (where an array padded with <code>0d</code> will be - * returned). The returned array is always of length - * <code>to - from</code>. - * - * @param original the array from which to copy. - * @param from the initial index of the range, inclusive. - * @param to the final index of the range, exclusive. - * @return a copy of the specified range, with padding to - * obtain the required length. - * @throws ArrayIndexOutOfBoundsException if <code>from < 0</code> - * or <code>from > original.length</code> - * @throws IllegalArgumentException if <code>from > to</code> - * @throws NullPointerException if <code>original</code> is <code>null</code>. - * @since 1.6 - * @see #copyOf(double[],int) - */ - public static double[] copyOfRange(double[] original, int from, int to) - { - if (from > to) - throw new IllegalArgumentException("The initial index is after " + - "the final index."); - double[] newArray = new double[to - from]; - if (to > original.length) - { - System.arraycopy(original, from, newArray, 0, - original.length - from); - fill(newArray, original.length, newArray.length, 0d); - } - else - System.arraycopy(original, from, newArray, 0, to - from); - return newArray; - } - - /** - * Returns a copy of the supplied array, truncating or padding as - * necessary with <code>0f</code> to obtain the specified length. - * Indices that are valid for both arrays will return the same value. - * Indices that only exist in the returned array (due to the new length - * being greater than the original length) will return <code>0f</code>. - * This is equivalent to calling - * <code>copyOfRange(original, 0, newLength)</code>. - * - * @param original the original array to be copied. - * @param newLength the length of the returned array. - * @return a copy of the original array, truncated or padded with - * <code>0f</code> to obtain the required length. - * @throws NegativeArraySizeException if <code>newLength</code> is negative. - * @throws NullPointerException if <code>original</code> is <code>null</code>. - * @since 1.6 - * @see #copyOfRange(float[],int,int) - */ - public static float[] copyOf(float[] original, int newLength) - { - if (newLength < 0) - throw new NegativeArraySizeException("The array size is negative."); - return copyOfRange(original, 0, newLength); - } - - /** - * Copies the specified range of the supplied array to a new - * array, padding as necessary with <code>0f</code> - * if <code>to</code> is greater than the length of the original - * array. <code>from</code> must be in the range zero to - * <code>original.length</code> and can not be greater than - * <code>to</code>. The initial element of the - * returned array will be equal to <code>original[from]</code>, - * except where <code>from</code> is equal to <code>to</code> - * (where a zero-length array will be returned) or <code> - * <code>from</code> is equal to <code>original.length</code> - * (where an array padded with <code>0f</code> will be - * returned). The returned array is always of length - * <code>to - from</code>. - * - * @param original the array from which to copy. - * @param from the initial index of the range, inclusive. - * @param to the final index of the range, exclusive. - * @return a copy of the specified range, with padding to - * obtain the required length. - * @throws ArrayIndexOutOfBoundsException if <code>from < 0</code> - * or <code>from > original.length</code> - * @throws IllegalArgumentException if <code>from > to</code> - * @throws NullPointerException if <code>original</code> is <code>null</code>. - * @since 1.6 - * @see #copyOf(float[],int) - */ - public static float[] copyOfRange(float[] original, int from, int to) - { - if (from > to) - throw new IllegalArgumentException("The initial index is after " + - "the final index."); - float[] newArray = new float[to - from]; - if (to > original.length) - { - System.arraycopy(original, from, newArray, 0, - original.length - from); - fill(newArray, original.length, newArray.length, 0f); - } - else - System.arraycopy(original, from, newArray, 0, to - from); - return newArray; - } - - /** - * Returns a copy of the supplied array, truncating or padding as - * necessary with <code>0</code> to obtain the specified length. - * Indices that are valid for both arrays will return the same value. - * Indices that only exist in the returned array (due to the new length - * being greater than the original length) will return <code>0</code>. - * This is equivalent to calling - * <code>copyOfRange(original, 0, newLength)</code>. - * - * @param original the original array to be copied. - * @param newLength the length of the returned array. - * @return a copy of the original array, truncated or padded with - * <code>0</code> to obtain the required length. - * @throws NegativeArraySizeException if <code>newLength</code> is negative. - * @throws NullPointerException if <code>original</code> is <code>null</code>. - * @since 1.6 - * @see #copyOfRange(int[],int,int) - */ - public static int[] copyOf(int[] original, int newLength) - { - if (newLength < 0) - throw new NegativeArraySizeException("The array size is negative."); - return copyOfRange(original, 0, newLength); - } - - /** - * Copies the specified range of the supplied array to a new - * array, padding as necessary with <code>0</code> - * if <code>to</code> is greater than the length of the original - * array. <code>from</code> must be in the range zero to - * <code>original.length</code> and can not be greater than - * <code>to</code>. The initial element of the - * returned array will be equal to <code>original[from]</code>, - * except where <code>from</code> is equal to <code>to</code> - * (where a zero-length array will be returned) or <code> - * <code>from</code> is equal to <code>original.length</code> - * (where an array padded with <code>0</code> will be - * returned). The returned array is always of length - * <code>to - from</code>. - * - * @param original the array from which to copy. - * @param from the initial index of the range, inclusive. - * @param to the final index of the range, exclusive. - * @return a copy of the specified range, with padding to - * obtain the required length. - * @throws ArrayIndexOutOfBoundsException if <code>from < 0</code> - * or <code>from > original.length</code> - * @throws IllegalArgumentException if <code>from > to</code> - * @throws NullPointerException if <code>original</code> is <code>null</code>. - * @since 1.6 - * @see #copyOf(int[],int) - */ - public static int[] copyOfRange(int[] original, int from, int to) - { - if (from > to) - throw new IllegalArgumentException("The initial index is after " + - "the final index."); - int[] newArray = new int[to - from]; - if (to > original.length) - { - System.arraycopy(original, from, newArray, 0, - original.length - from); - fill(newArray, original.length, newArray.length, 0); - } - else - System.arraycopy(original, from, newArray, 0, to - from); - return newArray; - } - - /** - * Returns a copy of the supplied array, truncating or padding as - * necessary with <code>0L</code> to obtain the specified length. - * Indices that are valid for both arrays will return the same value. - * Indices that only exist in the returned array (due to the new length - * being greater than the original length) will return <code>0L</code>. - * This is equivalent to calling - * <code>copyOfRange(original, 0, newLength)</code>. - * - * @param original the original array to be copied. - * @param newLength the length of the returned array. - * @return a copy of the original array, truncated or padded with - * <code>0L</code> to obtain the required length. - * @throws NegativeArraySizeException if <code>newLength</code> is negative. - * @throws NullPointerException if <code>original</code> is <code>null</code>. - * @since 1.6 - * @see #copyOfRange(long[],int,int) - */ - public static long[] copyOf(long[] original, int newLength) - { - if (newLength < 0) - throw new NegativeArraySizeException("The array size is negative."); - return copyOfRange(original, 0, newLength); - } - - /** - * Copies the specified range of the supplied array to a new - * array, padding as necessary with <code>0L</code> - * if <code>to</code> is greater than the length of the original - * array. <code>from</code> must be in the range zero to - * <code>original.length</code> and can not be greater than - * <code>to</code>. The initial element of the - * returned array will be equal to <code>original[from]</code>, - * except where <code>from</code> is equal to <code>to</code> - * (where a zero-length array will be returned) or <code> - * <code>from</code> is equal to <code>original.length</code> - * (where an array padded with <code>0L</code> will be - * returned). The returned array is always of length - * <code>to - from</code>. - * - * @param original the array from which to copy. - * @param from the initial index of the range, inclusive. - * @param to the final index of the range, exclusive. - * @return a copy of the specified range, with padding to - * obtain the required length. - * @throws ArrayIndexOutOfBoundsException if <code>from < 0</code> - * or <code>from > original.length</code> - * @throws IllegalArgumentException if <code>from > to</code> - * @throws NullPointerException if <code>original</code> is <code>null</code>. - * @since 1.6 - * @see #copyOf(long[],int) - */ - public static long[] copyOfRange(long[] original, int from, int to) - { - if (from > to) - throw new IllegalArgumentException("The initial index is after " + - "the final index."); - long[] newArray = new long[to - from]; - if (to > original.length) - { - System.arraycopy(original, from, newArray, 0, - original.length - from); - fill(newArray, original.length, newArray.length, 0L); - } - else - System.arraycopy(original, from, newArray, 0, to - from); - return newArray; - } - - /** - * Returns a copy of the supplied array, truncating or padding as - * necessary with <code>(short)0</code> to obtain the specified length. - * Indices that are valid for both arrays will return the same value. - * Indices that only exist in the returned array (due to the new length - * being greater than the original length) will return <code>(short)0</code>. - * This is equivalent to calling - * <code>copyOfRange(original, 0, newLength)</code>. - * - * @param original the original array to be copied. - * @param newLength the length of the returned array. - * @return a copy of the original array, truncated or padded with - * <code>(short)0</code> to obtain the required length. - * @throws NegativeArraySizeException if <code>newLength</code> is negative. - * @throws NullPointerException if <code>original</code> is <code>null</code>. - * @since 1.6 - * @see #copyOfRange(short[],int,int) - */ - public static short[] copyOf(short[] original, int newLength) - { - if (newLength < 0) - throw new NegativeArraySizeException("The array size is negative."); - return copyOfRange(original, 0, newLength); - } - - /** - * Copies the specified range of the supplied array to a new - * array, padding as necessary with <code>(short)0</code> - * if <code>to</code> is greater than the length of the original - * array. <code>from</code> must be in the range zero to - * <code>original.length</code> and can not be greater than - * <code>to</code>. The initial element of the - * returned array will be equal to <code>original[from]</code>, - * except where <code>from</code> is equal to <code>to</code> - * (where a zero-length array will be returned) or <code> - * <code>from</code> is equal to <code>original.length</code> - * (where an array padded with <code>(short)0</code> will be - * returned). The returned array is always of length - * <code>to - from</code>. - * - * @param original the array from which to copy. - * @param from the initial index of the range, inclusive. - * @param to the final index of the range, exclusive. - * @return a copy of the specified range, with padding to - * obtain the required length. - * @throws ArrayIndexOutOfBoundsException if <code>from < 0</code> - * or <code>from > original.length</code> - * @throws IllegalArgumentException if <code>from > to</code> - * @throws NullPointerException if <code>original</code> is <code>null</code>. - * @since 1.6 - * @see #copyOf(short[],int) - */ - public static short[] copyOfRange(short[] original, int from, int to) - { - if (from > to) - throw new IllegalArgumentException("The initial index is after " + - "the final index."); - short[] newArray = new short[to - from]; - if (to > original.length) - { - System.arraycopy(original, from, newArray, 0, - original.length - from); - fill(newArray, original.length, newArray.length, (short)0); - } - else - System.arraycopy(original, from, newArray, 0, to - from); - return newArray; - } - - /** - * Returns a copy of the supplied array, truncating or padding as - * necessary with <code>null</code> to obtain the specified length. - * Indices that are valid for both arrays will return the same value. - * Indices that only exist in the returned array (due to the new length - * being greater than the original length) will return <code>null</code>. - * This is equivalent to calling - * <code>copyOfRange(original, 0, newLength)</code>. - * - * @param original the original array to be copied. - * @param newLength the length of the returned array. - * @return a copy of the original array, truncated or padded with - * <code>null</code> to obtain the required length. - * @throws NegativeArraySizeException if <code>newLength</code> is negative. - * @throws NullPointerException if <code>original</code> is <code>null</code>. - * @since 1.6 - * @see #copyOfRange(T[],int,int) - */ - public static <T> T[] copyOf(T[] original, int newLength) - { - if (newLength < 0) - throw new NegativeArraySizeException("The array size is negative."); - return copyOfRange(original, 0, newLength); - } - - /** - * Copies the specified range of the supplied array to a new - * array, padding as necessary with <code>null</code> - * if <code>to</code> is greater than the length of the original - * array. <code>from</code> must be in the range zero to - * <code>original.length</code> and can not be greater than - * <code>to</code>. The initial element of the - * returned array will be equal to <code>original[from]</code>, - * except where <code>from</code> is equal to <code>to</code> - * (where a zero-length array will be returned) or <code> - * <code>from</code> is equal to <code>original.length</code> - * (where an array padded with <code>null</code> will be - * returned). The returned array is always of length - * <code>to - from</code>. - * - * @param original the array from which to copy. - * @param from the initial index of the range, inclusive. - * @param to the final index of the range, exclusive. - * @return a copy of the specified range, with padding to - * obtain the required length. - * @throws ArrayIndexOutOfBoundsException if <code>from < 0</code> - * or <code>from > original.length</code> - * @throws IllegalArgumentException if <code>from > to</code> - * @throws NullPointerException if <code>original</code> is <code>null</code>. - * @since 1.6 - * @see #copyOf(T[],int) - */ - public static <T> T[] copyOfRange(T[] original, int from, int to) - { - if (from > to) - throw new IllegalArgumentException("The initial index is after " + - "the final index."); - Class elemType = original.getClass().getComponentType(); - T[] newArray = (T[]) Array.newInstance(elemType, to - from); - if (to > original.length) - { - System.arraycopy(original, from, newArray, 0, - original.length - from); - fill(newArray, original.length, newArray.length, null); - } - else - System.arraycopy(original, from, newArray, 0, to - from); - return newArray; - } - - /** - * Returns a copy of the supplied array, truncating or padding as - * necessary with <code>null</code> to obtain the specified length. - * Indices that are valid for both arrays will return the same value. - * Indices that only exist in the returned array (due to the new length - * being greater than the original length) will return <code>null</code>. - * This is equivalent to calling - * <code>copyOfRange(original, 0, newLength, newType)</code>. The returned - * array will be of the specified type, <code>newType</code>. - * - * @param original the original array to be copied. - * @param newLength the length of the returned array. - * @param newType the type of the returned array. - * @return a copy of the original array, truncated or padded with - * <code>null</code> to obtain the required length. - * @throws NegativeArraySizeException if <code>newLength</code> is negative. - * @throws NullPointerException if <code>original</code> is <code>null</code>. - * @since 1.6 - * @see #copyOfRange(U[],int,int,Class) - */ - public static <T,U> T[] copyOf(U[] original, int newLength, - Class<? extends T[]> newType) - { - if (newLength < 0) - throw new NegativeArraySizeException("The array size is negative."); - return copyOfRange(original, 0, newLength, newType); - } - - /** - * Copies the specified range of the supplied array to a new - * array, padding as necessary with <code>null</code> - * if <code>to</code> is greater than the length of the original - * array. <code>from</code> must be in the range zero to - * <code>original.length</code> and can not be greater than - * <code>to</code>. The initial element of the - * returned array will be equal to <code>original[from]</code>, - * except where <code>from</code> is equal to <code>to</code> - * (where a zero-length array will be returned) or <code> - * <code>from</code> is equal to <code>original.length</code> - * (where an array padded with <code>null</code> will be - * returned). The returned array is always of length - * <code>to - from</code> and will be of the specified type, - * <code>newType</code>. - * - * @param original the array from which to copy. - * @param from the initial index of the range, inclusive. - * @param to the final index of the range, exclusive. - * @param newType the type of the returned array. - * @return a copy of the specified range, with padding to - * obtain the required length. - * @throws ArrayIndexOutOfBoundsException if <code>from < 0</code> - * or <code>from > original.length</code> - * @throws IllegalArgumentException if <code>from > to</code> - * @throws NullPointerException if <code>original</code> is <code>null</code>. - * @since 1.6 - * @see #copyOf(T[],int) - */ - public static <T,U> T[] copyOfRange(U[] original, int from, int to, - Class<? extends T[]> newType) - { - if (from > to) - throw new IllegalArgumentException("The initial index is after " + - "the final index."); - T[] newArray = (T[]) Array.newInstance(newType.getComponentType(), - to - from); - if (to > original.length) - { - System.arraycopy(original, from, newArray, 0, - original.length - from); - fill(newArray, original.length, newArray.length, null); - } - else - System.arraycopy(original, from, newArray, 0, to - from); - return newArray; - } -} diff --git a/libjava/classpath/java/util/BitSet.java b/libjava/classpath/java/util/BitSet.java deleted file mode 100644 index 1072978..0000000 --- a/libjava/classpath/java/util/BitSet.java +++ /dev/null @@ -1,758 +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 gnu.java.lang.CPStringBuilder; - -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 bs the second bit set - * @throws NullPointerException if bs 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>bs</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 bs the second bit set - * @throws NullPointerException if bs 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>pos</code> from this set. That is - * the corresponding bit is cleared. If the index is not in the set, - * this method does nothing. - * - * @param pos a non-negative integer - * @throws IndexOutOfBoundsException if pos < 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 position - * @throws IndexOutOfBoundsException if the pos 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 || to == from) - 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() - { - CPStringBuilder r = new CPStringBuilder("{"); - 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; - } - } - - // This is used by EnumSet for efficiency. - final boolean containsAll(BitSet other) - { - for (int i = other.bits.length - 1; i >= 0; i--) - { - if ((bits[i] & other.bits[i]) != other.bits[i]) - return false; - } - return true; - } -} diff --git a/libjava/classpath/java/util/Calendar.java b/libjava/classpath/java/util/Calendar.java deleted file mode 100644 index 8123b17..0000000 --- a/libjava/classpath/java/util/Calendar.java +++ /dev/null @@ -1,1620 +0,0 @@ -/* Calendar.java -- - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, - 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 gnu.java.lang.CPStringBuilder; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; - -import java.text.DateFormatSymbols; - -/** - * This class is an abstract base class for Calendars, which can be - * used to convert between <code>Date</code> objects and a set of - * integer fields which represent <code>YEAR</code>, - * <code>MONTH</code>, <code>DAY</code>, etc. The <code>Date</code> - * object represents a time in milliseconds since the Epoch. <br> - * - * This class is locale sensitive. To get the Object matching the - * current locale you can use <code>getInstance</code>. You can even provide - * a locale or a timezone. <code>getInstance</code> returns currently - * a <code>GregorianCalendar</code> for the current date. <br> - * - * If you want to convert a date from the Year, Month, Day, DayOfWeek, - * etc. Representation to a <code>Date</code>-Object, you can create - * a new Calendar with <code>getInstance()</code>, - * <code>clear()</code> all fields, <code>set(int,int)</code> the - * fields you need and convert it with <code>getTime()</code>. <br> - * - * If you want to convert a <code>Date</code>-object to the Calendar - * representation, create a new Calendar, assign the - * <code>Date</code>-Object with <code>setTime()</code>, and read the - * fields with <code>get(int)</code>. <br> - * - * When computing the date from time fields, it may happen, that there - * are either two few fields set, or some fields are inconsistent. This - * cases will handled in a calendar specific way. Missing fields are - * replaced by the fields of the epoch: 1970 January 1 00:00. <br> - * - * To understand, how the day of year is computed out of the fields - * look at the following table. It is traversed from top to bottom, - * and for the first line all fields are set, that line is used to - * compute the day. <br> - * - * -<pre>month + day_of_month -month + week_of_month + day_of_week -month + day_of_week_of_month + day_of_week -day_of_year -day_of_week + week_of_year</pre> - * - * The hour_of_day-field takes precedence over the ampm and - * hour_of_ampm fields. <br> - * - * <STRONG>Note:</STRONG> This can differ for non-Gregorian calendar. <br> - * - * To convert a calendar to a human readable form and vice versa, use - * the <code>java.text.DateFormat</code> class. <br> - * - * Other useful things you can do with an calendar, is - * <code>roll</code>ing fields (that means increase/decrease a - * specific field by one, propagating overflows), or - * <code>add</code>ing/substracting a fixed amount to a field. - * - * @author Aaron M. Renn (arenn@urbanophile.com) - * @author Jochen Hoenicke (Jochen.Hoenicke@Informatik.Uni-Oldenburg.de) - * @author Warren Levy (warrenl@cygnus.com) - * @author Jeff Sturm (jsturm@one-point.com) - * @author Tom Tromey (tromey@redhat.com) - * @author Bryce McKinlay (mckinlay@redhat.com) - * @author Ingo Proetel (proetel@aicas.com) - * @author Jerry Quinn (jlquinn@optonline.net) - * @author Jeroen Frijters (jeroen@frijters.net) - * @author Noa Resare (noa@resare.com) - * @author Sven de Marothy (sven@physto.se) - * @author David Gilbert (david.gilbert@object-refinery.com) - * @author Olivier Jolly (olivier.jolly@pcedev.com) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @see Date - * @see GregorianCalendar - * @see TimeZone - * @see java.text.DateFormat - */ -public abstract class Calendar - implements Serializable, Cloneable, Comparable<Calendar> -{ - /** - * Constant representing the era time field. - */ - public static final int ERA = 0; - - /** - * Constant representing the year time field. - */ - public static final int YEAR = 1; - - /** - * Constant representing the month time field. This field - * should contain one of the JANUARY,...,DECEMBER constants below. - */ - public static final int MONTH = 2; - - /** - * Constant representing the week of the year field. - * @see #setFirstDayOfWeek(int) - */ - public static final int WEEK_OF_YEAR = 3; - - /** - * Constant representing the week of the month time field. - * @see #setFirstDayOfWeek(int) - */ - public static final int WEEK_OF_MONTH = 4; - - /** - * Constant representing the day time field, synonym for DAY_OF_MONTH. - */ - public static final int DATE = 5; - - /** - * Constant representing the day time field. - */ - public static final int DAY_OF_MONTH = 5; - - /** - * Constant representing the day of year time field. This is - * 1 for the first day in month. - */ - public static final int DAY_OF_YEAR = 6; - - /** - * Constant representing the day of week time field. This field - * should contain one of the SUNDAY,...,SATURDAY constants below. - */ - public static final int DAY_OF_WEEK = 7; - - /** - * Constant representing the day-of-week-in-month field. For - * instance this field contains 2 for the second thursday in a - * month. If you give a negative number here, the day will count - * from the end of the month. - */ - public static final int DAY_OF_WEEK_IN_MONTH = 8; - - /** - * Constant representing the part of the day for 12-hour clock. This - * should be one of AM or PM. - */ - public static final int AM_PM = 9; - - /** - * Constant representing the hour time field for 12-hour clock. - */ - public static final int HOUR = 10; - - /** - * Constant representing the hour of day time field for 24-hour clock. - */ - public static final int HOUR_OF_DAY = 11; - - /** - * Constant representing the minute of hour time field. - */ - public static final int MINUTE = 12; - - /** - * Constant representing the second time field. - */ - public static final int SECOND = 13; - - /** - * Constant representing the millisecond time field. - */ - public static final int MILLISECOND = 14; - - /** - * Constant representing the time zone offset time field for the - * time given in the other fields. It is measured in - * milliseconds. The default is the offset of the time zone. - */ - public static final int ZONE_OFFSET = 15; - - /** - * Constant representing the daylight saving time offset in - * milliseconds. The default is the value given by the time zone. - */ - public static final int DST_OFFSET = 16; - - /** - * Number of time fields. - */ - public static final int FIELD_COUNT = 17; - - /** - * Constant representing Sunday. - */ - public static final int SUNDAY = 1; - - /** - * Constant representing Monday. - */ - public static final int MONDAY = 2; - - /** - * Constant representing Tuesday. - */ - public static final int TUESDAY = 3; - - /** - * Constant representing Wednesday. - */ - public static final int WEDNESDAY = 4; - - /** - * Constant representing Thursday. - */ - public static final int THURSDAY = 5; - - /** - * Constant representing Friday. - */ - public static final int FRIDAY = 6; - - /** - * Constant representing Saturday. - */ - public static final int SATURDAY = 7; - - /** - * Constant representing January. - */ - public static final int JANUARY = 0; - - /** - * Constant representing February. - */ - public static final int FEBRUARY = 1; - - /** - * Constant representing March. - */ - public static final int MARCH = 2; - - /** - * Constant representing April. - */ - public static final int APRIL = 3; - - /** - * Constant representing May. - */ - public static final int MAY = 4; - - /** - * Constant representing June. - */ - public static final int JUNE = 5; - - /** - * Constant representing July. - */ - public static final int JULY = 6; - - /** - * Constant representing August. - */ - public static final int AUGUST = 7; - - /** - * Constant representing September. - */ - public static final int SEPTEMBER = 8; - - /** - * Constant representing October. - */ - public static final int OCTOBER = 9; - - /** - * Constant representing November. - */ - public static final int NOVEMBER = 10; - - /** - * Constant representing December. - */ - public static final int DECEMBER = 11; - - /** - * Constant representing Undecimber. This is an artificial name useful - * for lunar calendars. - */ - public static final int UNDECIMBER = 12; - - /** - * Useful constant for 12-hour clock. - */ - public static final int AM = 0; - - /** - * Useful constant for 12-hour clock. - */ - public static final int PM = 1; - - /** - * A style specifier for {@link #getDisplayNames(int,int,Locale)} - * stating that names should be returned in both long and short variants. - * - * @since 1.6 - * @see #SHORT - * @see #LONG - */ - public static final int ALL_STYLES = 0; - - /** - * A style specifier for {@link #getDisplayName(int,int,Locale)} - * and {@link #getDisplayNames(int,int,Locale)} stating that names - * should be returned in their short variant if applicable. - * - * @since 1.6 - */ - public static final int SHORT = 1; - - /** - * A style specifier for {@link #getDisplayName(int,int,Locale)} - * and {@link #getDisplayNames(int,int,Locale)} stating that names - * should be returned in their long variant if applicable. - * - * @since 1.6 - */ - public static final int LONG = 2; - - /** - * The time fields. The array is indexed by the constants YEAR to - * DST_OFFSET. - * @serial - */ - protected int[] fields = new int[FIELD_COUNT]; - - /** - * The flags which tell if the fields above have a value. - * @serial - */ - protected boolean[] isSet = new boolean[FIELD_COUNT]; - - /** - * The time in milliseconds since the epoch. - * @serial - */ - protected long time; - - /** - * Tells if the above field has a valid value. - * @serial - */ - protected boolean isTimeSet; - - /** - * Tells if the fields have a valid value. This superseeds the isSet - * array. - * @serial - */ - protected boolean areFieldsSet; - - /** - * The time zone of this calendar. Used by sub classes to do UTC / local - * time conversion. Sub classes can access this field with getTimeZone(). - * @serial - */ - private TimeZone zone; - - /** - * This is the default calendar class, that is returned on - * java.util.Calendar.getInstance(). - * XXX - this isn't localized anywhere, is it? - * @see java.util.Calendar#getInstance() - */ - private static final String calendarClassName = "java.util.GregorianCalendar"; - - /** - * Specifies if the date/time interpretation should be lenient. - * If the flag is set, a date such as "February 30, 1996" will be - * treated as the 29th day after the February 1. If this flag - * is false, such dates will cause an exception. - * @serial - */ - private boolean lenient; - - /** - * Sets what the first day of week is. This is used for - * WEEK_OF_MONTH and WEEK_OF_YEAR fields. - * @serial - */ - private int firstDayOfWeek; - - /** - * Sets how many days are required in the first week of the year. - * If the first day of the year should be the first week you should - * set this value to 1. If the first week must be a full week, set - * it to 7. - * @serial - */ - private int minimalDaysInFirstWeek; - - /** - * Is set to true if DST_OFFSET is explicitly set. In that case - * it's value overrides the value computed from the current - * time and the timezone. - */ - private boolean explicitDSTOffset = false; - - /** - * The version of the serialized data on the stream. - * <dl><dt>0 or not present</dt> - * <dd> JDK 1.1.5 or later.</dd> - * <dt>1</dt> - * <dd>JDK 1.1.6 or later. This always writes a correct `time' value - * on the stream, as well as the other fields, to be compatible with - * earlier versions</dd></dl> - * @since JDK1.1.6 - * @serial - */ - private int serialVersionOnStream = 1; - - /** - * XXX - I have not checked the compatibility. The documentation of - * the serialized-form is quite hairy... - */ - static final long serialVersionUID = -1807547505821590642L; - - /** - * The name of the resource bundle. Used only by getBundle() - */ - private static final String bundleName = "gnu.java.locale.LocaleInformation"; - - /** - * get resource bundle: - * The resources should be loaded via this method only. Iff an application - * uses this method, the resourcebundle is required. - */ - private static ResourceBundle getBundle(Locale locale) - { - return ResourceBundle.getBundle(bundleName, locale, - ClassLoader.getSystemClassLoader()); - } - - /** - * The set of properties for obtaining the minimum number of days in - * the first week. - */ - private static transient final Properties properties; - - /** - * Reads in the properties. - */ - static - { - properties = new Properties(); - try - { - properties.load(Calendar.class.getResourceAsStream("weeks.properties")); - } - catch (IOException exception) - { - System.out.println("Failed to load weeks resource: " + exception); - } - } - - /** - * Constructs a new Calendar with the default time zone and the default - * locale. - */ - protected Calendar() - { - this(TimeZone.getDefault(), Locale.getDefault()); - } - - /** - * Constructs a new Calendar with the given time zone and the given - * locale. - * @param zone a time zone. - * @param locale a locale. - */ - protected Calendar(TimeZone zone, Locale locale) - { - this.zone = zone; - lenient = true; - String[] days = { "", "sun", "mon", "tue", "wed", "thu", "fri", "sat" }; - - String country = locale.getCountry(); - String min = properties.getProperty("minDays." + country); - if (min == null) - min = properties.getProperty("minDays.DEFAULT"); - String first = properties.getProperty("firstDay." + country); - if (first == null) - first = properties.getProperty("firstDay.DEFAULT"); - try - { - if (min != null) - minimalDaysInFirstWeek = Integer.parseInt(min); - } - catch (NumberFormatException ex) - { - minimalDaysInFirstWeek = 1; - } - - firstDayOfWeek = 1; - if (first != null) - for (int i = 0; i < 8; i++) - if (days[i].equals(first)) - firstDayOfWeek = i; - - clear(); - } - - /** - * Creates a calendar representing the actual time, using the default - * time zone and locale. - * - * @return The new calendar. - */ - public static synchronized Calendar getInstance() - { - return getInstance(TimeZone.getDefault(), Locale.getDefault()); - } - - /** - * Creates a calendar representing the actual time, using the given - * time zone and the default locale. - * - * @param zone a time zone (<code>null</code> not permitted). - * - * @return The new calendar. - * - * @throws NullPointerException if <code>zone</code> is <code>null</code>. - */ - public static synchronized Calendar getInstance(TimeZone zone) - { - return getInstance(zone, Locale.getDefault()); - } - - /** - * Creates a calendar representing the actual time, using the default - * time zone and the given locale. - * - * @param locale a locale (<code>null</code> not permitted). - * - * @return The new calendar. - * - * @throws NullPointerException if <code>locale</code> is <code>null</code>. - */ - public static synchronized Calendar getInstance(Locale locale) - { - return getInstance(TimeZone.getDefault(), locale); - } - - /** - * Cache of locale->calendar-class mappings. This avoids having to do a ResourceBundle - * lookup for every getInstance call. - */ - private static final HashMap<Locale,Class> cache = new HashMap<Locale,Class>(); - - /** Preset argument types for calendar-class constructor lookup. */ - private static Class[] ctorArgTypes = new Class[] - { - TimeZone.class, Locale.class - }; - - /** - * Creates a calendar representing the actual time, using the given - * time zone and locale. - * - * @param zone a time zone (<code>null</code> not permitted). - * @param locale a locale (<code>null</code> not permitted). - * - * @return The new calendar. - * - * @throws NullPointerException if <code>zone</code> or <code>locale</code> - * is <code>null</code>. - */ - public static synchronized Calendar getInstance(TimeZone zone, Locale locale) - { - Class calendarClass = cache.get(locale); - Throwable exception = null; - - try - { - if (calendarClass == null) - { - calendarClass = Class.forName(calendarClassName); - if (Calendar.class.isAssignableFrom(calendarClass)) - cache.put(locale, calendarClass); - } - - // GregorianCalendar is by far the most common case. Optimize by - // avoiding reflection. - if (calendarClass == GregorianCalendar.class) - return new GregorianCalendar(zone, locale); - - if (Calendar.class.isAssignableFrom(calendarClass)) - { - Constructor ctor = calendarClass.getConstructor(ctorArgTypes); - return (Calendar) ctor.newInstance(new Object[] { zone, locale }); - } - } - catch (ClassNotFoundException ex) - { - exception = ex; - } - catch (IllegalAccessException ex) - { - exception = ex; - } - catch (NoSuchMethodException ex) - { - exception = ex; - } - catch (InstantiationException ex) - { - exception = ex; - } - catch (InvocationTargetException ex) - { - exception = ex; - } - - throw new RuntimeException("Error instantiating calendar for locale " - + locale, exception); - } - - /** - * Gets the set of locales for which a Calendar is available. - * @exception MissingResourceException if locale data couldn't be found. - * @return the set of locales. - */ - public static synchronized Locale[] getAvailableLocales() - { - ResourceBundle rb = getBundle(new Locale("", "")); - return (Locale[]) rb.getObject("availableLocales"); - } - - /** - * Converts the time field values (<code>fields</code>) to - * milliseconds since the epoch UTC (<code>time</code>). Override - * this method if you write your own Calendar. */ - protected abstract void computeTime(); - - /** - * Converts the milliseconds since the epoch UTC - * (<code>time</code>) to time fields - * (<code>fields</code>). Override this method if you write your - * own Calendar. - */ - protected abstract void computeFields(); - - /** - * Converts the time represented by this object to a - * <code>Date</code>-Object. - * @return the Date. - */ - public final Date getTime() - { - if (! isTimeSet) - computeTime(); - return new Date(time); - } - - /** - * Sets this Calendar's time to the given Date. All time fields - * are invalidated by this method. - * - * @param date the date (<code>null</code> not permitted). - * - * @throws NullPointerException if <code>date</code> is <code>null</code>. - */ - public final void setTime(Date date) - { - setTimeInMillis(date.getTime()); - } - - /** - * Returns the time represented by this Calendar. - * @return the time in milliseconds since the epoch. - * @specnote This was made public in 1.4. - */ - public long getTimeInMillis() - { - if (! isTimeSet) - computeTime(); - return time; - } - - /** - * Sets this Calendar's time to the given Time. All time fields - * are invalidated by this method. - * @param time the time in milliseconds since the epoch - * @specnote This was made public in 1.4. - */ - public void setTimeInMillis(long time) - { - clear(); - this.time = time; - isTimeSet = true; - computeFields(); - } - - /** - * Gets the value of the specified field. They are recomputed - * if they are invalid. - * @param field the time field. One of the time field constants. - * @return the value of the specified field - * @throws ArrayIndexOutOfBoundsException if the field is outside - * the valid range. The value of field must be >= 0 and - * <= <code>FIELD_COUNT</code>. - * @specnote Not final since JDK 1.4 - */ - public int get(int field) - { - // If the requested field is invalid, force all fields to be recomputed. - if (! isSet[field]) - areFieldsSet = false; - complete(); - return fields[field]; - } - - /** - * Gets the value of the specified field. This method doesn't - * recompute the fields, if they are invalid. - * @param field the time field. One of the time field constants. - * @return the value of the specified field, undefined if - * <code>areFieldsSet</code> or <code>isSet[field]</code> is false. - * @throws ArrayIndexOutOfBoundsException if the field is outside - * the valid range. The value of field must be >= 0 and - * <= <code>FIELD_COUNT</code>. - */ - protected final int internalGet(int field) - { - return fields[field]; - } - - /** - * Sets the time field with the given value. This does invalidate - * the time in milliseconds. - * @param field the time field. One of the time field constants - * @param value the value to be set. - * @throws ArrayIndexOutOfBoundsException if field is outside - * the valid range. The value of field must be >= 0 and - * <= <code>FIELD_COUNT</code>. - * @specnote Not final since JDK 1.4 - */ - public void set(int field, int value) - { - if (isTimeSet) - for (int i = 0; i < FIELD_COUNT; i++) - isSet[i] = false; - isTimeSet = false; - fields[field] = value; - isSet[field] = true; - - // The five valid date patterns, in order of priority - // 1 YEAR + MONTH + DAY_OF_MONTH - // 2 YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK - // 3 YEAR + MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK - // 4 YEAR + DAY_OF_YEAR - // 5 YEAR + DAY_OF_WEEK + WEEK_OF_YEAR - switch (field) - { - case MONTH: // pattern 1,2 or 3 - isSet[DAY_OF_YEAR] = false; - isSet[WEEK_OF_YEAR] = false; - break; - case DAY_OF_MONTH: // pattern 1 - isSet[YEAR] = true; - isSet[MONTH] = true; - isSet[WEEK_OF_MONTH] = true; - isSet[DAY_OF_WEEK] = false; - isSet[DAY_OF_WEEK_IN_MONTH] = false; - isSet[DAY_OF_YEAR] = false; - isSet[WEEK_OF_YEAR] = false; - break; - case WEEK_OF_MONTH: // pattern 2 - if (! isSet[DAY_OF_WEEK]) - fields[DAY_OF_WEEK] = getFirstDayOfWeek(); - isSet[YEAR] = true; - isSet[MONTH] = true; - isSet[DAY_OF_WEEK] = true; - isSet[DAY_OF_MONTH] = false; - isSet[DAY_OF_WEEK_IN_MONTH] = false; - isSet[DAY_OF_YEAR] = false; - isSet[WEEK_OF_YEAR] = false; - break; - case DAY_OF_WEEK_IN_MONTH: // pattern 3 - if (! isSet[DAY_OF_WEEK]) - fields[DAY_OF_WEEK] = getFirstDayOfWeek(); - isSet[YEAR] = true; - isSet[MONTH] = true; - isSet[DAY_OF_WEEK] = true; - isSet[DAY_OF_YEAR] = false; - isSet[DAY_OF_MONTH] = false; - isSet[WEEK_OF_MONTH] = false; - isSet[WEEK_OF_YEAR] = false; - break; - case DAY_OF_YEAR: // pattern 4 - isSet[YEAR] = true; - isSet[MONTH] = false; - isSet[WEEK_OF_MONTH] = false; - isSet[DAY_OF_MONTH] = false; - isSet[DAY_OF_WEEK] = false; - isSet[WEEK_OF_YEAR] = false; - isSet[DAY_OF_WEEK_IN_MONTH] = false; - break; - case WEEK_OF_YEAR: // pattern 5 - if (! isSet[DAY_OF_WEEK]) - fields[DAY_OF_WEEK] = getFirstDayOfWeek(); - isSet[YEAR] = true; - isSet[DAY_OF_WEEK] = true; - isSet[MONTH] = false; - isSet[DAY_OF_MONTH] = false; - isSet[WEEK_OF_MONTH] = false; - isSet[DAY_OF_YEAR] = false; - isSet[DAY_OF_WEEK_IN_MONTH] = false; - break; - case AM_PM: - isSet[HOUR] = true; - isSet[HOUR_OF_DAY] = false; - break; - case HOUR_OF_DAY: - isSet[AM_PM] = false; - isSet[HOUR] = false; - break; - case HOUR: - isSet[AM_PM] = true; - isSet[HOUR_OF_DAY] = false; - break; - case DST_OFFSET: - explicitDSTOffset = true; - } - - // May have crossed over a DST boundary. - if (! explicitDSTOffset && (field != DST_OFFSET && field != ZONE_OFFSET)) - isSet[DST_OFFSET] = false; - } - - /** - * Sets the fields for year, month, and date - * @param year the year. - * @param month the month, one of the constants JANUARY..UNDICEMBER. - * @param date the day of the month - */ - public final void set(int year, int month, int date) - { - isTimeSet = false; - fields[YEAR] = year; - fields[MONTH] = month; - fields[DATE] = date; - isSet[YEAR] = isSet[MONTH] = isSet[DATE] = true; - isSet[WEEK_OF_YEAR] = false; - isSet[DAY_OF_YEAR] = false; - isSet[WEEK_OF_MONTH] = false; - isSet[DAY_OF_WEEK] = false; - isSet[DAY_OF_WEEK_IN_MONTH] = false; - isSet[ERA] = false; - - if (! explicitDSTOffset) - isSet[DST_OFFSET] = false; // May have crossed a DST boundary. - } - - /** - * Sets the fields for year, month, date, hour, and minute - * @param year the year. - * @param month the month, one of the constants JANUARY..UNDICEMBER. - * @param date the day of the month - * @param hour the hour of day. - * @param minute the minute. - */ - public final void set(int year, int month, int date, int hour, int minute) - { - set(year, month, date); - fields[HOUR_OF_DAY] = hour; - fields[MINUTE] = minute; - isSet[HOUR_OF_DAY] = isSet[MINUTE] = true; - isSet[AM_PM] = false; - isSet[HOUR] = false; - } - - /** - * Sets the fields for year, month, date, hour, and minute - * @param year the year. - * @param month the month, one of the constants JANUARY..UNDICEMBER. - * @param date the day of the month - * @param hour the hour of day. - * @param minute the minute. - * @param second the second. - */ - public final void set(int year, int month, int date, int hour, int minute, - int second) - { - set(year, month, date, hour, minute); - fields[SECOND] = second; - isSet[SECOND] = true; - } - - /** - * Clears the values of all the time fields. - */ - public final void clear() - { - isTimeSet = false; - areFieldsSet = false; - int zoneOffs = zone.getRawOffset(); - int[] tempFields = - { - 1, 1970, JANUARY, 1, 1, 1, 1, THURSDAY, 1, AM, 0, 0, 0, - 0, 0, zoneOffs, 0 - }; - fields = tempFields; - for (int i = 0; i < FIELD_COUNT; i++) - isSet[i] = false; - } - - /** - * Clears the values of the specified time field. - * @param field the time field. One of the time field constants. - * @throws ArrayIndexOutOfBoundsException if field is outside - * the valid range. The value of field must be >= 0 and - * <= <code>FIELD_COUNT</code>. - */ - public final void clear(int field) - { - int[] tempFields = - { - 1, 1970, JANUARY, 1, 1, 1, 1, THURSDAY, 1, AM, 0, 0, 0, - 0, 0, zone.getRawOffset(), 0 - }; - complete(); - isTimeSet = false; - areFieldsSet = false; - isSet[field] = false; - fields[field] = tempFields[field]; - } - - /** - * Determines if the specified field has a valid value. - * @return true if the specified field has a value. - * @throws ArrayIndexOutOfBoundsException if the field is outside - * the valid range. The value of field must be >= 0 and - * <= <code>FIELD_COUNT</code>. - */ - public final boolean isSet(int field) - { - return isSet[field]; - } - - /** - * Fills any unset fields in the time field list - */ - protected void complete() - { - if (! isTimeSet) - computeTime(); - if (! areFieldsSet) - computeFields(); - } - - /** - * Compares the given calendar with this. - * @param o the object to that we should compare. - * @return true, if the given object is a calendar, that represents - * the same time (but doesn't necessary have the same fields). - */ - public boolean equals(Object o) - { - if (! (o instanceof Calendar)) - return false; - Calendar cal = (Calendar) o; - if (getTimeInMillis() == ((Calendar) o).getTimeInMillis() - && cal.getFirstDayOfWeek() == getFirstDayOfWeek() - && cal.isLenient() == isLenient() - && cal.getMinimalDaysInFirstWeek() == getMinimalDaysInFirstWeek()) - { - TimeZone self = getTimeZone(); - TimeZone oth = cal.getTimeZone(); - return self == null ? oth == null : self.equals(oth); - } - return false; - } - - /** - * Returns a hash code for this calendar. - * @return a hash code, which fullfits the general contract of - * <code>hashCode()</code> - */ - public int hashCode() - { - long time = getTimeInMillis(); - int val = (int) ((time & 0xffffffffL) ^ (time >> 32)); - val += (getFirstDayOfWeek() + (isLenient() ? 1230 : 1237) - + getMinimalDaysInFirstWeek()); - TimeZone self = getTimeZone(); - if (self != null) - val ^= self.hashCode(); - return val; - } - - /** - * Compares the given calendar with this. - * @param o the object to that we should compare. - * @return true, if the given object is a calendar, and this calendar - * represents a smaller time than the calendar o. - * @exception ClassCastException if o is not an calendar. - * @since JDK1.2 you don't need to override this method - */ - public boolean before(Object o) - { - return getTimeInMillis() < ((Calendar) o).getTimeInMillis(); - } - - /** - * Compares the given calendar with this. - * @param o the object to that we should compare. - * @return true, if the given object is a calendar, and this calendar - * represents a bigger time than the calendar o. - * @exception ClassCastException if o is not an calendar. - * @since JDK1.2 you don't need to override this method - */ - public boolean after(Object o) - { - return getTimeInMillis() > ((Calendar) o).getTimeInMillis(); - } - - /** - * Adds the specified amount of time to the given time field. The - * amount may be negative to subtract the time. If the field overflows - * it does what you expect: Jan, 25 + 10 Days is Feb, 4. - * @param field the time field. One of the time field constants. - * @param amount the amount of time. - * @throws ArrayIndexOutOfBoundsException if the field is outside - * the valid range. The value of field must be >= 0 and - * <= <code>FIELD_COUNT</code>. - */ - public abstract void add(int field, int amount); - - /** - * Rolls the specified time field up or down. This means add one - * to the specified field, but don't change the other fields. If - * the maximum for this field is reached, start over with the - * minimum value. <br> - * - * <strong>Note:</strong> There may be situation, where the other - * fields must be changed, e.g rolling the month on May, 31. - * The date June, 31 is automatically converted to July, 1. - * @param field the time field. One of the time field constants. - * @param up the direction, true for up, false for down. - * @throws ArrayIndexOutOfBoundsException if the field is outside - * the valid range. The value of field must be >= 0 and - * <= <code>FIELD_COUNT</code>. - */ - public abstract void roll(int field, boolean up); - - /** - * Rolls up or down the specified time field by the given amount. - * A negative amount rolls down. The default implementation is - * call <code>roll(int, boolean)</code> for the specified amount. - * - * Subclasses should override this method to do more intuitiv things. - * - * @param field the time field. One of the time field constants. - * @param amount the amount to roll by, positive for rolling up, - * negative for rolling down. - * @throws ArrayIndexOutOfBoundsException if the field is outside - * the valid range. The value of field must be >= 0 and - * <= <code>FIELD_COUNT</code>. - * @since JDK1.2 - */ - public void roll(int field, int amount) - { - while (amount > 0) - { - roll(field, true); - amount--; - } - while (amount < 0) - { - roll(field, false); - amount++; - } - } - - /** - * Sets the time zone to the specified value. - * @param zone the new time zone - */ - public void setTimeZone(TimeZone zone) - { - this.zone = zone; - computeTime(); - computeFields(); - } - - /** - * Gets the time zone of this calendar - * @return the current time zone. - */ - public TimeZone getTimeZone() - { - return zone; - } - - /** - * Specifies if the date/time interpretation should be lenient. - * If the flag is set, a date such as "February 30, 1996" will be - * treated as the 29th day after the February 1. If this flag - * is false, such dates will cause an exception. - * @param lenient true, if the date should be interpreted linient, - * false if it should be interpreted strict. - */ - public void setLenient(boolean lenient) - { - this.lenient = lenient; - } - - /** - * Tells if the date/time interpretation is lenient. - * @return true, if the date should be interpreted linient, - * false if it should be interpreted strict. - */ - public boolean isLenient() - { - return lenient; - } - - /** - * Sets what the first day of week is. This is used for - * WEEK_OF_MONTH and WEEK_OF_YEAR fields. - * @param value the first day of week. One of SUNDAY to SATURDAY. - */ - public void setFirstDayOfWeek(int value) - { - firstDayOfWeek = value; - } - - /** - * Gets what the first day of week is. This is used for - * WEEK_OF_MONTH and WEEK_OF_YEAR fields. - * @return the first day of week. One of SUNDAY to SATURDAY. - */ - public int getFirstDayOfWeek() - { - return firstDayOfWeek; - } - - /** - * Sets how many days are required in the first week of the year. - * If the first day of the year should be the first week you should - * set this value to 1. If the first week must be a full week, set - * it to 7. - * @param value the minimal days required in the first week. - */ - public void setMinimalDaysInFirstWeek(int value) - { - minimalDaysInFirstWeek = value; - } - - /** - * Gets how many days are required in the first week of the year. - * @return the minimal days required in the first week. - * @see #setMinimalDaysInFirstWeek - */ - public int getMinimalDaysInFirstWeek() - { - return minimalDaysInFirstWeek; - } - - /** - * Gets the smallest value that is allowed for the specified field. - * @param field the time field. One of the time field constants. - * @return the smallest value. - */ - public abstract int getMinimum(int field); - - /** - * Gets the biggest value that is allowed for the specified field. - * @param field the time field. One of the time field constants. - * @return the biggest value. - */ - public abstract int getMaximum(int field); - - /** - * Gets the greatest minimum value that is allowed for the specified field. - * @param field the time field. One of the time field constants. - * @return the greatest minimum value. - */ - public abstract int getGreatestMinimum(int field); - - /** - * Gets the smallest maximum value that is allowed for the - * specified field. For example this is 28 for DAY_OF_MONTH. - * @param field the time field. One of the time field constants. - * @return the least maximum value. - */ - public abstract int getLeastMaximum(int field); - - /** - * Gets the actual minimum value that is allowed for the specified field. - * This value is dependent on the values of the other fields. - * @param field the time field. One of the time field constants. - * @return the actual minimum value. - * @throws ArrayIndexOutOfBoundsException if the field is outside - * the valid range. The value of field must be >= 0 and - * <= <code>FIELD_COUNT</code>. - * @since jdk1.2 - */ - public int getActualMinimum(int field) - { - Calendar tmp = (Calendar) clone(); // To avoid restoring state - int min = tmp.getGreatestMinimum(field); - int end = tmp.getMinimum(field); - tmp.set(field, min); - for (; min > end; min--) - { - tmp.add(field, -1); // Try to get smaller - if (tmp.get(field) != min - 1) - break; // Done if not successful - } - return min; - } - - /** - * Gets the actual maximum value that is allowed for the specified field. - * This value is dependent on the values of the other fields. - * @param field the time field. One of the time field constants. - * @return the actual maximum value. - * @throws ArrayIndexOutOfBoundsException if the field is outside - * the valid range. The value of field must be >= 0 and - * <= <code>FIELD_COUNT</code>. - * @since jdk1.2 - */ - public int getActualMaximum(int field) - { - Calendar tmp = (Calendar) clone(); // To avoid restoring state - int max = tmp.getLeastMaximum(field); - int end = tmp.getMaximum(field); - tmp.set(field, max); - for (; max < end; max++) - { - tmp.add(field, 1); - if (tmp.get(field) != max + 1) - break; - } - return max; - } - - /** - * Compares the time of two calendar instances. - * @param cal the calendar to which the time should be compared. - * @return 0 if the two calendars are set to the same time, - * less than 0 if the time of this calendar is before that of - * <code>cal</code>, or more than 0 if the time of this calendar is after - * that of <code>cal</code>. - * - * @param cal the calendar to compare this instance with. - * @throws NullPointerException if <code>cal</code> is null. - * @throws IllegalArgumentException if either calendar has fields set to - * invalid values. - * @since 1.5 - */ - public int compareTo(Calendar cal) - { - long t1 = getTimeInMillis(); - long t2 = cal.getTimeInMillis(); - if(t1 == t2) - return 0; - if(t1 > t2) - return 1; - return -1; - } - - /** - * Return a clone of this object. - */ - public Object clone() - { - try - { - Calendar cal = (Calendar) super.clone(); - cal.fields = (int[]) fields.clone(); - cal.isSet = (boolean[]) isSet.clone(); - return cal; - } - catch (CloneNotSupportedException ex) - { - return null; - } - } - - private static final String[] fieldNames = - { - ",ERA=", ",YEAR=", ",MONTH=", - ",WEEK_OF_YEAR=", - ",WEEK_OF_MONTH=", - ",DAY_OF_MONTH=", - ",DAY_OF_YEAR=", ",DAY_OF_WEEK=", - ",DAY_OF_WEEK_IN_MONTH=", - ",AM_PM=", ",HOUR=", - ",HOUR_OF_DAY=", ",MINUTE=", - ",SECOND=", ",MILLISECOND=", - ",ZONE_OFFSET=", ",DST_OFFSET=" - }; - - /** - * Returns a string representation of this object. It is mainly - * for debugging purposes and its content is implementation - * specific. - */ - public String toString() - { - CPStringBuilder sb = new CPStringBuilder(getClass().getName()); - sb.append('['); - sb.append("time="); - if (isTimeSet) - sb.append(time); - else - sb.append("?"); - sb.append(",zone=" + zone); - sb.append(",areFieldsSet=" + areFieldsSet); - for (int i = 0; i < FIELD_COUNT; i++) - { - sb.append(fieldNames[i]); - if (isSet[i]) - sb.append(fields[i]); - else - sb.append("?"); - } - sb.append(",lenient=").append(lenient); - sb.append(",firstDayOfWeek=").append(firstDayOfWeek); - sb.append(",minimalDaysInFirstWeek=").append(minimalDaysInFirstWeek); - sb.append("]"); - return sb.toString(); - } - - /** - * Saves the state of the object to the stream. Ideally we would - * only write the time field, but we need to be compatible with - * earlier versions. <br> - * - * This doesn't write the JDK1.1 field nextStamp to the stream, as - * I don't know what it is good for, and because the documentation - * says, that it could be omitted. */ - private void writeObject(ObjectOutputStream stream) throws IOException - { - if (! isTimeSet) - computeTime(); - stream.defaultWriteObject(); - } - - /** - * Reads the object back from stream (deserialization). - */ - private void readObject(ObjectInputStream stream) - throws IOException, ClassNotFoundException - { - stream.defaultReadObject(); - if (! isTimeSet) - computeTime(); - - if (serialVersionOnStream > 1) - { - // This is my interpretation of the serial number: - // Sun wants to remove all fields from the stream someday - // and will then increase the serialVersion number again. - // We prepare to be compatible. - fields = new int[FIELD_COUNT]; - isSet = new boolean[FIELD_COUNT]; - areFieldsSet = false; - } - } - - /** - * Returns a localised textual representation of the current value - * of the given field using the specified style. If there is no - * applicable textual representation (e.g. the field has a numeric - * value), then <code>null</code> is returned. If one does exist, - * then the value is obtained from {@link #get(int)} and converted - * appropriately. For example, if the <code>MONTH</code> field is - * requested, then <code>get(MONTH)</code> is called. This is then - * converted to a textual representation based on its value and - * the style requested; if the <code>LONG</code> style is requested - * and the returned value is <code>11</code> from a - * {@link GregorianCalendar} implementation, then <code>"December"</code> - * is returned. By default, a textual representation is available - * for all fields which have an applicable value obtainable from - * {@link java.text.DateFormatSymbols}. - * - * @param field the calendar field whose textual representation should - * be obtained. - * @param style the style to use; either {@link #LONG} or {@link #SHORT}. - * @param locale the locale to use for translation. - * @return the textual representation of the given field in the specified - * style, or <code>null</code> if none is applicable. - * @throws IllegalArgumentException if <code>field</code> or <code>style</code> - * or invalid, or the calendar is non-lenient - * and has invalid values. - * @throws NullPointerException if <code>locale</code> is <code>null</code>. - * @since 1.6 - */ - public String getDisplayName(int field, int style, Locale locale) - { - if (field < 0 || field >= FIELD_COUNT) - throw new IllegalArgumentException("The field value, " + field + - ", is invalid."); - if (style != SHORT && style != LONG) - throw new IllegalArgumentException("The style must be either " + - "short or long."); - if (field == YEAR || field == WEEK_OF_YEAR || - field == WEEK_OF_MONTH || field == DAY_OF_MONTH || - field == DAY_OF_YEAR || field == DAY_OF_WEEK_IN_MONTH || - field == HOUR || field == HOUR_OF_DAY || field == MINUTE || - field == SECOND || field == MILLISECOND) - return null; - - int value = get(field); - DateFormatSymbols syms = DateFormatSymbols.getInstance(locale); - if (field == ERA) - return syms.getEras()[value]; - if (field == MONTH) - if (style == LONG) - return syms.getMonths()[value]; - else - return syms.getShortMonths()[value]; - if (field == DAY_OF_WEEK) - if (style == LONG) - return syms.getWeekdays()[value]; - else - return syms.getShortWeekdays()[value]; - if (field == AM_PM) - return syms.getAmPmStrings()[value]; - if (field == ZONE_OFFSET) - if (style == LONG) - return syms.getZoneStrings()[value][1]; - else - return syms.getZoneStrings()[value][2]; - if (field == DST_OFFSET) - if (style == LONG) - return syms.getZoneStrings()[value][3]; - else - return syms.getZoneStrings()[value][4]; - - throw new InternalError("Failed to resolve field " + field + - " with style " + style + " for locale " + - locale); - } - - /** - * Returns a map linking all specified textual representations - * of the given field to their numerical values. The textual - * representations included are determined by the specified - * style and locale. For example, if the style <code>LONG</code> - * is specified and the German locale, then the map will - * contain "Montag" to {@link #MONDAY}, "Dienstag" to - * {@link #TUESDAY}, "Mittwoch" to {@link #WEDNESDAY} and - * so on. The default implementation uses the values returned - * by {@link DateFormatSymbols} so, for example, the style - * {@link #ALL_STYLES} and the field {@link #MONTH} will return - * a map filled with the values returned from - * {@link DateFormatSymbols#getMonths()} and - * {@link DateFormatSymbols#getShortMonths()}. If there are - * no textual representations for a given field (usually because - * it is purely numeric, such as the year in the - * {@link GregorianCalendar}), <code>null</code> is returned. - * - * @param field the calendar field whose textual representation should - * be obtained. - * @param style the style to use; either {@link #LONG}, {@link #SHORT} - * or {@link ALL_STYLES}. - * @param locale the locale to use for translation. - * @return a map of the textual representations of the given field in the - * specified style to their numeric values, or <code>null</code> - * if none is applicable. - * @throws IllegalArgumentException if <code>field</code> or <code>style</code> - * or invalid, or the calendar is non-lenient - * and has invalid values. - * @throws NullPointerException if <code>locale</code> is <code>null</code>. - * @since 1.6 - */ - public Map<String,Integer> getDisplayNames(int field, int style, Locale locale) - { - if (field < 0 || field >= FIELD_COUNT) - throw new IllegalArgumentException("The field value, " + field + - ", is invalid."); - if (style != SHORT && style != LONG && style != ALL_STYLES) - throw new IllegalArgumentException("The style must be either " + - "short, long or all styles."); - if (field == YEAR || field == WEEK_OF_YEAR || - field == WEEK_OF_MONTH || field == DAY_OF_MONTH || - field == DAY_OF_YEAR || field == DAY_OF_WEEK_IN_MONTH || - field == HOUR || field == HOUR_OF_DAY || field == MINUTE || - field == SECOND || field == MILLISECOND) - return null; - - DateFormatSymbols syms = DateFormatSymbols.getInstance(locale); - Map<String,Integer> map = new HashMap<String,Integer>(); - if (field == ERA) - { - String[] eras = syms.getEras(); - for (int a = 0; a < eras.length; ++a) - map.put(eras[a], a); - return map; - } - if (field == MONTH) - { - if (style == LONG || style == ALL_STYLES) - { - String[] months = syms.getMonths(); - for (int a = 0; a < months.length; ++a) - map.put(months[a], a); - } - if (style == SHORT || style == ALL_STYLES) - { - String[] months = syms.getShortMonths(); - for (int a = 0; a < months.length; ++a) - map.put(months[a], a); - } - return map; - } - if (field == DAY_OF_WEEK) - { - if (style == LONG || style == ALL_STYLES) - { - String[] weekdays = syms.getWeekdays(); - for (int a = SUNDAY; a < weekdays.length; ++a) - map.put(weekdays[a], a); - } - if (style == SHORT || style == ALL_STYLES) - { - String[] weekdays = syms.getShortWeekdays(); - for (int a = SUNDAY; a < weekdays.length; ++a) - map.put(weekdays[a], a); - } - return map; - } - if (field == AM_PM) - { - String[] ampms = syms.getAmPmStrings(); - for (int a = 0; a < ampms.length; ++a) - map.put(ampms[a], a); - return map; - } - if (field == ZONE_OFFSET) - { - String[][] zones = syms.getZoneStrings(); - for (int a = 0; a < zones.length; ++a) - { - if (style == LONG || style == ALL_STYLES) - map.put(zones[a][1], a); - if (style == SHORT || style == ALL_STYLES) - map.put(zones[a][2], a); - } - return map; - } - if (field == DST_OFFSET) - { - String[][] zones = syms.getZoneStrings(); - for (int a = 0; a < zones.length; ++a) - { - if (style == LONG || style == ALL_STYLES) - map.put(zones[a][3], a); - if (style == SHORT || style == ALL_STYLES) - map.put(zones[a][4], a); - } - return map; - } - - throw new InternalError("Failed to resolve field " + field + - " with style " + style + " for locale " + - locale); - } - -} diff --git a/libjava/classpath/java/util/Collection.java b/libjava/classpath/java/util/Collection.java deleted file mode 100644 index b57566f..0000000 --- a/libjava/classpath/java/util/Collection.java +++ /dev/null @@ -1,290 +0,0 @@ -/* Collection.java -- Interface that represents a collection of objects - 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; - -/** - * 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) - * @author Tom Tromey (tromey@redhat.com) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @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<E> extends Iterable<E> -{ - /** - * 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(E 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<? extends E> 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<E> 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. - */ - <T> T[] toArray(T[] a); -} diff --git a/libjava/classpath/java/util/Collections.java b/libjava/classpath/java/util/Collections.java deleted file mode 100644 index b970dd8..0000000 --- a/libjava/classpath/java/util/Collections.java +++ /dev/null @@ -1,7627 +0,0 @@ -/* Collections.java -- Utility class with methods to operate on collections - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006 - 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 gnu.java.lang.CPStringBuilder; - -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) - * @author Tom Tromey (tromey@redhat.com) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @see Collection - * @see Set - * @see List - * @see Map - * @see Arrays - * @since 1.2 - * @status updated to 1.5 - */ -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(); - - /** - * Returns an immutable, serializable parameterized empty set. - * Unlike the constant <code>EMPTY_SET</code>, the set returned by - * this method is type-safe. - * - * @return an empty parameterized set. - * @since 1.5 - */ - @SuppressWarnings("unchecked") - public static final <T> Set<T> emptySet() - { - return (Set<T>) EMPTY_SET; - } - - /** - * 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<T> extends AbstractSet<T> - 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. - @SuppressWarnings("unchecked") - public Iterator<T> iterator() - { - return (Iterator<T>) 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 <E> E[] toArray(E[] 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(); - - /** - * Returns an immutable, serializable parameterized empty list. - * Unlike the constant <code>EMPTY_LIST</code>, the list returned by - * this method is type-safe. - * - * @return an empty parameterized list. - * @since 1.5 - */ - @SuppressWarnings("unchecked") - public static final <T> List<T> emptyList() - { - return (List<T>) EMPTY_LIST; - } - - /** - * 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<T> extends AbstractList<T> - 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 T 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 <E> E[] toArray(E[] 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(); - - /** - * Returns an immutable, serializable parameterized empty map. - * Unlike the constant <code>EMPTY_MAP</code>, the map returned by - * this method is type-safe. - * - * @return an empty parameterized map. - * @since 1.5 - */ - @SuppressWarnings("unchecked") - public static final <K,V> Map<K,V> emptyMap() - { - return (Map<K,V>) EMPTY_MAP; - } - - /** - * 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<K, V> extends AbstractMap<K, V> - 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. - */ - @SuppressWarnings("unchecked") - public Set<Map.Entry<K, V>> entrySet() - { - return (Set<Map.Entry<K, V>>) 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 V get(Object o) - { - return null; - } - - /** - * The hashcode is always 0. - * @return 0. - */ - public int hashCode() - { - return 0; - } - - /** - * No entries. - * @return The empty set. - */ - @SuppressWarnings("unchecked") - public Set<K> keySet() - { - return (Set<K>) 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 V 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. - */ - @SuppressWarnings("unchecked") - public Collection<V> values() - { - return (Collection<V>) 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 <T> int compare(T o1, T o2, Comparator<? super T> 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 <T> int binarySearch(List<? extends Comparable<? super T>> l, - T 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 <T> int binarySearch(List<? extends T> l, T key, - Comparator<? super T> 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<T> itr = ((List<T>) l).listIterator(); - int i = 0; - T 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(o, key, 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(((List<T>) l).get(pos), key, 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 <T> void copy(List<? super T> dest, List<? extends T> source) - { - int pos = source.size(); - if (dest.size() < pos) - throw new IndexOutOfBoundsException("Source does not fit in dest"); - - Iterator<? extends T> i1 = source.iterator(); - ListIterator<? super T> 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 <T> Enumeration<T> enumeration(Collection<T> c) - { - final Iterator<T> i = c.iterator(); - return new Enumeration<T>() - { - /** - * 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 T 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 <T> void fill(List<? super T> l, T val) - { - ListIterator<? super T> 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 <T> ArrayList<T> list(Enumeration<T> e) - { - ArrayList<T> l = new ArrayList<T>(); - 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 <T extends Object & Comparable<? super T>> - T max(Collection<? extends T> 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 <T> T max(Collection<? extends T> c, - Comparator<? super T> order) - { - Iterator<? extends T> itr = c.iterator(); - T max = itr.next(); // throws NoSuchElementException - int csize = c.size(); - for (int i = 1; i < csize; i++) - { - T 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 <T extends Object & Comparable<? super T>> - T min(Collection<? extends T> 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 <T> T min(Collection<? extends T> c, - Comparator<? super T> order) - { - Iterator<? extends T> itr = c.iterator(); - T min = itr.next(); // throws NoSuchElementExcception - int csize = c.size(); - for (int i = 1; i < csize; i++) - { - T 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 <T> List<T> nCopies(final int n, final T o) - { - return new CopiesList<T>(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<T> extends AbstractList<T> - 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 T element; - - /** - * Constructs the list. - * - * @param n the count - * @param o the object - * @throws IllegalArgumentException if n < 0 - */ - CopiesList(int n, T 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 T 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<T> subList(int from, int to) - { - if (from < 0 || to > n) - throw new IndexOutOfBoundsException(); - return new CopiesList<T>(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() - { - CPStringBuilder r = new CPStringBuilder("{"); - 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 <T> boolean replaceAll(List<T> list, T oldval, T newval) - { - ListIterator<T> 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 o1 = i1.next(); - Object o2 = i2.previous(); - i1.set(o2); - i2.set(o1); - ++pos1; - --pos2; - } - } - - /** - * Get a comparator that implements the reverse of the ordering - * specified by the given Comparator. If the Comparator is null, - * this is equivalent to {@link #reverseOrder()}. The return value - * of this method is Serializable, if the specified Comparator is - * either Serializable or null. - * - * @param c the comparator to invert - * @return a comparator that imposes reverse ordering - * @see Comparable - * @see Serializable - * - * @since 1.5 - */ - public static <T> Comparator<T> reverseOrder(final Comparator<T> c) - { - if (c == null) - return (Comparator<T>) rcInstance; - return new ReverseComparator<T> () - { - public int compare(T a, T b) - { - return - c.compare(a, b); - } - }; - } - - /** - * 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 <T> Comparator<T> reverseOrder() - { - return (Comparator<T>) 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 class ReverseComparator<T> - implements Comparator<T>, 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(T a, T 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. - List<Object> objList = (List<Object>) list; - while (--lcm >= 0) - { - Object o = objList.get(lcm); - for (int i = lcm + distance; i != lcm; i = (i + distance) % size) - o = objList.set(i, o); - objList.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(); - List<Object> list = (List<Object>) l; - ListIterator<Object> i = list.listIterator(lsize); - boolean sequential = isSequential(l); - Object[] a = null; // stores a copy of the list for the sequential case - - if (sequential) - a = list.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 = list.set(swap, i.previous()); - - i.set(o); - } - } - - /** - * Returns the frequency of the specified object within the supplied - * collection. The frequency represents the number of occurrences of - * elements within the collection which return <code>true</code> when - * compared with the object using the <code>equals</code> method. - * - * @param c the collection to scan for occurrences of the object. - * @param o the object to locate occurrances of within the collection. - * @throws NullPointerException if the collection is <code>null</code>. - * @since 1.5 - */ - public static int frequency (Collection<?> c, Object o) - { - int result = 0; - final Iterator<?> it = c.iterator(); - while (it.hasNext()) - { - Object v = it.next(); - if (AbstractCollection.equals(o, v)) - ++result; - } - return result; - } - - /** - * Adds all the specified elements to the given collection, in a similar - * way to the <code>addAll</code> method of the <code>Collection</code>. - * However, this is a variable argument method which allows the new elements - * to be specified individually or in array form, as opposed to the list - * required by the collection's <code>addAll</code> method. This has - * benefits in both simplicity (multiple elements can be added without - * having to be wrapped inside a grouping structure) and efficiency - * (as a redundant list doesn't have to be created to add an individual - * set of elements or an array). - * - * @param c the collection to which the elements should be added. - * @param a the elements to be added to the collection. - * @return true if the collection changed its contents as a result. - * @throws UnsupportedOperationException if the collection does not support - * addition. - * @throws NullPointerException if one or more elements in a are null, - * and the collection does not allow null - * elements. This exception is also thrown - * if either <code>c</code> or <code>a</code> - * are null. - * @throws IllegalArgumentException if the collection won't allow an element - * to be added for some other reason. - * @since 1.5 - */ - public static <T> boolean addAll(Collection<? super T> c, T... a) - { - boolean overall = false; - - for (T element : a) - { - boolean result = c.add(element); - if (result) - overall = true; - } - return overall; - } - - /** - * Returns true if the two specified collections have no elements in - * common. This method may give unusual results if one or both collections - * use a non-standard equality test. In the trivial case of comparing - * a collection with itself, this method returns true if, and only if, - * the collection is empty. - * - * @param c1 the first collection to compare. - * @param c2 the second collection to compare. - * @return true if the collections are disjoint. - * @throws NullPointerException if either collection is null. - * @since 1.5 - */ - public static boolean disjoint(Collection<?> c1, Collection<?> c2) - { - Collection<Object> oc1 = (Collection<Object>) c1; - final Iterator<Object> it = oc1.iterator(); - while (it.hasNext()) - if (c2.contains(it.next())) - return false; - return true; - } - - - /** - * 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 <T> Set<T> singleton(T o) - { - return new SingletonSet<T>(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<T> extends AbstractSet<T> - 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 T element; - - /** - * Construct a singleton. - * @param o the element - */ - SingletonSet(T o) - { - element = o; - } - - /** - * The size: always 1! - * @return 1. - */ - public int size() - { - return 1; - } - - /** - * Returns an iterator over the lone element. - */ - public Iterator<T> iterator() - { - return new Iterator<T>() - { - /** - * 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 T 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 <T> List<T> singletonList(T o) - { - return new SingletonList<T>(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<T> extends AbstractList<T> - implements Serializable, RandomAccess - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 3093736618740652951L; - - /** - * The single element. - * @serial the singleton - */ - private final T element; - - /** - * Construct a singleton. - * @param o the element - */ - SingletonList(T 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 T 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<T> subList(int from, int to) - { - if (from == to && (to == 0 || to == 1)) - return emptyList(); - 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 <K, V> Map<K, V> singletonMap(K key, V value) - { - return new SingletonMap<K, V>(key, value); - } - - /** - * The implementation of {@link #singletonMap(Object, 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<K, V> extends AbstractMap<K, V> - implements Serializable - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = -6979724477215052911L; - - /** - * The single key. - * @serial the singleton key - */ - private final K k; - - /** - * The corresponding value. - * @serial the singleton value - */ - private final V v; - - /** - * Cache the entry set. - */ - private transient Set<Map.Entry<K, V>> entries; - - /** - * Construct a singleton. - * @param key the key - * @param value the value - */ - SingletonMap(K key, V value) - { - k = key; - v = value; - } - - /** - * There is a single immutable entry. - * - * @return A singleton containing the map entry. - */ - public Set<Map.Entry<K, V>> entrySet() - { - if (entries == null) - { - Map.Entry<K,V> entry = new AbstractMap.SimpleEntry<K, V>(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 V setValue(V o) - { - throw new UnsupportedOperationException(); - } - }; - entries = singleton(entry); - } - 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 V 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<K> 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<V> 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 (<code>null</code> not permitted) - * @throws ClassCastException if some items are not mutually comparable - * @throws UnsupportedOperationException if the List is not modifiable - * @throws NullPointerException if the list is <code>null</code>, or contains - * some element that is <code>null</code>. - * @see Arrays#sort(Object[]) - */ - public static <T extends Comparable<? super T>> void sort(List<T> 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 (<code>null</code> not permitted) - * @param c the Comparator specifying the ordering for the elements, or - * <code>null</code> 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 the List is <code>null</code> or - * <code>null</code> is compared by natural ordering (only possible - * when c is <code>null</code>) - * - * @see Arrays#sort(Object[], Comparator) - */ - public static <T> void sort(List<T> l, Comparator<? super T> c) - { - T[] a = (T[]) l.toArray(); - Arrays.sort(a, c); - ListIterator<T> 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) - { - List<Object> list = (List<Object>) l; - list.set(i, list.set(j, list.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 <T> Collection<T> synchronizedCollection(Collection<T> c) - { - return new SynchronizedCollection<T>(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<T> - implements Collection<T>, 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<T> 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<T> 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<T> 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(T 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<? extends T> 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 c1 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<T> iterator() - { - synchronized (mutex) - { - return new SynchronizedIterator<T>(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 <E> E[] toArray(E[] 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<T> implements Iterator<T> - { - /** - * The object to synchronize on. Package visible for use by subclass. - */ - final Object mutex; - - /** - * The wrapped iterator. - */ - private final Iterator<T> i; - - /** - * Only trusted code creates a wrapper, with the specified sync. - * @param sync the mutex - * @param i the wrapped iterator - */ - SynchronizedIterator(Object sync, Iterator<T> 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 T 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 <T> List<T> synchronizedList(List<T> l) - { - if (l instanceof RandomAccess) - return new SynchronizedRandomAccessList<T>(l); - return new SynchronizedList<T>(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<T> extends SynchronizedCollection<T> - implements List<T> - { - /** - * 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<T> list; - - /** - * Wrap a given list. - * @param l the list to wrap - * @throws NullPointerException if l is null - */ - SynchronizedList(List<T> 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<T> 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, T o) - { - synchronized (mutex) - { - list.add(index, o); - } - } - - /** - * Add the contents of a collection to the underlying list at the given - * index (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 index the index at which to insert - * @param c the collection 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<? extends T> 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 T 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<T> listIterator() - { - synchronized (mutex) - { - return new SynchronizedListIterator<T>(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<T> listIterator(int index) - { - synchronized (mutex) - { - return new SynchronizedListIterator<T>(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 T 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 T set(int index, T 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<T> subList(int fromIndex, int toIndex) - { - synchronized (mutex) - { - return new SynchronizedList<T>(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<T> - extends SynchronizedList<T> 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<T> 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<T> 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<T> subList(int fromIndex, int toIndex) - { - synchronized (mutex) - { - return new SynchronizedRandomAccessList<T>(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<T> - extends SynchronizedIterator<T> implements ListIterator<T> - { - /** - * The wrapped iterator, stored both here and in the superclass to - * avoid excessive casting. - */ - private final ListIterator<T> li; - - /** - * Only trusted code creates a wrapper, with the specified sync. - * @param sync the mutex - * @param li the wrapped iterator - */ - SynchronizedListIterator(Object sync, ListIterator<T> 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(T 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 T 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(T 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 <K, V> Map<K, V> synchronizedMap(Map<K, V> m) - { - return new SynchronizedMap<K, V>(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<K, V> implements Map<K, V>, Serializable - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 1978198479659022715L; - - /** - * The wrapped map. - * @serial the real map - */ - private final Map<K, V> 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<Map.Entry<K, V>> entries; - - /** - * Cache the key set. - */ - private transient Set<K> keys; - - /** - * Cache the value collection. - */ - private transient Collection<V> values; - - /** - * Wrap a given map. - * @param m the map to wrap - * @throws NullPointerException if m is null - */ - SynchronizedMap(Map<K, V> 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<K, V> 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<Map.Entry<K, V>> entrySet() - { - // Define this here to spare some nesting. - class SynchronizedMapEntry<K, V> implements Map.Entry<K, V> - { - final Map.Entry<K, V> e; - SynchronizedMapEntry(Map.Entry<K, V> o) - { - e = 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 K 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 V 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 V setValue(V 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<Map.Entry<K, V>>(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<Map.Entry<K, V>> iterator() - { - synchronized (super.mutex) - { - return new SynchronizedIterator<Map.Entry<K, V>>(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 Map.Entry<K, V> next() - { - synchronized (super.mutex) - { - return new SynchronizedMapEntry<K, V>(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 V 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<K> keySet() - { - if (keys == null) - synchronized (mutex) - { - keys = new SynchronizedSet<K>(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 V put(K key, V 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 map 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<? extends K, ? extends V> 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 o 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 V 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<V> values() - { - if (values == null) - synchronized (mutex) - { - values = new SynchronizedCollection<V>(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 <T> Set<T> synchronizedSet(Set<T> s) - { - return new SynchronizedSet<T>(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<T> extends SynchronizedCollection<T> - implements Set<T> - { - /** - * 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<T> 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<T> 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 <K, V> SortedMap<K, V> synchronizedSortedMap(SortedMap<K, V> m) - { - return new SynchronizedSortedMap<K, V>(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<K, V> - extends SynchronizedMap<K, V> - implements SortedMap<K, V> - { - /** - * 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<K, V> sm; - - /** - * Wrap a given map. - * @param sm the map to wrap - * @throws NullPointerException if sm is null - */ - SynchronizedSortedMap(SortedMap<K, V> 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<K, V> 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<? super K> 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 K 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<K, V> headMap(K toKey) - { - synchronized (mutex) - { - return new SynchronizedSortedMap<K, V>(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 K 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<K, V> subMap(K fromKey, K toKey) - { - synchronized (mutex) - { - return new SynchronizedSortedMap<K, V>(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<K, V> tailMap(K fromKey) - { - synchronized (mutex) - { - return new SynchronizedSortedMap<K, V>(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 <T> SortedSet<T> synchronizedSortedSet(SortedSet<T> s) - { - return new SynchronizedSortedSet<T>(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<T> - extends SynchronizedSet<T> - implements SortedSet<T> - { - /** - * 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<T> ss; - - /** - * Wrap a given set. - * @param ss the set to wrap - * @throws NullPointerException if ss is null - */ - SynchronizedSortedSet(SortedSet<T> 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 ss the set - */ - SynchronizedSortedSet(Object sync, SortedSet<T> 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<? super T> 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 T 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<T> headSet(T toElement) - { - synchronized (mutex) - { - return new SynchronizedSortedSet<T>(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 T 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<T> subSet(T fromElement, T toElement) - { - synchronized (mutex) - { - return new SynchronizedSortedSet<T>(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<T> tailSet(T fromElement) - { - synchronized (mutex) - { - return new SynchronizedSortedSet<T>(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 <T> Collection<T> unmodifiableCollection(Collection<? extends T> c) - { - return new UnmodifiableCollection<T>(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<T> - implements Collection<T>, 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<? extends T> c; - - /** - * Wrap a given collection. - * @param c the collection to wrap - * @throws NullPointerException if c is null - */ - UnmodifiableCollection(Collection<? extends T> 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(T 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<? extends T> 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 c1 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<T> iterator() - { - return new UnmodifiableIterator<T>(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 <S> S[] toArray(S[] 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<T> implements Iterator<T> - { - /** - * The wrapped iterator. - */ - private final Iterator<? extends T> i; - - /** - * Only trusted code creates a wrapper. - * @param i the wrapped iterator - */ - UnmodifiableIterator(Iterator<? extends T> 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 T 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 <T> List<T> unmodifiableList(List<? extends T> l) - { - if (l instanceof RandomAccess) - return new UnmodifiableRandomAccessList<T>(l); - return new UnmodifiableList<T>(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<T> extends UnmodifiableCollection<T> - implements List<T> - { - /** - * 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<T> list; - - /** - * Wrap a given list. - * @param l the list to wrap - * @throws NullPointerException if l is null - */ - UnmodifiableList(List<? extends T> l) - { - super(l); - list = (List<T>) 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, T 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<? extends T> 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 T 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<T> listIterator() - { - return new UnmodifiableListIterator<T>(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<T> listIterator(int index) - { - return new UnmodifiableListIterator<T>(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 T 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 T set(int index, T 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<T> 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<T> - extends UnmodifiableList<T> 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<? extends T> l) - { - super(l); - } - } // class UnmodifiableRandomAccessList - - /** - * The implementation of {@link UnmodifiableList#listIterator()}. - * - * @author Eric Blake (ebb9@email.byu.edu) - */ - private static final class UnmodifiableListIterator<T> - extends UnmodifiableIterator<T> implements ListIterator<T> - { - /** - * The wrapped iterator, stored both here and in the superclass to - * avoid excessive casting. - */ - private final ListIterator<T> li; - - /** - * Only trusted code creates a wrapper. - * @param li the wrapped iterator - */ - UnmodifiableListIterator(ListIterator<T> 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(T 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 T 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(T 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 <K, V> Map<K, V> unmodifiableMap(Map<? extends K, - ? extends V> m) - { - return new UnmodifiableMap<K, V>(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<K, V> implements Map<K, V>, Serializable - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = -1034234728574286014L; - - /** - * The wrapped map. - * @serial the real map - */ - private final Map<K, V> m; - - /** - * Cache the entry set. - */ - private transient Set<Map.Entry<K, V>> entries; - - /** - * Cache the key set. - */ - private transient Set<K> keys; - - /** - * Cache the value collection. - */ - private transient Collection<V> values; - - /** - * Wrap a given map. - * @param m the map to wrap - * @throws NullPointerException if m is null - */ - UnmodifiableMap(Map<? extends K, ? extends V> m) - { - this.m = (Map<K,V>) 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<Map.Entry<K, V>> entrySet() - { - if (entries == null) - entries = new UnmodifiableEntrySet<K,V>(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<K,V> - extends UnmodifiableSet<Map.Entry<K,V>> - implements Serializable - { - // Unmodifiable implementation of Map.Entry used as return value for - // UnmodifiableEntrySet accessors (iterator, toArray, toArray(Object[])) - private static final class UnmodifiableMapEntry<K,V> - implements Map.Entry<K,V> - { - private final Map.Entry<K,V> e; - - private UnmodifiableMapEntry(Map.Entry<K,V> e) - { - super(); - this.e = e; - } - - /** - * 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 K getKey() - { - return e.getKey(); - } - - /** - * Returns the value of this map entry. - * - * @return the value. - */ - public V 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 V setValue(V 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(); - } - } - - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 7854390611657943733L; - - /** - * Wrap a given set. - * @param s the set to wrap - */ - UnmodifiableEntrySet(Set<Map.Entry<K,V>> s) - { - super(s); - } - - // The iterator must return unmodifiable map entries. - public Iterator<Map.Entry<K,V>> iterator() - { - return new UnmodifiableIterator<Map.Entry<K,V>>(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 Map.Entry<K,V> next() - { - final Map.Entry<K,V> e = super.next(); - return new UnmodifiableMapEntry<K,V>(e); - } - }; - } - - // The array returned is an array of UnmodifiableMapEntry instead of - // Map.Entry - public Object[] toArray() - { - Object[] mapEntryResult = super.toArray(); - UnmodifiableMapEntry<K,V> result[] = null; - - if (mapEntryResult != null) - { - result = (UnmodifiableMapEntry<K,V>[]) - new UnmodifiableMapEntry[mapEntryResult.length]; - for (int i = 0; i < mapEntryResult.length; ++i) - result[i] = new UnmodifiableMapEntry<K,V>((Map.Entry<K,V>)mapEntryResult[i]); - } - return result; - } - - // The array returned is an array of UnmodifiableMapEntry instead of - // Map.Entry - public <S> S[] toArray(S[] array) - { - S[] result = super.toArray(array); - - if (result != null) - for (int i = 0; i < result.length; i++) - array[i] = - (S) new UnmodifiableMapEntry<K,V>((Map.Entry<K,V>) result[i]); - return array; - } - - - } // 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 V 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 V put(K key, V 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<K> keySet() - { - if (keys == null) - keys = new UnmodifiableSet<K>(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<? extends K, ? extends V> 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 V 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<V> values() - { - if (values == null) - values = new UnmodifiableCollection<V>(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 <T> Set<T> unmodifiableSet(Set<? extends T> s) - { - return new UnmodifiableSet<T>(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<T> extends UnmodifiableCollection<T> - implements Set<T> - { - /** - * 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<? extends T> 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 <K, V> SortedMap<K, V> unmodifiableSortedMap(SortedMap<K, - ? extends V> m) - { - return new UnmodifiableSortedMap<K, V>(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<K, V> - extends UnmodifiableMap<K, V> - implements SortedMap<K, V> - { - /** - * 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<K, V> sm; - - /** - * Wrap a given map. - * @param sm the map to wrap - * @throws NullPointerException if sm is null - */ - UnmodifiableSortedMap(SortedMap<K, ? extends V> sm) - { - super(sm); - this.sm = (SortedMap<K,V>) 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<? super K> 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 K 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<K, V> headMap(K toKey) - { - return new UnmodifiableSortedMap<K, V>(sm.headMap(toKey)); - } - - /** - * Returns the last (highest sorted) key in the map. - * - * @return the last key. - * @throws NoSuchElementException if this map is empty. - */ - public K 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<K, V> subMap(K fromKey, K toKey) - { - return new UnmodifiableSortedMap<K, V>(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<K, V> tailMap(K fromKey) - { - return new UnmodifiableSortedMap<K, V>(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 <T> SortedSet<T> unmodifiableSortedSet(SortedSet<T> s) - { - return new UnmodifiableSortedSet<T>(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<T> extends UnmodifiableSet<T> - implements SortedSet<T> - { - /** - * 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<T> ss; - - /** - * Wrap a given set. - * @param ss the set to wrap - * @throws NullPointerException if ss is null - */ - UnmodifiableSortedSet(SortedSet<T> 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<? super T> 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 T 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<T> headSet(T toElement) - { - return new UnmodifiableSortedSet<T>(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 T 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<T> subSet(T fromElement, T toElement) - { - return new UnmodifiableSortedSet<T>(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<T> tailSet(T fromElement) - { - return new UnmodifiableSortedSet<T>(ss.tailSet(fromElement)); - } - } // class UnmodifiableSortedSet - - /** - * <p> - * Returns a dynamically typesafe view of the given collection, - * where any modification is first checked to ensure that the type - * of the new data is appropriate. Although the addition of - * generics and parametrically-typed collections prevents an - * incorrect type of element being added to a collection at - * compile-time, via static type checking, this can be overridden by - * casting. In contrast, wrapping the collection within a - * dynamically-typesafe wrapper, using this and associated methods, - * <emph>guarantees</emph> that the collection will only contain - * elements of an appropriate type (provided it only contains such - * at the type of wrapping, and all subsequent access is via the - * wrapper). This can be useful for debugging the cause of a - * <code>ClassCastException</code> caused by erroneous casting, or - * for protecting collections from corruption by external libraries. - * </p> - * <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. - * </p> - * - * @param c the collection to wrap in a dynamically typesafe wrapper - * @param type the type of elements the collection should hold. - * @return a dynamically typesafe view of the collection. - * @see Serializable - * @since 1.5 - */ - public static <E> Collection<E> checkedCollection(Collection<E> c, - Class<E> type) - { - return new CheckedCollection<E>(c, type); - } - - /** - * The implementation of {@link #checkedCollection(Collection,Class)}. This - * class name is required for compatibility with Sun's JDK serializability. - * - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.5 - */ - private static class CheckedCollection<E> - implements Collection<E>, Serializable - { - /** - * Compatible with JDK 1.5. - */ - private static final long serialVersionUID = 1578914078182001775L; - - /** - * The wrapped collection. Package visible for use by subclasses. - * @serial the real collection - */ - final Collection<E> c; - - /** - * The type of the elements of this collection. - * @serial the element type. - */ - final Class<E> type; - - /** - * Wrap a given collection. - * @param c the collection to wrap - * @param type the type to wrap - * @throws NullPointerException if c is null - */ - CheckedCollection(Collection<E> c, Class<E> type) - { - this.c = c; - this.type = type; - if (c == null) - throw new NullPointerException(); - } - - /** - * Adds the supplied object to the collection, on the condition that - * it is of the correct type. - * - * @param o the object to add. - * @return <code>true</code> if the collection was modified as a result - * of this action. - * @throws ClassCastException if the object is not of the correct type. - */ - public boolean add(E o) - { - if (type.isInstance(o)) - return c.add(o); - else - throw new ClassCastException("The element is of the incorrect type."); - } - - /** - * Adds the elements of the specified collection to the backing collection, - * provided they are all of the correct type. - * - * @param coll the collection to add. - * @return <code>true</code> if the collection was modified as a result - * of this action. - * @throws ClassCastException if <code>c</code> contained elements of an - * incorrect type. - */ - public boolean addAll(Collection<? extends E> coll) - { - Collection<E> typedColl = (Collection<E>) c; - final Iterator<E> it = typedColl.iterator(); - while (it.hasNext()) - { - final E element = it.next(); - if (!type.isInstance(element)) - throw new ClassCastException("A member of the collection is not of the correct type."); - } - return c.addAll(typedColl); - } - - /** - * Removes all elements from the underlying collection. - */ - public void clear() - { - c.clear(); - } - - /** - * 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 coll 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<?> coll) - { - return c.containsAll(coll); - } - - /** - * 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 checked nature. - * - * @return a Iterator over the elements of the underlying - * collection, in any order. - */ - public Iterator<E> iterator() - { - return new CheckedIterator<E>(c.iterator(), type); - } - - /** - * Removes the supplied object from the collection, if it exists. - * - * @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). - */ - public boolean remove(Object o) - { - return c.remove(o); - } - - /** - * Removes all objects in the supplied collection from the backing - * collection, if they exist within it. - * - * @param coll the collection of objects to remove. - * @return <code>true</code> if the collection was modified. - */ - public boolean removeAll(Collection<?> coll) - { - return c.removeAll(coll); - } - - /** - * Retains all objects specified by the supplied collection which exist - * within the backing collection, and removes all others. - * - * @param coll the collection of objects to retain. - * @return <code>true</code> if the collection was modified. - */ - public boolean retainAll(Collection<?> coll) - { - return c.retainAll(coll); - } - - /** - * 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(); - } - - /** - * <p> - * 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. - * </p> - * <p> - * 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. - * </p> - * <p> - * <emph>Note</emph>: 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 <S> S[] toArray(S[] a) - { - return c.toArray(a); - } - - /** - * A textual representation of the unmodifiable collection. - * - * @return The checked collection in the form of a <code>String</code>. - */ - public String toString() - { - return c.toString(); - } - } // class CheckedCollection - - /** - * The implementation of the various iterator methods in the - * checked classes. - * - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.5 - */ - private static class CheckedIterator<E> - implements Iterator<E> - { - /** - * The wrapped iterator. - */ - private final Iterator<E> i; - - /** - * The type of the elements of this collection. - * @serial the element type. - */ - final Class<E> type; - - /** - * Only trusted code creates a wrapper. - * @param i the wrapped iterator - * @param type the type of the elements within the checked list. - */ - CheckedIterator(Iterator<E> i, Class<E> type) - { - this.i = i; - this.type = type; - } - - /** - * Obtains the next element in the underlying collection. - * - * @return the next element in the collection. - * @throws NoSuchElementException if there are no more elements. - */ - public E 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(); - } - - /** - * Removes the next element from the collection. - */ - public void remove() - { - i.remove(); - } - } // class CheckedIterator - - /** - * <p> - * Returns a dynamically typesafe view of the given list, - * where any modification is first checked to ensure that the type - * of the new data is appropriate. Although the addition of - * generics and parametrically-typed collections prevents an - * incorrect type of element being added to a collection at - * compile-time, via static type checking, this can be overridden by - * casting. In contrast, wrapping the collection within a - * dynamically-typesafe wrapper, using this and associated methods, - * <emph>guarantees</emph> that the collection will only contain - * elements of an appropriate type (provided it only contains such - * at the type of wrapping, and all subsequent access is via the - * wrapper). This can be useful for debugging the cause of a - * <code>ClassCastException</code> caused by erroneous casting, or - * for protecting collections from corruption by external libraries. - * </p> - * <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. - * </p> - * - * @param l the list to wrap - * @param type the type of the elements within the checked list. - * @return a dynamically typesafe view of the list - * @see Serializable - * @see RandomAccess - */ - public static <E> List<E> checkedList(List<E> l, Class<E> type) - { - if (l instanceof RandomAccess) - return new CheckedRandomAccessList<E>(l, type); - return new CheckedList<E>(l, type); - } - - /** - * The implementation of {@link #checkedList(List,Class)} for sequential - * lists. This class name is required for compatibility with Sun's JDK - * serializability. - * - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.5 - */ - private static class CheckedList<E> - extends CheckedCollection<E> - implements List<E> - { - /** - * Compatible with JDK 1.5. - */ - private static final long serialVersionUID = 65247728283967356L; - - /** - * 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<E> list; - - /** - * Wrap a given list. - * @param l the list to wrap - * @param type the type of the elements within the checked list. - * @throws NullPointerException if l is null - */ - CheckedList(List<E> l, Class<E> type) - { - super(l, type); - list = l; - } - - /** - * Adds the supplied element to the underlying list at the specified - * index, provided it is of the right type. - * - * @param index The index at which to place the new element. - * @param o the object to add. - * @throws ClassCastException if the type of the object is not a - * valid type for the underlying collection. - */ - public void add(int index, E o) - { - if (type.isInstance(o)) - list.add(index, o); - else - throw new ClassCastException("The object is of the wrong type."); - } - - /** - * Adds the members of the supplied collection to the underlying - * collection at the specified index, provided they are all of the - * correct type. - * - * @param index the index at which to place the new element. - * @param coll the collections of objects to add. - * @throws ClassCastException if the type of any element in c is not a - * valid type for the underlying collection. - */ - public boolean addAll(int index, Collection<? extends E> coll) - { - Collection<E> typedColl = (Collection<E>) coll; - final Iterator<E> it = typedColl.iterator(); - while (it.hasNext()) - { - if (!type.isInstance(it.next())) - throw new ClassCastException("A member of the collection is not of the correct type."); - } - return list.addAll(index, coll); - } - - /** - * 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 the specified index in the underlying list - * @throws IndexOutOfBoundsException if index < 0 || index >= size() - */ - public E 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 checked nature of this list. - * - * @return a <code>CheckedListIterator</code> over the elements of the - * underlying list, in order, starting at the beginning. - */ - public ListIterator<E> listIterator() - { - return new CheckedListIterator<E>(list.listIterator(), type); - } - - /** - * Obtains a list iterator over the underlying list, starting at the - * specified index and maintaining the checked 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>CheckedListIterator</code> over the elements of the - * underlying list, in order, starting at the specified index. - * @throws IndexOutOfBoundsException if index < 0 || index > size() - */ - public ListIterator<E> listIterator(int index) - { - return new CheckedListIterator<E>(list.listIterator(index), type); - } - - /** - * Removes the element at the specified index. - * - * @param index The index of the element to remove. - * @return the removed element. - */ - public E remove(int index) - { - return list.remove(index); - } - - /** - * Replaces the element at the specified index in the underlying list - * with that supplied. - * - * @param index the index of the element to replace. - * @param o the new object to place at the specified index. - * @return the replaced element. - */ - public E set(int index, E o) - { - 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 will be - * checked, like this list. Changes to the elements of the - * returned list will be reflected in the underlying list. The effect - * of structural modifications 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 the underlying list. - * @throws IndexOutOfBoundsException if fromIndex < 0 - * || toIndex > size() || fromIndex > toIndex. - */ - public List<E> subList(int fromIndex, int toIndex) - { - return checkedList(list.subList(fromIndex, toIndex), type); - } - } // class CheckedList - - /** - * The implementation of {@link #checkedList(List)} for random-access - * lists. This class name is required for compatibility with Sun's JDK - * serializability. - * - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.5 - */ - private static final class CheckedRandomAccessList<E> - extends CheckedList<E> - implements RandomAccess - { - /** - * Compatible with JDK 1.5. - */ - private static final long serialVersionUID = 1638200125423088369L; - - /** - * Wrap a given list. - * @param l the list to wrap - * @param type the type of the elements within the checked list. - * @throws NullPointerException if l is null - */ - CheckedRandomAccessList(List<E> l, Class<E> type) - { - super(l, type); - } - } // class CheckedRandomAccessList - - /** - * The implementation of {@link CheckedList#listIterator()}. - * - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.5 - */ - private static final class CheckedListIterator<E> - extends CheckedIterator<E> - implements ListIterator<E> - { - /** - * The wrapped iterator, stored both here and in the superclass to - * avoid excessive casting. - */ - private final ListIterator<E> li; - - /** - * Only trusted code creates a wrapper. - * @param li the wrapped iterator - */ - CheckedListIterator(ListIterator<E> li, Class<E> type) - { - super(li, type); - this.li = li; - } - - /** - * Adds the supplied object at the current iterator position, provided - * it is of the correct type. - * - * @param o the object to add. - * @throws ClassCastException if the type of the object is not a - * valid type for the underlying collection. - */ - public void add(E o) - { - if (type.isInstance(o)) - li.add(o); - else - throw new ClassCastException("The object is of the wrong type."); - } - - /** - * 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 E 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(); - } - - /** - * Sets the next element to that supplied, provided that it is of the - * correct type. - * - * @param o The new object to replace the existing one. - * @throws ClassCastException if the type of the object is not a - * valid type for the underlying collection. - */ - public void set(E o) - { - if (type.isInstance(o)) - li.set(o); - else - throw new ClassCastException("The object is of the wrong type."); - } - } // class CheckedListIterator - - /** - * <p> - * Returns a dynamically typesafe view of the given map, - * where any modification is first checked to ensure that the type - * of the new data is appropriate. Although the addition of - * generics and parametrically-typed collections prevents an - * incorrect type of element being added to a collection at - * compile-time, via static type checking, this can be overridden by - * casting. In contrast, wrapping the collection within a - * dynamically-typesafe wrapper, using this and associated methods, - * <emph>guarantees</emph> that the collection will only contain - * elements of an appropriate type (provided it only contains such - * at the type of wrapping, and all subsequent access is via the - * wrapper). This can be useful for debugging the cause of a - * <code>ClassCastException</code> caused by erroneous casting, or - * for protecting collections from corruption by external libraries. - * </p> - * <p> - * The returned Map implements Serializable, but can only be serialized if - * the map it wraps is likewise Serializable. - * </p> - * - * @param m the map to wrap - * @param keyType the dynamic type of the map's keys. - * @param valueType the dynamic type of the map's values. - * @return a dynamically typesafe view of the map - * @see Serializable - */ - public static <K, V> Map<K, V> checkedMap(Map<K, V> m, Class<K> keyType, - Class<V> valueType) - { - return new CheckedMap<K, V>(m, keyType, valueType); - } - - /** - * The implementation of {@link #checkedMap(Map)}. This - * class name is required for compatibility with Sun's JDK serializability. - * - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.5 - */ - private static class CheckedMap<K, V> - implements Map<K, V>, Serializable - { - /** - * Compatible with JDK 1.5. - */ - private static final long serialVersionUID = 5742860141034234728L; - - /** - * The wrapped map. - * @serial the real map - */ - private final Map<K, V> m; - - /** - * The type of the map's keys. - * @serial the key type. - */ - final Class<K> keyType; - - /** - * The type of the map's values. - * @serial the value type. - */ - final Class<V> valueType; - - /** - * Cache the entry set. - */ - private transient Set<Map.Entry<K, V>> entries; - - /** - * Cache the key set. - */ - private transient Set<K> keys; - - /** - * Cache the value collection. - */ - private transient Collection<V> values; - - /** - * Wrap a given map. - * @param m the map to wrap - * @param keyType the dynamic type of the map's keys. - * @param valueType the dynamic type of the map's values. - * @throws NullPointerException if m is null - */ - CheckedMap(Map<K, V> m, Class<K> keyType, Class<V> valueType) - { - this.m = m; - this.keyType = keyType; - this.valueType = valueType; - if (m == null) - throw new NullPointerException(); - } - - /** - * Clears all pairs from the map. - */ - public void clear() - { - m.clear(); - } - - /** - * 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); - } - - /** - * <p> - * Returns a checked set view of the entries in the underlying map. - * Each element in the set is a unmodifiable variant of - * <code>Map.Entry</code>. - * </p> - * <p> - * 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. - * </p> - * - * @return the checked set view of all mapping entries. - * @see Map.Entry - */ - public Set<Map.Entry<K, V>> entrySet() - { - if (entries == null) - { - Class<Map.Entry<K,V>> klass = - (Class<Map.Entry<K,V>>) (Class) Map.Entry.class; - entries = new CheckedEntrySet<Map.Entry<K,V>,K,V>(m.entrySet(), - klass, - keyType, - valueType); - } - return entries; - } - - /** - * The implementation of {@link CheckedMap#entrySet()}. This class - * is <emph>not</emph> serializable. - * - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.5 - */ - private static final class CheckedEntrySet<E,SK,SV> - extends CheckedSet<E> - { - /** - * The type of the map's keys. - * @serial the key type. - */ - private final Class<SK> keyType; - - /** - * The type of the map's values. - * @serial the value type. - */ - private final Class<SV> valueType; - - /** - * Wrap a given set of map entries. - * - * @param s the set to wrap. - * @param type the type of the set's entries. - * @param keyType the type of the map's keys. - * @param valueType the type of the map's values. - */ - CheckedEntrySet(Set<E> s, Class<E> type, Class<SK> keyType, - Class<SV> valueType) - { - super(s, type); - this.keyType = keyType; - this.valueType = valueType; - } - - // The iterator must return checked map entries. - public Iterator<E> iterator() - { - return new CheckedIterator<E>(c.iterator(), type) - { - /** - * 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 E next() - { - final Map.Entry e = (Map.Entry) super.next(); - return (E) 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(); - } - - /** - * Sets the value of this map entry, provided it is of the - * right type. - * - * @param value The new value. - * @throws ClassCastException if the type of the value is not - * a valid type for the underlying - * map. - */ - public Object setValue(Object value) - { - if (valueType.isInstance(value)) - return e.setValue(value); - else - throw new ClassCastException("The value is of the wrong type."); - } - - /** - * Returns a textual representation of the map entry. - * - * @return The map entry as a <code>String</code>. - */ - public String toString() - { - return e.toString(); - } - }; - } - }; - } - } // class CheckedEntrySet - - /** - * 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 V get(Object key) - { - return m.get(key); - } - - /** - * Adds a new pair to the map, provided both the key and the value are - * of the correct types. - * - * @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 ClassCastException if the type of the key or the value is - * not a valid type for the underlying map. - */ - public V put(K key, V value) - { - if (keyType.isInstance(key)) - { - if (valueType.isInstance(value)) - return m.put(key,value); - else - throw new ClassCastException("The value is of the wrong type."); - } - throw new ClassCastException("The key is of the wrong type."); - } - - /** - * 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(); - } - - /** - * <p> - * Returns a checked 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. - * </p> - * <p> - * Modifications made while an iterator is in progress cause undefined - * behavior. These modifications are again limited to the values of - * the keys. - * </p> - * - * @return the set view of all keys. - */ - public Set<K> keySet() - { - if (keys == null) - keys = new CheckedSet<K>(m.keySet(), keyType); - return keys; - } - - /** - * Adds all pairs within the supplied map to the underlying map, - * provided they are all have the correct key and value types. - * - * @param map the map, the entries of which should be added - * to the underlying map. - * @throws ClassCastException if the type of a key or value is - * not a valid type for the underlying map. - */ - public void putAll(Map<? extends K, ? extends V> map) - { - Map<K,V> typedMap = (Map<K,V>) map; - final Iterator<Map.Entry<K,V>> it = typedMap.entrySet().iterator(); - while (it.hasNext()) - { - final Map.Entry<K,V> entry = it.next(); - if (!keyType.isInstance(entry.getKey())) - throw new ClassCastException("A key is of the wrong type."); - if (!valueType.isInstance(entry.getValue())) - throw new ClassCastException("A value is of the wrong type."); - } - m.putAll(typedMap); - } - - /** - * Removes a pair from the map. - * - * @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 V remove(Object o) - { - return m.remove(o); - } - - - /** - * 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(); - } - - /** - * <p> - * 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. - * </p> - * <p> - * Modifications made while an iterator is in progress cause undefined - * behavior. These modifications are again limited to the values of - * the keys. - * </p> - * - * @return the collection view of all values. - */ - public Collection<V> values() - { - if (values == null) - values = new CheckedCollection<V>(m.values(), valueType); - return values; - } - } // class CheckedMap - - /** - * <p> - * Returns a dynamically typesafe view of the given set, - * where any modification is first checked to ensure that the type - * of the new data is appropriate. Although the addition of - * generics and parametrically-typed collections prevents an - * incorrect type of element being added to a collection at - * compile-time, via static type checking, this can be overridden by - * casting. In contrast, wrapping the collection within a - * dynamically-typesafe wrapper, using this and associated methods, - * <emph>guarantees</emph> that the collection will only contain - * elements of an appropriate type (provided it only contains such - * at the type of wrapping, and all subsequent access is via the - * wrapper). This can be useful for debugging the cause of a - * <code>ClassCastException</code> caused by erroneous casting, or - * for protecting collections from corruption by external libraries. - * </p> - * <p> - * The returned Set implements Serializable, but can only be serialized if - * the set it wraps is likewise Serializable. - * </p> - * - * @param s the set to wrap. - * @param type the type of the elements within the checked list. - * @return a dynamically typesafe view of the set - * @see Serializable - */ - public static <E> Set<E> checkedSet(Set<E> s, Class<E> type) - { - return new CheckedSet<E>(s, type); - } - - /** - * The implementation of {@link #checkedSet(Set)}. This class - * name is required for compatibility with Sun's JDK serializability. - * - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.5 - */ - private static class CheckedSet<E> - extends CheckedCollection<E> - implements Set<E> - { - /** - * Compatible with JDK 1.5. - */ - private static final long serialVersionUID = 4694047833775013803L; - - /** - * Wrap a given set. - * - * @param s the set to wrap - * @throws NullPointerException if s is null - */ - CheckedSet(Set<E> s, Class<E> type) - { - super(s, type); - } - - /** - * 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 CheckedSet - - /** - * <p> - * Returns a dynamically typesafe view of the given sorted map, - * where any modification is first checked to ensure that the type - * of the new data is appropriate. Although the addition of - * generics and parametrically-typed collections prevents an - * incorrect type of element being added to a collection at - * compile-time, via static type checking, this can be overridden by - * casting. In contrast, wrapping the collection within a - * dynamically-typesafe wrapper, using this and associated methods, - * <emph>guarantees</emph> that the collection will only contain - * elements of an appropriate type (provided it only contains such - * at the type of wrapping, and all subsequent access is via the - * wrapper). This can be useful for debugging the cause of a - * <code>ClassCastException</code> caused by erroneous casting, or - * for protecting collections from corruption by external libraries. - * </p> - * <p> - * The returned SortedMap implements Serializable, but can only be - * serialized if the map it wraps is likewise Serializable. - * </p> - * - * @param m the map to wrap. - * @param keyType the dynamic type of the map's keys. - * @param valueType the dynamic type of the map's values. - * @return a dynamically typesafe view of the map - * @see Serializable - */ - public static <K, V> SortedMap<K, V> checkedSortedMap(SortedMap<K, V> m, - Class<K> keyType, - Class<V> valueType) - { - return new CheckedSortedMap<K, V>(m, keyType, valueType); - } - - /** - * The implementation of {@link #checkedSortedMap(SortedMap,Class,Class)}. - * This class name is required for compatibility with Sun's JDK - * serializability. - * - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - */ - private static class CheckedSortedMap<K, V> - extends CheckedMap<K, V> - implements SortedMap<K, V> - { - /** - * Compatible with JDK 1.5. - */ - private static final long serialVersionUID = 1599671320688067438L; - - /** - * The wrapped map; stored both here and in the superclass to avoid - * excessive casting. - * @serial the wrapped map - */ - private final SortedMap<K, V> sm; - - /** - * Wrap a given map. - * - * @param sm the map to wrap - * @param keyType the dynamic type of the map's keys. - * @param valueType the dynamic type of the map's values. - * @throws NullPointerException if sm is null - */ - CheckedSortedMap(SortedMap<K, V> sm, Class<K> keyType, Class<V> valueType) - { - super(sm, keyType, valueType); - 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<? super K> 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 K firstKey() - { - return sm.firstKey(); - } - - /** - * <p> - * Returns a checked 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> - * <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>. - * </p> - * - * @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<K, V> headMap(K toKey) - { - return new CheckedSortedMap<K, V>(sm.headMap(toKey), keyType, valueType); - } - - /** - * Returns the last (highest sorted) key in the map. - * - * @return the last key. - * @throws NoSuchElementException if this map is empty. - */ - public K lastKey() - { - return sm.lastKey(); - } - - /** - * <p> - * Returns a checked 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> - * <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. - * </p> - * - * @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<K, V> subMap(K fromKey, K toKey) - { - return new CheckedSortedMap<K, V>(sm.subMap(fromKey, toKey), keyType, - valueType); - } - - /** - * <p> - * Returns a checked 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> - * <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>. - * </p> - * - * @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<K, V> tailMap(K fromKey) - { - return new CheckedSortedMap<K, V>(sm.tailMap(fromKey), keyType, - valueType); - } - } // class CheckedSortedMap - - /** - * <p> - * Returns a dynamically typesafe view of the given sorted set, - * where any modification is first checked to ensure that the type - * of the new data is appropriate. Although the addition of - * generics and parametrically-typed collections prevents an - * incorrect type of element being added to a collection at - * compile-time, via static type checking, this can be overridden by - * casting. In contrast, wrapping the collection within a - * dynamically-typesafe wrapper, using this and associated methods, - * <emph>guarantees</emph> that the collection will only contain - * elements of an appropriate type (provided it only contains such - * at the type of wrapping, and all subsequent access is via the - * wrapper). This can be useful for debugging the cause of a - * <code>ClassCastException</code> caused by erroneous casting, or - * for protecting collections from corruption by external libraries. - * </p> - * <p> - * The returned SortedSet implements Serializable, but can only be - * serialized if the set it wraps is likewise Serializable. - * </p> - * - * @param s the set to wrap. - * @param type the type of the set's elements. - * @return a dynamically typesafe view of the set - * @see Serializable - */ - public static <E> SortedSet<E> checkedSortedSet(SortedSet<E> s, - Class<E> type) - { - return new CheckedSortedSet<E>(s, type); - } - - /** - * The implementation of {@link #checkedSortedSet(SortedSet,Class)}. This - * class name is required for compatibility with Sun's JDK serializability. - * - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.5 - */ - private static class CheckedSortedSet<E> - extends CheckedSet<E> - implements SortedSet<E> - { - /** - * Compatible with JDK 1.4. - */ - private static final long serialVersionUID = 1599911165492914959L; - - /** - * The wrapped set; stored both here and in the superclass to avoid - * excessive casting. - * - * @serial the wrapped set - */ - private SortedSet<E> ss; - - /** - * Wrap a given set. - * - * @param ss the set to wrap. - * @param type the type of the set's elements. - * @throws NullPointerException if ss is null - */ - CheckedSortedSet(SortedSet<E> ss, Class<E> type) - { - super(ss, type); - 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<? super E> 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 E first() - { - return ss.first(); - } - - /** - * <p> - * Returns a checked 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> - * <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>. - * </p> - * - * @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<E> headSet(E toElement) - { - return new CheckedSortedSet<E>(ss.headSet(toElement), type); - } - - /** - * Returns the last (highest sorted) element in the underlying - * set. - * - * @return the last element. - * @throws NoSuchElementException if the set is empty. - */ - public E last() - { - return ss.last(); - } - - /** - * <p> - * Returns a checked 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> - * <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. - * </p> - * - * @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<E> subSet(E fromElement, E toElement) - { - return new CheckedSortedSet<E>(ss.subSet(fromElement, toElement), type); - } - - /** - * <p> - * Returns a checked 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> - * <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>. - * </p> - * - * @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<E> tailSet(E fromElement) - { - return new CheckedSortedSet<E>(ss.tailSet(fromElement), type); - } - } // class CheckedSortedSet - - /** - * Returns a view of a {@link Deque} as a stack or LIFO (Last-In-First-Out) - * {@link Queue}. Each call to the LIFO queue corresponds to one - * equivalent method call to the underlying deque, with the exception - * of {@link Collection#addAll(Collection)}, which is emulated by a series - * of {@link Deque#push(E)} calls. - * - * @param deque the deque to convert to a LIFO queue. - * @return a LIFO queue. - * @since 1.6 - */ - public static <T> Queue<T> asLifoQueue(Deque<T> deque) - { - return new LIFOQueue<T>(deque); - } - - /** - * Returns a set backed by the supplied map. The resulting set - * has the same performance, concurrency and ordering characteristics - * as the original map. The supplied map must be empty and should not - * be used after the set is created. Each call to the set corresponds - * to one equivalent method call to the underlying map, with the exception - * of {@link Set#addAll(Collection)} which is emulated by a series of - * calls to <code>put</code>. - * - * @param map the map to convert to a set. - * @return a set backed by the supplied map. - * @throws IllegalArgumentException if the map is not empty. - * @since 1.6 - */ - public static <E> Set<E> newSetFromMap(Map<E,Boolean> map) - { - return new MapSet<E>(map); - } - - /** - * The implementation of {@link #asLIFOQueue(Deque)}. - * - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.6 - */ - private static class LIFOQueue<T> - extends AbstractQueue<T> - { - - /** - * The backing deque. - */ - private Deque<T> deque; - - /** - * Constructs a new {@link LIFOQueue} with the specified - * backing {@link Deque}. - * - * @param deque the backing deque. - */ - public LIFOQueue(Deque<T> deque) - { - this.deque = deque; - } - - public boolean add(T e) - { - return deque.offerFirst(e); - } - - public boolean addAll(Collection<? extends T> c) - { - boolean result = false; - final Iterator<? extends T> it = c.iterator(); - while (it.hasNext()) - result |= deque.offerFirst(it.next()); - return result; - } - - public void clear() - { - deque.clear(); - } - - public boolean isEmpty() - { - return deque.isEmpty(); - } - - public Iterator<T> iterator() - { - return deque.iterator(); - } - - public boolean offer(T e) - { - return deque.offerFirst(e); - } - - public T peek() - { - return deque.peek(); - } - - public T poll() - { - return deque.poll(); - } - - public int size() - { - return deque.size(); - } - } // class LIFOQueue - - /** - * The implementation of {@link #newSetFromMap(Map)}. - * - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.6 - */ - private static class MapSet<E> - extends AbstractSet<E> - { - - /** - * The backing map. - */ - private Map<E,Boolean> map; - - /** - * Constructs a new {@link MapSet} using the specified - * backing {@link Map}. - * - * @param map the backing map. - * @throws IllegalArgumentException if the map is not empty. - */ - public MapSet(Map<E,Boolean> map) - { - if (!map.isEmpty()) - throw new IllegalArgumentException("The map must be empty."); - this.map = map; - } - - public boolean add(E e) - { - return map.put(e, true) == null; - } - - public boolean addAll(Collection<? extends E> c) - { - boolean result = false; - final Iterator<? extends E> it = c.iterator(); - while (it.hasNext()) - result |= (map.put(it.next(), true) == null); - return result; - } - - public void clear() - { - map.clear(); - } - - public boolean contains(Object o) - { - return map.containsKey(o); - } - - public boolean isEmpty() - { - return map.isEmpty(); - } - - public Iterator<E> iterator() - { - return map.keySet().iterator(); - } - - public boolean remove(Object o) - { - return map.remove(o) != null; - } - - public int size() - { - return map.size(); - } - } // class MapSet - -} // class Collections diff --git a/libjava/classpath/java/util/Comparator.java b/libjava/classpath/java/util/Comparator.java deleted file mode 100644 index ca414e7..0000000 --- a/libjava/classpath/java/util/Comparator.java +++ /dev/null @@ -1,119 +0,0 @@ -/* Comparator.java -- Interface for objects that specify an ordering - 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; - -/** - * 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<T> -{ - /** - * 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(T o1, T 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/classpath/java/util/ConcurrentModificationException.java b/libjava/classpath/java/util/ConcurrentModificationException.java deleted file mode 100644 index 3d7ae10..0000000 --- a/libjava/classpath/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/classpath/java/util/Currency.java b/libjava/classpath/java/util/Currency.java deleted file mode 100644 index d58082c..0000000 --- a/libjava/classpath/java/util/Currency.java +++ /dev/null @@ -1,471 +0,0 @@ -/* Currency.java -- Representation of a currency - Copyright (C) 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 gnu.java.locale.LocaleHelper; - -import java.io.IOException; -import java.io.ObjectStreamException; -import java.io.Serializable; - -import java.util.spi.CurrencyNameProvider; - -/** - * Representation of a currency for a particular locale. Each currency - * is identified by its ISO 4217 code, and only one instance of this - * class exists per currency. As a result, instances are created - * via the <code>getInstance()</code> methods rather than by using - * a constructor. - * - * @see java.util.Locale - * @author Guilhem Lavaux (guilhem.lavaux@free.fr) - * @author Dalibor Topic (robilad@kaffe.org) - * @author Bryce McKinlay (mckinlay@redhat.com) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.4 - */ -public final class Currency - implements Serializable -{ - /** - * For compatability with Sun's JDK - */ - static final long serialVersionUID = -158308464356906721L; - - /** - * The set of properties which map a currency to - * the currency information such as the ISO 4217 - * currency code and the number of decimal points. - * - * @see #getCurrencyCode() - * @serial ignored. - */ - private static transient Properties properties; - - /** - * The ISO 4217 currency code associated with this - * particular instance. - * - * @see #getCurrencyCode() - * @serial the ISO 4217 currency code - */ - private String currencyCode; - - /** - * The number of fraction digits associated with this - * particular instance. - * - * @see #getDefaultFractionDigits() - * @serial the number of fraction digits - */ - private transient int fractionDigits; - - /** - * A cached map of country codes - * instances to international currency code - * <code>String</code>s. Seperating this - * from the <code>Currency</code> instances - * ensures we have a common lookup between - * the two <code>getInstance()</code> methods. - * - * @see #getInstance(java.util.Locale) - * @serial ignored. - */ - private static transient Map countryMap; - - /** - * A cache of <code>Currency</code> instances to - * ensure the singleton nature of this class. The key - * is the international currency code. - * - * @see #getInstance(java.util.Locale) - * @see #getInstance(java.lang.String) - * @see #readResolve() - * @serial ignored. - */ - private static transient Map cache; - - /** - * Instantiates the cache and reads in the properties. - */ - static - { - /* Create a hash map for the locale mappings */ - countryMap = new HashMap(); - /* Create a hash map for the cache */ - cache = new HashMap(); - /* Create the properties object */ - properties = new Properties(); - /* Try and load the properties from our iso4217.properties resource */ - try - { - properties.load(Currency.class.getResourceAsStream("iso4217.properties")); - } - catch (IOException exception) - { - throw new InternalError("Failed to load currency resource: " + exception); - } - } - - /** - * Default constructor for deserialization - */ - private Currency() - { - } - - /** - * Constructor to create a <code>Currency</code> object - * for a particular <code>Locale</code>. - * All components of the given locale, other than the - * country code, are ignored. The results of calling this - * method may vary over time, as the currency associated with - * a particular country changes. For countries without - * a given currency (e.g. Antarctica), the result is null. - * - * @param loc the locale for the new currency, or null if - * there is no country code specified or a currency - * for this country. - */ - private Currency(Locale loc) - { - String countryCode; - String currencyKey; - String fractionDigitsKey; - int commaPosition; - - /* Retrieve the country code from the locale */ - countryCode = loc.getCountry(); - /* If there is no country code, return */ - if (countryCode.equals("")) - { - throw new - IllegalArgumentException("Invalid (empty) country code for locale:" - + loc); - } - /* Construct the key for the currency */ - currencyKey = countryCode + ".currency"; - /* Construct the key for the fraction digits */ - fractionDigitsKey = countryCode + ".fractionDigits"; - /* Retrieve the currency */ - currencyCode = properties.getProperty(currencyKey); - /* Return if the currency code is null */ - if (currencyCode == null) - { - return; - } - /* Split off the first currency code (we only use the first for now) */ - commaPosition = currencyCode.indexOf(","); - if (commaPosition != -1) - { - currencyCode = currencyCode.substring(0, commaPosition); - } - /* Retrieve the fraction digits */ - fractionDigits = Integer.parseInt(properties.getProperty(fractionDigitsKey)); - } - - /** - * Constructor for the "XXX" special case. This allows - * a Currency to be constructed from an assumed good - * currency code. - * - * @param code the code to use. - */ - private Currency(String code) - { - currencyCode = code; - fractionDigits = -1; /* Pseudo currency */ - } - - /** - * Returns the ISO4217 currency code of this currency. - * - * @return a <code>String</code> containing currency code. - */ - public String getCurrencyCode() - { - return currencyCode; - } - - /** - * Returns the number of digits which occur after the decimal point - * for this particular currency. For example, currencies such - * as the U.S. dollar, the Euro and the Great British pound have two - * digits following the decimal point to indicate the value which exists - * in the associated lower-valued coinage (cents in the case of the first - * two, pennies in the latter). Some currencies such as the Japanese - * Yen have no digits after the decimal point. In the case of pseudo - * currencies, such as IMF Special Drawing Rights, -1 is returned. - * - * @return the number of digits after the decimal separator for this currency. - */ - public int getDefaultFractionDigits() - { - return fractionDigits; - } - - /** - * Builds a new currency instance for this locale. - * All components of the given locale, other than the - * country code, are ignored. The results of calling this - * method may vary over time, as the currency associated with - * a particular country changes. For countries without - * a given currency (e.g. Antarctica), the result is null. - * - * @param locale a <code>Locale</code> instance. - * @return a new <code>Currency</code> instance. - * @throws NullPointerException if the locale or its - * country code is null. - * @throws IllegalArgumentException if the country of - * the given locale is not a supported ISO3166 code. - */ - public static Currency getInstance(Locale locale) - { - /** - * The new instance must be the only available instance - * for the currency it supports. We ensure this happens, - * while maintaining a suitable performance level, by - * creating the appropriate object on the first call to - * this method, and returning the cached instance on - * later calls. - */ - Currency newCurrency; - - String country = locale.getCountry(); - if (locale == null || country == null) - { - throw new - NullPointerException("The locale or its country is null."); - } - - /* Check that country of locale given is valid. */ - if (country.length() != 2) - throw new IllegalArgumentException(); - - /* Attempt to get the currency from the cache */ - String code = (String) countryMap.get(country); - if (code == null) - { - /* Create the currency for this locale */ - newCurrency = new Currency(locale); - /* - * If the currency code is null, then creation failed - * and we return null. - */ - code = newCurrency.getCurrencyCode(); - if (code == null) - { - return null; - } - else - { - /* Cache it */ - countryMap.put(country, code); - cache.put(code, newCurrency); - } - } - else - { - newCurrency = (Currency) cache.get(code); - } - /* Return the instance */ - return newCurrency; - } - - /** - * Builds the currency corresponding to the specified currency code. - * - * @param currencyCode a string representing a currency code. - * @return a new <code>Currency</code> instance. - * @throws NullPointerException if currencyCode is null. - * @throws IllegalArgumentException if the supplied currency code - * is not a supported ISO 4217 code. - */ - public static Currency getInstance(String currencyCode) - { - Locale[] allLocales; - - /* - * Throw a null pointer exception explicitly if currencyCode is null. - * One is not thrown otherwise. It results in an - * IllegalArgumentException. - */ - if (currencyCode == null) - { - throw new NullPointerException("The supplied currency code is null."); - } - /* Nasty special case to allow an erroneous currency... blame Sun */ - if (currencyCode.equals("XXX")) - return new Currency("XXX"); - Currency newCurrency = (Currency) cache.get(currencyCode); - if (newCurrency == null) - { - /* Get all locales */ - allLocales = Locale.getAvailableLocales(); - /* Loop through each locale, looking for the code */ - for (int i = 0;i < allLocales.length; i++) - { - try - { - Currency testCurrency = getInstance (allLocales[i]); - if (testCurrency != null && - testCurrency.getCurrencyCode().equals(currencyCode)) - { - return testCurrency; - } - } - catch (IllegalArgumentException exception) - { - /* Ignore locales without valid countries */ - } - } - /* - * If we get this far, the code is not supported by any of - * our locales. - */ - throw new IllegalArgumentException("The currency code, " + currencyCode + - ", is not supported."); - } - else - { - return newCurrency; - } - } - - /** - * This method returns the symbol which precedes or follows a - * value in this particular currency in the default locale. - * In cases where there is no such symbol for the currency, - * the ISO 4217 currency code is returned. - * - * @return the currency symbol, or the ISO 4217 currency code if - * one doesn't exist. - */ - public String getSymbol() - { - return getSymbol(Locale.getDefault()); - } - - /** - * <p> - * This method returns the symbol which precedes or follows a - * value in this particular currency. The returned value is - * the symbol used to denote the currency in the specified locale. - * </p> - * <p> - * For example, a supplied locale may specify a different symbol - * for the currency, due to conflicts with its own currency. - * This would be the case with the American currency, the dollar. - * Locales that also use a dollar-based currency (e.g. Canada, Australia) - * need to differentiate the American dollar using 'US$' rather than '$'. - * So, supplying one of these locales to <code>getSymbol()</code> would - * return this value, rather than the standard '$'. - * </p> - * <p> - * In cases where there is no such symbol for a particular currency, - * the ISO 4217 currency code is returned. - * </p> - * - * @param locale the locale to express the symbol in. - * @return the currency symbol, or the ISO 4217 currency code if - * one doesn't exist. - * @throws NullPointerException if the locale is null. - */ - public String getSymbol(Locale locale) - { - String property = "currenciesSymbol." + currencyCode; - try - { - return ResourceBundle.getBundle("gnu.java.locale.LocaleInformation", - locale).getString(property); - } - catch (MissingResourceException exception) - { - /* This means runtime support for the locale - * is not available, so we check providers. */ - } - for (CurrencyNameProvider p : - ServiceLoader.load(CurrencyNameProvider.class)) - { - for (Locale loc : p.getAvailableLocales()) - { - if (loc.equals(locale)) - { - String localizedString = p.getSymbol(currencyCode, - locale); - if (localizedString != null) - return localizedString; - break; - } - } - } - if (locale.equals(Locale.ROOT)) // Base case - return currencyCode; - return getSymbol(LocaleHelper.getFallbackLocale(locale)); - } - - /** - * Returns the international ISO4217 currency code of this currency. - * - * @return a <code>String</code> containing the ISO4217 currency code. - */ - public String toString() - { - return getCurrencyCode(); - } - - /** - * Resolves the deserialized object to the singleton instance for its - * particular currency. The currency code of the deserialized instance - * is used to return the correct instance. - * - * @return the singleton instance for the currency specified by the - * currency code of the deserialized object. This replaces - * the deserialized object as the returned object from - * deserialization. - * @throws ObjectStreamException if a problem occurs with deserializing - * the object. - */ - private Object readResolve() - throws ObjectStreamException - { - return getInstance(currencyCode); - } - -} diff --git a/libjava/classpath/java/util/Date.java b/libjava/classpath/java/util/Date.java deleted file mode 100644 index 3f7ba6f..0000000 --- a/libjava/classpath/java/util/Date.java +++ /dev/null @@ -1,1256 +0,0 @@ -/* java.util.Date - 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; - -import gnu.java.lang.CPStringBuilder; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.text.DateFormat; -import java.text.SimpleDateFormat; - -/** - * <p> - * This class represents a specific time in milliseconds since the epoch. - * The epoch is 1970, January 1 00:00:00.0000 UTC. - * </p> - * <p> - * <code>Date</code> is intended to reflect universal time coordinate (UTC), - * but this depends on the underlying host environment. Most operating systems - * don't handle the leap second, which occurs about once every year or - * so. The leap second is added to the last minute of the day on either - * the 30th of June or the 31st of December, creating a minute 61 seconds - * in length. - * </p> - * <p> - * The representations of the date fields are as follows: - * <ul> - * <li> - * Years are specified as the difference between the year - * and 1900. Thus, the final year used is equal to - * 1900 + y, where y is the input value. - * </li> - * <li> - * Months are represented using zero-based indexing, - * making 0 January and 11 December. - * </li> - * <li> - * Dates are represented with the usual values of - * 1 through to 31. - * </li> - * <li> - * Hours are represented in the twenty-four hour clock, - * with integer values from 0 to 23. 12am is 0, and - * 12pm is 12. - * </li> - * <li> - * Minutes are again as usual, with values from 0 to 59. - * </li> - * <li> - * Seconds are represented with the values 0 through to 61, - * with 60 and 61 being leap seconds (as per the ISO C standard). - * </li> - * </ul> - * </p> - * <p> - * Prior to JDK 1.1, this class was the sole class handling date and time - * related functionality. However, this particular solution was not - * amenable to internationalization. The new <code>Calendar</code> - * class should now be used to handle dates and times, with <code>Date</code> - * being used only for values in milliseconds since the epoch. The - * <code>Calendar</code> class, and its concrete implementations, handle - * the interpretation of these values into minutes, hours, days, months - * and years. The formatting and parsing of dates is left to the - * <code>DateFormat</code> class, which is able to handle the different - * types of date format which occur in different locales. - * </p> - * - * @see Calendar - * @see GregorianCalendar - * @see java.text.DateFormat - * @author Jochen Hoenicke - * @author Per Bothner (bothner@cygnus.com) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - */ -public class Date - implements Cloneable, Comparable<Date>, Serializable -{ - /** - * This is the serialization UID for this class - * for compatability with Sun's JDK. - */ - private static final long serialVersionUID = 7523967970034938905L; - - /** - * The time in milliseconds since the epoch. - */ - private transient long time; - - /** - * An array of week names used to map names to integer values. - */ - private static final String[] weekNames = { "Sun", "Mon", "Tue", "Wed", - "Thu", "Fri", "Sat" }; - /** - * An array of month names used to map names to integer values. - */ - private static final String[] monthNames = { "Jan", "Feb", "Mar", "Apr", - "May", "Jun", "Jul", "Aug", - "Sep", "Oct", "Nov", "Dec" }; - /** - * Creates a new Date Object representing the current time. - */ - public Date() - { - time = System.currentTimeMillis(); - } - - /** - * Creates a new Date Object representing the given time. - * - * @param time the time in milliseconds since the epoch. - */ - public Date(long time) - { - this.time = time; - } - - /** - * Creates a new Date Object representing the given time. - * - * @deprecated use <code>new GregorianCalendar(year+1900, month, - * day)</code> instead. - * @param year the difference between the required year and 1900. - * @param month the month as a value between 0 and 11. - * @param day the day as a value between 0 and 31. - */ - public Date(int year, int month, int day) - { - this(year, month, day, 0, 0, 0); - } - - /** - * Creates a new Date Object representing the given time. - * - * @deprecated use <code>new GregorianCalendar(year+1900, month, - * day, hour, min)</code> instead. - * @param year the difference between the required year and 1900. - * @param month the month as a value between 0 and 11. - * @param day the day as a value between 0 and 31. - * @param hour the hour as a value between 0 and 23, in 24-hour - * clock notation. - * @param min the minute as a value between 0 and 59. - */ - public Date(int year, int month, int day, int hour, int min) - { - this(year, month, day, hour, min, 0); - } - - /** - * Creates a new Date Object representing the given time. - * - * @deprecated use <code>new GregorianCalendar(year+1900, month, - * day, hour, min, sec)</code> instead. - * @param year the difference between the required year and 1900. - * @param month the month as a value between 0 and 11. - * @param day the day as a value between 0 and 31. - * @param hour the hour as a value between 0 and 23, in 24-hour - * clock notation. - * @param min the minute as a value between 0 and 59. - * @param sec the second as a value between 0 and 61 (with 60 - * and 61 being leap seconds). - */ - public Date(int year, int month, int day, int hour, int min, int sec) - { - GregorianCalendar cal = - new GregorianCalendar(year + 1900, month, day, hour, min, sec); - time = cal.getTimeInMillis(); - } - - /** - * Creates a new Date from the given string representation. This - * does the same as <code>new Date(Date.parse(s))</code> - * @see #parse - * @deprecated use <code>java.text.DateFormat.parse(s)</code> instead. - */ - public Date(String s) - { - time = parse(s); - } - - /** - * Returns a copy of this <code>Date</code> object. - * - * @return a copy, or null if the object couldn't be - * cloned. - * @see Object#clone() - */ - public Object clone() - { - try - { - return super.clone(); - } - catch (CloneNotSupportedException ex) - { - return null; - } - } - - /** - * Returns the number of milliseconds since the epoch - * specified by the given arguments. The arguments are - * interpreted relative to UTC rather than the local - * time zone. - * - * @deprecated Use <code>Calendar</code> with a UTC - * <code>TimeZone</code> instead. - * @param year the difference between the required year and 1900. - * @param month the month as a value between 0 and 11. - * @param date the day as a value between 0 and 31. - * @param hrs the hour as a value between 0 and 23, in 24-hour - * clock notation. - * @param min the minute as a value between 0 and 59. - * @param sec the second as a value between 0 and 61 (with 60 - * and 61 being leap seconds). - * @return the time in milliseconds since the epoch. - */ - public static long UTC(int year, int month, int date, - int hrs, int min, int sec) - { - GregorianCalendar cal = - new GregorianCalendar(year + 1900, month, date, hrs, min, sec); - cal.set(Calendar.ZONE_OFFSET, 0); - cal.set(Calendar.DST_OFFSET, 0); - return cal.getTimeInMillis(); - } - - /** - * Gets the time represented by this object. - * - * @return the time in milliseconds since the epoch. - */ - public long getTime() - { - return time; - } - - /** - * Returns the number of minutes offset used with UTC to give the time - * represented by this object in the current time zone. The date information - * from this object is also used to determine whether or not daylight savings - * time is in effect. For example, the offset for the UK would be 0 if the - * month of the date object was January, and 1 if the month was August. - * - * @deprecated use - * <code>Calendar.get(Calendar.ZONE_OFFSET)+Calendar.get(Calendar.DST_OFFSET)</code> - * instead. - * @return The time zone offset in minutes of the local time zone - * relative to UTC. The time represented by this object is used to - * determine if we should use daylight savings. - */ - public int getTimezoneOffset() - { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(time); - return - (cal.get(Calendar.ZONE_OFFSET) - + cal.get(Calendar.DST_OFFSET)) / (60 * 1000); - } - - /** - * Sets the time which this object should represent. - * - * @param time the time in milliseconds since the epoch. - */ - public void setTime(long time) - { - this.time = time; - } - - /** - * Tests if this date is after the specified date. - * - * @param when the other date - * @return true, if the date represented by this object is - * strictly later than the time represented by when. - */ - public boolean after(Date when) - { - return time > when.time; - } - - /** - * Tests if this date is before the specified date. - * - * @param when the other date - * @return true, if the date represented by when is strictly later - * than the time represented by this object. - */ - public boolean before(Date when) - { - return time < when.time; - } - - /** - * Compares two dates for equality. - * - * @param obj the object to compare. - * @return true, if obj is a Date object and the time represented - * by obj is exactly the same as the time represented by this - * object. - */ - public boolean equals(Object obj) - { - return (obj instanceof Date && time == ((Date) obj).time); - } - - /** - * Compares two dates. - * - * @param when the other date. - * @return 0, if the date represented - * by obj is exactly the same as the time represented by this - * object, a negative if this Date is before the other Date, and - * a positive value otherwise. - */ - public int compareTo(Date when) - { - return (time < when.time) ? -1 : (time == when.time) ? 0 : 1; - } - - /** - * Computes the hash code of this <code>Date</code> as the - * XOR of the most significant and the least significant - * 32 bits of the 64 bit milliseconds value. - * - * @return the hash code. - */ - public int hashCode() - { - return (int) time ^ (int) (time >>> 32); - } - - /** - * <p> - * Returns a string representation of this date using - * the following date format: - * </p> - * <p> - * <code>day mon dd hh:mm:ss zz yyyy</code> - * </p> - * <p>where the fields used here are: - * <ul> - * <li> - * <code>day</code> -- the day of the week - * (Sunday through to Saturday). - * </li> - * <li> - * <code>mon</code> -- the month (Jan to Dec). - * </li> - * <li> - * <code>dd</code> -- the day of the month - * as two decimal digits (01 to 31). - * </li> - * <li> - * <code>hh</code> -- the hour of the day - * as two decimal digits in 24-hour clock notation - * (01 to 23). - * </li> - * <li> - * <code>mm</code> -- the minute of the day - * as two decimal digits (01 to 59). - * </li> - * <li> - * <code>ss</code> -- the second of the day - * as two decimal digits (01 to 61). - * </li> - * <li> - * <code>zz</code> -- the time zone information if available. - * The possible time zones used include the abbreviations - * recognised by <code>parse()</code> (e.g. GMT, CET, etc.) - * and may reflect the fact that daylight savings time is in - * effect. The empty string is used if there is no time zone - * information. - * </li> - * <li> - * <code>yyyy</code> -- the year as four decimal digits. - * </li> - * </ul> - * <p> - * The <code>DateFormat</code> class should now be - * preferred over using this method. - * </p> - * - * @return A string of the form 'day mon dd hh:mm:ss zz yyyy' - * @see #parse(String) - * @see DateFormat - */ - public String toString() - { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(time); - String day = "0" + cal.get(Calendar.DATE); - String hour = "0" + cal.get(Calendar.HOUR_OF_DAY); - String min = "0" + cal.get(Calendar.MINUTE); - String sec = "0" + cal.get(Calendar.SECOND); - String year = "000" + cal.get(Calendar.YEAR); - return weekNames[cal.get(Calendar.DAY_OF_WEEK) - 1] + " " - + monthNames[cal.get(Calendar.MONTH)] + " " - + day.substring(day.length() - 2) + " " - + hour.substring(hour.length() - 2) + ":" - + min.substring(min.length() - 2) + ":" - + sec.substring(sec.length() - 2) + " " - + - cal.getTimeZone().getDisplayName(cal.getTimeZone().inDaylightTime(this), - TimeZone.SHORT) + " " + - year.substring(year.length() - 4); - } - - /** - * Returns a locale-dependent string representation of this - * <code>Date</code> object. - * - * @deprecated Use DateFormat.format(Date) - * @return A locale-dependent string representation. - * @see #parse(String) - * @see DateFormat - */ - public String toLocaleString() - { - return java.text.DateFormat.getInstance().format(this); - } - - /** - * <p> - * Returns a string representation of this <code>Date</code> - * object using GMT rather than the local timezone. - * The following date format is used: - * </p> - * <p> - * <code>d mon yyyy hh:mm:ss GMT</code> - * </p> - * <p>where the fields used here are: - * <ul> - * <li> - * <code>d</code> -- the day of the month - * as one or two decimal digits (1 to 31). - * </li> - * <li> - * <code>mon</code> -- the month (Jan to Dec). - * </li> - * <li> - * <code>yyyy</code> -- the year as four decimal digits. - * </li> - * <li> - * <code>hh</code> -- the hour of the day - * as two decimal digits in 24-hour clock notation - * (01 to 23). - * </li> - * <li> - * <code>mm</code> -- the minute of the day - * as two decimal digits (01 to 59). - * </li> - * <li> - * <code>ss</code> -- the second of the day - * as two decimal digits (01 to 61). - * </li> - * <li> - * <code>GMT</code> -- the literal string "GMT" - * indicating Greenwich Mean Time as opposed to - * the local timezone. - * </li> - * </ul> - * - * @deprecated Use DateFormat.format(Date) with a GMT TimeZone. - * @return A string of the form 'd mon yyyy hh:mm:ss GMT' using - * GMT as opposed to the local timezone. - * @see #parse(String) - * @see DateFormat - */ - public String toGMTString() - { - java.text.DateFormat format = java.text.DateFormat.getInstance(); - format.setTimeZone(TimeZone.getTimeZone("GMT")); - return format.format(this); - } - - /** - * Parses the time zone string. - * - * @param tok The token containing the time zone. - * @param sign The sign (+ or -) used by the time zone. - * @return An integer representing the number of minutes offset - * from GMT for the time zone. - */ - private static int parseTz(String tok, char sign) - throws IllegalArgumentException - { - int num; - - try - { - // parseInt doesn't handle '+' so strip off sign. - num = Integer.parseInt(tok.substring(1)); - } - catch (NumberFormatException ex) - { - throw new IllegalArgumentException(tok); - } - - // Convert hours to minutes. - if (num < 24) - num *= 60; - else - num = (num / 100) * 60 + num % 100; - - return sign == '-' ? -num : num; - } - - /** - * Parses the month string. - * - * @param tok the token containing the month. - * @return An integer between 0 and 11, representing - * a month from January (0) to December (11), - * or -1 if parsing failed. - */ - private static int parseMonth(String tok) - { - // Initialize strings for month names. - // We could possibly use the fields of DateFormatSymbols but that is - // localized and thus might not match the English words specified. - String months[] = { "JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", - "JUNE", "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", - "NOVEMBER", "DECEMBER" }; - - int i; - for (i = 0; i < 12; i++) - if (months[i].startsWith(tok)) - return i; - - // Return -1 if not found. - return -1; - } - - /** - * Parses the day of the week string. - * - * @param tok the token containing the day of the week. - * @return true if the token was parsed successfully. - */ - private static boolean parseDayOfWeek(String tok) - { - // Initialize strings for days of the week names. - // We could possibly use the fields of DateFormatSymbols but that is - // localized and thus might not match the English words specified. - String daysOfWeek[] = { "SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY", - "THURSDAY", "FRIDAY", "SATURDAY" }; - - int i; - for (i = 0; i < 7; i++) - if (daysOfWeek[i].startsWith(tok)) - return true; - - return false; - } - - /** - * <p> - * Parses a String and returns the time, in milliseconds since the - * epoch, it represents. Most syntaxes are handled, including - * the IETF date standard "day, dd mon yyyy hh:mm:ss zz" (see - * <code>toString()</code> for definitions of these fields). - * Standard U.S. time zone abbreviations are recognised, in - * addition to time zone offsets in positive or negative minutes. - * If a time zone is specified, the specified time is assumed to - * be in UTC and the appropriate conversion is applied, following - * parsing, to convert this to the local time zone. If no zone - * is specified, the time is assumed to already be in the local - * time zone. - * </p> - * <p> - * The method parses the string progressively from left to right. - * At the end of the parsing process, either a time is returned - * or an <code>IllegalArgumentException</code> is thrown to signify - * failure. The ASCII characters A-Z, a-z, 0-9, and ',', '+', '-', - * ':' and '/' are the only characters permitted within the string, - * besides whitespace and characters enclosed within parantheses - * '(' and ')'. - * </p> - * <p> - * A sequence of consecutive digits are recognised as a number, - * and interpreted as follows: - * <ul> - * <li> - * A number preceded by a sign (+ or -) is taken to be a time zone - * offset. The time zone offset can be specified in either hours - * or minutes. The former is assumed if the number is less than 24. - * Otherwise, the offset is assumed to be in minutes. A - indicates - * a time zone west of GMT, while a + represents a time zone to the - * east of GMT. The time zones are always assumed to be relative - * to GMT, and a (redundant) specification of this can be included - * with the time zone. For example, '-9', 'utc-9' and 'GMT-9' all - * represent a time zone nine hours west of GMT. Similarly, - * '+4', 'ut+4' and 'UTC+4' all give 4 hours east of GMT. - * </li> - * <li> - * A number equal to or greater than 70 is regarded as a year specification. - * Values lower than 70 are only assumed to indicate a year if both the - * day of the month and the month itself have already been recognised. - * Year values less than 100 are interpreted as being relative to the current - * century when the <code>Date</code> class is initialised.. Given a century, - * x, the year is assumed to be within the range x - 80 to x + 19. The value - * itself is then used as a match against the two last digits of one of these - * years. For example, take x to be 2004. A two-digit year is assumed to fall - * within the range x - 80 (1924) and x + 19 (2023). Thus, any intepreted value - * between 0 and 23 is assumed to be 2000 to 2023 and values between 24 and 99 - * are taken as being 1924 to 1999. This only applies for the case of 2004. - * With a different year, the values will be interpreted differently. 2005 - * will used 0 to 24 as 2000 to 2024 and 25 to 99 as 1925 to 1999, for example. - * This behaviour differs from that of <code>SimpleDateFormat</code> and is - * time-dependent (a two-digit year will be interpreted differently depending - * on the time the code is run). - * </li> - * <li> - * Numbers followed by a colon are interpreted by first an hour, and then - * as a minute, once an hour has been found. - * </li> - * <li> - * <li> - * Numbers followed by a slash are regarded first as a month, and then as - * a day of the month once the month has been found. This follows the - * U.S. date format of mm/dd, rather than the European dd/mm. Months - * are converted to the recognised value - 1 before storage, in order - * to put the number within the range 0 to 11. - * </li> - * <li> - * Numbers followed by commas, whitespace, hyphens or the end of the string - * are interpreted in the following order: hour, minute, second, day of month. - * The first type not already recognised in the current string being parsed is - * assumed. - * </li> - * </ul> - * </p> - * <p> - * A sequence of consecutive alphabetic characters is recognised as a word, - * and interpreted as follows, in a case-insentive fashion: - * <ul> - * <li> - * The characters 'AM' or 'PM' restrict the hour value to a value between 0 - * and 12. In the latter case, 12 is added to the hour value before storage. - * </li> - * <li> - * Any words which match any prefix of one of the days of the week ('Monday', - * 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' and 'Sunday'), - * are simply ignored. - * </li> - * <li> - * Any words which match any prefix of one of the months of the year ('January', - * 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', - * 'October', 'November', 'December') are recognised and interpreted as the - * appropriate value between 0 and 11. The first match made against a - * month is the one used, in the order specified here. For example, 'Ma' is - * intepreted as 'March' (2) and not as 'May' (4). Similarly, 'Ju' is 'June', - * and not 'July'. - * </li> - * <li> - * The words 'GMT', 'UT' and 'UTC' are interpreted as specifying UTC as the - * time zone in use for this date. - * </li> - * <li> - * The word pairs 'EST'/'EDT', 'CST'/'CDT', 'MST'/'MDT' and 'PST'/'PDT' are - * interpreted as the appropriate U.S. time zone abbreviation. Each pair - * is the standard and daylight savings time zone specification, respectively, - * for each zone within the U.S, these being Eastern Standard/Daylight Time - * (-5), Central Standard/Daylight Time (-6), Mountain Standard/Daylight Time - * (-7) and Pacific Standard/Daylight Time (-8). - * </li> - * </ul> - * - * @param string The String to parse. - * @return The time in milliseconds since the epoch. - * @throws IllegalArgumentException if the string fails to parse. - * @deprecated Use DateFormat.parse(String) - * @see #toString() - * @see SimpleDateFormat - */ - public static long parse(String string) - { - // Initialize date/time fields before parsing begins. - int year = -1; - int month = -1; - int day = -1; - int hour = -1; - int minute = -1; - int second = -1; - int timezone = 0; - boolean localTimezone = true; - - // Trim out any nested stuff in parentheses now to make parsing easier. - CPStringBuilder buf = new CPStringBuilder(); - int parenNesting = 0; - int len = string.length(); - for (int i = 0; i < len; i++) - { - char ch = string.charAt(i); - if (ch >= 'a' && ch <= 'z') - ch -= 'a' - 'A'; - if (ch == '(') - parenNesting++; - else if (parenNesting == 0) - buf.append(ch); - else if (ch == ')') - parenNesting--; - } - int tmpMonth; - - // Make all chars upper case to simplify comparisons later. - // Also ignore commas; treat them as delimiters. - StringTokenizer strtok = new StringTokenizer(buf.toString(), " \t\n\r,"); - - while (strtok.hasMoreTokens()) - { - String tok = strtok.nextToken(); - char firstch = tok.charAt(0); - if ((firstch == '+' || firstch == '-') && year >= 0) - { - timezone = parseTz(tok, firstch); - localTimezone = false; - } - else if (firstch >= '0' && firstch <= '9') - { - int lastPunct = -1; - while (tok != null && tok.length() > 0) - { - int punctOffset = tok.length(); - int num = 0; - int punct; - for (int i = 0; ; i++) - { - if (i >= punctOffset) - { - punct = -1; - break; - } - else - { - punct = tok.charAt(i); - if (punct >= '0' && punct <= '9') - { - if (num > 999999999) // in case of overflow - throw new IllegalArgumentException(tok); - num = 10 * num + (punct - '0'); - } - else - { - punctOffset = i; - break; - } - } - - } - - if (punct == ':') - { - if (hour < 0) - hour = num; - else - minute = num; - } - else if (lastPunct == ':' && hour >= 0 && (minute < 0 || second < 0)) - { - if (minute < 0) - minute = num; - else - second = num; - } - else if ((num >= 70 - && (punct == ' ' || punct == ',' - || punct == '/' || punct < 0)) - || (num < 70 && day >= 0 && month >= 0 && year < 0)) - { - if (num >= 100) - year = num; - else - { - int curYear = 1900 + new Date().getYear(); - int firstYear = curYear - 80; - year = firstYear / 100 * 100 + num; - if (year < firstYear) - year += 100; - } - } - else if (punct == '/') - { - if (month < 0) - month = num - 1; - else - day = num; - } - else if (hour >= 0 && minute < 0) - minute = num; - else if (minute >= 0 && second < 0) - second = num; - else if (day < 0) - day = num; - else - throw new IllegalArgumentException(tok); - - // Advance string if there's more to process in this token. - if (punct < 0 || punctOffset + 1 >= tok.length()) - tok = null; - else - tok = tok.substring(punctOffset + 1); - lastPunct = punct; - } - } - else if (firstch >= 'A' && firstch <= 'Z') - { - if (tok.equals("AM")) - { - if (hour < 1 || hour > 12) - throw new IllegalArgumentException(tok); - if (hour == 12) - hour = 0; - } - else if (tok.equals("PM")) - { - if (hour < 1 || hour > 12) - throw new IllegalArgumentException(tok); - if (hour < 12) - hour += 12; - } - else if (parseDayOfWeek(tok)) - { /* Ignore it; throw the token away. */ } - else if (tok.equals("UT") || tok.equals("UTC") || tok.equals("GMT")) - localTimezone = false; - else if (tok.startsWith("UT") || tok.startsWith("GMT")) - { - int signOffset = 3; - if (tok.charAt(1) == 'T' && tok.charAt(2) != 'C') - signOffset = 2; - - char sign = tok.charAt(signOffset); - if (sign != '+' && sign != '-') - throw new IllegalArgumentException(tok); - - timezone = parseTz(tok.substring(signOffset), sign); - localTimezone = false; - } - else if ((tmpMonth = parseMonth(tok)) >= 0) - month = tmpMonth; - else if (tok.length() == 3 && tok.charAt(2) == 'T') - { - // Convert timezone offset from hours to minutes. - char ch = tok.charAt(0); - if (ch == 'E') - timezone = -5 * 60; - else if (ch == 'C') - timezone = -6 * 60; - else if (ch == 'M') - timezone = -7 * 60; - else if (ch == 'P') - timezone = -8 * 60; - else - throw new IllegalArgumentException(tok); - - // Shift 60 minutes for Daylight Savings Time. - if (tok.charAt(1) == 'D') - timezone += 60; - else if (tok.charAt(1) != 'S') - throw new IllegalArgumentException(tok); - - localTimezone = false; - } - else - throw new IllegalArgumentException(tok); - } - else - throw new IllegalArgumentException(tok); - } - - // Unspecified hours, minutes, or seconds should default to 0. - if (hour < 0) - hour = 0; - if (minute < 0) - minute = 0; - if (second < 0) - second = 0; - - // Throw exception if any other fields have not been recognized and set. - if (year < 0 || month < 0 || day < 0) - throw new IllegalArgumentException("Missing field"); - - // Return the time in either local time or relative to GMT as parsed. - // If no time-zone was specified, get the local one (in minutes) and - // convert to milliseconds before adding to the UTC. - GregorianCalendar cal - = new GregorianCalendar(year, month, day, hour, minute, second); - if (!localTimezone) - { - cal.set(Calendar.ZONE_OFFSET, timezone * 60 * 1000); - cal.set(Calendar.DST_OFFSET, 0); - } - return cal.getTimeInMillis(); - } - - /** - * Returns the difference between the year represented by this - * <code>Date</code> object and 1900. - * - * @return the year minus 1900 represented by this date object. - * @deprecated Use Calendar instead of Date, and use get(Calendar.YEAR) - * instead. Note the 1900 difference in the year. - * @see Calendar - * @see #setYear(int) - */ - public int getYear() - { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(time); - return cal.get(Calendar.YEAR) - 1900; - } - - /** - * Sets the year to the specified year, plus 1900. The other - * fields are only altered as required to match the same date - * and time in the new year. Usually, this will mean that - * the fields are not changed at all, but in the case of - * a leap day or leap second, the fields will change in - * relation to the existence of such an event in the new year. - * For example, if the date specifies February the 29th, 2000, - * then this will become March the 1st if the year is changed - * to 2001, as 2001 is not a leap year. Similarly, a seconds - * value of 60 or 61 may result in the seconds becoming 0 and - * the minute increasing by 1, if the new time does not include - * a leap second. - * - * @param year the year minus 1900. - * @deprecated Use Calendar instead of Date, and use - * set(Calendar.YEAR, year) instead. Note about the 1900 - * difference in year. - * @see #getYear() - * @see Calendar - */ - public void setYear(int year) - { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(time); - cal.set(Calendar.YEAR, 1900 + year); - time = cal.getTimeInMillis(); - } - - /** - * Returns the month represented by this <code>Date</code> object, - * as a value between 0 (January) and 11 (December). - * - * @return the month represented by this date object (zero based). - * @deprecated Use Calendar instead of Date, and use get(Calendar.MONTH) - * instead. - * @see #setMonth(int) - * @see Calendar - */ - public int getMonth() - { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(time); - return cal.get(Calendar.MONTH); - } - - /** - * Sets the month to the given value. The other - * fields are only altered as necessary to match - * the same date and time in the new month. In most - * cases, the other fields won't change at all. However, - * in the case of a shorter month or a leap second, values - * may be adjusted. For example, if the day of the month - * is currently 31, and the month value is changed from - * January (0) to September (8), the date will become - * October the 1st, as September only has 30 days. Similarly, - * a seconds value of 60 or 61 (a leap second) may result - * in the seconds value being reset to 0 and the minutes - * value being incremented by 1, if the new time does - * not include a leap second. - * - * @param month the month, with a zero-based index - * from January. - * @deprecated Use Calendar instead of Date, and use - * set(Calendar.MONTH, month) instead. - * @see #getMonth() - * @see Calendar - */ - public void setMonth(int month) - { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(time); - cal.set(Calendar.MONTH, month); - time = cal.getTimeInMillis(); - } - - /** - * Returns the day of the month of this <code>Date</code> - * object, as a value between 0 and 31. - * - * @return the day of month represented by this date object. - * @deprecated Use Calendar instead of Date, and use get(Calendar.DATE) - * instead. - * @see Calendar - * @see #setDate(int) - */ - public int getDate() - { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(time); - return cal.get(Calendar.DATE); - } - - /** - * Sets the date to the given value. The other - * fields are only altered as necessary to match - * the same date and time on the new day of the month. In most - * cases, the other fields won't change at all. However, - * in the case of a leap second or the day being out of - * the range of the current month, values - * may be adjusted. For example, if the day of the month - * is currently 30 and the month is June, a new day of the - * month value of 31 will cause the month to change to July, - * as June only has 30 days . Similarly, - * a seconds value of 60 or 61 (a leap second) may result - * in the seconds value being reset to 0 and the minutes - * value being incremented by 1, if the new time does - * not include a leap second. - * - * @param date the date. - * @deprecated Use Calendar instead of Date, and use - * set(Calendar.DATE, date) instead. - * @see Calendar - * @see #getDate() - */ - public void setDate(int date) - { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(time); - cal.set(Calendar.DATE, date); - time = cal.getTimeInMillis(); - } - - /** - * Returns the day represented by this <code>Date</code> - * object as an integer between 0 (Sunday) and 6 (Saturday). - * - * @return the day represented by this date object. - * @deprecated Use Calendar instead of Date, and use get(Calendar.DAY_OF_WEEK) - * instead. - * @see Calendar - */ - public int getDay() - { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(time); - // For Calendar, Sunday is 1. For Date, Sunday is 0. - return cal.get(Calendar.DAY_OF_WEEK) - 1; - } - - /** - * Returns the hours represented by this <code>Date</code> - * object as an integer between 0 and 23. - * - * @return the hours represented by this date object. - * @deprecated Use Calendar instead of Date, and use get(Calendar.HOUR_OF_DAY) - * instead. - * @see Calendar - * @see #setHours(int) - */ - public int getHours() - { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(time); - return cal.get(Calendar.HOUR_OF_DAY); - } - - /** - * Sets the hours to the given value. The other - * fields are only altered as necessary to match - * the same date and time in the new hour. In most - * cases, the other fields won't change at all. However, - * in the case of a leap second, values - * may be adjusted. For example, - * a seconds value of 60 or 61 (a leap second) may result - * in the seconds value being reset to 0 and the minutes - * value being incremented by 1 if the new hour does - * not contain a leap second. - * - * @param hours the hours. - * @deprecated Use Calendar instead of Date, and use - * set(Calendar.HOUR_OF_DAY, hours) instead. - * @see Calendar - * @see #getHours() - */ - public void setHours(int hours) - { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(time); - cal.set(Calendar.HOUR_OF_DAY, hours); - time = cal.getTimeInMillis(); - } - - /** - * Returns the number of minutes represented by the <code>Date</code> - * object, as an integer between 0 and 59. - * - * @return the minutes represented by this date object. - * @deprecated Use Calendar instead of Date, and use get(Calendar.MINUTE) - * instead. - * @see Calendar - * @see #setMinutes(int) - */ - public int getMinutes() - { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(time); - return cal.get(Calendar.MINUTE); - } - - /** - * Sets the minutes to the given value. The other - * fields are only altered as necessary to match - * the same date and time in the new minute. In most - * cases, the other fields won't change at all. However, - * in the case of a leap second, values - * may be adjusted. For example, - * a seconds value of 60 or 61 (a leap second) may result - * in the seconds value being reset to 0 and the minutes - * value being incremented by 1 if the new minute does - * not contain a leap second. - * - * @param minutes the minutes. - * @deprecated Use Calendar instead of Date, and use - * set(Calendar.MINUTE, minutes) instead. - * @see Calendar - * @see #getMinutes() - */ - public void setMinutes(int minutes) - { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(time); - cal.set(Calendar.MINUTE, minutes); - time = cal.getTimeInMillis(); - } - - /** - * Returns the number of seconds represented by the <code>Date</code> - * object, as an integer between 0 and 61 (60 and 61 being leap seconds). - * - * @return the seconds represented by this date object. - * @deprecated Use Calendar instead of Date, and use get(Calendar.SECOND) - * instead. - * @see Calendar - * @see #setSeconds(int) - */ - public int getSeconds() - { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(time); - return cal.get(Calendar.SECOND); - } - - /** - * Sets the seconds to the given value. The other - * fields are only altered as necessary to match - * the same date and time in the new minute. In most - * cases, the other fields won't change at all. However, - * in the case of a leap second, values - * may be adjusted. For example, setting the - * seconds value to 60 or 61 (a leap second) may result - * in the seconds value being reset to 0 and the minutes - * value being incremented by 1, if the current time does - * not contain a leap second. - * - * @param seconds the seconds. - * @deprecated Use Calendar instead of Date, and use - * set(Calendar.SECOND, seconds) instead. - * @see Calendar - * @see #getSeconds() - */ - public void setSeconds(int seconds) - { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(time); - cal.set(Calendar.SECOND, seconds); - time = cal.getTimeInMillis(); - } - - /** - * Deserializes a <code>Date</code> object from an - * input stream, setting the time (in milliseconds - * since the epoch) to the long value read from the - * stream. - * - * @param input the input stream. - * @throws IOException if an I/O error occurs in the stream. - * @throws ClassNotFoundException if the class of the - * serialized object could not be found. - */ - private void readObject(ObjectInputStream input) - throws IOException, ClassNotFoundException - { - input.defaultReadObject(); - time = input.readLong(); - } - - /** - * Serializes a <code>Date</code> object to an output stream, - * storing the time (in milliseconds since the epoch) as a long - * value in the stream. - * - * @serialdata A long value representing the offset from the epoch - * in milliseconds. This is the same value that is returned by the - * method getTime(). - * @param output the output stream. - * @throws IOException if an I/O error occurs in the stream. - */ - private void writeObject(ObjectOutputStream output) - throws IOException - { - output.defaultWriteObject(); - output.writeLong(time); - } - -} diff --git a/libjava/classpath/java/util/Dictionary.java b/libjava/classpath/java/util/Dictionary.java deleted file mode 100644 index acd90eb..0000000 --- a/libjava/classpath/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, 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; - -/** - * 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<K, V> -{ - // 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<V> 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 V 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<K> 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 V put(K key, V 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 V 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/classpath/java/util/DuplicateFormatFlagsException.java b/libjava/classpath/java/util/DuplicateFormatFlagsException.java deleted file mode 100644 index 38c3766..0000000 --- a/libjava/classpath/java/util/DuplicateFormatFlagsException.java +++ /dev/null @@ -1,88 +0,0 @@ -/* DuplicateFormatFlagsException.java - Copyright (C) 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; - -/** - * Thrown when the flags supplied to the {@link Formatter#format()} - * method of a {@link Formatter} contain duplicates. - * - * @author Tom Tromey (tromey@redhat.com) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.5 - */ -public class DuplicateFormatFlagsException - extends IllegalFormatException -{ - private static final long serialVersionUID = 18890531L; - - /** - * The flags which contain a duplicate. - * - * @serial the flags containing a duplicate. - */ - // Note: name fixed by serialization. - private String flags; - - /** - * Constructs a new <code>DuplicateFormatFlagsException</code> - * which specifies that the supplied set of flags contains a - * duplicate. - * - * @param flags the flags containing a duplicate. - * @throws NullPointerException if <code>flags</code> is null. - */ - public DuplicateFormatFlagsException(String flags) - { - super("Duplicate flag passed in " + flags); - if (flags == null) - throw new - NullPointerException("Null flags value passed to constructor."); - this.flags = flags; - } - - /** - * Returns the flags which contain a duplicate. - * - * @return the flags. - */ - public String getFlags() - { - return flags; - } -} diff --git a/libjava/classpath/java/util/EmptyStackException.java b/libjava/classpath/java/util/EmptyStackException.java deleted file mode 100644 index e8b4509..0000000 --- a/libjava/classpath/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/classpath/java/util/EnumMap.java b/libjava/classpath/java/util/EnumMap.java deleted file mode 100644 index 78f0500..0000000 --- a/libjava/classpath/java/util/EnumMap.java +++ /dev/null @@ -1,405 +0,0 @@ -/* EnumMap.java - Map where keys are enum constants - Copyright (C) 2004, 2005, 2007 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; - -/** - * @author Tom Tromey (tromey@redhat.com) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.5 - */ - -public class EnumMap<K extends Enum<K>, V> - extends AbstractMap<K, V> - implements Cloneable, Serializable -{ - private static final long serialVersionUID = 458661240069192865L; - - V[] store; - int cardinality; - Class<K> enumClass; - - /** - * The cache for {@link #entrySet()}. - */ - transient Set<Map.Entry<K, V>> entries; - - static final Object emptySlot = new Object(); - - public EnumMap(Class<K> keyType) - { - store = (V[]) new Object[keyType.getEnumConstants().length]; - Arrays.fill(store, emptySlot); - cardinality = 0; - enumClass = keyType; - } - - public EnumMap(EnumMap<K, ? extends V> map) - { - store = (V[]) map.store.clone(); - cardinality = map.cardinality; - enumClass = map.enumClass; - } - - public EnumMap(Map<K, ? extends V> map) - { - if (map instanceof EnumMap) - { - EnumMap<K, ? extends V> other = (EnumMap<K, ? extends V>) map; - store = (V[]) other.store.clone(); - cardinality = other.cardinality; - enumClass = other.enumClass; - } - else - { - for (K key : map.keySet()) - { - V value = map.get(key); - if (store == null) - { - enumClass = key.getDeclaringClass(); - store = (V[]) new Object[enumClass.getEnumConstants().length]; - } - int o = key.ordinal(); - if (store[o] == emptySlot) - ++cardinality; - store[o] = value; - } - // There must be a single element. - if (store == null) - throw new IllegalArgumentException("no elements in map"); - } - } - - public int size() - { - return cardinality; - } - - public boolean containsValue(Object value) - { - for (V i : store) - { - if (i != emptySlot && AbstractCollection.equals(i , value)) - return true; - } - return false; - } - - public boolean containsKey(Object key) - { - if (! (key instanceof Enum)) - return false; - Enum<K> e = (Enum<K>) key; - if (e.getDeclaringClass() != enumClass) - return false; - return store[e.ordinal()] != emptySlot; - } - - public V get(Object key) - { - if (! (key instanceof Enum)) - return null; - Enum<K> e = (Enum<K>) key; - if (e.getDeclaringClass() != enumClass) - return null; - V o = store[e.ordinal()]; - return o == emptySlot ? null : o; - } - - public V put(K key, V value) - { - int o = key.ordinal(); - V result; - if (store[o] == emptySlot) - { - result = null; - ++cardinality; - } - else - result = store[o]; - store[o] = value; - return result; - } - - public V remove(Object key) - { - if (! (key instanceof Enum)) - return null; - Enum<K> e = (Enum<K>) key; - if (e.getDeclaringClass() != enumClass) - return null; - V result = store[e.ordinal()]; - if (result == emptySlot) - result = null; - else - --cardinality; - store[e.ordinal()] = (V) emptySlot; - return result; - } - - public void putAll(Map<? extends K, ? extends V> map) - { - for (K key : map.keySet()) - { - V value = map.get(key); - - int o = key.ordinal(); - if (store[o] == emptySlot) - ++cardinality; - store[o] = value; - } - } - - public void clear() - { - Arrays.fill(store, emptySlot); - cardinality = 0; - } - - public Set<K> keySet() - { - if (keys == null) - { - keys = new AbstractSet<K>() - { - public int size() - { - return cardinality; - } - - public Iterator<K> iterator() - { - return new Iterator<K>() - { - int count = 0; - int index = -1; - - public boolean hasNext() - { - return count < cardinality; - } - - public K next() - { - ++count; - for (++index; store[index] == emptySlot; ++index) - ; - return enumClass.getEnumConstants()[index]; - } - - public void remove() - { - --cardinality; - store[index] = (V) emptySlot; - } - }; - } - - public void clear() - { - EnumMap.this.clear(); - } - - public boolean contains(Object o) - { - return contains(o); - } - - public boolean remove(Object o) - { - return EnumMap.this.remove(o) != null; - } - }; - } - return keys; - } - - public Collection<V> values() - { - if (values == null) - { - values = new AbstractCollection<V>() - { - public int size() - { - return cardinality; - } - - public Iterator<V> iterator() - { - return new Iterator<V>() - { - int count = 0; - int index = -1; - - public boolean hasNext() - { - return count < cardinality; - } - - public V next() - { - ++count; - for (++index; store[index] == emptySlot; ++index) - ; - return store[index]; - } - - public void remove() - { - --cardinality; - store[index] = (V) emptySlot; - } - }; - } - - public void clear() - { - EnumMap.this.clear(); - } - }; - } - return values; - } - - public Set<Map.Entry<K, V>> entrySet() - { - if (entries == null) - { - entries = new AbstractSet<Map.Entry<K, V>>() - { - public int size() - { - return cardinality; - } - - public Iterator<Map.Entry<K, V>> iterator() - { - return new Iterator<Map.Entry<K, V>>() - { - int count = 0; - int index = -1; - - public boolean hasNext() - { - return count < cardinality; - } - - public Map.Entry<K,V> next() - { - ++count; - for (++index; store[index] == emptySlot; ++index) - ; - // FIXME: we could just return something that - // only knows the index. That would be cleaner. - return new AbstractMap.SimpleEntry<K, V>(enumClass.getEnumConstants()[index], - store[index]) - { - public V setValue(V newVal) - { - value = newVal; - return put(key, newVal); - } - }; - } - - public void remove() - { - --cardinality; - store[index] = (V) emptySlot; - } - }; - } - - public void clear() - { - EnumMap.this.clear(); - } - - public boolean contains(Object o) - { - if (! (o instanceof Map.Entry)) - return false; - Map.Entry<K, V> other = (Map.Entry<K, V>) o; - return (containsKey(other.getKey()) - && AbstractCollection.equals(get(other.getKey()), - other.getValue())); - } - - public boolean remove(Object o) - { - if (! (o instanceof Map.Entry)) - return false; - Map.Entry<K, V> other = (Map.Entry<K, V>) o; - return EnumMap.this.remove(other.getKey()) != null; - } - }; - } - return entries; - } - - public boolean equals(Object o) - { - if (! (o instanceof EnumMap)) - return false; - EnumMap<K, V> other = (EnumMap<K, V>) o; - if (other.enumClass != enumClass || other.cardinality != cardinality) - return false; - return Arrays.equals(store, other.store); - } - - public EnumMap<K, V> clone() - { - EnumMap<K, V> result; - try - { - result = (EnumMap<K, V>) super.clone(); - } - catch (CloneNotSupportedException ignore) - { - // Can't happen. - result = null; - } - result.store = (V[]) store.clone(); - return result; - } - -} diff --git a/libjava/classpath/java/util/EnumSet.java b/libjava/classpath/java/util/EnumSet.java deleted file mode 100644 index 60d0106..0000000 --- a/libjava/classpath/java/util/EnumSet.java +++ /dev/null @@ -1,518 +0,0 @@ -/* EnumSet.java - Set of enum objects - Copyright (C) 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; - -/** - * <p> - * Provides an efficient mechanism for recording a set of enumeration - * constants. As enumerations have a known set of possible values, certain - * assumptions can be made when creating a set of constants. The maximum - * size of the set will always be equal to the number of constants, and each - * value will always be one of these constants. As a result, the set only needs - * to store whether a particular constant is present or not rather than the - * values themselves. Each constant can thus be represented by a single bit. - * </p> - * <p> - * This class is designed to provide an alternative to using integer bit flags - * by providing a typesafe {@link Collection} interface with an underlying - * implementation that utilises the assumptions above to give an equivalent level - * of efficiency. The values in a {@link EnumSet} must all be from the same - * {@link Enum} type, which allows the contents to be packed into a bit vector. - * A containment test is then simply a matter of inspecting the appropriate bit, while - * addition involves setting the same. Such basic operations take place in constant - * time. - * </p> - * <p> - * The {@link Iterator} implementation traverses the values in the natural order - * of the enumeration provided by each constant's {@link Enum#ordinal()}. It is - * <emph>weakly consistent</emph> and will not throw a {@link ConcurrentModificationException}. - * This means that concurrent changes to the set may or may not be noticeable during - * traversal. - * </p> - * <p> - * As is usual with most collections, the set is not synchronized by default. This - * can be remedied by using the {@link Collections#synchronizedSet(Set)} method. Null - * elements are not supported and attempts to add one will throw a {@link NullPointerException}. - * </p> - * - * @author Tom Tromey (tromey@redhat.com) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @author Dalibor Topic (robilad@kaffe.org) - * @since 1.5 - */ - -// FIXME: serialization is special, uses SerializationProxy. -// of(E e) is the 'bottom' method that creates a real EnumSet. -public abstract class EnumSet<T extends Enum<T>> - extends AbstractSet<T> - implements Cloneable, Serializable -{ - private static final long serialVersionUID = 4782406773684236311L; - - // These fields could go into the anonymous inner class in of(E), - // complementOf would need to be refactored then, though. - /** - * The store which maintains the bits used to represent - * the enumeration constants. - */ - BitSet store; - - /** - * The cardinality of the set (the current number - * of bits set). - */ - int cardinality; - - /** - * The enumeration used by this set. - */ - Class<T> enumClass; - - /** - * Empty package-private constructor - */ - EnumSet() - { - } - - /** - * Returns a clone of the set. - * - * @return a clone of the set. - */ - public EnumSet<T> clone() - { - EnumSet<T> r; - - try - { - r = (EnumSet<T>) super.clone(); - } - catch (CloneNotSupportedException _) - { - /* Can't happen */ - return null; - } - r.store = (BitSet) store.clone(); - return r; - } - - /** - * Returns a set for the given enumeration type where - * all the constants are present. - * - * @param eltType the type of enumeration to use for the set. - * @return an {@link EnumSet} with all the bits set. - * @throws NullPointerException if the element type is <code>null</code>. - */ - public static <T extends Enum<T>> EnumSet<T> allOf(Class<T> eltType) - { - // create an EnumSet from the list of values of the type - return copyOf(Arrays.asList(eltType.getEnumConstants())); - } - - /** - * Returns a set for the given enumeration type where - * none of the constants are present. - * - * @param eltType the type of enumeration to use for the set. - * @return an {@link EnumSet} with none of the bits set. - * @throws NullPointerException if the element type is <code>null</code>. - */ - public static <T extends Enum<T>> EnumSet<T> noneOf(Class<T> eltType) - { - return complementOf(allOf(eltType)); - } - - /** - * Returns a clone of the given set. - * - * @param other the set to clone. - * @return an {@link EnumSet} that is a clone of the given set. - * @throws NullPointerException if <code>other</code> is <code>null</code>. - */ - public static <T extends Enum<T>> EnumSet<T> copyOf(EnumSet<T> other) - { - return other.clone(); - } - - /** - * Creates an {@link EnumSet} using the contents of the given collection. - * If the collection is also an {@link EnumSet}, this method works the - * same as {@link #copyOf(EnumSet)}. Otherwise, the elements of the collection - * are inspected and used to populate the new set. - * - * @param other the collection to use to populate the new set. - * @return an {@link EnumSet} containing elements from the given collection. - * @throws NullPointerException if <code>other</code> is <code>null</code>. - * @throws IllegalArgumentException if the collection is empty. - */ - public static <T extends Enum<T>> EnumSet<T> copyOf(Collection<T> other) - { - if (other instanceof EnumSet) - return copyOf((EnumSet<T>) other); - if (other.isEmpty()) - throw new IllegalArgumentException("Collection is empty"); - - EnumSet<T> r = null; - - for (T val : other) - { - if (r == null) - r = of(val); - else - r.add(val); - } - - return r; - } - - /** - * Returns a set which is the inverse of the supplied set. - * If a constant is present in the current set, it will not be - * present in the new set and vice versa. - * - * @param other the set to provide the complement of. - * @return an {@link EnumSet} which is the inverse of the current one. - * @throws NullPointerException if <code>other</code> is <code>null</code>. - */ - public static <T extends Enum<T>> EnumSet<T> complementOf(EnumSet<T> other) - { - EnumSet<T> r = other.clone(); - int numConstants = r.enumClass.getEnumConstants().length; - r.store.flip(0, numConstants); - r.cardinality = numConstants - other.cardinality; - return r; - } - - /** - * Creates a new {@link EnumSet} populated with the given element. - * - * @param first the element to use to populate the new set. - * @return an {@link EnumSet} containing the element. - * @throws NullPointerException if <code>first</code> is <code>null</code>. - */ - public static <T extends Enum<T>> EnumSet<T> of(T first) - { - EnumSet<T> r = new EnumSet<T>() - { - public boolean add(T val) - { - if (store.get(val.ordinal())) - return false; - - store.set(val.ordinal()); - ++cardinality; - return true; - } - - public boolean addAll(Collection<? extends T> c) - { - boolean result = false; - if (c instanceof EnumSet) - { - EnumSet<T> other = (EnumSet<T>) c; - if (enumClass == other.enumClass) - { - store.or(other.store); - int save = cardinality; - cardinality = store.cardinality(); - result = save != cardinality; - } - } - else - { - for (T val : c) - { - if (add (val)) - result = true; - } - } - return result; - } - - public void clear() - { - store.clear(); - cardinality = 0; - } - - public boolean contains(Object o) - { - if (! (o instanceof Enum)) - return false; - - Enum<T> e = (Enum<T>) o; - if (e.getDeclaringClass() != enumClass) - return false; - - return store.get(e.ordinal()); - } - - public boolean containsAll(Collection<?> c) - { - if (c instanceof EnumSet) - { - EnumSet<T> other = (EnumSet<T>) c; - if (enumClass == other.enumClass) - return store.containsAll(other.store); - - return false; - } - return super.containsAll(c); - } - - public Iterator<T> iterator() - { - return new Iterator<T>() - { - int next = -1; - int count = 0; - - public boolean hasNext() - { - return count < cardinality; - } - - public T next() - { - next = store.nextSetBit(next + 1); - ++count; - return enumClass.getEnumConstants()[next]; - } - - public void remove() - { - if (! store.get(next)) - { - store.clear(next); - --cardinality; - } - } - }; - } - - public boolean remove(Object o) - { - if (! (o instanceof Enum)) - return false; - - Enum<T> e = (Enum<T>) o; - if (e.getDeclaringClass() != enumClass) - return false; - - store.clear(e.ordinal()); - --cardinality; - return true; - } - - public boolean removeAll(Collection<?> c) - { - if (c instanceof EnumSet) - { - EnumSet<T> other = (EnumSet<T>) c; - if (enumClass != other.enumClass) - return false; - - store.andNot(other.store); - int save = cardinality; - cardinality = store.cardinality(); - return save != cardinality; - } - return super.removeAll(c); - } - - public boolean retainAll(Collection<?> c) - { - if (c instanceof EnumSet) - { - EnumSet<T> other = (EnumSet<T>) c; - if (enumClass != other.enumClass) - return false; - - store.and(other.store); - int save = cardinality; - cardinality = store.cardinality(); - return save != cardinality; - } - return super.retainAll(c); - } - - public int size() - { - return cardinality; - } - }; - - // initialize the class - r.enumClass = first.getDeclaringClass(); - r.store = new BitSet(r.enumClass.getEnumConstants().length); - - r.add(first); - return r; - } - - /** - * Creates a new {@link EnumSet} populated with the given two elements. - * - * @param first the first element to use to populate the new set. - * @param second the second element to use. - * @return an {@link EnumSet} containing the elements. - * @throws NullPointerException if any of the parameters are <code>null</code>. - */ - public static <T extends Enum<T>> EnumSet<T> of(T first, T second) - { - EnumSet<T> r = of(first); - r.add(second); - return r; - } - - /** - * Creates a new {@link EnumSet} populated with the given three elements. - * - * @param first the first element to use to populate the new set. - * @param second the second element to use. - * @param third the third element to use. - * @return an {@link EnumSet} containing the elements. - * @throws NullPointerException if any of the parameters are <code>null</code>. - */ - public static <T extends Enum<T>> EnumSet<T> of(T first, T second, T third) - { - EnumSet<T> r = of(first, second); - r.add(third); - return r; - } - - /** - * Creates a new {@link EnumSet} populated with the given four elements. - * - * @param first the first element to use to populate the new set. - * @param second the second element to use. - * @param third the third element to use. - * @param fourth the fourth element to use. - * @return an {@link EnumSet} containing the elements. - * @throws NullPointerException if any of the parameters are <code>null</code>. - */ - public static <T extends Enum<T>> EnumSet<T> of(T first, T second, T third, - T fourth) - { - EnumSet<T> r = of(first, second, third); - r.add(fourth); - return r; - } - - /** - * Creates a new {@link EnumSet} populated with the given five elements. - * - * @param first the first element to use to populate the new set. - * @param second the second element to use. - * @param third the third element to use. - * @param fourth the fourth element to use. - * @param fifth the fifth element to use. - * @return an {@link EnumSet} containing the elements. - * @throws NullPointerException if any of the parameters are <code>null</code>. - */ - public static <T extends Enum<T>> EnumSet<T> of(T first, T second, T third, - T fourth, T fifth) - { - EnumSet<T> r = of(first, second, third, fourth); - r.add(fifth); - return r; - } - - /** - * Creates a new {@link EnumSet} populated with the given elements. - * - * @param first the first element to use to populate the new set. - * @param rest the other elements to use. - * @return an {@link EnumSet} containing the elements. - * @throws NullPointerException if any of the parameters are <code>null</code>. - */ - public static <T extends Enum<T>> EnumSet<T> of(T first, T... rest) - { - EnumSet<T> r = noneOf(first.getDeclaringClass()); - r.add(first); - for (T val : rest) - r.add(val); - return r; - } - - /** - * Creates a new {@link EnumSet} using the enumeration constants - * starting from {@code from} and ending at {@code to} inclusive. - * The two may be the same, but they must be in the correct order. - * So giving the first constant twice would give a set with just that - * constant set, while supplying the first and second constant will give - * a set with those two elements. However, specifying the second as - * the {@code from} element followed by an earlier element as the - * {@code to} element will result in an error. - * - * @param from the element to start from. - * @param to the element to end at (may be the same as {@code from}. - * @return an {@link EnumSet} containing the specified range of elements. - * @throws NullPointerException if any of the parameters are <code>null</code>. - * @throws IllegalArgumentException if {@code first.compareTo(last) > 0}. - */ - public static <T extends Enum<T>> EnumSet<T> range(T from, T to) - { - if (from.compareTo(to) > 0) - throw new IllegalArgumentException(); - Class<T> type = from.getDeclaringClass(); - EnumSet<T> r = noneOf(type); - - T[] values = type.getEnumConstants(); - // skip over values until start of range is found - int i = 0; - while (from != values[i]) - i++; - - // add values until end of range is found - while (to != values[i]) { - r.add(values[i]); - i++; - } - - // add end of range - r.add(to); - - return r; - } -} diff --git a/libjava/classpath/java/util/Enumeration.java b/libjava/classpath/java/util/Enumeration.java deleted file mode 100644 index 2aec31b..0000000 --- a/libjava/classpath/java/util/Enumeration.java +++ /dev/null @@ -1,82 +0,0 @@ -/* Enumeration.java -- Interface for enumerating lists of objects - 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; - -/* 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<E> -{ - /** - * 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 - */ - E nextElement(); -} diff --git a/libjava/classpath/java/util/EventListener.java b/libjava/classpath/java/util/EventListener.java deleted file mode 100644 index c9a1795..0000000 --- a/libjava/classpath/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/classpath/java/util/EventListenerProxy.java b/libjava/classpath/java/util/EventListenerProxy.java deleted file mode 100644 index 245c5ff..0000000 --- a/libjava/classpath/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/classpath/java/util/EventObject.java b/libjava/classpath/java/util/EventObject.java deleted file mode 100644 index 7ced18a..0000000 --- a/libjava/classpath/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/classpath/java/util/FormatFlagsConversionMismatchException.java b/libjava/classpath/java/util/FormatFlagsConversionMismatchException.java deleted file mode 100644 index b28ded1..0000000 --- a/libjava/classpath/java/util/FormatFlagsConversionMismatchException.java +++ /dev/null @@ -1,111 +0,0 @@ -/* FormatFlagsConversionMismatchException.java - Copyright (C) 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; - -/** - * Thrown when the flags supplied to the {@link Formatter#format()} - * method of a {@link Formatter} contains a flag that does not match - * the conversion character specified for it. - * - * @author Tom Tromey (tromey@redhat.com) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.5 - */ -public class FormatFlagsConversionMismatchException - extends IllegalFormatException -{ - private static final long serialVersionUID = 19120414L; - - /** - * The mismatching flag. - * - * @serial the mismatching flag. - */ - // Note: name fixed by serialization. - private String f; - - /** - * The conversion character which doesn't match the - * appropriate flag. - * - * @serial the conversion character which doesn't match its flag. - */ - // Note: name fixed by serialization. - private char c; - - /** - * Constructs a new <code>FormatFlagsConversionMismatchException</code> - * which specifies that the flag, <code>f</code>, does - * not match its appropriate conversion character, <code>c</code>. - * - * @param f the mismatching flag. - * @param c the conversion character which doesn't match its flag. - * @throws NullPointerException if <code>f</code> is null. - */ - public FormatFlagsConversionMismatchException(String f, char c) - { - super("Invalid flag " + f + " for conversion " + c); - if (f == null) - throw new - NullPointerException("Null flag value passed to constructor."); - this.f = f; - this.c = c; - } - - /** - * Returns the conversion character which doesn't - * match the flag. - * - * @return the conversion character. - */ - public char getConversion() - { - return c; - } - - /** - * Returns the mismatching flag. - * - * @return the mismatching flag. - */ - public String getFlags() - { - return f; - } -} diff --git a/libjava/classpath/java/util/Formattable.java b/libjava/classpath/java/util/Formattable.java deleted file mode 100644 index 6a83ed5d..0000000 --- a/libjava/classpath/java/util/Formattable.java +++ /dev/null @@ -1,92 +0,0 @@ -/* Formattable.java -- Objects which can be passed to a Formatter - Copyright (C) 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; - -/** - * <p> - * The <code>Formattable</code> interface is used to provide customised - * formatting to arbitrary objects via the {@link Formatter}. The - * {@link #formatTo} method is called for <code>Formattable</code> - * objects used with the 's' conversion operator, allowing the object - * to provide its own formatting of its internal data. - * </p> - * <p> - * Thread safety is left up to the implementing class. Thus, - * {@link Formattable} objects are not guaranteed to be thread-safe, - * and users should make their own provisions for multiple thread access. - * </p> - * - * @author Tom Tromey (tromey@redhat.com) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.5 - */ -public interface Formattable -{ - - /** - * Formats the object using the supplied formatter to the specification - * provided by the given flags, width and precision. - * - * @param formatter the formatter to use for formatting the object. - * The formatter gives access to the output stream - * and locale via {@link Formatter#out()} and - * {@link Formatter#locale()} respectively. - * @param flags a bit mask constructed from the flags in the - * {@link FormattableFlags} class. When no flags - * are set, the implementing class should use its - * defaults. - * @param width the minimum number of characters to include. - * A value of -1 indicates no minimum. The remaining - * space is padded with ' ' either on the left - * (the default) or right (if left justification is - * specified by the flags). - * @param precision the maximum number of characters to include. - * A value of -1 indicates no maximum. This value - * is applied prior to the minimum (the width). Thus, - * a value may meet the minimum width initially, but - * not when the width value is applied, due to - * characters being removed by the precision value. - * @throws IllegalFormatException if there is a problem with - * the syntax of the format - * specification or a mismatch - * between it and the arguments. - */ - public void formatTo(Formatter formatter, int flags, int width, - int precision); -} diff --git a/libjava/classpath/java/util/FormattableFlags.java b/libjava/classpath/java/util/FormattableFlags.java deleted file mode 100644 index 2c5e199..0000000 --- a/libjava/classpath/java/util/FormattableFlags.java +++ /dev/null @@ -1,123 +0,0 @@ -/* FormattableFlags.java -- - Copyright (C) 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 contains a set of flags used - * by the {@link Formattable#formatTo()} method. - * They are used to modify the output of the - * {@link Formattable}. The interpretation and - * validation of the flags is left to the - * particular {@link Formattable}. - * - * @author Tom Tromey (tromey@redhat.com) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.5 - */ -public class FormattableFlags -{ - - /** - * Requires the output to be left-justified. Any spaces - * required to meet the specified width will be added to - * the right of the output. The default output is - * right-justified, where spaces are added to the left. - * The output is as for the format specifier - * '-' ('\u002d'). - */ - public static final int LEFT_JUSTIFY = 1; - - /** - * Requires the output to be in uppercase. The output - * should be the same as the result from calling - * {@link String#toUpperCase(java.util.Locale)} with - * the formatting locale. The output is as for the - * format specifier '^' ('\u005e'). - */ - public static final int UPPERCASE = 2; - - /** - * Requires the use of an alternate form, as specified - * in the documentation of {@link Formattable}. - * The output is as for the format specifier - * '#' ('\u0023'). - */ - public static final int ALTERNATE = 4; - - // Used internally by Formatter. - // Changes here must be reflected in the FLAGS string there. - - /** - * Requires the output to always include a '+' sign. - * The output is as for the format specifier '+'. - */ - static final int PLUS = 8; - - /** - * Requires the output to include a leading space on - * positive value. The output is as for the format - * specifier ' '. - */ - static final int SPACE = 16; - - /** - * Requires the output to be zero-padded. The output - * is as for the format specifier '0'. - */ - static final int ZERO = 32; - - /** - * Requires the output to include locale-specific - * grouping operators. The output is as for the - * format specifier ','. - */ - static final int COMMA = 64; - - /** - * Requires the output to include negative numbers - * enclosed in parentheses. The output is as for - * the format specifier '('. - */ - static final int PAREN = 128; - - // Not instantiable. - private FormattableFlags() - { - } -} diff --git a/libjava/classpath/java/util/Formatter.java b/libjava/classpath/java/util/Formatter.java deleted file mode 100644 index 466fab5..0000000 --- a/libjava/classpath/java/util/Formatter.java +++ /dev/null @@ -1,1513 +0,0 @@ -/* Formatter.java -- printf-style formatting - Copyright (C) 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 gnu.java.lang.CPStringBuilder; - -import java.io.Closeable; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.Flushable; -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.PrintStream; -import java.io.UnsupportedEncodingException; -import java.math.BigInteger; -import java.text.DateFormatSymbols; -import java.text.DecimalFormatSymbols; - -import gnu.classpath.SystemProperties; - -/** - * <p> - * A Java formatter for <code>printf</code>-style format strings, - * as seen in the C programming language. This differs from the - * C interpretation of such strings by performing much stricter - * checking of format specifications and their corresponding - * arguments. While unknown conversions will be ignored in C, - * and invalid conversions will only produce compiler warnings, - * the Java version utilises a full range of run-time exceptions to - * handle these cases. The Java version is also more customisable - * by virtue of the provision of the {@link Formattable} interface, - * which allows an arbitrary class to be formatted by the formatter. - * </p> - * <p> - * The formatter is accessible by more convienient static methods. - * For example, streams now have appropriate format methods - * (the equivalent of <code>fprintf</code>) as do <code>String</code> - * objects (the equivalent of <code>sprintf</code>). - * </p> - * <p> - * <strong>Note</strong>: the formatter is not thread-safe. For - * multi-threaded access, external synchronization should be provided. - * </p> - * - * @author Tom Tromey (tromey@redhat.com) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.5 - */ -public final class Formatter - implements Closeable, Flushable -{ - - /** - * The output of the formatter. - */ - private Appendable out; - - /** - * The locale used by the formatter. - */ - private Locale locale; - - /** - * Whether or not the formatter is closed. - */ - private boolean closed; - - /** - * The last I/O exception thrown by the output stream. - */ - private IOException ioException; - - // Some state used when actually formatting. - /** - * The format string. - */ - private String format; - - /** - * The current index into the string. - */ - private int index; - - /** - * The length of the format string. - */ - private int length; - - /** - * The formatting locale. - */ - private Locale fmtLocale; - - // Note that we include '-' twice. The flags are ordered to - // correspond to the values in FormattableFlags, and there is no - // flag (in the sense of this field used when parsing) for - // UPPERCASE; the second '-' serves as a placeholder. - /** - * A string used to index into the formattable flags. - */ - private static final String FLAGS = "--#+ 0,("; - - /** - * The system line separator. - */ - private static final String lineSeparator - = SystemProperties.getProperty("line.separator"); - - /** - * The type of numeric output format for a {@link BigDecimal}. - */ - public enum BigDecimalLayoutForm - { - DECIMAL_FLOAT, - SCIENTIFIC - } - - /** - * Constructs a new <code>Formatter</code> using the default - * locale and a {@link StringBuilder} as the output stream. - */ - public Formatter() - { - this(null, Locale.getDefault()); - } - - /** - * Constructs a new <code>Formatter</code> using the specified - * locale and a {@link StringBuilder} as the output stream. - * If the locale is <code>null</code>, then no localization - * is applied. - * - * @param loc the locale to use. - */ - public Formatter(Locale loc) - { - this(null, loc); - } - - /** - * Constructs a new <code>Formatter</code> using the default - * locale and the specified output stream. - * - * @param app the output stream to use. - */ - public Formatter(Appendable app) - { - this(app, Locale.getDefault()); - } - - /** - * Constructs a new <code>Formatter</code> using the specified - * locale and the specified output stream. If the locale is - * <code>null</code>, then no localization is applied. - * - * @param app the output stream to use. - * @param loc the locale to use. - */ - public Formatter(Appendable app, Locale loc) - { - this.out = app == null ? new StringBuilder() : app; - this.locale = loc; - } - - /** - * Constructs a new <code>Formatter</code> using the default - * locale and character set, with the specified file as the - * output stream. - * - * @param file the file to use for output. - * @throws FileNotFoundException if the file does not exist - * and can not be created. - * @throws SecurityException if a security manager is present - * and doesn't allow writing to the file. - */ - public Formatter(File file) - throws FileNotFoundException - { - this(new OutputStreamWriter(new FileOutputStream(file))); - } - - /** - * Constructs a new <code>Formatter</code> using the default - * locale, with the specified file as the output stream - * and the supplied character set. - * - * @param file the file to use for output. - * @param charset the character set to use for output. - * @throws FileNotFoundException if the file does not exist - * and can not be created. - * @throws SecurityException if a security manager is present - * and doesn't allow writing to the file. - * @throws UnsupportedEncodingException if the supplied character - * set is not supported. - */ - public Formatter(File file, String charset) - throws FileNotFoundException, UnsupportedEncodingException - { - this(file, charset, Locale.getDefault()); - } - - /** - * Constructs a new <code>Formatter</code> using the specified - * file as the output stream with the supplied character set - * and locale. If the locale is <code>null</code>, then no - * localization is applied. - * - * @param file the file to use for output. - * @param charset the character set to use for output. - * @param loc the locale to use. - * @throws FileNotFoundException if the file does not exist - * and can not be created. - * @throws SecurityException if a security manager is present - * and doesn't allow writing to the file. - * @throws UnsupportedEncodingException if the supplied character - * set is not supported. - */ - public Formatter(File file, String charset, Locale loc) - throws FileNotFoundException, UnsupportedEncodingException - { - this(new OutputStreamWriter(new FileOutputStream(file), charset), - loc); - } - - /** - * Constructs a new <code>Formatter</code> using the default - * locale and character set, with the specified output stream. - * - * @param out the output stream to use. - */ - public Formatter(OutputStream out) - { - this(new OutputStreamWriter(out)); - } - - /** - * Constructs a new <code>Formatter</code> using the default - * locale, with the specified file output stream and the - * supplied character set. - * - * @param out the output stream. - * @param charset the character set to use for output. - * @throws UnsupportedEncodingException if the supplied character - * set is not supported. - */ - public Formatter(OutputStream out, String charset) - throws UnsupportedEncodingException - { - this(out, charset, Locale.getDefault()); - } - - /** - * Constructs a new <code>Formatter</code> using the specified - * output stream with the supplied character set and locale. - * If the locale is <code>null</code>, then no localization is - * applied. - * - * @param out the output stream. - * @param charset the character set to use for output. - * @param loc the locale to use. - * @throws UnsupportedEncodingException if the supplied character - * set is not supported. - */ - public Formatter(OutputStream out, String charset, Locale loc) - throws UnsupportedEncodingException - { - this(new OutputStreamWriter(out, charset), loc); - } - - /** - * Constructs a new <code>Formatter</code> using the default - * locale with the specified output stream. The character - * set used is that of the output stream. - * - * @param out the output stream to use. - */ - public Formatter(PrintStream out) - { - this((Appendable) out); - } - - /** - * Constructs a new <code>Formatter</code> using the default - * locale and character set, with the specified file as the - * output stream. - * - * @param file the file to use for output. - * @throws FileNotFoundException if the file does not exist - * and can not be created. - * @throws SecurityException if a security manager is present - * and doesn't allow writing to the file. - */ - public Formatter(String file) throws FileNotFoundException - { - this(new OutputStreamWriter(new FileOutputStream(file))); - } - - /** - * Constructs a new <code>Formatter</code> using the default - * locale, with the specified file as the output stream - * and the supplied character set. - * - * @param file the file to use for output. - * @param charset the character set to use for output. - * @throws FileNotFoundException if the file does not exist - * and can not be created. - * @throws SecurityException if a security manager is present - * and doesn't allow writing to the file. - * @throws UnsupportedEncodingException if the supplied character - * set is not supported. - */ - public Formatter(String file, String charset) - throws FileNotFoundException, UnsupportedEncodingException - { - this(file, charset, Locale.getDefault()); - } - - /** - * Constructs a new <code>Formatter</code> using the specified - * file as the output stream with the supplied character set - * and locale. If the locale is <code>null</code>, then no - * localization is applied. - * - * @param file the file to use for output. - * @param charset the character set to use for output. - * @param loc the locale to use. - * @throws FileNotFoundException if the file does not exist - * and can not be created. - * @throws SecurityException if a security manager is present - * and doesn't allow writing to the file. - * @throws UnsupportedEncodingException if the supplied character - * set is not supported. - */ - public Formatter(String file, String charset, Locale loc) - throws FileNotFoundException, UnsupportedEncodingException - { - this(new OutputStreamWriter(new FileOutputStream(file), charset), - loc); - } - - /** - * Closes the formatter, so as to release used resources. - * If the underlying output stream supports the {@link Closeable} - * interface, then this is also closed. Attempts to use - * a formatter instance, via any method other than - * {@link #ioException()}, after closure results in a - * {@link FormatterClosedException}. - */ - public void close() - { - if (closed) - return; - try - { - if (out instanceof Closeable) - ((Closeable) out).close(); - } - catch (IOException _) - { - // FIXME: do we ignore these or do we set ioException? - // The docs seem to indicate that we should ignore. - } - closed = true; - } - - /** - * Flushes the formatter, writing any cached data to the output - * stream. If the underlying output stream supports the - * {@link Flushable} interface, it is also flushed. - * - * @throws FormatterClosedException if the formatter is closed. - */ - public void flush() - { - if (closed) - throw new FormatterClosedException(); - try - { - if (out instanceof Flushable) - ((Flushable) out).flush(); - } - catch (IOException _) - { - // FIXME: do we ignore these or do we set ioException? - // The docs seem to indicate that we should ignore. - } - } - - /** - * Return the name corresponding to a flag. - * - * @param flags the flag to return the name of. - * @return the name of the flag. - */ - private String getName(int flags) - { - // FIXME: do we want all the flags in here? - // Or should we redo how this is reported? - int bit = Integer.numberOfTrailingZeros(flags); - return FLAGS.substring(bit, bit + 1); - } - - /** - * Verify the flags passed to a conversion. - * - * @param flags the flags to verify. - * @param allowed the allowed flags mask. - * @param conversion the conversion character. - */ - private void checkFlags(int flags, int allowed, char conversion) - { - flags &= ~allowed; - if (flags != 0) - throw new FormatFlagsConversionMismatchException(getName(flags), - conversion); - } - - /** - * Throw an exception if a precision was specified. - * - * @param precision the precision value (-1 indicates not specified). - */ - private void noPrecision(int precision) - { - if (precision != -1) - throw new IllegalFormatPrecisionException(precision); - } - - /** - * Apply the numeric localization algorithm to a StringBuilder. - * - * @param builder the builder to apply to. - * @param flags the formatting flags to use. - * @param width the width of the numeric value. - * @param isNegative true if the value is negative. - */ - private void applyLocalization(CPStringBuilder builder, int flags, int width, - boolean isNegative) - { - DecimalFormatSymbols dfsyms; - if (fmtLocale == null) - dfsyms = new DecimalFormatSymbols(); - else - dfsyms = new DecimalFormatSymbols(fmtLocale); - - // First replace each digit. - char zeroDigit = dfsyms.getZeroDigit(); - int decimalOffset = -1; - for (int i = builder.length() - 1; i >= 0; --i) - { - char c = builder.charAt(i); - if (c >= '0' && c <= '9') - builder.setCharAt(i, (char) (c - '0' + zeroDigit)); - else if (c == '.') - { - assert decimalOffset == -1; - decimalOffset = i; - } - } - - // Localize the decimal separator. - if (decimalOffset != -1) - { - builder.deleteCharAt(decimalOffset); - builder.insert(decimalOffset, dfsyms.getDecimalSeparator()); - } - - // Insert the grouping separators. - if ((flags & FormattableFlags.COMMA) != 0) - { - char groupSeparator = dfsyms.getGroupingSeparator(); - int groupSize = 3; // FIXME - int offset = (decimalOffset == -1) ? builder.length() : decimalOffset; - // We use '>' because we don't want to insert a separator - // before the first digit. - for (int i = offset - groupSize; i > 0; i -= groupSize) - builder.insert(i, groupSeparator); - } - - if ((flags & FormattableFlags.ZERO) != 0) - { - // Zero fill. Note that according to the algorithm we do not - // insert grouping separators here. - for (int i = width - builder.length(); i > 0; --i) - builder.insert(0, zeroDigit); - } - - if (isNegative) - { - if ((flags & FormattableFlags.PAREN) != 0) - { - builder.insert(0, '('); - builder.append(')'); - } - else - builder.insert(0, '-'); - } - else if ((flags & FormattableFlags.PLUS) != 0) - builder.insert(0, '+'); - else if ((flags & FormattableFlags.SPACE) != 0) - builder.insert(0, ' '); - } - - /** - * A helper method that handles emitting a String after applying - * precision, width, justification, and upper case flags. - * - * @param arg the string to emit. - * @param flags the formatting flags to use. - * @param width the width to use. - * @param precision the precision to use. - * @throws IOException if the output stream throws an I/O error. - */ - private void genericFormat(String arg, int flags, int width, int precision) - throws IOException - { - if ((flags & FormattableFlags.UPPERCASE) != 0) - { - if (fmtLocale == null) - arg = arg.toUpperCase(); - else - arg = arg.toUpperCase(fmtLocale); - } - - if (precision >= 0 && arg.length() > precision) - arg = arg.substring(0, precision); - - boolean leftJustify = (flags & FormattableFlags.LEFT_JUSTIFY) != 0; - if (leftJustify && width == -1) - throw new MissingFormatWidthException("fixme"); - if (! leftJustify && arg.length() < width) - { - for (int i = width - arg.length(); i > 0; --i) - out.append(' '); - } - out.append(arg); - if (leftJustify && arg.length() < width) - { - for (int i = width - arg.length(); i > 0; --i) - out.append(' '); - } - } - - /** - * Emit a boolean. - * - * @param arg the boolean to emit. - * @param flags the formatting flags to use. - * @param width the width to use. - * @param precision the precision to use. - * @param conversion the conversion character. - * @throws IOException if the output stream throws an I/O error. - */ - private void booleanFormat(Object arg, int flags, int width, int precision, - char conversion) - throws IOException - { - checkFlags(flags, - FormattableFlags.LEFT_JUSTIFY | FormattableFlags.UPPERCASE, - conversion); - String result; - if (arg instanceof Boolean) - result = String.valueOf((Boolean) arg); - else - result = arg == null ? "false" : "true"; - genericFormat(result, flags, width, precision); - } - - /** - * Emit a hash code. - * - * @param arg the hash code to emit. - * @param flags the formatting flags to use. - * @param width the width to use. - * @param precision the precision to use. - * @param conversion the conversion character. - * @throws IOException if the output stream throws an I/O error. - */ - private void hashCodeFormat(Object arg, int flags, int width, int precision, - char conversion) - throws IOException - { - checkFlags(flags, - FormattableFlags.LEFT_JUSTIFY | FormattableFlags.UPPERCASE, - conversion); - genericFormat(arg == null ? "null" : Integer.toHexString(arg.hashCode()), - flags, width, precision); - } - - /** - * Emit a String or Formattable conversion. - * - * @param arg the String or Formattable to emit. - * @param flags the formatting flags to use. - * @param width the width to use. - * @param precision the precision to use. - * @param conversion the conversion character. - * @throws IOException if the output stream throws an I/O error. - */ - private void stringFormat(Object arg, int flags, int width, int precision, - char conversion) - throws IOException - { - if (arg instanceof Formattable) - { - checkFlags(flags, - (FormattableFlags.LEFT_JUSTIFY - | FormattableFlags.UPPERCASE - | FormattableFlags.ALTERNATE), - conversion); - Formattable fmt = (Formattable) arg; - fmt.formatTo(this, flags, width, precision); - } - else - { - checkFlags(flags, - FormattableFlags.LEFT_JUSTIFY | FormattableFlags.UPPERCASE, - conversion); - genericFormat(arg == null ? "null" : arg.toString(), flags, width, - precision); - } - } - - /** - * Emit a character. - * - * @param arg the character to emit. - * @param flags the formatting flags to use. - * @param width the width to use. - * @param precision the precision to use. - * @param conversion the conversion character. - * @throws IOException if the output stream throws an I/O error. - */ - private void characterFormat(Object arg, int flags, int width, int precision, - char conversion) - throws IOException - { - checkFlags(flags, - FormattableFlags.LEFT_JUSTIFY | FormattableFlags.UPPERCASE, - conversion); - noPrecision(precision); - - if (arg == null) - { - genericFormat("null", flags, width, precision); - return; - } - - int theChar; - if (arg instanceof Character) - theChar = ((Character) arg).charValue(); - else if (arg instanceof Byte) - theChar = (char) (((Byte) arg).byteValue ()); - else if (arg instanceof Short) - theChar = (char) (((Short) arg).shortValue ()); - else if (arg instanceof Integer) - { - theChar = ((Integer) arg).intValue(); - if (! Character.isValidCodePoint(theChar)) - throw new IllegalFormatCodePointException(theChar); - } - else - throw new IllegalFormatConversionException(conversion, arg.getClass()); - String result = new String(Character.toChars(theChar)); - genericFormat(result, flags, width, precision); - } - - /** - * Emit a '%'. - * - * @param flags the formatting flags to use. - * @param width the width to use. - * @param precision the precision to use. - * @throws IOException if the output stream throws an I/O error. - */ - private void percentFormat(int flags, int width, int precision) - throws IOException - { - checkFlags(flags, FormattableFlags.LEFT_JUSTIFY, '%'); - noPrecision(precision); - genericFormat("%", flags, width, precision); - } - - /** - * Emit a newline. - * - * @param flags the formatting flags to use. - * @param width the width to use. - * @param precision the precision to use. - * @throws IOException if the output stream throws an I/O error. - */ - private void newLineFormat(int flags, int width, int precision) - throws IOException - { - checkFlags(flags, 0, 'n'); - noPrecision(precision); - if (width != -1) - throw new IllegalFormatWidthException(width); - genericFormat(lineSeparator, flags, width, precision); - } - - /** - * Helper method to do initial formatting and checking for integral - * conversions. - * - * @param arg the formatted argument. - * @param flags the formatting flags to use. - * @param width the width to use. - * @param precision the precision to use. - * @param radix the radix of the number. - * @param conversion the conversion character. - * @return the result. - */ - private CPStringBuilder basicIntegralConversion(Object arg, int flags, - int width, int precision, - int radix, char conversion) - { - assert radix == 8 || radix == 10 || radix == 16; - - if (arg == null) - { - return new CPStringBuilder("null"); - } - - noPrecision(precision); - - // Some error checking. - if ((flags & FormattableFlags.PLUS) != 0 - && (flags & FormattableFlags.SPACE) != 0) - throw new IllegalFormatFlagsException(getName(flags)); - - if ((flags & FormattableFlags.LEFT_JUSTIFY) != 0 && width == -1) - throw new MissingFormatWidthException("fixme"); - - // Do the base translation of the value to a string. - String result; - int basicFlags = (FormattableFlags.LEFT_JUSTIFY - // We already handled any possible error when - // parsing. - | FormattableFlags.UPPERCASE - | FormattableFlags.ZERO); - if (radix == 10) - basicFlags |= (FormattableFlags.PLUS - | FormattableFlags.SPACE - | FormattableFlags.COMMA - | FormattableFlags.PAREN); - else - basicFlags |= FormattableFlags.ALTERNATE; - - if (arg instanceof BigInteger) - { - checkFlags(flags, - (basicFlags - | FormattableFlags.PLUS - | FormattableFlags.SPACE - | FormattableFlags.PAREN), - conversion); - BigInteger bi = (BigInteger) arg; - result = bi.toString(radix); - } - else if (arg instanceof Number - && ! (arg instanceof Float) - && ! (arg instanceof Double)) - { - checkFlags(flags, basicFlags, conversion); - long value = ((Number) arg).longValue (); - if (radix == 8) - result = Long.toOctalString(value); - else if (radix == 16) - result = Long.toHexString(value); - else - result = Long.toString(value); - } - else - throw new IllegalFormatConversionException(conversion, arg.getClass()); - - return new CPStringBuilder(result); - } - - /** - * Emit a hex or octal value. - * - * @param arg the hexadecimal or octal value. - * @param flags the formatting flags to use. - * @param width the width to use. - * @param precision the precision to use. - * @param radix the radix of the number. - * @param conversion the conversion character. - * @throws IOException if the output stream throws an I/O error. - */ - private void hexOrOctalConversion(Object arg, int flags, int width, - int precision, int radix, - char conversion) - throws IOException - { - assert radix == 8 || radix == 16; - - CPStringBuilder builder = basicIntegralConversion(arg, flags, width, - precision, radix, - conversion); - int insertPoint = 0; - - // Insert the sign. - if (builder.charAt(0) == '-') - { - // Already inserted. Note that we don't insert a sign, since - // the only case where it is needed it BigInteger, and it has - // already been inserted by toString. - ++insertPoint; - } - else if ((flags & FormattableFlags.PLUS) != 0) - { - builder.insert(insertPoint, '+'); - ++insertPoint; - } - else if ((flags & FormattableFlags.SPACE) != 0) - { - builder.insert(insertPoint, ' '); - ++insertPoint; - } - - // Insert the radix prefix. - if ((flags & FormattableFlags.ALTERNATE) != 0) - { - builder.insert(insertPoint, radix == 8 ? "0" : "0x"); - insertPoint += radix == 8 ? 1 : 2; - } - - // Now justify the result. - int resultWidth = builder.length(); - if (resultWidth < width) - { - char fill = ((flags & FormattableFlags.ZERO) != 0) ? '0' : ' '; - if ((flags & FormattableFlags.LEFT_JUSTIFY) != 0) - { - // Left justify. - if (fill == ' ') - insertPoint = builder.length(); - } - else - { - // Right justify. Insert spaces before the radix prefix - // and sign. - insertPoint = 0; - } - while (resultWidth++ < width) - builder.insert(insertPoint, fill); - } - - String result = builder.toString(); - if ((flags & FormattableFlags.UPPERCASE) != 0) - { - if (fmtLocale == null) - result = result.toUpperCase(); - else - result = result.toUpperCase(fmtLocale); - } - - out.append(result); - } - - /** - * Emit a decimal value. - * - * @param arg the hexadecimal or octal value. - * @param flags the formatting flags to use. - * @param width the width to use. - * @param precision the precision to use. - * @param conversion the conversion character. - * @throws IOException if the output stream throws an I/O error. - */ - private void decimalConversion(Object arg, int flags, int width, - int precision, char conversion) - throws IOException - { - CPStringBuilder builder = basicIntegralConversion(arg, flags, width, - precision, 10, - conversion); - boolean isNegative = false; - if (builder.charAt(0) == '-') - { - // Sign handling is done during localization. - builder.deleteCharAt(0); - isNegative = true; - } - - applyLocalization(builder, flags, width, isNegative); - genericFormat(builder.toString(), flags, width, precision); - } - - /** - * Emit a single date or time conversion to a StringBuilder. - * - * @param builder the builder to write to. - * @param cal the calendar to use in the conversion. - * @param conversion the formatting character to specify the type of data. - * @param syms the date formatting symbols. - */ - private void singleDateTimeConversion(CPStringBuilder builder, Calendar cal, - char conversion, - DateFormatSymbols syms) - { - int oldLen = builder.length(); - int digits = -1; - switch (conversion) - { - case 'H': - builder.append(cal.get(Calendar.HOUR_OF_DAY)); - digits = 2; - break; - case 'I': - builder.append(cal.get(Calendar.HOUR)); - digits = 2; - break; - case 'k': - builder.append(cal.get(Calendar.HOUR_OF_DAY)); - break; - case 'l': - builder.append(cal.get(Calendar.HOUR)); - break; - case 'M': - builder.append(cal.get(Calendar.MINUTE)); - digits = 2; - break; - case 'S': - builder.append(cal.get(Calendar.SECOND)); - digits = 2; - break; - case 'N': - // FIXME: nanosecond ... - digits = 9; - break; - case 'p': - { - int ampm = cal.get(Calendar.AM_PM); - builder.append(syms.getAmPmStrings()[ampm]); - } - break; - case 'z': - { - int zone = cal.get(Calendar.ZONE_OFFSET) / (1000 * 60); - builder.append(zone); - digits = 4; - // Skip the '-' sign. - if (zone < 0) - ++oldLen; - } - break; - case 'Z': - { - // FIXME: DST? - int zone = cal.get(Calendar.ZONE_OFFSET) / (1000 * 60 * 60); - String[][] zs = syms.getZoneStrings(); - builder.append(zs[zone + 12][1]); - } - break; - case 's': - { - long val = cal.getTime().getTime(); - builder.append(val / 1000); - } - break; - case 'Q': - { - long val = cal.getTime().getTime(); - builder.append(val); - } - break; - case 'B': - { - int month = cal.get(Calendar.MONTH); - builder.append(syms.getMonths()[month]); - } - break; - case 'b': - case 'h': - { - int month = cal.get(Calendar.MONTH); - builder.append(syms.getShortMonths()[month]); - } - break; - case 'A': - { - int day = cal.get(Calendar.DAY_OF_WEEK); - builder.append(syms.getWeekdays()[day]); - } - break; - case 'a': - { - int day = cal.get(Calendar.DAY_OF_WEEK); - builder.append(syms.getShortWeekdays()[day]); - } - break; - case 'C': - builder.append(cal.get(Calendar.YEAR) / 100); - digits = 2; - break; - case 'Y': - builder.append(cal.get(Calendar.YEAR)); - digits = 4; - break; - case 'y': - builder.append(cal.get(Calendar.YEAR) % 100); - digits = 2; - break; - case 'j': - builder.append(cal.get(Calendar.DAY_OF_YEAR)); - digits = 3; - break; - case 'm': - builder.append(cal.get(Calendar.MONTH) + 1); - digits = 2; - break; - case 'd': - builder.append(cal.get(Calendar.DAY_OF_MONTH)); - digits = 2; - break; - case 'e': - builder.append(cal.get(Calendar.DAY_OF_MONTH)); - break; - case 'R': - singleDateTimeConversion(builder, cal, 'H', syms); - builder.append(':'); - singleDateTimeConversion(builder, cal, 'M', syms); - break; - case 'T': - singleDateTimeConversion(builder, cal, 'H', syms); - builder.append(':'); - singleDateTimeConversion(builder, cal, 'M', syms); - builder.append(':'); - singleDateTimeConversion(builder, cal, 'S', syms); - break; - case 'r': - singleDateTimeConversion(builder, cal, 'I', syms); - builder.append(':'); - singleDateTimeConversion(builder, cal, 'M', syms); - builder.append(':'); - singleDateTimeConversion(builder, cal, 'S', syms); - builder.append(' '); - singleDateTimeConversion(builder, cal, 'p', syms); - break; - case 'D': - singleDateTimeConversion(builder, cal, 'm', syms); - builder.append('/'); - singleDateTimeConversion(builder, cal, 'd', syms); - builder.append('/'); - singleDateTimeConversion(builder, cal, 'y', syms); - break; - case 'F': - singleDateTimeConversion(builder, cal, 'Y', syms); - builder.append('-'); - singleDateTimeConversion(builder, cal, 'm', syms); - builder.append('-'); - singleDateTimeConversion(builder, cal, 'd', syms); - break; - case 'c': - singleDateTimeConversion(builder, cal, 'a', syms); - builder.append(' '); - singleDateTimeConversion(builder, cal, 'b', syms); - builder.append(' '); - singleDateTimeConversion(builder, cal, 'd', syms); - builder.append(' '); - singleDateTimeConversion(builder, cal, 'T', syms); - builder.append(' '); - singleDateTimeConversion(builder, cal, 'Z', syms); - builder.append(' '); - singleDateTimeConversion(builder, cal, 'Y', syms); - break; - default: - throw new UnknownFormatConversionException(String.valueOf(conversion)); - } - - if (digits > 0) - { - int newLen = builder.length(); - int delta = newLen - oldLen; - while (delta++ < digits) - builder.insert(oldLen, '0'); - } - } - - /** - * Emit a date or time value. - * - * @param arg the date or time value. - * @param flags the formatting flags to use. - * @param width the width to use. - * @param precision the precision to use. - * @param conversion the conversion character. - * @param subConversion the sub conversion character. - * @throws IOException if the output stream throws an I/O error. - */ - private void dateTimeConversion(Object arg, int flags, int width, - int precision, char conversion, - char subConversion) - throws IOException - { - noPrecision(precision); - checkFlags(flags, - FormattableFlags.LEFT_JUSTIFY | FormattableFlags.UPPERCASE, - conversion); - - Calendar cal; - if (arg instanceof Calendar) - cal = (Calendar) arg; - else - { - Date date; - if (arg instanceof Date) - date = (Date) arg; - else if (arg instanceof Long) - date = new Date(((Long) arg).longValue()); - else - throw new IllegalFormatConversionException(conversion, - arg.getClass()); - if (fmtLocale == null) - cal = Calendar.getInstance(); - else - cal = Calendar.getInstance(fmtLocale); - cal.setTime(date); - } - - // We could try to be more efficient by computing this lazily. - DateFormatSymbols syms; - if (fmtLocale == null) - syms = new DateFormatSymbols(); - else - syms = new DateFormatSymbols(fmtLocale); - - CPStringBuilder result = new CPStringBuilder(); - singleDateTimeConversion(result, cal, subConversion, syms); - - genericFormat(result.toString(), flags, width, precision); - } - - /** - * Advance the internal parsing index, and throw an exception - * on overrun. - * - * @throws IllegalArgumentException on overrun. - */ - private void advance() - { - ++index; - if (index >= length) - { - // FIXME: what exception here? - throw new IllegalArgumentException(); - } - } - - /** - * Parse an integer appearing in the format string. Will return -1 - * if no integer was found. - * - * @return the parsed integer. - */ - private int parseInt() - { - int start = index; - while (Character.isDigit(format.charAt(index))) - advance(); - if (start == index) - return -1; - return Integer.parseInt(format.substring(start, index)); - } - - /** - * Parse the argument index. Returns -1 if there was no index, 0 if - * we should re-use the previous index, and a positive integer to - * indicate an absolute index. - * - * @return the parsed argument index. - */ - private int parseArgumentIndex() - { - int result = -1; - int start = index; - if (format.charAt(index) == '<') - { - result = 0; - advance(); - } - else if (Character.isDigit(format.charAt(index))) - { - result = parseInt(); - if (format.charAt(index) == '$') - advance(); - else - { - // Reset. - index = start; - result = -1; - } - } - return result; - } - - /** - * Parse a set of flags and return a bit mask of values from - * FormattableFlags. Will throw an exception if a flag is - * duplicated. - * - * @return the parsed flags. - */ - private int parseFlags() - { - int value = 0; - int start = index; - while (true) - { - int x = FLAGS.indexOf(format.charAt(index)); - if (x == -1) - break; - int newValue = 1 << x; - if ((value & newValue) != 0) - throw new DuplicateFormatFlagsException(format.substring(start, - index + 1)); - value |= newValue; - advance(); - } - return value; - } - - /** - * Parse the width part of a format string. Returns -1 if no width - * was specified. - * - * @return the parsed width. - */ - private int parseWidth() - { - return parseInt(); - } - - /** - * If the current character is '.', parses the precision part of a - * format string. Returns -1 if no precision was specified. - * - * @return the parsed precision. - */ - private int parsePrecision() - { - if (format.charAt(index) != '.') - return -1; - advance(); - int precision = parseInt(); - if (precision == -1) - // FIXME - throw new IllegalArgumentException(); - return precision; - } - - /** - * Outputs a formatted string based on the supplied specification, - * <code>fmt</code>, and its arguments using the specified locale. - * The locale of the formatter does not change as a result; the - * specified locale is just used for this particular formatting - * operation. If the locale is <code>null</code>, then no - * localization is applied. - * - * @param loc the locale to use for this format. - * @param fmt the format specification. - * @param args the arguments to apply to the specification. - * @throws IllegalFormatException if there is a problem with - * the syntax of the format - * specification or a mismatch - * between it and the arguments. - * @throws FormatterClosedException if the formatter is closed. - */ - public Formatter format(Locale loc, String fmt, Object... args) - { - if (closed) - throw new FormatterClosedException(); - - // Note the arguments are indexed starting at 1. - int implicitArgumentIndex = 1; - int previousArgumentIndex = 0; - - try - { - fmtLocale = loc; - format = fmt; - length = format.length(); - for (index = 0; index < length; ++index) - { - char c = format.charAt(index); - if (c != '%') - { - out.append(c); - continue; - } - - int start = index; - advance(); - - // We do the needed post-processing of this later, when we - // determine whether an argument is actually needed by - // this conversion. - int argumentIndex = parseArgumentIndex(); - - int flags = parseFlags(); - int width = parseWidth(); - int precision = parsePrecision(); - char origConversion = format.charAt(index); - char conversion = origConversion; - if (Character.isUpperCase(conversion)) - { - flags |= FormattableFlags.UPPERCASE; - conversion = Character.toLowerCase(conversion); - } - - Object argument = null; - if (conversion == '%' || conversion == 'n') - { - if (argumentIndex != -1) - { - // FIXME: not sure about this. - throw new UnknownFormatConversionException("FIXME"); - } - } - else - { - if (argumentIndex == -1) - argumentIndex = implicitArgumentIndex++; - else if (argumentIndex == 0) - argumentIndex = previousArgumentIndex; - // Argument indices start at 1 but array indices at 0. - --argumentIndex; - if (args != null) - { - if (argumentIndex < 0 || argumentIndex >= args.length) - throw new MissingFormatArgumentException(format.substring(start, index)); - argument = args[argumentIndex]; - } - } - - switch (conversion) - { - case 'b': - booleanFormat(argument, flags, width, precision, - origConversion); - break; - case 'h': - hashCodeFormat(argument, flags, width, precision, - origConversion); - break; - case 's': - stringFormat(argument, flags, width, precision, - origConversion); - break; - case 'c': - characterFormat(argument, flags, width, precision, - origConversion); - break; - case 'd': - checkFlags(flags & FormattableFlags.UPPERCASE, 0, 'd'); - decimalConversion(argument, flags, width, precision, - origConversion); - break; - case 'o': - checkFlags(flags & FormattableFlags.UPPERCASE, 0, 'o'); - hexOrOctalConversion(argument, flags, width, precision, 8, - origConversion); - break; - case 'x': - hexOrOctalConversion(argument, flags, width, precision, 16, - origConversion); - case 'e': - // scientificNotationConversion(); - break; - case 'f': - // floatingDecimalConversion(); - break; - case 'g': - // smartFloatingConversion(); - break; - case 'a': - // hexFloatingConversion(); - break; - case 't': - advance(); - char subConversion = format.charAt(index); - dateTimeConversion(argument, flags, width, precision, - origConversion, subConversion); - break; - case '%': - percentFormat(flags, width, precision); - break; - case 'n': - newLineFormat(flags, width, precision); - break; - default: - throw new UnknownFormatConversionException(String.valueOf(origConversion)); - } - } - } - catch (IOException exc) - { - ioException = exc; - } - return this; - } - - /** - * Outputs a formatted string based on the supplied specification, - * <code>fmt</code>, and its arguments using the formatter's locale. - * - * @param format the format specification. - * @param args the arguments to apply to the specification. - * @throws IllegalFormatException if there is a problem with - * the syntax of the format - * specification or a mismatch - * between it and the arguments. - * @throws FormatterClosedException if the formatter is closed. - */ - public Formatter format(String format, Object... args) - { - return format(locale, format, args); - } - - /** - * Returns the last I/O exception thrown by the - * <code>append()</code> operation of the underlying - * output stream. - * - * @return the last I/O exception. - */ - public IOException ioException() - { - return ioException; - } - - /** - * Returns the locale used by this formatter. - * - * @return the formatter's locale. - * @throws FormatterClosedException if the formatter is closed. - */ - public Locale locale() - { - if (closed) - throw new FormatterClosedException(); - return locale; - } - - /** - * Returns the output stream used by this formatter. - * - * @return the formatter's output stream. - * @throws FormatterClosedException if the formatter is closed. - */ - public Appendable out() - { - if (closed) - throw new FormatterClosedException(); - return out; - } - - /** - * Returns the result of applying {@link Object#toString()} - * to the underlying output stream. The results returned - * depend on the particular {@link Appendable} being used. - * For example, a {@link StringBuilder} will return the - * formatted output but an I/O stream will not. - * - * @throws FormatterClosedException if the formatter is closed. - */ - public String toString() - { - if (closed) - throw new FormatterClosedException(); - return out.toString(); - } -} diff --git a/libjava/classpath/java/util/FormatterClosedException.java b/libjava/classpath/java/util/FormatterClosedException.java deleted file mode 100644 index 6206849..0000000 --- a/libjava/classpath/java/util/FormatterClosedException.java +++ /dev/null @@ -1,60 +0,0 @@ -/* FormatterClosedException.java - Copyright (C) 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; - -/** - * Thrown when a method is called on a {@link Formatter} but - * it has already been closed. - * - * @author Tom Tromey (tromey@redhat.com) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.5 - */ -public class FormatterClosedException - extends IllegalStateException -{ - private static final long serialVersionUID = 18111216L; - - /** - * Constructs a new <code>FormatterClosedException</code>. - */ - public FormatterClosedException() - { - } -} diff --git a/libjava/classpath/java/util/GregorianCalendar.java b/libjava/classpath/java/util/GregorianCalendar.java deleted file mode 100644 index b5d9e8c..0000000 --- a/libjava/classpath/java/util/GregorianCalendar.java +++ /dev/null @@ -1,1365 +0,0 @@ -/* java.util.GregorianCalendar - Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004, 2007 - 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; - - -/** - * <p> - * This class represents the Gregorian calendar, that is used in most - * countries all over the world. It does also handle the Julian calendar - * for dates smaller than the date of the change to the Gregorian calendar. - * The Gregorian calendar differs from the Julian calendar by a different - * leap year rule (no leap year every 100 years, except if year is divisible - * by 400). - * </p> - * <p> - * This change date is different from country to country, and can be changed with - * <code>setGregorianChange</code>. The first countries to adopt the Gregorian - * calendar did so on the 15th of October, 1582. This date followed October - * the 4th, 1582 in the Julian calendar system. The non-existant days that were - * omitted when the change took place are interpreted as Gregorian dates. - * </p> - * <p> - * Prior to the changeover date, New Year's Day occurred on the 25th of March. - * However, this class always takes New Year's Day as being the 1st of January. - * Client code should manually adapt the year value, if required, for dates - * between January the 1st and March the 24th in years prior to the changeover. - * </p> - * <p> - * Any date infinitely forwards or backwards in time can be represented by - * this class. A <em>proleptic</em> calendar system is used, which allows - * future dates to be created via the existing rules. This allows meaningful - * and consistent dates to be produced for all years. However, dates are only - * historically accurate following March the 1st, 4AD when the Julian calendar - * system was adopted. Prior to this, leap year rules were applied erraticly. - * </p> - * <p> - * There are two eras available for the Gregorian calendar, namely BC and AD. - * </p> - * <p> - * Weeks are defined as a period of seven days, beginning on the first day - * of the week, as returned by <code>getFirstDayOfWeek()</code>, and ending - * on the day prior to this. - * </p> - * <p> - * The weeks of the year are numbered from 1 to a possible 53. The first week - * of the year is defined as the first week that contains at least the minimum - * number of days of the first week in the new year (retrieved via - * <code>getMinimalDaysInFirstWeek()</code>). All weeks after this are numbered - * from 2 onwards. - * </p> - * <p> - * For example, take the year 2004. It began on a Thursday. The first week - * of 2004 depends both on where a week begins and how long it must minimally - * last. Let's say that the week begins on a Monday and must have a minimum - * of 5 days. In this case, the first week begins on Monday, the 5th of January. - * The first 4 days (Thursday to Sunday) are not eligible, as they are too few - * to make up the minimum number of days of the first week which must be in - * the new year. If the minimum was lowered to 4 days, then the first week - * would instead begin on Monday, the 29th of December, 2003. This first week - * has 4 of its days in the new year, and is now eligible. - * </p> - * <p> - * The weeks of the month are numbered from 0 to a possible 6. The first week - * of the month (numbered 1) is a set of days, prior to the first day of the week, - * which number at least the minimum number of days in a week. Unlike the first - * week of the year, the first week of the month only uses days from that particular - * month. As a consequence, it may have a variable number of days (from the minimum - * number required up to a full week of 7) and it need not start on the first day of - * the week. It must, however, be following by the first day of the week, as this - * marks the beginning of week 2. Any days of the month which occur prior to the - * first week (because the first day of the week occurs before the minimum number - * of days is met) are seen as week 0. - * </p> - * <p> - * Again, we will take the example of the year 2004 to demonstrate this. September - * 2004 begins on a Wednesday. Taking our first day of the week as Monday, and the - * minimum length of the first week as 6, we find that week 1 runs from Monday, - * the 6th of September to Sunday the 12th. Prior to the 6th, there are only - * 5 days (Wednesday through to Sunday). This is too small a number to meet the - * minimum, so these are classed as being days in week 0. Week 2 begins on the - * 13th, and so on. This changes if we reduce the minimum to 5. In this case, - * week 1 is a truncated week from Wednesday the 1st to Sunday the 5th, and week - * 0 doesn't exist. The first seven day week is week 2, starting on the 6th. - * </p> - * <p> - * On using the <code>clear()</code> method, the Gregorian calendar returns - * to its default value of the 1st of January, 1970 AD 00:00:00 (the epoch). - * The day of the week is set to the correct day for that particular time. - * The day is also the first of the month, and the date is in week 0. - * </p> - * - * @see Calendar - * @see TimeZone - * @see Calendar#getFirstDayOfWeek() - * @see Calendar#getMinimalDaysInFirstWeek() - */ -public class GregorianCalendar extends Calendar -{ - /** - * Constant representing the era BC (Before Christ). - */ - public static final int BC = 0; - - /** - * Constant representing the era AD (Anno Domini). - */ - public static final int AD = 1; - - /** - * The point at which the Gregorian calendar rules were used. - * This may be changed by using setGregorianChange; - * The default is midnight (UTC) on October 5, 1582 (Julian), - * or October 15, 1582 (Gregorian). - * - * @serial the changeover point from the Julian calendar - * system to the Gregorian. - */ - private long gregorianCutover = (new Date((24 * 60 * 60 * 1000L) * (((1582 * (365 * 4 - + 1)) / 4 - + (java.util.Calendar.OCTOBER * (31 - + 30 + 31 + 30 + 31) - 9) / 5 + 5) - - ((1970 * (365 * 4 + 1)) / 4 + 1 - - 13)))).getTime(); - - /** - * For compatability with Sun's JDK. - */ - static final long serialVersionUID = -8125100834729963327L; - - /** - * Days in the epoch. Relative Jan 1, year '0' which is not a leap year. - * (although there is no year zero, this does not matter.) - * This is consistent with the formula: - * = (year-1)*365L + ((year-1) >> 2) - * - * Plus the gregorian correction: - * Math.floor((year-1) / 400.) - Math.floor((year-1) / 100.); - * For a correct julian date, the correction is -2 instead. - * - * The gregorian cutover in 1582 was 10 days, so by calculating the - * correction from year zero, we have 15 non-leap days (even centuries) - * minus 3 leap days (year 400,800,1200) = 12. Subtracting two corrects - * this to the correct number 10. - */ - private static final int EPOCH_DAYS = 719162; - - /** - * Constructs a new GregorianCalender representing the current - * time, using the default time zone and the default locale. - */ - public GregorianCalendar() - { - this(TimeZone.getDefault(), Locale.getDefault()); - } - - /** - * Constructs a new GregorianCalender representing the current - * time, using the specified time zone and the default locale. - * - * @param zone a time zone. - */ - public GregorianCalendar(TimeZone zone) - { - this(zone, Locale.getDefault()); - } - - /** - * Constructs a new GregorianCalender representing the current - * time, using the default time zone and the specified locale. - * - * @param locale a locale. - */ - public GregorianCalendar(Locale locale) - { - this(TimeZone.getDefault(), locale); - } - - /** - * Constructs a new GregorianCalender representing the current - * time with the given time zone and the given locale. - * - * @param zone a time zone. - * @param locale a locale. - */ - public GregorianCalendar(TimeZone zone, Locale locale) - { - this(zone, locale, false); - setTimeInMillis(System.currentTimeMillis()); - } - - /** - * Common constructor that all constructors should call. - * @param zone a time zone. - * @param locale a locale. - * @param unused unused parameter to make the signature differ from - * the public constructor (TimeZone, Locale). - */ - private GregorianCalendar(TimeZone zone, Locale locale, boolean unused) - { - super(zone, locale); - } - - /** - * Constructs a new GregorianCalendar representing midnight on the - * given date with the default time zone and locale. - * - * @param year corresponds to the YEAR time field. - * @param month corresponds to the MONTH time field. - * @param day corresponds to the DAY time field. - */ - public GregorianCalendar(int year, int month, int day) - { - this(TimeZone.getDefault(), Locale.getDefault(), false); - set(year, month, day); - } - - /** - * Constructs a new GregorianCalendar representing midnight on the - * given date with the default time zone and locale. - * - * @param year corresponds to the YEAR time field. - * @param month corresponds to the MONTH time field. - * @param day corresponds to the DAY time field. - * @param hour corresponds to the HOUR_OF_DAY time field. - * @param minute corresponds to the MINUTE time field. - */ - public GregorianCalendar(int year, int month, int day, int hour, int minute) - { - this(TimeZone.getDefault(), Locale.getDefault(), false); - set(year, month, day, hour, minute); - } - - /** - * Constructs a new GregorianCalendar representing midnight on the - * given date with the default time zone and locale. - * - * @param year corresponds to the YEAR time field. - * @param month corresponds to the MONTH time field. - * @param day corresponds to the DAY time field. - * @param hour corresponds to the HOUR_OF_DAY time field. - * @param minute corresponds to the MINUTE time field. - * @param second corresponds to the SECOND time field. - */ - public GregorianCalendar(int year, int month, int day, int hour, int minute, - int second) - { - this(TimeZone.getDefault(), Locale.getDefault(), false); - set(year, month, day, hour, minute, second); - } - - /** - * Sets the date of the switch from Julian dates to Gregorian dates. - * You can use <code>new Date(Long.MAX_VALUE)</code> to use a pure - * Julian calendar, or <code>Long.MIN_VALUE</code> for a pure Gregorian - * calendar. - * - * @param date the date of the change. - */ - public void setGregorianChange(Date date) - { - gregorianCutover = date.getTime(); - } - - /** - * Gets the date of the switch from Julian dates to Gregorian dates. - * - * @return the date of the change. - */ - public final Date getGregorianChange() - { - return new Date(gregorianCutover); - } - - /** - * <p> - * Determines if the given year is a leap year. The result is - * undefined if the Gregorian change took place in 1800, so that - * the end of February is skipped, and that year is specified. - * (well...). - * </p> - * <p> - * To specify a year in the BC era, use a negative value calculated - * as 1 - y, where y is the required year in BC. So, 1 BC is 0, - * 2 BC is -1, 3 BC is -2, etc. - * </p> - * - * @param year a year (use a negative value for BC). - * @return true, if the given year is a leap year, false otherwise. - */ - public boolean isLeapYear(int year) - { - // Only years divisible by 4 can be leap years - if ((year & 3) != 0) - return false; - - // Is the leap-day a Julian date? Then it's a leap year - if (! isGregorian(year, 31 + 29 - 1)) - return true; - - // Apply gregorian rules otherwise - return ((year % 100) != 0 || (year % 400) == 0); - } - - /** - * Retrieves the day of the week corresponding to the specified - * day of the specified year. - * - * @param year the year in which the dayOfYear occurs. - * @param dayOfYear the day of the year (an integer between 0 and - * and 366) - */ - private int getWeekDay(int year, int dayOfYear) - { - boolean greg = isGregorian(year, dayOfYear); - int day = (int) getLinearDay(year, dayOfYear, greg); - - // The epoch was a thursday. - int weekday = (day + THURSDAY) % 7; - if (weekday <= 0) - weekday += 7; - return weekday; - } - - /** - * Returns the day of the week for the first day of a given month (0..11) - */ - private int getFirstDayOfMonth(int year, int month) - { - int[] dayCount = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; - - if (month > 11) - { - year += (month / 12); - month = month % 12; - } - - if (month < 0) - { - year += (int) month / 12; - month = month % 12; - if (month < 0) - { - month += 12; - year--; - } - } - - int dayOfYear = dayCount[month] + 1; - if (month > 1) - if (isLeapYear(year)) - dayOfYear++; - - boolean greg = isGregorian(year, dayOfYear); - int day = (int) getLinearDay(year, dayOfYear, greg); - - // The epoch was a thursday. - int weekday = (day + THURSDAY) % 7; - if (weekday <= 0) - weekday += 7; - return weekday; - } - - /** - * Takes a year, and a (zero based) day of year and determines - * if it is gregorian or not. - */ - private boolean isGregorian(int year, int dayOfYear) - { - int relativeDay = (year - 1) * 365 + ((year - 1) >> 2) + dayOfYear - - EPOCH_DAYS; // gregorian days from 1 to epoch. - int gregFactor = (int) Math.floor((double) (year - 1) / 400.) - - (int) Math.floor((double) (year - 1) / 100.); - - return ((relativeDay + gregFactor) * 60L * 60L * 24L * 1000L >= gregorianCutover); - } - - /** - * Check set fields for validity, without leniency. - * - * @throws IllegalArgumentException if a field is invalid - */ - private void nonLeniencyCheck() throws IllegalArgumentException - { - int[] month_days = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - int year = fields[YEAR]; - int month = fields[MONTH]; - int leap = isLeapYear(year) ? 1 : 0; - - if (isSet[ERA] && fields[ERA] != AD && fields[ERA] != BC) - throw new IllegalArgumentException("Illegal ERA."); - if (isSet[YEAR] && fields[YEAR] < 1) - throw new IllegalArgumentException("Illegal YEAR."); - if (isSet[MONTH] && (month < 0 || month > 11)) - throw new IllegalArgumentException("Illegal MONTH."); - if (isSet[WEEK_OF_YEAR]) - { - int daysInYear = 365 + leap; - daysInYear += (getFirstDayOfMonth(year, 0) - 1); // pad first week - int last = getFirstDayOfMonth(year, 11) + 4; - if (last > 7) - last -= 7; - daysInYear += 7 - last; - int weeks = daysInYear / 7; - if (fields[WEEK_OF_YEAR] < 1 || fields[WEEK_OF_YEAR] > weeks) - throw new IllegalArgumentException("Illegal WEEK_OF_YEAR."); - } - - if (isSet[WEEK_OF_MONTH]) - { - int weeks = (month == 1 && leap == 0) ? 5 : 6; - if (fields[WEEK_OF_MONTH] < 1 || fields[WEEK_OF_MONTH] > weeks) - throw new IllegalArgumentException("Illegal WEEK_OF_MONTH."); - } - - if (isSet[DAY_OF_MONTH]) - if (fields[DAY_OF_MONTH] < 1 - || fields[DAY_OF_MONTH] > month_days[month] - + ((month == 1) ? leap : 0)) - throw new IllegalArgumentException("Illegal DAY_OF_MONTH."); - - if (isSet[DAY_OF_YEAR] - && (fields[DAY_OF_YEAR] < 1 || fields[DAY_OF_YEAR] > 365 + leap)) - throw new IllegalArgumentException("Illegal DAY_OF_YEAR."); - - if (isSet[DAY_OF_WEEK] - && (fields[DAY_OF_WEEK] < 1 || fields[DAY_OF_WEEK] > 7)) - throw new IllegalArgumentException("Illegal DAY_OF_WEEK."); - - if (isSet[DAY_OF_WEEK_IN_MONTH]) - { - int weeks = (month == 1 && leap == 0) ? 4 : 5; - if (fields[DAY_OF_WEEK_IN_MONTH] < -weeks - || fields[DAY_OF_WEEK_IN_MONTH] > weeks) - throw new IllegalArgumentException("Illegal DAY_OF_WEEK_IN_MONTH."); - } - - if (isSet[AM_PM] && fields[AM_PM] != AM && fields[AM_PM] != PM) - throw new IllegalArgumentException("Illegal AM_PM."); - if (isSet[HOUR] && (fields[HOUR] < 0 || fields[HOUR] > 11)) - throw new IllegalArgumentException("Illegal HOUR."); - if (isSet[HOUR_OF_DAY] - && (fields[HOUR_OF_DAY] < 0 || fields[HOUR_OF_DAY] > 23)) - throw new IllegalArgumentException("Illegal HOUR_OF_DAY."); - if (isSet[MINUTE] && (fields[MINUTE] < 0 || fields[MINUTE] > 59)) - throw new IllegalArgumentException("Illegal MINUTE."); - if (isSet[SECOND] && (fields[SECOND] < 0 || fields[SECOND] > 59)) - throw new IllegalArgumentException("Illegal SECOND."); - if (isSet[MILLISECOND] - && (fields[MILLISECOND] < 0 || fields[MILLISECOND] > 999)) - throw new IllegalArgumentException("Illegal MILLISECOND."); - if (isSet[ZONE_OFFSET] - && (fields[ZONE_OFFSET] < -12 * 60 * 60 * 1000L - || fields[ZONE_OFFSET] > 12 * 60 * 60 * 1000L)) - throw new IllegalArgumentException("Illegal ZONE_OFFSET."); - if (isSet[DST_OFFSET] - && (fields[DST_OFFSET] < -12 * 60 * 60 * 1000L - || fields[DST_OFFSET] > 12 * 60 * 60 * 1000L)) - throw new IllegalArgumentException("Illegal DST_OFFSET."); - } - - /** - * Converts the time field values (<code>fields</code>) to - * milliseconds since the epoch UTC (<code>time</code>). - * - * @throws IllegalArgumentException if any calendar fields - * are invalid. - */ - protected synchronized void computeTime() - { - int millisInDay = 0; - int era = fields[ERA]; - int year = fields[YEAR]; - int month = fields[MONTH]; - int day = fields[DAY_OF_MONTH]; - - int minute = fields[MINUTE]; - int second = fields[SECOND]; - int millis = fields[MILLISECOND]; - int[] month_days = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - int[] dayCount = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; - int hour = 0; - - if (! isLenient()) - nonLeniencyCheck(); - - if (! isSet[MONTH] && (! isSet[DAY_OF_WEEK] || isSet[WEEK_OF_YEAR])) - { - // 5: YEAR + DAY_OF_WEEK + WEEK_OF_YEAR - if (isSet[WEEK_OF_YEAR]) - { - int first = getFirstDayOfMonth(year, 0); - int offs = 1; - int daysInFirstWeek = getFirstDayOfWeek() - first; - if (daysInFirstWeek <= 0) - daysInFirstWeek += 7; - - if (daysInFirstWeek < getMinimalDaysInFirstWeek()) - offs += daysInFirstWeek; - else - offs -= 7 - daysInFirstWeek; - month = 0; - day = offs + 7 * (fields[WEEK_OF_YEAR] - 1); - offs = fields[DAY_OF_WEEK] - getFirstDayOfWeek(); - - if (offs < 0) - offs += 7; - day += offs; - } - else - { - // 4: YEAR + DAY_OF_YEAR - month = 0; - day = fields[DAY_OF_YEAR]; - } - } - else - { - if (isSet[DAY_OF_WEEK]) - { - int first = getFirstDayOfMonth(year, month); - - // 3: YEAR + MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK - if (isSet[DAY_OF_WEEK_IN_MONTH]) - { - if (fields[DAY_OF_WEEK_IN_MONTH] < 0) - { - month++; - first = getFirstDayOfMonth(year, month); - day = 1 + 7 * (fields[DAY_OF_WEEK_IN_MONTH]); - } - else - day = 1 + 7 * (fields[DAY_OF_WEEK_IN_MONTH] - 1); - - int offs = fields[DAY_OF_WEEK] - first; - if (offs < 0) - offs += 7; - day += offs; - } - else - { // 2: YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK - int offs = 1; - int daysInFirstWeek = getFirstDayOfWeek() - first; - if (daysInFirstWeek <= 0) - daysInFirstWeek += 7; - - if (daysInFirstWeek < getMinimalDaysInFirstWeek()) - offs += daysInFirstWeek; - else - offs -= 7 - daysInFirstWeek; - - day = offs + 7 * (fields[WEEK_OF_MONTH] - 1); - offs = fields[DAY_OF_WEEK] - getFirstDayOfWeek(); - if (offs < 0) - offs += 7; - day += offs; - } - } - - // 1: YEAR + MONTH + DAY_OF_MONTH - } - if (era == BC && year > 0) - year = 1 - year; - - // rest of code assumes day/month/year set - // should negative BC years be AD? - // get the hour (but no check for validity) - if (isSet[HOUR]) - { - hour = fields[HOUR]; - if (fields[AM_PM] == PM) - hour += 12; - } - else - hour = fields[HOUR_OF_DAY]; - - // Read the era,year,month,day fields and convert as appropriate. - // Calculate number of milliseconds into the day - // This takes care of both h, m, s, ms over/underflows. - long allMillis = (((hour * 60L) + minute) * 60L + second) * 1000L + millis; - day += allMillis / (24 * 60 * 60 * 1000L); - millisInDay = (int) (allMillis % (24 * 60 * 60 * 1000L)); - - if (month < 0) - { - year += (int) month / 12; - month = month % 12; - if (month < 0) - { - month += 12; - year--; - } - } - if (month > 11) - { - year += (month / 12); - month = month % 12; - } - - month_days[1] = isLeapYear(year) ? 29 : 28; - - while (day <= 0) - { - if (month == 0) - { - year--; - month_days[1] = isLeapYear(year) ? 29 : 28; - } - month = (month + 11) % 12; - day += month_days[month]; - } - while (day > month_days[month]) - { - day -= (month_days[month]); - month = (month + 1) % 12; - if (month == 0) - { - year++; - month_days[1] = isLeapYear(year) ? 29 : 28; - } - } - - // ok, by here we have valid day,month,year,era and millisinday - int dayOfYear = dayCount[month] + day - 1; // (day starts on 1) - if (isLeapYear(year) && month > 1) - dayOfYear++; - - int relativeDay = (year - 1) * 365 + ((year - 1) >> 2) + dayOfYear - - EPOCH_DAYS; // gregorian days from 1 to epoch. - int gregFactor = (int) Math.floor((double) (year - 1) / 400.) - - (int) Math.floor((double) (year - 1) / 100.); - - if ((relativeDay + gregFactor) * 60L * 60L * 24L * 1000L >= gregorianCutover) - relativeDay += gregFactor; - else - relativeDay -= 2; - - time = relativeDay * (24 * 60 * 60 * 1000L) + millisInDay; - - // the epoch was a Thursday. - int weekday = (int) (relativeDay + THURSDAY) % 7; - if (weekday <= 0) - weekday += 7; - fields[DAY_OF_WEEK] = weekday; - - // Time zone corrections. - TimeZone zone = getTimeZone(); - int rawOffset = isSet[ZONE_OFFSET] ? fields[ZONE_OFFSET] - : zone.getRawOffset(); - - int dstOffset = isSet[DST_OFFSET] ? fields[DST_OFFSET] - : (zone.getOffset((year < 0) ? BC : AD, - (year < 0) ? 1 - year - : year, - month, day, weekday, - millisInDay) - - zone.getRawOffset()); - - time -= rawOffset + dstOffset; - - isTimeSet = true; - } - - /** - * Get the linear day in days since the epoch, using the - * Julian or Gregorian calendar as specified. If you specify a - * nonpositive year it is interpreted as BC as following: 0 is 1 - * BC, -1 is 2 BC and so on. - * - * @param year the year of the date. - * @param dayOfYear the day of year of the date; 1 based. - * @param gregorian <code>true</code>, if we should use the Gregorian rules. - * @return the days since the epoch, may be negative. - */ - private long getLinearDay(int year, int dayOfYear, boolean gregorian) - { - // The 13 is the number of days, that were omitted in the Gregorian - // Calender until the epoch. - // We shift right by 2 instead of dividing by 4, to get correct - // results for negative years (and this is even more efficient). - long julianDay = (year - 1) * 365L + ((year - 1) >> 2) + (dayOfYear - 1) - - EPOCH_DAYS; // gregorian days from 1 to epoch. - - if (gregorian) - { - // subtract the days that are missing in gregorian calendar - // with respect to julian calendar. - // - // Okay, here we rely on the fact that the gregorian - // calendar was introduced in the AD era. This doesn't work - // with negative years. - // - // The additional leap year factor accounts for the fact that - // a leap day is not seen on Jan 1 of the leap year. - int gregOffset = (int) Math.floor((double) (year - 1) / 400.) - - (int) Math.floor((double) (year - 1) / 100.); - - return julianDay + gregOffset; - } - else - julianDay -= 2; - return julianDay; - } - - /** - * Converts the given linear day into era, year, month, - * day_of_year, day_of_month, day_of_week, and writes the result - * into the fields array. - * - * @param day the linear day. - * @param gregorian true, if we should use Gregorian rules. - */ - private void calculateDay(int[] fields, long day, boolean gregorian) - { - // the epoch was a Thursday. - int weekday = (int) (day + THURSDAY) % 7; - if (weekday <= 0) - weekday += 7; - fields[DAY_OF_WEEK] = weekday; - - // get a first approximation of the year. This may be one - // year too big. - int year = 1970 - + (int) (gregorian - ? ((day - 100L) * 400L) / (365L * 400L + 100L - 4L - + 1L) : ((day - 100L) * 4L) / (365L * 4L + 1L)); - if (day >= 0) - year++; - - long firstDayOfYear = getLinearDay(year, 1, gregorian); - - // Now look in which year day really lies. - if (day < firstDayOfYear) - { - year--; - firstDayOfYear = getLinearDay(year, 1, gregorian); - } - - day -= firstDayOfYear - 1; // day of year, one based. - - fields[DAY_OF_YEAR] = (int) day; - if (year <= 0) - { - fields[ERA] = BC; - fields[YEAR] = 1 - year; - } - else - { - fields[ERA] = AD; - fields[YEAR] = year; - } - - int leapday = isLeapYear(year) ? 1 : 0; - if (day <= 31 + 28 + leapday) - { - fields[MONTH] = (int) day / 32; // 31->JANUARY, 32->FEBRUARY - fields[DAY_OF_MONTH] = (int) day - 31 * fields[MONTH]; - } - else - { - // A few more magic formulas - int scaledDay = ((int) day - leapday) * 5 + 8; - fields[MONTH] = scaledDay / (31 + 30 + 31 + 30 + 31); - fields[DAY_OF_MONTH] = (scaledDay % (31 + 30 + 31 + 30 + 31)) / 5 + 1; - } - } - - /** - * Converts the milliseconds since the epoch UTC - * (<code>time</code>) to time fields - * (<code>fields</code>). - */ - protected synchronized void computeFields() - { - boolean gregorian = (time >= gregorianCutover); - - TimeZone zone = getTimeZone(); - fields[ZONE_OFFSET] = zone.getRawOffset(); - long localTime = time + fields[ZONE_OFFSET]; - - long day = localTime / (24 * 60 * 60 * 1000L); - int millisInDay = (int) (localTime % (24 * 60 * 60 * 1000L)); - - if (millisInDay < 0) - { - millisInDay += (24 * 60 * 60 * 1000); - day--; - } - - calculateDay(fields, day, gregorian); - fields[DST_OFFSET] = zone.getOffset(fields[ERA], fields[YEAR], - fields[MONTH], fields[DAY_OF_MONTH], - fields[DAY_OF_WEEK], millisInDay) - - fields[ZONE_OFFSET]; - - millisInDay += fields[DST_OFFSET]; - if (millisInDay >= 24 * 60 * 60 * 1000) - { - millisInDay -= 24 * 60 * 60 * 1000; - calculateDay(fields, ++day, gregorian); - } - - fields[DAY_OF_WEEK_IN_MONTH] = (fields[DAY_OF_MONTH] + 6) / 7; - - // which day of the week are we (0..6), relative to getFirstDayOfWeek - int relativeWeekday = (7 + fields[DAY_OF_WEEK] - getFirstDayOfWeek()) % 7; - - // which day of the week is the first of this month? - // nb 35 is the smallest multiple of 7 that ensures that - // the left hand side of the modulo operator is positive. - int relativeWeekdayOfFirst = (relativeWeekday - fields[DAY_OF_MONTH] - + 1 + 35) % 7; - - // which week of the month is the first of this month in? - int minDays = getMinimalDaysInFirstWeek(); - int weekOfFirst = ((7 - relativeWeekdayOfFirst) >= minDays) ? 1 : 0; - - // which week of the month is this day in? - fields[WEEK_OF_MONTH] = (fields[DAY_OF_MONTH] - + relativeWeekdayOfFirst - 1) / 7 + weekOfFirst; - - int weekOfYear = (fields[DAY_OF_YEAR] - relativeWeekday + 6) / 7; - - // Do the Correction: getMinimalDaysInFirstWeek() is always in the - // first week. - int firstWeekday = (7 + getWeekDay(fields[YEAR], minDays) - - getFirstDayOfWeek()) % 7; - if (minDays - firstWeekday < 1) - weekOfYear++; - fields[WEEK_OF_YEAR] = weekOfYear; - - int hourOfDay = millisInDay / (60 * 60 * 1000); - fields[AM_PM] = (hourOfDay < 12) ? AM : PM; - int hour = hourOfDay % 12; - fields[HOUR] = hour; - fields[HOUR_OF_DAY] = hourOfDay; - millisInDay %= (60 * 60 * 1000); - fields[MINUTE] = millisInDay / (60 * 1000); - millisInDay %= (60 * 1000); - fields[SECOND] = millisInDay / (1000); - fields[MILLISECOND] = millisInDay % 1000; - - areFieldsSet = isSet[ERA] = isSet[YEAR] = isSet[MONTH] = isSet[WEEK_OF_YEAR] = isSet[WEEK_OF_MONTH] = isSet[DAY_OF_MONTH] = isSet[DAY_OF_YEAR] = isSet[DAY_OF_WEEK] = isSet[DAY_OF_WEEK_IN_MONTH] = isSet[AM_PM] = isSet[HOUR] = isSet[HOUR_OF_DAY] = isSet[MINUTE] = isSet[SECOND] = isSet[MILLISECOND] = isSet[ZONE_OFFSET] = isSet[DST_OFFSET] = true; - } - - /** - * Return a hash code for this object, following the general contract - * specified by {@link Object#hashCode()}. - * @return the hash code - */ - public int hashCode() - { - int val = (int) ((gregorianCutover >>> 32) ^ (gregorianCutover & 0xffffffff)); - return super.hashCode() ^ val; - } - - /** - * Compares the given calendar with this. An object, o, is - * equivalent to this if it is also a <code>GregorianCalendar</code> - * with the same time since the epoch under the same conditions - * (same change date and same time zone). - * - * @param o the object to that we should compare. - * @return true, if the given object is a calendar, that represents - * the same time (but doesn't necessarily have the same fields). - * @throws IllegalArgumentException if one of the fields - * <code>ZONE_OFFSET</code> or <code>DST_OFFSET</code> is - * specified, if an unknown field is specified or if one - * of the calendar fields receives an illegal value when - * leniancy is not enabled. - */ - public boolean equals(Object o) - { - if (! (o instanceof GregorianCalendar)) - return false; - - GregorianCalendar cal = (GregorianCalendar) o; - return (cal.gregorianCutover == gregorianCutover - && super.equals(o)); - } - - /** - * Adds the specified amount of time to the given time field. The - * amount may be negative to subtract the time. If the field overflows - * it does what you expect: Jan, 25 + 10 Days is Feb, 4. - * @param field one of the time field constants. - * @param amount the amount of time to add. - * @exception IllegalArgumentException if <code>field</code> is - * <code>ZONE_OFFSET</code>, <code>DST_OFFSET</code>, or invalid; or - * if <code>amount</code> contains an out-of-range value and the calendar - * is not in lenient mode. - */ - public void add(int field, int amount) - { - switch (field) - { - case YEAR: - complete(); - fields[YEAR] += amount; - isTimeSet = false; - break; - case MONTH: - complete(); - int months = fields[MONTH] + amount; - fields[YEAR] += months / 12; - fields[MONTH] = months % 12; - if (fields[MONTH] < 0) - { - fields[MONTH] += 12; - fields[YEAR]--; - } - int maxDay = getActualMaximum(DAY_OF_MONTH); - if (fields[DAY_OF_MONTH] > maxDay) - fields[DAY_OF_MONTH] = maxDay; - set(YEAR, fields[YEAR]); - set(MONTH, fields[MONTH]); - break; - case DAY_OF_MONTH: - case DAY_OF_YEAR: - case DAY_OF_WEEK: - if (! isTimeSet) - computeTime(); - time += amount * (24 * 60 * 60 * 1000L); - areFieldsSet = false; - break; - case WEEK_OF_YEAR: - case WEEK_OF_MONTH: - case DAY_OF_WEEK_IN_MONTH: - if (! isTimeSet) - computeTime(); - time += amount * (7 * 24 * 60 * 60 * 1000L); - areFieldsSet = false; - break; - case AM_PM: - if (! isTimeSet) - computeTime(); - time += amount * (12 * 60 * 60 * 1000L); - areFieldsSet = false; - break; - case HOUR: - case HOUR_OF_DAY: - if (! isTimeSet) - computeTime(); - time += amount * (60 * 60 * 1000L); - areFieldsSet = false; - break; - case MINUTE: - if (! isTimeSet) - computeTime(); - time += amount * (60 * 1000L); - areFieldsSet = false; - break; - case SECOND: - if (! isTimeSet) - computeTime(); - time += amount * (1000L); - areFieldsSet = false; - break; - case MILLISECOND: - if (! isTimeSet) - computeTime(); - time += amount; - areFieldsSet = false; - break; - case ZONE_OFFSET: - case DST_OFFSET:default: - throw new IllegalArgumentException("Invalid or unknown field"); - } - } - - /** - * Rolls the specified time field up or down. This means add one - * to the specified field, but don't change the other fields. If - * the maximum for this field is reached, start over with the - * minimum value. - * - * <strong>Note:</strong> There may be situation, where the other - * fields must be changed, e.g rolling the month on May, 31. - * The date June, 31 is automatically converted to July, 1. - * This requires lenient settings. - * - * @param field the time field. One of the time field constants. - * @param up the direction, true for up, false for down. - * @throws IllegalArgumentException if one of the fields - * <code>ZONE_OFFSET</code> or <code>DST_OFFSET</code> is - * specified, if an unknown field is specified or if one - * of the calendar fields receives an illegal value when - * leniancy is not enabled. - */ - public void roll(int field, boolean up) - { - roll(field, up ? 1 : -1); - } - - /** - * Checks that the fields are still within their legal bounds, - * following use of the <code>roll()</code> method. - * - * @param field the field to check. - * @param delta multipler for alterations to the <code>time</code>. - * @see #roll(int, boolean) - * @see #roll(int, int) - */ - private void cleanUpAfterRoll(int field, int delta) - { - switch (field) - { - case ERA: - case YEAR: - case MONTH: - // check that day of month is still in correct range - if (fields[DAY_OF_MONTH] > getActualMaximum(DAY_OF_MONTH)) - fields[DAY_OF_MONTH] = getActualMaximum(DAY_OF_MONTH); - isTimeSet = false; - isSet[WEEK_OF_MONTH] = false; - isSet[DAY_OF_WEEK] = false; - isSet[DAY_OF_WEEK_IN_MONTH] = false; - isSet[DAY_OF_YEAR] = false; - isSet[WEEK_OF_YEAR] = false; - break; - case DAY_OF_MONTH: - isSet[WEEK_OF_MONTH] = false; - isSet[DAY_OF_WEEK] = false; - isSet[DAY_OF_WEEK_IN_MONTH] = false; - isSet[DAY_OF_YEAR] = false; - isSet[WEEK_OF_YEAR] = false; - time += delta * (24 * 60 * 60 * 1000L); - break; - case WEEK_OF_MONTH: - isSet[DAY_OF_MONTH] = false; - isSet[DAY_OF_WEEK_IN_MONTH] = false; - isSet[DAY_OF_YEAR] = false; - isSet[WEEK_OF_YEAR] = false; - time += delta * (7 * 24 * 60 * 60 * 1000L); - break; - case DAY_OF_WEEK_IN_MONTH: - isSet[DAY_OF_MONTH] = false; - isSet[WEEK_OF_MONTH] = false; - isSet[DAY_OF_YEAR] = false; - isSet[WEEK_OF_YEAR] = false; - time += delta * (7 * 24 * 60 * 60 * 1000L); - break; - case DAY_OF_YEAR: - isSet[MONTH] = false; - isSet[DAY_OF_MONTH] = false; - isSet[WEEK_OF_MONTH] = false; - isSet[DAY_OF_WEEK_IN_MONTH] = false; - isSet[DAY_OF_WEEK] = false; - isSet[WEEK_OF_YEAR] = false; - time += delta * (24 * 60 * 60 * 1000L); - break; - case WEEK_OF_YEAR: - isSet[MONTH] = false; - isSet[DAY_OF_MONTH] = false; - isSet[WEEK_OF_MONTH] = false; - isSet[DAY_OF_WEEK_IN_MONTH] = false; - isSet[DAY_OF_YEAR] = false; - time += delta * (7 * 24 * 60 * 60 * 1000L); - break; - case AM_PM: - isSet[HOUR_OF_DAY] = false; - time += delta * (12 * 60 * 60 * 1000L); - break; - case HOUR: - isSet[HOUR_OF_DAY] = false; - time += delta * (60 * 60 * 1000L); - break; - case HOUR_OF_DAY: - isSet[HOUR] = false; - isSet[AM_PM] = false; - time += delta * (60 * 60 * 1000L); - break; - case MINUTE: - time += delta * (60 * 1000L); - break; - case SECOND: - time += delta * (1000L); - break; - case MILLISECOND: - time += delta; - break; - } - } - - /** - * Rolls the specified time field by the given amount. This means - * add amount to the specified field, but don't change the other - * fields. If the maximum for this field is reached, start over - * with the minimum value and vice versa for negative amounts. - * - * <strong>Note:</strong> There may be situation, where the other - * fields must be changed, e.g rolling the month on May, 31. - * The date June, 31 is automatically corrected to June, 30. - * - * @param field the time field. One of the time field constants. - * @param amount the amount by which we should roll. - * @throws IllegalArgumentException if one of the fields - * <code>ZONE_OFFSET</code> or <code>DST_OFFSET</code> is - * specified, if an unknown field is specified or if one - * of the calendar fields receives an illegal value when - * leniancy is not enabled. - */ - public void roll(int field, int amount) - { - switch (field) - { - case DAY_OF_WEEK: - // day of week is special: it rolls automatically - add(field, amount); - return; - case ZONE_OFFSET: - case DST_OFFSET: - throw new IllegalArgumentException("Can't roll time zone"); - } - complete(); - int min = getActualMinimum(field); - int range = getActualMaximum(field) - min + 1; - int oldval = fields[field]; - int newval = (oldval - min + range + amount) % range + min; - if (newval < min) - newval += range; - fields[field] = newval; - cleanUpAfterRoll(field, newval - oldval); - } - - /** - * The minimum values for the calendar fields. - */ - private static final int[] minimums = - { - BC, 1, 0, 0, 1, 1, 1, SUNDAY, 1, AM, - 1, 0, 0, 0, 0, -(12 * 60 * 60 * 1000), - 0 - }; - - /** - * The maximum values for the calendar fields. - */ - private static final int[] maximums = - { - AD, 5000000, 11, 53, 6, 31, 366, - SATURDAY, 5, PM, 12, 23, 59, 59, 999, - +(12 * 60 * 60 * 1000), - (12 * 60 * 60 * 1000) - }; - - /** - * Gets the smallest value that is allowed for the specified field. - * - * @param field one of the time field constants. - * @return the smallest value for the specified field. - */ - public int getMinimum(int field) - { - return minimums[field]; - } - - /** - * Gets the biggest value that is allowed for the specified field. - * - * @param field one of the time field constants. - * @return the biggest value. - */ - public int getMaximum(int field) - { - return maximums[field]; - } - - /** - * Gets the greatest minimum value that is allowed for the specified field. - * This is the largest value returned by the <code>getActualMinimum(int)</code> - * method. - * - * @param field the time field. One of the time field constants. - * @return the greatest minimum value. - * @see #getActualMinimum(int) - */ - public int getGreatestMinimum(int field) - { - if (field == WEEK_OF_YEAR) - return 1; - return minimums[field]; - } - - /** - * Gets the smallest maximum value that is allowed for the - * specified field. This is the smallest value returned - * by the <code>getActualMaximum(int)</code>. For example, - * this is 28 for DAY_OF_MONTH (as all months have at least - * 28 days). - * - * @param field the time field. One of the time field constants. - * @return the least maximum value. - * @see #getActualMaximum(int) - * @since 1.2 - */ - public int getLeastMaximum(int field) - { - switch (field) - { - case WEEK_OF_YEAR: - return 52; - case DAY_OF_MONTH: - return 28; - case DAY_OF_YEAR: - return 365; - case DAY_OF_WEEK_IN_MONTH: - case WEEK_OF_MONTH: - return 4; - default: - return maximums[field]; - } - } - - /** - * Gets the actual minimum value that is allowed for the specified field. - * This value is dependent on the values of the other fields. Note that - * this calls <code>complete()</code> if not enough fields are set. This - * can have ugly side effects. The value given depends on the current - * time used by this instance. - * - * @param field the time field. One of the time field constants. - * @return the actual minimum value. - * @since 1.2 - */ - public int getActualMinimum(int field) - { - if (field == WEEK_OF_YEAR) - { - int min = getMinimalDaysInFirstWeek(); - if (min == 0) - return 1; - if (! areFieldsSet || ! isSet[ERA] || ! isSet[YEAR]) - complete(); - - int year = fields[ERA] == AD ? fields[YEAR] : 1 - fields[YEAR]; - int weekday = getWeekDay(year, min); - if ((7 + weekday - getFirstDayOfWeek()) % 7 >= min - 1) - return 1; - return 0; - } - return minimums[field]; - } - - /** - * Gets the actual maximum value that is allowed for the specified field. - * This value is dependent on the values of the other fields. Note that - * this calls <code>complete()</code> if not enough fields are set. This - * can have ugly side effects. The value given depends on the current time - * used by this instance; thus, leap years have a maximum day of month value of - * 29, rather than 28. - * - * @param field the time field. One of the time field constants. - * @return the actual maximum value. - */ - public int getActualMaximum(int field) - { - switch (field) - { - case WEEK_OF_YEAR: - { - if (! areFieldsSet || ! isSet[ERA] || ! isSet[YEAR]) - complete(); - - // This is wrong for the year that contains the gregorian change. - // I.e it gives the weeks in the julian year or in the gregorian - // year in that case. - int year = fields[ERA] == AD ? fields[YEAR] : 1 - fields[YEAR]; - int lastDay = isLeapYear(year) ? 366 : 365; - int weekday = getWeekDay(year, lastDay); - int week = (lastDay + 6 - (7 + weekday - getFirstDayOfWeek()) % 7) / 7; - - int minimalDays = getMinimalDaysInFirstWeek(); - int firstWeekday = getWeekDay(year, minimalDays); - /* - * Is there a set of days at the beginning of the year, before the - * first day of the week, equal to or greater than the minimum number - * of days required in the first week? - */ - if (minimalDays - (7 + firstWeekday - getFirstDayOfWeek()) % 7 < 1) - return week + 1; /* Add week 1: firstWeekday through to firstDayOfWeek */ - } - case DAY_OF_MONTH: - { - if (! areFieldsSet || ! isSet[MONTH]) - complete(); - int month = fields[MONTH]; - - // If you change this, you should also change - // SimpleTimeZone.getDaysInMonth(); - if (month == FEBRUARY) - { - if (! isSet[YEAR] || ! isSet[ERA]) - complete(); - int year = fields[ERA] == AD ? fields[YEAR] : 1 - fields[YEAR]; - return isLeapYear(year) ? 29 : 28; - } - else if (month < AUGUST) - return 31 - (month & 1); - else - return 30 + (month & 1); - } - case DAY_OF_YEAR: - { - if (! areFieldsSet || ! isSet[ERA] || ! isSet[YEAR]) - complete(); - int year = fields[ERA] == AD ? fields[YEAR] : 1 - fields[YEAR]; - return isLeapYear(year) ? 366 : 365; - } - case DAY_OF_WEEK_IN_MONTH: - { - // This is wrong for the month that contains the gregorian change. - int daysInMonth = getActualMaximum(DAY_OF_MONTH); - - // That's black magic, I know - return (daysInMonth - (fields[DAY_OF_MONTH] - 1) % 7 + 6) / 7; - } - case WEEK_OF_MONTH: - { - int daysInMonth = getActualMaximum(DAY_OF_MONTH); - int weekday = (daysInMonth - fields[DAY_OF_MONTH] - + fields[DAY_OF_WEEK] - SUNDAY) % 7 + SUNDAY; - return (daysInMonth + 6 - (7 + weekday - getFirstDayOfWeek()) % 7) / 7; - } - default: - return maximums[field]; - } - } -} diff --git a/libjava/classpath/java/util/HashMap.java b/libjava/classpath/java/util/HashMap.java deleted file mode 100644 index f5194a2..0000000 --- a/libjava/classpath/java/util/HashMap.java +++ /dev/null @@ -1,909 +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<K, V> extends AbstractMap<K, V> - implements Map<K, V>, Cloneable, Serializable -{ - /** - * Default number of buckets; this is currently set to 16. - * Package visible for use by HashSet. - */ - static final int DEFAULT_CAPACITY = 16; - - /** - * 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<K, V>[] 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<Map.Entry<K, V>> 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<K, V> extends AbstractMap.SimpleEntry<K, V> - { - /** - * The next entry in the linked list. Package visible for use by subclass. - */ - HashEntry<K, V> next; - - /** - * Simple constructor. - * @param key the key - * @param value the value - */ - HashEntry(K key, V 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 - */ - V 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<? extends K, ? extends V> 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 = (HashEntry<K, V>[]) 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 V get(Object key) - { - int idx = hash(key); - HashEntry<K, V> 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<K, V> 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 V put(K key, V value) - { - int idx = hash(key); - HashEntry<K, V> e = buckets[idx]; - - int hash1 = key == null ? 0 : key.hashCode(); - while (e != null) - { - int hash2 = e.key == null ? 0 : e.key.hashCode(); - - if ((hash1 == hash2) && equals(key, e.key)) - { - e.access(); // Must call this for bookkeeping in LinkedHashMap. - V 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<? extends K, ? extends V> m) - { - final Map<K,V> addMap = (Map<K,V>) m; - final Iterator<Map.Entry<K,V>> it = addMap.entrySet().iterator(); - while (it.hasNext()) - { - final Map.Entry<K,V> e = it.next(); - // Optimize in case the Entry is one of our own. - if (e instanceof AbstractMap.SimpleEntry) - { - AbstractMap.SimpleEntry<? extends K, ? extends V> entry - = (AbstractMap.SimpleEntry<? extends K, ? extends V>) 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 V remove(Object key) - { - int idx = hash(key); - HashEntry<K, V> e = buckets[idx]; - HashEntry<K, V> 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<K, V> 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<K, V> copy = null; - try - { - copy = (HashMap<K, V>) super.clone(); - } - catch (CloneNotSupportedException x) - { - // This is impossible. - } - copy.buckets = (HashEntry<K, V>[]) 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<K> keySet() - { - if (keys == null) - // Create an AbstractSet with custom implementations of those methods - // that can be overridden easily and efficiently. - keys = new AbstractSet<K>() - { - public int size() - { - return size; - } - - public Iterator<K> 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<V> 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<V>() - { - public int size() - { - return size; - } - - public Iterator<V> 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<Map.Entry<K, V>> entrySet() - { - if (entries == null) - // Create an AbstractSet with custom implementations of those methods - // that can be overridden easily and efficiently. - entries = new AbstractSet<Map.Entry<K, V>>() - { - public int size() - { - return size; - } - - public Iterator<Map.Entry<K, V>> 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<K, V> 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(K key, V value, int idx, boolean callRemove) - { - HashEntry<K, V> e = new HashEntry<K, V>(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<K, V> getEntry(Object o) - { - if (! (o instanceof Map.Entry)) - return null; - Map.Entry<K, V> me = (Map.Entry<K, V>) o; - K key = me.getKey(); - int idx = hash(key); - HashEntry<K, V> 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 - */ - <T> Iterator<T> iterator(int type) - { - // FIXME: bogus cast here. - return new HashIterator<T>(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<? extends K, ? extends V> m) - { - final Map<K,V> addMap = (Map<K,V>) m; - final Iterator<Map.Entry<K,V>> it = addMap.entrySet().iterator(); - size = 0; - while (it.hasNext()) - { - final Map.Entry<K,V> e = it.next(); - size++; - K 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<K, V>[] oldBuckets = buckets; - - int newcapacity = (buckets.length * 2) + 1; - threshold = (int) (newcapacity * loadFactor); - buckets = (HashEntry<K, V>[]) new HashEntry[newcapacity]; - - for (int i = oldBuckets.length - 1; i >= 0; i--) - { - HashEntry<K, V> e = oldBuckets[i]; - while (e != null) - { - int idx = hash(e.key); - HashEntry<K, V> dest = buckets[idx]; - HashEntry<K, V> 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<HashEntry<K, V>> it = iterator(ENTRIES); - while (it.hasNext()) - { - HashEntry<K, V> entry = 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 = (HashEntry<K, V>[]) new HashEntry[s.readInt()]; - int len = s.readInt(); - size = len; - while (len-- > 0) - { - Object key = s.readObject(); - addEntry((K) key, (V) 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<T> implements Iterator<T> - { - /** - * 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 - */ - public boolean hasNext() - { - 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 T 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 (T) e.value; - if (type == KEYS) - return (T) e.key; - return (T) 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/classpath/java/util/HashSet.java b/libjava/classpath/java/util/HashSet.java deleted file mode 100644 index c08b6db..0000000 --- a/libjava/classpath/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<T> extends AbstractSet<T> - implements Set<T>, Cloneable, Serializable -{ - /** - * Compatible with JDK 1.2. - */ - private static final long serialVersionUID = -5024744406713321676L; - - /** - * The HashMap which backs this Set. - */ - private transient HashMap<T, String> 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<? extends T> 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(T 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<T> copy = null; - try - { - copy = (HashSet<T>) super.clone(); - } - catch (CloneNotSupportedException x) - { - // Impossible to get here. - } - copy.map = (HashMap<T, String>) 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<T> 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<T> 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((T) s.readObject(), ""); - } -} diff --git a/libjava/classpath/java/util/Hashtable.java b/libjava/classpath/java/util/Hashtable.java deleted file mode 100644 index 8f08e96..0000000 --- a/libjava/classpath/java/util/Hashtable.java +++ /dev/null @@ -1,1397 +0,0 @@ -/* Hashtable.java -- a class providing a basic hashtable data structure, - mapping Object --> Object - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006 - 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 gnu.java.lang.CPStringBuilder; - -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<K, V> extends Dictionary<K, V> - implements Map<K, V>, 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; - - /** - * 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<K, V>[] 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<K> keys; - - /** - * The cache for {@link #values()}. - */ - private transient Collection<V> values; - - /** - * The cache for {@link #entrySet()}. - */ - private transient Set<Map.Entry<K, V>> 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<K, V> - extends AbstractMap.SimpleEntry<K, V> - { - /** The next entry in the linked list. */ - HashEntry<K, V> next; - - /** - * Simple constructor. - * @param key the key, already guaranteed non-null - * @param value the value, already guaranteed non-null - */ - HashEntry(K key, V value) - { - super(key, value); - } - - /** - * Resets the value. - * @param newVal the new value - * @return the prior value - * @throws NullPointerException if <code>newVal</code> is null - */ - public V setValue(V 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<? extends K, ? extends V> 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 = (HashEntry<K, V>[]) 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<K> keys() - { - return new KeyEnumerator(); - } - - /** - * 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<V> elements() - { - return new ValueEnumerator(); - } - - /** - * 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) - { - if (value == null) - throw new NullPointerException(); - - for (int i = buckets.length - 1; i >= 0; i--) - { - HashEntry<K, V> e = buckets[i]; - while (e != null) - { - if (e.value.equals(value)) - return true; - e = e.next; - } - } - - 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<K, V> e = buckets[idx]; - while (e != null) - { - if (e.key.equals(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 V get(Object key) - { - int idx = hash(key); - HashEntry<K, V> e = buckets[idx]; - while (e != null) - { - if (e.key.equals(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 V put(K key, V value) - { - int idx = hash(key); - HashEntry<K, V> e = buckets[idx]; - - // Check if value is null since it is not permitted. - if (value == null) - throw new NullPointerException(); - - while (e != null) - { - if (e.key.equals(key)) - { - // Bypass e.setValue, since we already know value is non-null. - V 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<K, V>(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 V remove(Object key) - { - int idx = hash(key); - HashEntry<K, V> e = buckets[idx]; - HashEntry<K, V> last = null; - - while (e != null) - { - if (e.key.equals(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<? extends K, ? extends V> m) - { - final Map<K,V> addMap = (Map<K,V>) m; - final Iterator<Map.Entry<K,V>> it = addMap.entrySet().iterator(); - while (it.hasNext()) - { - final Map.Entry<K,V> e = it.next(); - // Optimize in case the Entry is one of our own. - if (e instanceof AbstractMap.SimpleEntry) - { - AbstractMap.SimpleEntry<? extends K, ? extends V> entry - = (AbstractMap.SimpleEntry<? extends K, ? extends V>) 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<K, V> copy = null; - try - { - copy = (Hashtable<K, V>) super.clone(); - } - catch (CloneNotSupportedException x) - { - // This is impossible. - } - copy.buckets = (HashEntry<K, V>[]) 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 EntryIterator instead. - Iterator<Map.Entry<K, V>> entries = new EntryIterator(); - CPStringBuilder r = new CPStringBuilder("{"); - 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<K> keySet() - { - if (keys == null) - { - // Create a synchronized AbstractSet with custom implementations of - // those methods that can be overridden easily and efficiently. - Set<K> r = new AbstractSet<K>() - { - public int size() - { - return size; - } - - public Iterator<K> iterator() - { - return new KeyIterator(); - } - - 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<K>(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<V> 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<V> r = new AbstractCollection<V>() - { - public int size() - { - return size; - } - - public Iterator<V> iterator() - { - return new ValueIterator(); - } - - 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<V>(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<Map.Entry<K, V>> entrySet() - { - if (entries == null) - { - // Create an AbstractSet with custom implementations of those methods - // that can be overridden easily and efficiently. - Set<Map.Entry<K, V>> r = new AbstractSet<Map.Entry<K, V>>() - { - public int size() - { - return size; - } - - public Iterator<Map.Entry<K, V>> iterator() - { - return new EntryIterator(); - } - - public void clear() - { - Hashtable.this.clear(); - } - - public boolean contains(Object o) - { - return getEntry(o) != null; - } - - public boolean remove(Object o) - { - HashEntry<K, V> 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<Map.Entry<K, V>>(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 EntryIterator instead. - Iterator<Map.Entry<K, V>> itr = new EntryIterator(); - 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<K, V> getEntry(Object o) - { - if (! (o instanceof Map.Entry)) - return null; - K key = ((Map.Entry<K, V>) o).getKey(); - if (key == null) - return null; - - int idx = hash(key); - HashEntry<K, V> e = buckets[idx]; - while (e != null) - { - if (e.equals(o)) - 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<? extends K, ? extends V> m) - { - final Map<K,V> addMap = (Map<K,V>) m; - final Iterator<Map.Entry<K,V>> it = addMap.entrySet().iterator(); - size = 0; - while (it.hasNext()) - { - final Map.Entry<K,V> e = it.next(); - size++; - K key = e.getKey(); - int idx = hash(key); - HashEntry<K, V> he = new HashEntry<K, V>(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<K, V>[] oldBuckets = buckets; - - int newcapacity = (buckets.length * 2) + 1; - threshold = (int) (newcapacity * loadFactor); - buckets = (HashEntry<K, V>[]) new HashEntry[newcapacity]; - - for (int i = oldBuckets.length - 1; i >= 0; i--) - { - HashEntry<K, V> e = oldBuckets[i]; - while (e != null) - { - int idx = hash(e.key); - HashEntry<K, V> dest = buckets[idx]; - - if (dest != null) - { - HashEntry next = dest.next; - while (next != null) - { - dest = next; - next = dest.next; - } - dest.next = e; - } - else - { - buckets[idx] = e; - } - - HashEntry<K, V> 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 EntryIterator instead. - Iterator<Map.Entry<K, V>> it = new EntryIterator(); - while (it.hasNext()) - { - HashEntry<K, V> entry = (HashEntry<K, V>) 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 = (HashEntry<K, V>[]) 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((K) s.readObject(), (V) s.readObject()); - } - - /** - * A class which implements the Iterator interface and is used for - * iterating over Hashtables. - * This implementation iterates entries. Subclasses are used to - * iterate key and values. 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 - * @author Fridjof Siebert - */ - private class EntryIterator - implements Iterator<Entry<K,V>> - { - /** - * 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<K, V> 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<K, V> next; - - /** - * Construct a new EntryIterator - */ - EntryIterator() - { - } - - - /** - * Returns true if the Iterator has more elements. - * @return true if there are more elements - */ - public boolean hasNext() - { - 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 Map.Entry<K,V> next() - { - if (knownMod != modCount) - throw new ConcurrentModificationException(); - if (count == 0) - throw new NoSuchElementException(); - count--; - HashEntry<K, V> e = next; - - while (e == null) - if (idx <= 0) - return null; - else - e = buckets[--idx]; - - next = e.next; - last = e; - 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 EntryIterator - - /** - * A class which implements the Iterator interface and is used for - * iterating over keys in Hashtables. This class uses an - * <code>EntryIterator</code> to obtain the keys of each entry. - * - * @author Fridtjof Siebert - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - */ - private class KeyIterator - implements Iterator<K> - { - - /** - * This entry iterator is used for most operations. Only - * <code>next()</code> gives a different result, by returning just - * the key rather than the whole element. - */ - private final EntryIterator iterator; - - /** - * Construct a new KeyIterator - */ - KeyIterator() - { - iterator = new EntryIterator(); - } - - - /** - * Returns true if the entry iterator has more elements. - * - * @return true if there are more elements - * @throws ConcurrentModificationException if the hashtable was modified - */ - public boolean hasNext() - { - return iterator.hasNext(); - } - - /** - * 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 K next() - { - return ((HashEntry<K,V>) iterator.next()).key; - } - - /** - * Removes the last element used by the <code>next()</code> method - * using the entry iterator. - * - * @throws ConcurrentModificationException if the hashtable was modified - * @throws IllegalStateException if called when there is no last element - */ - public void remove() - { - iterator.remove(); - } - } // class KeyIterator - - /** - * A class which implements the Iterator interface and is used for - * iterating over values in Hashtables. This class uses an - * <code>EntryIterator</code> to obtain the values of each entry. - * - * @author Fridtjof Siebert - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - */ - private class ValueIterator - implements Iterator<V> - { - - /** - * This entry iterator is used for most operations. Only - * <code>next()</code> gives a different result, by returning just - * the value rather than the whole element. - */ - private final EntryIterator iterator; - - /** - * Construct a new KeyIterator - */ - ValueIterator() - { - iterator = new EntryIterator(); - } - - - /** - * Returns true if the entry iterator has more elements. - * - * @return true if there are more elements - * @throws ConcurrentModificationException if the hashtable was modified - */ - public boolean hasNext() - { - return iterator.hasNext(); - } - - /** - * Returns the value of the next element in the iterator's sequential view. - * - * @return the next value - * - * @throws ConcurrentModificationException if the hashtable was modified - * @throws NoSuchElementException if there is none - */ - public V next() - { - return ((HashEntry<K,V>) iterator.next()).value; - } - - /** - * Removes the last element used by the <code>next()</code> method - * using the entry iterator. - * - * @throws ConcurrentModificationException if the hashtable was modified - * @throws IllegalStateException if called when there is no last element - */ - public void remove() - { - iterator.remove(); - } - - } // class ValueIterator - - /** - * Enumeration view of the entries in this Hashtable, providing - * sequential access to its elements. - * - * <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 implies that modifications to the - * hashtable during enumeration causes indeterminate results. Don't do it! - * - * @author Jon Zeppieri - * @author Fridjof Siebert - */ - private class EntryEnumerator - implements Enumeration<Entry<K,V>> - { - /** 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<K, V> next; - - /** - * Construct the enumeration. - */ - EntryEnumerator() - { - // Nothing to do here. - } - - /** - * 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 Map.Entry<K,V> nextElement() - { - if (count == 0) - throw new NoSuchElementException("Hashtable Enumerator"); - count--; - HashEntry<K, V> e = next; - - while (e == null) - if (idx <= 0) - return null; - else - e = buckets[--idx]; - - next = e.next; - return e; - } - } // class EntryEnumerator - - - /** - * Enumeration view of this Hashtable, providing sequential access to its - * elements. - * - * <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 implies that modifications to the - * hashtable during enumeration causes indeterminate results. Don't do it! - * - * @author Jon Zeppieri - * @author Fridjof Siebert - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - */ - private final class KeyEnumerator - implements Enumeration<K> - { - /** - * This entry enumerator is used for most operations. Only - * <code>nextElement()</code> gives a different result, by returning just - * the key rather than the whole element. - */ - private final EntryEnumerator enumerator; - - /** - * Construct a new KeyEnumerator - */ - KeyEnumerator() - { - enumerator = new EntryEnumerator(); - } - - - /** - * Returns true if the entry enumerator has more elements. - * - * @return true if there are more elements - * @throws ConcurrentModificationException if the hashtable was modified - */ - public boolean hasMoreElements() - { - return enumerator.hasMoreElements(); - } - - /** - * Returns the next element. - * @return the next element - * @throws NoSuchElementException if there is none. - */ - public K nextElement() - { - HashEntry<K,V> entry = (HashEntry<K,V>) enumerator.nextElement(); - K retVal = null; - if (entry != null) - retVal = entry.key; - return retVal; - } - } // class KeyEnumerator - - - /** - * Enumeration view of this Hashtable, providing sequential access to its - * values. - * - * <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 implies that modifications to the - * hashtable during enumeration causes indeterminate results. Don't do it! - * - * @author Jon Zeppieri - * @author Fridjof Siebert - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - */ - private final class ValueEnumerator - implements Enumeration<V> - { - /** - * This entry enumerator is used for most operations. Only - * <code>nextElement()</code> gives a different result, by returning just - * the value rather than the whole element. - */ - private final EntryEnumerator enumerator; - - /** - * Construct a new ValueEnumerator - */ - ValueEnumerator() - { - enumerator = new EntryEnumerator(); - } - - - /** - * Returns true if the entry enumerator has more elements. - * - * @return true if there are more elements - * @throws ConcurrentModificationException if the hashtable was modified - */ - public boolean hasMoreElements() - { - return enumerator.hasMoreElements(); - } - - /** - * Returns the next element. - * @return the next element - * @throws NoSuchElementException if there is none. - */ - public V nextElement() - { - HashEntry<K,V> entry = (HashEntry<K,V>) enumerator.nextElement(); - V retVal = null; - if (entry != null) - retVal = entry.value; - return retVal; - } - } // class ValueEnumerator - -} // class Hashtable diff --git a/libjava/classpath/java/util/IdentityHashMap.java b/libjava/classpath/java/util/IdentityHashMap.java deleted file mode 100644 index 89a7525..0000000 --- a/libjava/classpath/java/util/IdentityHashMap.java +++ /dev/null @@ -1,990 +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<K,V> extends AbstractMap<K,V> - implements Map<K,V>, Serializable, Cloneable -{ - /** The default capacity. */ - private static final int DEFAULT_CAPACITY = 21; - - /** - * This object is used to mark a slot whose key or value is 'null'. - * This is more efficient than using a special value to mark an empty - * slot, because null entries are rare, empty slots are common, and - * the JVM will clear new arrays for us. - * Package visible for use by nested classes. - */ - static final Object nullslot = 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<Map.Entry<K,V>> 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]; - 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<? extends K, ? extends V> 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, null); - 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) - { - key = xform(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) - { - value = xform(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<Map.Entry<K,V>> entrySet() - { - if (entries == null) - entries = new AbstractSet<Map.Entry<K,V>>() - { - public int size() - { - return size; - } - - public Iterator<Map.Entry<K,V>> iterator() - { - return new IdentityIterator<Map.Entry<K,V>>(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; - Object value = xform(m.getValue()); - Object key = xform(m.getKey()); - return value == table[hash(key) + 1]; - } - - public int hashCode() - { - return IdentityHashMap.this.hashCode(); - } - - public boolean remove(Object o) - { - if (! (o instanceof Map.Entry)) - return false; - Object key = xform(((Map.Entry) o).getKey()); - int h = hash(key); - if (table[h] == key) - { - size--; - modCount++; - IdentityHashMap.this.removeAtIndex(h); - 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 V get(Object key) - { - key = xform(key); - int h = hash(key); - return (V) (table[h] == key ? unxform(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 == null) - continue; - // FIXME: this is a lame computation. - hash += (System.identityHashCode(unxform(key)) - ^ System.identityHashCode(unxform(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<K> keySet() - { - if (keys == null) - keys = new AbstractSet<K>() - { - public int size() - { - return size; - } - - public Iterator<K> iterator() - { - return new IdentityIterator<K>(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 == null) - continue; - hash += System.identityHashCode(unxform(key)); - } - return hash; - } - - public boolean remove(Object o) - { - o = xform(o); - int h = hash(o); - if (table[h] == o) - { - size--; - modCount++; - removeAtIndex(h); - 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 V put(K key, V value) - { - key = (K) xform(key); - value = (V) xform(value); - - // We don't want to rehash if we're overwriting an existing slot. - int h = hash(key); - if (table[h] == key) - { - V r = (V) unxform(table[h + 1]); - table[h + 1] = value; - return r; - } - - // 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]; - size = 0; - threshold = (table.length >>> 3) * 3; - - for (int i = old.length - 2; i >= 0; i -= 2) - { - K oldkey = (K) old[i]; - if (oldkey != null) - { - h = hash(oldkey); - table[h] = oldkey; - table[h + 1] = old[i + 1]; - ++size; - // No need to update modCount here, we'll do it - // just after the loop. - } - } - - // Now that we've resize, recompute the hash value. - h = hash(key); - } - - // 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<? extends K, ? extends V> m) - { - // Why did Sun specify this one? The superclass does the right thing. - super.putAll(m); - } - - /** - * Remove the element at index and update the table to compensate. - * This is package-private for use by inner classes. - * @param i index of the removed element - */ - final void removeAtIndex(int i) - { - // This is Algorithm R from Knuth, section 6.4. - // Variable names are taken directly from the text. - while (true) - { - table[i] = null; - table[i + 1] = null; - int j = i; - int r; - do - { - i -= 2; - if (i < 0) - i = table.length - 2; - Object key = table[i]; - if (key == null) - return; - r = Math.abs(System.identityHashCode(key) - % (table.length >> 1)) << 1; - } - while ((i <= r && r < j) - || (r < j && j < i) - || (j < i && i <= r)); - table[j] = table[i]; - table[j + 1] = table[i + 1]; - } - } - - /** - * 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 V remove(Object key) - { - key = xform(key); - int h = hash(key); - if (table[h] == key) - { - modCount++; - size--; - Object r = unxform(table[h + 1]); - removeAtIndex(h); - return (V) 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<V> values() - { - if (values == null) - values = new AbstractCollection<V>() - { - public int size() - { - return size; - } - - public Iterator<V> iterator() - { - return new IdentityIterator<V>(VALUES); - } - - public void clear() - { - IdentityHashMap.this.clear(); - } - - public boolean remove(Object o) - { - o = xform(o); - // This approach may look strange, but it is ok. - for (int i = table.length - 1; i > 0; i -= 2) - if (table[i] == o) - { - modCount++; - size--; - IdentityHashMap.this.removeAtIndex(i - 1); - return true; - } - return false; - } - }; - return values; - } - - /** - * Transform a reference from its external form to its internal form. - * This is package-private for use by inner classes. - */ - final Object xform(Object o) - { - if (o == null) - o = nullslot; - return o; - } - - /** - * Transform a reference from its internal form to its external form. - * This is package-private for use by inner classes. - */ - final Object unxform(Object o) - { - if (o == nullslot) - o = null; - return o; - } - - /** - * Helper method which computes the hash code, then traverses the table - * until it finds the key, or the spot where the key would go. the key - * must already be in its internal form. - * - * @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. - final int hash(Object key) - { - int h = Math.abs(System.identityHashCode(key) % (table.length >> 1)) << 1; - - while (true) - { - // By requiring at least 2 key/value slots, and rehashing at 75% - // capacity, we guarantee that there will always be either an empty - // slot somewhere in the table. - if (table[h] == key || table[h] == null) - return h; - // We use linear probing as it is friendlier to the cache and - // it lets us efficiently remove entries. - h -= 2; - if (h < 0) - h = table.length - 2; - } - } - - /** - * 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<I> implements Iterator<I> - { - /** - * 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 - */ - public boolean hasNext() - { - 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 I next() - { - if (knownMod != modCount) - throw new ConcurrentModificationException(); - if (count == 0) - throw new NoSuchElementException(); - count--; - - Object key; - do - { - loc -= 2; - key = table[loc]; - } - while (key == null); - - return (I) (type == KEYS ? unxform(key) - : (type == VALUES ? unxform(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) - throw new IllegalStateException(); - modCount++; - size--; - removeAtIndex(loc); - 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<EK,EV> implements Map.Entry<EK,EV> - { - /** 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) - throw new ConcurrentModificationException(); - if (! (o instanceof Map.Entry)) - return false; - Map.Entry e = (Map.Entry) o; - return table[loc] == xform(e.getKey()) - && table[loc + 1] == xform(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 EK getKey() - { - if (knownMod != modCount) - throw new ConcurrentModificationException(); - return (EK) unxform(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 EV getValue() - { - if (knownMod != modCount) - throw new ConcurrentModificationException(); - return (EV) unxform(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) - throw new ConcurrentModificationException(); - return (System.identityHashCode(unxform(table[loc])) - ^ System.identityHashCode(unxform(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 EV setValue(EV value) - { - if (knownMod != modCount) - throw new ConcurrentModificationException(); - EV r = (EV) unxform(table[loc + 1]); - table[loc + 1] = xform(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) - throw new ConcurrentModificationException(); - return unxform(table[loc]) + "=" + unxform(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((K) s.readObject(), (V) 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 != null) - { - s.writeObject(unxform(key)); - s.writeObject(unxform(table[i + 1])); - } - } - } -} diff --git a/libjava/classpath/java/util/IllegalFormatCodePointException.java b/libjava/classpath/java/util/IllegalFormatCodePointException.java deleted file mode 100644 index f6d5c2f..0000000 --- a/libjava/classpath/java/util/IllegalFormatCodePointException.java +++ /dev/null @@ -1,85 +0,0 @@ -/* IllegalFormatCodePointException.java - Copyright (C) 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; - -/** - * Thrown when a {@link Formatter} receives a character with an - * invalid Unicode codepoint, as defined by - * {@link Character#isValidCodePoint(int)}. - * - * @author Tom Tromey (tromey@redhat.com) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.5 - */ -public class IllegalFormatCodePointException - extends IllegalFormatException -{ - private static final long serialVersionUID = 19080630L; - - /** - * The character which is an invalid Unicode code point. - * - * @serial the invalid character. - */ - // Note: name fixed by serialization. - int c; - - /** - * Constructs a new <code>IllegalFormatCodePointException</code> - * which specifies that the character, <code>c</code>, passed to - * a {@link Formatter} is an invalid Unicode code point. - * - * @param c the invalid character. - */ - public IllegalFormatCodePointException(int c) - { - super("An invalid Unicode code point was supplied."); - this.c = c; - } - - /** - * Returns the invalid character. - * - * @return the invalid character. - */ - public int getCodePoint() - { - return c; - } -} diff --git a/libjava/classpath/java/util/IllegalFormatConversionException.java b/libjava/classpath/java/util/IllegalFormatConversionException.java deleted file mode 100644 index 58aa918..0000000 --- a/libjava/classpath/java/util/IllegalFormatConversionException.java +++ /dev/null @@ -1,110 +0,0 @@ -/* IllegalFormatConversionException.java - Copyright (C) 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; - -/** - * Thrown when the type of an argument supplied to the - * {@link Formatter#format()} method of a {@link Formatter} - * does not match the conversion character specified for it. - * - * @author Tom Tromey (tromey@redhat.com) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.5 - */ -public class IllegalFormatConversionException - extends IllegalFormatException -{ - private static final long serialVersionUID = 17000126L; - - /** - * The conversion character which doesn't match - * the type of the argument. - * - * @serial the conversion character. - */ - // Note: name fixed by serialization. - char c; - - /** - * The type of the mismatching argument. - * - * @serial the mismatching argument type. - */ - // Note: name fixed by serialization. - Class<?> arg; - - /** - * Constructs a new <code>IllegalFormatConversionException</code> - * which specifies that the argument of type <code>arg</code> does - * not match the conversion character, <code>c</code>. - * - * @param c the conversion character. - * @param arg the type which doesn't match the conversion character. - * @throws NullPointerException if <code>arg</code> is null. - */ - public IllegalFormatConversionException(char c, Class<?> arg) - { - super("The type, " + arg + ", is invalid for the conversion character, " + - c + "."); - if (arg == null) - throw new NullPointerException("The supplied type was null."); - this.c = c; - this.arg = arg; - } - - /** - * Returns the conversion character. - * - * @return the conversion character. - */ - public char getConversion() - { - return c; - } - - /** - * Returns the type of the mismatched argument. - * - * @return the type of the mismatched argument. - */ - public Class<?> getArgumentClass() - { - return arg; - } -} diff --git a/libjava/classpath/java/util/IllegalFormatException.java b/libjava/classpath/java/util/IllegalFormatException.java deleted file mode 100644 index b5c740a..0000000 --- a/libjava/classpath/java/util/IllegalFormatException.java +++ /dev/null @@ -1,75 +0,0 @@ -/* IllegalFormatException.java - Copyright (C) 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 general exception thrown when a format string is supplied - * to a {@link Formatter} that contains either invalid syntax - * or a mismatch between the format specification and the - * supplied arguments. This class is never instantiated; - * instead one of its subclasses is used to throw a more - * specific exception. - * - * @author Tom Tromey (tromey@redhat.com) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.5 - */ -public class IllegalFormatException - extends IllegalArgumentException -{ - private static final long serialVersionUID = 18830826L; - - /** - * Constructs a new <code>IllegalFormatException</code>. - */ - IllegalFormatException() - { - } - - /** - * Constructs a new <code>IllegalFormatException</code> - * with the specified message. - * - * @param msg the error message for this exception. - */ - IllegalFormatException(String msg) - { - super(msg); - } -} diff --git a/libjava/classpath/java/util/IllegalFormatFlagsException.java b/libjava/classpath/java/util/IllegalFormatFlagsException.java deleted file mode 100644 index b53bfa5..0000000 --- a/libjava/classpath/java/util/IllegalFormatFlagsException.java +++ /dev/null @@ -1,86 +0,0 @@ -/* IllegalFormatFlagsException.java - Copyright (C) 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; - -/** - * Thrown when the flags supplied to the {@link Formatter#format()} - * method of a {@link Formatter} form an illegal combination. - * - * @author Tom Tromey (tromey@redhat.com) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.5 - */ -public class IllegalFormatFlagsException - extends IllegalFormatException -{ - private static final long serialVersionUID = 790824L; - - /** - * The set of flags which forms an illegal combination. - * - * @serial the illegal set of flags. - */ - // Note: name fixed by serialization. - private String flags; - - /** - * Constructs a new <code>IllegalFormatFlagsException</code> - * for the specified flags. - * - * @param flags the illegal set of flags. - * @throws NullPointerException if <code>flags</code> is null. - */ - public IllegalFormatFlagsException(String flags) - { - super("An illegal set of flags, " + flags + ", was supplied."); - if (flags == null) - throw new NullPointerException("The supplied flags are null."); - this.flags = flags; - } - - /** - * Returns the illegal flags. - * - * @return the illegal flags. - */ - public String getFlags() - { - return flags; - } -} diff --git a/libjava/classpath/java/util/IllegalFormatPrecisionException.java b/libjava/classpath/java/util/IllegalFormatPrecisionException.java deleted file mode 100644 index a216dc1..0000000 --- a/libjava/classpath/java/util/IllegalFormatPrecisionException.java +++ /dev/null @@ -1,85 +0,0 @@ -/* IllegalFormatPrecisionException.java - Copyright (C) 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; - -/** - * Thrown when the specified precision for a {@link Formatter} - * argument is illegal. This may be because the number is - * a negative number (other than -1), the argument does not - * accept a precision or for some other reason. - * - * @author Tom Tromey (tromey@redhat.com) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.5 - */ -public class IllegalFormatPrecisionException - extends IllegalFormatException -{ - private static final long serialVersionUID = 18711008L; - - /** - * The illegal precision value. - * - * @serial the illegal precision. - */ - // Note: name fixed by serialization. - private int p; - - /** - * Constructs a new <code>IllegalFormatPrecisionException</code> - * for the precision, <code>p</code>. - * - * @param p the illegal precision. - */ - public IllegalFormatPrecisionException(int p) - { - super("The precision, " + p + ", is illegal."); - this.p = p; - } - - /** - * Returns the illegal precision. - * - * @return the illegal precision. - */ - public int getPrecision() - { - return p; - } -} diff --git a/libjava/classpath/java/util/IllegalFormatWidthException.java b/libjava/classpath/java/util/IllegalFormatWidthException.java deleted file mode 100644 index 7f2a625..0000000 --- a/libjava/classpath/java/util/IllegalFormatWidthException.java +++ /dev/null @@ -1,84 +0,0 @@ -/* IllegalFormatWidthException.java - Copyright (C) 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; - -/** - * Thrown when the specified width for a {@link Formatter} - * argument is illegal. This may be because the number is - * a negative number (other than -1) or for some other reason. - * - * @author Tom Tromey (tromey@redhat.com) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.5 - */ -public class IllegalFormatWidthException - extends IllegalFormatException -{ - private static final long serialVersionUID = 16660902L; - - /** - * The illegal width value. - * - * @serial the illegal width. - */ - // Note: name fixed by serialization. - private int w; - - /** - * Constructs a new <code>IllegalFormatWidthException</code> - * with the specified width, <code>w</code>. - * - * @param w the illegal width. - */ - public IllegalFormatWidthException(int w) - { - super("The width, " + w + ", is illegal."); - this.w = w; - } - - /** - * Returns the illegal width. - * - * @return the illegal width. - */ - public int getWidth() - { - return w; - } -} diff --git a/libjava/classpath/java/util/InputMismatchException.java b/libjava/classpath/java/util/InputMismatchException.java deleted file mode 100644 index ee29e46..0000000 --- a/libjava/classpath/java/util/InputMismatchException.java +++ /dev/null @@ -1,73 +0,0 @@ -/* InputMismatchException.java - Copyright (C) 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; - -/** - * Thrown when a {@link Scanner} instance encounters a mismatch - * between the input data and the pattern it is trying to match it - * against. This could be because the input data represents an - * out-of-range value for the type the pattern represents, or simply - * because the data does not fit that particular type. - * - * @author Tom Tromey (tromey@redhat.com) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.5 - */ -public class InputMismatchException - extends NoSuchElementException -{ - /** - * Constructs a new <code>InputMismatchException</code> - * with a <code>null</code> message. - */ - public InputMismatchException() - { - } - - /** - * Constructs a new <code>InputMismatchException</code> - * with the supplied error message. - * - * @param s the error message to report back to the user. - */ - public InputMismatchException(String s) - { - super(s); - } -} diff --git a/libjava/classpath/java/util/InvalidPropertiesFormatException.java b/libjava/classpath/java/util/InvalidPropertiesFormatException.java deleted file mode 100644 index aaa6c4e..0000000 --- a/libjava/classpath/java/util/InvalidPropertiesFormatException.java +++ /dev/null @@ -1,72 +0,0 @@ -/* InvalidPropertiesFormatException.java - Copyright (C) 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.NotSerializableException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; - -/** @since 1.5 */ -public class InvalidPropertiesFormatException extends IOException -{ - // This class won't serialize, but we have a UID to placate the compiler. - private static final long serialVersionUID = 7763056076009360219L; - - public InvalidPropertiesFormatException(String message) - { - super(message); - } - - public InvalidPropertiesFormatException(Throwable cause) - { - super(); - initCause(cause); - } - - private void writeObject(ObjectOutputStream out) throws IOException - { - throw new NotSerializableException("objects of this type are not serializable"); - } - - private void readObject(ObjectInputStream in) throws IOException - { - throw new NotSerializableException("objects of this type are not serializable"); - } -} diff --git a/libjava/classpath/java/util/Iterator.java b/libjava/classpath/java/util/Iterator.java deleted file mode 100644 index 41111a5..0000000 --- a/libjava/classpath/java/util/Iterator.java +++ /dev/null @@ -1,87 +0,0 @@ -/* Iterator.java -- Interface for iterating over collections - 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 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<E> -{ - /** - * 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 - */ - E 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/classpath/java/util/LinkedHashMap.java b/libjava/classpath/java/util/LinkedHashMap.java deleted file mode 100644 index 7701d77..0000000 --- a/libjava/classpath/java/util/LinkedHashMap.java +++ /dev/null @@ -1,500 +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) - * @author Tom Tromey (tromey@redhat.com) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @see Object#hashCode() - * @see Collection - * @see Map - * @see HashMap - * @see TreeMap - * @see Hashtable - * @since 1.4 - * @status updated to 1.4 - */ -public class LinkedHashMap<K,V> extends HashMap<K,V> -{ - /** - * 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<K,V> extends HashEntry<K,V> - { - /** - * The predecessor in the iteration list. If this entry is the root - * (eldest), pred points to the newest entry. - */ - LinkedHashEntry<K,V> pred; - - /** The successor in the iteration list, null if this is the newest. */ - LinkedHashEntry<K,V> succ; - - /** - * Simple constructor. - * - * @param key the key - * @param value the value - */ - LinkedHashEntry(K key, V 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 - */ - V 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<? extends K, ? extends V> 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 V get(Object key) - { - int idx = hash(key); - HashEntry<K,V> 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<K,V> 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(K key, V 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 - */ - public boolean hasNext() - { - 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/classpath/java/util/LinkedHashSet.java b/libjava/classpath/java/util/LinkedHashSet.java deleted file mode 100644 index 2caebaf..0000000 --- a/libjava/classpath/java/util/LinkedHashSet.java +++ /dev/null @@ -1,159 +0,0 @@ -/* LinkedHashSet.java -- a set backed by a LinkedHashMap, for linked - list traversal. - Copyright (C) 2001, 2004, 2005, 2007 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<T> extends HashSet<T> - implements Set<T>, 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 loadFactor (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<? extends T> 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<T, String> init(int capacity, float load) - { - return new LinkedHashMap<T, String>(capacity, load); - } -} diff --git a/libjava/classpath/java/util/LinkedList.java b/libjava/classpath/java/util/LinkedList.java deleted file mode 100644 index 813d099..0000000 --- a/libjava/classpath/java/util/LinkedList.java +++ /dev/null @@ -1,1260 +0,0 @@ -/* LinkedList.java -- Linked list implementation of the List interface - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006 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) - * @author Tom Tromey (tromey@redhat.com) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @see List - * @see ArrayList - * @see Vector - * @see Collections#synchronizedList(List) - * @since 1.2 - * @status Complete to 1.6 - */ -public class LinkedList<T> extends AbstractSequentialList<T> - implements List<T>, Deque<T>, Cloneable, Serializable -{ - /** - * Compatible with JDK 1.2. - */ - private static final long serialVersionUID = 876323262645176354L; - - /** - * The first element in the list. - */ - transient Entry<T> first; - - /** - * The last element in the list. - */ - transient Entry<T> 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<T> - { - /** The element in the list. */ - T data; - - /** The next list entry, null if this is last. */ - Entry<T> next; - - /** The previous list entry, null if this is first. */ - Entry<T> previous; - - /** - * Construct an entry. - * @param data the list element - */ - Entry(T 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<T> getEntry(int n) - { - Entry<T> 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<T> 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<? extends T> c) - { - addAll(c); - } - - /** - * Returns the first element in the list. - * - * @return the first list element - * @throws NoSuchElementException if the list is empty - */ - public T 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 T 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 T removeFirst() - { - if (size == 0) - throw new NoSuchElementException(); - modCount++; - size--; - T 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 T removeLast() - { - if (size == 0) - throw new NoSuchElementException(); - modCount++; - size--; - T 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(T o) - { - Entry<T> 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(T o) - { - addLastEntry(new Entry<T>(o)); - } - - /** - * Inserts an element at the end of the list. - * - * @param e the entry to add - */ - private void addLastEntry(Entry<T> 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<T> 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 o the entry to add - * @return true, as it always succeeds - */ - public boolean add(T o) - { - addLastEntry(new Entry<T>(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<T> 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<? extends T> 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<? extends T> c) - { - checkBoundsInclusive(index); - int csize = c.size(); - - if (csize == 0) - return false; - - Iterator<? extends T> 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<T> after = null; - Entry<T> 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<T> e = new Entry<T>(itr.next()); - e.previous = before; - Entry<T> prev = e; - Entry<T> firstNew = e; - - // Create and link all the remaining entries. - for (int pos = 1; pos < csize; pos++) - { - e = new Entry<T>(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 T 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 T set(int index, T o) - { - checkBoundsExclusive(index); - Entry<T> e = getEntry(index); - T 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, T o) - { - checkBoundsInclusive(index); - Entry<T> e = new Entry<T>(o); - - if (index < size) - { - modCount++; - Entry<T> 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 T remove(int index) - { - checkBoundsExclusive(index); - Entry<T> 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<T> 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<T> 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<T> listIterator(int index) - { - checkBoundsInclusive(index); - return new LinkedListItr<T>(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<T> copy = null; - try - { - copy = (LinkedList<T>) 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<T> 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 <S> S[] toArray(S[] a) - { - if (a.length < size) - a = (S[]) Array.newInstance(a.getClass().getComponentType(), size); - else if (a.length > size) - a[size] = null; - Entry<T> e = first; - for (int i = 0; i < size; i++) - { - a[i] = (S) e.data; - e = e.next; - } - return a; - } - - /** - * Adds the specified element to the end of the list. - * - * @param value the value to add. - * @return true. - * @since 1.5 - */ - public boolean offer(T value) - { - return add(value); - } - - /** - * Returns the first element of the list without removing - * it. - * - * @return the first element of the list. - * @throws NoSuchElementException if the list is empty. - * @since 1.5 - */ - public T element() - { - return getFirst(); - } - - /** - * Returns the first element of the list without removing - * it. - * - * @return the first element of the list, or <code>null</code> - * if the list is empty. - * @since 1.5 - */ - public T peek() - { - if (size == 0) - return null; - return getFirst(); - } - - /** - * Removes and returns the first element of the list. - * - * @return the first element of the list, or <code>null</code> - * if the list is empty. - * @since 1.5 - */ - public T poll() - { - if (size == 0) - return null; - return removeFirst(); - } - - /** - * Removes and returns the first element of the list. - * - * @return the first element of the list. - * @throws NoSuchElementException if the list is empty. - * @since 1.5 - */ - public T remove() - { - return removeFirst(); - } - - /** - * 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<T> 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<T>((T) 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<I> - implements ListIterator<I> - { - /** Number of modifications we know about. */ - private int knownMod = modCount; - - /** Entry that will be returned by next(). */ - private Entry<I> next; - - /** Entry that will be returned by previous(). */ - private Entry<I> previous; - - /** Entry that will be affected by remove() or set(). */ - private Entry<I> lastReturned; - - /** Index of `next'. */ - private int position; - - /** - * Initialize the iterator. - * - * @param index the initial index - */ - LinkedListItr(int index) - { - if (index == size) - { - next = null; - previous = (Entry<I>) last; - } - else - { - next = (Entry<I>) 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 - */ - public int nextIndex() - { - return position; - } - - /** - * Returns the index of the previous element. - * - * @return the previous index - */ - public int previousIndex() - { - return position - 1; - } - - /** - * Returns true if more elements exist via next. - * - * @return true if next will succeed - */ - public boolean hasNext() - { - return (next != null); - } - - /** - * Returns true if more elements exist via previous. - * - * @return true if previous will succeed - */ - public boolean hasPrevious() - { - 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 I 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 I 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((Entry<T>) 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(I o) - { - checkMod(); - modCount++; - knownMod++; - size++; - position++; - Entry<I> e = new Entry<I>(o); - e.previous = previous; - e.next = next; - - if (previous != null) - previous.next = e; - else - first = (Entry<T>) e; - - if (next != null) - next.previous = e; - else - last = (Entry<T>) 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(I o) - { - checkMod(); - if (lastReturned == null) - throw new IllegalStateException(); - lastReturned.data = o; - } - } // class LinkedListItr - - /** - * Obtain an Iterator over this list in reverse sequential order. - * - * @return an Iterator over the elements of the list in - * reverse order. - * @since 1.6 - */ - public Iterator<T> descendingIterator() - { - return new Iterator<T>() - { - /** Number of modifications we know about. */ - private int knownMod = modCount; - - /** Entry that will be returned by next(). */ - private Entry<T> next = last; - - /** Entry that will be affected by remove() or set(). */ - private Entry<T> lastReturned; - - /** Index of `next'. */ - private int position = size() - 1; - - // 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 start of the list has not yet been - * reached. - */ - public boolean hasNext() - { - return next != null; - } - - /** - * 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 T next() - { - checkMod(); - if (next == null) - throw new NoSuchElementException(); - --position; - lastReturned = next; - next = lastReturned.previous; - return lastReturned.data; - } - - /** - * 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. - */ - public void remove() - { - checkMod(); - if (lastReturned == null) - throw new IllegalStateException(); - removeEntry(lastReturned); - lastReturned = null; - ++knownMod; - } - }; - } - - /** - * Inserts the specified element at the front of the list. - * - * @param value the element to insert. - * @return true. - * @since 1.6 - */ - public boolean offerFirst(T value) - { - addFirst(value); - return true; - } - - /** - * Inserts the specified element at the end of the list. - * - * @param value the element to insert. - * @return true. - * @since 1.6 - */ - public boolean offerLast(T value) - { - return add(value); - } - - /** - * Returns the first element of the list without removing - * it. - * - * @return the first element of the list, or <code>null</code> - * if the list is empty. - * @since 1.6 - */ - public T peekFirst() - { - return peek(); - } - - /** - * Returns the last element of the list without removing - * it. - * - * @return the last element of the list, or <code>null</code> - * if the list is empty. - * @since 1.6 - */ - public T peekLast() - { - if (size == 0) - return null; - return getLast(); - } - - /** - * Removes and returns the first element of the list. - * - * @return the first element of the list, or <code>null</code> - * if the list is empty. - * @since 1.6 - */ - public T pollFirst() - { - return poll(); - } - - /** - * Removes and returns the last element of the list. - * - * @return the last element of the list, or <code>null</code> - * if the list is empty. - * @since 1.6 - */ - public T pollLast() - { - if (size == 0) - return null; - return removeLast(); - } - - /** - * Pops an element from the stack by removing and returning - * the first element in the list. This is equivalent to - * calling {@link #removeFirst()}. - * - * @return the top of the stack, which is the first element - * of the list. - * @throws NoSuchElementException if the list is empty. - * @since 1.6 - * @see #removeFirst() - */ - public T pop() - { - return removeFirst(); - } - - /** - * Pushes an element on to the stack by adding it to the - * front of the list. This is equivalent to calling - * {@link #addFirst(T)}. - * - * @param value the element to push on to the stack. - * @throws NoSuchElementException if the list is empty. - * @since 1.6 - * @see #addFirst(T) - */ - public void push(T value) - { - addFirst(value); - } - - /** - * Removes the first occurrence of the specified element - * from the list, when traversing the list from head to - * tail. The list is unchanged if the element is not found. - * This is equivalent to calling {@link #remove(Object)}. - * - * @param o the element to remove. - * @return true if an instance of the object was removed. - * @since 1.6 - */ - public boolean removeFirstOccurrence(Object o) - { - return remove(o); - } - - /** - * Removes the last occurrence of the specified element - * from the list, when traversing the list from head to - * tail. The list is unchanged if the element is not found. - * - * @param o the element to remove. - * @return true if an instance of the object was removed. - * @since 1.6 - */ - public boolean removeLastOccurrence(Object o) - { - Entry<T> e = last; - while (e != null) - { - if (equals(o, e.data)) - { - removeEntry(e); - return true; - } - e = e.previous; - } - return false; - } - -} diff --git a/libjava/classpath/java/util/List.java b/libjava/classpath/java/util/List.java deleted file mode 100644 index 3a437a5..0000000 --- a/libjava/classpath/java/util/List.java +++ /dev/null @@ -1,451 +0,0 @@ -/* List.java -- An ordered collection which allows indexed access - 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 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<E> extends Collection<E> -{ - /** - * 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, E 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(E 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<? extends E> 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<? extends E> 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() - */ - E 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<E> 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<E> 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<E> 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() - */ - E 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. - */ - E set(int index, E 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<E> 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 - */ - <T> T[] toArray(T[] a); -} diff --git a/libjava/classpath/java/util/ListIterator.java b/libjava/classpath/java/util/ListIterator.java deleted file mode 100644 index 9b74528..0000000 --- a/libjava/classpath/java/util/ListIterator.java +++ /dev/null @@ -1,170 +0,0 @@ -/* ListIterator.java -- Extended Iterator for iterating over ordered lists - 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; - -/** - * 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<E> extends Iterator<E> -{ - /** - * 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 - */ - E 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 - */ - E 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(E 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(E o); -} diff --git a/libjava/classpath/java/util/ListResourceBundle.java b/libjava/classpath/java/util/ListResourceBundle.java deleted file mode 100644 index 2e48a22..0000000 --- a/libjava/classpath/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<String> 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<String> s = new HashSet<String>(); - int i = contents.length; - while (--i >= 0) - s.add((String) contents[i][0]); - ResourceBundle bundle = parent; - // Eliminate tail recursion. - while (bundle != null) - { - Enumeration<String> 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/classpath/java/util/Locale.java b/libjava/classpath/java/util/Locale.java deleted file mode 100644 index ef11173..0000000 --- a/libjava/classpath/java/util/Locale.java +++ /dev/null @@ -1,1029 +0,0 @@ -/* Locale.java -- i18n locales - Copyright (C) 1998, 1999, 2001, 2002, 2005, 2006 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 gnu.classpath.SystemProperties; - -import gnu.java.lang.CPStringBuilder; - -import gnu.java.locale.LocaleHelper; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; - -import java.util.spi.LocaleNameProvider; - -/** - * Locales represent a specific country and culture. Classes which can be - * passed a Locale object tailor their information for a given locale. For - * instance, currency number formatting is handled differently for the USA - * and France. - * - * <p>Locales are made up of a language code, a country code, and an optional - * set of variant strings. Language codes are represented by - * <a href="http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt"> - * ISO 639:1988</a> w/ additions from ISO 639/RA Newsletter No. 1/1989 - * and a decision of the Advisory Committee of ISO/TC39 on August 8, 1997. - * - * <p>Country codes are represented by - * <a href="http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html"> - * ISO 3166</a>. Variant strings are vendor and browser specific. Standard - * variant strings include "POSIX" for POSIX, "WIN" for MS-Windows, and - * "MAC" for Macintosh. When there is more than one variant string, they must - * be separated by an underscore (U+005F). - * - * <p>The default locale is determined by the values of the system properties - * user.language, user.country (or user.region), and user.variant, defaulting - * to "en_US". Note that the locale does NOT contain the conversion and - * formatting capabilities (for that, use ResourceBundle and java.text). - * Rather, it is an immutable tag object for identifying a given locale, which - * is referenced by these other classes when they must make locale-dependent - * decisions. - * - * @see ResourceBundle - * @see java.text.Format - * @see java.text.NumberFormat - * @see java.text.Collator - * @author Jochen Hoenicke - * @author Paul Fisher - * @author Eric Blake (ebb9@email.byu.edu) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.1 - * @status updated to 1.4 - */ -public final class Locale implements Serializable, Cloneable -{ - /** Locale which represents the English language. */ - public static final Locale ENGLISH = getLocale("en"); - - /** Locale which represents the French language. */ - public static final Locale FRENCH = getLocale("fr"); - - /** Locale which represents the German language. */ - public static final Locale GERMAN = getLocale("de"); - - /** Locale which represents the Italian language. */ - public static final Locale ITALIAN = getLocale("it"); - - /** Locale which represents the Japanese language. */ - public static final Locale JAPANESE = getLocale("ja"); - - /** Locale which represents the Korean language. */ - public static final Locale KOREAN = getLocale("ko"); - - /** Locale which represents the Chinese language. */ - public static final Locale CHINESE = getLocale("zh"); - - /** Locale which represents the Chinese language as used in China. */ - public static final Locale SIMPLIFIED_CHINESE = getLocale("zh", "CN"); - - /** - * Locale which represents the Chinese language as used in Taiwan. - * Same as TAIWAN Locale. - */ - public static final Locale TRADITIONAL_CHINESE = getLocale("zh", "TW"); - - /** Locale which represents France. */ - public static final Locale FRANCE = getLocale("fr", "FR"); - - /** Locale which represents Germany. */ - public static final Locale GERMANY = getLocale("de", "DE"); - - /** Locale which represents Italy. */ - public static final Locale ITALY = getLocale("it", "IT"); - - /** Locale which represents Japan. */ - public static final Locale JAPAN = getLocale("ja", "JP"); - - /** Locale which represents Korea. */ - public static final Locale KOREA = getLocale("ko", "KR"); - - /** - * Locale which represents China. - * Same as SIMPLIFIED_CHINESE Locale. - */ - public static final Locale CHINA = SIMPLIFIED_CHINESE; - - /** - * Locale which represents the People's Republic of China. - * Same as CHINA Locale. - */ - public static final Locale PRC = CHINA; - - /** - * Locale which represents Taiwan. - * Same as TRADITIONAL_CHINESE Locale. - */ - public static final Locale TAIWAN = TRADITIONAL_CHINESE; - - /** Locale which represents the United Kingdom. */ - public static final Locale UK = getLocale("en", "GB"); - - /** Locale which represents the United States. */ - public static final Locale US = getLocale("en", "US"); - - /** Locale which represents the English speaking portion of Canada. */ - public static final Locale CANADA = getLocale("en", "CA"); - - /** Locale which represents the French speaking portion of Canada. */ - public static final Locale CANADA_FRENCH = getLocale("fr", "CA"); - - /** The root locale, used as the base case in lookups by - * locale-sensitive operations. - */ - public static final Locale ROOT = new Locale("","",""); - - /** - * Compatible with JDK 1.1+. - */ - private static final long serialVersionUID = 9149081749638150636L; - - /** - * The language code, as returned by getLanguage(). - * - * @serial the languange, possibly "" - */ - private final String language; - - /** - * The country code, as returned by getCountry(). - * - * @serial the country, possibly "" - */ - private final String country; - - /** - * The variant code, as returned by getVariant(). - * - * @serial the variant, possibly "" - */ - private final String variant; - - /** - * This is the cached hashcode. When writing to stream, we write -1. - * - * @serial should be -1 in serial streams - */ - private int hashcode; - - /** - * Array storing all available locales. - */ - private static transient Locale[] availableLocales; - - /** - * Locale cache. Only created locale objects are stored. - * Contains all supported locales when getAvailableLocales() - * got called. - */ - private static transient HashMap localeMap; - - /** - * The default locale. Except for during bootstrapping, this should never be - * null. Note the logic in the main constructor, to detect when - * bootstrapping has completed. - */ - private static Locale defaultLocale; - - static { - String language = SystemProperties.getProperty("user.language", "en"); - String country = SystemProperties.getProperty("user.country", "US"); - String region = SystemProperties.getProperty("user.region", null); - String variant = SystemProperties.getProperty("user.variant", ""); - - defaultLocale = getLocale(language, - (region != null) ? region : country, - variant); - } - - /** - * Array storing all the available two-letter ISO639 languages. - */ - private static transient String[] languageCache; - - /** - * Array storing all the available two-letter ISO3166 country codes. - */ - private static transient String[] countryCache; - - /** - * Retrieves the locale with the specified language from the cache. - * - * @param language the language of the locale to retrieve. - * @return the locale. - */ - private static Locale getLocale(String language) - { - return getLocale(language, "", ""); - } - - /** - * Retrieves the locale with the specified language and country - * from the cache. - * - * @param language the language of the locale to retrieve. - * @param country the country of the locale to retrieve. - * @return the locale. - */ - private static Locale getLocale(String language, String country) - { - return getLocale(language, country, ""); - } - - /** - * Retrieves the locale with the specified language, country - * and variant from the cache. - * - * @param language the language of the locale to retrieve. - * @param country the country of the locale to retrieve. - * @param variant the variant of the locale to retrieve. - * @return the locale. - */ - private static Locale getLocale(String language, String country, String variant) - { - if (localeMap == null) - localeMap = new HashMap(256); - - String name = language + "_" + country + "_" + variant; - Locale locale = (Locale) localeMap.get(name); - - if (locale == null) - { - locale = new Locale(language, country, variant); - localeMap.put(name, locale); - } - - return locale; - } - - /** - * Convert new iso639 codes to the old ones. - * - * @param language the language to check - * @return the appropriate code - */ - private String convertLanguage(String language) - { - if (language.equals("")) - return language; - language = language.toLowerCase(); - int index = "he,id,yi".indexOf(language); - if (index != -1) - return "iw,in,ji".substring(index, index + 2); - return language; - } - - /** - * Creates a new locale for the given language and country. - * - * @param language lowercase two-letter ISO-639 A2 language code - * @param country uppercase two-letter ISO-3166 A2 contry code - * @param variant vendor and browser specific - * @throws NullPointerException if any argument is null - */ - public Locale(String language, String country, String variant) - { - // During bootstrap, we already know the strings being passed in are - // the correct capitalization, and not null. We can't call - // String.toUpperCase during this time, since that depends on the - // default locale. - if (defaultLocale != null) - { - language = convertLanguage(language); - country = country.toUpperCase(); - } - this.language = language.intern(); - this.country = country.intern(); - this.variant = variant.intern(); - hashcode = language.hashCode() ^ country.hashCode() ^ variant.hashCode(); - } - - /** - * Creates a new locale for the given language and country. - * - * @param language lowercase two-letter ISO-639 A2 language code - * @param country uppercase two-letter ISO-3166 A2 country code - * @throws NullPointerException if either argument is null - */ - public Locale(String language, String country) - { - this(language, country, ""); - } - - /** - * Creates a new locale for a language. - * - * @param language lowercase two-letter ISO-639 A2 language code - * @throws NullPointerException if either argument is null - * @since 1.4 - */ - public Locale(String language) - { - this(language, "", ""); - } - - /** - * Returns the default Locale. The default locale is generally once set - * on start up and then never changed. Normally you should use this locale - * for everywhere you need a locale. The initial setting matches the - * default locale, the user has chosen. - * - * @return the default locale for this virtual machine - */ - public static Locale getDefault() - { - return defaultLocale; - } - - /** - * Changes the default locale. Normally only called on program start up. - * Note that this doesn't change the locale for other programs. This has - * a security check, - * <code>PropertyPermission("user.language", "write")</code>, because of - * its potential impact to running code. - * - * @param newLocale the new default locale - * @throws NullPointerException if newLocale is null - * @throws SecurityException if permission is denied - */ - public static void setDefault(Locale newLocale) - { - if (newLocale == null) - throw new NullPointerException(); - SecurityManager sm = System.getSecurityManager(); - if (sm != null) - sm.checkPermission(new PropertyPermission("user.language", "write")); - defaultLocale = newLocale; - } - - /** - * Returns the list of available locales. - * - * @return the installed locales - */ - public static synchronized Locale[] getAvailableLocales() - { - if (availableLocales == null) - { - int len = LocaleHelper.getLocaleCount(); - availableLocales = new Locale[len]; - - for (int i = 0; i < len; i++) - { - String language; - String country = ""; - String variant = ""; - String name = LocaleHelper.getLocaleName(i); - - language = name.substring(0, 2); - - if (name.length() > 2) - country = name.substring(3); - - int index = country.indexOf("_"); - if (index > 0) - { - variant = country.substring(index + 1); - country = country.substring(0, index - 1); - } - - availableLocales[i] = getLocale(language, country, variant); - } - } - - return (Locale[]) availableLocales.clone(); - } - - /** - * Returns a list of all 2-letter uppercase country codes as defined - * in ISO 3166. - * - * @return a list of acceptable country codes - */ - public static String[] getISOCountries() - { - if (countryCache == null) - { - countryCache = getISOStrings("territories"); - } - - return (String[]) countryCache.clone(); - } - - /** - * Returns a list of all 2-letter lowercase language codes as defined - * in ISO 639 (both old and new variant). - * - * @return a list of acceptable language codes - */ - public static String[] getISOLanguages() - { - if (languageCache == null) - { - languageCache = getISOStrings("languages"); - } - return (String[]) languageCache.clone(); - } - - /** - * Returns the set of keys from the specified resource hashtable, filtered - * so that only two letter strings are returned. - * - * @param tableName the name of the table from which to retrieve the keys. - * @return an array of two-letter strings. - */ - private static String[] getISOStrings(String tableName) - { - int count = 0; - ResourceBundle bundle = - ResourceBundle.getBundle("gnu.java.locale.LocaleInformation"); - Enumeration e = bundle.getKeys(); - ArrayList tempList = new ArrayList(); - - while (e.hasMoreElements()) - { - String key = (String) e.nextElement(); - - if (key.startsWith(tableName + ".")) - { - String str = key.substring(tableName.length() + 1); - - if (str.length() == 2 - && Character.isLetter(str.charAt(0)) - && Character.isLetter(str.charAt(1))) - { - tempList.add(str); - ++count; - } - } - } - - String[] strings = new String[count]; - - for (int a = 0; a < count; ++a) - strings[a] = (String) tempList.get(a); - - return strings; - } - - /** - * Returns the language code of this locale. Some language codes have changed - * as ISO 639 has evolved; this returns the old name, even if you built - * the locale with the new one. - * - * @return language code portion of this locale, or an empty String - */ - public String getLanguage() - { - return language; - } - - /** - * Returns the country code of this locale. - * - * @return country code portion of this locale, or an empty String - */ - public String getCountry() - { - return country; - } - - /** - * Returns the variant code of this locale. - * - * @return the variant code portion of this locale, or an empty String - */ - public String getVariant() - { - return variant; - } - - /** - * Gets the string representation of the current locale. This consists of - * the language, the country, and the variant, separated by an underscore. - * The variant is listed only if there is a language or country. Examples: - * "en", "de_DE", "_GB", "en_US_WIN", "de__POSIX", "fr__MAC". - * - * @return the string representation of this Locale - * @see #getDisplayName() - */ - public String toString() - { - if (language.length() == 0 && country.length() == 0) - return ""; - else if (country.length() == 0 && variant.length() == 0) - return language; - CPStringBuilder result = new CPStringBuilder(language); - result.append('_').append(country); - if (variant.length() != 0) - result.append('_').append(variant); - return result.toString(); - } - - /** - * Returns the three-letter ISO language abbrevation of this locale. - * - * @throws MissingResourceException if the three-letter code is not known - */ - public String getISO3Language() - { - // We know all strings are interned so we can use '==' for better performance. - if (language == "") - return ""; - int index - = ("aa,ab,af,am,ar,as,ay,az,ba,be,bg,bh,bi,bn,bo,br,ca,co,cs,cy,da," - + "de,dz,el,en,eo,es,et,eu,fa,fi,fj,fo,fr,fy,ga,gd,gl,gn,gu,ha,iw," - + "hi,hr,hu,hy,ia,in,ie,ik,in,is,it,iu,iw,ja,ji,jw,ka,kk,kl,km,kn," - + "ko,ks,ku,ky,la,ln,lo,lt,lv,mg,mi,mk,ml,mn,mo,mr,ms,mt,my,na,ne," - + "nl,no,oc,om,or,pa,pl,ps,pt,qu,rm,rn,ro,ru,rw,sa,sd,sg,sh,si,sk," - + "sl,sm,sn,so,sq,sr,ss,st,su,sv,sw,ta,te,tg,th,ti,tk,tl,tn,to,tr," - + "ts,tt,tw,ug,uk,ur,uz,vi,vo,wo,xh,ji,yo,za,zh,zu") - .indexOf(language); - - if (index % 3 != 0 || language.length() != 2) - throw new MissingResourceException - ("Can't find ISO3 language for " + language, - "java.util.Locale", language); - - // Don't read this aloud. These are the three letter language codes. - return - ("aarabkaframharaasmaymazebakbelbulbihbisbenbodbrecatcoscescymdandeu" - + "dzoellengepospaesteusfasfinfijfaofrafrygaigdhglggrngujhauhebhinhrv" - + "hunhyeinaindileipkindislitaikuhebjpnyidjawkatkazkalkhmkankorkaskur" - + "kirlatlinlaolitlavmlgmrimkdmalmonmolmarmsamltmyanaunepnldnorociorm" - + "oripanpolpusporquerohrunronruskinsansndsagsrpsinslkslvsmosnasomsqi" - + "srpsswsotsunsweswatamteltgkthatirtuktgltsntonturtsotattwiuigukrurd" - + "uzbvievolwolxhoyidyorzhazhozul") - .substring(index, index + 3); - } - - /** - * Returns the three-letter ISO country abbrevation of the locale. - * - * @throws MissingResourceException if the three-letter code is not known - */ - public String getISO3Country() - { - // We know all strings are interned so we can use '==' for better performance. - if (country == "") - return ""; - int index - = ("AD,AE,AF,AG,AI,AL,AM,AN,AO,AQ,AR,AS,AT,AU,AW,AZ,BA,BB,BD,BE,BF," - + "BG,BH,BI,BJ,BM,BN,BO,BR,BS,BT,BV,BW,BY,BZ,CA,CC,CF,CG,CH,CI,CK," - + "CL,CM,CN,CO,CR,CU,CV,CX,CY,CZ,DE,DJ,DK,DM,DO,DZ,EC,EE,EG,EH,ER," - + "ES,ET,FI,FJ,FK,FM,FO,FR,FX,GA,GB,GD,GE,GF,GH,GI,GL,GM,GN,GP,GQ," - + "GR,GS,GT,GU,GW,GY,HK,HM,HN,HR,HT,HU,ID,IE,IL,IN,IO,IQ,IR,IS,IT," - + "JM,JO,JP,KE,KG,KH,KI,KM,KN,KP,KR,KW,KY,KZ,LA,LB,LC,LI,LK,LR,LS," - + "LT,LU,LV,LY,MA,MC,MD,MG,MH,MK,ML,MM,MN,MO,MP,MQ,MR,MS,MT,MU,MV," - + "MW,MX,MY,MZ,NA,NC,NE,NF,NG,NI,NL,NO,NP,NR,NU,NZ,OM,PA,PE,PF,PG," - + "PH,PK,PL,PM,PN,PR,PT,PW,PY,QA,RE,RO,RU,RW,SA,SB,SC,SD,SE,SG,SH," - + "SI,SJ,SK,SL,SM,SN,SO,SR,ST,SV,SY,SZ,TC,TD,TF,TG,TH,TJ,TK,TM,TN," - + "TO,TP,TR,TT,TV,TW,TZ,UA,UG,UM,US,UY,UZ,VA,VC,VE,VG,VI,VN,VU,WF," - + "WS,YE,YT,YU,ZA,ZM,ZR,ZW") - .indexOf(country); - - if (index % 3 != 0 || country.length() != 2) - throw new MissingResourceException - ("Can't find ISO3 country for " + country, - "java.util.Locale", country); - - // Don't read this aloud. These are the three letter country codes. - return - ("ANDAREAFGATGAIAALBARMANTAGOATAARGASMAUTAUSABWAZEBIHBRBBGDBELBFABGR" - + "BHRBDIBENBMUBRNBOLBRABHSBTNBVTBWABLRBLZCANCCKCAFCOGCHECIVCOKCHLCMR" - + "CHNCOLCRICUBCPVCXRCYPCZEDEUDJIDNKDMADOMDZAECUESTEGYESHERIESPETHFIN" - + "FJIFLKFSMFROFRAFXXGABGBRGRDGEOGUFGHAGIBGRLGMBGINGLPGNQGRCSGSGTMGUM" - + "GNBGUYHKGHMDHNDHRVHTIHUNIDNIRLISRINDIOTIRQIRNISLITAJAMJORJPNKENKGZ" - + "KHMKIRCOMKNAPRKKORKWTCYMKAZLAOLBNLCALIELKALBRLSOLTULUXLVALBYMARMCO" - + "MDAMDGMHLMKDMLIMMRMNGMACMNPMTQMRTMSRMLTMUSMDVMWIMEXMYSMOZNAMNCLNER" - + "NFKNGANICNLDNORNPLNRUNIUNZLOMNPANPERPYFPNGPHLPAKPOLSPMPCNPRIPRTPLW" - + "PRYQATREUROMRUSRWASAUSLBSYCSDNSWESGPSHNSVNSJMSVKSLESMRSENSOMSURSTP" - + "SLVSYRSWZTCATCDATFTGOTHATJKTKLTKMTUNTONTMPTURTTOTUVTWNTZAUKRUGAUMI" - + "USAURYUZBVATVCTVENVGBVIRVNMVUTWLFWSMYEMMYTYUGZAFZMBZARZWE") - .substring(index, index + 3); - } - - /** - * Gets the country name suitable for display to the user, formatted - * for the default locale. This has the same effect as - * <pre> - * getDisplayLanguage(Locale.getDefault()); - * </pre> - * - * @return the language name of this locale localized to the default locale, - * with the ISO code as backup - */ - public String getDisplayLanguage() - { - return getDisplayLanguage(defaultLocale); - } - - /** - * <p> - * Gets the name of the language specified by this locale, in a form suitable - * for display to the user. If possible, the display name will be localized - * to the specified locale. For example, if the locale instance is - * <code>Locale.GERMANY</code>, and the specified locale is <code>Locale.UK</code>, - * the result would be 'German'. Using the German locale would instead give - * 'Deutsch'. If the display name can not be localized to the supplied - * locale, it will fall back on other output in the following order: - * </p> - * <ul> - * <li>the display name in the default locale</li> - * <li>the display name in English</li> - * <li>the ISO code</li> - * </ul> - * <p> - * If the language is unspecified by this locale, then the empty string is - * returned. - * </p> - * - * @param inLocale the locale to use for formatting the display string. - * @return the language name of this locale localized to the given locale, - * with the default locale, English and the ISO code as backups. - * @throws NullPointerException if the supplied locale is null. - */ - public String getDisplayLanguage(Locale inLocale) - { - if (language.isEmpty()) - return ""; - try - { - ResourceBundle res = - ResourceBundle.getBundle("gnu.java.locale.LocaleInformation", - inLocale, - ClassLoader.getSystemClassLoader()); - - return res.getString("languages." + language); - } - catch (MissingResourceException e) - { - /* This means runtime support for the locale - * is not available, so we check providers. */ - } - for (LocaleNameProvider p : - ServiceLoader.load(LocaleNameProvider.class)) - { - for (Locale loc : p.getAvailableLocales()) - { - if (loc.equals(inLocale)) - { - String locLang = p.getDisplayLanguage(language, - inLocale); - if (locLang != null) - return locLang; - break; - } - } - } - if (inLocale.equals(Locale.ROOT)) // Base case - return language; - return getDisplayLanguage(LocaleHelper.getFallbackLocale(inLocale)); - } - - /** - * Returns the country name of this locale localized to the - * default locale. If the localized is not found, the ISO code - * is returned. This has the same effect as - * <pre> - * getDisplayCountry(Locale.getDefault()); - * </pre> - * - * @return the country name of this locale localized to the given locale, - * with the ISO code as backup - */ - public String getDisplayCountry() - { - return getDisplayCountry(defaultLocale); - } - - /** - * <p> - * Gets the name of the country specified by this locale, in a form suitable - * for display to the user. If possible, the display name will be localized - * to the specified locale. For example, if the locale instance is - * <code>Locale.GERMANY</code>, and the specified locale is <code>Locale.UK</code>, - * the result would be 'Germany'. Using the German locale would instead give - * 'Deutschland'. If the display name can not be localized to the supplied - * locale, it will fall back on other output in the following order: - * </p> - * <ul> - * <li>the display name in the default locale</li> - * <li>the display name in English</li> - * <li>the ISO code</li> - * </ul> - * <p> - * If the country is unspecified by this locale, then the empty string is - * returned. - * </p> - * - * @param inLocale the locale to use for formatting the display string. - * @return the country name of this locale localized to the given locale, - * with the default locale, English and the ISO code as backups. - * @throws NullPointerException if the supplied locale is null. - */ - public String getDisplayCountry(Locale inLocale) - { - if (country.isEmpty()) - return ""; - try - { - ResourceBundle res = - ResourceBundle.getBundle("gnu.java.locale.LocaleInformation", - inLocale, - ClassLoader.getSystemClassLoader()); - - return res.getString("territories." + country); - } - catch (MissingResourceException e) - { - /* This means runtime support for the locale - * is not available, so we check providers. */ - } - for (LocaleNameProvider p : - ServiceLoader.load(LocaleNameProvider.class)) - { - for (Locale loc : p.getAvailableLocales()) - { - if (loc.equals(inLocale)) - { - String locCountry = p.getDisplayCountry(country, - inLocale); - if (locCountry != null) - return locCountry; - break; - } - } - } - if (inLocale.equals(Locale.ROOT)) // Base case - return country; - return getDisplayCountry(LocaleHelper.getFallbackLocale(inLocale)); - } - - /** - * Returns the variant name of this locale localized to the - * default locale. If the localized is not found, the variant code - * itself is returned. This has the same effect as - * <pre> - * getDisplayVariant(Locale.getDefault()); - * </pre> - * - * @return the variant code of this locale localized to the given locale, - * with the ISO code as backup - */ - public String getDisplayVariant() - { - return getDisplayVariant(defaultLocale); - } - - - /** - * <p> - * Gets the name of the variant specified by this locale, in a form suitable - * for display to the user. If possible, the display name will be localized - * to the specified locale. For example, if the locale instance is a revised - * variant, and the specified locale is <code>Locale.UK</code>, the result - * would be 'REVISED'. Using the German locale would instead give - * 'Revidiert'. If the display name can not be localized to the supplied - * locale, it will fall back on other output in the following order: - * </p> - * <ul> - * <li>the display name in the default locale</li> - * <li>the display name in English</li> - * <li>the ISO code</li> - * </ul> - * <p> - * If the variant is unspecified by this locale, then the empty string is - * returned. - * </p> - * - * @param inLocale the locale to use for formatting the display string. - * @return the variant name of this locale localized to the given locale, - * with the default locale, English and the ISO code as backups. - * @throws NullPointerException if the supplied locale is null. - */ - public String getDisplayVariant(Locale inLocale) - { - if (variant.isEmpty()) - return ""; - try - { - ResourceBundle res = - ResourceBundle.getBundle("gnu.java.locale.LocaleInformation", - inLocale, - ClassLoader.getSystemClassLoader()); - - return res.getString("variants." + variant); - } - catch (MissingResourceException e) - { - /* This means runtime support for the locale - * is not available, so we check providers. */ - } - for (LocaleNameProvider p : - ServiceLoader.load(LocaleNameProvider.class)) - { - for (Locale loc : p.getAvailableLocales()) - { - if (loc.equals(inLocale)) - { - String locVar = p.getDisplayVariant(variant, - inLocale); - if (locVar != null) - return locVar; - break; - } - } - } - if (inLocale.equals(Locale.ROOT)) // Base case - return country; - return getDisplayVariant(LocaleHelper.getFallbackLocale(inLocale)); - } - - /** - * Gets all local components suitable for display to the user, formatted - * for the default locale. For the language component, getDisplayLanguage - * is called. For the country component, getDisplayCountry is called. - * For the variant set component, getDisplayVariant is called. - * - * <p>The returned String will be one of the following forms:<br> - * <pre> - * language (country, variant) - * language (country) - * language (variant) - * country (variant) - * language - * country - * variant - * </pre> - * - * @return String version of this locale, suitable for display to the user - */ - public String getDisplayName() - { - return getDisplayName(defaultLocale); - } - - /** - * Gets all local components suitable for display to the user, formatted - * for a specified locale. For the language component, - * getDisplayLanguage(Locale) is called. For the country component, - * getDisplayCountry(Locale) is called. For the variant set component, - * getDisplayVariant(Locale) is called. - * - * <p>The returned String will be one of the following forms:<br> - * <pre> - * language (country, variant) - * language (country) - * language (variant) - * country (variant) - * language - * country - * variant - * </pre> - * - * @param locale locale to use for formatting - * @return String version of this locale, suitable for display to the user - */ - public String getDisplayName(Locale locale) - { - CPStringBuilder result = new CPStringBuilder(); - int count = 0; - String[] delimiters = {"", " (", ","}; - if (language.length() != 0) - { - result.append(delimiters[count++]); - result.append(getDisplayLanguage(locale)); - } - if (country.length() != 0) - { - result.append(delimiters[count++]); - result.append(getDisplayCountry(locale)); - } - if (variant.length() != 0) - { - result.append(delimiters[count++]); - result.append(getDisplayVariant(locale)); - } - if (count > 1) - result.append(")"); - return result.toString(); - } - - /** - * Does the same as <code>Object.clone()</code> but does not throw - * a <code>CloneNotSupportedException</code>. Why anyone would - * use this method is a secret to me, since this class is immutable. - * - * @return the clone - */ - public Object clone() - { - // This class is final, so no need to use native super.clone(). - return new Locale(language, country, variant); - } - - /** - * Return the hash code for this locale. The hashcode is the logical - * xor of the hash codes of the language, the country and the variant. - * The hash code is precomputed, since <code>Locale</code>s are often - * used in hash tables. - * - * @return the hashcode - */ - public int hashCode() - { - return hashcode; - } - - /** - * Compares two locales. To be equal, obj must be a Locale with the same - * language, country, and variant code. - * - * @param obj the other locale - * @return true if obj is equal to this - */ - public boolean equals(Object obj) - { - if (this == obj) - return true; - if (! (obj instanceof Locale)) - return false; - Locale l = (Locale) obj; - - return (language == l.language - && country == l.country - && variant == l.variant); - } - - /** - * Write the locale to an object stream. - * - * @param s the stream to write to - * @throws IOException if the write fails - * @serialData The first three fields are Strings representing language, - * country, and variant. The fourth field is a placeholder for - * the cached hashcode, but this is always written as -1, and - * recomputed when reading it back. - */ - private void writeObject(ObjectOutputStream s) - throws IOException - { - ObjectOutputStream.PutField fields = s.putFields(); - fields.put("hashcode", -1); - s.defaultWriteObject(); - } - - /** - * Reads a locale from the input stream. - * - * @param s the stream to read from - * @throws IOException if reading fails - * @throws ClassNotFoundException if reading fails - * @serialData the hashCode is always invalid and must be recomputed - */ - private void readObject(ObjectInputStream s) - throws IOException, ClassNotFoundException - { - s.defaultReadObject(); - hashcode = language.hashCode() ^ country.hashCode() ^ variant.hashCode(); - } -} // class Locale diff --git a/libjava/classpath/java/util/Map.java b/libjava/classpath/java/util/Map.java deleted file mode 100644 index 1bcb1b2..0000000 --- a/libjava/classpath/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<K, V> -{ - /** - * 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<Map.Entry<K, V>> 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) - */ - V 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) - */ - V put(K key, V 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<K> 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<? extends K, ? extends V> 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. - */ - V remove(Object o); - - /** - * 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<V> 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<K, V> - { - /** - * Get the key corresponding to this entry. - * - * @return the key - */ - K getKey(); - - /** - * Get the value corresponding to this entry. If you already called - * Iterator.remove(), this is undefined. - * - * @return the value - */ - V 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 - */ - V setValue(V 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 ? ((Map.Entry) o).getKey() == null - : getKey().equals(((Map.Entry) o).getKey())) -&& (getValue() == null ? ((Map.Entry) o).getValue() == null - : getValue().equals(((Map.Entry) 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/classpath/java/util/MissingFormatArgumentException.java b/libjava/classpath/java/util/MissingFormatArgumentException.java deleted file mode 100644 index e53de0a..0000000 --- a/libjava/classpath/java/util/MissingFormatArgumentException.java +++ /dev/null @@ -1,90 +0,0 @@ -/* MissingFormatArgumentException.java - Copyright (C) 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; - -/** - * Thrown when the a format specification for a {@link Formatter} - * refers to an argument that is non-existent, or an argument index - * references a non-existent argument. - * - * @author Tom Tromey (tromey@redhat.com) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.5 - */ -public class MissingFormatArgumentException - extends IllegalFormatException -{ - private static final long serialVersionUID = 19190115L; - - /** - * The format specification which contains the - * unmatched argument. - * - * @serial the format specification. - */ - // Note: name fixed by serialization. - private String s; - - /** - * Constructs a new <code>MissingFormatArgumentException</code> - * for a format specification, <code>s</code>, which refers - * to a non-existent argument. - * - * @param s the format specification. - * @throws NullPointerException if <code>s</code> is null. - */ - public MissingFormatArgumentException(String s) - { - super("The specification, " + s + - ", refers to a non-existent argument."); - if (s == null) - throw new NullPointerException("The specification is null."); - this.s = s; - } - - /** - * Returns the format specification. - * - * @return the format specification. - */ - public String getFormatSpecifier() - { - return s; - } -} diff --git a/libjava/classpath/java/util/MissingFormatWidthException.java b/libjava/classpath/java/util/MissingFormatWidthException.java deleted file mode 100644 index e083172..0000000 --- a/libjava/classpath/java/util/MissingFormatWidthException.java +++ /dev/null @@ -1,88 +0,0 @@ -/* MissingFormatWidthException.java - Copyright (C) 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; - -/** - * Thrown when the a format specification for a {@link Formatter} - * does not include a width for a value where one is required. - * - * @author Tom Tromey (tromey@redhat.com) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.5 - */ -public class MissingFormatWidthException - extends IllegalFormatException -{ - private static final long serialVersionUID = 15560123L; - - /** - * The format specification which contains the - * unmatched argument. - * - * @serial the format specification. - */ - // Note: name fixed by serialization. - private String s; - - /** - * Constructs a new <code>MissingFormatWidthException</code> - * for a format specification, <code>s</code>, which excludes - * a required width argument. - * - * @param s the format specification. - * @throws NullPointerException if <code>s</code> is null. - */ - public MissingFormatWidthException(String s) - { - super("The specification, " + s + ", misses a required width."); - if (s == null) - throw new NullPointerException("The specification is null."); - this.s = s; - } - - /** - * Returns the format specification. - * - * @return the format specification. - */ - public String getFormatSpecifier() - { - return s; - } -} diff --git a/libjava/classpath/java/util/MissingResourceException.java b/libjava/classpath/java/util/MissingResourceException.java deleted file mode 100644 index 26640de..0000000 --- a/libjava/classpath/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/classpath/java/util/NoSuchElementException.java b/libjava/classpath/java/util/NoSuchElementException.java deleted file mode 100644 index 5e1a217..0000000 --- a/libjava/classpath/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/classpath/java/util/Observable.java b/libjava/classpath/java/util/Observable.java deleted file mode 100644 index 916abe4..0000000 --- a/libjava/classpath/java/util/Observable.java +++ /dev/null @@ -1,182 +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) - { - if (observer == null) - throw new NullPointerException("can't add null 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/classpath/java/util/Observer.java b/libjava/classpath/java/util/Observer.java deleted file mode 100644 index c59a0ca..0000000 --- a/libjava/classpath/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/classpath/java/util/PriorityQueue.java b/libjava/classpath/java/util/PriorityQueue.java deleted file mode 100644 index 5b6a368..0000000 --- a/libjava/classpath/java/util/PriorityQueue.java +++ /dev/null @@ -1,336 +0,0 @@ -/* PriorityQueue.java -- Unbounded priority queue - Copyright (C) 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; - -/** - * @author Tom Tromey (tromey@redhat.com) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.5 - */ -public class PriorityQueue<E> extends AbstractQueue<E> implements Serializable -{ - private static final int DEFAULT_CAPACITY = 11; - - private static final long serialVersionUID = -7720805057305804111L; - - /** Number of elements actually used in the storage array. */ - int used; - - /** - * This is the storage for the underlying binomial heap. - * The idea is, each node is less than or equal to its children. - * A node at index N (0-based) has two direct children, at - * nodes 2N+1 and 2N+2. - */ - E[] storage; - - /** - * The comparator we're using, or null for natural ordering. - */ - Comparator<? super E> comparator; - - public PriorityQueue() - { - this(DEFAULT_CAPACITY, null); - } - - public PriorityQueue(Collection<? extends E> c) - { - this(Math.max(1, (int) (1.1 * c.size())), null); - - // Special case where we can find the comparator to use. - if (c instanceof SortedSet) - { - SortedSet<? extends E> ss = (SortedSet<? extends E>) c; - this.comparator = (Comparator<? super E>) ss.comparator(); - // We can insert the elements directly, since they are sorted. - int i = 0; - for (E val : ss) - { - if (val == null) - throw new NullPointerException(); - storage[i++] = val; - } - } - else if (c instanceof PriorityQueue) - { - PriorityQueue<? extends E> pq = (PriorityQueue<? extends E>) c; - this.comparator = (Comparator<? super E>)pq.comparator(); - // We can just copy the contents. - System.arraycopy(pq.storage, 0, storage, 0, pq.storage.length); - } - - addAll(c); - } - - public PriorityQueue(int cap) - { - this(cap, null); - } - - public PriorityQueue(int cap, Comparator<? super E> comp) - { - if (cap < 1) - throw new IllegalArgumentException(); - this.used = 0; - this.storage = (E[]) new Object[cap]; - this.comparator = comp; - } - - public PriorityQueue(PriorityQueue<? extends E> c) - { - this(Math.max(1, (int) (1.1 * c.size())), - (Comparator<? super E>)c.comparator()); - // We can just copy the contents. - System.arraycopy(c.storage, 0, storage, 0, c.storage.length); - } - - public PriorityQueue(SortedSet<? extends E> c) - { - this(Math.max(1, (int) (1.1 * c.size())), - (Comparator<? super E>)c.comparator()); - // We can insert the elements directly, since they are sorted. - int i = 0; - for (E val : c) - { - if (val == null) - throw new NullPointerException(); - storage[i++] = val; - } - } - - public void clear() - { - Arrays.fill(storage, null); - used = 0; - } - - public Comparator<? super E> comparator() - { - return comparator; - } - - public Iterator<E> iterator() - { - return new Iterator<E>() - { - int index = -1; - int count = 0; - - public boolean hasNext() - { - return count < used; - } - - public E next() - { - while (storage[++index] == null) - ; - - ++count; - return storage[index]; - } - - public void remove() - { - PriorityQueue.this.remove(index); - index--; - } - }; - } - - public boolean offer(E o) - { - if (o == null) - throw new NullPointerException(); - - int slot = findSlot(-1); - - storage[slot] = o; - ++used; - bubbleUp(slot); - - return true; - } - - public E peek() - { - return used == 0 ? null : storage[0]; - } - - public E poll() - { - if (used == 0) - return null; - E result = storage[0]; - remove(0); - return result; - } - - public boolean remove(Object o) - { - if (o != null) - { - for (int i = 0; i < storage.length; ++i) - { - if (o.equals(storage[i])) - { - remove(i); - return true; - } - } - } - return false; - } - - public int size() - { - return used; - } - - // It is more efficient to implement this locally -- less searching - // for free slots. - public boolean addAll(Collection<? extends E> c) - { - if (c == this) - throw new IllegalArgumentException(); - - int newSlot = -1; - int save = used; - for (E val : c) - { - if (val == null) - throw new NullPointerException(); - newSlot = findSlot(newSlot); - storage[newSlot] = val; - ++used; - bubbleUp(newSlot); - } - - return save != used; - } - - int findSlot(int start) - { - int slot; - if (used == storage.length) - { - resize(); - slot = used; - } - else - { - for (slot = start + 1; slot < storage.length; ++slot) - { - if (storage[slot] == null) - break; - } - // We'll always find a slot. - } - return slot; - } - - void remove(int index) - { - // Remove the element at INDEX. We do this by finding the least - // child and moving it into place, then iterating until we reach - // the bottom of the tree. - while (storage[index] != null) - { - int child = 2 * index + 1; - - // See if we went off the end. - if (child >= storage.length) - { - storage[index] = null; - break; - } - - // Find which child we want to promote. If one is not null, - // we pick it. If both are null, it doesn't matter, we're - // about to leave. If neither is null, pick the lesser. - if (child + 1 >= storage.length || storage[child + 1] == null) - { - // Nothing. - } - else if (storage[child] == null - || (Collections.compare(storage[child], storage[child + 1], - comparator) > 0)) - ++child; - storage[index] = storage[child]; - index = child; - } - --used; - } - - void bubbleUp(int index) - { - // The element at INDEX was inserted into a blank spot. Now move - // it up the tree to its natural resting place. - while (index > 0) - { - // This works regardless of whether we're at 2N+1 or 2N+2. - int parent = (index - 1) / 2; - if (Collections.compare(storage[parent], storage[index], comparator) - <= 0) - { - // Parent is the same or smaller than this element, so the - // invariant is preserved. Note that if the new element - // is smaller than the parent, then it is necessarily - // smaller than the parent's other child. - break; - } - - E temp = storage[index]; - storage[index] = storage[parent]; - storage[parent] = temp; - - index = parent; - } - } - - void resize() - { - E[] new_data = (E[]) new Object[2 * storage.length]; - System.arraycopy(storage, 0, new_data, 0, storage.length); - storage = new_data; - } -} diff --git a/libjava/classpath/java/util/Properties.java b/libjava/classpath/java/util/Properties.java deleted file mode 100644 index b0f436f..0000000 --- a/libjava/classpath/java/util/Properties.java +++ /dev/null @@ -1,822 +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 gnu.java.lang.CPStringBuilder; - -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; -import java.io.Reader; - -import javax.xml.stream.XMLInputFactory; -import javax.xml.stream.XMLStreamConstants; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamReader; - -import org.w3c.dom.Document; -import org.w3c.dom.DocumentType; -import org.w3c.dom.DOMImplementation; -import org.w3c.dom.Element; -import org.w3c.dom.bootstrap.DOMImplementationRegistry; -import org.w3c.dom.ls.DOMImplementationLS; -import org.w3c.dom.ls.LSOutput; -import org.w3c.dom.ls.LSSerializer; - -/** - * 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<Object, Object> -{ - // 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 a character 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 inReader the input {@link java.io.Reader}. - * @throws IOException if an error occurred when reading the input - * @throws NullPointerException if in is null - * @since 1.6 - */ - public void load(Reader inReader) throws IOException - { - BufferedReader reader = new BufferedReader(inReader); - 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. - // Try to short-circuit when there is no escape char. - int start = pos; - boolean needsEscape = line.indexOf('\\', pos) != -1; - CPStringBuilder key = needsEscape ? new CPStringBuilder() : null; - while (pos < line.length() - && ! Character.isWhitespace(c = line.charAt(pos++)) - && c != '=' && c != ':') - { - if (needsEscape && c == '\\') - { - if (pos == line.length()) - { - // The line continues on the next line. If there - // is no next line, just treat it as a key with an - // empty value. - line = reader.readLine(); - if (line == null) - line = ""; - 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 if (needsEscape) - key.append(c); - } - - boolean isDelim = (c == ':' || c == '='); - - String keyString; - if (needsEscape) - keyString = key.toString(); - else if (isDelim || Character.isWhitespace(c)) - keyString = line.substring(start, pos - 1); - else - keyString = line.substring(start, pos); - - 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++; - } - - // Short-circuit if no escape chars found. - if (!needsEscape) - { - put(keyString, line.substring(pos)); - continue; - } - - // Escape char found so iterate through the rest of the line. - StringBuilder element = new StringBuilder(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(keyString, element.toString()); - } - } - - /** - * Reads a property list from the supplied input stream. - * This method has the same functionality as {@link #load(Reader)} - * but the character encoding is assumed to be ISO-8859-1. - * Unicode characters not within the Latin1 set supplied by - * ISO-8859-1 should be escaped using '\\uXXXX' where XXXX - * is the UTF-16 code unit in hexadecimal. - * - * @param inStream the byte stream to read the property list from. - * @throws IOException if an I/O error occurs. - * @see #load(Reader) - * @since 1.2 - */ - public void load(InputStream inStream) throws IOException - { - load(new InputStreamReader(inStream, "ISO-8859-1")); - } - - /** - * 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 - */ - @Deprecated - 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 (); - CPStringBuilder s = new CPStringBuilder (); // 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) - { - 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 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) - { - String prop = getProperty(key); - if (prop == null) - prop = defaultValue; - return prop; - } - - /** - * 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, CPStringBuilder 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; - } - } - - /** - * <p> - * Encodes the properties as an XML file using the UTF-8 encoding. - * The format of the XML file matches the DTD - * <a href="http://java.sun.com/dtd/properties.dtd"> - * http://java.sun.com/dtd/properties.dtd</a>. - * </p> - * <p> - * Invoking this method provides the same behaviour as invoking - * <code>storeToXML(os, comment, "UTF-8")</code>. - * </p> - * - * @param os the stream to output to. - * @param comment a comment to include at the top of the XML file, or - * <code>null</code> if one is not required. - * @throws IOException if the serialization fails. - * @throws NullPointerException if <code>os</code> is null. - * @since 1.5 - */ - public void storeToXML(OutputStream os, String comment) - throws IOException - { - storeToXML(os, comment, "UTF-8"); - } - - /** - * <p> - * Encodes the properties as an XML file using the supplied encoding. - * The format of the XML file matches the DTD - * <a href="http://java.sun.com/dtd/properties.dtd"> - * http://java.sun.com/dtd/properties.dtd</a>. - * </p> - * - * @param os the stream to output to. - * @param comment a comment to include at the top of the XML file, or - * <code>null</code> if one is not required. - * @param encoding the encoding to use for the XML output. - * @throws IOException if the serialization fails. - * @throws NullPointerException if <code>os</code> or <code>encoding</code> - * is null. - * @since 1.5 - */ - public void storeToXML(OutputStream os, String comment, String encoding) - throws IOException - { - if (os == null) - throw new NullPointerException("Null output stream supplied."); - if (encoding == null) - throw new NullPointerException("Null encoding supplied."); - try - { - DOMImplementationRegistry registry = - DOMImplementationRegistry.newInstance(); - DOMImplementation domImpl = registry.getDOMImplementation("LS 3.0"); - DocumentType doctype = - domImpl.createDocumentType("properties", null, - "http://java.sun.com/dtd/properties.dtd"); - Document doc = domImpl.createDocument(null, "properties", doctype); - Element root = doc.getDocumentElement(); - if (comment != null) - { - Element commentElement = doc.createElement("comment"); - commentElement.appendChild(doc.createTextNode(comment)); - root.appendChild(commentElement); - } - Iterator iterator = entrySet().iterator(); - while (iterator.hasNext()) - { - Map.Entry entry = (Map.Entry) iterator.next(); - Element entryElement = doc.createElement("entry"); - entryElement.setAttribute("key", (String) entry.getKey()); - entryElement.appendChild(doc.createTextNode((String) - entry.getValue())); - root.appendChild(entryElement); - } - DOMImplementationLS loadAndSave = (DOMImplementationLS) domImpl; - LSSerializer serializer = loadAndSave.createLSSerializer(); - LSOutput output = loadAndSave.createLSOutput(); - output.setByteStream(os); - output.setEncoding(encoding); - serializer.write(doc, output); - } - catch (ClassNotFoundException e) - { - throw (IOException) - new IOException("The XML classes could not be found.").initCause(e); - } - catch (InstantiationException e) - { - throw (IOException) - new IOException("The XML classes could not be instantiated.") - .initCause(e); - } - catch (IllegalAccessException e) - { - throw (IOException) - new IOException("The XML classes could not be accessed.") - .initCause(e); - } - } - - /** - * <p> - * Decodes the contents of the supplied <code>InputStream</code> as - * an XML file, which represents a set of properties. The format of - * the XML file must match the DTD - * <a href="http://java.sun.com/dtd/properties.dtd"> - * http://java.sun.com/dtd/properties.dtd</a>. - * </p> - * - * @param in the input stream from which to receive the XML data. - * @throws IOException if an I/O error occurs in reading the input data. - * @throws InvalidPropertiesFormatException if the input data does not - * constitute an XML properties - * file. - * @throws NullPointerException if <code>in</code> is null. - * @since 1.5 - */ - public void loadFromXML(InputStream in) - throws IOException, InvalidPropertiesFormatException - { - if (in == null) - throw new NullPointerException("Null input stream supplied."); - try - { - XMLInputFactory factory = XMLInputFactory.newInstance(); - // Don't resolve external entity references - factory.setProperty("javax.xml.stream.isSupportingExternalEntities", - Boolean.FALSE); - XMLStreamReader reader = factory.createXMLStreamReader(in); - String name, key = null; - CPStringBuilder buf = null; - while (reader.hasNext()) - { - switch (reader.next()) - { - case XMLStreamConstants.START_ELEMENT: - name = reader.getLocalName(); - if (buf == null && "entry".equals(name)) - { - key = reader.getAttributeValue(null, "key"); - if (key == null) - { - String msg = "missing 'key' attribute"; - throw new InvalidPropertiesFormatException(msg); - } - buf = new CPStringBuilder(); - } - else if (!"properties".equals(name) && !"comment".equals(name)) - { - String msg = "unexpected element name '" + name + "'"; - throw new InvalidPropertiesFormatException(msg); - } - break; - case XMLStreamConstants.END_ELEMENT: - name = reader.getLocalName(); - if (buf != null && "entry".equals(name)) - { - put(key, buf.toString()); - buf = null; - } - else if (!"properties".equals(name) && !"comment".equals(name)) - { - String msg = "unexpected element name '" + name + "'"; - throw new InvalidPropertiesFormatException(msg); - } - break; - case XMLStreamConstants.CHARACTERS: - case XMLStreamConstants.SPACE: - case XMLStreamConstants.CDATA: - if (buf != null) - buf.append(reader.getText()); - break; - } - } - reader.close(); - } - catch (XMLStreamException e) - { - throw (InvalidPropertiesFormatException) - new InvalidPropertiesFormatException("Error in parsing XML."). - initCause(e); - } - } - -} // class Properties diff --git a/libjava/classpath/java/util/PropertyPermission.java b/libjava/classpath/java/util/PropertyPermission.java deleted file mode 100644 index 6ed4690..0000000 --- a/libjava/classpath/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/classpath/java/util/PropertyPermissionCollection.java b/libjava/classpath/java/util/PropertyPermissionCollection.java deleted file mode 100644 index 768b112..0000000 --- a/libjava/classpath/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/classpath/java/util/PropertyResourceBundle.java b/libjava/classpath/java/util/PropertyResourceBundle.java deleted file mode 100644 index b528f08..0000000 --- a/libjava/classpath/java/util/PropertyResourceBundle.java +++ /dev/null @@ -1,171 +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; -import java.io.Reader; - -/** - * 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(InputStream) - * @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. The property file must - * be encoded using ISO-8859-1. - * - * @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); - } - - /** - * Creates a new property resource bundle. The encoding of the property - * file is determined by the supplied {@link Reader} object. - * - * @param reader an input stream, where the resources are read from - * @throws NullPointerException if stream is null - * @throws IOException if reading the stream fails - * @since 1.6 - */ - public PropertyResourceBundle(Reader reader) throws IOException - { - properties = new Properties(); - properties.load(reader); - } - - /** - * 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<String> getKeys() - { - if (parent == null) - // FIXME: bogus cast. - return (Enumeration<String>) 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<String> s = new HashSet<String>(); - // FIXME: bogus cast. - Enumeration<String> e = (Enumeration<String>) 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/classpath/java/util/Random.java b/libjava/classpath/java/util/Random.java deleted file mode 100644 index 999e895..0000000 --- a/libjava/classpath/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(int) - */ - 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/classpath/java/util/RandomAccess.java b/libjava/classpath/java/util/RandomAccess.java deleted file mode 100644 index 054266a..0000000 --- a/libjava/classpath/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/classpath/java/util/ResourceBundle.java b/libjava/classpath/java/util/ResourceBundle.java deleted file mode 100644 index 966eb02..0000000 --- a/libjava/classpath/java/util/ResourceBundle.java +++ /dev/null @@ -1,625 +0,0 @@ -/* ResourceBundle -- aids in loading resource bundles - Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006 - 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 gnu.classpath.VMStackWalker; - -import gnu.java.lang.CPStringBuilder; - -import java.io.IOException; -import java.io.InputStream; - -/** - * A resource bundle contains locale-specific data. If you need localized - * data, you can load a resource bundle that matches the locale with - * <code>getBundle</code>. Now you can get your object by calling - * <code>getObject</code> or <code>getString</code> on that bundle. - * - * <p>When a bundle is demanded for a specific locale, the ResourceBundle - * is searched in following order (<i>def. language</i> stands for the - * two letter ISO language code of the default locale (see - * <code>Locale.getDefault()</code>). - * -<pre>baseName_<i>language code</i>_<i>country code</i>_<i>variant</i> -baseName_<i>language code</i>_<i>country code</i> -baseName_<i>language code</i> -baseName_<i>def. language</i>_<i>def. country</i>_<i>def. variant</i> -baseName_<i>def. language</i>_<i>def. country</i> -baseName_<i>def. language</i> -baseName</pre> - * - * <p>A bundle is backed up by less specific bundles (omitting variant, country - * or language). But it is not backed up by the default language locale. - * - * <p>If you provide a bundle for a given locale, say - * <code>Bundle_en_UK_POSIX</code>, you must also provide a bundle for - * all sub locales, ie. <code>Bundle_en_UK</code>, <code>Bundle_en</code>, and - * <code>Bundle</code>. - * - * <p>When a bundle is searched, we look first for a class with the given - * name, then for a file with <code>.properties</code> extension in the - * classpath. The name must be a fully qualified classname (with dots as - * path separators). - * - * <p>(Note: This implementation always backs up the class with a properties - * file if that is existing, but you shouldn't rely on this, if you want to - * be compatible to the standard JDK.) - * - * @author Jochen Hoenicke - * @author Eric Blake (ebb9@email.byu.edu) - * @see Locale - * @see ListResourceBundle - * @see PropertyResourceBundle - * @since 1.1 - * @status updated to 1.4 - */ -public abstract class ResourceBundle -{ - /** - * Maximum size of our cache of <code>ResourceBundle</code>s keyed by - * {@link BundleKey} instances. - * - * @see BundleKey - */ - private static final int CACHE_SIZE = 100; - - /** - * The parent bundle. This is consulted when you call getObject and there - * is no such resource in the current bundle. This field may be null. - */ - protected ResourceBundle parent; - - /** - * The locale of this resource bundle. You can read this with - * <code>getLocale</code> and it is automatically set in - * <code>getBundle</code>. - */ - private Locale locale; - - /** - * A VM-wide cache of resource bundles already fetched. - * <p> - * This {@link Map} is a Least Recently Used (LRU) cache, of the last - * {@link #CACHE_SIZE} accessed <code>ResourceBundle</code>s keyed by the - * tuple: default locale, resource-bundle name, resource-bundle locale, and - * classloader. - * - * @see BundleKey - */ - private static Map<BundleKey,Object> bundleCache = - new LinkedHashMap<BundleKey,Object>(CACHE_SIZE + 1, 0.75F, true) - { - public boolean removeEldestEntry(Map.Entry<BundleKey,Object> entry) - { - return size() > CACHE_SIZE; - } - }; - - /** - * The constructor. It does nothing special. - */ - public ResourceBundle() - { - } - - /** - * Get a String from this resource bundle. Since most localized Objects - * are Strings, this method provides a convenient way to get them without - * casting. - * - * @param key the name of the resource - * @throws MissingResourceException if the resource can't be found - * @throws NullPointerException if key is null - * @throws ClassCastException if resource is not a string - */ - public final String getString(String key) - { - return (String) getObject(key); - } - - /** - * Get an array of Strings from this resource bundle. This method - * provides a convenient way to get it without casting. - * - * @param key the name of the resource - * @throws MissingResourceException if the resource can't be found - * @throws NullPointerException if key is null - * @throws ClassCastException if resource is not a string - */ - public final String[] getStringArray(String key) - { - return (String[]) getObject(key); - } - - /** - * Get an object from this resource bundle. This will call - * <code>handleGetObject</code> for this resource and all of its parents, - * until it finds a non-null resource. - * - * @param key the name of the resource - * @throws MissingResourceException if the resource can't be found - * @throws NullPointerException if key is null - */ - public final Object getObject(String key) - { - for (ResourceBundle bundle = this; bundle != null; bundle = bundle.parent) - { - Object o = bundle.handleGetObject(key); - if (o != null) - return o; - } - - String className = getClass().getName(); - throw new MissingResourceException("Key '" + key - + "'not found in Bundle: " - + className, className, key); - } - - /** - * Return the actual locale of this bundle. You can use it after calling - * getBundle, to know if the bundle for the desired locale was loaded or - * if the fall back was used. - * - * @return the bundle's locale - */ - public Locale getLocale() - { - return locale; - } - - /** - * Set the parent of this bundle. The parent is consulted when you call - * getObject and there is no such resource in the current bundle. - * - * @param parent the parent of this bundle - */ - protected void setParent(ResourceBundle parent) - { - this.parent = parent; - } - - /** - * Get the appropriate ResourceBundle for the default locale. This is like - * calling <code>getBundle(baseName, Locale.getDefault(), - * getClass().getClassLoader()</code>, except that any security check of - * getClassLoader won't fail. - * - * @param baseName the name of the ResourceBundle - * @return the desired resource bundle - * @throws MissingResourceException if the resource bundle can't be found - * @throws NullPointerException if baseName is null - */ - public static ResourceBundle getBundle(String baseName) - { - ClassLoader cl = VMStackWalker.getCallingClassLoader(); - if (cl == null) - cl = ClassLoader.getSystemClassLoader(); - return getBundle(baseName, Locale.getDefault(), cl); - } - - /** - * Get the appropriate ResourceBundle for the given locale. This is like - * calling <code>getBundle(baseName, locale, - * getClass().getClassLoader()</code>, except that any security check of - * getClassLoader won't fail. - * - * @param baseName the name of the ResourceBundle - * @param locale A locale - * @return the desired resource bundle - * @throws MissingResourceException if the resource bundle can't be found - * @throws NullPointerException if baseName or locale is null - */ - public static ResourceBundle getBundle(String baseName, Locale locale) - { - ClassLoader cl = VMStackWalker.getCallingClassLoader(); - if (cl == null) - cl = ClassLoader.getSystemClassLoader(); - return getBundle(baseName, locale, cl); - } - - /** Cache key for the ResourceBundle cache. Resource bundles are keyed - by the combination of bundle name, locale, and class loader. */ - private static class BundleKey - { - Locale defaultLocale; - String baseName; - Locale locale; - ClassLoader classLoader; - int hashcode; - - BundleKey() {} - - BundleKey(Locale dl, String s, Locale l, ClassLoader cl) - { - set(dl, s, l, cl); - } - - void set(Locale dl, String s, Locale l, ClassLoader cl) - { - defaultLocale = dl; - baseName = s; - locale = l; - classLoader = cl; - hashcode = defaultLocale.hashCode() ^ baseName.hashCode() - ^ locale.hashCode() ^ classLoader.hashCode(); - } - - public int hashCode() - { - return hashcode; - } - - public boolean equals(Object o) - { - if (! (o instanceof BundleKey)) - return false; - BundleKey key = (BundleKey) o; - return hashcode == key.hashcode - && defaultLocale.equals(key.defaultLocale) - && baseName.equals(key.baseName) - && locale.equals(key.locale) - && classLoader.equals(key.classLoader); - } - - public String toString() - { - CPStringBuilder builder = new CPStringBuilder(getClass().getName()); - builder.append("[defaultLocale="); - builder.append(defaultLocale); - builder.append(",baseName="); - builder.append(baseName); - builder.append(",locale="); - builder.append(locale); - builder.append(",classLoader="); - builder.append(classLoader); - builder.append("]"); - return builder.toString(); - } - } - - /** A cache lookup key. This avoids having to a new one for every - * getBundle() call. */ - private static final BundleKey lookupKey = new BundleKey(); - - /** Singleton cache entry to represent previous failed lookups. */ - private static final Object nullEntry = new Object(); - - /** - * Get the appropriate ResourceBundle for the given locale. The following - * strategy is used: - * - * <p>A sequence of candidate bundle names are generated, and tested in - * this order, where the suffix 1 means the string from the specified - * locale, and the suffix 2 means the string from the default locale:</p> - * - * <ul> - * <li>baseName + "_" + language1 + "_" + country1 + "_" + variant1</li> - * <li>baseName + "_" + language1 + "_" + country1</li> - * <li>baseName + "_" + language1</li> - * <li>baseName + "_" + language2 + "_" + country2 + "_" + variant2</li> - * <li>baseName + "_" + language2 + "_" + country2</li> - * <li>baseName + "_" + language2</li> - * <li>baseName</li> - * </ul> - * - * <p>In the sequence, entries with an empty string are ignored. Next, - * <code>getBundle</code> tries to instantiate the resource bundle:</p> - * - * <ul> - * <li>First, an attempt is made to load a class in the specified classloader - * which is a subclass of ResourceBundle, and which has a public constructor - * with no arguments, via reflection.</li> - * <li>Next, a search is made for a property resource file, by replacing - * '.' with '/' and appending ".properties", and using - * ClassLoader.getResource(). If a file is found, then a - * PropertyResourceBundle is created from the file's contents.</li> - * </ul> - * If no resource bundle was found, a MissingResourceException is thrown. - * - * <p>Next, the parent chain is implemented. The remaining candidate names - * in the above sequence are tested in a similar manner, and if any results - * in a resource bundle, it is assigned as the parent of the first bundle - * using the <code>setParent</code> method (unless the first bundle already - * has a parent).</p> - * - * <p>For example, suppose the following class and property files are - * provided: MyResources.class, MyResources_fr_CH.properties, - * MyResources_fr_CH.class, MyResources_fr.properties, - * MyResources_en.properties, and MyResources_es_ES.class. The contents of - * all files are valid (that is, public non-abstract subclasses of - * ResourceBundle with public nullary constructors for the ".class" files, - * syntactically correct ".properties" files). The default locale is - * Locale("en", "UK").</p> - * - * <p>Calling getBundle with the shown locale argument values instantiates - * resource bundles from the following sources:</p> - * - * <ul> - * <li>Locale("fr", "CH"): result MyResources_fr_CH.class, parent - * MyResources_fr.properties, parent MyResources.class</li> - * <li>Locale("fr", "FR"): result MyResources_fr.properties, parent - * MyResources.class</li> - * <li>Locale("de", "DE"): result MyResources_en.properties, parent - * MyResources.class</li> - * <li>Locale("en", "US"): result MyResources_en.properties, parent - * MyResources.class</li> - * <li>Locale("es", "ES"): result MyResources_es_ES.class, parent - * MyResources.class</li> - * </ul> - * - * <p>The file MyResources_fr_CH.properties is never used because it is hidden - * by MyResources_fr_CH.class.</p> - * - * @param baseName the name of the ResourceBundle - * @param locale A locale - * @param classLoader a ClassLoader - * @return the desired resource bundle - * @throws MissingResourceException if the resource bundle can't be found - * @throws NullPointerException if any argument is null - * @since 1.2 - */ - // This method is synchronized so that the cache is properly - // handled. - public static synchronized ResourceBundle getBundle - (String baseName, Locale locale, ClassLoader classLoader) - { - Locale defaultLocale = Locale.getDefault(); - // This will throw NullPointerException if any arguments are null. - lookupKey.set(defaultLocale, baseName, locale, classLoader); - Object obj = bundleCache.get(lookupKey); - if (obj instanceof ResourceBundle) - return (ResourceBundle) obj; - - if (obj == nullEntry) - throw new MissingResourceException("Bundle " + baseName - + " not found for locale " + locale - + " by classloader " + classLoader, - baseName, ""); - // First, look for a bundle for the specified locale. We don't want - // the base bundle this time. - boolean wantBase = locale.equals(defaultLocale); - ResourceBundle bundle = tryBundle(baseName, locale, classLoader, wantBase); - // Try the default locale if neccessary. - if (bundle == null && ! wantBase) - bundle = tryBundle(baseName, defaultLocale, classLoader, true); - - BundleKey key = new BundleKey(defaultLocale, baseName, locale, classLoader); - if (bundle == null) - { - // Cache the fact that this lookup has previously failed. - bundleCache.put(key, nullEntry); - throw new MissingResourceException("Bundle " + baseName - + " not found for locale " + locale - + " by classloader " + classLoader, - baseName, ""); - } - // Cache the result and return it. - bundleCache.put(key, bundle); - return bundle; - } - - /** - * Override this method to provide the resource for a keys. This gets - * called by <code>getObject</code>. If you don't have a resource - * for the given key, you should return null instead throwing a - * MissingResourceException. You don't have to ask the parent, getObject() - * already does this; nor should you throw a MissingResourceException. - * - * @param key the key of the resource - * @return the resource for the key, or null if not in bundle - * @throws NullPointerException if key is null - */ - protected abstract Object handleGetObject(String key); - - /** - * This method should return all keys for which a resource exists; you - * should include the enumeration of any parent's keys, after filtering out - * duplicates. - * - * @return an enumeration of the keys - */ - public abstract Enumeration<String> getKeys(); - - /** - * Tries to load a class or a property file with the specified name. - * - * @param localizedName the name - * @param classloader the classloader - * @return the resource bundle if it was loaded, otherwise the backup - */ - private static ResourceBundle tryBundle(String localizedName, - ClassLoader classloader) - { - ResourceBundle bundle = null; - try - { - Class<?> rbClass; - if (classloader == null) - rbClass = Class.forName(localizedName); - else - rbClass = classloader.loadClass(localizedName); - // Note that we do the check up front instead of catching - // ClassCastException. The reason for this is that some crazy - // programs (Eclipse) have classes that do not extend - // ResourceBundle but that have the same name as a property - // bundle; in fact Eclipse relies on ResourceBundle not - // instantiating these classes. - if (ResourceBundle.class.isAssignableFrom(rbClass)) - bundle = (ResourceBundle) rbClass.newInstance(); - } - catch (Exception ex) {} - - if (bundle == null) - { - try - { - InputStream is; - String resourceName - = localizedName.replace('.', '/') + ".properties"; - if (classloader == null) - is = ClassLoader.getSystemResourceAsStream(resourceName); - else - is = classloader.getResourceAsStream(resourceName); - if (is != null) - bundle = new PropertyResourceBundle(is); - } - catch (IOException ex) - { - MissingResourceException mre = new MissingResourceException - ("Failed to load bundle: " + localizedName, localizedName, ""); - mre.initCause(ex); - throw mre; - } - } - - return bundle; - } - - /** - * Tries to load the bundle for a given locale, also loads the backup - * locales with the same language. - * - * @param baseName the raw bundle name, without locale qualifiers - * @param locale the locale - * @param classLoader the classloader - * @param wantBase whether a resource bundle made only from the base name - * (with no locale information attached) should be returned. - * @return the resource bundle if it was loaded, otherwise the backup - */ - private static ResourceBundle tryBundle(String baseName, Locale locale, - ClassLoader classLoader, - boolean wantBase) - { - String language = locale.getLanguage(); - String country = locale.getCountry(); - String variant = locale.getVariant(); - - int baseLen = baseName.length(); - - // Build up a CPStringBuilder containing the complete bundle name, fully - // qualified by locale. - CPStringBuilder sb = new CPStringBuilder(baseLen + variant.length() + 7); - - sb.append(baseName); - - if (language.length() > 0) - { - sb.append('_'); - sb.append(language); - - if (country.length() > 0) - { - sb.append('_'); - sb.append(country); - - if (variant.length() > 0) - { - sb.append('_'); - sb.append(variant); - } - } - } - - // Now try to load bundles, starting with the most specialized name. - // Build up the parent chain as we go. - String bundleName = sb.toString(); - ResourceBundle first = null; // The most specialized bundle. - ResourceBundle last = null; // The least specialized bundle. - - while (true) - { - ResourceBundle foundBundle = tryBundle(bundleName, classLoader); - if (foundBundle != null) - { - if (first == null) - first = foundBundle; - if (last != null) - last.parent = foundBundle; - foundBundle.locale = locale; - last = foundBundle; - } - int idx = bundleName.lastIndexOf('_'); - // Try the non-localized base name only if we already have a - // localized child bundle, or wantBase is true. - if (idx > baseLen || (idx == baseLen && (first != null || wantBase))) - bundleName = bundleName.substring(0, idx); - else - break; - } - - return first; - } - - /** - * Remove all resources from the cache that were loaded - * using the class loader of the calling class. - * - * @since 1.6 - */ - public static final void clearCache() - { - clearCache(VMStackWalker.getCallingClassLoader()); - } - - /** - * Remove all resources from the cache that were loaded - * using the specified class loader. - * - * @param loader the loader used for the bundles that will be removed. - * @throws NullPointerException if {@code loader} is {@code null}. - * @since 1.6 - */ - public static final void clearCache(ClassLoader loader) - { - if (loader == null) - throw new NullPointerException("The loader can not be null."); - synchronized (ResourceBundle.class) - { - Iterator<BundleKey> iter = bundleCache.keySet().iterator(); - while (iter.hasNext()) - { - BundleKey key = iter.next(); - if (key.classLoader == loader) - iter.remove(); - } - } - } - -} diff --git a/libjava/classpath/java/util/Scanner.java b/libjava/classpath/java/util/Scanner.java deleted file mode 100644 index 59c4cc0..0000000 --- a/libjava/classpath/java/util/Scanner.java +++ /dev/null @@ -1,2223 +0,0 @@ -/* java.util.Scanner -- Parses primitive types and strings using regexps - Copyright (C) 2007 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.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; - -import java.math.BigDecimal; -import java.math.BigInteger; - -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.channels.ReadableByteChannel; - -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; -import java.text.NumberFormat; -import java.text.ParseException; - -import java.util.Iterator; -import java.util.Locale; -import java.util.regex.MatchResult; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * @author E0327023 Hernadi Laszlo -*/ -public class Scanner - implements Iterator <String> -{ - private static final String NOT_LONG = "\" is not a long"; //$NON-NLS-1$ - - private static final String ERR_PREFIX = "\""; //$NON-NLS-1$ - - private static final String NOT_INT = "\" is not an integer"; //$NON-NLS-1$ - - private static final String NOT_DOUBLE = "\" is not a double"; //$NON-NLS-1$ - - private static final String NOT_BYTE = "\" is not a byte"; //$NON-NLS-1$ - - private static final String NOT_BOOLEAN = "\" is not a boolean"; //$NON-NLS-1$ - - private static final String IS_NOT = "\" is not "; //$NON-NLS-1$ - - private static final String DEFAULT_PATTERN_S = "\\p{javaWhitespace}+"; //$NON-NLS-1$ - - private static final Pattern DEFAULT_PATTERN = - Pattern.compile (DEFAULT_PATTERN_S); - - private static final String BIG_INTEGER = "BigInteger"; //$NON-NLS-1$ - - private final static String NEW_LINE = - System.getProperty ("line.separator"); - - private IOException lastIOException = null; - - /** - * An InputStream source if a Constructor with an InputStream source is called, otherwise it - * stays <source> null </source>. - */ - private InputStream bIS = null; - - /** - * Length of the input Buffer, which is the maximum bytes to be read at once. - */ - private final int MaxBufferLen = 1000000; - - /** - * Minimum buffer length. If there are less chars in the Buffer than this value reading from - * source is tried. - */ - private final int MIN_BUF_LEN = 100; - - /** - * Maximum number of processed chars in the Buffer. If exeeded, all processed chars from the - * beginning of the Buffer will be discarded to save space. The bytes left are copyed into a new - * Buffer. - */ - private final int MAX_PREFIX = 10000; - - /** - * The Buffer which is used by the Matcher to find given patterns. It is filled up when matcher - * hits end or <code> MIN_BUF_LEN </code> is reached. - */ - private String actBuffer = new String (); - - /** - * The current radix to use by the methods getNextXXX and hasNextXXX. - */ - private int currentRadix = 10; - - /** - * The current locale. - * - * @see #useLocale(Locale) - * @see #locale() - */ - private Locale actLocale = Locale.getDefault (); - - /** - * The current pattern for the matcher. - */ - private Pattern p = DEFAULT_PATTERN; - - /** - * The current position in the Buffer, at which the next match should start. - */ - private int actPos = 0; - - /** - * A global buffer to save new allocations by reading from source. - */ - private final byte[] tmpBuffer = new byte[this.MaxBufferLen]; - - /** - * The charsetName to use with the source. - */ - private String charsetName = null; - - /** - * The Matcher which is used. - */ - private Matcher myMatcher = this.p.matcher (this.actBuffer); - - /** - * The MatchResult is generated at each match, even if match() isn't called. - */ - private MatchResult actResult = null; - - /** - * A Readable source if a Constructor with a Readable source is called, otherwise it stays - * <source> null </source>. - */ - private Readable readableSource = null; - - /** - * A ReadableByteChannel source if a Constructor with a ReadableByteChannel source is called, - * otherwise it stays <source> null </source>. - */ - private ReadableByteChannel rbcSource = null; - - /** - * Indicates if the close() method was called. - */ - private boolean isClosed = false; - - /** - * For performance reasons the last Found is saved, if a hasNextXXX method was called. - */ - private String lastFound = null; - - private boolean lastFoundPresent = false; - - private int lastNextPos = 0; - - private int lastPatternHash = 0; - - private int last_RegionStart = 0; - - private int last_RegionEnd = 0; - - private boolean last_anchor = false; - - private boolean last_transparent = false; - - private MatchResult lastResult = null; - - /** - * To keep track of the current position in the stream for the toString method, each time - * processed chars are removed the amount is added to processedChars. - */ - private int procesedChars = 0; - - /** - * needInput is set <code> true </code> before a read method, and if there is no input it blocks - * and stays <code>true</code>. Right after a read it is set to <code>false</code>. - */ - private boolean needInput = false; - - private boolean skipped = false; - - /** - * <code> {@link #doSkipp} </code> indicates that the found pattern belongs to the result. If - * <code> {@link #doSkipp} </code> is false the match result ends at the beginning of the match. - * In both cases the current position is set after the pattern, if the found pattern has to be - * removed, a nextXXX method is called. - */ - private boolean doSkipp = false; - - /** - * Indicates if the last match was valid or not. - */ - private boolean matchValid = false; - - private NumberFormat actFormat = NumberFormat.getInstance (this.actLocale); - - private DecimalFormat df = (DecimalFormat) this.actFormat; - - /** - * Indicates if current Locale should be used at the input. - */ - private boolean useLocale = true; - - private DecimalFormatSymbols dfs = - new DecimalFormatSymbols (this.actLocale); - - /** - * Constructs a new Scanner with the given File as source. - * {@link #Scanner(InputStream, String)} is called with <code> null </code> as charsetName. - * - * @param source - * The File to use as source. - * @throws FileNotFoundException - * If the file is not found an Exception is thrown. - */ - public Scanner (final File source) throws FileNotFoundException // TESTED - { - this (source, null); - } - - /** - * Constructs a new Scanner with the given File as source. <br> - * {@link #Scanner(InputStream, String)} is called with the given charsetName. - * - * @param source - * The File to use as source. - * @param charsetName - * Current charset name of the file. If charsetName is null it behaves if it was not - * set. - * @throws FileNotFoundException - * If the file is not found an Exception is thrown. - */ - public Scanner (final File source, - final String charsetName) throws FileNotFoundException - { - this (new FileInputStream (source), charsetName); - } - - /** - * Constructs a new Scanner with the given inputStream. <br> - * {@link #Scanner(InputStream, String)} is called with <code> null </code> as charsetName. - * - * @param source - * The InputStream to use as source. - */ - public Scanner (final InputStream source) // TESTED - { - this (source, null); - } - - /** - * Constructs a new Scanner with the InputSream and a charsetName. Afterwards the Buffer is - * filled. - * - * @param source - * The InputStream to use as source. - * @param charsetName - * The charsetName to apply on the source's data. - */ - public Scanner (final InputStream source, final String charsetName) - { - this.bIS = (new BufferedInputStream (source)); - this.charsetName = charsetName; - myFillBuffer (); - } - - /** - * Constructs a new Scanner with a Readable input as source. - * - * @param source - * The Readable to use as source. - */ - public Scanner (final Readable source) - { - this.readableSource = source; - myFillBuffer (); - } - - /** - * Constructs a new Scanner with a ReadableByteChannel as - * source. Therfore the {@link #Scanner(ReadableByteChannel, - * String)} is called with <code> null </code> as charsetName. - * - * @param source - * The ReadableByteChannel to use as source. - */ - public Scanner (final ReadableByteChannel source) - { - this (source, null); - } - - /** - * Constructs a new Scanner with a ReadableByteChannel as source and - * a given charsetName, which is to be applied on it. <br> It also - * initiates the main Buffer. - * - * @param source - * The ReadableByteChannel to use as source. - * @param charsetName - * The charsetName to be applied on the source. - */ - public Scanner (final ReadableByteChannel source, final String charsetName) - { - this.charsetName = charsetName; - this.rbcSource = source; - myFillBuffer (); - } - - /** - * Constructs a new Scanner using the given String as input only. - * - * @param source - * The whole String to be used as source. - */ - public Scanner (final String source) // TESTED - { - this.actBuffer = new String (source); - this.myMatcher.reset (this.actBuffer); - } - - /** - * Closes this Scanner. If an {@link IOException} occurs it is - * catched and is available under {@link #ioException()}.<br> After - * the Scanner is closed, all searches will lead to a {@link - * IllegalStateException}. - */ - public void close () - { - try - { - if (this.bIS != null) - this.bIS.close (); - if (this.rbcSource != null) - this.rbcSource.close (); - this.isClosed = true; - } - catch (IOException ioe) - { - this.lastIOException = ioe; - } - } - - /** - * Returns the current delimiter. - * - * @return the current delimiter. - */ - public Pattern delimiter () // TESTED - { - return this.p; - } - - /** - * Tries to find the pattern in the current line. - * - * @param pattern The pattern which should be searched in the - * current line of the input. - * @throws NoSuchElementException - * If the pattern was not found. - * @return If the search was successful, the result or otherwise a - * {@link NoSuchElementException} is thrown. - */ - public String findInLine (final Pattern pattern) throws NoSuchElementException // TESTED - { - String tmpStr = myNextLine (false); - return myFindPInStr (pattern, tmpStr, 0); - } - - /** - * Compiles the given pattern into a {@link Pattern} and calls - * {@link #findInLine(Pattern)} with the compiled pattern and - * returns whatever it returns. - * - * @param pattern - * The pattern which should be matched in the input. - * @throws NoSuchElementException - * If the pattern was not found. - * @return The match in the current line. - */ - public String findInLine (final String pattern) // TESTED - { - return findInLine (Pattern.compile (pattern)); - } - - /** - * Trys to match the pattern within the given horizon. - * - * @param pattern - * Pattern to search. - * @param horizon - * @return The result of the match. - * @throws IllegalArgumentException - * if the horizon is negative. - * @throws IllegalStateException - * if the Scanner is closed. - */ - public String findWithinHorizon (final Pattern pattern, final int horizon) - throws IllegalArgumentException, IllegalStateException - { - if (horizon < 0) - { - throw new IllegalArgumentException (horizon + " is negative"); - } - - if (this.isClosed) - { - throw new IllegalStateException ("Scanner is closed"); - } - - // doSkipp is set true to get the matching patern together with the found String - this.doSkipp = true; - String rc = myFindPInStr (pattern, this.actBuffer, horizon); - - if (rc != null) - { - this.actPos += rc.length (); - } - - return rc; - } - - /** - * Compile the pattern and call {@link #findWithinHorizon(Pattern, - * int)}. - * - * @param pattern - * Pattern to search. - * @param horizon - * @return The result of the match. - * @throws IllegalArgumentException - * if the horizon is negative. - * @throws IllegalStateException - * if the Scanner is closed. - */ - public String findWithinHorizon (final String pattern, final int horizon) - throws IllegalArgumentException, IllegalStateException - { - return findWithinHorizon (Pattern.compile (pattern), horizon); - } - - /** - * Checks if there is any next String using the current - * delimiter. Therefore the string must not be <code> null </code> - * and the length must be greater then 0. If a {@link - * NoSuchElementException} is thrown by the search method, it is - * catched and false is returned. - * - * @return <code> true </code> if there is any result using the current delimiter. This wouldn't - * lead to a {@link NoSuchElementException}. - * @throws IllegalStateException - * if the Scanner is closed. - */ - public boolean hasNext () throws IllegalStateException // TESTED - { - String tmpStr = null; - - try - { - tmpStr = myCoreNext (false, this.p); - } - catch (NoSuchElementException nf) - { - } - - if (tmpStr == null || tmpStr.length () <= 0) - { - return false; - } - return true; - } - - /** - * Searches the pattern in the next subString before the next - * current delimiter. - * - * @param pattern - * The pattern to search for. - * @return <code> true </code> if the pattern is found before the current delimiter. - * @throws IllegalStateException - * if the Scanner is closed. - */ - public boolean hasNext (final Pattern pattern) throws IllegalStateException // TESTED - { - String tmpStr; - - tmpStr = myNext (pattern, false); - - if (tmpStr == null || tmpStr.length () <= 0) - { - return false; - } - return true; - } - - /** - * Compiles the pattern to a {@link Pattern} and calls {@link - * #hasNext(Pattern)}. - * - * @see #hasNext(Pattern) - * @param pattern - * The pattern as string to search for. - * @return <code> true </code> if the pattern is found before the current delimiter. - * @throws IllegalStateException - * if the Scanner is closed. - */ - public boolean hasNext (final String pattern) throws IllegalStateException // TESTED - { - return hasNext (Pattern.compile (pattern)); - } - - /** - * Checks if the string to the next delimiter can be interpreted as - * a BigDecimal number. <br> BigDecimal numbers are always tryed - * with radix 10. - * - * @see #nextBigDecimal() - * @return <code> true </code> if the next string is a BigDecimal number. - * @throws IllegalStateException - * if the Scanner is closed. - */ - public boolean hasNextBigDecimal () throws IllegalStateException // TESTED - { - try - { - myBigDecimal (false); - return true; - } - catch (InputMismatchException nfe) - { - return false; - } - } - - /** - * Checks if the string to the next delimiter can be interpreted as - * a BigInteger number. <br> Call {@link #hasNextBigInteger(int)} - * with the current radix. - * - * @see #nextBigInteger() - * @return <code> true </code> if the next string is a BigInteger number. - * @throws IllegalStateException - * if the Scanner is closed. - */ - public boolean hasNextBigInteger () throws IllegalStateException // TESTED - { - return hasNextBigInteger (this.currentRadix); - } - - /** - * Checks if the string to the next delimiter can be interpreted as - * a BigInteger number. <br> - * - * @param radix - * The radix to use for this check. The global radix of the Scanner will not be - * changed. - * @return <code> true </code> if the next string is a BigInteger number. - * @throws IllegalStateException - * if the Scanner is closed. - */ - public boolean hasNextBigInteger (final int radix) throws - IllegalStateException - { - try - { - myNextBigInteger (radix, false, BIG_INTEGER); - return true; - } - catch (InputMismatchException ime) - { - return false; - } - } - - /** - * Checks if the next string could be a boolean. The method handles - * the input not case sensitiv, so "true" and "TRUE" and even "tRuE" - * are <code> true </code>. - * - * @see #nextBoolean() - * @return Return <code> true </code> if the next string is a boolean. - * @throws IllegalStateException - * if the Scanner is closed. - */ - public boolean hasNextBoolean () throws IllegalStateException // TESTED - { - try - { - myNextBoolean (false); - return true; - } - catch (InputMismatchException ime) - { - return false; - } - } - - /** - * Checks if the string to the next delimiter can be interpreted as - * a byte number. <br> Calls {@link #hasNextByte(int)} with the - * current radix. - * - * @see #nextByte() - * @return <code> true </code> if the next string is a byte number. - * @throws IllegalStateException - * if the Scanner is closed. - */ - public boolean hasNextByte () throws IllegalStateException // TESTED - { - return hasNextByte (this.currentRadix); - } - - /** - * Checks if the string to the next delimiter can be interpreted as - * a byte number with the given radix. <br> To check, the private - * method {@link #myNextByte(int, boolean)} is called, and if no - * error occurs the next string could be a byte. - * - * @see #nextByte(int) - * @param radix The radix to use for this check. The global radix of - * the Scanner will not be changed. - * @return <code> true </code> if the next string is a byte number. - * @throws IllegalStateException - * if the Scanner is closed. - */ - public boolean hasNextByte (final int radix) throws IllegalStateException - { - try - { - myNextByte (radix, false); - return true; - } - catch (InputMismatchException ime) - { - return false; - } - } - - /** - * Checks if the string to the next delimiter can be interpreted as - * a double number. <br> To check, the private method {@link - * #myNextDouble(boolean)} is called, and if no error occurs the - * next string could be a double. - * - * @see #nextDouble() - * @return <code> true </code> if the next string is a double number. - * @throws IllegalStateException - * if the Scanner is closed. - */ - public boolean hasNextDouble () throws IllegalStateException // TESTED - { - try - { - myNextDouble (false); - return true; - } - catch (InputMismatchException ime) - { - return false; - } - } - - /** - * Checks if the string to the next delimiter can be interpreted as - * a double number. Because every float is a double this is - * checked.<br> To check, the private method {@link - * #myNextDouble(boolean)} is called, and if no error occurs the - * next string could be a double. - * - * @see #nextFloat() - * @return <code> true </code> if the next string is a double number. - * @throws IllegalStateException - * if the Scanner is closed. - */ - public boolean hasNextFloat () throws IllegalStateException // TESTED - { - try - { - myNextDouble (false); - // myNextFloat(false); - return true; - } - catch (InputMismatchException ime) - { - return false; - } - } - - /** - * Checks if the string to the next delimiter can be interpreted as - * an int number. <br> To check, the private method {@link - * #myNextInt(int, boolean)} is called, and if no error occurs the - * next string could be an int. - * - * @see #nextInt(int) - * @return <code> true </code> if the next string is an int number. - * @throws IllegalStateException - * if the Scanner is closed. - */ - public boolean hasNextInt () throws IllegalStateException // TESTED - { - return hasNextInt (this.currentRadix); - } - - /** - * Checks if the string to the next delimiter can be interpreted as - * an int number with the given radix. <br> To check, the private - * method {@link #myNextInt(int, boolean)} is called, and if no - * error occurs the next string could be an int. - * - * @see #nextInt(int) - * @param radix - * The radix to use for this check. The global radix of the Scanner will not be - * changed. - * @return <code> true </code> if the next string is an int number. - * @throws IllegalStateException - * if the Scanner is closed. - */ - public boolean hasNextInt (final int radix) throws IllegalStateException - { - try - { - myNextInt (radix, false); - return true; - } - catch (InputMismatchException ime) - { - return false; - } - } - - /** - * Checks if there is a current line, which ends at the next line - * break or the end of the input. - * - * @return <code> true </code> if there is a current line. - * @throws IllegalStateException - * if the Scanner is closed. - */ - public boolean hasNextLine () throws IllegalStateException // TESTED - { - return (myNextLine (false) != null); - } - - /** - * Checks if the string to the next delimiter can be interpreted as - * a long number. <br> To check, the private method {@link - * #myNextLong(int, boolean)} is called, and if no error occurs the - * next string could be a long. - * - * @see #nextLong() - * @return <code> true </code> if the next string is a long number. - * @throws IllegalStateException - * if the Scanner is closed. - */ - public boolean hasNextLong () throws IllegalStateException // TESTED - { - return hasNextLong (this.currentRadix); - } - - /** - * Checks if the string to the next delimiter can be interpreted as - * a long number with the given radix. <br> To check, the private - * method {@link #myNextLong(int, boolean)} is called, and if no - * error occurs the next string could be a long. - * - * @see #nextLong(int) - * @param radix - * The radix to use for this check. The global radix of the Scanner will not be - * changed. - * @return <code> true </code> if the next string is a long number. - * @throws IllegalStateException - * if the Scanner is closed. - */ - public boolean hasNextLong (final int radix) throws IllegalStateException - { - try - { - myNextLong (radix, false); - return true; - } - catch (InputMismatchException ime) - { - return false; - } - } - - /** - * Checks if the string to the next delimiter can be interpreted as - * a short number with the given radix. <br> To check, the private - * method {@link #myNextShort(int, boolean)} is called, and if no - * error occurs the next string could be a short. - * - * @see #nextShort(int) - * @return <code> true </code> if the next string is a short number. - * @throws IllegalStateException - * if the Scanner is closed. - */ - public boolean hasNextShort () throws IllegalStateException // TESTED - { - return hasNextShort (this.currentRadix); - } - - /** - * Checks if the string to the next delimiter can be interpreted as - * a short number. <br> To check, the private method {@link - * #myNextShort(int, boolean)} is called, and if no error occurs the - * next string could be a short. - * - * @see #nextShort(int) - * @param radix - * The radix to use for this check. The global radix of the Scanner will not be - * changed. - * @return <code> true </code> if the next string is a short number. - * @throws IllegalStateException - * if the Scanner is closed. - */ - public boolean hasNextShort (final int radix) throws IllegalStateException - { - try - { - myNextShort (radix, false); - return true; - } - catch (InputMismatchException ime) - { - return false; - } - } - - /** - * Returns the last {@link IOException} occured. - * - * @return Returns the last {@link IOException}. - */ - public IOException ioException () - { - return this.lastIOException; - } - - /** - * Returns the current value of {@link #useLocale}. This is used to - * tell the Scanner if it should use the Locale format or just - * handle numbers of the default format. - * - * @see #setUseLocale(boolean) - * @return the useLoclae. - */ - public boolean isUseLocale () // TESTED - { - return this.useLocale; - } - - /** - * Returns the current Locale. It is initialized with {@link - * Locale#getDefault()}. - * - * @see #useLocale(Locale) - * @return Returns the current Locale. - */ - public Locale locale () // TESTED - { - return this.actLocale; - } - - /** - * Returns the last MatchResult found. This is updated after every - * successfully search. - * - * @return Returns the last {@link MatchResult} found. - */ - public MatchResult match () // TESTED - { - return this.actResult; - } - - /** - * Uses the current delimiter to find the next string in the - * buffer. If a string is found the current position is set after - * the delimiter, otherwise a {@link NoSuchElementException} is - * thrown. A successful match sets the matchResult. - * - * @see #match() - * @return Returns the next string of the buffer. - * @throws NoSuchElementException - * If no element was found an exception is thrown. - * @throws IllegalStateException - * If the Scanner is closed. - */ - public String next () throws NoSuchElementException, IllegalStateException // TESTED - { - return myCoreNext (true, this.p); - } - - /** - * Tries to match the buffer with the given pattern. The current - * delimiter will not be changed. - * - * @param pattern - * The pattern to match. - * @return Returns the next string matching the pattern. - * @throws NoSuchElementException - * If no element was found an exception is thrown. - * @throws IllegalStateException - * If the Scanner is closed. - */ - public String next (final Pattern pattern) throws NoSuchElementException, IllegalStateException // TESTED - { - return myNext (pattern, true); - } - - /** - * Tries to match the buffer with the given pattern. The current - * delimiter will not be changed. Calls the {@link #next(Pattern)} - * with the compiled pattern. - * - * @see #next(Pattern) - * @param pattern - * The pattern to match. - * @return Returns the next string matching the pattern. - * @throws NoSuchElementException - * If no element was found an exception is thrown. - * @throws IllegalStateException - * If the Scanner is closed. - */ - public String next (final String pattern) throws NoSuchElementException, IllegalStateException // TESTED - { - return next (Pattern.compile (pattern)); - } - - /** - * Tries to interpret the next string as a BigDecimal value. - * - * @return Returns the BigDecimal value of the next string. - * @throws NoSuchElementException - * If no string is found or the string is not a BigDecimal. - * @throws IllegalStateException - * If the Scanner is closed. - */ - public BigDecimal nextBigDecimal () throws NoSuchElementException, IllegalStateException // TESTED - { - return myBigDecimal (true); - } - - /** - * Tries to interpret the next string as a BigInteger value. Call - * {@link #nextBigInteger(int)} with the current radix as parameter, - * and return the value. - * - * @see #nextBigInteger(int) - * @return Returns the BigInteger value of the next string. - * @throws NoSuchElementException - * If no string is found or the string is not a BigInteger. - * @throws IllegalStateException - * If the Scanner is closed. - */ - public BigInteger nextBigInteger () throws NoSuchElementException, IllegalStateException // TESTED - { - return nextBigInteger (this.currentRadix); - } - - /** - * Tries to interpret the next string as a BigInteger value with the - * given radix. - * - * @param radix - * The radix to be used for this BigInteger. The current radix of the Scanner is not - * changed. - * @return Returns the BigInteger value of the next string. - * @throws NoSuchElementException - * If no string is found or the string is not a BigInteger. - * @throws IllegalStateException - * If the Scanner is closed. - */ - public BigInteger nextBigInteger (final int radix) throws - NoSuchElementException, IllegalStateException - { - return myNextBigInteger (radix, true, BIG_INTEGER); - } - - /** - * Tries to interpret the next string to the delimiter as a boolean - * value, ignoring case. - * - * @return Returns the boolean value of the next matching string or throws an exception. - * @throws NoSuchElementException - * If no string is found or the string is not a boolean. - * @throws IllegalStateException - * If the Scanner is closed. - */ - public boolean nextBoolean () throws NoSuchElementException, IllegalStateException // TESTED - { - return myNextBoolean (true); - } - - /** - * Tries to interpret the next string as a byte value. Call {@link - * #nextByte(int)} with the current radix as parameter, and return - * the value. - * - * @see #nextByte(int) - * @return Returns the byte value of the next string. - * @throws NoSuchElementException - * If no string is found or the string is not a byte - * @throws IllegalStateException - * If the Scanner is closed. - */ - public byte nextByte () throws NoSuchElementException, IllegalStateException // TESTED - { - return nextByte (this.currentRadix); - } - - /** - * Tries to interpret the next string as a byte value with the given - * radix. - * - * @param radix - * The radix to be used for this byte. The current radix of the Scanner is not - * changed. - * @return Returns the byte value of the next string. - * @throws NoSuchElementException - * If no string is found or the string is not a byte. - * @throws IllegalStateException - * If the Scanner is closed. - */ - public byte nextByte (final int radix) throws NoSuchElementException, - IllegalStateException - { - return myNextByte (radix, true); - } - - /** - * Tries to interpret the next string as a double value. - * - * @return Returns the int value of the next string. - * @throws NoSuchElementException - * If no string is found or the string is not a double. - * @throws IllegalStateException - * If the Scanner is closed. - */ - public double nextDouble () throws NoSuchElementException, IllegalStateException // TESTED - { - return myNextDouble (true); - } - - /** - * Tries to interpret the next string as a double value, and then - * casts down to float. - * - * @return Returns the int value of the next string. - * @throws NoSuchElementException - * If no string is found or the string is not a double. - * @throws IllegalStateException - * If the Scanner is closed. - */ - public float nextFloat () throws NoSuchElementException, IllegalStateException // TESTED - { - return (float) myNextDouble (true); - // return myNextFloat(true); - } - - /** - * Tries to interpret the next string as an int value. Calls {@link - * #nextInt(int)} with the current radix as parameter, and return - * the value. - * - * @see #nextInt(int) - * @return Returns the int value of the next string. - * @throws NoSuchElementException - * If no string is found or the string is not an int. - * @throws IllegalStateException - * If the Scanner is closed. - */ - public int nextInt () throws NoSuchElementException, IllegalStateException // TESTED - { - return nextInt (this.currentRadix); - } - - /** - * Tries to interpret the next string as an int value with the given - * radix. - * - * @param radix - * The radix to be used for this int. The current radix of the Scanner is not changed - * @return Returns the int value of the next string. - * @throws NoSuchElementException - * If no string is found or the string is not an int. - * @throws IllegalStateException - * If the Scanner is closed. - */ - public int nextInt (final int radix) throws NoSuchElementException, - IllegalStateException - { - return myNextInt (radix, true); - } - - /** - * Tries to match the system line seperator, and returns the current - * line. - * - * @return Returns the current line. - * @throws NoSuchElementException - * If the current delimiter is not found. - * @throws IllegalStateException - * If the Scanner is closed. - */ - public String nextLine () throws NoSuchElementException, IllegalStateException // TESTED - { - return myNextLine (true); - } - - /** - * Tries to interpret the next string as a long value. Calls {@link - * #nextLong(int)} with the current radix as parameter, and return - * the value. - * - * @see #nextLong(int) - * @return Returns the long value of the next string. - * @throws NoSuchElementException - * If no string is found or the string is not a long. - * @throws IllegalStateException - * If the Scanner is closed. - */ - public long nextLong () throws NoSuchElementException, IllegalStateException // TESTED - { - return nextLong (this.currentRadix); - } - - /** - * Tries to interpret the next string as a long value with the given - * radix. - * - * @param radix - * The radix to be used for this long. The current radix of the Scanner is not - * changed - * @return Returns the long value of the next string. - * @throws NoSuchElementException - * If no string is found or the string is not a long. - * @throws IllegalStateException - * If the Scanner is closed. - */ - public long nextLong (final int radix) throws NoSuchElementException, - IllegalStateException - { - return myNextLong (radix, true); - } - - /** - * Tries to interpret the next string as a short value. Calls {@link - * #nextShort(int)} with the current radix as parameter, and return - * the value. - * - * @see #nextShort(int) - * @return Returns the short value of the next string. - * @throws NoSuchElementException - * If no string is found or the string is not a short. - */ - public short nextShort () throws NoSuchElementException // TESTED - { - return nextShort (this.currentRadix); - } - - /** - * Tries to interpret the next string as a short value with the - * given radix. - * - * @param radix - * The radix to be used for this short. The current radix of the Scanner is not - * changed. - * @return Returns the short value of the next string. - * @throws NoSuchElementException - * If no string is found or the string is not a short. - */ - public short nextShort (final int radix) throws NoSuchElementException - { - return myNextShort (radix, true); - } - - /** - * @return Returns the current radix. - */ - public int radix () - { - return this.currentRadix; - } - - /** - * The remove operation is not supported by this implementation of - * Iterator. - */ - public void remove () - { - } - - /** - * @param useLocale the useLocale to set. - */ - public void setUseLocale (final boolean useLocale) // TESTED - { - this.useLocale = useLocale; - } - - /** - * Skips the given pattern. Sets skipped <code>true</code>. - * - * @param pattern - * Pattern which should be skipped. - * @return <code>this</code> with the skipped buffer. - * @throws NoSuchElementException - * If the Pattern is not found. - */ - public Scanner skip (final Pattern pattern) throws NoSuchElementException - { - this.doSkipp = true; - int end; - boolean found; - Matcher matcher = pattern.matcher (this.actBuffer); - matcher.region (this.actPos - 1, this.actBuffer.length ()); - - found = matcher.find (); - found = myFillBuffer_loop (matcher, this.actPos - 1, found); - end = matcher.end (); - - this.actPos = end + 1; - - this.doSkipp = false; - this.skipped = true; - - actResult = null; - - if (!found) - { - throw new NoSuchElementException (); - } - return this; - } - - /** - * Skips a given pattern. Calls {@link #skip(Pattern)} with the - * compiled pattern. - * - * @see #skip(Pattern) - * @param pattern - * Pattern which should be skipped. - * @return <code>this</code> with the skipped buffer. - */ - public Scanner skip (final String pattern) - { - return skip (Pattern.compile (pattern)); - } - - /** - * Returns the string representation of this Scanner. - */ - @Override - public String toString () - { - String tmpStr2; - String rc = this.getClass ().getName (); - tmpStr2 = rc; - tmpStr2 = "[delimiters=" + this.p.pattern () + "]"; - rc += tmpStr2; - tmpStr2 = "[position=" + (this.procesedChars + this.actPos) + "]"; - rc += tmpStr2; - tmpStr2 = "[match valid=" + this.matchValid + "]"; - rc += tmpStr2; - tmpStr2 = "[need input=" + this.needInput + "]"; - rc += tmpStr2; - tmpStr2 = "[source closed=" + this.isClosed + "]"; - rc += tmpStr2; - tmpStr2 = "[skipped=" + this.skipped + "]"; - rc += tmpStr2; - tmpStr2 = "[group separator=\\" + this.dfs.getGroupingSeparator () + "]"; - rc += tmpStr2; - tmpStr2 = "[decimal separator=\\" + this.dfs.getDecimalSeparator () + "]"; - rc += tmpStr2; - tmpStr2 = - "[positive prefix=" + myConvert (this.df.getPositivePrefix ()) + "]"; - rc += tmpStr2; - tmpStr2 = - "[negative prefix=" + myConvert (this.df.getNegativePrefix ()) + "]"; - rc += tmpStr2; - tmpStr2 = - "[positive suffix=" + myConvert (this.df.getPositiveSuffix ()) + "]"; - rc += tmpStr2; - tmpStr2 = - "[negative suffix=" + myConvert (this.df.getNegativeSuffix ()) + "]"; - rc += tmpStr2; - tmpStr2 = "[NaN string=" + myConvert (this.dfs.getNaN ()) + "]"; - rc += tmpStr2; - tmpStr2 = "[infinity string=" + myConvert (this.dfs.getInfinity ()) + "]"; - rc += tmpStr2; - return rc; - } - - /** - * Sets the current pattern to the given parameter, and updates the - * {@link Matcher} with the new pattern. - * - * @param pattern - * The new pattern to use. - * @return Returns the Scanner (<code>this</code>) with the new pattern. - */ - public Scanner useDelimiter (final Pattern pattern) // TESTED - { - if (pattern != null) - { - this.p = pattern; - this.myMatcher = this.p.matcher (this.actBuffer); - } - return this; - } - - /** - * Sets the current pattern to the given parameter. Compiles the - * pattern and calls {@link #useDelimiter(Pattern)} - * - * @see #useDelimiter(Pattern) - * @param pattern - * The new pattern to use. - * @return Returns the Scanner (<code>this</code>) with the new pattern. - */ - public Scanner useDelimiter (final String pattern) // TESTED - { - return useDelimiter (Pattern.compile (pattern)); - } - - /** - * Sets the current Locale to the given parameter. Formats and - * Symbols are also set using the new Locale. - * - * @param locale The new Locale to use. If it is <code>null</code> - * nothing happens. - * @return Returns the Scanner (<code>this</code>) with the new Locale. - */ - public Scanner useLocale (final Locale locale) // TESTED - { - if (locale != null) - { - this.actLocale = locale; - this.actFormat = NumberFormat.getInstance (this.actLocale); - this.dfs = new DecimalFormatSymbols (this.actLocale); - this.df = (DecimalFormat) this.actFormat; - } - return this; - } - - /** - * Sets the current radix to the current value if the given radix is - * >= 2 and <= 36 otherwise an {@link IllegalArgumentException} is - * thrown. - * - * @param radix - * the new radix to use as default. - * @return <code> this </code> with the new radix value. - * @throws IllegalArgumentException - * When the given radix is out of bounds. - */ - public Scanner useRadix (final int radix) throws IllegalArgumentException - { - if (radix < 2 || radix > 36) - { - throw new IllegalArgumentException (); - } - this.currentRadix = radix; - return this; - } - - /** - * Checks if it is necessary to apply the current Locale on the - * String. If so the String is converted using the {@link - * NumberFormat#parse(String)} into a Number and then back to a - * default stringrepresentation of that Number. - * - * @see #setUseLocale(boolean) - * @param str - * String to convert into another string. - * @param radix Radix of the Number in the original string. It has - * to be 10 for anything to happen. - * @return Eighter the Stringrepresention of the number without the - * Locale or an unchanged string. - * @throws ParseException - * if {@link NumberFormat#parse(String)} fails to parse. - */ - private String myApplyLocale (final String str, - final int radix) throws ParseException - { - String rc; - - if (this.useLocale && radix == 10) - { - rc = this.actFormat.parse (str).toString (); - return rc; - } - - return str; - } - - /** - * If {@link #useLocale} is set and radix is 10 the string is tryed - * to be converted to string without Locale settings, because the - * "normal" convert from Local has only double precision and it is - * not enough for the about 50 digits of precision of the - * BigDecimal. So in the first step the string is seperated into the - * integer part which is converted to a long, and the fraction part - * is appended afterwards. Between the integer and the fraction part - * comes a ".". Finally the resulting string is returned. - * - * @see #setUseLocale(boolean) - * @param str String representation of a BigDecimal number. - * @return The default String representation (without Locale) of the - * BigInteger. - * @throws ParseException - * If the String has more than one decimal seperators a parse exception is thrown. - */ - private String myApplyLocaleBD (final String str) throws ParseException - { - if (!this.useLocale || this.currentRadix != 10) - { - return str; - } - - String negPrefix = this.df.getNegativePrefix (); - String negSuffix = this.df.getNegativeSuffix (); - String posPrefix = this.df.getPositivePrefix (); - String posSuffix = this.df.getPositiveSuffix (); - - char d = this.dfs.getDecimalSeparator (); - int begin1, begin2; - boolean isNegativ = false; - String parts = null; - - String tmpStr1 = ""; - - begin1 = str.indexOf (d); - begin2 = str.indexOf (d, begin1 + 1); - - if (begin2 > 0) - { - throw new ParseException ("more than one Decimal seperators", begin2); - } - - parts = str.substring (0, begin1); - - if ((negPrefix.length () > 0 - && str.substring (0, negPrefix.length ()).equals (negPrefix)) - || (negSuffix.length () > 0 - && str.substring (str.length () - - negSuffix.length ()).equals (negSuffix))) - { - parts += negSuffix; - isNegativ = true; - } - else - if ((posPrefix.length () > 0 - && str.substring (0, posPrefix.length ()).equals (posPrefix)) - || (posSuffix.length () > 0 - && str.substring (str.length () - - posSuffix.length ()).equals (posSuffix))) - { - parts += posSuffix; - } - - tmpStr1 = this.actFormat.parse (parts).toString (); - - if (isNegativ) - { - tmpStr1 += - "." + str.substring (str.indexOf (d) + 1, - str.length () - negSuffix.length ()); - } - else - { - tmpStr1 += - "." + str.substring (str.indexOf (d) + 1, - str.length () - posSuffix.length ()); - } - - return tmpStr1; - } - - /** - * Tries to interpret the next String as a BigDecimal. Therfore the - * next String is get with {@link #myCoreNext(boolean, Pattern)} and - * then {@link #myApplyLocaleBD(String)} is called to convert the - * String into a BigDecimal. - * - * @param delete - * Should the found string be deleted or not. - * @return Returns the BigDecimal value of the next string. - * @throws InputMismatchException - * If the string is not a BigDecimal - */ - private BigDecimal myBigDecimal (final boolean delete) throws - InputMismatchException - { - BigDecimal rc; - String tmp = myCoreNext (delete, this.p); - try - { - tmp = myApplyLocaleBD (tmp); - } - catch (ParseException e) - { - throw new InputMismatchException (ERR_PREFIX + tmp + IS_NOT + - "BigDecimal!!"); - } - rc = new BigDecimal (tmp); - - return rc; - } - - /** - * Applies suffix ("\E") and prefix ("\Q") if str.length != 0 Used - * by the toString method. - * - * @param str - * the string on which the suffix and prefix should be applied. - * @return The new new string with the suffix and prefix. - */ - private String myConvert (final String str) - { - if (str != null && str.length () > 0) - { - return "\\Q" + str + "\\E"; - } - return str; - } - - /** - * Searches the current Matcher for the current Pattern. If the end - * is reached during the search it tried to read again from the - * source. The search results are always saved in {@link #actResult} - * which is returned when match() is called. If doSkip is true the - * pattern is also taken. - * - * @param delete - * if true the aktPos is set. - * @param pattern - * pattern to search for. - * @return Returns the String which matches the pattern. - * @throws NoSuchElementException - * If the search has no result. - */ - private String myCoreNext (final boolean delete, final Pattern pattern) - throws NoSuchElementException - { - if (this.isClosed) - { - throw new IllegalStateException ("Scanner closed"); - } - if (shallUseLastFound (pattern != null ? pattern : this.p)) - { - if (this.last_RegionEnd != this.myMatcher.regionEnd ()) - { - System.out.println (this.last_RegionEnd + " != " + - this.myMatcher.regionEnd () + " (" + - (this.last_RegionEnd - - this.myMatcher.regionEnd ()) + ")"); - } - if (delete) - { - this.actPos = this.lastNextPos; - this.lastFoundPresent = false; - this.actResult = this.lastResult; - } - return this.lastFound; - } - - boolean found = false; - int left; - int endIndex; - - String tmp2 = null; - - if (this.actPos > this.MAX_PREFIX) - { - // skipp the processed chars so that the size of the buffer don't grow to much even with - // huge files - this.procesedChars += this.actPos; - this.actBuffer = this.actBuffer.substring (this.actPos); - this.actPos = 0; - this.myMatcher = pattern.matcher (this.actBuffer); - } - - left = this.actBuffer.length () - this.actPos; - if (left < this.MIN_BUF_LEN) - { - myFillBuffer (); - } - found = this.myMatcher.find (this.actPos); - - found = myFillBuffer_loop (this.myMatcher, this.actPos, found); - - this.needInput = false; - - if (found) - { - if (this.doSkipp) - { - endIndex = this.myMatcher.end (); - } - else - { - endIndex = this.myMatcher.start (); - } - tmp2 = this.actBuffer.substring (this.actPos, endIndex); - this.lastNextPos = this.myMatcher.end (); - /* - * if the delete flag is set, just set the current position after the end of the matched - * pattern. - */ - if (delete) - { - this.actPos = this.lastNextPos; - } - else - { - this.lastFound = tmp2; - this.lastFoundPresent = true; - this.lastPatternHash = pattern.hashCode (); - } - this.last_RegionStart = this.myMatcher.regionStart (); - this.last_RegionEnd = this.myMatcher.regionEnd (); - this.last_anchor = this.myMatcher.hasAnchoringBounds (); - this.last_transparent = this.myMatcher.hasTransparentBounds (); - } - else if (this.myMatcher.hitEnd ()) - // the end of input is matched - { - tmp2 = this.actBuffer.substring (this.actPos); - if (tmp2.length() == 0) - tmp2 = null; - this.lastNextPos = this.actBuffer.length (); - if (delete) - { - this.actPos = this.lastNextPos; - } - else - { - this.lastFound = tmp2; - this.lastFoundPresent = true; - this.lastPatternHash = pattern.hashCode (); - } - this.last_RegionStart = this.myMatcher.regionStart (); - this.last_RegionEnd = this.myMatcher.regionEnd (); - this.last_anchor = this.myMatcher.hasAnchoringBounds (); - this.last_transparent = this.myMatcher.hasTransparentBounds (); - } - else - { - /* - * if no match found an Exception is throwed - */ - throw new NoSuchElementException (); - } - /* - * change the Result only when a nextXXX() method was called, not if a hasNextXXX() method - * is called - */ - if (delete) - { - this.actResult = this.myMatcher.toMatchResult (); - - this.matchValid = this.actResult != null; - } - else - { - this.lastResult = this.myMatcher.toMatchResult (); - } - - this.skipped = this.doSkipp; - this.doSkipp = false; - - return tmp2; - } - - /** - * Used to fill the String buffer from a source. Therfore the 3 - * possible sources are checked if they are not <code>null</code> - * and this not used, otherwise the read method is called on the - * source. If a charsetName is set and not <code>null</code> it is - * applied to convert to String. - */ - private void myFillBuffer () - { - int len; - String tmpStr; - CharBuffer cb = null; - ByteBuffer bb = null; - - if (this.bIS != null) - { - try - { - len = this.bIS.read (this.tmpBuffer); - if (len < 0) - { - return; - } - if (this.charsetName != null) - { - tmpStr = new String (this.tmpBuffer, 0, len, this.charsetName); - } - else - { - tmpStr = new String (this.tmpBuffer, 0, len); - } - this.actBuffer += tmpStr; - } - catch (IOException e) - { - this.lastIOException = e; - } - } - else if (this.readableSource != null) - { - try - { - cb = CharBuffer.allocate (1000); - this.needInput = true; - len = this.readableSource.read (cb); - if (len < 0) - { - return; - } - this.needInput = false; - tmpStr = new String (cb.array ()); - this.actBuffer += tmpStr; - } - catch (IOException e) - { - this.lastIOException = e; - } - } - else if (this.rbcSource != null) - { - try - { - bb = ByteBuffer.allocate (1000); - this.needInput = true; - len = this.rbcSource.read (bb); - this.needInput = false; - if (len < 0) - { - return; - } - if (this.charsetName != null) - { - tmpStr = new String (bb.array (), 0, len, this.charsetName); - } - else - { - tmpStr = new String (bb.array (), 0, len); - } - this.actBuffer += tmpStr; - } - catch (IOException e) - { - this.lastIOException = e; - } - } - - this.myMatcher.reset (this.actBuffer); - } - - /** - * A loop in which the {@link #myFillBuffer()} is called and checked - * if the pattern is found in the matcher and if the buffersize - * changes after the read. - * - * @param aktM - * The current Matcher. - * @param pos - * Position from which the matcher should start matching. - * @param found - * if already found. - * @return <code> true </code> if the matcher has found a match. - */ - private boolean myFillBuffer_loop (final Matcher aktM, final int pos, - boolean found) - { - int tmp; - - tmp = this.actBuffer.length (); - while (aktM.hitEnd () - && ((this.bIS != null) || (this.readableSource != null) - || (this.rbcSource != null))) - { - myFillBuffer (); - if (tmp == this.actBuffer.length ()) - { - break; - } - found = aktM.find (pos); - this.needInput = true; - } - return found; - } - - /** - * Used to find the given pattern in the given string before the - * given horizon. Therfore the current matcher is copied, and - * overwritten using the given pattern and the given Sting. <br> - * After the search the original values are restored, and skipped is - * set <code> true </code>. - * - * @param pattern - * Pattern which should be matched. - * @param str - * The String in which the pattern should be matched. - * @param horizon - * the horizon whithin the match should be, if 0 then it is ignored. - * @return Returns the String in the given String that matches the pattern. - */ - private String myFindPInStr (final Pattern pattern, final String str, - final int horizon) - { - String rc = null; - int curPos = this.actPos; - Matcher aktMatcher = this.myMatcher; - - this.myMatcher = pattern.matcher (str); - if (horizon > 0) - { - this.myMatcher.useAnchoringBounds (true); - this.myMatcher.useTransparentBounds (true); - this.myMatcher.region (this.actPos, this.actPos + horizon); - } - rc = myCoreNext (true, pattern); - this.myMatcher = aktMatcher; - - this.actPos = curPos; - this.skipped = true; - - return rc; - } - - /** - * Used by the {@link #hasNext(Pattern)} and {@link #next(Pattern)} - * methods. Therfore a substring is taken first to the current - * delimiter, afterwards the given pattern is searched in this - * subsring.<br> Finally the current Buffer and matcher (which have - * been temporarily changed) are set back.<br> <br> The {@link - * #skipped} is set <code> true </code>. - * - * @param pattern - * Pattern to find until the current delimiter. - * @param delete - * Is <code> true </code> if a next method is called.<br> - * Is <code> false </code> if a hasNext method is called. - * @return Returns the String which is returned by the public methods. - */ - private String myNext (final Pattern pattern, final boolean delete) - { - String tmpStr; - Matcher aktMatcher = this.myMatcher; - String result; - String currBuffer = this.actBuffer; - int currAktPos; - - tmpStr = myCoreNext (delete, this.p); - this.myMatcher = pattern.matcher (tmpStr); - this.actBuffer = tmpStr; - currAktPos = this.actPos; - this.actPos = 0; - result = myCoreNext (delete, pattern); - this.actPos = currAktPos; - - this.actBuffer = currBuffer; - this.myMatcher = aktMatcher; - this.skipped = true; - - return result; - } - - /** - * Calls the next() method internally to get the next String, and - * trys to apply a locale which is only applied if the radix is 10 - * and useLocale is <code> true </code>. Afterwards it is tried to - * call the Constructor of a {@link BigInteger} with the given - * radix. - * - * @param radix The radix to use. - * @param delete If the found String should be removed from input or - * not. - * @param name name of "BigInteger" in case of an Error. - * @return Returns the new BigInteger created if there is no Error. - * @throws InputMismatchException - * If there is a {@link ParseException} or a {@link NumberFormatException}. - */ - private BigInteger myNextBigInteger (final int radix, final boolean delete, - final String name) - { - BigInteger rc; - String tmp = myPrepareForNext (this.p, delete); - - try - { - tmp = myApplyLocale (tmp, radix); - rc = new BigInteger (tmp, radix); - return rc; - } - catch (NumberFormatException nfe) - { - } - catch (ParseException e) - { - } - throw new InputMismatchException (ERR_PREFIX + tmp + IS_NOT + name); - } - - /** - * Checks if the next String is either "true" or "false", otherwise - * an {@link InputMismatchException} is thrown. It ignores the case - * of the string so that "true" and "TRUE" and even "TrUe" are - * accepted. - * - * @param delete Should the found value be removed from the input or - * not. - * @return Returns the boolean value (if it is a boolean). - * @throws InputMismatchException - * If the next String is not a boolean. - */ - private boolean myNextBoolean (final boolean delete) throws - InputMismatchException - { - String tmp = myPrepareForNext (this.p, delete); - if (tmp.equalsIgnoreCase ("true")) - { - return true; - } - else if (tmp.equalsIgnoreCase ("false")) - { - return false; - } - else - { - throw new InputMismatchException (ERR_PREFIX + tmp + NOT_BOOLEAN); - } - } - - /** - * Calls the {@link #myPrepareForNext(Pattern, boolean)} which calls - * the {@link #myCoreNext(boolean, Pattern)} to return the next - * String matching the current delimier. Afterwards it is tryed to - * convert the String into a byte. Any Error will lead into a {@link - * InputMismatchException}. - * - * @param radix The radix to use. - * @param delete Should the found String be removed from the input. - * @return Returns the byte value of the String. - * @throws InputMismatchException if the next String is not a byte. - */ - private byte myNextByte (final int radix, - final boolean delete) throws InputMismatchException - { - byte rc; - String tmp = myPrepareForNext (this.p, delete); - - try - { - tmp = myApplyLocale (tmp, radix); - rc = Byte.parseByte (tmp, radix); - return rc; - } - catch (NumberFormatException nfe) - { - } - catch (ParseException e) - { - } - throw new InputMismatchException (ERR_PREFIX + tmp + NOT_BYTE); - } - - /** - * Tries to interpret the next String as a double value. To verify - * if the double value is correct, it is converted back to a String - * using the default Locale and this String is compared with the - * String from which the double was converted. If the two Strings - * don't match, an {@link InputMismatchException} is thrown.<br> - * <br> The radix used is always 10 even if the global radix is - * changed. - * - * @param delete Should the String be removed, if true it will be - * also removed if the String is not a double value. - * @return Returns the double value of the next String. - * @throws InputMismatchException if the next String is not a - * double. - */ - private double myNextDouble (final boolean delete) throws - InputMismatchException - { - double rc; - String tmp = myPrepareForNext (this.p, delete); - - try - { - tmp = myApplyLocale (tmp, 10); - rc = Double.parseDouble (tmp); - if (("" + rc).equals (tmp)) - { - return rc; - } - } - catch (ParseException e) - { - } - throw new InputMismatchException (ERR_PREFIX + tmp + NOT_DOUBLE); - } - - /** - * Tries to interpret the next String as an int value. Therfore - * {@link #myApplyLocale(String, int)} decides if the current Locale - * should be applied or not and then the result is parsed using - * {@link Integer#parseInt(String, int)}. Any Error will lead to an - * {@link InputMismatchException}. - * - * @param radix The radix to use. - * @param delete <code> true </code> if the String should be deleted - * from the input. - * @return Returns the int value of the String. - * @throws InputMismatchException if the next String is not an int. - */ - private int myNextInt (final int radix, - final boolean delete) throws InputMismatchException - { - int rc; - String tmp = myPrepareForNext (this.p, delete); - try - { - tmp = myApplyLocale (tmp, radix); - rc = Integer.parseInt (tmp, radix); - return rc; - } - catch (NumberFormatException nfe) - { - } - catch (ParseException e) - { - } - throw new InputMismatchException (ERR_PREFIX + tmp + NOT_INT); - } - - /** - * Finds the next line using the {@link #NEW_LINE} constant which is - * set to the system specific line seperator. - * - * @param delete should the found line be deleted from the input. - * @return the current line. - */ - private String myNextLine (final boolean delete) - { - return myPrepareForNext (Pattern.compile (NEW_LINE), delete); - } - - /** - * Tries to interpret the next String as a long value with the given - * radix. Therfore the {@link Long#parseLong(String, int)} is called - * and every Error will lead into a {@link InputMismatchException}. - * - * @param radix The radix to be used. - * @param delete Should the found String be deleted from the input. - * @return the long value of the next String. - * @throws InputMismatchException if the next String is not a long. - */ - private long myNextLong (final int radix, - final boolean delete) throws InputMismatchException - { - long rc; - String tmp = myPrepareForNext (this.p, delete); - - try - { - tmp = myApplyLocale (tmp, radix); - rc = Long.parseLong (tmp, radix); - return rc; - } - catch (NumberFormatException nfe) - { - } - catch (ParseException e) - { - } - throw new InputMismatchException (ERR_PREFIX + tmp + NOT_LONG); - } - - /** - * Tries to interpret the next String as a short value with the - * given radix. Therfore the {@link Short#parseShort(String, int)} - * is called and every Error will lead into a {@link - * InputMismatchException} . - * - * @param radix - * The radix to be used. - * @param delete - * Should the found String be deleted from the input. - * @return the long value of the next String. - * @throws InputMismatchException - * if the next String is not a short. - */ - private short myNextShort (final int radix, - final boolean delete) throws - InputMismatchException - { - short rc; - String tmp = myPrepareForNext (this.p, delete); - - try - { - tmp = myApplyLocale (tmp, radix); - rc = Short.parseShort (tmp, radix); - return rc; - } - catch (NumberFormatException nfe) - { - } - catch (ParseException e) - { - } - throw new InputMismatchException (ERR_PREFIX + tmp + - "\" is not a short"); - } - - /** - * Sets the current pattern to the given pattern and calls the - * {@link #myCoreNext(boolean, Pattern)}. Finally sets the pattern - * back to its old value. - * - * @param aktPattern Pattern to be used for the next match. - * @param delete Should the found String be deleted or not. - * @return Return the String returned from {@link - * #myCoreNext(boolean, Pattern)}. - */ - private String myPrepareForNext (final Pattern aktPattern, - final boolean delete) - { - - String rc; - Pattern oldPattern = this.p; - useDelimiter (aktPattern); - - rc = myCoreNext (delete, aktPattern); - - useDelimiter (oldPattern); - - return rc; - } - - /** - * Determinates if the last found can be used, so that after a - * hasNextXXX the nextXXX has not to search if nothing has - * changed.<br /> Used in {@link #myCoreNext(boolean, Pattern)}. - * - * @param aktP The pattern which should be checked. - * @return <code> true </code> if the searchresult is already ready. - */ - private boolean shallUseLastFound (final Pattern aktP) - { - if (this.lastFoundPresent && - this.lastPatternHash == aktP.hashCode () && - this.last_RegionStart == this.myMatcher.regionStart () && - this.last_anchor == this.myMatcher.hasAnchoringBounds () && - this.last_transparent == this.myMatcher.hasTransparentBounds ()) - { - if (this.last_RegionEnd != this.myMatcher.regionEnd ()) - { - int tmpVal = - this.myMatcher.regionEnd () - - this.last_RegionEnd - this.MAX_PREFIX; - if (tmpVal > 0 && tmpVal < 20) - { - this.last_RegionEnd = - this.myMatcher.regionEnd (); - return true; - } - } - else - return true; - } - return false; - } - -} diff --git a/libjava/classpath/java/util/ServiceConfigurationError.java b/libjava/classpath/java/util/ServiceConfigurationError.java deleted file mode 100644 index 40d744c2..0000000 --- a/libjava/classpath/java/util/ServiceConfigurationError.java +++ /dev/null @@ -1,94 +0,0 @@ -/* ServiceConfigurationError.java -- An error on service loading. - Copyright (C) 2007 Free Software Foundation - -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; - -/** - * <p> - * An error thrown when a problem occurs during the loading - * of a service provider by a {@link ServiceLoader}. Such - * an error can occur for a number of reasons: - * </p> - * <ul> - * <li>An I/O error occurs</li> - * <li>The configuration file doesn't meet the specifications</li> - * <li>A listed class can not be found</li> - * <li>A listed class does not implement the service</li> - * <li>A listed class can not be instantiated</li> - * </ul> - * - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.6 - */ -public class ServiceConfigurationError - extends Error -{ - - /** - * Compatible with JDK 1.6 - */ - private static final long serialVersionUID = 74132770414881L; - - /** - * Constructs a new {@link ServiceConfigurationError} - * with the specified message. - * - * @param message a message describing the error, or - * <code>null</code> if none is required. - */ - public ServiceConfigurationError(String message) - { - super(message); - } - - /** - * Constructs a new {@link ServiceConfigurationError} - * with the specified message and cause. - * - * @param message a message describing the error, or - * <code>null</code> if none is required. - * @param cause the cause of the error, or - * <code>null</code> if this is unknown - * or inappropriate. - */ - public ServiceConfigurationError(String message, - Throwable cause) - { - super(message,cause); - } - -} diff --git a/libjava/classpath/java/util/ServiceLoader.java b/libjava/classpath/java/util/ServiceLoader.java deleted file mode 100644 index bcac070..0000000 --- a/libjava/classpath/java/util/ServiceLoader.java +++ /dev/null @@ -1,274 +0,0 @@ -/* ServiceLoader.java -- Allows loading of plug-in services. - Copyright (C) 2006, 2007 Free Software Foundation - -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 gnu.classpath.ServiceFactory; - -/** - * <p> - * Facilities for loading service providers. A service is - * defined by a set of interfaces or abstract classes, and - * a service provider gives a concrete implementation of this. - * Service providers may be installed as part of the runtime - * environment using JAR files in the extension directories, - * or may be simply supplied on the classpath. - * </p> - * <p> - * In terms of loading a service, the service is defined by - * a single interface or abstract class which the provider - * implements. This may not constitute the entire service, - * but is simply a mechanism by which a provider of the - * service can be loaded and its capabilities determined. - * The variety of possible services means that no more - * requirements are made of the service provider other than - * that it must have an accessible zero argument constructor - * in order to allow an instance to be created. - * </p> - * <p> - * Service providers are listed in a file named after the - * service type in the directory <code>META-INF/services</code>. - * The file contains a list of classes, and must be encoded - * using UTF-8. Whitespace is ignored. Comments can be - * included by using a <code>'#'</code> prefix; anything occurring - * on the same line after this symbol is ignored. Duplicate classes - * are ignored. - * </p> - * <p> - * The classes are loaded using the same classloader that was - * queried in order to locate the configuration file. As a result, - * the providers do not need to reside in the same JAR file as the - * resource; they merely have to be accessible to this classloader, - * which may differ from the one that loaded the file itself. - * </p> - * <p> - * Providers are located and instantiated lazily, as calls to the - * {@link #iterator()} are made. Providers are cached, and those in - * the cache are returned first. The cache may be cleared by calling - * {@link #reload()}. Service loaders always execute in the security - * context of the caller, so ideally calls should be made from a trusted - * source. - * </p> - * <p> - * Note that this class is not thread-safe, and that strange errors may - * occur as the result of the use of remote URLs occurring on the classpath, - * which lead to erroneous web pages. - * </p> - * - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.6 - */ -public final class ServiceLoader<S> - implements Iterable<S> -{ - - /** - * The class of the service provider. - */ - private Class<S> spi; - - /** - * The class loader for the service provider. - */ - private ClassLoader loader; - - /** - * The cache of service providers. - */ - private List<S> cache; - - /** - * The {@link gnu.classpath.ServiceFactory} iterator - * from which providers are obtained. - */ - private Iterator<S> serviceIt; - - /** - * Constructs a new {@link ServiceLoader} with - * the specified provider and class loader. - * - * @param spi the service to load. - * @param loader the class loader to use. - */ - private ServiceLoader(Class<S> spi, ClassLoader loader) - { - this.spi = spi; - this.loader = loader; - cache = new ArrayList<S>(); - } - - /** - * Lazily loads the available providers. The iterator first returns - * providers from the cache, in instantiation order, followed by any - * remaining providers, which are added to the cache after loading. - * The actual loading and parsing of the configuration file takes - * place in the {@link Iterator#hasNext()} and {@link Iterator#next()} - * methods, which means that they may result in a - * {@link ServiceConfigurationError} being thrown. If such an error - * does occur, subsequent invocations will attempt to recover. - * The {@link remove()} method is not supported and instead throws - * an {@link UnsupportedOperationException}. - * - * @return an iterator that lazily loads service providers. - */ - public Iterator<S> iterator() - { - return new Iterator<S>() - { - /** - * The cache iterator. - */ - private Iterator<S> cacheIt = cache.iterator(); - - public boolean hasNext() - { - if (cacheIt.hasNext()) - return true; - if (serviceIt == null) - serviceIt = - ServiceFactory.lookupProviders(spi, loader, true); - return serviceIt.hasNext(); - } - - public S next() - { - if (cacheIt.hasNext()) - return cacheIt.next(); - if (serviceIt == null) - serviceIt = - ServiceFactory.lookupProviders(spi, loader, true); - S nextService = serviceIt.next(); - cache.add(nextService); - return nextService; - } - - public void remove() - { - throw new UnsupportedOperationException(); - } - }; - } - - /** - * Creates a new service loader for the given service, - * using the context class loader of the current thread. - * This is equivalent to calling <code>ServiceLoader.load(service, - * Thread.currentThread().getContextClassLoader())</code>. - * - * @param service the interface or abstract class that represents - * the service. - * @return a new {@link ServiceLoader} instance. - */ - public static <S> ServiceLoader<S> load(Class<S> service) - { - return load(service, - Thread.currentThread().getContextClassLoader()); - } - - /** - * Creates a new service loader for the given service, - * using the specified class loader. The class loader is - * used to access the configuration file and the service - * provider instances themselves. If the loader is - * <code>null</code>, the system class loader (or, if - * this is also <code>null</code>, the bootstrap class - * loader). - * - * @param service the interface or abstract class that represents - * the service. - * @param loader the class loader used to load the configuration - * file and service providers. - * @return a new {@link ServiceLoader} instance. - */ - public static <S> ServiceLoader<S> load(Class<S> service, - ClassLoader loader) - { - if (loader == null) - loader = ClassLoader.getSystemClassLoader(); - return new ServiceLoader(service, loader); - } - - /** - * Creates a new service loader for the given service, - * using the extension class loader. If the extension - * class loader can not be found, the system class loader - * is used (or, if this is <code>null</code>, the - * bootstrap class loader). The primary use of this method - * is to only obtain installed services, ignoring any which - * may appear on the classpath. This is equivalent to calling - * <code>load(service, extClassLoader)</code> where - * <code>extClassLoader</code> is the extension class loader - * (or <code>null</code> if this is unavailable). - * - * @param service the interface or abstract class that represents - * the service. - * @return a new {@link ServiceLoader} instance. - */ - public static <S> ServiceLoader<S> loadInstalled(Class<S> service) - { - /* We expect the extension class loader to be the parent - * of the system class loader, as in - * ClassLoader.getDefaultSystemClassLoader() */ - return load(service, - ClassLoader.getSystemClassLoader().getParent()); - } - - /** - * Clears the cache of the provider, so that all providers - * are again read from the configuration file and instantiated. - */ - public void reload() - { - cache.clear(); - } - - /** - * Returns a textual representation of this - * {@link ServiceLoader}. - * - * @return a textual representation of the - * service loader. - */ - public String toString() - { - return getClass().getName() + - "[spi=" + spi + - ",loader=" + loader + - "]"; - } - -} diff --git a/libjava/classpath/java/util/Set.java b/libjava/classpath/java/util/Set.java deleted file mode 100644 index 35f75b5..0000000 --- a/libjava/classpath/java/util/Set.java +++ /dev/null @@ -1,265 +0,0 @@ -/* Set.java -- A collection that prohibits duplicates - 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; - -/** - * 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<E> extends Collection<E> -{ - /** - * 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(E 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<? extends E> 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<E> 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() - */ - <T> T[] toArray(T[] a); -} diff --git a/libjava/classpath/java/util/SimpleTimeZone.java b/libjava/classpath/java/util/SimpleTimeZone.java deleted file mode 100644 index 6b3b55f..0000000 --- a/libjava/classpath/java/util/SimpleTimeZone.java +++ /dev/null @@ -1,1052 +0,0 @@ -/* java.util.SimpleTimeZone - Copyright (C) 1998, 1999, 2000, 2003, 2004, 2005, 2007 - 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 a simple time zone offset and handles - * daylight savings. It can only handle one daylight savings rule, so - * it can't represent historical changes. - * - * This object is tightly bound to the Gregorian calendar. It assumes - * a regular seven days week, and the month lengths are that of the - * Gregorian Calendar. It can only handle daylight savings for years - * lying in the AD era. - * - * @see Calendar - * @see GregorianCalendar - * @author Jochen Hoenicke - */ -public class SimpleTimeZone extends TimeZone -{ - /** - * The raw time zone offset in milliseconds to GMT, ignoring - * daylight savings. - * @serial - */ - private int rawOffset; - - /** - * True, if this timezone uses daylight savings, false otherwise. - * @serial - */ - private boolean useDaylight; - - /** - * 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 hour. - * @serial - * @since JDK1.1.4 - */ - private int dstSavings = 60 * 60 * 1000; - - /** - * The first year, in which daylight savings rules applies. - * @serial - */ - private int startYear; - private static final int DOM_MODE = 1; - private static final int DOW_IN_MONTH_MODE = 2; - private static final int DOW_GE_DOM_MODE = 3; - private static final int DOW_LE_DOM_MODE = 4; - - /** - * The mode of the start rule. This takes one of the following values: - * <dl> - * <dt>DOM_MODE (1)</dt> - * <dd> startDay contains the day in month of the start date, - * startDayOfWeek is unused. </dd> - * <dt>DOW_IN_MONTH_MODE (2)</dt> - * <dd> The startDay gives the day of week in month, and - * startDayOfWeek the day of week. For example startDay=2 and - * startDayOfWeek=Calender.SUNDAY specifies that the change is on - * the second sunday in that month. You must make sure, that this - * day always exists (ie. don't specify the 5th sunday). - * </dd> - * <dt>DOW_GE_DOM_MODE (3)</dt> - * <dd> The start is on the first startDayOfWeek on or after - * startDay. For example startDay=13 and - * startDayOfWeek=Calendar.FRIDAY specifies that the daylight - * savings start on the first FRIDAY on or after the 13th of that - * Month. Make sure that the change is always in the given month, or - * the result is undefined. - * </dd> - * <dt>DOW_LE_DOM_MONTH (4)</dt> - * <dd> The start is on the first startDayOfWeek on or before the - * startDay. Make sure that the change is always in the given - * month, or the result is undefined. - </dd> - * </dl> - * @serial */ - private int startMode; - - /** - * The month in which daylight savings start. This is one of the - * constants Calendar.JANUARY, ..., Calendar.DECEMBER. - * @serial - */ - private int startMonth; - - /** - * This variable can have different meanings. See startMode for details - * @see #startMode - * @serial - */ - private int startDay; - - /** - * This variable specifies the day of week the change takes place. If - * startMode == DOM_MODE, this is undefined. - * @serial - * @see #startMode - */ - private int startDayOfWeek; - - /** - * This variable specifies the time of change to daylight savings. - * This time is given in milliseconds after midnight in startTimeMode - * chosen time mode. - * @serial - */ - private int startTime; - - /** - * This variable specifies the mode that startTime is specified in. By - * default it is WALL_TIME, but can also be STANDARD_TIME or UTC_TIME. For - * startTime, STANDARD_TIME and WALL_TIME are equivalent. - * @serial - */ - private int startTimeMode = WALL_TIME; - - /** - * The month in which daylight savings ends. This is one of the - * constants Calendar.JANUARY, ..., Calendar.DECEMBER. - * @serial - */ - private int endMonth; - - /** - * This variable gives the mode for the end of daylight savings rule. - * It can take the same values as startMode. - * @serial - * @see #startMode - */ - private int endMode; - - /** - * This variable can have different meanings. See startMode for details - * @serial - * @see #startMode - */ - private int endDay; - - /** - * This variable specifies the day of week the change takes place. If - * endMode == DOM_MODE, this is undefined. - * @serial - * @see #startMode - */ - private int endDayOfWeek; - - /** - * This variable specifies the time of change back to standard time. - * This time is given in milliseconds after midnight in endTimeMode - * chosen time mode. - * @serial - */ - private int endTime; - - /** - * This variable specifies the mode that endTime is specified in. By - * default it is WALL_TIME, but can also be STANDARD_TIME or UTC_TIME. - * @serial - */ - private int endTimeMode = WALL_TIME; - - /** - * This variable points to a deprecated array from JDK 1.1. It is - * ignored in JDK 1.2 but streamed out for compatibility with JDK 1.1. - * The array contains the lengths of the months in the year and is - * assigned from a private static final field to avoid allocating - * the array for every instance of the object. - * Note that static final fields are not serialized. - * @serial - */ - private byte[] monthLength = monthArr; - private static final byte[] monthArr = - { - 31, 28, 31, 30, 31, 30, 31, 31, 30, - 31, 30, 31 - }; - - /** - * The version of the serialized data on the stream. - * <dl> - * <dt>0 or not present on stream</dt> - * <dd> JDK 1.1.3 or earlier, only provides this fields: - * rawOffset, startDay, startDayOfWeek, startMonth, startTime, - * startYear, endDay, endDayOfWeek, endMonth, endTime - * </dd> - * <dd> JDK 1.1.4 or later. This includes three new fields, namely - * startMode, endMode and dstSavings. And there is a optional section - * as described in writeObject. - * </dd> - * </dl> - * - * XXX - JDK 1.2 Beta 4 docu states 1.1.4, but my 1.1.5 has the old - * version. - * - * When streaming out this class it is always written in the latest - * version. - * @serial - * @since JDK1.1.4 - */ - private int serialVersionOnStream = 2; - private static final long serialVersionUID = -403250971215465050L; - - /** - * Constant to indicate that start and end times are specified in standard - * time, without adjusting for daylight savings. - */ - public static final int STANDARD_TIME = 1; - - /** - * Constant to indicate that start and end times are specified in wall - * time, adjusting for daylight savings. This is the default. - */ - public static final int WALL_TIME = 0; - - /** - * Constant to indicate that start and end times are specified in UTC. - */ - public static final int UTC_TIME = 2; - - /** - * Create a <code>SimpleTimeZone</code> with the given time offset - * from GMT and without daylight savings. - * @param rawOffset the time offset from GMT in milliseconds. - * @param id The identifier of this time zone. - */ - public SimpleTimeZone(int rawOffset, String id) - { - this.rawOffset = rawOffset; - setID(id); - useDaylight = false; - startYear = 0; - } - - /** - * Create a <code>SimpleTimeZone</code> with the given time offset - * from GMT and with daylight savings. The start/end parameters - * can have different meaning (replace WEEKDAY with a real day of - * week). Only the first two meanings were supported by earlier - * versions of jdk. - * - * <dl> - * <dt><code>day > 0, dayOfWeek = Calendar.WEEKDAY</code></dt> - * <dd>The start/end of daylight savings is on the <code>day</code>-th - * <code>WEEKDAY</code> in the given month. </dd> - * <dt><code>day < 0, dayOfWeek = Calendar.WEEKDAY</code></dt> - * <dd>The start/end of daylight savings is on the <code>-day</code>-th - * <code>WEEKDAY</code> counted from the <i>end</i> of the month. </dd> - * <dt><code>day > 0, dayOfWeek = 0</code></dt> - * <dd>The start/end of daylight is on the <code>day</code>-th day of - * the month. </dd> - * <dt><code>day > 0, dayOfWeek = -Calendar.WEEKDAY</code></dt> - * <dd>The start/end of daylight is on the first WEEKDAY on or after - * the <code>day</code>-th day of the month. You must make sure that - * this day lies in the same month. </dd> - * <dt><code>day < 0, dayOfWeek = -Calendar.WEEKDAY</code></dt> - * <dd>The start/end of daylight is on the first WEEKDAY on or - * <i>before</i> the <code>-day</code>-th day of the month. You - * must make sure that this day lies in the same month. </dd> - * </dl> - * - * If you give a non existing month, a day that is zero, or too big, - * or a dayOfWeek that is too big, the result is undefined. - * - * The start rule must have a different month than the end rule. - * This restriction shouldn't hurt for all possible time zones. - * - * @param rawOffset The time offset from GMT in milliseconds. - * @param id The identifier of this time zone. - * @param startMonth The start month of daylight savings; use the - * constants in Calendar. - * @param startDayOfWeekInMonth A day in month or a day of week number, as - * described above. - * @param startDayOfWeek The start rule day of week; see above. - * @param startTime A time in millis in standard time. - * @param endMonth The end month of daylight savings; use the - * constants in Calendar. - * @param endDayOfWeekInMonth A day in month or a day of week number, as - * described above. - * @param endDayOfWeek The end rule day of week; see above. - * @param endTime A time in millis in standard time. - * @throws IllegalArgumentException if parameters are invalid or out of - * range. - */ - public SimpleTimeZone(int rawOffset, String id, int startMonth, - int startDayOfWeekInMonth, int startDayOfWeek, - int startTime, int endMonth, int endDayOfWeekInMonth, - int endDayOfWeek, int endTime) - { - this.rawOffset = rawOffset; - setID(id); - useDaylight = true; - - setStartRule(startMonth, startDayOfWeekInMonth, startDayOfWeek, startTime); - setEndRule(endMonth, endDayOfWeekInMonth, endDayOfWeek, endTime); - if (startMonth == endMonth) - throw new IllegalArgumentException("startMonth and endMonth must be different"); - this.startYear = 0; - } - - /** - * This constructs a new SimpleTimeZone that supports a daylight savings - * rule. The parameter are the same as for the constructor above, except - * there is the additional dstSavaings parameter. - * - * @param dstSavings the amount of savings for daylight savings - * time in milliseconds. This must be positive. - * @since 1.2 - */ - public SimpleTimeZone(int rawOffset, String id, int startMonth, - int startDayOfWeekInMonth, int startDayOfWeek, - int startTime, int endMonth, int endDayOfWeekInMonth, - int endDayOfWeek, int endTime, int dstSavings) - { - this(rawOffset, id, startMonth, startDayOfWeekInMonth, startDayOfWeek, - startTime, endMonth, endDayOfWeekInMonth, endDayOfWeek, endTime); - - this.dstSavings = dstSavings; - } - - /** - * This constructs a new SimpleTimeZone that supports a daylight savings - * rule. The parameter are the same as for the constructor above, except - * there are the additional startTimeMode, endTimeMode, and dstSavings - * parameters. - * - * @param startTimeMode the mode that start times are specified in. One of - * WALL_TIME, STANDARD_TIME, or UTC_TIME. - * @param endTimeMode the mode that end times are specified in. One of - * WALL_TIME, STANDARD_TIME, or UTC_TIME. - * @param dstSavings the amount of savings for daylight savings - * time in milliseconds. This must be positive. - * @throws IllegalArgumentException if parameters are invalid or out of - * range. - * @since 1.4 - */ - public SimpleTimeZone(int rawOffset, String id, int startMonth, - int startDayOfWeekInMonth, int startDayOfWeek, - int startTime, int startTimeMode, int endMonth, - int endDayOfWeekInMonth, int endDayOfWeek, - int endTime, int endTimeMode, int dstSavings) - { - this(rawOffset, id, startMonth, startDayOfWeekInMonth, startDayOfWeek, - startTime, endMonth, endDayOfWeekInMonth, endDayOfWeek, endTime); - - if (startTimeMode < WALL_TIME || startTimeMode > UTC_TIME) - throw new IllegalArgumentException("startTimeMode must be one of WALL_TIME, STANDARD_TIME, or UTC_TIME"); - if (endTimeMode < WALL_TIME || endTimeMode > UTC_TIME) - throw new IllegalArgumentException("endTimeMode must be one of WALL_TIME, STANDARD_TIME, or UTC_TIME"); - - this.dstSavings = dstSavings; - this.startTimeMode = startTimeMode; - this.endTimeMode = endTimeMode; - } - - /** - * Sets the first year, where daylight savings applies. The daylight - * savings rule never apply for years in the BC era. Note that this - * is gregorian calendar specific. - * @param year the start year. - */ - public void setStartYear(int year) - { - startYear = year; - useDaylight = true; - } - - /** - * Checks if the month, day, dayOfWeek arguments are in range and - * returns the mode of the rule. - * @param month the month parameter as in the constructor - * @param day the day parameter as in the constructor - * @param dayOfWeek the day of week parameter as in the constructor - * @return the mode of this rule see startMode. - * @exception IllegalArgumentException if parameters are out of range. - * @see #SimpleTimeZone(int, String, int, int, int, int, int, int, int, int) - * @see #startMode - */ - private int checkRule(int month, int day, int dayOfWeek) - { - if (month < 0 || month > 11) - throw new IllegalArgumentException("month out of range"); - - int daysInMonth = getDaysInMonth(month, 1); - if (dayOfWeek == 0) - { - if (day <= 0 || day > daysInMonth) - throw new IllegalArgumentException("day out of range"); - return DOM_MODE; - } - else if (dayOfWeek > 0) - { - if (Math.abs(day) > (daysInMonth + 6) / 7) - throw new IllegalArgumentException("dayOfWeekInMonth out of range"); - if (dayOfWeek > Calendar.SATURDAY) - throw new IllegalArgumentException("dayOfWeek out of range"); - return DOW_IN_MONTH_MODE; - } - else - { - if (day == 0 || Math.abs(day) > daysInMonth) - throw new IllegalArgumentException("day out of range"); - if (dayOfWeek < -Calendar.SATURDAY) - throw new IllegalArgumentException("dayOfWeek out of range"); - if (day < 0) - return DOW_LE_DOM_MODE; - else - return DOW_GE_DOM_MODE; - } - } - - /** - * Sets the daylight savings start rule. You must also set the - * end rule with <code>setEndRule</code> or the result of - * getOffset is undefined. For the parameters see the ten-argument - * constructor above. - * - * @param month The month where daylight savings start, zero - * based. You should use the constants in Calendar. - * @param day A day of month or day of week in month. - * @param dayOfWeek The day of week where daylight savings start. - * @param time The time in milliseconds standard time where daylight - * savings start. - * @exception IllegalArgumentException if parameters are out of range. - * @see SimpleTimeZone - */ - public void setStartRule(int month, int day, int dayOfWeek, int time) - { - this.startMode = checkRule(month, day, dayOfWeek); - this.startMonth = month; - this.startDay = day; - this.startDayOfWeek = Math.abs(dayOfWeek); - this.startTime = time; - this.startTimeMode = WALL_TIME; - } - - /** - * Sets the daylight savings start rule. You must also set the - * end rule with <code>setEndRule</code> or the result of - * getOffset is undefined. For the parameters see the ten-argument - * constructor above. - * - * Note that this API isn't incredibly well specified. It appears that the - * after flag must override the parameters, since normally, the day and - * dayofweek can select this. I.e., if day < 0 and dayOfWeek < 0, on or - * before mode is chosen. But if after == true, this implementation - * overrides the signs of the other arguments. And if dayOfWeek == 0, it - * falls back to the behavior in the other APIs. I guess this should be - * checked against Sun's implementation. - * - * @param month The month where daylight savings start, zero - * based. You should use the constants in Calendar. - * @param day A day of month or day of week in month. - * @param dayOfWeek The day of week where daylight savings start. - * @param time The time in milliseconds standard time where daylight - * savings start. - * @param after If true, day and dayOfWeek specify first day of week on or - * after day, else first day of week on or before. - * @since 1.2 - * @see SimpleTimeZone - */ - public void setStartRule(int month, int day, int dayOfWeek, int time, - boolean after) - { - if (after) - setStartRule(month, day, -dayOfWeek, time); - else - setStartRule(month, -day, -dayOfWeek, time); - } - - /** - * Sets the daylight savings start rule. You must also set the - * end rule with <code>setEndRule</code> or the result of - * getOffset is undefined. For the parameters see the ten-argument - * constructor above. - * - * @param month The month where daylight savings start, zero - * based. You should use the constants in Calendar. - * @param day A day of month or day of week in month. - * @param time The time in milliseconds standard time where daylight - * savings start. - * @see SimpleTimeZone - * @since 1.2 - */ - public void setStartRule(int month, int day, int time) - { - setStartRule(month, day, 0, time); - } - - /** - * Sets the daylight savings end rule. You must also set the - * start rule with <code>setStartRule</code> or the result of - * getOffset is undefined. For the parameters see the ten-argument - * constructor above. - * - * @param month The end month of daylight savings. - * @param day A day in month, or a day of week in month. - * @param dayOfWeek A day of week, when daylight savings ends. - * @param time A time in millis in standard time. - * @see #setStartRule(int, int, int, int) - */ - public void setEndRule(int month, int day, int dayOfWeek, int time) - { - this.endMode = checkRule(month, day, dayOfWeek); - this.endMonth = month; - this.endDay = day; - this.endDayOfWeek = Math.abs(dayOfWeek); - this.endTime = time; - this.endTimeMode = WALL_TIME; - useDaylight = true; - } - - /** - * Sets the daylight savings end rule. You must also set the - * start rule with <code>setStartRule</code> or the result of - * getOffset is undefined. For the parameters see the ten-argument - * constructor above. - * - * Note that this API isn't incredibly well specified. It appears that the - * after flag must override the parameters, since normally, the day and - * dayofweek can select this. I.e., if day < 0 and dayOfWeek < 0, on or - * before mode is chosen. But if after == true, this implementation - * overrides the signs of the other arguments. And if dayOfWeek == 0, it - * falls back to the behavior in the other APIs. I guess this should be - * checked against Sun's implementation. - * - * @param month The end month of daylight savings. - * @param day A day in month, or a day of week in month. - * @param dayOfWeek A day of week, when daylight savings ends. - * @param time A time in millis in standard time. - * @param after If true, day and dayOfWeek specify first day of week on or - * after day, else first day of week on or before. - * @since 1.2 - * @see #setStartRule(int, int, int, int, boolean) - */ - public void setEndRule(int month, int day, int dayOfWeek, int time, - boolean after) - { - if (after) - setEndRule(month, day, -dayOfWeek, time); - else - setEndRule(month, -day, -dayOfWeek, time); - } - - /** - * Sets the daylight savings end rule. You must also set the - * start rule with <code>setStartRule</code> or the result of - * getOffset is undefined. For the parameters see the ten-argument - * constructor above. - * - * @param month The end month of daylight savings. - * @param day A day in month, or a day of week in month. - * @param time A time in millis in standard time. - * @see #setStartRule(int, int, int) - */ - public void setEndRule(int month, int day, int time) - { - setEndRule(month, day, 0, time); - } - - /** - * 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. - * - * In the standard JDK the results given by this method may result in - * inaccurate results at the end of February or the beginning of March. - * To avoid this, you should use Calendar instead: - * <code>offset = cal.get(Calendar.ZONE_OFFSET) - * + cal.get(Calendar.DST_OFFSET);</code> - * - * This version doesn't suffer this inaccuracy. - * - * The arguments don't follow the approach for setting start and end rules. - * The day must be a positive number and dayOfWeek must be a positive value - * from Calendar. dayOfWeek is redundant, but must match the other values - * or an inaccurate result may be returned. - * - * @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; this must match the other fields. - * @param millis the millis in the day (in local standard time) - * @return the time zone offset in milliseconds. - * @throws IllegalArgumentException if arguments are incorrect. - */ - public int getOffset(int era, int year, int month, int day, int dayOfWeek, - int millis) - { - int daysInMonth = getDaysInMonth(month, year); - if (day < 1 || day > daysInMonth) - throw new IllegalArgumentException("day out of range"); - if (dayOfWeek < Calendar.SUNDAY || dayOfWeek > Calendar.SATURDAY) - throw new IllegalArgumentException("dayOfWeek out of range"); - if (month < Calendar.JANUARY || month > Calendar.DECEMBER) - throw new IllegalArgumentException("month out of range:" + month); - - // This method is called by Calendar, so we mustn't use that class. - int daylightSavings = 0; - if (useDaylight && era == GregorianCalendar.AD && year >= startYear) - { - int orig_year = year; - int time = startTime + (startTimeMode == UTC_TIME ? rawOffset : 0); - // This does only work for Gregorian calendars :-( - // This is mainly because setStartYear doesn't take an era. - boolean afterStart = ! isBefore(year, month, day, dayOfWeek, millis, - startMode, startMonth, startDay, - startDayOfWeek, time); - millis += dstSavings; - if (millis >= 24 * 60 * 60 * 1000) - { - millis -= 24 * 60 * 60 * 1000; - dayOfWeek = (dayOfWeek % 7) + 1; - if (++day > daysInMonth) - { - day = 1; - if (month++ == Calendar.DECEMBER) - { - month = Calendar.JANUARY; - year++; - } - } - } - time = endTime + (endTimeMode == UTC_TIME ? rawOffset : 0); - if (endTimeMode != WALL_TIME) - time += dstSavings; - boolean beforeEnd = isBefore(year, month, day, dayOfWeek, millis, - endMode, endMonth, endDay, endDayOfWeek, - time); - - if (year != orig_year) - afterStart = false; - if (startMonth < endMonth) - // use daylight savings, if the date is after the start of - // savings, and before the end of savings. - daylightSavings = afterStart && beforeEnd ? dstSavings : 0; - else - // use daylight savings, if the date is before the end of - // savings, or after the start of savings. - daylightSavings = beforeEnd || afterStart ? dstSavings : 0; - } - return rawOffset + daylightSavings; - } - - /** - * Returns the time zone offset to GMT in milliseconds, ignoring - * day light savings. - * @return the time zone offset. - */ - public int getRawOffset() - { - return rawOffset; - } - - /** - * Sets the standard time zone offset to GMT. - * @param rawOffset The time offset from GMT in milliseconds. - */ - public void setRawOffset(int rawOffset) - { - this.rawOffset = rawOffset; - } - - /** - * 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. - * @return the daylight savings offset in milliseconds. - * - * @since 1.2 - */ - public int getDSTSavings() - { - return dstSavings; - } - - /** - * Sets the daylight savings offset. This is a positive offset in - * milliseconds with respect to standard time. - * - * @param dstSavings the daylight savings offset in milliseconds. - * - * @since 1.2 - */ - public void setDSTSavings(int dstSavings) - { - if (dstSavings <= 0) - throw new IllegalArgumentException("illegal value for dstSavings"); - - this.dstSavings = dstSavings; - } - - /** - * Returns if this time zone uses daylight savings time. - * @return true, if we use daylight savings time, false otherwise. - */ - public boolean useDaylightTime() - { - return useDaylight; - } - - /** - * Returns the number of days in the given month. - * Uses gregorian rules prior to 1582 (The default and earliest cutover) - * @param month The month, zero based; use one of the Calendar constants. - * @param year The year. - */ - private int getDaysInMonth(int month, int year) - { - if (month == Calendar.FEBRUARY) - { - if ((year & 3) != 0) - return 28; - - // Assume default Gregorian cutover, - // all years prior to this must be Julian - if (year < 1582) - return 29; - - // Gregorian rules - return ((year % 100) != 0 || (year % 400) == 0) ? 29 : 28; - } - else - return monthArr[month]; - } - - /** - * Checks if the date given in calXXXX, is before the change between - * dst and standard time. - * @param calYear the year of the date to check (for leap day checking). - * @param calMonth the month of the date to check. - * @param calDayOfMonth the day of month of the date to check. - * @param calDayOfWeek the day of week of the date to check. - * @param calMillis the millis of day of the date to check (standard time). - * @param mode the change mode; same semantic as startMode. - * @param month the change month; same semantic as startMonth. - * @param day the change day; same semantic as startDay. - * @param dayOfWeek the change day of week; - * @param millis the change time in millis since midnight standard time. - * same semantic as startDayOfWeek. - * @return true, if cal is before the change, false if cal is on - * or after the change. - */ - private boolean isBefore(int calYear, int calMonth, int calDayOfMonth, - int calDayOfWeek, int calMillis, int mode, - int month, int day, int dayOfWeek, int millis) - { - // This method is called by Calendar, so we mustn't use that class. - // We have to do all calculations by hand. - // check the months: - // XXX - this is not correct: - // for the DOW_GE_DOM and DOW_LE_DOM modes the change date may - // be in a different month. - if (calMonth != month) - return calMonth < month; - - // check the day: - switch (mode) - { - case DOM_MODE: - if (calDayOfMonth != day) - return calDayOfMonth < day; - break; - case DOW_IN_MONTH_MODE: - { - // This computes the day of month of the day of type - // "dayOfWeek" that lies in the same (sunday based) week as cal. - calDayOfMonth += (dayOfWeek - calDayOfWeek); - - // Now we convert it to 7 based number (to get a one based offset - // after dividing by 7). If we count from the end of the - // month, we get want a -7 based number counting the days from - // the end: - if (day < 0) - calDayOfMonth -= getDaysInMonth(calMonth, calYear) + 7; - else - calDayOfMonth += 6; - - // day > 0 day < 0 - // S M T W T F S S M T W T F S - // 7 8 9 10 11 12 -36-35-34-33-32-31 - // 13 14 15 16 17 18 19 -30-29-28-27-26-25-24 - // 20 21 22 23 24 25 26 -23-22-21-20-19-18-17 - // 27 28 29 30 31 32 33 -16-15-14-13-12-11-10 - // 34 35 36 -9 -8 -7 - // Now we calculate the day of week in month: - int week = calDayOfMonth / 7; - - // day > 0 day < 0 - // S M T W T F S S M T W T F S - // 1 1 1 1 1 1 -5 -5 -4 -4 -4 -4 - // 1 2 2 2 2 2 2 -4 -4 -4 -3 -3 -3 -3 - // 2 3 3 3 3 3 3 -3 -3 -3 -2 -2 -2 -2 - // 3 4 4 4 4 4 4 -2 -2 -2 -1 -1 -1 -1 - // 4 5 5 -1 -1 -1 - if (week != day) - return week < day; - - if (calDayOfWeek != dayOfWeek) - return calDayOfWeek < dayOfWeek; - - // daylight savings starts/ends on the given day. - break; - } - case DOW_LE_DOM_MODE: - // The greatest sunday before or equal December, 12 - // is the same as smallest sunday after or equal December, 6. - day = Math.abs(day) - 6; - case DOW_GE_DOM_MODE: - // Calculate the day of month of the day of type - // "dayOfWeek" that lies before (or on) the given date. - calDayOfMonth -= (calDayOfWeek < dayOfWeek ? 7 : 0) + calDayOfWeek - - dayOfWeek; - if (calDayOfMonth < day) - return true; - if (calDayOfWeek != dayOfWeek || calDayOfMonth >= day + 7) - return false; - - // now we have the same day - break; - } - - // the millis decides: - return (calMillis < millis); - } - - /** - * Determines if the given date is in daylight savings time. - * @return true, if it is in daylight savings time, false otherwise. - */ - public boolean inDaylightTime(Date date) - { - Calendar cal = Calendar.getInstance(this); - cal.setTime(date); - return (cal.get(Calendar.DST_OFFSET) != 0); - } - - /** - * Generates the hashCode for the SimpleDateFormat object. It is - * the rawOffset, possibly, if useDaylightSavings is true, xored - * with startYear, startMonth, startDayOfWeekInMonth, ..., endTime. - */ - public synchronized int hashCode() - { - return rawOffset - ^ (useDaylight - ? startMonth ^ startDay ^ startDayOfWeek ^ startTime ^ endMonth - ^ endDay ^ endDayOfWeek ^ endTime : 0); - } - - public synchronized boolean equals(Object o) - { - if (this == o) - return true; - if (! (o instanceof SimpleTimeZone)) - return false; - SimpleTimeZone zone = (SimpleTimeZone) o; - if (zone.hashCode() != hashCode() || ! getID().equals(zone.getID()) - || rawOffset != zone.rawOffset || useDaylight != zone.useDaylight) - return false; - if (! useDaylight) - return true; - return (startYear == zone.startYear && startMonth == zone.startMonth - && startDay == zone.startDay - && startDayOfWeek == zone.startDayOfWeek - && startTime == zone.startTime - && startTimeMode == zone.startTimeMode && endMonth == zone.endMonth - && endDay == zone.endDay && endDayOfWeek == zone.endDayOfWeek - && endTime == zone.endTime && endTimeMode == zone.endTimeMode); - } - - /** - * 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 other object is a SimpleTimeZone, - * the raw offsets and useDaylight are identical and if useDaylight - * is true, also the start and end datas are identical. - * @return true if this zone uses the same rule. - */ - public boolean hasSameRules(TimeZone other) - { - if (this == other) - return true; - if (! (other instanceof SimpleTimeZone)) - return false; - SimpleTimeZone zone = (SimpleTimeZone) other; - if (zone.hashCode() != hashCode() || rawOffset != zone.rawOffset - || useDaylight != zone.useDaylight) - return false; - if (! useDaylight) - return true; - return (startYear == zone.startYear && startMonth == zone.startMonth - && startDay == zone.startDay - && startDayOfWeek == zone.startDayOfWeek - && startTime == zone.startTime - && startTimeMode == zone.startTimeMode && endMonth == zone.endMonth - && endDay == zone.endDay && endDayOfWeek == zone.endDayOfWeek - && endTime == zone.endTime && endTimeMode == zone.endTimeMode); - } - - /** - * Returns a string representation of this SimpleTimeZone object. - * @return a string representation of this SimpleTimeZone object. - */ - public String toString() - { - // the test for useDaylight is an incompatibility to jdk1.2, but - // I think this shouldn't hurt. - return getClass().getName() + "[" + "id=" + getID() + ",offset=" - + rawOffset + ",dstSavings=" + dstSavings + ",useDaylight=" - + useDaylight - + (useDaylight - ? ",startYear=" + startYear + ",startMode=" + startMode - + ",startMonth=" + startMonth + ",startDay=" + startDay - + ",startDayOfWeek=" + startDayOfWeek + ",startTime=" - + startTime + ",startTimeMode=" + startTimeMode + ",endMode=" - + endMode + ",endMonth=" + endMonth + ",endDay=" + endDay - + ",endDayOfWeek=" + endDayOfWeek + ",endTime=" + endTime - + ",endTimeMode=" + endTimeMode : "") + "]"; - } - - /** - * Reads a serialized simple time zone from stream. - * @see #writeObject - */ - private void readObject(java.io.ObjectInputStream input) - throws java.io.IOException, ClassNotFoundException - { - input.defaultReadObject(); - if (serialVersionOnStream == 0) - { - // initialize the new fields to default values. - dstSavings = 60 * 60 * 1000; - endMode = DOW_IN_MONTH_MODE; - startMode = DOW_IN_MONTH_MODE; - startTimeMode = WALL_TIME; - endTimeMode = WALL_TIME; - serialVersionOnStream = 2; - } - else - { - int length = input.readInt(); - byte[] byteArray = new byte[length]; - input.read(byteArray, 0, length); - if (length >= 4) - { - // Lets hope that Sun does extensions to the serialized - // form in a sane manner. - startDay = byteArray[0]; - startDayOfWeek = byteArray[1]; - endDay = byteArray[2]; - endDayOfWeek = byteArray[3]; - } - } - } - - /** - * Serializes this object to a stream. @serialdata The object is - * first written in the old JDK 1.1 format, so that it can be read - * by the old classes. This means, that the - * <code>start/endDay(OfWeek)</code>-Fields are written in the - * DOW_IN_MONTH_MODE rule, since this was the only supported rule - * in 1.1. - * - * In the optional section, we write first the length of an byte - * array as int and afterwards the byte array itself. The byte - * array contains in this release four elements, namely the real - * startDay, startDayOfWeek endDay, endDayOfWeek in that Order. - * These fields are needed, because for compatibility reasons only - * approximative values are written to the required section, as - * described above. - */ - private void writeObject(java.io.ObjectOutputStream output) - throws java.io.IOException - { - byte[] byteArray = new byte[] - { - (byte) startDay, (byte) startDayOfWeek, (byte) endDay, - (byte) endDayOfWeek - }; - - /* calculate the approximation for JDK 1.1 */ - switch (startMode) - { - case DOM_MODE: - startDayOfWeek = Calendar.SUNDAY; // random day of week - - // fall through - case DOW_GE_DOM_MODE: - case DOW_LE_DOM_MODE: - startDay = (startDay + 6) / 7; - } - switch (endMode) - { - case DOM_MODE: - endDayOfWeek = Calendar.SUNDAY; - - // fall through - case DOW_GE_DOM_MODE: - case DOW_LE_DOM_MODE: - endDay = (endDay + 6) / 7; - } - - // the required part: - output.defaultWriteObject(); - // the optional part: - output.writeInt(byteArray.length); - output.write(byteArray, 0, byteArray.length); - } -} diff --git a/libjava/classpath/java/util/SortedMap.java b/libjava/classpath/java/util/SortedMap.java deleted file mode 100644 index 2b98848..0000000 --- a/libjava/classpath/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, 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; - -/** - * 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<K, V> extends Map<K, V> -{ - /** - * Returns the comparator used in sorting this map, or null if it is - * the keys' natural ordering. - * - * @return the sorting comparator - */ - Comparator<? super K> comparator(); - - /** - * Returns the first (lowest sorted) key in the map. - * - * @return the first key - * @throws NoSuchElementException if this map is empty. - */ - K 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<K, V> headMap(K toKey); - - /** - * Returns the last (highest sorted) key in the map. - * - * @return the last key - * @throws NoSuchElementException if this map is empty. - */ - K 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<K, V> subMap(K fromKey, K 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<K, V> tailMap(K fromKey); -} diff --git a/libjava/classpath/java/util/SortedSet.java b/libjava/classpath/java/util/SortedSet.java deleted file mode 100644 index 89f155a..0000000 --- a/libjava/classpath/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, 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; - -/** - * 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<E> extends Set<E> -{ - /** - * Returns the comparator used in sorting this set, or null if it is - * the elements' natural ordering. - * - * @return the sorting comparator - */ - Comparator<? super E> comparator(); - - /** - * Returns the first (lowest sorted) element in the set. - * - * @return the first element - * @throws NoSuchElementException if the set is empty. - */ - E 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<E> headSet(E toElement); - - /** - * Returns the last (highest sorted) element in the set. - * - * @return the last element - * @throws NoSuchElementException if the set is empty. - */ - E 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<E> subSet(E fromElement, E 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<E> tailSet(E fromElement); -} diff --git a/libjava/classpath/java/util/Stack.java b/libjava/classpath/java/util/Stack.java deleted file mode 100644 index 1d87928..0000000 --- a/libjava/classpath/java/util/Stack.java +++ /dev/null @@ -1,161 +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, 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; - -/* 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<T> extends Vector<T> -{ - // 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 T push(T 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 - */ - @SuppressWarnings("unchecked") - public synchronized T pop() - { - if (elementCount == 0) - throw new EmptyStackException(); - - modCount++; - T obj = (T) 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 - */ - @SuppressWarnings("unchecked") - public synchronized T peek() - { - if (elementCount == 0) - throw new EmptyStackException(); - - return (T) 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/classpath/java/util/StringTokenizer.java b/libjava/classpath/java/util/StringTokenizer.java deleted file mode 100644 index d16ec9b..0000000 --- a/libjava/classpath/java/util/StringTokenizer.java +++ /dev/null @@ -1,269 +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<Object> -{ - // 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; - this.delim = delim; - 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/classpath/java/util/TimeZone.java b/libjava/classpath/java/util/TimeZone.java deleted file mode 100644 index a8b2b51..0000000 --- a/libjava/classpath/java/util/TimeZone.java +++ /dev/null @@ -1,1781 +0,0 @@ -/* java.util.TimeZone - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2012 - 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 gnu.classpath.SystemProperties; -import gnu.java.lang.CPStringBuilder; -import gnu.java.util.ZoneInfo; - -import java.io.File; -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 = AccessController.doPrivileged - (new PrivilegedAction<TimeZone>() - { - public TimeZone 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 = getTimeZone ("GMT"); - - return zone; - } - }); - } - - return defaultZone0; - } - - private static final long serialVersionUID = 3581463369166924961L; - - /** - * Flag whether zoneinfo data should be used, - * otherwise builtin timezone data will be provided. - */ - private static String zoneinfo_dir; - - /** - * Cached copy of getAvailableIDs(). - */ - private static String[] availableIDs = null; - - /** - * JDK 1.1.x compatibility aliases. - */ - private static HashMap<String,String> aliases0; - - /** - * HashMap for timezones by ID. - */ - private static HashMap<String,TimeZone> timezones0; - /* initialize this static field lazily to overhead if - * it is not needed: - */ - // Package-private to avoid a trampoline. - static HashMap<String,TimeZone> timezones() - { - if (timezones0 == null) - { - HashMap<String,TimeZone> timezones = new HashMap<String,TimeZone>(); - timezones0 = timezones; - - zoneinfo_dir = SystemProperties.getProperty("gnu.java.util.zoneinfo.dir"); - if (zoneinfo_dir != null && !new File(zoneinfo_dir).isDirectory()) - zoneinfo_dir = null; - - if (zoneinfo_dir != null) - { - aliases0 = new HashMap<String,String>(); - - // These deprecated aliases for JDK 1.1.x compatibility - // should take precedence over data files read from - // /usr/share/zoneinfo. - aliases0.put("ACT", "Australia/Darwin"); - aliases0.put("AET", "Australia/Sydney"); - aliases0.put("AGT", "America/Argentina/Buenos_Aires"); - aliases0.put("ART", "Africa/Cairo"); - aliases0.put("AST", "America/Juneau"); - aliases0.put("BST", "Asia/Colombo"); - aliases0.put("CAT", "Africa/Gaborone"); - aliases0.put("CNT", "America/St_Johns"); - aliases0.put("CST", "CST6CDT"); - aliases0.put("CTT", "Asia/Brunei"); - aliases0.put("EAT", "Indian/Comoro"); - aliases0.put("ECT", "CET"); - aliases0.put("EST", "EST5EDT"); - aliases0.put("EST5", "EST5EDT"); - aliases0.put("IET", "EST5EDT"); - aliases0.put("IST", "Asia/Calcutta"); - aliases0.put("JST", "Asia/Seoul"); - aliases0.put("MIT", "Pacific/Niue"); - aliases0.put("MST", "MST7MDT"); - aliases0.put("MST7", "MST7MDT"); - aliases0.put("NET", "Indian/Mauritius"); - aliases0.put("NST", "Pacific/Auckland"); - aliases0.put("PLT", "Indian/Kerguelen"); - aliases0.put("PNT", "MST7MDT"); - aliases0.put("PRT", "America/Anguilla"); - aliases0.put("PST", "PST8PDT"); - aliases0.put("SST", "Pacific/Ponape"); - aliases0.put("VST", "Asia/Bangkok"); - return 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.MARCH, 2, Calendar.SUNDAY, 2000 * 3600, - Calendar.NOVEMBER, 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.MARCH, 2, Calendar.SUNDAY, 2000 * 3600, - Calendar.NOVEMBER, 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, "America/Tijuana", - Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("America/Tijuana", tz); - tz = new SimpleTimeZone - (-8000 * 3600, "PST", - Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600, - Calendar.NOVEMBER, 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/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, "America/Chihuahua", - Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("America/Chihuahua", tz); - timezones0.put("America/Mazatlan", 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 - (-7000 * 3600, "MST", - Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600, - Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("MST", tz); - timezones0.put("MST7MDT", tz); - timezones0.put("America/Boise", tz); - timezones0.put("America/Cambridge_Bay", tz); - timezones0.put("America/Denver", tz); - timezones0.put("America/Edmonton", tz); - timezones0.put("America/Inuvik", tz); - timezones0.put("America/Shiprock", tz); - timezones0.put("America/Yellowknife", tz); - tz = new SimpleTimeZone - (-6000 * 3600, "America/Cancun", - Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("America/Cancun", tz); - timezones0.put("America/Merida", tz); - timezones0.put("America/Mexico_City", tz); - timezones0.put("America/Monterrey", 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, "CST", - Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600, - Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("CST", tz); - timezones0.put("CST6CDT", tz); - timezones0.put("America/Chicago", tz); - timezones0.put("America/Indiana/Knox", tz); - timezones0.put("America/Indiana/Petersburg", tz); - timezones0.put("America/Indiana/Vincennes", tz); - timezones0.put("America/Menominee", tz); - timezones0.put("America/North_Dakota/Center", tz); - timezones0.put("America/North_Dakota/New_Salem", tz); - timezones0.put("America/Rainy_River", tz); - timezones0.put("America/Rankin_Inlet", tz); - timezones0.put("America/Winnipeg", tz); - tz = new SimpleTimeZone - (-6000 * 3600, "Pacific/Easter", - Calendar.OCTOBER, 2, Calendar.SATURDAY, 22000 * 3600, - Calendar.MARCH, 2, Calendar.SATURDAY, 22000 * 3600); - timezones0.put("Pacific/Easter", tz); - tz = new SimpleTimeZone(-5000 * 3600, "EST5"); - timezones0.put("EST5", tz); - timezones0.put("IET", tz); - timezones0.put("America/Atikokan", tz); - timezones0.put("America/Bogota", tz); - timezones0.put("America/Cayman", tz); - timezones0.put("America/Eirunepe", tz); - timezones0.put("America/Guayaquil", tz); - timezones0.put("America/Jamaica", tz); - timezones0.put("America/Lima", tz); - timezones0.put("America/Panama", tz); - timezones0.put("America/Rio_Branco", tz); - tz = new SimpleTimeZone - (-5000 * 3600, "America/Havana", - Calendar.APRIL, 1, Calendar.SUNDAY, 0 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 1000 * 3600); - timezones0.put("America/Havana", 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/Port-au-Prince", tz); - tz = new SimpleTimeZone - (-5000 * 3600, "EST", - Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600, - Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("EST", tz); - timezones0.put("EST5EDT", tz); - timezones0.put("America/Detroit", tz); - timezones0.put("America/Indiana/Indianapolis", tz); - timezones0.put("America/Indiana/Marengo", tz); - timezones0.put("America/Indiana/Vevay", tz); - timezones0.put("America/Iqaluit", tz); - timezones0.put("America/Kentucky/Louisville", tz); - timezones0.put("America/Kentucky/Monticello", 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/Pangnirtung", tz); - timezones0.put("America/Thunder_Bay", tz); - timezones0.put("America/Toronto", tz); - tz = new SimpleTimeZone - (-4000 * 3600, "America/Asuncion", - Calendar.OCTOBER, 3, Calendar.SUNDAY, 0 * 3600, - Calendar.MARCH, 2, Calendar.SUNDAY, 0 * 3600); - timezones0.put("America/Asuncion", 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/Blanc-Sablon", 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/Campo_Grande", - Calendar.NOVEMBER, 1, Calendar.SUNDAY, 0 * 3600, - Calendar.FEBRUARY, -1, Calendar.SUNDAY, 0 * 3600); - timezones0.put("America/Campo_Grande", tz); - timezones0.put("America/Cuiaba", tz); - tz = new SimpleTimeZone - (-4000 * 3600, "America/Goose_Bay", - Calendar.MARCH, 2, Calendar.SUNDAY, 60000, - Calendar.NOVEMBER, 1, Calendar.SUNDAY, 60000); - timezones0.put("America/Goose_Bay", tz); - tz = new SimpleTimeZone - (-4000 * 3600, "America/Glace_Bay", - Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600, - Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("America/Glace_Bay", tz); - timezones0.put("America/Halifax", tz); - timezones0.put("America/Moncton", 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, 1, Calendar.SUNDAY, 2000 * 3600, - Calendar.APRIL, 3, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("Atlantic/Stanley", tz); - tz = new SimpleTimeZone - (-3500 * 3600, "CNT", - Calendar.MARCH, 2, Calendar.SUNDAY, 60000, - Calendar.NOVEMBER, 1, Calendar.SUNDAY, 60000); - timezones0.put("CNT", tz); - timezones0.put("America/St_Johns", tz); - tz = new SimpleTimeZone - (-3000 * 3600, "America/Godthab", - Calendar.MARCH, 30, -Calendar.SATURDAY, 22000 * 3600, - Calendar.OCTOBER, 30, -Calendar.SATURDAY, 23000 * 3600); - timezones0.put("America/Godthab", tz); - tz = new SimpleTimeZone - (-3000 * 3600, "America/Miquelon", - Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600, - Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("America/Miquelon", tz); - tz = new SimpleTimeZone - (-3000 * 3600, "America/Montevideo", - Calendar.OCTOBER, 1, Calendar.SUNDAY, 2000 * 3600, - Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("America/Montevideo", tz); - tz = new SimpleTimeZone - (-3000 * 3600, "America/Sao_Paulo", - Calendar.NOVEMBER, 1, Calendar.SUNDAY, 0 * 3600, - Calendar.FEBRUARY, -1, Calendar.SUNDAY, 0 * 3600); - timezones0.put("America/Sao_Paulo", tz); - tz = new SimpleTimeZone(-3000 * 3600, "AGT"); - timezones0.put("AGT", tz); - timezones0.put("America/Araguaina", tz); - timezones0.put("America/Argentina/Buenos_Aires", tz); - timezones0.put("America/Argentina/Catamarca", tz); - timezones0.put("America/Argentina/Cordoba", tz); - timezones0.put("America/Argentina/Jujuy", tz); - timezones0.put("America/Argentina/La_Rioja", tz); - timezones0.put("America/Argentina/Mendoza", tz); - timezones0.put("America/Argentina/Rio_Gallegos", tz); - timezones0.put("America/Argentina/San_Juan", tz); - timezones0.put("America/Argentina/Tucuman", tz); - timezones0.put("America/Argentina/Ushuaia", tz); - timezones0.put("America/Bahia", tz); - timezones0.put("America/Belem", tz); - timezones0.put("America/Cayenne", tz); - timezones0.put("America/Fortaleza", tz); - timezones0.put("America/Maceio", tz); - timezones0.put("America/Paramaribo", tz); - timezones0.put("America/Recife", tz); - timezones0.put("Antarctica/Rothera", 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, 1000 * 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); - 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("America/Danmarkshavn", tz); - timezones0.put("Atlantic/Reykjavik", tz); - timezones0.put("Atlantic/St_Helena", tz); - tz = new SimpleTimeZone - (0 * 3600, "WET", - Calendar.MARCH, -1, Calendar.SUNDAY, 1000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); - timezones0.put("WET", tz); - timezones0.put("Atlantic/Canary", tz); - timezones0.put("Atlantic/Faroe", tz); - timezones0.put("Atlantic/Madeira", tz); - timezones0.put("Europe/Dublin", tz); - timezones0.put("Europe/Guernsey", tz); - timezones0.put("Europe/Isle_of_Man", tz); - timezones0.put("Europe/Jersey", tz); - timezones0.put("Europe/Lisbon", tz); - timezones0.put("Europe/London", 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); - 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, 3000 * 3600); - timezones0.put("CET", tz); - timezones0.put("ECT", tz); - timezones0.put("MET", tz); - timezones0.put("Africa/Ceuta", tz); - timezones0.put("Africa/Tunis", tz); - timezones0.put("Arctic/Longyearbyen", tz); - timezones0.put("Atlantic/Jan_Mayen", 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/Podgorica", 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, 24000 * 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("Asia/Jerusalem", tz); - tz = new SimpleTimeZone - (2000 * 3600, "Asia/Amman", - Calendar.MARCH, -1, Calendar.THURSDAY, 0 * 3600, - Calendar.OCTOBER, -1, Calendar.FRIDAY, 1000 * 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, 1, 0, 0 * 3600, - Calendar.OCTOBER, 3, Calendar.FRIDAY, 0 * 3600); - timezones0.put("Asia/Gaza", tz); - tz = new SimpleTimeZone - (2000 * 3600, "EET", - Calendar.MARCH, -1, Calendar.SUNDAY, 3000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 4000 * 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/Mariehamn", tz); - timezones0.put("Europe/Nicosia", tz); - timezones0.put("Europe/Riga", tz); - timezones0.put("Europe/Simferopol", tz); - timezones0.put("Europe/Sofia", tz); - timezones0.put("Europe/Tallinn", tz); - timezones0.put("Europe/Uzhgorod", tz); - timezones0.put("Europe/Vilnius", 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, 3000 * 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, 4000 * 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, 3000 * 3600); - timezones0.put("Europe/Moscow", tz); - timezones0.put("Europe/Volgograd", tz); - tz = new SimpleTimeZone(3000 * 3600, "EAT"); - timezones0.put("EAT", tz); - timezones0.put("Africa/Addis_Ababa", tz); - timezones0.put("Africa/Asmara", 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, 4000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 5000 * 3600); - timezones0.put("Asia/Baku", tz); - tz = new SimpleTimeZone - (4000 * 3600, "Asia/Yerevan", - Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 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("Asia/Tbilisi", 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/Yekaterinburg", - Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600); - timezones0.put("Asia/Yekaterinburg", tz); - tz = new SimpleTimeZone(5000 * 3600, "PLT"); - timezones0.put("PLT", tz); - timezones0.put("Asia/Aqtau", tz); - timezones0.put("Asia/Aqtobe", tz); - timezones0.put("Asia/Ashgabat", tz); - timezones0.put("Asia/Dushanbe", tz); - timezones0.put("Asia/Karachi", tz); - timezones0.put("Asia/Oral", tz); - timezones0.put("Asia/Samarkand", tz); - timezones0.put("Asia/Tashkent", tz); - timezones0.put("Indian/Kerguelen", tz); - timezones0.put("Indian/Maldives", tz); - tz = new SimpleTimeZone(5500 * 3600, "BST"); - timezones0.put("BST", tz); - timezones0.put("IST", tz); - timezones0.put("Asia/Calcutta", tz); - timezones0.put("Asia/Colombo", tz); - tz = new SimpleTimeZone(5750 * 3600, "Asia/Katmandu"); - timezones0.put("Asia/Katmandu", tz); - tz = new SimpleTimeZone(6000 * 3600, "Antarctica/Mawson"); - timezones0.put("Antarctica/Mawson", tz); - timezones0.put("Antarctica/Vostok", tz); - timezones0.put("Asia/Almaty", tz); - timezones0.put("Asia/Bishkek", tz); - timezones0.put("Asia/Dhaka", tz); - timezones0.put("Asia/Qyzylorda", tz); - timezones0.put("Asia/Thimphu", tz); - timezones0.put("Indian/Chagos", tz); - tz = new SimpleTimeZone - (6000 * 3600, "Asia/Novosibirsk", - Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 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/Jakarta", tz); - timezones0.put("Asia/Phnom_Penh", tz); - timezones0.put("Asia/Pontianak", tz); - timezones0.put("Asia/Saigon", tz); - timezones0.put("Asia/Vientiane", tz); - timezones0.put("Indian/Christmas", tz); - tz = new SimpleTimeZone - (7000 * 3600, "Asia/Hovd", - Calendar.MARCH, -1, Calendar.SATURDAY, 2000 * 3600, - Calendar.SEPTEMBER, -1, Calendar.SATURDAY, 2000 * 3600); - timezones0.put("Asia/Hovd", tz); - tz = new SimpleTimeZone - (7000 * 3600, "Asia/Krasnoyarsk", - Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 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/Chongqing", 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/Macau", tz); - timezones0.put("Asia/Makassar", tz); - timezones0.put("Asia/Manila", tz); - timezones0.put("Asia/Shanghai", tz); - timezones0.put("Asia/Singapore", tz); - timezones0.put("Asia/Taipei", 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, 3000 * 3600); - timezones0.put("Asia/Irkutsk", tz); - tz = new SimpleTimeZone - (8000 * 3600, "Asia/Ulaanbaatar", - Calendar.MARCH, -1, Calendar.SATURDAY, 2000 * 3600, - Calendar.SEPTEMBER, -1, Calendar.SATURDAY, 2000 * 3600); - timezones0.put("Asia/Ulaanbaatar", tz); - tz = new SimpleTimeZone(8750 * 3600, "Australia/Eucla"); - timezones0.put("Australia/Eucla", tz); - tz = new SimpleTimeZone - (9000 * 3600, "Asia/Choibalsan", - Calendar.MARCH, -1, Calendar.SATURDAY, 2000 * 3600, - Calendar.SEPTEMBER, -1, Calendar.SATURDAY, 2000 * 3600); - timezones0.put("Asia/Choibalsan", 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, 3000 * 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, 3000 * 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); - tz = new SimpleTimeZone - (10000 * 3600, "Asia/Sakhalin", - Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, - Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600); - timezones0.put("Asia/Sakhalin", tz); - timezones0.put("Asia/Vladivostok", tz); - tz = new SimpleTimeZone - (10000 * 3600, "Australia/Currie", - Calendar.OCTOBER, 1, Calendar.SUNDAY, 2000 * 3600, - Calendar.MARCH, -1, Calendar.SUNDAY, 3000 * 3600); - timezones0.put("Australia/Currie", tz); - timezones0.put("Australia/Hobart", tz); - tz = new SimpleTimeZone - (10000 * 3600, "AET", - Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600, - Calendar.MARCH, -1, Calendar.SUNDAY, 3000 * 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, 3000 * 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, 3000 * 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, 3000 * 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, 3750 * 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)[(DST zone name)[DST offset]]] - * </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> - * Alternately, a POSIX-style TZ string can be given, defining the time zone: - * <code>std offset dst offset,date/time,date/time</code> - * See the glibc manual, or the man page for <code>tzset</code> for details - * of this format. - * <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) - { - String stdName = null; - int stdOffs; - int dstOffs; - try - { - int idLength = sysTimeZoneId.length(); - - int index = 0; - int prevIndex; - char c; - - // get std - do - c = sysTimeZoneId.charAt(index); - while (c != '+' && c != '-' && c != ',' && c != ':' - && ! Character.isDigit(c) && c != '\0' && ++index < idLength); - - if (index >= idLength) - return getTimeZoneInternal(sysTimeZoneId); - - stdName = sysTimeZoneId.substring(0, index); - prevIndex = index; - - // get the std offset - do - c = sysTimeZoneId.charAt(index++); - while ((c == '-' || c == '+' || c == ':' || Character.isDigit(c)) - && index < idLength); - if (index < idLength) - index--; - - { // convert the dst string to a millis number - String offset = sysTimeZoneId.substring(prevIndex, index); - prevIndex = index; - - if (offset.charAt(0) == '+' || offset.charAt(0) == '-') - stdOffs = parseTime(offset.substring(1)); - else - stdOffs = parseTime(offset); - - if (offset.charAt(0) == '-') - stdOffs = -stdOffs; - - // TZ timezone offsets are positive when WEST of the meridian. - stdOffs = -stdOffs; - } - - // Done yet? (Format: std offset) - if (index >= idLength) - { - // Do we have an existing timezone with that name and offset? - TimeZone tz = getTimeZoneInternal(stdName); - if (tz != null) - if (tz.getRawOffset() == stdOffs) - return tz; - - // Custom then. - return new SimpleTimeZone(stdOffs, stdName); - } - - // get dst - do - c = sysTimeZoneId.charAt(index); - while (c != '+' && c != '-' && c != ',' && c != ':' - && ! Character.isDigit(c) && c != '\0' && ++index < idLength); - - // Done yet? (Format: std offset dst) - if (index >= idLength) - { - // Do we have an existing timezone with that name and offset - // which has DST? - TimeZone tz = getTimeZoneInternal(stdName); - if (tz != null) - if (tz.getRawOffset() == stdOffs && tz.useDaylightTime()) - return tz; - - // Custom then. - return new SimpleTimeZone(stdOffs, stdName); - } - - // get the dst offset - prevIndex = index; - do - c = sysTimeZoneId.charAt(index++); - while ((c == '-' || c == '+' || c == ':' || Character.isDigit(c)) - && index < idLength); - if (index < idLength) - index--; - - if (index == prevIndex && (c == ',' || c == ';')) - { - // Missing dst offset defaults to one hour ahead of standard - // time. - dstOffs = stdOffs + 60 * 60 * 1000; - } - else - { // convert the dst string to a millis number - String offset = sysTimeZoneId.substring(prevIndex, index); - prevIndex = index; - - if (offset.charAt(0) == '+' || offset.charAt(0) == '-') - dstOffs = parseTime(offset.substring(1)); - else - dstOffs = parseTime(offset); - - if (offset.charAt(0) == '-') - dstOffs = -dstOffs; - - // TZ timezone offsets are positive when WEST of the meridian. - dstOffs = -dstOffs; - } - - // Done yet? (Format: std offset dst offset) - // FIXME: We don't support DST without a rule given. Should we? - if (index >= idLength) - { - // Time Zone existing with same name, dst and offsets? - TimeZone tz = getTimeZoneInternal(stdName); - if (tz != null) - if (tz.getRawOffset() == stdOffs && tz.useDaylightTime() - && tz.getDSTSavings() == (dstOffs - stdOffs)) - return tz; - - return new SimpleTimeZone(stdOffs, stdName); - } - - // get the DST rule - if (sysTimeZoneId.charAt(index) == ',' - || sysTimeZoneId.charAt(index) == ';') - { - index++; - int offs = index; - while (sysTimeZoneId.charAt(index) != ',' - && sysTimeZoneId.charAt(index) != ';') - index++; - String startTime = sysTimeZoneId.substring(offs, index); - index++; - String endTime = sysTimeZoneId.substring(index); - - index = startTime.indexOf('/'); - int startMillis; - int endMillis; - String startDate; - String endDate; - if (index != -1) - { - startDate = startTime.substring(0, index); - startMillis = parseTime(startTime.substring(index + 1)); - } - else - { - startDate = startTime; - // if time isn't given, default to 2:00:00 AM. - startMillis = 2 * 60 * 60 * 1000; - } - index = endTime.indexOf('/'); - if (index != -1) - { - endDate = endTime.substring(0, index); - endMillis = parseTime(endTime.substring(index + 1)); - } - else - { - endDate = endTime; - // if time isn't given, default to 2:00:00 AM. - endMillis = 2 * 60 * 60 * 1000; - } - - int[] start = getDateParams(startDate); - int[] end = getDateParams(endDate); - return new SimpleTimeZone(stdOffs, stdName, start[0], start[1], - start[2], startMillis, end[0], end[1], - end[2], endMillis, (dstOffs - stdOffs)); - } - } - - // FIXME: Produce a warning here? - catch (IndexOutOfBoundsException _) - { - } - catch (NumberFormatException _) - { - } - - return null; - } - - /** - * Parses and returns the params for a POSIX TZ date field, - * in the format int[]{ month, day, dayOfWeek }, following the - * SimpleTimeZone constructor rules. - */ - private static int[] getDateParams(String date) - { - int[] dayCount = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; - int month; - - if (date.charAt(0) == 'M' || date.charAt(0) == 'm') - { - int day; - - // Month, week of month, day of week - - // "Mm.w.d". d is between 0 (Sunday) and 6. Week w is - // between 1 and 5; Week 1 is the first week in which day d - // occurs and Week 5 specifies the last d day in the month. - // Month m is between 1 and 12. - - month = Integer.parseInt(date.substring(1, date.indexOf('.'))); - int week = Integer.parseInt(date.substring(date.indexOf('.') + 1, - date.lastIndexOf('.'))); - int dayOfWeek = Integer.parseInt(date.substring(date.lastIndexOf('.') - + 1)); - dayOfWeek++; // Java day of week is one-based, Sunday is first day. - - if (week == 5) - day = -1; // last day of month is -1 in java, 5 in TZ - else - { - // First day of week starting on or after. For example, - // to specify the second Sunday of April, set month to - // APRIL, day-of-month to 8, and day-of-week to -SUNDAY. - day = (week - 1) * 7 + 1; - dayOfWeek = -dayOfWeek; - } - - month--; // Java month is zero-based. - return new int[] { month, day, dayOfWeek }; - } - - // julian day, either zero-based 0<=n<=365 (incl feb 29) - // or one-based 1<=n<=365 (no feb 29) - int julianDay; // Julian day, - - if (date.charAt(0) != 'J' || date.charAt(0) != 'j') - { - julianDay = Integer.parseInt(date.substring(1)); - julianDay++; // make 1-based - // Adjust day count to include feb 29. - dayCount = new int[] - { - 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 - }; - } - else - // 1-based julian day - julianDay = Integer.parseInt(date); - - int i = 11; - while (i > 0) - if (dayCount[i] < julianDay) - break; - else - i--; - julianDay -= dayCount[i]; - month = i; - return new int[] { month, julianDay, 0 }; - } - - /** - * Parses a time field hh[:mm[:ss]], returning the result - * in milliseconds. No leading sign. - */ - private static int parseTime(String time) - { - int millis = 0; - int i = 0; - - while (i < time.length()) - if (time.charAt(i) == ':') - break; - else - i++; - millis = 60 * 60 * 1000 * Integer.parseInt(time.substring(0, i)); - if (i >= time.length()) - return millis; - - int iprev = ++i; - while (i < time.length()) - if (time.charAt(i) == ':') - break; - else - i++; - millis += 60 * 1000 * Integer.parseInt(time.substring(iprev, i)); - if (i >= time.length()) - return millis; - - millis += 1000 * Integer.parseInt(time.substring(++i)); - return millis; - } - - /** - * 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() + (dst ? getDSTSavings() : 0); - - CPStringBuilder sb = new CPStringBuilder(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. - */ - private static TimeZone getTimeZoneInternal(String ID) - { - // First check timezones hash - TimeZone tz = null; - TimeZone tznew = null; - for (int pass = 0; pass < 2; pass++) - { - synchronized (TimeZone.class) - { - tz = timezones().get(ID); - if (tz != null) - { - if (!tz.getID().equals(ID)) - { - // 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; - } - else if (tznew != null) - { - timezones().put(ID, tznew); - return tznew; - } - } - - if (pass == 1 || zoneinfo_dir == null) - return null; - - // aliases0 is never changing after first timezones(), so should - // be safe without synchronization. - String zonename = aliases0.get(ID); - if (zonename == null) - zonename = ID; - - // Read the file outside of the critical section, it is expensive. - tznew = ZoneInfo.readTZFile (ID, zoneinfo_dir - + File.separatorChar + zonename); - if (tznew == null) - return null; - } - - return null; - } - - /** - * 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. - */ - public static TimeZone getTimeZone(String ID) - { - // Check for custom IDs first - if (ID.startsWith("GMT") && ID.length() > 3) - { - 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)); - } - } - - // Custom IDs have to be normalized - CPStringBuilder sb = new CPStringBuilder(9); - sb.append("GMT"); - - sb.append(offset_direction >= 0 ? '+' : '-'); - sb.append((char) ('0' + hour / 10)); - sb.append((char) ('0' + hour % 10)); - sb.append(':'); - sb.append((char) ('0' + minute / 10)); - sb.append((char) ('0' + minute % 10)); - ID = sb.toString(); - - return new SimpleTimeZone((hour * (60 * 60 * 1000) - + minute * (60 * 1000)) - * offset_direction, ID); - } - catch (NumberFormatException e) - { - } - } - - TimeZone tz = getTimeZoneInternal(ID); - if (tz != null) - return tz; - - return new SimpleTimeZone(0, "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) - { - synchronized (TimeZone.class) - { - HashMap<String,TimeZone> h = timezones(); - int count = 0; - if (zoneinfo_dir == null) - { - Iterator<Map.Entry<String,TimeZone>> iter = h.entrySet().iterator(); - while (iter.hasNext()) - { - // Don't iterate the values, since we want to count - // doubled values (aliases) - Map.Entry<String,TimeZone> entry = iter.next(); - if (entry.getValue().getRawOffset() == rawOffset) - count++; - } - - String[] ids = new String[count]; - count = 0; - iter = h.entrySet().iterator(); - while (iter.hasNext()) - { - Map.Entry<String,TimeZone> entry = iter.next(); - if (entry.getValue().getRawOffset() == rawOffset) - ids[count++] = (String) entry.getKey(); - } - return ids; - } - } - - String[] s = getAvailableIDs(); - int count = 0; - for (int i = 0; i < s.length; i++) - { - TimeZone t = getTimeZoneInternal(s[i]); - if (t == null || t.getRawOffset() != rawOffset) - s[i] = null; - else - count++; - } - String[] ids = new String[count]; - count = 0; - for (int i = 0; i < s.length; i++) - if (s[i] != null) - ids[count++] = s[i]; - - return ids; - } - - private static int getAvailableIDs(File d, String prefix, ArrayList<String[]> list) - { - String[] files = d.list(); - int count = files.length; - boolean top = prefix.length() == 0; - list.add (files); - for (int i = 0; i < files.length; i++) - { - if (top - && (files[i].equals("posix") - || files[i].equals("right") - || files[i].endsWith(".tab") - || aliases0.get(files[i]) != null)) - { - files[i] = null; - count--; - continue; - } - - File f = new File(d, files[i]); - if (f.isDirectory()) - { - count += getAvailableIDs(f, prefix + files[i] - + File.separatorChar, list) - 1; - files[i] = null; - } - else - files[i] = prefix + files[i]; - } - return count; - } - - /** - * Gets all available IDs. - * @return An array of all supported IDs. - */ - public static String[] getAvailableIDs() - { - synchronized (TimeZone.class) - { - HashMap<String,TimeZone> h = timezones(); - if (zoneinfo_dir == null) - return h.keySet().toArray(new String[h.size()]); - - if (availableIDs != null) - { - String[] ids = new String[availableIDs.length]; - for (int i = 0; i < availableIDs.length; i++) - ids[i] = availableIDs[i]; - return ids; - } - - File d = new File(zoneinfo_dir); - ArrayList<String[]> list = new ArrayList<String[]>(30); - int count = getAvailableIDs(d, "", list) + aliases0.size(); - availableIDs = new String[count]; - String[] ids = new String[count]; - - count = 0; - for (int i = 0; i < list.size(); i++) - { - String[] s = list.get(i); - for (int j = 0; j < s.length; j++) - if (s[j] != null) - { - availableIDs[count] = s[j]; - ids[count++] = s[j]; - } - } - - Iterator<Map.Entry<String,String>> iter = aliases0.entrySet().iterator(); - while (iter.hasNext()) - { - Map.Entry<String,String> entry = iter.next(); - availableIDs[count] = entry.getKey(); - ids[count++] = entry.getKey(); - } - - return ids; - } - } - - /** - * 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/classpath/java/util/Timer.java b/libjava/classpath/java/util/Timer.java deleted file mode 100644 index 9902755..0000000 --- a/libjava/classpath/java/util/Timer.java +++ /dev/null @@ -1,704 +0,0 @@ -/* Timer.java -- Timer that runs TimerTasks at a later time. - Copyright (C) 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; - -/** - * 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(); - } - - /** - * Remove all canceled tasks from the queue. - */ - public synchronized int purge() - { - int removed = 0; - // Null out any elements that are canceled. Skip element 0 as - // it is the sentinel. - for (int i = elements; i > 0; --i) - { - if (heap[i].scheduled < 0) - { - ++removed; - - // Remove an element by pushing the appropriate child - // into place, and then iterating to the bottom of the - // tree. - int index = i; - while (heap[index] != null) - { - int child = 2 * index; - if (child >= heap.length) - { - // Off end; we're done. - heap[index] = null; - break; - } - - if (child + 1 >= heap.length || heap[child + 1] == null) - { - // Nothing -- we're done. - } - else if (heap[child] == null - || (heap[child].scheduled - > heap[child + 1].scheduled)) - ++child; - heap[index] = heap[child]; - index = child; - } - } - } - - // Make a new heap if we shrank enough. - int newLen = heap.length; - while (elements - removed + DEFAULT_SIZE / 2 <= newLen / 4) - newLen /= 2; - if (newLen != heap.length) - { - TimerTask[] newHeap = new TimerTask[newLen]; - System.arraycopy(heap, 0, newHeap, 0, elements + 1); - heap = newHeap; - } - - return removed; - } - } // 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 immediately. 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); - } - - /** - * Create a new Timer whose Thread has the indicated name. It will have - * normal priority and will not be a daemon thread. - * @param name the name of the Thread - * @since 1.5 - */ - public Timer(String name) - { - this(false, Thread.NORM_PRIORITY, name); - } - - /** - * Create a new Timer whose Thread has the indicated name. It will have - * normal priority. The boolean argument controls whether or not it - * will be a daemon thread. - * @param name the name of the Thread - * @param daemon true if the Thread should be a daemon thread - * @since 1.5 - */ - public Timer(String name, boolean daemon) - { - this(daemon, Thread.NORM_PRIORITY, name); - } - - /** - * 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); - } - - /** - * Removes all cancelled tasks from the queue. - * @return the number of tasks removed - * @since 1.5 - */ - public int purge() - { - return queue.purge(); - } -} diff --git a/libjava/classpath/java/util/TimerTask.java b/libjava/classpath/java/util/TimerTask.java deleted file mode 100644 index b03118a..0000000 --- a/libjava/classpath/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/classpath/java/util/TooManyListenersException.java b/libjava/classpath/java/util/TooManyListenersException.java deleted file mode 100644 index 92ad772..0000000 --- a/libjava/classpath/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/classpath/java/util/TreeMap.java b/libjava/classpath/java/util/TreeMap.java deleted file mode 100644 index 87c532f..0000000 --- a/libjava/classpath/java/util/TreeMap.java +++ /dev/null @@ -1,3322 +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, 2006 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 gnu.java.lang.CPStringBuilder; - -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) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @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.6 - */ -public class TreeMap<K, V> extends AbstractMap<K, V> - implements NavigableMap<K, V>, 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<Map.Entry<K,V>> entries; - - /** - * The cache for {@link #descendingMap()}. - */ - private transient NavigableMap<K,V> descendingMap; - - /** - * The cache for {@link #navigableKeySet()}. - */ - private transient NavigableSet<K> nKeys; - - /** - * 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<? super K> 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<K, V> extends AbstractMap.SimpleEntry<K, V> - { - // All fields package visible for use by nested classes. - /** The color of this node. */ - int color; - - /** The left child node. */ - Node<K, V> left = nil; - /** The right child node. */ - Node<K, V> right = nil; - /** The parent node. */ - Node<K, V> parent = nil; - - /** - * Simple constructor. - * @param key the key - * @param value the value - */ - Node(K key, V 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 c the sort order for the keys of this map, or null - * for the natural order - */ - public TreeMap(Comparator<? super K> 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<? extends K, ? extends V> 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<K, ? extends V> 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<? super K> 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((K) 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<Map.Entry<K,V>> entrySet() - { - if (entries == null) - // Create an AbstractSet with custom implementations of those methods - // that can be overriden easily and efficiently. - entries = new NavigableEntrySet(); - return entries; - } - - /** - * Returns the first (lowest) key in the map. - * - * @return the first key - * @throws NoSuchElementException if the map is empty - */ - public K 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 V get(Object key) - { - // Exploit fact that nil.value == null. - return getNode((K) 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 - * or call <code>headMap(toKey, true)</code>. This is equivalent to - * calling <code>headMap(toKey, false)</code>. - * - * @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<K, V> headMap(K toKey) - { - return headMap(toKey, false); - } - - /** - * Returns a view of this Map including all entries with keys less than - * (or equal to, if <code>inclusive</code> is true) <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. - * - * @param toKey the cutoff point - * @param inclusive true if the cutoff point should be included. - * @return a view of the map less than (or equal to, if <code>inclusive</code> - * is true) 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 NavigableMap<K, V> headMap(K toKey, boolean inclusive) - { - return new SubMap((K)(Object)nil, inclusive - ? successor(getNode(toKey)).key : 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<K> keySet() - { - if (keys == null) - // Create an AbstractSet with custom implementations of those methods - // that can be overriden easily and efficiently. - keys = new KeySet(); - return keys; - } - - /** - * Returns the last (highest) key in the map. - * - * @return the last key - * @throws NoSuchElementException if the map is empty - */ - public K 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 V put(K key, V value) - { - Node<K,V> current = root; - Node<K,V> 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<? extends K, ? extends V> m) - { - Iterator itr = m.entrySet().iterator(); - int pos = m.size(); - while (--pos >= 0) - { - Map.Entry<K,V> e = (Map.Entry<K,V>) 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 V remove(Object key) - { - Node<K, V> n = getNode((K)key); - if (n == nil) - return null; - // Note: removeNode can alter the contents of n, so save value now. - V 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 or call - * {@link #subMap(K,boolean,K,boolean)}. This call is equivalent to - * <code>subMap(fromKey, true, toKey, false)</code>. - * - * @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<K, V> subMap(K fromKey, K toKey) - { - return subMap(fromKey, true, toKey, false); - } - - /** - * Returns a view of this Map including all entries with keys greater (or - * equal to, if <code>fromInclusive</code> is true) <code>fromKey</code> and - * less than (or equal to, if <code>toInclusive</code> is true) - * <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 cutoffs. - * - * @param fromKey the low cutoff point - * @param fromInclusive true if the low cutoff point should be included. - * @param toKey the high cutoff point - * @param toInclusive true if the high cutoff point should be included. - * @return a view of the map for the specified range. - * @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 NavigableMap<K, V> subMap(K fromKey, boolean fromInclusive, - K toKey, boolean toInclusive) - { - return new SubMap(fromInclusive ? fromKey : successor(getNode(fromKey)).key, - toInclusive ? successor(getNode(toKey)).key : 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. - * This is equivalent to calling <code>tailMap(fromKey, true)</code>. - * - * @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<K, V> tailMap(K fromKey) - { - return tailMap(fromKey, true); - } - - /** - * 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 low cutoff point - * @param inclusive true if the cutoff point should be included. - * @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 NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) - { - return new SubMap(inclusive ? fromKey : successor(getNode(fromKey)).key, - (K)(Object)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<V> 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<V>() - { - public int size() - { - return size; - } - - public Iterator<V> 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(K o1, K 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<K,V> node, Node<K,V> 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<K,V> 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<K,V> 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<K, V> 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<K, V> getNode(K key) - { - Node<K,V> 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<K,V> highestLessThan(K key) - { - return highestLessThan(key, false); - } - - /** - * Find the "highest" node which is < (or equal to, - * if <code>equal</code> is true) key. If key is nil, - * return last node. Package visible for use by nested - * classes. - * - * @param key the upper bound, exclusive - * @param equal true if the key should be returned if found. - * @return the previous node - */ - final Node<K,V> highestLessThan(K key, boolean equal) - { - if (key == nil) - return lastNode(); - - Node<K,V> last = nil; - Node<K,V> 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 (equal ? last : 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<K,V> 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<K,V> 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<K,V> lowestGreaterThan(K key, boolean first) - { - return lowestGreaterThan(key, first, true); - } - - /** - * Find the "lowest" node which is > (or equal to, if <code>equal</code> - * is true) 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 - * @param equal true if the key should be returned if found. - * @return the next node - */ - final Node<K,V> lowestGreaterThan(K key, boolean first, boolean equal) - { - if (key == nil) - return first ? firstNode() : nil; - - Node<K,V> last = nil; - Node<K,V> 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 (equal ? current : successor(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<K,V> predecessor(Node<K,V> 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 readValues 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, which uses a value type of String. - * - * @param keys the iterator over the sorted keys - * @param count the number of nodes to insert - * @see TreeSet#TreeSet(SortedSet) - */ - final void putKeysLinear(Iterator<K> keys, int count) - { - fabricateTree(count); - Node<K,V> node = firstNode(); - - while (--count >= 0) - { - node.key = keys.next(); - node.value = (V) ""; - 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<K,V> node) - { - Node<K,V> splice; - Node<K,V> 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<K,V> 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<K,V> 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<K,V> successor(Node<K,V> node) - { - if (node.right != nil) - { - node = node.right; - while (node.left != nil) - node = node.left; - return node; - } - - Node<K,V> 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) - { - this(type, firstNode(), 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 - */ - public boolean hasNext() - { - 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<K,V> - implements NavigableMap<K,V> - { - /** - * The lower range of this view, inclusive, or nil for unbounded. - * Package visible for use by nested classes. - */ - final K minKey; - - /** - * The upper range of this view, exclusive, or nil for unbounded. - * Package visible for use by nested classes. - */ - final K maxKey; - - /** - * The cache for {@link #entrySet()}. - */ - private Set<Map.Entry<K,V>> entries; - - /** - * The cache for {@link #descendingMap()}. - */ - private NavigableMap<K,V> descendingMap; - - /** - * The cache for {@link #navigableKeySet()}. - */ - private NavigableSet<K> nKeys; - - /** - * 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(K minKey, K 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(K key) - { - return ((minKey == nil || compare(key, minKey) >= 0) - && (maxKey == nil || compare(key, maxKey) < 0)); - } - - public Entry<K,V> ceilingEntry(K key) - { - Entry<K,V> n = TreeMap.this.ceilingEntry(key); - if (n != null && keyInRange(n.getKey())) - return n; - return null; - } - - public K ceilingKey(K key) - { - K found = TreeMap.this.ceilingKey(key); - if (keyInRange(found)) - return found; - else - return null; - } - - public NavigableSet<K> descendingKeySet() - { - return descendingMap().navigableKeySet(); - } - - public NavigableMap<K,V> descendingMap() - { - if (descendingMap == null) - descendingMap = new DescendingMap(this); - return descendingMap; - } - - 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<? super K> comparator() - { - return comparator; - } - - public boolean containsKey(Object key) - { - return keyInRange((K) 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<Map.Entry<K,V>> entrySet() - { - if (entries == null) - // Create an AbstractSet with custom implementations of those methods - // that can be overriden easily and efficiently. - entries = new SubMap.NavigableEntrySet(); - return entries; - } - - public Entry<K,V> firstEntry() - { - Node<K,V> node = lowestGreaterThan(minKey, true); - if (node == nil || ! keyInRange(node.key)) - return null; - return node; - } - - public K firstKey() - { - Entry<K,V> e = firstEntry(); - if (e == null) - throw new NoSuchElementException(); - return e.getKey(); - } - - public Entry<K,V> floorEntry(K key) - { - Entry<K,V> n = TreeMap.this.floorEntry(key); - if (n != null && keyInRange(n.getKey())) - return n; - return null; - } - - public K floorKey(K key) - { - K found = TreeMap.this.floorKey(key); - if (keyInRange(found)) - return found; - else - return null; - } - - public V get(Object key) - { - if (keyInRange((K) key)) - return TreeMap.this.get(key); - return null; - } - - public SortedMap<K,V> headMap(K toKey) - { - return headMap(toKey, false); - } - - public NavigableMap<K,V> headMap(K toKey, boolean inclusive) - { - if (!keyInRange(toKey)) - throw new IllegalArgumentException("Key outside submap range"); - return new SubMap(minKey, (inclusive ? - successor(getNode(toKey)).key : toKey)); - } - - public Set<K> keySet() - { - if (this.keys == null) - // Create an AbstractSet with custom implementations of those methods - // that can be overriden easily and efficiently. - this.keys = new SubMap.KeySet(); - return this.keys; - } - - public Entry<K,V> higherEntry(K key) - { - Entry<K,V> n = TreeMap.this.higherEntry(key); - if (n != null && keyInRange(n.getKey())) - return n; - return null; - } - - public K higherKey(K key) - { - K found = TreeMap.this.higherKey(key); - if (keyInRange(found)) - return found; - else - return null; - } - - public Entry<K,V> lastEntry() - { - return lowerEntry(maxKey); - } - - public K lastKey() - { - Entry<K,V> e = lastEntry(); - if (e == null) - throw new NoSuchElementException(); - return e.getKey(); - } - - public Entry<K,V> lowerEntry(K key) - { - Entry<K,V> n = TreeMap.this.lowerEntry(key); - if (n != null && keyInRange(n.getKey())) - return n; - return null; - } - - public K lowerKey(K key) - { - K found = TreeMap.this.lowerKey(key); - if (keyInRange(found)) - return found; - else - return null; - } - - public NavigableSet<K> navigableKeySet() - { - if (this.nKeys == null) - // Create an AbstractSet with custom implementations of those methods - // that can be overriden easily and efficiently. - this.nKeys = new SubMap.NavigableKeySet(); - return this.nKeys; - } - - public Entry<K,V> pollFirstEntry() - { - Entry<K,V> e = firstEntry(); - if (e != null) - removeNode((Node<K,V>) e); - return e; - } - - public Entry<K,V> pollLastEntry() - { - Entry<K,V> e = lastEntry(); - if (e != null) - removeNode((Node<K,V>) e); - return e; - } - - public V put(K key, V value) - { - if (! keyInRange(key)) - throw new IllegalArgumentException("Key outside range"); - return TreeMap.this.put(key, value); - } - - public V remove(Object key) - { - if (keyInRange((K)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<K,V> subMap(K fromKey, K toKey) - { - return subMap(fromKey, true, toKey, false); - } - - public NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive, - K toKey, boolean toInclusive) - { - if (! keyInRange(fromKey) || ! keyInRange(toKey)) - throw new IllegalArgumentException("key outside range"); - return new SubMap(fromInclusive ? fromKey : successor(getNode(fromKey)).key, - toInclusive ? successor(getNode(toKey)).key : toKey); - } - - public SortedMap<K, V> tailMap(K fromKey) - { - return tailMap(fromKey, true); - } - - public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) - { - if (! keyInRange(fromKey)) - throw new IllegalArgumentException("key outside range"); - return new SubMap(inclusive ? fromKey : successor(getNode(fromKey)).key, - maxKey); - } - - public Collection<V> 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<V> 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; - } - - private class KeySet - extends AbstractSet<K> - { - public int size() - { - return SubMap.this.size(); - } - - public Iterator<K> 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((K) o)) - return false; - return getNode((K) o) != nil; - } - - public boolean remove(Object o) - { - if (! keyInRange((K) o)) - return false; - Node n = getNode((K) o); - if (n != nil) - { - removeNode(n); - return true; - } - return false; - } - - } // class SubMap.KeySet - - private final class NavigableKeySet - extends KeySet - implements NavigableSet<K> - { - - public K ceiling(K k) - { - return SubMap.this.ceilingKey(k); - } - - public Comparator<? super K> comparator() - { - return comparator; - } - - public Iterator<K> descendingIterator() - { - return descendingSet().iterator(); - } - - public NavigableSet<K> descendingSet() - { - return new DescendingSet(this); - } - - public K first() - { - return SubMap.this.firstKey(); - } - - public K floor(K k) - { - return SubMap.this.floorKey(k); - } - - public SortedSet<K> headSet(K to) - { - return headSet(to, false); - } - - public NavigableSet<K> headSet(K to, boolean inclusive) - { - return SubMap.this.headMap(to, inclusive).navigableKeySet(); - } - - public K higher(K k) - { - return SubMap.this.higherKey(k); - } - - public K last() - { - return SubMap.this.lastKey(); - } - - public K lower(K k) - { - return SubMap.this.lowerKey(k); - } - - public K pollFirst() - { - return SubMap.this.pollFirstEntry().getKey(); - } - - public K pollLast() - { - return SubMap.this.pollLastEntry().getKey(); - } - - public SortedSet<K> subSet(K from, K to) - { - return subSet(from, true, to, false); - } - - public NavigableSet<K> subSet(K from, boolean fromInclusive, - K to, boolean toInclusive) - { - return SubMap.this.subMap(from, fromInclusive, - to, toInclusive).navigableKeySet(); - } - - public SortedSet<K> tailSet(K from) - { - return tailSet(from, true); - } - - public NavigableSet<K> tailSet(K from, boolean inclusive) - { - return SubMap.this.tailMap(from, inclusive).navigableKeySet(); - } - - } // class SubMap.NavigableKeySet - - /** - * Implementation of {@link #entrySet()}. - */ - private class EntrySet - extends AbstractSet<Entry<K,V>> - { - - public int size() - { - return SubMap.this.size(); - } - - public Iterator<Map.Entry<K,V>> 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<K,V> me = (Map.Entry<K,V>) o; - K key = me.getKey(); - if (! keyInRange(key)) - return false; - Node<K,V> 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<K,V> me = (Map.Entry<K,V>) o; - K key = me.getKey(); - if (! keyInRange(key)) - return false; - Node<K,V> n = getNode(key); - if (n != nil && AbstractSet.equals(me.getValue(), n.value)) - { - removeNode(n); - return true; - } - return false; - } - } // class SubMap.EntrySet - - private final class NavigableEntrySet - extends EntrySet - implements NavigableSet<Entry<K,V>> - { - - public Entry<K,V> ceiling(Entry<K,V> e) - { - return SubMap.this.ceilingEntry(e.getKey()); - } - - public Comparator<? super Entry<K,V>> comparator() - { - return new Comparator<Entry<K,V>>() - { - public int compare(Entry<K,V> t1, Entry<K,V> t2) - { - return comparator.compare(t1.getKey(), t2.getKey()); - } - }; - } - - public Iterator<Entry<K,V>> descendingIterator() - { - return descendingSet().iterator(); - } - - public NavigableSet<Entry<K,V>> descendingSet() - { - return new DescendingSet(this); - } - - public Entry<K,V> first() - { - return SubMap.this.firstEntry(); - } - - public Entry<K,V> floor(Entry<K,V> e) - { - return SubMap.this.floorEntry(e.getKey()); - } - - public SortedSet<Entry<K,V>> headSet(Entry<K,V> to) - { - return headSet(to, false); - } - - public NavigableSet<Entry<K,V>> headSet(Entry<K,V> to, boolean inclusive) - { - return (NavigableSet<Entry<K,V>>) - SubMap.this.headMap(to.getKey(), inclusive).entrySet(); - } - - public Entry<K,V> higher(Entry<K,V> e) - { - return SubMap.this.higherEntry(e.getKey()); - } - - public Entry<K,V> last() - { - return SubMap.this.lastEntry(); - } - - public Entry<K,V> lower(Entry<K,V> e) - { - return SubMap.this.lowerEntry(e.getKey()); - } - - public Entry<K,V> pollFirst() - { - return SubMap.this.pollFirstEntry(); - } - - public Entry<K,V> pollLast() - { - return SubMap.this.pollLastEntry(); - } - - public SortedSet<Entry<K,V>> subSet(Entry<K,V> from, Entry<K,V> to) - { - return subSet(from, true, to, false); - } - - public NavigableSet<Entry<K,V>> subSet(Entry<K,V> from, boolean fromInclusive, - Entry<K,V> to, boolean toInclusive) - { - return (NavigableSet<Entry<K,V>>) - SubMap.this.subMap(from.getKey(), fromInclusive, - to.getKey(), toInclusive).entrySet(); - } - - public SortedSet<Entry<K,V>> tailSet(Entry<K,V> from) - { - return tailSet(from, true); - } - - public NavigableSet<Entry<K,V>> tailSet(Entry<K,V> from, boolean inclusive) - { - return (NavigableSet<Entry<K,V>>) - SubMap.this.tailMap(from.getKey(), inclusive).navigableKeySet(); - } - - } // class SubMap.NavigableEntrySet - -} // class SubMap - - /** - * Returns the entry associated with the least or lowest key - * that is greater than or equal to the specified key, or - * <code>null</code> if there is no such key. - * - * @param key the key relative to the returned entry. - * @return the entry with the least key greater than or equal - * to the given key, or <code>null</code> if there is - * no such key. - * @throws ClassCastException if the specified key can not - * be compared with those in the map. - * @throws NullPointerException if the key is <code>null</code> - * and this map either uses natural - * ordering or a comparator that does - * not permit null keys. - * @since 1.6 - */ - public Entry<K,V> ceilingEntry(K key) - { - Node<K,V> n = lowestGreaterThan(key, false); - return (n == nil) ? null : n; - } - - /** - * Returns the the least or lowest key that is greater than - * or equal to the specified key, or <code>null</code> if - * there is no such key. - * - * @param key the key relative to the returned entry. - * @return the least key greater than or equal to the given key, - * or <code>null</code> if there is no such key. - * @throws ClassCastException if the specified key can not - * be compared with those in the map. - * @throws NullPointerException if the key is <code>null</code> - * and this map either uses natural - * ordering or a comparator that does - * not permit null keys. - * @since 1.6 - */ - public K ceilingKey(K key) - { - Entry<K,V> e = ceilingEntry(key); - return (e == null) ? null : e.getKey(); - } - - /** - * Returns a reverse ordered {@link NavigableSet} view of this - * map's keys. The set is backed by the {@link TreeMap}, so changes - * in one show up in the other. The set supports element removal, - * but not element addition. - * - * @return a reverse ordered set view of the keys. - * @since 1.6 - * @see #descendingMap() - */ - public NavigableSet<K> descendingKeySet() - { - return descendingMap().navigableKeySet(); - } - - /** - * Returns a view of the map in reverse order. The descending map - * is backed by the original map, so that changes affect both maps. - * Any changes occurring to either map while an iteration is taking - * place (with the exception of a {@link Iterator#remove()} operation) - * result in undefined behaviour from the iteration. The ordering - * of the descending map is the same as for a map with a - * {@link Comparator} given by {@link Collections#reverseOrder()}, - * and calling {@link #descendingMap()} on the descending map itself - * results in a view equivalent to the original map. - * - * @return a reverse order view of the map. - * @since 1.6 - */ - public NavigableMap<K,V> descendingMap() - { - if (descendingMap == null) - descendingMap = new DescendingMap<K,V>(this); - return descendingMap; - } - - /** - * Returns the entry associated with the least or lowest key - * in the map, or <code>null</code> if the map is empty. - * - * @return the lowest entry, or <code>null</code> if the map - * is empty. - * @since 1.6 - */ - public Entry<K,V> firstEntry() - { - Node<K,V> n = firstNode(); - return (n == nil) ? null : n; - } - - /** - * Returns the entry associated with the greatest or highest key - * that is less than or equal to the specified key, or - * <code>null</code> if there is no such key. - * - * @param key the key relative to the returned entry. - * @return the entry with the greatest key less than or equal - * to the given key, or <code>null</code> if there is - * no such key. - * @throws ClassCastException if the specified key can not - * be compared with those in the map. - * @throws NullPointerException if the key is <code>null</code> - * and this map either uses natural - * ordering or a comparator that does - * not permit null keys. - * @since 1.6 - */ - public Entry<K,V> floorEntry(K key) - { - Node<K,V> n = highestLessThan(key, true); - return (n == nil) ? null : n; - } - - /** - * Returns the the greatest or highest key that is less than - * or equal to the specified key, or <code>null</code> if - * there is no such key. - * - * @param key the key relative to the returned entry. - * @return the greatest key less than or equal to the given key, - * or <code>null</code> if there is no such key. - * @throws ClassCastException if the specified key can not - * be compared with those in the map. - * @throws NullPointerException if the key is <code>null</code> - * and this map either uses natural - * ordering or a comparator that does - * not permit null keys. - * @since 1.6 - */ - public K floorKey(K key) - { - Entry<K,V> e = floorEntry(key); - return (e == null) ? null : e.getKey(); - } - - /** - * Returns the entry associated with the least or lowest key - * that is strictly greater than the specified key, or - * <code>null</code> if there is no such key. - * - * @param key the key relative to the returned entry. - * @return the entry with the least key greater than - * the given key, or <code>null</code> if there is - * no such key. - * @throws ClassCastException if the specified key can not - * be compared with those in the map. - * @throws NullPointerException if the key is <code>null</code> - * and this map either uses natural - * ordering or a comparator that does - * not permit null keys. - * @since 1.6 - */ - public Entry<K,V> higherEntry(K key) - { - Node<K,V> n = lowestGreaterThan(key, false, false); - return (n == nil) ? null : n; - } - - /** - * Returns the the least or lowest key that is strictly - * greater than the specified key, or <code>null</code> if - * there is no such key. - * - * @param key the key relative to the returned entry. - * @return the least key greater than the given key, - * or <code>null</code> if there is no such key. - * @throws ClassCastException if the specified key can not - * be compared with those in the map. - * @throws NullPointerException if the key is <code>null</code> - * and this map either uses natural - * ordering or a comparator that does - * not permit null keys. - * @since 1.6 - */ - public K higherKey(K key) - { - Entry<K,V> e = higherEntry(key); - return (e == null) ? null : e.getKey(); - } - - /** - * Returns the entry associated with the greatest or highest key - * in the map, or <code>null</code> if the map is empty. - * - * @return the highest entry, or <code>null</code> if the map - * is empty. - * @since 1.6 - */ - public Entry<K,V> lastEntry() - { - Node<K,V> n = lastNode(); - return (n == nil) ? null : n; - } - - /** - * Returns the entry associated with the greatest or highest key - * that is strictly less than the specified key, or - * <code>null</code> if there is no such key. - * - * @param key the key relative to the returned entry. - * @return the entry with the greatest key less than - * the given key, or <code>null</code> if there is - * no such key. - * @throws ClassCastException if the specified key can not - * be compared with those in the map. - * @throws NullPointerException if the key is <code>null</code> - * and this map either uses natural - * ordering or a comparator that does - * not permit null keys. - * @since 1.6 - */ - public Entry<K,V> lowerEntry(K key) - { - Node<K,V> n = highestLessThan(key); - return (n == nil) ? null : n; - } - - /** - * Returns the the greatest or highest key that is strictly - * less than the specified key, or <code>null</code> if - * there is no such key. - * - * @param key the key relative to the returned entry. - * @return the greatest key less than the given key, - * or <code>null</code> if there is no such key. - * @throws ClassCastException if the specified key can not - * be compared with those in the map. - * @throws NullPointerException if the key is <code>null</code> - * and this map either uses natural - * ordering or a comparator that does - * not permit null keys. - * @since 1.6 - */ - public K lowerKey(K key) - { - Entry<K,V> e = lowerEntry(key); - return (e == null) ? null : e.getKey(); - } - - /** - * Returns a {@link NavigableSet} view of this map's keys. The set is - * backed by the {@link TreeMap}, so changes in one show up in the other. - * Any changes occurring to either while an iteration is taking - * place (with the exception of a {@link Iterator#remove()} operation) - * result in undefined behaviour from the iteration. The ordering - * The set supports element removal, but not element addition. - * - * @return a {@link NavigableSet} view of the keys. - * @since 1.6 - */ - public NavigableSet<K> navigableKeySet() - { - if (nKeys == null) - nKeys = new NavigableKeySet(); - return nKeys; - } - - /** - * Removes and returns the entry associated with the least - * or lowest key in the map, or <code>null</code> if the map - * is empty. - * - * @return the removed first entry, or <code>null</code> if the - * map is empty. - * @since 1.6 - */ - public Entry<K,V> pollFirstEntry() - { - Entry<K,V> e = firstEntry(); - if (e != null) - removeNode((Node<K,V>)e); - return e; - } - - /** - * Removes and returns the entry associated with the greatest - * or highest key in the map, or <code>null</code> if the map - * is empty. - * - * @return the removed last entry, or <code>null</code> if the - * map is empty. - * @since 1.6 - */ - public Entry<K,V> pollLastEntry() - { - Entry<K,V> e = lastEntry(); - if (e != null) - removeNode((Node<K,V>)e); - return e; - } - - /** - * Implementation of {@link #descendingMap()} and associated - * derivatives. This class provides a view of the - * original backing map in reverse order, and throws - * {@link IllegalArgumentException} for attempts to - * access beyond that range. - * - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - */ - private static final class DescendingMap<DK,DV> - implements NavigableMap<DK,DV> - { - - /** - * The cache for {@link #entrySet()}. - */ - private Set<Map.Entry<DK,DV>> entries; - - /** - * The cache for {@link #keySet()}. - */ - private Set<DK> keys; - - /** - * The cache for {@link #navigableKeySet()}. - */ - private NavigableSet<DK> nKeys; - - /** - * The cache for {@link #values()}. - */ - private Collection<DV> values; - - /** - * The backing {@link NavigableMap}. - */ - private NavigableMap<DK,DV> map; - - /** - * Create a {@link DescendingMap} around the specified - * map. - * - * @param map the map to wrap. - */ - public DescendingMap(NavigableMap<DK,DV> map) - { - this.map = map; - } - - public Map.Entry<DK,DV> ceilingEntry(DK key) - { - return map.floorEntry(key); - } - - public DK ceilingKey(DK key) - { - return map.floorKey(key); - } - - public void clear() - { - map.clear(); - } - - public Comparator<? super DK> comparator() - { - return Collections.reverseOrder(map.comparator()); - } - - public boolean containsKey(Object o) - { - return map.containsKey(o); - } - - public boolean containsValue(Object o) - { - return map.containsValue(o); - } - - public NavigableSet<DK> descendingKeySet() - { - return descendingMap().navigableKeySet(); - } - - public NavigableMap<DK,DV> descendingMap() - { - return map; - } - - public Set<Entry<DK,DV>> entrySet() - { - if (entries == null) - entries = - new DescendingSet<Entry<DK,DV>>((NavigableSet<Entry<DK,DV>>) - map.entrySet()); - return entries; - } - - public boolean equals(Object o) - { - return map.equals(o); - } - - public Entry<DK,DV> firstEntry() - { - return map.lastEntry(); - } - - public DK firstKey() - { - return map.lastKey(); - } - - public Entry<DK,DV> floorEntry(DK key) - { - return map.ceilingEntry(key); - } - - public DK floorKey(DK key) - { - return map.ceilingKey(key); - } - - public DV get(Object key) - { - return map.get(key); - } - - public int hashCode() - { - return map.hashCode(); - } - - public SortedMap<DK,DV> headMap(DK toKey) - { - return headMap(toKey, false); - } - - public NavigableMap<DK,DV> headMap(DK toKey, boolean inclusive) - { - return new DescendingMap(map.tailMap(toKey, inclusive)); - } - - public Entry<DK,DV> higherEntry(DK key) - { - return map.lowerEntry(key); - } - - public DK higherKey(DK key) - { - return map.lowerKey(key); - } - - public Set<DK> keySet() - { - if (keys == null) - keys = new DescendingSet<DK>(map.navigableKeySet()); - return keys; - } - - public boolean isEmpty() - { - return map.isEmpty(); - } - - public Entry<DK,DV> lastEntry() - { - return map.firstEntry(); - } - - public DK lastKey() - { - return map.firstKey(); - } - - public Entry<DK,DV> lowerEntry(DK key) - { - return map.higherEntry(key); - } - - public DK lowerKey(DK key) - { - return map.higherKey(key); - } - - public NavigableSet<DK> navigableKeySet() - { - if (nKeys == null) - nKeys = new DescendingSet<DK>(map.navigableKeySet()); - return nKeys; - } - - public Entry<DK,DV> pollFirstEntry() - { - return pollLastEntry(); - } - - public Entry<DK,DV> pollLastEntry() - { - return pollFirstEntry(); - } - - public DV put(DK key, DV value) - { - return map.put(key, value); - } - - public void putAll(Map<? extends DK, ? extends DV> m) - { - map.putAll(m); - } - - public DV remove(Object key) - { - return map.remove(key); - } - - public int size() - { - return map.size(); - } - - public SortedMap<DK,DV> subMap(DK fromKey, DK toKey) - { - return subMap(fromKey, true, toKey, false); - } - - public NavigableMap<DK,DV> subMap(DK fromKey, boolean fromInclusive, - DK toKey, boolean toInclusive) - { - return new DescendingMap(map.subMap(fromKey, fromInclusive, - toKey, toInclusive)); - } - - public SortedMap<DK,DV> tailMap(DK fromKey) - { - return tailMap(fromKey, true); - } - - public NavigableMap<DK,DV> tailMap(DK fromKey, boolean inclusive) - { - return new DescendingMap(map.headMap(fromKey, inclusive)); - } - - public String toString() - { - CPStringBuilder r = new CPStringBuilder("{"); - final Iterator<Entry<DK,DV>> it = entrySet().iterator(); - while (it.hasNext()) - { - final Entry<DK,DV> e = it.next(); - r.append(e.getKey()); - r.append('='); - r.append(e.getValue()); - r.append(", "); - } - r.replace(r.length() - 2, r.length(), "}"); - return r.toString(); - } - - public Collection<DV> values() - { - if (values == null) - // Create an AbstractCollection with custom implementations of those - // methods that can be overriden easily and efficiently. - values = new AbstractCollection() - { - public int size() - { - return DescendingMap.this.size(); - } - - public Iterator<DV> iterator() - { - return new Iterator<DV>() - { - /** The last Entry returned by a next() call. */ - private Entry<DK,DV> last; - - /** The next entry that should be returned by next(). */ - private Entry<DK,DV> next = firstEntry(); - - public boolean hasNext() - { - return next != null; - } - - public DV next() - { - if (next == null) - throw new NoSuchElementException(); - last = next; - next = higherEntry(last.getKey()); - - return last.getValue(); - } - - public void remove() - { - if (last == null) - throw new IllegalStateException(); - - DescendingMap.this.remove(last.getKey()); - last = null; - } - }; - } - - public void clear() - { - DescendingMap.this.clear(); - } - }; - return values; - } - - } // class DescendingMap - - /** - * Implementation of {@link #keySet()}. - */ - private class KeySet - extends AbstractSet<K> - { - - public int size() - { - return size; - } - - public Iterator<K> 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<K,V> n = getNode((K) key); - if (n == nil) - return false; - removeNode(n); - return true; - } - } // class KeySet - - /** - * Implementation of {@link #navigableKeySet()}. - * - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - */ - private final class NavigableKeySet - extends KeySet - implements NavigableSet<K> - { - - public K ceiling(K k) - { - return ceilingKey(k); - } - - public Comparator<? super K> comparator() - { - return comparator; - } - - public Iterator<K> descendingIterator() - { - return descendingSet().iterator(); - } - - public NavigableSet<K> descendingSet() - { - return new DescendingSet<K>(this); - } - - public K first() - { - return firstKey(); - } - - public K floor(K k) - { - return floorKey(k); - } - - public SortedSet<K> headSet(K to) - { - return headSet(to, false); - } - - public NavigableSet<K> headSet(K to, boolean inclusive) - { - return headMap(to, inclusive).navigableKeySet(); - } - - public K higher(K k) - { - return higherKey(k); - } - - public K last() - { - return lastKey(); - } - - public K lower(K k) - { - return lowerKey(k); - } - - public K pollFirst() - { - return pollFirstEntry().getKey(); - } - - public K pollLast() - { - return pollLastEntry().getKey(); - } - - public SortedSet<K> subSet(K from, K to) - { - return subSet(from, true, to, false); - } - - public NavigableSet<K> subSet(K from, boolean fromInclusive, - K to, boolean toInclusive) - { - return subMap(from, fromInclusive, - to, toInclusive).navigableKeySet(); - } - - public SortedSet<K> tailSet(K from) - { - return tailSet(from, true); - } - - public NavigableSet<K> tailSet(K from, boolean inclusive) - { - return tailMap(from, inclusive).navigableKeySet(); - } - - - } // class NavigableKeySet - - /** - * Implementation of {@link #descendingSet()} and associated - * derivatives. This class provides a view of the - * original backing set in reverse order, and throws - * {@link IllegalArgumentException} for attempts to - * access beyond that range. - * - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - */ - private static final class DescendingSet<D> - implements NavigableSet<D> - { - - /** - * The backing {@link NavigableSet}. - */ - private NavigableSet<D> set; - - /** - * Create a {@link DescendingSet} around the specified - * set. - * - * @param map the set to wrap. - */ - public DescendingSet(NavigableSet<D> set) - { - this.set = set; - } - - public boolean add(D e) - { - return set.add(e); - } - - public boolean addAll(Collection<? extends D> c) - { - return set.addAll(c); - } - - public D ceiling(D e) - { - return set.floor(e); - } - - public void clear() - { - set.clear(); - } - - public Comparator<? super D> comparator() - { - return Collections.reverseOrder(set.comparator()); - } - - public boolean contains(Object o) - { - return set.contains(o); - } - - public boolean containsAll(Collection<?> c) - { - return set.containsAll(c); - } - - public Iterator<D> descendingIterator() - { - return descendingSet().iterator(); - } - - public NavigableSet<D> descendingSet() - { - return set; - } - - public boolean equals(Object o) - { - return set.equals(o); - } - - public D first() - { - return set.last(); - } - - public D floor(D e) - { - return set.ceiling(e); - } - - public int hashCode() - { - return set.hashCode(); - } - - public SortedSet<D> headSet(D to) - { - return headSet(to, false); - } - - public NavigableSet<D> headSet(D to, boolean inclusive) - { - return new DescendingSet(set.tailSet(to, inclusive)); - } - - public D higher(D e) - { - return set.lower(e); - } - - public boolean isEmpty() - { - return set.isEmpty(); - } - - public Iterator<D> iterator() - { - return new Iterator<D>() - { - - /** The last element returned by a next() call. */ - private D last; - - /** The next element that should be returned by next(). */ - private D next = first(); - - public boolean hasNext() - { - return next != null; - } - - public D next() - { - if (next == null) - throw new NoSuchElementException(); - last = next; - next = higher(last); - - return last; - } - - public void remove() - { - if (last == null) - throw new IllegalStateException(); - - DescendingSet.this.remove(last); - last = null; - } - }; - } - - public D last() - { - return set.first(); - } - - public D lower(D e) - { - return set.higher(e); - } - - public D pollFirst() - { - return set.pollLast(); - } - - public D pollLast() - { - return set.pollFirst(); - } - - public boolean remove(Object o) - { - return set.remove(o); - } - - public boolean removeAll(Collection<?> c) - { - return set.removeAll(c); - } - - public boolean retainAll(Collection<?> c) - { - return set.retainAll(c); - } - - public int size() - { - return set.size(); - } - - public SortedSet<D> subSet(D from, D to) - { - return subSet(from, true, to, false); - } - - public NavigableSet<D> subSet(D from, boolean fromInclusive, - D to, boolean toInclusive) - { - return new DescendingSet(set.subSet(from, fromInclusive, - to, toInclusive)); - } - - public SortedSet<D> tailSet(D from) - { - return tailSet(from, true); - } - - public NavigableSet<D> tailSet(D from, boolean inclusive) - { - return new DescendingSet(set.headSet(from, inclusive)); - } - - public Object[] toArray() - { - D[] array = (D[]) set.toArray(); - Arrays.sort(array, comparator()); - return array; - } - - public <T> T[] toArray(T[] a) - { - T[] array = set.toArray(a); - Arrays.sort(array, (Comparator<? super T>) comparator()); - return array; - } - - public String toString() - { - CPStringBuilder r = new CPStringBuilder("["); - final Iterator<D> it = iterator(); - while (it.hasNext()) - { - final D o = it.next(); - if (o == this) - r.append("<this>"); - else - r.append(o); - r.append(", "); - } - r.replace(r.length() - 2, r.length(), "]"); - return r.toString(); - } - - } // class DescendingSet - - private class EntrySet - extends AbstractSet<Entry<K,V>> - { - public int size() - { - return size; - } - - public Iterator<Map.Entry<K,V>> 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<K,V> me = (Map.Entry<K,V>) o; - Node<K,V> 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<K,V> me = (Map.Entry<K,V>) o; - Node<K,V> n = getNode(me.getKey()); - if (n != nil && AbstractSet.equals(me.getValue(), n.value)) - { - removeNode(n); - return true; - } - return false; - } - } - - private final class NavigableEntrySet - extends EntrySet - implements NavigableSet<Entry<K,V>> - { - - public Entry<K,V> ceiling(Entry<K,V> e) - { - return ceilingEntry(e.getKey()); - } - - public Comparator<? super Entry<K,V>> comparator() - { - return new Comparator<Entry<K,V>>() - { - public int compare(Entry<K,V> t1, Entry<K,V> t2) - { - return comparator.compare(t1.getKey(), t2.getKey()); - } - }; - } - - public Iterator<Entry<K,V>> descendingIterator() - { - return descendingSet().iterator(); - } - - public NavigableSet<Entry<K,V>> descendingSet() - { - return new DescendingSet(this); - } - - public Entry<K,V> first() - { - return firstEntry(); - } - - public Entry<K,V> floor(Entry<K,V> e) - { - return floorEntry(e.getKey()); - } - - public SortedSet<Entry<K,V>> headSet(Entry<K,V> to) - { - return headSet(to, false); - } - - public NavigableSet<Entry<K,V>> headSet(Entry<K,V> to, boolean inclusive) - { - return (NavigableSet<Entry<K,V>>) headMap(to.getKey(), inclusive).entrySet(); - } - - public Entry<K,V> higher(Entry<K,V> e) - { - return higherEntry(e.getKey()); - } - - public Entry<K,V> last() - { - return lastEntry(); - } - - public Entry<K,V> lower(Entry<K,V> e) - { - return lowerEntry(e.getKey()); - } - - public Entry<K,V> pollFirst() - { - return pollFirstEntry(); - } - - public Entry<K,V> pollLast() - { - return pollLastEntry(); - } - - public SortedSet<Entry<K,V>> subSet(Entry<K,V> from, Entry<K,V> to) - { - return subSet(from, true, to, false); - } - - public NavigableSet<Entry<K,V>> subSet(Entry<K,V> from, boolean fromInclusive, - Entry<K,V> to, boolean toInclusive) - { - return (NavigableSet<Entry<K,V>>) subMap(from.getKey(), fromInclusive, - to.getKey(), toInclusive).entrySet(); - } - - public SortedSet<Entry<K,V>> tailSet(Entry<K,V> from) - { - return tailSet(from, true); - } - - public NavigableSet<Entry<K,V>> tailSet(Entry<K,V> from, boolean inclusive) - { - return (NavigableSet<Entry<K,V>>) tailMap(from.getKey(), inclusive).navigableKeySet(); - } - - } // class NavigableEntrySet - -} // class TreeMap diff --git a/libjava/classpath/java/util/TreeSet.java b/libjava/classpath/java/util/TreeSet.java deleted file mode 100644 index 06f4fa5..0000000 --- a/libjava/classpath/java/util/TreeSet.java +++ /dev/null @@ -1,641 +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) - * @author Tom Tromey (tromey@redhat.com) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @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.6 - */ -public class TreeSet<T> extends AbstractSet<T> - implements NavigableSet<T>, Cloneable, Serializable -{ - /** - * Compatible with JDK 1.2. - */ - private static final long serialVersionUID = -2479143000061671589L; - - /** - * The NavigableMap 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 NavigableMap<T, String> 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<T, String>(); - } - - /** - * 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<? super T> comparator) - { - map = new TreeMap<T, String>(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<? extends T> collection) - { - map = new TreeMap<T, String>(); - 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<T> sortedSet) - { - Iterator<T> itr; - - map = new TreeMap<T, String> - ((Comparator<? super T>)sortedSet.comparator()); - itr = ((SortedSet<T>) sortedSet).iterator(); - ((TreeMap<T, String>) 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(NavigableMap<T,String> 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(T 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<? extends T> c) - { - boolean result = false; - int pos = c.size(); - Iterator<? extends T> 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<T> copy = null; - try - { - copy = (TreeSet<T>) super.clone(); - // Map may be either TreeMap or TreeMap.SubMap, hence the ugly casts. - copy.map = (NavigableMap<T, String>) ((AbstractMap<T, String>) 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<? super T> 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 T 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 or - * call {@link #headSet(T,boolean)}. This call is equivalent to - * <code>headSet(to, false)</code>. - * - * @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<T> headSet(T to) - { - return headSet(to, false); - } - - /** - * Returns a view of this Set including all elements less than - * (or equal to, if <code>inclusive</code> is true) <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. - * - * @param to the cutoff point - * @param inclusive true if <code>to</code> should be included. - * @return a view of the set for the specified range. - * @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 NavigableSet<T> headSet(T to, boolean inclusive) - { - return new TreeSet<T>(map.headMap(to, inclusive)); - } - - /** - * 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<T> 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 T 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 - * or call {@link #subSet(T,boolean,T,boolean)}. This is equivalent to - * calling <code>subSet(from,true,to,false)</code>. - * - * @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<T> subSet(T from, T to) - { - return subSet(from, true, to, false); - } - - /** - * Returns a view of this Set including all elements greater than (or equal to, - * if <code>fromInclusive</code> is true</code> <code>from</code> and less than - * (or equal to, if <code>toInclusive</code> is true) <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 cutoffs. - * - * @param from the low cutoff point - * @param fromInclusive true if <code>from</code> should be included. - * @param to the high cutoff point - * @param toInclusive true if <code>to</code> should be included. - * @return a view of the set for the specified range. - * @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 NavigableSet<T> subSet(T from, boolean fromInclusive, - T to, boolean toInclusive) - { - return new TreeSet<T>(map.subMap(from, fromInclusive, - to, toInclusive)); - } - - /** - * 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 - * or call {@link #tailSet(T,boolean)}. This is equivalent to calling - * <code>tailSet(from, true)</code>. - * - * @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<T> tailSet(T from) - { - return tailSet(from, true); - } - - /** - * Returns a view of this Set including all elements greater (or equal to, - * if <code>inclusive</code> is true) <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. - * - * @param from the low cutoff point. - * @param inclusive true if <code>from</code> should be included. - * @return a view of the set for the specified range. - * @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 NavigableSet<T> tailSet(T from, boolean inclusive) - { - return new TreeSet<T>(map.tailMap(from, inclusive)); - } - - /** - * 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<T> 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<? super T> comparator = (Comparator<? super T>) s.readObject(); - int size = s.readInt(); - map = new TreeMap<T, String>(comparator); - ((TreeMap<T, String>) map).putFromObjStream(s, size, false); - } - - /** - * Returns the least or lowest element in the set greater than or - * equal to the given element, or <code>null</code> if there is - * no such element. - * - * @param e the element relative to the returned element. - * @return the least element greater than or equal - * to the given element, or <code>null</code> if there is - * no such element. - * @throws ClassCastException if the specified element can not - * be compared with those in the map. - * @throws NullPointerException if the element is <code>null</code> - * and this set either uses natural - * ordering or a comparator that does - * not permit null elements. - * @since 1.6 - */ - public T ceiling(T e) - { - return map.ceilingKey(e); - } - - /** - * Returns an iterator over the elements of this set in descending - * order. This is equivalent to calling - * <code>descendingSet().iterator()</code>. - * - * @return an iterator over the elements in descending order. - * @since 1.6 - */ - public Iterator<T> descendingIterator() - { - return descendingSet().iterator(); - } - - /** - * Returns a view of the set in reverse order. The descending set - * is backed by the original set, so that changes affect both sets. - * Any changes occurring to either set while an iteration is taking - * place (with the exception of a {@link Iterator#remove()} operation) - * result in undefined behaviour from the iteration. The ordering - * of the descending set is the same as for a set with a - * {@link Comparator} given by {@link Collections#reverseOrder()}, - * and calling {@link #descendingSet()} on the descending set itself - * results in a view equivalent to the original set. - * - * @return a reverse order view of the set. - * @since 1.6 - */ - public NavigableSet<T> descendingSet() - { - return map.descendingKeySet(); - } - - /** - * Returns the greatest or highest element in the set less than or - * equal to the given element, or <code>null</code> if there is - * no such element. - * - * @param e the element relative to the returned element. - * @return the greatest element less than or equal - * to the given element, or <code>null</code> if there is - * no such element. - * @throws ClassCastException if the specified element can not - * be compared with those in the map. - * @throws NullPointerException if the element is <code>null</code> - * and this set either uses natural - * ordering or a comparator that does - * not permit null elements. - * @since 1.6 - */ - public T floor(T e) - { - return map.floorKey(e); - } - - /** - * Returns the least or lowest element in the set strictly greater - * than the given element, or <code>null</code> if there is - * no such element. - * - * @param e the element relative to the returned element. - * @return the least element greater than - * the given element, or <code>null</code> if there is - * no such element. - * @throws ClassCastException if the specified element can not - * be compared with those in the map. - * @throws NullPointerException if the element is <code>null</code> - * and this set either uses natural - * ordering or a comparator that does - * not permit null elements. - * @since 1.6 - */ - public T higher(T e) - { - return map.higherKey(e); - } - - /** - * Returns the greatest or highest element in the set strictly less - * than the given element, or <code>null</code> if there is - * no such element. - * - * @param e the element relative to the returned element. - * @return the greatest element less than - * the given element, or <code>null</code> if there is - * no such element. - * @throws ClassCastException if the specified element can not - * be compared with those in the map. - * @throws NullPointerException if the element is <code>null</code> - * and this set either uses natural - * ordering or a comparator that does - * not permit null elements. - * @since 1.6 - */ - public T lower(T e) - { - return map.lowerKey(e); - } - - /** - * Removes and returns the least or lowest element in the set, - * or <code>null</code> if the map is empty. - * - * @return the removed first element, or <code>null</code> if the - * map is empty. - * @since 1.6 - */ - public T pollFirst() - { - return map.pollFirstEntry().getKey(); - } - - /** - * Removes and returns the greatest or highest element in the set, - * or <code>null</code> if the map is empty. - * - * @return the removed last element, or <code>null</code> if the - * map is empty. - * @since 1.6 - */ - public T pollLast() - { - return map.pollLastEntry().getKey(); - } - -} diff --git a/libjava/classpath/java/util/UUID.java b/libjava/classpath/java/util/UUID.java deleted file mode 100644 index bb25e07..0000000 --- a/libjava/classpath/java/util/UUID.java +++ /dev/null @@ -1,372 +0,0 @@ -/* UUID.java -- Class that represents a UUID object. - Copyright (C) 2006 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.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - -/** - * This class represents a 128-bit UUID value. - * - * There are several types of UUID, and while this class can be used to store - * them, only the Leach-Salz (variant 2) UUID specified in RFC-4122 will - * give meaningful results from the method calls. - * See: http://tools.ietf.org/html/4122 for the details - * - * The format of a Leach-Salz (variant 2) time-based (version 1) UUID - * is as follows: - * time_low - upper 32 bits of the most significant 64 bits, - * this is the least-significant part of the timestamp. - * - * time_mid - bits 16-31 of the most significant 64 bits, - * this is the middle portion of the timestamp. - * - * version - bits 8-15 of the most significant 64 bits. - * - * time_hi - bits 0-7 of the most significant 64 bits, - * the most significant portion of the timestamp. - * - * clock_and_reserved - bits 48-63 of the least significant 64 bits. - * a variable number of bits hold the variant - * (see the spec) - * - * node identifier - bits 0-47 of the least signficant 64 bits. - * - * These fields are valid only for version 1, in the remaining versions, - * only the version and variant fields are set, all others are used for data. - * - * @since 1.5 - * @author Sven de Marothy - */ -public final class UUID - extends Object - implements Serializable, Comparable<UUID> -{ - private static final long serialVersionUID = -4856846361193249489L; - - /** - * Serialized field - most significant 64 bits. - */ - private long mostSigBits; - - /** - * Serialized field - least significant 64 bits. - */ - private long leastSigBits; - - /** - * Random-number generator. - */ - private static transient Random r = new Random(); - - /** - * Constructs a new UUID. - * - * @since 1.5 - */ - public UUID(long mostSigBits, long leastSigBits) - { - this.mostSigBits = mostSigBits; - this.leastSigBits = leastSigBits; - } - - /** - * Returns the clock-sequence value of this UUID. - * This field only exists in a time-based (version 1) UUID. - * - * @throws UnsupportedOperationException if the UUID type is not 1. - * @returns an int containing the clock-sequence value. - */ - public int clockSequence() - { - if( version() != 1 ) - throw new UnsupportedOperationException("Not a type 1 UUID"); - return (int)((leastSigBits & 0x3FFF000000000000L) >> 48); - } - - /** - * Compare this UUID to another. - * The comparison is performed as between two 128-bit integers. - * - * @return -1 if this < val, 0 if they are equal, 1 if this > val. - */ - public int compareTo(UUID o) - { - if( mostSigBits < o.mostSigBits ) - return -1; - if( mostSigBits > o.mostSigBits ) - return 1; - if( leastSigBits < o.leastSigBits ) - return -1; - if( leastSigBits > o.mostSigBits ) - return 1; - return 0; - } - - /** - * Compare a (UUID) object to this one - */ - public boolean equals(Object obj) - { - if( !(obj instanceof UUID ) ) - return false; - return ( ((UUID)obj).mostSigBits == mostSigBits && - ((UUID)obj).leastSigBits == leastSigBits ); - } - - /** - * Creates a UUID object from a Sting representation. - * - * For the format of the string, - * @see #toString() - * - * @return a new UUID object. - */ - public static UUID fromString(String name) - { - StringTokenizer st = new StringTokenizer( name.trim(), "-" ); - if( st.countTokens() < 5 ) - throw new IllegalArgumentException( "Incorrect UUID string"+ - " representation:"+name ); - - long msb = (Long.parseLong(st.nextToken(), 16) << 32); // time low - msb |= (Long.parseLong(st.nextToken(), 16) << 16); // time mid - msb |= Long.parseLong(st.nextToken(), 16); // time high - - long lsb = (Long.parseLong(st.nextToken(), 16) << 48); // clock - lsb |= Long.parseLong(st.nextToken(), 16); // node - - return new UUID(msb, lsb); - } - - /** - * Returns a String representation of the UUID. - * - * The format of the standard string representation (given in RFC4122) is: - * - * time-low "-" time-mid "-" - * time-high-and-version "-" - * clock-seq-and-reserved - * clock-seq-low "-" node - * - * Where each field is represented as a hex string. - * - * @return the String representation. - */ - public String toString() - { - return // time-low first - padHex( (( mostSigBits & 0xFFFFFFFF00000000L) >> 32) & 0xFFFFFFFFL, 8) - + "-" + // then time-mid - padHex( (( mostSigBits & 0xFFFF0000L ) >> 16), 4 ) - + "-" + // time-high - padHex( ( mostSigBits & 0x0000000000000000FFFFL ), 4 ) - + "-" + // clock (note - no reason to separate high and low here) - padHex( (((leastSigBits & 0xFFFF000000000000L) >> 48) & 0xFFFF), 4 ) - + "-" + // finally the node value. - padHex(leastSigBits & 0xFFFFFFFFFFFFL, 12); - } - - /** - * Returns the least significant 64 bits of the UUID as a <code>long</code>. - */ - public long getLeastSignificantBits() - { - return leastSigBits; - } - - /** - * Returns the most significant 64 bits of the UUID as a <code>long</code>. - */ - public long getMostSignificantBits() - { - return mostSigBits; - } - - /** - * Returns a hash of this UUID. - */ - public int hashCode() - { - int l1 = (int)(leastSigBits & 0xFFFFFFFFL); - int l2 = (int)((leastSigBits & 0xFFFFFFFF00000000L) >> 32); - int m1 = (int)(mostSigBits & 0xFFFFFFFFL); - int m2 = (int)((mostSigBits & 0xFFFFFFFF00000000L) >> 32); - - return (l1 ^ l2) ^ (m1 ^ m2); - } - - /** - * Creates a UUID version 3 object (name based with MD5 hashing) - * from a series of bytes representing a name. - */ - public static UUID nameUUIDFromBytes(byte[] name) - { - long msb, lsb; - byte[] hash; - - try - { - MessageDigest md5 = MessageDigest.getInstance("MD5"); - hash = md5.digest( name ); - } - catch (NoSuchAlgorithmException e) - { - throw new UnsupportedOperationException("No MD5 algorithm available."); - } - - msb = ((hash[0] & 0xFFL) << 56) | ((hash[1] & 0xFFL) << 48) | - ((hash[2] & 0xFFL) << 40) | ((hash[3] & 0xFFL) << 32) | - ((hash[4] & 0xFFL) << 24) | ((hash[5] & 0xFFL) << 16) | - ((hash[6] & 0xFFL) << 8) | (hash[7] & 0xFFL); - - lsb = ((hash[8] & 0xFFL) << 56) | ((hash[9] & 0xFFL) << 48) | - ((hash[10] & 0xFFL) << 40) | ((hash[11] & 0xFFL) << 32) | - ((hash[12] & 0xFFL) << 24) | ((hash[13] & 0xFFL) << 16) | - ((hash[14] & 0xFFL) << 8) | (hash[15] & 0xFFL); - - lsb &= 0x3FFFFFFFFFFFFFFFL; - lsb |= 0x8000000000000000L; // set top two bits to variant 2 - - msb &= 0xFFFFFFFFFFFF0FFFL; - msb |= 0x3000; // Version 3; - - return new UUID(msb, lsb); - } - - /** - * Returns the 48-bit node value in a long. - * This field only exists in a time-based (version 1) UUID. - * - * @throws UnsupportedOperationException if the UUID type is not 1. - * @returns a long with the node value in the lower 48 bits. - */ - public long node() - { - if( version() != 1 ) - throw new UnsupportedOperationException("Not a type 1 UUID"); - return (leastSigBits & 0xFFFFFFFFFFFFL); - } - - /** - * Returns the 60-bit timestamp value of the UUID in a long. - * This field only exists in a time-based (version 1) UUID. - * - * @throws UnsupportedOperationException if the UUID type is not 1. - * @returns a long with the timestamp value. - */ - public long timestamp() - { - if( version() != 1 ) - throw new UnsupportedOperationException("Not a type 1 UUID"); - long time = (( mostSigBits & 0xFFFFFFFF00000000L) >> 32); - time |= (( mostSigBits & 0xFFFF0000L ) << 16); - long time_hi = ( mostSigBits & 0xFFFL ); - time |= (time_hi << 48); - return time; - } - - /** - * Generate a Leach-Salz (Variant 2) randomly generated (version 4) - * UUID. - * - */ - public static UUID randomUUID() - { - long lsb = r.nextLong(); - long msb = r.nextLong(); - - lsb &= 0x3FFFFFFFFFFFFFFFL; - lsb |= 0x8000000000000000L; // set top two bits to variant 2 - - msb &= 0xFFFFFFFFFFFF0FFFL; - msb |= 0x4000; // Version 4; - - return new UUID( msb, lsb ); - } - - /** - * Returns a hex String from l, padded to n spaces. - */ - private String padHex( long l, int n ) - { - String s = Long.toHexString( l ); - while( s.length() < n ) - s = "0" + s; - return s; - } - - /** - * Returns the variant of the UUID - * - * This may be: - * 0 = Reserved for NCS backwards-compatibility - * 2 = Leach-Salz (supports the other methods in this class) - * 6 = Reserved for Microsoft backwards-compatibility - * 7 = (reserved for future use) - */ - public int variant() - { - // Get the top 3 bits (not all may be part of the variant) - int v = (int)((leastSigBits & 0xE000000000000000L) >> 61); - if( (v & 0x04) == 0 ) // msb of the variant is 0 - return 0; - if( (v & 0x02) == 0 ) // variant is 0 1 (Leach-Salz) - return 2; - return v; // 6 or 7 - } - - /** - * Returns the version # of the UUID. - * - * Valid version numbers for a variant 2 UUID are: - * 1 = Time based UUID - * 2 = DCE security UUID - * 3 = Name-based UUID using MD5 hashing - * 4 = Randomly generated UUID - * 5 = Name-based UUID using SHA-1 hashing - * - * @return the version number - */ - public int version() - { - return (int)((mostSigBits & 0xF000L) >> 12); - } -} diff --git a/libjava/classpath/java/util/UnknownFormatConversionException.java b/libjava/classpath/java/util/UnknownFormatConversionException.java deleted file mode 100644 index 7326a82..0000000 --- a/libjava/classpath/java/util/UnknownFormatConversionException.java +++ /dev/null @@ -1,86 +0,0 @@ -/* UnknownFormatConversionException.java - Copyright (C) 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; - -/** - * Thrown when a {@link Formatter} is supplied with an - * unknown conversion. - * - * @author Tom Tromey (tromey@redhat.com) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.5 - */ -public class UnknownFormatConversionException - extends IllegalFormatException -{ - private static final long serialVersionUID = 19060418L; - - /** - * The unknown conversion. - * - * @serial the unknown conversion. - */ - // Note: name fixed by serialization. - private String s; - - /** - * Constructs a new <code>UnknownFormatConversionException</code> - * for the specified conversion string. - * - * @param s the conversion string. - * @throws NullPointerException if the conversion string is null. - */ - public UnknownFormatConversionException(String s) - { - super("Unknown format conversion: " + s); - if (s == null) - throw new NullPointerException("The conversion string is null."); - this.s = s; - } - - /** - * Returns the conversion string. - * - * @return the conversion string. - */ - public String getConversion() - { - return s; - } -} diff --git a/libjava/classpath/java/util/UnknownFormatFlagsException.java b/libjava/classpath/java/util/UnknownFormatFlagsException.java deleted file mode 100644 index a7f4fc6..0000000 --- a/libjava/classpath/java/util/UnknownFormatFlagsException.java +++ /dev/null @@ -1,88 +0,0 @@ -/* UnknownFormatFlagsException.java - Copyright (C) 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; - -/** - * Thrown when a {@link Formatter} is supplied with an - * unknown flag. - * - * @author Tom Tromey (tromey@redhat.com) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.5 - */ -public class UnknownFormatFlagsException - extends IllegalFormatException -{ - private static final long serialVersionUID = 19370506L; - - /** - * The set of flags containing the unknown flag. - * - * @serial the unknown conversion. - */ - // Note: name fixed by serialization. - private String flags; - - /** - * Constructs a new <code>UnknownFormatFlagsException</code> - * which specifies that the supplied set of flags contains a - * unknown. - * - * @param flags the flags containing a unknown. - * @throws NullPointerException if <code>flags</code> is null. - */ - public UnknownFormatFlagsException(String s) - { - super("Unknown flag passed in " + s); - if (s == null) - throw new - NullPointerException("Null flags value passed to constructor."); - this.flags = s; - } - - /** - * Returns the flags which contain a unknown. - * - * @return the flags. - */ - public String getFlags() - { - return flags; - } -} diff --git a/libjava/classpath/java/util/Vector.java b/libjava/classpath/java/util/Vector.java deleted file mode 100644 index 44370a1..0000000 --- a/libjava/classpath/java/util/Vector.java +++ /dev/null @@ -1,958 +0,0 @@ -/* Vector.java -- Class that provides growable arrays. - Copyright (C) 1998, 1999, 2000, 2001, 2004, 2005, 2006, - 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<T> extends AbstractList<T> - implements List<T>, 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<? extends T> 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 the Vector into the provided array. If the - * array is too small to fit all the elements in the Vector, an - * {@link IndexOutOfBoundsException} is thrown without modifying the array. - * Old elements in the array 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 - - T[] newArray = (T[]) 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; - - T[] newArray = (T[]) 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<T> elements() - { - return new Enumeration<T>() - { - private int i = 0; - - public boolean hasMoreElements() - { - return i < elementCount; - } - - @SuppressWarnings("unchecked") - public T nextElement() - { - if (i >= elementCount) - throw new NoSuchElementException(); - return (T) 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) - */ - @SuppressWarnings("unchecked") - public synchronized T elementAt(int index) - { - checkBoundExclusive(index); - return (T) elementData[index]; - } - - /** - * Returns the first element (index 0) in the Vector. - * - * @return the first Object in the Vector - * @throws NoSuchElementException the Vector is empty - */ - @SuppressWarnings("unchecked") - public synchronized T firstElement() - { - if (elementCount == 0) - throw new NoSuchElementException(); - - return (T) elementData[0]; - } - - /** - * Returns the last element in the Vector. - * - * @return the last Object in the Vector - * @throws NoSuchElementException the Vector is empty - */ - @SuppressWarnings("unchecked") - public synchronized T lastElement() - { - if (elementCount == 0) - throw new NoSuchElementException(); - - return (T) 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(T 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(T 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(T obj) - { - if (elementCount == elementData.length) - ensureCapacity(elementCount + 1); - modCount++; - elementData[elementCount++] = obj; - } - - /** - * Removes the first (the lowest index) occurrence 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 <S> S[] toArray(S[] a) - { - if (a.length < elementCount) - a = (S[]) 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 T 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 - */ - @SuppressWarnings("unchecked") - public synchronized T set(int index, T element) - { - checkBoundExclusive(index); - T temp = (T) 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(T 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, T 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 - */ - @SuppressWarnings("unchecked") - public synchronized T remove(int index) - { - checkBoundExclusive(index); - T temp = (T) 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<? extends T> 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) - { - // The NullPointerException is thrown implicitly when the Vector - // is not empty and c is null. The RI allows null arguments when - // the vector is empty. See Mauve test: - // gnu/testlet/java/util/Vector/removeAll.java - - 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) - { - // The NullPointerException is thrown implicitly when the Vector - // is not empty and c is null. The RI allows null arguments when - // the vector is empty. See Mauve test: - // gnu/testlet/java/util/Vector/retainAll.java - - 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<? extends T> c) - { - checkBoundInclusive(index); - Iterator<? extends T> 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<T> subList(int fromIndex, int toIndex) - { - List<T> 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<T>(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) - raiseBoundsError(index, " > "); - } - - /** - * 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) - raiseBoundsError(index, " >= "); - } - - /** - * Raise the ArrayIndexOfOutBoundsException. - * - * @param index the index of the access - * @param operator the operator to include in the error message - * @throws IndexOutOfBoundsException unconditionally - */ - private void raiseBoundsError(int index, String operator) - { - // Implementaion note: put in a separate method to make the JITs job easier - // (separate common from uncommon code at method boundaries when trivial to - // do so). - throw new ArrayIndexOutOfBoundsException(index + operator + 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/classpath/java/util/WeakHashMap.java b/libjava/classpath/java/util/WeakHashMap.java deleted file mode 100644 index 3e4d347..0000000 --- a/libjava/classpath/java/util/WeakHashMap.java +++ /dev/null @@ -1,880 +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, 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.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) - * @author Tom Tromey (tromey@redhat.com) - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * - * @see HashMap - * @see WeakReference - * @see LinkedHashMap - * @since 1.2 - * @status updated to 1.4 (partial 1.5) - */ -public class WeakHashMap<K,V> extends AbstractMap<K,V> -{ - // 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(knownMod + " != " - + modCount); - } - - /** - * 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. - */ - public boolean hasNext() - { - 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<K, V> extends WeakReference<K> - { - /** - * The value of this entry. The key is stored in the weak - * reference that we extend. - */ - V value; - - /** - * The next bucket describing another entry that uses the same - * slot. - */ - WeakBucket<K, V> 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(K key, ReferenceQueue queue, V 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<K, V> - { - /** - * The strong ref to the key. - */ - K key; - - /** - * Creates a new entry for the key. - * @param key the key - */ - public WeakEntry(K 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 K getKey() - { - return key == NULL_KEY ? null : key; - } - - /** - * Returns the value. - * @return the value - */ - public V 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 V setValue(V newVal) - { - V 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 WeakHashMap.equals(getKey(), e.getKey()) - && WeakHashMap.equals(value, e.getValue()); - } - return false; - } - - public String toString() - { - return getKey() + "=" + 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 K 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<? extends K, ? extends V> 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 && equals(key, 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; - - WeakBucket prev = null; - WeakBucket next = buckets[slot]; - while (next != bucket) - { - if (next == null) throw new InternalError("WeakHashMap in incosistent state"); - prev = next; - next = prev.next; - } - if (prev == null) - buckets[slot] = bucket.next; - else - 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 V get(Object key) - { - cleanQueue(); - WeakBucket<K, V>.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 V put(K key, V value) - { - cleanQueue(); - WeakBucket<K, V>.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 V remove(Object key) - { - cleanQueue(); - WeakBucket<K, V>.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<Map.Entry<K,V>> 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<K> 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<? extends K, ? extends V> 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<V> values() - { - cleanQueue(); - return super.values(); - } -} // class WeakHashMap diff --git a/libjava/classpath/java/util/concurrent/CopyOnWriteArrayList.java b/libjava/classpath/java/util/concurrent/CopyOnWriteArrayList.java deleted file mode 100644 index f9f1ac1..0000000 --- a/libjava/classpath/java/util/concurrent/CopyOnWriteArrayList.java +++ /dev/null @@ -1,1463 +0,0 @@ -/* CopyOnWriteArrayList.java - Copyright (C) 2006 Free Software Foundation - -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.concurrent; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; - -import java.lang.reflect.Array; - -import java.util.AbstractList; -import java.util.Arrays; -import java.util.Collection; -import java.util.ConcurrentModificationException; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.NoSuchElementException; -import java.util.RandomAccess; - -/** - * A thread-safe implementation of an ArrayList. A CopyOnWriteArrayList is - * as special ArrayList which performs copies of the underlying storage - * each time a write (<code>remove</code>, <code>add</code> etc..) operation - * is performed.<br /> - * <br /> - * The update operation in this class run usually in <code>O(n)</code> or worse, - * but traversal operations are fast and efficient, especially when running in - * a multi-thread environment without the need to design complex synchronize - * mechanisms.<br /> - * <br /> - * <code>Iterator</code>s in this class work on a snapshot of the backing store - * at the moment the iterator itself was created, hence the iterator will not - * reflect changes in the underlying storage. Thus, update operation on the - * <code>Iterator</code>s are not supported, but as interferences from other - * threads are impossible, no <code>ConcurrentModificationException</code> - * will be ever thrown from within the <code>Iterator</code>. - * <br /><br /> - * This class is especially useful when used with event handling, like the - * following code demonstrates:<br /> - * <code><pre> - * - * CopyOnWriteArrayList<EventListener> listeners = - * new CopyOnWriteArrayList<EventListener>(); - * - * [...] - * - * for (final EventListener listener : listeners) - * { - * Runnable dispatcher = new Runnable() { - * public void run() - * { - * listener.preferenceChange(event); - * } - * }; - * - * Executor executor = Executors.newSingleThreadExecutor(); - * executor.execute(dispatcher); - * } - * </pre></code> - * - * @since 1.5 - */ -public class CopyOnWriteArrayList<E> - implements List<E>, RandomAccess, Cloneable, Serializable -{ - /** - * - */ - private static final long serialVersionUID = 8673264195747942595L; - - /** - * Where the data is stored. - */ - private transient E[] data; - - /** - * Construct a new ArrayList with the default capacity (16). - */ - public CopyOnWriteArrayList() - { - data = (E[]) new Object[0]; - } - - /** - * 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 CopyOnWriteArrayList(Collection< ? extends E> c) - { - // FIXME ... correct? use c.toArray() - data = (E[]) new Object[c.size()]; - int index = 0; - for (E value : c) - data[index++] = value; - } - - /** - * Construct a new ArrayList, and initialize it with the elements in the - * supplied array. - * - * @param array - * the array used to initialize this list - * @throws NullPointerException - * if array is null - */ - public CopyOnWriteArrayList(E[] array) - { - data = (E[]) array.clone(); - } - - /** - * Returns the number of elements in this list. - * - * @return the list size - */ - public int size() - { - return data.length; - } - - /** - * Checks if the list is empty. - * - * @return true if there are no elements - */ - public boolean isEmpty() - { - return data.length == 0; - } - - /** - * Returns true if 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; - } - - /** - * 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; - } - - /** - * 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) - { - E[] data = this.data; - for (int i = 0; i < data.length; i++) - if (equals(e, data[i])) - return i; - return -1; - } - - /** - * Return the lowest index greater equal <code>index</code> at which - * <code>e</code> appears in this List, or -1 if it does not - * appear. - * - * @param e the element whose inclusion in the list is being tested - * @param index the index at which the search begins - * @return the index where <code>e</code> was found - */ - public int indexOf(E e, int index) - { - E[] data = this.data; - - for (int i = index; i < data.length; 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) - { - E[] data = this.data; - for (int i = data.length - 1; i >= 0; i--) - if (equals(e, data[i])) - return i; - return -1; - } - - /** - * Returns the highest index lesser equal <code>index</code> at - * which <code>e</code> appears in this List, or -1 if it does not - * appear. - * - * @param e the element whose inclusion in the list is being tested - * @param index the index at which the search begins - * @return the index where <code>e</code> was found - */ - public int lastIndexOf(E e, int index) - { - E[] data = this.data; - - for (int i = index; 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() - { - CopyOnWriteArrayList<E> clone = null; - try - { - clone = (CopyOnWriteArrayList<E>) super.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() - { - E[] data = this.data; - E[] array = (E[]) new Object[data.length]; - System.arraycopy(data, 0, array, 0, data.length); - 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 <T> T[] toArray(T[] a) - { - E[] data = this.data; - if (a.length < data.length) - a = (T[]) Array.newInstance(a.getClass().getComponentType(), data.length); - else if (a.length > data.length) - a[data.length] = null; - System.arraycopy(data, 0, a, 0, data.length); - 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 E get(int 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 synchronized E set(int index, E e) - { - E result = data[index]; - E[] newData = (E[]) data.clone(); - newData[index] = e; - data = newData; - 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 synchronized boolean add(E e) - { - E[] data = this.data; - E[] newData = (E[]) new Object[data.length + 1]; - System.arraycopy(data, 0, newData, 0, data.length); - newData[data.length] = e; - this.data = newData; - 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 synchronized void add(int index, E e) - { - E[] data = this.data; - E[] newData = (E[]) new Object[data.length + 1]; - System.arraycopy(data, 0, newData, 0, index); - newData[index] = e; - System.arraycopy(data, index, newData, index + 1, data.length - index); - this.data = newData; - } - - /** - * 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 synchronized E remove(int index) - { - if (index < 0 || index >= this.size()) - throw new IndexOutOfBoundsException("index = " + index); - - E[] snapshot = this.data; - E[] newData = (E[]) new Object[snapshot.length - 1]; - - E result = snapshot[index]; - - if (index > 0) - System.arraycopy(snapshot, 0, newData, 0, index); - - System.arraycopy(snapshot, index + 1, newData, index, - snapshot.length - index - 1); - - this.data = newData; - - return result; - } - - /** - * Remove the first occurrence, if any, of the given object from this list, - * returning <code>true</code> if the object was removed, <code>false</code> - * otherwise. - * - * @param element the object to be removed. - * @return true if element was removed, false otherwise. false means also that - * the underlying storage was unchanged after this operation concluded. - */ - public synchronized boolean remove(Object element) - { - E[] snapshot = this.data; - int len = snapshot.length; - - if (len == 0) - return false; - - E[] newData = (E[]) new Object[len - 1]; - - // search the element to remove while filling the backup array - // this way we can run this method in O(n) - int elementIndex = -1; - for (int i = 0; i < snapshot.length; i++) - { - if (equals(element, snapshot[i])) - { - elementIndex = i; - break; - } - - if (i < newData.length) - newData[i] = snapshot[i]; - } - - if (elementIndex < 0) - return false; - - System.arraycopy(snapshot, elementIndex + 1, newData, elementIndex, - snapshot.length - elementIndex - 1); - this.data = newData; - - return true; - } - - /** - * Removes all the elements contained in the given collection. - * This method removes the elements that are contained in both - * this list and in the given collection. - * - * @param c the collection containing the elements to be removed from this - * list. - * @return true if at least one element was removed, indicating that - * the list internal storage changed as a result, false otherwise. - */ - public synchronized boolean removeAll(Collection<?> c) - { - if (c.size() == 0) - return false; - - E [] snapshot = this.data; - E [] storage = (E[]) new Object[this.data.length]; - boolean changed = false; - - int length = 0; - for (E element : snapshot) - { - // copy all the elements, including null values - // if the collection can hold it - // FIXME: slow operation - if (c.contains(element)) - changed = true; - else - storage[length++] = element; - } - - if (!changed) - return false; - - E[] newData = (E[]) new Object[length]; - System.arraycopy(storage, 0, newData, 0, length); - - this.data = newData; - - return true; - } - - /** - * Removes all the elements that are not in the passed collection. - * If the collection is void, this method has the same effect of - * <code>clear()</code>. - * Please, note that this method is extremely slow (unless the argument has - * <code>size == 0</code>) and has bad performance is both space and time - * usage. - * - * @param c the collection containing the elements to be retained by this - * list. - * @return true the list internal storage changed as a result of this - * operation, false otherwise. - */ - public synchronized boolean retainAll(Collection<?> c) - { - // if the given collection does not contain elements - // we remove all the elements from our storage - if (c.size() == 0) - { - this.clear(); - return true; - } - - E [] snapshot = this.data; - E [] storage = (E[]) new Object[this.data.length]; - - int length = 0; - for (E element : snapshot) - { - if (c.contains(element)) - storage[length++] = element; - } - - // means we retained all the elements previously in our storage - // we are running already slow here, but at least we avoid copying - // another array and changing the internal storage - if (length == snapshot.length) - return false; - - E[] newData = (E[]) new Object[length]; - System.arraycopy(storage, 0, newData, 0, length); - - this.data = newData; - - return true; - } - - /** - * Removes all elements from this List - */ - public synchronized void clear() - { - data = (E[]) new Object[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 synchronized boolean addAll(Collection< ? extends E> c) - { - return addAll(data.length, 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 synchronized boolean addAll(int index, Collection< ? extends E> c) - { - if (index < 0 || index > this.size()) - throw new IndexOutOfBoundsException("index = " + index); - - int csize = c.size(); - if (csize == 0) - return false; - - E[] data = this.data; - Iterator<? extends E> itr = c.iterator(); - - E[] newData = (E[]) new Object[data.length + csize]; - - // avoid this call at all if we were asked to put the elements at the - // beginning of our storage - if (index != 0) - System.arraycopy(data, 0, newData, 0, index); - - int itemsLeft = index; - - for (E value : c) - newData[index++] = value; - - // now copy the remaining elements - System.arraycopy(data, itemsLeft, newData, 0, data.length - itemsLeft); - - this.data = newData; - - return true; - } - - /** - * Adds an element if the list does not contains it already. - * - * @param val the element to add to the list. - * @return true if the element was added, false otherwise. - */ - public synchronized boolean addIfAbsent(E val) - { - if (contains(val)) - return false; - add(val); - return true; - } - - /** - * Adds all the element from the given collection that are not already - * in this list. - * - * @param c the Collection containing the elements to be inserted - * @return true the list internal storage changed as a result of this - * operation, false otherwise. - */ - public synchronized int addAllAbsent(Collection<? extends E> c) - { - int size = c.size(); - if (size == 0) - return 0; - - E [] snapshot = this.data; - E [] storage = (E[]) new Object[size]; - - size = 0; - for (E val : c) - { - if (!this.contains(val)) - storage[size++] = val; - } - - if (size == 0) - return 0; - - // append storage to data - E [] newData = (E[]) new Object[snapshot.length + size]; - - System.arraycopy(snapshot, 0, newData, 0, snapshot.length); - System.arraycopy(storage, 0, newData, snapshot.length, size); - - this.data = newData; - - return size; - } - - public String toString() - { - return Arrays.toString(this.data); - } - - public boolean equals(Object o) - { - if (o == null) - return false; - - if (this == o) - return true; - - // let's see if 'o' is a list, if so, we need to compare the elements - // as returned by the iterator - if (o instanceof List) - { - List<?> source = (List<?>) o; - - if (source.size() != this.size()) - return false; - - Iterator<?> sourceIterator = source.iterator(); - for (E element : this) - { - if (!element.equals(sourceIterator.next())) - return false; - } - - return true; - } - - return false; - } - - public int hashCode() - { - // see http://java.sun.com/6/docs/api/java/util/List.html#hashcode() - int hashcode = 1; - for (E element : this) - { - hashcode = 31 * hashcode + (element == null ? 0 : element.hashCode()); - } - return hashcode; - } - - /** - * Return an Iterator containing the elements of this list. - * The Iterator uses a snapshot of the state of the internal storage - * at the moment this method is called and does <strong>not</strong> support - * update operations, so no synchronization is needed to traverse the - * iterator. - * - * @return an Iterator containing the elements of this list in sequence. - */ - public Iterator<E> iterator() - { - return new Iterator<E>() - { - E [] iteratorData = CopyOnWriteArrayList.this.data; - int currentElement = 0; - - public boolean hasNext() - { - return (currentElement < iteratorData.length); - } - - public E next() - { - return iteratorData[currentElement++]; - } - - public void remove() - { - throw new UnsupportedOperationException("updating of elements in " + - "iterators is not supported " + - "by this class"); - } - }; - } - - /** - * Return a ListIterator containing the elements of this list. - * The Iterator uses a snapshot of the state of the internal storage - * at the moment this method is called and does <strong>not</strong> support - * update operations, so no synchronization is needed to traverse the - * iterator. - * - * @return a ListIterator containing the elements of this list in sequence. - */ - public ListIterator<E> listIterator() - { - return listIterator(0); - } - - /** - * Return a ListIterator over the elements of this list starting at - * the specified index. An initial call to {@code next()} will thus - * return the element at {@code index}, while an initial call to - * {@code previous()} will return the element at {@code index-1}. The - * Iterator uses a snapshot of the state of the internal storage - * at the moment this method is called and does <strong>not</strong> support - * update operations, so no synchronization is needed to traverse the - * iterator. - * - * @param index the index at which to start iterating. - * @return a ListIterator containing the elements of this list in sequence. - */ - public ListIterator<E> listIterator(final int index) - { - if (index < 0 || index > size()) - throw new IndexOutOfBoundsException("Index: " + index + ", Size:" - + size()); - - return new ListIterator<E>() - { - E [] iteratorData = CopyOnWriteArrayList.this.data; - int currentElement = index; - - public void add(E o) - { - throw new UnsupportedOperationException("updating of elements in " + - "iterators is not supported " + - "by this class"); - } - - public boolean hasNext() - { - return (currentElement < iteratorData.length); - } - - public boolean hasPrevious() - { - return (currentElement > 0); - } - - public E next() - { - if (hasNext() == false) - throw new java.util.NoSuchElementException(); - - return iteratorData[currentElement++]; - } - - public int nextIndex() - { - return (currentElement + 1); - } - - public E previous() - { - if (hasPrevious() == false) - throw new java.util.NoSuchElementException(); - - return iteratorData[--currentElement]; - } - - public int previousIndex() - { - return (currentElement - 1); - } - - public void remove() - { - throw new UnsupportedOperationException("updating of elements in " + - "iterators is not supported " + - "by this class"); - } - - public void set(E o) - { - throw new UnsupportedOperationException("updating of elements in " + - "iterators is not supported " + - "by this class"); - } - - }; - } - - /** - * 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 IndexOutOfBoundsException if fromIndex > toIndex - * @see ConcurrentModificationException - * @see RandomAccess - */ - public synchronized List<E> 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 IndexOutOfBoundsException(fromIndex + " > " + toIndex); - if (fromIndex < 0 || toIndex > size()) - throw new IndexOutOfBoundsException(); - - if (this instanceof RandomAccess) - return new RandomAccessSubList<E>(this, fromIndex, toIndex); - return new SubList<E>(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<E> - extends AbstractList<E> - { - // Package visible, for use by iterator. - /** The original list. */ - final CopyOnWriteArrayList<E> backingList; - /** The index of the first element of the sublist. */ - final int offset; - /** The size of the sublist. */ - int size; - /** The backing data */ - E[] data; - - /** - * Construct the sublist. - * - * @param backing the list this comes from - * @param fromIndex the lower bound, inclusive - * @param toIndex the upper bound, exclusive - */ - SubList(CopyOnWriteArrayList<E> backing, int fromIndex, int toIndex) - { - backingList = backing; - data = backing.data; - 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 (data != backingList.data) - 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() - { - synchronized (backingList) - { - checkMod(); - return size; - } - } - - public void clear() - { - synchronized (backingList) - { - E[] snapshot = backingList.data; - E[] newData = (E[]) new Object[snapshot.length - size]; - - int toIndex = size + offset; - - System.arraycopy(snapshot, 0, newData, 0, offset); - System.arraycopy(snapshot, toIndex, newData, offset, - snapshot.length - toIndex); - - backingList.data = newData; - this.data = backingList.data; - this.size = 0; - } - } - - /** - * 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 E set(int index, E o) - { - synchronized (backingList) - { - checkMod(); - checkBoundsExclusive(index); - - E el = backingList.set(index + offset, o); - this.data = backingList.data; - - return el; - } - } - - /** - * 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 E get(int index) - { - synchronized (backingList) - { - 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, E o) - { - synchronized (backingList) - { - checkMod(); - checkBoundsInclusive(index); - - backingList.add(index + offset, o); - - this.data = backingList.data; - size++; - } - } - - /** - * 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 E remove(int index) - { - synchronized (backingList) - { - checkMod(); - checkBoundsExclusive(index); - E o = backingList.remove(index + offset); - - this.data = backingList.data; - size--; - - return o; - } - } - - /** - * 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<? extends E> c) - { - synchronized (backingList) - { - checkMod(); - checkBoundsInclusive(index); - int csize = c.size(); - boolean result = backingList.addAll(offset + index, c); - - this.data = backingList.data; - size += csize; - - 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<? extends E> c) - { - synchronized (backingList) - { - return addAll(size, c); - } - } - - /** - * Specified by AbstractList.subList to return listIterator(). - * - * @return an iterator over the sublist - */ - public Iterator<E> 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<E> listIterator(final int index) - { - checkMod(); - checkBoundsInclusive(index); - - return new ListIterator<E>() - { - private final ListIterator<E> 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. - */ - public boolean hasNext() - { - 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. - */ - public boolean hasPrevious() - { - 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 E 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 E 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. - */ - 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. - */ - 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() - { - throw new UnsupportedOperationException("Modification not supported " + - "on CopyOnWriteArrayList iterators"); - } - - /** - * 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(E o) - { - throw new UnsupportedOperationException("Modification not supported " + - "on CopyOnWriteArrayList iterators"); - } - - /** - * 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(E o) - { - throw new UnsupportedOperationException("Modification not supported " + - "on CopyOnWriteArrayList iterators"); - } - }; - } - } // 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<E> extends SubList<E> - 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(CopyOnWriteArrayList<E> backing, int fromIndex, int toIndex) - { - super(backing, fromIndex, toIndex); - } - } // class RandomAccessSubList - - /** - * Serializes this object to the given stream. - * - * @param s - * 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 < data.length; i++) - s.writeObject(data[i]); - } - - /** - * 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 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 = (E[]) new Object[capacity]; - for (int i = 0; i < capacity; i++) - data[i] = (E) s.readObject(); - } - - static final boolean equals(Object o1, Object o2) - { - return o1 == null ? o2 == null : o1.equals(o2); - } - - Object[] getArray() - { - return data; - } -} diff --git a/libjava/classpath/java/util/jar/Attributes.java b/libjava/classpath/java/util/jar/Attributes.java deleted file mode 100644 index 8880029..0000000 --- a/libjava/classpath/java/util/jar/Attributes.java +++ /dev/null @@ -1,629 +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 gnu.java.util.jar.JarUtils; - -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<Object, Object> -{ - - // 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<Object, Object> 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(JarUtils.MANIFEST_VERSION); - - /** - * General main attribute - - * the version of the jar file signature. - */ - public static final Name SIGNATURE_VERSION = new Name(JarUtils.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. - * - * @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 - */ - private 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<Map.Entry<Object, Object>> 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<Object> 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<Object> values() - { - return map.values(); - } -} diff --git a/libjava/classpath/java/util/jar/JarEntry.java b/libjava/classpath/java/util/jar/JarEntry.java deleted file mode 100644 index 52cb2c3..0000000 --- a/libjava/classpath/java/util/jar/JarEntry.java +++ /dev/null @@ -1,172 +0,0 @@ -/* JarEntry.java - Represents an entry in a jar file - Copyright (C) 2000, 2006 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.Set; -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; - JarFile jarfile; - - // 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; - jarfile = 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; - jarfile = 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 _) - { - } - jarfile = entry.jarfile; - } - - // 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 (jarfile != null) - { - synchronized (jarfile) - { - if (jarfile.entryCerts != null) - { - Set certs = (Set) jarfile.entryCerts.get(getName()); - if (certs != null - && jarfile.verified.get(getName()) == Boolean.TRUE) - return (Certificate[]) certs.toArray(new Certificate[certs.size()]); - } - } - } - return null; - } -} diff --git a/libjava/classpath/java/util/jar/JarException.java b/libjava/classpath/java/util/jar/JarException.java deleted file mode 100644 index d6f0634..0000000 --- a/libjava/classpath/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/classpath/java/util/jar/JarFile.java b/libjava/classpath/java/util/jar/JarFile.java deleted file mode 100644 index b67c953..0000000 --- a/libjava/classpath/java/util/jar/JarFile.java +++ /dev/null @@ -1,981 +0,0 @@ -/* JarFile.java - Representation of a jar file - Copyright (C) 2000, 2003, 2004, 2005, 2006 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 gnu.java.security.provider.Gnu; - -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.regex.Matcher; -import java.util.regex.Pattern; -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"; - - /** - * The security provider to use for signature verification. - * We need a known fallback to be able to read any signed jar file - * (which might contain the user selected security provider). - * This is package-private to avoid accessor methods for inner classes. - */ - static final Gnu provider = new Gnu(); - - // 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; - - /** - * A {@link Map} of message digest algorithm names to their implementation. - * Used to reduce object (algorithm implementation) instantiation. - */ - private HashMap digestAlgorithms = new HashMap(); - - 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<JarEntry> 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<JarEntry> - { - - private final Enumeration<? extends ZipEntry> entries; - private final JarFile jarfile; - - JarEnumeration(Enumeration<? extends ZipEntry> e, JarFile f) - { - entries = e; - jarfile = f; - } - - public boolean hasMoreElements() - { - return entries.hasMoreElements(); - } - - public JarEntry 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.verify && !jarfile.signaturesRead) - try - { - jarfile.readSignatures(); - } - catch (IOException ioe) - { - if (JarFile.DEBUG) - { - JarFile.debug(ioe); - ioe.printStackTrace(); - } - jarfile.signaturesRead = true; // fudge it. - } - } - jar.jarfile = jarfile; - 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 (verify && !signaturesRead) - try - { - readSignatures(); - } - catch (IOException ioe) - { - if (DEBUG) - { - debug(ioe); - ioe.printStackTrace(); - } - signaturesRead = true; - } - jarEntry.jarfile = this; - 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. - // Package private for use in inner classes. - 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(); - } - - // Read the manifest into a HashMap (String fileName, String entry) - // The fileName might be split into multiple lines in the manifest. - // Such additional lines will start with a space. - InputStream in = super.getInputStream(super.getEntry(MANIFEST_NAME)); - ByteArrayOutputStream baStream = new ByteArrayOutputStream(); - byte[] ba = new byte[1024]; - while (true) - { - int len = in.read(ba); - if (len < 0) - break; - baStream.write(ba, 0, len); - } - in.close(); - - HashMap hmManifestEntries = new HashMap(); - Pattern p = Pattern.compile("Name: (.+?\r?\n(?: .+?\r?\n)*)" - + ".+?-Digest: .+?\r?\n\r?\n"); - Matcher m = p.matcher(baStream.toString()); - while (m.find()) - { - String fileName = m.group(1).replaceAll("\r?\n ?", ""); - hmManifestEntries.put(fileName, m.group()); - } - - // 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, hmManifestEntries)) - { - 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", provider); - } - else if (alg.equals(RSA_ENCRYPTION_OID)) - { - OID hash = signerInfo.getDigestAlgorithmId(); - if (hash.equals(MD2_OID)) - sig = Signature.getInstance("md2WithRsaEncryption", provider); - else if (hash.equals(MD4_OID)) - sig = Signature.getInstance("md4WithRsaEncryption", provider); - else if (hash.equals(MD5_OID)) - sig = Signature.getInstance("md5WithRsaEncryption", provider); - else if (hash.equals(SHA1_OID)) - sig = Signature.getInstance("sha1WithRsaEncryption", provider); - 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. - * @param hmManifestEntries Mappings of Jar file entry names to their manifest - * entry text; i.e. the base-64 encoding of their - */ - private boolean verifyHashes(String entry, Attributes attr, - HashMap hmManifestEntries) - { - int verified = 0; - - String stringEntry = (String) hmManifestEntries.get(entry); - if (stringEntry == null) - { - if (DEBUG) - debug("could not find " + entry + " in manifest"); - return false; - } - // The bytes for ENTRY's manifest entry, which are signed in the - // signature file. - byte[] entryBytes = stringEntry.getBytes(); - - 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) digestAlgorithms.get(alg); - if (md == null) - { - md = MessageDigest.getInstance(alg, provider); - digestAlgorithms.put(alg, md); - } - md.reset(); - byte[] hash2 = md.digest(entryBytes); - 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; - } - - /** - * 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 - { - int length = key.length() - DIGEST_KEY_SUFFIX.length(); - String alg = key.substring(0, length); - md.add(MessageDigest.getInstance(alg, provider)); - } - 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/classpath/java/util/jar/JarInputStream.java b/libjava/classpath/java/util/jar/JarInputStream.java deleted file mode 100644 index 4de6609..0000000 --- a/libjava/classpath/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/classpath/java/util/jar/JarOutputStream.java b/libjava/classpath/java/util/jar/JarOutputStream.java deleted file mode 100644 index 0ba6002..0000000 --- a/libjava/classpath/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.putNextEntry()</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/classpath/java/util/jar/Manifest.java b/libjava/classpath/java/util/jar/Manifest.java deleted file mode 100644 index f266d82..0000000 --- a/libjava/classpath/java/util/jar/Manifest.java +++ /dev/null @@ -1,213 +0,0 @@ -/* Manifest.java -- Reads, writes and manipulates 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 gnu.java.util.jar.JarUtils; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Hashtable; -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<String, Attributes> entries; - - // Constructors - - /** - * Creates a new empty Manifest. - */ - public Manifest() - { - mainAttr = new Attributes(); - entries = new Hashtable<String, Attributes>(); - } - - /** - * Creates a Manifest from the supplied input stream. - * - * @see #read(InputStream) - * @see #write(OutputStream) - * - * @param in 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<String, Attributes>(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<String, Attributes> 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 getEntries().get(entryName); - } - - /** - * Clears the main attributes and removes all the entries from the - * manifest. - */ - public void clear() - { - mainAttr.clear(); - entries.clear(); - } - - /** - * Read and merge a <code>Manifest</code> from the designated input stream. - * - * @param in the input stream to read from. - * @throws IOException if an I/O related exception occurs during the process. - */ - public void read(InputStream in) throws IOException - { - JarUtils.readMFManifest(getMainAttributes(), getEntries(), in); - } - - /** - * Writes the contents of this <code>Manifest</code> to the designated - * output stream. Line-endings are platform-independent and consist of the - * 2-codepoint sequence <code>0x0D</code> and <code>0x0A</code>. - * - * @param out the output stream to write this <code>Manifest</code> to. - * @throws IOException if an I/O related exception occurs during the process. - */ - public void write(OutputStream out) throws IOException - { - JarUtils.writeMFManifest(getMainAttributes(), getEntries(), out); - } - - /** - * 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/classpath/java/util/jar/package.html b/libjava/classpath/java/util/jar/package.html deleted file mode 100644 index 7fd8787..0000000 --- a/libjava/classpath/java/util/jar/package.html +++ /dev/null @@ -1,47 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> -<!-- package.html - describes classes in java.util.jar package. - 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. --> - -<html> -<head><title>GNU Classpath - java.util.jar</title></head> - -<body> -<p>Utility classes for manipulating java archives -(zip files with a manifest file with attributes).</p> - -</body> -</html> diff --git a/libjava/classpath/java/util/logging/ConsoleHandler.java b/libjava/classpath/java/util/logging/ConsoleHandler.java deleted file mode 100644 index 9f6bb72..0000000 --- a/libjava/classpath/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/classpath/java/util/logging/ErrorManager.java b/libjava/classpath/java/util/logging/ErrorManager.java deleted file mode 100644 index 291efb2f..0000000 --- a/libjava/classpath/java/util/logging/ErrorManager.java +++ /dev/null @@ -1,193 +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/classpath/java/util/logging/FileHandler.java b/libjava/classpath/java/util/logging/FileHandler.java deleted file mode 100644 index 00d967f..0000000 --- a/libjava/classpath/java/util/logging/FileHandler.java +++ /dev/null @@ -1,665 +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 gnu.java.lang.CPStringBuilder; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.LinkedList; -import java.util.ListIterator; - -/** - * 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>user.home</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 -{ - /** - * A literal that prefixes all file-handler related properties in the - * logging.properties file. - */ - private static final String PROPERTY_PREFIX = "java.util.logging.FileHandler"; - /** - * The name of the property to set for specifying a file naming (incl. path) - * pattern to use with rotating log files. - */ - private static final String PATTERN_KEY = PROPERTY_PREFIX + ".pattern"; - /** - * The default pattern to use when the <code>PATTERN_KEY</code> property was - * not specified in the logging.properties file. - */ - private static final String DEFAULT_PATTERN = "%h/java%u.log"; - /** - * The name of the property to set for specifying an approximate maximum - * amount, in bytes, to write to any one log output file. A value of zero - * (which is the default) implies a no limit. - */ - private static final String LIMIT_KEY = PROPERTY_PREFIX + ".limit"; - private static final int DEFAULT_LIMIT = 0; - /** - * The name of the property to set for specifying how many output files to - * cycle through. The default value is 1. - */ - private static final String COUNT_KEY = PROPERTY_PREFIX + ".count"; - private static final int DEFAULT_COUNT = 1; - /** - * The name of the property to set for specifying whether this handler should - * append, or not, its output to existing files. The default value is - * <code>false</code> meaning NOT to append. - */ - private static final String APPEND_KEY = PROPERTY_PREFIX + ".append"; - private static final boolean DEFAULT_APPEND = false; - - /** - * 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; - - - /** - * The number of bytes that have currently been written to the stream. - * Package private for use in inner classes. - */ - long written; - - - /** - * A linked list of files we are, or have written to. The entries - * are file path strings, kept in the order - */ - private LinkedList logFiles; - - - /** - * 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(LogManager.getLogManager().getProperty(PATTERN_KEY), - LogManager.getIntProperty(LIMIT_KEY, DEFAULT_LIMIT), - LogManager.getIntProperty(COUNT_KEY, DEFAULT_COUNT), - LogManager.getBooleanProperty(APPEND_KEY, DEFAULT_APPEND)); - } - - - /* FIXME: Javadoc missing. */ - public FileHandler(String pattern) - throws IOException, SecurityException - { - this(pattern, DEFAULT_LIMIT, DEFAULT_COUNT, DEFAULT_APPEND); - } - - - /* FIXME: Javadoc missing. */ - public FileHandler(String pattern, boolean append) - throws IOException, SecurityException - { - this(pattern, DEFAULT_LIMIT, DEFAULT_COUNT, append); - } - - - /* FIXME: Javadoc missing. */ - public FileHandler(String pattern, int limit, int count) - throws IOException, SecurityException - { - this(pattern, limit, count, - LogManager.getBooleanProperty(APPEND_KEY, DEFAULT_APPEND)); - } - - - /** - * 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(/* output stream, created below */ null, - PROPERTY_PREFIX, - /* default level */ Level.ALL, - /* formatter */ null, - /* default formatter */ XMLFormatter.class); - - if ((limit <0) || (count < 1)) - throw new IllegalArgumentException(); - - this.pattern = pattern != null ? pattern : DEFAULT_PATTERN; - this.limit = limit; - this.count = count; - this.append = append; - this.written = 0; - this.logFiles = new LinkedList (); - - setOutputStream (createFileStream (this.pattern, limit, count, append, - /* generation */ 0)); - } - - - /* FIXME: Javadoc missing. */ - private 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(PATTERN_KEY); - if (pattern == null) - pattern = DEFAULT_PATTERN; - - if (count > 1 && !has (pattern, 'g')) - pattern = pattern + ".%g"; - - do - { - path = replaceFileNameEscapes(pattern, generation, unique, count); - - try - { - File file = new File(path); - if (!file.exists () || append) - { - FileOutputStream fout = new FileOutputStream (file, append); - // FIXME we need file locks for this to work properly, but they - // are not implemented yet in Classpath! Madness! -// FileChannel channel = fout.getChannel (); -// FileLock lock = channel.tryLock (); -// if (lock != null) // We've locked the file. -// { - if (logFiles.isEmpty ()) - logFiles.addFirst (path); - return new ostr (fout); -// } - } - } - catch (Exception ex) - { - reportError (null, ex, ErrorManager.OPEN_FAILURE); - } - - unique = unique + 1; - if (!has (pattern, 'u')) - 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) - { - CPStringBuilder buf = new CPStringBuilder(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. */ - public void publish(LogRecord record) - { - if (limit > 0 && written >= limit) - rotate (); - super.publish(record); - flush (); - } - - /** - * Rotates the current log files, possibly removing one if we - * exceed the file count. - */ - private synchronized void rotate () - { - if (logFiles.size () > 0) - { - File f1 = null; - ListIterator lit = null; - - // If we reach the file count, ditch the oldest file. - if (logFiles.size () == count) - { - f1 = new File ((String) logFiles.getLast ()); - f1.delete (); - lit = logFiles.listIterator (logFiles.size () - 1); - } - // Otherwise, move the oldest to a new location. - else - { - String path = replaceFileNameEscapes (pattern, logFiles.size (), - /* unique */ 0, count); - f1 = new File (path); - logFiles.addLast (path); - lit = logFiles.listIterator (logFiles.size () - 1); - } - - // Now rotate the files. - while (lit.hasPrevious ()) - { - String s = (String) lit.previous (); - File f2 = new File (s); - f2.renameTo (f1); - f1 = f2; - } - } - - setOutputStream (createFileStream (pattern, limit, count, append, - /* generation */ 0)); - - // Reset written count. - written = 0; - } - - /** - * Tell if <code>pattern</code> contains the pattern sequence - * with character <code>escape</code>. That is, if <code>escape</code> - * is 'g', this method returns true if the given pattern contains - * "%g", and not just the substring "%g" (for example, in the case of - * "%%g"). - * - * @param pattern The pattern to test. - * @param escape The escape character to search for. - * @return True iff the pattern contains the escape sequence with the - * given character. - */ - private static boolean has (final String pattern, final char escape) - { - final int len = pattern.length (); - boolean sawPercent = false; - for (int i = 0; i < len; i++) - { - char c = pattern.charAt (i); - if (sawPercent) - { - if (c == escape) - return true; - if (c == '%') // Double percent - { - sawPercent = false; - continue; - } - } - sawPercent = (c == '%'); - } - return false; - } - - /** - * An output stream that tracks the number of bytes written to it. - */ - private final class ostr extends FilterOutputStream - { - private ostr (OutputStream out) - { - super (out); - } - - public void write (final int b) throws IOException - { - out.write (b); - FileHandler.this.written++; // FIXME: synchronize? - } - - public void write (final byte[] b) throws IOException - { - write (b, 0, b.length); - } - - public void write (final byte[] b, final int offset, final int length) - throws IOException - { - out.write (b, offset, length); - FileHandler.this.written += length; // FIXME: synchronize? - } - } -} diff --git a/libjava/classpath/java/util/logging/Filter.java b/libjava/classpath/java/util/logging/Filter.java deleted file mode 100644 index ec45976..0000000 --- a/libjava/classpath/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/classpath/java/util/logging/Formatter.java b/libjava/classpath/java/util/logging/Formatter.java deleted file mode 100644 index feaf553..0000000 --- a/libjava/classpath/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/classpath/java/util/logging/Handler.java b/libjava/classpath/java/util/logging/Handler.java deleted file mode 100644 index e254b4d..0000000 --- a/libjava/classpath/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. - * - * @return 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>. - * - * @param filter 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/classpath/java/util/logging/Level.java b/libjava/classpath/java/util/logging/Level.java deleted file mode 100644 index ea2c83f..0000000 --- a/libjava/classpath/java/util/logging/Level.java +++ /dev/null @@ -1,416 +0,0 @@ -/* Level.java -- a class for indicating logging levels - Copyright (C) 2002, 2005, 2006 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++) - { - // It's safe to use == instead of .equals here because only the - // standard logging levels will be returned by this method, and - // they are all created using string literals. - 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/classpath/java/util/logging/LogManager.java b/libjava/classpath/java/util/logging/LogManager.java deleted file mode 100644 index f8c6c33..0000000 --- a/libjava/classpath/java/util/logging/LogManager.java +++ /dev/null @@ -1,1007 +0,0 @@ -/* LogManager.java -- a class for maintaining Loggers and managing - configuration properties - Copyright (C) 2002, 2005, 2006, 2007 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 gnu.classpath.SystemProperties; - -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeSupport; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.lang.ref.WeakReference; -import java.net.URL; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.StringTokenizer; - -/** - * The <code>LogManager</code> maintains a hierarchical namespace - * of Logger objects and manages properties for configuring the logging - * framework. There exists only one single <code>LogManager</code> - * per virtual machine. This instance can be retrieved using the - * static method {@link #getLogManager()}. - * - * <p><strong>Configuration Process:</strong> The global LogManager - * object is created and configured when the class - * <code>java.util.logging.LogManager</code> is initialized. - * The configuration process includes the subsequent steps: - * - * <ul> - * <li>If the system property <code>java.util.logging.manager</code> - * is set to the name of a subclass of - * <code>java.util.logging.LogManager</code>, an instance of - * that subclass is created and becomes the global LogManager. - * Otherwise, a new instance of LogManager is created.</li> - * <li>The <code>LogManager</code> constructor tries to create - * a new instance of the class specified by the system - * property <code>java.util.logging.config.class</code>. - * Typically, the constructor of this class will call - * <code>LogManager.getLogManager().readConfiguration(java.io.InputStream)</code> - * for configuring the logging framework. - * The configuration process stops at this point if - * the system property <code>java.util.logging.config.class</code> - * is set (irrespective of whether the class constructor - * could be called or an exception was thrown).</li> - * - * <li>If the system property <code>java.util.logging.config.class</code> - * is <em>not</em> set, the configuration parameters are read in from - * a file and passed to - * {@link #readConfiguration(java.io.InputStream)}. - * The name and location of this file are specified by the system - * property <code>java.util.logging.config.file</code>.</li> - * <li>If the system property <code>java.util.logging.config.file</code> - * is not set, however, the contents of the URL - * "{gnu.classpath.home.url}/logging.properties" are passed to - * {@link #readConfiguration(java.io.InputStream)}. - * Here, "{gnu.classpath.home.url}" stands for the value of - * the system property <code>gnu.classpath.home.url</code>.</li> - * </ul> - * - * <p>The <code>LogManager</code> has a level of <code>INFO</code> by - * default, and this will be inherited by <code>Logger</code>s unless they - * override it either by properties or programmatically. - * - * @author Sascha Brawer (brawer@acm.org) - */ -public class LogManager -{ - /** - * The object name for the logging management bean. - * @since 1.5 - */ - public static final String LOGGING_MXBEAN_NAME - = "java.util.logging:type=Logging"; - - /** - * The singleton LogManager instance. - */ - private static LogManager logManager; - - /** - * The singleton logging bean. - */ - private static LoggingMXBean loggingBean; - - /** - * The registered named loggers; maps the name of a Logger to - * a WeakReference to it. - */ - private Map<String, WeakReference<Logger>> loggers; - - /** - * The properties for the logging framework which have been - * read in last. - */ - private Properties properties; - - /** - * A delegate object that provides support for handling - * PropertyChangeEvents. The API specification does not - * mention which bean should be the source in the distributed - * PropertyChangeEvents, but Mauve test code has determined that - * the Sun J2SE 1.4 reference implementation uses the LogManager - * class object. This is somewhat strange, as the class object - * is not the bean with which listeners have to register, but - * there is no reason for the GNU Classpath implementation to - * behave differently from the reference implementation in - * this case. - */ - private final PropertyChangeSupport pcs = new PropertyChangeSupport( /* source bean */ - LogManager.class); - - protected LogManager() - { - loggers = new HashMap(); - } - - /** - * Returns the globally shared LogManager instance. - */ - public static synchronized LogManager getLogManager() - { - if (logManager == null) - { - logManager = makeLogManager(); - initLogManager(); - } - return logManager; - } - - private static final String MANAGER_PROPERTY = "java.util.logging.manager"; - - private static LogManager makeLogManager() - { - String managerClassName = SystemProperties.getProperty(MANAGER_PROPERTY); - LogManager manager = (LogManager) createInstance - (managerClassName, LogManager.class, MANAGER_PROPERTY); - if (manager == null) - manager = new LogManager(); - return manager; - } - - private static final String CONFIG_PROPERTY = "java.util.logging.config.class"; - - private static void initLogManager() - { - LogManager manager = getLogManager(); - Logger.root.setLevel(Level.INFO); - manager.addLogger(Logger.root); - - /* The Javadoc description of the class explains - * what is going on here. - */ - Object configurator = createInstance(System.getProperty(CONFIG_PROPERTY), - /* must be instance of */ Object.class, - CONFIG_PROPERTY); - - try - { - if (configurator == null) - manager.readConfiguration(); - } - catch (IOException ex) - { - /* FIXME: Is it ok to ignore exceptions here? */ - } - } - - /** - * Registers a listener which will be notified when the - * logging properties are re-read. - * - * @param listener the event listener to register. - * @throws NullPointerException if the listener is {@code null}. - * @throws SecurityException if a security manager exists and the - * calling code does not have the permission - * {@code LoggingPermission("control")}. - */ - public synchronized void addPropertyChangeListener(PropertyChangeListener listener) - { - if (listener == null) - throw new NullPointerException("Attempt to add null property change listener"); - - SecurityManager sm = System.getSecurityManager(); - if (sm != null) - sm.checkPermission(new LoggingPermission("control", null)); - - pcs.addPropertyChangeListener(listener); - } - - /** - * Unregisters a listener. - * - * If <code>listener</code> has not been registered previously, - * nothing happens. Also, no exception is thrown if - * <code>listener</code> is <code>null</code>. - * - * @param listener the listener to remove. - * @throws SecurityException if a security manager exists and the - * calling code does not have the permission - * {@code LoggingPermission("control")}. - */ - public synchronized void removePropertyChangeListener(PropertyChangeListener listener) - { - if (listener != null) - { - SecurityManager sm = System.getSecurityManager(); - if (sm != null) - sm.checkPermission(new LoggingPermission("control", null)); - - pcs.removePropertyChangeListener(listener); - } - } - - /** - * Adds a named logger. If a logger with the same name has - * already been registered, the method returns <code>false</code> - * without adding the logger. - * - * <p>The <code>LogManager</code> only keeps weak references - * to registered loggers. Therefore, names can become available - * after automatic garbage collection. - * - * @param logger the logger to be added. - * - * @return <code>true</code>if <code>logger</code> was added, - * <code>false</code> otherwise. - * - * @throws NullPointerException if <code>name</code> is - * <code>null</code>. - */ - public synchronized boolean addLogger(Logger logger) - { - /* To developers thinking about to remove the 'synchronized' - * declaration from this method: Please read the comment - * in java.util.logging.Logger.getLogger(String, String) - * and make sure that whatever you change wrt. synchronization - * does not endanger thread-safety of Logger.getLogger. - * The current implementation of Logger.getLogger assumes - * that LogManager does its synchronization on the globally - * shared instance of LogManager. - */ - String name; - WeakReference ref; - - /* This will throw a NullPointerException if logger is null, - * as required by the API specification. - */ - name = logger.getName(); - - ref = loggers.get(name); - if (ref != null) - { - if (ref.get() != null) - return false; - - /* There has been a logger under this name in the past, - * but it has been garbage collected. - */ - loggers.remove(ref); - } - - /* Adding a named logger requires a security permission. */ - if ((name != null) && ! name.equals("")) - checkAccess(); - - Logger parent = findAncestor(logger); - loggers.put(name, new WeakReference<Logger>(logger)); - if (parent != logger.getParent()) - logger.setParent(parent); - - // The level of the newly added logger must be specified. - // The easiest case is if there is a level for exactly this logger - // in the properties. If no such level exists the level needs to be - // searched along the hirachy. So if there is a new logger 'foo.blah.blub' - // and an existing parent logger 'foo' the properties 'foo.blah.blub.level' - // and 'foo.blah.level' need to be checked. If both do not exist in the - // properties the level of the new logger is set to 'null' (i.e. it uses the - // level of its parent 'foo'). - Level logLevel = logger.getLevel(); - String searchName = name; - String parentName = parent != null ? parent.getName() : ""; - while (logLevel == null && ! searchName.equals(parentName)) - { - logLevel = getLevelProperty(searchName + ".level", logLevel); - int index = searchName.lastIndexOf('.'); - if(index > -1) - searchName = searchName.substring(0,index); - else - searchName = ""; - } - logger.setLevel(logLevel); - - /* It can happen that existing loggers should be children of - * the newly added logger. For example, assume that there - * already exist loggers under the names "", "foo", and "foo.bar.baz". - * When adding "foo.bar", the logger "foo.bar.baz" should change - * its parent to "foo.bar". - */ - for (Iterator iter = loggers.keySet().iterator(); iter.hasNext();) - { - Logger possChild = (Logger) ((WeakReference) loggers.get(iter.next())) - .get(); - if ((possChild == null) || (possChild == logger) - || (possChild.getParent() != parent)) - continue; - - if (! possChild.getName().startsWith(name)) - continue; - - if (possChild.getName().charAt(name.length()) != '.') - continue; - - possChild.setParent(logger); - } - - return true; - } - - /** - * Finds the closest ancestor for a logger among the currently - * registered ones. For example, if the currently registered - * loggers have the names "", "foo", and "foo.bar", the result for - * "foo.bar.baz" will be the logger whose name is "foo.bar". - * - * @param child a logger for whose name no logger has been - * registered. - * - * @return the closest ancestor for <code>child</code>, - * or <code>null</code> if <code>child</code> - * is the root logger. - * - * @throws NullPointerException if <code>child</code> - * is <code>null</code>. - */ - private synchronized Logger findAncestor(Logger child) - { - String childName = child.getName(); - int childNameLength = childName.length(); - Logger best = Logger.root; - int bestNameLength = 0; - - Logger cand; - int candNameLength; - - if (child == Logger.root) - return null; - - for (String candName : loggers.keySet()) - { - candNameLength = candName.length(); - - if (candNameLength > bestNameLength - && childNameLength > candNameLength - && childName.startsWith(candName) - && childName.charAt(candNameLength) == '.') - { - cand = loggers.get(candName).get(); - if ((cand == null) || (cand == child)) - continue; - - bestNameLength = candName.length(); - best = cand; - } - } - - return best; - } - - /** - * Returns a Logger given its name. - * - * @param name the name of the logger. - * - * @return a named Logger, or <code>null</code> if there is no - * logger with that name. - * - * @throw java.lang.NullPointerException if <code>name</code> - * is <code>null</code>. - */ - public synchronized Logger getLogger(String name) - { - WeakReference<Logger> ref; - - /* Throw a NullPointerException if name is null. */ - name.getClass(); - - ref = loggers.get(name); - if (ref != null) - return ref.get(); - else - return null; - } - - /** - * Returns an Enumeration of currently registered Logger names. - * Since other threads can register loggers at any time, the - * result could be different any time this method is called. - * - * @return an Enumeration with the names of the currently - * registered Loggers. - */ - public synchronized Enumeration<String> getLoggerNames() - { - return Collections.enumeration(loggers.keySet()); - } - - /** - * Resets the logging configuration by removing all handlers for - * registered named loggers and setting their level to <code>null</code>. - * The level of the root logger will be set to <code>Level.INFO</code>. - * - * @throws SecurityException if a security manager exists and - * the caller is not granted the permission to control - * the logging infrastructure. - */ - public synchronized void reset() throws SecurityException - { - /* Throw a SecurityException if the caller does not have the - * permission to control the logging infrastructure. - */ - checkAccess(); - - properties = new Properties(); - - Iterator<WeakReference<Logger>> iter = loggers.values().iterator(); - while (iter.hasNext()) - { - WeakReference<Logger> ref; - Logger logger; - - ref = iter.next(); - if (ref != null) - { - logger = ref.get(); - - if (logger == null) - iter.remove(); - else if (logger != Logger.root) - { - logger.resetLogger(); - logger.setLevel(null); - } - } - } - - Logger.root.setLevel(Level.INFO); - Logger.root.resetLogger(); - } - - /** - * Configures the logging framework by reading a configuration file. - * The name and location of this file are specified by the system - * property <code>java.util.logging.config.file</code>. If this - * property is not set, the URL - * "{gnu.classpath.home.url}/logging.properties" is taken, where - * "{gnu.classpath.home.url}" stands for the value of the system - * property <code>gnu.classpath.home.url</code>. - * - * <p>The task of configuring the framework is then delegated to - * {@link #readConfiguration(java.io.InputStream)}, which will - * notify registered listeners after having read the properties. - * - * @throws SecurityException if a security manager exists and - * the caller is not granted the permission to control - * the logging infrastructure, or if the caller is - * not granted the permission to read the configuration - * file. - * - * @throws IOException if there is a problem reading in the - * configuration file. - */ - public synchronized void readConfiguration() - throws IOException, SecurityException - { - String path; - InputStream inputStream; - - path = System.getProperty("java.util.logging.config.file"); - if ((path == null) || (path.length() == 0)) - { - String url = (System.getProperty("gnu.classpath.home.url") - + "/logging.properties"); - try - { - inputStream = new URL(url).openStream(); - } - catch (Exception e) - { - inputStream=null; - } - - // If no config file could be found use a default configuration. - if(inputStream == null) - { - String defaultConfig = "handlers = java.util.logging.ConsoleHandler \n" - + ".level=INFO \n"; - inputStream = new ByteArrayInputStream(defaultConfig.getBytes()); - } - } - else - inputStream = new java.io.FileInputStream(path); - - try - { - readConfiguration(inputStream); - } - finally - { - // Close the stream in order to save - // resources such as file descriptors. - inputStream.close(); - } - } - - public synchronized void readConfiguration(InputStream inputStream) - throws IOException, SecurityException - { - Properties newProperties; - Enumeration keys; - - checkAccess(); - newProperties = new Properties(); - newProperties.load(inputStream); - reset(); - this.properties = newProperties; - keys = newProperties.propertyNames(); - - while (keys.hasMoreElements()) - { - String key = ((String) keys.nextElement()).trim(); - String value = newProperties.getProperty(key); - - if (value == null) - continue; - - value = value.trim(); - - if ("handlers".equals(key)) - { - // In Java 5 and earlier this was specified to be - // whitespace-separated, but in reality it also accepted - // commas (tomcat relied on this), and in Java 6 the - // documentation was updated to fit the implementation. - StringTokenizer tokenizer = new StringTokenizer(value, - " \t\n\r\f,"); - while (tokenizer.hasMoreTokens()) - { - String handlerName = tokenizer.nextToken(); - Handler handler = (Handler) - createInstance(handlerName, Handler.class, key); - // Tomcat also relies on the implementation ignoring - // items in 'handlers' which are not class names. - if (handler != null) - Logger.root.addHandler(handler); - } - } - - if (key.endsWith(".level")) - { - String loggerName = key.substring(0, key.length() - 6); - Logger logger = getLogger(loggerName); - - if (logger == null) - { - logger = Logger.getLogger(loggerName); - addLogger(logger); - } - Level level = null; - try - { - level = Level.parse(value); - } - catch (IllegalArgumentException e) - { - warn("bad level \'" + value + "\'", e); - } - if (level != null) - { - logger.setLevel(level); - } - continue; - } - } - - /* The API specification does not talk about the - * property name that is distributed with the - * PropertyChangeEvent. With test code, it could - * be determined that the Sun J2SE 1.4 reference - * implementation uses null for the property name. - */ - pcs.firePropertyChange(null, null, null); - } - - /** - * Returns the value of a configuration property as a String. - */ - public synchronized String getProperty(String name) - { - if (properties != null) - return properties.getProperty(name); - else - return null; - } - - /** - * Returns the value of a configuration property as an integer. - * This function is a helper used by the Classpath implementation - * of java.util.logging, it is <em>not</em> specified in the - * logging API. - * - * @param name the name of the configuration property. - * - * @param defaultValue the value that will be returned if the - * property is not defined, or if its value is not an integer - * number. - */ - static int getIntProperty(String name, int defaultValue) - { - try - { - return Integer.parseInt(getLogManager().getProperty(name)); - } - catch (Exception ex) - { - return defaultValue; - } - } - - /** - * Returns the value of a configuration property as an integer, - * provided it is inside the acceptable range. - * This function is a helper used by the Classpath implementation - * of java.util.logging, it is <em>not</em> specified in the - * logging API. - * - * @param name the name of the configuration property. - * - * @param minValue the lowest acceptable value. - * - * @param maxValue the highest acceptable value. - * - * @param defaultValue the value that will be returned if the - * property is not defined, or if its value is not an integer - * number, or if it is less than the minimum value, - * or if it is greater than the maximum value. - */ - static int getIntPropertyClamped(String name, int defaultValue, - int minValue, int maxValue) - { - int val = getIntProperty(name, defaultValue); - if ((val < minValue) || (val > maxValue)) - val = defaultValue; - return val; - } - - /** - * Returns the value of a configuration property as a boolean. - * This function is a helper used by the Classpath implementation - * of java.util.logging, it is <em>not</em> specified in the - * logging API. - * - * @param name the name of the configuration property. - * - * @param defaultValue the value that will be returned if the - * property is not defined, or if its value is neither - * <code>"true"</code> nor <code>"false"</code>. - */ - static boolean getBooleanProperty(String name, boolean defaultValue) - { - try - { - return (Boolean.valueOf(getLogManager().getProperty(name))).booleanValue(); - } - catch (Exception ex) - { - return defaultValue; - } - } - - /** - * Returns the value of a configuration property as a Level. - * This function is a helper used by the Classpath implementation - * of java.util.logging, it is <em>not</em> specified in the - * logging API. - * - * @param propertyName the name of the configuration property. - * - * @param defaultValue the value that will be returned if the - * property is not defined, or if - * {@link Level#parse(java.lang.String)} does not like - * the property value. - */ - static Level getLevelProperty(String propertyName, Level defaultValue) - { - try - { - String value = getLogManager().getProperty(propertyName); - if (value != null) - return Level.parse(getLogManager().getProperty(propertyName)); - else - return defaultValue; - } - catch (Exception ex) - { - return defaultValue; - } - } - - /** - * Returns the value of a configuration property as a Class. - * This function is a helper used by the Classpath implementation - * of java.util.logging, it is <em>not</em> specified in the - * logging API. - * - * @param propertyName the name of the configuration property. - * - * @param defaultValue the value that will be returned if the - * property is not defined, or if it does not specify - * the name of a loadable class. - */ - static final Class getClassProperty(String propertyName, Class defaultValue) - { - String propertyValue = logManager.getProperty(propertyName); - - if (propertyValue != null) - try - { - return locateClass(propertyValue); - } - catch (ClassNotFoundException e) - { - warn(propertyName + " = " + propertyValue, e); - } - - return defaultValue; - } - - static final Object getInstanceProperty(String propertyName, Class ofClass, - Class defaultClass) - { - Class klass = getClassProperty(propertyName, defaultClass); - if (klass == null) - return null; - - try - { - Object obj = klass.newInstance(); - if (ofClass.isInstance(obj)) - return obj; - } - catch (InstantiationException e) - { - warn(propertyName + " = " + klass.getName(), e); - } - catch (IllegalAccessException e) - { - warn(propertyName + " = " + klass.getName(), e); - } - - if (defaultClass == null) - return null; - - try - { - return defaultClass.newInstance(); - } - catch (java.lang.InstantiationException ex) - { - throw new RuntimeException(ex.getMessage()); - } - catch (java.lang.IllegalAccessException ex) - { - throw new RuntimeException(ex.getMessage()); - } - } - - /** - * An instance of <code>LoggingPermission("control")</code> - * that is shared between calls to <code>checkAccess()</code>. - */ - private static final LoggingPermission controlPermission = new LoggingPermission("control", - null); - - /** - * Checks whether the current security context allows changing - * the configuration of the logging framework. For the security - * context to be trusted, it has to be granted - * a LoggingPermission("control"). - * - * @throws SecurityException if a security manager exists and - * the caller is not granted the permission to control - * the logging infrastructure. - */ - public void checkAccess() throws SecurityException - { - SecurityManager sm = System.getSecurityManager(); - if (sm != null) - sm.checkPermission(controlPermission); - } - - /** - * Creates a new instance of a class specified by name and verifies - * that it is an instance (or subclass of) a given type. - * - * @param className the name of the class of which a new instance - * should be created. - * - * @param type the object created must be an instance of - * <code>type</code> or any subclass of <code>type</code> - * - * @param property the system property to reference in error - * messages - * - * @return the new instance, or <code>null</code> if - * <code>className</code> is <code>null</code>, if no class - * with that name could be found, if there was an error - * loading that class, or if the constructor of the class - * has thrown an exception. - */ - private static final Object createInstance(String className, Class type, - String property) - { - Class klass = null; - - if ((className == null) || (className.length() == 0)) - return null; - - try - { - klass = locateClass(className); - if (type.isAssignableFrom(klass)) - return klass.newInstance(); - warn(property, className, "not an instance of " + type.getName()); - } - catch (ClassNotFoundException e) - { - warn(property, className, "class not found", e); - } - catch (IllegalAccessException e) - { - warn(property, className, "illegal access", e); - } - catch (InstantiationException e) - { - warn(property, className, e); - } - catch (java.lang.LinkageError e) - { - warn(property, className, "linkage error", e); - } - - return null; - } - - private static final void warn(String property, String klass, Throwable t) - { - warn(property, klass, null, t); - } - - private static final void warn(String property, String klass, String msg) - { - warn(property, klass, msg, null); - } - - private static final void warn(String property, String klass, String msg, - Throwable t) - { - warn("error instantiating '" + klass + "' referenced by " + property + - (msg == null ? "" : ", " + msg), t); - } - - /** - * All debug warnings go through this method. - */ - - private static final void warn(String msg, Throwable t) - { - System.err.println("WARNING: " + msg); - if (t != null) - t.printStackTrace(System.err); - } - - /** - * Locates a class by first checking the system class loader and - * then checking the context class loader. - * - * @param name the fully qualified name of the Class to locate - * @return Class the located Class - */ - - private static Class locateClass(String name) throws ClassNotFoundException - { - ClassLoader loader = Thread.currentThread().getContextClassLoader(); - try - { - return Class.forName(name, true, loader); - } - catch (ClassNotFoundException e) - { - loader = ClassLoader.getSystemClassLoader(); - return Class.forName(name, true, loader); - } - } - - /** - * Return the logging bean. There is a single logging bean per - * VM instance. - * @since 1.5 - */ - public static synchronized LoggingMXBean getLoggingMXBean() - { - if (loggingBean == null) - { - loggingBean = new LoggingMXBean() - { - public String getLoggerLevel(String logger) - { - LogManager mgr = getLogManager(); - Logger l = mgr.getLogger(logger); - if (l == null) - return null; - Level lev = l.getLevel(); - if (lev == null) - return ""; - return lev.getName(); - } - - public List getLoggerNames() - { - LogManager mgr = getLogManager(); - // This is inefficient, but perhaps better for maintenance. - return Collections.list(mgr.getLoggerNames()); - } - - public String getParentLoggerName(String logger) - { - LogManager mgr = getLogManager(); - Logger l = mgr.getLogger(logger); - if (l == null) - return null; - l = l.getParent(); - if (l == null) - return ""; - return l.getName(); - } - - public void setLoggerLevel(String logger, String level) - { - LogManager mgr = getLogManager(); - Logger l = mgr.getLogger(logger); - if (l == null) - throw new IllegalArgumentException("no logger named " + logger); - Level newLevel; - if (level == null) - newLevel = null; - else - newLevel = Level.parse(level); - l.setLevel(newLevel); - } - }; - } - return loggingBean; - } -} diff --git a/libjava/classpath/java/util/logging/LogRecord.java b/libjava/classpath/java/util/logging/LogRecord.java deleted file mode 100644 index ee99ee6..0000000 --- a/libjava/classpath/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/classpath/java/util/logging/Logger.java b/libjava/classpath/java/util/logging/Logger.java deleted file mode 100644 index c55e133..0000000 --- a/libjava/classpath/java/util/logging/Logger.java +++ /dev/null @@ -1,1193 +0,0 @@ -/* Logger.java -- a class for logging messages - Copyright (C) 2002, 2004, 2006, 2007 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 gnu.java.lang.CPStringBuilder; - -import java.util.List; -import java.util.MissingResourceException; -import java.util.ResourceBundle; -import java.security.AccessController; -import java.security.PrivilegedAction; - -/** - * A Logger is used for logging information about events. Usually, there is a - * seprate logger for each subsystem or component, although there is a shared - * instance for components that make only occasional use of the logging - * framework. - * <p> - * It is common to name a logger after the name of a corresponding Java package. - * Loggers are organized into a hierarchical namespace; for example, the logger - * <code>"org.gnu.foo"</code> is the <em>parent</em> of logger - * <code>"org.gnu.foo.bar"</code>. - * <p> - * A logger for a named subsystem can be obtained through {@link - * java.util.logging.Logger#getLogger(java.lang.String)}. However, only code - * which has been granted the permission to control the logging infrastructure - * will be allowed to customize that logger. Untrusted code can obtain a - * private, anonymous logger through {@link #getAnonymousLogger()} if it wants - * to perform any modifications to the logger. - * <p> - * FIXME: Write more documentation. - * - * @author Sascha Brawer (brawer@acm.org) - */ -public class Logger -{ - static final Logger root = new Logger("", null); - - /** - * A logger provided to applications that make only occasional use of the - * logging framework, typically early prototypes. Serious products are - * supposed to create and use their own Loggers, so they can be controlled - * individually. - */ - public static final Logger global; - - /** - * Use to lock methods on this class instead of calling synchronize on methods - * to avoid deadlocks. Yeah, no kidding, we got them :) - */ - private static final Object[] lock = new Object[0]; - - static - { - // Our class might be initialized from an unprivileged context - global = (Logger) AccessController.doPrivileged(new PrivilegedAction() - { - public Object run() - { - return getLogger("global"); - } - }); - } - - /** - * The name of the Logger, or <code>null</code> if the logger is anonymous. - * <p> - * A previous version of the GNU Classpath implementation granted untrusted - * code the permission to control any logger whose name was null. However, - * test code revealed that the Sun J2SE 1.4 reference implementation enforces - * the security control for any logger that was not created through - * getAnonymousLogger, even if it has a null name. Therefore, a separate flag - * {@link Logger#anonymous} was introduced. - */ - private final String name; - - /** - * The name of the resource bundle used for localization. - * <p> - * This variable cannot be declared as <code>final</code> because its value - * can change as a result of calling getLogger(String,String). - */ - private String resourceBundleName; - - /** - * The resource bundle used for localization. - * <p> - * This variable cannot be declared as <code>final</code> because its value - * can change as a result of calling getLogger(String,String). - */ - private ResourceBundle resourceBundle; - - private Filter filter; - - private final List handlerList = new java.util.ArrayList(4); - - private Handler[] handlers = new Handler[0]; - - /** - * Indicates whether or not this logger is anonymous. While a - * LoggingPermission is required for any modifications to a normal logger, - * untrusted code can obtain an anonymous logger and modify it according to - * its needs. - * <p> - * A previous version of the GNU Classpath implementation granted access to - * every logger whose name was null. However, test code revealed that the Sun - * J2SE 1.4 reference implementation enforces the security control for any - * logger that was not created through getAnonymousLogger, even if it has a - * null name. - */ - private boolean anonymous; - - private boolean useParentHandlers; - - private Level level; - - private Logger parent; - - /** - * Constructs a Logger for a subsystem. Most applications do not need to - * create new Loggers explicitly; instead, they should call the static factory - * methods {@link #getLogger(java.lang.String,java.lang.String) getLogger} - * (with ResourceBundle for localization) or - * {@link #getLogger(java.lang.String) getLogger} (without ResourceBundle), - * respectively. - * - * @param name the name for the logger, for example "java.awt" or - * "com.foo.bar". The name should be based on the name of the - * package issuing log records and consist of dot-separated Java - * identifiers. - * @param resourceBundleName the name of a resource bundle for localizing - * messages, or <code>null</code> to indicate that messages do - * not need to be localized. - * @throws java.util.MissingResourceException if - * <code>resourceBundleName</code> is not <code>null</code> - * and no such bundle could be located. - */ - protected Logger(String name, String resourceBundleName) - throws MissingResourceException - { - this.name = name; - this.resourceBundleName = resourceBundleName; - - if (resourceBundleName == null) - resourceBundle = null; - else - resourceBundle = ResourceBundle.getBundle(resourceBundleName); - - level = null; - - /* - * This is null when the root logger is being constructed, and the root - * logger afterwards. - */ - parent = root; - - useParentHandlers = (parent != null); - } - - /** - * Finds a registered logger for a subsystem, or creates one in case no logger - * has been registered yet. - * - * @param name the name for the logger, for example "java.awt" or - * "com.foo.bar". The name should be based on the name of the - * package issuing log records and consist of dot-separated Java - * identifiers. - * @throws IllegalArgumentException if a logger for the subsystem identified - * by <code>name</code> has already been created, but uses a a - * resource bundle for localizing messages. - * @throws NullPointerException if <code>name</code> is <code>null</code>. - * @return a logger for the subsystem specified by <code>name</code> that - * does not localize messages. - */ - public static Logger getLogger(String name) - { - return getLogger(name, null); - } - - /** - * Finds a registered logger for a subsystem, or creates one in case no logger - * has been registered yet. - * <p> - * If a logger with the specified name has already been registered, the - * behavior depends on the resource bundle that is currently associated with - * the existing logger. - * <ul> - * <li>If the existing logger uses the same resource bundle as specified by - * <code>resourceBundleName</code>, the existing logger is returned.</li> - * <li>If the existing logger currently does not localize messages, the - * existing logger is modified to use the bundle specified by - * <code>resourceBundleName</code>. The existing logger is then returned. - * Therefore, all subsystems currently using this logger will produce - * localized messages from now on.</li> - * <li>If the existing logger already has an associated resource bundle, but - * a different one than specified by <code>resourceBundleName</code>, an - * <code>IllegalArgumentException</code> is thrown.</li> - * </ul> - * - * @param name the name for the logger, for example "java.awt" or - * "org.gnu.foo". The name should be based on the name of the - * package issuing log records and consist of dot-separated Java - * identifiers. - * @param resourceBundleName the name of a resource bundle for localizing - * messages, or <code>null</code> to indicate that messages do - * not need to be localized. - * @return a logger for the subsystem specified by <code>name</code>. - * @throws java.util.MissingResourceException if - * <code>resourceBundleName</code> is not <code>null</code> - * and no such bundle could be located. - * @throws IllegalArgumentException if a logger for the subsystem identified - * by <code>name</code> has already been created, but uses a - * different resource bundle for localizing messages. - * @throws NullPointerException if <code>name</code> is <code>null</code>. - */ - public static Logger getLogger(String name, String resourceBundleName) - { - LogManager lm = LogManager.getLogManager(); - Logger result; - - if (name == null) - throw new NullPointerException(); - - /* - * Without synchronized(lm), it could happen that another thread would - * create a logger between our calls to getLogger and addLogger. While - * addLogger would indicate this by returning false, we could not be sure - * that this other logger was still existing when we called getLogger a - * second time in order to retrieve it -- note that LogManager is only - * allowed to keep weak references to registered loggers, so Loggers can be - * garbage collected at any time in general, and between our call to - * addLogger and our second call go getLogger in particular. Of course, we - * assume here that LogManager.addLogger etc. are synchronizing on the - * global LogManager object. There is a comment in the implementation of - * LogManager.addLogger referring to this comment here, so that any change - * in the synchronization of LogManager will be reflected here. - */ - synchronized (lock) - { - synchronized (lm) - { - result = lm.getLogger(name); - if (result == null) - { - boolean couldBeAdded; - - result = new Logger(name, resourceBundleName); - couldBeAdded = lm.addLogger(result); - if (! couldBeAdded) - throw new IllegalStateException("cannot register new logger"); - } - else - { - /* - * The logger already exists. Make sure it uses the same - * resource bundle for localizing messages. - */ - String existingBundleName = result.getResourceBundleName(); - - /* - * The Sun J2SE 1.4 reference implementation will return the - * registered logger object, even if it does not have a resource - * bundle associated with it. However, it seems to change the - * resourceBundle of the registered logger to the bundle whose - * name was passed to getLogger. - */ - if ((existingBundleName == null) && - (resourceBundleName != null)) - { - /* - * If ResourceBundle.getBundle throws an exception, the - * existing logger will be unchanged. This would be - * different if the assignment to resourceBundleName came - * first. - */ - result.resourceBundle = - ResourceBundle.getBundle(resourceBundleName); - - result.resourceBundleName = resourceBundleName; - return result; - } - - if ((existingBundleName != resourceBundleName) - && ((existingBundleName == null) - || !existingBundleName.equals(resourceBundleName))) - { - throw new IllegalArgumentException(); - } - } - } - } - - return result; - } - - /** - * Creates a new, unnamed logger. Unnamed loggers are not registered in the - * namespace of the LogManager, and no special security permission is required - * for changing their state. Therefore, untrusted applets are able to modify - * their private logger instance obtained through this method. - * <p> - * The parent of the newly created logger will the the root logger, from which - * the level threshold and the handlers are inherited. - */ - public static Logger getAnonymousLogger() - { - return getAnonymousLogger(null); - } - - /** - * Creates a new, unnamed logger. Unnamed loggers are not registered in the - * namespace of the LogManager, and no special security permission is required - * for changing their state. Therefore, untrusted applets are able to modify - * their private logger instance obtained through this method. - * <p> - * The parent of the newly created logger will the the root logger, from which - * the level threshold and the handlers are inherited. - * - * @param resourceBundleName the name of a resource bundle for localizing - * messages, or <code>null</code> to indicate that messages do - * not need to be localized. - * @throws java.util.MissingResourceException if - * <code>resourceBundleName</code> is not <code>null</code> - * and no such bundle could be located. - */ - public static Logger getAnonymousLogger(String resourceBundleName) - throws MissingResourceException - { - Logger result; - - result = new Logger(null, resourceBundleName); - result.anonymous = true; - return result; - } - - /** - * Returns the name of the resource bundle that is being used for localizing - * messages. - * - * @return the name of the resource bundle used for localizing messages, or - * <code>null</code> if the parent's resource bundle is used for - * this purpose. - */ - public String getResourceBundleName() - { - synchronized (lock) - { - return resourceBundleName; - } - } - - /** - * Returns the resource bundle that is being used for localizing messages. - * - * @return the resource bundle used for localizing messages, or - * <code>null</code> if the parent's resource bundle is used for - * this purpose. - */ - public ResourceBundle getResourceBundle() - { - synchronized (lock) - { - return resourceBundle; - } - } - - /** - * 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, - * or <code>null</code> if the logger inherits the threshold from - * its parent. - */ - public Level getLevel() - { - synchronized (lock) - { - return level; - } - } - - /** - * Returns whether or not a message of the specified level would be logged by - * this logger. - * - * @throws NullPointerException if <code>level</code> is <code>null</code>. - */ - public boolean isLoggable(Level level) - { - synchronized (lock) - { - if (this.level != null) - return this.level.intValue() <= level.intValue(); - - if (parent != null) - return parent.isLoggable(level); - else - return false; - } - } - - /** - * Sets the severity level threshold for this <code>Handler</code>. All log - * records with a lower severity level will be discarded immediately. 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, or <code>null</code> to indicate that the logger - * should inherit the threshold from its parent. - * @throws SecurityException if this logger is not anonymous, a security - * manager exists, and the caller is not granted the permission to - * control the logging infrastructure by having - * LoggingPermission("control"). Untrusted code can obtain an - * anonymous logger through the static factory method - * {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}. - */ - public void setLevel(Level level) - { - synchronized (lock) - { - /* - * An application is allowed to control an anonymous logger without - * having the permission to control the logging infrastructure. - */ - if (! anonymous) - LogManager.getLogManager().checkAccess(); - - this.level = level; - } - } - - public Filter getFilter() - { - synchronized (lock) - { - return filter; - } - } - - /** - * @throws SecurityException if this logger is not anonymous, a security - * manager exists, and the caller is not granted the permission to - * control the logging infrastructure by having - * LoggingPermission("control"). Untrusted code can obtain an - * anonymous logger through the static factory method - * {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}. - */ - public void setFilter(Filter filter) throws SecurityException - { - synchronized (lock) - { - /* - * An application is allowed to control an anonymous logger without - * having the permission to control the logging infrastructure. - */ - if (! anonymous) - LogManager.getLogManager().checkAccess(); - - this.filter = filter; - } - } - - /** - * Returns the name of this logger. - * - * @return the name of this logger, or <code>null</code> if the logger is - * anonymous. - */ - public String getName() - { - /* - * Note that the name of a logger cannot be changed during its lifetime, so - * no synchronization is needed. - */ - return name; - } - - /** - * Passes a record to registered handlers, provided the record is considered - * as loggable both by {@link #isLoggable(Level)} and a possibly installed - * custom {@link #setFilter(Filter) filter}. - * <p> - * If the logger has been configured to use parent handlers, the record will - * be forwarded to the parent of this logger in addition to being processed by - * the handlers registered with this logger. - * <p> - * The other logging methods in this class are convenience methods that merely - * create a new LogRecord and pass it to this method. Therefore, subclasses - * usually just need to override this single method for customizing the - * logging behavior. - * - * @param record the log record to be inspected and possibly forwarded. - */ - public void log(LogRecord record) - { - synchronized (lock) - { - if (!isLoggable(record.getLevel())) - return; - - if ((filter != null) && ! filter.isLoggable(record)) - return; - - /* - * If no logger name has been set for the log record, use the name of - * this logger. - */ - if (record.getLoggerName() == null) - record.setLoggerName(name); - - /* - * Avoid that some other thread is changing the logger hierarchy while - * we are traversing it. - */ - synchronized (LogManager.getLogManager()) - { - Logger curLogger = this; - - do - { - /* - * The Sun J2SE 1.4 reference implementation seems to call the - * filter only for the logger whose log method is called, never - * for any of its parents. Also, parent loggers publish log - * record whatever their level might be. This is pretty weird, - * but GNU Classpath tries to be as compatible as possible to - * the reference implementation. - */ - for (int i = 0; i < curLogger.handlers.length; i++) - curLogger.handlers[i].publish(record); - - if (curLogger.getUseParentHandlers() == false) - break; - - curLogger = curLogger.getParent(); - } - while (parent != null); - } - } - } - - public void log(Level level, String message) - { - if (isLoggable(level)) - log(level, message, (Object[]) null); - } - - public void log(Level level, String message, Object param) - { - synchronized (lock) - { - if (isLoggable(level)) - { - StackTraceElement caller = getCallerStackFrame(); - logp(level, caller != null ? caller.getClassName() : "<unknown>", - caller != null ? caller.getMethodName() : "<unknown>", - message, param); - } - } - } - - public void log(Level level, String message, Object[] params) - { - synchronized (lock) - { - if (isLoggable(level)) - { - StackTraceElement caller = getCallerStackFrame(); - logp(level, caller != null ? caller.getClassName() : "<unknown>", - caller != null ? caller.getMethodName() : "<unknown>", - message, params); - - } - } - } - - public void log(Level level, String message, Throwable thrown) - { - synchronized (lock) - { - if (isLoggable(level)) - { - StackTraceElement caller = getCallerStackFrame(); - logp(level, caller != null ? caller.getClassName() : "<unknown>", - caller != null ? caller.getMethodName() : "<unknown>", - message, thrown); - } - } - } - - public void logp(Level level, String sourceClass, String sourceMethod, - String message) - { - synchronized (lock) - { - logp(level, sourceClass, sourceMethod, message, (Object[]) null); - } - } - - public void logp(Level level, String sourceClass, String sourceMethod, - String message, Object param) - { - synchronized (lock) - { - logp(level, sourceClass, sourceMethod, message, new Object[] { param }); - } - - } - - private ResourceBundle findResourceBundle() - { - synchronized (lock) - { - if (resourceBundle != null) - return resourceBundle; - - if (parent != null) - return parent.findResourceBundle(); - - return null; - } - } - - private void logImpl(Level level, String sourceClass, String sourceMethod, - String message, Object[] params) - { - synchronized (lock) - { - LogRecord rec = new LogRecord(level, message); - - rec.setResourceBundle(findResourceBundle()); - rec.setSourceClassName(sourceClass); - rec.setSourceMethodName(sourceMethod); - rec.setParameters(params); - - log(rec); - } - } - - public void logp(Level level, String sourceClass, String sourceMethod, - String message, Object[] params) - { - synchronized (lock) - { - logImpl(level, sourceClass, sourceMethod, message, params); - } - } - - public void logp(Level level, String sourceClass, String sourceMethod, - String message, Throwable thrown) - { - synchronized (lock) - { - LogRecord rec = new LogRecord(level, message); - - rec.setResourceBundle(resourceBundle); - rec.setSourceClassName(sourceClass); - rec.setSourceMethodName(sourceMethod); - rec.setThrown(thrown); - - log(rec); - } - } - - public void logrb(Level level, String sourceClass, String sourceMethod, - String bundleName, String message) - { - synchronized (lock) - { - logrb(level, sourceClass, sourceMethod, bundleName, message, - (Object[]) null); - } - } - - public void logrb(Level level, String sourceClass, String sourceMethod, - String bundleName, String message, Object param) - { - synchronized (lock) - { - logrb(level, sourceClass, sourceMethod, bundleName, message, - new Object[] { param }); - } - } - - public void logrb(Level level, String sourceClass, String sourceMethod, - String bundleName, String message, Object[] params) - { - synchronized (lock) - { - LogRecord rec = new LogRecord(level, message); - - rec.setResourceBundleName(bundleName); - rec.setSourceClassName(sourceClass); - rec.setSourceMethodName(sourceMethod); - rec.setParameters(params); - - log(rec); - } - } - - public void logrb(Level level, String sourceClass, String sourceMethod, - String bundleName, String message, Throwable thrown) - { - synchronized (lock) - { - LogRecord rec = new LogRecord(level, message); - - rec.setResourceBundleName(bundleName); - rec.setSourceClassName(sourceClass); - rec.setSourceMethodName(sourceMethod); - rec.setThrown(thrown); - - log(rec); - } - } - - public void entering(String sourceClass, String sourceMethod) - { - synchronized (lock) - { - if (isLoggable(Level.FINER)) - logp(Level.FINER, sourceClass, sourceMethod, "ENTRY"); - } - } - - public void entering(String sourceClass, String sourceMethod, Object param) - { - synchronized (lock) - { - if (isLoggable(Level.FINER)) - logp(Level.FINER, sourceClass, sourceMethod, "ENTRY {0}", param); - } - } - - public void entering(String sourceClass, String sourceMethod, Object[] params) - { - synchronized (lock) - { - if (isLoggable(Level.FINER)) - { - CPStringBuilder buf = new CPStringBuilder(80); - buf.append("ENTRY"); - for (int i = 0; i < params.length; i++) - { - buf.append(" {"); - buf.append(i); - buf.append('}'); - } - - logp(Level.FINER, sourceClass, sourceMethod, buf.toString(), params); - } - } - } - - public void exiting(String sourceClass, String sourceMethod) - { - synchronized (lock) - { - if (isLoggable(Level.FINER)) - logp(Level.FINER, sourceClass, sourceMethod, "RETURN"); - } - } - - public void exiting(String sourceClass, String sourceMethod, Object result) - { - synchronized (lock) - { - if (isLoggable(Level.FINER)) - logp(Level.FINER, sourceClass, sourceMethod, "RETURN {0}", result); - } - } - - public void throwing(String sourceClass, String sourceMethod, Throwable thrown) - { - synchronized (lock) - { - if (isLoggable(Level.FINER)) - logp(Level.FINER, sourceClass, sourceMethod, "THROW", thrown); - } - } - - /** - * Logs a message with severity level SEVERE, indicating 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. - * - * @see Level#SEVERE - * @param message the message text, also used as look-up key if the logger is - * localizing messages with a resource bundle. While it is possible - * to pass <code>null</code>, this is not recommended, since a - * logging message without text is unlikely to be helpful. - */ - public void severe(String message) - { - synchronized (lock) - { - if (isLoggable(Level.SEVERE)) - log(Level.SEVERE, message); - } - } - - /** - * Logs a message with severity level WARNING, indicating 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. - * - * @see Level#WARNING - * @param message the message text, also used as look-up key if the logger is - * localizing messages with a resource bundle. While it is possible - * to pass <code>null</code>, this is not recommended, since a - * logging message without text is unlikely to be helpful. - */ - public void warning(String message) - { - synchronized (lock) - { - if (isLoggable(Level.WARNING)) - log(Level.WARNING, message); - } - } - - /** - * Logs a message with severity level INFO. {@link Level#INFO} is intended for - * purely informational messages that do not indicate error or warning - * situations. 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. - * - * @param message the message text, also used as look-up key if the logger is - * localizing messages with a resource bundle. While it is possible - * to pass <code>null</code>, this is not recommended, since a - * logging message without text is unlikely to be helpful. - */ - public void info(String message) - { - synchronized (lock) - { - if (isLoggable(Level.INFO)) - log(Level.INFO, message); - } - } - - /** - * Logs a message with severity level CONFIG. {@link Level#CONFIG} is intended - * for static configuration messages, for example about the windowing - * environment, the operating system version, etc. - * - * @param message the message text, also used as look-up key if the logger is - * localizing messages with a resource bundle. While it is possible - * to pass <code>null</code>, this is not recommended, since a - * logging message without text is unlikely to be helpful. - */ - public void config(String message) - { - synchronized (lock) - { - if (isLoggable(Level.CONFIG)) - log(Level.CONFIG, message); - } - } - - /** - * Logs a message with severity level FINE. {@link Level#FINE} is intended for - * messages that are relevant for developers using the component generating - * log messages. Examples include minor, recoverable failures, or possible - * inefficiencies. - * - * @param message the message text, also used as look-up key if the logger is - * localizing messages with a resource bundle. While it is possible - * to pass <code>null</code>, this is not recommended, since a - * logging message without text is unlikely to be helpful. - */ - public void fine(String message) - { - synchronized (lock) - { - if (isLoggable(Level.FINE)) - log(Level.FINE, message); - } - } - - /** - * Logs a message with severity level FINER. {@link Level#FINER} is intended - * for rather detailed tracing, for example entering a method, returning from - * a method, or throwing an exception. - * - * @param message the message text, also used as look-up key if the logger is - * localizing messages with a resource bundle. While it is possible - * to pass <code>null</code>, this is not recommended, since a - * logging message without text is unlikely to be helpful. - */ - public void finer(String message) - { - synchronized (lock) - { - if (isLoggable(Level.FINER)) - log(Level.FINER, message); - } - } - - /** - * Logs a message with severity level FINEST. {@link Level#FINEST} is intended - * for highly detailed tracing, for example reaching a certain point inside - * the body of a method. - * - * @param message the message text, also used as look-up key if the logger is - * localizing messages with a resource bundle. While it is possible - * to pass <code>null</code>, this is not recommended, since a - * logging message without text is unlikely to be helpful. - */ - public void finest(String message) - { - synchronized (lock) - { - if (isLoggable(Level.FINEST)) - log(Level.FINEST, message); - } - } - - /** - * Adds a handler to the set of handlers that get notified when a log record - * is to be published. - * - * @param handler the handler to be added. - * @throws NullPointerException if <code>handler</code> is <code>null</code>. - * @throws SecurityException if this logger is not anonymous, a security - * manager exists, and the caller is not granted the permission to - * control the logging infrastructure by having - * LoggingPermission("control"). Untrusted code can obtain an - * anonymous logger through the static factory method - * {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}. - */ - public void addHandler(Handler handler) throws SecurityException - { - synchronized (lock) - { - if (handler == null) - throw new NullPointerException(); - - /* - * An application is allowed to control an anonymous logger without - * having the permission to control the logging infrastructure. - */ - if (! anonymous) - LogManager.getLogManager().checkAccess(); - - if (! handlerList.contains(handler)) - { - handlerList.add(handler); - handlers = getHandlers(); - } - } - } - - /** - * Removes a handler from the set of handlers that get notified when a log - * record is to be published. - * - * @param handler the handler to be removed. - * @throws SecurityException if this logger is not anonymous, a security - * manager exists, and the caller is not granted the permission to - * control the logging infrastructure by having - * LoggingPermission("control"). Untrusted code can obtain an - * anonymous logger through the static factory method {@link - * #getAnonymousLogger(java.lang.String) getAnonymousLogger}. - * @throws NullPointerException if <code>handler</code> is <code>null</code>. - */ - public void removeHandler(Handler handler) throws SecurityException - { - synchronized (lock) - { - /* - * An application is allowed to control an anonymous logger without - * having the permission to control the logging infrastructure. - */ - if (! anonymous) - LogManager.getLogManager().checkAccess(); - - if (handler == null) - throw new NullPointerException(); - - handlerList.remove(handler); - handlers = getHandlers(); - } - } - - /** - * Returns the handlers currently registered for this Logger. When a log - * record has been deemed as being loggable, it will be passed to all - * registered handlers for publication. In addition, if the logger uses parent - * handlers (see {@link #getUseParentHandlers() getUseParentHandlers} and - * {@link #setUseParentHandlers(boolean) setUseParentHandlers}, the log - * record will be passed to the parent's handlers. - */ - public Handler[] getHandlers() - { - synchronized (lock) - { - /* - * We cannot return our internal handlers array because we do not have - * any guarantee that the caller would not change the array entries. - */ - return (Handler[]) handlerList.toArray(new Handler[handlerList.size()]); - } - } - - /** - * Returns whether or not this Logger forwards log records to handlers - * registered for its parent loggers. - * - * @return <code>false</code> if this Logger sends log records merely to - * Handlers registered with itself; <code>true</code> if this Logger - * sends log records not only to Handlers registered with itself, but - * also to those Handlers registered with parent loggers. - */ - public boolean getUseParentHandlers() - { - synchronized (lock) - { - return useParentHandlers; - } - } - - /** - * Sets whether or not this Logger forwards log records to handlers registered - * for its parent loggers. - * - * @param useParentHandlers <code>false</code> to let this Logger send log - * records merely to Handlers registered with itself; - * <code>true</code> to let this Logger send log records not only - * to Handlers registered with itself, but also to those Handlers - * registered with parent loggers. - * @throws SecurityException if this logger is not anonymous, a security - * manager exists, and the caller is not granted the permission to - * control the logging infrastructure by having - * LoggingPermission("control"). Untrusted code can obtain an - * anonymous logger through the static factory method - * {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}. - */ - public void setUseParentHandlers(boolean useParentHandlers) - { - synchronized (lock) - { - /* - * An application is allowed to control an anonymous logger without - * having the permission to control the logging infrastructure. - */ - if (! anonymous) - LogManager.getLogManager().checkAccess(); - - this.useParentHandlers = useParentHandlers; - } - } - - /** - * Returns the parent of this logger. By default, the parent is assigned by - * the LogManager by inspecting the logger's name. - * - * @return the parent of this logger (as detemined by the LogManager by - * inspecting logger names), the root logger if no other logger has a - * name which is a prefix of this logger's name, or <code>null</code> - * for the root logger. - */ - public Logger getParent() - { - synchronized (lock) - { - return parent; - } - } - - /** - * Sets the parent of this logger. Usually, applications do not call this - * method directly. Instead, the LogManager will ensure that the tree of - * loggers reflects the hierarchical logger namespace. Basically, this method - * should not be public at all, but the GNU implementation follows the API - * specification. - * - * @throws NullPointerException if <code>parent</code> is <code>null</code>. - * @throws SecurityException if this logger is not anonymous, a security - * manager exists, and the caller is not granted the permission to - * control the logging infrastructure by having - * LoggingPermission("control"). Untrusted code can obtain an - * anonymous logger through the static factory method - * {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}. - */ - public void setParent(Logger parent) - { - synchronized (lock) - { - if (parent == null) - throw new NullPointerException(); - - if (this == root) - throw new IllegalArgumentException( - "the root logger can only have a null parent"); - - /* - * An application is allowed to control an anonymous logger without - * having the permission to control the logging infrastructure. - */ - if (! anonymous) - LogManager.getLogManager().checkAccess(); - - this.parent = parent; - } - } - - /** - * Gets the StackTraceElement of the first class that is not this class. That - * should be the initial caller of a logging method. - * - * @return caller of the initial logging method or null if unknown. - */ - private StackTraceElement getCallerStackFrame() - { - Throwable t = new Throwable(); - StackTraceElement[] stackTrace = t.getStackTrace(); - int index = 0; - - // skip to stackentries until this class - while (index < stackTrace.length - && ! stackTrace[index].getClassName().equals(getClass().getName())) - index++; - - // skip the stackentries of this class - while (index < stackTrace.length - && stackTrace[index].getClassName().equals(getClass().getName())) - index++; - - return index < stackTrace.length ? stackTrace[index] : null; - } - - /** - * Reset and close handlers attached to this logger. This function is package - * private because it must only be available to the LogManager. - */ - void resetLogger() - { - for (int i = 0; i < handlers.length; i++) - { - handlers[i].close(); - handlerList.remove(handlers[i]); - } - handlers = getHandlers(); - } -} diff --git a/libjava/classpath/java/util/logging/LoggingMXBean.java b/libjava/classpath/java/util/logging/LoggingMXBean.java deleted file mode 100644 index 24d8834..0000000 --- a/libjava/classpath/java/util/logging/LoggingMXBean.java +++ /dev/null @@ -1,85 +0,0 @@ -/* LoggingMxBean.java -- Management interface for logging - Copyright (C) 2006 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.List; - -/** - * This interface represents the management interface for logging. - * There is a single logging bean per VM instance, which can be - * retrieved via {@link LogManager#getLoggingMXBean()}. - * - * @since 1.5 - */ -public interface LoggingMXBean -{ - /** - * Return the name of the logging level given the name of - * a logger. Returns null if no such logger exists. - * @param logger the logger's name - * @return the logging level's name, or null - */ - String getLoggerLevel(String logger); - - /** - * Return a list of all logger names. - */ - List<String> getLoggerNames(); - - /** - * Return the name of the parent of the indicated logger. - * If no such logger exists, returns null. If the logger - * is the root logger, returns the empty string. - * @param logger the logger's name - * @return the name of the logger's parent, or null - */ - String getParentLoggerName(String logger); - - /** - * Sets the logging level for a particular logger. - * - * @param logger the name of the logger - * @param level the name of the new logging level, or null - * @throws IllegalArgumentException if the level is not - * recognized, or if the logger does not exist - * @throws SecurityException if access is denied; - * see {@link Logger#setLevel(Level)} - */ - void setLoggerLevel(String logger, String level); -} diff --git a/libjava/classpath/java/util/logging/LoggingPermission.java b/libjava/classpath/java/util/logging/LoggingPermission.java deleted file mode 100644 index 804fb94..0000000 --- a/libjava/classpath/java/util/logging/LoggingPermission.java +++ /dev/null @@ -1,75 +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 -{ - private static final long serialVersionUID = 63564341580231582L; - - /** - * 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/classpath/java/util/logging/MemoryHandler.java b/libjava/classpath/java/util/logging/MemoryHandler.java deleted file mode 100644 index e5c258b..0000000 --- a/libjava/classpath/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/classpath/java/util/logging/SimpleFormatter.java b/libjava/classpath/java/util/logging/SimpleFormatter.java deleted file mode 100644 index da731f2..0000000 --- a/libjava/classpath/java/util/logging/SimpleFormatter.java +++ /dev/null @@ -1,131 +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 gnu.java.lang.CPStringBuilder; - -import java.io.PrintWriter; -import java.io.StringWriter; -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 record 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) - { - CPStringBuilder buf = new CPStringBuilder(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); - - Throwable throwable = record.getThrown(); - if (throwable != null) - { - StringWriter sink = new StringWriter(); - throwable.printStackTrace(new PrintWriter(sink, true)); - buf.append(sink.toString()); - } - - return buf.toString(); - } -} diff --git a/libjava/classpath/java/util/logging/SocketHandler.java b/libjava/classpath/java/util/logging/SocketHandler.java deleted file mode 100644 index 3c17b9b..0000000 --- a/libjava/classpath/java/util/logging/SocketHandler.java +++ /dev/null @@ -1,220 +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/classpath/java/util/logging/StreamHandler.java b/libjava/classpath/java/util/logging/StreamHandler.java deleted file mode 100644 index d74dfac..0000000 --- a/libjava/classpath/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/classpath/java/util/logging/XMLFormatter.java b/libjava/classpath/java/util/logging/XMLFormatter.java deleted file mode 100644 index da7c6ef..0000000 --- a/libjava/classpath/java/util/logging/XMLFormatter.java +++ /dev/null @@ -1,389 +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 gnu.java.lang.CPStringBuilder; - -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 CPStringBuilder, provided that the element content is - * actually existing. - * - * @param buf the CPStringBuilder 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(CPStringBuilder 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 CPStringBuilder. - * - * @param buf the CPStringBuilder 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(CPStringBuilder buf, int indent, - String tag, long content) - { - appendTag(buf, indent, tag, Long.toString(content)); - } - - - public String format(LogRecord record) - { - CPStringBuilder buf = new CPStringBuilder(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", millis); - 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 h 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) - { - CPStringBuilder buf; - String encoding; - - buf = new CPStringBuilder(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/classpath/java/util/logging/package.html b/libjava/classpath/java/util/logging/package.html deleted file mode 100644 index 31f0494..0000000 --- a/libjava/classpath/java/util/logging/package.html +++ /dev/null @@ -1,46 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> -<!-- package.html - describes classes in java.util.logging package. - 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. --> - -<html> -<head><title>GNU Classpath - java.util.logging</title></head> - -<body> -<p>Utility classes for logging events.</p> - -</body> -</html> diff --git a/libjava/classpath/java/util/package.html b/libjava/classpath/java/util/package.html deleted file mode 100644 index ff2919c..0000000 --- a/libjava/classpath/java/util/package.html +++ /dev/null @@ -1,48 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> -<!-- package.html - describes classes in java.util package. - 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. --> - -<html> -<head><title>GNU Classpath - java.util</title></head> - -<body> -<p>Utility classes such as collections (maps, sets, lists, dictionaries and -stacks), calendars, dates, locales, properties, timers, resource bundles and -event objects.</p> - -</body> -</html> diff --git a/libjava/classpath/java/util/prefs/AbstractPreferences.java b/libjava/classpath/java/util/prefs/AbstractPreferences.java deleted file mode 100644 index 14fed38..0000000 --- a/libjava/classpath/java/util/prefs/AbstractPreferences.java +++ /dev/null @@ -1,1392 +0,0 @@ -/* AbstractPreferences -- Partial implementation of a Preference node - Copyright (C) 2001, 2003, 2004, 2006 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.classpath.toolkit.DefaultDaemonThreadFactory; -import gnu.java.lang.CPStringBuilder; -import gnu.java.util.prefs.NodeWriter; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.TreeSet; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; - -/** - * 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 constructor 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<String, AbstractPreferences> childCache - = new HashMap<String, AbstractPreferences>(); - - /** - * A list of all the registered NodeChangeListener objects. - */ - private ArrayList<NodeChangeListener> nodeListeners; - - /** - * A list of all the registered PreferenceChangeListener objects. - */ - private ArrayList<PreferenceChangeListener> preferenceListeners; - - // 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() - { - Collection<AbstractPreferences> vals = childCache.values(); - return vals.toArray(new AbstractPreferences[vals.size()]); - } - - /** - * 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<String> childrenNames = new TreeSet<String>(); - - // 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 - * than 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); - childCache.put(childName, child); - if (child.newNode && nodeListeners != null) - fire(new NodeChangeEvent(this, child), true); - } - - // 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 - - // Inherit javadoc. - public void exportNode(OutputStream os) - throws BackingStoreException, - IOException - { - NodeWriter nodeWriter = new NodeWriter(this, os); - nodeWriter.writePrefs(); - } - - // Inherit javadoc. - 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 immediately visible in this VM, but may not be - * immediately 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); - - if (preferenceListeners != null) - fire(new PreferenceChangeEvent(this, key, 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 void putBoolean(String key, boolean value) { - 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) { - CPStringBuilder sb = new CPStringBuilder((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 immediately visible in this VM, but may not be - * immediately 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); - - if (preferenceListeners != null) - fire(new PreferenceChangeEvent(this, key, null)); - } - } - - /** - * 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 immediately 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(new String[]{}); - } - - if (keys != null) { - for (int i = 0; i < keys.length; i++) { - // Have to lock this node again to access the childCache - AbstractPreferences subNode; - synchronized(lock) { - 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.lock) { - synchronized(this.lock) { - 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.lock) { - node.purge(); - } - } - - // Cache is empty now - childCache.clear(); - - // remove this node - removeNodeSpi(); - removed = true; - - if (nodeListeners != null) - fire(new NodeChangeEvent(parent, this), false); - } - - // listener methods - - /** - * Add a listener which is notified when a sub-node of this node - * is added or removed. - * @param listener the listener to add - */ - public void addNodeChangeListener(NodeChangeListener listener) - { - synchronized (lock) - { - if (isRemoved()) - throw new IllegalStateException("node has been removed"); - if (listener == null) - throw new NullPointerException("listener is null"); - if (nodeListeners == null) - nodeListeners = new ArrayList<NodeChangeListener>(); - nodeListeners.add(listener); - } - } - - /** - * Add a listener which is notified when a value in this node - * is added, changed, or removed. - * @param listener the listener to add - */ - public void addPreferenceChangeListener(PreferenceChangeListener listener) - { - synchronized (lock) - { - if (isRemoved()) - throw new IllegalStateException("node has been removed"); - if (listener == null) - throw new NullPointerException("listener is null"); - if (preferenceListeners == null) - preferenceListeners = new ArrayList<PreferenceChangeListener>(); - preferenceListeners.add(listener); - } - } - - /** - * Remove the indicated node change listener from the list of - * listeners to notify. - * @param listener the listener to remove - */ - public void removeNodeChangeListener(NodeChangeListener listener) - { - synchronized (lock) - { - if (isRemoved()) - throw new IllegalStateException("node has been removed"); - if (listener == null) - throw new NullPointerException("listener is null"); - if (nodeListeners != null) - nodeListeners.remove(listener); - } - } - - /** - * Remove the indicated preference change listener from the list of - * listeners to notify. - * @param listener the listener to remove - */ - public void removePreferenceChangeListener (PreferenceChangeListener listener) - { - synchronized (lock) - { - if (isRemoved()) - throw new IllegalStateException("node has been removed"); - if (listener == null) - throw new NullPointerException("listener is null"); - if (preferenceListeners != null) - preferenceListeners.remove(listener); - } - } - - /** - * Send a preference change event to all listeners. Note that - * the caller is responsible for holding the node's lock, and - * for checking that the list of listeners is not null. - * @param event the event to send - */ - private void fire(final PreferenceChangeEvent event) - { - for (final PreferenceChangeListener listener : preferenceListeners) - { - Runnable dispatcher = new Runnable() { - public void run() - { - listener.preferenceChange(event); - } - }; - - Executor executor = - Executors.newSingleThreadExecutor(new DefaultDaemonThreadFactory()); - executor.execute(dispatcher); - } - } - - /** - * Send a node change event to all listeners. Note that - * the caller is responsible for holding the node's lock, and - * for checking that the list of listeners is not null. - * @param event the event to send - */ - private void fire(final NodeChangeEvent event, final boolean added) - { - for (final NodeChangeListener listener : nodeListeners) - { - Runnable dispatcher = new Runnable() { - public void run() - { - if (added) - listener.childAdded(event); - else - listener.childRemoved(event); - } - }; - - Executor executor = - Executors.newSingleThreadExecutor(new DefaultDaemonThreadFactory()); - executor.execute(dispatcher); - } - } - - // 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 immediately. 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 immediately. 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/classpath/java/util/prefs/BackingStoreException.java b/libjava/classpath/java/util/prefs/BackingStoreException.java deleted file mode 100644 index 0ba358a..0000000 --- a/libjava/classpath/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/classpath/java/util/prefs/InvalidPreferencesFormatException.java b/libjava/classpath/java/util/prefs/InvalidPreferencesFormatException.java deleted file mode 100644 index f929b56..0000000 --- a/libjava/classpath/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/classpath/java/util/prefs/NodeChangeEvent.java b/libjava/classpath/java/util/prefs/NodeChangeEvent.java deleted file mode 100644 index 5bdeb33..0000000 --- a/libjava/classpath/java/util/prefs/NodeChangeEvent.java +++ /dev/null @@ -1,111 +0,0 @@ -/* NodeChangeEvent - ObjectEvent fired when a Preference node is added/removed - Copyright (C) 2001, 2006 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.IOException; -import java.io.NotSerializableException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -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>. - * <p> - * Note that although this class is marked as serializable, attempts to - * serialize it will fail with NotSerializableException. - * - * @since 1.4 - * @author Mark Wielaard (mark@klomp.org) - */ -public class NodeChangeEvent extends EventObject { - - // We have this to placate the compiler. - 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; - } - - private void readObject(ObjectInputStream ois) - throws IOException - { - throw new NotSerializableException("LineEvent is not serializable"); - } - - private void writeObject(ObjectOutputStream oos) - throws IOException - { - throw new NotSerializableException("LineEvent is not serializable"); - } -} diff --git a/libjava/classpath/java/util/prefs/NodeChangeListener.java b/libjava/classpath/java/util/prefs/NodeChangeListener.java deleted file mode 100644 index 8d018ab..0000000 --- a/libjava/classpath/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/classpath/java/util/prefs/PreferenceChangeEvent.java b/libjava/classpath/java/util/prefs/PreferenceChangeEvent.java deleted file mode 100644 index f273361..0000000 --- a/libjava/classpath/java/util/prefs/PreferenceChangeEvent.java +++ /dev/null @@ -1,125 +0,0 @@ -/* PreferenceChangeEvent - ObjectEvent fired when a Preferences entry changes - Copyright (C) 2001, 2006 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.IOException; -import java.io.NotSerializableException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -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>. - * <p> - * Note that although this class is marked as serializable, attempts to - * serialize it will fail with NotSerializableException. - * - * @since 1.4 - * @author Mark Wielaard (mark@klomp.org) - */ -public class PreferenceChangeEvent extends EventObject { - - // We have this to placate the compiler. - 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; - } - - private void readObject(ObjectInputStream ois) - throws IOException - { - throw new NotSerializableException("LineEvent is not serializable"); - } - - private void writeObject(ObjectOutputStream oos) - throws IOException - { - throw new NotSerializableException("LineEvent is not serializable"); - } -} diff --git a/libjava/classpath/java/util/prefs/PreferenceChangeListener.java b/libjava/classpath/java/util/prefs/PreferenceChangeListener.java deleted file mode 100644 index e6118bc..0000000 --- a/libjava/classpath/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/classpath/java/util/prefs/Preferences.java b/libjava/classpath/java/util/prefs/Preferences.java deleted file mode 100644 index 3ff9c85..0000000 --- a/libjava/classpath/java/util/prefs/Preferences.java +++ /dev/null @@ -1,696 +0,0 @@ -/* Preferences -- Preference node containing key value entries and subnodes - Copyright (C) 2001, 2004, 2005, 2006 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.classpath.ServiceFactory; -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; -import java.util.Iterator; - -/** - * 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. - */ - private static final String defaultFactoryClass - = "gnu.java.util.prefs.FileBasedFactory"; - - /** 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 = AccessController.doPrivileged( - new PrivilegedAction<PreferencesFactory>() { - public PreferencesFactory 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? Try to see if we have one defined - // as a System Preference - if (factory == null) - { - Iterator iter = ServiceFactory.lookupProviders - (PreferencesFactory.class, null); - - if (iter != null && iter.hasNext()) - factory = (PreferencesFactory) iter.next(); - } - - // 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 +"'", e); - } - } - - } - - return factory; - } - - /** - * Returns the system preferences node for the package of a class. - * The package node name of the class is determined by dropping the - * final component of the fully qualified class name and - * changing all '.' to '/' in the package name. If the class of the - * object has no package then the package node name is "<unnamed>". - * The returned node is <code>systemRoot().node(packageNodeName)</code>. - * - * @param c Object whose default system preference node is requested - * @returns system preferences node that should be used by class c - * @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 a class. - * The package node name of the class is determined by dropping the - * final component of the fully qualified class name and - * changing all '.' to '/' in the package name. If the class of the - * object has no package then the package node name is "<unnamed>". - * The returned node is <code>userRoot().node(packageNodeName)</code>. - * - * @param c Object whose default userpreference node is requested - * @returns userpreferences node that should be used by class c - * @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); - } - - /** - * Import preferences from the given input stream. This expects - * preferences to be represented in XML as emitted by - * {@link #exportNode(OutputStream)} and - * {@link #exportSubtree(OutputStream)}. - * @throws IOException if there is an error while reading - * @throws InvalidPreferencesFormatException if the XML is not properly - * formatted - */ - 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) - - /** - * Export this node, but not its descendants, as XML to the - * indicated output stream. The XML will be encoded using UTF-8 - * and will use a specified document type:<br> - * <code><!DOCTYPE preferences SYSTEM "http://java.sun.com/dtd/preferences.dtd"></code><br> - * @param os the output stream to which the XML is sent - * @throws BackingStoreException if preference data cannot be read - * @throws IOException if an error occurs while writing the XML - * @throws IllegalStateException if this node or an ancestor has been removed - */ - public abstract void exportNode(OutputStream os) - throws BackingStoreException, - IOException; - - /** - * Export this node and all its descendants as XML to the - * indicated output stream. The XML will be encoded using UTF-8 - * and will use a specified document type:<br> - * <code><!DOCTYPE preferences SYSTEM "http://java.sun.com/dtd/preferences.dtd"></code><br> - * @param os the output stream to which the XML is sent - * @throws BackingStoreException if preference data cannot be read - * @throws IOException if an error occurs while writing the XML - * @throws IllegalStateException if this node or an ancestor has been removed - */ - 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/classpath/java/util/prefs/PreferencesFactory.java b/libjava/classpath/java/util/prefs/PreferencesFactory.java deleted file mode 100644 index 5674f80..0000000 --- a/libjava/classpath/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/classpath/java/util/prefs/package.html b/libjava/classpath/java/util/prefs/package.html deleted file mode 100644 index 65fc1ac..0000000 --- a/libjava/classpath/java/util/prefs/package.html +++ /dev/null @@ -1,46 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> -<!-- package.html - describes classes in java.util.prefs package. - 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. --> - -<html> -<head><title>GNU Classpath - java.util.prefs</title></head> - -<body> -<p>Utility classes for storing and retrieving user and system preferences.</p> - -</body> -</html> diff --git a/libjava/classpath/java/util/regex/MatchResult.java b/libjava/classpath/java/util/regex/MatchResult.java deleted file mode 100644 index 605873d..0000000 --- a/libjava/classpath/java/util/regex/MatchResult.java +++ /dev/null @@ -1,81 +0,0 @@ -/* MatchResult.java -- Result of a regular expression match. - Copyright (C) 2006 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; - -/** - * This interface represents the result of a regular expression match. - * It can be used to query the contents of the match, but not to modify - * them. - * @since 1.5 - */ -public interface MatchResult -{ - /** Returns the index just after the last matched character. */ - int end(); - - /** - * Returns the index just after the last matched character of the - * given sub-match group. - * @param group the sub-match group - */ - int end(int group); - - /** Returns the substring of the input which was matched. */ - String group(); - - /** - * Returns the substring of the input which was matched by the - * given sub-match group. - * @param group the sub-match group - */ - String group(int group); - - /** Returns the number of sub-match groups in the matching pattern. */ - int groupCount(); - - /** Returns the index of the first character of the match. */ - int start(); - - /** - * Returns the index of the first character of the given sub-match - * group. - * @param group the sub-match group - */ - int start(int group); -} diff --git a/libjava/classpath/java/util/regex/Matcher.java b/libjava/classpath/java/util/regex/Matcher.java deleted file mode 100644 index 95a3553..0000000 --- a/libjava/classpath/java/util/regex/Matcher.java +++ /dev/null @@ -1,662 +0,0 @@ -/* Matcher.java -- Instance of a regular expression applied to a char sequence. - Copyright (C) 2002, 2004, 2006 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.java.lang.CPStringBuilder; - -import gnu.java.util.regex.CharIndexed; -import gnu.java.util.regex.RE; -import gnu.java.util.regex.REMatch; - -/** - * Instance of a regular expression applied to a char sequence. - * - * @since 1.4 - */ -public final class Matcher implements MatchResult -{ - private Pattern pattern; - private CharSequence input; - // We use CharIndexed as an input object to the getMatch method in order - // that /\G/ (the end of the previous match) may work. The information - // of the previous match is stored in the CharIndexed object. - private CharIndexed inputCharIndexed; - private int position; - private int appendPosition; - private REMatch match; - - /** - * The start of the region of the input on which to match. - */ - private int regionStart; - - /** - * The end of the region of the input on which to match. - */ - private int regionEnd; - - /** - * True if the match process should look beyond the - * region marked by regionStart to regionEnd when - * performing lookAhead, lookBehind and boundary - * matching. - */ - private boolean transparentBounds; - - /** - * The flags that affect the anchoring bounds. - * If {@link #hasAnchoringBounds()} is {@code true}, - * the match process will honour the - * anchoring bounds: ^, \A, \Z, \z and $. If - * {@link #hasAnchoringBounds()} is {@code false}, - * the anchors are ignored and appropriate flags, - * stored in this variable, are used to provide this - * behaviour. - */ - private int anchoringBounds; - - Matcher(Pattern pattern, CharSequence input) - { - this.pattern = pattern; - this.input = input; - this.inputCharIndexed = RE.makeCharIndexed(input, 0); - regionStart = 0; - regionEnd = input.length(); - transparentBounds = false; - anchoringBounds = 0; - } - - /** - * Changes the pattern used by the {@link Matcher} to - * the one specified. Existing match information is lost, - * but the input and the matcher's position within it is - * retained. - * - * @param newPattern the new pattern to use. - * @return this matcher. - * @throws IllegalArgumentException if {@code newPattern} is - * {@code null}. - * @since 1.5 - */ - public Matcher usePattern(Pattern newPattern) - { - if (newPattern == null) - throw new IllegalArgumentException("The new pattern was null."); - pattern = newPattern; - match = null; - - return this; - } - - /** - * @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(RE.getReplacement(replacement, match, - RE.REG_REPLACE_USE_BACKSLASHESCAPE)); - 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); - if (transparentBounds || (regionStart == 0 && regionEnd == input.length())) - match = pattern.getRE().getMatch(inputCharIndexed, position, anchoringBounds); - else - match = pattern.getRE().getMatch(input.subSequence(regionStart, regionEnd), - position, anchoringBounds); - if (match != null) - { - int endIndex = match.getEndIndex(); - // Is the match within input limits? - if (endIndex > input.length()) - { - match = null; - return false; - } - // 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) - { - if (transparentBounds || (regionStart == 0 && regionEnd == input.length())) - match = pattern.getRE().getMatch(inputCharIndexed, start, anchoringBounds); - else - match = pattern.getRE().getMatch(input.subSequence(regionStart, regionEnd), - start, anchoringBounds); - 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, - RE.REG_REPLACE_USE_BACKSLASHESCAPE); - } - - /** - * @param replacement The replacement string - */ - public String replaceAll (String replacement) - { - reset(); - return pattern.getRE().substituteAll(input, replacement, position, - RE.REG_REPLACE_USE_BACKSLASHESCAPE); - } - - public int groupCount () - { - return pattern.getRE().getNumSubs(); - } - - public boolean lookingAt () - { - if (transparentBounds || (regionStart == 0 && regionEnd == input.length())) - match = pattern.getRE().getMatch(inputCharIndexed, regionStart, - anchoringBounds|RE.REG_FIX_STARTING_POSITION|RE.REG_ANCHORINDEX); - else - match = pattern.getRE().getMatch(input.subSequence(regionStart, regionEnd), 0, - anchoringBounds|RE.REG_FIX_STARTING_POSITION); - 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 (transparentBounds || (regionStart == 0 && regionEnd == input.length())) - match = pattern.getRE().getMatch(inputCharIndexed, regionStart, - anchoringBounds|RE.REG_TRY_ENTIRE_MATCH|RE.REG_FIX_STARTING_POSITION|RE.REG_ANCHORINDEX); - else - match = pattern.getRE().getMatch(input.subSequence(regionStart, regionEnd), 0, - anchoringBounds|RE.REG_TRY_ENTIRE_MATCH|RE.REG_FIX_STARTING_POSITION); - if (match != null) - { - if (match.getStartIndex() == 0) - { - position = match.getEndIndex(); - if (position == input.length()) - return true; - } - match = null; - } - return false; - } - - /** - * Returns the Pattern that is interpreted by this Matcher - */ - public Pattern pattern () - { - return pattern; - } - - /** - * Resets the internal state of the matcher, including - * resetting the region to its default state of encompassing - * the whole input. The state of {@link #hasTransparentBounds()} - * and {@link #hasAnchoringBounds()} are unaffected. - * - * @return a reference to this matcher. - * @see #regionStart() - * @see #regionEnd() - * @see #hasTransparentBounds() - * @see #hasAnchoringBounds() - */ - public Matcher reset () - { - position = 0; - match = null; - regionStart = 0; - regionEnd = input.length(); - appendPosition = 0; - return this; - } - - /** - * Resets the internal state of the matcher, including - * resetting the region to its default state of encompassing - * the whole input. The state of {@link #hasTransparentBounds()} - * and {@link #hasAnchoringBounds()} are unaffected. - * - * @param input The new input character sequence. - * @return a reference to this matcher. - * @see #regionStart() - * @see #regionEnd() - * @see #hasTransparentBounds() - * @see #hasAnchoringBounds() - */ - public Matcher reset (CharSequence input) - { - this.input = input; - this.inputCharIndexed = RE.makeCharIndexed(input, 0); - return reset(); - } - - /** - * @return 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); - } - - /** - * @return True if and only if the matcher hit the end of input. - * @since 1.5 - */ - public boolean hitEnd() - { - return inputCharIndexed.hitEnd(); - } - - /** - * @return A string expression of this matcher. - */ - public String toString() - { - CPStringBuilder sb = new CPStringBuilder(); - sb.append(this.getClass().getName()) - .append("[pattern=").append(pattern.pattern()) - .append(" region=").append(regionStart).append(",").append(regionEnd) - .append(" anchoringBounds=").append(anchoringBounds == 0) - .append(" transparentBounds=").append(transparentBounds) - .append(" lastmatch=").append(match == null ? "" : match.toString()) - .append("]"); - return sb.toString(); - } - - private void assertMatchOp() - { - if (match == null) throw new IllegalStateException(); - } - - /** - * <p> - * Defines the region of the input on which to match. - * By default, the {@link Matcher} attempts to match - * the whole string (from 0 to the length of the input), - * but a region between {@code start} (inclusive) and - * {@code end} (exclusive) on which to match may instead - * be defined using this method. - * </p> - * <p> - * The behaviour of region matching is further affected - * by the use of transparent or opaque bounds (see - * {@link #useTransparentBounds(boolean)}) and whether or not - * anchors ({@code ^} and {@code $}) are in use - * (see {@link #useAnchoringBounds(boolean)}). With transparent - * bounds, the matcher is aware of input outside the bounds - * set by this method, whereas, with opaque bounds (the default) - * only the input within the bounds is used. The use of - * anchors are affected by this setting; with transparent - * bounds, anchors will match the beginning of the real input, - * while with opaque bounds they match the beginning of the - * region. {@link #useAnchoringBounds(boolean)} can be used - * to turn on or off the matching of anchors. - * </p> - * - * @param start the start of the region (inclusive). - * @param end the end of the region (exclusive). - * @return a reference to this matcher. - * @throws IndexOutOfBoundsException if either {@code start} or - * {@code end} are less than zero, - * if either {@code start} or - * {@code end} are greater than the - * length of the input, or if - * {@code start} is greater than - * {@code end}. - * @see #regionStart() - * @see #regionEnd() - * @see #hasTransparentBounds() - * @see #useTransparentBounds(boolean) - * @see #hasAnchoringBounds() - * @see #useAnchoringBounds(boolean) - * @since 1.5 - */ - public Matcher region(int start, int end) - { - int length = input.length(); - if (start < 0) - throw new IndexOutOfBoundsException("The start position was less than zero."); - if (start >= length) - throw new IndexOutOfBoundsException("The start position is after the end of the input."); - if (end < 0) - throw new IndexOutOfBoundsException("The end position was less than zero."); - if (end > length) - throw new IndexOutOfBoundsException("The end position is after the end of the input."); - if (start > end) - throw new IndexOutOfBoundsException("The start position is after the end position."); - reset(); - regionStart = start; - regionEnd = end; - return this; - } - - /** - * The start of the region on which to perform matches (inclusive). - * - * @return the start index of the region. - * @see #region(int,int) - * #see #regionEnd() - * @since 1.5 - */ - public int regionStart() - { - return regionStart; - } - - /** - * The end of the region on which to perform matches (exclusive). - * - * @return the end index of the region. - * @see #region(int,int) - * @see #regionStart() - * @since 1.5 - */ - public int regionEnd() - { - return regionEnd; - } - - /** - * Returns true if the bounds of the region marked by - * {@link #regionStart()} and {@link #regionEnd()} are - * transparent. When these bounds are transparent, the - * matching process can look beyond them to perform - * lookahead, lookbehind and boundary matching operations. - * By default, the bounds are opaque. - * - * @return true if the bounds of the matching region are - * transparent. - * @see #useTransparentBounds(boolean) - * @see #region(int,int) - * @see #regionStart() - * @see #regionEnd() - * @since 1.5 - */ - public boolean hasTransparentBounds() - { - return transparentBounds; - } - - /** - * Sets the transparency of the bounds of the region - * marked by {@link #regionStart()} and {@link #regionEnd()}. - * A value of {@code true} makes the bounds transparent, - * so the matcher can see beyond them to perform lookahead, - * lookbehind and boundary matching operations. A value - * of {@code false} (the default) makes the bounds opaque, - * restricting the match to the input region denoted - * by {@link #regionStart()} and {@link #regionEnd()}. - * - * @param transparent true if the bounds should be transparent. - * @return a reference to this matcher. - * @see #hasTransparentBounds() - * @see #region(int,int) - * @see #regionStart() - * @see #regionEnd() - * @since 1.5 - */ - public Matcher useTransparentBounds(boolean transparent) - { - transparentBounds = transparent; - return this; - } - - /** - * Returns true if the matcher will honour the use of - * the anchoring bounds: {@code ^}, {@code \A}, {@code \Z}, - * {@code \z} and {@code $}. By default, the anchors - * are used. Note that the effect of the anchors is - * also affected by {@link #hasTransparentBounds()}. - * - * @return true if the matcher will attempt to match - * the anchoring bounds. - * @see #useAnchoringBounds(boolean) - * @see #hasTransparentBounds() - * @since 1.5 - */ - public boolean hasAnchoringBounds() - { - return anchoringBounds == 0; - } - - /** - * Enables or disables the use of the anchoring bounds: - * {@code ^}, {@code \A}, {@code \Z}, {@code \z} and - * {@code $}. By default, their use is enabled. When - * disabled, the matcher will not attempt to match - * the anchors. - * - * @param useAnchors true if anchoring bounds should be used. - * @return a reference to this matcher. - * @since 1.5 - * @see #hasAnchoringBounds() - */ - public Matcher useAnchoringBounds(boolean useAnchors) - { - if (useAnchors) - anchoringBounds = 0; - else - anchoringBounds = RE.REG_NOTBOL|RE.REG_NOTEOL; - return this; - } - - /** - * Returns a read-only snapshot of the current state of - * the {@link Matcher} as a {@link MatchResult}. Any - * subsequent changes to this instance are not reflected - * in the returned {@link MatchResult}. - * - * @return a {@link MatchResult} instance representing the - * current state of the {@link Matcher}. - */ - public MatchResult toMatchResult() - { - Matcher snapshot = new Matcher(pattern, input); - if (match != null) - snapshot.match = (REMatch) match.clone(); - return snapshot; - } - - /** - * Returns a literalized string of s where characters {@code $} and {@code - * \\} are escaped. - * - * @param s the string to literalize. - * @return the literalized string. - * @since 1.5 - */ - public static String quoteReplacement(String s) - { - if (s == null) - throw new NullPointerException(); - CPStringBuilder sb = new CPStringBuilder(); - for (int i = 0; i < s.length(); i++) - { - char ch = s.charAt(i); - if (ch == '$' || ch == '\\') - sb.append('\\'); - sb.append(ch); - } - return sb.toString(); - } - -} diff --git a/libjava/classpath/java/util/regex/Pattern.java b/libjava/classpath/java/util/regex/Pattern.java deleted file mode 100644 index b1c937f..0000000 --- a/libjava/classpath/java/util/regex/Pattern.java +++ /dev/null @@ -1,309 +0,0 @@ -/* Pattern.java -- Compiled regular expression ready to be applied. - Copyright (C) 2002, 2004, 2005, 2007, 2010 - 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.java.lang.CPStringBuilder; - -import gnu.java.util.regex.RE; -import gnu.java.util.regex.REException; -import gnu.java.util.regex.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; - - RESyntax syntax = RESyntax.RE_SYNTAX_JAVA_1_4; - int gnuFlags = 0; - gnuFlags |= RE.REG_ICASE_USASCII; - if ((flags & CASE_INSENSITIVE) != 0) - gnuFlags |= RE.REG_ICASE; - if ((flags & MULTILINE) != 0) - { - gnuFlags |= RE.REG_MULTILINE; - syntax = new RESyntax(syntax); - syntax.setLineSeparator(null); - } - if ((flags & DOTALL) != 0) - gnuFlags |= RE.REG_DOT_NEWLINE; - if ((flags & UNICODE_CASE) != 0) - gnuFlags &= ~RE.REG_ICASE_USASCII; - // not yet supported: - // if ((flags & CANON_EQ) != 0) gnuFlags = - - if ((flags & UNIX_LINES) != 0) - { - // Use a syntax set with \n for linefeeds? - syntax = new RESyntax(syntax); - syntax.setLineSeparator("\n"); - } - - if ((flags & COMMENTS) != 0) - { - gnuFlags |= RE.REG_X_COMMENTS; - } - - try - { - this.re = new RE(regex, gnuFlags, syntax); - } - catch (REException e) - { - PatternSyntaxException pse; - pse = new PatternSyntaxException(e.getMessage(), - regex, e.getPosition()); - pse.initCause(e); - throw pse; - } - } - - // 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<String> list = new ArrayList<String>(); - int empties = 0; - int count = 0; - int start = 0; - int end; - boolean matched = matcher.find(); - - while (matched && (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(); - matched = matcher.find(); - } - - // 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); - } - - return list.toArray(new String[list.size()]); - } - - public String pattern () - { - return regex; - } - - /** - * Returns a literal pattern for the specified String. - * - * @param String to return a literal pattern for. - * @return a literal pattern for the specified String. - * @exception NullPointerException if str is null. - * @since 1.5 - */ - public static String quote(String str) - { - int eInd = str.indexOf("\\E"); - if (eInd < 0) - { - // No need to handle backslashes. - return "\\Q" + str + "\\E"; - } - - CPStringBuilder sb = new CPStringBuilder(str.length() + 16); - sb.append("\\Q"); // start quote - - int pos = 0; - do - { - // A backslash is quoted by another backslash; - // 'E' is not needed to be quoted. - sb.append(str.substring(pos, eInd)) - .append("\\E" + "\\\\" + "E" + "\\Q"); - pos = eInd + 2; - } while ((eInd = str.indexOf("\\E", pos)) >= 0); - - sb.append(str.substring(pos, str.length())) - .append("\\E"); // end quote - return sb.toString(); - } - - /** - * Return the regular expression used to construct this object. - * @specnote Prior to JDK 1.5 this method had a different behavior - * @since 1.5 - */ - public String toString() - { - return regex; - } -} diff --git a/libjava/classpath/java/util/regex/PatternSyntaxException.java b/libjava/classpath/java/util/regex/PatternSyntaxException.java deleted file mode 100644 index db73d06..0000000 --- a/libjava/classpath/java/util/regex/PatternSyntaxException.java +++ /dev/null @@ -1,135 +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; - -import gnu.java.lang.CPStringBuilder; - -/** - * Indicates illegal pattern for regular expression. - * Includes state to inspect the pattern and what and where the expression - * was not valid regular expression. - * @since 1.4 - */ -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"); - CPStringBuilder sb = new CPStringBuilder(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/classpath/java/util/regex/package.html b/libjava/classpath/java/util/regex/package.html deleted file mode 100644 index 0573a36..0000000 --- a/libjava/classpath/java/util/regex/package.html +++ /dev/null @@ -1,46 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> -<!-- package.html - describes classes in java.util.regex package. - 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. --> - -<html> -<head><title>GNU Classpath - java.util.regex</title></head> - -<body> -<p>Regular expression patterns and matchers.</p> - -</body> -</html> diff --git a/libjava/classpath/java/util/spi/CurrencyNameProvider.java b/libjava/classpath/java/util/spi/CurrencyNameProvider.java deleted file mode 100644 index 14fae4d..0000000 --- a/libjava/classpath/java/util/spi/CurrencyNameProvider.java +++ /dev/null @@ -1,100 +0,0 @@ -/* CurrencyNameProvider.java -- Providers of localized currency symbols - Copyright (C) 2007 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.spi; - -import java.util.Locale; - -/** - * A {@link CurrencyNameProvider} provides localized - * versions of the symbols that represent a particular - * currency. Note that currency symbols are regarded - * as names, and thus a <code>null</code> value may - * be returned, which should be treated as a lack of - * support for the specified {@link Locale}. - * - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.6 - */ -public abstract class CurrencyNameProvider - extends LocaleServiceProvider -{ - - /** - * Constructs a new {@link CurrencyNameProvider}. - * Provided for implicit invocation by subclasses. - */ - protected CurrencyNameProvider() - { - } - - /** - * <p> - * This method returns the symbol which precedes or follows a - * value in this particular currency. The returned value is - * the symbol used to denote the currency in the specified locale. - * </p> - * <p> - * For example, a supplied locale may specify a different symbol - * for the currency, due to conflicts with its own currency. - * This would be the case with the American currency, the dollar. - * Locales that also use a dollar-based currency (e.g. Canada, Australia) - * need to differentiate the American dollar using 'US$' rather than '$'. - * So, supplying one of these locales to <code>getSymbol()</code> would - * return this value, rather than the standard '$'. - * </p> - * <p> - * In cases where there is no such symbol for a particular currency, - * <code>null</code> should be returned. - * </p> - * - * @param currencyCode the ISO 4217 currency code, consisting - * of three uppercase letters from 'A' to 'Z' - * @param locale the locale to express the symbol in. - * @return the currency symbol, or <code>null</code> if one is - * unavailable. - * @throws NullPointerException if the locale is null. - * @throws IllegalArgumentException if the currency code is - * not in the correct format - * or the locale is not one - * returned by - * {@link getAvailableLocales()} - * @see java.util.Currency#getSymbol(java.util.Locale) - */ - public abstract String getSymbol(String currencyCode, Locale locale); - -} diff --git a/libjava/classpath/java/util/spi/LocaleNameProvider.java b/libjava/classpath/java/util/spi/LocaleNameProvider.java deleted file mode 100644 index 44250fe..0000000 --- a/libjava/classpath/java/util/spi/LocaleNameProvider.java +++ /dev/null @@ -1,135 +0,0 @@ -/* LocaleNameProvider.java -- Providers of localized locale names - Copyright (C) 2007 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.spi; - -import java.util.Locale; - -/** - * A {@link LocaleNameProvider} provides localized - * versions of the names that represent a particular - * locale. Note that a <code>null</code> value may - * be returned, which should be treated as a lack of - * support for the specified {@link Locale}. - * - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.6 - */ -public abstract class LocaleNameProvider - extends LocaleServiceProvider -{ - - /** - * Constructs a new {@link LocaleNameProvider}. - * Provided for implicit invocation by subclasses. - */ - protected LocaleNameProvider() - { - } - - /** - * Returns the localized name for the specified ISO 3166 - * country in the supplied {@link java.util.Locale}. - * For example, if the country code is <code>"DE"</code>, - * this method will return <code>"Germany"</code> for - * {@link Locale.ENGLISH} but <code>"Deutschland"</code> - * for {@link Locale.GERMANY}. If the name of the country - * in the given locale is not supported, <code>null</code> - * is returned. - * - * @param countryCode the ISO 3166 country code, consisting - * of two uppercase letters from 'A' to 'Z' - * @param locale the locale to express the country in. - * @return the country name, or <code>null</code> if one is - * not available. - * @throws NullPointerException if the locale is null. - * @throws IllegalArgumentException if the country code is - * not in the correct format - * or the locale is not one - * returned by - * {@link getAvailableLocales()} - * @see java.util.Locale#getDisplayCountry(java.util.Locale) - */ - public abstract String getDisplayCountry(String countryCode, - Locale locale); - - /** - * Returns the localized name for the specified ISO 639 - * language in the supplied {@link java.util.Locale}. - * For example, if the language code is <code>"de"</code>, - * this method will return <code>"German"</code> for - * {@link Locale.ENGLISH} but <code>"Deutsch"</code> - * for {@link Locale.GERMANY}. If the name of the language - * in the given locale is not supported, <code>null</code> - * is returned. - * - * @param langCode the ISO 639 language code, consisting - * of two lowercase letters from 'a' to 'z' - * @param locale the locale to express the language in. - * @return the country name, or <code>null</code> if one is - * not available. - * @throws NullPointerException if the locale is null. - * @throws IllegalArgumentException if the language code is - * not in the correct format - * or the locale is not one - * returned by - * {@link getAvailableLocales()} - * @see java.util.Locale#getDisplayLanguage(java.util.Locale) - */ - public abstract String getDisplayLanguage(String langCode, - Locale locale); - - /** - * Returns the localized name for the specified variant - * in the supplied {@link java.util.Locale}. If the name - * of the variant in the given locale is not supported, - * <code>null</code> is returned. - * - * @param variant the variant. - * @param locale the locale to express the variant in. - * @return the localized variant, or <code>null</code> if one is - * not available. - * @throws NullPointerException if the locale is null. - * @throws IllegalArgumentException if the locale is not one - * returned by - * {@link getAvailableLocales()} - * @see java.util.Locale#getDisplayVariant(java.util.Locale) - */ - public abstract String getDisplayVariant(String variant, - Locale locale); - -} diff --git a/libjava/classpath/java/util/spi/LocaleServiceProvider.java b/libjava/classpath/java/util/spi/LocaleServiceProvider.java deleted file mode 100644 index bb5b685..0000000 --- a/libjava/classpath/java/util/spi/LocaleServiceProvider.java +++ /dev/null @@ -1,125 +0,0 @@ -/* LocaleServiceProvider.java -- Superclass of locale SPIs - Copyright (C) 2007 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.spi; - -import java.util.Locale; - -/** - * <p> - * This is the superclass of all the {@link Locale} service - * provider interfaces or SPIs. The locale SPIs are used - * to allow for the provision of additional support for - * locale-specific data. The runtime environment has its - * own collection of locale data, but these interfaces allow - * this to be extended by external classes. - * </p> - * <p> - * Service providers are created as concrete implementations - * of these interfaces, and accessed using the extension - * mechanism, realised by {@link ServiceLoader}. When a factory - * method of one of the locale-specific classes (such as - * {@link java.text.DateFormatSymbols} or {@link java.util.Currency}) - * is called, the runtime environment is first asked to - * provide data for the specified locale. If the runtime - * environment fails to provide this, then the offer is - * made to service providers which implement the appropriate - * interface. - * </p> - * <p> - * Each provider implements the method specified by this - * class, {@link #getAvailableLocales()}. This method is - * called first to determine whether the provider will be of - * any use in providing data for the specified locale. If - * a provider is found to be capable, then a more specific - * method appropriate to the class requiring the data will - * be called. In the case of {@link java.text.DateFormatSymbols}, - * this would be - * {@link java.text.spi.DateFormatSymbols#getInstance(Locale)}. - * </p> - * <p> - * If neither a service provider nor the runtime environment - * itself can fulfill the request, a fallback procedure is - * engaged. The locale is modified by applying the first - * applicable rule: - * </p> - * <ol> - * <li>If the variant contains a <code>'_'</code>, then - * this and everything following it is trimmed.</li> - * <li>If the variant is non-empty, it is converted to - * an empty string.</li> - * <li>If the country is non-empty, it is converted to - * an empty string.</li> - * <li>If the language is non-empty, it is converted to - * an empty string.</li> - * </ol> - * <p> - * The modified locale is then used to start the same - * process again. The root locale (@link java.util.Locale#ROOT} - * must be supported by the runtime environment in order - * to terminate this cycle. - * </p> - * <p> - * Note that any names returned by the providers may - * be <code>null</code>. Returning a <code>null</code> - * name is considered equivalent to not supporting a - * particular locale. - * </p> - * - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.6 - */ -public abstract class LocaleServiceProvider -{ - - /** - * Constructs a new {@link LocaleServiceProvider}. - * Provided for implicit invocation by subclasses. - */ - protected LocaleServiceProvider() - { - } - - /** - * Returns an array of {@link Locale} instances, - * for which the provider can supply localized data. - * - * @return an array of supported locales. - */ - public abstract Locale[] getAvailableLocales(); - -} diff --git a/libjava/classpath/java/util/spi/TimeZoneNameProvider.java b/libjava/classpath/java/util/spi/TimeZoneNameProvider.java deleted file mode 100644 index afd56eb..0000000 --- a/libjava/classpath/java/util/spi/TimeZoneNameProvider.java +++ /dev/null @@ -1,97 +0,0 @@ -/* TimeZoneNameProvider.java -- Providers of localized currency symbols - Copyright (C) 2007 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.spi; - -import java.util.Locale; - -/** - * A {@link TimeZoneNameProvider} provides localized - * versions of the names that represent a particular - * timezone. A <code>null</code> value may - * be returned, which should be treated as a lack of - * support for the specified {@link Locale}. The names - * from this class are also used by - * {@link DateFormatSymbols#getZoneStrings()}. - * - * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @since 1.6 - */ -public abstract class TimeZoneNameProvider - extends LocaleServiceProvider -{ - - /** - * Constructs a new {@link TimeZoneNameProvider}. - * Provided for implicit invocation by subclasses. - */ - protected TimeZoneNameProvider() - { - } - - /** - * Returns a name for the specified time zone identifier - * localized to the supplied {@link java.util.Locale}. - * The time zone identifier is either <code>"GMT"</code> - * or one of the identifiers from the public domain "tz - * database" found at <a href="ftp://elsie.nci.nih.gov/pub/"> - * ftp://elsie.nci.nih.gov/pub</a>. Note that a translated - * name for the daylight savings time variant should be returned, - * even if the timezone has not observed daylight savings - * time in the past. If the name of the timezone - * in the given locale is not supported, <code>null</code> - * is returned. - * - * @param id a time zone identifier. - * @param daylight true if the daylight savings time variant - * should be returned. - * @param style either {@link java.util.TimeZone.LONG} or - * {@link java.util.TimeZone.SHORT} - * @param locale the locale to express the timezone in. - * @return the localized time zone name, or <code>null</code> - * if one is not available. - * @throws NullPointerException if the identifer or locale is null. - * @throws IllegalArgumentException if the style is invalid - * or the locale is not one - * returned by - * {@link getAvailableLocales()} - * @see java.util.TimeZone#getDisplayName(boolean,int,java.util.Locale) - */ - public abstract String getDisplayName(String id, boolean daylight, - int style, Locale locale); - -} diff --git a/libjava/classpath/java/util/spi/package.html b/libjava/classpath/java/util/spi/package.html deleted file mode 100644 index 1abdeb8..0000000 --- a/libjava/classpath/java/util/spi/package.html +++ /dev/null @@ -1,50 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> -<!-- package.html - describes classes in java.util.spi package. - Copyright (C) 2007 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. --> - -<html> -<head><title>GNU Classpath - java.util.spi</title></head> - -<body> - -<p> -A series of service provider interfaces for use by the -classes in <code>java.util</code>. -</p> -<p><span style="font-weight: bold;">Since</span>: 1.6</p> -</body> -</html> diff --git a/libjava/classpath/java/util/zip/Adler32.java b/libjava/classpath/java/util/zip/Adler32.java deleted file mode 100644 index cc27da9..0000000 --- a/libjava/classpath/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/classpath/java/util/zip/CRC32.java b/libjava/classpath/java/util/zip/CRC32.java deleted file mode 100644 index de2e708..0000000 --- a/libjava/classpath/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/classpath/java/util/zip/CheckedInputStream.java b/libjava/classpath/java/util/zip/CheckedInputStream.java deleted file mode 100644 index 163a4c4..0000000 --- a/libjava/classpath/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/classpath/java/util/zip/CheckedOutputStream.java b/libjava/classpath/java/util/zip/CheckedOutputStream.java deleted file mode 100644 index e022225..0000000 --- a/libjava/classpath/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/classpath/java/util/zip/Checksum.java b/libjava/classpath/java/util/zip/Checksum.java deleted file mode 100644 index 3342ba3..0000000 --- a/libjava/classpath/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/classpath/java/util/zip/DataFormatException.java b/libjava/classpath/java/util/zip/DataFormatException.java deleted file mode 100644 index dc5b10d..0000000 --- a/libjava/classpath/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/classpath/java/util/zip/Deflater.java b/libjava/classpath/java/util/zip/Deflater.java deleted file mode 100644 index dd81fe7..0000000 --- a/libjava/classpath/java/util/zip/Deflater.java +++ /dev/null @@ -1,537 +0,0 @@ -/* Deflater.java - Compress a data stream - 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.zip; - -/** - * This is the Deflater class. The deflater class compresses input - * with the deflate algorithm described in RFC 1951. It has several - * compression levels and three different strategies described below. - * - * This class is <i>not</i> thread safe. This is inherent in the API, due - * to the split of deflate and setInput. - * - * @author Jochen Hoenicke - * @author Tom Tromey - */ -public class Deflater -{ - /** - * The best and slowest compression level. This tries to find very - * long and distant string repetitions. - */ - public static final int BEST_COMPRESSION = 9; - /** - * The worst but fastest compression level. - */ - public static final int BEST_SPEED = 1; - /** - * The default compression level. - */ - public static final int DEFAULT_COMPRESSION = -1; - /** - * This level won't compress at all but output uncompressed blocks. - */ - public static final int NO_COMPRESSION = 0; - - /** - * The default strategy. - */ - public static final int DEFAULT_STRATEGY = 0; - /** - * This strategy will only allow longer string repetitions. It is - * useful for random data with a small character set. - */ - public static final int FILTERED = 1; - - /** - * This strategy will not look for string repetitions at all. It - * only encodes with Huffman trees (which means, that more common - * characters get a smaller encoding. - */ - public static final int HUFFMAN_ONLY = 2; - - /** - * The compression method. This is the only method supported so far. - * There is no need to use this constant at all. - */ - public static final int DEFLATED = 8; - - /* - * The Deflater can do the following state transitions: - * - * (1) -> INIT_STATE ----> INIT_FINISHING_STATE ---. - * / | (2) (5) | - * / v (5) | - * (3)| SETDICT_STATE ---> SETDICT_FINISHING_STATE |(3) - * \ | (3) | ,-------' - * | | | (3) / - * v v (5) v v - * (1) -> BUSY_STATE ----> FINISHING_STATE - * | (6) - * v - * FINISHED_STATE - * \_____________________________________/ - * | (7) - * v - * CLOSED_STATE - * - * (1) If we should produce a header we start in INIT_STATE, otherwise - * we start in BUSY_STATE. - * (2) A dictionary may be set only when we are in INIT_STATE, then - * we change the state as indicated. - * (3) Whether a dictionary is set or not, on the first call of deflate - * we change to BUSY_STATE. - * (4) -- intentionally left blank -- :) - * (5) FINISHING_STATE is entered, when flush() is called to indicate that - * there is no more INPUT. There are also states indicating, that - * the header wasn't written yet. - * (6) FINISHED_STATE is entered, when everything has been flushed to the - * internal pending output buffer. - * (7) At any time (7) - * - */ - - private static final int IS_SETDICT = 0x01; - private static final int IS_FLUSHING = 0x04; - private static final int IS_FINISHING = 0x08; - - private static final int INIT_STATE = 0x00; - private static final int SETDICT_STATE = 0x01; - private static final int INIT_FINISHING_STATE = 0x08; - private static final int SETDICT_FINISHING_STATE = 0x09; - private static final int BUSY_STATE = 0x10; - private static final int FLUSHING_STATE = 0x14; - private static final int FINISHING_STATE = 0x1c; - private static final int FINISHED_STATE = 0x1e; - private static final int CLOSED_STATE = 0x7f; - - /** Compression level. */ - private int level; - - /** should we include a header. */ - private boolean noHeader; - - /** The current state. */ - private int state; - - /** The total bytes of output written. */ - private long totalOut; - - /** The pending output. */ - private DeflaterPending pending; - - /** The deflater engine. */ - private DeflaterEngine engine; - - /** - * Creates a new deflater with default compression level. - */ - public Deflater() - { - this(DEFAULT_COMPRESSION, false); - } - - /** - * Creates a new deflater with given compression level. - * @param lvl the compression level, a value between NO_COMPRESSION - * and BEST_COMPRESSION, or DEFAULT_COMPRESSION. - * @exception IllegalArgumentException if lvl is out of range. - */ - public Deflater(int lvl) - { - this(lvl, false); - } - - /** - * Creates a new deflater with given compression level. - * @param lvl the compression level, a value between NO_COMPRESSION - * and BEST_COMPRESSION. - * @param nowrap true, iff we should suppress the deflate header at the - * beginning and the adler checksum at the end of the output. This is - * useful for the GZIP format. - * @exception IllegalArgumentException if lvl is out of range. - */ - public Deflater(int lvl, boolean nowrap) - { - if (lvl == DEFAULT_COMPRESSION) - lvl = 6; - else if (lvl < NO_COMPRESSION || lvl > BEST_COMPRESSION) - throw new IllegalArgumentException(); - - pending = new DeflaterPending(); - engine = new DeflaterEngine(pending); - this.noHeader = nowrap; - setStrategy(DEFAULT_STRATEGY); - setLevel(lvl); - reset(); - } - - /** - * Resets the deflater. The deflater acts afterwards as if it was - * just created with the same compression level and strategy as it - * had before. - */ - public void reset() - { - state = (noHeader ? BUSY_STATE : INIT_STATE); - totalOut = 0; - pending.reset(); - engine.reset(); - } - - /** - * Frees all objects allocated by the compressor. There's no - * reason to call this, since you can just rely on garbage - * collection. Exists only for compatibility against Sun's JDK, - * where the compressor allocates native memory. - * If you call any method (even reset) afterwards the behaviour is - * <i>undefined</i>. - */ - public void end() - { - engine = null; - pending = null; - state = CLOSED_STATE; - } - - /** - * Gets the current adler checksum of the data that was processed so - * far. - */ - public int getAdler() - { - return engine.getAdler(); - } - - /** - * Gets the number of input bytes processed so far. - */ - public int getTotalIn() - { - return (int) engine.getTotalIn(); - } - - /** - * Gets the number of input bytes processed so far. - * @since 1.5 - */ - public long getBytesRead() - { - return engine.getTotalIn(); - } - - /** - * Gets the number of output bytes so far. - */ - public int getTotalOut() - { - return (int) totalOut; - } - - /** - * Gets the number of output bytes so far. - * @since 1.5 - */ - public long getBytesWritten() - { - return totalOut; - } - - /** - * Finalizes this object. - */ - protected void finalize() - { - /* Exists solely for compatibility. We don't have any native state. */ - } - - /** - * Flushes the current input block. Further calls to deflate() will - * produce enough output to inflate everything in the current input - * block. This is not part of Sun's JDK so I have made it package - * private. It is used by DeflaterOutputStream to implement - * flush(). - */ - void flush() { - state |= IS_FLUSHING; - } - - /** - * Finishes the deflater with the current input block. It is an error - * to give more input after this method was called. This method must - * be called to force all bytes to be flushed. - */ - public void finish() { - state |= IS_FLUSHING | IS_FINISHING; - } - - /** - * Returns true iff the stream was finished and no more output bytes - * are available. - */ - public boolean finished() - { - return state == FINISHED_STATE && pending.isFlushed(); - } - - /** - * Returns true, if the input buffer is empty. - * You should then call setInput(). <br> - * - * <em>NOTE</em>: This method can also return true when the stream - * was finished. - */ - public boolean needsInput() - { - return engine.needsInput(); - } - - /** - * Sets the data which should be compressed next. This should be only - * called when needsInput indicates that more input is needed. - * If you call setInput when needsInput() returns false, the - * previous input that is still pending will be thrown away. - * The given byte array should not be changed, before needsInput() returns - * true again. - * This call is equivalent to <code>setInput(input, 0, input.length)</code>. - * @param input the buffer containing the input data. - * @exception IllegalStateException if the buffer was finished() or ended(). - */ - public void setInput(byte[] input) - { - setInput(input, 0, input.length); - } - - /** - * Sets the data which should be compressed next. This should be - * only called when needsInput indicates that more input is needed. - * The given byte array should not be changed, before needsInput() returns - * true again. - * @param input the buffer containing the input data. - * @param off the start of the data. - * @param len the length of the data. - * @exception IllegalStateException if the buffer was finished() or ended() - * or if previous input is still pending. - */ - public void setInput(byte[] input, int off, int len) - { - if ((state & IS_FINISHING) != 0) - throw new IllegalStateException("finish()/end() already called"); - engine.setInput(input, off, len); - } - - /** - * Sets the compression level. There is no guarantee of the exact - * position of the change, but if you call this when needsInput is - * true the change of compression level will occur somewhere near - * before the end of the so far given input. - * @param lvl the new compression level. - */ - public void setLevel(int lvl) - { - if (lvl == DEFAULT_COMPRESSION) - lvl = 6; - else if (lvl < NO_COMPRESSION || lvl > BEST_COMPRESSION) - throw new IllegalArgumentException(); - - - if (level != lvl) - { - level = lvl; - engine.setLevel(lvl); - } - } - - /** - * Sets the compression strategy. Strategy is one of - * DEFAULT_STRATEGY, HUFFMAN_ONLY and FILTERED. For the exact - * position where the strategy is changed, the same as for - * setLevel() applies. - * @param stgy the new compression strategy. - */ - public void setStrategy(int stgy) - { - if (stgy != DEFAULT_STRATEGY && stgy != FILTERED - && stgy != HUFFMAN_ONLY) - throw new IllegalArgumentException(); - engine.setStrategy(stgy); - } - - /** - * Deflates the current input block to the given array. It returns - * the number of bytes compressed, or 0 if either - * needsInput() or finished() returns true or length is zero. - * @param output the buffer where to write the compressed data. - */ - public int deflate(byte[] output) - { - return deflate(output, 0, output.length); - } - - /** - * Deflates the current input block to the given array. It returns - * the number of bytes compressed, or 0 if either - * needsInput() or finished() returns true or length is zero. - * @param output the buffer where to write the compressed data. - * @param offset the offset into the output array. - * @param length the maximum number of bytes that may be written. - * @exception IllegalStateException if end() was called. - * @exception IndexOutOfBoundsException if offset and/or length - * don't match the array length. - */ - public int deflate(byte[] output, int offset, int length) - { - int origLength = length; - - if (state == CLOSED_STATE) - throw new IllegalStateException("Deflater closed"); - - if (state < BUSY_STATE) - { - /* output header */ - int header = (DEFLATED + - ((DeflaterConstants.MAX_WBITS - 8) << 4)) << 8; - int level_flags = (level - 1) >> 1; - if (level_flags < 0 || level_flags > 3) - level_flags = 3; - header |= level_flags << 6; - if ((state & IS_SETDICT) != 0) - /* Dictionary was set */ - header |= DeflaterConstants.PRESET_DICT; - header += 31 - (header % 31); - - pending.writeShortMSB(header); - if ((state & IS_SETDICT) != 0) - { - int chksum = engine.getAdler(); - engine.resetAdler(); - pending.writeShortMSB(chksum >> 16); - pending.writeShortMSB(chksum & 0xffff); - } - - state = BUSY_STATE | (state & (IS_FLUSHING | IS_FINISHING)); - } - - for (;;) - { - int count = pending.flush(output, offset, length); - offset += count; - totalOut += count; - length -= count; - if (length == 0 || state == FINISHED_STATE) - break; - - if (!engine.deflate((state & IS_FLUSHING) != 0, - (state & IS_FINISHING) != 0)) - { - if (state == BUSY_STATE) - /* We need more input now */ - return origLength - length; - else if (state == FLUSHING_STATE) - { - if (level != NO_COMPRESSION) - { - /* We have to supply some lookahead. 8 bit lookahead - * are needed by the zlib inflater, and we must fill - * the next byte, so that all bits are flushed. - */ - int neededbits = 8 + ((-pending.getBitCount()) & 7); - while (neededbits > 0) - { - /* write a static tree block consisting solely of - * an EOF: - */ - pending.writeBits(2, 10); - neededbits -= 10; - } - } - state = BUSY_STATE; - } - else if (state == FINISHING_STATE) - { - pending.alignToByte(); - /* We have completed the stream */ - if (!noHeader) - { - int adler = engine.getAdler(); - pending.writeShortMSB(adler >> 16); - pending.writeShortMSB(adler & 0xffff); - } - state = FINISHED_STATE; - } - } - } - - return origLength - length; - } - - /** - * Sets the dictionary which should be used in the deflate process. - * This call is equivalent to <code>setDictionary(dict, 0, - * dict.length)</code>. - * @param dict the dictionary. - * @exception IllegalStateException if setInput () or deflate () - * were already called or another dictionary was already set. - */ - public void setDictionary(byte[] dict) - { - setDictionary(dict, 0, dict.length); - } - - /** - * Sets the dictionary which should be used in the deflate process. - * The dictionary should be a byte array containing strings that are - * likely to occur in the data which should be compressed. The - * dictionary is not stored in the compressed output, only a - * checksum. To decompress the output you need to supply the same - * dictionary again. - * @param dict the dictionary. - * @param offset an offset into the dictionary. - * @param length the length of the dictionary. - * @exception IllegalStateException if setInput () or deflate () were - * already called or another dictionary was already set. - */ - public void setDictionary(byte[] dict, int offset, int length) - { - if (state != INIT_STATE) - throw new IllegalStateException(); - - state = SETDICT_STATE; - engine.setDictionary(dict, offset, length); - } -} diff --git a/libjava/classpath/java/util/zip/DeflaterConstants.java b/libjava/classpath/java/util/zip/DeflaterConstants.java deleted file mode 100644 index bfef863..0000000 --- a/libjava/classpath/java/util/zip/DeflaterConstants.java +++ /dev/null @@ -1,78 +0,0 @@ -/* java.util.zip.DeflaterConstants - 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 DeflaterConstants -{ - boolean DEBUGGING = false; - - int STORED_BLOCK = 0; - int STATIC_TREES = 1; - int DYN_TREES = 2; - int PRESET_DICT = 0x20; - - int DEFAULT_MEM_LEVEL = 8; - - int MAX_MATCH = 258; - int MIN_MATCH = 3; - - int MAX_WBITS = 15; - int WSIZE = 1 << MAX_WBITS; - int WMASK = WSIZE - 1; - - int HASH_BITS = DEFAULT_MEM_LEVEL + 7; - int HASH_SIZE = 1 << HASH_BITS; - int HASH_MASK = HASH_SIZE - 1; - int HASH_SHIFT = (HASH_BITS + MIN_MATCH - 1) / MIN_MATCH; - - int MIN_LOOKAHEAD = MAX_MATCH + MIN_MATCH + 1; - int MAX_DIST = WSIZE - MIN_LOOKAHEAD; - - int PENDING_BUF_SIZE = 1 << (DEFAULT_MEM_LEVEL + 8); - int MAX_BLOCK_SIZE = Math.min(65535, PENDING_BUF_SIZE-5); - - int DEFLATE_STORED = 0; - int DEFLATE_FAST = 1; - int DEFLATE_SLOW = 2; - - int GOOD_LENGTH[] = { 0,4, 4, 4, 4, 8, 8, 8, 32, 32 }; - int MAX_LAZY[] = { 0,4, 5, 6, 4,16, 16, 32, 128, 258 }; - int NICE_LENGTH[] = { 0,8,16,32,16,32,128,128, 258, 258 }; - int MAX_CHAIN[] = { 0,4, 8,32,16,32,128,256,1024,4096 }; - int COMPR_FUNC[] = { 0,1, 1, 1, 1, 2, 2, 2, 2, 2 }; -} diff --git a/libjava/classpath/java/util/zip/DeflaterEngine.java b/libjava/classpath/java/util/zip/DeflaterEngine.java deleted file mode 100644 index 287558e..0000000 --- a/libjava/classpath/java/util/zip/DeflaterEngine.java +++ /dev/null @@ -1,698 +0,0 @@ -/* DeflaterEngine.java -- - 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.zip; - -class DeflaterEngine implements DeflaterConstants -{ - private static final int TOO_FAR = 4096; - - private int ins_h; - - /** - * Hashtable, hashing three characters to an index for window, so - * that window[index]..window[index+2] have this hash code. - * Note that the array should really be unsigned short, so you need - * to and the values with 0xffff. - */ - private short[] head; - - /** - * prev[index & WMASK] points to the previous index that has the - * same hash code as the string starting at index. This way - * entries with the same hash code are in a linked list. - * Note that the array should really be unsigned short, so you need - * to and the values with 0xffff. - */ - private short[] prev; - - private int matchStart, matchLen; - private boolean prevAvailable; - private int blockStart; - - /** - * strstart points to the current character in window. - */ - private int strstart; - - /** - * lookahead is the number of characters starting at strstart in - * window that are valid. - * So window[strstart] until window[strstart+lookahead-1] are valid - * characters. - */ - private int lookahead; - - /** - * This array contains the part of the uncompressed stream that - * is of relevance. The current character is indexed by strstart. - */ - private byte[] window; - - private int strategy, max_chain, max_lazy, niceLength, goodLength; - - /** The current compression function. */ - private int comprFunc; - - /** The input data for compression. */ - private byte[] inputBuf; - - /** The total bytes of input read. */ - private long totalIn; - - /** The offset into inputBuf, where input data starts. */ - private int inputOff; - - /** The end offset of the input data. */ - private int inputEnd; - - private DeflaterPending pending; - private DeflaterHuffman huffman; - - /** The adler checksum */ - private Adler32 adler; - - /* DEFLATE ALGORITHM: - * - * The uncompressed stream is inserted into the window array. When - * the window array is full the first half is thrown away and the - * second half is copied to the beginning. - * - * The head array is a hash table. Three characters build a hash value - * and they the value points to the corresponding index in window of - * the last string with this hash. The prev array implements a - * linked list of matches with the same hash: prev[index & WMASK] points - * to the previous index with the same hash. - * - * - */ - - - DeflaterEngine(DeflaterPending pending) { - this.pending = pending; - huffman = new DeflaterHuffman(pending); - adler = new Adler32(); - - window = new byte[2*WSIZE]; - head = new short[HASH_SIZE]; - prev = new short[WSIZE]; - - /* We start at index 1, to avoid a implementation deficiency, that - * we cannot build a repeat pattern at index 0. - */ - blockStart = strstart = 1; - } - - public void reset() - { - huffman.reset(); - adler.reset(); - blockStart = strstart = 1; - lookahead = 0; - totalIn = 0; - prevAvailable = false; - matchLen = MIN_MATCH - 1; - for (int i = 0; i < HASH_SIZE; i++) - head[i] = 0; - for (int i = 0; i < WSIZE; i++) - prev[i] = 0; - } - - public final void resetAdler() - { - adler.reset(); - } - - public final int getAdler() - { - int chksum = (int) adler.getValue(); - return chksum; - } - - public final long getTotalIn() - { - return totalIn; - } - - public final void setStrategy(int strat) - { - strategy = strat; - } - - public void setLevel(int lvl) - { - goodLength = DeflaterConstants.GOOD_LENGTH[lvl]; - max_lazy = DeflaterConstants.MAX_LAZY[lvl]; - niceLength = DeflaterConstants.NICE_LENGTH[lvl]; - max_chain = DeflaterConstants.MAX_CHAIN[lvl]; - - if (DeflaterConstants.COMPR_FUNC[lvl] != comprFunc) - { - if (DeflaterConstants.DEBUGGING) - System.err.println("Change from "+comprFunc +" to " - + DeflaterConstants.COMPR_FUNC[lvl]); - switch (comprFunc) - { - case DEFLATE_STORED: - if (strstart > blockStart) - { - huffman.flushStoredBlock(window, blockStart, - strstart - blockStart, false); - blockStart = strstart; - } - updateHash(); - break; - case DEFLATE_FAST: - if (strstart > blockStart) - { - huffman.flushBlock(window, blockStart, strstart - blockStart, - false); - blockStart = strstart; - } - break; - case DEFLATE_SLOW: - if (prevAvailable) - huffman.tallyLit(window[strstart-1] & 0xff); - if (strstart > blockStart) - { - huffman.flushBlock(window, blockStart, strstart - blockStart, - false); - blockStart = strstart; - } - prevAvailable = false; - matchLen = MIN_MATCH - 1; - break; - } - comprFunc = COMPR_FUNC[lvl]; - } - } - - private void updateHash() { - if (DEBUGGING) - System.err.println("updateHash: "+strstart); - ins_h = (window[strstart] << HASH_SHIFT) ^ window[strstart + 1]; - } - - /** - * Inserts the current string in the head hash and returns the previous - * value for this hash. - */ - private int insertString() { - short match; - int hash = ((ins_h << HASH_SHIFT) ^ window[strstart + (MIN_MATCH -1)]) - & HASH_MASK; - - if (DEBUGGING) - { - if (hash != (((window[strstart] << (2*HASH_SHIFT)) - ^ (window[strstart + 1] << HASH_SHIFT) - ^ (window[strstart + 2])) & HASH_MASK)) - throw new InternalError("hash inconsistent: "+hash+"/" - +window[strstart]+"," - +window[strstart+1]+"," - +window[strstart+2]+","+HASH_SHIFT); - } - - prev[strstart & WMASK] = match = head[hash]; - head[hash] = (short) strstart; - ins_h = hash; - return match & 0xffff; - } - - private void slideWindow() - { - System.arraycopy(window, WSIZE, window, 0, WSIZE); - matchStart -= WSIZE; - strstart -= WSIZE; - blockStart -= WSIZE; - - /* Slide the hash table (could be avoided with 32 bit values - * at the expense of memory usage). - */ - for (int i = 0; i < HASH_SIZE; i++) - { - int m = head[i] & 0xffff; - head[i] = m >= WSIZE ? (short) (m - WSIZE) : 0; - } - - /* Slide the prev table. - */ - for (int i = 0; i < WSIZE; i++) - { - int m = prev[i] & 0xffff; - prev[i] = m >= WSIZE ? (short) (m - WSIZE) : 0; - } - } - - /** - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * OUT assertions: strstart + lookahead <= 2*WSIZE - * lookahead >= MIN_LOOKAHEAD or inputOff == inputEnd - */ - private void fillWindow() - { - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (strstart >= WSIZE + MAX_DIST) - slideWindow(); - - /* If there is not enough lookahead, but still some input left, - * read in the input - */ - while (lookahead < DeflaterConstants.MIN_LOOKAHEAD && inputOff < inputEnd) - { - int more = 2*WSIZE - lookahead - strstart; - - if (more > inputEnd - inputOff) - more = inputEnd - inputOff; - - System.arraycopy(inputBuf, inputOff, - window, strstart + lookahead, more); - adler.update(inputBuf, inputOff, more); - inputOff += more; - totalIn += more; - lookahead += more; - } - - if (lookahead >= MIN_MATCH) - updateHash(); - } - - /** - * Find the best (longest) string in the window matching the - * string starting at strstart. - * - * Preconditions: - * strstart + MAX_MATCH <= window.length. - * - * - * @param curMatch - */ - private boolean findLongestMatch(int curMatch) { - int chainLength = this.max_chain; - int niceLength = this.niceLength; - short[] prev = this.prev; - int scan = this.strstart; - int match; - int best_end = this.strstart + matchLen; - int best_len = Math.max(matchLen, MIN_MATCH - 1); - - int limit = Math.max(strstart - MAX_DIST, 0); - - int strend = scan + MAX_MATCH - 1; - byte scan_end1 = window[best_end - 1]; - byte scan_end = window[best_end]; - - /* Do not waste too much time if we already have a good match: */ - if (best_len >= this.goodLength) - chainLength >>= 2; - - /* Do not look for matches beyond the end of the input. This is necessary - * to make deflate deterministic. - */ - if (niceLength > lookahead) - niceLength = lookahead; - - if (DeflaterConstants.DEBUGGING - && strstart > 2*WSIZE - MIN_LOOKAHEAD) - throw new InternalError("need lookahead"); - - do { - if (DeflaterConstants.DEBUGGING && curMatch >= strstart) - throw new InternalError("future match"); - if (window[curMatch + best_len] != scan_end - || window[curMatch + best_len - 1] != scan_end1 - || window[curMatch] != window[scan] - || window[curMatch+1] != window[scan + 1]) - continue; - - match = curMatch + 2; - scan += 2; - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - while (window[++scan] == window[++match] - && window[++scan] == window[++match] - && window[++scan] == window[++match] - && window[++scan] == window[++match] - && window[++scan] == window[++match] - && window[++scan] == window[++match] - && window[++scan] == window[++match] - && window[++scan] == window[++match] - && scan < strend) - ; - - if (scan > best_end) { -// if (DeflaterConstants.DEBUGGING && ins_h == 0) -// System.err.println("Found match: "+curMatch+"-"+(scan-strstart)); - matchStart = curMatch; - best_end = scan; - best_len = scan - strstart; - if (best_len >= niceLength) - break; - - scan_end1 = window[best_end-1]; - scan_end = window[best_end]; - } - scan = strstart; - } while ((curMatch = (prev[curMatch & WMASK] & 0xffff)) > limit - && --chainLength != 0); - - matchLen = Math.min(best_len, lookahead); - return matchLen >= MIN_MATCH; - } - - void setDictionary(byte[] buffer, int offset, int length) { - if (DeflaterConstants.DEBUGGING && strstart != 1) - throw new IllegalStateException("strstart not 1"); - adler.update(buffer, offset, length); - if (length < MIN_MATCH) - return; - if (length > MAX_DIST) { - offset += length - MAX_DIST; - length = MAX_DIST; - } - - System.arraycopy(buffer, offset, window, strstart, length); - - updateHash(); - length--; - while (--length > 0) - { - insertString(); - strstart++; - } - strstart += 2; - blockStart = strstart; - } - - private boolean deflateStored(boolean flush, boolean finish) - { - if (!flush && lookahead == 0) - return false; - - strstart += lookahead; - lookahead = 0; - - int storedLen = strstart - blockStart; - - if ((storedLen >= DeflaterConstants.MAX_BLOCK_SIZE) - /* Block is full */ - || (blockStart < WSIZE && storedLen >= MAX_DIST) - /* Block may move out of window */ - || flush) - { - boolean lastBlock = finish; - if (storedLen > DeflaterConstants.MAX_BLOCK_SIZE) - { - storedLen = DeflaterConstants.MAX_BLOCK_SIZE; - lastBlock = false; - } - - if (DeflaterConstants.DEBUGGING) - System.err.println("storedBlock["+storedLen+","+lastBlock+"]"); - - huffman.flushStoredBlock(window, blockStart, storedLen, lastBlock); - blockStart += storedLen; - return !lastBlock; - } - return true; - } - - private boolean deflateFast(boolean flush, boolean finish) - { - if (lookahead < MIN_LOOKAHEAD && !flush) - return false; - - while (lookahead >= MIN_LOOKAHEAD || flush) - { - if (lookahead == 0) - { - /* We are flushing everything */ - huffman.flushBlock(window, blockStart, strstart - blockStart, - finish); - blockStart = strstart; - return false; - } - - if (strstart > 2 * WSIZE - MIN_LOOKAHEAD) - { - /* slide window, as findLongestMatch need this. - * This should only happen when flushing and the window - * is almost full. - */ - slideWindow(); - } - - int hashHead; - if (lookahead >= MIN_MATCH - && (hashHead = insertString()) != 0 - && strategy != Deflater.HUFFMAN_ONLY - && strstart - hashHead <= MAX_DIST - && findLongestMatch(hashHead)) - { - /* longestMatch sets matchStart and matchLen */ - if (DeflaterConstants.DEBUGGING) - { - for (int i = 0 ; i < matchLen; i++) - { - if (window[strstart+i] != window[matchStart + i]) - throw new InternalError(); - } - } - boolean full = huffman.tallyDist(strstart - matchStart, matchLen); - - lookahead -= matchLen; - if (matchLen <= max_lazy && lookahead >= MIN_MATCH) - { - while (--matchLen > 0) - { - strstart++; - insertString(); - } - strstart++; - } - else - { - strstart += matchLen; - if (lookahead >= MIN_MATCH - 1) - updateHash(); - } - matchLen = MIN_MATCH - 1; - if (!full) - continue; - } - else - { - /* No match found */ - huffman.tallyLit(window[strstart] & 0xff); - strstart++; - lookahead--; - } - - if (huffman.isFull()) - { - boolean lastBlock = finish && lookahead == 0; - huffman.flushBlock(window, blockStart, strstart - blockStart, - lastBlock); - blockStart = strstart; - return !lastBlock; - } - } - return true; - } - - private boolean deflateSlow(boolean flush, boolean finish) - { - if (lookahead < MIN_LOOKAHEAD && !flush) - return false; - - while (lookahead >= MIN_LOOKAHEAD || flush) - { - if (lookahead == 0) - { - if (prevAvailable) - huffman.tallyLit(window[strstart-1] & 0xff); - prevAvailable = false; - - /* We are flushing everything */ - if (DeflaterConstants.DEBUGGING && !flush) - throw new InternalError("Not flushing, but no lookahead"); - huffman.flushBlock(window, blockStart, strstart - blockStart, - finish); - blockStart = strstart; - return false; - } - - if (strstart >= 2 * WSIZE - MIN_LOOKAHEAD) - { - /* slide window, as findLongestMatch need this. - * This should only happen when flushing and the window - * is almost full. - */ - slideWindow(); - } - - int prevMatch = matchStart; - int prevLen = matchLen; - if (lookahead >= MIN_MATCH) - { - int hashHead = insertString(); - if (strategy != Deflater.HUFFMAN_ONLY - && hashHead != 0 && strstart - hashHead <= MAX_DIST - && findLongestMatch(hashHead)) - { - /* longestMatch sets matchStart and matchLen */ - - /* Discard match if too small and too far away */ - if (matchLen <= 5 - && (strategy == Deflater.FILTERED - || (matchLen == MIN_MATCH - && strstart - matchStart > TOO_FAR))) { - matchLen = MIN_MATCH - 1; - } - } - } - - /* previous match was better */ - if (prevLen >= MIN_MATCH && matchLen <= prevLen) - { - if (DeflaterConstants.DEBUGGING) - { - for (int i = 0 ; i < matchLen; i++) - { - if (window[strstart-1+i] != window[prevMatch + i]) - throw new InternalError(); - } - } - huffman.tallyDist(strstart - 1 - prevMatch, prevLen); - prevLen -= 2; - do - { - strstart++; - lookahead--; - if (lookahead >= MIN_MATCH) - insertString(); - } - while (--prevLen > 0); - strstart ++; - lookahead--; - prevAvailable = false; - matchLen = MIN_MATCH - 1; - } - else - { - if (prevAvailable) - huffman.tallyLit(window[strstart-1] & 0xff); - prevAvailable = true; - strstart++; - lookahead--; - } - - if (huffman.isFull()) - { - int len = strstart - blockStart; - if (prevAvailable) - len--; - boolean lastBlock = (finish && lookahead == 0 && !prevAvailable); - huffman.flushBlock(window, blockStart, len, lastBlock); - blockStart += len; - return !lastBlock; - } - } - return true; - } - - public boolean deflate(boolean flush, boolean finish) - { - boolean progress; - do - { - fillWindow(); - boolean canFlush = flush && inputOff == inputEnd; - if (DeflaterConstants.DEBUGGING) - System.err.println("window: ["+blockStart+","+strstart+"," - +lookahead+"], "+comprFunc+","+canFlush); - switch (comprFunc) - { - case DEFLATE_STORED: - progress = deflateStored(canFlush, finish); - break; - case DEFLATE_FAST: - progress = deflateFast(canFlush, finish); - break; - case DEFLATE_SLOW: - progress = deflateSlow(canFlush, finish); - break; - default: - throw new InternalError(); - } - } - while (pending.isFlushed() /* repeat while we have no pending output */ - && progress); /* and progress was made */ - - return progress; - } - - public void setInput(byte[] buf, int off, int len) - { - if (inputOff < inputEnd) - throw new IllegalStateException - ("Old input was not completely processed"); - - int end = off + len; - - /* We want to throw an ArrayIndexOutOfBoundsException early. The - * check is very tricky: it also handles integer wrap around. - */ - if (0 > off || off > end || end > buf.length) - throw new ArrayIndexOutOfBoundsException(); - - inputBuf = buf; - inputOff = off; - inputEnd = end; - } - - public final boolean needsInput() - { - return inputEnd == inputOff; - } -} diff --git a/libjava/classpath/java/util/zip/DeflaterHuffman.java b/libjava/classpath/java/util/zip/DeflaterHuffman.java deleted file mode 100644 index 8da987e0..0000000 --- a/libjava/classpath/java/util/zip/DeflaterHuffman.java +++ /dev/null @@ -1,776 +0,0 @@ -/* DeflaterHuffman.java -- - 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.zip; - -/** - * This is the DeflaterHuffman class. - * - * This class is <i>not</i> thread safe. This is inherent in the API, due - * to the split of deflate and setInput. - * - * @author Jochen Hoenicke - * @date Jan 6, 2000 - */ -class DeflaterHuffman -{ - private static final int BUFSIZE = 1 << (DeflaterConstants.DEFAULT_MEM_LEVEL + 6); - private static final int LITERAL_NUM = 286; - private static final int DIST_NUM = 30; - private static final int BITLEN_NUM = 19; - private static final int REP_3_6 = 16; - private static final int REP_3_10 = 17; - private static final int REP_11_138 = 18; - private static final int EOF_SYMBOL = 256; - private static final int[] BL_ORDER = - { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; - - private static final String bit4Reverse = - "\000\010\004\014\002\012\006\016\001\011\005\015\003\013\007\017"; - - class Tree { - short[] freqs; - short[] codes; - byte[] length; - int[] bl_counts; - int minNumCodes, numCodes; - int maxLength; - - Tree(int elems, int minCodes, int maxLength) { - this.minNumCodes = minCodes; - this.maxLength = maxLength; - freqs = new short[elems]; - bl_counts = new int[maxLength]; - } - - void reset() { - for (int i = 0; i < freqs.length; i++) - freqs[i] = 0; - codes = null; - length = null; - } - - final void writeSymbol(int code) - { - if (DeflaterConstants.DEBUGGING) - { - freqs[code]--; -// System.err.print("writeSymbol("+freqs.length+","+code+"): "); - } - pending.writeBits(codes[code] & 0xffff, length[code]); - } - - final void checkEmpty() - { - boolean empty = true; - for (int i = 0; i < freqs.length; i++) - if (freqs[i] != 0) - { - System.err.println("freqs["+i+"] == "+freqs[i]); - empty = false; - } - if (!empty) - throw new InternalError(); - System.err.println("checkEmpty suceeded!"); - } - - void setStaticCodes(short[] stCodes, byte[] stLength) - { - codes = stCodes; - length = stLength; - } - - public void buildCodes() { - int[] nextCode = new int[maxLength]; - int code = 0; - codes = new short[freqs.length]; - - if (DeflaterConstants.DEBUGGING) - System.err.println("buildCodes: "+freqs.length); - for (int bits = 0; bits < maxLength; bits++) - { - nextCode[bits] = code; - code += bl_counts[bits] << (15 - bits); - if (DeflaterConstants.DEBUGGING) - System.err.println("bits: "+(bits+1)+" count: "+bl_counts[bits] - +" nextCode: "+Integer.toHexString(code)); - } - if (DeflaterConstants.DEBUGGING && code != 65536) - throw new RuntimeException("Inconsistent bl_counts!"); - - for (int i=0; i < numCodes; i++) - { - int bits = length[i]; - if (bits > 0) - { - if (DeflaterConstants.DEBUGGING) - System.err.println("codes["+i+"] = rev(" - +Integer.toHexString(nextCode[bits-1])+")," - +bits); - codes[i] = bitReverse(nextCode[bits-1]); - nextCode[bits-1] += 1 << (16 - bits); - } - } - } - - private void buildLength(int childs[]) - { - this.length = new byte [freqs.length]; - int numNodes = childs.length / 2; - int numLeafs = (numNodes + 1) / 2; - int overflow = 0; - - for (int i = 0; i < maxLength; i++) - bl_counts[i] = 0; - - /* First calculate optimal bit lengths */ - int lengths[] = new int[numNodes]; - lengths[numNodes-1] = 0; - for (int i = numNodes - 1; i >= 0; i--) - { - if (childs[2*i+1] != -1) - { - int bitLength = lengths[i] + 1; - if (bitLength > maxLength) - { - bitLength = maxLength; - overflow++; - } - lengths[childs[2*i]] = lengths[childs[2*i+1]] = bitLength; - } - else - { - /* A leaf node */ - int bitLength = lengths[i]; - bl_counts[bitLength - 1]++; - this.length[childs[2*i]] = (byte) lengths[i]; - } - } - - if (DeflaterConstants.DEBUGGING) - { - System.err.println("Tree "+freqs.length+" lengths:"); - for (int i=0; i < numLeafs; i++) - System.err.println("Node "+childs[2*i]+" freq: "+freqs[childs[2*i]] - + " len: "+length[childs[2*i]]); - } - - if (overflow == 0) - return; - - int incrBitLen = maxLength - 1; - do - { - /* Find the first bit length which could increase: */ - while (bl_counts[--incrBitLen] == 0) - ; - - /* Move this node one down and remove a corresponding - * amount of overflow nodes. - */ - do - { - bl_counts[incrBitLen]--; - bl_counts[++incrBitLen]++; - overflow -= 1 << (maxLength - 1 - incrBitLen); - } - while (overflow > 0 && incrBitLen < maxLength - 1); - } - while (overflow > 0); - - /* We may have overshot above. Move some nodes from maxLength to - * maxLength-1 in that case. - */ - bl_counts[maxLength-1] += overflow; - bl_counts[maxLength-2] -= overflow; - - /* Now recompute all bit lengths, scanning in increasing - * frequency. It is simpler to reconstruct all lengths instead of - * fixing only the wrong ones. This idea is taken from 'ar' - * written by Haruhiko Okumura. - * - * The nodes were inserted with decreasing frequency into the childs - * array. - */ - int nodePtr = 2 * numLeafs; - for (int bits = maxLength; bits != 0; bits--) - { - int n = bl_counts[bits-1]; - while (n > 0) - { - int childPtr = 2*childs[nodePtr++]; - if (childs[childPtr + 1] == -1) - { - /* We found another leaf */ - length[childs[childPtr]] = (byte) bits; - n--; - } - } - } - if (DeflaterConstants.DEBUGGING) - { - System.err.println("*** After overflow elimination. ***"); - for (int i=0; i < numLeafs; i++) - System.err.println("Node "+childs[2*i]+" freq: "+freqs[childs[2*i]] - + " len: "+length[childs[2*i]]); - } - } - - void buildTree() - { - int numSymbols = freqs.length; - - /* heap is a priority queue, sorted by frequency, least frequent - * nodes first. The heap is a binary tree, with the property, that - * the parent node is smaller than both child nodes. This assures - * that the smallest node is the first parent. - * - * The binary tree is encoded in an array: 0 is root node and - * the nodes 2*n+1, 2*n+2 are the child nodes of node n. - */ - int[] heap = new int[numSymbols]; - int heapLen = 0; - int maxCode = 0; - for (int n = 0; n < numSymbols; n++) - { - int freq = freqs[n]; - if (freq != 0) - { - /* Insert n into heap */ - int pos = heapLen++; - int ppos; - while (pos > 0 && - freqs[heap[ppos = (pos - 1) / 2]] > freq) { - heap[pos] = heap[ppos]; - pos = ppos; - } - heap[pos] = n; - maxCode = n; - } - } - - /* We could encode a single literal with 0 bits but then we - * don't see the literals. Therefore we force at least two - * literals to avoid this case. We don't care about order in - * this case, both literals get a 1 bit code. - */ - while (heapLen < 2) - { - int node = maxCode < 2 ? ++maxCode : 0; - heap[heapLen++] = node; - } - - numCodes = Math.max(maxCode + 1, minNumCodes); - - int numLeafs = heapLen; - int[] childs = new int[4*heapLen - 2]; - int[] values = new int[2*heapLen - 1]; - int numNodes = numLeafs; - for (int i = 0; i < heapLen; i++) - { - int node = heap[i]; - childs[2*i] = node; - childs[2*i+1] = -1; - values[i] = freqs[node] << 8; - heap[i] = i; - } - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - do - { - int first = heap[0]; - int last = heap[--heapLen]; - - /* Propagate the hole to the leafs of the heap */ - int ppos = 0; - int path = 1; - while (path < heapLen) - { - if (path + 1 < heapLen - && values[heap[path]] > values[heap[path+1]]) - path++; - - heap[ppos] = heap[path]; - ppos = path; - path = path * 2 + 1; - } - - /* Now propagate the last element down along path. Normally - * it shouldn't go too deep. - */ - int lastVal = values[last]; - while ((path = ppos) > 0 - && values[heap[ppos = (path - 1)/2]] > lastVal) - heap[path] = heap[ppos]; - heap[path] = last; - - - int second = heap[0]; - - /* Create a new node father of first and second */ - last = numNodes++; - childs[2*last] = first; - childs[2*last+1] = second; - int mindepth = Math.min(values[first] & 0xff, values[second] & 0xff); - values[last] = lastVal = values[first] + values[second] - mindepth + 1; - - /* Again, propagate the hole to the leafs */ - ppos = 0; - path = 1; - while (path < heapLen) - { - if (path + 1 < heapLen - && values[heap[path]] > values[heap[path+1]]) - path++; - - heap[ppos] = heap[path]; - ppos = path; - path = ppos * 2 + 1; - } - - /* Now propagate the new element down along path */ - while ((path = ppos) > 0 - && values[heap[ppos = (path - 1)/2]] > lastVal) - heap[path] = heap[ppos]; - heap[path] = last; - } - while (heapLen > 1); - - if (heap[0] != childs.length / 2 - 1) - throw new RuntimeException("Weird!"); - - buildLength(childs); - } - - int getEncodedLength() - { - int len = 0; - for (int i = 0; i < freqs.length; i++) - len += freqs[i] * length[i]; - return len; - } - - void calcBLFreq(Tree blTree) { - int max_count; /* max repeat count */ - int min_count; /* min repeat count */ - int count; /* repeat count of the current code */ - int curlen = -1; /* length of current code */ - - int i = 0; - while (i < numCodes) - { - count = 1; - int nextlen = length[i]; - if (nextlen == 0) - { - max_count = 138; - min_count = 3; - } - else - { - max_count = 6; - min_count = 3; - if (curlen != nextlen) - { - blTree.freqs[nextlen]++; - count = 0; - } - } - curlen = nextlen; - i++; - - while (i < numCodes && curlen == length[i]) - { - i++; - if (++count >= max_count) - break; - } - - if (count < min_count) - blTree.freqs[curlen] += count; - else if (curlen != 0) - blTree.freqs[REP_3_6]++; - else if (count <= 10) - blTree.freqs[REP_3_10]++; - else - blTree.freqs[REP_11_138]++; - } - } - - void writeTree(Tree blTree) - { - int max_count; /* max repeat count */ - int min_count; /* min repeat count */ - int count; /* repeat count of the current code */ - int curlen = -1; /* length of current code */ - - int i = 0; - while (i < numCodes) - { - count = 1; - int nextlen = length[i]; - if (nextlen == 0) - { - max_count = 138; - min_count = 3; - } - else - { - max_count = 6; - min_count = 3; - if (curlen != nextlen) - { - blTree.writeSymbol(nextlen); - count = 0; - } - } - curlen = nextlen; - i++; - - while (i < numCodes && curlen == length[i]) - { - i++; - if (++count >= max_count) - break; - } - - if (count < min_count) - { - while (count-- > 0) - blTree.writeSymbol(curlen); - } - else if (curlen != 0) - { - blTree.writeSymbol(REP_3_6); - pending.writeBits(count - 3, 2); - } - else if (count <= 10) - { - blTree.writeSymbol(REP_3_10); - pending.writeBits(count - 3, 3); - } - else - { - blTree.writeSymbol(REP_11_138); - pending.writeBits(count - 11, 7); - } - } - } - } - - - - DeflaterPending pending; - private Tree literalTree, distTree, blTree; - - private short d_buf[]; - private byte l_buf[]; - private int last_lit; - private int extra_bits; - - private static short staticLCodes[]; - private static byte staticLLength[]; - private static short staticDCodes[]; - private static byte staticDLength[]; - - /** - * Reverse the bits of a 16 bit value. - */ - static short bitReverse(int value) { - return (short) (bit4Reverse.charAt(value & 0xf) << 12 - | bit4Reverse.charAt((value >> 4) & 0xf) << 8 - | bit4Reverse.charAt((value >> 8) & 0xf) << 4 - | bit4Reverse.charAt(value >> 12)); - } - - static { - /* See RFC 1951 3.2.6 */ - /* Literal codes */ - staticLCodes = new short[LITERAL_NUM]; - staticLLength = new byte[LITERAL_NUM]; - int i = 0; - while (i < 144) { - staticLCodes[i] = bitReverse((0x030 + i) << 8); - staticLLength[i++] = 8; - } - while (i < 256) { - staticLCodes[i] = bitReverse((0x190 - 144 + i) << 7); - staticLLength[i++] = 9; - } - while (i < 280) { - staticLCodes[i] = bitReverse((0x000 - 256 + i) << 9); - staticLLength[i++] = 7; - } - while (i < LITERAL_NUM) { - staticLCodes[i] = bitReverse((0x0c0 - 280 + i) << 8); - staticLLength[i++] = 8; - } - - /* Distant codes */ - staticDCodes = new short[DIST_NUM]; - staticDLength = new byte[DIST_NUM]; - for (i = 0; i < DIST_NUM; i++) { - staticDCodes[i] = bitReverse(i << 11); - staticDLength[i] = 5; - } - } - - public DeflaterHuffman(DeflaterPending pending) - { - this.pending = pending; - - literalTree = new Tree(LITERAL_NUM, 257, 15); - distTree = new Tree(DIST_NUM, 1, 15); - blTree = new Tree(BITLEN_NUM, 4, 7); - - d_buf = new short[BUFSIZE]; - l_buf = new byte [BUFSIZE]; - } - - public final void reset() { - last_lit = 0; - extra_bits = 0; - literalTree.reset(); - distTree.reset(); - blTree.reset(); - } - - private int l_code(int len) { - if (len == 255) - return 285; - - int code = 257; - while (len >= 8) - { - code += 4; - len >>= 1; - } - return code + len; - } - - private int d_code(int distance) { - int code = 0; - while (distance >= 4) - { - code += 2; - distance >>= 1; - } - return code + distance; - } - - public void sendAllTrees(int blTreeCodes) { - blTree.buildCodes(); - literalTree.buildCodes(); - distTree.buildCodes(); - pending.writeBits(literalTree.numCodes - 257, 5); - pending.writeBits(distTree.numCodes - 1, 5); - pending.writeBits(blTreeCodes - 4, 4); - for (int rank = 0; rank < blTreeCodes; rank++) - pending.writeBits(blTree.length[BL_ORDER[rank]], 3); - literalTree.writeTree(blTree); - distTree.writeTree(blTree); - if (DeflaterConstants.DEBUGGING) - blTree.checkEmpty(); - } - - public void compressBlock() { - for (int i = 0; i < last_lit; i++) - { - int litlen = l_buf[i] & 0xff; - int dist = d_buf[i]; - if (dist-- != 0) - { - if (DeflaterConstants.DEBUGGING) - System.err.print("["+(dist+1)+","+(litlen+3)+"]: "); - - int lc = l_code(litlen); - literalTree.writeSymbol(lc); - - int bits = (lc - 261) / 4; - if (bits > 0 && bits <= 5) - pending.writeBits(litlen & ((1 << bits) - 1), bits); - - int dc = d_code(dist); - distTree.writeSymbol(dc); - - bits = dc / 2 - 1; - if (bits > 0) - pending.writeBits(dist & ((1 << bits) - 1), bits); - } - else - { - if (DeflaterConstants.DEBUGGING) - { - if (litlen > 32 && litlen < 127) - System.err.print("("+(char)litlen+"): "); - else - System.err.print("{"+litlen+"}: "); - } - literalTree.writeSymbol(litlen); - } - } - if (DeflaterConstants.DEBUGGING) - System.err.print("EOF: "); - literalTree.writeSymbol(EOF_SYMBOL); - if (DeflaterConstants.DEBUGGING) - { - literalTree.checkEmpty(); - distTree.checkEmpty(); - } - } - - public void flushStoredBlock(byte[] stored, - int stored_offset, int stored_len, - boolean lastBlock) { - if (DeflaterConstants.DEBUGGING) - System.err.println("Flushing stored block "+ stored_len); - pending.writeBits((DeflaterConstants.STORED_BLOCK << 1) - + (lastBlock ? 1 : 0), 3); - pending.alignToByte(); - pending.writeShort(stored_len); - pending.writeShort(~stored_len); - pending.writeBlock(stored, stored_offset, stored_len); - reset(); - } - - public void flushBlock(byte[] stored, int stored_offset, int stored_len, - boolean lastBlock) { - literalTree.freqs[EOF_SYMBOL]++; - - /* Build trees */ - literalTree.buildTree(); - distTree.buildTree(); - - /* Calculate bitlen frequency */ - literalTree.calcBLFreq(blTree); - distTree.calcBLFreq(blTree); - - /* Build bitlen tree */ - blTree.buildTree(); - - int blTreeCodes = 4; - for (int i = 18; i > blTreeCodes; i--) - { - if (blTree.length[BL_ORDER[i]] > 0) - blTreeCodes = i+1; - } - int opt_len = 14 + blTreeCodes * 3 + blTree.getEncodedLength() - + literalTree.getEncodedLength() + distTree.getEncodedLength() - + extra_bits; - - int static_len = extra_bits; - for (int i = 0; i < LITERAL_NUM; i++) - static_len += literalTree.freqs[i] * staticLLength[i]; - for (int i = 0; i < DIST_NUM; i++) - static_len += distTree.freqs[i] * staticDLength[i]; - if (opt_len >= static_len) - { - /* Force static trees */ - opt_len = static_len; - } - - if (stored_offset >= 0 && stored_len+4 < opt_len >> 3) - { - /* Store Block */ - if (DeflaterConstants.DEBUGGING) - System.err.println("Storing, since " + stored_len + " < " + opt_len - + " <= " + static_len); - flushStoredBlock(stored, stored_offset, stored_len, lastBlock); - } - else if (opt_len == static_len) - { - /* Encode with static tree */ - pending.writeBits((DeflaterConstants.STATIC_TREES << 1) - + (lastBlock ? 1 : 0), 3); - literalTree.setStaticCodes(staticLCodes, staticLLength); - distTree.setStaticCodes(staticDCodes, staticDLength); - compressBlock(); - reset(); - } - else - { - /* Encode with dynamic tree */ - pending.writeBits((DeflaterConstants.DYN_TREES << 1) - + (lastBlock ? 1 : 0), 3); - sendAllTrees(blTreeCodes); - compressBlock(); - reset(); - } - } - - public final boolean isFull() - { - return last_lit == BUFSIZE; - } - - public final boolean tallyLit(int lit) - { - if (DeflaterConstants.DEBUGGING) - { - if (lit > 32 && lit < 127) - System.err.println("("+(char)lit+")"); - else - System.err.println("{"+lit+"}"); - } - d_buf[last_lit] = 0; - l_buf[last_lit++] = (byte) lit; - literalTree.freqs[lit]++; - return last_lit == BUFSIZE; - } - - public final boolean tallyDist(int dist, int len) - { - if (DeflaterConstants.DEBUGGING) - System.err.println("["+dist+","+len+"]"); - - d_buf[last_lit] = (short) dist; - l_buf[last_lit++] = (byte) (len - 3); - - int lc = l_code(len-3); - literalTree.freqs[lc]++; - if (lc >= 265 && lc < 285) - extra_bits += (lc - 261) / 4; - - int dc = d_code(dist-1); - distTree.freqs[dc]++; - if (dc >= 4) - extra_bits += dc / 2 - 1; - return last_lit == BUFSIZE; - } -} diff --git a/libjava/classpath/java/util/zip/DeflaterOutputStream.java b/libjava/classpath/java/util/zip/DeflaterOutputStream.java deleted file mode 100644 index 6fd1c5c..0000000 --- a/libjava/classpath/java/util/zip/DeflaterOutputStream.java +++ /dev/null @@ -1,198 +0,0 @@ -/* DeflaterOutputStream.java - Output filter for compressing. - 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.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. - */ - -/** - * This is a special FilterOutputStream deflating the bytes that are - * written through it. It uses the Deflater for deflating. - * - * A special thing to be noted is that flush() doesn't flush - * everything in Sun's JDK, but it does so in jazzlib. This is because - * Sun's Deflater doesn't have a way to flush() everything, without - * finishing the stream. - * - * @author Tom Tromey, Jochen Hoenicke - * @date Jan 11, 2001 - */ -public class DeflaterOutputStream extends FilterOutputStream -{ - /** - * This buffer is used temporarily to retrieve the bytes from the - * deflater and write them to the underlying output stream. - */ - protected byte[] buf; - - /** - * The deflater which is used to deflate the stream. - */ - protected Deflater def; - - /** - * Deflates everything in the def's input buffers. This will call - * <code>def.deflate()</code> until all bytes from the input buffers - * are processed. - */ - protected void deflate() throws IOException - { - while (! def.needsInput()) - { - int len = def.deflate(buf, 0, buf.length); - - // System.err.println("DOS deflated " + len + " out of " + buf.length); - if (len <= 0) - break; - out.write(buf, 0, len); - } - - if (! def.needsInput()) - throw new InternalError("Can't deflate all input?"); - } - - /** - * Creates a new DeflaterOutputStream with a default Deflater and - * default buffer size. - * @param out the output stream where deflated output should be written. - */ - public DeflaterOutputStream(OutputStream out) - { - this(out, new Deflater(), 4096); - } - - /** - * Creates a new DeflaterOutputStream with the given Deflater and - * default buffer size. - * @param out the output stream where deflated output should be written. - * @param defl the underlying deflater. - */ - public DeflaterOutputStream(OutputStream out, Deflater defl) - { - this(out, defl, 4096); - } - - /** - * Creates a new DeflaterOutputStream with the given Deflater and - * buffer size. - * @param out the output stream where deflated output should be written. - * @param defl the underlying deflater. - * @param bufsize the buffer size. - * @exception IllegalArgumentException if bufsize isn't positive. - */ - public DeflaterOutputStream(OutputStream out, Deflater defl, int bufsize) - { - super(out); - if (bufsize <= 0) - throw new IllegalArgumentException("bufsize <= 0"); - buf = new byte[bufsize]; - def = defl; - } - - /** - * Flushes the stream by calling flush() on the deflater and then - * on the underlying stream. This ensures that all bytes are - * flushed. This function doesn't work in Sun's JDK, but only in - * jazzlib. - */ - public void flush() throws IOException - { - def.flush(); - deflate(); - out.flush(); - } - - /** - * Finishes the stream by calling finish() on the deflater. This - * was the only way to ensure that all bytes are flushed in Sun's - * JDK. - */ - public void finish() throws IOException - { - def.finish(); - while (! def.finished()) - { - int len = def.deflate(buf, 0, buf.length); - if (len <= 0) - break; - out.write(buf, 0, len); - } - if (! def.finished()) - throw new InternalError("Can't deflate all input?"); - out.flush(); - } - - /** - * Calls finish() and closes the stream. - */ - public void close() throws IOException - { - finish(); - out.close(); - } - - /** - * Writes a single byte to the compressed output stream. - * @param bval the byte value. - */ - public void write(int bval) throws IOException - { - byte[] b = new byte[1]; - b[0] = (byte) bval; - write(b, 0, 1); - } - - /** - * Writes a len bytes from an array to the compressed stream. - * @param buf the byte array. - * @param off the offset into the byte array where to start. - * @param len the number of bytes to write. - */ - public void write(byte[] buf, int off, int len) throws IOException - { - def.setInput(buf, off, len); - deflate(); - } -} diff --git a/libjava/classpath/java/util/zip/DeflaterPending.java b/libjava/classpath/java/util/zip/DeflaterPending.java deleted file mode 100644 index fabc226..0000000 --- a/libjava/classpath/java/util/zip/DeflaterPending.java +++ /dev/null @@ -1,53 +0,0 @@ -/* java.util.zip.DeflaterPending - 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; - -/** - * This class stores the pending output of the Deflater. - * - * @author Jochen Hoenicke - * @date Jan 5, 2000 - */ - -class DeflaterPending extends PendingBuffer -{ - public DeflaterPending() - { - super(DeflaterConstants.PENDING_BUF_SIZE); - } -} diff --git a/libjava/classpath/java/util/zip/GZIPInputStream.java b/libjava/classpath/java/util/zip/GZIPInputStream.java deleted file mode 100644 index ed99ee9..0000000 --- a/libjava/classpath/java/util/zip/GZIPInputStream.java +++ /dev/null @@ -1,355 +0,0 @@ -/* GZIPInputStream.java - Input filter for reading gzip file - Copyright (C) 1999, 2000, 2001, 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.zip; - -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; - -/** - * This filter stream is used to decompress a "GZIP" format stream. - * The "GZIP" format is described in RFC 1952. - * - * @author John Leuner - * @author Tom Tromey - * @since JDK 1.1 - */ -public class GZIPInputStream - extends InflaterInputStream -{ - /** - * The magic number found at the start of a GZIP stream. - */ - public static final int GZIP_MAGIC = 0x8b1f; - - /** - * The mask for bit 0 of the flag byte. - */ - static final int FTEXT = 0x1; - - /** - * The mask for bit 1 of the flag byte. - */ - static final int FHCRC = 0x2; - - /** - * The mask for bit 2 of the flag byte. - */ - static final int FEXTRA = 0x4; - - /** - * The mask for bit 3 of the flag byte. - */ - static final int FNAME = 0x8; - - /** - * The mask for bit 4 of the flag byte. - */ - static final int FCOMMENT = 0x10; - - /** - * The CRC-32 checksum value for uncompressed data. - */ - protected CRC32 crc; - - /** - * Indicates whether or not the end of the stream has been reached. - */ - protected boolean eos; - - /** - * Indicates whether or not the GZIP header has been read in. - */ - private boolean readGZIPHeader; - - /** - * Creates a GZIPInputStream with the default buffer size. - * - * @param in The stream to read compressed data from - * (in GZIP format). - * - * @throws IOException if an error occurs during an I/O operation. - */ - public GZIPInputStream(InputStream in) - throws IOException - { - this(in, 4096); - } - - /** - * Creates a GZIPInputStream with the specified buffer size. - * - * @param in The stream to read compressed data from - * (in GZIP format). - * @param size The size of the buffer to use. - * - * @throws IOException if an error occurs during an I/O operation. - * @throws IllegalArgumentException if <code>size</code> - * is less than or equal to 0. - */ - public GZIPInputStream(InputStream in, int size) - throws IOException - { - super(in, new Inflater(true), size); - crc = new CRC32(); - readHeader(); - } - - /** - * Closes the input stream. - * - * @throws IOException if an error occurs during an I/O operation. - */ - public void close() - throws IOException - { - // Nothing to do here. - super.close(); - } - - /** - * Reads in GZIP-compressed data and stores it in uncompressed form - * into an array of bytes. The method will block until either - * enough input data becomes available or the compressed stream - * reaches its end. - * - * @param buf the buffer into which the uncompressed data will - * be stored. - * @param offset the offset indicating where in <code>buf</code> - * the uncompressed data should be placed. - * @param len the number of uncompressed bytes to be read. - */ - public int read(byte[] buf, int offset, int len) throws IOException - { - // We first have to slurp in the GZIP header, then we feed all the - // rest of the data to the superclass. - // - // As we do that we continually update the CRC32. Once the data is - // finished, we check the CRC32. - // - // This means we don't need our own buffer, as everything is done - // in the superclass. - if (!readGZIPHeader) - readHeader(); - - if (eos) - return -1; - - // System.err.println("GZIPIS.read(byte[], off, len ... " + offset + " and len " + len); - - /* We don't have to read the header, - * so we just grab data from the superclass. - */ - int numRead = super.read(buf, offset, len); - if (numRead > 0) - crc.update(buf, offset, numRead); - - if (inf.finished()) - readFooter(); - return numRead; - } - - - /** - * Reads in the GZIP header. - */ - private void readHeader() throws IOException - { - /* 1. Check the two magic bytes */ - CRC32 headCRC = new CRC32(); - int magic = in.read(); - if (magic < 0) - { - eos = true; - return; - } - int magic2 = in.read(); - if ((magic + (magic2 << 8)) != GZIP_MAGIC) - throw new IOException("Error in GZIP header, bad magic code"); - headCRC.update(magic); - headCRC.update(magic2); - - /* 2. Check the compression type (must be 8) */ - int CM = in.read(); - if (CM != Deflater.DEFLATED) - throw new IOException("Error in GZIP header, data not in deflate format"); - headCRC.update(CM); - - /* 3. Check the flags */ - int flags = in.read(); - if (flags < 0) - throw new EOFException("Early EOF in GZIP header"); - headCRC.update(flags); - - /* This flag byte is divided into individual bits as follows: - - bit 0 FTEXT - bit 1 FHCRC - bit 2 FEXTRA - bit 3 FNAME - bit 4 FCOMMENT - bit 5 reserved - bit 6 reserved - bit 7 reserved - */ - - /* 3.1 Check the reserved bits are zero */ - if ((flags & 0xd0) != 0) - throw new IOException("Reserved flag bits in GZIP header != 0"); - - /* 4.-6. Skip the modification time, extra flags, and OS type */ - for (int i=0; i< 6; i++) - { - int readByte = in.read(); - if (readByte < 0) - throw new EOFException("Early EOF in GZIP header"); - headCRC.update(readByte); - } - - /* 7. Read extra field */ - if ((flags & FEXTRA) != 0) - { - /* Skip subfield id */ - for (int i=0; i< 2; i++) - { - int readByte = in.read(); - if (readByte < 0) - throw new EOFException("Early EOF in GZIP header"); - headCRC.update(readByte); - } - if (in.read() < 0 || in.read() < 0) - throw new EOFException("Early EOF in GZIP header"); - - int len1, len2, extraLen; - len1 = in.read(); - len2 = in.read(); - if ((len1 < 0) || (len2 < 0)) - throw new EOFException("Early EOF in GZIP header"); - headCRC.update(len1); - headCRC.update(len2); - - extraLen = (len1 << 8) | len2; - for (int i = 0; i < extraLen;i++) - { - int readByte = in.read(); - if (readByte < 0) - throw new EOFException("Early EOF in GZIP header"); - headCRC.update(readByte); - } - } - - /* 8. Read file name */ - if ((flags & FNAME) != 0) - { - int readByte; - while ( (readByte = in.read()) > 0) - headCRC.update(readByte); - if (readByte < 0) - throw new EOFException("Early EOF in GZIP file name"); - headCRC.update(readByte); - } - - /* 9. Read comment */ - if ((flags & FCOMMENT) != 0) - { - int readByte; - while ( (readByte = in.read()) > 0) - headCRC.update(readByte); - - if (readByte < 0) - throw new EOFException("Early EOF in GZIP comment"); - headCRC.update(readByte); - } - - /* 10. Read header CRC */ - if ((flags & FHCRC) != 0) - { - int tempByte; - int crcval = in.read(); - if (crcval < 0) - throw new EOFException("Early EOF in GZIP header"); - - tempByte = in.read(); - if (tempByte < 0) - throw new EOFException("Early EOF in GZIP header"); - - crcval = (crcval << 8) | tempByte; - if (crcval != ((int) headCRC.getValue() & 0xffff)) - throw new IOException("Header CRC value mismatch"); - } - - readGZIPHeader = true; - //System.err.println("Read GZIP header"); - } - - private void readFooter() throws IOException - { - byte[] footer = new byte[8]; - int avail = inf.getRemaining(); - if (avail > 8) - avail = 8; - System.arraycopy(buf, len - inf.getRemaining(), footer, 0, avail); - int needed = 8 - avail; - while (needed > 0) - { - int count = in.read(footer, 8-needed, needed); - if (count <= 0) - throw new EOFException("Early EOF in GZIP footer"); - needed -= count; //Jewel Jan 16 - } - - int crcval = (footer[0] & 0xff) | ((footer[1] & 0xff) << 8) - | ((footer[2] & 0xff) << 16) | (footer[3] << 24); - if (crcval != (int) crc.getValue()) - throw new IOException("GZIP crc sum mismatch, theirs \"" - + Integer.toHexString(crcval) - + "\" and ours \"" - + Integer.toHexString( (int) crc.getValue())); - - int total = (footer[4] & 0xff) | ((footer[5] & 0xff) << 8) - | ((footer[6] & 0xff) << 16) | (footer[7] << 24); - if (total != inf.getTotalOut()) - throw new IOException("Number of bytes mismatch"); - - /* FIXME" XXX Should we support multiple members. - * Difficult, since there may be some bytes still in buf - */ - eos = true; - } -} diff --git a/libjava/classpath/java/util/zip/GZIPOutputStream.java b/libjava/classpath/java/util/zip/GZIPOutputStream.java deleted file mode 100644 index 0080ab6..0000000 --- a/libjava/classpath/java/util/zip/GZIPOutputStream.java +++ /dev/null @@ -1,151 +0,0 @@ -/* GZIPOutputStream.java - Create a file in gzip format - 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; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * This filter stream is used to compress a stream into a "GZIP" stream. - * The "GZIP" format is described in RFC 1952. - * - * @author John Leuner - * @author Tom Tromey - * @since JDK 1.1 - */ - -/* Written using on-line Java Platform 1.2 API Specification - * and JCL book. - * Believed complete and correct. - */ - -public class GZIPOutputStream extends DeflaterOutputStream -{ - /** - * CRC-32 value for uncompressed data - */ - protected CRC32 crc; - - /** - * Creates a GZIPOutputStream with the default buffer size - * - * @param out The stream to read data (to be compressed) from - * - */ - public GZIPOutputStream(OutputStream out) throws IOException - { - this(out, 4096); - } - - /** - * Creates a GZIPOutputStream with the specified buffer size - * - * @param out The stream to read compressed data from - * @param size Size of the buffer to use - */ - public GZIPOutputStream(OutputStream out, int size) throws IOException - { - super(out, new Deflater(Deflater.DEFAULT_COMPRESSION, true), size); - crc = new CRC32(); - int mod_time = (int) (System.currentTimeMillis() / 1000L); - byte[] gzipHeader = - { - /* The two magic bytes */ - (byte) GZIPInputStream.GZIP_MAGIC, - (byte) (GZIPInputStream.GZIP_MAGIC >> 8), - - /* The compression type */ - (byte) Deflater.DEFLATED, - - /* The flags (not set) */ - 0, - - /* The modification time */ - (byte) mod_time, (byte) (mod_time >> 8), - (byte) (mod_time >> 16), (byte) (mod_time >> 24), - - /* The extra flags */ - 0, - - /* The OS type (unknown) */ - (byte) 255 - }; - - out.write(gzipHeader); - // System.err.println("wrote GZIP header (" + gzipHeader.length + " bytes )"); - } - - public synchronized void write(byte[] buf, int off, int len) - throws IOException - { - super.write(buf, off, len); - crc.update(buf, off, len); - } - - /** - * Writes remaining compressed output data to the output stream - * and closes it. - */ - public void close() throws IOException - { - finish(); - out.close(); - } - - public void finish() throws IOException - { - super.finish(); - - int totalin = def.getTotalIn(); - int crcval = (int) (crc.getValue() & 0xffffffff); - - // System.err.println("CRC val is " + Integer.toHexString( crcval ) + " and length " + Integer.toHexString(totalin)); - - byte[] gzipFooter = - { - (byte) crcval, (byte) (crcval >> 8), - (byte) (crcval >> 16), (byte) (crcval >> 24), - - (byte) totalin, (byte) (totalin >> 8), - (byte) (totalin >> 16), (byte) (totalin >> 24) - }; - - out.write(gzipFooter); - // System.err.println("wrote GZIP trailer (" + gzipFooter.length + " bytes )"); - } -} diff --git a/libjava/classpath/java/util/zip/Inflater.java b/libjava/classpath/java/util/zip/Inflater.java deleted file mode 100644 index 0f094d6..0000000 --- a/libjava/classpath/java/util/zip/Inflater.java +++ /dev/null @@ -1,726 +0,0 @@ -/* Inflater.java - Decompress a data stream - Copyright (C) 1999, 2000, 2001, 2003, 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.zip; - -/* Written using on-line Java Platform 1.2 API Specification - * and JCL book. - * Believed complete and correct. - */ - -/** - * Inflater is used to decompress data that has been compressed according - * to the "deflate" standard described in rfc1950. - * - * The usage is as following. First you have to set some input with - * <code>setInput()</code>, then inflate() it. If inflate doesn't - * inflate any bytes there may be three reasons: - * <ul> - * <li>needsInput() returns true because the input buffer is empty. - * You have to provide more input with <code>setInput()</code>. - * NOTE: needsInput() also returns true when, the stream is finished. - * </li> - * <li>needsDictionary() returns true, you have to provide a preset - * dictionary with <code>setDictionary()</code>.</li> - * <li>finished() returns true, the inflater has finished.</li> - * </ul> - * Once the first output byte is produced, a dictionary will not be - * needed at a later stage. - * - * @author John Leuner, Jochen Hoenicke - * @author Tom Tromey - * @date May 17, 1999 - * @since JDK 1.1 - */ -public class Inflater -{ - /* Copy lengths for literal codes 257..285 */ - private static final int CPLENS[] = - { - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258 - }; - - /* Extra bits for literal codes 257..285 */ - private static final int CPLEXT[] = - { - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 - }; - - /* Copy offsets for distance codes 0..29 */ - private static final int CPDIST[] = { - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577 - }; - - /* Extra bits for distance codes */ - private static final int CPDEXT[] = { - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, - 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, - 12, 12, 13, 13 - }; - - /* This are the state in which the inflater can be. */ - private static final int DECODE_HEADER = 0; - private static final int DECODE_DICT = 1; - private static final int DECODE_BLOCKS = 2; - private static final int DECODE_STORED_LEN1 = 3; - private static final int DECODE_STORED_LEN2 = 4; - private static final int DECODE_STORED = 5; - private static final int DECODE_DYN_HEADER = 6; - private static final int DECODE_HUFFMAN = 7; - private static final int DECODE_HUFFMAN_LENBITS = 8; - private static final int DECODE_HUFFMAN_DIST = 9; - private static final int DECODE_HUFFMAN_DISTBITS = 10; - private static final int DECODE_CHKSUM = 11; - private static final int FINISHED = 12; - - /** This variable contains the current state. */ - private int mode; - - /** - * The adler checksum of the dictionary or of the decompressed - * stream, as it is written in the header resp. footer of the - * compressed stream. <br> - * - * Only valid if mode is DECODE_DICT or DECODE_CHKSUM. - */ - private int readAdler; - /** - * The number of bits needed to complete the current state. This - * is valid, if mode is DECODE_DICT, DECODE_CHKSUM, - * DECODE_HUFFMAN_LENBITS or DECODE_HUFFMAN_DISTBITS. - */ - private int neededBits; - private int repLength, repDist; - private int uncomprLen; - /** - * True, if the last block flag was set in the last block of the - * inflated stream. This means that the stream ends after the - * current block. - */ - private boolean isLastBlock; - - /** - * The total number of inflated bytes. - */ - private long totalOut; - /** - * The total number of bytes set with setInput(). This is not the - * value returned by getTotalIn(), since this also includes the - * unprocessed input. - */ - private long totalIn; - /** - * This variable stores the nowrap flag that was given to the constructor. - * True means, that the inflated stream doesn't contain a header nor the - * checksum in the footer. - */ - private boolean nowrap; - - private StreamManipulator input; - private OutputWindow outputWindow; - private InflaterDynHeader dynHeader; - private InflaterHuffmanTree litlenTree, distTree; - private Adler32 adler; - - /** - * Creates a new inflater. - */ - public Inflater () - { - this (false); - } - - /** - * Creates a new inflater. - * @param nowrap true if no header and checksum field appears in the - * stream. This is used for GZIPed input. For compatibility with - * Sun JDK you should provide one byte of input more than needed in - * this case. - */ - public Inflater (boolean nowrap) - { - this.nowrap = nowrap; - this.adler = new Adler32(); - input = new StreamManipulator(); - outputWindow = new OutputWindow(); - mode = nowrap ? DECODE_BLOCKS : DECODE_HEADER; - } - - /** - * Finalizes this object. - */ - protected void finalize () - { - /* Exists only for compatibility */ - } - - /** - * Frees all objects allocated by the inflater. There's no reason - * to call this, since you can just rely on garbage collection (even - * for the Sun implementation). Exists only for compatibility - * with Sun's JDK, where the compressor allocates native memory. - * If you call any method (even reset) afterwards the behaviour is - * <i>undefined</i>. - */ - public void end () - { - outputWindow = null; - input = null; - dynHeader = null; - litlenTree = null; - distTree = null; - adler = null; - } - - /** - * Returns true, if the inflater has finished. This means, that no - * input is needed and no output can be produced. - */ - public boolean finished() - { - return mode == FINISHED && outputWindow.getAvailable() == 0; - } - - /** - * Gets the adler checksum. This is either the checksum of all - * uncompressed bytes returned by inflate(), or if needsDictionary() - * returns true (and thus no output was yet produced) this is the - * adler checksum of the expected dictionary. - * @returns the adler checksum. - */ - public int getAdler() - { - return needsDictionary() ? readAdler : (int) adler.getValue(); - } - - /** - * Gets the number of unprocessed input. Useful, if the end of the - * stream is reached and you want to further process the bytes after - * the deflate stream. - * @return the number of bytes of the input which were not processed. - */ - public int getRemaining() - { - return input.getAvailableBytes(); - } - - /** - * Gets the total number of processed compressed input bytes. - * @return the total number of bytes of processed input bytes. - */ - public int getTotalIn() - { - return (int) (totalIn - getRemaining()); - } - - /** - * Gets the total number of processed compressed input bytes. - * @return the total number of bytes of processed input bytes. - * @since 1.5 - */ - public long getBytesRead() - { - return totalIn - getRemaining(); - } - - /** - * Gets the total number of output bytes returned by inflate(). - * @return the total number of output bytes. - */ - public int getTotalOut() - { - return (int) totalOut; - } - - /** - * Gets the total number of output bytes returned by inflate(). - * @return the total number of output bytes. - * @since 1.5 - */ - public long getBytesWritten() - { - return totalOut; - } - - /** - * Inflates the compressed stream to the output buffer. If this - * returns 0, you should check, whether needsDictionary(), - * needsInput() or finished() returns true, to determine why no - * further output is produced. - * @param buf the output buffer. - * @return the number of bytes written to the buffer, 0 if no further - * output can be produced. - * @exception DataFormatException if deflated stream is invalid. - * @exception IllegalArgumentException if buf has length 0. - */ - public int inflate (byte[] buf) throws DataFormatException - { - return inflate (buf, 0, buf.length); - } - - /** - * Inflates the compressed stream to the output buffer. If this - * returns 0, you should check, whether needsDictionary(), - * needsInput() or finished() returns true, to determine why no - * further output is produced. - * @param buf the output buffer. - * @param off the offset into buffer where the output should start. - * @param len the maximum length of the output. - * @return the number of bytes written to the buffer, 0 if no further - * output can be produced. - * @exception DataFormatException if deflated stream is invalid. - * @exception IndexOutOfBoundsException if the off and/or len are wrong. - */ - public int inflate (byte[] buf, int off, int len) throws DataFormatException - { - /* Check for correct buff, off, len triple */ - if (0 > off || off > off + len || off + len > buf.length) - throw new ArrayIndexOutOfBoundsException(); - int count = 0; - for (;;) - { - if (outputWindow.getAvailable() == 0) - { - if (!decode()) - break; - } - else if (len > 0) - { - int more = outputWindow.copyOutput(buf, off, len); - adler.update(buf, off, more); - off += more; - count += more; - totalOut += more; - len -= more; - } - else - break; - } - return count; - } - - /** - * Returns true, if a preset dictionary is needed to inflate the input. - */ - public boolean needsDictionary () - { - return mode == DECODE_DICT && neededBits == 0; - } - - /** - * Returns true, if the input buffer is empty. - * You should then call setInput(). <br> - * - * <em>NOTE</em>: This method also returns true when the stream is finished. - */ - public boolean needsInput () - { - return input.needsInput (); - } - - /** - * Resets the inflater so that a new stream can be decompressed. All - * pending input and output will be discarded. - */ - public void reset () - { - mode = nowrap ? DECODE_BLOCKS : DECODE_HEADER; - totalIn = totalOut = 0; - input.reset(); - outputWindow.reset(); - dynHeader = null; - litlenTree = null; - distTree = null; - isLastBlock = false; - adler.reset(); - } - - /** - * Sets the preset dictionary. This should only be called, if - * needsDictionary() returns true and it should set the same - * dictionary, that was used for deflating. The getAdler() - * function returns the checksum of the dictionary needed. - * @param buffer the dictionary. - * @exception IllegalStateException if no dictionary is needed. - * @exception IllegalArgumentException if the dictionary checksum is - * wrong. - */ - public void setDictionary (byte[] buffer) - { - setDictionary(buffer, 0, buffer.length); - } - - /** - * Sets the preset dictionary. This should only be called, if - * needsDictionary() returns true and it should set the same - * dictionary, that was used for deflating. The getAdler() - * function returns the checksum of the dictionary needed. - * @param buffer the dictionary. - * @param off the offset into buffer where the dictionary starts. - * @param len the length of the dictionary. - * @exception IllegalStateException if no dictionary is needed. - * @exception IllegalArgumentException if the dictionary checksum is - * wrong. - * @exception IndexOutOfBoundsException if the off and/or len are wrong. - */ - public void setDictionary (byte[] buffer, int off, int len) - { - if (!needsDictionary()) - throw new IllegalStateException(); - - adler.update(buffer, off, len); - if ((int) adler.getValue() != readAdler) - throw new IllegalArgumentException("Wrong adler checksum"); - adler.reset(); - outputWindow.copyDict(buffer, off, len); - mode = DECODE_BLOCKS; - } - - /** - * Sets the input. This should only be called, if needsInput() - * returns true. - * @param buf the input. - * @exception IllegalStateException if no input is needed. - */ - public void setInput (byte[] buf) - { - setInput (buf, 0, buf.length); - } - - /** - * Sets the input. This should only be called, if needsInput() - * returns true. - * @param buf the input. - * @param off the offset into buffer where the input starts. - * @param len the length of the input. - * @exception IllegalStateException if no input is needed. - * @exception IndexOutOfBoundsException if the off and/or len are wrong. - */ - public void setInput (byte[] buf, int off, int len) - { - input.setInput (buf, off, len); - totalIn += len; - } - - /** - * Decodes the deflate header. - * @return false if more input is needed. - * @exception DataFormatException if header is invalid. - */ - private boolean decodeHeader () throws DataFormatException - { - int header = input.peekBits(16); - if (header < 0) - return false; - input.dropBits(16); - - /* The header is written in "wrong" byte order */ - header = ((header << 8) | (header >> 8)) & 0xffff; - if (header % 31 != 0) - throw new DataFormatException("Header checksum illegal"); - - if ((header & 0x0f00) != (Deflater.DEFLATED << 8)) - throw new DataFormatException("Compression Method unknown"); - - /* Maximum size of the backwards window in bits. - * We currently ignore this, but we could use it to make the - * inflater window more space efficient. On the other hand the - * full window (15 bits) is needed most times, anyway. - int max_wbits = ((header & 0x7000) >> 12) + 8; - */ - - if ((header & 0x0020) == 0) // Dictionary flag? - { - mode = DECODE_BLOCKS; - } - else - { - mode = DECODE_DICT; - neededBits = 32; - } - return true; - } - - /** - * Decodes the dictionary checksum after the deflate header. - * @return false if more input is needed. - */ - private boolean decodeDict () - { - while (neededBits > 0) - { - int dictByte = input.peekBits(8); - if (dictByte < 0) - return false; - input.dropBits(8); - readAdler = (readAdler << 8) | dictByte; - neededBits -= 8; - } - return false; - } - - /** - * Decodes the huffman encoded symbols in the input stream. - * @return false if more input is needed, true if output window is - * full or the current block ends. - * @exception DataFormatException if deflated stream is invalid. - */ - private boolean decodeHuffman () throws DataFormatException - { - int free = outputWindow.getFreeSpace(); - while (free >= 258) - { - int symbol; - switch (mode) - { - case DECODE_HUFFMAN: - /* This is the inner loop so it is optimized a bit */ - while (((symbol = litlenTree.getSymbol(input)) & ~0xff) == 0) - { - outputWindow.write(symbol); - if (--free < 258) - return true; - } - if (symbol < 257) - { - if (symbol < 0) - return false; - else - { - /* symbol == 256: end of block */ - distTree = null; - litlenTree = null; - mode = DECODE_BLOCKS; - return true; - } - } - - try - { - repLength = CPLENS[symbol - 257]; - neededBits = CPLEXT[symbol - 257]; - } - catch (ArrayIndexOutOfBoundsException ex) - { - throw new DataFormatException("Illegal rep length code"); - } - /* fall through */ - case DECODE_HUFFMAN_LENBITS: - if (neededBits > 0) - { - mode = DECODE_HUFFMAN_LENBITS; - int i = input.peekBits(neededBits); - if (i < 0) - return false; - input.dropBits(neededBits); - repLength += i; - } - mode = DECODE_HUFFMAN_DIST; - /* fall through */ - case DECODE_HUFFMAN_DIST: - symbol = distTree.getSymbol(input); - if (symbol < 0) - return false; - try - { - repDist = CPDIST[symbol]; - neededBits = CPDEXT[symbol]; - } - catch (ArrayIndexOutOfBoundsException ex) - { - throw new DataFormatException("Illegal rep dist code"); - } - /* fall through */ - case DECODE_HUFFMAN_DISTBITS: - if (neededBits > 0) - { - mode = DECODE_HUFFMAN_DISTBITS; - int i = input.peekBits(neededBits); - if (i < 0) - return false; - input.dropBits(neededBits); - repDist += i; - } - outputWindow.repeat(repLength, repDist); - free -= repLength; - mode = DECODE_HUFFMAN; - break; - default: - throw new IllegalStateException(); - } - } - return true; - } - - /** - * Decodes the adler checksum after the deflate stream. - * @return false if more input is needed. - * @exception DataFormatException if checksum doesn't match. - */ - private boolean decodeChksum () throws DataFormatException - { - while (neededBits > 0) - { - int chkByte = input.peekBits(8); - if (chkByte < 0) - return false; - input.dropBits(8); - readAdler = (readAdler << 8) | chkByte; - neededBits -= 8; - } - if ((int) adler.getValue() != readAdler) - throw new DataFormatException("Adler chksum doesn't match: " - +Integer.toHexString((int)adler.getValue()) - +" vs. "+Integer.toHexString(readAdler)); - mode = FINISHED; - return false; - } - - /** - * Decodes the deflated stream. - * @return false if more input is needed, or if finished. - * @exception DataFormatException if deflated stream is invalid. - */ - private boolean decode () throws DataFormatException - { - switch (mode) - { - case DECODE_HEADER: - return decodeHeader(); - case DECODE_DICT: - return decodeDict(); - case DECODE_CHKSUM: - return decodeChksum(); - - case DECODE_BLOCKS: - if (isLastBlock) - { - if (nowrap) - { - mode = FINISHED; - return false; - } - else - { - input.skipToByteBoundary(); - neededBits = 32; - mode = DECODE_CHKSUM; - return true; - } - } - - int type = input.peekBits(3); - if (type < 0) - return false; - input.dropBits(3); - - if ((type & 1) != 0) - isLastBlock = true; - switch (type >> 1) - { - case DeflaterConstants.STORED_BLOCK: - input.skipToByteBoundary(); - mode = DECODE_STORED_LEN1; - break; - case DeflaterConstants.STATIC_TREES: - litlenTree = InflaterHuffmanTree.defLitLenTree; - distTree = InflaterHuffmanTree.defDistTree; - mode = DECODE_HUFFMAN; - break; - case DeflaterConstants.DYN_TREES: - dynHeader = new InflaterDynHeader(); - mode = DECODE_DYN_HEADER; - break; - default: - throw new DataFormatException("Unknown block type "+type); - } - return true; - - case DECODE_STORED_LEN1: - { - if ((uncomprLen = input.peekBits(16)) < 0) - return false; - input.dropBits(16); - mode = DECODE_STORED_LEN2; - } - /* fall through */ - case DECODE_STORED_LEN2: - { - int nlen = input.peekBits(16); - if (nlen < 0) - return false; - input.dropBits(16); - if (nlen != (uncomprLen ^ 0xffff)) - throw new DataFormatException("broken uncompressed block"); - mode = DECODE_STORED; - } - /* fall through */ - case DECODE_STORED: - { - int more = outputWindow.copyStored(input, uncomprLen); - uncomprLen -= more; - if (uncomprLen == 0) - { - mode = DECODE_BLOCKS; - return true; - } - return !input.needsInput(); - } - - case DECODE_DYN_HEADER: - if (!dynHeader.decode(input)) - return false; - litlenTree = dynHeader.buildLitLenTree(); - distTree = dynHeader.buildDistTree(); - mode = DECODE_HUFFMAN; - /* fall through */ - case DECODE_HUFFMAN: - case DECODE_HUFFMAN_LENBITS: - case DECODE_HUFFMAN_DIST: - case DECODE_HUFFMAN_DISTBITS: - return decodeHuffman(); - case FINISHED: - return false; - default: - throw new IllegalStateException(); - } - } -} diff --git a/libjava/classpath/java/util/zip/InflaterDynHeader.java b/libjava/classpath/java/util/zip/InflaterDynHeader.java deleted file mode 100644 index 64e08d6..0000000 --- a/libjava/classpath/java/util/zip/InflaterDynHeader.java +++ /dev/null @@ -1,203 +0,0 @@ -/* java.util.zip.InflaterDynHeader - 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; - -class InflaterDynHeader -{ - private static final int LNUM = 0; - private static final int DNUM = 1; - private static final int BLNUM = 2; - private static final int BLLENS = 3; - private static final int LENS = 4; - private static final int REPS = 5; - - private static final int repMin[] = { 3, 3, 11 }; - private static final int repBits[] = { 2, 3, 7 }; - - - private byte[] blLens; - private byte[] litdistLens; - - private InflaterHuffmanTree blTree; - - private int mode; - private int lnum, dnum, blnum, num; - private int repSymbol; - private byte lastLen; - private int ptr; - - private static final int[] BL_ORDER = - { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; - - public InflaterDynHeader() - { - } - - public boolean decode(StreamManipulator input) throws DataFormatException - { - decode_loop: - for (;;) - { - switch (mode) - { - case LNUM: - lnum = input.peekBits(5); - if (lnum < 0) - return false; - lnum += 257; - input.dropBits(5); -// System.err.println("LNUM: "+lnum); - mode = DNUM; - /* fall through */ - case DNUM: - dnum = input.peekBits(5); - if (dnum < 0) - return false; - dnum++; - input.dropBits(5); -// System.err.println("DNUM: "+dnum); - num = lnum+dnum; - litdistLens = new byte[num]; - mode = BLNUM; - /* fall through */ - case BLNUM: - blnum = input.peekBits(4); - if (blnum < 0) - return false; - blnum += 4; - input.dropBits(4); - blLens = new byte[19]; - ptr = 0; -// System.err.println("BLNUM: "+blnum); - mode = BLLENS; - /* fall through */ - case BLLENS: - while (ptr < blnum) - { - int len = input.peekBits(3); - if (len < 0) - return false; - input.dropBits(3); -// System.err.println("blLens["+BL_ORDER[ptr]+"]: "+len); - blLens[BL_ORDER[ptr]] = (byte) len; - ptr++; - } - blTree = new InflaterHuffmanTree(blLens); - blLens = null; - ptr = 0; - mode = LENS; - /* fall through */ - case LENS: - { - int symbol; - while (((symbol = blTree.getSymbol(input)) & ~15) == 0) - { - /* Normal case: symbol in [0..15] */ - -// System.err.println("litdistLens["+ptr+"]: "+symbol); - litdistLens[ptr++] = lastLen = (byte) symbol; - - if (ptr == num) - { - /* Finished */ - return true; - } - } - - /* need more input ? */ - if (symbol < 0) - return false; - - /* otherwise repeat code */ - if (symbol >= 17) - { - /* repeat zero */ -// System.err.println("repeating zero"); - lastLen = 0; - } - else - { - if (ptr == 0) - throw new DataFormatException(); - } - repSymbol = symbol-16; - mode = REPS; - } - /* fall through */ - - case REPS: - { - int bits = repBits[repSymbol]; - int count = input.peekBits(bits); - if (count < 0) - return false; - input.dropBits(bits); - count += repMin[repSymbol]; -// System.err.println("litdistLens repeated: "+count); - - if (ptr + count > num) - throw new DataFormatException(); - while (count-- > 0) - litdistLens[ptr++] = lastLen; - - if (ptr == num) - { - /* Finished */ - return true; - } - } - mode = LENS; - continue decode_loop; - } - } - } - - public InflaterHuffmanTree buildLitLenTree() throws DataFormatException - { - byte[] litlenLens = new byte[lnum]; - System.arraycopy(litdistLens, 0, litlenLens, 0, lnum); - return new InflaterHuffmanTree(litlenLens); - } - - public InflaterHuffmanTree buildDistTree() throws DataFormatException - { - byte[] distLens = new byte[dnum]; - System.arraycopy(litdistLens, lnum, distLens, 0, dnum); - return new InflaterHuffmanTree(distLens); - } -} diff --git a/libjava/classpath/java/util/zip/InflaterHuffmanTree.java b/libjava/classpath/java/util/zip/InflaterHuffmanTree.java deleted file mode 100644 index 1a152d2..0000000 --- a/libjava/classpath/java/util/zip/InflaterHuffmanTree.java +++ /dev/null @@ -1,220 +0,0 @@ -/* InflaterHuffmanTree.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; - -class InflaterHuffmanTree -{ - private static final int MAX_BITLEN = 15; - - private short[] tree; - - static InflaterHuffmanTree defLitLenTree, defDistTree; - - static - { - try - { - byte[] codeLengths = new byte[288]; - int i = 0; - while (i < 144) - codeLengths[i++] = 8; - while (i < 256) - codeLengths[i++] = 9; - while (i < 280) - codeLengths[i++] = 7; - while (i < 288) - codeLengths[i++] = 8; - defLitLenTree = new InflaterHuffmanTree(codeLengths); - - codeLengths = new byte[32]; - i = 0; - while (i < 32) - codeLengths[i++] = 5; - defDistTree = new InflaterHuffmanTree(codeLengths); - } - catch (DataFormatException ex) - { - throw new InternalError - ("InflaterHuffmanTree: static tree length illegal"); - } - } - - /** - * Constructs a Huffman tree from the array of code lengths. - * - * @param codeLengths the array of code lengths - */ - InflaterHuffmanTree(byte[] codeLengths) throws DataFormatException - { - buildTree(codeLengths); - } - - private void buildTree(byte[] codeLengths) throws DataFormatException - { - int[] blCount = new int[MAX_BITLEN+1]; - int[] nextCode = new int[MAX_BITLEN+1]; - for (int i = 0; i < codeLengths.length; i++) - { - int bits = codeLengths[i]; - if (bits > 0) - blCount[bits]++; - } - - int max = 0; - int code = 0; - int treeSize = 512; - for (int bits = 1; bits <= MAX_BITLEN; bits++) - { - nextCode[bits] = code; - if (blCount[bits] > 0) - max = bits; - code += blCount[bits] << (16 - bits); - if (bits >= 10) - { - /* We need an extra table for bit lengths >= 10. */ - int start = nextCode[bits] & 0x1ff80; - int end = code & 0x1ff80; - treeSize += (end - start) >> (16 - bits); - } - } - if (code != 65536 && max > 1) - throw new DataFormatException("incomplete dynamic bit lengths tree"); - - /* Now create and fill the extra tables from longest to shortest - * bit len. This way the sub trees will be aligned. - */ - tree = new short[treeSize]; - int treePtr = 512; - for (int bits = MAX_BITLEN; bits >= 10; bits--) - { - int end = code & 0x1ff80; - code -= blCount[bits] << (16 - bits); - int start = code & 0x1ff80; - for (int i = start; i < end; i += 1 << 7) - { - tree[DeflaterHuffman.bitReverse(i)] - = (short) ((-treePtr << 4) | bits); - treePtr += 1 << (bits-9); - } - } - - for (int i = 0; i < codeLengths.length; i++) - { - int bits = codeLengths[i]; - if (bits == 0) - continue; - code = nextCode[bits]; - int revcode = DeflaterHuffman.bitReverse(code); - if (bits <= 9) - { - do - { - tree[revcode] = (short) ((i << 4) | bits); - revcode += 1 << bits; - } - while (revcode < 512); - } - else - { - int subTree = tree[revcode & 511]; - int treeLen = 1 << (subTree & 15); - subTree = -(subTree >> 4); - do - { - tree[subTree | (revcode >> 9)] = (short) ((i << 4) | bits); - revcode += 1 << bits; - } - while (revcode < treeLen); - } - nextCode[bits] = code + (1 << (16 - bits)); - } - } - - /** - * Reads the next symbol from input. The symbol is encoded using the - * huffman tree. - * @param input the input source. - * @return the next symbol, or -1 if not enough input is available. - */ - int getSymbol(StreamManipulator input) throws DataFormatException - { - int lookahead, symbol; - if ((lookahead = input.peekBits(9)) >= 0) - { - if ((symbol = tree[lookahead]) >= 0) - { - input.dropBits(symbol & 15); - return symbol >> 4; - } - int subtree = -(symbol >> 4); - int bitlen = symbol & 15; - if ((lookahead = input.peekBits(bitlen)) >= 0) - { - symbol = tree[subtree | (lookahead >> 9)]; - input.dropBits(symbol & 15); - return symbol >> 4; - } - else - { - int bits = input.getAvailableBits(); - lookahead = input.peekBits(bits); - symbol = tree[subtree | (lookahead >> 9)]; - if ((symbol & 15) <= bits) - { - input.dropBits(symbol & 15); - return symbol >> 4; - } - else - return -1; - } - } - else - { - int bits = input.getAvailableBits(); - lookahead = input.peekBits(bits); - symbol = tree[lookahead]; - if (symbol >= 0 && (symbol & 15) <= bits) - { - input.dropBits(symbol & 15); - return symbol >> 4; - } - else - return -1; - } - } -} diff --git a/libjava/classpath/java/util/zip/InflaterInputStream.java b/libjava/classpath/java/util/zip/InflaterInputStream.java deleted file mode 100644 index 1c5e9f2..0000000 --- a/libjava/classpath/java/util/zip/InflaterInputStream.java +++ /dev/null @@ -1,265 +0,0 @@ -/* InflaterInputStream.java - Input stream filter for decompressing - Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2006 - 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; - -/** - * This filter stream is used to decompress data compressed in the "deflate" - * format. The "deflate" format is described in RFC 1951. - * - * This stream may form the basis for other decompression filters, such - * as the <code>GZIPInputStream</code>. - * - * @author John Leuner - * @author Tom Tromey - * @since 1.1 - */ -public class InflaterInputStream extends FilterInputStream -{ - /** - * Decompressor for this filter - */ - protected Inflater inf; - - /** - * Byte array used as a buffer - */ - protected byte[] buf; - - /** - * Size of buffer - */ - protected int len; - - // We just use this if we are decoding one byte at a time with the - // read() call. - private byte[] onebytebuffer = new byte[1]; - - /** - * Create an InflaterInputStream with the default decompresseor - * and a default buffer size. - * - * @param in the InputStream to read bytes from - */ - public InflaterInputStream(InputStream in) - { - this(in, new Inflater(), 4096); - } - - /** - * Create an InflaterInputStream with the specified decompresseor - * and a default buffer size. - * - * @param in the InputStream to read bytes from - * @param inf the decompressor used to decompress data read from in - */ - public InflaterInputStream(InputStream in, Inflater inf) - { - this(in, inf, 4096); - } - - /** - * Create an InflaterInputStream with the specified decompresseor - * and a specified buffer size. - * - * @param in the InputStream to read bytes from - * @param inf the decompressor used to decompress data read from in - * @param size size of the buffer to use - */ - public InflaterInputStream(InputStream in, Inflater inf, int size) - { - super(in); - - if (in == null) - throw new NullPointerException("in may not be null"); - if (inf == null) - throw new NullPointerException("inf may not be null"); - if (size < 0) - throw new IllegalArgumentException("size may not be negative"); - - this.inf = inf; - this.buf = new byte [size]; - } - - /** - * Returns 0 once the end of the stream (EOF) has been reached. - * Otherwise returns 1. - */ - public int available() throws IOException - { - // According to the JDK 1.2 docs, this should only ever return 0 - // or 1 and should not be relied upon by Java programs. - if (inf == null) - throw new IOException("stream closed"); - return inf.finished() ? 0 : 1; - } - - /** - * Closes the input stream - */ - public synchronized void close() throws IOException - { - if (in != null) - in.close(); - in = null; - } - - /** - * Fills the buffer with more data to decompress. - */ - protected void fill() throws IOException - { - if (in == null) - throw new ZipException ("InflaterInputStream is closed"); - - len = in.read(buf, 0, buf.length); - - if (len < 0) - throw new ZipException("Deflated stream ends early."); - - inf.setInput(buf, 0, len); - } - - /** - * Reads one byte of decompressed data. - * - * The byte is in the lower 8 bits of the int. - */ - public int read() throws IOException - { - int nread = read(onebytebuffer, 0, 1); - if (nread > 0) - return onebytebuffer[0] & 0xff; - return -1; - } - - /** - * Decompresses data into the byte array - * - * @param b the array to read and decompress data into - * @param off the offset indicating where the data should be placed - * @param len the number of bytes to decompress - */ - public int read(byte[] b, int off, int len) throws IOException - { - if (inf == null) - throw new IOException("stream closed"); - if (len == 0) - return 0; - if (inf.finished()) - return -1; - - int count = 0; - while (count == 0) - { - if (inf.needsInput()) - fill(); - - try - { - count = inf.inflate(b, off, len); - if (count == 0) - { - if (this.len == -1) - { - // Couldn't get any more data to feed to the Inflater - return -1; - } - if (inf.needsDictionary()) - throw new ZipException("Inflater needs Dictionary"); - } - } - catch (DataFormatException dfe) - { - throw new ZipException(dfe.getMessage()); - } - } - return count; - } - - /** - * Skip specified number of bytes of uncompressed data - * - * @param n number of bytes to skip - */ - public long skip(long n) throws IOException - { - if (inf == null) - throw new IOException("stream closed"); - if (n < 0) - throw new IllegalArgumentException(); - - if (n == 0) - return 0; - - int buflen = (int) Math.min(n, 2048); - byte[] tmpbuf = new byte[buflen]; - - long skipped = 0L; - while (n > 0L) - { - int numread = read(tmpbuf, 0, buflen); - if (numread <= 0) - break; - n -= numread; - skipped += numread; - buflen = (int) Math.min(n, 2048); - } - - return skipped; - } - - public boolean markSupported() - { - return false; - } - - public void mark(int readLimit) - { - } - - public void reset() throws IOException - { - throw new IOException("reset not supported"); - } -} diff --git a/libjava/classpath/java/util/zip/OutputWindow.java b/libjava/classpath/java/util/zip/OutputWindow.java deleted file mode 100644 index 59dadb5..0000000 --- a/libjava/classpath/java/util/zip/OutputWindow.java +++ /dev/null @@ -1,175 +0,0 @@ -/* OutputWindow.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; - -/** - * Contains the output from the Inflation process. - * - * We need to have a window so that we can refer backwards into the output stream - * to repeat stuff. - * - * @author John Leuner - * @since 1.1 - */ -class OutputWindow -{ - private static final int WINDOW_SIZE = 1 << 15; - private static final int WINDOW_MASK = WINDOW_SIZE - 1; - - private byte[] window = new byte[WINDOW_SIZE]; //The window is 2^15 bytes - private int window_end = 0; - private int window_filled = 0; - - public void write(int abyte) - { - if (window_filled++ == WINDOW_SIZE) - throw new IllegalStateException("Window full"); - window[window_end++] = (byte) abyte; - window_end &= WINDOW_MASK; - } - - private void slowRepeat(int rep_start, int len, int dist) - { - while (len-- > 0) - { - window[window_end++] = window[rep_start++]; - window_end &= WINDOW_MASK; - rep_start &= WINDOW_MASK; - } - } - - public void repeat(int len, int dist) - { - if ((window_filled += len) > WINDOW_SIZE) - throw new IllegalStateException("Window full"); - - int rep_start = (window_end - dist) & WINDOW_MASK; - int border = WINDOW_SIZE - len; - if (rep_start <= border && window_end < border) - { - if (len <= dist) - { - System.arraycopy(window, rep_start, window, window_end, len); - window_end += len; - } - else - { - /* We have to copy manually, since the repeat pattern overlaps. - */ - while (len-- > 0) - window[window_end++] = window[rep_start++]; - } - } - else - slowRepeat(rep_start, len, dist); - } - - public int copyStored(StreamManipulator input, int len) - { - len = Math.min(Math.min(len, WINDOW_SIZE - window_filled), - input.getAvailableBytes()); - int copied; - - int tailLen = WINDOW_SIZE - window_end; - if (len > tailLen) - { - copied = input.copyBytes(window, window_end, tailLen); - if (copied == tailLen) - copied += input.copyBytes(window, 0, len - tailLen); - } - else - copied = input.copyBytes(window, window_end, len); - - window_end = (window_end + copied) & WINDOW_MASK; - window_filled += copied; - return copied; - } - - public void copyDict(byte[] dict, int offset, int len) - { - if (window_filled > 0) - throw new IllegalStateException(); - - if (len > WINDOW_SIZE) - { - offset += len - WINDOW_SIZE; - len = WINDOW_SIZE; - } - System.arraycopy(dict, offset, window, 0, len); - window_end = len & WINDOW_MASK; - } - - public int getFreeSpace() - { - return WINDOW_SIZE - window_filled; - } - - public int getAvailable() - { - return window_filled; - } - - public int copyOutput(byte[] output, int offset, int len) - { - int copy_end = window_end; - if (len > window_filled) - len = window_filled; - else - copy_end = (window_end - window_filled + len) & WINDOW_MASK; - - int copied = len; - int tailLen = len - copy_end; - - if (tailLen > 0) - { - System.arraycopy(window, WINDOW_SIZE - tailLen, - output, offset, tailLen); - offset += tailLen; - len = copy_end; - } - System.arraycopy(window, copy_end - len, output, offset, len); - window_filled -= copied; - if (window_filled < 0) - throw new IllegalStateException(); - return copied; - } - - public void reset() { - window_filled = window_end = 0; - } -} diff --git a/libjava/classpath/java/util/zip/PendingBuffer.java b/libjava/classpath/java/util/zip/PendingBuffer.java deleted file mode 100644 index 50f561f..0000000 --- a/libjava/classpath/java/util/zip/PendingBuffer.java +++ /dev/null @@ -1,199 +0,0 @@ -/* java.util.zip.PendingBuffer - 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; - -/** - * This class is general purpose class for writing data to a buffer. - * - * It allows you to write bits as well as bytes - * - * Based on DeflaterPending.java - * - * @author Jochen Hoenicke - * @date Jan 5, 2000 - */ - -class PendingBuffer -{ - protected byte[] buf; - int start; - int end; - - int bits; - int bitCount; - - public PendingBuffer() - { - this( 4096 ); - } - - public PendingBuffer(int bufsize) - { - buf = new byte[bufsize]; - } - - public final void reset() { - start = end = bitCount = 0; - } - - public final void writeByte(int b) - { - if (DeflaterConstants.DEBUGGING && start != 0) - throw new IllegalStateException(); - buf[end++] = (byte) b; - } - - public final void writeShort(int s) - { - if (DeflaterConstants.DEBUGGING && start != 0) - throw new IllegalStateException(); - buf[end++] = (byte) s; - buf[end++] = (byte) (s >> 8); - } - - public final void writeInt(int s) - { - if (DeflaterConstants.DEBUGGING && start != 0) - throw new IllegalStateException(); - buf[end++] = (byte) s; - buf[end++] = (byte) (s >> 8); - buf[end++] = (byte) (s >> 16); - buf[end++] = (byte) (s >> 24); - } - - public final void writeBlock(byte[] block, int offset, int len) - { - if (DeflaterConstants.DEBUGGING && start != 0) - throw new IllegalStateException(); - System.arraycopy(block, offset, buf, end, len); - end += len; - } - - public final int getBitCount() { - return bitCount; - } - - public final void alignToByte() { - if (DeflaterConstants.DEBUGGING && start != 0) - throw new IllegalStateException(); - if (bitCount > 0) - { - buf[end++] = (byte) bits; - if (bitCount > 8) - buf[end++] = (byte) (bits >>> 8); - } - bits = 0; - bitCount = 0; - } - - public final void writeBits(int b, int count) - { - if (DeflaterConstants.DEBUGGING && start != 0) - throw new IllegalStateException(); - if (DeflaterConstants.DEBUGGING) - System.err.println("writeBits("+Integer.toHexString(b)+","+count+")"); - bits |= b << bitCount; - bitCount += count; - if (bitCount >= 16) { - buf[end++] = (byte) bits; - buf[end++] = (byte) (bits >>> 8); - bits >>>= 16; - bitCount -= 16; - } - } - - public final void writeShortMSB(int s) { - if (DeflaterConstants.DEBUGGING && start != 0) - throw new IllegalStateException(); - buf[end++] = (byte) (s >> 8); - buf[end++] = (byte) s; - } - - public final boolean isFlushed() { - return end == 0; - } - - /** - * Flushes the pending buffer into the given output array. If the - * output array is to small, only a partial flush is done. - * - * @param output the output array; - * @param offset the offset into output array; - * @param length the maximum number of bytes to store; - * @exception IndexOutOfBoundsException if offset or length are - * invalid. - */ - public final int flush(byte[] output, int offset, int length) { - if (bitCount >= 8) - { - buf[end++] = (byte) bits; - bits >>>= 8; - bitCount -= 8; - } - if (length > end - start) - { - length = end - start; - System.arraycopy(buf, start, output, offset, length); - start = 0; - end = 0; - } - else - { - System.arraycopy(buf, start, output, offset, length); - start += length; - } - return length; - } - - /** - * Flushes the pending buffer and returns that data in a new array - * - * @return the output stream - */ - - public final byte[] toByteArray() - { - byte[] ret = new byte[ end - start ]; - System.arraycopy(buf, start, ret, 0, ret.length); - start = 0; - end = 0; - return ret; - } - - -} diff --git a/libjava/classpath/java/util/zip/StreamManipulator.java b/libjava/classpath/java/util/zip/StreamManipulator.java deleted file mode 100644 index 105d807..0000000 --- a/libjava/classpath/java/util/zip/StreamManipulator.java +++ /dev/null @@ -1,215 +0,0 @@ -/* java.util.zip.StreamManipulator - 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; - -/** - * This class allows us to retrieve a specified amount of bits from - * the input buffer, as well as copy big byte blocks. - * - * It uses an int buffer to store up to 31 bits for direct - * manipulation. This guarantees that we can get at least 16 bits, - * but we only need at most 15, so this is all safe. - * - * There are some optimizations in this class, for example, you must - * never peek more then 8 bits more than needed, and you must first - * peek bits before you may drop them. This is not a general purpose - * class but optimized for the behaviour of the Inflater. - * - * @author John Leuner, Jochen Hoenicke - */ - -class StreamManipulator -{ - private byte[] window; - private int window_start = 0; - private int window_end = 0; - - private int buffer = 0; - private int bits_in_buffer = 0; - - /** - * Get the next n bits but don't increase input pointer. n must be - * less or equal 16 and if you if this call succeeds, you must drop - * at least n-8 bits in the next call. - * - * @return the value of the bits, or -1 if not enough bits available. */ - public final int peekBits(int n) - { - if (bits_in_buffer < n) - { - if (window_start == window_end) - return -1; - buffer |= (window[window_start++] & 0xff - | (window[window_start++] & 0xff) << 8) << bits_in_buffer; - bits_in_buffer += 16; - } - return buffer & ((1 << n) - 1); - } - - /* Drops the next n bits from the input. You should have called peekBits - * with a bigger or equal n before, to make sure that enough bits are in - * the bit buffer. - */ - public final void dropBits(int n) - { - buffer >>>= n; - bits_in_buffer -= n; - } - - /** - * Gets the next n bits and increases input pointer. This is equivalent - * to peekBits followed by dropBits, except for correct error handling. - * @return the value of the bits, or -1 if not enough bits available. - */ - public final int getBits(int n) - { - int bits = peekBits(n); - if (bits >= 0) - dropBits(n); - return bits; - } - /** - * Gets the number of bits available in the bit buffer. This must be - * only called when a previous peekBits() returned -1. - * @return the number of bits available. - */ - public final int getAvailableBits() - { - return bits_in_buffer; - } - - /** - * Gets the number of bytes available. - * @return the number of bytes available. - */ - public final int getAvailableBytes() - { - return window_end - window_start + (bits_in_buffer >> 3); - } - - /** - * Skips to the next byte boundary. - */ - public void skipToByteBoundary() - { - buffer >>= (bits_in_buffer & 7); - bits_in_buffer &= ~7; - } - - public final boolean needsInput() { - return window_start == window_end; - } - - - /* Copies length bytes from input buffer to output buffer starting - * at output[offset]. You have to make sure, that the buffer is - * byte aligned. If not enough bytes are available, copies fewer - * bytes. - * @param length the length to copy, 0 is allowed. - * @return the number of bytes copied, 0 if no byte is available. - */ - public int copyBytes(byte[] output, int offset, int length) - { - if (length < 0) - throw new IllegalArgumentException("length negative"); - if ((bits_in_buffer & 7) != 0) - /* bits_in_buffer may only be 0 or 8 */ - throw new IllegalStateException("Bit buffer is not aligned!"); - - int count = 0; - while (bits_in_buffer > 0 && length > 0) - { - output[offset++] = (byte) buffer; - buffer >>>= 8; - bits_in_buffer -= 8; - length--; - count++; - } - if (length == 0) - return count; - - int avail = window_end - window_start; - if (length > avail) - length = avail; - System.arraycopy(window, window_start, output, offset, length); - window_start += length; - - if (((window_start - window_end) & 1) != 0) - { - /* We always want an even number of bytes in input, see peekBits */ - buffer = (window[window_start++] & 0xff); - bits_in_buffer = 8; - } - return count + length; - } - - public StreamManipulator() - { - } - - public void reset() - { - window_start = window_end = buffer = bits_in_buffer = 0; - } - - public void setInput(byte[] buf, int off, int len) - { - if (window_start < window_end) - throw new IllegalStateException - ("Old input was not completely processed"); - - int end = off + len; - - /* We want to throw an ArrayIndexOutOfBoundsException early. The - * check is very tricky: it also handles integer wrap around. - */ - if (0 > off || off > end || end > buf.length) - throw new ArrayIndexOutOfBoundsException(); - - if ((len & 1) != 0) - { - /* We always want an even number of bytes in input, see peekBits */ - buffer |= (buf[off++] & 0xff) << bits_in_buffer; - bits_in_buffer += 8; - } - - window = buf; - window_start = off; - window_end = end; - } -} diff --git a/libjava/classpath/java/util/zip/ZipConstants.java b/libjava/classpath/java/util/zip/ZipConstants.java deleted file mode 100644 index 69f589a..0000000 --- a/libjava/classpath/java/util/zip/ZipConstants.java +++ /dev/null @@ -1,93 +0,0 @@ -/* java.util.zip.ZipConstants - Copyright (C) 2001, 2006 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; - long 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 */ - long 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 */ - long 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 */ - long ENDSIG = 'P'|('K'<<8)|(5<<16)|(6<<24); - int ENDHDR = 22; - - int ENDSUB = 8; - int ENDTOT = 10; - int ENDSIZ = 12; - int ENDOFF = 16; - int ENDCOM = 20; -} diff --git a/libjava/classpath/java/util/zip/ZipEntry.java b/libjava/classpath/java/util/zip/ZipEntry.java deleted file mode 100644 index 73afc89..0000000 --- a/libjava/classpath/java/util/zip/ZipEntry.java +++ /dev/null @@ -1,457 +0,0 @@ -/* ZipEntry.java -- - 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.zip; - -import java.util.Calendar; - -/** - * This class represents a member of a zip archive. ZipFile and - * ZipInputStream will give you instances of this class as information - * about the members in an archive. On the other hand ZipOutputStream - * needs an instance of this class to create a new member. - * - * @author Jochen Hoenicke - */ -public class ZipEntry implements ZipConstants, Cloneable -{ - private static final byte KNOWN_SIZE = 1; - private static final byte KNOWN_CSIZE = 2; - private static final byte KNOWN_CRC = 4; - private static final byte KNOWN_TIME = 8; - private static final byte KNOWN_DOSTIME = 16; - private static final byte KNOWN_EXTRA = 32; - - /** Immutable name of the entry */ - private final String name; - /** Uncompressed size */ - private int size; - /** Compressed size */ - private long compressedSize = -1; - /** CRC of uncompressed data */ - private int crc; - /** Comment or null if none */ - private String comment = null; - /** The compression method. Either DEFLATED or STORED, by default -1. */ - private byte method = -1; - /** Flags specifying what we know about this entry */ - private byte known = 0; - /** - * The 32bit DOS encoded format for the time of this entry. Only valid if - * KNOWN_DOSTIME is set in known. - */ - private int dostime; - /** - * The 64bit Java encoded millisecond time since the beginning of the epoch. - * Only valid if KNOWN_TIME is set in known. - */ - private long time; - /** Extra data */ - private byte[] extra = null; - - int flags; /* used by ZipOutputStream */ - int offset; /* used by ZipFile and ZipOutputStream */ - - /** - * 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 zip entry with the given name. - * @param name the name. May include directory components separated - * by '/'. - * - * @exception NullPointerException when name is null. - * @exception IllegalArgumentException when name is bigger then 65535 chars. - */ - public ZipEntry(String name) - { - int length = name.length(); - if (length > 65535) - throw new IllegalArgumentException("name length is " + length); - this.name = name; - } - - /** - * Creates a copy of the given zip entry. - * @param e the entry to copy. - */ - public ZipEntry(ZipEntry e) - { - this(e, e.name); - } - - ZipEntry(ZipEntry e, String name) - { - this.name = name; - known = e.known; - size = e.size; - compressedSize = e.compressedSize; - crc = e.crc; - dostime = e.dostime; - time = e.time; - method = e.method; - extra = e.extra; - comment = e.comment; - } - - final void setDOSTime(int dostime) - { - this.dostime = dostime; - known |= KNOWN_DOSTIME; - known &= ~KNOWN_TIME; - } - - final int getDOSTime() - { - if ((known & KNOWN_DOSTIME) != 0) - return dostime; - else if ((known & KNOWN_TIME) != 0) - { - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(time); - dostime = (cal.get(Calendar.YEAR) - 1980 & 0x7f) << 25 - | (cal.get(Calendar.MONTH) + 1) << 21 - | (cal.get(Calendar.DAY_OF_MONTH)) << 16 - | (cal.get(Calendar.HOUR_OF_DAY)) << 11 - | (cal.get(Calendar.MINUTE)) << 5 - | (cal.get(Calendar.SECOND)) >> 1; - known |= KNOWN_DOSTIME; - return dostime; - } - else - return 0; - } - - /** - * Creates a copy of this zip entry. - */ - public Object clone() - { - // JCL defines this as being the same as the copy constructor above, - // except that value of the "extra" field is also copied. Take care - // that in the case of a subclass we use clone() rather than the copy - // constructor. - ZipEntry clone; - if (this.getClass() == ZipEntry.class) - clone = new ZipEntry(this); - else - { - try - { - clone = (ZipEntry) super.clone(); - } - catch (CloneNotSupportedException e) - { - throw new InternalError(); - } - } - if (extra != null) - { - clone.extra = new byte[extra.length]; - System.arraycopy(extra, 0, clone.extra, 0, extra.length); - } - return clone; - } - - /** - * Returns the entry name. The path components in the entry are - * always separated by slashes ('/'). - */ - public String getName() - { - return name; - } - - /** - * Sets the time of last modification of the entry. - * @time the time of last modification of the entry. - */ - public void setTime(long time) - { - this.time = time; - this.known |= KNOWN_TIME; - this.known &= ~KNOWN_DOSTIME; - } - - /** - * Gets the time of last modification of the entry. - * @return the time of last modification of the entry, or -1 if unknown. - */ - public long getTime() - { - // The extra bytes might contain the time (posix/unix extension) - parseExtra(); - - if ((known & KNOWN_TIME) != 0) - return time; - else if ((known & KNOWN_DOSTIME) != 0) - { - int sec = 2 * (dostime & 0x1f); - int min = (dostime >> 5) & 0x3f; - int hrs = (dostime >> 11) & 0x1f; - int day = (dostime >> 16) & 0x1f; - int mon = ((dostime >> 21) & 0xf) - 1; - int year = ((dostime >> 25) & 0x7f) + 1980; /* since 1900 */ - - try - { - Calendar cal = Calendar.getInstance(); - cal.set(year, mon, day, hrs, min, sec); - time = cal.getTimeInMillis(); - known |= KNOWN_TIME; - return time; - } - catch (RuntimeException ex) - { - /* Ignore illegal time stamp */ - known &= ~KNOWN_TIME; - return -1; - } - } - else - return -1; - } - - /** - * Sets the size of the uncompressed data. - * @exception IllegalArgumentException if size is not in 0..0xffffffffL - */ - public void setSize(long size) - { - if ((size & 0xffffffff00000000L) != 0) - throw new IllegalArgumentException(); - this.size = (int) size; - this.known |= KNOWN_SIZE; - } - - /** - * Gets the size of the uncompressed data. - * @return the size or -1 if unknown. - */ - public long getSize() - { - return (known & KNOWN_SIZE) != 0 ? size & 0xffffffffL : -1L; - } - - /** - * Sets the size of the compressed data. - */ - public void setCompressedSize(long csize) - { - this.compressedSize = csize; - } - - /** - * Gets the size of the compressed data. - * @return the size or -1 if unknown. - */ - public long getCompressedSize() - { - return compressedSize; - } - - /** - * Sets the crc of the uncompressed data. - * @exception IllegalArgumentException if crc is not in 0..0xffffffffL - */ - public void setCrc(long crc) - { - if ((crc & 0xffffffff00000000L) != 0) - throw new IllegalArgumentException(); - this.crc = (int) crc; - this.known |= KNOWN_CRC; - } - - /** - * Gets the crc of the uncompressed data. - * @return the crc or -1 if unknown. - */ - public long getCrc() - { - return (known & KNOWN_CRC) != 0 ? crc & 0xffffffffL : -1L; - } - - /** - * Sets the compression method. Only DEFLATED and STORED are - * supported. - * @exception IllegalArgumentException if method is not supported. - * @see ZipOutputStream#DEFLATED - * @see ZipOutputStream#STORED - */ - public void setMethod(int method) - { - if (method != ZipOutputStream.STORED - && method != ZipOutputStream.DEFLATED) - throw new IllegalArgumentException(); - this.method = (byte) method; - } - - /** - * Gets the compression method. - * @return the compression method or -1 if unknown. - */ - public int getMethod() - { - return method; - } - - /** - * Sets the extra data. - * @exception IllegalArgumentException if extra is longer than 0xffff bytes. - */ - public void setExtra(byte[] extra) - { - if (extra == null) - { - this.extra = null; - return; - } - if (extra.length > 0xffff) - throw new IllegalArgumentException(); - this.extra = extra; - } - - private void parseExtra() - { - // Already parsed? - if ((known & KNOWN_EXTRA) != 0) - return; - - if (extra == null) - { - known |= KNOWN_EXTRA; - return; - } - - try - { - int pos = 0; - while (pos < extra.length) - { - int sig = (extra[pos++] & 0xff) - | (extra[pos++] & 0xff) << 8; - int len = (extra[pos++] & 0xff) - | (extra[pos++] & 0xff) << 8; - if (sig == 0x5455) - { - /* extended time stamp */ - int flags = extra[pos]; - if ((flags & 1) != 0) - { - long time = ((extra[pos+1] & 0xff) - | (extra[pos+2] & 0xff) << 8 - | (extra[pos+3] & 0xff) << 16 - | (extra[pos+4] & 0xff) << 24); - setTime(time*1000); - } - } - pos += len; - } - } - catch (ArrayIndexOutOfBoundsException ex) - { - /* be lenient */ - } - - known |= KNOWN_EXTRA; - return; - } - - /** - * Gets the extra data. - * @return the extra data or null if not set. - */ - public byte[] getExtra() - { - return extra; - } - - /** - * Sets the entry comment. - * @exception IllegalArgumentException if comment is longer than 0xffff. - */ - public void setComment(String comment) - { - if (comment != null && comment.length() > 0xffff) - throw new IllegalArgumentException(); - this.comment = comment; - } - - /** - * Gets the comment. - * @return the comment or null if not set. - */ - public String getComment() - { - return comment; - } - - /** - * Gets true, if the entry is a directory. This is solely - * determined by the name, a trailing slash '/' marks a directory. - */ - public boolean isDirectory() - { - int nlen = name.length(); - return nlen > 0 && name.charAt(nlen - 1) == '/'; - } - - /** - * Gets the string representation of this ZipEntry. This is just - * the name as returned by getName(). - */ - public String toString() - { - return name; - } - - /** - * Gets the hashCode of this ZipEntry. This is just the hashCode - * of the name. Note that the equals method isn't changed, though. - */ - public int hashCode() - { - return name.hashCode(); - } -} diff --git a/libjava/classpath/java/util/zip/ZipException.java b/libjava/classpath/java/util/zip/ZipException.java deleted file mode 100644 index c5bfc1e..0000000 --- a/libjava/classpath/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/classpath/java/util/zip/ZipFile.java b/libjava/classpath/java/util/zip/ZipFile.java deleted file mode 100644 index b582c84..0000000 --- a/libjava/classpath/java/util/zip/ZipFile.java +++ /dev/null @@ -1,785 +0,0 @@ -/* ZipFile.java -- - Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 - 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 gnu.java.util.EmptyEnumeration; - -import java.io.EOFException; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.RandomAccessFile; -import java.io.UnsupportedEncodingException; -import java.nio.ByteBuffer; -import java.nio.charset.Charset; -import java.nio.charset.CharsetDecoder; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.LinkedHashMap; - -/** - * This class represents a Zip archive. You can ask for the contained - * entries, or get an input stream for a file entry. The entry is - * automatically decompressed. - * - * This class is thread safe: You can open input streams for arbitrary - * entries in different threads. - * - * @author Jochen Hoenicke - * @author Artur Biesiadowski - */ -public class ZipFile implements ZipConstants -{ - - /** - * Mode flag to open a zip file for reading. - */ - public static final int OPEN_READ = 0x1; - - /** - * Mode flag to delete a zip file after reading. - */ - public static final int OPEN_DELETE = 0x4; - - /** - * This field isn't defined in the JDK's ZipConstants, but should be. - */ - static final int ENDNRD = 4; - - // Name of this zip file. - private final String name; - - // File from which zip entries are read. - private final RandomAccessFile raf; - - // The entries of this zip file when initialized and not yet closed. - private LinkedHashMap<String, ZipEntry> entries; - - private boolean closed = false; - - - /** - * Helper function to open RandomAccessFile and throw the proper - * ZipException in case opening the file fails. - * - * @param name the file name, or null if file is provided - * - * @param file the file, or null if name is provided - * - * @return the newly open RandomAccessFile, never null - */ - private RandomAccessFile openFile(String name, - File file) - throws ZipException, IOException - { - try - { - return - (name != null) - ? new RandomAccessFile(name, "r") - : new RandomAccessFile(file, "r"); - } - catch (FileNotFoundException f) - { - ZipException ze = new ZipException(f.getMessage()); - ze.initCause(f); - throw ze; - } - } - - - /** - * Opens a Zip file with the given name for reading. - * @exception IOException if a i/o error occured. - * @exception ZipException if the file doesn't contain a valid zip - * archive. - */ - public ZipFile(String name) throws ZipException, IOException - { - this.raf = openFile(name,null); - this.name = name; - checkZipFile(); - } - - /** - * Opens a Zip file reading the given File. - * @exception IOException if a i/o error occured. - * @exception ZipException if the file doesn't contain a valid zip - * archive. - */ - public ZipFile(File file) throws ZipException, IOException - { - this.raf = openFile(null,file); - this.name = file.getPath(); - checkZipFile(); - } - - /** - * Opens a Zip file reading the given File in the given mode. - * - * If the OPEN_DELETE mode is specified, the zip file will be deleted at - * some time moment after it is opened. It will be deleted before the zip - * file is closed or the Virtual Machine exits. - * - * The contents of the zip file will be accessible until it is closed. - * - * @since JDK1.3 - * @param mode Must be one of OPEN_READ or OPEN_READ | OPEN_DELETE - * - * @exception IOException if a i/o error occured. - * @exception ZipException if the file doesn't contain a valid zip - * archive. - */ - public ZipFile(File file, int mode) throws ZipException, IOException - { - if (mode != OPEN_READ && mode != (OPEN_READ | OPEN_DELETE)) - throw new IllegalArgumentException("invalid mode"); - if ((mode & OPEN_DELETE) != 0) - file.deleteOnExit(); - this.raf = openFile(null,file); - this.name = file.getPath(); - checkZipFile(); - } - - private void checkZipFile() throws ZipException - { - boolean valid = false; - - try - { - byte[] buf = new byte[4]; - raf.readFully(buf); - int sig = buf[0] & 0xFF - | ((buf[1] & 0xFF) << 8) - | ((buf[2] & 0xFF) << 16) - | ((buf[3] & 0xFF) << 24); - valid = sig == LOCSIG; - } - catch (IOException _) - { - } - - if (!valid) - { - try - { - raf.close(); - } - catch (IOException _) - { - } - throw new ZipException("Not a valid zip file"); - } - } - - /** - * Checks if file is closed and throws an exception. - */ - private void checkClosed() - { - if (closed) - throw new IllegalStateException("ZipFile has closed: " + name); - } - - /** - * Read the central directory of a zip file and fill the entries - * array. This is called exactly once when first needed. It is called - * while holding the lock on <code>raf</code>. - * - * @exception IOException if a i/o error occured. - * @exception ZipException if the central directory is malformed - */ - private void readEntries() throws ZipException, IOException - { - /* Search for the End Of Central Directory. When a zip comment is - * present the directory may start earlier. - * Note that a comment has a maximum length of 64K, so that is the - * maximum we search backwards. - */ - PartialInputStream inp = new PartialInputStream(raf, 4096); - long pos = raf.length() - ENDHDR; - long top = Math.max(0, pos - 65536); - do - { - if (pos < top) - throw new ZipException - ("central directory not found, probably not a zip file: " + name); - inp.seek(pos--); - } - while (inp.readLeInt() != ENDSIG); - - if (inp.skip(ENDTOT - ENDNRD) != ENDTOT - ENDNRD) - throw new EOFException(name); - int count = inp.readLeShort(); - if (inp.skip(ENDOFF - ENDSIZ) != ENDOFF - ENDSIZ) - throw new EOFException(name); - int centralOffset = inp.readLeInt(); - - entries = new LinkedHashMap<String, ZipEntry> (count+count/2); - inp.seek(centralOffset); - - for (int i = 0; i < count; i++) - { - if (inp.readLeInt() != CENSIG) - throw new ZipException("Wrong Central Directory signature: " + name); - - inp.skip(4); - int flags = inp.readLeShort(); - if ((flags & 1) != 0) - throw new ZipException("invalid CEN header (encrypted entry)"); - int method = inp.readLeShort(); - int dostime = inp.readLeInt(); - int crc = inp.readLeInt(); - int csize = inp.readLeInt(); - int size = inp.readLeInt(); - int nameLen = inp.readLeShort(); - int extraLen = inp.readLeShort(); - int commentLen = inp.readLeShort(); - inp.skip(8); - int offset = inp.readLeInt(); - String name = inp.readString(nameLen); - - ZipEntry entry = new ZipEntry(name); - entry.setMethod(method); - entry.setCrc(crc & 0xffffffffL); - entry.setSize(size & 0xffffffffL); - entry.setCompressedSize(csize & 0xffffffffL); - entry.setDOSTime(dostime); - if (extraLen > 0) - { - byte[] extra = new byte[extraLen]; - inp.readFully(extra); - entry.setExtra(extra); - } - if (commentLen > 0) - { - entry.setComment(inp.readString(commentLen)); - } - entry.offset = offset; - entries.put(name, entry); - } - } - - /** - * Closes the ZipFile. This also closes all input streams given by - * this class. After this is called, no further method should be - * called. - * - * @exception IOException if a i/o error occured. - */ - public void close() throws IOException - { - RandomAccessFile raf = this.raf; - if (raf == null) - return; - - synchronized (raf) - { - closed = true; - entries = null; - raf.close(); - } - } - - /** - * Calls the <code>close()</code> method when this ZipFile has not yet - * been explicitly closed. - */ - protected void finalize() throws IOException - { - if (!closed && raf != null) close(); - } - - /** - * Returns an enumeration of all Zip entries in this Zip file. - * - * @exception IllegalStateException when the ZipFile has already been closed - */ - public Enumeration<? extends ZipEntry> entries() - { - checkClosed(); - - try - { - return new ZipEntryEnumeration(getEntries().values().iterator()); - } - catch (IOException ioe) - { - return new EmptyEnumeration<ZipEntry>(); - } - } - - /** - * Checks that the ZipFile is still open and reads entries when necessary. - * - * @exception IllegalStateException when the ZipFile has already been closed. - * @exception IOException when the entries could not be read. - */ - private LinkedHashMap<String, ZipEntry> getEntries() throws IOException - { - synchronized(raf) - { - checkClosed(); - - if (entries == null) - readEntries(); - - return entries; - } - } - - /** - * Searches for a zip entry in this archive with the given name. - * - * @param name the name. May contain directory components separated by - * slashes ('/'). - * @return the zip entry, or null if no entry with that name exists. - * - * @exception IllegalStateException when the ZipFile has already been closed - */ - public ZipEntry getEntry(String name) - { - checkClosed(); - - try - { - LinkedHashMap<String, ZipEntry> entries = getEntries(); - ZipEntry entry = entries.get(name); - // If we didn't find it, maybe it's a directory. - if (entry == null && !name.endsWith("/")) - entry = entries.get(name + '/'); - return entry != null ? new ZipEntry(entry, name) : null; - } - catch (IOException ioe) - { - return null; - } - } - - /** - * Creates an input stream reading the given zip entry as - * uncompressed data. Normally zip entry should be an entry - * returned by getEntry() or entries(). - * - * This implementation returns null if the requested entry does not - * exist. This decision is not obviously correct, however, it does - * appear to mirror Sun's implementation, and it is consistant with - * their javadoc. On the other hand, the old JCL book, 2nd Edition, - * claims that this should return a "non-null ZIP entry". We have - * chosen for now ignore the old book, as modern versions of Ant (an - * important application) depend on this behaviour. See discussion - * in this thread: - * http://gcc.gnu.org/ml/java-patches/2004-q2/msg00602.html - * - * @param entry the entry to create an InputStream for. - * @return the input stream, or null if the requested entry does not exist. - * - * @exception IllegalStateException when the ZipFile has already been closed - * @exception IOException if a i/o error occured. - * @exception ZipException if the Zip archive is malformed. - */ - public InputStream getInputStream(ZipEntry entry) throws IOException - { - checkClosed(); - - LinkedHashMap<String, ZipEntry> entries = getEntries(); - String name = entry.getName(); - ZipEntry zipEntry = entries.get(name); - if (zipEntry == null) - return null; - - PartialInputStream inp = new PartialInputStream(raf, 1024); - inp.seek(zipEntry.offset); - - if (inp.readLeInt() != LOCSIG) - throw new ZipException("Wrong Local header signature: " + name); - - inp.skip(4); - - if (zipEntry.getMethod() != inp.readLeShort()) - throw new ZipException("Compression method mismatch: " + name); - - inp.skip(16); - - int nameLen = inp.readLeShort(); - int extraLen = inp.readLeShort(); - inp.skip(nameLen + extraLen); - - inp.setLength(zipEntry.getCompressedSize()); - - int method = zipEntry.getMethod(); - switch (method) - { - case ZipOutputStream.STORED: - return inp; - case ZipOutputStream.DEFLATED: - inp.addDummyByte(); - final Inflater inf = new Inflater(true); - final int sz = (int) entry.getSize(); - return new InflaterInputStream(inp, inf) - { - public int available() throws IOException - { - if (sz == -1) - return super.available(); - if (super.available() != 0) - return sz - inf.getTotalOut(); - return 0; - } - }; - default: - throw new ZipException("Unknown compression method " + method); - } - } - - /** - * Returns the (path) name of this zip file. - */ - public String getName() - { - return name; - } - - /** - * Returns the number of entries in this zip file. - * - * @exception IllegalStateException when the ZipFile has already been closed - */ - public int size() - { - checkClosed(); - - try - { - return getEntries().size(); - } - catch (IOException ioe) - { - return 0; - } - } - - private static class ZipEntryEnumeration implements Enumeration<ZipEntry> - { - private final Iterator<ZipEntry> elements; - - public ZipEntryEnumeration(Iterator<ZipEntry> elements) - { - this.elements = elements; - } - - public boolean hasMoreElements() - { - return elements.hasNext(); - } - - public ZipEntry nextElement() - { - /* We return a clone, just to be safe that the user doesn't - * change the entry. - */ - return (ZipEntry) (elements.next().clone()); - } - } - - private static final class PartialInputStream extends InputStream - { - /** - * The UTF-8 charset use for decoding the filenames. - */ - private static final Charset UTF8CHARSET = Charset.forName("UTF-8"); - - /** - * The actual UTF-8 decoder. Created on demand. - */ - private CharsetDecoder utf8Decoder; - - private final RandomAccessFile raf; - private final byte[] buffer; - private long bufferOffset; - private int pos; - private long end; - // We may need to supply an extra dummy byte to our reader. - // See Inflater. We use a count here to simplify the logic - // elsewhere in this class. Note that we ignore the dummy - // byte in methods where we know it is not needed. - private int dummyByteCount; - - public PartialInputStream(RandomAccessFile raf, int bufferSize) - throws IOException - { - this.raf = raf; - buffer = new byte[bufferSize]; - bufferOffset = -buffer.length; - pos = buffer.length; - end = raf.length(); - } - - void setLength(long length) - { - end = bufferOffset + pos + length; - } - - private void fillBuffer() throws IOException - { - synchronized (raf) - { - long len = end - bufferOffset; - if (len == 0 && dummyByteCount > 0) - { - buffer[0] = 0; - dummyByteCount = 0; - } - else - { - raf.seek(bufferOffset); - raf.readFully(buffer, 0, (int) Math.min(buffer.length, len)); - } - } - } - - public int available() - { - long amount = end - (bufferOffset + pos); - if (amount > Integer.MAX_VALUE) - return Integer.MAX_VALUE; - return (int) amount; - } - - public int read() throws IOException - { - if (bufferOffset + pos >= end + dummyByteCount) - return -1; - if (pos == buffer.length) - { - bufferOffset += buffer.length; - pos = 0; - fillBuffer(); - } - - return buffer[pos++] & 0xFF; - } - - public int read(byte[] b, int off, int len) throws IOException - { - if (len > end + dummyByteCount - (bufferOffset + pos)) - { - len = (int) (end + dummyByteCount - (bufferOffset + pos)); - if (len == 0) - return -1; - } - - int totalBytesRead = Math.min(buffer.length - pos, len); - System.arraycopy(buffer, pos, b, off, totalBytesRead); - pos += totalBytesRead; - off += totalBytesRead; - len -= totalBytesRead; - - while (len > 0) - { - bufferOffset += buffer.length; - pos = 0; - fillBuffer(); - int remain = Math.min(buffer.length, len); - System.arraycopy(buffer, pos, b, off, remain); - pos += remain; - off += remain; - len -= remain; - totalBytesRead += remain; - } - - return totalBytesRead; - } - - public long skip(long amount) throws IOException - { - if (amount < 0) - return 0; - if (amount > end - (bufferOffset + pos)) - amount = end - (bufferOffset + pos); - seek(bufferOffset + pos + amount); - return amount; - } - - void seek(long newpos) throws IOException - { - long offset = newpos - bufferOffset; - if (offset >= 0 && offset <= buffer.length) - { - pos = (int) offset; - } - else - { - bufferOffset = newpos; - pos = 0; - fillBuffer(); - } - } - - void readFully(byte[] buf) throws IOException - { - if (read(buf, 0, buf.length) != buf.length) - throw new EOFException(); - } - - void readFully(byte[] buf, int off, int len) throws IOException - { - if (read(buf, off, len) != len) - throw new EOFException(); - } - - int readLeShort() throws IOException - { - int result; - if(pos + 1 < buffer.length) - { - result = ((buffer[pos + 0] & 0xff) | (buffer[pos + 1] & 0xff) << 8); - pos += 2; - } - else - { - int b0 = read(); - int b1 = read(); - if (b1 == -1) - throw new EOFException(); - result = (b0 & 0xff) | (b1 & 0xff) << 8; - } - return result; - } - - int readLeInt() throws IOException - { - int result; - if(pos + 3 < buffer.length) - { - result = (((buffer[pos + 0] & 0xff) | (buffer[pos + 1] & 0xff) << 8) - | ((buffer[pos + 2] & 0xff) - | (buffer[pos + 3] & 0xff) << 8) << 16); - pos += 4; - } - else - { - int b0 = read(); - int b1 = read(); - int b2 = read(); - int b3 = read(); - if (b3 == -1) - throw new EOFException(); - result = (((b0 & 0xff) | (b1 & 0xff) << 8) | ((b2 & 0xff) - | (b3 & 0xff) << 8) << 16); - } - return result; - } - - /** - * Decode chars from byte buffer using UTF8 encoding. This - * operation is performance-critical since a jar file contains a - * large number of strings for the name of each file in the - * archive. This routine therefore avoids using the expensive - * utf8Decoder when decoding is straightforward. - * - * @param buffer the buffer that contains the encoded character - * data - * @param pos the index in buffer of the first byte of the encoded - * data - * @param length the length of the encoded data in number of - * bytes. - * - * @return a String that contains the decoded characters. - */ - private String decodeChars(byte[] buffer, int pos, int length) - throws IOException - { - String result; - int i=length - 1; - while ((i >= 0) && (buffer[i] <= 0x7f)) - { - i--; - } - if (i < 0) - { - result = new String(buffer, 0, pos, length); - } - else - { - ByteBuffer bufferBuffer = ByteBuffer.wrap(buffer, pos, length); - if (utf8Decoder == null) - utf8Decoder = UTF8CHARSET.newDecoder(); - utf8Decoder.reset(); - char [] characters = utf8Decoder.decode(bufferBuffer).array(); - result = String.valueOf(characters); - } - return result; - } - - String readString(int length) throws IOException - { - if (length > end - (bufferOffset + pos)) - throw new EOFException(); - - String result = null; - try - { - if (buffer.length - pos >= length) - { - result = decodeChars(buffer, pos, length); - pos += length; - } - else - { - byte[] b = new byte[length]; - readFully(b); - result = decodeChars(b, 0, length); - } - } - catch (UnsupportedEncodingException uee) - { - throw new AssertionError(uee); - } - return result; - } - - public void addDummyByte() - { - dummyByteCount = 1; - } - } -} diff --git a/libjava/classpath/java/util/zip/ZipInputStream.java b/libjava/classpath/java/util/zip/ZipInputStream.java deleted file mode 100644 index 3eae026..0000000 --- a/libjava/classpath/java/util/zip/ZipInputStream.java +++ /dev/null @@ -1,381 +0,0 @@ -/* ZipInputStream.java -- - Copyright (C) 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.zip; - -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; - -/** - * 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; - try - { - name = new String(buffer, "UTF-8"); - } - catch (UnsupportedEncodingException uee) - { - throw new AssertionError(uee); - } - - 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/classpath/java/util/zip/ZipOutputStream.java b/libjava/classpath/java/util/zip/ZipOutputStream.java deleted file mode 100644 index bc1c3e9..0000000 --- a/libjava/classpath/java/util/zip/ZipOutputStream.java +++ /dev/null @@ -1,440 +0,0 @@ -/* ZipOutputStream.java -- - Copyright (C) 2001, 2004, 2005, 2006 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.io.UnsupportedEncodingException; -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; - try - { - commentBytes = comment.getBytes("UTF-8"); - } - catch (UnsupportedEncodingException uee) - { - throw new AssertionError(uee); - } - 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); - } - - /** - * Write a long value as an int. Some of the zip constants - * are declared as longs even though they fit perfectly well - * into integers. - */ - private void writeLeInt(long value) throws IOException - { - writeLeInt((int) value); - } - - /** - * 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; - try - { - name = entry.getName().getBytes("UTF-8"); - } - catch (UnsupportedEncodingException uee) - { - throw new AssertionError(uee); - } - 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; - try - { - name = entry.getName().getBytes("UTF-8"); - } - catch (UnsupportedEncodingException uee) - { - throw new AssertionError(uee); - } - if (name.length > 0xffff) - throw new ZipException("Name too long."); - byte[] extra = entry.getExtra(); - if (extra == null) - extra = new byte[0]; - String str = entry.getComment(); - byte[] comment; - try - { - comment = str != null ? str.getBytes("UTF-8") : new byte[0]; - } - catch (UnsupportedEncodingException uee) - { - throw new AssertionError(uee); - } - 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; - } -} diff --git a/libjava/classpath/java/util/zip/package.html b/libjava/classpath/java/util/zip/package.html deleted file mode 100644 index 5f3ac49..0000000 --- a/libjava/classpath/java/util/zip/package.html +++ /dev/null @@ -1,47 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> -<!-- package.html - describes classes in java.util.zip package. - 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. --> - -<html> -<head><title>GNU Classpath - java.util.zip</title></head> - -<body> -<p>Utility classes to manipulate zip and gzip archives as files or streams, -includes checksum and compression support.</p> - -</body> -</html> |