/* * Copyright (c) 2009 Armando Blancas. All rights reserved. * * The use and distribution terms for this software are covered by the * Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) * which can be found in the file epl-v10.html at the root of this distribution. * * By using this software in any fashion, you are agreeing to be bound by * the terms of this license. * * You must not remove this notice, or any other, from this software. */ package clojure.contrib.jsr223; import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.script.ScriptEngine; import javax.script.ScriptEngineFactory; /** * Implementation of a {@code ScriptEngineFactory} for Clojure. * * @author Armando Blancas * @version 1.2 */ public class ClojureScriptEngineFactory implements ScriptEngineFactory { private ScriptEngine engine; private List<String> extensions; private List<String> names; private List<String> mimeTypes; /* * Default Constructor. * * Initializes the cached immutable lists and creates the local * engine used to return default settings. */ public ClojureScriptEngineFactory() { List<String> list = new ArrayList<String>(1); list.add("clj"); extensions = Collections.unmodifiableList(list); list = new ArrayList<String>(1); list.add("Clojure"); names = Collections.unmodifiableList(list); list = new ArrayList<String>(2); list.add("application/clojure"); list.add("text/clojure"); mimeTypes = Collections.unmodifiableList(list); engine = new ClojureScriptEngine(this); } /** * {@inheritDoc} * <p> * This method returns <i>Clojure Scripting Engine</i>. */ public String getEngineName() { return (String) engine.get(ScriptEngine.ENGINE); } /** * {@inheritDoc} * <p> * This method returns <i>1.2</i>. */ public String getEngineVersion() { return (String) engine.get(ScriptEngine.ENGINE_VERSION); } /** * {@inheritDoc} * <p> * This method returns a list with a single value <i>clj</i>. */ public List<String> getExtensions() { return extensions; } /** * {@inheritDoc} * <p> * This method returns <i>Clojure</i>. */ public String getLanguageName() { return (String) engine.get(ScriptEngine.LANGUAGE); } /** * {@inheritDoc} * <p> * This method returns <i>1.2</i>. */ public String getLanguageVersion() { return (String) engine.get(ScriptEngine.LANGUAGE_VERSION); } /** * {@inheritDoc} * Uses the recommended sugared shortcut for calling Java methods * in idiomatic Clojure: * <p> * {@code (.method object arg)} */ public String getMethodCallSyntax(String obj, String m, String... args) { if (obj == null) throw new NullPointerException("obj is null"); if (m == null) throw new NullPointerException("m is null"); StringBuilder b = new StringBuilder("(."); b.append(m).append(' ').append(obj); for (int i = 0; i < args.length; i++) b.append(' ').append(args[i]); b.append(')'); return b.toString(); } /** * {@inheritDoc} * <p> * This method returns a list with two values: * <pre> * application/clojure * text/clojure * </pre> */ public List<String> getMimeTypes() { return mimeTypes; } /** * {@inheritDoc} * <p> * This method returns a list with a single value <i>Clojure</i>. */ public List<String> getNames() { return names; } /** * {@inheritDoc} * Uses the {@code println} function with the argument inlined: * <p> * {@code (println "Now is the time")} */ public String getOutputStatement(String toDisplay) { if (toDisplay == null) throw new NullPointerException("toDisplay is null"); return "(println \"" + toDisplay + "\")"; } /** * {@inheritDoc} * <p> * The Clojure Scripting Engine supports these additional properties: * <p> * {@code clojure.source.path} Additional locations of Clojure source files, * to be appended to the value of "java.class.path". This is an optional * property and defaults to {@code null}. * <p> * {@code clojure.compile.path} The location for the generated .class files. * Defaults to {@code "classes"}. * <p> * {@code clojure.compile.warn-on-reflection} Whether to get a warning when Clojure will * use Java reflection. Defaults to {@code Boolean false}. */ public Object getParameter(String key) { return (String) engine.get(key); } /** * {@inheritDoc} * It prints a Clojure program as a list of statements, each in its own line: * <pre> * (foo...) * (bar...) * </pre> */ public String getProgram(String... statements) { StringBuilder b = new StringBuilder(); for (int i = 0; i < statements.length; i++) b.append(statements[i]).append('\n'); return b.toString(); } /** * {@inheritDoc} * <p> * It always returns a new instance of the Clojure script engine. The Clojure runtime * is the same for all engines, but keeping multiple engines can simplify usage if * each one will set different bindings and redirection. * <p> */ public ScriptEngine getScriptEngine() { return new ClojureScriptEngine(this); } }