package org.simpleflatmapper.reflect.impl;
import org.simpleflatmapper.reflect.Instantiator;
import org.simpleflatmapper.reflect.MethodGetterPair;
import org.simpleflatmapper.util.ErrorHelper;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public final class BuilderInstantiator<S, T> implements Instantiator<S, T> {
private final Instantiator<Void, ?> builderInstantiator;
private final MethodGetterPair<S>[] chainedArguments;
private final MethodGetterPair<S>[] unchainedArguments;
private final Method buildMethod;
public BuilderInstantiator(
Instantiator<Void, ?> builderInstantiator,
MethodGetterPair<S>[] chainedArguments,
MethodGetterPair<S>[] unchainedArguments,
Method buildMethod) {
this.builderInstantiator = builderInstantiator;
this.chainedArguments = chainedArguments;
this.unchainedArguments = unchainedArguments;
this.buildMethod = buildMethod;
}
@Override
@SuppressWarnings("unchecked")
public T newInstance(S s) throws Exception {
try {
Object builder = builderInstantiator.newInstance(null);
for (MethodGetterPair<S> argument : chainedArguments) {
builder = argument.getMethod().invoke(builder, argument.getGetter().get(s));
}
for (MethodGetterPair<S> argument : unchainedArguments) {
argument.getMethod().invoke(builder, argument.getGetter().get(s));
}
return (T) buildMethod.invoke(builder);
} catch (InvocationTargetException e) {
return ErrorHelper.rethrow(e.getCause());
}
}
}