Java tutorial
/*****************************************************import org.omnaest.utils.beans.replicator.BeanReplicator.DTOPackage; nsed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package org.omnaest.utils.reflection; import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.omnaest.utils.structure.collection.list.ListUtils; import org.omnaest.utils.structure.collection.set.SetUtils; import org.omnaest.utils.structure.element.converter.ElementConverter; import org.omnaest.utils.structure.element.converter.ElementConverterObjectToClassOfObject; import org.omnaest.utils.structure.element.factory.concrete.LinkedHashSetFactory; import org.omnaest.utils.structure.map.MapUtils; /** * Helper for Java Reflection. * * @author Omnaest */ public class ReflectionUtils { /* ********************************************** Classes/Interfaces ********************************************** */ /** * Represents the meta information about a single {@link Method} parameter * * @author Omnaest */ public static class MethodParameterMetaInformation { /* ********************************************** Variables ********************************************** */ private Class<?> type = null; private List<Annotation> declaredAnnotationList = null; /* ********************************************** Methods ********************************************** */ public MethodParameterMetaInformation(Class<?> type, List<Annotation> declaredAnnotationList) { super(); this.type = type; this.declaredAnnotationList = declaredAnnotationList; } public Class<?> getType() { return this.type; } public List<Annotation> getDeclaredAnnotationList() { return this.declaredAnnotationList; } } /* ********************************************** Methods ********************************************** */ /** * Determines the index position of a declared {@link Method} within a given {@link Class}. * * @param clazz * @param method * @return */ public static int declaredMethodIndexPosition(Class<?> clazz, Method method) { // int retval = -1; // if (clazz != null && method != null) { // Method[] declaredMethods = clazz.getDeclaredMethods(); if (declaredMethods != null) { retval = ArrayUtils.indexOf(declaredMethods, method); } } // return retval; } /** * Determines the index position of a declared {@link Field} within a given {@link Class}. * * @param clazz * @param field * @return */ public static int declaredFieldIndexPosition(Class<?> clazz, Field field) { // int retval = -1; // if (clazz != null && field != null) { // Field[] declaredFields = clazz.getDeclaredFields(); if (declaredFields != null) { retval = ArrayUtils.indexOf(declaredFields, field); } } // return retval; } /** * Determines the index position of a declared {@link Field} within a given {@link Class}. * * @param clazz * @param fieldname * @return -1 if the {@link Field} could not be determined at all. */ public static int declaredFieldIndexPosition(Class<?> clazz, String fieldname) { // int retval = -1; // if (clazz != null && fieldname != null) { // try { // Field field = clazz.getField(fieldname); // if (field != null) { // Field[] declaredFields = clazz.getDeclaredFields(); if (declaredFields != null) { retval = ArrayUtils.indexOf(declaredFields, field); } } } catch (Exception e) { } } // return retval; } /** * Returns the number of declared {@link Field}s of a {@link Class}. * * @param clazz * @return number of declared {@link Field}s or 0 if clazz == null */ public static int numberOfDeclaredFields(Class<?> clazz) { return clazz != null ? clazz.getDeclaredFields().length : 0; } /** * Returns the number of declared {@link Method}s of a {@link Class}. * * @param clazz * @return number of declared {@link Method}s or 0 if clazz == null */ public static int numberOfDeclaredMethods(Class<?> clazz) { return clazz != null ? clazz.getDeclaredMethods().length : 0; } /** * Returns true if the given {@link Class} type has a {@link Constructor} for the given arguments * * @param type * @param arguments * @return */ public static <B> boolean hasConstructorFor(Class<? extends B> type, Object... arguments) { return constructorFor(type, arguments) != null; } /** * Returns true if the given {@link Class} type has a {@link Constructor} for the given parameter types * * @param type * @param parameterTypes * @return */ public static <B> boolean hasConstructorFor(Class<? extends B> type, Class<?>... parameterTypes) { return constructorFor(type, parameterTypes) != null; } /** * Returns true if the given {@link Class} type has a default {@link Constructor} * * @param type * @return */ public static <B> boolean hasDefaultConstructorFor(Class<? extends B> type) { return hasConstructorFor(type); } /** * Returns the {@link Constructor} for the given {@link Class} type and arguments * * @param type * @param arguments * @return */ public static <B> Constructor<B> constructorFor(Class<? extends B> type, Object... arguments) { // final Class<?>[] parameterTypes = determineParameterTypesFromArguments(arguments); return constructorFor(type, parameterTypes); } /** * @param arguments * @return */ private static Class<?>[] determineParameterTypesFromArguments(Object... arguments) { return ListUtils.convert(Arrays.asList(arguments), new ElementConverterObjectToClassOfObject()) .toArray(new Class<?>[arguments.length]); } /** * Returns the {@link Constructor} for the given {@link Class} type and parameter types * * @param type * @param parameterTypes * @return */ @SuppressWarnings("unchecked") public static <B> Constructor<B> constructorFor(Class<? extends B> type, Class<?>... parameterTypes) { // Constructor<B> constructor = null; // try { // constructor = (Constructor<B>) type.getDeclaredConstructor(parameterTypes); } catch (Exception e) { try { constructor = (Constructor<B>) type.getConstructor(parameterTypes); } catch (Exception e2) { try { constructor = (Constructor<B>) resolveConstructorFor(type, parameterTypes); } catch (Exception e3) { } } } // return constructor; } /** * Resolves a matching constructor for the given type and the given parameter types * * @param type * @param parameterTypes * @return */ public static <C> Constructor<C> resolveConstructorFor(Class<C> type, Class<?>... parameterTypes) { // Constructor<C> retval = null; // if (type != null) { // @SuppressWarnings("unchecked") Constructor<C>[] constructors = (Constructor<C>[]) type.getConstructors(); if (constructors != null) { for (Constructor<C> constructor : constructors) { Class<?>[] parameterTypesOfContstructor = constructor.getParameterTypes(); boolean areConstructorTypesAssignableFromParameterTypes = areAssignableFrom( parameterTypesOfContstructor, parameterTypes); if (areConstructorTypesAssignableFromParameterTypes) { retval = constructor; break; } } } } // return retval; } /** * Returns true if all types of the assignable types are {@link Class#isAssignableFrom(Class)} to their source type counterpart. * Both arrays have to have the same size. Every element of one of the arrays will map to its counterpart with the same index * position. * * @param assignableTypes * @param sourceTypes * @return */ public static boolean areAssignableFrom(Class<?>[] assignableTypes, Class<?>[] sourceTypes) { // boolean retval = assignableTypes != null && sourceTypes != null && assignableTypes.length == sourceTypes.length; if (retval) { for (int ii = 0; ii < assignableTypes.length; ii++) { // Class<?> assignableType = assignableTypes[ii]; Class<?> sourceType = sourceTypes[ii]; // retval &= assignableType.isAssignableFrom(sourceType); if (!retval) { break; } } } // return retval; } /** * Creates a new instance of a given {@link Class} using a constructor which has the same parameter signature as the provided * arguments. <br> * <br> * Primitive arguments will be matched to their java wrapper types.<br> * <br> * This method never throws an {@link Exception} instead null is returned. * * @see #newInstanceByValueOf(Class, Object...) * @param type * {@link Class} * @param arguments */ public static <B> B newInstanceOf(Class<? extends B> type, Object... arguments) { // B retval = null; // if (type != null) { // try { // Constructor<? extends B> constructor = constructorFor(type, arguments); constructor.setAccessible(true); // retval = constructor.newInstance(arguments); } catch (Exception e) { } } // return retval; } /** * Creates a new instance of a given {@link Class} using a possibly present valueOf method which has the same parameter * signature as the provided arguments. <br> * <br> * Any primitive arguments will match their java wrapper type signature as well. <br> * <br> * This method does not throw any {@link Exception} instead it will return null, if the invocation fails for any reason. * * @see #newInstanceOf * @param type * {@link Class} * @param arguments */ @SuppressWarnings("unchecked") public static <B> B newInstanceByValueOf(Class<? extends B> type, Object... arguments) { // B retval = null; // if (type != null) { // final Class<?>[] parameterTypes = determineParameterTypesFromArguments(arguments); try { // final String name = "valueOf"; Method valueOfMethod = type.getDeclaredMethod(name, parameterTypes); valueOfMethod.setAccessible(true); // retval = (B) valueOfMethod.invoke(null, arguments); } catch (Exception e) { } } // return retval; } /** * Returns a {@link Map} with the declared {@link Method}s of the given type and the return type of the {@link Method}s * * @param type * @return */ public static Map<Method, Class<?>> declaredMethodToReturnTypeMap(Class<?> type) { List<Method> methodList = declaredMethodList(type); return methodToReturnTypeMap(methodList); } /** * Returns a {@link Map} with {@link Method}s of the given type and the return type of the {@link Method}s * * @param type * @return */ public static Map<Method, Class<?>> methodToReturnTypeMap(Class<?> type) { List<Method> methodList = methodList(type); return methodToReturnTypeMap(methodList); } /** * Returns a {@link Map} with all the given {@link Method}s and their return type * * @param methodList * @return */ protected static Map<Method, Class<?>> methodToReturnTypeMap(List<Method> methodList) { // Map<Method, Class<?>> retmap = new LinkedHashMap<Method, Class<?>>(); // if (methodList != null) { // for (Method method : methodList) { Class<?> returnType = method.getReturnType(); retmap.put(method, returnType); } } // return retmap; } /** * Returns a {@link Map} with all {@link Method}s of a given {@link Class} and the annotation instance for the given method. * Methods which will have no matching {@link Annotation}s will be excluded and will not show as keys. * * @param type * @param annotationType * @return */ public static <A extends Annotation> Map<Method, A> methodToAnnotationMap(final Class<?> type, final Class<A> annotationType) { // Map<Method, A> retmap = null; Map<Method, Set<Annotation>> methodToAnnotationSetMap = methodToAnnotationSetMap(type); ElementConverter<Set<Annotation>, A> valueElementConverter = new ElementConverter<Set<Annotation>, A>() { @SuppressWarnings("unchecked") @Override public A convert(Set<Annotation> annotationSet) { // A retval = null; // if (annotationSet != null) { for (Annotation annotation : annotationSet) { if (annotation != null && annotationType.isAssignableFrom(annotation.getClass())) { retval = (A) annotation; break; } } } // return retval; } }; retmap = MapUtils.convertMapValue(methodToAnnotationSetMap, valueElementConverter); retmap = MapUtils.filteredMapExcludingNullValues(retmap); // return retmap; } /** * Returns all {@link Class#getDeclaredAnnotations()} as {@link List} * * @param type * @return */ public static List<Annotation> declaredAnnotationList(Class<?> type) { // List<Annotation> retlist = new ArrayList<Annotation>(); // if (type != null) { // retlist.addAll(Arrays.asList(type.getDeclaredAnnotations())); } // return retlist; } /** * Returns all {@link Class#getAnnotations()} as {@link List} * * @param type * @return */ public static List<Annotation> annotationList(Class<?> type) { // List<Annotation> retlist = new ArrayList<Annotation>(); // if (type != null) { // retlist.addAll(Arrays.asList(type.getAnnotations())); } // return retlist; } /** * Returns all {@link Field#getAnnotations()} as {@link List} * * @param field * @return */ public static List<Annotation> annotationList(Field field) { // List<Annotation> retlist = new ArrayList<Annotation>(); // if (field != null) { // retlist.addAll(Arrays.asList(field.getAnnotations())); } // return retlist; } /** * Returns the {@link Annotation} instance for the given type and annotation type. If no matching annotation type is found null * is returned. The matching includes any super interfaces as well. * * @see #hasAnnotationIncludingInterfaces(Class, Class) * @see #annotation(Class, Class) * @see #declaredAnnotation(Class, Class) * @param type * @param annotationType * @return */ @SuppressWarnings("unchecked") public static <A extends Annotation> A annotationIncludingInterfaces(Class<?> type, Class<? extends A> annotationType) { // A retval = null; // final List<Annotation> annotationList = annotationList(type); for (Annotation annotation : annotationList) { if (annotation.annotationType().equals(annotationType)) { retval = (A) annotation; break; } } // if (retval == null) { // final boolean inherited = true; final Set<Class<?>> interfaceSet = interfaceSet(type, inherited); for (Class<?> interfaceType : interfaceSet) { // final A declaredAnnotation = declaredAnnotation(interfaceType, annotationType); if (declaredAnnotation != null) { retval = declaredAnnotation; break; } } } // return retval; } /** * Returns true if the given {@link Class} type declares or inherits the given {@link Annotation} class from any supertype, but * not from interfaces * * @see #hasDeclaredAnnotation(Class, Class) * @see #hasAnnotationIncludingInterfaces(Class, Class) * @see #annotation(Class, Class) * @param type * @param annotationType * @return */ public static boolean hasAnnotation(Class<?> type, Class<? extends Annotation> annotationType) { return annotation(type, annotationType) != null; } /** * Returns the {@link Annotation} instance for any {@link Annotation} declared on a {@link Package} with the given type of * {@link Annotation} * * @param package_ * @param annotationType * @return */ public static <A extends Annotation> A annotation(Package package_, Class<? extends A> annotationType) { // A retval = null; // if (package_ != null) { retval = package_.getAnnotation(annotationType); } // return retval; } /** * Returns the {@link Annotation} instance for the given type and annotation type. If no matching annotation type is found null * is returned. * * @see #hasAnnotation(Class, Class) * @see #annotationIncludingInterfaces(Class, Class) * @see #declaredAnnotation(Class, Class) * @param type * @param annotationType * @return */ @SuppressWarnings("unchecked") public static <A extends Annotation> A annotation(Class<?> type, Class<? extends A> annotationType) { // A retval = null; // if (type != null && annotationType != null) { List<Annotation> annotationList = annotationList(type); for (Annotation annotation : annotationList) { if (annotation.annotationType().equals(annotationType)) { retval = (A) annotation; break; } } } // return retval; } /** * Returns true if the given {@link Field} declares the given {@link Annotation} class * * @param field * @param annotationType * @return */ public static boolean hasAnnotation(Field field, Class<? extends Annotation> annotationType) { // boolean retval = false; // final List<Annotation> annotationList = annotationList(field); for (Annotation annotation : annotationList) { if (annotation.annotationType().equals(annotationType)) { retval = true; break; } } // return retval; } /** * Returns true if the given {@link Class} type declares or inherits the given {@link Annotation} class from any supertype, but * not from interfaces * * @see #annotationIncludingInterfaces(Class, Class) * @param type * @param annotationType * @return */ public static boolean hasAnnotationIncludingInterfaces(Class<?> type, Class<? extends Annotation> annotationType) { return annotationIncludingInterfaces(type, annotationType) != null; } /** * Returns true if the given {@link Class} type declares the given {@link Annotation} class * * @param type * @param annotationType * @return */ public static boolean hasDeclaredAnnotation(Class<?> type, Class<? extends Annotation> annotationType) { return declaredAnnotation(type, annotationType) != null; } /** * Returns the {@link Annotation} if the given {@link Class} type declares the given {@link Annotation} class * * @see #annotation(Class, Class) * @see #annotationIncludingInterfaces(Class, Class) * @param type * @param annotationType * @return */ @SuppressWarnings("unchecked") public static <A extends Annotation> A declaredAnnotation(Class<?> type, Class<? extends A> annotationType) { // A retval = null; // if (type != null && annotationType != null) { // final List<Annotation> declaredAnnotationList = declaredAnnotationList(type); for (Annotation declaredAnnotation : declaredAnnotationList) { if (declaredAnnotation.annotationType().equals(annotationType)) { retval = (A) declaredAnnotation; break; } } } // return retval; } /** * Returns true if the given {@link Method} declares the given {@link Annotation} class * * @param method * @param annotationType * @return */ public static boolean hasDeclaredAnnotation(Method method, Class<? extends Annotation> annotationType) { // boolean retval = false; // Set<Annotation> declaredAnnotationSet = declaredAnnotationSet(method); for (Annotation declaredAnnotation : declaredAnnotationSet) { if (declaredAnnotation.annotationType().equals(annotationType)) { retval = true; break; } } // return retval; } /** * Returns true if the given {@link Class} type has any annotation of the given type on any of its methods * * @param type * @param annotationType * @return */ @SuppressWarnings("unchecked") public static boolean hasAnnotationOnAnyMethod(Class<?> type, Class<? extends Annotation> annotationType) { return hasAnnotationOnAnyMethod(annotationType, new Class[] { annotationType }); } /** * Returns true if the given {@link Class} type has any annotation of the given types on any of its methods * * @param type * @param annotationTypes * @return */ public static boolean hasAnnotationOnAnyMethod(Class<?> type, Class<? extends Annotation>... annotationTypes) { // boolean retval = false; // if (type != null && annotationTypes != null) { final Method[] methods = type.getMethods(); if (methods != null) { for (Method method : methods) { for (Class<? extends Annotation> annotationType : annotationTypes) { Annotation annotation = method.getAnnotation(annotationType); if (annotation != null) { retval = true; break; } } } } } // return retval; } /** * Returns all {@link AnnotatedElement#getDeclaredAnnotations()} as {@link Set} * * @param annotatedElement * {@link Field} * @return */ public static Set<Annotation> declaredAnnotationSet(AnnotatedElement annotatedElement) { return annotatedElement != null ? SetUtils.valueOf(annotatedElement.getDeclaredAnnotations()) : new LinkedHashSet<Annotation>(); } /** * Returns all {@link AnnotatedElement#getAnnotations()} as {@link Map} which has the {@link Annotation} type as key and its * related instance as value. * * @param annotatedElement * {@link Field} * @return always a {@link Map} instance, even if the annotatedElement is null */ @SuppressWarnings("unchecked") public static Map<Class<Annotation>, Annotation> annotationTypeToAnnotationMap( AnnotatedElement annotatedElement) { final Map<Class<Annotation>, Annotation> retmap = new LinkedHashMap<Class<Annotation>, Annotation>(); if (annotatedElement != null) { final Set<Annotation> annotationSet = SetUtils.valueOf(annotatedElement.getAnnotations()); for (Annotation annotation : annotationSet) { if (annotation != null) { final Class<Annotation> annotationType = (Class<Annotation>) annotation.annotationType(); retmap.put(annotationType, annotation); } } } return retmap; } /** * Returns a {@link Map} of all {@link Method}s of the given {@link Class} type and a {@link List} of declared * {@link Annotation}s related to the {@link Method}s * * @see #declaredMethodList(Class) * @see #declaredAnnotationSet(AnnotatedElement) * @param type * @return */ public static Map<Method, Set<Annotation>> methodToAnnotationSetMap(Class<?> type) { List<Method> methodList = methodList(type); return methodToAnnotationSetMap(methodList); } /** * Returns a {@link Map} of all declared {@link Method}s of the given {@link Class} type and a {@link List} of declared * {@link Annotation}s related to the {@link Method}s * * @see #declaredMethodList(Class) * @see #declaredAnnotationSet(AnnotatedElement) * @param type * @return */ public static Map<Method, Set<Annotation>> declaredMethodToAnnotationSetMap(Class<?> type) { List<Method> methodList = declaredMethodList(type); return methodToAnnotationSetMap(methodList); } /** * Returns a {@link Map} of all the given {@link Method}s and a {@link List} of declared {@link Annotation}s related to the * {@link Method}s * * @see #declaredMethodList(Class) * @see #declaredAnnotationSet(Method) * @param methodList * @return */ protected static Map<Method, Set<Annotation>> methodToAnnotationSetMap(List<Method> methodList) { // Map<Method, Set<Annotation>> retmap = new LinkedHashMap<Method, Set<Annotation>>(); // if (methodList != null) { for (Method declaredMethod : methodList) { // Set<Annotation> declaredAnnotationSet = declaredAnnotationSet(declaredMethod); if (declaredAnnotationSet != null) { // retmap.put(declaredMethod, declaredAnnotationSet); } } } // return retmap; } /** * Returns an ordered {@link List} of {@link MethodParameterMetaInformation} instances for each parameter the given * {@link Method} has. * * @param method * @return */ public static List<MethodParameterMetaInformation> declaredMethodParameterMetaInformationList(Method method) { // List<MethodParameterMetaInformation> retlist = new ArrayList<MethodParameterMetaInformation>(); // if (method != null) { // Class<?>[] parameterTypes = method.getParameterTypes(); Annotation[][] parametersAnnotations = method.getParameterAnnotations(); // for (int ii = 0; ii < Math.max(parameterTypes.length, parametersAnnotations.length); ii++) { // Class<?> parameterType = parameterTypes[ii]; Annotation[] parameterAnnotations = parametersAnnotations[ii]; // MethodParameterMetaInformation methodParameterMetaInformation = new MethodParameterMetaInformation( parameterType, Arrays.asList(parameterAnnotations)); retlist.add(methodParameterMetaInformation); } } // return retlist; } /** * Returns the {@link Class#getDeclaredMethods()} for a given {@link Class}. Returns always a {@link List} instance. * * @param type * @return */ public static List<Method> declaredMethodList(Class<?> type) { // final List<Method> retlist = new ArrayList<Method>(); // if (type != null) { // retlist.addAll(Arrays.asList(type.getDeclaredMethods())); } // return retlist; } /** * Returns the {@link Class#getDeclaredFields()} for a given {@link Class}. Returns always a {@link List} instance. * * @param type * @return */ public static List<Field> declaredFieldList(Class<?> type) { // final List<Field> retlist = new ArrayList<Field>(); // if (type != null) { // retlist.addAll(Arrays.asList(type.getDeclaredFields())); } // return retlist; } /** * Returns the {@link Class#getFields()} for a given {@link Class}. Returns always a {@link List} instance. * * @param type * @return */ public static List<Field> fieldList(Class<?> type) { // final List<Field> retlist = new ArrayList<Field>(); // if (type != null) { // retlist.addAll(Arrays.asList(type.getFields())); } // return retlist; } /** * Returns the {@link Class#getMethods()} for a given {@link Class}. Returns always a {@link List} instance. * * @param type * @return */ public static List<Method> methodList(Class<?> type) { final List<Method> retlist = new ArrayList<Method>(); if (type != null) { retlist.addAll(Arrays.asList(type.getMethods())); } return retlist; } /** * Similar to {@link #methodList(Class)} but including the methods of all inherited interfaces and superclasses * * @param type * @return */ public static List<Method> methodListIncludingSuperMethods(Class<?> type) { List<Method> retlist = new ArrayList<Method>(); if (type != null) { final boolean inherited = true; final Set<Class<?>> assignableTypeSet = assignableTypeSet(type, inherited); if (assignableTypeSet != null) { for (Class<?> assignableType : assignableTypeSet) { retlist.addAll(methodList(assignableType)); } } } return retlist; } /** * Returns as {@link Set} of interfaces which are implemented by the given type. This includes inherited interfaces if the * respective parameter is set to true. If the given type is an interface it is included in the result. * * @param type * @return */ public static Set<Class<?>> interfaceSet(Class<?> type, boolean inherited) { boolean interfaceOnly = true; return assignableTypeSet(type, inherited, interfaceOnly); } /** * Returns as {@link Set} of assignable types which are implemented by the given type. This includes inherited types if the * respective parameter is set to true. The given type itself is included in the returned {@link Set}. * * @param type * @param inherited * @return */ public static Set<Class<?>> assignableTypeSet(Class<?> type, boolean inherited) { boolean interfaceOnly = false; return assignableTypeSet(type, inherited, interfaceOnly); } /** * Returns as {@link Set} of assignable types which are implemented by the given type. This includes inherited types if the * respective parameter is set to true. The given type is returned within the result {@link Set} if it is compliant to the * onlyReturnInterfaces flag. * * @param type * @param inherited * @param onlyReturnInterfaces * @return */ public static Set<Class<?>> assignableTypeSet(Class<?> type, boolean inherited, boolean onlyReturnInterfaces) { // final Set<Class<?>> retset = new LinkedHashSet<Class<?>>(); // if (type != null) { // final Set<Class<?>> remainingTypeSet = new LinkedHashSet<Class<?>>(); // class Helper { public void addNewInterfaceTypes(Class<?> type) { Class<?>[] interfaces = type.getInterfaces(); if (interfaces != null) { for (Class<?> interfaceType : interfaces) { if (!retset.contains(interfaceType)) { remainingTypeSet.add(interfaceType); } } } } } // if (!onlyReturnInterfaces || type.isInterface()) { retset.add(type); } // if (inherited) { remainingTypeSet.addAll(supertypeSet(type)); } // Helper helper = new Helper(); helper.addNewInterfaceTypes(type); // while (!remainingTypeSet.isEmpty()) { // Iterator<Class<?>> iterator = remainingTypeSet.iterator(); Class<?> remainingType = iterator.next(); iterator.remove(); // if (!onlyReturnInterfaces || remainingType.isInterface()) { retset.add(remainingType); } // if (inherited) { // helper.addNewInterfaceTypes(remainingType); } } } // return retset; } /** * Returns a {@link Set} of all supertypes the given type extends. The given type is not within the result {@link Set}. * * @param type * @return */ public static Set<Class<?>> supertypeSet(Class<?> type) { // Set<Class<?>> retset = new LinkedHashSet<Class<?>>(); // if (type != null) { Class<?> supertype = type.getSuperclass(); while (supertype != null) { retset.add(supertype); supertype = supertype.getSuperclass(); } } // return retset; } /** * Returns as {@link Set} of assignable types which are implemented by the given type. This includes inherited types if the * respective parameter is set to true. The given types are included within the result {@link Set} if they are compliant to the * onlyReturnInterfaces flag. * * @param inherited * @param intersection * : false -> types are merged, true -> intersection of type sets for each type * @param onlyReturnInterfaces * @param types * @return */ public static Set<Class<?>> assignableTypeSet(boolean inherited, boolean onlyReturnInterfaces, boolean intersection, Class<?>... types) { // Set<Class<?>> retset = new HashSet<Class<?>>(); // if (types.length > 0) { // Set<Set<Class<?>>> assignableTypeSetSet = new LinkedHashSet<Set<Class<?>>>(); for (Class<?> type : types) { if (type != null) { // final Set<Class<?>> assignableTypeSet = assignableTypeSet(type, inherited, onlyReturnInterfaces); assignableTypeSetSet.add(assignableTypeSet); } } // if (!intersection) { retset = SetUtils.mergeAll(assignableTypeSetSet); } else { retset = SetUtils.intersection(assignableTypeSetSet); } } // return retset; } /** * Returns true if the given target {@link Class} is {@link Class#isAssignableFrom(Class)} for the given {@link Class} type. * * @param targetType * @param type * @return */ public static boolean isAssignableFrom(Class<?> targetType, Class<?> type) { return type != null && targetType != null && targetType.isAssignableFrom(type); } /** * Returns a {@link Set} of all {@link Package} instances known to the {@link ClassLoader} which are annotated with the given * package {@link Annotation} type * * @see #annotatedPackageToAnnotationSetMap(Class...) * @param packageAnnotationTypes * @return */ public static <A extends Annotation> Set<Package> annotatedPackageSet( Class<? extends A>... packageAnnotationTypes) { return annotatedPackageToAnnotationSetMap(packageAnnotationTypes).keySet(); } /** * Returns a {@link Set} of all {@link Package} instances out of the given {@link Set} of {@link Package}s which are annotated * with at least one of the given package {@link Annotation} types * * @see #annotatedPackageToAnnotationSetMap(Class...) * @param scannedPackageSet * @param packageAnnotationTypes * @return */ public static <A extends Annotation> Set<Package> annotatedPackageSet(Set<Package> scannedPackageSet, Class<? extends A>... packageAnnotationTypes) { return annotatedPackageToAnnotationSetMap(scannedPackageSet, packageAnnotationTypes).keySet(); } /** * Returns a {@link Map} of all {@link Package}s annotated with at least one of the given package level {@link Annotation}s * including the {@link Annotation} instances related to each {@link Package}. <br> * <br> * If no {@link Annotation} is specified an empty {@link Map} is returned. * * @see #annotatedPackageSet(Class...) * @param packageAnnotationTypes * @return */ public static <A extends Annotation> Map<Package, Set<A>> annotatedPackageToAnnotationSetMap( Class<? extends A>... packageAnnotationTypes) { final Set<Package> scannedPackageSet = SetUtils.valueOf(Package.getPackages()); return annotatedPackageToAnnotationSetMap(scannedPackageSet, packageAnnotationTypes); } /** * Returns a {@link Map} of all {@link Package}s out of the given {@link Package}s {@link Set} annotated with at least one of * the given package level {@link Annotation}s including the {@link Annotation} instances related to each {@link Package}. <br> * <br> * If no {@link Annotation} or {@link Package} is specified an empty {@link Map} is returned. * * @see #annotatedPackageSet(Class...) * @param scannedPackageSet * @param packageAnnotationTypes * @return */ @SuppressWarnings("unchecked") public static <A extends Annotation> Map<Package, Set<A>> annotatedPackageToAnnotationSetMap( Set<Package> scannedPackageSet, Class<? extends A>... packageAnnotationTypes) { // final Map<Package, Set<A>> retmap = MapUtils.initializedMap(new LinkedHashSetFactory<A>()); // if (scannedPackageSet != null && packageAnnotationTypes.length > 0) { // for (Package package_ : scannedPackageSet) { for (Class<? extends Annotation> packageAnnotationType : packageAnnotationTypes) { // final Annotation annotation = package_.getAnnotation(packageAnnotationType); if (annotation != null) { retmap.get(package_).add((A) annotation); } } } } // return retmap; } /** * Invokes {@link Class#forName(String)} for the given type name but does not throw any {@link Exception}. Instead it returns * null, if the resolvation failed. * * @param className * @return */ @SuppressWarnings("unchecked") public static <T> Class<T> classForName(String className) { // Class<T> retval = null; // try { Class<?> forName = Class.forName(className); retval = (Class<T>) forName; } catch (Exception e) { } // return retval; } /** * Invokes the given method name on the given object. This does not throw any {@link Exception}. * * @param object * @param methodName * @param arguments * @return */ @SuppressWarnings("unchecked") public static <E> E invokeMethod(Object object, String methodName, Object... arguments) { // E retval = null; // try { // final Class<?>[] parameterTypes = ReflectionUtils.determineParameterTypesFromArguments(arguments); if (object != null) { // final boolean isClass = object instanceof Class; final Class<? extends Object> type = isClass ? (Class<? extends Object>) object : object.getClass(); // Method declaredMethod = null; try { declaredMethod = type.getDeclaredMethod(methodName, parameterTypes); } catch (Exception e) { for (Method method : type.getDeclaredMethods()) { // final String name = method.getName(); if (StringUtils.equals(methodName, name)) { // final Class<?>[] parameterTypesOfMethod = method.getParameterTypes(); final boolean areAssignableFrom = areAssignableFrom(parameterTypesOfMethod, parameterTypes); if (areAssignableFrom) { declaredMethod = method; break; } } } } // if (declaredMethod != null) { retval = (E) declaredMethod.invoke(isClass ? null : object, arguments); } } } catch (Exception e) { } // return retval; } }