In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

JSON オブジェクトのデコードとクラスプロパティの列挙

JSON オブジェクトのデコードとクラスプロパティの列挙

as3corelib の JSON クラスだと、デコード後は Object 型になってしまうので、
型を指定できるように CustomJSON クラスを作ってデコードしてます。

クラスプロパティの列挙についてはおまけ。

--- 参考 ---
BeInteractive! - for..inループの仕様変更
http://www.be-interactive.org/?itemid=26

@author tkinjo
Get Adobe Flash player
by tkinjo 30 Sep 2009
/**
 * Copyright tkinjo ( http://wonderfl.net/user/tkinjo )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/mFLm
 */

package  
{
	import flash.display.Sprite;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.utils.describeType;
	
	/**
	 * JSON オブジェクトのデコードとクラスプロパティの列挙
	 * 
	 * as3corelib の JSON クラスだと、デコード後は Object 型になってしまうので、
	 * 型を指定できるように CustomJSON クラスを作ってデコードしてます。
	 * 
	 * クラスプロパティの列挙についてはおまけ。
	 * 
	 * --- 参考 ---
	 * BeInteractive! - for..inループの仕様変更
	 * http://www.be-interactive.org/?itemid=26
	 * 
	 * @author tkinjo
	 */
	public class Main extends Sprite
	{
		
		public function Main() 
		{
			var textField:TextField = new TextField();
			textField.autoSize = TextFieldAutoSize.LEFT;
			addChild( textField );
			
			var a:A = new A();
			a.value = "0";
			a.values = [ "a", "b", "c" ];
			
			var jsonString:String = CustomJSON.encode( a );
			textField.appendText( jsonString + "\n\n" );
			
			var decodedA:A = CustomJSON.decode( jsonString, A );
			
			// クラスプロパティの列挙
			var elementRegExp:RegExp = /^<(variable|accessor|constant)/;
			
			/* // なぜか wonderfl では動かず。代わりの処理は for each 三連続。
			for each( var children:XML in describeType(decodedA).children() ) {
				if ( elementRegExp.test( children.toString() ) )
					textField.appendText( "decodedA." + children.@name + " = " + decodedA[ children.@name ] + "\n" );
			}//*/
			
			for each( var variable:XML in describeType(decodedA).variable )
				textField.appendText( "decodedA." + variable.@name + " = " + decodedA[ variable.@name ] + "\n" );
			
			for each( var accessor:XML in describeType(decodedA).accessor )
				textField.appendText( "decodedA." + accessor.@name + " = " + decodedA[ accessor.@name ] + "\n" );
			
			for each( var constant:XML in describeType(decodedA).constant )
				textField.appendText( "decodedA." + constant.@name + " = " + decodedA[ constant.@name ] + "\n" );
		}
		
	}
	
}

import com.adobe.serialization.json.JSON;
class CustomJSON 
{
	public static function decode( jsonString:String, jsonClass:Class, exact:Boolean = false ):* {
		
		var tempJsonObject:Object = JSON.decode( jsonString );
		
		var jsonObject:Object = new jsonClass();
		
		for( var key:String in tempJsonObject ) {
			
			if( jsonObject.hasOwnProperty( key ) )
				jsonObject[ key ] = tempJsonObject[ key ];
				
			else if( exact )
				throw new CustomJSONDecodeError( "デコードに失敗しました。" );
		}
		
		return jsonObject;
	}
	
	public static function encode( object:Object ):String {
		
		return JSON.encode( object );
	}
}

class CustomJSONDecodeError extends Error
{
	
	public function CustomJSONDecodeError( message:String ) 
	{
		super( message );
	}
	
}

class JSONObject
{
	public static const OBJECT_NAME:String = "JSONObject";
	private var _objectName:String;
	public function get objectName():String {
		
		if ( !_objectName )
			throw new Error("json object name isn't set.");
		
		return _objectName;
	}
	public function set objectName( value:String ):void { _objectName = value; }
	
	public function JSONObject() 
	{
		_objectName = this["constructor"].OBJECT_NAME;
	}
}

class A extends JSONObject
{
	public static const OBJECT_NAME:String = "A";
	
	public var value:String;
	public var values:Array;
}