diff options
Diffstat (limited to 'libjava/classpath/java/lang')
35 files changed, 2379 insertions, 145 deletions
diff --git a/libjava/classpath/java/lang/Boolean.java b/libjava/classpath/java/lang/Boolean.java index 902c93b..2399252 100644 --- a/libjava/classpath/java/lang/Boolean.java +++ b/libjava/classpath/java/lang/Boolean.java @@ -1,5 +1,5 @@ /* Boolean.java -- object wrapper for boolean - Copyright (C) 1998, 2001, 2002, 2005 Free Software Foundation, Inc. + Copyright (C) 1998, 2001, 2002, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -47,9 +47,9 @@ import java.io.Serializable; * @author Paul Fisher * @author Eric Blake (ebb9@email.byu.edu) * @since 1.0 - * @status updated to 1.4 + * @status updated to 1.5 */ -public final class Boolean implements Serializable +public final class Boolean implements Serializable, Comparable { /** * Compatible with JDK 1.0.2+. @@ -223,34 +223,37 @@ public final class Boolean implements Serializable } /** - * If the String argument is "true", ignoring case, return true. - * Otherwise, return false. + * Compares this Boolean to another. * - * @param b String to parse + * @param other the Boolean to compare this Boolean to + * @return 0 if both Booleans represent the same value, a positive number + * if this Boolean represents true and the other false, and a negative + * number otherwise. * @since 1.5 */ - public static boolean parseBoolean(String b) + public int compareTo(Boolean other) { - return "true".equalsIgnoreCase(b) ? true : false; + return value == other.value ? 0 : (value ? 1 : -1); } - + /** - * Compares this Boolean to another. - * @param b the Boolean to compare this Boolean to - * @return 0 if both Booleans represent the same value, a positive number - * if this Boolean represents true and b represents false, or a negative - * number otherwise. + * Bridge method + */ + public int compareTo(Object other) + { + return compareTo((Boolean)other); + } + + /** + * If the String argument is "true", ignoring case, return true. + * Otherwise, return false. + * + * @param b String to parse * @since 1.5 */ - public int compareTo (Boolean b) + public static boolean parseBoolean(String b) { - if (b == null) - throw new NullPointerException("argument passed to compareTo(Boolean) cannot be null"); - - if (this.value == b.value) - return 0; - if (this.value == true) - return 1; - return -1; + return "true".equalsIgnoreCase(b) ? true : false; } + } diff --git a/libjava/classpath/java/lang/Character.java b/libjava/classpath/java/lang/Character.java index 98ad147..59ae12f 100644 --- a/libjava/classpath/java/lang/Character.java +++ b/libjava/classpath/java/lang/Character.java @@ -47,7 +47,7 @@ import java.util.Locale; /** * Wrapper class for the primitive char data type. In addition, this class * allows one to retrieve property information and perform transformations - * on the 57,707 defined characters in the Unicode Standard, Version 3.0.0. + * on the defined characters in the Unicode Standard, Version 4.0.0. * java.lang.Character is designed to be very dynamic, and as such, it * retrieves information on the Unicode character set from a separate * database, gnu.java.lang.CharData, which can be easily upgraded. @@ -55,7 +55,7 @@ import java.util.Locale; * <p>For predicates, boundaries are used to describe * the set of characters for which the method will return true. * This syntax uses fairly normal regular expression notation. - * See 5.13 of the Unicode Standard, Version 3.0, for the + * See 5.13 of the Unicode Standard, Version 4.0, for the * boundary specification. * * <p>See <a href="http://www.unicode.org">http://www.unicode.org</a> diff --git a/libjava/classpath/java/lang/Class.java b/libjava/classpath/java/lang/Class.java index c4235e6..090ac23 100644 --- a/libjava/classpath/java/lang/Class.java +++ b/libjava/classpath/java/lang/Class.java @@ -1,5 +1,5 @@ /* Class.java -- Representation of a Java class. - Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005 + Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006 Free Software Foundation This file is part of GNU Classpath. @@ -39,17 +39,25 @@ exception statement from your version. */ package java.lang; import gnu.classpath.VMStackWalker; +import gnu.java.lang.reflect.ClassSignatureParser; import java.io.InputStream; import java.io.ObjectStreamClass; import java.io.Serializable; +import java.lang.annotation.Annotation; import java.lang.reflect.Array; +import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Constructor; import java.lang.reflect.Field; +import java.lang.reflect.GenericDeclaration; +import java.lang.reflect.GenericSignatureFormatError; import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.MalformedParameterizedTypeException; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; import java.net.URL; import java.security.AccessController; import java.security.AllPermission; @@ -87,17 +95,37 @@ import java.util.HashSet; * * @author John Keiser * @author Eric Blake (ebb9@email.byu.edu) + * @author Tom Tromey (tromey@redhat.com) + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) * @author Tom Tromey (tromey@cygnus.com) * @since 1.0 * @see ClassLoader */ -public final class Class implements Serializable +public final class Class + implements Serializable, Type, AnnotatedElement, GenericDeclaration { /** * Compatible with JDK 1.0+. */ private static final long serialVersionUID = 3206093459760846163L; + /** + * Flag indicating a synthetic member. + * Note that this duplicates a constant in Modifier. + */ + private static final int SYNTHETIC = 0x1000; + + /** + * Flag indiciating an annotation class. + */ + private static final int ANNOTATION = 0x2000; + + /** + * Flag indicating an enum constant or an enum class. + * Note that this duplicates a constant in Modifier. + */ + private static final int ENUM = 0x4000; + /** The class signers. */ private Object[] signers = null; /** The class protection domain. */ @@ -259,7 +287,7 @@ public final class Class implements Serializable ClassLoader loader = VMClass.getClassLoader(this); // Check if we may get the classloader SecurityManager sm = SecurityManager.current; - if (sm != null) + if (loader != null && sm != null) { // Get the calling classloader ClassLoader cl = VMStackWalker.getCallingClassLoader(); @@ -631,17 +659,16 @@ public final class Class implements Serializable public boolean equals(Object o) { - if(o instanceof MethodKey) + if (o instanceof MethodKey) { - MethodKey m = (MethodKey)o; - if(m.name.equals(name) && m.params.length == params.length && m.returnType == returnType) + MethodKey m = (MethodKey) o; + if (m.name.equals(name) && m.params.length == params.length + && m.returnType == returnType) { - for(int i = 0; i < params.length; i++) + for (int i = 0; i < params.length; i++) { - if(m.params[i] != params[i]) - { - return false; - } + if (m.params[i] != params[i]) + return false; } return true; } @@ -1252,8 +1279,60 @@ public final class Class implements Serializable } /** - * Like <code>getField(String)</code> but without the security checks and returns null - * instead of throwing NoSuchFieldException. + * <p> + * Casts this class to represent a subclass of the specified class. + * This method is useful for `narrowing' the type of a class so that + * the class object, and instances of that class, can match the contract + * of a more restrictive method. For example, if this class has the + * static type of <code>Class<Object></code>, and a dynamic type of + * <code>Class<Rectangle></code>, then, assuming <code>Shape</code> is + * a superclass of <code>Rectangle</code>, this method can be used on + * this class with the parameter, <code>Class<Shape></code>, to retain + * the same instance but with the type + * <code>Class<? extends Shape></code>. + * </p> + * <p> + * If this class can be converted to an instance which is parameterised + * over a subtype of the supplied type, <code>U</code>, then this method + * returns an appropriately cast reference to this object. Otherwise, + * a <code>ClassCastException</code> is thrown. + * </p> + * + * @param klass the class object, the parameterized type (<code>U</code>) of + * which should be a superclass of the parameterized type of + * this instance. + * @return a reference to this object, appropriately cast. + * @throws ClassCastException if this class can not be converted to one + * which represents a subclass of the specified + * type, <code>U</code>. + * @since 1.5 + */ + /* FIXME[GENERICS]: Should be <U> Class<? extends U> asSubClass(Class<U> klass */ + public Class asSubclass(Class klass) + { + if (! klass.isAssignableFrom(this)) + throw new ClassCastException(); + return this; /* FIXME[GENERICS]: Should cast to Class<? extends U> */ + } + + /** + * Returns the specified object, cast to this <code>Class</code>' type. + * + * @param obj the object to cast + * @throws ClassCastException if obj is not an instance of this class + * @since 1.5 + */ + /* FIXME[GENERICS]: Should be T cast(Object obj) */ + public Object cast(Object obj) + { + if (obj != null && ! isInstance(obj)) + throw new ClassCastException(); + return obj; /* FIXME[GENERICS]: Should be cast to T */ + } + + /** + * Like <code>getField(String)</code> but without the security checks and + * returns null instead of throwing NoSuchFieldException. */ private Field internalGetField(String name) { @@ -1306,4 +1385,411 @@ public final class Class implements Serializable sm.checkPackageAccess(pkg.getName()); } } + + /** + * Returns the enumeration constants of this class, or + * null if this class is not an <code>Enum</code>. + * + * @return an array of <code>Enum</code> constants + * associated with this class, or null if this + * class is not an <code>enum</code>. + * @since 1.5 + */ + /* FIXME[GENERICS]: T[] getEnumConstants() */ + public Object[] getEnumConstants() + { + if (isEnum()) + { + try + { + return (Object[]) + getMethod("values", new Class[0]).invoke(null, new Object[0]); + } + catch (NoSuchMethodException exception) + { + throw new Error("Enum lacks values() method"); + } + catch (IllegalAccessException exception) + { + throw new Error("Unable to access Enum class"); + } + catch (InvocationTargetException exception) + { + throw new + RuntimeException("The values method threw an exception", + exception); + } + } + else + { + return null; + } + } + + /** + * Returns true if this class is an <code>Enum</code>. + * + * @return true if this is an enumeration class. + * @since 1.5 + */ + public boolean isEnum() + { + int mod = VMClass.getModifiers (this, true); + return (mod & ENUM) != 0; + } + + /** + * Returns true if this class is a synthetic class, generated by + * the compiler. + * + * @return true if this is a synthetic class. + * @since 1.5 + */ + public boolean isSynthetic() + { + int mod = VMClass.getModifiers (this, true); + return (mod & SYNTHETIC) != 0; + } + + /** + * Returns true if this class is an <code>Annotation</code>. + * + * @return true if this is an annotation class. + * @since 1.5 + */ + public boolean isAnnotation() + { + int mod = VMClass.getModifiers (this, true); + return (mod & ANNOTATION) != 0; + } + + /** + * Returns the simple name for this class, as used in the source + * code. For normal classes, this is the content returned by + * <code>getName()</code> which follows the last ".". Anonymous + * classes have no name, and so the result of calling this method is + * "". The simple name of an array consists of the simple name of + * its component type, followed by "[]". Thus, an array with the + * component type of an anonymous class has a simple name of simply + * "[]". + * + * @return the simple name for this class. + * @since 1.5 + */ + public String getSimpleName() + { + return VMClass.getSimpleName(this); + } + + /** + * Returns this class' annotation for the specified annotation type, + * or <code>null</code> if no such annotation exists. + * + * @param annotationClass the type of annotation to look for. + * @return this class' annotation for the specified type, or + * <code>null</code> if no such annotation exists. + * @since 1.5 + */ + /* FIXME[GENERICS]: <T extends Annotation> T getAnnotation(Class <T>) */ + public Annotation getAnnotation(Class annotationClass) + { + Annotation foundAnnotation = null; + Annotation[] annotations = getAnnotations(); + for (int i = 0; i < annotations.length; i++) + if (annotations[i].annotationType() == annotationClass) + foundAnnotation = annotations[i]; + return foundAnnotation; + } + + /** + * Returns all annotations associated with this class. If there are + * no annotations associated with this class, then a zero-length array + * will be returned. The returned array may be modified by the client + * code, but this will have no effect on the annotation content of this + * class, and hence no effect on the return value of this method for + * future callers. + * + * @return this class' annotations. + * @since 1.5 + */ + public Annotation[] getAnnotations() + { + HashSet set = new HashSet(); + set.addAll(Arrays.asList(getDeclaredAnnotations())); + Class[] interfaces = getInterfaces(); + for (int i = 0; i < interfaces.length; i++) + set.addAll(Arrays.asList(interfaces[i].getAnnotations())); + Class superClass = getSuperclass(); + if (superClass != null) + set.addAll(Arrays.asList(superClass.getAnnotations())); + return (Annotation[]) set.toArray(new Annotation[set.size()]); + } + + /** + * <p> + * Returns the canonical name of this class, as defined by section + * 6.7 of the Java language specification. Each package, top-level class, + * top-level interface and primitive type has a canonical name. A member + * class has a canonical name, if its parent class has one. Likewise, + * an array type has a canonical name, if its component type does. + * Local or anonymous classes do not have canonical names. + * </p> + * <p> + * The canonical name for top-level classes, top-level interfaces and + * primitive types is always the same as the fully-qualified name. + * For array types, the canonical name is the canonical name of its + * component type with `[]' appended. + * </p> + * <p> + * The canonical name of a member class always refers to the place where + * the class was defined, and is composed of the canonical name of the + * defining class and the simple name of the member class, joined by `.'. + * For example, if a <code>Person</code> class has an inner class, + * <code>M</code>, then both its fully-qualified name and canonical name + * is <code>Person.M</code>. A subclass, <code>Staff</code>, of + * <code>Person</code> refers to the same inner class by the fully-qualified + * name of <code>Staff.M</code>, but its canonical name is still + * <code>Person.M</code>. + * </p> + * <p> + * Where no canonical name is present, <code>null</code> is returned. + * </p> + * + * @return the canonical name of the class, or <code>null</code> if the + * class doesn't have a canonical name. + * @since 1.5 + */ + public String getCanonicalName() + { + return VMClass.getCanonicalName(this); + } + + /** + * Returns all annotations directly defined by this class. If there are + * no annotations associated with this class, then a zero-length array + * will be returned. The returned array may be modified by the client + * code, but this will have no effect on the annotation content of this + * class, and hence no effect on the return value of this method for + * future callers. + * + * @return the annotations directly defined by this class. + * @since 1.5 + */ + public Annotation[] getDeclaredAnnotations() + { + return VMClass.getDeclaredAnnotations(this); + } + + /** + * Returns the class which immediately encloses this class. If this class + * is a top-level class, this method returns <code>null</code>. + * + * @return the immediate enclosing class, or <code>null</code> if this is + * a top-level class. + * @since 1.5 + */ + /* FIXME[GENERICS]: Should return Class<?> */ + public Class getEnclosingClass() + { + return VMClass.getEnclosingClass(this); + } + + /** + * Returns the constructor which immediately encloses this class. If + * this class is a top-level class, or a local or anonymous class + * immediately enclosed by a type definition, instance initializer + * or static initializer, then <code>null</code> is returned. + * + * @return the immediate enclosing constructor if this class is + * declared within a constructor. Otherwise, <code>null</code> + * is returned. + * @since 1.5 + */ + /* FIXME[GENERICS]: Should return Constructor<?> */ + public Constructor getEnclosingConstructor() + { + return VMClass.getEnclosingConstructor(this); + } + + /** + * Returns the method which immediately encloses this class. If + * this class is a top-level class, or a local or anonymous class + * immediately enclosed by a type definition, instance initializer + * or static initializer, then <code>null</code> is returned. + * + * @return the immediate enclosing method if this class is + * declared within a method. Otherwise, <code>null</code> + * is returned. + * @since 1.5 + */ + public Method getEnclosingMethod() + { + return VMClass.getEnclosingMethod(this); + } + + /** + * <p> + * Returns an array of <code>Type</code> objects which represent the + * interfaces directly implemented by this class or extended by this + * interface. + * </p> + * <p> + * If one of the superinterfaces is a parameterized type, then the + * object returned for this interface reflects the actual type + * parameters used in the source code. Type parameters are created + * using the semantics specified by the <code>ParameterizedType</code> + * interface, and only if an instance has not already been created. + * </p> + * <p> + * The order of the interfaces in the array matches the order in which + * the interfaces are declared. For classes which represent an array, + * an array of two interfaces, <code>Cloneable</code> and + * <code>Serializable</code>, is always returned, with the objects in + * that order. A class representing a primitive type or void always + * returns an array of zero size. + * </p> + * + * @return an array of interfaces implemented or extended by this class. + * @throws GenericSignatureFormatError if the generic signature of one + * of the interfaces does not comply with that specified by the Java + * Virtual Machine specification, 3rd edition. + * @throws TypeNotPresentException if any of the superinterfaces refers + * to a non-existant type. + * @throws MalformedParameterizedTypeException if any of the interfaces + * refer to a parameterized type that can not be instantiated for + * some reason. + * @since 1.5 + * @see java.lang.reflect.ParameterizedType + */ + public Type[] getGenericInterfaces() + { + if (isPrimitive()) + return new Type[0]; + + String sig = VMClass.getClassSignature(this); + if (sig == null) + return getInterfaces(); + + ClassSignatureParser p = new ClassSignatureParser(this, sig); + return p.getInterfaceTypes(); + } + + /** + * <p> + * Returns a <code>Type</code> object representing the direct superclass, + * whether class, interface, primitive type or void, of this class. + * If this class is an array class, then a class instance representing + * the <code>Object</code> class is returned. If this class is primitive, + * an interface, or a representation of either the <code>Object</code> + * class or void, then <code>null</code> is returned. + * </p> + * <p> + * If the superclass is a parameterized type, then the + * object returned for this interface reflects the actual type + * parameters used in the source code. Type parameters are created + * using the semantics specified by the <code>ParameterizedType</code> + * interface, and only if an instance has not already been created. + * </p> + * + * @return the superclass of this class. + * @throws GenericSignatureFormatError if the generic signature of the + * class does not comply with that specified by the Java + * Virtual Machine specification, 3rd edition. + * @throws TypeNotPresentException if the superclass refers + * to a non-existant type. + * @throws MalformedParameterizedTypeException if the superclass + * refers to a parameterized type that can not be instantiated for + * some reason. + * @since 1.5 + * @see java.lang.reflect.ParameterizedType + */ + public Type getGenericSuperclass() + { + if (isArray()) + return Object.class; + + if (isPrimitive() || isInterface() || this == Object.class) + return null; + + String sig = VMClass.getClassSignature(this); + if (sig == null) + return getSuperclass(); + + ClassSignatureParser p = new ClassSignatureParser(this, sig); + return p.getSuperclassType(); + } + + /** + * Returns an array of <code>TypeVariable</code> objects that represents + * the type variables declared by this class, in declaration order. + * An array of size zero is returned if this class has no type + * variables. + * + * @return the type variables associated with this class. + * @throws GenericSignatureFormatError if the generic signature does + * not conform to the format specified in the Virtual Machine + * specification, version 3. + * @since 1.5 + */ + /* FIXME[GENERICS]: Should return TypeVariable<Class<T>> */ + public TypeVariable[] getTypeParameters() + { + String sig = VMClass.getClassSignature(this); + if (sig == null) + return new TypeVariable[0]; + + ClassSignatureParser p = new ClassSignatureParser(this, sig); + return p.getTypeParameters(); + } + + /** + * Returns true if an annotation for the specified type is associated + * with this class. This is primarily a short-hand for using marker + * annotations. + * + * @param annotationClass the type of annotation to look for. + * @return true if an annotation exists for the specified type. + * @since 1.5 + */ + /* FIXME[GENERICS]: Should be Class<? extends Annotation> */ + public boolean isAnnotationPresent(Class + annotationClass) + { + return getAnnotation(annotationClass) != null; + } + + /** + * Returns true if this object represents an anonymous class. + * + * @return true if this object represents an anonymous class. + * @since 1.5 + */ + public boolean isAnonymousClass() + { + return VMClass.isAnonymousClass(this); + } + + /** + * Returns true if this object represents an local class. + * + * @return true if this object represents an local class. + * @since 1.5 + */ + public boolean isLocalClass() + { + return VMClass.isLocalClass(this); + } + + /** + * Returns true if this object represents an member class. + * + * @return true if this object represents an member class. + * @since 1.5 + */ + public boolean isMemberClass() + { + return VMClass.isMemberClass(this); + } + + } diff --git a/libjava/classpath/java/lang/ClassLoader.java b/libjava/classpath/java/lang/ClassLoader.java index 9f586c4..83ef98d 100644 --- a/libjava/classpath/java/lang/ClassLoader.java +++ b/libjava/classpath/java/lang/ClassLoader.java @@ -469,7 +469,8 @@ public abstract class ClassLoader if (domain == null) domain = StaticData.defaultProtectionDomain; - return VMClassLoader.defineClass(this, name, data, offset, len, domain); + return VMClassLoader.defineClassWithTransformers(this, name, data, offset, + len, domain); } /** @@ -628,8 +629,9 @@ public abstract class ClassLoader * @return an enumaration of all resources found * @throws IOException if I/O errors occur in the process * @since 1.2 + * @specnote this was <code>final</code> prior to 1.5 */ - public final Enumeration getResources(String name) throws IOException + public Enumeration getResources(String name) throws IOException { Enumeration parentResources; if (parent == null) @@ -834,7 +836,7 @@ public abstract class ClassLoader throw new IllegalArgumentException("Package " + name + " already defined"); Package p = new Package(name, specTitle, specVendor, specVersion, - implTitle, implVendor, implVersion, sealed); + implTitle, implVendor, implVersion, sealed, this); synchronized (definedPackages) { definedPackages.put(name, p); diff --git a/libjava/classpath/java/lang/Enum.java b/libjava/classpath/java/lang/Enum.java new file mode 100644 index 0000000..5344d5c --- /dev/null +++ b/libjava/classpath/java/lang/Enum.java @@ -0,0 +1,248 @@ +/* Enum.java - Base class for all enums + Copyright (C) 2004, 2005 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.lang; + +import java.io.Serializable; +import java.lang.reflect.Field; + +/** + * This class represents a Java enumeration. All enumerations are + * subclasses of this class. + * + * @author Tom Tromey (tromey@redhat.com) + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +/* FIXME[GENERICS]: Should be Enum<T extends Enum<T>> + and Comparable<T> */ +public abstract class Enum + implements Comparable, Serializable +{ + + /** + * For compatability with Sun's JDK + */ + private static final long serialVersionUID = -4300926546619394005L; + + /** + * The name of this enum constant. + */ + String name; + + /** + * The number of this enum constant. Each constant is given a number + * which matches the order in which it was declared, starting with zero. + */ + int ordinal; + + /** + * This constructor is used by the compiler to create enumeration constants. + * + * @param name the name of the enumeration constant. + * @param ordinal the number of the enumeration constant, based on the + * declaration order of the constants and starting from zero. + */ + protected Enum(String name, int ordinal) + { + this.name = name; + this.ordinal = ordinal; + } + + /** + * Returns an Enum for a enum class given a description string of + * the enum constant. + * + * @exception NullPointerException when etype or s are null. + * @exception IllegalArgumentException when there is no value s in + * the enum etype. + */ + /* FIXME[GENERICS]: Should be <S extends Enum<S>> S valueOf(Class<S>) */ + public static Enum valueOf(Class etype, String s) + { + if (etype == null || s == null) + throw new NullPointerException(); + + try + { + Field f = etype.getDeclaredField(s); + if (! f.isEnumConstant()) + throw new IllegalArgumentException(s); + /* FIXME[GENERICS]: Should cast to S */ + return (Enum) f.get(null); + } + catch (NoSuchFieldException exception) + { + throw new IllegalArgumentException(s); + } + catch (IllegalAccessException exception) + { + throw new Error("Unable to access Enum class"); + } + } + + /** + * Returns true if this enumeration is equivalent to the supplied object, + * <code>o</code>. Only one instance of an enumeration constant exists, + * so the comparison is simply done using <code>==</code>. + * + * @param o the object to compare to this. + * @return true if <code>this == o</code>. + */ + public final boolean equals(Object o) + { + // Enum constants are singular, so we need only compare `=='. + return this == o; + } + + /** + * Returns the hash code of this constant. This is simply the ordinal. + * + * @return the hash code of this enumeration constant. + */ + public final int hashCode() + { + return ordinal; + } + + /** + * Returns a textual representation of this enumeration constant. + * By default, this is simply the declared name of the constant, but + * specific enumeration types may provide an implementation more suited + * to the data being stored. + * + * @return a textual representation of this constant. + */ + public String toString() + { + return name; + } + + /** + * Returns an integer which represents the relative ordering of this + * enumeration constant. Enumeration constants are ordered by their + * ordinals, which represents their declaration order. So, comparing + * two identical constants yields zero, while one declared prior to + * this returns a positive integer and one declared after yields a + * negative integer. + * + * @param e the enumeration constant to compare. + * @return a negative integer if <code>e.ordinal < this.ordinal</code>, + * zero if <code>e.ordinal == this.ordinal</code> and a positive + * integer if <code>e.ordinal > this.ordinal</code>. + * @throws ClassCastException if <code>e</code> is not an enumeration + * constant of the same class. + */ + public final int compareTo(Enum e) + { + if (getDeclaringClass() != e.getDeclaringClass()) + throw new ClassCastException(); + return ordinal - e.ordinal; + } + + /** + * Returns an integer which represents the relative ordering of this + * enumeration constant. Enumeration constants are ordered by their + * ordinals, which represents their declaration order. So, comparing + * two identical constants yields zero, while one declared prior to + * this returns a positive integer and one declared after yields a + * negative integer. + * + * @param o the enumeration constant to compare. + * @return a negative integer if <code>e.ordinal < this.ordinal</code>, + * zero if <code>e.ordinal == this.ordinal</code> and a positive + * integer if <code>e.ordinal > this.ordinal</code>. + * @throws ClassCastException if <code>e</code> is not an enumeration + * constant of the same class. + */ + /* FIXME[GENERICS]: Remove this method */ + public final int compareTo(Object o) + { + return compareTo((Enum)o); + } + + /** + * Cloning of enumeration constants is prevented, to maintain their + * singleton status. + * + * @return the cloned object. + * @throws CloneNotSupportedException as enumeration constants can't be + * cloned. + */ + protected final Object clone() throws CloneNotSupportedException + { + throw new CloneNotSupportedException("can't clone an enum constant"); + } + + /** + * Returns the name of this enumeration constant. + * + * @return the name of the constant. + */ + public final String name() + { + return name; + } + + /** + * Returns the number of this enumeration constant, which represents + * the order in which it was originally declared, starting from zero. + * + * @return the number of this constant. + */ + public final int ordinal() + { + return ordinal; + } + + /** + * Returns the type of this enumeration constant. This is the class + * corresponding to the declaration of the enumeration. + * + * @return the type of this enumeration constant. + */ + /* FIXME[GENERICS]: Should return Class<T> */ + public final Class getDeclaringClass() + { + Class k = getClass(); + // We might be in an anonymous subclass of the enum class, so go + // up one more level. + if (k.getSuperclass() != Enum.class) + k = k.getSuperclass(); + return k; + } +} diff --git a/libjava/classpath/java/lang/EnumConstantNotPresentException.java b/libjava/classpath/java/lang/EnumConstantNotPresentException.java index dbec9d6..12b30fd 100644 --- a/libjava/classpath/java/lang/EnumConstantNotPresentException.java +++ b/libjava/classpath/java/lang/EnumConstantNotPresentException.java @@ -48,6 +48,8 @@ package java.lang; */ public class EnumConstantNotPresentException extends RuntimeException { + private static final long serialVersionUID = -6046998521960521108L; + /** * The enum's type. Note that the name is fixed by the * serialization spec. diff --git a/libjava/classpath/java/lang/Iterable.java b/libjava/classpath/java/lang/Iterable.java new file mode 100644 index 0000000..8223bcf --- /dev/null +++ b/libjava/classpath/java/lang/Iterable.java @@ -0,0 +1,59 @@ +/* Iterable.java -- Notes collection over which one may iterate + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.lang; + +import java.util.Iterator; + +/** + * This interface is used to indicate that a given class can be + * iterated over. The compiler uses this interface to determine which + * classes are suitable targets of the <code>foreach</code> construct. + * + * @author Tom Tromey <tromey@redhat.com> + * @since 1.5 + */ +public interface Iterable +{ + /** + * Returns an iterator for the collection. + * + * @return an iterator. + */ + Iterator iterator (); +} diff --git a/libjava/classpath/java/lang/Math.java b/libjava/classpath/java/lang/Math.java index d7c8aa1..90574d5 100644 --- a/libjava/classpath/java/lang/Math.java +++ b/libjava/classpath/java/lang/Math.java @@ -948,4 +948,105 @@ public final class Math return VMMath.tanh(a); } + /** + * Return the ulp for the given double argument. The ulp is the + * difference between the argument and the next larger double. Note + * that the sign of the double argument is ignored, that is, + * ulp(x) == ulp(-x). If the argument is a NaN, then NaN is returned. + * If the argument is an infinity, then +Inf is returned. If the + * argument is zero (either positive or negative), then + * {@link Double#MIN_VALUE} is returned. + * @param d the double whose ulp should be returned + * @return the difference between the argument and the next larger double + * @since 1.5 + */ + public static double ulp(double d) + { + if (Double.isNaN(d)) + return d; + if (Double.isInfinite(d)) + return Double.POSITIVE_INFINITY; + // This handles both +0.0 and -0.0. + if (d == 0.0) + return Double.MIN_VALUE; + long bits = Double.doubleToLongBits(d); + final int mantissaBits = 52; + final int exponentBits = 11; + final long mantMask = (1L << mantissaBits) - 1; + long mantissa = bits & mantMask; + final long expMask = (1L << exponentBits) - 1; + long exponent = (bits >>> mantissaBits) & expMask; + + // Denormal number, so the answer is easy. + if (exponent == 0) + { + long result = (exponent << mantissaBits) | 1L; + return Double.longBitsToDouble(result); + } + + // Conceptually we want to have '1' as the mantissa. Then we would + // shift the mantissa over to make a normal number. If this underflows + // the exponent, we will make a denormal result. + long newExponent = exponent - mantissaBits; + long newMantissa; + if (newExponent > 0) + newMantissa = 0; + else + { + newMantissa = 1L << -(newExponent - 1); + newExponent = 0; + } + return Double.longBitsToDouble((newExponent << mantissaBits) | newMantissa); + } + + /** + * Return the ulp for the given float argument. The ulp is the + * difference between the argument and the next larger float. Note + * that the sign of the float argument is ignored, that is, + * ulp(x) == ulp(-x). If the argument is a NaN, then NaN is returned. + * If the argument is an infinity, then +Inf is returned. If the + * argument is zero (either positive or negative), then + * {@link Float#MIN_VALUE} is returned. + * @param f the float whose ulp should be returned + * @return the difference between the argument and the next larger float + * @since 1.5 + */ + public static float ulp(float f) + { + if (Float.isNaN(f)) + return f; + if (Float.isInfinite(f)) + return Float.POSITIVE_INFINITY; + // This handles both +0.0 and -0.0. + if (f == 0.0) + return Float.MIN_VALUE; + int bits = Float.floatToIntBits(f); + final int mantissaBits = 23; + final int exponentBits = 8; + final int mantMask = (1 << mantissaBits) - 1; + int mantissa = bits & mantMask; + final int expMask = (1 << exponentBits) - 1; + int exponent = (bits >>> mantissaBits) & expMask; + + // Denormal number, so the answer is easy. + if (exponent == 0) + { + int result = (exponent << mantissaBits) | 1; + return Float.intBitsToFloat(result); + } + + // Conceptually we want to have '1' as the mantissa. Then we would + // shift the mantissa over to make a normal number. If this underflows + // the exponent, we will make a denormal result. + int newExponent = exponent - mantissaBits; + int newMantissa; + if (newExponent > 0) + newMantissa = 0; + else + { + newMantissa = 1 << -(newExponent - 1); + newExponent = 0; + } + return Float.intBitsToFloat((newExponent << mantissaBits) | newMantissa); + } } diff --git a/libjava/classpath/java/lang/Package.java b/libjava/classpath/java/lang/Package.java index 4cded0a..38bb324 100644 --- a/libjava/classpath/java/lang/Package.java +++ b/libjava/classpath/java/lang/Package.java @@ -1,5 +1,6 @@ /* Package.java -- information about a package - Copyright (C) 2000, 2001, 2002, 2003, 2005 Free Software Foundation, Inc. + Copyright (C) 2000, 2001, 2002, 2003, 2005, 2006 + Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -39,6 +40,8 @@ package java.lang; import gnu.classpath.VMStackWalker; +import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedElement; import java.net.URL; import java.util.NoSuchElementException; import java.util.StringTokenizer; @@ -70,9 +73,10 @@ import java.util.StringTokenizer; * @see ClassLoader#definePackage(String, String, String, String, String, * String, String, URL) * @since 1.2 - * @status updated to 1.4 + * @status updated to 1.5 */ public class Package + implements AnnotatedElement { /** The name of the Package */ private final String name; @@ -98,6 +102,20 @@ public class Package /** If sealed the origin of the package classes, otherwise null */ private final URL sealed; + /** The class loader that defined this package */ + private ClassLoader loader; + + /** @deprecated Please use the other constructor that takes the class loader + * that defines the Package. + */ + Package(String name, + String specTitle, String specVendor, String specVersion, + String implTitle, String implVendor, String implVersion, URL sealed) + { + this(name, specTitle, specVendor, specVersion, implTitle, implVendor, + implVersion, sealed, null); + } + /** * A package local constructor for the Package class. All parameters except * the <code>name</code> of the package may be <code>null</code>. @@ -115,7 +133,8 @@ public class Package */ Package(String name, String specTitle, String specVendor, String specVersion, - String implTitle, String implVendor, String implVersion, URL sealed) + String implTitle, String implVendor, String implVersion, URL sealed, + ClassLoader loader) { if (name == null) throw new IllegalArgumentException("null Package name"); @@ -128,6 +147,7 @@ public class Package this.specVendor = specVendor; this.specVersion = specVersion; this.sealed = sealed; + this.loader = loader; } /** @@ -233,7 +253,7 @@ public class Package * * @return true if the version is compatible, false otherwise * - * @Throws NumberFormatException if either version string is invalid + * @throws NumberFormatException if either version string is invalid * @throws NullPointerException if either version string is null */ public boolean isCompatibleWith(String version) @@ -315,4 +335,82 @@ public class Package return ("package " + name + (specTitle == null ? "" : ", " + specTitle) + (specVersion == null ? "" : ", version " + specVersion)); } + + /** + * Returns this package's annotation for the specified annotation type, + * or <code>null</code> if no such annotation exists. + * + * @param annotationClass the type of annotation to look for. + * @return this package's annotation for the specified type, or + * <code>null</code> if no such annotation exists. + * @since 1.5 + */ + /* FIXME[GENERICS]: <T extends Annotation> T getAnnotation(Class <T>) */ + public Annotation getAnnotation(Class annotationClass) + { + Annotation foundAnnotation = null; + Annotation[] annotations = getAnnotations(); + for (int i = 0; i < annotations.length; i++) + if (annotations[i].annotationType() == annotationClass) + foundAnnotation = annotations[i]; + return foundAnnotation; + } + + /** + * Returns all annotations associated with this package. If there are + * no annotations associated with this package, then a zero-length array + * will be returned. The returned array may be modified by the client + * code, but this will have no effect on the annotation content of this + * package, and hence no effect on the return value of this method for + * future callers. + * + * @return this package' annotations. + * @since 1.5 + */ + public Annotation[] getAnnotations() + { + /** All a package's annotations are declared within it. */ + return getDeclaredAnnotations(); + } + + /** + * Returns all annotations directly defined by this package. If there are + * no annotations associated with this package, then a zero-length array + * will be returned. The returned array may be modified by the client + * code, but this will have no effect on the annotation content of this + * package, and hence no effect on the return value of this method for + * future callers. + * + * @return the annotations directly defined by this package. + * @since 1.5 + */ + public Annotation[] getDeclaredAnnotations() + { + try + { + Class pkgInfo = Class.forName(name + ".package-info", false, loader); + return pkgInfo.getDeclaredAnnotations(); + } + catch (ClassNotFoundException _) + { + return new Annotation[0]; + } + } + + /** + * Returns true if an annotation for the specified type is associated + * with this package. This is primarily a short-hand for using marker + * annotations. + * + * @param annotationClass the type of annotation to look for. + * @return true if an annotation exists for the specified type. + * @since 1.5 + */ + /* FIXME[GENERICS]: Signature is Class<? extends Annotation> */ + public boolean isAnnotationPresent(Class + annotationClass) + { + return getAnnotation(annotationClass) != null; + } + } // class Package diff --git a/libjava/classpath/java/lang/StackTraceElement.java b/libjava/classpath/java/lang/StackTraceElement.java index cf4d1c7..746dd63 100644 --- a/libjava/classpath/java/lang/StackTraceElement.java +++ b/libjava/classpath/java/lang/StackTraceElement.java @@ -1,5 +1,5 @@ /* StackTraceElement.java -- One function call or call stack element - Copyright (C) 2001, 2002, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2001, 2002, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -211,7 +211,7 @@ public final class StackTraceElement implements Serializable } if (methodName != null) sb.append(methodName); - sb.append(" ("); + sb.append("("); if (fileName != null) sb.append(fileName); else diff --git a/libjava/classpath/java/lang/StrictMath.java b/libjava/classpath/java/lang/StrictMath.java index 2079cc1..548a6f1 100644 --- a/libjava/classpath/java/lang/StrictMath.java +++ b/libjava/classpath/java/lang/StrictMath.java @@ -1841,4 +1841,84 @@ public final strictfp class StrictMath double t = (float) a; return t + a * (1 + t * z + t * v); } + + /** + * <p> + * Returns the sign of the argument as follows: + * </p> + * <ul> + * <li>If <code>a</code> is greater than zero, the result is 1.0.</li> + * <li>If <code>a</code> is less than zero, the result is -1.0.</li> + * <li>If <code>a</code> is <code>NaN</code>, the result is <code>NaN</code>. + * <li>If <code>a</code> is positive or negative zero, the result is the + * same.</li> + * </ul> + * + * @param a the numeric argument. + * @return the sign of the argument. + * @since 1.5. + */ + public static double signum(double a) + { + // There's no difference. + return Math.signum(a); + } + + /** + * <p> + * Returns the sign of the argument as follows: + * </p> + * <ul> + * <li>If <code>a</code> is greater than zero, the result is 1.0f.</li> + * <li>If <code>a</code> is less than zero, the result is -1.0f.</li> + * <li>If <code>a</code> is <code>NaN</code>, the result is <code>NaN</code>. + * <li>If <code>a</code> is positive or negative zero, the result is the + * same.</li> + * </ul> + * + * @param a the numeric argument. + * @return the sign of the argument. + * @since 1.5. + */ + public static float signum(float a) + { + // There's no difference. + return Math.signum(a); + } + + /** + * Return the ulp for the given double argument. The ulp is the + * difference between the argument and the next larger double. Note + * that the sign of the double argument is ignored, that is, + * ulp(x) == ulp(-x). If the argument is a NaN, then NaN is returned. + * If the argument is an infinity, then +Inf is returned. If the + * argument is zero (either positive or negative), then + * {@link Double#MIN_VALUE} is returned. + * @param d the double whose ulp should be returned + * @return the difference between the argument and the next larger double + * @since 1.5 + */ + public static double ulp(double d) + { + // There's no difference. + return Math.ulp(d); + } + + /** + * Return the ulp for the given float argument. The ulp is the + * difference between the argument and the next larger float. Note + * that the sign of the float argument is ignored, that is, + * ulp(x) == ulp(-x). If the argument is a NaN, then NaN is returned. + * If the argument is an infinity, then +Inf is returned. If the + * argument is zero (either positive or negative), then + * {@link Float#MIN_VALUE} is returned. + * @param f the float whose ulp should be returned + * @return the difference between the argument and the next larger float + * @since 1.5 + */ + public static float ulp(float f) + { + // There's no difference. + return Math.ulp(f); + } } diff --git a/libjava/classpath/java/lang/StringBuilder.java b/libjava/classpath/java/lang/StringBuilder.java index 01a83ca..98af48f 100644 --- a/libjava/classpath/java/lang/StringBuilder.java +++ b/libjava/classpath/java/lang/StringBuilder.java @@ -206,7 +206,7 @@ public final class StringBuilder int max = value.length * 2 + 2; minimumCapacity = (minimumCapacity < max ? max : minimumCapacity); char[] nb = new char[minimumCapacity]; - System.arraycopy(value, 0, nb, 0, count); + VMSystem.arraycopy(value, 0, nb, 0, count); value = nb; } } @@ -285,7 +285,7 @@ public final class StringBuilder { if (srcOffset < 0 || srcEnd > count || srcEnd < srcOffset) throw new StringIndexOutOfBoundsException(); - System.arraycopy(value, srcOffset, dst, dstOffset, srcEnd - srcOffset); + VMSystem.arraycopy(value, srcOffset, dst, dstOffset, srcEnd - srcOffset); } /** @@ -355,7 +355,7 @@ public final class StringBuilder { int len = stringBuffer.count; ensureCapacity(count + len); - System.arraycopy(stringBuffer.value, 0, value, count, len); + VMSystem.arraycopy(stringBuffer.value, 0, value, count, len); count += len; } return this; @@ -395,7 +395,7 @@ public final class StringBuilder if (offset < 0 || count < 0 || offset > data.length - count) throw new StringIndexOutOfBoundsException(); ensureCapacity(this.count + count); - System.arraycopy(data, offset, value, this.count, count); + VMSystem.arraycopy(data, offset, value, this.count, count); this.count += count; return this; } @@ -558,7 +558,7 @@ public final class StringBuilder // This will unshare if required. ensureCapacity(count); if (count - end != 0) - System.arraycopy(value, end, value, start, count - end); + VMSystem.arraycopy(value, end, value, start, count - end); count -= end - start; return this; } @@ -599,7 +599,7 @@ public final class StringBuilder ensureCapacity(count + delta); if (delta != 0 && end < count) - System.arraycopy(value, end, value, end + delta, count - end); + VMSystem.arraycopy(value, end, value, end + delta, count - end); str.getChars(0, len, value, start); count += delta; @@ -677,8 +677,8 @@ public final class StringBuilder || str_offset < 0 || str_offset > str.length - len) throw new StringIndexOutOfBoundsException(); ensureCapacity(count + len); - System.arraycopy(value, offset, value, offset + len, count - offset); - System.arraycopy(str, str_offset, value, offset, len); + VMSystem.arraycopy(value, offset, value, offset + len, count - offset); + VMSystem.arraycopy(str, str_offset, value, offset, len); count += len; return this; } @@ -717,7 +717,7 @@ public final class StringBuilder str = "null"; int len = str.count; ensureCapacity(count + len); - System.arraycopy(value, offset, value, offset + len, count - offset); + VMSystem.arraycopy(value, offset, value, offset + len, count - offset); str.getChars(0, len, value, offset); count += len; return this; @@ -814,7 +814,7 @@ public final class StringBuilder if (offset < 0 || offset > count) throw new StringIndexOutOfBoundsException(offset); ensureCapacity(count + 1); - System.arraycopy(value, offset, value, offset + 1, count - offset); + VMSystem.arraycopy(value, offset, value, offset + 1, count - offset); value[offset] = ch; count++; return this; @@ -1063,7 +1063,7 @@ public final class StringBuilder if (count < value.length) { char[] newValue = new char[count]; - System.arraycopy(value, 0, newValue, 0, count); + VMSystem.arraycopy(value, 0, newValue, 0, count); value = newValue; } } diff --git a/libjava/classpath/java/lang/System.java b/libjava/classpath/java/lang/System.java index 34bbfdd..b538b79 100644 --- a/libjava/classpath/java/lang/System.java +++ b/libjava/classpath/java/lang/System.java @@ -364,7 +364,7 @@ public final class System SecurityManager sm = SecurityManager.current; // Be thread-safe. if (sm != null) sm.checkPropertyAccess(key); - else if (key.length() == 0) + if (key.length() == 0) throw new IllegalArgumentException("key can't be empty"); return SystemProperties.getProperty(key); } @@ -385,6 +385,10 @@ public final class System SecurityManager sm = SecurityManager.current; // Be thread-safe. if (sm != null) sm.checkPropertyAccess(key); + // This handles both the null pointer exception and the illegal + // argument exception. + if (key.length() == 0) + throw new IllegalArgumentException("key can't be empty"); return SystemProperties.getProperty(key, def); } @@ -405,10 +409,37 @@ public final class System SecurityManager sm = SecurityManager.current; // Be thread-safe. if (sm != null) sm.checkPermission(new PropertyPermission(key, "write")); + // This handles both the null pointer exception and the illegal + // argument exception. + if (key.length() == 0) + throw new IllegalArgumentException("key can't be empty"); return SystemProperties.setProperty(key, value); } /** + * Remove a single system property by name. A security check may be + * performed, <code>checkPropertyAccess(key, "write")</code>. + * + * @param key the name of the system property to remove + * @return the previous value, or null + * @throws SecurityException if permission is denied + * @throws NullPointerException if key is null + * @throws IllegalArgumentException if key is "" + * @since 1.5 + */ + public static String clearProperty(String key) + { + SecurityManager sm = SecurityManager.current; // Be thread-safe. + if (sm != null) + sm.checkPermission(new PropertyPermission(key, "write")); + // This handles both the null pointer exception and the illegal + // argument exception. + if (key.length() == 0) + throw new IllegalArgumentException("key can't be empty"); + return SystemProperties.remove(key); + } + + /** * Gets the value of an environment variable. * * @param name the name of the environment variable diff --git a/libjava/classpath/java/lang/Thread.java b/libjava/classpath/java/lang/Thread.java index 76df103..2362054 100644 --- a/libjava/classpath/java/lang/Thread.java +++ b/libjava/classpath/java/lang/Thread.java @@ -1,5 +1,5 @@ /* Thread -- an independent thread of executable code - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation This file is part of GNU Classpath. @@ -81,6 +81,7 @@ import java.util.Map; * @author Tom Tromey * @author John Keiser * @author Eric Blake (ebb9@email.byu.edu) + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) * @see Runnable * @see Runtime#exit(int) * @see #run() @@ -130,15 +131,27 @@ public class Thread implements Runnable /** The context classloader for this Thread. */ private ClassLoader contextClassLoader; + + /** This thread's ID. */ + private final long threadId; /** The next thread number to use. */ private static int numAnonymousThreadsCreated; + + /** The next thread ID to use. */ + private static long nextThreadId; + + /** The default exception handler. */ + private static UncaughtExceptionHandler defaultHandler; /** Thread local storage. Package accessible for use by * InheritableThreadLocal. */ WeakIdentityHashMap locals; + /** The uncaught exception handler. */ + UncaughtExceptionHandler exceptionHandler; + /** * Allocates a new <code>Thread</code> object. This constructor has * the same effect as <code>Thread(null, null,</code> @@ -342,6 +355,11 @@ public class Thread implements Runnable this.name = name.toString(); this.runnable = target; this.stacksize = size; + + synchronized (Thread.class) + { + this.threadId = nextThreadId++; + } priority = current.priority; daemon = current.daemon; @@ -371,6 +389,11 @@ public class Thread implements Runnable this.priority = priority; this.daemon = daemon; this.contextClassLoader = ClassLoader.getSystemClassLoader(); + synchronized (Thread.class) + { + this.threadId = nextThreadId++; + } + } /** @@ -434,6 +457,19 @@ public class Thread implements Runnable /** * Originally intended to destroy this thread, this method was never * implemented by Sun, and is hence a no-op. + * + * @deprecated This method was originally intended to simply destroy + * the thread without performing any form of cleanup operation. + * However, it was never implemented. It is now deprecated + * for the same reason as <code>suspend()</code>, + * <code>stop()</code> and <code>resume()</code>; namely, + * it is prone to deadlocks. If a thread is destroyed while + * it still maintains a lock on a resource, then this resource + * will remain locked and any attempts by other threads to + * access the resource will result in a deadlock. Thus, even + * an implemented version of this method would be still be + * deprecated, due to its unsafe nature. + * @throws NoSuchMethodError as this method was never implemented. */ public void destroy() { @@ -1000,4 +1036,159 @@ public class Thread implements Runnable } return locals; } + + /** + * Assigns the given <code>UncaughtExceptionHandler</code> to this + * thread. This will then be called if the thread terminates due + * to an uncaught exception, pre-empting that of the + * <code>ThreadGroup</code>. + * + * @param h the handler to use for this thread. + * @throws SecurityException if the current thread can't modify this thread. + * @since 1.5 + */ + public void setUncaughtExceptionHandler(UncaughtExceptionHandler h) + { + SecurityManager sm = SecurityManager.current; // Be thread-safe. + if (sm != null) + sm.checkAccess(this); + exceptionHandler = h; + } + + /** + * <p> + * Returns the handler used when this thread terminates due to an + * uncaught exception. The handler used is determined by the following: + * </p> + * <ul> + * <li>If this thread has its own handler, this is returned.</li> + * <li>If not, then the handler of the thread's <code>ThreadGroup</code> + * object is returned.</li> + * <li>If both are unavailable, then <code>null</code> is returned + * (which can only happen when the thread was terminated since + * then it won't have an associated thread group anymore).</li> + * </ul> + * + * @return the appropriate <code>UncaughtExceptionHandler</code> or + * <code>null</code> if one can't be obtained. + * @since 1.5 + */ + public UncaughtExceptionHandler getUncaughtExceptionHandler() + { + return exceptionHandler != null ? exceptionHandler : group; + } + + /** + * <p> + * Sets the default uncaught exception handler used when one isn't + * provided by the thread or its associated <code>ThreadGroup</code>. + * This exception handler is used when the thread itself does not + * have an exception handler, and the thread's <code>ThreadGroup</code> + * does not override this default mechanism with its own. As the group + * calls this handler by default, this exception handler should not defer + * to that of the group, as it may lead to infinite recursion. + * </p> + * <p> + * Uncaught exception handlers are used when a thread terminates due to + * an uncaught exception. Replacing this handler allows default code to + * be put in place for all threads in order to handle this eventuality. + * </p> + * + * @param h the new default uncaught exception handler to use. + * @throws SecurityException if a security manager is present and + * disallows the runtime permission + * "setDefaultUncaughtExceptionHandler". + * @since 1.5 + */ + public static void + setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler h) + { + SecurityManager sm = SecurityManager.current; // Be thread-safe. + if (sm != null) + sm.checkPermission(new RuntimePermission("setDefaultUncaughtExceptionHandler")); + defaultHandler = h; + } + + /** + * Returns the handler used by default when a thread terminates + * unexpectedly due to an exception, or <code>null</code> if one doesn't + * exist. + * + * @return the default uncaught exception handler. + * @since 1.5 + */ + public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() + { + return defaultHandler; + } + + /** + * Returns the unique identifier for this thread. This ID is generated + * on thread creation, and may be re-used on its death. + * + * @return a positive long number representing the thread's ID. + * @since 1.5 + */ + public long getId() + { + return threadId; + } + + /** + * <p> + * This interface is used to handle uncaught exceptions + * which cause a <code>Thread</code> to terminate. When + * a thread, t, is about to terminate due to an uncaught + * exception, the virtual machine looks for a class which + * implements this interface, in order to supply it with + * the dying thread and its uncaught exception. + * </p> + * <p> + * The virtual machine makes two attempts to find an + * appropriate handler for the uncaught exception, in + * the following order: + * </p> + * <ol> + * <li> + * <code>t.getUncaughtExceptionHandler()</code> -- + * the dying thread is queried first for a handler + * specific to that thread. + * </li> + * <li> + * <code>t.getThreadGroup()</code> -- + * the thread group of the dying thread is used to + * handle the exception. If the thread group has + * no special requirements for handling the exception, + * it may simply forward it on to + * <code>Thread.getDefaultUncaughtExceptionHandler()</code>, + * the default handler, which is used as a last resort. + * </li> + * </ol> + * <p> + * The first handler found is the one used to handle + * the uncaught exception. + * </p> + * + * @author Tom Tromey <tromey@redhat.com> + * @author Andrew John Hughes <gnu_andrew@member.fsf.org> + * @since 1.5 + * @see Thread#getUncaughtExceptionHandler() + * @see Thread#setUncaughtExceptionHander(java.lang.Thread.UncaughtExceptionHandler) + * @see Thread#getDefaultUncaughtExceptionHandler() + * @see + * Thread#setDefaultUncaughtExceptionHandler(java.lang.Thread.UncaughtExceptionHandler) + */ + public interface UncaughtExceptionHandler + { + /** + * Invoked by the virtual machine with the dying thread + * and the uncaught exception. Any exceptions thrown + * by this method are simply ignored by the virtual + * machine. + * + * @param thr the dying thread. + * @param exc the uncaught exception. + */ + void uncaughtException(Thread thr, Throwable exc); + } } diff --git a/libjava/classpath/java/lang/ThreadGroup.java b/libjava/classpath/java/lang/ThreadGroup.java index 6e4c27a..7fbef88 100644 --- a/libjava/classpath/java/lang/ThreadGroup.java +++ b/libjava/classpath/java/lang/ThreadGroup.java @@ -37,6 +37,7 @@ exception statement from your version. */ package java.lang; +import java.lang.Thread.UncaughtExceptionHandler; import java.util.Vector; /** @@ -53,7 +54,7 @@ import java.util.Vector; * @since 1.0 * @status updated to 1.4 */ -public class ThreadGroup +public class ThreadGroup implements UncaughtExceptionHandler { /** The Initial, top-level ThreadGroup. */ static ThreadGroup root = new ThreadGroup(); @@ -545,6 +546,8 @@ public class ThreadGroup { if (parent != null) parent.uncaughtException(thread, t); + else if (Thread.getDefaultUncaughtExceptionHandler() != null) + Thread.getDefaultUncaughtExceptionHandler().uncaughtException(thread, t); else if (! (t instanceof ThreadDeath)) { if (t == null) diff --git a/libjava/classpath/java/lang/ThreadLocal.java b/libjava/classpath/java/lang/ThreadLocal.java index aceb255..64df8c3 100644 --- a/libjava/classpath/java/lang/ThreadLocal.java +++ b/libjava/classpath/java/lang/ThreadLocal.java @@ -152,4 +152,15 @@ public class ThreadLocal // ever modify the map. map.put(this, value == null ? NULL : value); } + + /** + * Removes the value associated with the ThreadLocal object for the + * currently executing Thread. + * @since 1.5 + */ + public void remove() + { + Map map = Thread.getThreadLocals(); + map.remove(this); + } } diff --git a/libjava/classpath/java/lang/TypeNotPresentException.java b/libjava/classpath/java/lang/TypeNotPresentException.java index 3010c96..65d98457 100644 --- a/libjava/classpath/java/lang/TypeNotPresentException.java +++ b/libjava/classpath/java/lang/TypeNotPresentException.java @@ -58,7 +58,8 @@ package java.lang; public class TypeNotPresentException extends RuntimeException { - + private static final long serialVersionUID = -5101214195716534496L; + /** * Constructs a <code>TypeNotPresentException</code> for * the supplied type. The specified cause <code>Throwable</code> diff --git a/libjava/classpath/java/lang/annotation/Annotation.java b/libjava/classpath/java/lang/annotation/Annotation.java new file mode 100644 index 0000000..01e2393 --- /dev/null +++ b/libjava/classpath/java/lang/annotation/Annotation.java @@ -0,0 +1,136 @@ +/* Annotation.java - Base interface for all annotations + Copyright (C) 2004 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.lang.annotation; + +/** + * This is the common interface for all annotations. Note that classes + * that implement this class manually are not classed as annotations, and + * that this interface does not define an annotation type in itself. + * + * @author Tom Tromey (tromey@redhat.com) + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface Annotation +{ + + /** + * Returns the type of this annotation. + * + * @return the class of which this annotation is an instance. + */ + /* FIXME[GENERICS]: Should return Class<? extends Annotation> */ + Class annotationType(); + + /** + * <p> + * Returns true if the supplied object is equivalent to this annotation. + * For this property to hold, the following must be true of <code>o</code>: + * </p> + * <ul> + * <li>The object is also an instance of the same annotation type.</li> + * <li>The members of the supplied annotation are equal to those of this + * annotation, according to the following: + * <ul> + * <li>If the members are <code>float</code>s, then, for floats + * <code>x</code> and <code>y</code>, + * <code>Float.valueOf(x).equals(Float.valueOf(y)</code> must return + * true. This differs from the usual (<code>==</code>) comparison + * in that <code>NaN</code> is considered equal to itself and positive + * and negative zero are seen as different.</li> + * <li>Likewise, if the members are <code>double</code>s, then, for doubles + * <code>x</code> and <code>y</code>, + * <code>Double.valueOf(x).equals(Double.valueOf(y)</code> must return + * true. This differs from the usual (<code>==</code>) comparison + * in that <code>NaN</code> is considered equal to itself and positive + * and negative zero are seen as different.</li> + * <li>Strings, classes, enumerations and annotations are considered + * equal according to the <code>equals()</code> implementation for these + * types.</li> + * <li>Arrays are considered equal according to <code>Arrays.equals()</code> + * </li> + * <li>Any remaining types are considered equal using <code>==</code>.</li> + * </li> + * </ul> + * + * @param o the object to compare with this annotation. + * @return true if the supplied object is an annotation with equivalent + * members. + */ + boolean equals(Object o); + + /** + * <p> + * Returns the hash code of the annotation. This is computed as the + * sum of the hash codes of the annotation's members. + * </p> + * <p> + * The hash code of a member of the annotation is the result of XORing + * the hash code of its value with the result of multiplying the hash code + * of its name by 127. Formally, if the value is <code>v</code> and the + * name is <code>n</code>, the hash code of the member is + * v.hashCode() XOR (127 * String.hashCode(n)). <code>v.hashCode()</code> + * is defined as follows: + * </p> + * <ul> + * <li>The hash code of a primitive value (i.e. <code>byte</code>, + * <code>char</code>, <code>double</code>, <code>float</code>, + * <code>int</code>, <code>long</code>, <code>short</code> and + * <code>boolean</code>) is the hash code obtained from its corresponding + * wrapper class using <code>valueOf(v).hashCode()</code>, where + * <code>v</code> is the primitive value.</li> + * <li>The hash code of an enumeration, string, class or other annotation + * is obtained using <code>v.hashCode()</code>.</li> + * <li>The hash code of an array is computed using + * <code>Arrays.hashCode(v)</code>.</li> + * </ul> + * + * @return the hash code of the annotation, computed as the sum of its + * member hashcodes. + */ + int hashCode(); + + /** + * Returns a textual representation of the annotation. This is + * implementation-dependent, but is expected to include the classname + * and the names and values of each member. + * + * @return a textual representation of the annotation. + */ + String toString(); +} diff --git a/libjava/classpath/java/lang/annotation/AnnotationFormatError.java b/libjava/classpath/java/lang/annotation/AnnotationFormatError.java index 40ce3ca..36f6006 100644 --- a/libjava/classpath/java/lang/annotation/AnnotationFormatError.java +++ b/libjava/classpath/java/lang/annotation/AnnotationFormatError.java @@ -49,6 +49,7 @@ package java.lang.annotation; */ public class AnnotationFormatError extends Error { + private static final long serialVersionUID = -4256701562333669892L; /** * Constructs a new <code>AnnotationFormatError</code> diff --git a/libjava/classpath/java/lang/class-dependencies.conf b/libjava/classpath/java/lang/class-dependencies.conf deleted file mode 100644 index 4fbf75e..0000000 --- a/libjava/classpath/java/lang/class-dependencies.conf +++ /dev/null @@ -1,58 +0,0 @@ -# This property file contains dependencies of classes, methods, and -# field on other methods or classes. -# -# Syntax: -# -# <used>: <needed 1> [... <needed N>] -# -# means that when <used> is included, <needed 1> (... <needed N>) must -# be included as well. -# -# <needed X> and <used> are of the form -# -# <class.methodOrField(signature)> -# -# or just -# -# <class> -# -# Within dependencies, variables can be used. A variable is defined as -# follows: -# -# {variable}: value1 value2 ... value<n> -# -# variables can be used on the right side of dependencies as follows: -# -# <used>: com.bla.blu.{variable}.Class.m()V -# -# The use of the variable will expand to <n> dependencies of the form -# -# <used>: com.bla.blu.value1.Class.m()V -# <used>: com.bla.blu.value2.Class.m()V -# ... -# <used>: com.bla.blu.value<n>.Class.m()V -# -# Variables can be redefined when building a system to select the -# required support for features like encodings, protocols, etc. -# -# Hints: -# -# - For methods and fields, the signature is mandatory. For -# specification, please see the Java Virtual Machine Specification by -# SUN. Unlike in the spec, field signatures (types) are in brackets. -# -# - Package names must be separated by '/' (and not '.'). E.g., -# java/lang/Class (this is necessary, because the '.' is used to -# separate method or field names from classes) -# -# - In case <needed> refers to a class, only the class itself will be -# included in the resulting binary, NOT necessarily all its methods -# and fields. If you want to refer to all methods and fields, you can -# write class.* as an abbreviation. -# -# - Abbreviations for packages are also possible: my/package/* means all -# methods and fields of all classes in my/package. -# -# - A line with a trailing '\' continues in the next line. - -# end of file diff --git a/libjava/classpath/java/lang/instrument/ClassDefinition.java b/libjava/classpath/java/lang/instrument/ClassDefinition.java new file mode 100644 index 0000000..841597c --- /dev/null +++ b/libjava/classpath/java/lang/instrument/ClassDefinition.java @@ -0,0 +1,88 @@ +/* ClassDefinition.java -- Class that binds a class with a new class file + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.lang.instrument; + +/** + * This class binds a class that will be redefined with a new + * class file. + * + * @author Nicolas Geoffray (nicolas.geoffray@menlina.com) + * @see Instrumentation#redefineClasses(java.lang.instrument.ClassDefinition[]) + * @since 1.5 + */ +public final class ClassDefinition +{ + + /* The class it's related */ + private Class theClass; + + /* The new bytecode of theClass */ + private byte[] theClassFile; + + /** + * @param theClass the Class that will be redefined + * @param theClassFile the new class file + * @throws NullPointerException if one of the argument is null + */ + /* FIXME[GENERICS]: Signature should be (Class<?>, byte[]) */ + public ClassDefinition(Class theClass, byte[] theClassFile) + { + if (theClass == null || theClassFile == null) + throw new NullPointerException(); + this.theClass = theClass; + this.theClassFile = theClassFile; + } + + /** + * @return the Class + */ + /* FIXME[GENERICS]: Should return Class<?> */ + public Class getDefinitionClass() + { + return theClass; + } + + /** + * @return the bytes + */ + public byte[] getDefinitionClassFile() + { + return theClassFile; + } +} diff --git a/libjava/classpath/java/lang/instrument/ClassFileTransformer.java b/libjava/classpath/java/lang/instrument/ClassFileTransformer.java new file mode 100644 index 0000000..68638d7 --- /dev/null +++ b/libjava/classpath/java/lang/instrument/ClassFileTransformer.java @@ -0,0 +1,86 @@ +/* ClassFileTransformer.java -- Implementation of this interface is used by an agent to + transform class files. + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.lang.instrument; + +import java.security.ProtectionDomain; + +/** + * This interface should be implemented by classes wishing to transform + * classes bytecode when defining or redefining classes. + * + * @author Nicolas Geoffray (nicolas.geoffray@menlina.com) + * @see Instrumentation + * @see Instrumentation#addTransformer(java.lang.instrument.ClassFileTransformer) + * @see Instrumentation#removeTransformer(java.lang.instrument.ClassFileTransformer) + * @since 1.5 + */ +public interface ClassFileTransformer +{ + + /** + * Implementation of this method transforms a class by redefining its + * bytecodes. Once a ClassFileTransformer object registers itself to the + * Instrumentation object, this method will be called each time a class is + * defined (<code>ClassLoader.defineClass</code>) or redefined + * (<code>Instrumentation.redefineClasses</code>) + * @param loader the loader of the class + * @param className the name of the class with packages separated with "/" + * @param classBeingRedefined the class being redefined if it's the case, + * null otherwise + * @param protectionDomain the protection domain of the class being defined or + * redefined + * @param classfileBuffer the input byte buffer in class file format + * + * @return a class file buffer or null when no transformation has been performed + * + * @throws IllegalClassFormatException if the byte buffer does not represent + * a well-formed class file + * @see Instrumentation#redefineClasses(java.lang.instrument.ClassDefinition[]) + * + */ + /* FIXME[GENERICS]: Class should be Class<?> */ + byte[] transform(ClassLoader loader, + String className, + Class classBeingRedefined, + ProtectionDomain protectionDomain, + byte[] classfileBuffer) + throws IllegalClassFormatException; +} + diff --git a/libjava/classpath/java/lang/instrument/IllegalClassFormatException.java b/libjava/classpath/java/lang/instrument/IllegalClassFormatException.java new file mode 100644 index 0000000..c75bde0 --- /dev/null +++ b/libjava/classpath/java/lang/instrument/IllegalClassFormatException.java @@ -0,0 +1,70 @@ +/* IllegalClassFormatException.java -- thrown when an array of byte does + not represent a valid class file + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.lang.instrument; + +/** + * @author Nicolas Geoffray (nicolas.geoffray@menlina.com) + * @since 1.5 + */ +public class IllegalClassFormatException extends Exception +{ + + /** + * Compatible with JDK 1.5+. + */ + private static final long serialVersionUID = -3841736710924794009L; + + /** + * Create an exception without a message. + */ + public IllegalClassFormatException() + { + } + + /** + * Create an exception with a message. + * + * @param s the message + */ + public IllegalClassFormatException(String s) + { + super(s); + } +} diff --git a/libjava/classpath/java/lang/instrument/Instrumentation.java b/libjava/classpath/java/lang/instrument/Instrumentation.java new file mode 100644 index 0000000..81aefa6 --- /dev/null +++ b/libjava/classpath/java/lang/instrument/Instrumentation.java @@ -0,0 +1,139 @@ +/* Instrumentation.java -- Implementation of this interface is used to + instrument Java bytecode. + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.lang.instrument; + +/** + * An Instrumentation object has transformers that will + * be called each time a class is defined or redefined. + * The object is given to a <code>premain</code> function + * that is called before the <code>main</code> function. + * + * @author Nicolas Geoffray (nicolas.geoffray@menlina.com) + * @since 1.5 + */ +public interface Instrumentation +{ + + /** + * Adds a <code>ClassFileTransformer</class> object + * to the instrumentation. Each time a class is defined + * or redefined, the <code>transform</code> method of the + * <code>transformer</code> object is called. + * + * @param transformer the transformer to add + * @throws NullPointerException if transformer is null + */ + void addTransformer(ClassFileTransformer transformer); + + /** + * Removes the given transformer from the set of transformers + * this Instrumentation object has. + * + * @param transformer the transformer to remove + * @return true if the transformer was found and removed, false if + * the transformer was not found + * @throws NullPointerException if transformer is null + */ + boolean removeTransformer(ClassFileTransformer transformer); + + /** + * Returns if the current JVM supports class redefinition + * + * @return true if the current JVM supports class redefinition + */ + boolean isRedefineClassesSupported(); + + /** + * Redefine classes present in the definitions array, with + * the corresponding class files. + * + * @param definitions an array of classes to redefine + * + * @throws ClassNotFoundException if a class cannot be found + * @throws UnmodifiableClassException if a class cannot be modified + * @throws UnsupportedOperationException if the JVM does not support + * redefinition or the redefinition made unsupported changes + * @throws ClassFormatError if a class file is not valid + * @throws NoClassDefFoundError if a class name is not equal to the name + * in the class file specified + * @throws UnsupportedClassVersionError if the class file version numbers + * are unsupported + * @throws ClassCircularityError if circularity occured with the new + * classes + * @throws LinkageError if a linkage error occurs + * @throws NullPointerException if the definitions array is null, or any + * of its element + * + * @see #isRedefineClassesSupported() + * @see #addTransformer(java.lang.instrument.ClassFileTransformer) + * @see ClassFileTransformer + */ + void redefineClasses(ClassDefinition[] definitions) + throws ClassNotFoundException, + UnmodifiableClassException; + + + /** + * Get all the classes loaded by the JVM. + * + * @return an array containing all the classes loaded by the JVM. The array + * is empty if no class is loaded. + */ + Class[] getAllLoadedClasses(); + + /** + * Get all the classes loaded by a given class loader + * + * @param loader the loader + * + * @return an array containing all the classes loaded by the given loader. + * The array is empty if no class was loaded by the loader. + */ + Class[] getInitiatedClasses(ClassLoader loader); + + /** + * Get the size of an object. It contains the size of all fields. + * + * @param objectToSize the object + * @return the size of the object + * @throws NullPointerException if objectToSize is null. + */ + long getObjectSize(Object objectToSize); +} diff --git a/libjava/classpath/java/lang/instrument/UnmodifiableClassException.java b/libjava/classpath/java/lang/instrument/UnmodifiableClassException.java new file mode 100644 index 0000000..a01bd70 --- /dev/null +++ b/libjava/classpath/java/lang/instrument/UnmodifiableClassException.java @@ -0,0 +1,69 @@ +/* UnmodifiableClassException.java -- thrown when attempting to redefine + an unmodifiable class + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.lang.instrument; + +/** + * @author Nicolas Geoffray (nicolas.geoffray@menlina.com) + * @since 1.5 + */ +public class UnmodifiableClassException extends Exception +{ + /** + * Compatible with JDK 1.5+. + */ + private static final long serialVersionUID = 1716652643585309178L; + + /** + * Create an exception without a message. + */ + public UnmodifiableClassException() + { + } + + /** + * Create an exception with a message. + * + * @param s the message + */ + public UnmodifiableClassException(String s) + { + super(s); + } +} diff --git a/libjava/classpath/java/lang/reflect/AccessibleObject.java b/libjava/classpath/java/lang/reflect/AccessibleObject.java index 24418c9..8f09eac 100644 --- a/libjava/classpath/java/lang/reflect/AccessibleObject.java +++ b/libjava/classpath/java/lang/reflect/AccessibleObject.java @@ -1,5 +1,5 @@ /* java.lang.reflect.AccessibleObject - Copyright (C) 2001, 2005 Free Software Foundation, Inc. + Copyright (C) 2001, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,6 +38,8 @@ exception statement from your version. */ package java.lang.reflect; +import java.lang.annotation.Annotation; + /** * This class is the superclass of various reflection classes, and * allows sufficiently trusted code to bypass normal restrictions to @@ -53,9 +55,10 @@ package java.lang.reflect; * @see Method * @see ReflectPermission * @since 1.2 - * @status updated to 1.4 + * @status updated to 1.5 */ public class AccessibleObject + implements AnnotatedElement { /** * True if this object is marked accessible, which means the reflected @@ -156,4 +159,26 @@ public class AccessibleObject throw new SecurityException("Cannot make object accessible: " + this); this.flag = flag; } + + /* FIXME[GENERICS]: <T extends Annotation> T getAnnotation(Class <T>) */ + public Annotation getAnnotation(Class annotationClass) + { + throw new AssertionError("Subclass must override this method"); + } + + public Annotation[] getAnnotations() + { + return getDeclaredAnnotations(); + } + + public Annotation[] getDeclaredAnnotations() + { + throw new AssertionError("Subclass must override this method"); + } + + /* FIXME[GENERICS]: Signature is Class<? extends Annotation> */ + public boolean isAnnotationPresent(Class annotationClass) + { + return getAnnotation(annotationClass) != null; + } } diff --git a/libjava/classpath/java/lang/reflect/AnnotatedElement.java b/libjava/classpath/java/lang/reflect/AnnotatedElement.java new file mode 100644 index 0000000..69a64a0 --- /dev/null +++ b/libjava/classpath/java/lang/reflect/AnnotatedElement.java @@ -0,0 +1,117 @@ +/* AnnotatedElement.java + Copyright (C) 2004, 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.lang.reflect; + +import java.lang.annotation.Annotation; + +/** + * <p> + * Represents an element that can be annotated. The methods of this interface + * provide reflection-based access to the annotations associated with a + * particular element, such as a class, field, method or package. Each + * annotation returned by these methods is both immutable and serializable. + * The returned arrays may be freely modified, without any effect on the + * arrays returned to future callers. + * </p> + * <p> + * If an annotation refers to a type or enumeration constant that is + * inaccessible, then a <code>TypeNotPresentException</code> or + * <code>EnumConstantNotPresentException</code> will be thrown. Likewise, + * invalid annotations will produce either a + * <code>AnnotationTypeMismatchException</code> or + * <code>IncompleteAnnotationException</code>. + * </p> + * + * @author Tom Tromey (tromey@redhat.com) + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface AnnotatedElement +{ + + /** + * Returns the element's annotation for the specified annotation type, + * or <code>null</code> if no such annotation exists. + * + * @param annotationClass the type of annotation to look for. + * @return this element's annotation for the specified type, or + * <code>null</code> if no such annotation exists. + * @throws NullPointerException if the annotation class is <code>null</code>. + */ + /* FIXME[GENERICS]: <T extends Annotation> T getAnnotation(Class <T>) */ + Annotation getAnnotation(Class annotationClass); + + /** + * Returns all annotations associated with the element. If there are + * no annotations associated with the element, then a zero-length array + * will be returned. The returned array may be modified by the client + * code, but this will have no effect on the annotation content of the + * element, and hence no effect on the return value of this method for + * future callers. + * + * @return this element's annotations. + */ + Annotation[] getAnnotations(); + + /** + * Returns all annotations directly defined by the element. If there are + * no annotations directly associated with the element, then a zero-length + * array will be returned. The returned array may be modified by the client + * code, but this will have no effect on the annotation content of this + * class, and hence no effect on the return value of this method for + * future callers. + * + * @return the annotations directly defined by the element. + * @since 1.5 + */ + Annotation[] getDeclaredAnnotations(); + + /** + * Returns true if an annotation for the specified type is associated + * with the element. This is primarily a short-hand for using marker + * annotations. + * + * @param annotationClass the type of annotation to look for. + * @return true if an annotation exists for the specified type. + * @since 1.5 + */ + /* FIXME[GENERICS]: Signature is Class<? extends Annotation> */ + boolean isAnnotationPresent(Class annotationClass); + +} diff --git a/libjava/classpath/java/lang/reflect/Array.java b/libjava/classpath/java/lang/reflect/Array.java index 35c77da..ae65ffb 100644 --- a/libjava/classpath/java/lang/reflect/Array.java +++ b/libjava/classpath/java/lang/reflect/Array.java @@ -38,8 +38,6 @@ exception statement from your version. */ package java.lang.reflect; -import gnu.classpath.Configuration; - /** * Array holds static helper functions that allow you to create and * manipulate arrays by reflection. Operations know how to perform widening @@ -78,13 +76,6 @@ import gnu.classpath.Configuration; */ public final class Array { - static - { - if (Configuration.INIT_LOAD_LIBRARY) - { - System.loadLibrary("javalangreflect"); - } - } /** * This class is uninstantiable. @@ -107,7 +98,7 @@ public final class Array public static Object newInstance(Class componentType, int length) { if (! componentType.isPrimitive()) - return createObjectArray(componentType, length); + return VMArray.createObjectArray(componentType, length); if (componentType == boolean.class) return new boolean[length]; if (componentType == byte.class) @@ -653,7 +644,7 @@ public final class Array Object toAdd = createMultiArray(type, dimensions, index - 1); Class thisType = toAdd.getClass(); Object[] retval - = (Object[]) createObjectArray(thisType, dimensions[index]); + = (Object[]) VMArray.createObjectArray(thisType, dimensions[index]); if (dimensions[index] > 0) retval[0] = toAdd; int i = dimensions[index]; @@ -662,14 +653,4 @@ public final class Array return retval; } - /** - * Dynamically create an array of objects. - * - * @param type guaranteed to be a valid object type - * @param dim the length of the array - * @return the new array - * @throws NegativeArraySizeException if dim is negative - * @throws OutOfMemoryError if memory allocation fails - */ - private static native Object createObjectArray(Class type, int dim); } diff --git a/libjava/classpath/java/lang/reflect/GenericDeclaration.java b/libjava/classpath/java/lang/reflect/GenericDeclaration.java new file mode 100644 index 0000000..14f5ba8 --- /dev/null +++ b/libjava/classpath/java/lang/reflect/GenericDeclaration.java @@ -0,0 +1,63 @@ +/* GenericDeclaration.java + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.lang.reflect; + +/** + * Represents an entity that declares one or more type parameters. + * This includes classes and methods (including constructors). + * + * @author Tom Tromey (tromey@redhat.com) + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public interface GenericDeclaration +{ + /** + * Returns a <code>TypeVariable</code> object for each type variable + * declared by this entity, in order of declaration. An empty array + * is returned if no type variables are declared. + * + * @return an array of <code>TypeVariable</code> objects. + * @throws GenericSignatureFormatError if the signature format within the + * class file does not conform to that specified in the 3rd edition + * of the Java Virtual Machine Specification. + */ + /* FIXME[GENERICS]: Should be TypeVariable<?>[] */ + TypeVariable[] getTypeParameters(); +} diff --git a/libjava/classpath/java/lang/reflect/GenericSignatureFormatError.java b/libjava/classpath/java/lang/reflect/GenericSignatureFormatError.java index ab6928d..0f09522 100644 --- a/libjava/classpath/java/lang/reflect/GenericSignatureFormatError.java +++ b/libjava/classpath/java/lang/reflect/GenericSignatureFormatError.java @@ -51,6 +51,7 @@ package java.lang.reflect; public class GenericSignatureFormatError extends ClassFormatError { + private static final long serialVersionUID = 6709919147137911034L; /** * Constructs a new <code>GenericSignatureFormatError</code>. diff --git a/libjava/classpath/java/lang/reflect/MalformedParameterizedTypeException.java b/libjava/classpath/java/lang/reflect/MalformedParameterizedTypeException.java new file mode 100644 index 0000000..50ae230 --- /dev/null +++ b/libjava/classpath/java/lang/reflect/MalformedParameterizedTypeException.java @@ -0,0 +1,60 @@ +/* MalformedParameterizedTypeException.java + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.lang.reflect; + +/** + * This exception class is thrown when one of the reflection + * methods encountered an invalid parameterized type within + * the metadata of a class. One possible reason for this + * exception being thrown is the specification of too few or + * too many type variables. + * + * @author Tom Tromey (tromey@redhat.com) + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +public class MalformedParameterizedTypeException + extends RuntimeException +{ + private static final long serialVersionUID = -5696557788586220964L; + + public MalformedParameterizedTypeException() + { + } +} diff --git a/libjava/classpath/java/lang/reflect/Member.java b/libjava/classpath/java/lang/reflect/Member.java index c39731f..fed962c 100644 --- a/libjava/classpath/java/lang/reflect/Member.java +++ b/libjava/classpath/java/lang/reflect/Member.java @@ -97,4 +97,13 @@ public interface Member * @see Modifier */ int getModifiers(); + + /** + * Return true if this member is synthetic, meaning that it was + * created by the compiler and does not appear in the user's + * source code. + * @return true if the member is synthetic + * @since 1.5 + */ + boolean isSynthetic(); } diff --git a/libjava/classpath/java/lang/reflect/Modifier.java b/libjava/classpath/java/lang/reflect/Modifier.java index efc88c9..45fc4e3 100644 --- a/libjava/classpath/java/lang/reflect/Modifier.java +++ b/libjava/classpath/java/lang/reflect/Modifier.java @@ -158,6 +158,26 @@ public class Modifier static final int ALL_FLAGS = 0xfff; /** + * Flag indicating a bridge method. + */ + static final int BRIDGE = 0x40; + + /** + * Flag indicating a varargs method. + */ + static final int VARARGS = 0x80; + + /** + * Flag indicating a synthetic member. + */ + static final int SYNTHETIC = 0x1000; + + /** + * Flag indicating an enum constant or an enum class. + */ + static final int ENUM = 0x4000; + + /** * Check whether the given modifier is abstract. * @param mod the modifier. * @return <code>true</code> if abstract, <code>false</code> otherwise. @@ -288,7 +308,19 @@ public class Modifier */ public static String toString(int mod) { - return toString(mod, new StringBuffer()).toString(); + return toString(mod, new StringBuilder()).toString(); + } + + /** + * Package helper method that can take a StringBuilder. + * @param mod the modifier + * @param r the StringBuilder to which the String representation is appended + * @return r, with information appended + */ + static StringBuilder toString(int mod, StringBuilder r) + { + r.append(toString(mod, new StringBuffer())); + return r; } /** diff --git a/libjava/classpath/java/lang/reflect/ParameterizedType.java b/libjava/classpath/java/lang/reflect/ParameterizedType.java index 61081c9..7a8a7b4 100644 --- a/libjava/classpath/java/lang/reflect/ParameterizedType.java +++ b/libjava/classpath/java/lang/reflect/ParameterizedType.java @@ -63,7 +63,7 @@ package java.lang.reflect; * * @author Tom Tromey (tromey@redhat.com) * @author Andrew John Hughes (gnu_andrew@member.fsf.org) - * @see GenericTypeDeclaration + * @see GenericDeclaration * @see TypeVariable * @since 1.5 */ diff --git a/libjava/classpath/java/lang/reflect/TypeVariable.java b/libjava/classpath/java/lang/reflect/TypeVariable.java new file mode 100644 index 0000000..4ecc20c --- /dev/null +++ b/libjava/classpath/java/lang/reflect/TypeVariable.java @@ -0,0 +1,99 @@ +/* TypeVariable.java + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.lang.reflect; + +/** + * <p> + * This is a common interface for all type variables provided by + * the Java language. Instances are created the first time a type + * variable is needed by one of the reflective methods declared in + * this package. + * </p> + * <p> + * Creating a type variable requires resolving the appropriate type. + * This may involve resolving other classes as a side effect (e.g. + * if the type is nested inside other classes). Creation should not + * involve resolving the bounds. Repeated creation has no effect; an + * equivalent instance is returned. Caching is not required, but all + * instances must be <code>equal()</code> to each other. + * </p> + * + * @author Tom Tromey (tromey@redhat.com) + * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @since 1.5 + */ +/* FIXME[GENERICS]: Should be TypeVariable<T extends GenericDeclaration> */ +public interface TypeVariable + extends Type +{ + + /** + * Returns an array of <code>Type</code> objects which represent the upper + * bounds of this type variable. There is always a default bound of + * <code>Object</code>. Any <code>ParameterizedType</code>s will be + * created as necessary, and other types resolved. + * + * @return an array of <code>Type</code> objects representing the upper + * bounds. + * @throws TypeNotPresentException if any of the bounds refer to a + * non-existant type. + * @throws MalformedParameterizedTypeException if the creation of a + * <code>ParameterizedType</code> fails. + */ + Type[] getBounds(); + + + /** + * Returns a representation of the declaration used to declare this + * type variable. + * + * @return the <code>GenericDeclaration</code> object for this type + * variable. + */ + /* FIXME[GENERICS]: Should return type T */ + GenericDeclaration getGenericDeclaration(); + + /** + * Returns the name of the type variable, as written in the source + * code. + * + * @return the name of the type variable. + */ + String getName(); +} |