diff --git a/.gitignore b/.gitignore index 5231862..a52a82d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .idea *.iml target +/env.bat diff --git a/src/main/java/fr/ybonnel/simpleweb4j/SimpleWeb4j.java b/src/main/java/fr/ybonnel/simpleweb4j/SimpleWeb4j.java index b97069a..2cd904e 100644 --- a/src/main/java/fr/ybonnel/simpleweb4j/SimpleWeb4j.java +++ b/src/main/java/fr/ybonnel/simpleweb4j/SimpleWeb4j.java @@ -28,6 +28,8 @@ import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.handler.AbstractHandler; +import java.io.IOException; +import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -240,6 +242,20 @@ public static void stop() { started = false; } + /** + * Adds the routes defined in the specified input stream. Each route is defined by a line with the following format: + * + * [HttpMethod] [ParamType] [routePath] [controllerMethod]\n + * + * @param inputStream Input that contains the route definitions. + * @throws NoSuchMethodException If the controller method does not exist. + * @throws IOException If an I/O error occurs + * @throws ClassNotFoundException In the controller class does not exist. + */ + public static void loadRoutes(InputStream inputStream) throws NoSuchMethodException, IOException, ClassNotFoundException { + jsonHandler.loadRoutes(inputStream); + } + /** * Add a new route for GET method. * Use : diff --git a/src/main/java/fr/ybonnel/simpleweb4j/handlers/JsonHandler.java b/src/main/java/fr/ybonnel/simpleweb4j/handlers/JsonHandler.java index d00c94b..57abb0e 100644 --- a/src/main/java/fr/ybonnel/simpleweb4j/handlers/JsonHandler.java +++ b/src/main/java/fr/ybonnel/simpleweb4j/handlers/JsonHandler.java @@ -22,14 +22,14 @@ import fr.ybonnel.simpleweb4j.exception.HttpErrorException; import fr.ybonnel.simpleweb4j.handlers.filter.AbstractFilter; import fr.ybonnel.simpleweb4j.model.SimpleEntityManager; +import fr.ybonnel.simpleweb4j.router.ControllerRoute; +import fr.ybonnel.simpleweb4j.util.StringUtils; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.handler.AbstractHandler; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; +import java.io.*; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Enumeration; @@ -62,6 +62,47 @@ public class JsonHandler extends AbstractHandler { */ private Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXX").create(); + /** + * + * @param inputStream + * @throws IOException + * @throws NoSuchMethodException + * @throws ClassNotFoundException + */ + public void loadRoutes(InputStream inputStream) throws IOException, NoSuchMethodException, ClassNotFoundException { + BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); + String line = null; + while ((line = reader.readLine()) != null){ + HttpMethod httpMethod = null; + Class> paramType = null; + String routePath = null; + String controller = null; + + // Read Http Method + line = line.trim(); + int firstBlankCharacterIndex = StringUtils.getIndexOfBlank(line); + httpMethod = HttpMethod.valueOf(line.substring(0, firstBlankCharacterIndex).toUpperCase()); + + // Read Parameter type + line = line.substring(firstBlankCharacterIndex).trim(); + firstBlankCharacterIndex = StringUtils.getIndexOfBlank(line); + paramType = Class.forName(line.substring(0, firstBlankCharacterIndex)); + + // Read route routePath + line = line.substring(firstBlankCharacterIndex).trim(); + firstBlankCharacterIndex = StringUtils.getIndexOfBlank(line); + routePath = line.substring(0, firstBlankCharacterIndex); + + // Read controller method + line = line.substring(firstBlankCharacterIndex).trim(); + controller = line; + + // Create and add route. + ControllerRoute,?> route = new ControllerRoute(routePath, paramType, controller); + addRoute(httpMethod, route); + } + + } /** * Add a route. * @param httpMethod http method of the route. diff --git a/src/main/java/fr/ybonnel/simpleweb4j/router/ControllerRoute.java b/src/main/java/fr/ybonnel/simpleweb4j/router/ControllerRoute.java new file mode 100644 index 0000000..b7118f8 --- /dev/null +++ b/src/main/java/fr/ybonnel/simpleweb4j/router/ControllerRoute.java @@ -0,0 +1,68 @@ +package fr.ybonnel.simpleweb4j.router; + +import fr.ybonnel.simpleweb4j.exception.HttpErrorException; +import fr.ybonnel.simpleweb4j.handlers.Response; +import fr.ybonnel.simpleweb4j.handlers.Route; +import fr.ybonnel.simpleweb4j.handlers.RouteParameters; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + */ +public class ControllerRoute
extends Route
{ + + /** Controller method. */ + private Method controllerMethod; + + /** + * Constructor of a route. + * + * @param routePath routePath of the route. + * @param paramType class of the object in request's body. + */ + public ControllerRoute(String routePath, Class
paramType, String controller) throws ClassNotFoundException, NoSuchMethodException {
+ super(routePath, paramType);
+
+ int lastDotIndex = controller.lastIndexOf(".");
+ if (lastDotIndex < 1) {
+ throw new IllegalArgumentException("Controller param is not a controller method.");
+ }
+ String controllerClassName = controller.substring(0, lastDotIndex);
+ String controllerMethodName = controller.substring(lastDotIndex + 1);
+
+ Class> controllerClass = Class.forName(controllerClassName);
+
+ if (Void.class.equals(paramType)) {
+ controllerMethod = controllerClass.getMethod(controllerMethodName, RouteParameters.class);
+ }
+ else {
+ controllerMethod = controllerClass.getMethod(controllerMethodName, paramType, RouteParameters.class);
+ }
+ }
+
+ /**
+ * Invokes the controller static method to compute the HTTP Response.
+ *
+ * @param param the parameter object in request's body.
+ * @param routeParams parameters in the routePath.
+ * @return The request response.
+ * @throws HttpErrorException If an error occured.
+ */
+ @Override
+ public Response> handle(Void param, RouteParameters routeParams) throws HttpErrorException {
- return new Response<>(Countries.list());
+ InputStream inputStream = null;
+ try {
+ inputStream = Forms.class.getResourceAsStream("/fr/ybonnel/simpleweb4j/samples/forms/routes");
+ loadRoutes(inputStream);
+ }
+ finally {
+ if (inputStream != null) {
+ try { inputStream.close(); }
+ catch (Exception e) { }
}
- });
+ }
start();
}
- public static void main(String[] args) {
+ public static void main(String[] args) throws Exception {
startServer(9999);
}
diff --git a/src/test/java/fr/ybonnel/simpleweb4j/samples/forms/controllers/CountryController.java b/src/test/java/fr/ybonnel/simpleweb4j/samples/forms/controllers/CountryController.java
new file mode 100644
index 0000000..8315fa9
--- /dev/null
+++ b/src/test/java/fr/ybonnel/simpleweb4j/samples/forms/controllers/CountryController.java
@@ -0,0 +1,16 @@
+package fr.ybonnel.simpleweb4j.samples.forms.controllers;
+
+import fr.ybonnel.simpleweb4j.handlers.Response;
+import fr.ybonnel.simpleweb4j.handlers.RouteParameters;
+import fr.ybonnel.simpleweb4j.samples.forms.model.Countries;
+
+import java.util.List;
+
+/**
+ */
+public class CountryController {
+
+ public static List