de.invation.code.toval.reflect.ReflectionUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of TOVAL Show documentation
Show all versions of TOVAL Show documentation
TOVAL comprises a set of java classes for common programming issues. It includes utils for arrays, lists, sets and collections for convenient handling and modification, but also support for mathematic definitions concerning logic (clauses + resolution) together with some algorithms for permutations, powersets and resolution. Additionally it contains a number of types for multisets, matrices with object keys and much more.
The newest version!
package de.invation.code.toval.reflect;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import de.invation.code.toval.validate.ParameterException;
import de.invation.code.toval.validate.Validate;
/**
* A collection of helpful methods for finding subclasses, superclasses, and
* implemented interfaces for given classes and interfaces.
*
* @version 1.0
* @author Adrian Lange
*/
public class ReflectionUtils {
/** Suffix for array class names: "[]" */
public static final String ARRAY_SUFFIX = "[]";
/** Separator for the class name suffix: "." */
public static final String CLASS_SUFFIX_SEPARATOR = ".";
/** The ".class" file suffix */
public static final String CLASS_FILE_SUFFIX = CLASS_SUFFIX_SEPARATOR + "class";
/** Name pattern for package name elements: "[a-z0-9]*" */
public static final String PACKAGE_NAME_PATTERN = "[a-z0-9]*";
/** Separator for package name elements: "." */
public static final String PACKAGE_SEPARATOR = ".";
/** Separator for package name elements in path form: "/" */
public static final String PACKAGE_PATH_SEPARATOR = "/";
public static Set> getClassesInPackage(String packageName, boolean recursive) throws ReflectionException{
Validate.notNull(packageName);
Validate.notEmpty(packageName);
try {
String packagePath = packageName.replace(PACKAGE_SEPARATOR, PACKAGE_PATH_SEPARATOR);
URL packageURL = Thread.currentThread().getContextClassLoader().getResource(packagePath);
Set> classes = new HashSet>();
try {
BufferedReader in = new BufferedReader(new InputStreamReader(packageURL.openStream()));
String line = null;
while ((line = in.readLine()) != null) {
if (line.endsWith(CLASS_FILE_SUFFIX)) { // class, enum, or
// interface
String className = line.substring(0, line.lastIndexOf(CLASS_SUFFIX_SEPARATOR));
try {
Class> currentClass = Class.forName(packageName + PACKAGE_SEPARATOR + className);
classes.add(currentClass);
} catch (ClassNotFoundException e) {
throw new ReflectionException("Cannot locate class \"" + className + "\"", e);
}
} else if (line.matches(PACKAGE_NAME_PATTERN) && recursive) { // package
// recursive call to add classes in the package
classes.addAll(getClassesInPackage(packageName + PACKAGE_SEPARATOR + line, recursive));
}
}
} catch (IOException e) {
throw new ReflectionException("Cannot access package directory", e);
}
return classes;
} catch (Exception e) {
throw new ReflectionException(e);
}
}
/**
* The same method as {@link #getSubclassesInPackage(Class, String, boolean)},
* but with the possibility to search in multiple packages. Since the result
* is returned as a {@link Set}, there won't be any duplicates.
* @throws ReflectionException
*/
public static Set> getClassesInPackages(List packageNames, boolean recursive) throws ReflectionException {
Validate.notNull(packageNames);
Set> classes = new HashSet>();
for (String packageName : packageNames) {
classes.addAll(getClassesInPackage(packageName, recursive));
}
return classes;
}
/**
*
* Returns a {@link List} of {@link Class} objects containing all classes of
* a specified package (including subpackages) which extend the given class.
*
*
* Example:
*
*
*
* String pack = "de.uni.freiburg.iig.telematik.sepia";
* Class<?> superclass = AbstractPlace.class;
* List<Class<?>> classes = ReflectionUtils.getSubclasses(superclass, pack);
* for (Class<?> c : classes) {
* System.out.println(c);
* }
*
* // class de.uni.freiburg.iig.telematik.sepia.petrinet.cpn.abstr.AbstractCPNPlace
* // class de.uni.freiburg.iig.telematik.sepia.petrinet.cpn.CPNPlace
* // class
* // de.uni.freiburg.iig.telematik.sepia.petrinet.ifnet.abstr.AbstractIFNetPlace
* // class de.uni.freiburg.iig.telematik.sepia.petrinet.ifnet.IFNetPlace
* // class de.uni.freiburg.iig.telematik.sepia.petrinet.pt.abstr.AbstractPTPlace
* // class de.uni.freiburg.iig.telematik.sepia.petrinet.pt.PTPlace
*
*
* @param clazz
* Class which should be extended.
* @param packageName
* Package to search for subclasses.
* @return {@link List} of {@link Class} objects extending the given class
* in the specified package.
* @throws ReflectionException
*/
public static Set> getSubclassesInPackage(Class> clazz, String packageName, boolean recursive) throws ReflectionException {
Validate.notNull(clazz);
if (clazz.isInterface() || clazz.isEnum()) {
throw new ParameterException("Parameter is not a class");
}
Set> classesInPackage = getClassesInPackage(packageName, recursive);
try{
Set> subClassesInPackage = new HashSet>();
for (Class> classInPackage : classesInPackage) {
if (getSuperclasses(classInPackage).contains(clazz) && clazz != classInPackage) {
subClassesInPackage.add(classInPackage);
}
}
return subClassesInPackage;
} catch(Exception e){
throw new ReflectionException(e);
}
}
/**
*
* Returns a {@link Set} of {@link Class} objects containing all classes of
* a specified package (including subpackages) which implement the given
* interface.
*
*
* Example:
*
*
*
* String pack = "de.uni.freiburg.iig.telematik.sepia";
* Class<?> interf = PNParserInterface.class;
* Set<Class<?>> classes = ReflectionUtils.getInterfaceImplementations(interf, pack);
* for (Class<?> c : classes) {
* System.out.println(c);
* }
*
* // class de.uni.freiburg.iig.telematik.sepia.parser.petrify.PetrifyParser
* // class de.uni.freiburg.iig.telematik.sepia.parser.pnml.PNMLParser
*
*
* @param interfaze
* Interface which should be implemented.
* @param packageName
* Package to search for classes.
* @return {@link Set} of {@link Class} objects implementing the given
* interface in the specified package.
* @throws ReflectionException
*/
public static Set> getInterfaceImplementationsInPackage(Class> interfaze, String packageName, boolean recursive) throws ReflectionException {
Validate.notNull(interfaze);
if (!interfaze.isInterface()) {
throw new ParameterException("Parameter is not an interface");
}
Set> classesInPackage = getClassesInPackage(packageName, recursive);
try{
Set> interfaceImplamantationsInPackage = new HashSet>();
for (Class> classInPackage : classesInPackage) {
if (getInterfaces(classInPackage).contains(interfaze)) {
interfaceImplamantationsInPackage.add(classInPackage);
}
}
return interfaceImplamantationsInPackage;
} catch(Exception e){
throw new ReflectionException(e);
}
}
/**
* The same method as
* {@link ReflectionUtils#getInterfaceImplementationsInPackage(Class, String, boolean)}, but
* with the possibility to search in multiple packages. Since the result is
* returned as a {@link Set}, there won't be any duplicates.
* @throws ReflectionException
*/
public static Set> getInterfaceImplementationsInPackages(Class> interfaze, List packageNames, boolean recursive) throws ReflectionException {
Validate.notNull(interfaze);
Validate.notNull(packageNames);
if (!interfaze.isInterface()) {
throw new ParameterException("Parameter is not an interface");
}
Set> classes = new HashSet>();
for (String packageName : packageNames) {
classes.addAll(getInterfaceImplementationsInPackage(interfaze, packageName, recursive));
}
return classes;
}
/**
* Returns all superclasses of the given class ordered top down. The last
* element is always {@link java.lang.Object}.
*/
public static List> getSuperclasses(Class> clazz) throws ReflectionException {
Validate.notNull(clazz);
try {
List> clazzes = new ArrayList>();
if (clazz.getSuperclass() != null) {
clazzes.add(clazz.getSuperclass());
clazzes.addAll(getSuperclasses(clazz.getSuperclass()));
}
return clazzes;
} catch (Exception e) {
throw new ReflectionException(e);
}
}
/**
* Returns all implemented interfaces of the given class.
*/
public static Set> getInterfaces(Class> clazz) throws ReflectionException {
Validate.notNull(clazz);
try{
Set> interfaces = new HashSet>();
interfaces.addAll(Arrays.asList(clazz.getInterfaces()));
List> superclasses = getSuperclasses(clazz);
for (Class> superclass : superclasses) {
interfaces.addAll(Arrays.asList(superclass.getInterfaces()));
}
return interfaces;
} catch(Exception e){
throw new ReflectionException(e);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy