OSDN Git Service

New docs for Thread.java, and little tweaks identified by japi.
[pf3gnuchains/gcc-fork.git] / libjava / java / lang / Class.java
1 // Class.java - Representation of a Java class.
2
3 /* Copyright (C) 1998, 1999, 2000, 2002, 2003  Free Software Foundation
4
5    This file is part of libgcj.
6
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
9 details.  */
10
11 package java.lang;
12 import java.io.Serializable;
13 import java.io.InputStream;
14 import java.lang.reflect.*;
15 import java.security.*;
16
17 /**
18  * @author Tom Tromey <tromey@cygnus.com>
19  * @date October 1, 1998 
20  */
21
22 /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
23  * "The Java Language Specification", ISBN 0-201-63451-1
24  * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
25  * plus gcj compiler sources (to determine object layout)
26  * Status:  Sufficient for our purposes, but some methods missing
27  * and some not implemented.
28  */
29
30 public final class Class implements Serializable
31 {
32   public static native Class forName (String className)
33     throws ClassNotFoundException;
34   /** @since 1.2 */
35   public static native Class forName (String className, boolean initialize,
36                                       ClassLoader loader)
37     throws ClassNotFoundException;
38   public native Class[] getClasses ();
39   public native ClassLoader getClassLoader ();
40   public native Class getComponentType ();
41
42   public native Constructor getConstructor (Class[] parameterTypes)
43     throws NoSuchMethodException, SecurityException;
44
45   // This is used to implement getConstructors and
46   // getDeclaredConstructors.
47   private native Constructor[] _getConstructors (boolean declared)
48     throws SecurityException;
49
50   public Constructor[] getConstructors () throws SecurityException
51   {
52     return _getConstructors (false);
53   }
54
55   public native Constructor getDeclaredConstructor (Class[] parameterTypes)
56     throws NoSuchMethodException, SecurityException;
57
58   public native Class[] getDeclaredClasses () throws SecurityException;
59
60   public Constructor[] getDeclaredConstructors () throws SecurityException
61   {
62     return _getConstructors (true);
63   }
64
65   public native Field getDeclaredField (String fieldName)
66     throws NoSuchFieldException, SecurityException;
67   public native Field[] getDeclaredFields () throws SecurityException;
68
69   private native Method _getDeclaredMethod (String methodName,
70                                             Class[] parameterTypes);
71
72   public Method getDeclaredMethod (String methodName, Class[] parameterTypes)
73     throws NoSuchMethodException, SecurityException
74   {
75     SecurityManager sm = System.getSecurityManager();
76     if (sm != null)
77       {
78         sm.checkMemberAccess(this, Member.DECLARED);
79         Package p = getPackage();
80         if (p != null)
81           sm.checkPackageAccess(p.getName());
82       }
83
84     if ("<init>".equals(methodName) || "<clinit>".equals(methodName))
85       throw new NoSuchMethodException(methodName);
86
87     Method m = _getDeclaredMethod(methodName, parameterTypes);
88     if (m == null)
89       throw new NoSuchMethodException (methodName);
90     return m;
91   }
92
93   public native Method[] getDeclaredMethods () throws SecurityException;
94
95   // This is marked as unimplemented in the JCL book.
96   public native Class getDeclaringClass ();
97
98   private native Field getField (String fieldName, int hash)
99     throws NoSuchFieldException, SecurityException;
100
101   public Field getField (String fieldName)
102     throws NoSuchFieldException, SecurityException
103   {
104     SecurityManager s = System.getSecurityManager();
105     if (s != null)
106       s.checkMemberAccess (this, java.lang.reflect.Member.DECLARED);
107     Field fld = getField(fieldName, fieldName.hashCode());
108     if (fld == null)
109       throw new NoSuchFieldException(fieldName);
110     return fld;
111   }
112
113   private native Field[] _getFields (Field[] result, int offset);
114   public native Field[] getFields () throws SecurityException;
115
116   /**
117    * Returns the <code>Package</code> in which this class is defined
118    * Returns null when this information is not available from the
119    * classloader of this class or when the classloader of this class
120    * is null.
121    *
122    * @since 1.2
123    */
124   public Package getPackage()
125   {
126     ClassLoader cl = getClassLoader();
127     if (cl != null)
128       {
129         String name = getName();
130         String pkg = "";
131         int idx = name.lastIndexOf('.');
132         if (idx >= 0)
133           pkg = name.substring(0, idx);
134         return cl.getPackage(pkg);
135       }
136     else
137       return null;
138   }
139
140   public native Class[] getInterfaces ();
141
142   private final native void getSignature (StringBuffer buffer);
143   private static final native String getSignature (Class[] parameterTypes,
144                                                    boolean is_construtor);
145
146   public native Method _getMethod (String methodName, Class[] parameterTypes);
147
148   public Method getMethod (String methodName, Class[] parameterTypes)
149     throws NoSuchMethodException, SecurityException
150   {
151     SecurityManager sm = System.getSecurityManager();
152     if (sm != null)
153       {
154         sm.checkMemberAccess(this, Member.PUBLIC);
155         Package p = getPackage();
156         if (p != null)
157           sm.checkPackageAccess(p.getName());
158       }
159
160     if ("<init>".equals(methodName) || "<clinit>".equals(methodName))
161       throw new NoSuchMethodException(methodName);
162
163     Method m = _getMethod(methodName, parameterTypes);
164     if (m == null)
165       throw new NoSuchMethodException (methodName);
166     return m;
167   }
168
169   private native int _getMethods (Method[] result, int offset);
170   public native Method[] getMethods () throws SecurityException;
171
172   public native int getModifiers ();
173   public native String getName ();
174
175   public java.net.URL getResource (String resourceName)
176   {
177     String name = resourcePath (resourceName);
178     ClassLoader loader = getClassLoader ();
179     if (loader == null)
180       return ClassLoader.getSystemResource (name);
181     else
182       return loader.getResource (name);
183   }
184
185   public java.io.InputStream getResourceAsStream (String resourceName)
186   {
187     String name = resourcePath (resourceName);
188     ClassLoader loader = getClassLoader ();
189     if (loader == null)
190       return ClassLoader.getSystemResourceAsStream (name);
191     else
192       return loader.getResourceAsStream (name);
193   }
194
195   private String resourcePath (String resourceName)
196   {
197     if (resourceName.startsWith ("/"))
198       return resourceName.substring (1);
199
200     Class c = this;
201     while (c.isArray ())
202       c = c.getComponentType ();
203
204     String packageName = c.getName ().replace ('.', '/');
205     int end = packageName.lastIndexOf ('/');
206     if (end == -1)
207       return resourceName;
208     else
209       return packageName.substring (0, end+1) + resourceName;
210   }
211
212   // FIXME: implement.  Requires java.security.
213   public Object[] getSigners ()
214   {
215     return null;
216   }
217
218   public native Class getSuperclass ();
219   public native boolean isArray ();
220   public native boolean isAssignableFrom (Class cls);
221   public native boolean isInstance (Object obj);
222   public native boolean isInterface ();
223   public native boolean isPrimitive ();
224   public native Object newInstance ()
225     throws InstantiationException, IllegalAccessException;
226
227   // We need a native method to retrieve the protection domain, because we
228   // can't add fields to java.lang.Class that are accessible from Java.
229   private native ProtectionDomain getProtectionDomain0();
230
231   /**
232    * Returns the protection domain of this class. If the classloader
233    * did not record the protection domain when creating this class
234    * the unknown protection domain is returned which has a <code>null</code>
235    * code source and all permissions.
236    *
237    * @exception SecurityException if a security manager exists and the caller
238    * does not have <code>RuntimePermission("getProtectionDomain")</code>.
239    *
240    * @since 1.2
241    */
242   public ProtectionDomain getProtectionDomain()
243   {
244     SecurityManager sm = System.getSecurityManager();
245     if (sm != null)
246       sm.checkPermission(ClassLoader.protectionDomainPermission);
247     
248     ProtectionDomain protectionDomain = getProtectionDomain0();
249
250     if (protectionDomain == null)
251       return ClassLoader.unknownProtectionDomain;
252     else
253       return protectionDomain;
254   }
255
256   public String toString ()
257   {
258     if (isPrimitive ())
259       return getName ();
260     return (isInterface () ? "interface " : "class ") + getName ();
261   }
262
263   /**
264    * Returns the desired assertion status of this class, if it were to be
265    * initialized at this moment. The class assertion status, if set, is
266    * returned; the backup is the default package status; then if there is
267    * a class loader, that default is returned; and finally the system default
268    * is returned. This method seldom needs calling in user code, but exists
269    * for compilers to implement the assert statement. Note that there is no
270    * guarantee that the result of this method matches the class's actual
271    * assertion status.
272    *
273    * @return the desired assertion status
274    * @see ClassLoader#setClassAssertionStatus(String, boolean)
275    * @see ClassLoader#setPackageAssertionStatus(String, boolean)
276    * @see ClassLoader#setDefaultAssertionStatus(boolean)
277    * @since 1.4
278    */
279   public boolean desiredAssertionStatus()
280   {
281     ClassLoader c = getClassLoader();
282     Object status;
283     if (c == null)
284       return VMClassLoader.defaultAssertionStatus();
285     if (c.classAssertionStatus != null)
286       synchronized (c)
287         {
288           status = c.classAssertionStatus.get(getName());
289           if (status != null)
290             return status.equals(Boolean.TRUE);
291         }
292     else
293       {
294         status = ClassLoader.systemClassAssertionStatus.get(getName());
295         if (status != null)
296           return status.equals(Boolean.TRUE);
297       }
298     if (c.packageAssertionStatus != null)
299       synchronized (c)
300         {
301           String name = getPackagePortion(getName());
302           if ("".equals(name))
303             status = c.packageAssertionStatus.get(null);
304           else
305             do
306               {
307                 status = c.packageAssertionStatus.get(name);
308                 name = getPackagePortion(name);
309               }
310             while (! "".equals(name) && status == null);
311           if (status != null)
312             return status.equals(Boolean.TRUE);
313         }
314     else
315       {
316         String name = getPackagePortion(getName());
317         if ("".equals(name))
318           status = ClassLoader.systemPackageAssertionStatus.get(null);
319         else
320           do
321             {
322               status = ClassLoader.systemPackageAssertionStatus.get(name);
323               name = getPackagePortion(name);
324             }
325           while (! "".equals(name) && status == null);
326         if (status != null)
327           return status.equals(Boolean.TRUE);
328       }
329     return c.defaultAssertionStatus;
330   }
331
332   // Don't allow new classes to be made.
333   private Class ()
334   {
335   }
336
337   // Do a security check.
338   private void checkMemberAccess (int flags)
339   {
340     SecurityManager sm = System.getSecurityManager();
341     if (sm != null)
342       sm.checkMemberAccess(this, flags);
343   }
344
345   // Initialize the class.
346   private native void initializeClass ();
347
348   // finalization
349   protected native void finalize () throws Throwable;
350
351   /**
352    * Strip the last portion of the name (after the last dot).
353    *
354    * @param name the name to get package of
355    * @return the package name, or "" if no package
356    */
357   private static String getPackagePortion(String name)
358   {
359     int lastInd = name.lastIndexOf('.');
360     if (lastInd == -1)
361       return "";
362     return name.substring(0, lastInd);
363   }
364 }