Fixes null captured parameters
[jpf-core.git] / src / main / gov / nasa / jpf / util / Reflection.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 gov.nasa.jpf.util;
19
20 import gov.nasa.jpf.JPFException;
21
22 import java.lang.reflect.InvocationTargetException;
23 import java.lang.reflect.Method;
24 import java.lang.reflect.Modifier;
25
26 /**
27  * reflection utilities
28  */
29 public class Reflection {
30
31   /**
32    * find callers class
33    *
34    * @param up levels upwards from our caller (NOT counting ourselves)
35    * @return caller class, null if illegal 'up' value
36    */
37   public static Class<?> getCallerClass(int up) {
38     int idx = up + 1; // don't count this stackframe
39
40     StackTraceElement[] st = (new Throwable()).getStackTrace();
41     if ((up < 0) || (idx >= st.length)) {
42       return null;
43     } else {
44       try {
45         return Class.forName(st[idx].getClassName());
46       } catch (Throwable t) {
47         return null;
48       }
49     }
50   }
51
52   public static Class<?> getCallerClass () {
53     return getCallerClass(2);
54   }
55
56   public static <T> Class<? extends T>  getCallerClass (Class<T> type){
57     Class<?> cls = getCallerClass(2);
58
59     if (cls != null) {
60       if (type.isAssignableFrom(cls)) {
61         return cls.asSubclass(type);
62       } else {
63         throw new JPFException("caller class: " + cls.getName() + " not of type: " + type.getName());
64       }
65     }
66     return null;
67   }
68
69   public static StackTraceElement getCallerElement (int up){
70     int idx = up + 1; // don't count this stackframe
71
72     StackTraceElement[] st = (new Throwable()).getStackTrace();
73     if ((up < 0) || (idx >= st.length)) {
74       return null;
75     } else {
76       return st[idx];
77     }
78   }
79   public static StackTraceElement getCallerElement () {
80     StackTraceElement[] st = (new Throwable()).getStackTrace();
81     if (st.length > 2){
82       return st[2]; // '0' is this method itself
83     } else {
84       return null;
85     }
86   }
87
88   public static boolean tryCallMain(Class<?> cls, String[] args) throws InvocationTargetException {
89     try {
90       Method method = cls.getDeclaredMethod("main", String[].class);
91       int modifiers = method.getModifiers();
92
93       if ((modifiers & (Modifier.PUBLIC | Modifier.STATIC | Modifier.ABSTRACT)) == (Modifier.PUBLIC | Modifier.STATIC)) {
94         method.invoke(null, (Object)args);
95         return true;
96       }
97
98     } catch (NoSuchMethodException nsmx) {
99       //System.out.println(nsmx);
100       // just return false
101     } catch (IllegalAccessException iax){
102       //System.out.println(iax);
103       // can't happen, we checked for it before invoking
104     } catch (IllegalArgumentException iargx){
105       //System.out.println(iargx);
106       // can't happen, we checked for it before invoking
107     }
108
109     return false;
110   }
111
112 }