dbus-service : Map JS object method with DBus agent
authorFrederic PAUT <frederic.paut@linux.intel.com>
Thu, 4 Apr 2013 14:48:17 +0000 (16:48 +0200)
committerFrederic PAUT <frederic.paut@linux.intel.com>
Thu, 4 Apr 2013 14:48:17 +0000 (16:48 +0200)
1  2 
cloudeebus/cloudeebus.js
doc/agent/client.html
doc/agent/server.html

@@@ -217,73 -217,7 +217,86 @@@ cloudeebus.Service.prototype.remove = f
        this.wampSession.call("serviceRelease", arglist).then(ServiceRemovedSuccessCB, errorCB);
  };
  
- cloudeebus.Service.prototype._addMethod = function(objectPath, objectJS, method, nArgs) {
 -cloudeebus.Service.prototype.addAgent = function(objectPath, xmlTemplate, successCB, errorCB) {
++cloudeebus.Service.prototype._searchMethod = function(ifName, method, objectJS) {
 +
-       var self = this;
-       var methodId = self.name + "#" + objectPath + "#" + method;
-       var object = objectJS;
-       
-       objectJS.wrapperFunc[method] = function() {
-               var result;
-               if (arguments.length < nArgs || arguments.length > nArgs + 2)
-                       throw "Error: method " + method + " takes " + nArgs + " parameters, got " + arguments.length + ".";
-               var args = [];
-               var successCB = null;
-               var errorCB = null;
-               var methodId = arguments[0];
-               var callDict = JSON.parse(arguments[1]);
-               for (var i=0; i < nArgs; i++ )
-                       args.push(arguments[i]);
-               if (arguments.length > nArgs)
-                       successCB = arguments[nArgs];
-               if (arguments.length > nArgs + 1)
-                       errorCB = arguments[nArgs + 1];
-               
-               var str_exec = "object.prototype."+method+"()";
-               try {
-                       result = eval(str_exec);
-                       self._returnMethod(methodId, callDict.callIndex, true, result);         
-               }
-               catch (e) {
-                       alert(arguments.callee.name + "-> Method callback exception: " + e);
-                       self._returnMethod(methodId, callDict.callIndex, false, e);             
-               }
-       };
++      var funcToCall = null;
 +      
-       self._registerMethod(methodId, objectJS.wrapperFunc[method]);
++      // Check if 'objectJS' has a member 'interfaceProxies' with an interface named 'ifName' 
++      // and a method named 'method'
++      if (objectJS.interfaceProxies && objectJS.interfaceProxies[ifName] &&
++              objectJS.interfaceProxies[ifName][method]) {
++              funcToCall = objectJS.interfaceProxies[ifName][method];
++      } else {
++              // retrieve the method directly from 'root' of objectJs
++              funcToCall = objectJS[method];
++      }
 +
-       
++      return funcToCall;
++}
++
++cloudeebus.Service.prototype._addMethod = function(objectPath, ifName, method, objectJS) {
++
++      var service = this;
++      var methodId = this.name + "#" + objectPath + "#" + ifName + "#" + method;
++      var funcToCall = this._searchMethod(ifName, method, objectJS);
++
++      if (funcToCall == null)
++              cloudeebus.log("Method " + method + " doesn't exist in Javascript object");
++      else {
++              objectJS.wrapperFunc[method] = function() {
++                      var result;
++                      var methodId = arguments[0];
++                      var callDict = JSON.parse(arguments[1]);
++                      try {
++                              result = funcToCall.apply(objectJS, callDict.args);
++                              service._returnMethod(methodId, callDict.callIndex, true, result);
++                      }
++                      catch (e) {
++                              cloudeebus.log(arguments.callee.name + "-> Method callback exception: " + e);
++                              service._returnMethod(methodId, callDict.callIndex, false, e.message);
++                      }
++              };
++              this._registerMethod(methodId, objectJS.wrapperFunc[method]);
++      }
++};
++
++cloudeebus.Service.prototype._addSignal = function(objectPath, signal, objectJS) {
++      var service = this;
++
++      if (objectJS[signal] != undefined && objectJS[signal] != null)
++              cloudeebus.log("Can not create new method to emit signal '" + signal + "' in object JS this method already exist!");
++      else {
++              objectJS[signal] = function() {
++                      var result = JSON.parse(arguments[0]);
++                      service.emitSignal(objectPath, signal, result);
++              };
++    }
 +};
 +
 +cloudeebus.Service.prototype._createWrapper = function(xmlTemplate, objectPath, objectJS) {
 +      var self = this;
 +      var parser = new DOMParser();
 +      var xmlDoc = parser.parseFromString(xmlTemplate, "text/xml");
-       var interfaces = xmlDoc.getElementsByTagName("interface");
++      var ifXml = xmlDoc.getElementsByTagName("interface");
 +      objectJS.wrapperFunc = []
-       for (var i=0; i < interfaces.length; i++) {
- //            var ifName = interfaces[i].attributes.getNamedItem("name").value;
-               var ifChild = interfaces[i].firstChild;
++      for (var i=0; i < ifXml.length; i++) {
++              var ifName = ifXml[i].attributes.getNamedItem("name").value;
++              var ifChild = ifXml[i].firstChild;
 +              while (ifChild) {
 +                      if (ifChild.nodeName == "method") {
-                               var nArgs = 0;
-                               var metChild = ifChild.firstChild;
-                               while (metChild) {
-                                       if (metChild.nodeName == "arg" &&
-                                               metChild.attributes.getNamedItem("direction") != null && 
-                                               metChild.attributes.getNamedItem("direction").value == "in")
-                                                       nArgs++;
-                                       metChild = metChild.nextSibling;
-                               }
 +                              var metName = ifChild.attributes.getNamedItem("name").value;
-                               self._addMethod(objectPath, objectJS, metName, nArgs);
++                              self._addMethod(objectPath, ifName, metName, objectJS);
++                      }
++                      if (ifChild.nodeName == "signal") {
++                              var metName = ifChild.attributes.getNamedItem("name").value;
++                              self._addSignal(objectPath, metName, objectJS);
 +                      }
 +                      ifChild = ifChild.nextSibling;
 +              }
 +      }
 +};
 +
 +cloudeebus.Service.prototype.addAgent = function(objectPath, xmlTemplate, objectJS, successCB, errorCB) {
        function ServiceAddAgentSuccessCB(objPath) {
                if (successCB) {
                        try { // calling dbus hook object function for un-translated types
@@@ -51,6 -51,7 +51,7 @@@ function signalHandler(aSum) 
  
  function gotProxy(proxy) {
    logCB(proxy);
 -  proxy.connectToSignal("org.cloudeebus.Sample", "ResultChanged", signalHandler);
++  proxy.connectToSignal("org.cloudeebus.Sample1", "ResultChanged", signalHandler);
    for (var i=-10; i<10; i++)
      proxy.Add(i,i*2,gotAddResult,errorCB);
    sampleProxy = proxy;
@@@ -17,7 -17,7 +17,7 @@@
     <body>
          <center><h1>cloudeebus</h1></center>
          <br>
--              <textarea style="width:80%" rows="32" id="script">var sampleXml= '<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"\n"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">\n<node><interface name="org.cloudeebus.Sample"><method name="Release"></method><method name="Add"><arg type="i" name="arg1"/><arg type="i" name="arg2"/><arg type="i" name="result" direction="out"/></method><signal name="ResultChanged"><arg type="i" name="result"/></signal></interface></node>';
++              <textarea style="width:80%" rows="32" id="script">var sampleXml= '<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"\n"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">\n<node><interface name="org.cloudeebus.Sample1"><method name="Release"></method><method name="Add"><arg type="i" name="arg1"/><arg type="i" name="arg2"/><arg type="i" name="result" direction="out"/></method><signal name="ResultChanged"><arg type="i" name="result"/></signal></interface><interface name="org.cloudeebus.Sample2"><method name="Div"><arg type="i" name="arg1"/><arg type="i" name="arg2"/><arg type="i" name="result" direction="out"/></method></interface></node>';
  cloudeebus.log = function(msg) {
    document.getElementById("log").innerHTML += msg + "\n";
  }
@@@ -30,50 -30,34 +30,27 @@@ function errorCB(error) 
    cloudeebus.log(error.desc ? error.desc : error);
  }
  
 -function addCalled(args) {
 -  var methodId = arguments[0];
 -  var objPath = methodId.split("#")[1];
 -  var callDict = JSON.parse(arguments[1]);
 -  cloudeebus.log("Method called: " + methodId);
 -  result = callDict.args[0] + callDict.args[1];
 -  cloudeebus.log("Add: " + callDict.args[0] + " + " + callDict.args[1] + " = " + result);
 -  cloudeebus.SessionBus().service.returnMethod(methodId, callDict.callIndex, true, result);
 -  cloudeebus.log("Emit signal 'ResultChanged' with value " + result);
 -  cloudeebus.SessionBus().service.emitSignal(objPath, "ResultChanged", result);
 -}
 -
 -function releaseCalled() {
 -  var methodId = arguments[0];
 -  var callDict = JSON.parse(arguments[1]);
 -  cloudeebus.log("Method called: " + methodId);
 -  cloudeebus.SessionBus().service.returnMethod(methodId, 0, true, null);
 -  cloudeebus.SessionBus().service.wampSession.unsubscribe(methodId);  
 -  cloudeebus.SessionBus().service.delAgent("/org/cloudeebus/Sample", logCB, errorCB);
 -  cloudeebus.SessionBus().service.remove(logCB, errorCB);
 -}
 +sampleObjectHandler = {
 +  Add: function(a,b) {
++    this.ResultChanged(a+b);
 +    return a+b;
 +  }, 
 +  Release: function() {
-     return;
++    cloudeebus.SessionBus().service.delAgent("/org/cloudeebus/Sample", logCB, errorCB);
++    cloudeebus.SessionBus().service.remove(logCB, errorCB);
 +  },
-   interfaceProxies = {
-     "org.free.props": {
-       Release: function() {
-         return;
-         }
++  interfaceProxies : {
++    "org.cloudeebus.Sample2" : {
++      Div: function(a,b) {
++        return a/b;
++      } 
 +    }
 +  }
 +};
  
- function addCalled(args) {
-   var methodId = arguments[0];
-   var objPath = methodId.split("#")[1];
-   var callDict = JSON.parse(arguments[1]);
-   cloudeebus.log("Method called: " + methodId);
-   result = callDict.args[0] + callDict.args[1];
-   cloudeebus.log("Add: " + callDict.args[0] + " + " + callDict.args[1] + " = " + result);
-   cloudeebus.SessionBus().service.returnMethod(methodId, callDict.callIndex, true, result);
-   cloudeebus.log("Emit signal 'ResultChanged' with value " + result);
-   cloudeebus.SessionBus().service.emitSignal(objPath, "ResultChanged", result);
- }
- function releaseCalled() {
-   var methodId = arguments[0];
-   var callDict = JSON.parse(arguments[1]);
-   cloudeebus.log("Method called: " + methodId);
-   cloudeebus.SessionBus().service.returnMethod(methodId, 0, true, null);
-   cloudeebus.SessionBus().service.wampSession.unsubscribe(methodId);  
-   cloudeebus.SessionBus().service.delAgent("/org/cloudeebus/Sample", logCB, errorCB);
-   cloudeebus.SessionBus().service.remove(logCB, errorCB);
- }
  function serviceAdded(service) {
    var agentName = "/org/cloudeebus/Sample"; // = DBUS object name
- //   cloudeebus.SessionBus().service.registerMethod(service.name + "#" + agentName + "#Add",addCalled);
- //  cloudeebus.SessionBus().service.registerMethod(service.name + "#" + agentName + "#Release",releaseCalled);
-    cloudeebus.SessionBus().service.addAgent(agentName, sampleXml, sampleObjectHandler, logCB, errorCB);
 -  var ifName = "org.cloudeebus.Sample"
 -  cloudeebus.SessionBus().service.registerMethod(service.name + "#" + agentName + "#" + ifName + "#Add",addCalled);
 -  cloudeebus.SessionBus().service.registerMethod(service.name + "#" + agentName + "#" + ifName + "#Release",releaseCalled);
 -  cloudeebus.SessionBus().service.addAgent(agentName, sampleXml, logCB, errorCB);
++  cloudeebus.SessionBus().service.addAgent(agentName, sampleXml, sampleObjectHandler, logCB, errorCB);
  }
  
  function connectSuccess() {