Reflection / Introspection in Flex ActionScript

Posted in Glen Whitbeck on July 15th, 2009 by admin

As part of an effort to create enterprise components, libraries, and architectures, a company may want to take advantage of reflection. For example, a company may want a consistent way to create and populate various components. This might allow your developers to work more quickly since all of the components are handled in the same manner. However, many of the components in Flex (and, likely, many of a company’s custom components), have differences in how they’re created and populated … even when the functionality is conceptually similar. In order to accomplish a consistent interface, you may need some abstraction that allows you to dynamically create and populate objects at runtime. To that end, I thought it might be helpful to discuss the low-level how-to’s of reflection within Flex / ActionScript.

The Flex framework includes an implementation of the Class Factory pattern in mx.core.ClassFactory. This class allows you to instantiate classes determined at runtime.

Here are a couple of examples of how to instantiate a class determined at runtime:

INSTANTIATE AN OBJECT FROM IT’S CLASS

import mx.core.ClassFactory;
public static function instantiateUsingClass(classToInstantiate:Class):* {
	var myClassFactory : ClassFactory = new ClassFactory(classToInstantiate);
	var myObjectInstance : * = myClassFactory.newInstance();
	return myObjectInstance;
}

INSTANTIATE AN OBJECT FROM IT’S CLASS NAME (i.e., from a String like “com.domain.Person”)

import flash.utils.getDefinitionByName;
import mx.core.ClassFactory;
public static function instantiateUsingClassName(className:String):* {
	var classToInstantiate : Class = getDefinitionByName(className) as Class;
	var myClassFactory : ClassFactory = new ClassFactory(classToInstantiate);
	var myObjectInstance : * = myClassFactory.newInstance();
	return myObjectInstance;
}

At a basic level, mx.core.ClassFactory does the following to instantiate the class:

public var generator:Class;
...
this.generator = classToInstantiate;
...
var instance:Object = new generator();

There are other times when you need more than to simply instantiate a class. For example, you may need to query the class definition to find out what methods, properties, etc. are declared on that class. The flash.utils package provides some package-level functions for introspecting classes and objects. Here is a link to the flash.utils API: http://livedocs.adobe.com/flex/3/langref/flash/utils/package.html. For the purposes of reflection, the describeType() method is one of the best places to start (the call to getDefinitionByName() that was used above is another package-level function provided by flash.utils). Here is a way to find out what “accessor” methods (get/set methods) are declared for a class:

RETRIEVE NAMES OF ACCESSOR METHODS FOR A GIVEN CLASS

import flash.utils.describeType;
public static function getNonstaticAccessors(classOfInterest:Class):Array {
	var xmlDescriptionOfClass:XML = describeType(classOfInterest);
	var nonstaticAccessorsXML:XMLList = xmlDescriptionOfClass.factory.accessor;

	var accessors:Array = [];
	for each (var accessorXML:XML in nonstaticAccessorsXML) {
		accessors.push(accessorXML.@name);
	}
	return accessors;
}

In order to obtain the static accessors, use xmlDescriptionOfClass.accessor, instead of xmlDescriptionOfClass.factory.accessor. In addition to @name, you might also be interested in information contained in @access, @type, and @declaredBy.

When you modify a public property on an object using dot notation (i.e., myPerson.name = “Fred”;), Flex does exactly what you’d expect and modifies the public property value. But, Flex offers an additional convenience. If you decide, at a later time, that you’d like to make the properties private and force them to be accessed through accessor methods (i.e., public function set name(myName:String):void {…}), Flex will automatically call your accessor method (without having to change your code to call the accessor, instead of the property). Hooray!

When it comes to reflection, however, the factual separation between properties (class attributes … class variables … whatever term you prefer) and accessors is maintained. The point of this tangent is that your public properties (that do not have declared accessor methods) will not be returned by the above method. Instead, in order to discover the properties of a given class, you’ll need to query for them specifically (using the “.variable” notation).

Here is an example of how to query for the attributes of a class:

RETRIEVE NAMES OF PROPERTIES (CLASS ATTRIBUTES) FOR A GIVEN CLASS

import flash.utils.describeType;
public static function getProperties(classOfInterest:Class):Array {
	var xmlDescriptionOfClass:XML = describeType(classOfInterest);
	var nonstaticPropertiesXML:XMLList = xmlDescriptionOfClass.factory.variable;
	var properties:Array = [];

	for each (var propertyXML:XML in nonstaticPropertiesXML) {
		var property:Property = new Property(	propertyXML.@name,
							propertyXML.@type.toString(),
							isStatic );
		properties.push(propertyXML.@name);
	}
	return properties;
}

In order to obtain the static accessors, use xmlDescriptionOfClass.variable, instead of xmlDescriptionOfClass.factory.variable. In addition to @name, you might also be interested in information contained in @type.

Accessor methods (discussed earlier) are also kept separate from all of the other methods. Here is an example of how to query for the non-accessor methods of a given class

RETRIEVE NAMES OF METHODS FOR A GIVEN CLASS

import flash.utils.describeType;
public static function getMethods(classOfInterest:Class):Array {
	var xmlDescriptionOfClass:XML = describeType(classOfInterest);
	var nonstaticMethodsXML:XMLList = xmlDescriptionOfClass.factory.method;

	var methods:Array = [];
	for each (var methodXML:XML in nonstaticMethodsXML) {
		methods.push(methodXML.@name);
	}
	return methods;
}

In order to obtain the static accessors, use xmlDescriptionOfClass.method, instead of xmlDescriptionOfClass.factory.method. In addition to @name, you might also be interested in information contained in @type.

OK, great! We now have a few tools (I’m sure you’ll discover more as you begin experimenting with the reflection capabilities provided by Flex) to help us with introspection of ActionScript classes at runtime. But, hey, maybe we actually want to DO something with that information. Here is an example of how to trigger a method call on a class and method discovered at runtime:

INVOKE A METHOD ON AN INSTANTIATED OBJECT

public static function invokeMethod(objectContainingMethod:*, methodName:String, parms:Array):* {
	var method:Function = objectContainingMethod[methodName];
	var returnValue:* = method.apply(objectContainingMethod, parms);

	return returnValue;
}

= = = = = = = = = =
Now that I’ve taken your time discussing some basics of how to implement reflection within Flex / ActionScript, I’m now going to suggest that you do it differently!

I was discussing writing a blog on reflection awhile back with Justin Shacklette (Justin’s blog) and Jon Rose (Jon’s blog). Justin immediately pointed out that Spring was splitting their reflection functionality out into a separate library. This reflection library improves on some of the above techniques by implementing work-arounds for some known bugs, etc., etc. behind the scenes. In addition, it allows you to deal with objects that might be a bit more intuitive than the XML object that is returned by describeType(). On the other hand, this means that you’ll occasionally need to step down through the object hierarchy to find the desired value. I found it pretty easy to investigate the various classes and source code at this site: http://as3-commons.googlecode.com/svn/trunk/as3-commons-reflect/src/main/actionscript/org/as3commons/reflect/. The best classes to start with are Type.as and ClassUtils.as.

To get started, download the AS3 Commons Reflection library (as3commons-reflect-1.0.0.swc) from http://code.google.com/p/as3-commons/.

Add this SWC file to your Flex project’s lib folder.

Now, let’s revisit the above examples to see how they might differ when using the AS3 Commons Reflection library.

INSTANTIATE AN OBJECT FROM IT’S CLASS

import org.as3commons.reflect.ClassUtils;
public static function instantiateUsingClass(classToInstantiate:Class):* {
	var myObjectInstance:* = ClassUtils.newInstance(classToInstantiate);
	return myObjectInstance;
}

INSTANTIATE AN OBJECT FROM IT’S CLASS NAME (a String like “com.domain.Person”)

import org.as3commons.reflect.ClassUtils;
public static function instantiateUsingClassName(className:String):* {
	var classToInstantiate:Class = ClassUtils.forName(className);
	var myObjectInstance:* = ClassUtils.newInstance(classToInstantiate);
	return myObjectInstance;
}

RETRIEVE NAMES OF ACCESSOR METHODS FOR A GIVEN CLASS

public static function getStaticAccessors(classOfInterest:Class):Array {
	var type:Type = Type.forClass(classOfInterest);
	var accessors:Array = type.accessors;
	return accessors;
}

RETRIEVE NAMES OF PROPERTIES (CLASS ATTRIBUTES) FOR A GIVEN CLASS

public static function getProperties(classOfInterest:Class):Array {
	var type:Type = Type.forClass(classOfInterest);

	var nonstaticProperties:Array = type.variables;
	var staticProperties:Array = type.staticVariables;

	var properties:Array = nonstaticProperties.concat(staticProperties);
	return properties;
}

RETRIEVE METHODS DECLARED BY A GIVEN CLASS

public static function getMethods(classOfInterest:Class):Array {
	var type:Type = Type.forClass(classOfInterest);
	var methods:Array = type.methods;
	return methods;
}

INVOKE A METHOD ON AN INSTANTIATED OBJECT

public static function invokeMethod(objectContainingMethod:*, methodName:String, parms:Array):* {
	var methodInvoker:MethodInvoker = new MethodInvoker();

	methodInvoker.target = objectContainingMethod;
	methodInvoker.method = methodName;
	methodInvoker.arguments = parms;

	var returnValue:* = methodInvoker.invoke();

	return returnValue;
}

Ultimately, the AS3 Commons Reflection library makes a few things easier or more intuitive. Moreover, it handles some complexities and bug work-arounds for you. But, the nuts-and-bolts are still basically using the the same techniques that I discussed in the upper-half of this post.

FlexMonkey: Easing the Pain of RIA Testing

Posted in Jeff Johnson on July 15th, 2009 by admin

admin originally posted this on Ruminations on Large-Scale Software Development.

UI testing - ugh. The mere mention of it can make hardened software veterans weep. As someone who's been developing GUI's since the 80's, I know all too well what a pain it can be to test them. And now that the industry is finally shifting away from its unfortunate digression into boring & clumsy page-based UI's back to exciting & seamless "fat client"-style interfaces using Flex, there is a whole new generation of developers and QA folks who will be experiencing the joys of trying to test every nuance of their whiz-bang RIA. Enter FlexMonkey 1.0, Gorilla Logic's new open source, automated record, playback & verification testing tool for Flex. With all the features you'd expect from an enterprise-class, commercial-quality testing tool, FlexMonkey enables you to immediately begin testing your browser and AIR-based Flex applications. And, like many of the best development tools available today, it's open source and free!

For more information on FlexMonkey: http://flexmonkey.gorillalogic.com/

For more information on Gorilla Logic's full line of Flex-related services: http://www.gorillalogic.com/what.development.services.flex.html

FlexMonkey: test automation for Adobe Flex

Posted in Jerry Andrews on July 15th, 2009 by admin

I’m a real fan of automated testing. I really don’t understand the idea of teams of people driving a UI as a way of regression testing, though there are certainly a lot of major products out there which use exactly that method to test. I think one big reason for that is that user interfaces which aren’t written in HTML are notoriously hard to regression test.

A lot of what we do at Gorilla Logic is Flex atop Java. As a result of that, we had to find a way to regression test Flex user interfaces; it’s not really practical for an agile team to survive without automated regression testing. Enter FlexMonkey. FlexMonkey was developed and offered to the community in open source as THE way to do regression testing for Flex, and having seen it in action, I have to say I’m really impressed. It’s easy to get started with, easy to use, and easy to fully automate. The documentation is enterprise-grade, and best of all, it’s free. It took me about half an hour to get it running and automated under ant, and I’ve never coded in Flex.

So go check it out: FlexMonkey 1.0 released in Google Code (open source) yesterday. http://flexmonkey.gorillalogic.com/gl/stuff.flexmonkey.html.

Here’s a bit more about Flex and what we do at Gorilla Logic: http://www.gorillalogic.com/what.development.services.flex.html.

FlexMonkey 1.0 Released

Posted in Wayne Adams on July 15th, 2009 by admin

admin originally posted this on Wayne Adams' Blog.

My entries here are usually about Java, but today I want to call attention to the 1.0 release of FlexMonkey, an Adobe AIR app for testing Flex and Adobe AIR applications (I work for Gorilla Logic, the creator of FlexMonkey). If you have a need to run automated tests of Flex and AIR apps, please give it a try. If you are familiar with "old" versions of FlexMonkey (as in, 2008), take another look at it; it has evolved quite a lot during its short lifetime!

To learn about FlexMonkey and to download, go to http://flexmonkey.gorillalogic.com/. Don't let the "Beta 1" fool you; I've been using FlexMonkey since its birth and it is significantly more polished than a certain operating system I use every day. There is also a site describing Gorilla Logic's Flex service offerings at http://www.gorillalogic.com/what.development.services.flex.html.

Finally, I should mention that you are not alone should you become a FlexMonkey user. I've been on a lot of support mailing lists in my time, and I am very impressed by the dedication of the user community (including a number of Gorillas!) who respond to questions. So by all means give it a try with the confidence that you'll have all the help you need for both "newbie" and more advanced questions!

Eric Owens’ Introduction to FlexMonkey Article

Posted in FlexMonkey on July 15th, 2009 by jonr

jonr originally posted this on FlexMonkey :: Flex UI Testing Tool.

In his recent Adobe Developer Center article, Eric shows you how to get started using FlexMonkey as part of your development flow.  Check out the article here: Testing Flex applications with FlexMonkey 1.0

The monkey has landed!

Posted in Stu Stern on July 14th, 2009 by Stu Stern

Stu Stern originally posted this on Big Gorilla - Stu Stern's Blog.

FlexMonkey 1.0 is here! After nearly nine months of gestation we've delivered what is undoubtedly the premier record/playback testing automation tool for Adobe Flex and AIR applications. And it's free!

For the thousands of folks who are already using FlexMonkey 0.8, FlexMonkey 1.0 brings significant new functionality including a completely revamped user interface which makes it much easier to record and playback tests. We've also added the ability to take snapshots of portions of the screen or of property values to be verified during playback. In addition to testing Flex apps, FlexMonkey 1.0 for the first time provides direct support for testing AIR apps. The FlexMonkey Console is now itself an AIR app, but can launch standalone as well as browser-based SWFs for testing.

Please let us show you our monkey at http://flexmonkey.gorillalogic.com! You can also check out Gorilla Logic's Flex service offerings at http://www.gorillalogic.com/what.development.services.flex.html.

FlexMonkey 1.0 Released

Posted in FlexMonkey on July 14th, 2009 by jonr

jonr originally posted this on FlexMonkey :: Flex UI Testing Tool.

Gorilla Logic Announces Release of FlexMonkey 1.0, an Open Source Tool for Testing Adobe Flex RIAs

FlexMonkey Brings the Power of Professional Record/Playback Test Automation Tools to Adobe Flex Development

Gorilla Logic, firm known industry-wide for providing “gorilla” consultants that deliver a 10X productivity improvement over other options, today announced the release of FlexMonkey 1.0. FlexMonkey, an open source testing tool for optimizing automated and unit testing of Adobe Flex RIAs, is another example of Gorilla Logic’s commitment to assisting clients and the market in developing the highest-quality applications possible.

”Adobe Flex is the leading standard for enterprise RIA development. When developing Flex-based mission-critical systems for our clients, we needed a production-quality testing tool that would tightly integrate with Flex Builder and FlexUnit,” said Eric Owens, FlexMonkey Product Manager. “FlexMonkey 1.0 is the answer to that need: by automating our interface testing with record/playback functionality, we provide higher quality solutions to our clients. We feel strongly that FlexMonkey should be free and open-sourced, and we’re now providing clients with FlexMonkey training as well as FlexMonkey-based testing services.”

Available since October 2008, Gorilla Logic has used FlexMonkey with a diverse set of clients in a variety of industries ranging from financial services to aerospace to media. During each project FlexMonkey has been an integral part of Gorilla Logic’s quality assurance for clients. Based on this proven value and their unique experience, Gorilla Logic is now offering FlexMonkey Training as well as Testing Services for Adobe Flex applications.

“We have been using FlexMonkey since October 2008 to test our Flex Applications interactively. We evaluated several interactive testing tools, and found FlexMonkey to be much lighter and more agile than the expensive products, even outperforming them in several areas. It is a great product, and the support from the Gorilla Logic team has been superb,” said Tracy Ellis, Manager, SAS (www.sas.com).

FlexMonkey 1.0 is an open-source solution for testing Adobe Flex RIAs and can be downloaded from flexmonkey.gorillalogic.com.  For questions regarding Adobe Flex training / mentoring, functional and load testing using FlexMonkey or other off-shore testing services provided by Gorilla Logic, please visit our website (www.gorillalogic.com) or send an email to info@gorillalogic.com.

About Gorilla Logic

Gorilla Logic is an enterprise application development services and consulting firm known industry-wide for providing “gorilla” consultants that deliver a 10X productivity improvement over other options. With industry-leading expertise in Java-related technologies and Adobe Flex RIA application development, Gorilla Logic has been engaged by Fortune 500 companies in industries ranging from financial services to entertainment to aerospace and government to work on mission critical projects. Gorilla Logic also develops tools to decrease the product development lifecycle and open sources them for the benefit of the market – FlexMonkey (flexmonkey.gorillalogic.com) and OpenGXE (www.gorillalogic.com/opengxe).

For more information about Gorilla Logic, please visit www.gorillalogic.com or email info@gorillalogic.com.

FlexMonkey 1.0 Release announced today by Gorilla Logic

Posted in FlexMonkey, Glen Whitbeck, Gorilla Logic, Uncategorized on July 14th, 2009 by admin

FlexMonkey 1.0 was released today by Gorilla Logic. FlexMonkey is an open source tool enabling visual testing of Adobe Flex Rich Internet Applications (RIAs). FlexMonkey can record user actions taken on a Flex UI (button clicks, typing, navigation, etc.). Along the way, the user can indicate assertion / validation information at desired points to test whether the UI has responded as expected. Then, FlexMonkey can playback the tests and report on the passage / failure of the assertions imbedded in the tests. This enables automated regression testing of a Flex User Interface.

FlexMonkey has been designed to integrate with FlexBuilder and FlexUnit. It is available as a free download at http://flexmonkey.gorillalogic.com/. Gorilla Logic also offers training and testing services. Information about these services can be explored at http://www.gorillalogic.com/what.development.services.flex.html.

Testing Web Applications

Posted in Bob Hedlund on July 14th, 2009 by admin

admin originally posted this on Eldorado Software.

How many times have you been on a project and seen changes to code cause the application to blow up, and yet the Unit Tests all succeeded? To avoid this situation I use HtmlUnit, an open source project distributed under the Apache License.

HtmlUnit emulates a browser that is visiting your web application. Coupled with JUnit, it allows you to write tests that click through the application just as QA does. It ensures that the functionality you put into your pages exists and works properly.

With HtmlUnit and Junit I am able to test most functionality in the web tier : page flow, form population and submission, javascript, popups, dialogs, and AJAX calls. I even created a suite of convenience methods to work with my Trinidad components.

The one shortcoming has been the ability to test Flex animations. These were always a black box to my test suites. However, Gorilla Logic has now released FlexMonkey, which is also based on HtmlUnit, and allows you to test the flex animations from an easy to use test suite.

I use these tests as both integration and unit tests. I ensure the application can be "clicked through"; that all pages appear at the correct time, and that interactions in the page all function correctly. I also test various scenarios that will occur in the application, and ensure that the application responds correctly based on the processing of the data passed in.

I no longer worry about the application blowing up in meetings or demos:

IT'S BEEN TESTED!!

Hibernate Search by Date

Posted in Bob Hedlund on July 14th, 2009 by admin

admin originally posted this on Eldorado Software.

On the project I am on now, we use Dates as a basis for monetary calculations. The Dates are simply based on the day, month and year, disregarding hours, minutes and seconds. We store our dates after base-lining them - stripping out the H:M:S. This is achieved with Calendar utilities:

static Date baseLineDate(Date myDate) {
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(myDate);
cal.set(Calendar.HOUR, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
}

Determining if a Date is before, after, or equal to another is straightforward thereafter- just use the Calendar before() and after() methods.

If you look in the database, the dates are stored as 01-Jan-2009. It would be tempting to simply run a Hibernate query that tests equality. You could simply generate a base-lined date and ask Hibernate to return the objects that have this Date. And it works.

However... Databases are part of the seedier side of the software town. Lurking there is data imported from other systems and/or updated by rogue administrators. The best way to handle all possible situations correctly is to use the Hibernate Criteria's between() method:


getCurrentSession().createCriteria( MyItem.class )
.add(Expression.between("myDateField", base-lined-Date, end-lined-Date))
.list();

Where the base-lined-Date has been base-lined as above, and the end-lined-Date corresponds to a Date that is the last millisecond of the day:

static Date EndLineDate(Date d){
if(d==null)return null;
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(d);
cal.set(Calendar.HOUR, 11);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.HOUR_OF_DAY,23);
cal.set(Calendar.MILLISECOND, 999);
return cal.getTime();
}

This solution pulls in all objects that have a certain Date defined by Day, Month and Year only.