Package io.lumify.core.formula

Source Code of io.lumify.core.formula.FormulaEvaluator

package io.lumify.core.formula;

import com.google.inject.Inject;
import io.lumify.core.config.Configuration;
import io.lumify.core.exception.LumifyException;
import io.lumify.core.model.ontology.OntologyRepository;
import io.lumify.core.util.ClientApiConverter;
import io.lumify.core.util.LumifyLogger;
import io.lumify.core.util.LumifyLoggerFactory;
import io.lumify.web.clientapi.model.ClientApiOntology;
import io.lumify.web.clientapi.model.ClientApiVertex;
import io.lumify.web.clientapi.model.util.ObjectMapperFactory;
import org.apache.commons.io.IOUtils;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.securegraph.Authorizations;
import org.securegraph.Vertex;

import java.io.IOException;
import java.io.InputStream;
import java.util.Locale;

/**
* Not Thread Safe, Do not share instance across threads
*/
public class FormulaEvaluator {
    private static final LumifyLogger LOGGER = LumifyLoggerFactory.getLogger(FormulaEvaluator.class);
    private Configuration configuration;
    private OntologyRepository ontologyRepository;
    private Context context;
    private ScriptableObject scope;
    private Locale locale;
    private String timeZone;
    private boolean skipCloseWarning;

    @Inject
    public FormulaEvaluator(Configuration configuration, OntologyRepository ontologyRepository, Locale locale, String timeZone) {
        this.configuration = configuration;
        this.ontologyRepository = ontologyRepository;
        this.context = Context.enter();
        this.locale = locale == null ? Locale.getDefault() : locale;
        this.timeZone = timeZone;
        this.skipCloseWarning = false;

        setupContext();
        loadJavaScript();
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        if (!skipCloseWarning) {
            LOGGER.warn("close() method not called to clean up JavaScript Context");
            this.close();
        }
    }

    public void close() {
        context.exit();
        this.skipCloseWarning = true;
    }

    public String evaluateTitleFormula(Vertex vertex, String workspaceId, Authorizations authorizations) {
        return evaluateFormula("Title", vertex, workspaceId, authorizations);
    }

    public String evaluateTimeFormula(Vertex vertex, String workspaceId, Authorizations authorizations) {
        return evaluateFormula("Time", vertex, workspaceId, authorizations);
    }

    public String evaluateSubtitleFormula(Vertex vertex, String workspaceId, Authorizations authorizations) {
        return evaluateFormula("Subtitle", vertex, workspaceId, authorizations);
    }

    private String evaluateFormula(String type, Vertex vertex, String workspaceId, Authorizations authorizations) {
        String json = toJson(vertex, workspaceId, authorizations);

        Function f = (Function) scope.get("evaluate" + type + "FormulaJson", scope);
        Object result = f.call(context, scope, scope, new Object[]{json});

        return (String) Context.jsToJava(result, String.class);
    }

    private void setupContext() {
        context.setLanguageVersion(Context.VERSION_1_6);

        final RequireJsSupport browserSupport = new RequireJsSupport();

        this.scope = (ScriptableObject) context.initStandardObjects(browserSupport);

        try {
            scope.put("ONTOLOGY_JSON", scope, Context.toObject(getOntologyJson(), scope));
            scope.put("CONFIG_JSON", scope, Context.toObject(getConfigurationJson(), scope));
            scope.put("USERS_TIMEZONE", scope, Context.toObject(timeZone, scope));
        } catch (Exception e) {
            throw new LumifyException("Json resource not available", e);
        }

        String[] names = new String[] { "print", "load", "consoleWarn", "consoleError", "readFile" };
        browserSupport.defineFunctionProperties(names, scope.getClass(), ScriptableObject.DONTENUM);

        Scriptable argsObj = context.newArray(scope, new Object[]{});
        scope.defineProperty("arguments", argsObj, ScriptableObject.DONTENUM);
    }

    private void loadJavaScript() {
        evaluateFile("libs/underscore.js");
        evaluateFile("libs/r.js");
        evaluateFile("loader.js");
    }

    private String getOntologyJson() throws Exception {
        ClientApiOntology result = ontologyRepository.getClientApiObject();
        return ObjectMapperFactory.getInstance().writeValueAsString(result);
    }

    private String getConfigurationJson() throws Exception {
        return configuration.toJSON(this.locale).toString();
    }

    private Object evaluateFile(String filename) {
        InputStream is = FormulaEvaluator.class.getResourceAsStream(filename);
        if (is != null) {
            try {
                return context.evaluateString(scope, IOUtils.toString(is), filename, 0, null);
            } catch (IOException e) {
                LOGGER.error("File not readable %s", filename);
            }
        } else LOGGER.error("File not found %s", filename);
        return null;
    }

    private String toJson(Vertex vertex, String workspaceId, Authorizations authorizations) {
        ClientApiVertex v = ClientApiConverter.toClientApiVertex(vertex, workspaceId, authorizations);
        return v.toString();
    }
}
TOP

Related Classes of io.lumify.core.formula.FormulaEvaluator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.