IBM®
메인 컨텐츠로 가기
    Korea [국가변경]    이용약관
 
 
   
        제품    서비스 & 솔루션    고객지원 & 다운로드    회원 서비스    
메인 컨텐츠로 가기

한국 developerWorks  >  자바 | XML | 오픈 소스  >

JiBX 1.2, Part 2: XML 스키마를 Java 코드로 변환

XML 스키마에서 정돈된 형태의 사용자 정의 Java 코드 생성하기

developerWorks
Go to the previous page14 페이지 중 7 페이지Go to the next page

문서 옵션
PDF format - Fits A4 and Letter

PDF - Fits A4 and Letter
222 KB (36 pages)

Get Adobe® Reader®

샘플 코드


제안 및 의견
피드백

튜토리얼 평가

이 컨텐츠를 개선하기 위한 도움을 주십시오.


데이터 모델 사용자 정의하기

이 튜토리얼의 앞에서 설명한 예제에서는 간단한 CodeGen 사용자 정의를 살펴보았으며, CodeGen이 기본 설정을 사용하여 HR-XML TimeCard 스키마를 처리하는 방법에 대해서도 설명했다. 이제 몇 가지 강력한 사용자 정의를 살펴볼 것이다.

데이터 모델 사용자 정의하기

CodeGen에서 기본 설정을 사용하여 생성된 데이터 모델 코드에는 몇 가지 단점이 있다. 그 중 하나는 스키마 유형 이름이 모두 Type으로 끝나기 때문에 해당하는 생성된 클래스 이름이 필요 이상으로 길어질 수 있다는 것이다. 스키마 네임스페이스 org.hrxml.ns에서 생성된 패키지 이름은 합리적이긴 하지만 구체적으로 TimeCard 문서를 위한 데이터 모델임을 나타내는 패키지 이름을 사용하는 것이 더 효과적이다.

Listing 11에서는 생성된 데이터 모델 클래스의 또 다른 약점을 보여 준다. 여기에서는 java.math.BigInteger를 사용해서 xs:integer 유형을 나타낸다. 이 유형이 표준 Java 클래스를 사용하여 xs:integer를 가장 정확하게 표현할 수 있는 유형이기는 하지만 BigInteger는 간단한 int 프리미티브 또는 java.lang.Integer 오브젝트 유형에 비해 사용하기가 까다롭다. 아쉽게도, xs:int 유형이 더 적합하다 하더라도 xs:integer 유형을 사용하여 스키마를 작성하는 경우가 종종 있기 때문에 생성된 코드에서 BigInteger 값을 처리해야 한다. GenderCode에 허용되는 실제 값이 모두 한 자리 숫자인(listing 하단의 원래 스키마 부분 참조) 이 예제가 이에 해당한다.


Listing 11. xs:integer 생성 예제
/**
 * Schema fragment(s) for this class:
 * <pre>
 * <xs:element xmlns:xs="http://www.w3.org/2001/XMLSchema" type="xs:integer" 
 *    name="GenderCode"/>
 * </pre>
 */
public class GenderCode
{
    private BigInteger genderCode;

    /**
     * Get the 'GenderCode' element value.
     *
     * @return value
     */
    public BigInteger getGenderCode() {
        return genderCode;
    }

    /**
     * Set the 'GenderCode' element value.
     *
     * @param genderCode
     */
    public void setGenderCode(BigInteger genderCode) {
        this.genderCode = genderCode;
    }
}

  <xsd:simpleType name="GenderCodeType">
    <xsd:annotation>
      <xsd:documentation>Must conform to ISO 5218 - Representation of Human Sexes 
         (0 - Not Known; 1 - Male; 2 - Female; 9 - Not specified)</xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:integer">
      <xsd:pattern value="[0129]"/>
    </xsd:restriction>
  </xsd:simpleType>

Listing 12에서는 생성된 데이터 모델의 이러한 특성을 개선하기 위한 사용자 정의를 보여 준다. package="org.hrxml.timecard" 속성은 생성된 클래스에 사용할 Java 패키지를 지정한다. type-substitutions="xs:integer xs:int" 속성은 CodeGen에서 적용할 스키마 유형 대체를 정의한다. 이 경우에는 xs:integer가 스키마에서 참조될 때마다 xs:int 유형을 사용한다. 목록에 유형 이름을 추가하여 여러 쌍의 대체를 정의할 수 있다. 이 경우 공백을 구분 기호로 사용하여 쌍과 쌍을 구분하고 각 쌍에 포함된 각각의 유형 이름을 구분해야 한다.

중첩된 name-converter 요소는 Java 이름으로 변환할 XML 이름에 대한 처리 방법을 구성한다. 이 예제의 경우, strip-suffixes="Type" 속성은 CodeGen이 이름 끝에 있는 Type을 항상 제거하도록 한다. 이 속성을 사용하여 제거할 여러 대체 항목을 공백으로 구분된 목록으로 제공할 수 있다. 또한 strip-prefixes 속성과 여러 다른 형식의 사용자 정의를 사용하여 이름 앞쪽에 있는 불필요한 텍스트를 제거할 수도 있다. 이름 변환 중에 실제로 특별한 작업을 수행하려는 경우 기본 이름 변환 클래스를 사용자의 고유한 구현으로 바꿀 수도 있다. 이러한 name-converter 옵션에 대한 자세한 설명은 JiBX CodeGen 문서에서 볼 수 있다.

마지막으로, 중첩된 class-decorator 요소는 코드 생성 시퀀스에 데코레이터를 추가한다. 이 예제에서는 CodeGen 배포판의 일부로 제공되는 사전 정의된 데코레이터를 사용하며, 이 데코레이터는 컬렉션 값에 유용하게 사용할 수 있는 지원 메소드를 추가한다. CodeGen은 구성된 코드 생성 데코레이터를 차례대로 호출하여 데이터 모델 클래스에 대한 소스 코드를 생성하며, 이러한 데코레이터를 통해 CodeGen에서 생성된 필드, 메소드 및 클래스 구문을 수정하거나 추가할 수도 있다. 이러한 각 구문은 Eclipse AST(Abstract Syntax Tree) 구현을 통해 데코레이터에게 AST 구성 요소로 전달된다. 제공된 데코레이터(여기에서 메소드를 추가하는 데 사용한 org.jibx.schema.codegen.extend.CollectionMethodsDecorator 데코레이터 및 java.io.Serializable 인터페이스와 버전 ID(선택적)를 데이터 모델 클래스에 추가하는 데 사용된 org.jibx.schema.codegen.extend.SerializableDecorator 포함)는 Eclipse AST를 사용하여 CodeGen을 확장하는 예제를 제공한다. 따라서 이러한 클래스의 코드를 기반으로 사용자 고유의 데코레이터를 쉽게 작성할 수 있다.


Listing 12. TimeCard 사용자 정의 예제
<schema-set xmlns:xs="http://www.w3.org/2001/XMLSchema" package="org.hrxml.timecard"
    type-substitutions="xs:integer xs:int">
  <name-converter strip-suffixes="Type"/>
  <class-decorator class="org.jibx.schema.codegen.extend.CollectionMethodsDecorator"/>
</schema-set>

custgen1 Ant 대상을 사용하여 Listing 12 사용자 정의를 실행하거나 custom1 대상을 사용하여 생성, 컴파일, 바인딩 및 테스트를 차례대로 실행할 수 있다. Listing 13에서는 사용자 정의의 적용 결과를 보여 준다. TimeCardType 클래스 이름이 TimeCard로 변경되었고, List get 및 set 메소드 외에도 size, add, 인덱싱된 get 및 clear 메소드가 추가되었다. GenderCode 클래스의 경우 BigInteger 참조가 단순 int 프리미티브 유형으로 바뀌었다.


Listing 13. 사용자 정의된 데이터 모델
/** 
 * Schema fragment(s) for this class:
 * <pre>
 * ...
 * </pre>
 */
public class TimeCard
{
    ...
    private List<ReportedTime> reportedTimeList = new ArrayList<ReportedTime>();
    ...
    /** 
     * Get the list of 'ReportedTime' element items.
     * 
     * @return list
     */
    public List<ReportedTime> getReportedTimes() {
        return reportedTimeList;
    }

    /** 
     * Set the list of 'ReportedTime' element items.
     * 
     * @param list
     */
    public void setReportedTimes(List<ReportedTime> list) {
        reportedTimeList = list;
    }

    /** 
     * Get the number of 'ReportedTime' element items.
     * @return count
     */
    public int sizeReportedTime() {
        return reportedTimeList.size();
    }

    /** 
     * Add a 'ReportedTime' element item.
     * @param item
     */
    public void addReportedTime(ReportedTime item) {
        reportedTimeList.add(item);
    }

    /** 
     * Get 'ReportedTime' element item by position.
     * @return item
     * @param index
     */
    public ReportedTime getReportedTime(int index) {
        return reportedTimeList.get(index);
    }

    /** 
     * Remove all 'ReportedTime' element items.
     */
    public void clearReportedTime() {
        reportedTimeList.clear();
    }
    ...
}
/** 
 * Schema fragment(s) for this class:
 * <pre>
 * &lt;xs:element xmlns:xs="http://www.w3.org/2001/XMLSchema" type="xs:int"
 *   name="GenderCode"/>
 * </pre>
 */
public class GenderCode
{
    private int genderCode;

    /** 
     * Get the 'GenderCode' element value.
     * 
     * @return value
     */
    public int getGenderCode() {
        return genderCode;
    }

    /** 
     * Set the 'GenderCode' element value.
     * 
     * @param genderCode
     */
    public void setGenderCode(int genderCode) {
        this.genderCode = genderCode;
    }
}




위로


사용하지 않는 정의 제거

첫 번째 사용자 정의 예제에서는 간단한 원래 스키마를 사용하여 생성된 데이터 모델에 포함된 유형 정의를 제어하는 방법을 살펴보았다. 이 예제에서는 generate-all="false"를 사용하여 모든 전역 정의가 생성되지 않도록 설정하고 includes 목록을 사용하여 특정 정의를 생성하도록 설정했다. Listing 14에서는 이러한 속성이 추가된 TimeCard 스키마에 대한 수정된 사용자 정의를 보여 준다. 이 경우에는 TimeCard 표현에 사용되는 모든 항목과 함께 TimeCard 요소가 생성된 데이터 모델에 포함된다.


Listing 14. TimeCard 구성 요소만을 사용한 사용자 정의
<schema-set xmlns:xs="http://www.w3.org/2001/XMLSchema" package="org.hrxml.timecard"
    type-substitutions="xs:integer xs:int" generate-all="false">
  <name-converter strip-suffixes="Type"/>
  <class-decorator class="org.jibx.schema.codegen.extend.CollectionMethodsDecorator"/>
  <schema name="TimeCard.xsd" includes="TimeCard"/>
</schema-set>

CodeGen에서 custgen2 Ant 대상을 사용하여 이 사용자 정의를 실행하거나 custom2 대상을 사용하여 생성, 컴파일, 바인딩 및 테스트를 차례대로 실행할 수 있다. 이 변경으로 인해 데이터 모델의 최상위 레벨 클래스 수가 15개에서 10개로 줄어들면서 데이터 모델이 단순해진다.




위로



Go to the previous page14 페이지 중 7 페이지Go to the next page
    IBM 소개 개인정보 보호정책 문의