99import io .jooby .internal .MissingValue ;
1010import io .jooby .internal .SingleValue ;
1111import io .jooby .internal .UrlParser ;
12+ import io .jooby .internal .ValueConverters ;
13+ import io .jooby .internal .reflect .$Types ;
1214
1315import javax .annotation .Nonnull ;
1416import javax .annotation .Nullable ;
1719import java .io .InputStream ;
1820import java .io .OutputStream ;
1921import java .io .PrintWriter ;
22+ import java .lang .reflect .Type ;
2023import java .nio .channels .FileChannel ;
2124import java .nio .charset .Charset ;
2225import java .nio .charset .StandardCharsets ;
@@ -83,7 +86,7 @@ public interface DefaultContext extends Context {
8386 * @return Flash attribute.
8487 */
8588 @ Override default @ Nonnull Value flash (@ Nonnull String name ) {
86- return Value .create (name , flash ().get (name ));
89+ return Value .create (this , name , flash ().get (name ));
8790 }
8891
8992 @ Override default @ Nonnull Session session () {
@@ -121,26 +124,22 @@ public interface DefaultContext extends Context {
121124
122125 @ Override default @ Nonnull Value cookie (@ Nonnull String name ) {
123126 String value = cookieMap ().get (name );
124- return value == null ? Value .missing (name ) : Value .value (name , value );
127+ return value == null ? Value .missing (name ) : Value .value (this , name , value );
125128 }
126129
127130 @ Override @ Nonnull default Value path (@ Nonnull String name ) {
128131 String value = pathMap ().get (name );
129132 return value == null
130133 ? new MissingValue (name )
131- : new SingleValue (name , UrlParser .decodePathSegment (value ));
132- }
133-
134- @ Override @ Nonnull default <T > T path (@ Nonnull Reified <T > type ) {
135- return path ().to (type );
134+ : new SingleValue (this , name , UrlParser .decodePathSegment (value ));
136135 }
137136
138137 @ Override @ Nonnull default <T > T path (@ Nonnull Class <T > type ) {
139138 return path ().to (type );
140139 }
141140
142141 @ Override @ Nonnull default Value path () {
143- HashValue path = new HashValue (null );
142+ HashValue path = new HashValue (this , null );
144143 for (Map .Entry <String , String > entry : pathMap ().entrySet ()) {
145144 path .put (entry .getKey (), entry .getValue ());
146145 }
@@ -155,10 +154,6 @@ public interface DefaultContext extends Context {
155154 return query ().queryString ();
156155 }
157156
158- @ Override @ Nonnull default <T > T query (@ Nonnull Reified <T > type ) {
159- return query ().to (type );
160- }
161-
162157 @ Override @ Nonnull default <T > T query (@ Nonnull Class <T > type ) {
163158 return query ().to (type );
164159 }
@@ -244,10 +239,6 @@ public interface DefaultContext extends Context {
244239 return form ().get (name );
245240 }
246241
247- @ Override @ Nonnull default <T > T form (@ Nonnull Reified <T > type ) {
248- return form ().to (type );
249- }
250-
251242 @ Override @ Nonnull default <T > T form (@ Nonnull Class <T > type ) {
252243 return form ().to (type );
253244 }
@@ -256,10 +247,6 @@ public interface DefaultContext extends Context {
256247 return multipart ().get (name );
257248 }
258249
259- @ Override @ Nonnull default <T > T multipart (@ Nonnull Reified <T > type ) {
260- return multipart ().to (type );
261- }
262-
263250 @ Override @ Nonnull default <T > T multipart (@ Nonnull Class <T > type ) {
264251 return multipart ().to (type );
265252 }
@@ -307,24 +294,30 @@ public interface DefaultContext extends Context {
307294 throw new TypeMismatchException (name , FileUpload .class );
308295 }
309296
310- @ Override default @ Nonnull <T > T body (@ Nonnull Reified <T > type ) {
311- return body (type , getRequestType ( MediaType . text ) );
297+ @ Override default @ Nonnull <T > T body (@ Nonnull Class <T > type ) {
298+ return body (). to ( type );
312299 }
313300
314- @ Override default @ Nonnull <T > T body (@ Nonnull Reified <T > type , @ Nonnull MediaType contentType ) {
315- try {
316- return decoder (contentType ).decode (this , type .getType ());
317- } catch (Exception x ) {
318- throw SneakyThrows .propagate (x );
319- }
301+ @ Override default @ Nonnull <T > T body (@ Nonnull Type type ) {
302+ return body ().to (type );
320303 }
321304
322- @ Override default @ Nonnull <T > T body (@ Nonnull Class <T > type ) {
323- return body (type , getRequestType (MediaType .text ));
305+ @ Override default @ Nullable <T > T convert (Value value , Class <T > type ) {
306+ T result = ValueConverters .convert (value , type , getRouter ().getConverters ());
307+ if (result == null ) {
308+ throw new TypeMismatchException (value .name (), type );
309+ }
310+ return result ;
324311 }
325312
326- @ Override default @ Nonnull <T > T body (@ Nonnull Class < T > type , @ Nonnull MediaType contentType ) {
313+ @ Override default @ Nonnull <T > T decode (@ Nonnull Type type , @ Nonnull MediaType contentType ) {
327314 try {
315+ if (MediaType .text .equals (contentType )) {
316+ T result = ValueConverters .convert (body (), type , getRouter ().getConverters ());
317+ if (result != null ) {
318+ return result ;
319+ }
320+ }
328321 return decoder (contentType ).decode (this , type );
329322 } catch (Exception x ) {
330323 throw SneakyThrows .propagate (x );
0 commit comments