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

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

package org.simpleflatmapper.reflect;

import org.simpleflatmapper.reflect.asm.AsmFactory;
import org.simpleflatmapper.reflect.asm.AsmFactoryProvider;
import org.simpleflatmapper.reflect.getter.FieldGetter;
import org.simpleflatmapper.reflect.getter.MethodGetter;
import org.simpleflatmapper.reflect.getter.GetterHelper;
import org.simpleflatmapper.reflect.primitive.BooleanGetter;
import org.simpleflatmapper.reflect.primitive.BoxedBooleanGetter;
import org.simpleflatmapper.reflect.primitive.BoxedByteGetter;
import org.simpleflatmapper.reflect.primitive.BoxedCharacterGetter;
import org.simpleflatmapper.reflect.primitive.BoxedDoubleGetter;
import org.simpleflatmapper.reflect.primitive.BoxedFloatGetter;
import org.simpleflatmapper.reflect.primitive.BoxedIntGetter;
import org.simpleflatmapper.reflect.primitive.BoxedLongGetter;
import org.simpleflatmapper.reflect.primitive.BoxedShortGetter;
import org.simpleflatmapper.reflect.primitive.ByteGetter;
import org.simpleflatmapper.reflect.primitive.CharacterGetter;
import org.simpleflatmapper.reflect.primitive.DoubleGetter;
import org.simpleflatmapper.reflect.primitive.FloatGetter;
import org.simpleflatmapper.reflect.primitive.IntGetter;
import org.simpleflatmapper.reflect.primitive.LongGetter;
import org.simpleflatmapper.reflect.primitive.ShortGetter;

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

import static org.simpleflatmapper.util.Asserts.requireNonNull;


/**
 *
 */
public final class ObjectGetterFactory {
    private final AsmFactoryProvider asmFactory;

	public ObjectGetterFactory(AsmFactoryProvider asmFactory) {
        this.asmFactory = asmFactory;
    }
	

	public  Getter getGetter(final Class target, final String property) {
		// first look for method
		final Method method = lookForMethod(target, property);
		final Getter getter;
		if (method == null) {
            getter = getFieldGetter(target, property);
		} else {
            getter = getMethodGetter(method);
		}
		return getter;
	}

	public  Getter getMethodGetter(final Method method) {
		boolean accessible = Modifier.isPublic(method.getModifiers()) && Modifier.isPublic(method.getDeclaringClass().getModifiers());
		if (asmFactory != null && accessible) {
            try {
                return asmFactory.getAsmFactory(method.getDeclaringClass().getClassLoader()).createGetter(method);
            } catch(Throwable e) {
                // ignore
            }
        }
		if (!accessible) {
			try {
				method.setAccessible(true);
			} catch (Exception e) {
				// cannot make field accessible
				return null;
			}
		}
        return new MethodGetter(method);
	}

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

    public  Getter getFieldGetter(Field field) {
		requireNonNull("field", field);
		boolean accessible = Modifier.isPublic(field.getModifiers()) && Modifier.isPublic(field.getDeclaringClass().getModifiers());
		if (asmFactory != null && accessible) {
            try {
				AsmFactory asmFactory = this.asmFactory.getAsmFactory(field.getDeclaringClass().getClassLoader());
				if (asmFactory != null) {
					return asmFactory.createGetter(field);
				}
            } catch(Throwable e) {}
        }

        if (!accessible) {
        	try {
				field.setAccessible(true);
			} catch (Exception e) {
        		// cannot make field accessible
        		return null;
			}
        }
        return new FieldGetter(field);
    }

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

		for(Method m : target.getDeclaredMethods()) {
			if(GetterHelper.isPublicMember(m.getModifiers())
					&& GetterHelper.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(GetterHelper.fieldModifiersMatches(field.getModifiers())
					&& GetterHelper.fieldNameMatchesProperty(field.getName(), property)) {
				return field;
			}
		}
		
		return lookForField(target.getSuperclass(), property);
	}

	@SuppressWarnings("unchecked")
	public static  BooleanGetter toBooleanGetter(final Getter getter) {
		if (getter instanceof BooleanGetter) {
			return (BooleanGetter) getter;
		} else {
			return new BoxedBooleanGetter(getter);
		}
	}

	@SuppressWarnings("unchecked")
	public static  IntGetter toIntGetter(Getter getter) {
		if (getter instanceof IntGetter) {
			return (IntGetter) getter;
		} else {
			return new BoxedIntGetter(getter);
		}
	}

	@SuppressWarnings("unchecked")
	public static  LongGetter toLongGetter(Getter getter) {
		if (getter instanceof LongGetter) {
			return (LongGetter) getter;
		} else {
			return new BoxedLongGetter(getter);
		}
	}

	@SuppressWarnings("unchecked")
	public static  FloatGetter toFloatGetter(Getter getter) {
		if (getter instanceof FloatGetter) {
			return (FloatGetter) getter;
		} else {
			return new BoxedFloatGetter(getter);
		}
	}

	@SuppressWarnings("unchecked")
	public static  DoubleGetter toDoubleGetter(Getter getter) {
		if (getter instanceof DoubleGetter) {
			return (DoubleGetter) getter;
		} else {
			return new BoxedDoubleGetter(getter);
		}
	}

	@SuppressWarnings("unchecked")
	public static  ByteGetter toByteGetter(Getter getter) {
		if (getter instanceof ByteGetter) {
			return (ByteGetter) getter;
		} else {
			return new BoxedByteGetter(getter);
		}
	}

	@SuppressWarnings("unchecked")
	public static  ShortGetter toShortGetter(Getter getter) {
		if (getter instanceof ShortGetter) {
			return (ShortGetter) getter;
		} else {
			return new BoxedShortGetter(getter);
		}
	}

	@SuppressWarnings("unchecked")
	public static  CharacterGetter toCharGetter(Getter getter) {
		if (getter instanceof CharacterGetter) {
			return (CharacterGetter) getter;
		} else {
			return new BoxedCharacterGetter(getter);
		}
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy