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