-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathResourceRoute.java
More file actions
113 lines (88 loc) · 3.78 KB
/
ResourceRoute.java
File metadata and controls
113 lines (88 loc) · 3.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package JavaREST;
import JavaREST.Framework.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.*;
/**
* Author: Keith Jackson
* Date: 4/18/2016
* License: MIT
*
*/
public class ResourceRoute extends Route{
private Object handler;
public ResourceRoute(String uriPattern, Object handler) {
super(uriPattern);
this.handler = handler;
}
@Override
public boolean isMatch(HttpRequest request) {
return parser.isMatch(request.getUri().getRawPath());
}
@Override
public HttpResponse route(HttpRequest request) throws InternalServerErrorException, RouteNotFoundException {
Method method = getMethodWithAnnotatedVerb(request.getVerb(), handler);
if(method == null) throw new RouteNotFoundException();
int methodParameterCount = method.getParameterCount();
Parameter[] parameters = method.getParameters();
boolean injectRequest = methodParameterCount > 0 && parameters[0].getType().isAssignableFrom(HttpRequest.class);
if(injectRequest) methodParameterCount--;
if(methodParameterCount != parser.getVariableCount() ||
!method.getReturnType().isAssignableFrom(HttpResponse.class))
throw new InternalServerErrorException();
Map<String, String> args = parser.getVariableValues(request.getUri().getRawPath());
Map<Integer, String> order = new LinkedHashMap<>();
Map<String, Class<?>> argTypes = new LinkedHashMap<>();
int index = injectRequest ? 1 : 0;
for(String variable : args.keySet()) {
order.put(index, variable);
argTypes.put(variable, parameters[index].getType());
index++;
}
try {
Object[] realArgs = new Object[parameters.length];
for(int i = 0; i < realArgs.length; i++) {
String varName = order.get(i);
if(i == 0 && injectRequest) {
realArgs[i] = request;
} else {
realArgs[i] = toObject(argTypes.get(varName), args.get(varName));
}
}
return (HttpResponse)method.invoke(handler, realArgs);
} catch(IllegalAccessException|InvocationTargetException|NumberFormatException e) {
throw new InternalServerErrorException();
}
}
@Override
public boolean equals(Object o) {
try {
return isMatch((HttpRequest)o);
} catch(ClassCastException e) {
return false;
}
}
private static Method getMethodWithAnnotatedVerb(Verb verb, Object o) {
Class<?> klass = o.getClass();
while(klass != Object.class) {
for(Method method : klass.getDeclaredMethods()) {
if(method.isAnnotationPresent(HttpVerb.class) && method.getAnnotation(HttpVerb.class).value() == verb) {
return method;
}
}
klass = klass.getSuperclass();
}
return null;
}
private static Object toObject( Class clazz, String value ) {
if( Boolean.class == clazz || boolean.class == clazz ) return Boolean.parseBoolean( value );
if( Byte.class == clazz || byte.class == clazz) return Byte.parseByte( value );
if( Short.class == clazz || short.class == clazz) return Short.parseShort( value );
if( Integer.class == clazz || int.class == clazz) return Integer.parseInt( value );
if( Long.class == clazz || long.class == clazz) return Long.parseLong( value );
if( Float.class == clazz || float.class == clazz) return Float.parseFloat( value );
if( Double.class == clazz || double.class == clazz) return Double.parseDouble( value );
return value;
}
}