explorers’ club


Tutorial: AppCoreLib’s XMLDataBroker, mock XML data & Cairngorm
Monday, May 12, 2008, 6:46 pm
Filed under: actionScript, appCoreLib, cairngorm, client side, development, flex, projects, server side, tutorial, xml

The potential of Flex for rapid prototyping and general application development is amazingly fast. With some mock data and a basic user-experience (UX) scenario, a developer can create a functioning sample application in a matter of minutes.

If you are developing either a full blown RIA or a prototype application then you have probably at least heard of Cairngorm. If not, familiarize yourself with the basics here – link. I use a stripped down version of it for almost every project I have worked on. It works beautifully

I plan to show you an example of using AppCoreLib’s XMLDataBroker to fill in some mock XML data for your commands. This is helpful when you have a basic idea of an API/services but they are not returning anything or not ready to be tapped or you wanna test out a service’s result format before the server developers implement it.

Before I continue, let’s set one or two rules about this tutorial.

  • the expected format for the returned data is XML
  • the mock XML data format will reflect the same format of the actual service’s result

Firstly let’s take a look at a basic Cairngorm command. This is a stripped down version so you won’t see any delegate-type references in here.

package com.foo.controller.commands
{
    import com.adobe.cairngorm.commands.ICommand;
    import com.adobe.cairngorm.control.CairngormEvent;
    import com.foo.business.Services;

    import mx.rpc.AsyncToken;
    import mx.rpc.IResponder;
    import mx.rpc.events.ResultEvent;
    import mx.rpc.http.HTTPService;

    public class SampleCairngormCommand implements ICommand, IResponder
    {
        private var _vo:Object = {};

        public function execute (event:CairngormEvent):void
        {
            var call:HTTPService = Services.getInstance().httpService;
            call.url = "http://www.foo.com/someService";

            var param:Object = {};

            var token:AsyncToken = call.send(param);
            token.addResponder(this);
        }

        public function result (data:Object):void
        {
            var xmlResult:XML = ResultEvent(data).result as XML;
        }

        public function fault (info:Object):void
        {
        }

    }
}

So now with about 5 lines of code, I will show you how to inject mock XML data for creating a response that fits within the Cairngorm command structure:

package com.foo.controller.commands
{
    import appCoreLib.business.XMLDataBroker;
    import appCoreLib.events.XMLLoadEvent;

    import com.adobe.cairngorm.commands.ICommand;
    import com.adobe.cairngorm.control.CairngormEvent;

    import mx.rpc.IResponder;

    public class SampleCairngormCommand implements ICommand, IResponder
    {
        public function execute (event:CairngormEvent):void
        {
            var x:XMLDataBroker = new XMLDataBroker();
            x.addEventListener(XMLLoadEvent.XML_LOAD_SUCCESS, result);
            x.addEventListener(XMLLoadEvent.XML_LOAD_FAILURE, fault);
            x.loadXML("assets/xml/someMockXMLData.xml");

            /* var call:HTTPService = Services.getInstance().httpService;
            call.url = "http://www.foo.com/someService";

            var param:Object = {};

            var token:AsyncToken = call.send(param);
            token.addResponder(this); */
        }

        public function result (data:Object):void
        {
            var xmlResult:XML = XMLLoadEvent(data).xml;
            //var xmlResult:XML = ResultEvent(data).result as XML;
        }

        public function fault (info:Object):void
        {
        }
    }
}

That’s it! Simple, effective and most importantly, easy to remove once an actual service response is available.



Tutorial: handling service validation errors & cairngorm – part 3
Friday, April 25, 2008, 8:52 pm
Filed under: actionScript, cairngorm, client side, development, flex, server side, tutorial, validation

recap

Last time we discussed two methods for handling service validation errors in a Cairngorm application. The first method was to borrow from some AS2/ARP techniques by passing a reference. The second method was to leverage the event nature of Flex and use a central event dispatcher type approach. Both of these have their advantages and certainly have their disadvantages. This last approach will try to take the best from both worlds and combine them to alleviate some of the problems we encountered.

ServiceValidationErrorManager method

Again you will have to pardon the names here but this gets the point across. There is no doubt what this puppy does. For the sake of simplicity I will continue to call it “the manager”. Ok so the manager is a) a Singleton-type class and b) has at its root a property called currentClient. Here’s a peek:

pacakge com.foo.managers
{
     public class ServiceValidationErrorManager
     {
         public var currentClient:IServiceValidationClient;
         static private var _instance:ServiceValidationErrorManager;
         static public function getInstance (){}//you get the idea....
     }
}

The idea is pretty much the same as the first method in that our views serve as the IServiceValidationClient. When dispatching a Cairngorm event we register the client with the manager class (if applicable). Basically that is achieved by:

ServiceValidationErrorManager.getInstance().currentClient = this; //the view/implementor

So this fixes issues from the other two methods. Firstly it eliminates the need to pass the view to the command. Secondly it doesn’t get us tangled up in all these IEventDispatcher methods.

Now upon a response that has some validation errors, we can simply say:

ServiceValidationErrorManager.getInstance().currentClient.handleValidationErrors();

The other nice thing is that we needn’t really worry about garbage collection because we’re only dealing with one property on one class. It gets overwritten when needed. Now you may be asking why use a separate manager type class. Well you may want to have some logic in there for various things including queuing the views, and other crap I can’t think of right now.

summary

This could easily be adapted to a preexisting singleton model so you can reduce the need for the additional class. You just gotta remember its there. Also, even though you needn’t clear out the property on the manager, it does make good practice. Having a manager class allows you to do just that: manage validation errors appropriately. Of course this might be a grotesque oversimplification of a very serious need, you get the gist of the idea.

pros:

  • OOP
  • negates the use of IEventDispatcher logic in both view and command
  • provides a centralized place to handle more robust registration for error handling

cons:

  • adds another class
  • still doesn’t address timing issue, unless you implement some queuing mechanism in the manager when setting the current client
  • not as elegantly simple as method one

That’s it folks. 3 very ugly solutions to an ugly problem. Chime in and let me know how you do it. Thanks.



Tutorial: handling service validation errors & cairngorm – part 2
Friday, April 25, 2008, 6:52 pm
Filed under: actionScript, development, flex, server side, tutorial, validation

recap

So last we left off we had discussed the reference method for passing info back and forth to the relevant view notifying the user about needed data changes. If you need a refresher check part 1. This next way of handling service validation errors is very simple, however it requires a bit more work.

central event dispatcher method

This method requires two additional classes which we will call something like ServiceValidationEventDispatcher & ServiceValidationErrorEvent. I am not too good at naming things off the top of my head so feel free to lay into me on this one. The point is this: We want a globally accessible IEventDispatcher class we can tap into from both the views and the commands. And we want an event that we can attach some data to in order to pass it back. The SVED is pretty straight forward so I won’t create that here. Just know its an IEventDispatcher and I would make it a Singleton-type class. The new event class should probably look kinda like this:

package com.foo.events
{
     public class ServiceValidationErrorEvent extends Event
     {
          static public const SERVICE_VALIDATION_ERRORS:String = "serviceValidationErrors";

          public var errors:Array = [];
     }
}

hooking it up

We are hanging onto the interface from part 1 but we’re gonna modify it for this particular implementation. Instead of the passing the array to the handleValidationErrors, we are gonna pass it a ServiceValidationErrorEvent as the parameter.

Another change we do is instead of passing the view as a value on the Cairngorm event, we will tell the ServiceValidationEventDispatcher instance to register our handleValidationError method for the ServiceValidationErrorEvent:

ServiceValidationEventDispatcher.getInstance().addEventListener(ServiceValidationErrorEvent.SERVICE_VALIDATION_ERRORS, handleValidationError);

Now at this point we have a few choices. We need to make sure that we are doing our best to preserve memory and garbage collection. One way is to use a weakReference when adding the event handler. I am not a fan of this because a) we cannot control garbage collection and b) it leaves too many doors open for timing issues.

Another means would be to make sure that we always trigger the handleValidationError method on our view, checking the errors array’s length. For one reason we will be removing the event handler from the SVED. But this means then we always have to trigger it from the SVED within the command regardless of the response’s success. The other way would be to have yet another handler on the view for successful validation so that you can go ahead and remove the handler. This means fattening up our interface. There are so many little things you could do here, but the main purpose is that we are using events to trigger out handlers rather than direct triggering via a reference.

summary

I really don’t dig this implementation because it adds more classes and more crap to remember to do. But here is a pro/con list for this method:

pros:

  • better OOP than the ref method
  • decouples the view from the command
  • leverages the event driven nature of the flash player

cons:

  • adds additional weight to your project
  • prone to timing issues
  • more stuff to remember to do

Ok so part 3 is coming next. It will basically be a blending of the two previous methods. See ya then



as3pogkit
Thursday, March 20, 2008, 7:11 pm
Filed under: actionScript, amf, amfphp, development, flash, flex, mysql, orm, php, pog, remoting, tutorial

It seems based on initial feedback that the Flex + AMFPHP + POG tutorial has peeked the interest of many in the RIA developer community. Of course my tutorial was simply an introduction and how-to to getting these 3 technologies playing together. However it did not go beyond that and as such didn’t present some issues that a real implementation of this environment poses.

I set up a project on Google Code in order to not only present further updates for this framework to the community, but also to encourage collaboration and discovery.  The goals of the project include:

  • successful implementation of a remoting solution utilizing AS3 and POG
  • AS3 code generation based on POG objects

as3pogkit – link



tutorial: Flex + AMFPHP + POG
Wednesday, March 12, 2008, 5:30 pm
Filed under: actionScript, amf, amfphp, cairngorm, development, flash, flex, mysql, orm, php, pog, remoting, tutorial, xml

Preface

If you are no stranger to the concept of a Rich Internet Application (aka. RIA) and the different constituents that make up a RIA, you can skip this introduction. This tutorial will help developers to setup a Flex application to a database using PHP while minimizing manual database queries. Let’s familiarize ourselves with a few basic RIA concepts. Generally a RIA is comprised of 3 main components:

  • the client – no, not your client that sends the checks, but rather the Graphical (User) Interface that a user of a RIA interacts with. In our case, this the flex client that is deployed to a particular URL.
  • the service layer -this component is the hidden part of the application that interprets client events, requests information stored on a database, and then sends the requested data back to the client. In our case AMFPHP, PHP and POG will be in this category. I will explain what these mean in a bit.
  • the database – this is where our data is stored. In my case this is MySQL. Depending on your local setup, you may be using a different database.

For most of this tutorial we will be dealing with the client and the service layer. The service layer will be comprised of AMFPHP which is a very small framework which facilitates remoting between Flex and PHP. Remoting is simply a means to send and receive native ActionScript objects to a service layer. POG is another small framework for taking PHP objects and allowing CRUD methods for their database counterparts. CRUD stands for Create, Read, Update and Delete and POG simply stands for PHP Object Generator. In our case, we are setting up a RIA so that the objects sent to and from Flex will easily be able to be manipulated via CRUD methods. To sum this up we are establishing a seamless means of having Flex and a database to communicate with a minimum amount of manual data manipulation. If that confused the hell out of you, I apologize as I am kinda new to making tutorials.

Resources

POGTestApp client & server – link
AMFPHP v1.9 20070513 – link
POG – link

The Quest

Anyone who frequents this blog know that I have been on a mission for some time to get some sort of ORM setup for my pet-project. I didn’t want to be encumbered by a heavy framework with a complex API or inheritance structure. I’d looked at CakePHP, Doctrine, Propel, Junction and a few others. As a non-PHP guy, I found all of those to be overwhelming. I’d rather spend my time coding than having to read config documentation or learn a new API. That is not to say that I don’t want to learn something new, I do. I just felt enough of my time had been spent trying to find the right solution. The right solution had to be ultra-simple and intuitive.

Enter POG

POG stands for PHP Object Generator. I’ll spare you my praises of it for now (you can read up on their site if you like). Suffice it to say it is an ORM framework that is simple, intuitive and light weight. And it works for me. This looks like a long read, and it is, but it will go rather quickly. Lot’s of pictures too!!!

Your first Flex + AMFPHP + POG RIA

Server setup

I have my project setup in two places. One location is where my deployable flex content, AMFPHP and POG code goes. The other is simply where I house my Flex project source. Here is a pic of the deploy location:

picture-2.png

I use MAMP (Mac + Apache + MySQL + PHP) which is a turnkey PHP server. It works well for me because I really didn’t like doing all the Terminal setup to get my Mac’s built in PHP setup for this. If my project makes it to the big time, then all this server side setup will be delegated to a more knowledgeable person who can set it up better than I have.

AMFPHP

Firstly I want to tackle the AMFPHP part since its probably the most straight forward part of the process. Go and download AMFPHP 1.9. I am using the 20070513 release. Once downloaded, unzip it and place it in the aforementioned deploy location. The only things you need to do for AMFPHP is:

  • make note of you services folder (I put a symlink to the whole AMF folder in my flex project so I could have direct access to it from within Eclipse without having to use the bin folder).
  • adjust the following information on the globals.php
    • $servicesPath – in my case “services/”
    • $voPath – this will point to your POG objects folder once we get it setup, in my case “../pog/objects/”

That is all on the AMFPHP aside from constructing your services.

[EDIT 2008.03.21]

Since initially this tutorial only happened to touch upon the setup of these technologies there hadn’t been any issues encountered. Obviously this tutorial didn’t reflect a real implementation of such a setup beyond the simple Get method. Further development has turned up an interesting find about sending AS3 objects out from Flex to be mapped to a POG object. As it is now, it can’t. That is because the naming convention chosen by the POG framework doesn’t get picked up by the AMFPHP deserializer. My gunslinger buddy Renaun Erickson has found a simple solution for this that doesn’t break the POG naming convention. You can read more about it on his blog – link.

You need to open the AMFBaseDeserializer.php and insert the following code at line 384:

elseif(file_exists($GLOBALS['amfphp']['customMappingsPath'] . 'class.' . strtolower($mappedClass) . '.php'))
{
        $include = $GLOBALS['amfphp']['customMappingsPath'] . 'class.' . strtolower($mappedClass) . '.php';
}

POG

POG is unique in that you don’t just go and download a framework (at least not yet). If you visit POG, you are greeted with a little RIA that takes some information about the object you want to create. I decided to use the name TestObject and give it two properties: userName and password both being varchar(255). Just to reiterate, I am using the PHP5.1+ along with the POG database wrapper:

picture-3.png

Notice that I am NOT using the PDO mysql wrapper. Reason being that AMFPHP has issues finding the mysql PDO driver and not everyone’s php environment contains those. So let’s stick to the POG database wrapper.

Since this is the first interaction with POG, we want to download the full framework in addition to you new object:

dlzip.png

Then unzip the file, rename it simple as “pog” and place it in your deployment location. Next locate the {yourMainDeploymentFolder}/pog/configuration.php and update the needed information so that POG can access your database. Here is a snap of mine:

configs.png

Notice that I have my mysql port set to 8889 rather than the default 3306? Also the plugin settings url is an absolute path. In your browser navigate to the following location: http://localhost{:yourPort}/{yourMainDeploymentFolder}/pog/setup/index.php. Go through the initial welcome/setup screen. POG will do some quick unit test, and if everything goes well, you are then presented with a portal to do basic CRUD methods on your new POG object. This is useful because we can setup a few test objects to use in setting up and testing the Flex application.

Now it would appear that POG is ready to go. And you’d be correct if you just want to use the local POG portal to play with it. In order to get it working with Flex and AMFPHP, you need to fix a few things with a few classes in POG. We will come back to that after we get the Flex project setup.

Flex

I am providing my POGTestApp source for you to download, but I also want you to see the steps necessary to do it yourself. First let’s create a new Flex project. I called mine POGTestApp. Now I also have mine located in a different place than the deployment location so I used some advanced options:

flexpath.png

In the provided flex project, I have the Cairngorm.swc in the libs folder. Make sure to add the libs folder to the library path. Also point it to the services-config.xml:

picture-5.png

Open the services-config.xml and make sure to modify the endpoint uri to point to your amfphp gateway.php:

services-config.png

Now at this point you should be able to modify your Services.mxml (ServiceLocator subclass) and add your php services there. If you downloaded the files I have provided, I suggest taking a look at Services.mxml. Since this is a testing application, I have a genericFaultHandler and a genericResultHandler in this file that you can add breakpoints to for debugging purposes. So even though I am making the calls from the application file without any responders, I am still listening for them in Services.mxml. Now if you decide to make some calls of you own, without using my files, you will notice that you get some errors or it just doesn’t seem to work. That is because POG needs some adjustments to work properly.

POG adjustments

Even though POG works inside the provided POG setup.php, it won’t want to play with Flex or AMFPHP unless you give it some help. Here are a few things to modify:

  • open the class.database.php and hardcode your configuration.php settings in there. For some reason the global vars are not making through to the Database class. Since I suck at php, I was advised to put it here until a better solution is found.
  • open the class.testobject.php (or whatever your POG object is named) and add the remoting string: var $_explicitType = YourRemotingClassNameHere.
  • also add include_once(‘class.database.php’);to class.testobject.php.

That should do it. Make your own or use the POGTestingServices and play with it. Keep in mind that even though my provided files work, you might get some PHP specific errors that appear to fail silently. If you experience this behavior you need to check your php.log to see what the issue is. Generally its due to the remoting code rather than the POG code.

Retrospective

I really like the idea of remoting for prototyping. It takes the hassle away from having to parse your responses in flex. POG is an ideal solution for developers not that familiar with PHP as the objects translate rather easily and since it is OO, its easy to do the mysql input without having to get involved with writing queries.

When time is of the essence, maybe you will consider this beautifully simple solution. Thanks goes out to Joel Wan (POG) and Renaun Erickson (the gunslinger) for help sorting this out. Let me know if you have any advice, suggestions, criticism and or corrections for this tutorial.



Whatchya doin?
Wednesday, February 6, 2008, 9:45 pm
Filed under: actionScript, components, development, flash, flex, mysql

Me?  Well thanks for asking.  I have been hard at work on:

  • trying to gain the fortitude to start going back to the gym after a 1.5 year hiatus
  • restoring an antique chair (fun to get back to hands-on projects)
  • researching RFID technology and how it may play with ActionScript (any pointers would be great)
  • learning PHP
  • learning MySQL
  • learning AMFPHP (remoting is so cool, I never want to go back)
  • researching different PHP ORM frameworks (implementation pointers would be great, thanks)
  • debating the further development of my IsoLib over using something like Sandy 3D
  • debating on my making my touchscreenLib open source or not.
  • enjoying my new Psycroptic – Symbols of Failure CD (Corporal Jigsaw Quandary is so sick it makes me wanna ax my guitar!)

So I write this post with two intentions in mind: a) to maybe prompt some discussion in which I may further my development goals and b) to break the monotony of this week’s rather uneventful start.  Chime in and let me know if your goals match mine.  Maybe we can mind-meld and break new ground?

Later,
j



As my eyes glaze over… Some Community Input Please?
Wednesday, January 30, 2008, 5:05 pm
Filed under: actionScript, development, flash, flex, mysql

I have been pluggin’ away at my pet project for a while now. Learned a little here about PHP5, a little there about MySQL and a quite a bit over yonder about AMFPHP.

Up until now, I was doing all of my PHP/MySQL communication by hand. Manually coding queries in PHP is rather intense for a noob. Plus it broadens my rather narrow OO mind. But I think its time to graduate to the big leagues now. I am really wanting to implement some sort of MVC or ORM type framework onto my project so that I can focus on developing my application more efficiently.

The problem is that there is a wealth of these frameworks out there and very little in the way of melding them specifically with my technology combination: Flex – AMFPHP – MySQL – Apache. Firstly, my eye glaze over when I start to read highly-technical documents on integration. These folks write these things as though you have been working with their technology for decades. Nope, I am new and need some noobie documentation please.

So I pose this question to my fellow developers: Have you any experience with a particular ORM/MVC framework working with AMFPHP & MySQL?  Can you give me some input on the pros/cons for combining them with AMFPHP Specifically any of these:

  • Propel
  • Creole
  • Symfony
  • Seagull
  • CakePHP
  • any others I don’t know of?

I look forward to your responses.

J



Getting MySQL & Mac OS X 10.5 (Leopard) together….finally
Sunday, December 9, 2007, 6:11 pm
Filed under: development, mac, mysql

[UPDATE]
It appears that a 10.5 friendly version of mysql has been released.  Before engaging in this tutorial you might want to check with a more traditional install procedure that comes with the newest version of mysql.

======================

Firstly, I should preface this post by saying that there are probably at least a dozen posts on this topic. All are basically the same with little differences here and there. None of them worked for me. But what did work (so far) is taking bits and pieces from a post here and a post there to finally get something working. Thanks goes out to all those other bloggers who provided the information found here.

Additionally, if things keep going the way they had been, this might not work at all. I have had MySQL up and running several times only to return to find it no longer wants to start for me.

Keep in mind that this is my attempt at a new install of MySQL on my newly acquired MacBook Pro (MBP hereinafter).

Step 1: Enable your root user

  1. Open the Directory Utility: In the Finder, navigate to the Utilities folder (tip: click on the desktop, hit Cmd+Shift+U).
  2. Click on the padlock to allow edits.
  3. Go Edit > Enable Root User
  4. Enter and re-enter your password.

Now, you are set to access protected areas of the system via the terminal.

[Excerpt from StringFoo's post]

Step 2: Backup any existing databases from previous versions of MySQL

I never had anything installed so I never attempted to do so. But this goes without saying for you other folks.

Step 3: Remove previous versions of MySQL

I did attempt multiple installs so I did remove them prior to my finally working install. I had nothing to preserve so again, if you are looking to backup a previous version you might want to research it.

  1. Open a new Terminal window.
  2. Remove the installed location by typing sudo rm -rf /usr/local/mysql (keep in mind that if you backed up your databases in this directory it is targeted to get deleted!!!). What this basically says (for all of we new Mac users is: super user remove the targeted folder and recursively do so to any subsequent folders and files from this location.
  3. Remove any launchers by typing sudo rm -rf /Library/StartupItems/MySQLCOM/

[Excerpt from Hivelogic's post]

Step 4: Add environment variables and some Terminal alias to launch MySQL

  1. Open a Terminal window.
  2. Use a command-line text editor to create the enviro-vars and aliases by typing pico ~/.bash_login (that is a tilde not a dash btw).  This opens the pico text editor and either opens or creates the .bash_login hidden file at your user’s folder.
  3. Add the following text:

    export PATH="/usr/local/bin:/usr/local/sbin:/usr/local/mysql/bin:$PATH"
    alias mysql-start="sudo /usr/local/mysql/support-files/mysql.server start"
    alias mysql-stop="sudo /usr/local/mysql/support-files/mysql.server stop"

  4. type ctrl-x to initiate closing Pico.
  5. type y to save it.
  6. type enter to save to the prompted location
  7. You should now be back in Bash
  8. Now get Teminal to load those new aliases and path type: . ~/.bash_login

Step 5: Grab the MySQL installer and install

  1. Grab the appropriate installer from the MySQL download page (I am using the intel based MBP)
  2. Install to the default locations.
  3. I went ahead and installed the System Preferences utility that is supposed to help you start/stop MySQL’s server, however it did not work. Do so if you wish and maybe you can get it to work. Here are some comments on how you might get it going

Step 6: Update ownership of some launch-specific files

  1. In a terminal window, type the following in order to create a folder where the MySQL sock file will live.
  2. Create the folder: sudo mkdir /var/mysql This just says super user make directory mysql in the var directory
  3. Change ownership of that directory to the user _mysql: sudo chown _mysql /var/mysql

[Excerpt from StringFoo's post]

Step 7: Start the MySQL server and then login

Hopefully, if I remember all the steps I took to get this working and it actually works for you, then you should be able start the MySQL server and login.

  1. Type mysql-start
  2. If all is well you should see a succsss message. So now login by typing: mysql -u root This just means login to the MySQL server as the user root
  3. If that works then you should see a prompt saying mysql>
  4. If you want to stop the MySQL server, exit the current user by typing: exit
  5. You should now be back in the terminal so type: mysql-stop You should then see another Success message saying that you stopped the server

That’s it. Again, I should really thank the community out there for providing various approaches to getting this thing up and running on Leopard. If you are like me, a new Mac user, then hopefully this will get you working with MySQL. Keep checking the web for a Leopard supported installer so then we can make use of the System Preferences MySQL launcher.