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

org.simpleflatmapper.reflect.ObjectSetterFactory Maven / Gradle / Ivy

package org.simpleflatmapper.reflect;

import org.simpleflatmapper.reflect.asm.AsmFactoryProvider;
import org.simpleflatmapper.reflect.getter.FieldSetter;
import org.simpleflatmapper.reflect.setter.MethodSetter;
import org.simpleflatmapper.reflect.setter.NullSetter;
import org.simpleflatmapper.reflect.setter.SetterHelper;
import org.simpleflatmapper.reflect.primitive.BooleanFieldSetter;
import org.simpleflatmapper.reflect.primitive.BooleanMethodSetter;
import org.simpleflatmapper.reflect.primitive.BooleanSetter;
import org.simpleflatmapper.reflect.primitive.ByteFieldSetter;
import org.simpleflatmapper.reflect.primitive.ByteMethodSetter;
import org.simpleflatmapper.reflect.primitive.ByteSetter;
import org.simpleflatmapper.reflect.primitive.CharacterFieldSetter;
import org.simpleflatmapper.reflect.primitive.CharacterMethodSetter;
import org.simpleflatmapper.reflect.primitive.CharacterSetter;
import org.simpleflatmapper.reflect.primitive.DoubleFieldSetter;
import org.simpleflatmapper.reflect.primitive.DoubleMethodSetter;
import org.simpleflatmapper.reflect.primitive.DoubleSetter;
import org.simpleflatmapper.reflect.primitive.FloatFieldSetter;
import org.simpleflatmapper.reflect.primitive.FloatMethodSetter;
import org.simpleflatmapper.reflect.primitive.FloatSetter;
import org.simpleflatmapper.reflect.primitive.IntFieldSetter;
import org.simpleflatmapper.reflect.primitive.IntMethodSetter;
import org.simpleflatmapper.reflect.primitive.IntSetter;
import org.simpleflatmapper.reflect.primitive.LongFieldSetter;
import org.simpleflatmapper.reflect.primitive.LongMethodSetter;
import org.simpleflatmapper.reflect.primitive.LongSetter;
import org.simpleflatmapper.reflect.primitive.ShortFieldSetter;
import org.simpleflatmapper.reflect.primitive.ShortMethodSetter;
import org.simpleflatmapper.reflect.primitive.ShortSetter;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 *
 */
public final class ObjectSetterFactory {
	
	private final AsmFactoryProvider asmFactoryProvider;
	
	public ObjectSetterFactory(final AsmFactoryProvider asmFactoryProvider) {
		this.asmFactoryProvider = asmFactoryProvider;
	}

	public  Setter getSetter(final Class target, final String property) {
		// first look for method
		final Method method = lookForMethod(target, property);
		final Setter setter;
		if (method == null) {
			setter = getFieldSetter(target, property);
		} else {
			setter = getMethodSetter(method);
		}
		return setter;
	}

	public  Setter getMethodSetter(final Method method) {
		boolean accessible = Modifier.isPublic(method.getModifiers()) && Modifier.isPublic(method.getDeclaringClass().getModifiers());
		if (asmFactoryProvider != null && accessible) {
			try {
				return asmFactoryProvider.getAsmFactory(method.getDeclaringClass().getClassLoader()).createSetter(method);
			} catch(Throwable e) {
                // ignore
			}
		}
		if (!accessible) {
			try {
				method.setAccessible(true);
			} catch (Exception e) {
				// cannot make field accessible
				return null;
			}
		}
        return new MethodSetter(method);
	}

	public  Setter getFieldSetter(final Class target, final String property) {
		// look for field
		final Field field = lookForField(target, property);
		
		if (field != null) {
            return getFieldSetter(field);
		} else {
			return null;
		}
	}

    public  Setter getFieldSetter(Field field) {
		boolean accessible = Modifier.isPublic(field.getModifiers()) && Modifier.isPublic(field.getDeclaringClass().getModifiers());
		if (asmFactoryProvider != null && accessible) {
            try {
                return asmFactoryProvider.getAsmFactory(field.getDeclaringClass().getClassLoader()).createSetter(field);
            } catch(Throwable e) {
            }
        }
        if (!accessible) {
        	try {
				field.setAccessible(true);
			} catch (Exception e) {
				// cannot make field accessible
				return null;
			}
        }
        return new FieldSetter(field);
    }

    private Method lookForMethod(final Class target, final String property) {
        if (target == null)  return null;

		for(Method m : target.getDeclaredMethods()) {
			if(SetterHelper.isSetter(m)
					&& SetterHelper.methodNameMatchesProperty(m.getName(), property)) {
				return m;
			}
		}
		
		if (!Object.class.equals(target)) {
			return lookForMethod(target.getSuperclass(), property);
		}
		
		return null;
	}
	

	private Field lookForField(final Class target, final String property) {
        if (target == null)  return null;

		for(Field field : target.getDeclaredFields()) {
			if(SetterHelper.fieldModifiersMatches(field.getModifiers())
					&& SetterHelper.fieldNameMatchesProperty(field.getName(), property)) {
				return field;
			}
		}
		
		if (!Object.class.equals(target)) {
			return lookForField(target.getSuperclass(), property);
		}
		
		return null;
	}
	

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static  BooleanSetter toBooleanSetter(final Setter setter) {
		if (isNullSetter(setter)) {
			return null;
		} else if (setter instanceof BooleanSetter) {
			return (BooleanSetter) setter;
		} else if (setter instanceof MethodSetter) {
			return new BooleanMethodSetter(((MethodSetter) setter).getMethod());
		} else if (setter instanceof FieldSetter) {
			return new BooleanFieldSetter(((FieldSetter) setter).getField());
		} else {
			throw new IllegalArgumentException("Invalid type " + setter);
		}
	}

	private static boolean isNullSetter(Setter setter) {
		return NullSetter.isNull(setter);
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static  ByteSetter toByteSetter(final Setter setter) {
		if (isNullSetter(setter)) {
			return null;
		} else if (setter instanceof ByteSetter) {
			return (ByteSetter) setter;
		} else if (setter instanceof MethodSetter) {
			return new ByteMethodSetter(((MethodSetter) setter).getMethod());
		} else if (setter instanceof FieldSetter) {
			return new ByteFieldSetter(((FieldSetter) setter).getField());
		} else {
			throw new IllegalArgumentException("Invalid type " + setter);
		}
	}
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static  CharacterSetter toCharacterSetter(final Setter setter) {
		if (isNullSetter(setter)) {
			return null;
		} else if (setter instanceof CharacterSetter) {
			return (CharacterSetter) setter;
		} else if (setter instanceof MethodSetter) {
			return new CharacterMethodSetter(((MethodSetter) setter).getMethod());
		} else if (setter instanceof FieldSetter) {
			return new CharacterFieldSetter(((FieldSetter) setter).getField());
		} else {
			throw new IllegalArgumentException("Invalid type " + setter);
		}
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static  ShortSetter toShortSetter(final Setter setter) {
		if (isNullSetter(setter)) {
			return null;
		} else if (setter instanceof ShortSetter) {
			return (ShortSetter) setter;
		} else if (setter instanceof MethodSetter) {
			return new ShortMethodSetter(((MethodSetter) setter).getMethod());
		} else if (setter instanceof FieldSetter) {
			return new ShortFieldSetter(((FieldSetter) setter).getField());
		} else {
			throw new IllegalArgumentException("Invalid type " + setter);
		}
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static  IntSetter toIntSetter(final Setter setter) {
		if (isNullSetter(setter)) {
			return null;
		} else if (setter instanceof IntSetter) {
			return (IntSetter) setter;
		} else if (setter instanceof MethodSetter) {
			return new IntMethodSetter(((MethodSetter) setter).getMethod());
		} else if (setter instanceof FieldSetter) {
			return new IntFieldSetter(((FieldSetter) setter).getField());
		} else {
			throw new IllegalArgumentException("Invalid type " + setter);
		}
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static  LongSetter toLongSetter(final Setter setter) {
		if (isNullSetter(setter)) {
			return null;
		} else if (setter instanceof LongSetter) {
			return (LongSetter) setter;
		} else if (setter instanceof MethodSetter) {
			return new LongMethodSetter(((MethodSetter) setter).getMethod());
		} else if (setter instanceof FieldSetter) {
			return new LongFieldSetter(((FieldSetter) setter).getField());
		} else {
			throw new IllegalArgumentException("Invalid type " + setter);
		}
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static  FloatSetter toFloatSetter(final Setter setter) {
		if (isNullSetter(setter)) {
			return null;
		} else if (setter instanceof FloatSetter) {
			return (FloatSetter) setter;
		} else if (setter instanceof MethodSetter) {
			return new FloatMethodSetter(((MethodSetter) setter).getMethod());
		} else if (setter instanceof FieldSetter) {
			return new FloatFieldSetter(((FieldSetter) setter).getField());
		} else {
			throw new IllegalArgumentException("Invalid type " + setter);
		}
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static  DoubleSetter toDoubleSetter(final Setter setter) {
		if (isNullSetter(setter)) {
			return null;
		} else if (setter instanceof DoubleSetter) {
			return (DoubleSetter) setter;
		} else if (setter instanceof MethodSetter) {
			return new DoubleMethodSetter(((MethodSetter) setter).getMethod());
		} else if (setter instanceof FieldSetter) {
			return new DoubleFieldSetter(((FieldSetter) setter).getField());
		} else {
			throw new IllegalArgumentException("Invalid type " + setter);
		}
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy