blob: 3667e91611b275c1baacf50bc045719f04178cb1 [file] [log] [blame]
David Brazdil11b67b22018-01-18 16:41:40 +00001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17import java.lang.reflect.Constructor;
18import java.lang.reflect.Field;
19import java.lang.reflect.Method;
20import java.lang.reflect.Modifier;
21import java.util.Arrays;
22
23public class Reflection {
24 public static boolean canDiscoverWithGetDeclaredField(Class<?> klass, String name) {
25 try {
26 klass.getDeclaredField(name);
27 return true;
28 } catch (NoSuchFieldException ex) {
29 return false;
30 }
31 }
32
33 public static boolean canDiscoverWithGetDeclaredFields(Class<?> klass, String name) {
34 for (Field f : klass.getDeclaredFields()) {
35 if (f.getName().equals(name)) {
36 return true;
37 }
38 }
39 return false;
40 }
41
42 public static boolean canDiscoverWithGetField(Class<?> klass, String name) {
43 try {
44 klass.getField(name);
45 return true;
46 } catch (NoSuchFieldException ex) {
47 return false;
48 }
49 }
50
51 public static boolean canDiscoverWithGetFields(Class<?> klass, String name) {
52 for (Field f : klass.getFields()) {
53 if (f.getName().equals(name)) {
54 return true;
55 }
56 }
57 return false;
58 }
59
60 public static boolean canGetField(Class<?> klass, String name) {
61 try {
62 Field f = klass.getDeclaredField(name);
63 f.setAccessible(true);
64 f.getInt(Modifier.isStatic(f.getModifiers()) ? null : klass.newInstance());
65 return true;
66 } catch (Exception ex) {
67 ex.printStackTrace();
68 return false;
69 }
70 }
71
72 public static boolean canSetField(Class<?> klass, String name) {
73 try {
74 Field f = klass.getDeclaredField(name);
75 f.setAccessible(true);
76 f.setInt(Modifier.isStatic(f.getModifiers()) ? null : klass.newInstance(), 42);
77 return true;
78 } catch (Exception ex) {
79 ex.printStackTrace();
80 return false;
81 }
82 }
83
84 public static boolean canDiscoverWithGetDeclaredMethod(Class<?> klass, String name) {
85 try {
86 klass.getDeclaredMethod(name);
87 return true;
88 } catch (NoSuchMethodException ex) {
89 return false;
90 }
91 }
92
93 public static boolean canDiscoverWithGetDeclaredMethods(Class<?> klass, String name) {
94 for (Method m : klass.getDeclaredMethods()) {
95 if (m.getName().equals(name)) {
96 return true;
97 }
98 }
99 return false;
100 }
101
102 public static boolean canDiscoverWithGetMethod(Class<?> klass, String name) {
103 try {
104 klass.getMethod(name);
105 return true;
106 } catch (NoSuchMethodException ex) {
107 return false;
108 }
109 }
110
111 public static boolean canDiscoverWithGetMethods(Class<?> klass, String name) {
112 for (Method m : klass.getMethods()) {
113 if (m.getName().equals(name)) {
114 return true;
115 }
116 }
117 return false;
118 }
119
120 public static boolean canInvokeMethod(Class<?> klass, String name) {
121 try {
122 Method m = klass.getDeclaredMethod(name);
123 m.setAccessible(true);
124 m.invoke(klass.isInterface() ? null : klass.newInstance());
125 return true;
126 } catch (Exception ex) {
127 ex.printStackTrace();
128 return false;
129 }
130 }
131
132 public static boolean canDiscoverWithGetDeclaredConstructor(Class<?> klass, Class<?> args[]) {
133 try {
134 klass.getDeclaredConstructor(args);
135 return true;
136 } catch (NoSuchMethodException ex) {
137 return false;
138 }
139 }
140
141 public static boolean canDiscoverWithGetDeclaredConstructors(Class<?> klass, Class<?> args[]) {
142 for (Constructor c : klass.getDeclaredConstructors()) {
143 if (Arrays.equals(c.getParameterTypes(), args)) {
144 return true;
145 }
146 }
147 return false;
148 }
149
150 public static boolean canDiscoverWithGetConstructor(Class<?> klass, Class<?> args[]) {
151 try {
152 klass.getConstructor(args);
153 return true;
154 } catch (NoSuchMethodException ex) {
155 return false;
156 }
157 }
158
159 public static boolean canDiscoverWithGetConstructors(Class<?> klass, Class<?> args[]) {
160 for (Constructor c : klass.getConstructors()) {
161 if (Arrays.equals(c.getParameterTypes(), args)) {
162 return true;
163 }
164 }
165 return false;
166 }
167
168 public static boolean canInvokeConstructor(Class<?> klass, Class<?> args[], Object[] initargs) {
169 try {
170 Constructor c = klass.getDeclaredConstructor(args);
171 c.setAccessible(true);
172 c.newInstance(initargs);
173 return true;
174 } catch (Exception ex) {
175 ex.printStackTrace();
176 return false;
177 }
178 }
179
180 public static boolean canUseNewInstance(Class<?> klass) throws IllegalAccessException {
181 try {
182 klass.newInstance();
183 return true;
184 } catch (InstantiationException ex) {
185 return false;
186 }
187 }
188
189 private static native int getHiddenApiAccessFlags();
190
191 public static boolean canObserveFieldHiddenAccessFlags(Class<?> klass, String name)
192 throws Exception {
193 return (klass.getDeclaredField(name).getModifiers() & getHiddenApiAccessFlags()) != 0;
194 }
195
196 public static boolean canObserveMethodHiddenAccessFlags(Class<?> klass, String name)
197 throws Exception {
198 return (klass.getDeclaredMethod(name).getModifiers() & getHiddenApiAccessFlags()) != 0;
199 }
200
201 public static boolean canObserveConstructorHiddenAccessFlags(Class<?> klass, Class<?> args[])
202 throws Exception {
203 return (klass.getConstructor(args).getModifiers() & getHiddenApiAccessFlags()) != 0;
204 }
205}