Home | History | Annotate | Download | only in src-ex
      1 /*
      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 
     17 import java.lang.reflect.Constructor;
     18 import java.lang.reflect.Field;
     19 import java.lang.reflect.Method;
     20 import java.lang.reflect.Modifier;
     21 import java.util.Arrays;
     22 
     23 public 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 }
    206