[jboss-svn-commits] JBL Code SVN: r21360 - in labs/jbossesb/trunk/product: rosetta/src/org/jboss/soa/esb/actions/scripting and 1 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Tue Aug 5 07:04:16 EDT 2008


Author: kevin.conner at jboss.com
Date: 2008-08-05 07:04:16 -0400 (Tue, 05 Aug 2008)
New Revision: 21360

Added:
   labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/actions/scripting/ScriptingAction.java
   labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/actions/scripting/ScriptingActionUnitTest.java
   labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/actions/scripting/test.bsh
Modified:
   labs/jbossesb/trunk/product/docs/ProgrammersGuide.odt
Log:
Added scripting action: JBESB-1683

Modified: labs/jbossesb/trunk/product/docs/ProgrammersGuide.odt
===================================================================
(Binary files differ)

Added: labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/actions/scripting/ScriptingAction.java
===================================================================
--- labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/actions/scripting/ScriptingAction.java	                        (rev 0)
+++ labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/actions/scripting/ScriptingAction.java	2008-08-05 11:04:16 UTC (rev 21360)
@@ -0,0 +1,272 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, JBoss Inc., and others contributors as indicated 
+ * by the @authors tag. All rights reserved. 
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors. 
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A 
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * MA  02110-1301, USA.
+ * 
+ * (C) 2005-2007,
+ */
+
+package org.jboss.soa.esb.actions.scripting;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+import org.apache.bsf.BSFException;
+import org.apache.bsf.BSFManager;
+import org.apache.log4j.Logger;
+import org.jboss.internal.soa.esb.util.StreamUtils;
+import org.jboss.soa.esb.actions.AbstractActionPipelineProcessor;
+import org.jboss.soa.esb.actions.ActionLifecycleException;
+import org.jboss.soa.esb.actions.ActionProcessingException;
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.listeners.message.MessageDeliverException;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.message.MessagePayloadProxy;
+import org.jboss.soa.esb.util.ClassUtil;
+
+/**
+ * <a href="http://jakarta.apache.org/bsf/">BSF</a> Scripting action pipeline processor.
+ * <p/>
+ * Based on {@link GroovyActionProcessor} by Gregory Pierce and Tom Fennelly.
+ * <p>
+ * <pre>
+ * &lt;action name="helloWorld" class="org.jboss.soa.esb.actions.scripting.ScriptingAction"&gt;
+ *     &lt;property name="script" value="/scripts/helloWorld.bsh"/&gt;
+ *     &lt;-- The language property is not required; it is deduced via the script extension but can be overridden --&gt;
+ *     &lt;property name="language" value="beanshell"/&gt;
+ * &lt;/action&gt;
+ * </pre>
+ * </p>
+ * The {@link Message} is bound on the script under the name "message".
+ * The {@link ConfigTree} is bound under the name "config".
+ * The {@link MessagePayloadProxy} is bound under the name "payloadProxy".
+ * <p/>
+ * The script can also be supplied to this action as the message payload,
+ * allowing you to dynamically supply the action with a script.
+ * <p/>
+ * The following are the supported scripting languages, although the developer
+ * is responsible for including the appropriate 3rd party libraries (from bsf.jar's
+ * org/apache/bsf/Languages.properties):
+ * 
+ * <pre>
+ * # List of script types and their associated scripting engines
+ * #
+ * # languageDescriptor = engineClass, ext1|ext2|... {, codebaseURL, ...}
+ * #
+ * # where exti are extensions for the language. Note that we leave
+ * # all the engines enabled now and allow them to fail at load time.
+ * # This way engines can be added by just adding to the classpath
+ * # without having to edit this file. Cheating, really, but it works.
+ * #
+ * javascript = org.apache.bsf.engines.javascript.JavaScriptEngine, js
+ * jacl = org.apache.bsf.engines.jacl.JaclEngine, jacl
+ * netrexx = org.apache.bsf.engines.netrexx.NetRexxEngine, nrx
+ * java = org.apache.bsf.engines.java.JavaEngine, java
+ * javaclass = org.apache.bsf.engines.javaclass.JavaClassEngine, class
+ * bml = org.apache.bml.ext.BMLEngine, bml
+ * vbscript = org.apache.bsf.engines.activescript.ActiveScriptEngine, vbs
+ * jscript = org.apache.bsf.engines.activescript.ActiveScriptEngine, jss
+ * perlscript = org.apache.bsf.engines.activescript.ActiveScriptEngine, pls
+ * perl = org.apache.bsf.engines.perl.PerlEngine, pl
+ * jpython = org.apache.bsf.engines.jpython.JPythonEngine, py
+ * jython = org.apache.bsf.engines.jython.JythonEngine, py
+ * lotusscript = org.apache.bsf.engines.lotusscript.LsEngine, lss
+ * xslt = org.apache.bsf.engines.xslt.XSLTEngine, xslt
+ * pnuts = pnuts.ext.PnutsBSFEngine, pnut
+ * beanbasic = org.apache.bsf.engines.beanbasic.BeanBasicEngine, bb
+ * beanshell = bsh.util.BeanShellBSFEngine, bsh
+ * ruby = org.jruby.javasupport.bsf.JRubyEngine, rb
+ * judoscript = com.judoscript.BSFJudoEngine, judo|jud
+ * </pre>
+ *
+ * @author dward at jboss.org
+ */
+public class ScriptingAction extends AbstractActionPipelineProcessor
+{
+	
+	private static Logger logger = Logger.getLogger(ScriptingAction.class);
+	
+	private static final Map<String,String> LANGUAGES = new HashMap<String,String>();
+	
+	static
+	{
+		InputStream is = null;
+		try
+		{
+			is = BSFManager.class.getClassLoader().getResourceAsStream("org/apache/bsf/Languages.properties");
+			is = new BufferedInputStream(is);
+			Properties props = new Properties();
+			props.load(is);
+			for (Enumeration<?> names = props.propertyNames(); names.hasMoreElements();)
+			{
+				String lang = (String)names.nextElement();
+				StringTokenizer st = new StringTokenizer(props.getProperty(lang), ",");
+				st.nextToken(); // throw out the engine class name
+				st = new StringTokenizer(st.nextToken(), "|");
+				while ( st.hasMoreTokens() ) // now get each extension
+					LANGUAGES.put(st.nextToken().trim(), lang);
+			}
+		}
+		catch (IOException ioe) {}
+		finally
+		{
+			try { if (is != null) is.close(); } catch (Throwable t) {}
+		}
+	}
+	
+	private ConfigTree config;
+	private MessagePayloadProxy payloadProxy;
+	private String script = null;
+	private String language = null;
+	
+	public ScriptingAction(ConfigTree config)
+	{
+		this.config = config;
+		payloadProxy = new MessagePayloadProxy(config);
+	}
+	
+	public void initialise() throws ActionLifecycleException
+	{
+		// attempt to get the script
+		String scriptPath = getAttribute("script");
+		if (scriptPath == null)
+		{
+			final boolean supportMessageBasedScripting = config.getBooleanAttribute("supportMessageBasedScripting", false);
+			if(supportMessageBasedScripting)
+			{
+				if (logger.isDebugEnabled())
+				{
+					logger.debug("No script specified on action config " + config.getAttribute("name")
+						+ ". Expecting script to be in message.");
+				}
+			}
+			else
+			{
+				throw new ActionLifecycleException("'script' not configured on the action and message based scripting is not enabled ('supportMessageBasedScripting=false').");
+			}
+		}
+		else
+		{
+			InputStream scriptStream = null;
+			try
+			{
+				scriptStream = ClassUtil.getResourceAsStream(scriptPath, ScriptingAction.class);
+				if (scriptStream != null)
+				{
+					scriptStream = new BufferedInputStream(scriptStream);
+					script = new String( StreamUtils.readStream(scriptStream) );
+				}
+				else
+				{
+					// TODO: i18n
+					throw new ActionLifecycleException(
+							"script '" + scriptPath + "' not found on classpath"  );
+				}
+			}
+			catch (Throwable t)
+			{
+				throw new ActionLifecycleException(t);
+			}
+			finally
+			{
+				try { if (scriptStream != null) scriptStream.close(); } catch (Throwable t) {}
+			}
+		}
+		// attempt to get the language
+		language = getAttribute("language");
+		if (language == null && script != null)
+		{
+			// try again via extension
+			int pos = scriptPath.lastIndexOf('.');
+			if (pos > -1 && pos < scriptPath.length()-1)
+				language = scriptPath.substring( pos+1, scriptPath.length() );
+		}
+		if (language != null)
+		{
+			// substitute extension for language if we can
+			if ( LANGUAGES.containsKey(language) )
+				language = LANGUAGES.get(language);
+		}
+		else
+		{
+			// TODO: i18n
+			throw new ActionLifecycleException("language not specified");
+		}
+	}
+
+	public Message process(Message message) throws ActionProcessingException
+	{
+		BSFManager bsf = new BSFManager();
+		try
+		{
+			bsf.declareBean( "message", message, message.getClass() );
+			bsf.declareBean( "config", config, config.getClass() );
+			bsf.declareBean( "payloadProxy", payloadProxy, payloadProxy.getClass() );
+			// NOTE: cannot use eval here since it does not work for all engines (jython in particular)
+			bsf.exec( language, null, 0, 0, getScript(message) );
+		}
+		catch (BSFException bsfe)
+		{
+			throw new ActionProcessingException(bsfe);
+		}
+		return message;
+	}
+	
+	private String getScript(Message message) throws ActionProcessingException
+	{
+		if (script != null)
+			return script;
+		else
+		{
+			Object messageScript;
+			try
+			{
+				messageScript = payloadProxy.getPayload(message);
+			}
+			catch (MessageDeliverException mde)
+			{
+				throw new ActionProcessingException(mde);
+			}
+			if (messageScript instanceof String)
+				return (String)messageScript;
+			else if (messageScript instanceof byte[])
+				return new String( (byte[])messageScript );
+			else
+			{
+				// TODO: i18n
+				throw new ActionProcessingException("script not specified in message");
+			}
+		}
+	}
+	
+	private String getAttribute(String name)
+	{
+		String value = config.getAttribute(name);
+		if (value != null)
+		{
+			value = value.trim();
+			if (value.length() == 0)
+				value = null;
+		}
+		return value;
+	}
+
+}


Property changes on: labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/actions/scripting/ScriptingAction.java
___________________________________________________________________
Name: svn:keywords
   + Rev Date
Name: svn:eol-style
   + native

Added: labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/actions/scripting/ScriptingActionUnitTest.java
===================================================================
--- labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/actions/scripting/ScriptingActionUnitTest.java	                        (rev 0)
+++ labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/actions/scripting/ScriptingActionUnitTest.java	2008-08-05 11:04:16 UTC (rev 21360)
@@ -0,0 +1,99 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, JBoss Inc., and others contributors as indicated 
+ * by the @authors tag. All rights reserved. 
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors. 
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A 
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+ * MA  02110-1301, USA.
+ * 
+ * (C) 2005-2007,
+ */
+
+package org.jboss.soa.esb.actions.scripting;
+
+import junit.framework.TestCase;
+
+import org.jboss.soa.esb.ConfigurationException;
+import org.jboss.soa.esb.actions.ActionLifecycleException;
+import org.jboss.soa.esb.actions.ActionProcessingException;
+import org.jboss.soa.esb.helpers.ConfigTree;
+import org.jboss.soa.esb.message.Message;
+import org.jboss.soa.esb.message.format.MessageFactory;
+
+/**
+ * Unit tests for ScriptingAction.
+ * <p/>
+ * Based on {@link GroovyActionProcessorUnitTest} by Tom Fennelly.
+ *
+ * @author dward at jboss.org
+ */
+public class ScriptingActionUnitTest extends TestCase
+{
+	public void test_bsh_file()
+		throws ConfigurationException, ActionLifecycleException, ActionProcessingException
+	{
+		do_script_file("test.bsh");
+	}
+
+	private void do_script_file(String script)
+		throws ConfigurationException, ActionLifecycleException, ActionProcessingException
+	{
+		ConfigTree config = new ConfigTree("<config/>");
+		config.setAttribute("script", "/org/jboss/soa/esb/actions/scripting/" + script);
+		String messageContents = "Hello World!";
+		config.setAttribute("messageContents", messageContents);
+		ScriptingAction action = new ScriptingAction(config);
+		Message message = MessageFactory.getInstance().getMessage();
+		assertProcessingOK(action, message, messageContents);
+	}
+	
+	public void test_bsh_inlined()
+		throws ConfigurationException, ActionLifecycleException, ActionProcessingException
+	{
+		do_script_inlined(
+				"message.getBody().add(config.getAttribute(\"messageContents\").getBytes());",
+				"bsh" );
+	}
+	
+	public void test_beanshell_inlined()
+		throws ConfigurationException, ActionLifecycleException, ActionProcessingException
+	{
+		do_script_inlined(
+				"message.getBody().add(config.getAttribute(\"messageContents\").getBytes());",
+				"beanshell" );
+	}
+
+	private void do_script_inlined(String script, String language)
+		throws ConfigurationException, ActionLifecycleException, ActionProcessingException
+	{
+		ConfigTree config = new ConfigTree("<config/>");
+		config.setAttribute("language", language);
+		config.setAttribute("supportMessageBasedScripting", "true") ;
+		String messageContents = "Hello World - Inlined!";
+		config.setAttribute("messageContents", messageContents);
+		ScriptingAction action = new ScriptingAction(config);
+		Message message = MessageFactory.getInstance().getMessage();
+		message.getBody().add(script);
+		assertProcessingOK(action, message, messageContents);
+	}
+
+	private void assertProcessingOK(ScriptingAction action, Message message, String messageContents)
+		throws ActionLifecycleException, ActionProcessingException
+	{
+		action.initialise();
+		action.process(message);
+		byte[] bodyContents = (byte[]) message.getBody().get();
+		assertNotNull("Expected body contents to be set.", bodyContents);
+		assertEquals( messageContents, new String(bodyContents) );
+	}
+
+}


Property changes on: labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/actions/scripting/ScriptingActionUnitTest.java
___________________________________________________________________
Name: svn:keywords
   + Rev Date
Name: svn:eol-style
   + native

Added: labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/actions/scripting/test.bsh
===================================================================
--- labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/actions/scripting/test.bsh	                        (rev 0)
+++ labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/actions/scripting/test.bsh	2008-08-05 11:04:16 UTC (rev 21360)
@@ -0,0 +1 @@
+message.getBody().add(config.getAttribute("messageContents").getBytes());
\ No newline at end of file




More information about the jboss-svn-commits mailing list