mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-16 18:40:57 +08:00
javaprims.h: Updated class declaration list.
* gcj/javaprims.h: Updated class declaration list. * Makefile.in: Rebuilt. * Makefile.am (core_java_source_files): Added PropertyPermissionCollection.java. * java/lang/Thread.java (group, name): Now package-private. * java/lang/ThreadGroup.java: Re-merge with Classpath. * java/util/AbstractList.java: Likewise. * java/util/AbstractMap.java: Likewise. * java/util/Calendar.java: Likewise. * java/util/Collections.java: Likewise. * java/util/HashMap.java: Likewise. * java/util/Hashtable.java: Likewise. * java/util/LinkedHashMap.java: Likewise. * java/util/LinkedList.java: Likewise. * java/util/List.java: Likewise. * java/util/ListResourceBundle.java: Likewise. * java/util/Map.java: Likewise. * java/util/Observable.java: Likewise. * java/util/Properties.java: Likewise. * java/util/PropertyPermission.java: Likewise. * java/util/PropertyPermissionCollection.java: Likewise. * java/util/PropertyResourceBundle.java: Likewise. * java/util/Random.java: Likewise. * java/util/SimpleTimeZone.java: Likewise. * java/util/StringTokenizer.java: Likewise. * java/util/TimerTask.java: Likewise. * java/util/TreeMap.java: Likewise. * java/util/WeakHashMap.java: Likewise. * java/util/jar/Attributes.java: Likewise. * java/util/jar/JarException.java: Likewise. * java/util/jar/Manifest.java: Likewise. From-SVN: r54743
This commit is contained in:
parent
0fd534ed06
commit
3831381763
@ -1,3 +1,37 @@
|
||||
2002-06-18 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* gcj/javaprims.h: Updated class declaration list.
|
||||
* Makefile.in: Rebuilt.
|
||||
* Makefile.am (core_java_source_files): Added
|
||||
PropertyPermissionCollection.java.
|
||||
* java/lang/Thread.java (group, name): Now package-private.
|
||||
* java/lang/ThreadGroup.java: Re-merge with Classpath.
|
||||
* java/util/AbstractList.java: Likewise.
|
||||
* java/util/AbstractMap.java: Likewise.
|
||||
* java/util/Calendar.java: Likewise.
|
||||
* java/util/Collections.java: Likewise.
|
||||
* java/util/HashMap.java: Likewise.
|
||||
* java/util/Hashtable.java: Likewise.
|
||||
* java/util/LinkedHashMap.java: Likewise.
|
||||
* java/util/LinkedList.java: Likewise.
|
||||
* java/util/List.java: Likewise.
|
||||
* java/util/ListResourceBundle.java: Likewise.
|
||||
* java/util/Map.java: Likewise.
|
||||
* java/util/Observable.java: Likewise.
|
||||
* java/util/Properties.java: Likewise.
|
||||
* java/util/PropertyPermission.java: Likewise.
|
||||
* java/util/PropertyPermissionCollection.java: Likewise.
|
||||
* java/util/PropertyResourceBundle.java: Likewise.
|
||||
* java/util/Random.java: Likewise.
|
||||
* java/util/SimpleTimeZone.java: Likewise.
|
||||
* java/util/StringTokenizer.java: Likewise.
|
||||
* java/util/TimerTask.java: Likewise.
|
||||
* java/util/TreeMap.java: Likewise.
|
||||
* java/util/WeakHashMap.java: Likewise.
|
||||
* java/util/jar/Attributes.java: Likewise.
|
||||
* java/util/jar/JarException.java: Likewise.
|
||||
* java/util/jar/Manifest.java: Likewise.
|
||||
|
||||
2002-06-17 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* gcj/javaprims.h: Updated class declaration list.
|
||||
|
@ -1220,6 +1220,7 @@ java/util/Observable.java \
|
||||
java/util/Observer.java \
|
||||
java/util/Properties.java \
|
||||
java/util/PropertyPermission.java \
|
||||
java/util/PropertyPermissionCollection.java \
|
||||
java/util/PropertyResourceBundle.java \
|
||||
java/util/Random.java \
|
||||
java/util/RandomAccess.java \
|
||||
|
@ -987,6 +987,7 @@ java/util/Observable.java \
|
||||
java/util/Observer.java \
|
||||
java/util/Properties.java \
|
||||
java/util/PropertyPermission.java \
|
||||
java/util/PropertyPermissionCollection.java \
|
||||
java/util/PropertyResourceBundle.java \
|
||||
java/util/Random.java \
|
||||
java/util/RandomAccess.java \
|
||||
@ -2550,6 +2551,7 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
|
||||
.deps/java/util/NoSuchElementException.P .deps/java/util/Observable.P \
|
||||
.deps/java/util/Observer.P .deps/java/util/Properties.P \
|
||||
.deps/java/util/PropertyPermission.P \
|
||||
.deps/java/util/PropertyPermissionCollection.P \
|
||||
.deps/java/util/PropertyResourceBundle.P .deps/java/util/Random.P \
|
||||
.deps/java/util/RandomAccess.P .deps/java/util/ResourceBundle.P \
|
||||
.deps/java/util/Set.P .deps/java/util/SimpleTimeZone.P \
|
||||
|
@ -243,6 +243,7 @@ extern "Java"
|
||||
class AbstractCollection;
|
||||
class AbstractList;
|
||||
class AbstractMap;
|
||||
class AbstractMap$BasicMapEntry;
|
||||
class AbstractSequentialList;
|
||||
class AbstractSet;
|
||||
class ArrayList;
|
||||
@ -317,11 +318,13 @@ extern "Java"
|
||||
class Map$Entry;
|
||||
class Map$Map;
|
||||
class MissingResourceException;
|
||||
class MyResources;
|
||||
class NoSuchElementException;
|
||||
class Observable;
|
||||
class Observer;
|
||||
class Properties;
|
||||
class PropertyPermission;
|
||||
class PropertyPermissionCollection;
|
||||
class PropertyResourceBundle;
|
||||
class Random;
|
||||
class RandomAccess;
|
||||
|
@ -301,8 +301,8 @@ public class Thread implements Runnable
|
||||
public static native void yield ();
|
||||
|
||||
// Private data.
|
||||
private ThreadGroup group;
|
||||
private String name;
|
||||
ThreadGroup group;
|
||||
String name;
|
||||
private Runnable runnable;
|
||||
private int priority;
|
||||
private boolean daemon_flag;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
/* AbstractList.java -- Abstract implementation of most of List
|
||||
Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@ -237,20 +237,22 @@ public abstract class AbstractList extends AbstractCollection implements List
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain 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>
|
||||
* 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)
|
||||
*/
|
||||
@ -611,19 +613,21 @@ public abstract class AbstractList extends AbstractCollection implements List
|
||||
|
||||
/**
|
||||
* This class follows the implementation requirements set forth in
|
||||
* {@link AbstractList#subList(int, int)}. Some compilers have problems
|
||||
* with AbstractList.this.modCount if this class is nested in AbstractList,
|
||||
* even though the JLS defines that to be legal, so we make it a top-level
|
||||
* class.
|
||||
* {@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>
|
||||
*/
|
||||
class SubList extends AbstractList
|
||||
{
|
||||
private final AbstractList backingList;
|
||||
private final int offset;
|
||||
private int size;
|
||||
// Package visible, for use by iterator.
|
||||
/** The original list. */
|
||||
final AbstractList backingList;
|
||||
/** The index of the first element of the sublist. */
|
||||
final int offset;
|
||||
/** The size of the sublist. */
|
||||
int size;
|
||||
|
||||
/**
|
||||
* Construct the sublist.
|
||||
@ -647,8 +651,8 @@ class SubList extends AbstractList
|
||||
* @throws ConcurrentModificationException if the backing list has been
|
||||
* modified externally to this sublist
|
||||
*/
|
||||
// This will get inlined, since it is private.
|
||||
private void checkMod()
|
||||
// This can be inlined. Package visible, for use by iterator.
|
||||
void checkMod()
|
||||
{
|
||||
if (modCount != backingList.modCount)
|
||||
throw new ConcurrentModificationException();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* AbstractMap.java -- Abstract implementation of most of Map
|
||||
Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@ -518,4 +518,130 @@ public abstract class AbstractMap implements Map
|
||||
{
|
||||
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>
|
||||
*/
|
||||
static class BasicMapEntry implements Map.Entry
|
||||
{ // XXX - FIXME Use fully qualified implements as gcj 3.1 workaround.
|
||||
/**
|
||||
* The key. Package visible for direct manipulation.
|
||||
*/
|
||||
Object key;
|
||||
|
||||
/**
|
||||
* The value. Package visible for direct manipulation.
|
||||
*/
|
||||
Object value;
|
||||
|
||||
/**
|
||||
* Basic constructor initializes the fields.
|
||||
* @param newKey the key
|
||||
* @param newValue the value
|
||||
*/
|
||||
BasicMapEntry(Object newKey, Object newValue)
|
||||
{
|
||||
key = newKey;
|
||||
value = newValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the specified object with this entry. Returns true only if
|
||||
* the object is a mapping of identical key and value. In other words,
|
||||
* this must be:
|
||||
*
|
||||
<pre>(o instanceof Map.Entry) &&
|
||||
(getKey() == null ? ((HashMap) o).getKey() == null
|
||||
: getKey().equals(((HashMap) o).getKey())) &&
|
||||
(getValue() == null ? ((HashMap) o).getValue() == null
|
||||
: getValue().equals(((HashMap) o).getValue()))</pre>
|
||||
*
|
||||
* @param o the object to compare
|
||||
*
|
||||
* @return <code>true</code> if it is equal
|
||||
*/
|
||||
public final boolean equals(Object o)
|
||||
{
|
||||
if (! (o instanceof Map.Entry))
|
||||
return false;
|
||||
// Optimize for our own entries.
|
||||
if (o instanceof BasicMapEntry)
|
||||
{
|
||||
BasicMapEntry e = (BasicMapEntry) o;
|
||||
return (AbstractMap.equals(key, e.key)
|
||||
&& AbstractMap.equals(value, e.value));
|
||||
}
|
||||
Map.Entry e = (Map.Entry) o;
|
||||
return (AbstractMap.equals(key, e.getKey())
|
||||
&& AbstractMap.equals(value, e.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the key corresponding to this entry.
|
||||
*
|
||||
* @return the key
|
||||
*/
|
||||
public final Object getKey()
|
||||
{
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value corresponding to this entry. If you already called
|
||||
* Iterator.remove(), the behavior undefined, but in this case it works.
|
||||
*
|
||||
* @return the value
|
||||
*/
|
||||
public final Object getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code of the entry. This is defined as the exclusive-or
|
||||
* of the hashcodes of the key and value (using 0 for null). In other
|
||||
* words, this must be:
|
||||
*
|
||||
<pre>(getKey() == null ? 0 : getKey().hashCode())
|
||||
^ (getValue() == null ? 0 : getValue().hashCode())</pre>
|
||||
*
|
||||
* @return the hash code
|
||||
*/
|
||||
public final int hashCode()
|
||||
{
|
||||
return (AbstractMap.hashCode(key) ^ AbstractMap.hashCode(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the value with the specified object. This writes through
|
||||
* to the map, unless you have already called Iterator.remove(). It
|
||||
* may be overridden to restrict a null value.
|
||||
*
|
||||
* @param newVal the new value to store
|
||||
* @return the old value
|
||||
* @throws NullPointerException if the map forbids null values
|
||||
*/
|
||||
public Object setValue(Object newVal)
|
||||
{
|
||||
Object r = value;
|
||||
value = newVal;
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* This provides a string representation of the entry. It is of the form
|
||||
* "key=value", where string concatenation is used on key and value.
|
||||
*
|
||||
* @return the string representation
|
||||
*/
|
||||
public final String toString()
|
||||
{
|
||||
return key + "=" + value;
|
||||
}
|
||||
} // class BasicMapEntry
|
||||
}
|
||||
|
@ -73,13 +73,12 @@ import java.io.*;
|
||||
* 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>
|
||||
*
|
||||
<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>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Collections.java -- Utility class with methods to operate on collections
|
||||
Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@ -60,7 +60,6 @@ import java.io.Serializable;
|
||||
* modify the set.
|
||||
*
|
||||
* @author Original author unknown
|
||||
* @author Bryce McKinlay
|
||||
* @author Eric Blake <ebb9@email.byu.edu>
|
||||
* @see Collection
|
||||
* @see Set
|
||||
@ -108,24 +107,6 @@ public class Collections
|
||||
*/
|
||||
public static final Set EMPTY_SET = new EmptySet();
|
||||
|
||||
private static final Iterator EMPTY_ITERATOR = new Iterator()
|
||||
{
|
||||
public boolean hasNext()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public Object next()
|
||||
{
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
public void remove()
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The implementation of {@link #EMPTY_SET}. This class name is required
|
||||
* for compatibility with Sun's JDK serializability.
|
||||
@ -158,9 +139,94 @@ public class Collections
|
||||
/**
|
||||
* Returns an iterator that does not iterate.
|
||||
*/
|
||||
// This is really cheating! I think it's perfectly valid, though.
|
||||
public Iterator iterator()
|
||||
{
|
||||
return EMPTY_ITERATOR;
|
||||
return EMPTY_LIST.iterator();
|
||||
}
|
||||
|
||||
// The remaining methods are optional, but provide a performance
|
||||
// advantage by not allocating unnecessary iterators in AbstractSet.
|
||||
/**
|
||||
* The empty set never contains anything.
|
||||
*/
|
||||
public boolean contains(Object o)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is true only if the given collection is also empty.
|
||||
*/
|
||||
public boolean containsAll(Collection c)
|
||||
{
|
||||
return c.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Equal only if the other set is empty.
|
||||
*/
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
return o instanceof Set && ((Set) o).isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* The hashcode is always 0.
|
||||
*/
|
||||
public int hashCode()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Always succeeds with false result.
|
||||
*/
|
||||
public boolean remove(Object o)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Always succeeds with false result.
|
||||
*/
|
||||
public boolean removeAll(Collection c)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Always succeeds with false result.
|
||||
*/
|
||||
public boolean retainAll(Collection c)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The array is always empty.
|
||||
*/
|
||||
public Object[] toArray()
|
||||
{
|
||||
return new Object[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* We don't even need to use reflection!
|
||||
*/
|
||||
public Object[] toArray(Object[] a)
|
||||
{
|
||||
if (a.length > 0)
|
||||
a[0] = null;
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* The string never changes.
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return "[]";
|
||||
}
|
||||
} // class EmptySet
|
||||
|
||||
@ -207,15 +273,106 @@ public class Collections
|
||||
{
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
|
||||
// The remaining methods are optional, but provide a performance
|
||||
// advantage by not allocating unnecessary iterators in AbstractList.
|
||||
/**
|
||||
* Returns an iterator that does not iterate. Optional, but avoids
|
||||
* allocation of an iterator in AbstractList.
|
||||
* Never contains anything.
|
||||
*/
|
||||
public Iterator iterator()
|
||||
public boolean contains(Object o)
|
||||
{
|
||||
return EMPTY_ITERATOR;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is true only if the given collection is also empty.
|
||||
*/
|
||||
public boolean containsAll(Collection c)
|
||||
{
|
||||
return c.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Equal only if the other set is empty.
|
||||
*/
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
return o instanceof List && ((List) o).isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* The hashcode is always 1.
|
||||
*/
|
||||
public int hashCode()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns -1.
|
||||
*/
|
||||
public int indexOf(Object o)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns -1.
|
||||
*/
|
||||
public int lastIndexOf(Object o)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Always succeeds with false result.
|
||||
*/
|
||||
public boolean remove(Object o)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Always succeeds with false result.
|
||||
*/
|
||||
public boolean removeAll(Collection c)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Always succeeds with false result.
|
||||
*/
|
||||
public boolean retainAll(Collection c)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The array is always empty.
|
||||
*/
|
||||
public Object[] toArray()
|
||||
{
|
||||
return new Object[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* We don't even need to use reflection!
|
||||
*/
|
||||
public Object[] toArray(Object[] a)
|
||||
{
|
||||
if (a.length > 0)
|
||||
a[0] = null;
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* The string never changes.
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return "[]";
|
||||
}
|
||||
} // class EmptyList
|
||||
|
||||
/**
|
||||
@ -253,6 +410,64 @@ public class Collections
|
||||
return EMPTY_SET;
|
||||
}
|
||||
|
||||
// The remaining methods are optional, but provide a performance
|
||||
// advantage by not allocating unnecessary iterators in AbstractMap.
|
||||
/**
|
||||
* No entries!
|
||||
*/
|
||||
public boolean containsKey(Object key)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* No entries!
|
||||
*/
|
||||
public boolean containsValue(Object value)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Equal to all empty maps.
|
||||
*/
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
return o instanceof Map && ((Map) o).isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* No mappings, so this returns null.
|
||||
*/
|
||||
public Object get(Object o)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The hashcode is always 0.
|
||||
*/
|
||||
public int hashCode()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* No entries.
|
||||
*/
|
||||
public Set keySet()
|
||||
{
|
||||
return EMPTY_SET;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove always succeeds, with null result.
|
||||
*/
|
||||
public Object remove(Object o)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Size is always 0.
|
||||
*/
|
||||
@ -269,8 +484,17 @@ public class Collections
|
||||
{
|
||||
return EMPTY_SET;
|
||||
}
|
||||
|
||||
/**
|
||||
* The string never changes.
|
||||
*/
|
||||
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
|
||||
@ -502,7 +726,7 @@ public class Collections
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array list holding the elements visited by a given
|
||||
* Returns an ArrayList holding the elements visited by a given
|
||||
* Enumeration. This method exists for interoperability between legacy
|
||||
* APIs and the new Collection API.
|
||||
*
|
||||
@ -511,9 +735,9 @@ public class Collections
|
||||
* @see ArrayList
|
||||
* @since 1.4
|
||||
*/
|
||||
public static List list(Enumeration e)
|
||||
public static ArrayList list(Enumeration e)
|
||||
{
|
||||
List l = new ArrayList();
|
||||
ArrayList l = new ArrayList();
|
||||
while (e.hasMoreElements())
|
||||
l.add(e.nextElement());
|
||||
return l;
|
||||
@ -1353,7 +1577,7 @@ public class Collections
|
||||
public Set entrySet()
|
||||
{
|
||||
if (entries == null)
|
||||
entries = singleton(new BasicMapEntry(k, v)
|
||||
entries = singleton(new AbstractMap.BasicMapEntry(k, v)
|
||||
{
|
||||
public Object setValue(Object o)
|
||||
{
|
||||
@ -1500,6 +1724,7 @@ public class Collections
|
||||
l.set(i, l.set(j, l.get(i)));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a synchronized (thread-safe) collection wrapper backed by the
|
||||
* given collection. Notice that element access through the iterators
|
||||
@ -2682,6 +2907,7 @@ public class Collections
|
||||
}
|
||||
} // class SynchronizedSortedSet
|
||||
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable view of the given collection. This allows
|
||||
* "read-only" access, although changes in the backing collection show up
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* HashMap.java -- a class providing a basic hashtable data structure,
|
||||
mapping Object --> Object
|
||||
Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@ -162,7 +162,7 @@ public class HashMap extends AbstractMap
|
||||
*
|
||||
* @author Eric Blake <ebb9@email.byu.edu>
|
||||
*/
|
||||
static class HashEntry extends BasicMapEntry
|
||||
static class HashEntry extends AbstractMap.BasicMapEntry
|
||||
{
|
||||
/**
|
||||
* The next entry in the linked list. Package visible for use by subclass.
|
||||
@ -373,9 +373,9 @@ public class HashMap extends AbstractMap
|
||||
{
|
||||
Map.Entry e = (Map.Entry) itr.next();
|
||||
// Optimize in case the Entry is one of our own.
|
||||
if (e instanceof BasicMapEntry)
|
||||
if (e instanceof AbstractMap.BasicMapEntry)
|
||||
{
|
||||
BasicMapEntry entry = (BasicMapEntry) e;
|
||||
AbstractMap.BasicMapEntry entry = (AbstractMap.BasicMapEntry) e;
|
||||
put(entry.key, entry.value);
|
||||
}
|
||||
else
|
||||
@ -647,7 +647,8 @@ public class HashMap extends AbstractMap
|
||||
* @return the matching entry, if found, or null
|
||||
* @see #entrySet()
|
||||
*/
|
||||
private HashEntry getEntry(Object o)
|
||||
// Package visible, for use in nested classes.
|
||||
HashEntry getEntry(Object o)
|
||||
{
|
||||
if (!(o instanceof Map.Entry))
|
||||
return null;
|
||||
@ -710,14 +711,13 @@ public class HashMap extends AbstractMap
|
||||
}
|
||||
|
||||
/**
|
||||
* 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>
|
||||
* 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.
|
||||
*
|
||||
* This is not specified, but the new size is twice the current size plus
|
||||
* one; this number is not always prime, unfortunately.
|
||||
* <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()
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Hashtable.java -- a class providing a basic hashtable data structure,
|
||||
mapping Object --> Object
|
||||
Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@ -102,6 +102,9 @@ import java.io.ObjectOutputStream;
|
||||
public class Hashtable extends Dictionary
|
||||
implements Map, Cloneable, Serializable
|
||||
{
|
||||
// WARNING: Hashtable is a CORE class in the bootstrap cycle. See the
|
||||
// comments in vm/reference/java/lang/Runtime for implications of this fact.
|
||||
|
||||
/** Default number of buckets. This is the value the JDK 1.3 uses. Some
|
||||
* early documentation specified this value as 101. That is incorrect.
|
||||
*/
|
||||
@ -176,7 +179,7 @@ public class Hashtable extends Dictionary
|
||||
* pair. A Hashtable Entry is identical to a HashMap Entry, except that
|
||||
* `null' is not allowed for keys and values.
|
||||
*/
|
||||
private static final class HashEntry extends BasicMapEntry
|
||||
private static final class HashEntry extends AbstractMap.BasicMapEntry
|
||||
{
|
||||
/** The next entry in the linked list. */
|
||||
HashEntry next;
|
||||
@ -340,9 +343,9 @@ public class Hashtable extends Dictionary
|
||||
*
|
||||
* @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 #contains(Object)
|
||||
* @see #containsKey(Object)
|
||||
* @throws NullPointerException if <code>value</code> is null
|
||||
* @since 1.2
|
||||
*/
|
||||
public boolean containsValue(Object value)
|
||||
@ -361,7 +364,7 @@ public class Hashtable extends Dictionary
|
||||
// Must throw on null argument even if the table is empty
|
||||
if (value == null)
|
||||
throw new NullPointerException();
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -511,9 +514,9 @@ public class Hashtable extends Dictionary
|
||||
{
|
||||
Map.Entry e = (Map.Entry) itr.next();
|
||||
// Optimize in case the Entry is one of our own.
|
||||
if (e instanceof BasicMapEntry)
|
||||
if (e instanceof AbstractMap.BasicMapEntry)
|
||||
{
|
||||
BasicMapEntry entry = (BasicMapEntry) e;
|
||||
AbstractMap.BasicMapEntry entry = (AbstractMap.BasicMapEntry) e;
|
||||
put(entry.key, entry.value);
|
||||
}
|
||||
else
|
||||
@ -763,9 +766,9 @@ public class Hashtable extends Dictionary
|
||||
/**
|
||||
* Returns true if this Hashtable equals the supplied Object <code>o</code>.
|
||||
* As specified by Map, this is:
|
||||
* <pre>
|
||||
* <code>
|
||||
* (o instanceof Map) && entrySet().equals(((Map) o).entrySet());
|
||||
* </pre>
|
||||
* </code>
|
||||
*
|
||||
* @param o the object to compare to
|
||||
* @return true if o is an equal map
|
||||
@ -812,7 +815,10 @@ public class Hashtable extends Dictionary
|
||||
*/
|
||||
private int hash(Object key)
|
||||
{
|
||||
return Math.abs(key.hashCode() % buckets.length);
|
||||
// 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;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -823,7 +829,8 @@ public class Hashtable extends Dictionary
|
||||
* @return the matching entry, if found, or null
|
||||
* @see #entrySet()
|
||||
*/
|
||||
private HashEntry getEntry(Object o)
|
||||
// Package visible, for use in nested classes.
|
||||
HashEntry getEntry(Object o)
|
||||
{
|
||||
if (! (o instanceof Map.Entry))
|
||||
return null;
|
||||
@ -869,7 +876,7 @@ public class Hashtable extends Dictionary
|
||||
/**
|
||||
* 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
|
||||
* size() > threshold. Note that the existing Entry objects are reused in
|
||||
* the new hash table.
|
||||
* <p>
|
||||
*
|
||||
@ -1139,4 +1146,4 @@ public class Hashtable extends Dictionary
|
||||
return type == VALUES ? e.value : e.key;
|
||||
}
|
||||
} // class Enumerator
|
||||
}
|
||||
} // class Hashtable
|
||||
|
@ -71,7 +71,7 @@ package java.util;
|
||||
* <p>
|
||||
*
|
||||
* Under ideal circumstances (no collisions), LinkedHashMap offers O(1)
|
||||
* performance on most operations (<pre>containsValue()</pre> is,
|
||||
* 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>
|
||||
@ -87,7 +87,7 @@ package java.util;
|
||||
* {@link ConcurrentModificationException} rather than exhibit
|
||||
* non-deterministic behavior.
|
||||
*
|
||||
* @author Eric Blake <ebb9@email.byu.edu>
|
||||
* @author Eric Blake (ebb9@email.byu.edu)
|
||||
* @see Object#hashCode()
|
||||
* @see Collection
|
||||
* @see Map
|
||||
@ -256,8 +256,9 @@ public class LinkedHashMap extends HashMap
|
||||
* @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)
|
||||
*
|
||||
* @throws IllegalArgumentException if (initialCapacity < 0) ||
|
||||
* ! (loadFactor > 0.0)
|
||||
*/
|
||||
public LinkedHashMap(int initialCapacity, float loadFactor,
|
||||
boolean accessOrder)
|
||||
@ -277,11 +278,12 @@ public class LinkedHashMap extends HashMap
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this HashMap contains a value <pre>o</pre>, such that
|
||||
* <pre>o.equals(value)</pre>.
|
||||
* 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 true if at least one key maps to the value
|
||||
*
|
||||
* @return <code>true</code> if at least one key maps to the value
|
||||
*/
|
||||
public boolean containsValue(Object value)
|
||||
{
|
||||
@ -297,7 +299,7 @@ public class LinkedHashMap extends HashMap
|
||||
|
||||
/**
|
||||
* Return the value in this Map associated with the supplied key,
|
||||
* or <pre>null</pre> if the key maps to nothing. If this is an
|
||||
* 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
|
||||
@ -350,14 +352,14 @@ public class LinkedHashMap extends HashMap
|
||||
* <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>
|
||||
*
|
||||
<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.
|
||||
@ -376,6 +378,7 @@ public class LinkedHashMap extends HashMap
|
||||
* returns true. For an access-order map, this is the least
|
||||
* recently accessed; for an insertion-order map, this is the
|
||||
* earliest element inserted.
|
||||
*
|
||||
* @return true if <code>eldest</code> should be removed
|
||||
*/
|
||||
protected boolean removeEldestEntry(Map.Entry eldest)
|
||||
@ -467,8 +470,10 @@ public class LinkedHashMap extends HashMap
|
||||
|
||||
/**
|
||||
* Removes from the backing HashMap the last element which was fetched
|
||||
* with the <pre>next()</pre> method.
|
||||
* 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()
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* LinkedList.java -- Linked list implementation of the List interface
|
||||
Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@ -125,12 +125,13 @@ public class LinkedList extends AbstractSequentialList
|
||||
* 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).
|
||||
* 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
|
||||
*/
|
||||
private Entry getEntry(int n)
|
||||
// Package visible for use in nested classes.
|
||||
Entry getEntry(int n)
|
||||
{
|
||||
Entry e;
|
||||
if (n < size / 2)
|
||||
@ -156,7 +157,8 @@ public class LinkedList extends AbstractSequentialList
|
||||
*
|
||||
* @param e the entry to remove
|
||||
*/
|
||||
private void removeEntry(Entry e)
|
||||
// Package visible for use in nested classes.
|
||||
void removeEntry(Entry e)
|
||||
{
|
||||
modCount++;
|
||||
size--;
|
||||
|
@ -201,7 +201,7 @@ public interface List extends Collection
|
||||
* @see Object#equals(Object)
|
||||
* @see #hashCode()
|
||||
*/
|
||||
/* boolean equals(Object o);*/
|
||||
boolean equals(Object o);
|
||||
|
||||
/**
|
||||
* Get the element at a given index in this list.
|
||||
@ -213,18 +213,20 @@ public interface List extends Collection
|
||||
Object get(int index);
|
||||
|
||||
/**
|
||||
* Obtain 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.
|
||||
* 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()
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* java.util.ListResourceBundle
|
||||
Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
|
||||
/* ListResourceBundle -- a resource bundle build around a list
|
||||
Copyright (C) 1998, 1999, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@ -39,73 +39,102 @@ 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.
|
||||
* <br>
|
||||
* The key/value list is a two dimensional list of Object. The first
|
||||
* dimension ranges over the resources. The second dimension ranges
|
||||
* from zero (key) to one (value). The keys must be of type String.
|
||||
* <br>
|
||||
* XXX Example!
|
||||
* 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
|
||||
* @author Jochen Hoenicke */
|
||||
* @since 1.1
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public abstract class ListResourceBundle extends ResourceBundle
|
||||
{
|
||||
/**
|
||||
* The constructor. It does nothing special.
|
||||
* The constructor. It does nothing special.
|
||||
*/
|
||||
public ListResourceBundle()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the key/value list. You must override this method.
|
||||
* @return a two dimensional list of Objects. The first dimension
|
||||
* ranges over the objects, and the second dimension ranges from
|
||||
* zero (key) to one (value).
|
||||
*/
|
||||
protected abstract Object[][] getContents();
|
||||
|
||||
/**
|
||||
* Override this method to provide the resource for a keys. This gets
|
||||
* called by <code>getObject</code>.
|
||||
* @param key The key of the resource.
|
||||
* @return The resource for the key or null if it doesn't exists.
|
||||
* 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();
|
||||
for (int i = 0; i < contents.length; i++)
|
||||
{
|
||||
if (key.equals(contents[i][0]))
|
||||
return contents[i][1];
|
||||
}
|
||||
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.
|
||||
*
|
||||
* @return an enumeration of the keys
|
||||
*/
|
||||
public Enumeration getKeys()
|
||||
{
|
||||
// We make a new Set that holds all the keys, then return an enumeration
|
||||
// for that. This prevents modifications from ruining the enumeration,
|
||||
// as well as ignoring duplicates.
|
||||
final Object[][] contents = getContents();
|
||||
|
||||
return new Enumeration()
|
||||
{
|
||||
int i = 0;
|
||||
public boolean hasMoreElements()
|
||||
Set s = new HashSet();
|
||||
int i = contents.length;
|
||||
while (--i >= 0)
|
||||
s.add(contents[i][0]);
|
||||
ResourceBundle bundle = parent;
|
||||
// Eliminate tail recursion.
|
||||
while (bundle != null)
|
||||
{
|
||||
return i < contents.length;
|
||||
Enumeration e = bundle.getKeys();
|
||||
while (e.hasMoreElements())
|
||||
s.add(e.nextElement());
|
||||
bundle = bundle.parent;
|
||||
}
|
||||
public Object nextElement()
|
||||
{
|
||||
return contents[i++][0];
|
||||
}
|
||||
};
|
||||
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
|
||||
|
@ -296,14 +296,14 @@ public interface Map
|
||||
*/
|
||||
public Object setValue(Object value);
|
||||
|
||||
|
||||
/**
|
||||
* Returns the hash code of the entry. This is defined as the exclusive-or
|
||||
* of the hashcodes of the key and value (using 0 for null). In other
|
||||
* words, this must be:
|
||||
* <pre>
|
||||
* (getKey() == null ? 0 : getKey().hashCode()) ^
|
||||
* (getValue() == null ? 0 : getValue().hashCode())
|
||||
* </pre>
|
||||
* 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
|
||||
*/
|
||||
@ -313,16 +313,16 @@ public interface Map
|
||||
* 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:
|
||||
* <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>
|
||||
*
|
||||
<p><pre>(o instanceof Map.Entry)
|
||||
&& (getKey() == null ? ((HashMap) o).getKey() == null
|
||||
: getKey().equals(((HashMap) o).getKey()))
|
||||
&& (getValue() == null ? ((HashMap) o).getValue() == null
|
||||
: getValue().equals(((HashMap) o).getValue()))</pre>
|
||||
*
|
||||
* @param o the object to compare
|
||||
* @return true if it is equal
|
||||
*
|
||||
* @return <code>true</code> if it is equal
|
||||
*/
|
||||
public boolean equals(Object o);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* java.util.Observable
|
||||
Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
/* Observable.java -- an object to be observed
|
||||
Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@ -38,55 +38,53 @@ 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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>
|
||||
* @date September 2, 1998.
|
||||
* @author Eric Blake <ebb9@email.byu.edu>
|
||||
* @see Observer
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public class Observable
|
||||
{
|
||||
/** tracks whether this object has changed */
|
||||
/** Tracks whether this object has changed. */
|
||||
private boolean changed;
|
||||
|
||||
/* list of the Observers registered as interested in this Observable */
|
||||
private Vector observers;
|
||||
|
||||
/* TBD: This might be better implemented as an Observer[]
|
||||
* but that would mean writing more code rather than making use of
|
||||
* the existing Vector class (this also implies a larger text code
|
||||
* space in resulting executables). The tradeoff is one of speed
|
||||
* (manipulating the Observer[] directly) vs. size/reuse. In the future,
|
||||
* we may decide to make the tradeoff and reimplement with an Observer[].
|
||||
*/
|
||||
/* List of the Observers registered as interested in this Observable. */
|
||||
private LinkedHashSet observers;
|
||||
|
||||
/**
|
||||
* Constructs an Observable with zero Observers.
|
||||
*/
|
||||
public Observable()
|
||||
{
|
||||
changed = false;
|
||||
observers = new Vector();
|
||||
observers = new LinkedHashSet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an Observer. If the observer was already added this method does
|
||||
* nothing.
|
||||
*
|
||||
* @param observer Observer to add.
|
||||
* @param observer Observer to add
|
||||
* @throws NullPointerException if observer is null
|
||||
*/
|
||||
public synchronized void addObserver(Observer observer)
|
||||
{
|
||||
if (!observers.contains(observer))
|
||||
observers.addElement(observer);
|
||||
observers.add(observer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset this Observable's state to unchanged.
|
||||
* 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()
|
||||
{
|
||||
@ -94,7 +92,9 @@ public class Observable
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Number of Observers for this Observable.
|
||||
* Returns the number of observers for this object.
|
||||
*
|
||||
* @return number of Observers for this
|
||||
*/
|
||||
public synchronized int countObservers()
|
||||
{
|
||||
@ -104,11 +104,11 @@ public class Observable
|
||||
/**
|
||||
* Deletes an Observer of this Observable.
|
||||
*
|
||||
* @param victim Observer to delete.
|
||||
* @param victim Observer to delete
|
||||
*/
|
||||
public synchronized void deleteObserver(Observer victim)
|
||||
{
|
||||
observers.removeElement(victim);
|
||||
observers.remove(victim);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -116,11 +116,14 @@ public class Observable
|
||||
*/
|
||||
public synchronized void deleteObservers()
|
||||
{
|
||||
observers.removeAllElements();
|
||||
observers.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether or not this Observable has changed.
|
||||
* 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()
|
||||
{
|
||||
@ -129,7 +132,10 @@ public class Observable
|
||||
|
||||
/**
|
||||
* If the Observable has actually changed then tell all Observers about it,
|
||||
* then resets state to unchanged.
|
||||
* then reset state to unchanged.
|
||||
*
|
||||
* @see #notifyObservers(Object)
|
||||
* @see Observer#update(Observable, Object)
|
||||
*/
|
||||
public void notifyObservers()
|
||||
{
|
||||
@ -138,21 +144,29 @@ public class Observable
|
||||
|
||||
/**
|
||||
* If the Observable has actually changed then tell all Observers about it,
|
||||
* then resets state to unchanged.
|
||||
* Note that though the order of notification is unspecified in subclasses,
|
||||
* in Observable it is in the order of registration.
|
||||
* 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 Arguement to Observer's update method.
|
||||
* @param obj argument to Observer's update method
|
||||
* @see Observer#update(Observable, Object)
|
||||
*/
|
||||
public void notifyObservers(Object obj)
|
||||
{
|
||||
if (!hasChanged())
|
||||
if (! hasChanged())
|
||||
return;
|
||||
Vector ob1 = (Vector) observers.clone();
|
||||
|
||||
for (int i = 0; i < ob1.size(); i++)
|
||||
((Observer) ob1.elementAt(i)).update(this, obj);
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* java.util.Properties
|
||||
Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
/* Properties.java -- a set of persistent properties
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@ -37,70 +37,109 @@ exception statement from your version. */
|
||||
|
||||
|
||||
package java.util;
|
||||
import java.io.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.PrintStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
|
||||
/**
|
||||
* 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 ä)
|
||||
*
|
||||
* <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>
|
||||
*
|
||||
* Although this is a sub class of a hash table, you should never
|
||||
*
|
||||
<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>.
|
||||
*
|
||||
* @see PropertyResourceBundle
|
||||
* Properties are saved in ISO 8859-1 encoding, using Unicode escapes with
|
||||
* a single <code>u</code> for any character which cannot be represented.
|
||||
*
|
||||
* @author Jochen Hoenicke
|
||||
* @author Eric Blake <ebb9@email.byu.edu>
|
||||
* @see PropertyResourceBundle
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public class Properties extends Hashtable
|
||||
{
|
||||
// WARNING: Properties is a CORE class in the bootstrap cycle. See the
|
||||
// comments in vm/reference/java/lang/Runtime for implications of this fact.
|
||||
|
||||
/**
|
||||
* The property list that contains default values for any keys not
|
||||
* in this property list.
|
||||
* 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.
|
||||
* Creates a new empty property list with no default values.
|
||||
*/
|
||||
public Properties()
|
||||
{
|
||||
this.defaults = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new empty property list with the specified default values.
|
||||
* @param defaults a Properties object containing the default values.
|
||||
*
|
||||
* @param defaults a Properties object containing the default values
|
||||
*/
|
||||
public Properties(Properties defaults)
|
||||
{
|
||||
this.defaults = defaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given key/value pair to this properties. This calls
|
||||
* the hashtable method put.
|
||||
*
|
||||
* @param key the key for this property
|
||||
* @param value the value for this property
|
||||
* @return The old value for the given key
|
||||
* @see #getProperty(String)
|
||||
* @since 1.2
|
||||
*/
|
||||
public Object setProperty(String key, String value)
|
||||
{
|
||||
return put(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a property list from an input stream. The stream should
|
||||
* have the following format: <br>
|
||||
@ -120,173 +159,176 @@ public class Properties extends Hashtable
|
||||
*
|
||||
* Escape sequences <code>\t, \n, \r, \\, \", \', \!, \#, \ </code>(a
|
||||
* space), and unicode characters with the
|
||||
* <code>\</code><code>u</code>xxxx notation are detected, and
|
||||
* <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:\<code></code>u0020
|
||||
* </pre>
|
||||
*
|
||||
<pre># This is a comment
|
||||
key = value
|
||||
k\:5 \ a string starting with space and ending with newline\n
|
||||
# This is a multiline specification; note that the value contains
|
||||
# no white space.
|
||||
weekdays: Sunday,Monday,Tuesday,Wednesday,\\
|
||||
Thursday,Friday,Saturday
|
||||
# The safest way to include a space at the end of a value:
|
||||
label = Name:\\u0020</pre>
|
||||
*
|
||||
* @param in the input stream
|
||||
* @exception IOException if an error occurred when reading
|
||||
* from the input. */
|
||||
* @throws IOException if an error occurred when reading the input
|
||||
* @throws NullPointerException if in is null
|
||||
*/
|
||||
public void load(InputStream inStream) throws IOException
|
||||
{
|
||||
// The spec says that the file must be encoded using ISO-8859-1.
|
||||
BufferedReader reader =
|
||||
new BufferedReader(new InputStreamReader(inStream, "ISO-8859-1"));
|
||||
String line;
|
||||
|
||||
|
||||
while ((line = reader.readLine()) != null)
|
||||
{
|
||||
char c = 0;
|
||||
int pos = 0;
|
||||
while (pos < line.length()
|
||||
&& Character.isWhitespace(c = line.charAt(pos)))
|
||||
pos++;
|
||||
char c = 0;
|
||||
int pos = 0;
|
||||
while (pos < line.length()
|
||||
&& Character.isWhitespace(c = line.charAt(pos)))
|
||||
pos++;
|
||||
|
||||
// If line is empty or begins with a comment character,
|
||||
// skip this line.
|
||||
if (pos == line.length() || c == '#' || c == '!')
|
||||
continue;
|
||||
// If line is empty or begins with a comment character,
|
||||
// skip this line.
|
||||
if (pos == line.length() || c == '#' || c == '!')
|
||||
continue;
|
||||
|
||||
// The characters up to the next Whitespace, ':', or '='
|
||||
// describe the key. But look for escape sequences.
|
||||
StringBuffer key = new StringBuffer();
|
||||
while (pos < line.length()
|
||||
&& !Character.isWhitespace(c = line.charAt(pos++))
|
||||
&& c != '=' && c != ':')
|
||||
{
|
||||
if (c == '\\')
|
||||
{
|
||||
if (pos == line.length())
|
||||
{
|
||||
// The line continues on the next line.
|
||||
line = reader.readLine();
|
||||
pos = 0;
|
||||
while (pos < line.length()
|
||||
&& Character.isWhitespace(c = line.charAt(pos)))
|
||||
pos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
c = line.charAt(pos++);
|
||||
switch (c)
|
||||
{
|
||||
case 'n':
|
||||
key.append('\n');
|
||||
break;
|
||||
case 't':
|
||||
key.append('\t');
|
||||
break;
|
||||
case 'r':
|
||||
key.append('\r');
|
||||
break;
|
||||
case 'u':
|
||||
if (pos + 4 <= line.length())
|
||||
{
|
||||
char uni = (char) Integer.parseInt
|
||||
(line.substring(pos, pos + 4), 16);
|
||||
key.append(uni);
|
||||
pos += 4;
|
||||
} // else throw exception?
|
||||
break;
|
||||
default:
|
||||
key.append(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
key.append(c);
|
||||
}
|
||||
// The characters up to the next Whitespace, ':', or '='
|
||||
// describe the key. But look for escape sequences.
|
||||
StringBuffer key = new StringBuffer();
|
||||
while (pos < line.length()
|
||||
&& ! Character.isWhitespace(c = line.charAt(pos++))
|
||||
&& c != '=' && c != ':')
|
||||
{
|
||||
if (c == '\\')
|
||||
{
|
||||
if (pos == line.length())
|
||||
{
|
||||
// The line continues on the next line.
|
||||
line = reader.readLine();
|
||||
pos = 0;
|
||||
while (pos < line.length()
|
||||
&& Character.isWhitespace(c = line.charAt(pos)))
|
||||
pos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
c = line.charAt(pos++);
|
||||
switch (c)
|
||||
{
|
||||
case 'n':
|
||||
key.append('\n');
|
||||
break;
|
||||
case 't':
|
||||
key.append('\t');
|
||||
break;
|
||||
case 'r':
|
||||
key.append('\r');
|
||||
break;
|
||||
case 'u':
|
||||
if (pos + 4 <= line.length())
|
||||
{
|
||||
char uni = (char) Integer.parseInt
|
||||
(line.substring(pos, pos + 4), 16);
|
||||
key.append(uni);
|
||||
pos += 4;
|
||||
} // else throw exception?
|
||||
break;
|
||||
default:
|
||||
key.append(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
key.append(c);
|
||||
}
|
||||
|
||||
boolean isDelim = (c == ':' || c == '=');
|
||||
while (pos < line.length()
|
||||
&& Character.isWhitespace(c = line.charAt(pos)))
|
||||
pos++;
|
||||
boolean isDelim = (c == ':' || c == '=');
|
||||
while (pos < line.length()
|
||||
&& Character.isWhitespace(c = line.charAt(pos)))
|
||||
pos++;
|
||||
|
||||
if (!isDelim && (c == ':' || c == '='))
|
||||
{
|
||||
pos++;
|
||||
while (pos < line.length()
|
||||
&& Character.isWhitespace(c = line.charAt(pos)))
|
||||
pos++;
|
||||
}
|
||||
if (! isDelim && (c == ':' || c == '='))
|
||||
{
|
||||
pos++;
|
||||
while (pos < line.length()
|
||||
&& Character.isWhitespace(c = line.charAt(pos)))
|
||||
pos++;
|
||||
}
|
||||
|
||||
StringBuffer element = new StringBuffer(line.length() - pos);
|
||||
while (pos < line.length())
|
||||
{
|
||||
c = line.charAt(pos++);
|
||||
if (c == '\\')
|
||||
{
|
||||
if (pos == line.length())
|
||||
{
|
||||
// The line continues on the next line.
|
||||
line = reader.readLine();
|
||||
pos = 0;
|
||||
while (pos < line.length()
|
||||
&& Character.isWhitespace(c = line.charAt(pos)))
|
||||
pos++;
|
||||
element.ensureCapacity(line.length() - pos +
|
||||
element.length());
|
||||
}
|
||||
else
|
||||
{
|
||||
c = line.charAt(pos++);
|
||||
switch (c)
|
||||
{
|
||||
case 'n':
|
||||
element.append('\n');
|
||||
break;
|
||||
case 't':
|
||||
element.append('\t');
|
||||
break;
|
||||
case 'r':
|
||||
element.append('\r');
|
||||
break;
|
||||
case 'u':
|
||||
if (pos + 4 <= line.length())
|
||||
{
|
||||
char uni = (char) Integer.parseInt
|
||||
(line.substring(pos, pos + 4), 16);
|
||||
element.append(uni);
|
||||
pos += 4;
|
||||
} // else throw exception?
|
||||
break;
|
||||
default:
|
||||
element.append(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
element.append(c);
|
||||
}
|
||||
put(key.toString(), element.toString());
|
||||
StringBuffer element = new StringBuffer(line.length() - pos);
|
||||
while (pos < line.length())
|
||||
{
|
||||
c = line.charAt(pos++);
|
||||
if (c == '\\')
|
||||
{
|
||||
if (pos == line.length())
|
||||
{
|
||||
// The line continues on the next line.
|
||||
line = reader.readLine();
|
||||
pos = 0;
|
||||
while (pos < line.length()
|
||||
&& Character.isWhitespace(c = line.charAt(pos)))
|
||||
pos++;
|
||||
element.ensureCapacity(line.length() - pos +
|
||||
element.length());
|
||||
}
|
||||
else
|
||||
{
|
||||
c = line.charAt(pos++);
|
||||
switch (c)
|
||||
{
|
||||
case 'n':
|
||||
element.append('\n');
|
||||
break;
|
||||
case 't':
|
||||
element.append('\t');
|
||||
break;
|
||||
case 'r':
|
||||
element.append('\r');
|
||||
break;
|
||||
case 'u':
|
||||
if (pos + 4 <= line.length())
|
||||
{
|
||||
char uni = (char) Integer.parseInt
|
||||
(line.substring(pos, pos + 4), 16);
|
||||
element.append(uni);
|
||||
pos += 4;
|
||||
} // else throw exception?
|
||||
break;
|
||||
default:
|
||||
element.append(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
element.append(c);
|
||||
}
|
||||
put(key.toString(), element.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls <code>store(OutputStream out, String header)</code> and
|
||||
* ignores the IOException that may be thrown.
|
||||
* @deprecated use store instead.
|
||||
* @exception ClassCastException if this property contains any key or
|
||||
* value that isn't a string.
|
||||
*
|
||||
* @param out the stream to write to
|
||||
* @param header a description of the property list
|
||||
* @throws ClassCastException if this property contains any key or
|
||||
* value that are not strings
|
||||
* @deprecated use {@link #store(OutputStream, String)} instead
|
||||
*/
|
||||
public void save(OutputStream out, String header)
|
||||
{
|
||||
try
|
||||
{
|
||||
store(out, header);
|
||||
store(out, header);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
@ -294,13 +336,14 @@ public class Properties extends Hashtable
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the key/value pairs to the given output stream. <br>
|
||||
* 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>
|
||||
* 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.
|
||||
@ -308,47 +351,42 @@ public class Properties extends Hashtable
|
||||
* 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.
|
||||
* <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.
|
||||
* @exception ClassCastException if this property contains any key or
|
||||
* value that isn't a string.
|
||||
* @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"));
|
||||
= new PrintWriter(new OutputStreamWriter(out, "ISO-8859-1"));
|
||||
if (header != null)
|
||||
writer.println("#" + header);
|
||||
writer.println("#" + new Date().toString());
|
||||
writer.println("#" + new Date());
|
||||
list(writer);
|
||||
writer.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @since JDK1.2 */
|
||||
public Object setProperty(String key, String value)
|
||||
{
|
||||
return put(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 default or the default of
|
||||
* default, null is returned.
|
||||
* @param key The key for this property.
|
||||
* @param defaulValue A default value
|
||||
* @return The value for the given key, or null if not found.
|
||||
* @exception ClassCastException if this property contains any key or
|
||||
* value that isn't a string.
|
||||
* 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)
|
||||
{
|
||||
@ -358,13 +396,16 @@ public class Properties extends Hashtable
|
||||
/**
|
||||
* 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 default or the default of default, the
|
||||
* specified defaultValue is returned.
|
||||
* @param key The key for this property.
|
||||
* @param defaulValue A default value
|
||||
* @return The value for the given key.
|
||||
* @exception ClassCastException if this property contains any key or
|
||||
* value that isn't a string.
|
||||
* 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)
|
||||
{
|
||||
@ -372,184 +413,145 @@ public class Properties extends Hashtable
|
||||
// Eliminate tail recursion.
|
||||
do
|
||||
{
|
||||
String value = (String) prop.get(key);
|
||||
if (value != null)
|
||||
return value;
|
||||
prop = prop.defaults;
|
||||
String value = (String) prop.get(key);
|
||||
if (value != null)
|
||||
return value;
|
||||
prop = prop.defaults;
|
||||
}
|
||||
while (prop != null);
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
private final void addHashEntries(Hashtable base)
|
||||
{
|
||||
if (defaults != null)
|
||||
defaults.addHashEntries(base);
|
||||
Enumeration keys = keys();
|
||||
while (keys.hasMoreElements())
|
||||
base.put(keys.nextElement(), base);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 Hashtable that holds all the keys. Then we
|
||||
// return an enumeration for this hash. We do this because we
|
||||
// don't want modifications to be reflected in the enumeration
|
||||
// (per JCL), and because there doesn't seem to be a
|
||||
// particularly better way to ensure that duplicates are
|
||||
// ignored.
|
||||
Hashtable t = new Hashtable();
|
||||
addHashEntries(t);
|
||||
return t.keys();
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a key/value pair for output in a properties file.
|
||||
* See store for a description of the format.
|
||||
* @param key the key.
|
||||
* @param value the value.
|
||||
* @see #store
|
||||
*/
|
||||
private String formatForOutput(String key, String value)
|
||||
{
|
||||
// This is a simple approximation of the expected line size.
|
||||
StringBuffer result =
|
||||
new StringBuffer(key.length() + value.length() + 16);
|
||||
boolean head = true;
|
||||
for (int i = 0; i < key.length(); i++)
|
||||
// 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
|
||||
{
|
||||
char c = key.charAt(i);
|
||||
switch (c)
|
||||
{
|
||||
case '\n':
|
||||
result.append("\\n");
|
||||
break;
|
||||
case '\r':
|
||||
result.append("\\r");
|
||||
break;
|
||||
case '\t':
|
||||
result.append("\\t");
|
||||
break;
|
||||
case '\\':
|
||||
result.append("\\\\");
|
||||
break;
|
||||
case '!':
|
||||
result.append("\\!");
|
||||
break;
|
||||
case '#':
|
||||
result.append("\\#");
|
||||
break;
|
||||
case '=':
|
||||
result.append("\\=");
|
||||
break;
|
||||
case ':':
|
||||
result.append("\\:");
|
||||
break;
|
||||
case ' ':
|
||||
result.append("\\ ");
|
||||
break;
|
||||
default:
|
||||
if (c < 32 || c > '~')
|
||||
{
|
||||
String hex = Integer.toHexString(c);
|
||||
result.append("\\u0000".substring(0, 6 - hex.length()));
|
||||
result.append(hex);
|
||||
}
|
||||
else
|
||||
result.append(c);
|
||||
}
|
||||
if (c != 32)
|
||||
head = false;
|
||||
s.addAll(prop.keySet());
|
||||
prop = prop.defaults;
|
||||
}
|
||||
result.append('=');
|
||||
head = true;
|
||||
for (int i = 0; i < value.length(); i++)
|
||||
{
|
||||
char c = value.charAt(i);
|
||||
switch (c)
|
||||
{
|
||||
case '\n':
|
||||
result.append("\\n");
|
||||
break;
|
||||
case '\r':
|
||||
result.append("\\r");
|
||||
break;
|
||||
case '\t':
|
||||
result.append("\\t");
|
||||
break;
|
||||
case '\\':
|
||||
result.append("\\\\");
|
||||
break;
|
||||
case '!':
|
||||
result.append("\\!");
|
||||
break;
|
||||
case '#':
|
||||
result.append("\\#");
|
||||
break;
|
||||
case ' ':
|
||||
result.append(head ? "\\ " : " ");
|
||||
break;
|
||||
default:
|
||||
if (c < 32 || c > '~')
|
||||
{
|
||||
String hex = Integer.toHexString(c);
|
||||
result.append("\\u0000".substring(0, 6 - hex.length()));
|
||||
result.append(hex);
|
||||
}
|
||||
else
|
||||
result.append(c);
|
||||
}
|
||||
if (c != 32)
|
||||
head = false;
|
||||
}
|
||||
return result.toString();
|
||||
while (prop != null);
|
||||
return Collections.enumeration(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the key/value pairs to the given print stream. They are
|
||||
* written in the way, described in the method store.
|
||||
* @param out the stream, where the key/value pairs are written to.
|
||||
* @exception ClassCastException if this property contains any key or
|
||||
* value that isn't a string.
|
||||
* @see #store
|
||||
* written in the way described in the method store. This does not visit
|
||||
* the keys in the default properties.
|
||||
*
|
||||
* @param out the stream, where the key/value pairs are written to
|
||||
* @throws ClassCastException if this property contains any key or
|
||||
* value that isn't a string
|
||||
* @see #store(OutputStream, String)
|
||||
*/
|
||||
public void list(PrintStream out)
|
||||
{
|
||||
Enumeration keys = keys();
|
||||
Enumeration elts = elements();
|
||||
while (keys.hasMoreElements())
|
||||
Iterator iter = entrySet().iterator();
|
||||
int i = size();
|
||||
StringBuffer s = new StringBuffer(); // Reuse the same buffer.
|
||||
while (--i >= 0)
|
||||
{
|
||||
String key = (String) keys.nextElement();
|
||||
String elt = (String) elts.nextElement();
|
||||
String output = formatForOutput(key, elt);
|
||||
out.println(output);
|
||||
Map.Entry entry = (Map.Entry) iter.next();
|
||||
formatForOutput((String) entry.getKey(), s, true);
|
||||
s.append('=');
|
||||
formatForOutput((String) entry.getValue(), s, false);
|
||||
out.println(s);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the key/value pairs to the given print writer. They are
|
||||
* written in the way, described in the method store.
|
||||
* @param out the writer, where the key/value pairs are written to.
|
||||
* @exception ClassCastException if this property contains any key or
|
||||
* value that isn't a string.
|
||||
* @see #store
|
||||
* @see #list(java.io.PrintStream)
|
||||
* @since JDK1.1
|
||||
*
|
||||
* @param out the writer, where the key/value pairs are written to
|
||||
* @throws ClassCastException if this property contains any key or
|
||||
* value that isn't a string
|
||||
* @see #store(OutputStream, String)
|
||||
* @see #list(PrintStream)
|
||||
* @since 1.1
|
||||
*/
|
||||
public void list(PrintWriter out)
|
||||
{
|
||||
Enumeration keys = keys();
|
||||
Enumeration elts = elements();
|
||||
while (keys.hasMoreElements())
|
||||
Iterator iter = entrySet().iterator();
|
||||
int i = size();
|
||||
StringBuffer s = new StringBuffer(); // Reuse the same buffer.
|
||||
while (--i >= 0)
|
||||
{
|
||||
String key = (String) keys.nextElement();
|
||||
String elt = (String) elts.nextElement();
|
||||
String output = formatForOutput(key, elt);
|
||||
out.println(output);
|
||||
Map.Entry entry = (Map.Entry) iter.next();
|
||||
formatForOutput((String) entry.getKey(), s, true);
|
||||
s.append('=');
|
||||
formatForOutput((String) entry.getValue(), s, false);
|
||||
out.println(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a key or value for output in a properties file.
|
||||
* See store for a description of the format.
|
||||
*
|
||||
* @param str the string to format
|
||||
* @param buffer the buffer to add it to
|
||||
* @param key true if all ' ' must be escaped for the key, false if only
|
||||
* leading spaces must be escaped for the value
|
||||
* @see #store(OutputStream, String)
|
||||
*/
|
||||
private void formatForOutput(String str, StringBuffer buffer, boolean key)
|
||||
{
|
||||
if (key)
|
||||
{
|
||||
buffer.setLength(0);
|
||||
buffer.ensureCapacity(str.length());
|
||||
}
|
||||
else
|
||||
buffer.ensureCapacity(buffer.length() + str.length());
|
||||
boolean head = true;
|
||||
int size = str.length();
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
char c = str.charAt(i);
|
||||
switch (c)
|
||||
{
|
||||
case '\n':
|
||||
buffer.append("\\n");
|
||||
break;
|
||||
case '\r':
|
||||
buffer.append("\\r");
|
||||
break;
|
||||
case '\t':
|
||||
buffer.append("\\t");
|
||||
break;
|
||||
case ' ':
|
||||
buffer.append(head ? "\\ " : " ");
|
||||
break;
|
||||
case '\\':
|
||||
case '!':
|
||||
case '#':
|
||||
case '=':
|
||||
case ':':
|
||||
buffer.append('\\').append(c);
|
||||
default:
|
||||
if (c < ' ' || c > '~')
|
||||
{
|
||||
String hex = Integer.toHexString(c);
|
||||
buffer.append("\\u0000".substring(0, 6 - hex.length()));
|
||||
buffer.append(hex);
|
||||
}
|
||||
else
|
||||
buffer.append(c);
|
||||
}
|
||||
if (c != ' ')
|
||||
head = key;
|
||||
}
|
||||
}
|
||||
} // class Properties
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* java.util.PropertyPermission
|
||||
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
|
||||
/* PropertyPermission.java -- permission to get and set System properties
|
||||
Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@ -37,6 +37,7 @@ exception statement from your version. */
|
||||
|
||||
|
||||
package java.util;
|
||||
|
||||
import java.security.Permission;
|
||||
import java.security.BasicPermission;
|
||||
import java.security.PermissionCollection;
|
||||
@ -49,135 +50,107 @@ import java.io.IOException;
|
||||
* 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>
|
||||
* use an asterisk "*" as described in BasicPermission.<br>
|
||||
*
|
||||
* The action string is a comma-separated list if keywords. There are
|
||||
* The action string is a comma-separated list of keywords. There are
|
||||
* two possible actions:
|
||||
* <dl>
|
||||
* <dt>read</dt>
|
||||
* <dt>read</dt>
|
||||
* <dd>Allows to read the property via <code>System.getProperty</code>.</dd>
|
||||
* <dt>write</dt>
|
||||
* <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
|
||||
* @author Jochen Hoenicke
|
||||
* @see SecurityManager
|
||||
* @author Jochen Hoenicke
|
||||
* @since 1.2
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public final class PropertyPermission extends BasicPermission
|
||||
{
|
||||
/**
|
||||
* @serialField action String
|
||||
* The action string.
|
||||
* 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;
|
||||
private transient int actions;
|
||||
|
||||
/** 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 witha he specified property. Possible
|
||||
* actions are read and write.
|
||||
* @param name the name of the property.
|
||||
* @param actions the action string.
|
||||
* @exception IllegalArgumentException if name string contains an
|
||||
* illegal wildcard or actions string contains an illegal action
|
||||
* 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.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the action string and convert actions from external to internal
|
||||
* form. This will set the internal actions field.
|
||||
* @param actions the action string.
|
||||
* @exception IllegalArgumentException if actions string contains an
|
||||
* illegal action */
|
||||
private void setActions(String actions)
|
||||
{
|
||||
this.actions = 0;
|
||||
StringTokenizer actionTokenizer = new StringTokenizer(actions, ",");
|
||||
while (actionTokenizer.hasMoreElements())
|
||||
{
|
||||
String anAction = actionTokenizer.nextToken();
|
||||
if ("read".equals(anAction))
|
||||
this.actions |= READ;
|
||||
else if ("write".equals(anAction))
|
||||
this.actions |= WRITE;
|
||||
else
|
||||
throw new IllegalArgumentException("illegal action " + anAction);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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>
|
||||
*/
|
||||
public boolean implies(Permission p)
|
||||
{
|
||||
if (!(p instanceof PropertyPermission))
|
||||
return false;
|
||||
|
||||
// We have to check the actions.
|
||||
PropertyPermission pp = (PropertyPermission) p;
|
||||
if ((pp.actions & ~actions) != 0)
|
||||
return false;
|
||||
|
||||
// BasicPermission checks for name.
|
||||
if (!super.implies(p))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public String getActions()
|
||||
{
|
||||
return actionStrings[actions];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see whether this object is the same as another
|
||||
* PropertyPermission object.
|
||||
*
|
||||
* @param obj The other object
|
||||
* @param str the action string
|
||||
* @throws IllegalArgumentException if actions string contains an
|
||||
* illegal action
|
||||
*/
|
||||
public boolean equals (Object obj)
|
||||
private void setActions(String str)
|
||||
{
|
||||
if (! (obj instanceof PropertyPermission))
|
||||
return false;
|
||||
PropertyPermission p = (PropertyPermission) obj;
|
||||
return actions == p.actions && super.equals (p);
|
||||
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
|
||||
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
|
||||
@ -189,6 +162,9 @@ public final class PropertyPermission extends BasicPermission
|
||||
/**
|
||||
* 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
|
||||
{
|
||||
@ -197,66 +173,75 @@ public final class PropertyPermission extends BasicPermission
|
||||
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.
|
||||
*
|
||||
* @return a new empty PermissionCollection
|
||||
*/
|
||||
public PermissionCollection newPermissionCollection()
|
||||
{
|
||||
return new PermissionCollection()
|
||||
{
|
||||
Hashtable permissions = new Hashtable();
|
||||
int allActions = 0;
|
||||
|
||||
public void add(Permission permission)
|
||||
{
|
||||
if (isReadOnly())
|
||||
throw new IllegalStateException("readonly");
|
||||
|
||||
// also check that permission is of correct type.
|
||||
PropertyPermission pp = (PropertyPermission) permission;
|
||||
String name = pp.getName();
|
||||
if (name.equals("*"))
|
||||
allActions |= pp.actions;
|
||||
permissions.put(name, pp);
|
||||
}
|
||||
|
||||
public boolean implies(Permission permission)
|
||||
{
|
||||
if (!(permission instanceof PropertyPermission))
|
||||
return false;
|
||||
|
||||
PropertyPermission toImply = (PropertyPermission) permission;
|
||||
if ((toImply.actions & ~allActions) == 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 && (toImply.actions & ~forName.actions) == 0)
|
||||
return true;
|
||||
|
||||
prefixLength = name.lastIndexOf('.', prefixLength);
|
||||
if (prefixLength < 0)
|
||||
return false;
|
||||
name = name.substring(0, prefixLength + 1) + '*';
|
||||
}
|
||||
}
|
||||
|
||||
public Enumeration elements()
|
||||
{
|
||||
return permissions.elements();
|
||||
}
|
||||
};
|
||||
return new PropertyPermissionCollection();
|
||||
}
|
||||
}
|
||||
|
164
libjava/java/util/PropertyPermissionCollection.java
Normal file
164
libjava/java/util/PropertyPermissionCollection.java
Normal file
@ -0,0 +1,164 @@
|
||||
/* PropertyPermissionCollection.java -- a collection of PropertyPermissions
|
||||
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., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the 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:
|
||||
* <p>
|
||||
<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);
|
||||
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();
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/* java.util.PropertyResourceBundle
|
||||
Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
|
||||
/* 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.
|
||||
|
||||
@ -38,11 +38,13 @@ exception statement from your version. */
|
||||
|
||||
package java.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import gnu.java.util.DoubleEnumeration;
|
||||
|
||||
/**
|
||||
* This class is a concrete <code>ResourceBundle</code> that gets it
|
||||
* resources from a property file. This implies that the resources are
|
||||
* resources from a property file. This implies that the resources are
|
||||
* strings. For more information about resource bundles see the class
|
||||
* <code>ResourceBundle</code>.
|
||||
*
|
||||
@ -52,75 +54,68 @@ import gnu.java.util.DoubleEnumeration;
|
||||
* file.
|
||||
*
|
||||
* If there is also a class for this resource and the same locale, the
|
||||
* class does win.
|
||||
*
|
||||
* The properties file should have the name of the resource bundle,
|
||||
* appended with the locale (e.g. <code>_de</code) and the extension
|
||||
* <code>.properties</code>. The file should have the same format
|
||||
* 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>
|
||||
*
|
||||
* XXX- move this to properties.
|
||||
* The file should have the following
|
||||
* format: An empty line or a line starting with <code>#</code> is
|
||||
* ignored. An backslash (<code>\</code>) at the end of the line
|
||||
* makes the line continueing on the next line. Otherwise, each line
|
||||
* describes a key/value pair. The chars up to the first whitespace,
|
||||
* = or : are the key. The key is followed by one or more
|
||||
* whitespaces, <code>=</code> or <code>:</code>. The rest of the
|
||||
* line is the resource belonging to the key. You can give unicode
|
||||
* characters with the <code>\\uxxxx</code> notation, where
|
||||
* <code>xxxx</code> is the hex encoding of the 16 bit unicode char
|
||||
* number.
|
||||
*
|
||||
* An example of a properties file for the german language is given
|
||||
* here. This extends the example given in ListResourceBundle.
|
||||
* here. This extends the example given in ListResourceBundle.
|
||||
* Create a file MyResource_de.properties with the following contents
|
||||
* and put it in the CLASSPATH. (The char <code>\u00e4<char> is the
|
||||
* and put it in the CLASSPATH. (The char <code>\u00e4<char> is the
|
||||
* german ä)
|
||||
*
|
||||
* <pre>
|
||||
* s1=3
|
||||
* s2=MeineDisk
|
||||
* s3=3. M\u00e4rz 96
|
||||
* s4=Die Diskette ''{1}'' enth\u00e4lt {0} in {2}.
|
||||
* s5=0
|
||||
* s6=keine Dateien
|
||||
* s7=1
|
||||
* s8=eine Datei
|
||||
* s9=2
|
||||
* s10={0,number} Dateien
|
||||
* s11=Die Formatierung warf eine Exception: {0}
|
||||
* s12=FEHLER
|
||||
* s13=Ergebnis
|
||||
* s14=Dialog
|
||||
* s15=Auswahlkriterium
|
||||
* s16=1,3
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
<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()
|
||||
* @author Jochen Hoenicke */
|
||||
* @since 1.1
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public class PropertyResourceBundle extends ResourceBundle
|
||||
{
|
||||
Properties properties;
|
||||
/** The properties file this bundle is based on. */
|
||||
private Properties properties;
|
||||
|
||||
/**
|
||||
* Creates a new property resource bundle.
|
||||
* @param stream An input stream, where the resources are read from.
|
||||
*
|
||||
* @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(java.io.InputStream stream)
|
||||
throws java.io.IOException
|
||||
public PropertyResourceBundle(InputStream stream) throws IOException
|
||||
{
|
||||
properties = new Properties();
|
||||
properties.load(stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by <code>getObject</code> when a resource is needed. This
|
||||
* Called by <code>getObject</code> when a resource is needed. This
|
||||
* returns the resource given by the key.
|
||||
* @param key The key of the resource.
|
||||
* @return The resource for the key or null if it doesn't exists.
|
||||
*
|
||||
* @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)
|
||||
{
|
||||
@ -129,16 +124,30 @@ public class PropertyResourceBundle extends ResourceBundle
|
||||
|
||||
/**
|
||||
* This method should return all keys for which a resource exists.
|
||||
* @return An enumeration of the keys.
|
||||
*
|
||||
* @return an enumeration of the keys
|
||||
*/
|
||||
public Enumeration getKeys()
|
||||
{
|
||||
// We must also return the keys of our parent.
|
||||
if (parent != null)
|
||||
if (parent == null)
|
||||
return properties.propertyNames();
|
||||
// We make a new Set that holds all the keys, then return an enumeration
|
||||
// for that. This prevents modifications from ruining the enumeration,
|
||||
// as well as ignoring duplicates.
|
||||
Set s = new HashSet();
|
||||
Enumeration e = properties.propertyNames();
|
||||
while (e.hasMoreElements())
|
||||
s.add(e.nextElement());
|
||||
ResourceBundle bundle = parent;
|
||||
// Eliminate tail recursion.
|
||||
do
|
||||
{
|
||||
return new DoubleEnumeration(properties.propertyNames(),
|
||||
parent.getKeys());
|
||||
e = bundle.getKeys();
|
||||
while (e.hasMoreElements())
|
||||
s.add(e.nextElement());
|
||||
bundle = bundle.parent;
|
||||
}
|
||||
return properties.propertyNames();
|
||||
while (bundle != null);
|
||||
return Collections.enumeration(s);
|
||||
}
|
||||
}
|
||||
} // class PropertyResourceBundle
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* java.util.Random
|
||||
Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
/* 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.
|
||||
|
||||
@ -38,13 +38,16 @@ 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.
|
||||
* 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
|
||||
@ -57,7 +60,7 @@ package java.util;
|
||||
* <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
|
||||
* 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.
|
||||
*
|
||||
@ -66,51 +69,65 @@ package java.util;
|
||||
*
|
||||
* @see java.security.SecureRandom
|
||||
* @see Math#random()
|
||||
* @author Jochen Hoenicke */
|
||||
public class Random implements java.io.Serializable
|
||||
* @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.
|
||||
* @see #nextGaussian. */
|
||||
* and returns the second on the second call.
|
||||
*
|
||||
* @serial whether nextNextGaussian is available
|
||||
* @see #nextGaussian()
|
||||
* @see #nextNextGaussian
|
||||
*/
|
||||
private boolean haveNextNextGaussian;
|
||||
|
||||
/**
|
||||
* The next nextGaussian if available. This is used by nextGaussian,
|
||||
* 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.
|
||||
* @see #nextGaussian.
|
||||
*
|
||||
* @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.
|
||||
* @see #next
|
||||
*
|
||||
* @serial the internal state of this generator
|
||||
* @see #next()
|
||||
*/
|
||||
private long seed;
|
||||
|
||||
/**
|
||||
* Compatible with JDK 1.0+.
|
||||
*/
|
||||
private static final long serialVersionUID = 3905348978240129619L;
|
||||
|
||||
/**
|
||||
* Creates a new pseudorandom number generator. The seed is initialized
|
||||
* to the current time as follows.
|
||||
* <pre>
|
||||
* setSeed(System.currentTimeMillis());
|
||||
* </pre>
|
||||
* to the current time, as if by
|
||||
* <code>setSeed(System.currentTimeMillis());</code>.
|
||||
*
|
||||
* @see System#currentTimeMillis()
|
||||
*/
|
||||
public Random()
|
||||
{
|
||||
setSeed(System.currentTimeMillis());
|
||||
this(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new pseudorandom number generator, starting with the
|
||||
* specified seed. This does:
|
||||
* <pre>
|
||||
* setSeed(seed);
|
||||
* </pre>
|
||||
* @param seed the initial seed.
|
||||
* specified seed, using <code>setSeed(seed);</code>.
|
||||
*
|
||||
* @param seed the initial seed
|
||||
*/
|
||||
public Random(long seed)
|
||||
{
|
||||
@ -122,12 +139,14 @@ public class Random implements java.io.Serializable
|
||||
* 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>
|
||||
*
|
||||
<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)
|
||||
{
|
||||
@ -140,20 +159,18 @@ public class Random implements java.io.Serializable
|
||||
* an int value whose <code>bits</code> low order bits are
|
||||
* independent chosen random bits (0 and 1 are equally likely).
|
||||
* The implementation for java.util.Random is:
|
||||
* <pre>
|
||||
* protected synchronized int next(int bits) {
|
||||
* seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
|
||||
* return (int) (seed >>> (48 - bits));
|
||||
* }
|
||||
* </pre>
|
||||
* @param bits the number of random bits to generate. Must be in range
|
||||
* 1..32.
|
||||
* @return the next pseudorandom value.
|
||||
* @since JDK1.1
|
||||
*
|
||||
<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)
|
||||
/*{ require { 1 <= bits && bits <=32 ::
|
||||
"bits "+bits+" not in range [1..32]" } } */
|
||||
{
|
||||
seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
|
||||
return (int) (seed >>> (48 - bits));
|
||||
@ -163,42 +180,45 @@ public class Random implements java.io.Serializable
|
||||
* Fills an array of bytes with random numbers. All possible values
|
||||
* are (approximately) equally likely.
|
||||
* The JDK documentation gives no implementation, but it seems to be:
|
||||
* <pre>
|
||||
* public void nextBytes(byte[] bytes) {
|
||||
* for (int i=0; i< bytes.length; i+=4) {
|
||||
* int random = next(32);
|
||||
* for (int j=0; i+j< bytes.length && j<4; j++)
|
||||
* bytes[i+j] = (byte) (random & 0xff)
|
||||
* random >>= 8;
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
* @param bytes The byte array that should be filled.
|
||||
* @since JDK1.1
|
||||
*
|
||||
<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)
|
||||
/*{ require { bytes != null :: "bytes is null"; } } */
|
||||
{
|
||||
int random;
|
||||
/* Do a little bit unrolling of the above algorithm. */
|
||||
// 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);
|
||||
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;
|
||||
}
|
||||
random = next(32);
|
||||
for (int j = max; j < bytes.length; j++)
|
||||
{
|
||||
bytes[j] = (byte) random;
|
||||
random >>= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -207,13 +227,14 @@ public class Random implements java.io.Serializable
|
||||
* 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>
|
||||
*
|
||||
<pre>public int nextInt()
|
||||
{
|
||||
return next(32);
|
||||
}</pre>
|
||||
*
|
||||
* @return the next pseudorandom value. */
|
||||
* @return the next pseudorandom value
|
||||
*/
|
||||
public int nextInt()
|
||||
{
|
||||
return next(32);
|
||||
@ -225,51 +246,58 @@ public class Random implements java.io.Serializable
|
||||
* each value has the same likelihodd (1/<code>n</code>).
|
||||
* (0 and 1 are equally likely). The implementation for
|
||||
* java.util.Random is:
|
||||
* <pre>
|
||||
* public int nextInt(int n) {
|
||||
* if (n<=0)
|
||||
* throw new IllegalArgumentException("n must be positive");
|
||||
* if ((n & -n) == n) // i.e., n is a power of 2
|
||||
* return (int)((n * (long)next(31)) >> 31);
|
||||
* int bits, val;
|
||||
* do {
|
||||
* bits = next(32);
|
||||
* val = bits % n;
|
||||
* } while(bits - val + (n-1) < 0);
|
||||
* return val;
|
||||
* }
|
||||
* </pre>
|
||||
* This algorithm would return every value with exactly the same
|
||||
*
|
||||
<pre>
|
||||
public int nextInt(int n)
|
||||
{
|
||||
if (n <= 0)
|
||||
throw new IllegalArgumentException("n must be positive");
|
||||
|
||||
if ((n & -n) == n) // i.e., n is a power of 2
|
||||
return (int)((n * (long) next(31)) >> 31);
|
||||
|
||||
int bits, val;
|
||||
do
|
||||
{
|
||||
bits = next(32);
|
||||
val = bits % n;
|
||||
}
|
||||
while(bits - val + (n-1) < 0);
|
||||
|
||||
return val;
|
||||
}</pre>
|
||||
*
|
||||
* <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 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
|
||||
* number generators (like the one used in this class) are known to be
|
||||
* ``less random'' than the high order bits.
|
||||
*
|
||||
* @param n the upper bound.
|
||||
* @exception IllegalArgumentException if the given upper bound is negative
|
||||
* @return the next pseudorandom value.
|
||||
* @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)
|
||||
/*{ require { n > 0 :: "n must be positive"; } } */
|
||||
{
|
||||
if (n <= 0)
|
||||
throw new IllegalArgumentException("n must be positive");
|
||||
if ((n & -n) == n) // i.e., n is a power of 2
|
||||
if ((n & -n) == n) // i.e., n is a power of 2
|
||||
return (int) ((n * (long) next(31)) >> 31);
|
||||
int bits, val;
|
||||
do
|
||||
{
|
||||
bits = next(32);
|
||||
val = bits % n;
|
||||
bits = next(32);
|
||||
val = bits % n;
|
||||
}
|
||||
while (bits - val + (n - 1) < 0);
|
||||
return val;
|
||||
@ -279,12 +307,13 @@ public class Random implements java.io.Serializable
|
||||
* 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.
|
||||
*
|
||||
<pre>public long nextLong()
|
||||
{
|
||||
return ((long) next(32) << 32) + next(32);
|
||||
}</pre>
|
||||
*
|
||||
* @return the next pseudorandom value
|
||||
*/
|
||||
public long nextLong()
|
||||
{
|
||||
@ -294,12 +323,14 @@ public class Random implements java.io.Serializable
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
<pre>public boolean nextBoolean()
|
||||
{
|
||||
return next(1) != 0;
|
||||
}</pre>
|
||||
*
|
||||
* @return the next pseudorandom boolean
|
||||
* @since 1.2
|
||||
*/
|
||||
public boolean nextBoolean()
|
||||
{
|
||||
@ -308,83 +339,91 @@ public class Random implements java.io.Serializable
|
||||
|
||||
/**
|
||||
* Generates the next pseudorandom float uniformly distributed
|
||||
* between 0.0f (inclusive) and 1.0 (exclusive). The
|
||||
* 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. */
|
||||
*
|
||||
<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));
|
||||
return next(24) / (float) (1 << 24);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the next pseudorandom double uniformly distributed
|
||||
* between 0.0f (inclusive) and 1.0 (exclusive). The
|
||||
* 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)(1 << 53);
|
||||
* }
|
||||
* </pre>
|
||||
* @return the next pseudorandom double. */
|
||||
*
|
||||
<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
|
||||
* Generates the next pseudorandom, Gaussian (normally) distributed
|
||||
* double value, with mean 0.0 and standard deviation 1.0.
|
||||
* The algorithm is as follows.
|
||||
* <pre>
|
||||
* public synchronized double nextGaussian() {
|
||||
* if (haveNextNextGaussian) {
|
||||
* haveNextNextGaussian = false;
|
||||
* return nextNextGaussian;
|
||||
* } else {
|
||||
* double v1, v2, s;
|
||||
* do {
|
||||
* v1 = 2 * nextDouble() - 1; // between -1.0 and 1.0
|
||||
* v2 = 2 * nextDouble() - 1; // between -1.0 and 1.0
|
||||
* s = v1 * v1 + v2 * v2;
|
||||
* } while (s >= 1);
|
||||
* double norm = Math.sqrt(-2 * Math.log(s)/s);
|
||||
* nextNextGaussian = v2 * norm;
|
||||
* haveNextNextGaussian = true;
|
||||
* return v1 * norm;
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
* This is described in section 3.4.1 of <em>The Art of Computer
|
||||
*
|
||||
<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.
|
||||
* @return the next pseudorandom Gaussian distributed double
|
||||
*/
|
||||
public synchronized double nextGaussian()
|
||||
{
|
||||
if (haveNextNextGaussian)
|
||||
{
|
||||
haveNextNextGaussian = false;
|
||||
return nextNextGaussian;
|
||||
haveNextNextGaussian = false;
|
||||
return nextNextGaussian;
|
||||
}
|
||||
else
|
||||
double v1, v2, s;
|
||||
do
|
||||
{
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,8 @@ import java.text.DateFormatSymbols;
|
||||
*
|
||||
* @see Calendar
|
||||
* @see GregorianCalender
|
||||
* @author Jochen Hoenicke */
|
||||
* @author Jochen Hoenicke
|
||||
*/
|
||||
public class SimpleTimeZone extends TimeZone
|
||||
{
|
||||
/**
|
||||
@ -436,9 +437,9 @@ public class SimpleTimeZone extends TimeZone
|
||||
* 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:
|
||||
* <pre>
|
||||
* offset = cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET);
|
||||
* </pre>
|
||||
* <code>offset = cal.get(Calendar.ZONE_OFFSET)
|
||||
* + cal.get(Calendar.DST_OFFSET);</code>
|
||||
*
|
||||
* You could also use in
|
||||
*
|
||||
* This version doesn't suffer this inaccuracy.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* java.util.StringTokenizer
|
||||
Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
|
||||
/* StringTokenizer -- breaks a String into tokens
|
||||
Copyright (C) 1998, 1999, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@ -39,75 +39,79 @@ exception statement from your version. */
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* This class splits a string into tokens. The caller can set on which
|
||||
* 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.
|
||||
* returned. This is much simpler than {@link java.io.StreamTokenizer}.
|
||||
*
|
||||
* You may change the delimiter set on the fly by calling
|
||||
* <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 returned.
|
||||
* after the last token are candidates for being returned.
|
||||
*
|
||||
* If you want to get the delimiters, you have to use the three argument
|
||||
* <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.
|
||||
* single character.
|
||||
*
|
||||
* @author Jochen Hoenicke
|
||||
* @author Warren Levy <warrenl@cygnus.com>
|
||||
* @see java.io.StreamTokenizer
|
||||
* @status updated to 1.4
|
||||
*/
|
||||
public class StringTokenizer implements Enumeration
|
||||
{
|
||||
// WARNING: StringTokenizer is a CORE class in the bootstrap cycle. See the
|
||||
// comments in vm/reference/java/lang/Runtime for implications of this fact.
|
||||
|
||||
/**
|
||||
* The position in the str, where we currently are.
|
||||
*/
|
||||
private int pos;
|
||||
|
||||
/**
|
||||
* The string that should be split into tokens.
|
||||
*/
|
||||
private String str;
|
||||
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 boolean retDelims;
|
||||
|
||||
/*{
|
||||
invariant {
|
||||
pos >= 0 :: "position is negative";
|
||||
pos <= str.length() :: "position is out of string";
|
||||
str != null :: "String is null";
|
||||
delim != null :: "Delimiters are null";
|
||||
}
|
||||
} */
|
||||
private final boolean retDelims;
|
||||
|
||||
/**
|
||||
* Creates a new StringTokenizer for the string <code>str</code>,
|
||||
* that should split on the default delimiter set (space, tap,
|
||||
* 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.
|
||||
*
|
||||
* @param str The string to split
|
||||
* @throws NullPointerException if str is null
|
||||
*/
|
||||
public StringTokenizer(String str)
|
||||
/*{ require { str != null :: "str must not be null"; } } */
|
||||
{
|
||||
this(str, " \t\n\r\f", false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new StringTokenizer, that splits the given string on
|
||||
* 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.
|
||||
* @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)
|
||||
/*{ require { str != null :: "str must not be null";
|
||||
delim != null :: "delim must not be null"; } } */
|
||||
{
|
||||
this(str, delim, false);
|
||||
}
|
||||
@ -119,34 +123,34 @@ public class StringTokenizer implements Enumeration
|
||||
* 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.
|
||||
* @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)
|
||||
/*{ require { str != null :: "str must not be null";
|
||||
delim != null :: "delim must not be null"; } } */
|
||||
{
|
||||
len = str.length();
|
||||
this.str = str;
|
||||
this.delim = delim;
|
||||
// The toString() hack causes the NullPointerException.
|
||||
this.delim = delim.toString();
|
||||
this.retDelims = returnDelims;
|
||||
this.pos = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells if there are more tokens.
|
||||
* @return True, if the next call of nextToken() succeeds, false otherwise.
|
||||
*
|
||||
* @return true if the next call of nextToken() will succeed
|
||||
*/
|
||||
public boolean hasMoreTokens()
|
||||
{
|
||||
if (!retDelims)
|
||||
if (! retDelims)
|
||||
{
|
||||
while (pos < str.length() && delim.indexOf(str.charAt(pos)) > -1)
|
||||
{
|
||||
pos++;
|
||||
}
|
||||
while (pos < len && delim.indexOf(str.charAt(pos)) >= 0)
|
||||
pos++;
|
||||
}
|
||||
return pos < str.length();
|
||||
return pos < len;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -154,13 +158,13 @@ public class StringTokenizer implements Enumeration
|
||||
* <code>delim</code>. The change of the delimiter set is
|
||||
* permanent, ie. the next call of nextToken(), uses the same
|
||||
* delimiter set.
|
||||
* @param delim a string containing the new delimiter characters.
|
||||
* @return the next token with respect to the new delimiter characters.
|
||||
* @exception NoSuchElementException if there are no more tokens.
|
||||
*
|
||||
* @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
|
||||
/*{ require { hasMoreTokens() :: "no more Tokens available";
|
||||
ensure { $return != null && $return.length() > 0; } } */
|
||||
{
|
||||
this.delim = delim;
|
||||
return nextToken();
|
||||
@ -168,32 +172,24 @@ public class StringTokenizer implements Enumeration
|
||||
|
||||
/**
|
||||
* Returns the nextToken of the string.
|
||||
* @param delim a string containing the new delimiter characters.
|
||||
* @return the next token with respect to the new delimiter characters.
|
||||
* @exception NoSuchElementException if there are no more tokens.
|
||||
*
|
||||
* @return the next token with respect to the current delimiter characters
|
||||
* @throws NoSuchElementException if there are no more tokens
|
||||
*/
|
||||
public String nextToken() throws NoSuchElementException
|
||||
/*{ require { hasMoreTokens() :: "no more Tokens available";
|
||||
ensure { $return != null && $return.length() > 0; } } */
|
||||
{
|
||||
if (pos < str.length() && delim.indexOf(str.charAt(pos)) > -1)
|
||||
if (pos < len && delim.indexOf(str.charAt(pos)) >= 0)
|
||||
{
|
||||
if (retDelims)
|
||||
return str.substring(pos, ++pos);
|
||||
|
||||
while (++pos < str.length() && delim.indexOf(str.charAt(pos)) > -1)
|
||||
{
|
||||
/* empty */
|
||||
}
|
||||
if (retDelims)
|
||||
return str.substring(pos, ++pos);
|
||||
while (++pos < len && delim.indexOf(str.charAt(pos)) >= 0);
|
||||
}
|
||||
if (pos < str.length())
|
||||
if (pos < len)
|
||||
{
|
||||
int start = pos;
|
||||
while (++pos < str.length() && delim.indexOf(str.charAt(pos)) == -1)
|
||||
{
|
||||
/* empty */
|
||||
}
|
||||
return str.substring(start, pos);
|
||||
int start = pos;
|
||||
while (++pos < len && delim.indexOf(str.charAt(pos)) < 0);
|
||||
|
||||
return str.substring(start, pos);
|
||||
}
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
@ -201,9 +197,9 @@ public class StringTokenizer implements Enumeration
|
||||
/**
|
||||
* This does the same as hasMoreTokens. This is the
|
||||
* <code>Enumeration</code interface method.
|
||||
* @return True, if the next call of nextElement() succeeds, false
|
||||
* otherwise.
|
||||
* @see #hasMoreTokens
|
||||
*
|
||||
* @return true, if the next call of nextElement() will succeed
|
||||
* @see #hasMoreTokens()
|
||||
*/
|
||||
public boolean hasMoreElements()
|
||||
{
|
||||
@ -213,9 +209,10 @@ public class StringTokenizer implements Enumeration
|
||||
/**
|
||||
* This does the same as nextTokens. This is the
|
||||
* <code>Enumeration</code interface method.
|
||||
* @return the next token with respect to the new delimiter characters.
|
||||
* @exception NoSuchElementException if there are no more tokens.
|
||||
* @see #nextToken
|
||||
*
|
||||
* @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
|
||||
{
|
||||
@ -225,49 +222,47 @@ public class StringTokenizer implements Enumeration
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* @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
|
||||
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 < str.length())
|
||||
while (tmpPos < len)
|
||||
{
|
||||
if (delim.indexOf(str.charAt(tmpPos++)) > -1)
|
||||
{
|
||||
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 < str.length()
|
||||
&& delim.indexOf(str.charAt(tmpPos)) == -1)
|
||||
++tmpPos;
|
||||
}
|
||||
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
|
||||
// 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
|
||||
|
@ -44,11 +44,11 @@ package java.util;
|
||||
* it should have been scheduled and cancel itself when no longer needed.
|
||||
* <p>
|
||||
* Example:
|
||||
* <code>
|
||||
* <pre>
|
||||
* Timer timer = new Timer();
|
||||
* TimerTask task = new TimerTask() {
|
||||
* public void run() {
|
||||
* if (this.scheduledExecutionTime() < System.currentTimeMillis() + 500)
|
||||
* if (this.scheduledExecutionTime() < System.currentTimeMillis() + 500)
|
||||
* // Do something
|
||||
* else
|
||||
* // Complain: We are more then half a second late!
|
||||
@ -56,7 +56,7 @@ package java.util;
|
||||
* this.cancel(); // This was our last execution
|
||||
* };
|
||||
* timer.scheduleAtFixedRate(task, 1000, 1000); // schedule every second
|
||||
* </code>
|
||||
* </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,
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* TreeMap.java -- a class providing a basic Red-Black Tree data structure,
|
||||
mapping Object --> Object
|
||||
Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
@ -162,7 +162,7 @@ public class TreeMap extends AbstractMap
|
||||
*
|
||||
* @author Eric Blake <ebb9@email.byu.edu>
|
||||
*/
|
||||
private static final class Node extends BasicMapEntry
|
||||
private static final class Node extends AbstractMap.BasicMapEntry
|
||||
{
|
||||
// All fields package visible for use by nested classes.
|
||||
/** The color of this node. */
|
||||
@ -623,8 +623,10 @@ public class TreeMap extends AbstractMap
|
||||
Node n = getNode(key);
|
||||
if (n == nil)
|
||||
return null;
|
||||
// Note: removeNode can alter the contents of n, so save value now.
|
||||
Object result = n.value;
|
||||
removeNode(n);
|
||||
return n.value;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1768,7 +1770,7 @@ public class TreeMap extends AbstractMap
|
||||
SubMap.this.clear();
|
||||
}
|
||||
};
|
||||
return this.keys;
|
||||
return this.values;
|
||||
}
|
||||
} // class SubMap
|
||||
} // class TreeMap
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* java.util.WeakHashMap -- a hashtable that keeps only weak references
|
||||
/* WeakHashMap -- a hashtable that keeps only weak references
|
||||
to its keys, allowing the virtual machine to reclaim them
|
||||
Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
@ -43,41 +43,41 @@ import java.lang.ref.WeakReference;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
|
||||
/**
|
||||
* A weak hash map has only weak references to the key. This means
|
||||
* that it allows the key to be garbage collected if they are not used
|
||||
* otherwise. If this happens, the weak hash map will eventually
|
||||
* remove the whole entry from this map. <br>
|
||||
* 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.
|
||||
*
|
||||
* A weak hash map makes most sense, if the keys doesn't override the
|
||||
* <code>equals</code>-method: If there is no other reference to the
|
||||
* <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, if the <code>equals</code>
|
||||
* method is overloaded, e.g. with Strings as keys, but you should be
|
||||
* prepared that some entries disappear spontaneously. <br>
|
||||
* 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.
|
||||
*
|
||||
* You should also be prepared that this hash map behaves very
|
||||
* strange: 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
|
||||
* synchronizations. The entry set returned by <code>entrySet</code>
|
||||
* <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. <br>
|
||||
* entry, that was in the set before, suddenly disappears.
|
||||
*
|
||||
* A weak hash map is not meant for caches; use a normal map, with
|
||||
* soft references as values instead, or try {@link LinkedHashMap}. <br>
|
||||
* <p>A weak hash map is not meant for caches; use a normal map, with
|
||||
* soft references as values instead, or try {@link LinkedHashMap}.
|
||||
*
|
||||
* 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. <br>
|
||||
* <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.
|
||||
*
|
||||
* The value objects are strongly referenced by this table. So if a
|
||||
* <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 Eric Blake (ebb9@email.byu.edu)
|
||||
*
|
||||
* @see HashMap
|
||||
* @see WeakReference
|
||||
* @see LinkedHashMap
|
||||
@ -86,6 +86,9 @@ import java.lang.ref.ReferenceQueue;
|
||||
*/
|
||||
public class WeakHashMap extends AbstractMap implements Map
|
||||
{
|
||||
// WARNING: WeakHashMap is a CORE class in the bootstrap cycle. See the
|
||||
// comments in vm/reference/java/lang/Runtime for implications of this fact.
|
||||
|
||||
/**
|
||||
* The default capacity for an instance of HashMap.
|
||||
* Sun's documentation mildly suggests that this (11) is the correct
|
||||
@ -148,7 +151,7 @@ public class WeakHashMap extends AbstractMap implements Map
|
||||
/**
|
||||
* 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 <pre>rehash()</pre>.
|
||||
* threshold, the HashMap calls <code>rehash()</code>.
|
||||
*/
|
||||
private int threshold;
|
||||
|
||||
@ -364,11 +367,11 @@ public class WeakHashMap extends AbstractMap implements Map
|
||||
|
||||
/**
|
||||
* The slot of this entry. This should be
|
||||
* <pre>
|
||||
* Math.abs(key.hashCode() % buckets.length)
|
||||
* </pre>
|
||||
* <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.
|
||||
*/
|
||||
@ -503,9 +506,10 @@ public class WeakHashMap extends AbstractMap implements Map
|
||||
private final WeakEntrySet theEntrySet;
|
||||
|
||||
/**
|
||||
* The hash buckets. These are linked lists.
|
||||
* The hash buckets. These are linked lists. Package visible for use in
|
||||
* nested classes.
|
||||
*/
|
||||
private WeakBucket[] buckets;
|
||||
WeakBucket[] buckets;
|
||||
|
||||
/**
|
||||
* Creates a new weak hash map with default load factor and default
|
||||
@ -676,10 +680,12 @@ public class WeakHashMap extends AbstractMap implements Map
|
||||
|
||||
/**
|
||||
* 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)
|
||||
* (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.
|
||||
*/
|
||||
private void internalRemove(WeakBucket bucket)
|
||||
void internalRemove(WeakBucket bucket)
|
||||
{
|
||||
int slot = bucket.slot;
|
||||
if (slot == -1)
|
||||
@ -870,4 +876,4 @@ public class WeakHashMap extends AbstractMap implements Map
|
||||
cleanQueue();
|
||||
return super.values();
|
||||
}
|
||||
}
|
||||
} // class WeakHashMap
|
||||
|
@ -430,7 +430,7 @@ public class Attributes implements Cloneable, Map
|
||||
* @returns the old value of the attribute name or null if it didn't exist
|
||||
* yet
|
||||
*/
|
||||
private String putValue(Name name, String value)
|
||||
String putValue(Name name, String value)
|
||||
{
|
||||
return (String) put(name, value);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Attributes.java -- exception thrown to indicate an problem with a jar file
|
||||
Copyright (C) 2000 Free Software Foundation, Inc.
|
||||
/* 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.
|
||||
|
||||
@ -41,35 +41,34 @@ import java.util.zip.ZipException;
|
||||
|
||||
/**
|
||||
* This exception is thrown to indicate an problem with a jar file.
|
||||
* It can be constructed with or without a descriptive message of the problem.
|
||||
* <p>
|
||||
* 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.
|
||||
*
|
||||
* @since 1.2
|
||||
*
|
||||
* @author Mark Wielaard (mark@klomp.org)
|
||||
* @since 1.2
|
||||
*/
|
||||
|
||||
public class JarException extends ZipException
|
||||
{
|
||||
// Constructors
|
||||
/**
|
||||
* Compatible with JDK 1.2+.
|
||||
*/
|
||||
private static final long serialVersionUID = 7159778400963954473L;
|
||||
|
||||
/**
|
||||
* Create a new JarException without a descriptive error message.
|
||||
*/
|
||||
public JarException()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @see java.lang.Throwable@getMessage()
|
||||
*
|
||||
* @param message The descriptive error message
|
||||
* @see #getMessage()
|
||||
*/
|
||||
public JarException(String message)
|
||||
{
|
||||
|
@ -174,10 +174,19 @@ public class Manifest implements Cloneable
|
||||
private static void read_main_section(Attributes attr,
|
||||
BufferedReader br) throws IOException
|
||||
{
|
||||
read_version_info(attr, br);
|
||||
// According to the spec we should actually call read_version_info() here.
|
||||
read_attributes(attr, br);
|
||||
// Explicitly set Manifest-Version attribute if not set in Main
|
||||
// attributes of Manifest.
|
||||
if (attr.getValue(Attributes.Name.MANIFEST_VERSION) == null)
|
||||
attr.putValue(Attributes.Name.MANIFEST_VERSION, "0.0");
|
||||
}
|
||||
|
||||
/**
|
||||
* Pedantic method that requires the next attribute in the Manifest to be
|
||||
* the "Manifest-Version". This follows the Manifest spec closely but
|
||||
* reject some jar Manifest files out in the wild.
|
||||
*/
|
||||
private static void read_version_info(Attributes attr,
|
||||
BufferedReader br) throws IOException
|
||||
{
|
||||
@ -185,7 +194,7 @@ public class Manifest implements Cloneable
|
||||
try
|
||||
{
|
||||
String value = expect_header(version_header, br);
|
||||
attr.putValue(version_header, value);
|
||||
attr.putValue(Attributes.Name.MANIFEST_VERSION, value);
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user