com.collective.celos.WorkflowConfigurationParser.java Source code

Java tutorial

Introduction

Here is the source code for com.collective.celos.WorkflowConfigurationParser.java

Source

/*
 * Copyright 2015 Collective, Inc.
 *
 * 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.collective.celos;

import com.collective.celos.database.StateDatabaseConnection;
import com.google.common.collect.Maps;
import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.JavaScriptException;
import org.mozilla.javascript.tools.shell.Global;

import java.io.*;
import java.util.Collection;
import java.util.Map;

/**
 * Reads a set of JS files from a directory and creates a WorkflowConfiguration.
 * 
 * The JS engine has one variable defined, celosWorkflowConfigurationParser, which
 * points to the parser instance.
 * 
 * The helper script celos-scripts.js defines the utility function celos.defineWorkflow(object)
 * Reads a set of JS files from a directory and creates a WorkflowConfiguration.
 */
public class WorkflowConfigurationParser {

    public static final String WORKFLOW_FILE_EXTENSION = "js";

    private static final Logger LOGGER = Logger.getLogger(WorkflowConfigurationParser.class);
    private static final String CELOS_SCRIPTS_FILENAME = "celos-scripts.js";

    private final WorkflowConfiguration cfg = new WorkflowConfiguration();
    private final JSConfigParser jsConfigParser = new JSConfigParser();
    private final File defaultsDir;
    private final Map<String, String> additionalJsVariables;

    public WorkflowConfigurationParser(File defaultsDir, Map<String, String> additionalJsVariables)
            throws Exception {
        this.defaultsDir = Util.requireNonNull(defaultsDir);
        this.additionalJsVariables = additionalJsVariables;
    }

    public WorkflowConfigurationParser parseConfiguration(File workflowsDir, StateDatabaseConnection connection) {
        LOGGER.info("Using workflows directory: " + workflowsDir);
        LOGGER.info("Using defaults directory: " + defaultsDir);
        Collection<File> files = FileUtils.listFiles(workflowsDir, new String[] { WORKFLOW_FILE_EXTENSION }, false);
        for (File f : files) {
            try {
                parseFile(f, connection);
            } catch (Exception e) {
                LOGGER.error("Failed to load file: " + f + ": " + e.getMessage(), e);
            }
        }
        return this;
    }

    void parseFile(File f, StateDatabaseConnection connection) throws Exception {
        LOGGER.info("Loading file: " + f);
        FileReader fileReader = new FileReader(f);
        String fileName = f.toString();
        evaluateReader(fileReader, fileName, connection);
    }

    Object evaluateReader(Reader r, String fileName, StateDatabaseConnection connection) throws Exception {

        Global scope = jsConfigParser.createGlobalScope();

        Object wrappedThis = Context.javaToJS(this, scope);
        Map jsProperties = Maps.newHashMap(additionalJsVariables);
        jsProperties.put("celosWorkflowConfigurationParser", wrappedThis);
        jsProperties.put("celosConnection", connection);

        jsConfigParser.putPropertiesInScope(jsProperties, scope);

        InputStream scripts = WorkflowConfigurationParser.class.getResourceAsStream(CELOS_SCRIPTS_FILENAME);
        jsConfigParser.evaluateReader(scope, new InputStreamReader(scripts), CELOS_SCRIPTS_FILENAME);

        return jsConfigParser.evaluateReader(scope, r, fileName);
    }

    public WorkflowConfiguration getWorkflowConfiguration() {
        return cfg;
    }

    public void importDefaultsIntoScope(String label, Global scope) throws IOException {
        File defaultsFile = new File(defaultsDir, label + "." + WORKFLOW_FILE_EXTENSION);
        LOGGER.info("Loading defaults: " + defaultsFile);
        FileReader fileReader = new FileReader(defaultsFile);
        String fileName = defaultsFile.toString();
        jsConfigParser.evaluateReader(scope, fileReader, fileName);
    }

    public void addWorkflow(Workflow wf) {
        cfg.addWorkflow(wf);
    }

}