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

com.ajjpj.asysmon.servlet.AbstractASysMonServlet Maven / Gradle / Ivy

There is a newer version: 1.0-pre28
Show newest version
package com.ajjpj.asysmon.servlet;

import com.ajjpj.abase.io.AJsonSerHelper;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;


/**
 * This servlet_ class serves static resources and dispatches RESTful service calls
 *
 * @author arno
 */
public abstract class AbstractASysMonServlet extends HttpServlet {
    public static final String ASYSMON_MARKER_SEGMENT = "/_$_asysmon_$_/";
    public static final String ASYSMON_MARKER_STATIC = ASYSMON_MARKER_SEGMENT + "static/";
    public static final String ASYSMON_MARKER_REST = ASYSMON_MARKER_SEGMENT + "rest/";

    @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        try {
            final String uri = req.getRequestURI();

            if(uri.contains(ASYSMON_MARKER_STATIC)) {
                serveStaticResource(substringAfter(uri, ASYSMON_MARKER_STATIC), resp);
                return;
            }

            if(uri.contains(ASYSMON_MARKER_REST)) {
                try {
                    final String[] restPart = substringAfter(uri, ASYSMON_MARKER_REST).split("/");
                    if(!handleRestCall(new ArrayList(Arrays.asList(restPart)), resp)) {
                        throw new IllegalArgumentException("unsupported REST call: " + uri);
                    }
                    return;
                }
                catch(Exception exc) {
                    try {
                        // special status code to indicate an exception that is reported as a JSON message
                        resp.setStatus(599);
                        writeExceptionToJson(new AJsonSerHelper(resp.getOutputStream()), exc);
                    }
                    catch(Exception e2) {
                        // throw the original exception if there is a problem in the special handling code
                        throw new ServletException(exc);
                    }
                }
            }

            if(uri.contains(ASYSMON_MARKER_SEGMENT)) {
                final String[] dynamicPart = substringAfter(uri, ASYSMON_MARKER_SEGMENT).split("/");
                if(! handleDynamic(new ArrayList(Arrays.asList(dynamicPart)), resp)) {
                    resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
                }
                return;
            }

            if(! uri.endsWith("/")) {
                resp.sendRedirect(uri + "/");
                return;
            }

            serveStaticResource(getDefaultHtmlName(), resp);
        }
        catch (RuntimeException exc) {
            throw exc;
        }
        catch (IOException exc) {
            throw exc;
        }
        catch (ServletException exc) {
            throw exc;
        }
        catch(Exception exc) {
            throw new ServletException(exc);
        }
    }

    private void writeExceptionToJson(AJsonSerHelper json, Exception exc) throws IOException {
        json.startObject();

        if(exc.getMessage() != null) {
            json.writeKey("msg");
            json.writeStringLiteral(exc.getMessage());
        }

        final StringWriter sw = new StringWriter();
        final PrintWriter pw = new PrintWriter(sw);
        exc.printStackTrace(pw);
        pw.close();

        json.writeKey("details");
        json.startArray();

        final BufferedReader br = new BufferedReader(new StringReader(sw.toString()));
        String line;
        while ((line = br.readLine()) != null) {
            json.writeStringLiteral(line);
        }

        json.endArray();

        json.endObject();
    }

    protected abstract String getDefaultHtmlName();
    protected abstract boolean handleRestCall(List pathSegments, HttpServletResponse resp) throws Exception;
    protected boolean handleDynamic(List pathSegments, HttpServletResponse resp) throws IOException {
        return false;
    }

    private static String substringAfter(String s, String sub) {
        final int idx = s.indexOf(sub);
        return s.substring(idx + sub.length());
    }

    private void serveStaticResource(String resName, HttpServletResponse resp) throws IOException {
        if(resName.contains("..") || resName.startsWith("/") || resName.contains("//")) {
            throw new IllegalArgumentException("rejected resource request '"  + resName + "' for security reasons");
        }

        if(getContentType(resName) != null) {
            resp.setContentType(getContentType(resName));
        }

        final InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("asysmon-res/" + resName);
        if(in == null) {
            resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
            return;
        }

        resp.addHeader("Cache-Control", "max-age=36000");

        final OutputStream out = resp.getOutputStream();

        final byte[] buf = new byte[4096];
        int numRead=0;
        while((numRead = in.read(buf)) > 0) {
            out.write(buf, 0, numRead);
        }
    }

    protected String getContentType(String resName) {
        if(resName.contains(".html")) {
            return "text/html";
        }

        return null;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy