From 9698b2c2821986fdf2bb66dc4a52b2d50fbea151 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Fri, 5 Jan 2007 04:33:38 +0000 Subject: r20538: Web Application Framework - correct an error message in the JSON-RPC server - provide a common RPC request function - make it easier to have multiple pending RPC requests. this allows an application-specified request to return "not logged in"; authentication information to be requested and sent; and the original request to be reissued. - in statistics module, if a time is provided as zero, leave it blank rather than displaying 1 Jan 1970. this showed up in the last_used_at field in the SMB status report. - clean up makefile: remove no-longer-used hard-coded path and install target; remove "chmod" and "nice" commands which were part of the original skeleton, since that is not deemed appropriate for samba makefiles (This used to be commit 339ee73ce2809905f608b1003cc645231f256420) --- .../source/class/swat/module/AbstractModuleFsm.js | 120 ++++++++++++++++++++- .../swat/source/class/swat/module/ldbbrowse/Fsm.js | 96 +++++++---------- .../source/class/swat/module/statistics/Fsm.js | 21 ++-- .../source/class/swat/module/statistics/Gui.js | 5 + 4 files changed, 168 insertions(+), 74 deletions(-) (limited to 'webapps/swat/source') diff --git a/webapps/swat/source/class/swat/module/AbstractModuleFsm.js b/webapps/swat/source/class/swat/module/AbstractModuleFsm.js index 57b8baaac9..cffeb8b00a 100644 --- a/webapps/swat/source/class/swat/module/AbstractModuleFsm.js +++ b/webapps/swat/source/class/swat/module/AbstractModuleFsm.js @@ -14,6 +14,9 @@ qx.OO.defineClass("swat.module.AbstractModuleFsm", qx.core.Object, function() { qx.core.Object.call(this); + + // Create an array for pushing request objects + this._requests = [ ]; }); @@ -26,6 +29,7 @@ qx.Proto.buildFsm = function(module) qx.Proto.addAwaitRpcResultState = function(module) { var fsm = module.fsm; + var _this = this; /* * State: AwaitRpcResult @@ -107,7 +111,7 @@ qx.Proto.addAwaitRpcResultState = function(module) "onentry" : function(fsm, state) { - // If we're coming from some other start... + // If we're coming from some other state... if (fsm.getPreviousState() != "State_AwaitRpcResult") { // ... then push the previous state onto the state stack @@ -147,7 +151,7 @@ qx.Proto.addAwaitRpcResultState = function(module) function(fsm, event) { // Get the request object - var request = fsm.getObject("swat.module.fsmUtils.request"); + var request = _this.getCurrentRpcRequest(); // Issue an abort for the pending request request.abort(); @@ -170,7 +174,7 @@ qx.Proto.addAwaitRpcResultState = function(module) function(fsm, event) { // Get the request object - var request = fsm.getObject("swat.module.fsmUtils.request"); + var request = _this.getCurrentRpcRequest(); // Generate the result for a completed request request.setUserData("result", @@ -197,7 +201,7 @@ qx.Proto.addAwaitRpcResultState = function(module) function(fsm, event) { // Get the request object - var request = fsm.getObject("swat.module.fsmUtils.request"); + var request = _this.getCurrentRpcRequest(); // Generate the result for a completed request request.setUserData("result", @@ -209,3 +213,111 @@ qx.Proto.addAwaitRpcResultState = function(module) }); state.addTransition(trans); }; + + +/** + * Issue a remote procedure call. + * + * @param fsm {qx.util.fsm.FiniteStateMachine} + * The finite state machine issuing this remote procedure call. + * + * @param service {String} + * The name of the remote service which provides the specified method. + * + * @param method {String} + * The name of the method within the specified service. + * + * @param params {Array} + * The parameters to be passed to the specified method. + * + * @return {qx.io.remote.Request} + * The request object for the just-issued RPC request. + */ +qx.Proto.callRpc = function(fsm, service, method, params) +{ + // Create an object to hold a copy of the parameters. (We need a + // qx.core.Object() to be able to store this in the finite state machine.) + var o = new qx.core.Object(); + + // copy the parameters; we'll prefix our copy with additional params + o.allParams = params.slice(0); + + // prepend the method + o.allParams.unshift(method); + + // prepend the flag indicating to coalesce failure events + o.allParams.unshift(true); + + // prepend the service name + o.allParams.unshift(service); + + // Save the complete parameter list in case authentication fails and we need + // to reissue the request. + fsm.addObject("swat.module.rpc_params", o); + + // Retrieve the RPC object */ + var rpc = fsm.getObject("swat.module.rpc"); + + // Set the service name + rpc.setServiceName(o.allParams[0]); + + // Issue the request, skipping the already-specified service name + var request = + qx.io.remote.Rpc.prototype.callAsyncListeners.apply(rpc, + o.allParams.slice(1)); + + // Make the request object available to the AwaitRpcResult state + this.pushRpcRequest(request); + + // Give 'em what they came for + return request; +}; + + +/** + * Push an RPC request onto the request stack. + * + * @param request {qx.io.remote.Request} + * The just-issued request + */ +qx.Proto.pushRpcRequest = function(request) +{ + this._requests.push(request); +}; + + +/** + * Retrieve the most recent RPC request from the request stack and pop the + * stack. + * + * @return {qx.io.remote.Request} + * The request from the top of the request stack + */ +qx.Proto.popRpcRequest = function() +{ + if (this._requests.length == 0) + { + throw new Error("Attempt to pop an RPC request when list is empty."); + } + + var request = this._requests.pop(); + return request; +}; + + +/** + * Retrieve the most recent RPC request. + * + * @return {qx.io.remote.Request} + * The request at the top of the request stack + */ +qx.Proto.getCurrentRpcRequest = function() +{ + if (this._requests.length == 0) + { + throw new Error("Attempt to retrieve an RPC request when list is empty."); + } + + return this._requests[this._requests.length - 1]; +}; + diff --git a/webapps/swat/source/class/swat/module/ldbbrowse/Fsm.js b/webapps/swat/source/class/swat/module/ldbbrowse/Fsm.js index 9362ef7687..8052d9a579 100644 --- a/webapps/swat/source/class/swat/module/ldbbrowse/Fsm.js +++ b/webapps/swat/source/class/swat/module/ldbbrowse/Fsm.js @@ -20,6 +20,7 @@ function() qx.Proto.buildFsm = function(module) { var fsm = module.fsm; + var _this = this; /* * State: Idle @@ -42,10 +43,7 @@ qx.Proto.buildFsm = function(module) if (fsm.getPreviousState() == "State_AwaitRpcResult") { // Yup. Display the result. We need to get the request object - var request = fsm.getObject("swat.module.fsmUtils.request"); - - // We don't need the request object to be saved any more - fsm.removeObject("swat.module.fsmUtils.request"); + var request = _this.popRpcRequest(); // Display the result var gui = swat.module.ldbbrowse.Gui.getInstance(); @@ -107,9 +105,6 @@ qx.Proto.buildFsm = function(module) "ontransition" : function(fsm, event) { - // Obtain the RPC object - var rpc = fsm.getObject("swat.module.rpc"); - // Get our module descriptor var module = fsm.getObject("swat.module.module"); @@ -128,21 +123,21 @@ qx.Proto.buildFsm = function(module) // We want all attributes var attributes = [ "*" ]; - rpc.setServiceName("samba.ldb"); - var request = rpc.callAsyncListeners(true, // coalesce failure events - "search", - dbHandle, - searchExpr, - baseDN, - scope, - attributes); + // Issue a Search call + var request = _this.callRpc(fsm, + "samba.ldb", + "search", + [ + dbHandle, + searchExpr, + baseDN, + scope, + attributes + ]); // When we get the result, we'll need to know what type of request // we made. request.setUserData("requestType", "find"); - - // Save the request object - fsm.addObject("swat.module.fsmUtils.request", request); } }); state.addTransition(trans); @@ -207,23 +202,23 @@ qx.Proto.buildFsm = function(module) // Build the search expression var searchExpr = "(objectclass=*)"; - // Obtain the RPC object - var rpc = fsm.getObject("swat.module.rpc"); - // Get our module descriptor var module = fsm.getObject("swat.module.module"); // Retrieve the database handle var dbHandle = module.dbHandle; - rpc.setServiceName("samba.ldb"); - var request = rpc.callAsyncListeners(true, // coalesce failure events - "search", - dbHandle, - searchExpr, - baseDN, - scope, - attributes); + // Issue a Get Statistics call + var request = _this.callRpc(fsm, + "samba.ldb", + "search", + [ + dbHandle, + searchExpr, + baseDN, + scope, + attributes + ]); // When we get the result, we'll need to know what type of request // we made. @@ -232,9 +227,6 @@ qx.Proto.buildFsm = function(module) // We'll also need some of our parameters request.setUserData("parent", parent); request.setUserData("attributes", attributes); - - // Save the request object - fsm.addObject("swat.module.fsmUtils.request", request); } }); state.addTransition(trans); @@ -306,30 +298,27 @@ qx.Proto.buildFsm = function(module) // Build the search expression var searchExpr = "(objectclass=*)"; - // Obtain the RPC object - var rpc = fsm.getObject("swat.module.rpc"); - // Get our module descriptor var module = fsm.getObject("swat.module.module"); // Retrieve the database handle var dbHandle = module.dbHandle; - rpc.setServiceName("samba.ldb"); - var request = rpc.callAsyncListeners(true, // coalesce failure events - "search", - dbHandle, - searchExpr, - baseDN, - scope, - attributes); + // Issue a Get Statistics call + var request = _this.callRpc(fsm, + "samba.ldb", + "search", + [ + dbHandle, + searchExpr, + baseDN, + scope, + attributes + ]); // When we get the result, we'll need to know what type of request // we made. request.setUserData("requestType", "tree_selection_changed"); - - // Save the request object - fsm.addObject("swat.module.fsmUtils.request", request); } }); state.addTransition(trans); @@ -351,23 +340,18 @@ qx.Proto.buildFsm = function(module) "ontransition" : function(fsm, event) { - // Obtain the RPC object - var rpc = fsm.getObject("swat.module.rpc"); - // Obtain the name of the database to be connected to var dbName = fsm.getObject("dbName").getValue(); - rpc.setServiceName("samba.ldb"); - var request = rpc.callAsyncListeners(true, // coalesce failure events - "connect", - dbName); + // Issue a Get Statistics call + var request = _this.callRpc(fsm, + "samba.ldb", + "connect", + [ dbName ]); // When we get the result, we'll need to know what type of request // we made. request.setUserData("requestType", "database_name_changed"); - - // Save the request object - fsm.addObject("swat.module.fsmUtils.request", request); } }); state.addTransition(trans); diff --git a/webapps/swat/source/class/swat/module/statistics/Fsm.js b/webapps/swat/source/class/swat/module/statistics/Fsm.js index 771044172e..1aeab8a4a3 100644 --- a/webapps/swat/source/class/swat/module/statistics/Fsm.js +++ b/webapps/swat/source/class/swat/module/statistics/Fsm.js @@ -45,7 +45,7 @@ qx.Class._stopTimer = function(fsm) qx.Proto.buildFsm = function(module) { var fsm = module.fsm; - var thisClass = this; + var _this = this; /* * State: Idle @@ -67,10 +67,7 @@ qx.Proto.buildFsm = function(module) if (fsm.getPreviousState() == "State_AwaitRpcResult") { // Yup. Display the result. We need to get the request object - var request = fsm.getObject("swat.module.fsmUtils.request"); - - // We don't need the request object to be saved any more - fsm.removeObject("swat.module.fsmUtils.request"); + var request = _this.popRpcRequest(); // Display the result var gui = swat.module.statistics.Gui.getInstance(); @@ -141,15 +138,11 @@ qx.Proto.buildFsm = function(module) "ontransition" : function(fsm, event) { - var rpc = fsm.getObject("swat.module.rpc"); - - rpc.setServiceName("samba.management"); - var request = rpc.callAsyncListeners(true, // coalesce failure events - "get_statistics", - true, - true); - // Make the request object available to the AwaitRpcResult state - fsm.addObject("swat.module.fsmUtils.request", request); + // Issue a Get Statistics call + _this.callRpc(fsm, + "samba.management", + "get_statistics", + [ true, true ]); } }); state.addTransition(trans); diff --git a/webapps/swat/source/class/swat/module/statistics/Gui.js b/webapps/swat/source/class/swat/module/statistics/Gui.js index 777caa7328..28b21aa46d 100644 --- a/webapps/swat/source/class/swat/module/statistics/Gui.js +++ b/webapps/swat/source/class/swat/module/statistics/Gui.js @@ -366,6 +366,11 @@ qx.Proto.displayData = function(module, result) // Create a function for formatting dates var dateFormat = function(unixepoch) { + if (unixepoch == 0) + { + return ""; + } + var d = new Date(unixepoch * 1000); return (d.getFullYear() + "-" + ("0" + (d.getMonth() + 1)).substr(-2) + "-" + -- cgit