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

org.hibernate.validator.internal.util.classhierarchy.ClassHierarchyHelper Maven / Gradle / Ivy

There is a newer version: 8.0.1.Final
Show newest version
/*
 * Hibernate Validator, declare and validate application constraints
 *
 * License: Apache License, Version 2.0
 * See the license.txt file in the root directory or .
 */
package org.hibernate.validator.internal.util.classhierarchy;

import java.util.Arrays;
import java.util.List;
import java.util.Set;

import org.hibernate.validator.internal.util.Contracts;

import static org.hibernate.validator.internal.util.CollectionHelper.newArrayList;
import static org.hibernate.validator.internal.util.CollectionHelper.newHashSet;

/**
 * Helper class for dealing with inheritance hierarchies of given types which
 * allows to selectively retrieve elements from such hierarchies, e.g. all
 * super-classes, all implemented interfaces etc.
 *
 * @author Hardy Ferentschik
 * @author Gunnar Morling
 */
public class ClassHierarchyHelper {

	private ClassHierarchyHelper() {
		// Not allowed
	}

	/**
	 * Gets the elements of the hierarchy of the given class which match the
	 * given filters. Classes are added by starting with the class itself and
	 * its implemented interfaces. Then its super class and interfaces are added
	 * and so on.
	 *
	 * @param clazz the class for which to retrieve the hierarchy
	 * @param filters filters applying for the search
	 * @param  the type of the class
	 *
	 * @return List of hierarchy classes. Will only contain those types matching
	 *         the given filters. The list contains the given class itself, if
	 *         it is no proxy class.
	 */
	public static  List> getHierarchy(Class clazz, Filter... filters) {
		Contracts.assertNotNull( clazz );

		List> classes = newArrayList();

		List allFilters = newArrayList();
		allFilters.addAll( Arrays.asList( filters ) );
		allFilters.add( Filters.excludeProxies() );

		getHierarchy( clazz, classes, allFilters );
		return classes;
	}

	/**
	 * Retrieves all superclasses and interfaces recursively.
	 *
	 * @param clazz the class to start the search with
	 * @param classes list of classes to which to add all found super types matching
	 * the given filters
	 * @param filters filters applying for the search
	 */
	private static  void getHierarchy(Class clazz, List> classes, Iterable filters) {
		for ( Class current = clazz; current != null; current = current.getSuperclass() ) {
			if ( classes.contains( current ) ) {
				return;
			}

			if ( acceptedByAllFilters( current, filters ) ) {
				classes.add( current );
			}

			for ( Class currentInterface : current.getInterfaces() ) {
				//safe since interfaces are super-types
				@SuppressWarnings("unchecked")
				Class currentInterfaceCasted = (Class) currentInterface;
				getHierarchy( currentInterfaceCasted, classes, filters );
			}
		}
	}

	private static boolean acceptedByAllFilters(Class clazz, Iterable filters) {
		for ( Filter classFilter : filters ) {
			if ( !classFilter.accepts( clazz ) ) {
				return false;
			}
		}

		return true;
	}

	/**
	 * Gets all interfaces (and recursively their super-interfaces) which the
	 * given class directly implements. Interfaces implemented by super-classes
	 * are not contained.
	 *
	 * @param clazz the class for which to retrieve the implemented interfaces
	 * @param  the type of the class
	 *
	 * @return Set of all interfaces implemented by the class represented by
	 *         this hierarchy. The empty list is returned if it does not
	 *         implement any interfaces.
	 */
	public static  Set> getDirectlyImplementedInterfaces(Class clazz) {
		Contracts.assertNotNull( clazz );

		Set> classes = newHashSet();
		getImplementedInterfaces( clazz, classes );
		return classes;
	}

	private static  void getImplementedInterfaces(Class clazz, Set> classes) {
		for ( Class currentInterface : clazz.getInterfaces() ) {
			@SuppressWarnings("unchecked") //safe since interfaces are super-types
					Class currentInterfaceCasted = (Class) currentInterface;
			classes.add( currentInterfaceCasted );
			getImplementedInterfaces( currentInterfaceCasted, classes );
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy