Java/Reflection/Inheritance
Версия от 18:01, 31 мая 2010; (обсуждение)
Содержание
Class comparator: compare and sort classes and their superclasses.
/*
* JCommon : a free general purpose class library for the Java(tm) platform
*
*
* (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
*
* Project Info: http://www.jfree.org/jcommon/index.html
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* --------------------
* ClassComparator.java
* --------------------
* (C)opyright 2003-2005, by Thomas Morgner and Contributors.
*
* Original Author: Thomas Morgner (taquera@sherito.org);
* Contributor(s): David Gilbert (for Object Refinery Limited);
*
* $Id: ClassComparator.java,v 1.3 2005/10/18 13:24:19 mungady Exp $
*
* Changes
* -------
* 02-May-2003 : Initial version
*
*/
import java.io.Serializable;
import java.util.ruparator;
/**
* The class comparator can be used to compare and sort classes and their
* superclasses. The comparator is not able to compare classes which have no
* relation...
*
* @author Thomas Morgner
*/
public class ClassComparator implements Comparator, Serializable {
/** For serialization. */
private static final long serialVersionUID = -5225335361837391120L;
/**
* Defaultconstructor.
*/
public ClassComparator() {
super();
}
/**
* Compares its two arguments for order. Returns a negative integer, zero, or
* a positive integer as the first argument is less than, equal to, or greater
* than the second.
* <p>
* <P>
* Note: throws ClassCastException if the arguments" types prevent them from
* being compared by this Comparator. And IllegalArgumentException if the
* classes share no relation.
*
* The implementor must ensure that <tt>sgn(compare(x, y)) ==
* -sgn(compare(y, x))</tt>
* for all <tt>x</tt> and <tt>y</tt>. (This implies that
* <tt>compare(x, y)</tt> must throw an exception if and only if
* <tt>compare(y, x)</tt> throws an exception.)
* <p>
*
* The implementor must also ensure that the relation is transitive:
* <tt>((compare(x, y)>0) && (compare(y, z)>0))</tt> implies
* <tt>compare(x, z)>0</tt>.
* <p>
*
* Finally, the implementer must ensure that <tt>compare(x, y)==0</tt>
* implies that <tt>sgn(compare(x, z))==sgn(compare(y, z))</tt> for all
* <tt>z</tt>.
* <p>
*
* It is generally the case, but <i>not</i> strictly required that
* <tt>(compare(x, y)==0) == (x.equals(y))</tt>. Generally speaking, any
* comparator that violates this condition should clearly indicate this fact.
* The recommended language is "Note: this comparator imposes orderings that
* are inconsistent with equals."
*
* @param o1
* the first object to be compared.
* @param o2
* the second object to be compared.
* @return a negative integer, zero, or a positive integer as the first
* argument is less than, equal to, or greater than the second.
*/
public int compare(final Object o1, final Object o2) {
final Class c1 = (Class) o1;
final Class c2 = (Class) o2;
if (c1.equals(o2)) {
return 0;
}
if (c1.isAssignableFrom(c2)) {
return -1;
} else {
if (!c2.isAssignableFrom(c2)) {
throw new IllegalArgumentException("The classes share no relation");
}
return 1;
}
}
/**
* Checks, whether the given classes are comparable. This method will return
* true, if one of the classes is assignable from the other class.
*
* @param c1
* the first class to compare
* @param c2
* the second class to compare
* @return true, if the classes share a direct relation, false otherwise.
*/
public boolean isComparable(final Class c1, final Class c2) {
return (c1.isAssignableFrom(c2) || c2.isAssignableFrom(c1));
}
}
Find Inherited Field
//
//$Id: IntrospectionUtil.java 1540 2007-01-19 12:24:10Z janb $
//Copyright 2006 Mort Bay Consulting Pty. Ltd.
//------------------------------------------------------------------------
//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.
//
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.List;
public class IntrospectionUtil {
protected static Field findInheritedField(Package pack, Class clazz, String fieldName,
Class fieldType, boolean strictType) throws NoSuchFieldException {
if (clazz == null)
throw new NoSuchFieldException("No class");
if (fieldName == null)
throw new NoSuchFieldException("No field name");
try {
Field field = clazz.getDeclaredField(fieldName);
if (isInheritable(pack, field) && isTypeCompatible(fieldType, field.getType(), strictType))
return field;
else
return findInheritedField(clazz.getPackage(), clazz.getSuperclass(), fieldName, fieldType,
strictType);
} catch (NoSuchFieldException e) {
return findInheritedField(clazz.getPackage(), clazz.getSuperclass(), fieldName, fieldType,
strictType);
}
}
public static boolean isInheritable(Package pack, Member member) {
if (pack == null)
return false;
if (member == null)
return false;
int modifiers = member.getModifiers();
if (Modifier.isPublic(modifiers))
return true;
if (Modifier.isProtected(modifiers))
return true;
if (!Modifier.isPrivate(modifiers) && pack.equals(member.getDeclaringClass().getPackage()))
return true;
return false;
}
public static boolean checkParams(Class[] formalParams, Class[] actualParams, boolean strict) {
if (formalParams == null && actualParams == null)
return true;
if (formalParams == null && actualParams != null)
return false;
if (formalParams != null && actualParams == null)
return false;
if (formalParams.length != actualParams.length)
return false;
if (formalParams.length == 0)
return true;
int j = 0;
if (strict) {
while (j < formalParams.length && formalParams[j].equals(actualParams[j]))
j++;
} else {
while ((j < formalParams.length) && (formalParams[j].isAssignableFrom(actualParams[j]))) {
j++;
}
}
if (j != formalParams.length) {
return false;
}
return true;
}
public static boolean isSameSignature(Method methodA, Method methodB) {
if (methodA == null)
return false;
if (methodB == null)
return false;
List parameterTypesA = Arrays.asList(methodA.getParameterTypes());
List parameterTypesB = Arrays.asList(methodB.getParameterTypes());
if (methodA.getName().equals(methodB.getName()) && parameterTypesA.containsAll(parameterTypesB))
return true;
return false;
}
public static boolean isTypeCompatible(Class formalType, Class actualType, boolean strict) {
if (formalType == null && actualType != null)
return false;
if (formalType != null && actualType == null)
return false;
if (formalType == null && actualType == null)
return true;
if (strict)
return formalType.equals(actualType);
else
return formalType.isAssignableFrom(actualType);
}
}
Find Inherited Method
//
//$Id: IntrospectionUtil.java 1540 2007-01-19 12:24:10Z janb $
//Copyright 2006 Mort Bay Consulting Pty. Ltd.
//------------------------------------------------------------------------
//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.
//
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.List;
public class IntrospectionUtil {
protected static Method findInheritedMethod(Package pack, Class clazz, String methodName,
Class[] args, boolean strictArgs) throws NoSuchMethodException {
if (clazz == null)
throw new NoSuchMethodException("No class");
if (methodName == null)
throw new NoSuchMethodException("No method name");
Method method = null;
Method[] methods = clazz.getDeclaredMethods();
for (int i = 0; i < methods.length && method == null; i++) {
if (methods[i].getName().equals(methodName) && isInheritable(pack, methods[i])
&& checkParams(methods[i].getParameterTypes(), args, strictArgs))
method = methods[i];
}
if (method != null) {
return method;
} else
return findInheritedMethod(clazz.getPackage(), clazz.getSuperclass(), methodName, args,
strictArgs);
}
protected static Field findInheritedField(Package pack, Class clazz, String fieldName,
Class fieldType, boolean strictType) throws NoSuchFieldException {
if (clazz == null)
throw new NoSuchFieldException("No class");
if (fieldName == null)
throw new NoSuchFieldException("No field name");
try {
Field field = clazz.getDeclaredField(fieldName);
if (isInheritable(pack, field) && isTypeCompatible(fieldType, field.getType(), strictType))
return field;
else
return findInheritedField(clazz.getPackage(), clazz.getSuperclass(), fieldName, fieldType,
strictType);
} catch (NoSuchFieldException e) {
return findInheritedField(clazz.getPackage(), clazz.getSuperclass(), fieldName, fieldType,
strictType);
}
}
public static boolean isInheritable(Package pack, Member member) {
if (pack == null)
return false;
if (member == null)
return false;
int modifiers = member.getModifiers();
if (Modifier.isPublic(modifiers))
return true;
if (Modifier.isProtected(modifiers))
return true;
if (!Modifier.isPrivate(modifiers) && pack.equals(member.getDeclaringClass().getPackage()))
return true;
return false;
}
public static boolean checkParams(Class[] formalParams, Class[] actualParams, boolean strict) {
if (formalParams == null && actualParams == null)
return true;
if (formalParams == null && actualParams != null)
return false;
if (formalParams != null && actualParams == null)
return false;
if (formalParams.length != actualParams.length)
return false;
if (formalParams.length == 0)
return true;
int j = 0;
if (strict) {
while (j < formalParams.length && formalParams[j].equals(actualParams[j]))
j++;
} else {
while ((j < formalParams.length) && (formalParams[j].isAssignableFrom(actualParams[j]))) {
j++;
}
}
if (j != formalParams.length) {
return false;
}
return true;
}
public static boolean isSameSignature(Method methodA, Method methodB) {
if (methodA == null)
return false;
if (methodB == null)
return false;
List parameterTypesA = Arrays.asList(methodA.getParameterTypes());
List parameterTypesB = Arrays.asList(methodB.getParameterTypes());
if (methodA.getName().equals(methodB.getName()) && parameterTypesA.containsAll(parameterTypesB))
return true;
return false;
}
public static boolean isTypeCompatible(Class formalType, Class actualType, boolean strict) {
if (formalType == null && actualType != null)
return false;
if (formalType != null && actualType == null)
return false;
if (formalType == null && actualType == null)
return true;
if (strict)
return formalType.equals(actualType);
else
return formalType.isAssignableFrom(actualType);
}
}
Is Inheritable
//
//$Id: IntrospectionUtil.java 1540 2007-01-19 12:24:10Z janb $
//Copyright 2006 Mort Bay Consulting Pty. Ltd.
//------------------------------------------------------------------------
//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.
//
import java.lang.reflect.Member;
import java.lang.reflect.Modifier;
public class Utils {
public static boolean isInheritable(Package pack, Member member) {
if (pack == null)
return false;
if (member == null)
return false;
int modifiers = member.getModifiers();
if (Modifier.isPublic(modifiers))
return true;
if (Modifier.isProtected(modifiers))
return true;
if (!Modifier.isPrivate(modifiers) && pack.equals(member.getDeclaringClass().getPackage()))
return true;
return false;
}
}
Return a List of super-classes for the given class.
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
/*
* Copyright 2005 Joe Walker
*
* 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.
*/
/**
* @author Joe Walker [joe at getahead dot ltd dot uk]
*/
public class Main {
/**
* Return a List of super-classes for the given class.
* @param clazz the class to look up
* @return the List of super-classes in order going up from this one
*/
public static List<Class<?>> getAllSuperclasses(Class<?> clazz)
{
List<Class<?>> classes = new ArrayList<Class<?>>();
Class<?> superclass = clazz.getSuperclass();
while (superclass != null)
{
classes.add(superclass);
superclass = superclass.getSuperclass();
}
return classes;
}
}