Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package com.cloudhopper.commons.util;
/*
* #%L
* ch-commons-util
* %%
* Copyright (C) 2012 Cloudhopper by Twitter
* %%
* 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.
* #L%
*/
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayDeque;
/**
* This class implements utilities for working with classes.
*
* @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
* @author john woolf (twitter: @jwoolf330 or http://twitter.com/jwoolf330)
*/
public class ClassUtil {
/**
* Finds an instance of an Enum constant on a class. Useful for safely
* getting the value of an enum constant without an exception being thrown
* like the Enum.valueOf() method causes. Searches for enum constant
* where case is sensitive.
*/
public static Object findEnumConstant(Class> type, String constantName) {
return findEnumConstant(type, constantName, true);
}
/**
* Finds an instance of an Enum constant on a class. Useful for safely
* getting the value of an enum constant without an exception being thrown
* like the Enum.valueOf() method causes. Also, this method optionally allows
* the caller to choose whether case matters during the search.
*/
public static Object findEnumConstant(Class> type, String constantName, boolean caseSensitive) {
if (!type.isEnum()) {
return null;
}
for (Object obj : type.getEnumConstants()) {
String name = obj.toString();
if ((caseSensitive && name.equals(constantName)) || (!caseSensitive && name.equalsIgnoreCase(constantName))) {
return obj;
}
}
// otherwise, it wasn't found
return null;
}
/**
* Returns an array of class objects representing the entire class hierarchy
* with the most-super class as the first element followed by all subclasses
* in the order they are declared. This method does not include the generic
* Object type in its list. If this class represents the Object type, this
* method will return a zero-size array.
*/
public static Class>[] getClassHierarchy(Class> type) {
ArrayDeque> classes = new ArrayDeque>();
// class to start our search from, we'll loop thru the entire class hierarchy
Class> classType = type;
// keep searching up until we reach an Object class type
while (classType != null && !classType.equals(Object.class)) {
// keep adding onto front
classes.addFirst(classType);
classType = classType.getSuperclass();
}
return classes.toArray(new Class[0]);
}
/**
* Checks if the class implements public "bean" methods (get and set) for the
* name. For example, for a name such as "firstName", this method will
* check if the class has both getFirstName() and setFirstName() methods.
* Also, this method will validate the return type matches the paramType
* on the getXXX() method and that the setXXX() method only accepts that
* paramType. The search is optionally case sensitive.
* @param type The class to search
* @param propertyName The property name to search for, if "firstName", then
* this method will internally add the "get" and "set" to the beginning.
* @param propertyType The class type of the property
* @param caseSensitive If the search is case sensitive or not
* @return True if the "bean" methods are correct, otherwise false.
*/
public static boolean hasBeanMethods(Class> type, String propertyName, Class> propertyType, boolean caseSensitive) {
try {
// if this succeeds without an exception, then the properties exist!
@SuppressWarnings("unused")
Method[] methods = getBeanMethods(type, propertyName, propertyType, caseSensitive);
return true;
} catch (Exception e) {
return false;
}
}
/**
* Gets the methods within this class that implements public "bean" methods
* (get and set) for the property name. Returns an array of methods where
* index=0 is the get method and index=1 is the set method.
* For example, for a name such as "firstName", this method will
* check if the class has both getFirstName() and setFirstName() methods.
* Also, this method will validate the return type matches the propertyType
* on the getXXX() method and that the setXXX() method only accepts that
* propertyType. The search is optionally case sensitive.
* @param type The class to search
* @param propertyName The name to search for
* @param paramType The class type of the property
* @param caseSensitive If the search is case sensitive or not
* @return An array of Methods were index=0 is the get method and index=1 is the set method
* @throws java.lang.IllegalAccessException If the method was found, but is not public.
* @throws java.lang.NoSuchMethodException If the method was not found
*/
public static Method[] getBeanMethods(Class> type, String propertyName, Class> propertyType, boolean caseSensitive)
throws IllegalAccessException, NoSuchMethodException {
Method methods[] = new Method[2];
// search for the "get"
methods[0] = getMethod(type, "get"+propertyName, propertyType, null, caseSensitive);
// search for the "set"
methods[1] = getMethod(type, "set"+propertyName, null, propertyType, caseSensitive);
return methods;
}
/**
* Gets the public method within the type that matches the method name, return type,
* and single parameter type. Optionally is a case sensitive search. Useful
* for searching for "bean" methods on classes.
* @param type The class to search for the method
* @param name The name of the method to search for
* @param returnType The expected return type or null if its expected to be a void method
* @param paramType The expected parameter type or null if no parameters are expected
* @param caseSensitive True if its a case sensitive search, otherwise false
* @return The method matching the search criteria
* @throws java.lang.IllegalAccessException If the method was found, but is not public.
* @throws java.lang.NoSuchMethodException If the method was not found
*/
public static Method getMethod(Class> type, String name, Class> returnType, Class> paramType, boolean caseSensitive)
throws IllegalAccessException, NoSuchMethodException {
// flag to help modify the exception to make it a little easier for debugging
boolean methodNameFound = false;
// start our search
Class> classType = type;
while (classType != null && !classType.equals(Object.class)) {
for (Method m : classType.getDeclaredMethods()) {
if ((!caseSensitive && m.getName().equalsIgnoreCase(name)) || (caseSensitive && m.getName().equals(name))) {
// we found the method name, but its possible the signature won't
// match below, we'll set this flag to help construct a better exception
// below
methodNameFound = true;
// should we validate the return type?
if (returnType != null) {
// if the return types don't match, then this must be invalid
// since the JVM doesn't allow the same return type
if (!m.getReturnType().equals(returnType)) {
throw new NoSuchMethodException("Method '" + name + "' was found in " + type.getSimpleName() + ".class"
+ ", but the returnType " + m.getReturnType().getSimpleName() + ".class did not match expected " + returnType.getSimpleName() + ".class");
}
// make sure the return type is VOID
} else {
if (!m.getReturnType().equals(void.class)) {
throw new NoSuchMethodException("Method '" + name + "' was found in " + type.getSimpleName() + ".class"
+ ", but the returnType " + m.getReturnType().getSimpleName() + ".class was expected to be void");
}
}
// return type was okay, check the parameters
Class>[] paramTypes = m.getParameterTypes();
// should we check the parameter type?
if (paramType != null) {
// must have exactly 1 parameter
if (paramTypes.length != 1) {
// this might not be the method we want, keep searching
continue;
} else {
// if the parameters don't match, keep searching
if (!paramTypes[0].equals(paramType)) {
continue;
}
}
// if paramType was null, then make sure no parameters are expected
} else {
if (paramTypes.length != 0) {
continue;
}
}
// if we got here, then everything matches so far
// now its time to check if the method is accessible
if (!Modifier.isPublic(m.getModifiers())) {
throw new IllegalAccessException("Method '" + name + "' was found in " + type.getSimpleName() + ".class "+
", but its not accessible since its " + Modifier.toString(m.getModifiers()));
}
// everything was okay
return m;
}
}
// move onto the superclass
classType = classType.getSuperclass();
}
String signature = "public " + (returnType == null ? "void" : returnType.getName()) + " " + name + "(" + (paramType == null ? "" : paramType.getName()) + ")";
if (methodNameFound) {
throw new NoSuchMethodException("Method '" + signature + "' was found in " + type.getSimpleName() + ".class, but signature match failed");
} else {
throw new NoSuchMethodException("Method '" + signature + "' was not found in " + type.getSimpleName() + ".class");
}
}
}