Forget the question. I found a solution that consists in walking through 
the Qooxdoo value object graph and transform them recursively into JS 
untyped Object before sending them to the server. The reverse operation 
is done when receiving the result. When hitting a qx.core.Object 
descendant, only its public properties are processed. Moreover, a 
special handling is performed for qx.data.IListData that I want to map 
to java.util.List.

For those who are interested, find below the 2 helper methods :

    /**
     * Transforms a Qooxdoo object graph into a simple untyped JS object 
graph
     * ready to be sent to server-side. Only public properties are handled.
     * @param {var} root the object graph containing Qooxdoo objects.
     * @return {var} the corresponding untyped JS Object graph.
     */
    untypeObjectGraph : function(root) {
      var untypedRoot = null;
      if(root != null) {
        if(root instanceof Array) {
          untypedRoot = new Array();
          for(var i = 0; i < root.length; i++) {
            untypedRoot[i] = this.untypeObjectGraph(root[i]);
          }
        } else if(root instanceof qx.core.Object) {
          untypedRoot = new Object();
          untypedRoot["class"] = root.classname;
          if(qx.Class.implementsInterface(root, qx.data.IListData)) {
            untypedRoot["array"] = this.untypeObjectGraph(root.toArray());
          } else {
              var clazz = root.constructor;
              var properties = qx.Class.getProperties(clazz);
              for(var i = 0; i < properties.length; i++) {
                var propertyName = properties[i];
                if(propertyName.charAt(0) != "_") {
                  untypedRoot[propertyName] = 
this.untypeObjectGraph(root.get(propertyName));
                }
              }
          }
        } else if (root instanceof Object){
          untypedRoot = new Object();
          for(var member in root) {
            untypedRoot[member] = this.untypeObjectGraph(root[member]);
          }
        } else {
          untypedRoot = root;
        }
      }
      return untypedRoot;
    }
   
    /**
     * Transforms an untyped JS object graph into a Qooxdoo object graph.
     * All JS object members are considered public properties whenever 
the class
     * hint refers to a Qooxdoo object.
     * @param {var} root the object graph containing untyped JS Object.
     * @return {var} the corresponding object graph containing typed 
Qooxdoo objects.
     */
    typeObjectGraph : function(root) {
      var typedRoot = null;
      if(root != null) {
        if(root instanceof Array) {
          typedRoot = new Array();
          for(var i = 0; i < root.length; i++) {
            typedRoot[i] = this.typeObjectGraph(root[i]);
          }
        } else if(root instanceof Object) {
            var className = root["class"];
            if(className && qx.Class.isDefined(className)) {
            var typedClass = qx.Class.getByName(className);
            typedRoot = new typedClass();
            if(qx.Class.implementsInterface(typedRoot, qx.data.IListData)) {
              typedRoot.append(this.typeObjectGraph(root["array"]));
            } else {
              for (var propertyName in root) {
                if(propertyName != "class") {
                  typedRoot.set(propertyName, 
this.typeObjectGraph(root[propertyName]));
                }
              }
            }
          } else {
            typedRoot = new Object();
            for(var member in root) {
              typedRoot[member] = this.typeObjectGraph(root[member]);
            }
          }
        } else {
          typedRoot = root;
        }
      }
      return typedRoot;
    }

Regards,
Vincent


Vincent Vandenschrick a écrit :
> Hi all,
> I've defined a complete class hierarchy of value objects that need to 
> be exchanged with a Java backend through Qooxdoo RPC.
>
> This implies, for service method parameters:
>
> -> transforming JS objects to JSON and then to their equivalent Java 
> beans instances on the server with automatic class hinting (JS objects 
> class names match Java beans class names with default contructors, and 
> so on...); I've overriden the "resolveClassHint" method of 
> RemoteCallUtils to achieve this.
>
> -> doing it also the reverse way with automatic client side class 
> hinting; I've overriden the "filter" method of  RemoteCallUtils to 
> include a "class" property to each transfered JSON structure so that 
> it can be leveraged on the client side to construct their equivalent 
> JS object.
>
>
> All the JS value objects inherit (even indirectly) from qx.core.Object 
> to leverage properties, event handling, .... The first shot ended up 
> with a "too much recusion" JS error. Debugging the execution code 
> shows that all the value object members are recrusively serialized to 
> JSON, and qx.core.Object holds a lot ;-)
>
> So, here is the question : What is the best way to plug-in a custom 
> JSON serialization/de-serialization strategy on the client side ? It 
> seems that the qx.util.Json static class is responsible for this but I 
> don't have a clue on how to cleanly override its default behavior.
>
> Thanks for any hint.
> Regards,
> Vincent
>


-- 
Vincent Vandenschrick
 Jspresso Framework
 http://www.jspresso.org


------------------------------------------------------------------------------
Register Now for Creativity and Technology (CaT), June 3rd, NYC. CaT
is a gathering of tech-side developers & brand creativity professionals. Meet
the minds behind Google Creative Lab, Visual Complexity, Processing, & 
iPhoneDevCamp asthey present alongside digital heavyweights like Barbarian
Group, R/GA, & Big Spaceship. http://www.creativitycat.com 
_______________________________________________
qooxdoo-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/qooxdoo-devel

Reply via email to