package com.lexicalscope.fluentreflection; import static ch.lambdaj.Lambda.convert; import static com.lexicalscope.fluentreflection.Visibility.visibilityFromModifiers; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.List; import com.google.inject.TypeLiteral; final class FluentConstructorImpl<T> extends AbstractFluentAnnotated implements FluentConstructor<T> { private final ReflectedTypeFactory reflectedTypeFactory; private final TypeLiteral<T> typeLiteral; private final Constructor<T> constructor; public FluentConstructorImpl( final ReflectedTypeFactory reflectedTypeFactory, final TypeLiteral<T> typeLiteral, final Constructor<T> constructor) { super(reflectedTypeFactory, constructor); this.reflectedTypeFactory = reflectedTypeFactory; this.typeLiteral = typeLiteral; this.constructor = constructor; } @Override public int argCount() { return constructor.getParameterTypes().length; } @Override public List<FluentClass<?>> args() { return convert( typeLiteral.getParameterTypes(constructor), new ConvertTypeLiteralToReflectedType(reflectedTypeFactory)); } @Override public Constructor<T> member() { return constructor; } private T callRaw(final Object... args) { try { return constructor.newInstance(args); } catch (final InstantiationException e) { throw new InstantiationRuntimeException(e, constructor); } catch (final IllegalAccessException e) { throw new IllegalAccessRuntimeException(e, constructor); } catch (final InvocationTargetException e) { throw new InvocationTargetRuntimeException(e, constructor); } } @SuppressWarnings({ "unchecked", "rawtypes" }) @Override public FluentObject<T> call(final Object... args) { final Object object = callRaw(args); if(object == null) { return null; } return reflectedTypeFactory.reflect((Class) object.getClass(), object); } @Override public FluentClass<?> declarer() { return reflectedTypeFactory.reflect(typeLiteral); } @Override public String name() { return constructor.getName(); } @Override public String property() { return "<init>"; } @Override public FluentClass<?> type() { return declarer(); } @Override public Visibility visibility() { return visibilityFromModifiers(constructor.getModifiers()); } @Override public boolean isStatic() { return true; } @Override public boolean isFinal() { return false; } }