2121import java .lang .reflect .Constructor ;
2222import java .lang .reflect .Field ;
2323import java .lang .reflect .Modifier ;
24+ import java .util .Arrays ;
2425import java .util .List ;
2526import java .util .Map ;
2627import java .util .Map .Entry ;
28+ import java .util .stream .Collectors ;
29+
30+ import javax .inject .Inject ;
2731
2832import org .jooby .Mutant ;
2933import org .jooby .Parser ;
4549public class BeanParser implements Parser {
4650
4751 @ Override
48- public Object parse (final TypeLiteral <?> type , final Context ctx ) throws Exception {
52+ public Object parse (final TypeLiteral <?> type , final Context ctx ) throws Throwable {
4953 Class <?> beanType = type .getRawType ();
5054 if (Primitives .isWrapperType (Primitives .wrap (beanType ))
5155 || CharSequence .class .isAssignableFrom (beanType )) {
@@ -69,17 +73,22 @@ public String toString() {
6973 }
7074
7175 private Object newBean (final Request req , final Response rsp ,
72- final Map <String , Mutant > params , final Class <?> beanType )
73- throws Exception {
76+ final Map <String , Mutant > params , final Class <?> beanType ) throws Throwable {
7477 ParameterNameProvider classInfo = req .require (ParameterNameProvider .class );
75- Constructor <?>[] constructors = beanType .getDeclaredConstructors ();
76- if (constructors .length > 1 ) {
78+ List <Constructor <?>> constructors = Arrays .asList (beanType .getDeclaredConstructors ()).stream ()
79+ .filter (c -> c .isAnnotationPresent (Inject .class ))
80+ .collect (Collectors .toList ());
81+ if (constructors .size () == 0 ) {
82+ // No inject annotation, use a declared constructor
83+ constructors .addAll (Arrays .asList (beanType .getDeclaredConstructors ()));
84+ }
85+ if (constructors .size () > 1 ) {
7786 return null ;
7887 }
7988 final Object bean ;
80- Constructor <?> constructor = constructors [ 0 ] ;
81- RequestParamProvider provider =
82- new RequestParamProviderImpl ( new RequestParamNameProviderImpl (classInfo ));
89+ Constructor <?> constructor = constructors . get ( 0 ) ;
90+ RequestParamProvider provider = new RequestParamProviderImpl (
91+ new RequestParamNameProviderImpl (classInfo ));
8392 List <RequestParam > parameters = provider .parameters (constructor );
8493 Object [] args = new Object [parameters .size ()];
8594 for (int i = 0 ; i < args .length ; i ++) {
@@ -100,9 +109,8 @@ private Object newBean(final Request req, final Response rsp,
100109 int mods = field .getModifiers ();
101110 if (!Modifier .isFinal (mods ) && !Modifier .isStatic (mods ) && !Modifier .isTransient (mods )) {
102111 // get
103- RequestParam fparam = new RequestParam (field );
104- @ SuppressWarnings ("unchecked" )
105- Object value = req .param (pname ).to (fparam .type );
112+ RequestParam fparam = new RequestParam (field , pname , field .getGenericType ());
113+ Object value = fparam .value (req , rsp );
106114
107115 // set
108116 field .setAccessible (true );
@@ -145,8 +153,7 @@ private Object newBeanInterface(final Request req, final Class<?> beanType) {
145153 return Reflection .newProxy (beanType , (proxy , method , args ) -> {
146154 StringBuilder name = new StringBuilder (method .getName ()
147155 .replace ("get" , "" )
148- .replace ("is" , "" )
149- );
156+ .replace ("is" , "" ));
150157 name .setCharAt (0 , Character .toLowerCase (name .charAt (0 )));
151158 return req .param (name .toString ()).to (TypeLiteral .get (method .getGenericReturnType ()));
152159 });
0 commit comments