ActionScript 3 AS3 | ClassUtil |反射

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ActionScript 3 AS3 | ClassUtil |反射相关的知识,希望对你有一定的参考价值。

package kc.utils {
	
	import flash.errors.IllegalOperationError;
	import flash.system.ApplicationDomain;
	import flash.utils.describeType;
	import flash.utils.getQualifiedClassName;
	import flash.utils.getQualifiedSuperclassName;
	import kc.core.KCStatic;

	public class ClassUtil extends KCStatic {
		
		// @const
		
		private static const RESOLVE_NAME:String = "name";
		private static const RESOLVE_PACKAGE:String = "package";
		private static const RESOLVE_PATH:String = "path";
		private static const RESOLVE_PATH_COMPLEX:String = "pathComplex";
		private static const RESOLVE_CONSTANT:String = "constant";
		private static const RESOLVE_EXTENDS:String = "extendsClass";
		private static const RESOLVE_INTERFACE:String = "implementsInterface";
		private static const RESOLVE_METHOD:String = "method";
		private static const RESOLVE_PROPERTY:String = "accessor";
		private static const RESOLVE_PROPERTY_READ:String = "readonly";
		private static const RESOLVE_PROPERTY_WRITABLE:String = "readwrite";
		private static const RESOLVE_VARIABLE:String = "variable";
		private static const RESOLVE_GET_INSTANCE:String = "getInstance";
		private static const RESOLVE_GET_CLASS:String = "getClass";
		private static const RESOLVE_HAS_CLASS:String = "hasClass";
		
		// package.package.package:, package.package.package::
		private static const PATTERN_NAME:RegExp = /^[a-z].+([\:]+|[\.])/;
		// .Class, :Class, ::Class
		private static const PATTERN_PACKAGE:RegExp = /([\:]+|[\.])[A-Z]\w*$/;
		// :, ::
		private static const PATTERN_PATH:RegExp = /\:+/g;
		
		// @constructor
		
		public function ClassUtil() {
			super();
		}
		
		// @class
		
		public static function getInstance( value:String, domain:ApplicationDomain = null ):* {
			return ClassUtil.ResolveClass( value, RESOLVE_GET_INSTANCE, domain );
		}
		
		public static function getClass( value:String, domain:ApplicationDomain = null ):Class {
			return ClassUtil.ResolveClass( value, RESOLVE_GET_CLASS, domain );
		}
		
		public static function hasClass( value:String, domain:ApplicationDomain = null ):Boolean {
			return ClassUtil.ResolveClass( value, RESOLVE_HAS_CLASS, domain );
		}
		
		public static function ResolveClass( value:String, type:String, domain:ApplicationDomain = null ):* {
			
			if ( domain == null ) {
				domain = ApplicationDomain.currentDomain;
			}
			
			value = ClassUtil.pathComplexName( value );
			
			if ( type == RESOLVE_HAS_CLASS ) {
				return domain.hasDefinition( value );
			}
			
			try {
				var instance:Class = domain.getDefinition( value ) as Class;
				return ( type != RESOLVE_GET_INSTANCE ) 
					? instance 
					: new instance();					
			} catch (e:Error) {
				throw new IllegalOperationError(
					( ( type != RESOLVE_GET_INSTANCE )
						? "Cannot find class with qualified class name: \""
						: "Cannot create class with qualified class name: \""
					) + value + "\""
				);
			}
			
		}
		
		// @names
		
		public static function longName( value:* ):String {
			return getQualifiedClassName( value );	
		}
		
		public static function shortName( value:* ):String {
			return ClassUtil.ResolveNames( value, RESOLVE_NAME );
		}
		
		public static function packageName( value:* ):String {
			return ClassUtil.ResolveNames( value, RESOLVE_PACKAGE );
		}
		
		public static function pathName( value:* ):String {
			return ClassUtil.ResolveNames( value, RESOLVE_PATH );	
		}
		
		public static function pathComplexName( value:* ):String {
			return ClassUtil.ResolveNames( value, RESOLVE_PATH_COMPLEX );	
		}
		
		public static function SLongName( value:* ):String {
			return getQualifiedSuperclassName( value );	
		}
		
		public static function SShortName( value:* ):String {
			return ClassUtil.ResolveNames( value, RESOLVE_NAME, true );
		}
		
		public static function SPackageName( value:* ):String {
			return ClassUtil.ResolveNames( value, RESOLVE_PACKAGE, true );	
		}
		
		public static function SPathName( value:* ):String {
			return ClassUtil.ResolveNames( value, RESOLVE_PATH, true );	
		}
		
		public static function SPathComplexName( value:* ):String {
			return ClassUtil.ResolveNames( value, RESOLVE_PATH_COMPLEX, true );	
		}
		
		private static function ResolveNames( value:*, type:String, inheritance:Boolean = false ):String {
			
			var source:String;
			
			if( typeof( value ) != "string" ){
				source = ( ! inheritance ) 
					? longName( value ) 
					: SLongName( value );
			}else{
				source = value;
			}
			
			switch( type ){
				
				case RESOLVE_NAME:
					return source.replace( PATTERN_NAME, "" );
				
				case RESOLVE_PACKAGE:
					source = source.replace( PATTERN_PACKAGE, "" );
					return ( source != value ) ? source : new String();
					
				case RESOLVE_PATH:
					return source.replace( PATTERN_PATH, "." );
				
				case RESOLVE_PATH_COMPLEX:
					return String( 
						ResolveNames( value, RESOLVE_PACKAGE ) 
						+ "::" 
						+ ResolveNames( value, RESOLVE_NAME )
					);
				
			}
			
			return value;
			
		}
		
		// @thisIs
		
		public static function isDynamic( value:* ):Boolean {
			return ( describeType( value ).@isDynamic.toString() == "true" );
		}
		
		public static function isFinal( value:* ):Boolean {
			return ( describeType( value ).@isFinal.toString() == "true" );
		}
		
		public static function isStatic( value:* ):Boolean {
			return ( describeType( value ).@isStatic.toString() == "true" );
		}
		
		public static function isConstant( value:*, name:String ):Boolean {
			return ResolveThisIs( value, name, RESOLVE_CONSTANT );
		}
		
		public static function isInterface( value:* ):Boolean {
			return ResolveThisIs( value, null, RESOLVE_INTERFACE );
		}
		
		public static function isMethod( value:*, name:String ):Boolean {
			return ResolveThisIs( value, name, RESOLVE_METHOD );
		}
		
		public static function isProperty( value:*, name:String ):Boolean {
			return ResolveThisIs( value, name, RESOLVE_PROPERTY );
		}
		
		public static function isPropertyRead( value:*, name:String ):Boolean {
			return ResolveThisIs( value, name, RESOLVE_PROPERTY_READ );
		}
		
		public static function isPropertyWritable( value:*, name:String ):Boolean {
			return ResolveThisIs( value, name, RESOLVE_PROPERTY_WRITABLE );
		}
		
		private static function ResolveThisIs( value:*, name:String, type:String  ):Boolean {
			
			if ( type == RESOLVE_INTERFACE ) {
				var describe:XML = describeType( value );
				return ( describe.@base == "Class" 
					&& describe.@isStatic == "true" 
					&& describe.factory..extendsClass.length() == 0  ) 
						? true 
						: false;
			}
			
			var source:XMLList = ClassUtil.ResolveCaptureNode( value, type );
			return ( source.( @name == name ).@name.toString() == name  );
			
		}
		
		// @list
		
		public static function constantsList( value:* ):Array {
			return ClassUtil.ResolveListAttributes( value, RESOLVE_CONSTANT );
		}

		public static function heritageList( value:* ):Array {
			return ClassUtil.ResolveListAttributes( value, RESOLVE_EXTENDS );
		}
		
		public static function interfacesList( value:* ):Array {
			return ClassUtil.ResolveListAttributes( value, RESOLVE_INTERFACE );
		}
		
		public static function methodsList( value:*, inherited:int = 0 ):Array {
			return ClassUtil.ResolveListAttributes( value, RESOLVE_METHOD, inherited );
		}
		
		public static function propertiesList( value:*, inherited:int = 0 ):Array {
			return ClassUtil.ResolveListAttributes( value, RESOLVE_PROPERTY, inherited );
		}
		
		public static function variablesList( value:* ):Array {
			return ClassUtil.ResolveListAttributes( value, RESOLVE_VARIABLE );
		}
		
		private static function ResolveListAttributes( value:*, type:String, inherited:int = 0 ):Array {
			
			var list:Array = new Array();
			var inheritance:String = ClassUtil.pathComplexName( value );
			var source:XMLList = ClassUtil.ResolveCaptureNode( value, type );
			
			for each( var element:XML in source ){
				
				switch( type ){
					
					case RESOLVE_CONSTANT:
					case RESOLVE_VARIABLE:
						list.push( element.@name );
						break;
						
					case RESOLVE_EXTENDS:
					case RESOLVE_INTERFACE:
						list.push( element.@type );
						break;
						
					case RESOLVE_METHOD:
					case RESOLVE_PROPERTY:						
						if( inherited == 0 
							|| ( inherited == -1 && element.@declaredBy != inheritance )
							|| ( inherited ==  1 && element.@declaredBy == inheritance )
						){
							list.push( element.@name );
						}
						break;
					
				}
				
			}
			
			return list;
			
		}
		
		// @implemented
		
		public static function implementsMethod( value:*, inheritance:*, name:String ):Boolean {
			return ClassUtil.ResolveImplemented( value, inheritance, name, RESOLVE_METHOD );
		}
		
		public static function implementsProperty( value:*, inheritance:*, name:String ):Boolean {
			return ClassUtil.ResolveImplemented( value, inheritance, name, RESOLVE_PROPERTY );
		}
		
		private static function ResolveImplemented( value:*, inheritance:*, name:String, type:String ):Boolean {
			
			var source:XMLList = ClassUtil.ResolveCaptureNode( value, type );
			
			if ( typeof( value ) != "string" ) {
				value = longName( value );
			} 
			
			if ( typeof( inheritance ) != "string" ) {
				inheritance = longName( inheritance );
			}
			
			return ( source.( @name == name ).@declaredBy == inheritance );
			
		}
		
		// @helpers
		
		private static function ResolveCaptureNode( value:*, type:String ):XMLList {
			
			var source:XML = describeType( value );
			
			switch( type ){
				
				case RESOLVE_CONSTANT:
					return source..constant;
				
				case RESOLVE_EXTENDS:
					return source..extendsClass;
				
				case RESOLVE_METHOD:
					return source..method;
				
				case RESOLVE_PROPERTY:
					return source..accessor;
				
				case RESOLVE_PROPERTY_READ:
				case RESOLVE_PROPERTY_WRITABLE:
					return source..accessor.( @access == type );
				
				case RESOLVE_INTERFACE:
					return source..implementsInterface;
				
				case RESOLVE_VARIABLE:
					return source..variable;
				
				default:
					return null;
				
			}	
			
		}
		
	}
	
}

package kc.core {

	import flash.errors.IllegalOperationError;
	
	public class KCStatic extends Object {
		
		// @constructor
		
		public function KCStatic() {
			throw new IllegalOperationError()( "Illegal instantiation attempted on class of static type." );
		}
		
	}
	
}

以上是关于ActionScript 3 AS3 | ClassUtil |反射的主要内容,如果未能解决你的问题,请参考以下文章

[ActionScript 3.0] AS3.0 水面波纹效果

ActionScript 3 AS3:使用SWFObject2和AS3传递变量

ActionScript 3 克隆数组(AS3)

ActionScript 3 AS3序列化

ActionScript 3 As3初始上限

ActionScript 3 AS3 HTML清理