| 49 | } |
| 50 | |
| 51 | public static int register(@NotNull HttpServer httpServer, @NotNull Class<?> handleClass) { |
| 52 | int n = 0; |
| 53 | var pathAnno = handleClass.getDeclaredAnnotation(Path.class); |
| 54 | var parentPath = pathAnno != null ? pathAnno.path() : ""; |
| 55 | if (parentPath == null) |
| 56 | parentPath = ""; |
| 57 | else if (!(parentPath = parentPath.trim()).isEmpty() && parentPath.charAt(0) != '/') { |
| 58 | throw new IllegalStateException("Http.register: path must be started with '/' in class: " |
| 59 | + handleClass.getName()); |
| 60 | } |
| 61 | |
| 62 | var lookup = Reflect.lookup; |
| 63 | for (var method : handleClass.getDeclaredMethods()) { |
| 64 | Annotation httpAnno = null; |
| 65 | for (var anno : method.getAnnotations()) { |
| 66 | var annoType = anno.annotationType(); |
| 67 | if (annoType == Get.class || annoType == Post.class) { |
| 68 | if (httpAnno != null) { |
| 69 | throw new IllegalStateException("Http.register: duplicated annotations in method: " |
| 70 | + method.getName() + " @ " + handleClass.getName()); |
| 71 | } |
| 72 | httpAnno = anno; |
| 73 | } |
| 74 | } |
| 75 | if (httpAnno == null) |
| 76 | continue; |
| 77 | if ((method.getModifiers() & (Modifier.PUBLIC | Modifier.STATIC)) != (Modifier.PUBLIC | Modifier.STATIC)) { |
| 78 | throw new IllegalStateException("Http.register: not public static method: " |
| 79 | + method.getName() + " @ " + handleClass.getName()); |
| 80 | } |
| 81 | if (method.getParameterCount() != 1 || method.getParameterTypes()[0] != HttpExchange.class) { |
| 82 | throw new IllegalStateException("Http.register: must be one HttpExchange parameter in method: " |
| 83 | + method.getName() + " @ " + handleClass.getName()); |
| 84 | } |
| 85 | |
| 86 | String path; |
| 87 | int maxContentLength; |
| 88 | TransactionLevel transactionLevel; |
| 89 | DispatchMode dispatchMode; |
| 90 | if (httpAnno.annotationType() == Get.class) { |
| 91 | var getAnno = (Get)httpAnno; |
| 92 | path = getAnno.path(); |
| 93 | maxContentLength = 0; |
| 94 | transactionLevel = getAnno.transactionLevel(); |
| 95 | dispatchMode = getAnno.dispatchMode(); |
| 96 | } else { // Post.class |
| 97 | var postAnno = (Post)httpAnno; |
| 98 | path = postAnno.path(); |
| 99 | maxContentLength = postAnno.maxContentLength(); |
| 100 | transactionLevel = postAnno.transactionLevel(); |
| 101 | dispatchMode = postAnno.dispatchMode(); |
| 102 | } |
| 103 | if (path == null || (path = path.trim()).isEmpty()) |
| 104 | path = '/' + method.getName(); |
| 105 | else if (path.charAt(0) != '/') { |
| 106 | throw new IllegalStateException("Http.register: path must be started with '/' in method: " |
| 107 | + method.getName() + " @ " + handleClass.getName()); |
| 108 | } |