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

org.databene.formats.script.ScriptUtil Maven / Gradle / Ivy

Go to download

'Databene Formats' is an open source software library for supporting data file and other formats like CSV, fixed width files, XLS, Properties and Regex. It is designed for multithreaded use and high performance.

There is a newer version: 1.0.14
Show newest version
/*
 * Copyright (C) 2011-2015 Volker Bergmann ([email protected]).
 * All rights reserved.
 *
 * 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 org.databene.formats.script;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;

import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;

import org.databene.commons.BeanUtil;
import org.databene.commons.ConfigurationError;
import org.databene.commons.Context;
import org.databene.commons.FileUtil;
import org.databene.commons.IOUtil;
import org.databene.commons.LogCategories;
import org.databene.commons.StringUtil;
import org.databene.formats.script.jsr223.Jsr223ScriptFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Utility class for scripting.
 * @since 0.3.0
 * @author Volker Bergmann
 */
public class ScriptUtil {
    
    private static final Logger CONFIG_LOGGER = LoggerFactory.getLogger(LogCategories.CONFIG);
    private static final Logger SCRIPTUTIL_LOGGER = LoggerFactory.getLogger(ScriptUtil.class);

    // extension mapping -----------------------------------------------------------------------------------------------
    
	private static String defaultScriptEngine = "ftl";

	private static Map factories;

    private static final String SETUP_FILE_NAME = "org/databene/formats/script/script.properties";

    static {
        parseConfigFile();
    }
    
    // utility methods -------------------------------------------------------------------------------------------------

    public static Object execute(Script script, Context context) {
    	return script.evaluate(context);
    }

    /*    
    public static void execute(String filename, Writer out,
            String variableName, Object variableValue) throws IOException,
            ScriptException {
        Context context = new DefaultContext();
        context.set(variableName, variableValue);
        execute(filename, context, out);
    }

    public static void execute(String filename, Context context, Writer out)
            throws IOException, ScriptException {
        Script script = getInstance(filename);
        script.execute(context, out);
    }

    public static void execute(String filename, Writer out,
            ScriptVariable... variables) throws IOException, ScriptException {
        Script script = getInstance(filename);
        Context context = new DefaultContext();
        for (ScriptVariable variable : variables)
            context.set(variable.getName(), variable.getValue());
        script.execute(context, out);
    }
*/

    public static Object evaluate(String text, Context context) {
    	String trimmedText = text.trim();
		if (trimmedText.startsWith("{{") && trimmedText.endsWith("}}"))
            return trimmedText.substring(1, trimmedText.length() - 1);
        else if (isScript(trimmedText)) {
            Script script = parseUnspecificText(text);
            return execute(script, context);
        } else
        	return text;
    }
    
	// static factory methods ------------------------------------------------------------------------------------------

    private static Map scriptsByName = new WeakHashMap();

    public static Script readFile(String uri) throws IOException {
        Script script = scriptsByName.get(uri);
        if (script == null) {
            String engineId = FileUtil.suffix(uri);
            ScriptFactory factory = getFactory(engineId, true);
            script = factory.readFile(uri);
            scriptsByName.put(uri, script);
        }
        return script;
    }

    public static Script parseUnspecificText(String text) {
        if (isScript(text))
        	return parseScriptText(text.substring(1, text.length() - 1), false);
        return new ConstantScript(text);
    }

	public static boolean isScript(String text) {
		if (StringUtil.isEmpty(text))
			return false;
		String trimmedText = text.trim();
	    return trimmedText.startsWith("{") && trimmedText.endsWith("}");
    }

    public static Script parseScriptText(String text) {
    	return parseScriptText(text, true);
    }

    public static Script parseScriptText(String text, boolean removeBrackets) {
    	if (text == null)
    		return null;
        if (removeBrackets && text.startsWith("{") && text.endsWith("}"))
        	text = text.substring(1, text.length() - 1);
        String[] tokens = StringUtil.splitOnFirstSeparator(text, ':');
        String engineId = tokens[0];
        if (getFactory(engineId, false) != null) {
            String scriptText = tokens[1];
            return parseScriptText(scriptText, engineId);
        } else
            return parseScriptText(text, ScriptUtil.getDefaultScriptEngine());
    }

    public static Script parseScriptText(String text, String engineId) {
        if (engineId == null)
            throw new IllegalArgumentException("engineId is null");
        ScriptFactory factory = getFactory(engineId, false);
        if (factory != null)
            return factory.parseText(text);
        else
            return new ConstantScript(text);
    }
    
    public static void addFactory(String name, ScriptFactory factory) {
	    factories.put(name, factory);
    }

	public static String getDefaultScriptEngine() {
		return defaultScriptEngine;
	}

	public static void setDefaultScriptEngine(String defaultScriptEngine) {
		if (factories.get(defaultScriptEngine) == null)
			throw new RuntimeException("Unknown script engine id: " + defaultScriptEngine);
		ScriptUtil.defaultScriptEngine = defaultScriptEngine;
	}
	
	public static String combineScriptableParts(String... parts) {
		String scriptEngine = getCommonScriptEngine(parts);
		boolean template = ("ftl".equals(scriptEngine));
		boolean language = (scriptEngine != null && !template);
		StringBuilder builder = new StringBuilder();
		for (int i = 0; i < parts.length; i++) {
			if (i > 0 && language)
				builder.append(" + ");
			String part = parts[i];
			ScriptDescriptor descriptor = new ScriptDescriptor(part);
			if (descriptor.level != ScriptLevel.NONE || !language) {
				builder.append(descriptor.text);
			} else
				builder.append("'").append(descriptor.text).append("'");	
		}
		if (scriptEngine != null) {
			builder.insert(0, '{');
			if (!ScriptUtil.getDefaultScriptEngine().equals(scriptEngine))
				builder.insert(1, scriptEngine + ":");
			builder.append('}');
		}
		return builder.toString();
	}

    // private helpers -------------------------------------------------------------------------------------------------
    
	static String getCommonScriptEngine(String... parts) {
	    ScriptDescriptor[] descriptors = describe(parts);
	    for (int i = 0; i < parts.length; i++)
	    	if (descriptors[i].scriptEngine != null)
	    		return descriptors[i].scriptEngine;
	    return null;
    }

	static ScriptDescriptor[] describe(String... parts) {
	    ScriptDescriptor[] descriptors = new ScriptDescriptor[parts.length];
	    for (int i = 0; i < parts.length; i++)
	    	descriptors[i] = new ScriptDescriptor(parts[i]);
	    return descriptors;
    }

	static ScriptFactory getFactory(String engineId, boolean required) {
		ScriptFactory factory = factories.get(engineId);
		if (factory == null && required)
			throw new ConfigurationError("Not a supported script engine: " + engineId);
		return factory;
	}
    
    private static void parseConfigFile() {
        String className = null;
        try {
            factories = new HashMap();
            
            try {
	            // check installed JSR 223 script engines
	            ScriptEngineManager mgr = new ScriptEngineManager();
	            for (ScriptEngineFactory engineFactory : mgr.getEngineFactories()) {
	        		Jsr223ScriptFactory factory = new Jsr223ScriptFactory(engineFactory.getScriptEngine());
	            	List names = engineFactory.getNames();
					for (String name : names)
						addFactory(name, factory);
	            }
            } catch (NoClassDefFoundError e) {
            	CONFIG_LOGGER.error("Java 6/JSR 223 script engines not available, deactivating script engine support.");
            }

            // read config file
            SCRIPTUTIL_LOGGER.debug("Initializing Script mapping from file " + SETUP_FILE_NAME);
            Map properties = IOUtil.readProperties(SETUP_FILE_NAME);
            for (Map.Entry entry : properties.entrySet()) {
                className = entry.getValue().toString();
                ScriptFactory factory = (ScriptFactory) BeanUtil.newInstance(className);
                addFactory(entry.getKey().toString(), factory);
            }
        } catch (FileNotFoundException e) {
            throw new ConfigurationError("Setup file not found: " + SETUP_FILE_NAME, e);
        } catch (IOException e) {
            throw new ConfigurationError("I/O Error while reading file: " + SETUP_FILE_NAME, e);
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy