net.sf.javaprinciples.FieldUtils Maven / Gradle / Ivy
package net.sf.javaprinciples;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
public class FieldUtils
{
private static FieldUtils> singleton;
/**
* Searches the class of the target object and all ancestors for the field.
* @param target The base class to be searched
* @param fieldName The field name.
* @return Null if the field is not found
*/
private static Field findField(Class> targetClass, String fieldName)
{
try
{
return targetClass.getDeclaredField(fieldName);
}
catch (NoSuchFieldException e)
{
Class> superClass = targetClass.getSuperclass();
if (superClass == null)
return null;
return findField(superClass, fieldName);
}
}
/**
* Set a value on a field.
* @param target The object that defines the field
* @param fieldName The name of the field to change
* @param value The value to be set
*/
public static void setAttribute(Object target, String fieldName, Object value)
{
try
{
Field field = findField(target.getClass(), fieldName);
if (field == null)
throw new RuntimeException("Field does not exist:" + fieldName);
field.setAccessible(true);
field.set(target, value);
}
catch (IllegalArgumentException e)
{
throw new RuntimeException("The value is not appropriate for the Field:" + fieldName, e);
}
catch (IllegalAccessException e)
{
throw new RuntimeException("The field is not accessible:" + fieldName, e);
}
}
private static void findResourceFields(Class> targetClass, List matches)
{
Field[] fields = targetClass.getDeclaredFields();
for (Field field: fields)
{
Resource annotation = field.getAnnotation(Resource.class);
if (annotation != null)
matches.add(field);
}
Class> superClass = targetClass.getSuperclass();
if (superClass != null)
findResourceFields(superClass, matches);
}
public static Field[] findResourceFields(Object target)
{
synchronized(lock)
{
if (singleton == null)
{
singleton = new FieldUtils();
}
}
return singleton.findFields(target);
}
public Field[] findFields(Object target)
{
List matches = new ArrayList();
findResourceFields(target.getClass(), matches);
return matches.toArray(new Field[] {});
}
private Map, T> implCache = new HashMap, T>();
private static Object lock = new Object();
public static void injectResources(Object target)
{
synchronized(lock)
{
if (singleton == null)
{
singleton = new FieldUtils();
}
}
singleton.inject(target);
}
public void inject(Object target)
{
Field[] fields = findResourceFields(target);
for (Field field: fields)
{
Class> type = field.getType();
String implName = type.getName() + "Impl";
Class implClass;
try
{
implClass = (Class)getClassLoader(type).loadClass(implName);
}
catch (ClassNotFoundException e)
{
throw new RuntimeException("Could not find impl class:" + field.getName(), e);
}
T impl = implCache.get(implClass);
try
{
if (impl == null)
{
impl = implClass.newInstance();
implCache.put(implClass, impl);
}
}
catch (InstantiationException e)
{
throw new RuntimeException("Could not instantiate class:" + field.getName(), e);
}
catch (IllegalAccessException e)
{
throw new RuntimeException("Illgeal Access class:" + field.getName(), e);
}
field.setAccessible(true);
try
{
field.set(target, impl);
}
catch (IllegalArgumentException e)
{
throw new RuntimeException("The value is not appropriate for the Field:" + field.getName(), e);
}
catch (IllegalAccessException e)
{
throw new RuntimeException("The field is not accessible:" + field.getName(), e);
}
}
}
private ClassLoader getClassLoader(Class> c)
{
ClassLoader classLoader = c.getClassLoader();
if (classLoader != null)
{
return classLoader;
}
return Thread.currentThread().getContextClassLoader();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy