AS3 | ClassUtil | Reflection


/ Published in: ActionScript 3
Save to your folder(s)



Copy this code and paste it in your HTML
  1. package kc.utils {
  2.  
  3. import flash.errors.IllegalOperationError;
  4. import flash.system.ApplicationDomain;
  5. import flash.utils.describeType;
  6. import flash.utils.getQualifiedClassName;
  7. import flash.utils.getQualifiedSuperclassName;
  8. import kc.core.KCStatic;
  9.  
  10. public class ClassUtil extends KCStatic {
  11.  
  12. // @const
  13.  
  14. private static const RESOLVE_NAME:String = "name";
  15. private static const RESOLVE_PACKAGE:String = "package";
  16. private static const RESOLVE_PATH:String = "path";
  17. private static const RESOLVE_PATH_COMPLEX:String = "pathComplex";
  18. private static const RESOLVE_CONSTANT:String = "constant";
  19. private static const RESOLVE_EXTENDS:String = "extendsClass";
  20. private static const RESOLVE_INTERFACE:String = "implementsInterface";
  21. private static const RESOLVE_METHOD:String = "method";
  22. private static const RESOLVE_PROPERTY:String = "accessor";
  23. private static const RESOLVE_PROPERTY_READ:String = "readonly";
  24. private static const RESOLVE_PROPERTY_WRITABLE:String = "readwrite";
  25. private static const RESOLVE_VARIABLE:String = "variable";
  26. private static const RESOLVE_GET_INSTANCE:String = "getInstance";
  27. private static const RESOLVE_GET_CLASS:String = "getClass";
  28. private static const RESOLVE_HAS_CLASS:String = "hasClass";
  29.  
  30. // package.package.package:, package.package.package::
  31. private static const PATTERN_NAME:RegExp = /^[a-z].+([\:]+|[\.])/;
  32. // .Class, :Class, ::Class
  33. private static const PATTERN_PACKAGE:RegExp = /([\:]+|[\.])[A-Z]\w*$/;
  34. // :, ::
  35. private static const PATTERN_PATH:RegExp = /\:+/g;
  36.  
  37. // @constructor
  38.  
  39. public function ClassUtil() {
  40. super();
  41. }
  42.  
  43. // @class
  44.  
  45. public static function getInstance( value:String, domain:ApplicationDomain = null ):* {
  46. return ClassUtil.ResolveClass( value, RESOLVE_GET_INSTANCE, domain );
  47. }
  48.  
  49. public static function getClass( value:String, domain:ApplicationDomain = null ):Class {
  50. return ClassUtil.ResolveClass( value, RESOLVE_GET_CLASS, domain );
  51. }
  52.  
  53. public static function hasClass( value:String, domain:ApplicationDomain = null ):Boolean {
  54. return ClassUtil.ResolveClass( value, RESOLVE_HAS_CLASS, domain );
  55. }
  56.  
  57. public static function ResolveClass( value:String, type:String, domain:ApplicationDomain = null ):* {
  58.  
  59. if ( domain == null ) {
  60. domain = ApplicationDomain.currentDomain;
  61. }
  62.  
  63. value = ClassUtil.pathComplexName( value );
  64.  
  65. if ( type == RESOLVE_HAS_CLASS ) {
  66. return domain.hasDefinition( value );
  67. }
  68.  
  69. try {
  70. var instance:Class = domain.getDefinition( value ) as Class;
  71. return ( type != RESOLVE_GET_INSTANCE )
  72. ? instance
  73. : new instance();
  74. } catch (e:Error) {
  75. throw new IllegalOperationError(
  76. ( ( type != RESOLVE_GET_INSTANCE )
  77. ? "Cannot find class with qualified class name: \""
  78. : "Cannot create class with qualified class name: \""
  79. ) + value + "\""
  80. );
  81. }
  82.  
  83. }
  84.  
  85. // @names
  86.  
  87. public static function longName( value:* ):String {
  88. return getQualifiedClassName( value );
  89. }
  90.  
  91. public static function shortName( value:* ):String {
  92. return ClassUtil.ResolveNames( value, RESOLVE_NAME );
  93. }
  94.  
  95. public static function packageName( value:* ):String {
  96. return ClassUtil.ResolveNames( value, RESOLVE_PACKAGE );
  97. }
  98.  
  99. public static function pathName( value:* ):String {
  100. return ClassUtil.ResolveNames( value, RESOLVE_PATH );
  101. }
  102.  
  103. public static function pathComplexName( value:* ):String {
  104. return ClassUtil.ResolveNames( value, RESOLVE_PATH_COMPLEX );
  105. }
  106.  
  107. public static function SLongName( value:* ):String {
  108. return getQualifiedSuperclassName( value );
  109. }
  110.  
  111. public static function SShortName( value:* ):String {
  112. return ClassUtil.ResolveNames( value, RESOLVE_NAME, true );
  113. }
  114.  
  115. public static function SPackageName( value:* ):String {
  116. return ClassUtil.ResolveNames( value, RESOLVE_PACKAGE, true );
  117. }
  118.  
  119. public static function SPathName( value:* ):String {
  120. return ClassUtil.ResolveNames( value, RESOLVE_PATH, true );
  121. }
  122.  
  123. public static function SPathComplexName( value:* ):String {
  124. return ClassUtil.ResolveNames( value, RESOLVE_PATH_COMPLEX, true );
  125. }
  126.  
  127. private static function ResolveNames( value:*, type:String, inheritance:Boolean = false ):String {
  128.  
  129. var source:String;
  130.  
  131. if( typeof( value ) != "string" ){
  132. source = ( ! inheritance )
  133. ? longName( value )
  134. : SLongName( value );
  135. }else{
  136. source = value;
  137. }
  138.  
  139. switch( type ){
  140.  
  141. case RESOLVE_NAME:
  142. return source.replace( PATTERN_NAME, "" );
  143.  
  144. case RESOLVE_PACKAGE:
  145. source = source.replace( PATTERN_PACKAGE, "" );
  146. return ( source != value ) ? source : new String();
  147.  
  148. case RESOLVE_PATH:
  149. return source.replace( PATTERN_PATH, "." );
  150.  
  151. case RESOLVE_PATH_COMPLEX:
  152. return String(
  153. ResolveNames( value, RESOLVE_PACKAGE )
  154. + "::"
  155. + ResolveNames( value, RESOLVE_NAME )
  156. );
  157.  
  158. }
  159.  
  160. return value;
  161.  
  162. }
  163.  
  164. // @thisIs
  165.  
  166. public static function isDynamic( value:* ):Boolean {
  167. return ( describeType( value ).@isDynamic.toString() == "true" );
  168. }
  169.  
  170. public static function isFinal( value:* ):Boolean {
  171. return ( describeType( value ).@isFinal.toString() == "true" );
  172. }
  173.  
  174. public static function isStatic( value:* ):Boolean {
  175. return ( describeType( value ).@isStatic.toString() == "true" );
  176. }
  177.  
  178. public static function isConstant( value:*, name:String ):Boolean {
  179. return ResolveThisIs( value, name, RESOLVE_CONSTANT );
  180. }
  181.  
  182. public static function isInterface( value:* ):Boolean {
  183. return ResolveThisIs( value, null, RESOLVE_INTERFACE );
  184. }
  185.  
  186. public static function isMethod( value:*, name:String ):Boolean {
  187. return ResolveThisIs( value, name, RESOLVE_METHOD );
  188. }
  189.  
  190. public static function isProperty( value:*, name:String ):Boolean {
  191. return ResolveThisIs( value, name, RESOLVE_PROPERTY );
  192. }
  193.  
  194. public static function isPropertyRead( value:*, name:String ):Boolean {
  195. return ResolveThisIs( value, name, RESOLVE_PROPERTY_READ );
  196. }
  197.  
  198. public static function isPropertyWritable( value:*, name:String ):Boolean {
  199. return ResolveThisIs( value, name, RESOLVE_PROPERTY_WRITABLE );
  200. }
  201.  
  202. private static function ResolveThisIs( value:*, name:String, type:String ):Boolean {
  203.  
  204. if ( type == RESOLVE_INTERFACE ) {
  205. var describe:XML = describeType( value );
  206. return ( describe.@base == "Class"
  207. && describe.@isStatic == "true"
  208. && describe.factory..extendsClass.length() == 0 )
  209. ? true
  210. : false;
  211. }
  212.  
  213. var source:XMLList = ClassUtil.ResolveCaptureNode( value, type );
  214. return ( source.( @name == name ).@name.toString() == name );
  215.  
  216. }
  217.  
  218. // @list
  219.  
  220. public static function constantsList( value:* ):Array {
  221. return ClassUtil.ResolveListAttributes( value, RESOLVE_CONSTANT );
  222. }
  223.  
  224. public static function heritageList( value:* ):Array {
  225. return ClassUtil.ResolveListAttributes( value, RESOLVE_EXTENDS );
  226. }
  227.  
  228. public static function interfacesList( value:* ):Array {
  229. return ClassUtil.ResolveListAttributes( value, RESOLVE_INTERFACE );
  230. }
  231.  
  232. public static function methodsList( value:*, inherited:int = 0 ):Array {
  233. return ClassUtil.ResolveListAttributes( value, RESOLVE_METHOD, inherited );
  234. }
  235.  
  236. public static function propertiesList( value:*, inherited:int = 0 ):Array {
  237. return ClassUtil.ResolveListAttributes( value, RESOLVE_PROPERTY, inherited );
  238. }
  239.  
  240. public static function variablesList( value:* ):Array {
  241. return ClassUtil.ResolveListAttributes( value, RESOLVE_VARIABLE );
  242. }
  243.  
  244. private static function ResolveListAttributes( value:*, type:String, inherited:int = 0 ):Array {
  245.  
  246. var list:Array = new Array();
  247. var inheritance:String = ClassUtil.pathComplexName( value );
  248. var source:XMLList = ClassUtil.ResolveCaptureNode( value, type );
  249.  
  250. for each( var element:XML in source ){
  251.  
  252. switch( type ){
  253.  
  254. case RESOLVE_CONSTANT:
  255. case RESOLVE_VARIABLE:
  256. list.push( element.@name );
  257. break;
  258.  
  259. case RESOLVE_EXTENDS:
  260. case RESOLVE_INTERFACE:
  261. list.push( element.@type );
  262. break;
  263.  
  264. case RESOLVE_METHOD:
  265. case RESOLVE_PROPERTY:
  266. if( inherited == 0
  267. || ( inherited == -1 && element.@declaredBy != inheritance )
  268. || ( inherited == 1 && element.@declaredBy == inheritance )
  269. ){
  270. list.push( element.@name );
  271. }
  272. break;
  273.  
  274. }
  275.  
  276. }
  277.  
  278. return list;
  279.  
  280. }
  281.  
  282. // @implemented
  283.  
  284. public static function implementsMethod( value:*, inheritance:*, name:String ):Boolean {
  285. return ClassUtil.ResolveImplemented( value, inheritance, name, RESOLVE_METHOD );
  286. }
  287.  
  288. public static function implementsProperty( value:*, inheritance:*, name:String ):Boolean {
  289. return ClassUtil.ResolveImplemented( value, inheritance, name, RESOLVE_PROPERTY );
  290. }
  291.  
  292. private static function ResolveImplemented( value:*, inheritance:*, name:String, type:String ):Boolean {
  293.  
  294. var source:XMLList = ClassUtil.ResolveCaptureNode( value, type );
  295.  
  296. if ( typeof( value ) != "string" ) {
  297. value = longName( value );
  298. }
  299.  
  300. if ( typeof( inheritance ) != "string" ) {
  301. inheritance = longName( inheritance );
  302. }
  303.  
  304. return ( source.( @name == name ).@declaredBy == inheritance );
  305.  
  306. }
  307.  
  308. // @helpers
  309.  
  310. private static function ResolveCaptureNode( value:*, type:String ):XMLList {
  311.  
  312. var source:XML = describeType( value );
  313.  
  314. switch( type ){
  315.  
  316. case RESOLVE_CONSTANT:
  317. return source..constant;
  318.  
  319. case RESOLVE_EXTENDS:
  320. return source..extendsClass;
  321.  
  322. case RESOLVE_METHOD:
  323. return source..method;
  324.  
  325. case RESOLVE_PROPERTY:
  326. return source..accessor;
  327.  
  328. case RESOLVE_PROPERTY_READ:
  329. case RESOLVE_PROPERTY_WRITABLE:
  330. return source..accessor.( @access == type );
  331.  
  332. case RESOLVE_INTERFACE:
  333. return source..implementsInterface;
  334.  
  335. case RESOLVE_VARIABLE:
  336. return source..variable;
  337.  
  338. default:
  339. return null;
  340.  
  341. }
  342.  
  343. }
  344.  
  345. }
  346.  
  347. }
  348.  
  349. package kc.core {
  350.  
  351. import flash.errors.IllegalOperationError;
  352.  
  353. public class KCStatic extends Object {
  354.  
  355. // @constructor
  356.  
  357. public function KCStatic() {
  358. throw new IllegalOperationError()( "Illegal instantiation attempted on class of static type." );
  359. }
  360.  
  361. }
  362.  
  363. }

URL: http://www.kirikacode.com.ar/

Report this snippet


Comments

RSS Icon Subscribe to comments

You need to login to post a comment.