My new best friend – describeType

Praise to the flash.utils.describeType – a method that became my number one friend when I was validating parameters set by user and solving how to validate proper data types without knowing what they were.

So, what does flash.utils.describeType do? In a nutshell it converts any class into a xml that describes

  • getters and setters
  • methods
  • parameters and variables
  • access type of the former (read, write, readwrite)

My project uses ExternalInterface to talk with javascript and the user can pass an object whose property / value pairs  override the values of a class in my Flash. The class holds over 80 private / public properties and getters/ setters, so writing a separate validator for each one would be too much pain. So describeType to the rescue! I use it to convert my class to an object and from that object I can check which properties are writable and what are the data types of each property and getters / setters.

I added a method called ”getObjectParameters” to my Utils class and it converts any class to an object.

/**
 * runs through a class and converts its properties into an object
 * <code>Utils.getObjectParameters(obj,true,false,false)</code>
 *
 * @param obj the object to parse
 * @param onlyWritable get only properties that are writable
 * @param fullInfo if true, the returned array contains objecs with properties "type" (uint, String,..), "value" (value of the property), "name", "access" (readwrite,read,write). If "fullInfo" is false, the property contains only the value)
 * @param indexWithNumber If false the an associative array: array[name of a property] = value of the property, otherwise index based. It does not make sense to have indexWithNumber=true and fullInfo = false as it returns only values.
 *
 * @return an array of values or objects
 *
 */
public static function getObjectParameters(object:*, onlyWritable:Boolean= false, fullInfo:Boolean=false, indexWithNumber:Boolean = false):Array
{
       var description:XML = describeType(object);
       var arr:Array = [];
       var val:String;
       var type:String;
       var access:String;

       var o:Object
       var write:*;

       var props:XMLList = description..*.(name() == "accessor" || name() == "variable");

       for (var p in props) {
         access = (props[p].@access) ? props[p].@access.toXMLString() : "readwrite";
         if (access == "") access = "readwrite";

         if (onlyWritable && access != "readwrite") continue;

         val = props[p].@name.toXMLString();
         type = props[p].@type.toXMLString();

         if (fullInfo) {
           o = { };
           o.type = type;
           o.value =  object[val];
           o.name = val;
           o.access = access;

         }

      if (indexWithNumber) {
         if (fullInfo) arr.push(o);
         else arr.push(val);
      }
      else {
        if (fullInfo) arr[val] = o;
        else arr[val] = object[val];
     }
   }
   return arr;
}

You can download my Utils class, including this method.

Kommentoi