이름 기반의 유연한 객체구조를 이용하여 순차적인 데이터를 개발자가 생성하지 않고 setValue만을 호출하여 데이터처리가 가능하도록 만든 구조로 놀새가 많이 사용할 것 같아 올립니다. ( 2004/01/29 ) 144
Written by ienvyou - 최지웅
1 of 1
 


지금 하는 곳뿐만이 아니라 다른곳에서 상당히 많이 사용할 것 같아서 미리 올려둡니다.
쓰실수 있으면 쓰시구요.
Dependency를 가진 Value Object(VO)의 형태가 아니라 여러가지 형태의 데이터를 이름값에
의하여 처리가 되도록 jolt package내용을 참조하여 만들었습니다.

▶ AsiDataSet

그냥 이름하여 AsiDataSet이라고 붙였습니다  ASI(Application System Integration)이라고 
뭐 어쩌구 저쩌구 하는게 있는데요. 거기서 사용할려고 만들었다가 분명 나중에 또 쓰이게 될것같아서
잃어버릴까봐 올립니다.

어디다가 쓰려고 했냐면 메시지 포맷팅(자리수 맞추고, 순서맞추고 등등) 과 work flow처리, 
transaction처리, rule처리등을 위하여 하나의 객체를 사용하도록 하려한겁니다.

이걸 사용하는 곳은 5개의 서로다른 업무계 시스템(WAS, Tuxedo)이며 AsiDataSet에 
다른 시스템(Tuxedo, ELink, TCP/IP Socket Adapter, FTP, MQ Series, Soap)에 대한 타켓정보를
물고 들어오면 실제 DataSet에 있는 데이터를 각각의 대외시스템에 맞게끔 조합하여 처리될 수 있도록
만든 자동화 클래스의 핵심 데이터를 물고 있습니다.




/*
 * @(#)AsiDataSet.java	1.0 04/01/12
 *
 * Copyright (C) The Javapattern.info All rights reserved.
 *
 */

package com.javapattern.pool;

import java.util.Map;
import java.util.Hashtable;
import java.util.Vector;
import java.util.ArrayList;

/**
* WLI에 요청을 하게 되는 request parameter data set을 정의한다.
* Member Variable은 _를 이용하여 해당 전역변수임을 알아볼수 있도록 하였다
* 각 파라미터를 이용하여 데이터를 세팅할 수 있도록 처리하며 하나의 String index에 
* 다수개의 value값이 순차적으로 들어갈수 있는
* 형태로 선택하여 만들었다. 즉 name-value의 pair가 반드시 이루어지는 것이 아니라 1-n의 유연한 구조로서
* 데이터를 핸들링하도록 하며, 파라미터에 값이 유동적으로 처리되어질 수 있는 특징을 가지게 한다.
* 궁금한 사항이 있으면 아래 메일로 메일보내기.
*
* @version 0.0a
* @author Choi Ji Woong
*/
public class AsiDataSet extends Hashtable implements java.io.Serializable {
    protected boolean unrestricted;

    private String _svcName;

    // to do : Constructor here
    /**
    *	AsiDataSet 생성자로서 생성인수가 없으면 초기의 10의 크기로 데이터셋을 만들어제공하도록 한다.
    */
    public AsiDataSet(){
        super(10);
        unrestricted = true;
    }

    /**
    *	기본적으로 application요청에 의하여 생성하도록 한다.
    *	@param i 초기 DataSet size
    */
    public AsiDataSet(int i)	{
        super(i);
        unrestricted = true;
    }

    protected AsiDataSet(int i, boolean flag)	{
        super(i);
        unrestricted = flag;
    }

    /**
    * Service 명 설정
    * @param	svc_name	Tuxedo Service Name
    */
    public void setSvcName(String svcName){
        this._svcName = svcName;
    }

    /**
    *	Service명의 반환
    *	@return _svcName 서비스의 실제 이름
    */
    public String getSvcName() {
        return this._svcName;
    }


    /**
    *	Result를 통하여 결과값을 얻어가도록 처리한다.
    *	@param s value값에 대한 유일한 식별자
    *	@param i 객체의 위치
    *	@param obj default객체
    *	@return 결과반환값
    */
    public Object getValue(String s, int i, Object obj)	{
        Vector vector = (Vector)super.get(s);
        if(vector == null)	 return obj;
        try {
            return vector.elementAt(i);
        } catch(ArrayIndexOutOfBoundsException ex) {
            return obj;
        }
    }

    /**
    *	Result를 통하여 결과값을 얻어가도록 처리한다.
    *	@param s value값에 대한 유일한 식별자
    *	@param i 객체의 위치
    *	@param obj default객체
    */
    public Object getValue(String s, Object obj) {
        return getValue(s, 0, obj);
    }

    /**
    *	Hashtable의 s값의 데이터를 put하도록 하며
    *	실제 그안의 데이터를 순차값을 가진 Vector를 사용한다
    */
    public void setValue(String s, int i, Object obj) {
        Vector vector = (Vector)get(s);
        if(vector == null) {
            vector = new Vector(1, 5);
            put(s, vector);
        }
        if(i >= vector.size()) vector.setSize(i + 1);
        vector.setElementAt(obj, i);
    }

    /**
    *	Hashtable의 s값의 데이터를 put하도록 하며
    *	실제 그안의 데이터를 순차값을 가진 Vector를 사용한다
    *	setValue(s, 0, obj를 호출한다.
    */
    public void setValue(String s, Object obj) {
        setValue(s, 0, obj);
    }

    /**
    *	s값에 의하여 저장된 데이터의 사이즈를 구하도록 한다.
    */
    public int getCount(String s) {
        Vector vector = (Vector)super.get(s);
        if(vector == null)
            return 0;
        else
            return vector.size();
    }

    /**
    *	확장여부를 확인한다.
    */
    protected boolean expanded() {
        return true;
    }

}
이제 위의 클래스를 이용하여 legacy system과 연동후 결과값에 대한 클래스가 필요하겠네요 그 결과는 그냥 DataSet을 그대로 상속하여 클라이언트측에서도 같은 방법으로 데이터에 접근하도록 합니다.

/*
 * @(#)AsiResult.java	1.0 04/01/12
 *
 * Copyright (C) The Javapattern.info. All rights reserved.
 */

/**
* 이 클래스는 AsiDataSet의 기본적인 데이터와 값을 그래도 취합하여 사용할수 있도록
* 상속받고 있는 형태를 취한다.
* 결과값에 대한 application코드와 error 및 기타정보에 대한 내용을 담고 있도록 한다.
*
* @version 0.0a
* @author Choi Ji Woong
*/
public class AsiResult extends AsiDataSet implements  java.io.Serializable{
    // 다른 패키지 접근제한
    protected int applicationCode;
    protected static final int NO_ERROR = 0;
    protected static final int APPLICATION_ERROR = 1;
    protected static final int SYSTEM_ERROR = 2;

    // to do : Field mapping required
    protected AsiResult(int i) {
        super(i);
    }

    public int getApplicationCode() {
        return applicationCode;
    }
}
클라이언트는 Hashtable에 순차적인 List형태의 값을 저장하기 위하여 굳이 java.util.List계열의 클래스를 사용하지 않아도 된다. 그저 setValue(), getValue()메소드를 통하여 원하는 target시스템으로 data를 전송하고 받을뿐이다 위의 클래스를 테스트하는 클라이언트 코드를 보도록 하자.

public class TestClient extends Thread 
{
    public static void main(String [] args) throws Exception{
        TestClient x = new TestClient();
        x.start();
    }

    public void run() {
        try{
            AsiDataSet dataSet = new AsiDataSet();
            dataSet.setSvcName("MSS001");
            dataSet.setValue("NAME", "최지웅");
            dataSet.setValue("ADDRESS", "경기도 용인시 수지읍 동천동");
            dataSet.setValue("MOVIE", 0, "태극기휘날리며");
            dataSet.setValue("MOVIE", 1, "그녀를 모르면 간첩");
            dataSet.setValue("HOBBY", "술마시기");
            dataSet.setValue("E", "E");
            System.out.println(dataSet);
        }catch(Exception e) {
            e.printStackTrace();	
        }
    }
};
위에꺼 실행하면 아래처럼 나온다. {E=[E], NAME=[최지웅], MOVIE=[태극기휘날리며, 그녀를 모르면 간첩], HOBBY=[술마시기], ADDRESS=[경기도 용인시 수지읍 동천동]}

public class TestClient extends Thread 
{
    public static void main(String [] args) throws Exception{
        TestClient x = new TestClient();
        x.start();
    }

    public void run() {
        try{
            AsiDataSet dataSet = new AsiDataSet();
            dataSet.setSvcName("MSS001");
            dataSet.setValue("NAME", "최지웅");
            dataSet.setValue("ADDRESS", "경기도 용인시 수지읍 동천동");
            dataSet.setValue("MOVIE", 0, "태극기휘날리며");
            dataSet.setValue("MOVIE", 3, "그녀를 모르면 간첩");
            dataSet.setValue("HOBBY", "술마시기");
            dataSet.setValue("E", "E");
            System.out.println(dataSet);
        }catch(Exception e) {
            e.printStackTrace();	
        }
    }
};
위처럼 1을 3으로 바꾸고 실행하면 아래처럼 나온다. {E=[E], NAME=[최지웅], MOVIE=[태극기휘날리며, null, null, 그녀를 모르면 간첩], HOBBY=[술마시기], ADDRESS=[경기도 용인시 수지읍 동천동]} 이제부터는 호스트와 클라이언트사이의 인터페이스만 보고서도 우리는 핸들링 할수 있게 되었다.

크리에이티브 커먼즈 라이센스
Creative Commons License
2012/01/20 16:02 2012/01/20 16:02


프로젝트의 빌드버전 확인 - QA관점의 몰래 빌드 금지

SVN을 이용하여 hudson을 빌드시 SVN Head를 포함시켜 중간에 개발자가 변경하여 빌드하는 것을 방지하기 위해 만든 스크립트.

checkversion.jar 파일을 만들어 Manifest에 build date와 최종 svn version을 기록합니다.
아래 쪽의 JSP를 만들어 디플로이 시킨 후 jar 파일의 manifest를 이용하여 버전을 확인합니다.

<target name="jar-checkversion">

		<svn javahl="true"> 
		    <info target="${svn.url}/" /> 
		</svn> 
		<property name="latestRevisionNo" value="${svn.info.lastRev}"/> 
		<echo>******** URL : ${svn.url}/projects/${project.name}/${target}/${REPO_BRANCH}</echo>
		<echo>******** REVISION HEAD : ${latestRevisionNo}</echo>
		
		<jar destfile="checkversion.jar">
			<manifest>
				<attribute name="Revision-Number" value="${latestRevisionNo}"/>

				<attribute name="Build-Date" value="${DSTAMP} ${TSTAMP}"/>
			</manifest>
		</jar>
		<echo>SVN Revision : ${latestRevisionNo}</echo>
		<copy file="checkversion.jar" tofile="${build.dir}/src/${target}/lib/checkversion.jar"
			overwrite="true" failonerror="false"/>
	</target>



<%@ page import="java.util.*, java.io.*, java.util.jar.*" %>

<%!
    public String [] checkVersion(String jarFileUrl) throws Exception {
        JarFile jarFile = new JarFile(new File(jarFileUrl)); 
        Manifest manifest = jarFile.getManifest();
        Attributes attributes = (Attributes) manifest.getMainAttributes();
        String buildDate = attributes.getValue("Build-Date"); 
        String revision = attributes.getValue("Revision-Number"); 

	return new String [] {buildDate, revision};
    }
%>	

<%
    String portalJar = "/jboss/apps/admin/portal.war/WEB-INF/lib/checkversion.jar";
    String [] data = checkVersion(portalJar);

    
    out.println("Admin Portal Version<br>");
    out.println("===============================<br>");
    out.println("Build Date : " + data[0] + "<br>");
    out.println("Revision : " + data[1] + "<br><p>");
%>
크리에이티브 커먼즈 라이센스
Creative Commons License
2012/01/18 08:41 2012/01/18 08:41


<project name="Import Database" basedir="." default="import">


  <property name="sql.driver" value="com.mysql.jdbc.Driver"/>
  <property name="sql.url" value="jdbc:mysql://url:port/dbname"/>
  <property name="sql.user" value="user"/>
  <property name="sql.pass" value="pass"/>


  <target name="import">
    <sql driver="${sql.driver}" 
            src="${sql.file}" 
            url="${sql.url}" 
            userid="${sql.user}" 
            password="${sql.pass}" 
            classpath="mysql-connector-java-5.1.16-bin.jar">
    </sql>
  </target>


</project>
크리에이티브 커먼즈 라이센스
Creative Commons License
2012/01/05 10:21 2012/01/05 10:21



#!/bin/bash CHARSET=utf8 DATABASE="db_name" USER="user" PASSWORD="password" HOST="myrds.c4moohzbz3zn.us-east-1.rds.amazonaws.com" for i in `mysql --default-character-set $CHARSET -u$USER -p$PASSWORD -h $HOST  $DATABASE -e "show tables;" | sed -n 2,$\p` do mysql --default-character-set $CHARSET -u$USER -p$PASSWORD -h $HOST     $DATABASE -e "drop table $i" echo "$i table delete." done
크리에이티브 커먼즈 라이센스
Creative Commons License
2012/01/05 10:17 2012/01/05 10:17



spring과 hornetq를 사용하는 EJB 애플리케이션을 등록하다가 ear 애플리케이션 디플로이시 바인딩되지도 않은 JMS Connection Factory를 접근하다가 에러가 발생을 하는데 아래와 같이 설정을 바꿈으로써 가능합니다.

좋은 정보를 알려주신 송민우 책임, 감사합니다.

Many people talked about getting error when they deploy ear application including MDB, EJB like this :
http://stackoverflow.com/questions/4616078/how-to-order-deployment-of-ejbs-and-jms-queue-config-in-jboss-5 

http://community.jboss.org/thread/93539 http://community.jboss.org/thread/93539


In earlier version of JBoss, there was a method you can change deployment order in configuration file.

In JBoss EAP5 or AS5, you can configure deployment order like this :

$SERVER_HOME/conf/bootstrap/deployers.xml

 <!-- use legacy ordering -->
 <bean name="topContextComparator">
      <constructor factoryClass="org.jboss.system.deployers.LegacyDeploymentContextComparator" factoryMethod="getInstance"/>
         <property name="suffixOrder" class="java.util.Map">
             <map keyClass="java.lang.String" valueClass="java.lang.Integer">
              <entry>
               <key>-beans.xml</key>
               <value>200</value>
              </entry>
              <entry>
               <key>.ear</key>
               <value>1000</value>
              </entry>
              <entry>
               <key>.jar</key>
               <value>1000</value>
              </entry>
              <entry>
               <key>.war</key>
               <value>1000</value>
              </entry>
          </map>
       </property>
 </bean>


크리에이티브 커먼즈 라이센스
Creative Commons License
2011/12/20 08:57 2011/12/20 08:57