All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.projectmonkey.object.mapper.util.ReflectionUtil Maven / Gradle / Ivy

Go to download

Object mapping implementation written as an alternative to modelmapper which is able to support inheritance, handles flattening / expanding in a precise way, and is extensible / configurable

The newest version!
package net.projectmonkey.object.mapper.util;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;

/*
 *
 *  * Copyright 2012 the original author or authors.
 *  *
 *  * 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 Andy Moody
 */
public class ReflectionUtil
{
	private static final Logger logger = Logger.getLogger(ReflectionUtil.class);
	static int PUBLIC_STATIC_MODS = createMods(Modifier.PUBLIC, Modifier.STATIC);
	static int PUBLIC_STATIC_FINAL_MODS = createMods(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL);
	private static Map, Method[]> methodsCache = new HashMap, Method[]>();
	private static Map, Field[]> fieldsCache = new HashMap, Field[]>();


	public static Field[] getAllFields(Class clazz)
	{
		if(fieldsCache.containsKey(clazz))
		{
			return fieldsCache.get(clazz);
		}

		Field[] fields = new Field[0];
		if(clazz != null && clazz != Object.class)
		{
			fields = CollectionUtil.addTo(fields, clazz.getDeclaredFields());
			fields = CollectionUtil.addTo(fields, getAllFields(clazz.getSuperclass()));
		}

		fieldsCache.put(clazz, fields);
		return fields;
	}

	public static Method[] getAllMethods(final Class clazz)
	{
		if(methodsCache.containsKey(clazz))
		{
			return methodsCache.get(clazz);
		}

		Method[] methods = new Method[0];
		if(clazz != null && clazz != Object.class)
		{
			methods = CollectionUtil.addTo(methods, clazz.getDeclaredMethods());
			methods = CollectionUtil.addTo(methods, getAllMethods(clazz.getSuperclass()));
		}

		methodsCache.put(clazz, methods);
		return methods;
	}

	public static Object getValue(Field field, Object source)
	{
		try
		{
			field.setAccessible(true);
			return field.get(source);
		}
		catch(Exception e)
		{
			throw new RuntimeException("Unable to retrieve value for "+field.getName()+" from object "+source, e);
		}
	}

	public static Object getValue(Method method, Object source)
	{
		try
		{
			method.setAccessible(true);
			return method.invoke(source);
		}
		catch(Exception e)
		{
			throw new RuntimeException("Unable to retrieve value for "+method.getName()+" from object "+source, e);
		}
	}

	public static void setValue(final Field field, final Object value, final Object destination)
	{
		try
		{
			field.setAccessible(true);
			field.set(destination, value);
		}
		catch(Exception e)
		{
			throw new RuntimeException("Unable to set value "+value+" for "+field.getName()+" on object "+destination, e);
		}
	}

	public static void setValue(final Method method, final Object value, final Object destination)
	{
		try
		{
			method.setAccessible(true);
			method.invoke(destination, value);
		}
		catch(Exception e)
		{
			throw new RuntimeException("Unable to set value "+value+" for "+method.getName()+" on object "+destination, e);
		}
	}

	public static  Constructor getConstructor(final Class type, final Class... argTypes)
	{
		try
		{
			return type.getConstructor(argTypes);
		}
		catch(Exception e)
		{
			return null;
		}
	}

	public static  T createOrRetrieve(final Class clazz)
	{
		T toReturn = null;
		try
		{
			Constructor constructor = getConstructor(clazz);
			toReturn = constructor.newInstance();
		}
		catch (Exception e)
		{
			toReturn = getPublicStaticFieldOfType(clazz, clazz);
		}
		if(toReturn == null)
		{
			throw new IllegalStateException("Unable to instantiate " + clazz + " or retrieve public static field of the same type");
		}
		return toReturn;
	}

	private static  T getPublicStaticFieldOfType(final Class containingClass, final Class fieldType)
	{
		Field[] fields = getAllFields(containingClass);
		T value = null;
		for (Field field : fields)
		{
			if(field.getType().equals(fieldType) && (field.getModifiers() == PUBLIC_STATIC_FINAL_MODS || field.getModifiers() == PUBLIC_STATIC_MODS))
			{
				try
				{
					value = (T) field.get(containingClass);
				}
				catch (IllegalAccessException e)
				{
					throw new RuntimeException("Unable to retrieve value for public static field "+field.getName()+" from class "+containingClass, e);
				}
			}
		}
		return value;
	}

	private static int createMods(int...mods)
	{
		int base = 0x0;
		for (int mod : mods)
		{
			base = base |= mod;
		}
		return base;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy