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.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;
32 import java.util.HashMap;
35 import sun.reflect.ConstantPool;
36 import sun.reflect.annotation.AnnotationType;
39 * MJI model class for java.lang.Class library abstraction
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).
46 * Note that this class never gets seen by the real VM - it's for JPF's eyes only.
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
52 @SuppressWarnings("unused") // native peer uses
53 public final class Class<T> implements Serializable, GenericDeclaration, Type, AnnotatedElement {
55 /** don't use serialVersionUID from JDK 1.1 for interoperability */
56 private static final long serialVersionUID = 3206093459760846163L + 1;
58 // we init this on demand (from MJIEnv) since it's not used too often
59 private static Annotation[] emptyAnnotations; // = new Annotation[0];
63 private ClassLoader classLoader;
66 * search global id of the corresponding ClassInfo, which factors in the classloader
71 * to be set during <clinit> of the corresponding class
73 private boolean isPrimitive;
77 public native boolean isArray ();
80 public native Annotation[] getAnnotations();
83 public native <A extends Annotation> A getAnnotation( Class<A> annotationCls);
85 // those are from Java 6
86 public native boolean isAnnotation ();
88 public native boolean isAnnotationPresent(Class<? extends Annotation> annotationClass);
90 public native Class<?> getComponentType ();
92 public native Field[] getFields() throws SecurityException;
94 public native Field getDeclaredField (String fieldName) throws NoSuchFieldException,
97 public native Field[] getDeclaredFields () throws SecurityException;
99 public native Method getDeclaredMethod (String mthName, Class<?>... paramTypes)
100 throws NoSuchMethodException, SecurityException;
102 public native Method getMethod (String mthName, Class<?>... paramTypes)
103 throws NoSuchMethodException, SecurityException;
105 public native Method[] getDeclaredMethods () throws SecurityException;
107 public native Method[] getMethods () throws SecurityException;
109 public native Constructor<?>[] getDeclaredConstructors() throws SecurityException;
111 public native Constructor<?>[] getConstructors() throws SecurityException;
113 private native byte[] getByteArrayFromResourceStream(String name);
115 public InputStream getResourceAsStream (String name) {
116 byte[] byteArray = getByteArrayFromResourceStream(name);
117 if (byteArray == null) return null;
118 return new ByteArrayInputStream(byteArray);
121 private native String getResolvedName (String rname);
123 public URL getResource (String rname) {
124 String resolvedName = getResolvedName(rname);
125 return getClassLoader().getResource(resolvedName);
128 public Package getPackage() {
129 // very very crude version for now, only supports the package name
130 String pkgName = null;
132 int idx = name.lastIndexOf('.');
134 pkgName = name.substring(0,idx);
136 Package pkg = new Package(pkgName,
137 "spectitle", "specversion", "specvendor",
138 "impltitle", "implversion", "implvendor",
139 null, getClassLoader());
142 } else { // weird, but there is no Package object for the default package
148 //--- enum support ()
150 public native T[] getEnumConstants();
153 T[] getEnumConstantsShared() {
154 return getEnumConstants();
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;
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>();
166 T[] ae = getEnumConstants();
168 map.put(((Enum)e).name(), e);
171 enumConstantDirectory = map;
173 return enumConstantDirectory;
177 public native Constructor<T> getDeclaredConstructor (Class<?>... paramTypes)
178 throws NoSuchMethodException, SecurityException;
180 public native Field getField (String fieldName) throws NoSuchFieldException,
183 public native boolean isInstance (Object o);
185 public native boolean isAssignableFrom (Class<?> clazz);
187 public native boolean isInterface();
189 public native Constructor<T> getConstructor (Class<?>... argTypes) throws NoSuchMethodException, SecurityException;
191 public native int getModifiers();
193 public native Class<?>[] getInterfaces();
195 // no use to have a ctor, we can't call it
196 public String getName () {
200 public String getSimpleName () {
201 int idx; // <2do> not really - inner classes?
202 Class<?> enclosingClass = getEnclosingClass();
204 if(enclosingClass!=null){
205 idx = enclosingClass.getName().length();
207 idx = name.lastIndexOf('.');
210 return name.substring(idx+1);
213 static native Class<?> getPrimitiveClass (String clsName);
216 * this one is in JPF reflection land, it's 'native' for us
218 public static native Class<?> forName (String clsName) throws ClassNotFoundException;
220 public static Class<?> forName (String clsName, boolean initialize, ClassLoader loader) throws ClassNotFoundException {
223 cls = forName(clsName);
225 cls = loader.loadClass(clsName);
235 * forces clinit without explicit field or method access
237 private native void initialize0 ();
239 public boolean isPrimitive () {
243 public native Class<? super T> getSuperclass ();
245 public native T newInstance () throws InstantiationException,
246 IllegalAccessException;
249 public String toString () {
250 return (isInterface() ? "interface " : "class ") + name;
253 @SuppressWarnings("unchecked")
254 public T cast(Object o) {
255 if (o != null && !isInstance(o)) throw new ClassCastException();
259 @SuppressWarnings("unchecked")
260 public <U> Class<? extends U> asSubclass(Class<U> clazz) {
261 if (clazz.isAssignableFrom(this)) {
262 return (Class<? extends U>) this;
264 throw new ClassCastException("" + this + " is not a " + clazz);
268 native public boolean desiredAssertionStatus ();
270 public ClassLoader getClassLoader() {
274 native ConstantPool getConstantPool();
276 native void setAnnotationType (AnnotationType at);
278 native AnnotationType getAnnotationType();
281 public TypeVariable<Class<T>>[] getTypeParameters() {
282 throw new UnsupportedOperationException();
285 public Type getGenericSuperclass() {
286 throw new UnsupportedOperationException();
289 public Type[] getGenericInterfaces() {
290 throw new UnsupportedOperationException();
293 public Object[] getSigners() {
294 throw new UnsupportedOperationException();
297 void setSigners(Object[] signers) {
298 signers = null; // Get rid of IDE warning
299 throw new UnsupportedOperationException();
302 public Method getEnclosingMethod() {
303 throw new UnsupportedOperationException();
306 public Constructor<?> getEnclosingConstructor() {
307 throw new UnsupportedOperationException();
310 public Class<?> getDeclaringClass() {
311 throw new UnsupportedOperationException();
314 public native Class<?> getEnclosingClass();
316 public String getCanonicalName() {
317 throw new UnsupportedOperationException();
320 public boolean isAnonymousClass() {
321 throw new UnsupportedOperationException();
324 public boolean isLocalClass() {
325 throw new UnsupportedOperationException();
328 public boolean isMemberClass() {
329 throw new UnsupportedOperationException();
332 public Class<?>[] getClasses() {
333 throw new UnsupportedOperationException();
336 public Class<?>[] getDeclaredClasses() throws SecurityException {
337 throw new UnsupportedOperationException();
340 public java.security.ProtectionDomain getProtectionDomain() {
341 throw new UnsupportedOperationException();
344 void setProtectionDomain0(java.security.ProtectionDomain pd) {
345 pd = null; // Get rid of IDE warning
346 throw new UnsupportedOperationException();
349 public boolean isEnum() {
350 throw new UnsupportedOperationException();
354 public Annotation[] getDeclaredAnnotations() {
355 throw new UnsupportedOperationException();
358 public boolean isSynthetic (){
359 final int SYNTHETIC = 0x00001000;
360 return (getModifiers() & SYNTHETIC) != 0;