6
6
package io .jooby ;
7
7
8
8
import java .io .Serializable ;
9
+ import java .lang .invoke .MethodHandle ;
10
+ import java .lang .invoke .MethodHandles ;
11
+ import java .lang .invoke .MethodType ;
9
12
import java .lang .reflect .Method ;
10
13
import java .lang .reflect .Type ;
11
14
import java .util .ArrayList ;
@@ -370,12 +373,55 @@ public interface Handler extends Serializable, Aware {
370
373
if (contentType == null ) {
371
374
throw new UnsupportedMediaType (null );
372
375
}
373
- if (! ctx .getRoute ().getConsumes ().stream ().anyMatch (contentType ::matches )) {
376
+ if (ctx .getRoute ().getConsumes ().stream ().noneMatch (contentType ::matches )) {
374
377
throw new UnsupportedMediaType (contentType .getValue ());
375
378
}
376
379
}
377
380
};
378
381
382
+ /**
383
+ * Carry metadata for mvc/controller method.
384
+ *
385
+ * @param declaringClass Controller class.
386
+ * @param name Method name.
387
+ * @param returnType Method return type.
388
+ * @param parameterTypes Method argument types.
389
+ */
390
+ public record MvcMethod (
391
+ @ NonNull Class <?> declaringClass ,
392
+ @ NonNull String name ,
393
+ @ NonNull Class <?> returnType ,
394
+ Class <?>... parameterTypes ) {
395
+
396
+ /**
397
+ * Convert to {@link java.lang.reflect.Method}.
398
+ *
399
+ * @return A {@link java.lang.reflect.Method}.
400
+ */
401
+ public Method toMethod () {
402
+ try {
403
+ return declaringClass .getDeclaredMethod (name , parameterTypes );
404
+ } catch (NoSuchMethodException e ) {
405
+ throw SneakyThrows .propagate (e );
406
+ }
407
+ }
408
+
409
+ /**
410
+ * Convert to {@link MethodHandle}.
411
+ *
412
+ * @return A {@link MethodHandle}.
413
+ */
414
+ public MethodHandle toMethodHandle () {
415
+ var lookup = MethodHandles .publicLookup ();
416
+ var methodType = MethodType .methodType (returnType , parameterTypes );
417
+ try {
418
+ return lookup .findVirtual (declaringClass , name , methodType );
419
+ } catch (NoSuchMethodException | IllegalAccessException e ) {
420
+ throw SneakyThrows .propagate (e );
421
+ }
422
+ }
423
+ }
424
+
379
425
/** Favicon handler as a silent 404 error. */
380
426
public static final Handler FAVICON = ctx -> ctx .send (StatusCode .NOT_FOUND );
381
427
@@ -423,7 +469,7 @@ public interface Handler extends Serializable, Aware {
423
469
424
470
private Boolean nonBlocking ;
425
471
426
- private Method mvcMethod ;
472
+ private MvcMethod mvcMethod ;
427
473
428
474
private boolean httpHead ;
429
475
@@ -655,7 +701,9 @@ public boolean isNonBlockingSet() {
655
701
* Route return type.
656
702
*
657
703
* @return Return type.
704
+ * @deprecated Marked for removal on 4.0
658
705
*/
706
+ @ Deprecated
659
707
public @ Nullable Type getReturnType () {
660
708
return returnType ;
661
709
}
@@ -665,7 +713,9 @@ public boolean isNonBlockingSet() {
665
713
*
666
714
* @param returnType Return type.
667
715
* @return This route.
716
+ * @deprecated Marked for removal on 4.0
668
717
*/
718
+ @ Deprecated
669
719
public @ NonNull Route setReturnType (@ Nullable Type returnType ) {
670
720
this .returnType = returnType ;
671
721
return this ;
@@ -1046,7 +1096,7 @@ public boolean isTransactional(boolean defaultValue) {
1046
1096
*
1047
1097
* @return Method for MVC/Controller. Not available for lambda routes.
1048
1098
*/
1049
- public @ Nullable Method getMvcMethod () {
1099
+ public @ Nullable MvcMethod getMvcMethod () {
1050
1100
return mvcMethod ;
1051
1101
}
1052
1102
@@ -1056,7 +1106,7 @@ public boolean isTransactional(boolean defaultValue) {
1056
1106
* @param mvcMethod Mvc/controller method.
1057
1107
* @return This route
1058
1108
*/
1059
- public @ NonNull Route setMvcMethod (@ Nullable Method mvcMethod ) {
1109
+ public @ NonNull Route setMvcMethod (@ Nullable MvcMethod mvcMethod ) {
1060
1110
this .mvcMethod = mvcMethod ;
1061
1111
return this ;
1062
1112
}
@@ -1067,7 +1117,7 @@ public boolean isTransactional(boolean defaultValue) {
1067
1117
* @param mvcMethod Mvc/controller method.
1068
1118
* @return This route
1069
1119
*/
1070
- public @ NonNull Route mvcMethod (@ Nullable Method mvcMethod ) {
1120
+ public @ NonNull Route mvcMethod (@ Nullable MvcMethod mvcMethod ) {
1071
1121
return setMvcMethod (mvcMethod );
1072
1122
}
1073
1123
0 commit comments