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;
33 * MJI model class for java.lang.Class library abstraction
35 * This is a JPF specific version of a system class because we can't use the real,
36 * platform VM specific version (it's native all over the place, its field
37 * structure isn't documented, most of its methods are private, hence we can't
38 * even instantiate it properly).
40 * Note that this class never gets seen by the real VM - it's for JPF's eyes only.
42 * For now, it's only a fragment to test the mechanism, and provide basic
43 * class.getName() / Class.ForName() support (which is (almost) enough for
44 * Java assertion support
46 @SuppressWarnings("unused") // native peer uses
47 public final class Class<T> implements Serializable, GenericDeclaration, Type, AnnotatedElement {
49 /** don't use serialVersionUID from JDK 1.1 for interoperability */
50 private static final long serialVersionUID = 3206093459760846163L + 1;
52 // we init this on demand (from MJIEnv) since it's not used too often
53 private static Annotation[] emptyAnnotations; // = new Annotation[0];
57 private ClassLoader classLoader;
60 * search global id of the corresponding ClassInfo, which factors in the classloader
65 * to be set during <clinit> of the corresponding class
67 private boolean isPrimitive;
71 public native boolean isArray ();
74 public native Annotation[] getAnnotations();
77 public native <A extends Annotation> A getAnnotation( Class<A> annotationCls);
79 // those are from Java 6
80 public native boolean isAnnotation ();
82 public native boolean isAnnotationPresent(Class<? extends Annotation> annotationClass);
84 public native Class<?> getComponentType ();
86 public native Field[] getFields() throws SecurityException;
88 public native Field getDeclaredField (String fieldName) throws NoSuchFieldException,
91 public native Field[] getDeclaredFields () throws SecurityException;
93 public native Method getDeclaredMethod (String mthName, Class<?>... paramTypes)
94 throws NoSuchMethodException, SecurityException;
96 public native Method getMethod (String mthName, Class<?>... paramTypes)
97 throws NoSuchMethodException, SecurityException;
99 public native Method[] getDeclaredMethods () throws SecurityException;
101 public native Method[] getMethods () throws SecurityException;
103 public native Constructor<?>[] getDeclaredConstructors() throws SecurityException;
105 public native Constructor<?>[] getConstructors() throws SecurityException;
107 private native byte[] getByteArrayFromResourceStream(String name);
109 public InputStream getResourceAsStream (String name) {
110 byte[] byteArray = getByteArrayFromResourceStream(name);
111 if (byteArray == null) return null;
112 return new ByteArrayInputStream(byteArray);
115 private native String getResolvedName (String rname);
117 public URL getResource (String rname) {
118 String resolvedName = getResolvedName(rname);
119 return getClassLoader().getResource(resolvedName);
122 public Package getPackage() {
123 // very very crude version for now, only supports the package name
124 String pkgName = null;
126 int idx = name.lastIndexOf('.');
128 pkgName = name.substring(0,idx);
130 Package pkg = new Package(pkgName,
131 "spectitle", "specversion", "specvendor",
132 "impltitle", "implversion", "implvendor",
133 null, getClassLoader());
136 } else { // weird, but there is no Package object for the default package
142 //--- enum support ()
144 public native T[] getEnumConstants();
147 T[] getEnumConstantsShared() {
148 return getEnumConstants();
151 // lazy initialized map for field name -> Enum constants
152 // <2do> we should move this to the native side, since Enum constants don't change
153 private transient Map<String, T> enumConstantDirectory = null;
155 // package private helper for Enum.valueOf()
156 Map<String,T> enumConstantDirectory() {
157 if (enumConstantDirectory == null) {
158 Map<String,T> map = new HashMap<String,T>();
160 T[] ae = getEnumConstants();
162 map.put(((Enum)e).name(), e);
165 enumConstantDirectory = map;
167 return enumConstantDirectory;
171 public native Constructor<T> getDeclaredConstructor (Class<?>... paramTypes)
172 throws NoSuchMethodException, SecurityException;
174 public native Field getField (String fieldName) throws NoSuchFieldException,
177 public native boolean isInstance (Object o);
179 public native boolean isAssignableFrom (Class<?> clazz);
181 public native boolean isInterface();
183 public native Constructor<T> getConstructor (Class<?>... argTypes) throws NoSuchMethodException, SecurityException;
185 public native int getModifiers();
187 public native Class<?>[] getInterfaces();
189 // no use to have a ctor, we can't call it
190 public String getName () {
194 public String getSimpleName () {
195 int idx; // <2do> not really - inner classes?
196 Class<?> enclosingClass = getEnclosingClass();
198 if(enclosingClass!=null){
199 idx = enclosingClass.getName().length();
201 idx = name.lastIndexOf('.');
204 return name.substring(idx+1);
207 static native Class<?> getPrimitiveClass (String clsName);
210 * this one is in JPF reflection land, it's 'native' for us
212 public static native Class<?> forName (String clsName) throws ClassNotFoundException;
214 public static Class<?> forName (String clsName, boolean initialize, ClassLoader loader) throws ClassNotFoundException {
217 cls = forName(clsName);
219 cls = loader.loadClass(clsName);
229 * forces clinit without explicit field or method access
231 private native void initialize0 ();
233 public boolean isPrimitive () {
237 public native Class<? super T> getSuperclass ();
239 public native T newInstance () throws InstantiationException,
240 IllegalAccessException;
243 public String toString () {
244 return (isInterface() ? "interface " : "class ") + name;
247 @SuppressWarnings("unchecked")
248 public T cast(Object o) {
249 if (o != null && !isInstance(o)) throw new ClassCastException();
253 @SuppressWarnings("unchecked")
254 public <U> Class<? extends U> asSubclass(Class<U> clazz) {
255 if (clazz.isAssignableFrom(this)) {
256 return (Class<? extends U>) this;
258 throw new ClassCastException("" + this + " is not a " + clazz);
262 native public boolean desiredAssertionStatus ();
264 public ClassLoader getClassLoader() {
268 native ConstantPool getConstantPool();
270 native void setAnnotationType (AnnotationType at);
272 native AnnotationType getAnnotationType();
274 // TODO: Fix for Groovy's model-checking
275 public native TypeVariable<Class<T>>[] getTypeParameters();
277 public native Type getGenericSuperclass();
278 /*public Type getGenericSuperclass() {
279 throw new UnsupportedOperationException();
282 public native Type[] getGenericInterfaces();
283 /*public Type[] getGenericInterfaces() {
284 throw new UnsupportedOperationException();
287 public Object[] getSigners() {
288 throw new UnsupportedOperationException();
291 void setSigners(Object[] signers) {
292 signers = null; // Get rid of IDE warning
293 throw new UnsupportedOperationException();
296 public Method getEnclosingMethod() {
297 throw new UnsupportedOperationException();
300 public Constructor<?> getEnclosingConstructor() {
301 throw new UnsupportedOperationException();
304 public Class<?> getDeclaringClass() {
305 throw new UnsupportedOperationException();
308 public native Class<?> getEnclosingClass();
310 public String getCanonicalName() {
311 throw new UnsupportedOperationException();
314 public boolean isAnonymousClass() {
315 throw new UnsupportedOperationException();
318 public boolean isLocalClass() {
319 throw new UnsupportedOperationException();
322 public boolean isMemberClass() {
323 throw new UnsupportedOperationException();
326 public Class<?>[] getClasses() {
327 throw new UnsupportedOperationException();
330 public Class<?>[] getDeclaredClasses() throws SecurityException {
331 throw new UnsupportedOperationException();
334 public java.security.ProtectionDomain getProtectionDomain() {
335 throw new UnsupportedOperationException();
338 void setProtectionDomain0(java.security.ProtectionDomain pd) {
339 pd = null; // Get rid of IDE warning
340 throw new UnsupportedOperationException();
343 public boolean isEnum() {
344 throw new UnsupportedOperationException();
348 public Annotation[] getDeclaredAnnotations() {
349 throw new UnsupportedOperationException();
352 public boolean isSynthetic (){
353 final int SYNTHETIC = 0x00001000;
354 return (getModifiers() & SYNTHETIC) != 0;