tech.greenfield.vertx.irked.Controller Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of irked-vertx Show documentation
Show all versions of irked-vertx Show documentation
Opinionated framework for vertx-web route configuration and dispatch
package tech.greenfield.vertx.irked;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import io.vertx.core.Handler;
import io.vertx.ext.web.RoutingContext;
import tech.greenfield.vertx.irked.exceptions.InvalidRouteConfiguration;
import tech.greenfield.vertx.irked.websocket.WebSocketMessage;
public class Controller {
protected interface RawVertxHandler extends Handler {}
protected interface WebHandler extends Handler {}
protected interface MessageHandler extends Handler {}
private List routes;
/**
* Controller implementations should override this to generate local
* request implementation (wrapped routing contexts).
*
* The default implementation just returns the passes request wrapper
* @param request Top level request wrapper generated by Irked
* @return Implementation of a sub-context request
*/
protected Request getRequestContext(Request request) {
return request;
}
/**
* Helper method for {@link Router} to discover routing endpoints
* @return list of fields that are routing endpoints
* @throws InvalidRouteConfiguration If one of the declared and annotated routes is invalid
*/
List getRoutes() throws InvalidRouteConfiguration {
ArrayList out = new ArrayList<>();
for (Field f : getClass().getDeclaredFields())
out.add(RouteConfiguration.wrap(this, f));
for (Method m : getClass().getDeclaredMethods())
out.add(RouteConfiguration.wrap(this, m));
return routes = out.stream().filter(RouteConfiguration::isValid).collect(Collectors.toList());
}
/**
* Helper method for {@link Router} to create the appropriate request
* handler for Vert.X
* @param field routing endpoint handler exposed by this controller
* @return a handler that takes a Vert.x original routing context and
* wraps it in a local request context before delegating to the routing endpoint
*/
@SuppressWarnings("unchecked")
Handler getHandler(Field field) {
try {
field.setAccessible(true);
if (Handler.class.isAssignableFrom(field.getType()))
return (Handler)field.get(this);
return null;
} catch (IllegalArgumentException | IllegalAccessException e) {
// shouldn't happen
throw new RuntimeException("Error accessing field " + field + ": " + e, e);
}
}
/**
* Helper method for {@link Router} to mount sub-controllers
* @param field routing endpoint exposed by this controller
* @return Controller instance if the routing endpoint is a sub-controller,
* null otherwise
*/
Controller getController(Field field) {
try {
field.setAccessible(true);
if (Controller.class.isAssignableFrom(field.getType()))
return (Controller)field.get(this);
return null;
} catch (IllegalArgumentException | IllegalAccessException e) {
// shouldn't happen
throw new RuntimeException("Error accessing field " + field + ": " + e, e);
}
}
public void remove() {
routes.forEach(RouteConfiguration::remove);
}
@Override
public String toString() {
return getClass().getSimpleName();
}
}