Here’s a tip regarding logging messages in Cairngorm application. I would recommend using ThunderBolt with Mozilla firebug. ThunderBolt is a light weight logging mechanism and very simple to implement; on every user gesture add a logger message during the following methods: execute, result and fault.
To use ThunderBolt just place the ThunderBolt swc in your lib folder and log a message, for instance:
Logger.error (”Logging two objects: A number typed as int and a string”, myNumber, myString);
Once you compile and run the application you can keep track of all the methods that got executed and save time debugging the application. Additionally, using this method can help you figure out if there are unnecessary double calls to the same commands.
Thunderbolt is available to AS2/3 code as well as AIR and Flex Gumbo: http://code.google.com/p/flash-thunderbolt/
There are two ways to implement, one directly through ThunderBolt such as here:
Example:
/*
Copyright (c) 2008 Elrom LLC, All Rights Reserved
@author Elad Elrom
@contact elad.ny at gmail.com
@project Example project
@internal
*/
package com.elad.Project.commands.services
{
import com.adobe.cairngorm.commands.ICommand;
import com.adobe.cairngorm.control.CairngormEvent;
import com.elad.Project.business.SequenceDelegate;
import com.elad.Project.events.SequenceEvent;
import com.elad.Project.model.ModelLocator;
import mx.rpc.IResponder;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import org.osflash.thunderbolt.Logger;
/**
*
* Defines the associated <code>ICommand</code> implementation for
* an "Sequence" use-case.
*
* <p>
* The <code>SequenceCommand</code> is utilized to abstract the
* handling of a <code>SequenceEvent</code>.
* </p>
*
* @see com.elad.Project.events.SequenceEvent
* @see com.adobe.cairngorm.commands.ICommand
*
*/
public final class SequenceCommand implements ICommand, IResponder
{
/**
*
* Defines a local convenience reference to the application
* <code>ModelLocator</code> implementations
*
*/
private var modelLocator:ModelLocator = ModelLocator.getInstance();
/**
*
* Concrete <code>ICommand</code> implementation which handles
* an <code>SequenceEvent</code>.
*
*/
public function execute(event:CairngormEvent) : void
{
Logger.info( "SequenceCommand"+" execute" );
var evt:SequenceEvent = event as SequenceEvent;
var delegate:SequenceDelegate = new SequenceDelegate( this );
delegate.callSomeMethod();
}
/**
*
* Handles the service result of the <code>SequenceDelegate</code>
* service invocation.
*
* @see mx.rpc.events.ResultEvent
*
*/
public function result(data:Object) : void
{
Logger.info( "SequenceCommand"+" result" );
var result:ResultEvent = data as ResultEvent;
}
/**
*
* Handles the service fault of the <code>SequenceDelegate</code>
* service invocation.
*
* @see mx.rpc.events.ResultEvent
*
*/
public function fault(info:Object) : void
{
var fault:FaultEvent = info as FaultEvent;
Logger.error( "SequenceCommand", fault );
}
}
}
A better way to implements, as suggested by Stefan Bistram which is more recommended since your classes don’t really need to know anything about ThunderBolt and you will be able to make changes without changing your entire code is using ThunderBoltTarget. The way it works is that you inject ThunderBolt to the Logging API built into Flex. You just set the target object in your entry class in MXML;
/** * * Define an instance of <code>ThunderBoltTarget</code> * * @see org.osflash.thunderbolt.ThunderBoltTarget * @see mx.logging.Log * */ private var _target: ThunderBoltTarget = new ThunderBoltTarget();
Than on set the filter to point to your command package;
_target.filters = ["com.elad.project.commands.*"]; Log.addTarget(_target);
And now you can use the Flex Log API to inject your messages;
/*
Copyright (c) 2008 Elrom LLC, All Rights Reserved
@author Elad Elrom
@contact elad.ny at gmail.com
@project Example project
@internal
*/
package com.elad.Project.commands.services
{
import com.adobe.cairngorm.commands.ICommand;
import com.adobe.cairngorm.control.CairngormEvent;
import com.elad.Project.business.SequenceDelegate;
import com.elad.Project.events.SequenceEvent;
import com.elad.Project.model.ModelLocator;
import mx.rpc.IResponder;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
/**
*
* Defines the associated <code>ICommand</code> implementation for
* an "Sequence" use-case.
*
* <p>
* The <code>SequenceCommand</code> is utilized to abstract the
* handling of a <code>SequenceEvent</code>.
* </p>
*
* @see com.elad.Project.events.SequenceEvent
* @see com.adobe.cairngorm.commands.ICommand
*
*/
public final class SequenceCommand implements ICommand, IResponder
{
/**
*
* Defines a local convenience reference to the application
* <code>ModelLocator</code> implementations
*
*/
private var modelLocator:ModelLocator = ModelLocator.getInstance();
/**
*
* Concrete <code>ICommand</code> implementation which handles
* an <code>SequenceEvent</code>.
*
*/
public function execute(event:CairngormEvent) : void
{
Log.getLogger("com.elad.project.commands.services.SequenceCommand").info("execute");
var evt:SequenceEvent = event as SequenceEvent;
var delegate:SequenceDelegate = new SequenceDelegate( this );
delegate.callSomeMethod();
}
/**
*
* Handles the service result of the <code>SequenceDelegate</code>
* service invocation.
*
* @see mx.rpc.events.ResultEvent
*
*/
public function result(data:Object) : void
{
Log.getLogger("com.elad.project.commands.services.SequenceCommand").info("result");
var result:ResultEvent = data as ResultEvent;
}
/**
*
* Handles the service fault of the <code>SequenceDelegate</code>
* service invocation.
*
* @see mx.rpc.events.ResultEvent
*
*/
public function fault(info:Object) : void
{
var fault:FaultEvent = info as FaultEvent;
Log.getLogger("com.elad.project.commands.services.SequenceCommand").error("fault", fault);
}
}
}
If you are using Cairngen 2.1.1 I have created template that you can just paste into your library for Cairngorm 2.2.1. Feel free to download and use them. Here’s the one for CommandExcludeDelegate.tpl:
@copy@
package @namespace@.commands
{
import com.adobe.cairngorm.commands.ICommand;
import com.adobe.cairngorm.control.CairngormEvent;
import @namespace@.events.@sequence@Event;
import @namespace@.model.ModelLocator;
import mx.logging.Log;
/**
*
* Defines the associated <code>ICommand</code> implementation for
* the "@sequence@" use-case.
*
* <p>
* The <code>@sequence@Command</code> is utilized to abstract the
* handling of an <code>@sequence@Event</code>
* </p>
*
* @see @namespace@.events.@sequence@Event
* @see com.adobe.cairngorm.commands.ICommand
*
*/
public final class @sequence@Command implements ICommand
{
/**
*
* Defines a local convenience reference to the application
* <code>ModelLocator</code> implementations
*
*/
private var modelLocator:ModelLocator = ModelLocator.getInstance();
/**
*
* <code>ICommand</code> implementation which handles an
* <code>@sequence@Event</code>.
*
* <p>
* The <code>@sequence@Command</code> does not require a specific
* service invocation to be made, therefore the handling of an
* <code>@sequence@Event</code> is completely managed by the
* <code>@sequence@Command</code>.
* </p>
*
*/
public function execute(event:CairngormEvent) : void
{
Log.getLogger("@namespace@.commands.@sequence@Command").info("execute");
var evt:@sequence@Event = event as @sequence@Event;
}
}
}
And here’s the one for CommandIncludeDelegate.tpl:
@copy@
package @namespace@.commands
{
import com.adobe.cairngorm.commands.ICommand;
import com.adobe.cairngorm.control.CairngormEvent;
import @namespace@.business.@sequence@Delegate;
import @namespace@.events.@sequence@Event;
import @namespace@.model.ModelLocator;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.AsyncToken;
import mx.rpc.IResponder;
import mx.logging.Log;
/**
*
* Defines the associated <code>ICommand</code> implementation for
* an "@sequence@" use-case.
*
* <p>
* The <code>@sequence@Command</code> is utilized to abstract the
* handling of a <code>@sequence@Event</code>.
* </p>
*
* @see @namespace@.events.@sequence@Event
* @see com.adobe.cairngorm.commands.ICommand
*
*/
public final class @sequence@Command implements ICommand, IResponder
{
/**
*
* Defines a local convenience reference to the application
* <code>ModelLocator</code> implementations
*
*/
private var modelLocator:ModelLocator = ModelLocator.getInstance();
/**
*
* Concrete <code>ICommand</code> implementation which handles
* an <code>@sequence@Event</code>.
*
*/
public function execute(event:CairngormEvent) : void
{
Log.getLogger("@namespace@.commands.@sequence@Command").info("execute");
var evt:@sequence@Event = event as @sequence@Event;
var delegate:@sequence@Delegate = new @sequence@Delegate( this );
}
/**
*
* Handles the service result of the <code>@sequence@Delegate</code>
* service invocation.
*
* @see mx.rpc.events.ResultEvent
*
*/
public function result(data:Object) : void
{
Log.getLogger("@namespace@.commands.@sequence@Command").info("result");
var result:ResultEvent = data as ResultEvent;
}
/**
*
* Handles the service fault of the <code>@sequence@Delegate</code>
* service invocation.
*
* @see mx.rpc.events.ResultEvent
*
*/
public function fault(info:Object) : void
{
var fault:FaultEvent = info as FaultEvent;
Log.getLogger("@namespace@.commands.@sequence@Command")..error("fault", fault);
}
}
}






















