찬익님의 블로그(http://blog.chanik.com/25)로 부터 매우 재미있는 내용을 봤다. 바로 커스텀 메타데이터 태그(custom metadata tag)에 대한 내용인데 커스텀 컴포넌트, 커스텀 이벤트등의 용어는 들어봤어도 커스텀 메타데이터 태그는 생소하다. 말그대로 Flex에서 사용하는 메타데이터 태그인 [Event], [Bindable] 이런 것 들은 사실 예전부터 mxmlc로 컴파일될 때에 ActionScript 3.0으로 변환된다는 것은 알고 있었지만 메타데이터 태그가 이렇게 사용되는지에 대한 내막은 전혀 알지 못했던 것이 사실이다. 아무튼 너무 좋은 정보라 공유하고자 한다.

사실 Flex 2시절부터 커스텀 메타데이타에 대한 이야기가 있었다고 한다. 하지만 Flex 3서부터 컴파일 옵션에 "-keep-as3-metadata MyTag"와 같은 형태로 사용할 수 있게 되었다. 이는 다음과 같이 ActionScript 3.0 코드에서 사용할 수 있게 된다.
[Listen(obj="this.closeButton", event="click")]
public function closeClickHandler(event:MouseEvent) {...}

메타데이타 태그는 위처럼 메소드 뿐 아니라 변수 및 클래스에도 사용할 수 있다.


커스텀 메타데이타를 사용하는 방법

커스텀 메타데이타를 사용하는 방법은 3단계로 이뤄진다.

1. 컴파일러 구성
Flex 프로젝트 컴파일 옵션으로 "-keep-as3-metadata+=Meta1, Meta2" 를 삽입한다. 만약 라이브러리 프로젝트에서 한다면 거기에 이 옵션을 사용하면 이 라이브러리 프로젝트를 참조하는 다른 프로젝트에 따로 줄필요는 없다.

2. metadata를 작성

package
{
    [Meta2(param1 = "param 1 value")]
    public class TestClass
    {

        [Meta1(param1 = "param 1 value", param2 = "param 2 value")]
        public var test1:String;
        
        
        [Meta2(paramA = "param 1 value", paramB = "param 2 value")]
        public function get test2():String
        {
            return null;
        }
        
        public function set test2(val:String):void
        {
        }

        [Meta1(param1 = "param 1 value")]
        public function someMethod():void
        {
        };

    }
}

3. 런타임(runtime)시에 작성한 메타데이타를 사용
describeType(TestClass)를 이용한다. 위처럼 클래스와 메소드에 메타데이타를 작성했다면 다음과 같이 E4X형태의 XML로 접근할 수 있다.

<type name="TestClass" base="Class" isDynamic="true" isFinal="true" isStatic="true">
  <extendsClass type="Class"/>
  <extendsClass type="Object"/>
  <accessor name="prototype" access="readonly" type="*" declaredBy="Class"/>
  <factory type="TestClass">

    <metadata name="Meta2">
      <arg key="param1" value="param 1 value"/>
    </metadata>

    <extendsClass type="Object"/>

    <method name="someMethod" declaredBy="TestClass" returnType="void">
      <metadata name="Meta1">
        <arg key="param1" value="param 1 value"/>
      </metadata>
    </method>

    <variable name="test1" type="String">
      <metadata name="Meta1">
        <arg key="param1" value="param 1 value"/>
        <arg key="param2" value="param 2 value"/>
      </metadata>
    </variable>

    <accessor name="test2" access="readwrite" type="String" declaredBy="TestClass">
      <metadata name="Meta2">
        <arg key="paramA" value="param 1 value"/>
        <arg key="paramB" value="param 2 value"/>
      </metadata>
    </accessor>

  </factory>
</type>

만약 Class의 [Meta2]의 param1에 접근한다면 다음과 같처럼 하면 된다.
var testClass:TestClass = new TestClass();
var xml:XML = describeType(testClass);
trace(xml.metadata.(@name==Meta2).arg.(@key==param1).@value);

위에 대한 결과는 'param 1 value'이 된다.


어떻게 활용할 수 있을까?
이것을 어떻게 활용할지에 대해서는 찬익님의 언급처럼 FlexUnit 4에서 지원하는 [Test] [BeforeClass]등과 같은 좋은 예시가 있다. 그 외에 것도 예제가 있는지 확인해봤다. 그 결과 재미있는 글을 발견했다.

Annotating ActionScript Classes with Custom Metadata + Simple ORM Framework for AIR

이 글에서 말하고 있는 요지는 커스텀 메타데이타를 이용해서 Value Object로 작성한 클래스에 이로 만들어진 객체가 데이타베이스의 어떤 테이블과 어떤 필드에 들어가는지 결정해줄 수 있다는 것이다.


package
{
	[Bindable]
	[Table(name="contact")]
	public class Contact
	{
		[Id]
		[Column(name="contact_id")]
		public var contactId:int;

		[Column(name="first_name")]
		public var firstName:String;

		[Column(name="last_name")]
		public var lastName:String;
		public var address:String;
		public var city:String;
		public var state:String;
		public var zip:String;
		public var phone:String;
		public var email:String;
	}
}


위처럼 작성된 클래스는 contactId 값은 contact 테이블의 contact_id 필드와 매치가 되도록 만든다는 것이다. [Id]메타데이타는 Primay Key와 같은 존재이다. 결국 이것을 해석해서 DB와 연동하는 AIR기반의 EntityManager를 만들어 위 클래스의 객체를 다음과 같이 사용하면 DB연동까지 된다.


var contact:Contact = new Contact();
contact.firstName = "Christophe";
contact.lastName = "Coenraets";
contact.email = "ccoenrae@adob.com";
entityManager.save(contact);


이를 수정하려면 다음처럼 쓴다.
contact.firstName = "Chris";
entityManager.save(contact);


삭제하려면 다음처럼 쓴다.
entityManager.remove(contact);

너무 기발하다. 만약 Metadata를 사용하지 않았다면 Value Object와 DB 테이블의 필드명을 맞추기 위해 좀 노가다를 해야할지 모른다. 그런데 Metadata를 이용함으로써 프레임워크 단위로 말끔하게 이 문제를 해결해준다. 

이에 대한 소스와 테스트 자료는 [여기]에서 다운로드 받는다.
혹시 링크가 깨졌다면 다음 링크에서 받길 바란다. 
 
이렇게 활용할 수 있다는 것이 감동이다. 
 

정리하며
찬익(http://blog.chanik.com)님 덕분에 아침부터 재미있는 정보를 얻을 수 있었다. 좋은 정보를 공유해주신 찬익님께 감사하며 커스텀 메타데이타에 대한 활용을 담은 글들이 많이 나왔으면 한다.


참고글
Custom metadata in three simple steps.
Annotating ActionScript Classes with Custom Metadata + Simple ORM Framework for AIR
찬익님의 커스텀 메타데이터 태그


위 모든 예제는 Flash Builder 4 및 Flex Builder 3에서 테스트 해볼 수 있습니다.


글쓴이 : 지돌스타(http://blog.jidolstar.com/620)

+ Recent posts