* Simplify function handling a bit, plus minor cleanup

This commit is contained in:
hns 2007-04-02 15:29:19 +00:00
parent aa648dd876
commit ab4ea1e144

View file

@ -62,10 +62,7 @@ public final class RequestEvaluator implements Runnable {
// the object on which to invoke a function, if specified // the object on which to invoke a function, if specified
private volatile Object thisObject; private volatile Object thisObject;
// the function to be executed // the method to be executed
private volatile String functionName;
// the function or function name to be executed
private volatile Object function; private volatile Object function;
// the session object associated with the current request // the session object associated with the current request
@ -117,7 +114,7 @@ public final class RequestEvaluator implements Runnable {
if (t instanceof RuntimeException) { if (t instanceof RuntimeException) {
throw((RuntimeException) t); throw((RuntimeException) t);
} else { } else {
throw new RuntimeException(t.toString()); throw new RuntimeException(t.toString(), t);
} }
} finally { } finally {
app.setCurrentRequestEvaluator(null); app.setCurrentRequestEvaluator(null);
@ -153,6 +150,8 @@ public final class RequestEvaluator implements Runnable {
int tries = 0; int tries = 0;
boolean done = false; boolean done = false;
String error = null; String error = null;
String functionName = function instanceof String ?
(String) function : null;
while (!done && localrtx == rtx) { while (!done && localrtx == rtx) {
// catch errors in path resolution and script execution // catch errors in path resolution and script execution
@ -168,7 +167,7 @@ public final class RequestEvaluator implements Runnable {
// avoid going into transaction if called function doesn't exist. // avoid going into transaction if called function doesn't exist.
// this only works for the (common) case that method is a plain // this only works for the (common) case that method is a plain
// method name, not an obj.method path // method name, not an obj.method path
if (reqtype == INTERNAL && functionName != null) { if (reqtype == INTERNAL) {
// if object is an instance of NodeHandle, get the node object itself. // if object is an instance of NodeHandle, get the node object itself.
if (thisObject instanceof NodeHandle) { if (thisObject instanceof NodeHandle) {
thisObject = ((NodeHandle) thisObject).getNode(app.nmgr.safe); thisObject = ((NodeHandle) thisObject).getNode(app.nmgr.safe);
@ -180,13 +179,16 @@ public final class RequestEvaluator implements Runnable {
} }
} }
// If function doesn't exist, return immediately // If function doesn't exist, return immediately
if (functionName.indexOf('.') < 0 && if (functionName != null && functionName.indexOf('.') < 0 &&
!scriptingEngine.hasFunction(thisObject, functionName)) { !scriptingEngine.hasFunction(thisObject, functionName)) {
app.logEvent(missingFunctionMessage(thisObject, functionName)); app.logEvent(missingFunctionMessage(thisObject, functionName));
done = true; done = true;
reqtype = NONE; reqtype = NONE;
break; break;
} }
} else if (function != null && functionName == null) {
// only internal requests may pass a function instead of a function name
throw new IllegalStateException("No function name in non-internal request ");
} }
// Transaction name is used for logging etc. // Transaction name is used for logging etc.
@ -407,8 +409,9 @@ public final class RequestEvaluator implements Runnable {
} }
// check if request is still valid, or if the requesting thread has stopped waiting already // check if request is still valid, or if the requesting thread has stopped waiting already
if (localrtx != rtx) if (localrtx != rtx) {
return; return;
}
commitTransaction(); commitTransaction();
done = true; done = true;
@ -426,15 +429,12 @@ public final class RequestEvaluator implements Runnable {
for (int i = 1; i < cnt; i++) { for (int i = 1; i < cnt; i++) {
String next = st.nextToken(); String next = st.nextToken();
currentElement = getChildElement(currentElement, next);
currentElement = getChildElement(currentElement,
next);
} }
if (currentElement == null) { if (currentElement == null) {
throw new FrameworkException("Method name \"" + throw new FrameworkException("Method name \"" +
functionName + function + "\" could not be resolved.");
"\" could not be resolved.");
} }
functionName = st.nextToken(); functionName = st.nextToken();
@ -443,7 +443,6 @@ public final class RequestEvaluator implements Runnable {
if (reqtype == XMLRPC) { if (reqtype == XMLRPC) {
// check XML-RPC access permissions // check XML-RPC access permissions
String proto = app.getPrototypeName(currentElement); String proto = app.getPrototypeName(currentElement);
app.checkXmlRpcAccess(proto, functionName); app.checkXmlRpcAccess(proto, functionName);
} }
@ -457,13 +456,15 @@ public final class RequestEvaluator implements Runnable {
ScriptingEngine.ARGS_WRAP_XMLRPC, ScriptingEngine.ARGS_WRAP_XMLRPC,
false); false);
// check if request is still valid, or if the requesting thread has stopped waiting already // check if request is still valid, or if the requesting thread has stopped waiting already
if (localrtx != rtx) if (localrtx != rtx) {
return; return;
}
commitTransaction(); commitTransaction();
} catch (Exception x) { } catch (Exception x) {
// check if request is still valid, or if the requesting thread has stopped waiting already // check if request is still valid, or if the requesting thread has stopped waiting already
if (localrtx != rtx) if (localrtx != rtx) {
return; return;
}
abortTransaction(); abortTransaction();
app.logError(txname + ": " + error, x); app.logError(txname + ": " + error, x);
@ -495,13 +496,15 @@ public final class RequestEvaluator implements Runnable {
ScriptingEngine.ARGS_WRAP_DEFAULT, ScriptingEngine.ARGS_WRAP_DEFAULT,
true); true);
// check if request is still valid, or if the requesting thread has stopped waiting already // check if request is still valid, or if the requesting thread has stopped waiting already
if (localrtx != rtx) if (localrtx != rtx) {
return; return;
}
commitTransaction(); commitTransaction();
} catch (Exception x) { } catch (Exception x) {
// check if request is still valid, or if the requesting thread has stopped waiting already // check if request is still valid, or if the requesting thread has stopped waiting already
if (localrtx != rtx) if (localrtx != rtx) {
return; return;
}
abortTransaction(); abortTransaction();
app.logError(txname + ": " + error, x); app.logError(txname + ": " + error, x);
@ -522,8 +525,9 @@ public final class RequestEvaluator implements Runnable {
// res.abort() just aborts the transaction and // res.abort() just aborts the transaction and
// leaves the response untouched // leaves the response untouched
// check if request is still valid, or if the requesting thread has stopped waiting already // check if request is still valid, or if the requesting thread has stopped waiting already
if (localrtx != rtx) if (localrtx != rtx) {
return; return;
}
abortTransaction(); abortTransaction();
done = true; done = true;
} catch (ConcurrencyException x) { } catch (ConcurrencyException x) {
@ -532,8 +536,9 @@ public final class RequestEvaluator implements Runnable {
if (++tries < 8) { if (++tries < 8) {
// try again after waiting some period // try again after waiting some period
// check if request is still valid, or if the requesting thread has stopped waiting already // check if request is still valid, or if the requesting thread has stopped waiting already
if (localrtx != rtx) if (localrtx != rtx) {
return; return;
}
abortTransaction(); abortTransaction();
try { try {
@ -549,8 +554,9 @@ public final class RequestEvaluator implements Runnable {
} }
} else { } else {
// check if request is still valid, or if the requesting thread has stopped waiting already // check if request is still valid, or if the requesting thread has stopped waiting already
if (localrtx != rtx) if (localrtx != rtx) {
return; return;
}
abortTransaction(); abortTransaction();
if (error == null) if (error == null)
@ -563,8 +569,9 @@ public final class RequestEvaluator implements Runnable {
} catch (Throwable x) { } catch (Throwable x) {
String txname = localrtx.getTransactionName(); String txname = localrtx.getTransactionName();
// check if request is still valid, or if the requesting thread has stopped waiting already // check if request is still valid, or if the requesting thread has stopped waiting already
if (localrtx != rtx) if (localrtx != rtx) {
return; return;
}
abortTransaction(); abortTransaction();
// If the transactor thread has been killed by the invoker thread we don't have to // If the transactor thread has been killed by the invoker thread we don't have to
@ -794,7 +801,9 @@ public final class RequestEvaluator implements Runnable {
*/ */
public synchronized Object invokeXmlRpc(String functionName, Object[] args) public synchronized Object invokeXmlRpc(String functionName, Object[] args)
throws Exception { throws Exception {
initObjects(functionName, args, XMLRPC, RequestTrans.XMLRPC); initObjects(functionName, XMLRPC, RequestTrans.XMLRPC);
this.function = functionName;
this.args = args;
startTransactor(); startTransactor();
wait(app.requestTimeout); wait(app.requestTimeout);
@ -826,7 +835,9 @@ public final class RequestEvaluator implements Runnable {
*/ */
public synchronized Object invokeExternal(String functionName, Object[] args) public synchronized Object invokeExternal(String functionName, Object[] args)
throws Exception { throws Exception {
initObjects(functionName, args, EXTERNAL, RequestTrans.EXTERNAL); initObjects(functionName, EXTERNAL, RequestTrans.EXTERNAL);
this.function = functionName;
this.args = args;
startTransactor(); startTransactor();
wait(); wait();
@ -892,11 +903,10 @@ public final class RequestEvaluator implements Runnable {
public synchronized Object invokeInternal(Object object, Object function, public synchronized Object invokeInternal(Object object, Object function,
Object[] args, long timeout) Object[] args, long timeout)
throws Exception { throws Exception {
String funcName = function instanceof String ? initObjects(function, INTERNAL, RequestTrans.INTERNAL);
(String) function : null;
initObjects(funcName, args, INTERNAL, RequestTrans.INTERNAL);
thisObject = object; thisObject = object;
this.function = function; this.function = function;
this.args = args;
startTransactor(); startTransactor();
if (timeout < 0) if (timeout < 0)
@ -938,22 +948,16 @@ public final class RequestEvaluator implements Runnable {
* Init this evaluator's objects for an internal, external or XML-RPC type * Init this evaluator's objects for an internal, external or XML-RPC type
* request. * request.
* *
* @param funcName the function name, may be null * @param function the function name or object
* @param args the argument array
* @param reqtype the request type * @param reqtype the request type
* @param reqtypeName the request type name * @param reqtypeName the request type name
*/ */
private synchronized void initObjects(String funcName, Object[] args, private synchronized void initObjects(Object function, int reqtype, String reqtypeName) {
int reqtype, String reqtypeName) {
this.functionName = funcName;
this.args = args;
this.reqtype = reqtype; this.reqtype = reqtype;
// if function name is null, use a placeholder for req, session etc, String functionName = function instanceof String ?
// but make sure functionName field remains null. (String) function : "<function>";
if (funcName == null) req = new RequestTrans(reqtypeName, functionName);
funcName = "<function>"; session = new Session(functionName, app);
req = new RequestTrans(reqtypeName, funcName);
session = new Session(funcName, app);
res = new ResponseTrans(app, req); res = new ResponseTrans(app, req);
result = null; result = null;
exception = null; exception = null;
@ -1008,7 +1012,6 @@ public final class RequestEvaluator implements Runnable {
res = null; res = null;
req = null; req = null;
session = null; session = null;
functionName = null;
function = null; function = null;
args = null; args = null;
result = null; result = null;