2 * Copyright (C) 2014, United States Government, as represented by the
3 * Administrator of the National Aeronautics and Space Administration.
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
10 * http://www.apache.org/licenses/LICENSE-2.0.
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.
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.*;
26 import java.util.HashMap;
29 import sun.reflect.ConstantPool;
30 import sun.reflect.annotation.AnnotationType;
32 import sun.reflect.generics.factory.CoreReflectionFactory;
33 import sun.reflect.generics.factory.GenericsFactory;
34 import sun.reflect.generics.repository.ClassRepository;
35 import sun.reflect.generics.scope.ClassScope;
38 * MJI model class for java.lang.Class library abstraction
40 * This is a JPF specific version of a system class because we can't use the real,
41 * platform VM specific version (it's native all over the place, its field
42 * structure isn't documented, most of its methods are private, hence we can't
43 * even instantiate it properly).
45 * Note that this class never gets seen by the real VM - it's for JPF's eyes only.
47 * For now, it's only a fragment to test the mechanism, and provide basic
48 * class.getName() / Class.ForName() support (which is (almost) enough for
49 * Java assertion support
51 @SuppressWarnings("unused") // native peer uses
52 public final class Class<T> implements Serializable, GenericDeclaration, Type, AnnotatedElement {
54 /** don't use serialVersionUID from JDK 1.1 for interoperability */
55 private static final long serialVersionUID = 3206093459760846163L + 1;
57 // we init this on demand (from MJIEnv) since it's not used too often
58 private static Annotation[] emptyAnnotations; // = new Annotation[0];
62 private ClassLoader classLoader;
65 * search global id of the corresponding ClassInfo, which factors in the classloader
70 * to be set during <clinit> of the corresponding class
72 private boolean isPrimitive;
76 public native boolean isArray ();
79 public native Annotation[] getAnnotations();
82 public native <A extends Annotation> A getAnnotation( Class<A> annotationCls);
84 // those are from Java 6
85 public native boolean isAnnotation ();
87 public native boolean isAnnotationPresent(Class<? extends Annotation> annotationClass);
89 public native Class<?> getComponentType ();
91 public native Field[] getFields() throws SecurityException;
93 public native Field getDeclaredField (String fieldName) throws NoSuchFieldException,
96 public native Field[] getDeclaredFields () throws SecurityException;
98 public native Method getDeclaredMethod (String mthName, Class<?>... paramTypes)
99 throws NoSuchMethodException, SecurityException;
101 public native Method getMethod (String mthName, Class<?>... paramTypes)
102 throws NoSuchMethodException, SecurityException;
104 public native Method[] getDeclaredMethods () throws SecurityException;
106 public native Method[] getMethods () throws SecurityException;
108 public native Constructor<?>[] getDeclaredConstructors() throws SecurityException;
110 public native Constructor<?>[] getConstructors() throws SecurityException;
112 private native byte[] getByteArrayFromResourceStream(String name);
114 public InputStream getResourceAsStream (String name) {
115 byte[] byteArray = getByteArrayFromResourceStream(name);
116 if (byteArray == null) return null;
117 return new ByteArrayInputStream(byteArray);
120 private native String getResolvedName (String rname);
122 public URL getResource (String rname) {
123 String resolvedName = getResolvedName(rname);
124 return getClassLoader().getResource(resolvedName);
127 public Package getPackage() {
128 // very very crude version for now, only supports the package name
129 String pkgName = null;
131 int idx = name.lastIndexOf('.');
133 pkgName = name.substring(0,idx);
135 Package pkg = new Package(pkgName,
136 "spectitle", "specversion", "specvendor",
137 "impltitle", "implversion", "implvendor",
138 null, getClassLoader());
141 } else { // weird, but there is no Package object for the default package
147 //--- enum support ()
149 public native T[] getEnumConstants();
152 T[] getEnumConstantsShared() {
153 return getEnumConstants();
156 // lazy initialized map for field name -> Enum constants
157 // <2do> we should move this to the native side, since Enum constants don't change
158 private transient Map<String, T> enumConstantDirectory = null;
160 // package private helper for Enum.valueOf()
161 Map<String,T> enumConstantDirectory() {
162 if (enumConstantDirectory == null) {
163 Map<String,T> map = new HashMap<String,T>();
165 T[] ae = getEnumConstants();
167 map.put(((Enum)e).name(), e);
170 enumConstantDirectory = map;
172 return enumConstantDirectory;
176 public native Constructor<T> getDeclaredConstructor (Class<?>... paramTypes)
177 throws NoSuchMethodException, SecurityException;
179 public native Field getField (String fieldName) throws NoSuchFieldException,
182 public native boolean isInstance (Object o);
184 public native boolean isAssignableFrom (Class<?> clazz);
186 public native boolean isInterface();
188 public native Constructor<T> getConstructor (Class<?>... argTypes) throws NoSuchMethodException, SecurityException;
190 public native int getModifiers();
192 public native Class<?>[] getInterfaces();
194 // no use to have a ctor, we can't call it
195 public String getName () {
199 public String getSimpleName () {
200 int idx; // <2do> not really - inner classes?
201 Class<?> enclosingClass = getEnclosingClass();
203 if(enclosingClass!=null){
204 idx = enclosingClass.getName().length();
206 idx = name.lastIndexOf('.');
209 return name.substring(idx+1);
212 static native Class<?> getPrimitiveClass (String clsName);
215 * this one is in JPF reflection land, it's 'native' for us
217 public static native Class<?> forName (String clsName) throws ClassNotFoundException;
219 public static Class<?> forName (String clsName, boolean initialize, ClassLoader loader) throws ClassNotFoundException {
222 cls = forName(clsName);
224 cls = loader.loadClass(clsName);
234 * forces clinit without explicit field or method access
236 private native void initialize0 ();
238 public boolean isPrimitive () {
242 public native Class<? super T> getSuperclass ();
244 public native T newInstance () throws InstantiationException,
245 IllegalAccessException;
248 public String toString () {
249 return (isInterface() ? "interface " : "class ") + name;
252 @SuppressWarnings("unchecked")
253 public T cast(Object o) {
254 if (o != null && !isInstance(o)) throw new ClassCastException();
258 @SuppressWarnings("unchecked")
259 public <U> Class<? extends U> asSubclass(Class<U> clazz) {
260 if (clazz.isAssignableFrom(this)) {
261 return (Class<? extends U>) this;
263 throw new ClassCastException("" + this + " is not a " + clazz);
267 native public boolean desiredAssertionStatus ();
269 public ClassLoader getClassLoader() {
273 native ConstantPool getConstantPool();
275 native void setAnnotationType (AnnotationType at);
277 native AnnotationType getAnnotationType();
279 // TODO: DIRTY HACKS!
280 //public native TypeVariable<Class<T>>[] getTypeParameters();
283 public TypeVariable<Class<T>>[] getTypeParameters() {
284 throw new UnsupportedOperationException();
287 // Generic info repository; lazily initialized
288 private volatile transient ClassRepository genericInfo;
290 // Generic signature handling
291 //private native String getGenericSignature0();
293 // accessor for factory
294 private GenericsFactory getFactory() {
295 // create scope and factory
296 return CoreReflectionFactory.make(this, ClassScope.make(this));
299 // accessor for generic info repository;
300 // generic info is lazily initialized
301 private ClassRepository getGenericInfo() {
302 ClassRepository genericInfo = this.genericInfo;
303 if (genericInfo == null) {
304 //String signature = getGenericSignature0();
305 //String signature = "Ljava/lang/Object;";
306 String signature = null;
307 if (signature == null) {
308 genericInfo = ClassRepository.NONE;
310 genericInfo = ClassRepository.make(signature, getFactory());
312 this.genericInfo = genericInfo;
314 return (genericInfo != ClassRepository.NONE) ? genericInfo : null;
318 public TypeVariable<Class<T>>[] getTypeParameters() {
319 //throw new UnsupportedOperationException();
320 ClassRepository info = getGenericInfo();
322 return (TypeVariable<Class<T>>[])info.getTypeParameters();
324 return (TypeVariable<Class<T>>[])new TypeVariable<?>[0];
327 public TypeVariable<Class<T>>[] getTypeParameters() {
328 //throw new UnsupportedOperationException();
329 System.out.println("Calling getTypeParameters for: " + this.name);
330 TypeVariable[] typeVariables = (TypeVariable<Class<T>>[])new TypeVariable<?>[1];
331 //Object obj = new Object();
332 //typeVariables[0] = (TypeVariable<Class<T>>) obj;
333 return typeVariables;
335 // TODO: DIRTY HACKS!
337 public Type getGenericSuperclass() {
338 throw new UnsupportedOperationException();
341 public Type[] getGenericInterfaces() {
342 throw new UnsupportedOperationException();
345 public Object[] getSigners() {
346 throw new UnsupportedOperationException();
349 void setSigners(Object[] signers) {
350 signers = null; // Get rid of IDE warning
351 throw new UnsupportedOperationException();
354 public Method getEnclosingMethod() {
355 throw new UnsupportedOperationException();
358 public Constructor<?> getEnclosingConstructor() {
359 throw new UnsupportedOperationException();
362 public Class<?> getDeclaringClass() {
363 throw new UnsupportedOperationException();
366 public native Class<?> getEnclosingClass();
368 public String getCanonicalName() {
369 throw new UnsupportedOperationException();
372 public boolean isAnonymousClass() {
373 throw new UnsupportedOperationException();
376 public boolean isLocalClass() {
377 throw new UnsupportedOperationException();
380 public boolean isMemberClass() {
381 throw new UnsupportedOperationException();
384 public Class<?>[] getClasses() {
385 throw new UnsupportedOperationException();
388 public Class<?>[] getDeclaredClasses() throws SecurityException {
389 throw new UnsupportedOperationException();
392 public java.security.ProtectionDomain getProtectionDomain() {
393 throw new UnsupportedOperationException();
396 void setProtectionDomain0(java.security.ProtectionDomain pd) {
397 pd = null; // Get rid of IDE warning
398 throw new UnsupportedOperationException();
401 public boolean isEnum() {
402 throw new UnsupportedOperationException();
406 public Annotation[] getDeclaredAnnotations() {
407 throw new UnsupportedOperationException();
410 public boolean isSynthetic (){
411 final int SYNTHETIC = 0x00001000;
412 return (getModifiers() & SYNTHETIC) != 0;