* Made most fields in RequestEvaluator private and use a synchronized getter to access them
* Minor change in ScriptingEngine interface
This commit is contained in:
parent
e05d4eabc8
commit
f9a327a9e8
8 changed files with 122 additions and 80 deletions
|
@ -1175,7 +1175,7 @@ public final class Application implements IPathElement, Runnable {
|
|||
for (int i = 0; i < l; i++) {
|
||||
RequestEvaluator r = (RequestEvaluator) allThreads.get(i);
|
||||
|
||||
if ((r != null) && (r.rtx == thread)) {
|
||||
if ((r != null) && (r.getThread() == thread)) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,42 +36,42 @@ public final class RequestEvaluator implements Runnable {
|
|||
static final int XMLRPC = 2; // via XML-RPC
|
||||
static final int INTERNAL = 3; // generic function call, e.g. by scheduler
|
||||
static final int EXTERNAL = 4; // function from script etc
|
||||
|
||||
public final Application app;
|
||||
|
||||
protected ScriptingEngine scriptingEngine;
|
||||
public volatile RequestTrans req;
|
||||
public volatile ResponseTrans res;
|
||||
|
||||
// the one and only transactor thread
|
||||
volatile Transactor rtx;
|
||||
|
||||
// the type of request to be serviced,
|
||||
// used to coordinate worker and waiter threads
|
||||
volatile int reqtype;
|
||||
|
||||
// the object on which to invoke a function, if specified
|
||||
Object thisObject;
|
||||
|
||||
// the method to be executed
|
||||
String functionName;
|
||||
|
||||
// the session object associated with the current request
|
||||
Session session;
|
||||
|
||||
// arguments passed to the function
|
||||
Object[] args;
|
||||
|
||||
// the object path of the request we're evaluating
|
||||
RequestPath requestPath;
|
||||
|
||||
// the result of the operation
|
||||
Object result;
|
||||
|
||||
// the exception thrown by the evaluator, if any.
|
||||
Exception exception;
|
||||
|
||||
// skin depth counter, used to avoid recursive skin rendering
|
||||
protected int skinDepth;
|
||||
|
||||
private volatile RequestTrans req;
|
||||
private volatile ResponseTrans res;
|
||||
|
||||
// the one and only transactor thread
|
||||
private volatile Transactor rtx;
|
||||
|
||||
// the type of request to be serviced,
|
||||
// used to coordinate worker and waiter threads
|
||||
private volatile int reqtype;
|
||||
|
||||
// the object on which to invoke a function, if specified
|
||||
private Object thisObject;
|
||||
|
||||
// the method to be executed
|
||||
private String functionName;
|
||||
|
||||
// the session object associated with the current request
|
||||
private Session session;
|
||||
|
||||
// arguments passed to the function
|
||||
private Object[] args;
|
||||
|
||||
// the result of the operation
|
||||
private Object result;
|
||||
|
||||
// the exception thrown by the evaluator, if any.
|
||||
private Exception exception;
|
||||
|
||||
/**
|
||||
* Create a new RequestEvaluator for this application.
|
||||
*/
|
||||
|
@ -131,8 +131,13 @@ public final class RequestEvaluator implements Runnable {
|
|||
// object reference to ressolve request path
|
||||
Object currentElement;
|
||||
|
||||
// Get req and res into local variables to avoid memory caching problems
|
||||
// in unsynchronized method.
|
||||
RequestTrans req = getRequest();
|
||||
ResponseTrans res = getResponse();
|
||||
|
||||
// request path object
|
||||
requestPath = new RequestPath(app);
|
||||
RequestPath requestPath = new RequestPath(app);
|
||||
|
||||
int tries = 0;
|
||||
boolean done = false;
|
||||
|
@ -160,7 +165,7 @@ public final class RequestEvaluator implements Runnable {
|
|||
|
||||
root = app.getDataRoot();
|
||||
|
||||
initGlobals(root);
|
||||
initGlobals(root, requestPath);
|
||||
|
||||
if (error != null) {
|
||||
res.error = error;
|
||||
|
@ -489,8 +494,6 @@ public final class RequestEvaluator implements Runnable {
|
|||
Thread.sleep((long) (base + (Math.random() * base * 2)));
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
|
||||
continue;
|
||||
} else {
|
||||
abortTransaction();
|
||||
|
||||
|
@ -859,7 +862,7 @@ public final class RequestEvaluator implements Runnable {
|
|||
* @param req
|
||||
* @param session
|
||||
*/
|
||||
private void initObjects(RequestTrans req, Session session) {
|
||||
private synchronized void initObjects(RequestTrans req, Session session) {
|
||||
this.req = req;
|
||||
this.reqtype = HTTP;
|
||||
this.session = session;
|
||||
|
@ -876,12 +879,12 @@ public final class RequestEvaluator implements Runnable {
|
|||
* @param reqtype
|
||||
* @param reqtypeName
|
||||
*/
|
||||
private void initObjects(String functionName, int reqtype, String reqtypeName) {
|
||||
private synchronized void initObjects(String functionName, int reqtype, String reqtypeName) {
|
||||
this.functionName = functionName;
|
||||
this.reqtype = reqtype;
|
||||
req = new RequestTrans(reqtypeName, functionName);
|
||||
session = new Session(functionName, app);
|
||||
res = new ResponseTrans(app, req);
|
||||
res = new ResponseTrans(app, getRequest());
|
||||
result = null;
|
||||
exception = null;
|
||||
}
|
||||
|
@ -892,7 +895,8 @@ public final class RequestEvaluator implements Runnable {
|
|||
* @param root
|
||||
* @throws ScriptingException
|
||||
*/
|
||||
private void initGlobals(Object root) throws ScriptingException {
|
||||
private synchronized void initGlobals(Object root, Object requestPath)
|
||||
throws ScriptingException {
|
||||
HashMap globals = new HashMap();
|
||||
|
||||
globals.put("root", root);
|
||||
|
@ -930,12 +934,11 @@ public final class RequestEvaluator implements Runnable {
|
|||
/**
|
||||
* Null out some fields, mostly for the sake of garbage collection.
|
||||
*/
|
||||
public void recycle() {
|
||||
public synchronized void recycle() {
|
||||
res = null;
|
||||
req = null;
|
||||
session = null;
|
||||
args = null;
|
||||
requestPath = null;
|
||||
result = null;
|
||||
exception = null;
|
||||
}
|
||||
|
@ -989,4 +992,39 @@ public final class RequestEvaluator implements Runnable {
|
|||
return scriptingEngine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the request object for the current request.
|
||||
*
|
||||
* @return the request object
|
||||
*/
|
||||
public synchronized RequestTrans getRequest() {
|
||||
return req;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the response object for the current request.
|
||||
*
|
||||
* @return the response object
|
||||
*/
|
||||
public synchronized ResponseTrans getResponse() {
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current transactor thread
|
||||
*
|
||||
* @return the current transactor thread
|
||||
*/
|
||||
public synchronized Transactor getThread() {
|
||||
return rtx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current session
|
||||
*
|
||||
* @return the session for the current request
|
||||
*/
|
||||
public synchronized Session getSession() {
|
||||
return session;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -154,7 +154,7 @@ public final class Skin {
|
|||
}
|
||||
|
||||
if (macros == null) {
|
||||
reval.res.writeCharArray(source, 0, sourceLength);
|
||||
reval.getResponse().writeCharArray(source, 0, sourceLength);
|
||||
reval.skinDepth--;
|
||||
|
||||
return;
|
||||
|
@ -170,7 +170,7 @@ public final class Skin {
|
|||
|
||||
for (int i = 0; i < macros.length; i++) {
|
||||
if (macros[i].start > written) {
|
||||
reval.res.writeCharArray(source, written, macros[i].start - written);
|
||||
reval.getResponse().writeCharArray(source, written, macros[i].start - written);
|
||||
}
|
||||
|
||||
macros[i].render(reval, thisObject, paramObject, handlerCache);
|
||||
|
@ -178,7 +178,7 @@ public final class Skin {
|
|||
}
|
||||
|
||||
if (written < sourceLength) {
|
||||
reval.res.writeCharArray(source, written, sourceLength - written);
|
||||
reval.getResponse().writeCharArray(source, written, sourceLength - written);
|
||||
}
|
||||
} finally {
|
||||
reval.skinDepth--;
|
||||
|
@ -403,7 +403,7 @@ public final class Skin {
|
|||
}
|
||||
|
||||
if ((sandbox != null) && !sandbox.contains(fullName)) {
|
||||
reval.res.write("[Macro " + fullName + " not allowed in sandbox]");
|
||||
reval.getResponse().write("[Macro " + fullName + " not allowed in sandbox]");
|
||||
|
||||
return;
|
||||
} else if ("response".equalsIgnoreCase(handler)) {
|
||||
|
@ -468,7 +468,7 @@ public final class Skin {
|
|||
// eiter because thisObject == null or the right object wasn't found
|
||||
// in the object's parent path. Check if a matching macro handler
|
||||
// is registered with the response object (res.handlers).
|
||||
handlerObject = reval.res.getMacroHandlers().get(handler);
|
||||
handlerObject = reval.getResponse().getMacroHandlers().get(handler);
|
||||
}
|
||||
|
||||
// the macro handler object couldn't be found
|
||||
|
@ -492,7 +492,7 @@ public final class Skin {
|
|||
String funcName = name + "_macro";
|
||||
|
||||
if (reval.scriptingEngine.hasFunction(handlerObject, funcName)) {
|
||||
StringBuffer buffer = reval.res.getBuffer();
|
||||
StringBuffer buffer = reval.getResponse().getBuffer();
|
||||
RenderParameters renderParams = defaultRenderParams;
|
||||
|
||||
// remember length of response buffer before calling macro
|
||||
|
@ -551,18 +551,18 @@ public final class Skin {
|
|||
// otherwise try property lookup
|
||||
if (handlerObject == null) {
|
||||
String msg = "[Macro unhandled: " + fullName + "]";
|
||||
reval.res.write(" " + msg + " ");
|
||||
reval.getResponse().write(" " + msg + " ");
|
||||
app.logEvent(msg);
|
||||
|
||||
} else {
|
||||
Object value = reval.scriptingEngine.get(handlerObject, name);
|
||||
writeResponse(value, reval.res.getBuffer(), defaultRenderParams, true);
|
||||
writeResponse(value, reval.getResponse().getBuffer(), defaultRenderParams, true);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
String msg = "[Macro unhandled: " + fullName + "]";
|
||||
reval.res.write(" " + msg + " ");
|
||||
reval.getResponse().write(" " + msg + " ");
|
||||
app.logEvent(msg);
|
||||
|
||||
}
|
||||
|
@ -581,7 +581,7 @@ public final class Skin {
|
|||
}
|
||||
|
||||
msg = "[Macro error in " + fullName + ": " + msg + "]";
|
||||
reval.res.write(" " + msg + " ");
|
||||
reval.getResponse().write(" " + msg + " ");
|
||||
app.logEvent(msg);
|
||||
}
|
||||
}
|
||||
|
@ -591,48 +591,48 @@ public final class Skin {
|
|||
Object value = null;
|
||||
|
||||
if ("message".equals(name)) {
|
||||
value = reval.res.message;
|
||||
value = reval.getResponse().message;
|
||||
} else if ("error".equals(name)) {
|
||||
value = reval.res.error;
|
||||
value = reval.getResponse().error;
|
||||
}
|
||||
|
||||
if (value == null) {
|
||||
value = reval.res.get(name);
|
||||
value = reval.getResponse().get(name);
|
||||
}
|
||||
|
||||
writeResponse(value, reval.res.getBuffer(), defaultRenderParams, true);
|
||||
writeResponse(value, reval.getResponse().getBuffer(), defaultRenderParams, true);
|
||||
}
|
||||
|
||||
private void renderFromRequest(RequestEvaluator reval)
|
||||
throws UnsupportedEncodingException {
|
||||
if (reval.req == null) {
|
||||
if (reval.getRequest() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object value = reval.req.get(name);
|
||||
Object value = reval.getRequest().get(name);
|
||||
|
||||
writeResponse(value, reval.res.getBuffer(), defaultRenderParams, true);
|
||||
writeResponse(value, reval.getResponse().getBuffer(), defaultRenderParams, true);
|
||||
}
|
||||
|
||||
private void renderFromSession(RequestEvaluator reval)
|
||||
throws UnsupportedEncodingException {
|
||||
if (reval.session == null) {
|
||||
if (reval.getSession() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object value = reval.session.getCacheNode().getString(name);
|
||||
Object value = reval.getSession().getCacheNode().getString(name);
|
||||
|
||||
writeResponse(value, reval.res.getBuffer(), defaultRenderParams, true);
|
||||
writeResponse(value, reval.getResponse().getBuffer(), defaultRenderParams, true);
|
||||
}
|
||||
|
||||
private void renderFromParam(RequestEvaluator reval, Map paramObject)
|
||||
throws UnsupportedEncodingException {
|
||||
if (paramObject == null) {
|
||||
reval.res.write("[Macro error: Skin requires a parameter object]");
|
||||
reval.getResponse().write("[Macro error: Skin requires a parameter object]");
|
||||
} else {
|
||||
Object value = paramObject.get(name);
|
||||
|
||||
writeResponse(value, reval.res.getBuffer(), defaultRenderParams, true);
|
||||
writeResponse(value, reval.getResponse().getBuffer(), defaultRenderParams, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ import helma.framework.core.RequestEvaluator;
|
|||
import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* This is the interface that must be implemented to make a scripting environment
|
||||
|
@ -68,7 +68,7 @@ public interface ScriptingEngine {
|
|||
* evaluation is entered. The globals parameter contains the global values
|
||||
* to be applied during this execution context.
|
||||
*/
|
||||
public void enterContext(HashMap globals) throws ScriptingException;
|
||||
public void enterContext(Map globals) throws ScriptingException;
|
||||
|
||||
/**
|
||||
* This method is called to let the scripting engine know that the current
|
||||
|
|
|
@ -18,6 +18,7 @@ package helma.scripting.rhino;
|
|||
|
||||
import helma.scripting.rhino.extensions.*;
|
||||
import helma.framework.core.*;
|
||||
import helma.framework.ResponseTrans;
|
||||
import helma.objectmodel.db.*;
|
||||
import helma.util.HtmlEncoder;
|
||||
import helma.util.MimePart;
|
||||
|
@ -178,10 +179,10 @@ public class GlobalObject extends ImporterTopLevel implements PropertyRecorder {
|
|||
Map param = RhinoCore.getSkinParam(paramobj);
|
||||
|
||||
if (skin != null) {
|
||||
reval.res.pushStringBuffer();
|
||||
ResponseTrans res = reval.getResponse();
|
||||
res.pushStringBuffer();
|
||||
skin.render(reval, null, param);
|
||||
|
||||
return reval.res.popStringBuffer();
|
||||
return res.popStringBuffer();
|
||||
}
|
||||
|
||||
return "";
|
||||
|
|
|
@ -19,6 +19,7 @@ package helma.scripting.rhino;
|
|||
import helma.scripting.ScriptingException;
|
||||
import helma.scripting.ScriptingEngine;
|
||||
import helma.framework.core.*;
|
||||
import helma.framework.ResponseTrans;
|
||||
import helma.objectmodel.*;
|
||||
import helma.objectmodel.db.*;
|
||||
import org.mozilla.javascript.*;
|
||||
|
@ -311,10 +312,10 @@ public class HopObject extends ScriptableObject implements Wrapper, PropertyReco
|
|||
checkNode();
|
||||
|
||||
if (skin != null) {
|
||||
reval.res.pushStringBuffer();
|
||||
ResponseTrans res = reval.getResponse();
|
||||
res.pushStringBuffer();
|
||||
skin.render(reval, node, param);
|
||||
|
||||
return reval.res.popStringBuffer();
|
||||
return res.popStringBuffer();
|
||||
}
|
||||
|
||||
return "";
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package helma.scripting.rhino;
|
||||
|
||||
import helma.framework.core.*;
|
||||
import helma.framework.ResponseTrans;
|
||||
import org.mozilla.javascript.*;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
|
@ -124,10 +125,10 @@ public class JavaObject extends NativeJavaObject {
|
|||
Map param = RhinoCore.getSkinParam(paramobj);
|
||||
|
||||
if (skin != null) {
|
||||
reval.res.pushStringBuffer();
|
||||
ResponseTrans res = reval.getResponse();
|
||||
res.pushStringBuffer();
|
||||
skin.render(reval, javaObject, param);
|
||||
|
||||
return reval.res.popStringBuffer();
|
||||
return res.popStringBuffer();
|
||||
}
|
||||
|
||||
return "";
|
||||
|
|
|
@ -187,7 +187,7 @@ public class RhinoEngine implements ScriptingEngine {
|
|||
* evaluation is entered. The globals parameter contains the global values
|
||||
* to be applied during this execution context.
|
||||
*/
|
||||
public void enterContext(HashMap globals) throws ScriptingException {
|
||||
public void enterContext(Map globals) throws ScriptingException {
|
||||
// set the thread filed in the FESI evaluator
|
||||
// evaluator.thread = Thread.currentThread ();
|
||||
// set globals on the global object
|
||||
|
@ -524,7 +524,7 @@ public class RhinoEngine implements ScriptingEngine {
|
|||
* Proxy method to RequestEvaluator.
|
||||
*/
|
||||
public ResponseTrans getResponse() {
|
||||
return reval.res;
|
||||
return reval.getResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -532,7 +532,7 @@ public class RhinoEngine implements ScriptingEngine {
|
|||
* Proxy method to RequestEvaluator.
|
||||
*/
|
||||
public RequestTrans getRequest() {
|
||||
return reval.req;
|
||||
return reval.getRequest();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -551,16 +551,17 @@ public class RhinoEngine implements ScriptingEngine {
|
|||
*/
|
||||
public Skin getSkin(String protoName, String skinName) throws IOException {
|
||||
SkinKey key = new SkinKey(protoName, skinName);
|
||||
ResponseTrans res = getResponse();
|
||||
|
||||
Skin skin = reval.res.getCachedSkin(key);
|
||||
Skin skin = res.getCachedSkin(key);
|
||||
|
||||
if (skin == null) {
|
||||
// retrieve res.skinpath, an array of objects that tell us where to look for skins
|
||||
// (strings for directory names and INodes for internal, db-stored skinsets)
|
||||
Object[] skinpath = reval.res.getSkinpath();
|
||||
Object[] skinpath = res.getSkinpath();
|
||||
RhinoCore.unwrapSkinpath(skinpath);
|
||||
skin = app.getSkin(protoName, skinName, skinpath);
|
||||
reval.res.cacheSkin(key, skin);
|
||||
res.cacheSkin(key, skin);
|
||||
}
|
||||
return skin;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue