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

com.predic8.membrane.core.interceptor.javascript.JavascriptInterceptor Maven / Gradle / Ivy

There is a newer version: 5.6.0
Show newest version
/*
 * Copyright 2016 predic8 GmbH, www.predic8.com
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *    http://www.apache.org/licenses/LICENSE-2.0
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.predic8.membrane.core.interceptor.javascript;

import com.google.common.base.Function;
import com.predic8.membrane.annot.MCElement;
import com.predic8.membrane.annot.MCTextContent;
import com.predic8.membrane.core.exchange.Exchange;
import com.predic8.membrane.core.http.Request;
import com.predic8.membrane.core.http.Response;
import com.predic8.membrane.core.interceptor.AbstractInterceptor;
import com.predic8.membrane.core.interceptor.Outcome;
import com.predic8.membrane.core.lang.javascript.JavascriptLanguageSupport;
import com.predic8.membrane.core.util.ClassFinder;
import com.predic8.membrane.core.util.TextUtil;
import org.apache.commons.lang.StringEscapeUtils;

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.*;

@MCElement(name = "javascript", mixed = true)
public class JavascriptInterceptor extends AbstractInterceptor {

    private String src = "";

    private Function, Object> script;
    private JavascriptLanguageSupport jls;
    private HashMap implicitClasses;

    public JavascriptInterceptor() {
        name = "Javascript";
    }

    @Override
    public Outcome handleRequest(Exchange exc) throws Exception {
        return runScript(exc, Flow.REQUEST);
    }

    @Override
    public Outcome handleResponse(Exchange exc) throws Exception {
        return runScript(exc, Flow.RESPONSE);
    }

    @Override
    public void handleAbort(Exchange exc) {
        try {
            runScript(exc, Flow.ABORT);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void init() throws IOException, ClassNotFoundException {
        if (router == null)
            return;
        if ("".equals(src))
            return;

        jls = new JavascriptLanguageSupport();
        implicitClasses = getJavascriptTypesForHttpClasses();
        script = jls.compileScript(router, src);

    }

    private Outcome runScript(Exchange exc, Flow flow) throws InterruptedException, IOException, ClassNotFoundException {
        HashMap parameters = new HashMap();
        parameters.put("exc", exc);
        parameters.put("flow", flow);
        parameters.put("spring", router.getBeanFactory());
        addOutcomeObjects(parameters);

        parameters.putAll(implicitClasses);
        Object res = script.apply(parameters);

        if (res instanceof Outcome) {
            return (Outcome) res;
        }

        if (res instanceof Response) {
            exc.setResponse((Response) res);
            return Outcome.RETURN;
        }

        if (res instanceof Request) {
            exc.setRequest((Request) res);
        }
        return Outcome.CONTINUE;

    }

    private HashMap getJavascriptTypesForHttpClasses() throws IOException, ClassNotFoundException {
        return getJavascriptTypesForClasses(getHttpPackageClasses());
    }

    private HashMap getJavascriptTypesForClasses(HashMap classes) {
        HashMap result = new HashMap<>();
        for(Object clazz : classes.values()){
            Class clazzz = (Class) clazz;
            String scriptSrc = clazzz.getSimpleName() + ".static;";
            //TODO this is hacky, do this differently ( maybe do this one time at startup )
            Object jsType = jls.compileScript(router, scriptSrc).apply(classes);

            result.put(clazzz.getSimpleName(),jsType);
        }
        return result;
    }

    private void addOutcomeObjects(HashMap parameters) {
        parameters.put("Outcome", Outcome.class);
        parameters.put("RETURN", Outcome.RETURN);
        parameters.put("CONTINUE", Outcome.CONTINUE);
        parameters.put("ABORT", Outcome.ABORT);
    }

    private HashMap getHttpPackageClasses() throws IOException, ClassNotFoundException {
        String httpPackage = "com.predic8.membrane.core.http";
        HashMap result = new HashMap<>();
        List> classes = ClassFinder.find(router.getBeanFactory().getClassLoader(), httpPackage);
        for(Class c : classes) {
            if(c.getPackage().getName().equals(httpPackage) && !c.getSimpleName().isEmpty())
                result.put(c.getSimpleName(), c);
        }
        return result;
    }

    public String getSrc() {
        return src;
    }

    @MCTextContent
    public void setSrc(String src) {
        this.src = src;
    }

    @Override
    public String getShortDescription() {
        return "Executes a Javascript script.";
    }

    @Override
    public String getLongDescription() {
        StringBuilder sb = new StringBuilder();
        sb.append(TextUtil.removeFinalChar(getShortDescription()));
        sb.append(":
");
        sb.append(StringEscapeUtils.escapeHtml(TextUtil.removeCommonLeadingIndentation(src)));
        sb.append("
"); return sb.toString(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy