JBoss용 모니터링 엔진 및 OA&M(Operation Administration and Management) 을 만들고 있는 중입니다. 얼핏 보면 개념이 단순하면서도 파고 들어가면 복잡한 것이 JBoss입니다. Multiplexing 기능 및 개념이 있었다면 편했었을 텐데 플러그인 구조의 아픔이 이 툴을 만들때 나타나고 있습니다.

각설하고 smooks라는 도구가 있습니다. EAI에서 자주 사용하는 transformation 도구입니다. 즉 다양한 source-target을 변환시킬 수 있는 도구인데 configuration 핸들러로 xml binding시에도 편리하게 사용 가능합니다.

이러한 변환도구의 output filter에 freemarker 템플릿을 이용하면 어떠한 메시지라도 다양한 결과값으로 전환해지는 것이 가능합니다. 안타깝게도 smooks라는 걸 모르는 분들이 대부분이고 제가 나중에 또 다른 모듈을 만들어야 할지 모르므로 기억을 남깁니다.

Java to XML이기 때문에 입력은 없습니다. Smooks config에서는 단순히 결과값이 freemarker 템플릿인 ftl 파일로 옮겨갈 것이라고 선언합니다.

smooks-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd" xmlns:ftl="http://www.milyn.org/xsd/smooks/freemarker-1.1.xsd" xmlns:jb="http://www.milyn.org/xsd/smooks/javabean-1.2.xsd">
  <ftl:freemarker applyOnElement="#document">
    <ftl:template>/org/jboss/jam/admin/jdbc/model/xa-datasource.ftl</ftl:template>
  </ftl:freemarker>
</smooks-resource-list>


그리고 변환을 실제 실행시키는 자바 코드를 작성합니다.

Test Java Source
package org.jboss.jam.admin.jdbc.model;

import org.jboss.jam.admin.jdbc.model.CommonDataSourceConfig;
import org.milyn.Smooks;
import org.milyn.SmooksException;
import org.milyn.payload.JavaSource;
import org.xml.sax.SAXException;

import javax.xml.transform.stream.StreamResult;
import java.io.IOException;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

public class XATest {
    @SuppressWarnings("unchecked")
    protected String runSmooksTransform(Object inputJavaObject) throws IOException, SAXException {
        Smooks smooks = new Smooks("smooks-config.xml");

        try {
           
            StringWriter writer = new StringWriter();
    
            JavaSource source = new JavaSource(inputJavaObject);
            source.setEventStreamRequired(false);
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("dsconfig", (CommonDataSourceConfig)inputJavaObject);
            source.setBeans(map);
            smooks.filterSource(source, new StreamResult(writer));
            
            return writer.toString();
            
        } finally {
            smooks.close();
        }
    }

    public static void main(String[] args) throws IOException, SAXException, SmooksException {
        XATest smooksMain = new XATest();
        XADataSourceConfig config = new XADataSourceConfig();
        config.setJndiName("JiraDS");
        config.setUseJavaContext("true");
        config.setXaDatasourceClass("com.mysql.jdbc.DataSource");
        config.addDataSourceProperty("DatabaseName", "multi1");
        config.addDataSourceProperty("ServerName", "localhost");
        config.addDataSourceProperty("PortNumber", "1360");

        System.out.println("This needs to be transformed to XML.");

        String transResult = smooksMain.runSmooksTransform(config);
        System.out.println("\n");
        System.out.println(transResult);
    }

}

        config.addDataSourceProperty("DatabaseName", "multi1");
        config.addDataSourceProperty("ServerName", "localhost");
        config.addDataSourceProperty("PortNumber", "1360");
붉은 글씨로 쓰여진 부분은 hashmap에 저장하는 부분입니다.
JavaSource의 setBean메소드에서 freemarker에서 사용하게 될 객체를 내보내고 있습니다.
map.put("dsconfig", (CommonDataSourceConfig)inputJavaObject);
위의 map에 저장한 dsconfig는 JavaBeans 규약에 의해 getter를 통한 접근을 시도하게 될 것입니다.

마지막으로 freemarker template를 선언합니다.

<?xml version="1.0" encoding="UTF-8"?>
<#-- ignore white space for common config -->
<datasources>
  <xa-datasource>
    <jndi-name>${dsconfig.jndiName}</jndi-name>
    <xa-datasource-class><#if dsconfig.xaDatasourceClass??>${dsconfig.xaDatasourceClass}<#else></#if></xa-datasource-class>
    <#list dsconfig.xaDatasourceProperty?keys as key>
        <xa-datasource-property name="${key}">${dsconfig.xaDatasourceProperty[key]}</xa-datasource-property>
    </#list>
    <#include "/org/jboss/jam/admin/jdbc/model/common-datasource.ftl">
    
  </xa-datasource>
</datasources>




그냥 자바 객체의 getter에 접근할 때는 dsconfig.getterName을 호출하면 됩니다. HashMap의 경우 key, value의 쌍으로 구성되어 있으므로 ?keys를 이용하여 해당 키값을 'key'로 추출한 후 "object.getter[key]" 의 형태로 추출하면 됩니다.



크리에이티브 커먼즈 라이센스
Creative Commons License
2009/12/11 14:59 2009/12/11 14:59
http://www.javapattern.info/trackback/315