All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.invation.code.toval.reflect.ReflectionUtils Maven / Gradle / Ivy

Go to download

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