1  
     2  /**
     3   * com.sekati.log.Inspector
     4   * @version 1.0.5
     5   * @author jason m horwitz | sekati.com
     6   * Copyright (C) 2007  jason m horwitz, Sekat LLC. All Rights Reserved.
     7   * Released under the MIT License: http://www.opensource.org/licenses/mit-license.php
     8   */
     9  
    10  /**
    11   * Recursively inspect an Objects contents.
    12   * {@code Usage:
    13   * 	var a = ["a", "b", ["aa"], "BB", ["aaa", "BBB"], {joe:[833, 38]}];
    14   * 	trace( new Inspector(a) );
    15   * 	}
    16   * }
    17   * @see {@link com.sekati.validate.TypeValidation}
    18   */
    19  class com.sekati.log.Inspector {
    20  
    21  	private var _result:String;
    22  
    23  	/**
    24  	 * Constructor - passthru to {@link recurse} loop.
    25  	 */
    26  	public function Inspector() {
    27  		_result = "";
    28  		recurse.apply( this, arguments );
    29  	}
    30  
    31  	/**
    32  	 * recursively stringify objects contents
    33  	 * @param obj (Object) target object
    34  	 * @param path (String) optional path to prepend for verbose output
    35  	 * @param level (Number) optional level
    36  	 * @param maxPathLength (Number) optional max path to be used with padding
    37  	 * @return Void
    38  	 */	
    39  	private function recurse(obj:Object, path:String, level:Number, maxPathLength:Number):Void {
    40  		var padding:String;
    41  		var paddingChar:String = " ";
    42  		var parentType:String;
    43  		var currentType:String;
    44  		var newPath:String;
    45  		//defaults
    46  		if (level == null) {
    47  			level = 0;
    48  		}
    49  		if (path == null) {
    50  			path = "";
    51  		}
    52  		//maxPathLength (only defined initially)   
    53  		if (maxPathLength == null) {
    54  			maxPathLength = paddingRecursion( obj, path ) + 3;
    55  		}
    56  		//calculate parents type   
    57  		parentType = (obj instanceof Array) ? "array" : typeof (obj);
    58  		for (var i in obj) {
    59  			//calculate path
    60  			newPath = (parentType == "array") ? path + "[" + i + "]" : path + "." + i;
    61  			//calculate this type
    62  			currentType = (obj[i] instanceof Array) ? "array" : typeof (obj[i]);
    63  			//find how much padding is needed for this item to print
    64  			padding = "";
    65  			for (var j:Number = 0; j < maxPathLength - newPath.length ; j++) {
    66  				padding += paddingChar;
    67  			}
    68  			_result += (newPath + padding + obj[i] + "  (" + currentType + ")\n");
    69  			//go deeper
    70  			recurse( obj[i], newPath, level + 1, maxPathLength );
    71  		}
    72  	}
    73  
    74  	/**
    75  	 * Recurse through everything to find what the biggest path string 
    76  	 * will be - strictly for formatting purposes.
    77  	 */
    78  	private function paddingRecursion(obj:Object, path:String, longestPath:Number):Number {
    79  		var parentType:String;
    80  		if (longestPath == null) {
    81  			longestPath = 0;
    82  		}
    83  		//calculate parents type   
    84  		parentType = (obj instanceof Array) ? "array" : typeof (obj);
    85  		for (var i in obj) {
    86  			//this levels path
    87  			var newPath:String = (parentType == "array") ? path + "[" + i + "]" : path + "." + i;
    88  			if (newPath.length > longestPath) {
    89  				longestPath = newPath.length;
    90  			}
    91  			//outside recursion   
    92  			var outsideRecursion:Number = paddingRecursion( obj[i], newPath, longestPath );
    93  			if (outsideRecursion > longestPath) {
    94  				longestPath = outsideRecursion;
    95  			}
    96  		}
    97  		return longestPath;
    98  	}
    99  
   100  	public function toString():String {
   101  		return _result;	
   102  	}
   103  }