Java/Reflection/Inheritance

Материал из Java эксперт
Перейти к: навигация, поиск

Class comparator: compare and sort classes and their superclasses.

   <source lang="java">
  

/*

* 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> * 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 sgn(compare(x, y)) == * -sgn(compare(y, x)) * for all x and y. (This implies that * compare(x, y) must throw an exception if and only if * compare(y, x) throws an exception.) * <p> * * The implementor must also ensure that the relation is transitive: * ((compare(x, y)>0) && (compare(y, z)>0)) implies * compare(x, z)>0. * <p> * * Finally, the implementer must ensure that compare(x, y)==0 * implies that sgn(compare(x, z))==sgn(compare(y, z)) for all * z. * <p> * * It is generally the case, but not strictly required that * (compare(x, y)==0) == (x.equals(y)). 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)); } } </source>

Find Inherited Field

   <source lang="java">
  

// //$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);
 }

}


 </source>
   
  
 
  



Find Inherited Method

   <source lang="java">
  

// //$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);
 }

}


 </source>
   
  
 
  



Is Inheritable

   <source lang="java">
  

// //$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;
 }

}


 </source>
   
  
 
  



Return a List of super-classes for the given class.

   <source lang="java">

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;
 }

}

 </source>