|
4 | 4 | import java.lang.annotation.Annotation; |
5 | 5 | import java.lang.reflect.AnnotatedElement; |
6 | 6 | import java.lang.reflect.Method; |
| 7 | +import java.lang.reflect.Modifier; |
7 | 8 | import java.util.ArrayList; |
8 | 9 | import java.util.Arrays; |
9 | 10 | import java.util.HashMap; |
|
12 | 13 | import java.util.Optional; |
13 | 14 | import java.util.Set; |
14 | 15 | import java.util.function.Function; |
15 | | -import java.util.stream.Collectors; |
16 | 16 |
|
17 | 17 | import jooby.MediaType; |
18 | 18 | import jooby.Mode; |
19 | 19 | import jooby.Route; |
20 | | -import jooby.internal.Reflection; |
| 20 | +import jooby.Route.Definition; |
21 | 21 | import jooby.mvc.Consumes; |
22 | 22 | import jooby.mvc.DELETE; |
23 | 23 | import jooby.mvc.GET; |
@@ -66,45 +66,52 @@ public static List<Route.Definition> routes(final Mode mode, final Class<?> rout |
66 | 66 |
|
67 | 67 | String rootPath = path(routeClass); |
68 | 68 |
|
69 | | - return Reflection |
70 | | - .methods(routeClass) |
| 69 | + Map<Method, List<Class<?>>> methods = new HashMap<>(); |
| 70 | + for (Method method : routeClass.getDeclaredMethods()) { |
| 71 | + List<Class<?>> annotations = new ArrayList<>(); |
| 72 | + for (Class annotationType : VERBS) { |
| 73 | + Annotation annotation = method.getAnnotation(annotationType); |
| 74 | + if (annotation != null) { |
| 75 | + annotations.add(annotationType); |
| 76 | + } |
| 77 | + } |
| 78 | + if (annotations.size() > 0) { |
| 79 | + if (!Modifier.isPublic(method.getModifiers())) { |
| 80 | + throw new IllegalArgumentException("Not a public method: " + method); |
| 81 | + } |
| 82 | + methods.put(method, annotations); |
| 83 | + } |
| 84 | + } |
| 85 | + |
| 86 | + List<Definition> definitions = new ArrayList<>(); |
| 87 | + |
| 88 | + methods |
| 89 | + .keySet() |
71 | 90 | .stream() |
72 | | - .filter( |
73 | | - m -> { |
74 | | - List<Annotation> annotations = new ArrayList<>(); |
75 | | - for (Class annotationType : VERBS) { |
76 | | - Annotation annotation = m.getAnnotation(annotationType); |
77 | | - if (annotation != null) { |
78 | | - annotations.add(annotation); |
79 | | - } |
80 | | - } |
81 | | - if (annotations.size() == 0) { |
82 | | - return false; |
83 | | - } |
84 | | - if (annotations.size() > 1) { |
85 | | - throw new IllegalStateException("A resource method: " + m |
86 | | - + " should have only one HTTP verb. Found: " |
87 | | - + annotations); |
88 | | - } |
89 | | - return true; |
90 | | - }) |
91 | 91 | .sorted((m1, m2) -> { |
92 | 92 | String k1 = key(m1); |
93 | 93 | String k2 = key(m2); |
94 | 94 | int l1 = lines.getOrDefault(k1, 0); |
95 | 95 | int l2 = lines.getOrDefault(k2, 0); |
96 | 96 | return l1 - l2; |
97 | 97 | }) |
98 | | - .map( |
99 | | - m -> { |
100 | | - String verb = verb(m); |
101 | | - String path = rootPath + "/" + path(m); |
102 | | - return new Route.Definition(verb, path, new MvcRoute(m, provider)) |
103 | | - .produces(produces(m)) |
104 | | - .consumes(consumes(m)) |
105 | | - .name(routeClass.getSimpleName() + "." + m.getName()); |
106 | | - }) |
107 | | - .collect(Collectors.toList()); |
| 98 | + .forEach( |
| 99 | + method -> { |
| 100 | + List<Class<?>> verbs = methods.get(method); |
| 101 | + String path = rootPath + "/" + path(method); |
| 102 | + String name = routeClass.getSimpleName() + "." + method.getName(); |
| 103 | + for (Class<?> verb : verbs) { |
| 104 | + Definition definition = new Route.Definition( |
| 105 | + verb.getSimpleName(), path, new MvcRoute(method, provider)) |
| 106 | + .produces(produces(method)) |
| 107 | + .consumes(consumes(method)) |
| 108 | + .name(name); |
| 109 | + |
| 110 | + definitions.add(definition); |
| 111 | + } |
| 112 | + }); |
| 113 | + |
| 114 | + return definitions; |
108 | 115 | } |
109 | 116 |
|
110 | 117 | private static String key(final Method method) { |
@@ -154,16 +161,6 @@ private static List<MediaType> consumes(final Method method) { |
154 | 161 | .orElse(ALL)); |
155 | 162 | } |
156 | 163 |
|
157 | | - @SuppressWarnings("unchecked") |
158 | | - private static String verb(final Method method) { |
159 | | - for (Class<?> annotation : VERBS) { |
160 | | - if (method.isAnnotationPresent((Class<? extends Annotation>) annotation)) { |
161 | | - return annotation.getSimpleName(); |
162 | | - } |
163 | | - } |
164 | | - throw new IllegalStateException("Couldn't find a HTTP annotation"); |
165 | | - } |
166 | | - |
167 | 164 | private static String path(final AnnotatedElement owner) { |
168 | 165 | Path annotation = owner.getAnnotation(Path.class); |
169 | 166 | if (annotation == null) { |
|
0 commit comments