Commit 7666af89 by Tom Tromey Committed by Tom Tromey

Class.java (getClasses): New method.

	* java/lang/Class.java (getClasses): New method.
	(internalGetClasses): Likewise.
	(getClassLoader): Updated documentation.
	(getDeclaredClasses): New overload; old overload no longer
	native.
	(_getConstructors): Removed.
	(resourcePath): Updated.
	* java/lang/natClass.cc (getClasses): Removed.
	* java/lang/Class.h (getDeclaredClasses, getDeclaredConstructors):
	Updated.
	(_getConstructors): Removed.

From-SVN: r100948
parent c9a3d128
2005-06-14 Tom Tromey <tromey@redhat.com>
* java/lang/Class.java (getClasses): New method.
(internalGetClasses): Likewise.
(getClassLoader): Updated documentation.
(getDeclaredClasses): New overload; old overload no longer
native.
(_getConstructors): Removed.
(resourcePath): Updated.
* java/lang/natClass.cc (getClasses): Removed.
* java/lang/Class.h (getDeclaredClasses, getDeclaredConstructors):
Updated.
(_getConstructors): Removed.
2005-06-13 Jim Huang <jserv@kaffe.org> 2005-06-13 Jim Huang <jserv@kaffe.org>
PR libgcj/22036: PR libgcj/22036:
......
...@@ -273,7 +273,7 @@ public: ...@@ -273,7 +273,7 @@ public:
java::lang::reflect::Constructor *getConstructor (JArray<jclass> *); java::lang::reflect::Constructor *getConstructor (JArray<jclass> *);
JArray<java::lang::reflect::Constructor *> *getConstructors (void); JArray<java::lang::reflect::Constructor *> *getConstructors (void);
java::lang::reflect::Constructor *getDeclaredConstructor (JArray<jclass> *); java::lang::reflect::Constructor *getDeclaredConstructor (JArray<jclass> *);
JArray<java::lang::reflect::Constructor *> *getDeclaredConstructors (void); JArray<java::lang::reflect::Constructor *> *getDeclaredConstructors (jboolean);
java::lang::reflect::Field *getDeclaredField (jstring); java::lang::reflect::Field *getDeclaredField (jstring);
JArray<java::lang::reflect::Field *> *getDeclaredFields (); JArray<java::lang::reflect::Field *> *getDeclaredFields ();
JArray<java::lang::reflect::Field *> *getDeclaredFields (jboolean); JArray<java::lang::reflect::Field *> *getDeclaredFields (jboolean);
...@@ -281,12 +281,12 @@ public: ...@@ -281,12 +281,12 @@ public:
JArray<java::lang::reflect::Method *> *getDeclaredMethods (void); JArray<java::lang::reflect::Method *> *getDeclaredMethods (void);
JArray<jclass> *getDeclaredClasses (void); JArray<jclass> *getDeclaredClasses (void);
JArray<jclass> *getDeclaredClasses (jboolean);
jclass getDeclaringClass (void); jclass getDeclaringClass (void);
java::lang::reflect::Field *getField (jstring); java::lang::reflect::Field *getField (jstring);
private: private:
JArray<java::lang::reflect::Field *> internalGetFields (); JArray<java::lang::reflect::Field *> internalGetFields ();
JArray<java::lang::reflect::Constructor *> *_getConstructors (jboolean);
java::lang::reflect::Field *getField (jstring, jint); java::lang::reflect::Field *getField (jstring, jint);
jint _getMethods (JArray<java::lang::reflect::Method *> *result, jint _getMethods (JArray<java::lang::reflect::Method *> *result,
jint offset); jint offset);
......
/* Class.java -- Representation of a Java class. /* Class.java -- Representation of a Java class.
Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004 Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005
Free Software Foundation Free Software Foundation
This file is part of GNU Classpath. This file is part of GNU Classpath.
...@@ -46,6 +46,7 @@ import java.lang.reflect.Member; ...@@ -46,6 +46,7 @@ import java.lang.reflect.Member;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.net.URL; import java.net.URL;
import java.security.ProtectionDomain; import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
...@@ -54,9 +55,11 @@ import java.util.HashSet; ...@@ -54,9 +55,11 @@ import java.util.HashSet;
* objects with identical names and ClassLoaders. Primitive types, array * objects with identical names and ClassLoaders. Primitive types, array
* types, and void also have a Class object. * types, and void also have a Class object.
* *
* <p>Arrays with identical type and number of dimensions share the same * <p>Arrays with identical type and number of dimensions share the same class.
* class (and null "system" ClassLoader, incidentally). The name of an * The array class ClassLoader is the same as the ClassLoader of the element
* array class is <code>[&lt;signature format&gt;;</code> ... for example, * type of the array (which can be null to indicate the bootstrap classloader).
* The name of an array class is <code>[&lt;signature format&gt;;</code>.
* <p> For example,
* String[]'s class is <code>[Ljava.lang.String;</code>. boolean, byte, * String[]'s class is <code>[Ljava.lang.String;</code>. boolean, byte,
* short, char, int, long, float and double have the "type name" of * short, char, int, long, float and double have the "type name" of
* Z,B,S,C,I,J,F,D for the purposes of array classes. If it's a * Z,B,S,C,I,J,F,D for the purposes of array classes. If it's a
...@@ -148,13 +151,31 @@ public final class Class implements Serializable ...@@ -148,13 +151,31 @@ public final class Class implements Serializable
* @throws SecurityException if the security check fails * @throws SecurityException if the security check fails
* @since 1.1 * @since 1.1
*/ */
public native Class[] getClasses (); public Class[] getClasses()
{
memberAccessCheck(Member.PUBLIC);
return internalGetClasses();
}
/**
* Like <code>getClasses()</code> but without the security checks.
*/
private Class[] internalGetClasses()
{
ArrayList list = new ArrayList();
list.addAll(Arrays.asList(getDeclaredClasses(true)));
Class superClass = getSuperclass();
if (superClass != null)
list.addAll(Arrays.asList(superClass.internalGetClasses()));
return (Class[])list.toArray(new Class[list.size()]);
}
/** /**
* Get the ClassLoader that loaded this class. If it was loaded by the * Get the ClassLoader that loaded this class. If the class was loaded
* system classloader, this method will return null. If there is a security * by the bootstrap classloader, this method will return null.
* manager, and the caller's class loader does not match the requested * If there is a security manager, and the caller's class loader is not
* one, a security check of <code>RuntimePermission("getClassLoader")</code> * an ancestor of the requested one, a security check of
* <code>RuntimePermission("getClassLoader")</code>
* must first succeed. Primitive types and void return null. * must first succeed. Primitive types and void return null.
* *
* @return the ClassLoader that loaded this class * @return the ClassLoader that loaded this class
...@@ -193,10 +214,6 @@ public final class Class implements Serializable ...@@ -193,10 +214,6 @@ public final class Class implements Serializable
public native Constructor getConstructor(Class[] args) public native Constructor getConstructor(Class[] args)
throws NoSuchMethodException; throws NoSuchMethodException;
// This is used to implement getConstructors and
// getDeclaredConstructors.
private native Constructor[] _getConstructors (boolean declared);
/** /**
* Get all the public constructors of this class. This returns an array of * Get all the public constructors of this class. This returns an array of
* length 0 if there are no constructors, including for primitive types, * length 0 if there are no constructors, including for primitive types,
...@@ -211,7 +228,8 @@ public final class Class implements Serializable ...@@ -211,7 +228,8 @@ public final class Class implements Serializable
*/ */
public Constructor[] getConstructors() public Constructor[] getConstructors()
{ {
return _getConstructors(false); memberAccessCheck(Member.PUBLIC);
return getDeclaredConstructors(true);
} }
/** /**
...@@ -243,7 +261,13 @@ public final class Class implements Serializable ...@@ -243,7 +261,13 @@ public final class Class implements Serializable
* @throws SecurityException if the security check fails * @throws SecurityException if the security check fails
* @since 1.1 * @since 1.1
*/ */
public native Class[] getDeclaredClasses(); public Class[] getDeclaredClasses()
{
memberAccessCheck(Member.DECLARED);
return getDeclaredClasses(false);
}
native Class[] getDeclaredClasses (boolean publicOnly);
/** /**
* Get all the declared constructors of this class. This returns an array of * Get all the declared constructors of this class. This returns an array of
...@@ -259,9 +283,12 @@ public final class Class implements Serializable ...@@ -259,9 +283,12 @@ public final class Class implements Serializable
*/ */
public Constructor[] getDeclaredConstructors() public Constructor[] getDeclaredConstructors()
{ {
return _getConstructors(true); memberAccessCheck(Member.DECLARED);
return getDeclaredConstructors(false);
} }
native Constructor[] getDeclaredConstructors (boolean publicOnly);
/** /**
* Get a field declared in this class, where name is its simple name. The * Get a field declared in this class, where name is its simple name. The
* implicit length field of arrays is not available. A security check may * implicit length field of arrays is not available. A security check may
...@@ -303,8 +330,8 @@ public final class Class implements Serializable ...@@ -303,8 +330,8 @@ public final class Class implements Serializable
/** /**
* Get a method declared in this class, where name is its simple name. The * Get a method declared in this class, where name is its simple name. The
* implicit methods of Object are not available from arrays or interfaces. * implicit methods of Object are not available from arrays or interfaces.
* Constructors (named "<init>" in the class file) and class initializers * Constructors (named "&lt;init&gt;" in the class file) and class initializers
* (name "<clinit>") are not available. The Virtual Machine allows * (name "&lt;clinit&gt;") are not available. The Virtual Machine allows
* multiple methods with the same signature but differing return types; in * multiple methods with the same signature but differing return types; in
* such a case the most specific return types are favored, then the final * such a case the most specific return types are favored, then the final
* choice is arbitrary. If the method takes no argument, an array of zero * choice is arbitrary. If the method takes no argument, an array of zero
...@@ -438,14 +465,7 @@ public final class Class implements Serializable ...@@ -438,14 +465,7 @@ public final class Class implements Serializable
{ {
ClassLoader cl = getClassLoader(); ClassLoader cl = getClassLoader();
if (cl != null) if (cl != null)
{ return cl.getPackage(getPackagePortion(getName()));
String name = getName();
String pkg = "";
int idx = name.lastIndexOf('.');
if (idx >= 0)
pkg = name.substring(0, idx);
return cl.getPackage(pkg);
}
return null; return null;
} }
...@@ -468,8 +488,8 @@ public final class Class implements Serializable ...@@ -468,8 +488,8 @@ public final class Class implements Serializable
/** /**
* Get a public method declared or inherited in this class, where name is * Get a public method declared or inherited in this class, where name is
* its simple name. The implicit methods of Object are not available from * its simple name. The implicit methods of Object are not available from
* interfaces. Constructors (named "<init>" in the class file) and class * interfaces. Constructors (named "&lt;init&gt;" in the class file) and class
* initializers (name "<clinit>") are not available. The Virtual * initializers (name "&lt;clinit&gt;") are not available. The Virtual
* Machine allows multiple methods with the same signature but differing * Machine allows multiple methods with the same signature but differing
* return types, and the class can inherit multiple methods of the same * return types, and the class can inherit multiple methods of the same
* return type; in such a case the most specific return types are favored, * return type; in such a case the most specific return types are favored,
...@@ -537,8 +557,16 @@ public final class Class implements Serializable ...@@ -537,8 +557,16 @@ public final class Class implements Serializable
/** /**
* Get the name of this class, separated by dots for package separators. * Get the name of this class, separated by dots for package separators.
* Primitive types and arrays are encoded as: * If the class represents a primitive type, or void, then the
* name of the type as it appears in the Java programming language
* is returned. For instance, <code>Byte.TYPE.getName()</code>
* returns "byte".
*
* Arrays are specially encoded as shown on this table.
* <pre> * <pre>
* array type [<em>element type</em>
* (note that the element type is encoded per
* this table)
* boolean Z * boolean Z
* byte B * byte B
* char C * char C
...@@ -548,9 +576,9 @@ public final class Class implements Serializable ...@@ -548,9 +576,9 @@ public final class Class implements Serializable
* float F * float F
* double D * double D
* void V * void V
* array type [<em>element type</em>
* class or interface, alone: &lt;dotted name&gt; * class or interface, alone: &lt;dotted name&gt;
* class or interface, as element type: L&lt;dotted name&gt;; * class or interface, as element type: L&lt;dotted name&gt;;
* </pre>
* *
* @return the name of this class * @return the name of this class
*/ */
...@@ -562,9 +590,9 @@ public final class Class implements Serializable ...@@ -562,9 +590,9 @@ public final class Class implements Serializable
* the system classloader, ClassLoader.getSystemResource() is used instead. * the system classloader, ClassLoader.getSystemResource() is used instead.
* *
* <p>If the name you supply is absolute (it starts with a <code>/</code>), * <p>If the name you supply is absolute (it starts with a <code>/</code>),
* then it is passed on to getResource() as is. If it is relative, the * then the leading <code>/</code> is removed and it is passed on to
* package name is prepended, and <code>.</code>'s are replaced with * getResource(). If it is relative, the package name is prepended, and
* <code>/</code>. * <code>.</code>'s are replaced with <code>/</code>.
* *
* <p>The URL returned is system- and classloader-dependent, and could * <p>The URL returned is system- and classloader-dependent, and could
* change across implementations. * change across implementations.
...@@ -590,9 +618,9 @@ public final class Class implements Serializable ...@@ -590,9 +618,9 @@ public final class Class implements Serializable
* instead. * instead.
* *
* <p>If the name you supply is absolute (it starts with a <code>/</code>), * <p>If the name you supply is absolute (it starts with a <code>/</code>),
* then it is passed on to getResource() as is. If it is relative, the * then the leading <code>/</code> is removed and it is passed on to
* package name is prepended, and <code>.</code>'s are replaced with * getResource(). If it is relative, the package name is prepended, and
* <code>/</code>. * <code>.</code>'s are replaced with <code>/</code>.
* *
* <p>The URL returned is system- and classloader-dependent, and could * <p>The URL returned is system- and classloader-dependent, and could
* change across implementations. * change across implementations.
...@@ -613,17 +641,19 @@ public final class Class implements Serializable ...@@ -613,17 +641,19 @@ public final class Class implements Serializable
private String resourcePath(String resourceName) private String resourcePath(String resourceName)
{ {
if (resourceName.startsWith("/")) if (resourceName.length() > 0)
return resourceName.substring(1); {
if (resourceName.charAt(0) != '/')
Class c = this; {
while (c.isArray()) String pkg = getPackagePortion(getName());
c = c.getComponentType(); if (pkg.length() > 0)
resourceName = pkg.replace('.','/') + '/' + resourceName;
String packageName = c.getName().replace('.', '/'); }
int end = packageName.lastIndexOf('/'); else
if (end != -1) {
return packageName.substring(0, end + 1) + resourceName; resourceName = resourceName.substring(1);
}
}
return resourceName; return resourceName;
} }
...@@ -739,18 +769,6 @@ public final class Class implements Serializable ...@@ -739,18 +769,6 @@ public final class Class implements Serializable
// can't add fields to java.lang.Class that are accessible from Java. // can't add fields to java.lang.Class that are accessible from Java.
private native ProtectionDomain getProtectionDomain0(); private native ProtectionDomain getProtectionDomain0();
/**
* Returns the protection domain of this class. If the classloader did not
* record the protection domain when creating this class the unknown
* protection domain is returned which has a <code>null</code> code source
* and all permissions.
*
* @return the protection domain
* @throws SecurityException if the security manager exists and the caller
* does not have <code>RuntimePermission("getProtectionDomain")</code>.
* @see RuntimePermission
* @since 1.2
*/
public ProtectionDomain getProtectionDomain() public ProtectionDomain getProtectionDomain()
{ {
SecurityManager sm = System.getSecurityManager(); SecurityManager sm = System.getSecurityManager();
......
...@@ -126,15 +126,6 @@ java::lang::Class::getClassLoader (void) ...@@ -126,15 +126,6 @@ java::lang::Class::getClassLoader (void)
s->checkPermission (new RuntimePermission (JvNewStringLatin1 ("getClassLoader"))); s->checkPermission (new RuntimePermission (JvNewStringLatin1 ("getClassLoader")));
} }
// This particular 'return' has been changed a couple of times over
// libgcj's history. This particular approach is a little weird,
// because it means that all classes linked into the application
// will see NULL for their class loader. This may confuse some
// applications that aren't expecting this; the solution is to use a
// different linking model for these applications. In the past we
// returned the system class loader in this case, but that is
// incorrect. Also, back then we didn't have other linkage models
// to fall back on.
return loader; return loader;
} }
...@@ -167,10 +158,8 @@ java::lang::Class::getConstructor (JArray<jclass> *param_types) ...@@ -167,10 +158,8 @@ java::lang::Class::getConstructor (JArray<jclass> *param_types)
} }
JArray<java::lang::reflect::Constructor *> * JArray<java::lang::reflect::Constructor *> *
java::lang::Class::_getConstructors (jboolean declared) java::lang::Class::getDeclaredConstructors (jboolean publicOnly)
{ {
memberAccessCheck(java::lang::reflect::Member::PUBLIC);
int numConstructors = 0; int numConstructors = 0;
int max = isPrimitive () ? 0 : method_count; int max = isPrimitive () ? 0 : method_count;
int i; int i;
...@@ -180,7 +169,7 @@ java::lang::Class::_getConstructors (jboolean declared) ...@@ -180,7 +169,7 @@ java::lang::Class::_getConstructors (jboolean declared)
if (method->name == NULL if (method->name == NULL
|| ! _Jv_equalUtf8Consts (method->name, init_name)) || ! _Jv_equalUtf8Consts (method->name, init_name))
continue; continue;
if (! declared if (publicOnly
&& ! java::lang::reflect::Modifier::isPublic(method->accflags)) && ! java::lang::reflect::Modifier::isPublic(method->accflags))
continue; continue;
numConstructors++; numConstructors++;
...@@ -197,7 +186,7 @@ java::lang::Class::_getConstructors (jboolean declared) ...@@ -197,7 +186,7 @@ java::lang::Class::_getConstructors (jboolean declared)
if (method->name == NULL if (method->name == NULL
|| ! _Jv_equalUtf8Consts (method->name, init_name)) || ! _Jv_equalUtf8Consts (method->name, init_name))
continue; continue;
if (! declared if (publicOnly
&& ! java::lang::reflect::Modifier::isPublic(method->accflags)) && ! java::lang::reflect::Modifier::isPublic(method->accflags))
continue; continue;
java::lang::reflect::Constructor *cons java::lang::reflect::Constructor *cons
...@@ -427,22 +416,8 @@ java::lang::Class::getName (void) ...@@ -427,22 +416,8 @@ java::lang::Class::getName (void)
} }
JArray<jclass> * JArray<jclass> *
java::lang::Class::getClasses (void) java::lang::Class::getDeclaredClasses (jboolean /*publicOnly*/)
{
// FIXME: security checking.
// Until we have inner classes, it always makes sense to return an
// empty array.
JArray<jclass> *result
= (JArray<jclass> *) JvNewObjectArray (0, &java::lang::Class::class$,
NULL);
return result;
}
JArray<jclass> *
java::lang::Class::getDeclaredClasses (void)
{ {
memberAccessCheck (java::lang::reflect::Member::DECLARED);
// Until we have inner classes, it always makes sense to return an // Until we have inner classes, it always makes sense to return an
// empty array. // empty array.
JArray<jclass> *result JArray<jclass> *result
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment