Author: tyrell
Date: Mon Feb  4 08:07:08 2008
New Revision: 13240

Log:

Fixing MASHUP-630

Modified:
   
trunk/mashup/java/modules/hostobjects/src/org/wso2/mashup/hostobjects/system/FunctionSchedulingJob.java
   
trunk/mashup/java/modules/hostobjects/src/org/wso2/mashup/hostobjects/system/SystemHostObject.java

Modified: 
trunk/mashup/java/modules/hostobjects/src/org/wso2/mashup/hostobjects/system/FunctionSchedulingJob.java
==============================================================================
--- 
trunk/mashup/java/modules/hostobjects/src/org/wso2/mashup/hostobjects/system/FunctionSchedulingJob.java
     (original)
+++ 
trunk/mashup/java/modules/hostobjects/src/org/wso2/mashup/hostobjects/system/FunctionSchedulingJob.java
     Mon Feb  4 08:07:08 2008
@@ -15,51 +15,190 @@
  */
 package org.wso2.mashup.hostobjects.system;
 
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.description.AxisService;
+import org.apache.axis2.description.Parameter;
 import org.mozilla.javascript.Context;
-import org.mozilla.javascript.ContextAction;
 import org.mozilla.javascript.Function;
 import org.quartz.Job;
 import org.quartz.JobExecutionContext;
 import org.quartz.JobExecutionException;
+import org.wso2.javascript.rhino.JavaScriptEngine;
+import org.wso2.javascript.rhino.JavaScriptEngineUtils;
+import org.wso2.javascript.rhino.JavaScriptEngineConstants;
+
+import java.net.URL;
+import java.io.Reader;
+import java.io.InputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
 
 public class FunctionSchedulingJob implements Job {
 
-    public static String RHINO_CONTEXT = "cx";
-    public static String SYSTEM_HOST_OBJECT = "systemhost";
     public static String JAVASCRIPT_FUNCTION = "jsfunction";
     public static String FUNCTION_PARAMETERS = "jsfunctionarguments";
-
-    Context cx;
+    public static String PARENT_MESSAGE_CONTEXT = "parentMessageContext";
 
     public void execute(JobExecutionContext jobExecutionContext) throws 
JobExecutionException {
-        cx = (Context) jobExecutionContext.getJobDetail().getJobDataMap()
-                .get(FunctionSchedulingJob.RHINO_CONTEXT);
-        final SystemHostObject systemHost = (SystemHostObject) 
jobExecutionContext.getJobDetail()
-                .getJobDataMap().get(FunctionSchedulingJob.SYSTEM_HOST_OBJECT);
-        final Object jsFunction = 
jobExecutionContext.getJobDetail().getJobDataMap()
-                .get(FunctionSchedulingJob.JAVASCRIPT_FUNCTION);
-
-        if (jsFunction instanceof Function) {
-            //A function name was passed, probably with arguments.
-            if (jobExecutionContext.getJobDetail().getJobDataMap()
-                    .get(FunctionSchedulingJob.FUNCTION_PARAMETERS) == null) {
-                ((Function) jsFunction).call(cx, systemHost, systemHost, null);
-            } else {
-                Object[] arguments = (Object[]) 
jobExecutionContext.getJobDetail().getJobDataMap()
-                        .get(FunctionSchedulingJob.FUNCTION_PARAMETERS);
-                ((Function) jsFunction).call(cx, systemHost, systemHost, 
arguments);
+
+        final Object jsFunction;
+        try {
+            MessageContext currentMessageContext =
+                    (MessageContext) 
jobExecutionContext.getJobDetail().getJobDataMap()
+                            .get(FunctionSchedulingJob.PARENT_MESSAGE_CONTEXT);
+
+            jsFunction = jobExecutionContext.getJobDetail().getJobDataMap()
+                    .get(FunctionSchedulingJob.JAVASCRIPT_FUNCTION);
+
+            JavaScriptEngine jsEngine =
+                    new 
JavaScriptEngine(currentMessageContext.getAxisService().getName());
+
+            // Rhino E4X XMLLibImpl object can be instantiated only from 
within a script
+            // So we instantiate it in here, so that we can use it outside of 
the script later
+            jsEngine.getCx().evaluateString(jsEngine, "new XML();", 
"Instantiate E4X", 0, null);
+
+            JavaScriptEngineUtils
+                    .loadHostObjects(jsEngine, 
currentMessageContext.getConfigurationContext()
+                            .getAxisConfiguration());
+
+            // Inject the incoming MessageContext to the Rhino Context. Some
+            // host objects need access to the MessageContext. Eg: FileSystem,
+            // WSRequest
+            Context context = jsEngine.getCx();
+            
context.putThreadLocal(JavaScriptEngineConstants.AXIS2_MESSAGECONTEXT,
+                                   currentMessageContext);
+
+            /*
+             * Some host objects depend on the data we obtain from the
+             * AxisService & ConfigurationContext.. It is possible to get these
+             * data through the MessageContext. But we face problems at the
+             * deployer, where we need to instantiate host objects in order for
+             * the annotations framework to work and the MessageContext is not
+             * available at that time. For the consistency we inject them in
+             * here too..
+             */
+            context.putThreadLocal(JavaScriptEngineConstants.AXIS2_SERVICE,
+                                   currentMessageContext.getAxisService());
+            
context.putThreadLocal(JavaScriptEngineConstants.AXIS2_CONFIGURATION_CONTEXT,
+                                   
currentMessageContext.getConfigurationContext());
+
+            JavaScriptEngineUtils.loadGlobalPropertyObjects(jsEngine, 
currentMessageContext
+                    .getConfigurationContext().getAxisConfiguration());
+
+            URL repoURL = 
currentMessageContext.getConfigurationContext().getAxisConfiguration()
+                    .getRepository();
+            if (repoURL != null) {
+                JavaScriptEngine.axis2RepositoryLocation = repoURL.getPath();
+            }
+
+            Reader reader = readJS(currentMessageContext);
+
+            Object[] args = null;
+
+            //support for importing javaScript files using services.xml or the 
axis2.xml
+            String scripts = getImportScriptsList(currentMessageContext);
+
+            //Loading imported JavaScript files if there are any
+            if (scripts != null) {
+                // Generate load command out of the parameter scripts
+                scripts = "load(" + ("[\"" + scripts + "\"]").replaceAll(",", 
"\"],[\"") + ")";
+                jsEngine.getCx().evaluateString(jsEngine, scripts, "Load 
Included JavaScript File(s)", 0, null);
             }
-        } else if (jsFunction instanceof String) {
-            //A string expression was passed, evaluate accrodingly
-            Context.call(new ContextAction() {
-                public Object run(Context context) {
-                    String script = (String) jsFunction;
-                    Object result = cx.evaluateString(systemHost, script, 
"<Scheduled_JavaScripts>",
-                                                      1, null);
-                    return null;
+
+            //Evaluating the JavaScript service file
+            jsEngine.getCx().evaluateReader(jsEngine, reader, "Load JSService 
file", 1, null);
+
+            if (jsFunction instanceof Function) {
+                if (jobExecutionContext.getJobDetail().getJobDataMap()
+                        .get(FunctionSchedulingJob.FUNCTION_PARAMETERS) != 
null) {
+                    args = (Object[]) 
jobExecutionContext.getJobDetail().getJobDataMap()
+                            .get(FunctionSchedulingJob.FUNCTION_PARAMETERS);
+                } else {
+                    args = new Object[0];
                 }
-            });
+
+                Function function = (Function) jsFunction;
+                function.call(jsEngine.getCx(), jsEngine, jsEngine, args);
+
+            } else if (jsFunction instanceof String) {
+                String jsString = (String) jsFunction;                    
+                jsEngine.getCx()
+                        .evaluateString(jsEngine, jsString, "Load 
JavaScriptString", 0, null);
+            }
+
+        } catch (Exception e) {
+            throw new JobExecutionException(e);
         }
 
     }
+
+    /**
+     * Locates the service Javascript file associated with ServiceJS parameter 
and returns
+     * a Reader for it.
+     *
+     * @param inMessage MessageContext object with information about the 
incoming message
+     * @return an input stream to the javascript source file
+     * @throws org.apache.axis2.AxisFault if the parameter ServiceJS is not 
specified or if the service
+     *                                    implementation is not available
+     */
+    private Reader readJS(MessageContext inMessage) throws AxisFault {
+        InputStream jsFileStream;
+        AxisService service = inMessage.getServiceContext().getAxisService();
+        Parameter implInfoParam = 
service.getParameter(JavaScriptEngineConstants.SERVICE_JS);
+        if (implInfoParam == null) {
+            throw new AxisFault("Parameter 'ServiceJS' not specified");
+        }
+        if (implInfoParam.getValue() instanceof File) {
+            try {
+                jsFileStream = new FileInputStream((File) 
(implInfoParam.getValue()));
+            } catch (FileNotFoundException e) {
+                throw new AxisFault("Unable to load the javaScript, File not 
Found", e);
+            }
+        } else {
+            jsFileStream = service.getClassLoader().getResourceAsStream(
+                    implInfoParam.getValue().toString());
+        }
+        if (jsFileStream == null) {
+            throw new AxisFault("Unable to load the javaScript");
+        }
+        return new BufferedReader(new InputStreamReader(jsFileStream));
+    }
+
+    /**
+     * Provides support for importing JavaScript files specified in the
+     * Services.xml or the Axis2.xml using the "loadJSScripts" parameter.
+     *
+     * @param inMessage - The incoming message Context
+     * @return String
+     */
+    private String getImportScriptsList(MessageContext inMessage) {
+        String scripts = null;
+
+        // Get necessary JavaScripts to be loaded from services.xml
+        Parameter param = 
inMessage.getOperationContext().getAxisOperation().getParameter(
+                JavaScriptEngineConstants.LOAD_JSSCRIPTS);
+        if (param != null) {
+            scripts = (String) param.getValue();
+        }
+
+        // Get necessary JavaScripts to be loaded from axis2.xml
+        param = 
inMessage.getConfigurationContext().getAxisConfiguration().getParameter(
+                JavaScriptEngineConstants.LOAD_JSSCRIPTS);
+        if (param != null) {
+            if (scripts == null) {
+                scripts = (String) param.getValue();
+            } else {
+                // Avoids loading the same set of script files twice
+                if (!scripts.equals(param.getValue())) {
+                    scripts += "," + param.getValue();
+                }
+            }
+        }
+        return scripts;
+    }
+
 }

Modified: 
trunk/mashup/java/modules/hostobjects/src/org/wso2/mashup/hostobjects/system/SystemHostObject.java
==============================================================================
--- 
trunk/mashup/java/modules/hostobjects/src/org/wso2/mashup/hostobjects/system/SystemHostObject.java
  (original)
+++ 
trunk/mashup/java/modules/hostobjects/src/org/wso2/mashup/hostobjects/system/SystemHostObject.java
  Mon Feb  4 08:07:08 2008
@@ -18,6 +18,7 @@
 import org.apache.axiom.om.util.UUIDGenerator;
 import org.apache.axis2.AxisFault;
 import org.apache.axis2.context.ConfigurationContext;
+import org.apache.axis2.context.MessageContext;
 import org.apache.axis2.description.AxisService;
 import org.apache.axis2.description.Parameter;
 import org.apache.axis2.engine.AxisConfiguration;
@@ -333,8 +334,9 @@
 
         SystemHostObject systemHostObject = checkInstance(thisObj);
 
-        // Getting the scheduler
         Object object = 
cx.getThreadLocal(JavaScriptEngineConstants.AXIS2_SERVICE);
+        Object currentMessageContext = 
cx.getThreadLocal(JavaScriptEngineConstants.AXIS2_MESSAGECONTEXT);
+
         AxisService axisService;
         if (object instanceof AxisService) {
             axisService = (AxisService) object;
@@ -387,14 +389,13 @@
                             "Invalid parameter. The second parameter must be 
the execution frequency in milliseconds.");
                 }
 
-                //Storing the session host instance, the jsfunction and 
contect in jobdata map
-                
jobDetail.getJobDataMap().put(FunctionSchedulingJob.RHINO_CONTEXT, cx);
+                //Storing the function meta-data to be used by the job at 
execution time
                 jobDetail.getJobDataMap()
                         .put(FunctionSchedulingJob.JAVASCRIPT_FUNCTION, 
jsFunction);
                 jobDetail.getJobDataMap()
                         .put(FunctionSchedulingJob.FUNCTION_PARAMETERS, 
functionParams);
                 jobDetail.getJobDataMap()
-                        .put(FunctionSchedulingJob.SYSTEM_HOST_OBJECT, 
systemHostObject);
+                        .put(FunctionSchedulingJob.PARENT_MESSAGE_CONTEXT, 
currentMessageContext);
 
                 //Creating the trigger. There will be a one-to-one mapping 
between jobs and triggers in this implementation
                 trigger = new SimpleTrigger(jobId + "-trigger", null, new 
Date(), null,
@@ -454,14 +455,13 @@
                     }
                 }
 
-                //Storing the session host instance, the jsfunction and 
contect in jobdata map
-                
jobDetail.getJobDataMap().put(FunctionSchedulingJob.RHINO_CONTEXT, cx);
+                //Storing the function meta-data to be used by the job at 
execution time
                 jobDetail.getJobDataMap()
                         .put(FunctionSchedulingJob.JAVASCRIPT_FUNCTION, 
jsFunction);
                 jobDetail.getJobDataMap()
                         .put(FunctionSchedulingJob.FUNCTION_PARAMETERS, 
functionParams);
                 jobDetail.getJobDataMap()
-                        .put(FunctionSchedulingJob.SYSTEM_HOST_OBJECT, 
systemHostObject);
+                        .put(FunctionSchedulingJob.PARENT_MESSAGE_CONTEXT, 
currentMessageContext);
 
                 //Creating the trigger. There will be a one-to-one mapping 
between jobs and triggers in this implementation
                 trigger = new SimpleTrigger(jobId + "-trigger", null, new 
Date(), null,
@@ -529,14 +529,13 @@
                             "Invalid parameter. The third parameter must be 
the start time in date format.");
                 }
 
-                //Storing the session host instance, the jsfunction and 
contect in jobdata map
-                
jobDetail.getJobDataMap().put(FunctionSchedulingJob.RHINO_CONTEXT, cx);
+                //Storing the function meta-data to be used by the job at 
execution time
                 jobDetail.getJobDataMap()
                         .put(FunctionSchedulingJob.JAVASCRIPT_FUNCTION, 
jsFunction);
                 jobDetail.getJobDataMap()
                         .put(FunctionSchedulingJob.FUNCTION_PARAMETERS, 
functionParams);
                 jobDetail.getJobDataMap()
-                        .put(FunctionSchedulingJob.SYSTEM_HOST_OBJECT, 
systemHostObject);
+                        .put(FunctionSchedulingJob.PARENT_MESSAGE_CONTEXT, 
currentMessageContext);
 
                 //Creating the trigger. There will be a one-to-one mapping 
between jobs and triggers in this implementation
                 trigger = new SimpleTrigger(jobId + "-trigger", null, 
startTime, null,
@@ -612,14 +611,13 @@
                             "Invalid parameter. The fourth parameter must be 
the end time in date format.");
                 }
 
-                //Storing the session host instance, the jsfunction and 
contect in jobdata map
-                
jobDetail.getJobDataMap().put(FunctionSchedulingJob.RHINO_CONTEXT, cx);
+                //Storing the function meta-data to be used by the job at 
execution time
                 jobDetail.getJobDataMap()
                         .put(FunctionSchedulingJob.JAVASCRIPT_FUNCTION, 
jsFunction);
                 jobDetail.getJobDataMap()
                         .put(FunctionSchedulingJob.FUNCTION_PARAMETERS, 
functionParams);
                 jobDetail.getJobDataMap()
-                        .put(FunctionSchedulingJob.SYSTEM_HOST_OBJECT, 
systemHostObject);
+                        .put(FunctionSchedulingJob.PARENT_MESSAGE_CONTEXT, 
currentMessageContext);
 
                 //Creating the trigger. There will be a one-to-one mapping 
between jobs and triggers in this implementation
                 trigger = new SimpleTrigger(jobId + "-trigger", null, 
startTime, endTime,
@@ -677,7 +675,7 @@
             Scheduler scheduler = (Scheduler) parameter.getValue();
 
             try {
-                scheduler.deleteJob(jobId, null);
+                scheduler.deleteJob(jobId, null);                 
             } catch (SchedulerException e) {
                 throw new MashupFault("Failed to remove job id from the 
scheduler", e);
             }

_______________________________________________
Mashup-dev mailing list
[email protected]
http://www.wso2.org/cgi-bin/mailman/listinfo/mashup-dev

Reply via email to