All Downloads are FREE. Search and download functionalities are using the official Maven repository.

tech.greenfield.vertx.irked.Controller Maven / Gradle / Ivy

There is a newer version: 4.5.10
Show newest version
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();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy