1  /**
     2   * com.sekati.reflect.Reflection
     3   * @version 1.0.0
     4   * @author jason m horwitz | sekati.com
     5   * Copyright (C) 2007  jason m horwitz, Sekat LLC. All Rights Reserved.
     6   * Released under the MIT License: http://www.opensource.org/licenses/mit-license.php
     7   */
     8   
     9  /**
    10   * Reflection allows class introspection for logging and identification purposes.
    11   * {@code Usage:
    12   * 	var loader:Baseloader = new Baseloader("init");
    13   * 	Reflection.getFullyQualifiedClassName(loader);	// returns: "com.sekati.load.BaseLoader"
    14   * 	ClasReflection.getClassName(loader);				// returns: "BaseLoader"
    15   * 	Reflection.getPackageName(loader);					// returns: "com.sekati.load"
    16   * }
    17   */
    18  class com.sekati.reflect.Reflection {
    19  
    20  	/**
    21  	 * Get the Fully Qualified Class Name Definition from a class instance.
    22  	 * @param o (Object) instance object to identify.
    23  	 * @return String - string representation of FQCN
    24  	 * {@code Usage:
    25  	 * 	Reflection.getFullyQualifiedClassName(myTest); // returns: "com.sekati.tests.MyTest"
    26  	 * }
    27  	 */
    28  	public static function getFullyQualifiedClassName(o:Object):String {
    29  		o = (typeof (o) == "function") ? Function( o ).prototype : o.__proto__;
    30  		return (Reflection._containsDefinition( o )) ? Reflection._getFullyQualifiedClassName( o ) : Reflection._buildDefinition( "", _global, o );
    31  	}
    32  
    33  	/**
    34  	 * Get the Class Name Definition from a class instance.
    35  	 * @param o (Object) instance object to identify.
    36  	 * @return String - string representation of CN
    37  	 * {@code Usage:
    38  	 * 	Reflection.getClassName(myTest); // returns: "MyTest"
    39  	 * }
    40  	 */	
    41  	public static function getClassName(o:Object):String {
    42  		var s:String = Reflection.getFullyQualifiedClassName( o );
    43  		return s.substr( s.lastIndexOf( "." ) + 1 );
    44  	}
    45  
    46  	/**
    47  	 * Get the Class Package Definition from a class instance.
    48  	 * @param o (Object) instance object to identify.
    49  	 * @return String - string representation of CP
    50  	 * {@code Usage:
    51  	 * 	Reflection.getPackageName(myTest);	// returns: "com.sekati.tests"
    52  	 * }
    53  	 */
    54  	public static function getPackageName(o:Object):String {
    55  		var s:String = Reflection.getFullyQualifiedClassName( o );
    56  		return s.slice( 0, s.lastIndexOf( "." ) );
    57  	}	
    58  
    59  	/**
    60  	 * Build the class instance definition and cache it as a property in the Object instance for future use.
    61  	 * @param s (String) package start string.
    62  	 * @param pkg (Object) top level object to recursively build definition from.
    63  	 * @param o (Object) instance object to identify.
    64  	 * @return String - the fully qualified class definition, if unable to locate Object name will be tried and if all else fails "undefined.Origin" is returned.
    65  	 */	
    66  	private static function _buildDefinition(s:String, pkg:Object, o:Object):String {
    67  		for (var p:String in pkg) {
    68  			var cProto:Function = pkg[p];
    69  			if (cProto.__constructor__ === Object) {
    70  				p = Reflection._buildDefinition( s + p + ".", cProto, o );
    71  				if (p) return p;
    72  			} else if (cProto.prototype === o) {
    73  				Reflection._setFullyQualifiedClassName( o, s + p );
    74  				return s + p;				
    75  			}
    76  		}
    77  	}
    78  
    79  	/**
    80  	 * Check if the instance already contains a cached FQCN
    81  	 * @param o (Object) instance object
    82  	 * @return Boolean
    83  	 */
    84  	private static function _containsDefinition(o:Object):Boolean {
    85  		return Boolean( o.__FQCN.length > 0 );
    86  	}
    87  
    88  	/**
    89  	 * Return the cached FQCN
    90  	 * @param o (Object) instance object
    91  	 * @return String - FQCN
    92  	 */
    93  	private static function _getFullyQualifiedClassName(o:Object):String {
    94  		return o.__FQCN;
    95  	}
    96  
    97  	/**
    98  	 * Cache the FQCN as a property in the object instance.
    99  	 * @param o (Object) instance object
   100  	 * @return Void
   101  	 */
   102  	private static function _setFullyQualifiedClassName(o:Object, s:String):Void {
   103  		o.__fullyQualifiedClassName = s;
   104  		_global.ASSetPropFlags( o, [ "__FQCN" ], 7, 1 );
   105  	}
   106  
   107  	private function Reflection() {
   108  	}
   109  }