Re: Mapping objects

"Luke DeWitt" <[email protected]> Wed, 5 Jul 2006 09:02:20 -0300
Newsgroups gmane.comp.java.openamf.user
Organization PenguinFire Media
Message-ID <003d01c6a02a$de7814c0$7a16a8c0@pflukedev>
Hello,

Thanks for the great info. I really look forward to getting into some of the
things you mentionned, unfortunately for me, my first implemenatation is due
Friday... yikes!

I actually do have a SmackletType.as and SmackletType.java file. I have my
SmackletType in a com.flashdb.domain package, with the HelloWorld class in
the com.flashdb.services. Basically, I just took that class of the tutorial
I was using to learn this stuff and made a minor modification in order to
send across a smacklet object. I had an error in my original posting. I have
cleaned the stuff up and everything seems to be working except the very last
part, which is taking my ResultEvent object and getting it to cast correctly
to the SmackletType object. I went through debugging my code and I can see
that that Result event (called msg) should be easily transferrable to a
SmackletType object if I just use "msg.result" however I cannot get that to
work. I can see the data is coming over correctly, I can see all of the
little pieces in this result, but I just can turn that into a SmackletType
object.

My cleaned up (and should be working) AS code looks as follows...

//Import needed classes
import mx.remoting.Service;
import mx.services.Log;
import mx.rpc.RelayResponder;
import mx.rpc.FaultEvent;
import mx.rpc.ResultEvent;
import mx.remoting.PendingCall;
import mx.remoting.debug.NetDebug
NetDebug.initialize()

// initialize the Logger
var myLogger : Log = new Log (Log.DEBUG, "logger1" );

// override the default log handler
myLogger.onLog = function (message:String):Void {
   trace ("myLogger-->>>" + message );
}

//Create the service
myService = new Service ("http://localhost/helloworld/gateway", myLogger,
"com.flashdb.services.HelloWorld", null, null);

//on Data handler
function onEchoData (msg:ResultEvent){
 Object.registerClass("com.flashdb.domain.SmackletType", SmackletType);
 var temp:SmackletType = SmackletType(msg.result);
 trace(temp);
}

//on Error handler
function onEchoFault (rs : ResultEvent){
   mx.remoting.debug.NetDebug.trace ({level : "None", message : "There was a
problem: " + fault.fault.faultstring     });
}

//Buttons callbacks
callButton.onPress = function () {
 //create the remoting call
   var pc : PendingCall = myService.makeEcho();
   pc.responder = new RelayResponder(this._parent, "onEchoData",
"onEchoFault" );
}

//just clear the textfield
clearButton.onPress = function (){
   show.text = "";
}

stop();



However 'temp' comes up as null. If I attempt to trace msg or msg.result I
get [object Object]. Finally, if I am to try
trace(msg.result._smackletName), I can actually trace the string "Slots".

I have been at this for quite a while tonight and just can't get anywhere. I
may be misunderstanding some of what you had written in your email, and if
something you mentionned is something I should try I would love it if you
could clear it up a bit for me. I haven't been able to find a whole lot of
documentation on OpenAMF so this is my best resource.

Thanks again,

--LD

----- Original Message ----- 
From: "Todd Hivnor" <[email protected]>
To: <[email protected]>
Sent: Tuesday, July 04, 2006 5:32 PM
Subject: Re: [Openamf-user] Mapping objects


> You are on the right path, generally.
>
> SmackletType is defined in
> public class HelloWorld, which seems wrong. I would define SmackletType
> in SmackletType.as. SmackletType is also defined in the
> com.flashdb.services package, but this package isn't included in your
> call to Object.registerClass.
>
> I keep the same class hierarchy in Flash and Java, so if SmackletType is
> defined in the com.flashdb.services package in Java, then I create that
> exact same package in Flash. It just keeps things clear, and makes the
> class mappings simple:
>
> <custom-class-mapping>
>  <java-class>com.flashdb.services.SmackletType</java-class>
>  <custom-class>com.flashdb.services.SmackletType</custom-class>
> </custom-class-mapping>
>
> Object.registerClass("com.flashdb.services.SmackletType",
> com.flashdb.services.SmackletType);
>
> You seem to have a couple of packages in play, com.flashdb.services and
> com.flashdb.domain. This might be part of the problem.
>
> I personally don't use the underscore in front of variable names. I use
> function names like  getSmackletName() and receive values in Flash like
> smackletName. The underscore may work, but if you might experiment with
> dropping it if you can't get things to work, after getting the packages
> in line.
>
> I recommend using local HTTP proxy server to inspect the Remoting
> traffic. I personally use ServiceCapture, but there is apparently
> something else called Charles which might work. But generally these let
> you see the data flows between Java and Flash, which is really handy.
>
> You do need to implement Serializable in your Java class, as I
> understand it.
>
> OpenAMF will use introspection to dig into your Java object, and call
> all of its getters. This is convenient, but can be a hassle if you have
> getters which access data you don't want serialized. I use methods like
> fetchSmackletName(), as opposed to getSmackletName(), if I don't want
> smackletName sent to Flash.
>
> If you want to learn about the serialization process, it is helpful to
> understand that OpenAMF uses CarbonFive's ASTranslator. The ASTranslator
> documentation is pretty good.
>
> You can do a lot of great things with Java and Flash Remoting, they work
> really well together. You can serialize very complex nested objects. I
> personally define my whole application interface in Java, and then have
> Flash just render it. So can change my user interface from Java, without
> recompiling the .swf. When I first started using Remoting, I didn't take
> the time to understand how powerful the object mapping stuff is. I later
> rewrote the app using object mapping, and the code is much simpler &
> cleaner. So I would encourage you to take the time to fully experiment
> with the object mapping stuff, before writing any real application code.
>
> One thing to understand is that the Java-->Flash serialization is more
> powerful than the Flash->Java serialization. If you have Object A which
> references Object B, and Object B references Object A, then you have a
> circular reference loop. When serializing from Java to Flash this is
> fine. Java will send one copy of each object, and not get confused. If
> you sent this back, from Flash to Java, then Flash will lock up. It
> can't resolve the circular reference, and gets hopelessly confused. So,
> watch out for that. You can do a recursion check in Flash, to detect this.
>
> Here is my code, which has a couple of references to things you don't
> have. It can easily be adapted. The code will recursively walk through
> an object, building up an array of the all the objects encountered thus
> far. If it finds a duplicate, then there is a recursive loop, so it
> reports the problem and bails out.
>
> class LearnerService {
>
>    /** Return true of the object is Ok.
>     * Also return true if we are not currently checking for recursion.
>     * If there is a problem trace it, and set the problematicObject
> variable
>     */
>
>    private static var problematicObject;
>    public static function recursionCheck(currObject : Object) : Boolean {
>        if (DebugConfig.checkRecursionInEvents()) {
>            trace(Log.L_INFO+ "Performing Recursion Check ...");
>            var result : Boolean =
> LearnerService.recursionCheckHelper(currObject, new Array());
>
>            if (result) {
>                trace(Log.L_INFO+ "Recursion Check Passed! ");
>            }
>            return result;
>        } else {
>            return true;
>        }
>    }
>
>    private static function recursionCheckHelper(currObject : Object,
> objectsFound : Array) : Boolean {
>        var childObject : Object;
>        var i : Number;
>        var hasError : Boolean = false;
>        for (var key : String in currObject) {
>            childObject = currObject[key];
>            if ( (typeof(childObject) == "object") ||
> (typeof(childObject) == "movieclip"))  {
>                for (i=0; i<objectsFound.length; i++) {
>                    if (childObject == objectsFound[i]) {
>                        trace(Log.L_ERROR+ "Found recursive child
> object=" + childObject + " with key=" + key +
>                                " in object=" + currObject + " inside
> runEvent.");
>                        LearnerService.problematicObject =childObject;
>                        return false;
>                    }
>                }
>                objectsFound.push(childObject);
>
>                // recursively check
>                if (recursionCheckHelper(childObject, objectsFound) ==
> false) {
>                    hasError = true;
>                    break;
>                }
>
>            } else if (childObject == null) {
>                // no need to check null's
>            } else if (
>                (typeof(childObject) == "string") ||
>                (typeof(childObject) == "boolean") ||
>                (typeof(childObject) == "number") ||
>                (typeof(childObject) == "function")
>                ) {
>                // no need to check these things
>
>
>            } else {
>                trace(Log.L_ERROR+ "Not an object: child object=" +
> childObject + " is " + typeof(childObject) + " with key=" + key +
>                        " in object=" + currObject + " inside runEvent.");
>            }
>        }
>        return ! hasError;
>    }
> }
>
>
>
> Luke DeWitt wrote:
>> Hey Guys,
>>
>> I finally got OpenAMF up and working (had to use the last release
>> though) and I am am so sorry to ask this question again, but I have
>> read through a bunch of the mail list archives and I am getting nowhere!
>>
>> I used this tutorial here:
>> http://www.flash-db.com/Tutorials/helloOpenamf/hello2.php?page=4 to
>> get started in the wonderful world that is java to flash remoting.
>> This was a simple little tutorial, but I am looking to do more than
>> just echo a String. At this moment I am trying to send a custom java
>> object (SmackletType) to Flash. I figure that if I can get this
>> working I will have no problem doing the next couple of steps which
>> are just extenstions of this.
>>
>> Here is some code to help people visualize what I am doing:
>>
>> Java Code for Smacklet Type:
>>
>> package com.flashdb.domain;
>>
>> import java.io.Serializable;
>>
>> public class SmackletType implements Serializable {      // does this
>> need to be serializable?
>>
>>  // class properties
>>  private String _smackletName;
>>  private String _smackletTeaseLink;
>>  private String _smackletLink;
>>  private String _smackletThumbnail;
>>
>>  // constructor
>>
>>  public SmackletType(String smackletName, String smackletLink, String
>> smackletTeaseLink, String smackletThumbnail) {
>>
>>   _smackletThumbnail = smackletThumbnail;
>>   _smackletTeaseLink = smackletTeaseLink;
>>   _smackletLink = smackletLink;
>>   _smackletName = smackletName;
>>
>>  } // SmackletType constructor
>>
>>  // getters and setters
>>
>>  public String get_smackletLink() {
>>   return _smackletLink;
>>  }
>>
>>  public void set_smackletLink(String link) {
>>   _smackletLink = link;
>>  }
>>
>>  public String get_smackletName() {
>>   return _smackletName;
>>  }
>>
>>  public void set_smackletName(String name) {
>>   _smackletName = name;
>>  }
>>
>>  public String get_smackletTeaseLink() {
>>   return _smackletTeaseLink;
>>  }
>>
>>  public void set_smackletTeaseLink(String teaseLink) {
>>   _smackletTeaseLink = teaseLink;
>>  }
>>
>>  public String get_smackletThumbnail() {
>>   return _smackletThumbnail;
>>  }
>>
>>  public void set_smackletThumbnail(String thumbnail) {
>>   _smackletThumbnail = thumbnail;
>>  }
>>
>> } // SmackletType class
>>
>>
>> ActionScript Code for SmackletType:
>>
>> class SmackletType {
>>
>>  // class properties
>>  private var _smackletName:String;
>>  private var _smackletTeaseLink:String;
>>  private var _smackletLink:String;
>>  private var _smackletThumbnail:String;
>>
>>  // constructor
>>
>>  public function SmackletType(smackletName:String,
>> smackletLink:String, smackletTeaseLink:String, smackletThumb:String) {
>>
>>   _smackletThumbnail = smackletThumb;
>>   _smackletTeaseLink = smackletTeaseLink;
>>   _smackletLink = smackletLink;
>>   _smackletName = smackletName;
>>
>> } // SmackletType constructor
>>
>>  // getters and setters
>>  public function get smackletName():String {
>>   return _smackletName;
>>  }
>>
>>  public function set smackletName(sSmackletName:String):Void {
>>   _smackletName = sSmackletName;
>>  }
>>
>>   public function get smackletLink():String {
>>   return _smackletLink;
>>  }
>>
>>  public function set smackletLink(sSmackletLink:String):Void {
>>   _smackletLink = sSmackletLink;
>>  }
>>
>>  public function set smackletTeaseLink(sSmackletTeaseLink:String):Void {
>>   _smackletTeaseLink = sSmackletTeaseLink;
>>  }
>>
>>  public function get smackletTeaseLink():String {
>>   return _smackletTeaseLink;
>>  }
>>
>>   public function get smackletThumbnail():String {
>>   return _smackletThumbnail;
>>  }
>>
>>  public function set smackletThumbnail(sSmackletThumbnail:String):Void {
>>   _smackletThumbnail = sSmackletThumbnail;
>>  }
>>
>> } // SmackletType class
>>
>> I have added the following into my openamf-config.xml file:
>>
>> <custom-class-mapping>
>>   <java-class>com.flashdb.domain.SmackletType</java-class>
>>   <custom-class>SmackletType</custom-class>
>> </custom-class-mapping>
>>
>> This is the simple piece of java code I have edited to send my object:
>>
>> package com.flashdb.services;
>>
>> import com.flashdb.domain.*;
>>
>> public class HelloWorld {
>>
>>  SmackletType testSmackletType = new SmackletType("Slots",
>> "http://www.google.com", "http://www.google.ca", "00.gif");
>>
>>  public SmackletType makeEcho(){
>>         return testSmackletType;
>>     }
>>
>> }
>>
>> And Finally, the ActionScript code to actually call for the object:
>>
>> //Import needed classes
>> import mx.remoting.Service;
>> import mx.services.Log;
>> import mx.rpc.RelayResponder;
>> import mx.rpc.FaultEvent;
>> import mx.rpc.ResultEvent;
>> import mx.remoting.PendingCall;
>> import mx.remoting.debug.NetDebug
>> NetDebug.initialize()
>> // initialize the Logger
>> var myLogger : Log = new Log (Log.DEBUG, "logger1" );
>> // override the default log handler
>> myLogger.onLog = function (message : String ) : Void {
>>    trace ("myLogger-->>>" + message );
>> }
>>
>> //Create the service
>> myService = new Service ("http://localhost/helloworld/gateway",
>> myLogger, "com.flashdb.services.HelloWorld", null, null);
>> Object.registerClass("com.flashdb.domain.SmackletType", SmackletType);
>> //on Data handler
>> //function onEchoData (msg : ResultEvent){
>> function onEchoData (msg : SmackletType){
>>    mx.remoting.debug.NetDebug.trace ({level : "Debug", message :
>> "onCategoryData" });
>> //   show.text = msg.result;
>>    //var temp:SmackletType = msg;
>>    var temp:SmackletType = msg;
>>    trace(temp.smackletName() + "            HOOGEY BOOGEY!");
>> }
>> //on Error handler
>> function onEchoFault (rs : ResultEvent){
>>    mx.remoting.debug.NetDebug.trace ({level : "None", message : "There
>> was a problem: " + fault.fault.faultstring     });
>> }
>> //Buttons callbacks
>> callButton.onPress = function () {
>>    //create the remoting call
>>    var pc : PendingCall = myService.makeEcho();
>>    pc.responder = new RelayResponder (this._parent, "onEchoData",
>>    "onEchoFault" );
>> }
>> //just clear the textfield
>> clearButton.onPress = function (){
>>    show.text = "";
>> }
>> stop();
>>
>>
>> When I run my program and hit the "callbutton", I get this...
>>
>> myLogger-->>>7/4 15:15:2 [INFO] logger1: Creating Service for
>> com.flashdb.services.HelloWorld
>> myLogger-->>>7/4 15:15:2 [INFO] logger1: Creating gateway connection
>> for http://localhost/helloworld/gateway
>> myLogger-->>>7/4 15:15:2 [INFO] logger1: Successfully created Service
>> myLogger-->>>7/4 15:15:3 [INFO] logger1: Invoking makeEcho on
>> com.flashdb.services.HelloWorld
>> undefined            HOOGEY BOOGEY!
>> myLogger-->>>7/4 15:15:3 [INFO] logger1:
>> com.flashdb.services.HelloWorld.makeEcho() returned {_smackletLink:
>> "http://www.google.com",
>>      _smackletName: "Slots",
>>      _smackletTeaseLink: "http://www.google.ca",
>>      _smackletThumbnail: "00.gif"}
>>
>>
>> I just want to be able to get that info that is being passed into
>> Flash to become my SmackletType object. Can anyone give me a hand?
>> This stuff is making my life so much easier right now over web
>> services, and any help I could get would be greatly appreciated.
>>
>> Thank you!
>>
>> --LD
>>
>
>
> Using Tomcat but need to do more? Need to support web services, security?
> Get stuff done quickly with pre-integrated technology to make your job 
> easier
> Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
> http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
> _______________________________________________
> Openamf-user mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/openamf-user
> 


Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642