Created
March 4, 2012 11:17
-
-
Save andreiRS/1972456 to your computer and use it in GitHub Desktop.
AS3 Object that can copy all properties(+recursive) from another object to himself
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.rsurdu.utils | |
{ | |
import flash.utils.Dictionary; | |
import flash.utils.describeType; | |
import flash.utils.getDefinitionByName; | |
import flash.utils.getQualifiedClassName; | |
import mx.utils.UIDUtil; | |
public class CloneableVO extends Object implements ICloneable | |
{ | |
public var uid:String; | |
public function CloneableVO(data:Object = null) | |
{ | |
super(); | |
if (data) | |
clone(data); | |
if (uid == null || uid.length == 0) | |
uid = UIDUtil.createUID(); | |
} | |
public function clone(o:Object, forceNewReference : Boolean = false):Object | |
{ | |
if(forceNewReference) | |
clonedObjects = new Dictionary(true); | |
if (clonedObjects[o] == null) | |
cloneInternal(o, this); | |
else | |
return clonedObjects[o]; | |
return this; | |
} | |
private var clonedObjects:Dictionary = new Dictionary(true); | |
private function cloneInternal(source:Object, target:Object):void | |
{ | |
clonedObjects[source] = target; | |
var classInfo:XML = describeType(target); | |
var propertyList:XMLList = classInfo..variable + classInfo..accessor.(@access == "readwrite"); | |
var propertyName:String; | |
var propertyType:String; | |
var propertyValue:*; | |
var fullClassName:String; | |
var viewClass:Class; | |
var instance:*; | |
var classIsDynamic:Boolean = classInfo.@isDynamic == "true"; | |
if (classIsDynamic) | |
{ | |
var dynamicTypeOf:String; | |
for (var dynamicProp:String in source) | |
{ | |
dynamicTypeOf = typeof source[dynamicProp]; | |
propertyList += <variable name={dynamicProp} type={dynamicTypeOf}/>; | |
} | |
} | |
for each (var propertyXML:XML in propertyList) | |
{ | |
propertyName = propertyXML.@name; | |
propertyType = propertyXML.@type; | |
propertyType = propertyType.toLowerCase(); | |
if (classIsDynamic == false && source.hasOwnProperty(propertyName) == false) | |
continue; | |
propertyValue = source[propertyName]; | |
if (propertyValue == null) | |
continue; | |
if (isSimpleType(propertyType)) | |
{ | |
target[propertyName] = propertyValue; | |
} else if (propertyType == "date") | |
{ | |
//TODO: Test with date | |
target[propertyName] = new Date( | |
(propertyValue as Date).fullYear, | |
(propertyValue as Date).month, | |
(propertyValue as Date).date, | |
(propertyValue as Date).hours, | |
(propertyValue as Date).minutes, | |
(propertyValue as Date).seconds | |
); | |
} else if (propertyType == "array") | |
{ | |
if (target[propertyName] == null) | |
target[propertyName] = []; | |
var index:uint = 0; | |
//TODO: Must change the algoritm so it knows | |
//how to mach elements in array for correct cloning | |
// also to take in consideration when the arrays have different nr of elements | |
for each (var arrayElement:Object in propertyValue) | |
{ | |
if (arrayElement == null) | |
{ | |
index++; | |
continue; | |
} | |
if(clonedObjects[arrayElement] != null) | |
{ | |
index++; | |
continue; | |
} | |
if (target[propertyName][index] == null) | |
{ | |
fullClassName = getQualifiedClassName(arrayElement); | |
if (fullClassName == "String") | |
{ | |
(target[propertyName] as Array)[index] = (source[propertyName] as Array)[index]; | |
index++; | |
continue; | |
} else | |
{ | |
viewClass = getDefinitionByName(fullClassName) as Class; | |
instance = new viewClass(); | |
} | |
} else | |
{ | |
instance = target[propertyName][index]; | |
} | |
cloneInternal(arrayElement, instance); | |
(target[propertyName] as Array)[index] = instance; | |
index++; | |
} | |
} else | |
{ | |
if(clonedObjects[propertyValue]==null){ | |
fullClassName = getQualifiedClassName(propertyValue); | |
viewClass = getDefinitionByName(fullClassName) as Class; | |
if (target[propertyName] == null) | |
target[propertyName] = new viewClass(); | |
cloneInternal(propertyValue, target[propertyName]); | |
}else | |
{ | |
if (target[propertyName] == null) | |
target[propertyName] = clonedObjects[propertyValue]; | |
} | |
} | |
} | |
} | |
private function isSimpleType(type:String):Boolean | |
{ | |
switch (type.toLowerCase()) | |
{ | |
case "uint": | |
case "int": | |
case "number": | |
case "string": | |
case "boolean": | |
case "class": | |
{ | |
return true; | |
} | |
} | |
return false; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment