You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicemix.apache.org by gn...@apache.org on 2008/08/01 01:25:28 UTC

svn commit: r681549 - in /servicemix/components/engines/servicemix-scripting/trunk: ./ src/main/java/org/apache/servicemix/scripting/ src/main/resources/META-INF/ src/main/resources/META-INF/spring/ src/test/resources/

Author: gnodet
Date: Thu Jul 31 16:25:27 2008
New Revision: 681549

URL: http://svn.apache.org/viewvc?rev=681549&view=rev
Log:
SM-1387: make servicemix-scripting OSGi aware, and improve the endpoint to use compiled script when possible

Added:
    servicemix/components/engines/servicemix-scripting/trunk/src/main/resources/META-INF/
    servicemix/components/engines/servicemix-scripting/trunk/src/main/resources/META-INF/spring/
    servicemix/components/engines/servicemix-scripting/trunk/src/main/resources/META-INF/spring/servicemix-scripting.xml
Modified:
    servicemix/components/engines/servicemix-scripting/trunk/pom.xml
    servicemix/components/engines/servicemix-scripting/trunk/src/main/java/org/apache/servicemix/scripting/DefaultScriptingMarshaler.java
    servicemix/components/engines/servicemix-scripting/trunk/src/main/java/org/apache/servicemix/scripting/ScriptingEndpoint.java
    servicemix/components/engines/servicemix-scripting/trunk/src/test/resources/spring.xml

Modified: servicemix/components/engines/servicemix-scripting/trunk/pom.xml
URL: http://svn.apache.org/viewvc/servicemix/components/engines/servicemix-scripting/trunk/pom.xml?rev=681549&r1=681548&r2=681549&view=diff
==============================================================================
--- servicemix/components/engines/servicemix-scripting/trunk/pom.xml (original)
+++ servicemix/components/engines/servicemix-scripting/trunk/pom.xml Thu Jul 31 16:25:27 2008
@@ -46,6 +46,20 @@
     <jruby-version>1.1.2</jruby-version>
     <rhino-version>1.7R1</rhino-version>
     <jsr223-version>20080611</jsr223-version>
+
+
+    <servicemix.osgi.import>
+      org.apache.servicemix.common,
+      org.apache.servicemix.common.osgi,
+      org.apache.servicemix.executors.impl,
+      org.apache.xbean.spring.context.v2,
+      org.springframework.beans.factory.xml,
+      *
+    </servicemix.osgi.import>
+    <servicemix.osgi.export>
+      org.apache.servicemix.scripting*;version=${project.version},
+      META-INF.services.org.apache.xbean.spring.http.servicemix.apache.org.scripting
+    </servicemix.osgi.export>
   </properties>
   
   <dependencies>
@@ -128,8 +142,8 @@
           <execution>
             <configuration>
               <namespace>
-								http://org.apache.servicemix/scripting/1.0
-							</namespace>
+                  http://servicemix.apache.org/scripting/1.0
+			  </namespace>
             </configuration>
             <goals>
               <goal>mapping</goal>

Modified: servicemix/components/engines/servicemix-scripting/trunk/src/main/java/org/apache/servicemix/scripting/DefaultScriptingMarshaler.java
URL: http://svn.apache.org/viewvc/servicemix/components/engines/servicemix-scripting/trunk/src/main/java/org/apache/servicemix/scripting/DefaultScriptingMarshaler.java?rev=681549&r1=681548&r2=681549&view=diff
==============================================================================
--- servicemix/components/engines/servicemix-scripting/trunk/src/main/java/org/apache/servicemix/scripting/DefaultScriptingMarshaler.java (original)
+++ servicemix/components/engines/servicemix-scripting/trunk/src/main/java/org/apache/servicemix/scripting/DefaultScriptingMarshaler.java Thu Jul 31 16:25:27 2008
@@ -61,6 +61,6 @@
      *      javax.jbi.messaging.MessageExchange)
      */
     public InputStream getScriptCode(ScriptingEndpoint endpoint, MessageExchange exchange) throws IOException {
-        return endpoint.getScript().getInputStream();
+        return null;
     }
 }

Modified: servicemix/components/engines/servicemix-scripting/trunk/src/main/java/org/apache/servicemix/scripting/ScriptingEndpoint.java
URL: http://svn.apache.org/viewvc/servicemix/components/engines/servicemix-scripting/trunk/src/main/java/org/apache/servicemix/scripting/ScriptingEndpoint.java?rev=681549&r1=681548&r2=681549&view=diff
==============================================================================
--- servicemix/components/engines/servicemix-scripting/trunk/src/main/java/org/apache/servicemix/scripting/ScriptingEndpoint.java (original)
+++ servicemix/components/engines/servicemix-scripting/trunk/src/main/java/org/apache/servicemix/scripting/ScriptingEndpoint.java Thu Jul 31 16:25:27 2008
@@ -33,8 +33,9 @@
 import javax.script.ScriptEngine;
 import javax.script.ScriptEngineManager;
 import javax.script.ScriptException;
+import javax.script.CompiledScript;
+import javax.script.Compilable;
 
-import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.servicemix.common.endpoints.ProviderEndpoint;
@@ -71,6 +72,7 @@
     private ScriptingMarshalerSupport marshaler = new DefaultScriptingMarshaler();
     private Resource script;
     private Logger scriptLogger;
+    private CompiledScript compiledScript;
 
     /**
      * @return
@@ -205,10 +207,6 @@
                 done(exchange);
             } else {
                 Bindings scriptBindings = engine.createBindings();
-
-                scriptBindings.put(KEY_IN_EXCHANGE, exchange);
-
-                // exec script engine code to do its thing for this
                 scriptBindings.put(KEY_CONTEXT, getContext());
                 scriptBindings.put(KEY_IN_EXCHANGE, exchange);
                 scriptBindings.put(KEY_IN_MSG, exchange.getMessage("in"));
@@ -228,55 +226,58 @@
                 scriptBindings.put(KEY_USER_BINDINGS, bindings);
                 scriptBindings.put(KEY_COMPONENT_NAMESPACE, scriptBindings);
 
-                // call back method for custom marshaler to inject it's own
-                // beans
+                // call back method for custom marshaler to inject it's own beans
                 this.marshaler.registerUserBeans(this, exchange, scriptBindings);
 
-                // get the input stream to the script code
+                // get the input stream to the script code from the marshaler
                 InputStream is = null;
                 try {
-                    // gets the input stream to the script code
                     is = this.marshaler.getScriptCode(this, exchange);
                 } catch (IOException ioex) {
-                    logger
-                        .error("Unable to load script in marshaler: " + this.marshaler.getClass().getName(),
-                               ioex);
-                    // io error getting the script code
+                    logger.error("Unable to load script in marshaler: "
+                                    + this.marshaler.getClass().getName(), ioex);
+                }
+                // if the marshaler does not return a valid input stream, use the script property to load it
+                if (is != null) {
+                    try {
+                        // execute the script
+                        this.engine.eval(new InputStreamReader(is), scriptBindings);
+                    } catch (ScriptException ex) {
+                        logger.error("Error executing the script: " + ex.getFileName() + " at line: "
+                                     + ex.getLineNumber() + " and column: " + ex.getColumnNumber(), ex);
+                        throw ex;
+                    }
+                } else {
                     try {
-                        is = this.script.getInputStream();
-                    } catch (IOException i2) {
-                        logger.error("Unable to load the script " + script.getFilename(), i2);
+                        // use the compiled script interfaces if possible
+                        if (compiledScript == null && engine instanceof Compilable) {
+                            compiledScript = ((Compilable) engine).compile(new InputStreamReader(this.script.getInputStream()));
+                        }
+                        if (compiledScript != null) {
+                            // execute the script
+                            compiledScript.eval(scriptBindings);
+                        } else {
+                            // execute the script
+                            engine.eval(new InputStreamReader(this.script.getInputStream()), scriptBindings);
+                        }
+                    } catch (IOException ioex) {
+                        logger.error("Unable to load the script " + script.getFilename(), ioex);
                         throw new MessagingException("Unable to load the script " + script.getFilename());
+                    } catch (ScriptException ex) {
+                        logger.error("Error executing the script: " + ex.getFileName() + " at line: "
+                                     + ex.getLineNumber() + " and column: " + ex.getColumnNumber(), ex);
+                        throw ex;
                     }
                 }
 
-                // create a reader for the stream
-                Reader reader = new InputStreamReader(is);
-
-                try {
-                    // execute the script
-                    this.engine.eval(reader, scriptBindings);
-
-                    exchange = (MessageExchange)scriptBindings.get(KEY_IN_EXCHANGE);
-
-                    // on InOut exchanges we always do answer
-                    if (exchange instanceof InOut) {
-                        if (!isDisableOutput()) {
-                            send(exchange);
-                        }
-                    } else {
-                        // if InOnly exchange then we only answer if user wants
-                        // to
-                        done(exchange);
+                // on InOut exchanges we always do answer
+                if (exchange instanceof InOut) {
+                    if (!isDisableOutput()) {
+                        send(exchange);
                     }
-                } catch (ScriptException ex) {
-                    logger.error("Error executing the script: " + ex.getFileName() + " at line: "
-                                 + ex.getLineNumber() + " and column: " + ex.getColumnNumber(), ex);
-                    fail(exchange, ex);
-                } catch (NullPointerException ex) {
-                    logger.error("Error executing the script: " + script.getFilename()
-                                 + ". A unexpected NullPointerException occured.", ex);
-                    fail(exchange, ex);
+                } else {
+                    // if InOnly exchange then we only answer if user wants to
+                    done(exchange);
                 }
             }
         } else { 
@@ -363,7 +364,7 @@
         super.start();
         try {
             // lazy instatiation
-            this.manager = new ScriptEngineManager();
+            this.manager = new ScriptEngineManager(serviceUnit.getConfigurationClassLoader());
 
             if (script == null) {
                 throw new IllegalArgumentException("Property script must be set");
@@ -371,11 +372,10 @@
                 // initialize the script engine
                 if (this.language.equalsIgnoreCase(LANGUAGE_AUTODETECT)) {
                     // detect language by file extension
-                    this.engine = this.manager.getEngineByExtension(FilenameUtils.getExtension(script
-                        .getFilename()));
+                    this.engine = this.manager.getEngineByExtension(getExtension(script.getFilename()));
                     if (this.engine == null) {
                         throw new RuntimeException("There is no script engine registered for extension "
-                                                   + FilenameUtils.getExtension(script.getFilename()));
+                                                   + getExtension(script.getFilename()));
                     }
                 } else {
                     // use predefined language from xbean
@@ -409,4 +409,43 @@
 
         super.stop();
     }
+
+    //
+    // utility
+    //
+
+    private static final char UNIX_SEPARATOR = '/';
+    private static final char WINDOWS_SEPARATOR = '\\';
+    public static final char EXTENSION_SEPARATOR = '.';
+
+    public static String getExtension(String filename) {
+        if (filename == null) {
+            return null;
+        }
+        int index = indexOfExtension(filename);
+        if (index == -1) {
+            return "";
+        } else {
+            return filename.substring(index + 1);
+        }
+    }
+
+    public static int indexOfExtension(String filename) {
+        if (filename == null) {
+            return -1;
+        }
+        int extensionPos = filename.lastIndexOf(EXTENSION_SEPARATOR);
+        int lastSeparator = indexOfLastSeparator(filename);
+        return (lastSeparator > extensionPos ? -1 : extensionPos);
+    }
+
+    public static int indexOfLastSeparator(String filename) {
+        if (filename == null) {
+            return -1;
+        }
+        int lastUnixPos = filename.lastIndexOf(UNIX_SEPARATOR);
+        int lastWindowsPos = filename.lastIndexOf(WINDOWS_SEPARATOR);
+        return Math.max(lastUnixPos, lastWindowsPos);
+    }
+
 }

Added: servicemix/components/engines/servicemix-scripting/trunk/src/main/resources/META-INF/spring/servicemix-scripting.xml
URL: http://svn.apache.org/viewvc/servicemix/components/engines/servicemix-scripting/trunk/src/main/resources/META-INF/spring/servicemix-scripting.xml?rev=681549&view=auto
==============================================================================
--- servicemix/components/engines/servicemix-scripting/trunk/src/main/resources/META-INF/spring/servicemix-scripting.xml (added)
+++ servicemix/components/engines/servicemix-scripting/trunk/src/main/resources/META-INF/spring/servicemix-scripting.xml Thu Jul 31 16:25:27 2008
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:osgi="http://www.springframework.org/schema/osgi"
+       xmlns:osgix="http://www.springframework.org/schema/osgi-compendium"
+       xmlns:util="http://www.springframework.org/schema/util"
+       xsi:schemaLocation="
+  http://www.springframework.org/schema/beans
+  http://www.springframework.org/schema/beans/spring-beans.xsd
+  http://www.springframework.org/schema/util
+  http://www.springframework.org/schema/util/spring-util.xsd
+  http://www.springframework.org/schema/osgi
+  http://www.springframework.org/schema/osgi/spring-osgi.xsd
+  http://www.springframework.org/schema/osgi-compendium
+  http://www.springframework.org/schema/osgi-compendium/spring-osgi-compendium.xsd">
+
+    <bean id="servicemix-scripting" class="org.apache.servicemix.scripting.ScriptingComponent">
+        <property name="executorFactory" ref="executorFactory" />
+    </bean>
+
+    <bean id="executorFactory" class="org.apache.servicemix.executors.impl.ExecutorFactoryImpl">
+        <property name="defaultConfig">
+            <bean class="org.apache.servicemix.executors.impl.ExecutorConfig">
+                <property name="corePoolSize" value="${threadPoolCorePoolSize}"/>
+                <property name="maximumPoolSize" value="${threadPoolMaximumPoolSize}"/>
+                <property name="queueSize" value="${threadPoolQueueSize}"/>
+            </bean>
+        </property>
+    </bean>
+
+    <bean id="endpoint-tracker" class="org.apache.servicemix.common.osgi.EndpointTracker">
+        <property name="component" ref="servicemix-scripting" />
+    </bean>
+
+    <osgi:list id="endpoints"
+               interface="org.apache.servicemix.common.osgi.EndpointWrapper"
+               cardinality="0..N">
+        <osgi:listener ref="endpoint-tracker" bind-method="register" unbind-method="unregister" />
+    </osgi:list>
+
+    <osgi:service ref="servicemix-scripting" interface="javax.jbi.component.Component">
+        <osgi:service-properties>
+            <entry key="NAME" value="servicemix-scripting" />
+            <entry key="TYPE" value="service-engine" />
+        </osgi:service-properties>
+    </osgi:service>
+
+    <osgix:property-placeholder persistent-id="servicemix-scripting">
+        <osgix:default-properties>
+            <prop key="threadPoolCorePoolSize">8</prop>
+            <prop key="threadPoolMaximumPoolSize">32</prop>
+            <prop key="threadPoolQueueSize">256</prop>
+        </osgix:default-properties>
+    </osgix:property-placeholder>
+
+</beans>

Modified: servicemix/components/engines/servicemix-scripting/trunk/src/test/resources/spring.xml
URL: http://svn.apache.org/viewvc/servicemix/components/engines/servicemix-scripting/trunk/src/test/resources/spring.xml?rev=681549&r1=681548&r2=681549&view=diff
==============================================================================
--- servicemix/components/engines/servicemix-scripting/trunk/src/test/resources/spring.xml (original)
+++ servicemix/components/engines/servicemix-scripting/trunk/src/test/resources/spring.xml Thu Jul 31 16:25:27 2008
@@ -18,7 +18,7 @@
 	
 -->
 <beans xmlns:sm="http://servicemix.apache.org/config/1.0"
-	xmlns:scripting="http://org.apache.servicemix/scripting/1.0"
+	xmlns:scripting="http://servicemix.apache.org/scripting/1.0"
 	xmlns:util="http://www.springframework.org/schema/util"
 	xmlns:test="urn:test">