I have been trying to figure out how to take the results of my web
service ( e4x ) and update an object with that data. I want to use
one function to handle many different object types . . .
Here is what I have come up with so far. Looking for some ideas to
make it better, more efficient and for things that I am missing.
Thanks in advance for any ideas . . .
package com.psc.utils
{
import flash.utils.describeType;
import flash.utils.getDefinitionByName;
import flash.utils.getQualifiedClassName;
import mx.utils.ObjectUtil;
/**
* Utility class to convert xml based Objects to class instances.
*
* Takes a value object as the destination and an xmlList of data
* Look through all the items in the value object. Note we are using
classInfo..accessor since
* our objects are bound all variables become getter / setter's or
accessors.
*
* Also note, we can handle custom objects, arrays and arrayCollections.
*
* History
* 03.11.2008 - Steven Rieger : Created class
*
*/
public final class XMLToInstance
{
public static function xmlToInstance( destinationObject :
Object,
sourceXMLList : XMLList ) : void
{
// Get the class definition in XML, from the passed in
object ( introspection so to speak )
var classInfo : XML = describeType( destinationObject );
// Loop through each variable defined in the class.
for each ( var aVar : XML in classInfo..accessor )
{
// If this is String, Number, etc. . . Just
copy the data into
the destination object.
if( isSimple( [EMAIL PROTECTED] ) )
[EMAIL PROTECTED] =
[EMAIL PROTECTED];
else
{
// Dynamically create a class of the appropriate type
var className : String = [EMAIL PROTECTED];
var ObjectClass : Class = getDefinitionByName(
className )
as Class;
var newDestObject : Object = Object( new ObjectClass());
// If this is a custom type
if( isCustomType( className ) && ObjectClass != null )
{
// Recursively call itself passing in the
custom
data type and the data to store in it.
// I haven't tested nested objects more than
one
level. I suppose it should work.
// Note to self. Check.
xmlToInstance( newDestObject,
[EMAIL PROTECTED] );
}
else
{
// Must be some sort of Array, Array
Collection . . .
if( ObjectClass != null )
{
var anXMLList : XMLList = new XMLList(
[EMAIL PROTECTED] );
for each( var anItem : XML in anXMLList
)
{
// I'm sure there are more
types, just not using any
of them yet.
if( newDestObject is Array )
newDestObject.push(
anItem )
else
newDestObject.addItem( anItem );
}
}
}
// Add the data to the destination object. . . .
[EMAIL PROTECTED] = newDestObject;
}
}
} // end function objectToInstance
public static function isSimple( dataType : String ) : Boolean
{
/**
* This function is pretty self explanatory.
*
* Check to see if this is a simple data type. Did I
miss any?
*
* History
* 03.11.2008 - Steven Rieger : Created function
*
*/
switch( dataType.toLowerCase() )
{
case "number":
case "string":
case "boolean":
{
return true;
}
}
return false;
} // end isSimple
public static function isCustomType( className : String ) :
Boolean
{
/**
* This function is pretty self explanatory.
*
* Check to see if this is a custom data type. Add
them here as
you need. . .
*
* History
* 03.11.2008 - Steven Rieger : Created function
*
*/
var aClassName : String = className.replace( "::", "."
).toLowerCase();
aClassName = aClassName.substr( aClassName.lastIndexOf(
"." ) + 1,
aClassName.length - aClassName.lastIndexOf( "." ) );
switch( aClassName )
{
case "ndatetimevo":
case "expenselineitemvo":
{
return true;
}
}
return false;
} // end isCustomType
} // end class
} // end package