org.hibernate.validator.internal.util.classhierarchy.ClassHierarchyHelper Maven / Gradle / Ivy
/*
* JBoss, Home of Professional Open Source
* Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed 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.hibernate.validator.internal.util.classhierarchy;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import org.hibernate.validator.internal.util.Contracts;
import org.hibernate.validator.internal.util.ReflectionHelper;
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 {
/**
* 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
*
* @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
*
* @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 );
}
}
/**
* Get a list of all methods wich the given class declares, implements,
* overrides or inherits. Methods are added by adding first all methods of
* the class itself and its implemented interfaces, then the super class and
* its interfaces, etc.
*
* @param clazz the class for which to retrieve the methods
*
* @return set of all methods of the given class
*/
public static List getAllMethods(Class clazz) {
Contracts.assertNotNull( clazz );
List methods = newArrayList();
for ( Class hierarchyClass : getHierarchy( clazz ) ) {
Collections.addAll( methods, ReflectionHelper.getMethods( hierarchyClass ) );
}
return methods;
}
}