Package jfix.util

Source Code of jfix.util.Reflections

/*
    Copyright (C) 2010 maik.jablonski@gmail.com

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package jfix.util;

import java.io.File;
import java.lang.reflect.Field;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
* Common utility-methods to handle reflection.
*/
public class Reflections {

  /**
   * Returns all fields of the referring class which might hold references to
   * given reference object. The reference object is used as "template object"
   * (and not as class) to make use of the
   * java.lang.reflect.Type.isInstance()-method.
   */
  public static Set<Field> getReferringFields(Class referringClazz,
      Object reference) {
    Set<Field> referringFields = new HashSet<Field>();
    for (Field possibleReferringField : getFields(referringClazz)) {
      if (isAssignable(reference.getClass(), possibleReferringField)) {
        referringFields.add(possibleReferringField);
      }
    }
    return referringFields;
  }

  /**
   * Returns true if given possible referrer is referencing given reference
   * object in one or more of the given referring fields.
   */
  public static boolean isReferrer(Object possibleReferrer,
      Set<Field> referringFields, Object reference) {
    try {
      for (Field field : referringFields) {
        Object fieldValue = field.get(possibleReferrer);
        if (fieldValue != null
            && (fieldValue == reference || (field.getType()
                .isArray() && Arrays.contains(
                (Object[]) fieldValue, reference)))) {
          return true;
        }
      }
      return false;
    } catch (Exception e) {
      e.printStackTrace();
      throw new RuntimeException(e);
    }
  }

  /**
   * Returns all interfaces and superclasses implemented by a given class.
   */
  public static Set<Class> getSuperClassesAndInterfaces(Class clazz) {
    Set<Class> result = new HashSet<Class>();
    if (clazz != null) {
      result.add(clazz);
      for (Class interfaceClass : clazz.getInterfaces()) {
        result.addAll(getSuperClassesAndInterfaces(interfaceClass));
      }
      result.addAll(getSuperClassesAndInterfaces(clazz.getSuperclass()));
    }
    return result;
  }

  /**
   * Returns all fields of a given class (including fields from superclasses).
   */
  public static Set<Field> getFields(Class clazz) {
    Set<Field> result = new HashSet<Field>();
    for (Class superClass : getSuperClassesAndInterfaces(clazz)) {
      for (Field field : superClass.getDeclaredFields()) {
        field.setAccessible(true);
        result.add(field);
      }
    }
    return result;
  }

  /**
   * Retrieves all objects of given class-type which are referred by all the
   * objects in given collection.
   */
  public static Set<Object> getReferredObjects(Collection objects,
      Class objectClass) {
    try {
      Set result = new HashSet();
      for (Object object : objects) {
        for (Field field : Reflections.getFields(object.getClass())) {
          if (isAssignable(objectClass, field)) {
            Object fieldValue = field.get(object);
            if (fieldValue != null) {
              if (field.getType().isArray()) {
                for (Object arrayElement : (Object[]) fieldValue) {
                  result.add(arrayElement);
                }
              } else {
                result.add(fieldValue);
              }
            }
          }
        }
      }
      return result;
    } catch (Exception e) {
      e.printStackTrace();
      throw new RuntimeException(e);
    }
  }

  /**
   * Returns all instanceable (sub-)classes of given type in given package.
   */
  public static <E> E[] find(Class<E> classType, Package pckage) {
    File directory;
    try {
      String name = "/" + pckage.getName().replace('.', '/');
      directory = new File(classType.getResource(name).toURI());
    } catch (URISyntaxException e) {
      throw new RuntimeException(e);
    }
    List<E> result = new ArrayList();
    if (directory.exists()) {
      String[] files = directory.list();
      for (int i = 0; i < files.length; i++) {
        if (files[i].endsWith(".class")) {
          String classname = files[i].substring(0,
              files[i].length() - 6);
          try {
            Object o = Class.forName(
                pckage.getName() + "." + classname)
                .newInstance();
            if (classType.isInstance(o)) {
              result.add((E) o);
            }
          } catch (ClassNotFoundException cnfex) {
            System.err.println(cnfex);
          } catch (InstantiationException iex) {
          } catch (IllegalAccessException iaex) {
          }
        }
      }
    }
    Collections.sort(result, new Comparator() {
      public int compare(Object o1, Object o2) {
        return o1.getClass().getSimpleName()
            .compareTo(o2.getClass().getSimpleName());
      }
    });
    return jfix.util.Arrays.cast(result, classType);
  }

  /**
   * Returns all instanceable (sub-)classes of given type contained in the
   * package of given type.
   */
  public static <E> E[] find(Class<E> classType) {
    return find(classType, classType.getPackage());
  }

  /**
   * Returns a new instance for given clazz.
   */
  public static Object newInstance(Class clazz) {
    try {
      return clazz.newInstance();
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  /**
   * Returns a new instance for given fully qualified classname.
   */
  public static Object newInstance(String classname) {
    try {
      return Class.forName(classname).newInstance();
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  /**
   * Returns true if given class can be assigned to given field (which might
   * be a simple field or array).
   */
  public static boolean isAssignable(Class clazz, Field field) {
    return clazz.isAssignableFrom(field.getType())
        || (field.getType().isArray() && clazz.isAssignableFrom(field
            .getType().getComponentType()));
  }

  /**
   * Initializes all declared static string fields in given class with name of
   * fields.
   */
  public static void init(Class clazz) {
    for (Field field : clazz.getDeclaredFields()) {
      field.setAccessible(true);
      try {
        field.set(null, field.getName());
      } catch (Exception e) {
      }
    }
  }
}
TOP

Related Classes of jfix.util.Reflections

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.