This project has retired. For details please refer to its Attic page.
ReflectionUtils xref
View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * 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  
19  package org.apache.giraph.utils;
20  
21  import java.lang.reflect.Modifier;
22  
23  import org.apache.giraph.conf.ContextSettable;
24  import org.apache.giraph.conf.ImmutableClassesGiraphConfiguration;
25  import org.apache.hadoop.mapreduce.Mapper;
26  import org.jodah.typetools.TypeResolver;
27  
28  /**
29   * Helper methods to get type arguments to generic classes.  Courtesy of
30   * Ian Robertson (overstock.com).  Make sure to use with abstract
31   * generic classes, not interfaces.
32   */
33  public class ReflectionUtils {
34    /**
35     * Do not instantiate.
36     */
37    private ReflectionUtils() { }
38  
39    /**
40     * Get package path to the object given. Used with resources.
41     *
42     * @param object the Object to check
43     * @return Path to package of object
44     */
45    public static String getPackagePath(Object object) {
46      return getPackagePath(object.getClass());
47    }
48  
49    /**
50     * Get package path to the class given. Used with resources.
51     *
52     * @param klass Class to check
53     * @return Path to package of class
54     */
55    public static String getPackagePath(Class klass) {
56      return klass.getPackage().getName().replaceAll("\\.", "/");
57    }
58  
59    /**
60     * Get the actual type arguments a child class has used to extend a
61     * generic base class.
62     *
63     * @param <T> Type to evaluate.
64     * @param baseClass the base class
65     * @param childClass the child class
66     * @return a list of the raw classes for the actual type arguments.
67     */
68    public static <T> Class<?>[] getTypeArguments(
69        Class<T> baseClass, Class<? extends T> childClass) {
70      return TypeResolver.resolveArguments(childClass, baseClass);
71    }
72  
73    /**
74     * Instantiate a class, wrap exceptions
75     *
76     * @param theClass Class to instantiate
77     * @param <T> Type to instantiate
78     * @return Newly instantiated object
79     */
80    @SuppressWarnings("unchecked")
81    public static <T> T newInstance(Class<T> theClass) {
82      try {
83        return theClass.newInstance();
84      } catch (InstantiationException e) {
85        throw new IllegalStateException(
86            "newInstance: Couldn't instantiate " + theClass.getName(), e);
87      } catch (IllegalAccessException e) {
88        throw new IllegalStateException(
89            "newInstance: Illegal access " + theClass.getName(), e);
90      }
91    }
92  
93    /**
94     * Instantiate classes that are ImmutableClassesGiraphConfigurable
95     *
96     * @param theClass Class to instantiate
97     * @param configuration Giraph configuration, may be null
98     * @param <T> Type to instantiate
99     * @return Newly instantiated object with configuration set if possible
100    */
101   @SuppressWarnings("unchecked")
102   public static <T> T newInstance(
103       Class<T> theClass,
104       ImmutableClassesGiraphConfiguration configuration) {
105     T result;
106     try {
107       result = theClass.newInstance();
108     } catch (InstantiationException e) {
109       throw new IllegalStateException(
110           "newInstance: Couldn't instantiate " + theClass.getName(), e);
111     } catch (IllegalAccessException e) {
112       throw new IllegalStateException(
113           "newInstance: Illegal access " + theClass.getName(), e);
114     }
115     ConfigurationUtils.configureIfPossible(result, configuration);
116     return result;
117   }
118 
119   /**
120    * Instantiate classes that are ImmutableClassesGiraphConfigurable,
121    * and optionally set context on them if they are ContextSettable
122    *
123    * @param theClass Class to instantiate
124    * @param configuration Giraph configuration, may be null
125    * @param context Mapper context
126    * @param <T> Type to instantiate
127    * @return Newly instantiated object with configuration and context set if
128    * possible
129    */
130   public static <T> T newInstance(
131       Class<T> theClass,
132       ImmutableClassesGiraphConfiguration configuration,
133       Mapper<?, ?, ?, ?>.Context context) {
134     T result = newInstance(theClass, configuration);
135     if (result instanceof ContextSettable) {
136       ((ContextSettable) result).setContext(context);
137     }
138     return result;
139   }
140 
141   /**
142    * Verify that found type matches the expected type. If types don't match an
143    * {@link IllegalStateException} will be thrown.
144    *
145    * @param concreteChild Concrete child type
146    * @param parent Parent type
147    * @param typeDesc String description of the type (for exception description)
148    * @param mainClass Class in which the actual type was found (for exception
149    *                  description)
150    */
151   public static void verifyTypes(Class<?> concreteChild, Class<?> parent,
152       String typeDesc, Class<?> mainClass) {
153     // unknown means object
154     if (parent == TypeResolver.Unknown.class) {
155       parent = Object.class;
156     }
157 
158     verifyConcrete(concreteChild, typeDesc);
159 
160     if (!parent.isAssignableFrom(concreteChild)) {
161       throw new IllegalStateException("verifyTypes: " + typeDesc + " types " +
162           "don't match, in " + mainClass.getName() + " " + concreteChild +
163           " expected, but " + parent + " found");
164     }
165   }
166 
167   /**
168    * Verify that given type is a concrete type that can be instantiated.
169    *
170    * @param concrete type to check
171    * @param typeDesc String description of the type (for exception description)
172    */
173   public static void verifyConcrete(
174       Class<?> concrete, String typeDesc) {
175     if (concrete.isInterface()) {
176       throw new IllegalStateException("verifyTypes: " +
177           "Type " + typeDesc + " must be concrete class " + concrete);
178     }
179     if (Modifier.isAbstract(concrete.getModifiers())) {
180       throw new IllegalStateException("verifyTypes: " +
181           "Type " + typeDesc + "can't be abstract class" + concrete);
182     }
183   }
184 }