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

com.github.gkutiel.flip.web.DynamicContentHandler Maven / Gradle / Ivy

package com.github.gkutiel.flip.web;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;

import com.github.gkutiel.flip.utils.Utils;
import com.github.gkutiel.flip.web.Flipper.RedirectException;

class DynamicContentHandler extends AbstractHandler {

	private static abstract class ResultSender {
		static ResultSender create(final Object result) {
			if (result instanceof byte[]) return new ResultSender() {

				@Override
				void send(final HttpServletResponse res, final MethodInvoker methodInvoker, final Formatter formatter) {
					try {
						res.setContentType(methodInvoker.getMimeType());
						final ServletOutputStream outputStream = res.getOutputStream();
						outputStream.write((byte[]) result);
						outputStream.close();
					} catch (final IOException e) {
						throw new RuntimeException(e);
					}
				}

			};
			return new ResultSender() {

				@Override
				void send(final HttpServletResponse res, final MethodInvoker methodInvoker, final Formatter formatter) {
					try {
						res.setCharacterEncoding("UTF-8");
						res.setContentType(formatter.mimeType());
						final PrintWriter writer = res.getWriter();
						writer.println(formatter.format(result, methodInvoker.getXsl()));
						writer.close();
					} catch (final IOException e) {
						throw new RuntimeException(e);
					}
				}

			};
		}

		abstract void send(final HttpServletResponse res, final MethodInvoker methodInvoker, final Formatter formatter);
	}

	private static final Logger LOGGER = Logger.getLogger(DynamicContentHandler.class.getCanonicalName());

	private final Map> catchAll = new HashMap<>();

	private final MethodInvokerFinder[] METHOD_FINDERS = new MethodInvokerFinder[] { 
//@formatter:off
			new MethodInvokerFinder.DefaultFinder(), 
			new MethodInvokerFinder.CatchAllFinder(Collections.unmodifiableMap(this.catchAll)) 
//@formatter:on
	};

	void catchAll(final String prefix, final Class clazz) {
		if (!prefix.startsWith("/") || !prefix.endsWith("/")) throw new IllegalArgumentException("prefix must start and ends with a '/'");
		this.catchAll.put(prefix, clazz);
	}

	private Formatter formmaterFromPath(final String path) {
		return path.endsWith("j") ? Formatter.JSON : Formatter.XML;
	}

	private MethodInvoker getMethodInvoker(final HttpServletRequest req, final HttpServletResponse res) {
		for (final MethodInvokerFinder finder : this.METHOD_FINDERS) {
			final MethodInvoker methodInvoker = finder.find(req, res);
			if (methodInvoker != null) return methodInvoker;
		}
		return null;
	}

	@Override
	public void handle(final String target, final Request baseRequest, final HttpServletRequest req, final HttpServletResponse res) throws ServletException {
		try {
			final MethodInvoker methodInvoker = this.getMethodInvoker(req, res);
			if (methodInvoker == null) {
				baseRequest.setHandled(false);
				return;
			}
			final Object result = methodInvoker.invoke(req, res);

			final Formatter formatter = this.formmaterFromPath(Utils.Strings.emptyIfNull(req.getPathInfo()));

			ResultSender.create(result).send(res, methodInvoker, formatter);
			baseRequest.setHandled(true);
		} catch (final RedirectException e) {
			LOGGER.info("REDIRECTING: " + e.getMessage());
		} catch (final Exception e) {
			throw new ServletException(e.getCause());
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy