/*
* Copyright 2011 Blazebit
*/
package com.blazebit.reflection;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* This class can be used to predefine a getter chain invocation but to be
* invoked later. It holds the source object on which to invoke the getter chain
* and the field names with which the getter methods are determined.
*
* @author Christian Beikov
* @since 0.1.2
*/
public class LazyGetterMethod {
private final Object source;
private final PropertyPathExpression<Object, Object> expression;
/**
* Constructs a LazyGetterMethod object for the given source object and
* field names as a string separated by '.' (dots). Using this constructor
* is equal to #
* {@link LazyGetterMethod#LazyGetterMethod(java.lang.Object, java.lang.String[]) }
* with the second parameter <code>fieldNames.split("\\.")</code>.
*
* @param source
* The object on which to invoke the first getter
* @param fieldNames
* The field names which should be used for the getter
* determination
*/
@SuppressWarnings("unchecked")
public LazyGetterMethod(Object source, String fieldNames) {
this.source = source;
this.expression = (PropertyPathExpression<Object, Object>) ExpressionUtils
.getExpression(source.getClass(), fieldNames);
}
/**
* Invokes the getter chain based on the source object. First the source
* object is used as invocation target for the first getter then the results
* of the previous operations will be used for the invocation.
*
* Example of how the chaining works:
*
* class A{ B getB(){ // return b element } }
*
* class B{ String getA(){ // return a element } }
*
* new LazyGetterMethod(new A(), "a.b").invoke()
*
* is equal to
*
* new A().getB().getA()
*
* @return The result of the last getter in the chain
* @throws InvocationTargetException
* {@link Method#invoke(java.lang.Object, java.lang.Object[]) }
* @throws IllegalAccessException
* {@link Method#invoke(java.lang.Object, java.lang.Object[]) }
*/
public Object invoke() throws InvocationTargetException,
IllegalAccessException {
return expression.getValue(source);
}
}