OSDN Git Service

* java/lang/ClassLoader.java (setSigners): Implemented.
[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     memberAccessCheck(Member.DECLARED);
76
77     if ("<init>".equals(methodName) || "<clinit>".equals(methodName))
78       throw new NoSuchMethodException(methodName);
79
80     Method m = _getDeclaredMethod(methodName, parameterTypes);
81     if (m == null)
82       throw new NoSuchMethodException (methodName);
83     return m;
84   }
85
86   public native Method[] getDeclaredMethods () throws SecurityException;
87
88   // This is marked as unimplemented in the JCL book.
89   public native Class getDeclaringClass ();
90
91   private native Field getField (String fieldName, int hash)
92     throws NoSuchFieldException, SecurityException;
93
94   public Field getField (String fieldName)
95     throws NoSuchFieldException, SecurityException
96   {
97     memberAccessCheck (Member.PUBLIC);
98     Field fld = getField(fieldName, fieldName.hashCode());
99     if (fld == null)
100       throw new NoSuchFieldException(fieldName);
101     return fld;
102   }
103
104   private native Field[] _getFields (Field[] result, int offset);
105   public native Field[] getFields () throws SecurityException;
106
107   /**
108    * Returns the <code>Package</code> in which this class is defined
109    * Returns null when this information is not available from the
110    * classloader of this class or when the classloader of this class
111    * is null.
112    *
113    * @since 1.2
114    */
115   public Package getPackage()
116   {
117     ClassLoader cl = getClassLoader();
118     if (cl != null)
119       {
120         String name = getName();
121         String pkg = "";
122         int idx = name.lastIndexOf('.');
123         if (idx >= 0)
124           pkg = name.substring(0, idx);
125         return cl.getPackage(pkg);
126       }
127     else
128       return null;
129   }
130
131   public native Class[] getInterfaces ();
132
133   private final native void getSignature (StringBuffer buffer);
134   private static final native String getSignature (Class[] parameterTypes,
135                                                    boolean is_construtor);
136
137   public native Method _getMethod (String methodName, Class[] parameterTypes);
138
139   public Method getMethod (String methodName, Class[] parameterTypes)
140     throws NoSuchMethodException, SecurityException
141   {
142     memberAccessCheck(Member.PUBLIC);
143
144     if ("<init>".equals(methodName) || "<clinit>".equals(methodName))
145       throw new NoSuchMethodException(methodName);
146
147     Method m = _getMethod(methodName, parameterTypes);
148     if (m == null)
149       throw new NoSuchMethodException (methodName);
150     return m;
151   }
152
153   private native int _getMethods (Method[] result, int offset);
154   public native Method[] getMethods () throws SecurityException;
155
156   public native int getModifiers ();
157   public native String getName ();
158
159   public java.net.URL getResource (String resourceName)
160   {
161     String name = resourcePath (resourceName);
162     ClassLoader loader = getClassLoader ();
163     if (loader == null)
164       return ClassLoader.getSystemResource (name);
165     else
166       return loader.getResource (name);
167   }
168
169   public java.io.InputStream getResourceAsStream (String resourceName)
170   {
171     String name = resourcePath (resourceName);
172     ClassLoader loader = getClassLoader ();
173     if (loader == null)
174       return ClassLoader.getSystemResourceAsStream (name);
175     else
176       return loader.getResourceAsStream (name);
177   }
178
179   private String resourcePath (String resourceName)
180   {
181     if (resourceName.startsWith ("/"))
182       return resourceName.substring (1);
183
184     Class c = this;
185     while (c.isArray ())
186       c = c.getComponentType ();
187
188     String packageName = c.getName ().replace ('.', '/');
189     int end = packageName.lastIndexOf ('/');
190     if (end == -1)
191       return resourceName;
192     else
193       return packageName.substring (0, end+1) + resourceName;
194   }
195
196   public native Object[] getSigners ();
197   native void setSigners(Object[] signers);
198
199   public native Class getSuperclass ();
200   public native boolean isArray ();
201   public native boolean isAssignableFrom (Class cls);
202   public native boolean isInstance (Object obj);
203   public native boolean isInterface ();
204   public native boolean isPrimitive ();
205   public native Object newInstance ()
206     throws InstantiationException, IllegalAccessException;
207
208   // We need a native method to retrieve the protection domain, because we
209   // can't add fields to java.lang.Class that are accessible from Java.
210   private native ProtectionDomain getProtectionDomain0();
211
212   /**
213    * Returns the protection domain of this class. If the classloader
214    * did not record the protection domain when creating this class
215    * the unknown protection domain is returned which has a <code>null</code>
216    * code source and all permissions.
217    *
218    * @exception SecurityException if a security manager exists and the caller
219    * does not have <code>RuntimePermission("getProtectionDomain")</code>.
220    *
221    * @since 1.2
222    */
223   public ProtectionDomain getProtectionDomain()
224   {
225     SecurityManager sm = System.getSecurityManager();
226     if (sm != null)
227       sm.checkPermission(VMClassLoader.protectionDomainPermission);
228     
229     ProtectionDomain protectionDomain = getProtectionDomain0();
230
231     if (protectionDomain == null)
232       return VMClassLoader.unknownProtectionDomain;
233     else
234       return protectionDomain;
235   }
236
237   public String toString ()
238   {
239     if (isPrimitive ())
240       return getName ();
241     return (isInterface () ? "interface " : "class ") + getName ();
242   }
243
244   /**
245    * Returns the desired assertion status of this class, if it were to be
246    * initialized at this moment. The class assertion status, if set, is
247    * returned; the backup is the default package status; then if there is
248    * a class loader, that default is returned; and finally the system default
249    * is returned. This method seldom needs calling in user code, but exists
250    * for compilers to implement the assert statement. Note that there is no
251    * guarantee that the result of this method matches the class's actual
252    * assertion status.
253    *
254    * @return the desired assertion status
255    * @see ClassLoader#setClassAssertionStatus(String, boolean)
256    * @see ClassLoader#setPackageAssertionStatus(String, boolean)
257    * @see ClassLoader#setDefaultAssertionStatus(boolean)
258    * @since 1.4
259    */
260   public boolean desiredAssertionStatus()
261   {
262     ClassLoader c = getClassLoader();
263     Object status;
264     if (c == null)
265       return VMClassLoader.defaultAssertionStatus();
266     if (c.classAssertionStatus != null)
267       synchronized (c)
268         {
269           status = c.classAssertionStatus.get(getName());
270           if (status != null)
271             return status.equals(Boolean.TRUE);
272         }
273     else
274       {
275         status = ClassLoader.systemClassAssertionStatus.get(getName());
276         if (status != null)
277           return status.equals(Boolean.TRUE);
278       }
279     if (c.packageAssertionStatus != null)
280       synchronized (c)
281         {
282           String name = getPackagePortion(getName());
283           if ("".equals(name))
284             status = c.packageAssertionStatus.get(null);
285           else
286             do
287               {
288                 status = c.packageAssertionStatus.get(name);
289                 name = getPackagePortion(name);
290               }
291             while (! "".equals(name) && status == null);
292           if (status != null)
293             return status.equals(Boolean.TRUE);
294         }
295     else
296       {
297         String name = getPackagePortion(getName());
298         if ("".equals(name))
299           status = ClassLoader.systemPackageAssertionStatus.get(null);
300         else
301           do
302             {
303               status = ClassLoader.systemPackageAssertionStatus.get(name);
304               name = getPackagePortion(name);
305             }
306           while (! "".equals(name) && status == null);
307         if (status != null)
308           return status.equals(Boolean.TRUE);
309       }
310     return c.defaultAssertionStatus;
311   }
312
313   // Don't allow new classes to be made.
314   private Class ()
315   {
316   }
317
318   // Initialize the class.
319   private native void initializeClass ();
320
321   // finalization
322   protected native void finalize () throws Throwable;
323
324   /**
325    * Strip the last portion of the name (after the last dot).
326    *
327    * @param name the name to get package of
328    * @return the package name, or "" if no package
329    */
330   private static String getPackagePortion(String name)
331   {
332     int lastInd = name.lastIndexOf('.');
333     if (lastInd == -1)
334       return "";
335     return name.substring(0, lastInd);
336   }
337
338   /**
339    * Perform security checks common to all of the methods that
340    * get members of this Class.
341    */
342   private void memberAccessCheck(int which)
343   {
344     SecurityManager sm = System.getSecurityManager();
345     if (sm != null)
346       {
347         sm.checkMemberAccess(this, which);
348         Package pkg = getPackage();
349         if (pkg != null)
350           sm.checkPackageAccess(pkg.getName());
351       }
352   }
353 }