aboutsummaryrefslogtreecommitdiff
path: root/velocity-engine-scripting/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'velocity-engine-scripting/src/main')
-rw-r--r--velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityCompiledScript.java70
-rw-r--r--velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptEngine.java338
-rw-r--r--velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptEngineFactory.java231
-rw-r--r--velocity-engine-scripting/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory1
4 files changed, 640 insertions, 0 deletions
diff --git a/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityCompiledScript.java b/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityCompiledScript.java
new file mode 100644
index 00000000..f88eb803
--- /dev/null
+++ b/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityCompiledScript.java
@@ -0,0 +1,70 @@
+package org.apache.velocity.script;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+
+import javax.script.CompiledScript;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptException;
+import java.io.StringWriter;
+import java.io.Writer;
+
+public class VelocityCompiledScript extends CompiledScript
+{
+ protected VelocityScriptEngine engine;
+ protected Template template;
+
+ public VelocityCompiledScript(VelocityScriptEngine e, Template t)
+ {
+ engine = e;
+ template = t;
+ }
+
+ @Override
+ public Object eval(ScriptContext scriptContext) throws ScriptException
+ {
+ VelocityContext velocityContext = VelocityScriptEngine.getVelocityContext(scriptContext);
+ Writer out = scriptContext.getWriter();
+ if (out == null)
+ {
+ out = new StringWriter();
+ scriptContext.setWriter(out);
+ }
+ try
+ {
+ template.merge(velocityContext, out);
+ out.flush();
+ }
+ catch (Exception exp)
+ {
+ throw new ScriptException(exp);
+ }
+ return out;
+ }
+
+ @Override
+ public ScriptEngine getEngine()
+ {
+ return engine;
+ }
+}
diff --git a/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptEngine.java b/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptEngine.java
new file mode 100644
index 00000000..469ca45d
--- /dev/null
+++ b/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptEngine.java
@@ -0,0 +1,338 @@
+package org.apache.velocity.script;
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met: Redistributions of source code
+ * must retain the above copyright notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution. Neither the name of the Sun Microsystems nor the names of
+ * is contributors may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Main class for the Velocity script engine.
+ * All the variants of the eval() methods return the writer. The default writer is a PrintWriter towards System.out.
+ * To specify a specific writer, use getContext().setWriter(writer). To get a resulting string, pass a StringWriter.
+ *
+ * You can specify a pathname towards a Velocity properties file using the "org.apache.velocity.script.properties" key,
+ * either as a ScriptContext attribute, or as a System property.
+ *
+ * Example use:
+ * <pre>
+ * ScriptEngine vel = new VelocityScriptEngine();
+ * vel.getContext().setAttribute(VelocityScriptEngine.VELOCITY_PROPERTIES_KEY, "path/to/velocity.properties");
+ * vel.getContext().setWriter(new StringWriter());
+ * vel.put("foo","World");
+ * Object result = vel.eval("Hello $foo !");
+ * String helloWorld = result.toString()
+ * </pre>
+ *
+ * Please refer to the javax.script.ScriptEngine documentation for additional details.
+ *
+ * @author A. Sundararajan
+ * @author <a href="mailto:claude.brisson@gmail.com">Claude Brisson</a>
+ * @version $Id: VelocityScriptEngine.java$
+ */
+
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.exception.ResourceNotFoundException;
+import org.apache.velocity.runtime.RuntimeInstance;
+import org.apache.velocity.runtime.resource.loader.ResourceLoader;
+import org.apache.velocity.runtime.resource.loader.StringResourceLoader;
+
+import javax.script.AbstractScriptEngine;
+import javax.script.Bindings;
+import javax.script.Compilable;
+import javax.script.CompiledScript;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+import javax.script.ScriptException;
+import javax.script.SimpleBindings;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.Properties;
+
+public class VelocityScriptEngine extends AbstractScriptEngine implements Compilable
+{
+ /**
+ * Key used to provide this engine with the pathname of the Velocity properties file.
+ * This key is first searched in the ScriptContext attributes, then as a System property
+ */
+ public static final String VELOCITY_PROPERTIES_KEY = "org.apache.velocity.script.properties";
+
+ // my factory, may be null
+ private volatile ScriptEngineFactory factory;
+ private volatile RuntimeInstance velocityEngine;
+
+ /**
+ * constructs a new Velocity script engine, linked to the given factory
+ * @param factory
+ */
+ public VelocityScriptEngine(ScriptEngineFactory factory)
+ {
+ this.factory = factory;
+ }
+
+ /**
+ * constructs a new standalone Velocity script engine
+ */
+ public VelocityScriptEngine()
+ {
+ this(null);
+ }
+
+ /**
+ * get the internal Velocity RuntimeInstance
+ * @return the internal Velocity RuntimeInstance
+ */
+ protected RuntimeInstance getVelocityEngine()
+ {
+ return velocityEngine;
+ }
+
+ /**
+ * Evaluate the given script.
+ * If you wish to get a resulting string, call getContext().setWriter(new StringWriter()) then call toString()
+ * on the returned writer.
+ * @param str script source
+ * @param ctx script context
+ * @return the script context writer (by default a PrintWriter towards System.out)
+ * @throws ScriptException
+ */
+ @Override
+ public Object eval(String str, ScriptContext ctx)
+ throws ScriptException
+ {
+ return eval(new StringReader(str), ctx);
+ }
+
+ /**
+ * Evaluate the given script.
+ * If you wish to get a resulting string, call getContext().setWriter(new StringWriter()) then call toString()
+ * on the returned writer.
+ * @param reader script source reader
+ * @param ctx script context
+ * @return the script context writer (by default a PrintWriter towards System.out)
+ * @throws ScriptException
+ */
+ @Override
+ public Object eval(Reader reader, ScriptContext ctx)
+ throws ScriptException
+ {
+ initVelocityEngine(ctx);
+ String fileName = getFilename(ctx);
+ VelocityContext vctx = getVelocityContext(ctx);
+ Writer out = ctx.getWriter();
+ if (out == null)
+ {
+ out = new StringWriter();
+ ctx.setWriter(out);
+ }
+ try
+ {
+ velocityEngine.evaluate(vctx, out, fileName, reader);
+ out.flush();
+ }
+ catch (Exception exp)
+ {
+ throw new ScriptException(exp);
+ }
+ return out;
+ }
+
+ /**
+ * get the factory used to create this script engine
+ * @return factory
+ */
+ @Override
+ public ScriptEngineFactory getFactory()
+ {
+ if (factory == null)
+ {
+ synchronized (this)
+ {
+ if (factory == null)
+ {
+ factory = new VelocityScriptEngineFactory();
+ }
+ }
+ }
+ return factory;
+ }
+
+ /**
+ * creates a new Bindings to be used with this script
+ * @return new bindings
+ */
+ @Override
+ public Bindings createBindings()
+ {
+ return new SimpleBindings();
+ }
+
+ private void initVelocityEngine(ScriptContext ctx)
+ {
+ if (ctx == null)
+ {
+ ctx = getContext();
+ }
+ if (velocityEngine == null)
+ {
+ synchronized (this)
+ {
+ if (velocityEngine != null) return;
+
+ Properties props = getVelocityProperties(ctx);
+ RuntimeInstance tmpEngine = new RuntimeInstance();
+ try
+ {
+ if (props != null)
+ {
+ tmpEngine.init(props);
+ }
+ else
+ {
+ tmpEngine.init();
+ }
+ }
+ catch (RuntimeException rexp)
+ {
+ throw rexp;
+ }
+ catch (Exception exp)
+ {
+ throw new RuntimeException(exp);
+ }
+ velocityEngine = tmpEngine;
+ }
+ }
+ }
+
+ protected static VelocityContext getVelocityContext(ScriptContext ctx)
+ {
+ ctx.setAttribute("context", ctx, ScriptContext.ENGINE_SCOPE);
+ Bindings globalScope = ctx.getBindings(ScriptContext.GLOBAL_SCOPE);
+ Bindings engineScope = ctx.getBindings(ScriptContext.ENGINE_SCOPE);
+ if (globalScope != null)
+ {
+ return new VelocityContext(engineScope, new VelocityContext(globalScope));
+ }
+ else
+ {
+ return new VelocityContext(engineScope);
+ }
+ }
+
+ protected static String getFilename(ScriptContext ctx)
+ {
+ Object fileName = ctx.getAttribute(ScriptEngine.FILENAME);
+ return fileName != null? fileName.toString() : "<unknown>";
+ }
+
+ protected static Properties getVelocityProperties(ScriptContext ctx)
+ {
+ try
+ {
+ Object props = ctx.getAttribute(VELOCITY_PROPERTIES_KEY);
+ if (props instanceof Properties)
+ {
+ return (Properties) props;
+ }
+ else
+ {
+ String propsName = System.getProperty(VELOCITY_PROPERTIES_KEY);
+ if (propsName != null)
+ {
+ File propsFile = new File(propsName);
+ if (propsFile.exists() && propsFile.canRead())
+ {
+ Properties p = new Properties();
+ p.load(new FileInputStream(propsFile));
+ return p;
+ }
+ }
+ }
+ }
+ catch (Exception exp)
+ {
+ System.err.println(exp);
+ }
+ return null;
+ }
+
+ /**
+ * Compile a template
+ * @param script template source
+ * @return compiled template
+ * @throws ScriptException
+ */
+ @Override
+ public CompiledScript compile(String script) throws ScriptException
+ {
+ return compile(new StringReader(script));
+ }
+
+ /**
+ * Compile a template
+ * @param script template source
+ * @return compiled template
+ * @throws ScriptException
+ */
+ @Override
+ public CompiledScript compile(Reader script) throws ScriptException
+ {
+ initVelocityEngine(null);
+ ResourceLoader resourceLoader = new SingleResourceReader(script);
+ Template template = new Template();
+ template.setRuntimeServices(velocityEngine);
+ template.setResourceLoader(resourceLoader);
+ try
+ {
+ template.process();
+ }
+ catch(Exception e)
+ {
+ // CB TODO - exception may have line/col informations, that ScriptException can exploit
+ throw new ScriptException(e);
+ }
+ return new VelocityCompiledScript(this, template);
+ }
+
+ // a dummy resource reader class, serving a single resource given by the provided resource reader
+ protected static class SingleResourceReader extends StringResourceLoader
+ {
+ private Reader reader;
+
+ public SingleResourceReader(Reader r)
+ {
+ reader = r;
+ }
+
+ @Override
+ public Reader getResourceReader(String source, String encoding) throws ResourceNotFoundException
+ {
+ return reader;
+ }
+ }
+}
diff --git a/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptEngineFactory.java b/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptEngineFactory.java
new file mode 100644
index 00000000..7dd77fc1
--- /dev/null
+++ b/velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptEngineFactory.java
@@ -0,0 +1,231 @@
+package org.apache.velocity.script;
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met: Redistributions of source code
+ * must retain the above copyright notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution. Neither the name of the Sun Microsystems nor the names of
+ * is contributors may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Factory class for the Velocity scripting interface. Please refer to the
+ * javax.script.ScriptEngineFactory documentation for details.
+ *
+ * @author A. Sundararajan
+ * @author <a href="mailto:claude.brisson@gmail.com">Claude Brisson</a>
+ * @version $Id: VelocityScriptEngineFactory.java$
+ */
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.velocity.runtime.VelocityEngineVersion;
+
+public class VelocityScriptEngineFactory implements ScriptEngineFactory
+{
+
+ private static final String VELOCITY_NAME = "Velocity";
+ private static final String VELOCITY_VERSION = VelocityEngineVersion.VERSION;
+ private static final String VELOCITY_LANGUAGE = "VTL";
+
+ private static List<String> names;
+ private static List<String> extensions;
+ private static List<String> mimeTypes;
+
+ private static Properties parameters;
+
+ static
+ {
+ names = new ArrayList<>();
+ names.add("velocity");
+ names.add("Velocity");
+ names = Collections.unmodifiableList(names);
+ extensions = new ArrayList<>();
+ extensions.add("vm");
+ extensions.add("vtl");
+ extensions.add("vhtml");
+ extensions = Collections.unmodifiableList(extensions);
+ mimeTypes = new ArrayList<>();
+ mimeTypes.add("text/x-velocity");
+ mimeTypes = Collections.unmodifiableList(mimeTypes);
+ parameters = new Properties();
+ parameters.put(ScriptEngine.NAME, VELOCITY_NAME);
+ parameters.put(ScriptEngine.ENGINE_VERSION, VELOCITY_VERSION);
+ parameters.put(ScriptEngine.ENGINE, VELOCITY_NAME);
+ parameters.put(ScriptEngine.LANGUAGE, VELOCITY_LANGUAGE);
+ parameters.put(ScriptEngine.LANGUAGE_VERSION, VELOCITY_VERSION);
+ parameters.put("THREADING", "MULTITHREADED");
+ }
+
+ /**
+ * get engine name
+ * @return engine name, aka "Velocity"
+ */
+ @Override
+ public String getEngineName()
+ {
+ return VELOCITY_NAME;
+ }
+
+ /**
+ * get engine version
+ * @return engine version string
+ */
+ @Override
+ public String getEngineVersion()
+ {
+ return VELOCITY_VERSION;
+ }
+
+ /**
+ * get the list of file extensions handled by Velocity: vm, vtl, vhtml
+ * @return extensions list
+ */
+ @Override
+ public List<String> getExtensions()
+ {
+ return extensions;
+ }
+
+ /**
+ * get language name
+ * @return language name, aka "VTL"
+ */
+ @Override
+ public String getLanguageName()
+ {
+ return VELOCITY_NAME;
+ }
+
+ /**
+ * get language version (same as engine version)
+ * @return language version string
+ */
+ @Override
+ public String getLanguageVersion()
+ {
+ return VELOCITY_VERSION;
+ }
+
+ /**
+ * get Velocity syntax for calling method 'm' on object 'obj' with provided arguments
+ * @param obj
+ * @param m
+ * @param args
+ * @return VTL call ${obj.m(args...)}
+ */
+ @Override
+ public String getMethodCallSyntax(String obj, String m, String... args)
+ {
+ StringBuilder buf = new StringBuilder();
+ buf.append("${");
+ buf.append(obj);
+ buf.append(".");
+ buf.append(m);
+ buf.append("(");
+ if (args.length != 0)
+ {
+ int i = 0;
+ for (; i < args.length - 1; i++)
+ {
+ buf.append("$").append(args[i]);
+ buf.append(", ");
+ }
+ buf.append("$").append(args[i]);
+ }
+ buf.append(")}");
+ return buf.toString();
+ }
+
+ /**
+ * get the list of Velocity mime types
+ * @return singleton { 'text/x-velocity' }
+ */
+ @Override
+ public List<String> getMimeTypes()
+ {
+ return mimeTypes;
+ }
+
+ /**
+ * get the list of names
+ * @return { 'velocity', 'Velocity' }
+ */
+ @Override
+ public List<String> getNames()
+ {
+ return names;
+ }
+
+ /**
+ * get VTL expression used to display specified string
+ * @param toDisplay
+ * @return escaped string #[[toDisplay]]#
+ */
+ @Override
+ public String getOutputStatement(String toDisplay)
+ {
+ StringBuilder buf = new StringBuilder();
+ buf.append("#[[").append(toDisplay).append("]]#");
+ return buf.toString();
+ }
+
+ /**
+ * get engine parameter for provided key
+ * @param key
+ * @return found parameter, or null
+ */
+ @Override
+ public String getParameter(String key)
+ {
+ return parameters.getProperty(key);
+ }
+
+ /**
+ * get whole VTL program given VTL lines
+ * @param statements VTL lines
+ * @return lines concatenated with carriage returns
+ */
+ @Override
+ public String getProgram(String... statements)
+ {
+ StringBuilder buf = new StringBuilder();
+ for (String statement : statements)
+ {
+ buf.append(statement);
+ buf.append(System.lineSeparator());
+ }
+ return buf.toString();
+ }
+
+ /**
+ * get a Velocity script engine
+ * @return a new Velocity script engine
+ */
+ @Override
+ public ScriptEngine getScriptEngine()
+ {
+ return new VelocityScriptEngine(this);
+ }
+}
diff --git a/velocity-engine-scripting/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory b/velocity-engine-scripting/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory
new file mode 100644
index 00000000..0a4afb48
--- /dev/null
+++ b/velocity-engine-scripting/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory
@@ -0,0 +1 @@
+org.apache.velocity.script.VelocityScriptEngineFactory