Initial import
[jpf-core.git] / src / classes / java / lang / Class.java
1 /*
2  * Copyright (C) 2014, United States Government, as represented by the
3  * Administrator of the National Aeronautics and Space Administration.
4  * All rights reserved.
5  *
6  * The Java Pathfinder core (jpf-core) platform is licensed under the
7  * Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  * 
10  *        http://www.apache.org/licenses/LICENSE-2.0. 
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and 
16  * limitations under the License.
17  */
18 package java.lang;
19
20 import java.io.ByteArrayInputStream;
21 import java.io.InputStream;
22 import java.io.Serializable;
23 import java.lang.annotation.Annotation;
24 import java.lang.reflect.AnnotatedElement;
25 import java.lang.reflect.Constructor;
26 import java.lang.reflect.Field;
27 import java.lang.reflect.GenericDeclaration;
28 import java.lang.reflect.Method;
29 import java.lang.reflect.Type;
30 import java.lang.reflect.TypeVariable;
31 import java.net.URL;
32 import java.util.HashMap;
33 import java.util.Map;
34
35 import sun.reflect.ConstantPool;
36 import sun.reflect.annotation.AnnotationType;
37
38 /**
39  * MJI model class for java.lang.Class library abstraction
40  *
41  * This is a JPF specific version of a system class because we can't use the real,
42  * platform VM specific version (it's native all over the place, its field
43  * structure isn't documented, most of its methods are private, hence we can't
44  * even instantiate it properly).
45  *
46  * Note that this class never gets seen by the real VM - it's for JPF's eyes only.
47  *
48  * For now, it's only a fragment to test the mechanism, and provide basic
49  * class.getName() / Class.ForName() support (which is (almost) enough for
50  * Java assertion support
51  */
52 @SuppressWarnings("unused")  // native peer uses
53 public final class Class<T> implements Serializable, GenericDeclaration, Type, AnnotatedElement {
54
55   /** don't use serialVersionUID from JDK 1.1 for interoperability */
56   private static final long serialVersionUID = 3206093459760846163L + 1;
57
58    // we init this on demand (from MJIEnv) since it's not used too often
59   private static Annotation[] emptyAnnotations; // = new Annotation[0];
60   
61   private String name;
62
63   private ClassLoader classLoader;
64   
65   /**
66    * search global id of the corresponding ClassInfo, which factors in the classloader
67    */
68   private int nativeId;
69
70   /**
71    * to be set during <clinit> of the corresponding class
72    */
73   private boolean isPrimitive;
74   
75   private Class() {}
76
77   public native boolean isArray ();
78
79   @Override
80   public native Annotation[] getAnnotations();
81
82   @Override
83   public native <A extends Annotation> A getAnnotation( Class<A> annotationCls);
84
85   // those are from Java 6
86   public native boolean isAnnotation ();
87   @Override
88   public native boolean isAnnotationPresent(Class<? extends Annotation> annotationClass);
89
90   public native Class<?> getComponentType ();
91
92   public native Field[] getFields() throws SecurityException;
93   
94   public native Field getDeclaredField (String fieldName) throws NoSuchFieldException,
95                                                           SecurityException;
96
97   public native Field[] getDeclaredFields () throws SecurityException;
98
99   public native Method getDeclaredMethod (String mthName, Class<?>... paramTypes)
100                             throws NoSuchMethodException, SecurityException;
101
102   public native Method getMethod (String mthName, Class<?>... paramTypes)
103                     throws NoSuchMethodException, SecurityException;
104
105   public native Method[] getDeclaredMethods () throws SecurityException;
106
107   public native Method[] getMethods () throws SecurityException;
108     
109   public native Constructor<?>[] getDeclaredConstructors() throws SecurityException;
110
111   public native Constructor<?>[] getConstructors() throws SecurityException;
112
113   private native byte[] getByteArrayFromResourceStream(String name);
114
115   public InputStream getResourceAsStream (String name) {
116     byte[] byteArray = getByteArrayFromResourceStream(name);
117     if (byteArray == null) return null;
118     return new ByteArrayInputStream(byteArray);
119   }
120
121   private native String getResolvedName (String rname);
122
123   public URL getResource (String rname) {
124     String resolvedName = getResolvedName(rname);
125     return getClassLoader().getResource(resolvedName);
126   }
127
128   public Package getPackage() {
129     // very very crude version for now, only supports the package name
130     String pkgName = null;
131
132     int idx = name.lastIndexOf('.');
133     if (idx >=0){
134       pkgName = name.substring(0,idx);
135
136       Package pkg = new Package(pkgName,
137                                 "spectitle", "specversion", "specvendor",
138                                 "impltitle", "implversion", "implvendor",
139                                  null, getClassLoader());
140         return pkg;
141
142     } else { // weird, but there is no Package object for the default package
143       return null;
144     }
145
146   }
147
148   //--- enum support ()
149   // Java 1.5
150   public native T[] getEnumConstants();
151
152   // Java 6
153   T[] getEnumConstantsShared() {
154     return getEnumConstants();
155   }
156   
157   // lazy initialized map for field name -> Enum constants
158   // <2do> we should move this to the native side, since Enum constants don't change
159   private transient Map<String, T> enumConstantDirectory = null;
160
161   // package private helper for Enum.valueOf()
162   Map<String,T> enumConstantDirectory() {
163     if (enumConstantDirectory == null) {
164       Map<String,T> map = new HashMap<String,T>();
165
166       T[] ae = getEnumConstants();
167       for (T e: ae) {
168         map.put(((Enum)e).name(), e);
169       }
170
171       enumConstantDirectory = map;
172     }
173     return enumConstantDirectory;
174   }
175
176
177   public native Constructor<T> getDeclaredConstructor (Class<?>... paramTypes)
178               throws NoSuchMethodException, SecurityException;
179
180   public native Field getField (String fieldName) throws NoSuchFieldException,
181                                                   SecurityException;
182
183   public native boolean isInstance (Object o);
184
185   public native boolean isAssignableFrom (Class<?> clazz);
186
187   public native boolean isInterface();
188
189   public native Constructor<T> getConstructor (Class<?>... argTypes) throws NoSuchMethodException, SecurityException;
190
191   public native int getModifiers();
192
193   public native Class<?>[] getInterfaces();
194
195   // no use to have a ctor, we can't call it
196   public String getName () {
197     return name;
198   }
199
200   public String getSimpleName () {
201     int idx; // <2do> not really - inner classes?
202     Class<?> enclosingClass = getEnclosingClass();
203     
204     if(enclosingClass!=null){
205       idx = enclosingClass.getName().length();
206     } else{
207       idx = name.lastIndexOf('.');
208     }
209     
210     return name.substring(idx+1);
211   }
212
213   static native Class<?> getPrimitiveClass (String clsName);
214
215    /**
216     * this one is in JPF reflection land, it's 'native' for us
217     */
218   public static native Class<?> forName (String clsName) throws ClassNotFoundException;
219
220   public static Class<?> forName (String clsName, boolean initialize, ClassLoader loader) throws ClassNotFoundException {
221     Class<?> cls;
222     if (loader == null){
223       cls = forName(clsName);
224     } else {
225       cls = loader.loadClass(clsName);
226     }
227     
228     if (initialize) {
229       cls.initialize0();
230     }
231     return cls;
232   }
233
234   /**
235    * forces clinit without explicit field or method access
236    */
237   private native void initialize0 ();
238   
239   public boolean isPrimitive () {
240     return isPrimitive;
241   }
242
243   public native Class<? super T> getSuperclass ();
244
245   public native T newInstance () throws InstantiationException,
246                                       IllegalAccessException;
247
248   @Override
249   public String toString () {
250     return (isInterface() ? "interface " : "class ") + name;
251   }
252
253   @SuppressWarnings("unchecked")
254   public T cast(Object o) {
255     if (o != null && !isInstance(o)) throw new ClassCastException();
256     return (T) o;
257   }
258   
259   @SuppressWarnings("unchecked")
260   public <U> Class<? extends U> asSubclass(Class<U> clazz) {
261     if (clazz.isAssignableFrom(this)) {
262       return (Class<? extends U>) this;
263     } else {
264       throw new ClassCastException("" + this + " is not a " + clazz);
265     }
266   }
267
268   native public boolean desiredAssertionStatus ();
269
270   public ClassLoader getClassLoader() {
271     return classLoader;
272   }
273
274   native ConstantPool getConstantPool();
275
276   native void setAnnotationType (AnnotationType at);
277
278   native AnnotationType getAnnotationType();
279   
280   @Override
281   public TypeVariable<Class<T>>[] getTypeParameters() {
282     throw new UnsupportedOperationException();
283   }
284   
285   public Type getGenericSuperclass() {
286     throw new UnsupportedOperationException();
287   }
288   
289   public Type[] getGenericInterfaces() {
290     throw new UnsupportedOperationException();
291   }
292
293   public Object[] getSigners() {
294     throw new UnsupportedOperationException();
295   }
296
297   void setSigners(Object[] signers) {
298     signers = null;  // Get rid of IDE warning 
299     throw new UnsupportedOperationException();
300   }
301   
302   public Method getEnclosingMethod() {
303     throw new UnsupportedOperationException();
304   }
305
306   public Constructor<?> getEnclosingConstructor() {
307     throw new UnsupportedOperationException();
308   }
309
310   public Class<?> getDeclaringClass() {
311     throw new UnsupportedOperationException();
312   }
313
314   public native Class<?> getEnclosingClass();
315   
316   public String getCanonicalName() {
317     throw new UnsupportedOperationException();
318   }
319
320   public boolean isAnonymousClass() {
321     throw new UnsupportedOperationException();
322   }
323
324   public boolean isLocalClass() {
325     throw new UnsupportedOperationException();
326   }
327
328   public boolean isMemberClass() {
329     throw new UnsupportedOperationException();
330   }
331
332   public Class<?>[] getClasses() {
333     throw new UnsupportedOperationException();
334   }
335   
336   public Class<?>[] getDeclaredClasses() throws SecurityException {
337     throw new UnsupportedOperationException();
338   }
339   
340   public java.security.ProtectionDomain getProtectionDomain() {
341     throw new UnsupportedOperationException();
342   }
343
344   void setProtectionDomain0(java.security.ProtectionDomain pd) {
345     pd = null;  // Get rid of IDE warning 
346     throw new UnsupportedOperationException();
347   }
348
349   public boolean isEnum() {
350     throw new UnsupportedOperationException();
351   }
352   
353   @Override
354   public Annotation[] getDeclaredAnnotations() {
355     throw new UnsupportedOperationException();
356   }
357
358   public boolean isSynthetic (){
359     final int SYNTHETIC = 0x00001000;
360     return (getModifiers() & SYNTHETIC) != 0;
361   }
362 }