/* * (c) 2008- RANDI2 Core Development Team * * This file is part of RANDI2. * * RANDI2 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. * * RANDI2 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 * RANDI2. If not, see <http://www.gnu.org/licenses/>. */ package de.randi2.utility; import java.io.File; import java.io.UnsupportedEncodingException; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.net.URL; import java.net.URLDecoder; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; /** * * @author jthoenes */ public final class ReflectionUtil { private ReflectionUtil() { throw new RuntimeException(); } /** * This method returns all found classes in a specified package by going * through the package directory. * * @param pckgname * the name of the package (e.g. de.randi2.model.criteria) * @return all found classes * @throws ClassNotFoundException */ public static List<Class<?>> getClasses(final String pckgname) throws ClassNotFoundException { ArrayList<Class<?>> classes = new ArrayList<Class<?>>(); // Get a File object for the package File directory = null; try { ClassLoader cld = Thread.currentThread().getContextClassLoader(); if (cld == null) { throw new ClassNotFoundException("Can't get class loader."); } String path = pckgname.replace('.', '/'); URL resource = cld.getResource(path); if (resource == null) { throw new ClassNotFoundException("No resource for " + path); } directory = new File(URLDecoder.decode(resource.getPath(), "UTF-8")); if (directory.exists()) { // Get the list of the files contained in the package String[] files = directory.list(); for (int i = 0; i < files.length; i++) { // we are only interested in .class files if (files[i].endsWith(".class")) { // removes the .class extension classes.add(Class.forName(pckgname + '.' + files[i].substring(0, files[i].length() - 6))); } } } else { throw new ClassNotFoundException(pckgname + " does not appear to be a valid package"); } } catch (NullPointerException x) { throw new ClassNotFoundException(pckgname + " (" + directory + ") does not appear to be a valid package"); } catch (UnsupportedEncodingException x) { x.printStackTrace(); } return classes; } public static Map<Field, Method> getPropertyWithGetter(Object o) { return getPropertyWithGetter(o.getClass()); } public static Map<Field, Method> getPropertyWithGetter(Class<?> klass) { Map<Field, Method> properties = new HashMap<Field, Method>(); for (Method getter : getGetters(klass)) { for (Method setter : getSetters(klass)) { if (!Modifier.isStatic(getter.getModifiers()) && Modifier.isPublic(getter.getModifiers()) && !Modifier.isStatic(setter.getModifiers()) && Modifier.isPublic(setter.getModifiers()) && getter.getName().substring(3).equals( setter.getName().substring(3))) { for (Field field : klass.getDeclaredFields()) { if (field.getName().equals( getPropertyName(getter))) { properties.put(field, getter); } } } } } return properties; } public static Set<Method> getGetters(Object o) { return getGetters(o.getClass()); } public static Set<Method> getGetters(Class<? extends Object> klass) { Set<Method> getters = new HashSet<Method>(); for (Method m : Arrays.asList(klass.getDeclaredMethods())) { if (m.getName().startsWith("get") && m.getParameterTypes().length == 0 && !void.class.equals(m.getReturnType())) { getters.add(m); } } return getters; } public static Set<Method> getSetters(Object o) { return getSetters(o.getClass()); } public static Set<Method> getSetters(Class<? extends Object> klass) { Set<Method> getters = new HashSet<Method>(); for (Method m : Arrays.asList(klass.getDeclaredMethods())) { if (m.getName().startsWith("set") && m.getParameterTypes().length == 1 && void.class.equals(m.getReturnType())) { getters.add(m); } } return getters; } public static String getPropertyName(Method m) { return m.getName().substring(3, 4).toLowerCase(Locale.ENGLISH) + m.getName().substring(4); } }