66package io .jooby ;
77
88import java .io .Serializable ;
9+ import java .lang .invoke .MethodHandle ;
10+ import java .lang .invoke .MethodHandles ;
11+ import java .lang .invoke .MethodType ;
912import java .lang .reflect .Method ;
1013import java .lang .reflect .Type ;
1114import java .util .ArrayList ;
@@ -370,12 +373,55 @@ public interface Handler extends Serializable, Aware {
370373 if (contentType == null ) {
371374 throw new UnsupportedMediaType (null );
372375 }
373- if (! ctx .getRoute ().getConsumes ().stream ().anyMatch (contentType ::matches )) {
376+ if (ctx .getRoute ().getConsumes ().stream ().noneMatch (contentType ::matches )) {
374377 throw new UnsupportedMediaType (contentType .getValue ());
375378 }
376379 }
377380 };
378381
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+
379425 /** Favicon handler as a silent 404 error. */
380426 public static final Handler FAVICON = ctx -> ctx .send (StatusCode .NOT_FOUND );
381427
@@ -423,7 +469,7 @@ public interface Handler extends Serializable, Aware {
423469
424470 private Boolean nonBlocking ;
425471
426- private Method mvcMethod ;
472+ private MvcMethod mvcMethod ;
427473
428474 private boolean httpHead ;
429475
@@ -655,7 +701,9 @@ public boolean isNonBlockingSet() {
655701 * Route return type.
656702 *
657703 * @return Return type.
704+ * @deprecated Marked for removal on 4.0
658705 */
706+ @ Deprecated
659707 public @ Nullable Type getReturnType () {
660708 return returnType ;
661709 }
@@ -665,7 +713,9 @@ public boolean isNonBlockingSet() {
665713 *
666714 * @param returnType Return type.
667715 * @return This route.
716+ * @deprecated Marked for removal on 4.0
668717 */
718+ @ Deprecated
669719 public @ NonNull Route setReturnType (@ Nullable Type returnType ) {
670720 this .returnType = returnType ;
671721 return this ;
@@ -1046,7 +1096,7 @@ public boolean isTransactional(boolean defaultValue) {
10461096 *
10471097 * @return Method for MVC/Controller. Not available for lambda routes.
10481098 */
1049- public @ Nullable Method getMvcMethod () {
1099+ public @ Nullable MvcMethod getMvcMethod () {
10501100 return mvcMethod ;
10511101 }
10521102
@@ -1056,7 +1106,7 @@ public boolean isTransactional(boolean defaultValue) {
10561106 * @param mvcMethod Mvc/controller method.
10571107 * @return This route
10581108 */
1059- public @ NonNull Route setMvcMethod (@ Nullable Method mvcMethod ) {
1109+ public @ NonNull Route setMvcMethod (@ Nullable MvcMethod mvcMethod ) {
10601110 this .mvcMethod = mvcMethod ;
10611111 return this ;
10621112 }
@@ -1067,7 +1117,7 @@ public boolean isTransactional(boolean defaultValue) {
10671117 * @param mvcMethod Mvc/controller method.
10681118 * @return This route
10691119 */
1070- public @ NonNull Route mvcMethod (@ Nullable Method mvcMethod ) {
1120+ public @ NonNull Route mvcMethod (@ Nullable MvcMethod mvcMethod ) {
10711121 return setMvcMethod (mvcMethod );
10721122 }
10731123
0 commit comments