|  |  |
|
CodeGen 사용자 정의 소개
이 섹션에서는 CodeGen을 사용자 정의하여 간단한 스키마에서 생성된 코드의 구조를 제어하는
기본적인 방법에 대해 설명한다.
간단한 사용자 정의 예제
CodeGen은 코드 및 바인딩 생성의 여러 부분을 제어할 수 있는 강력한 사용자 정의 기능을
지원한다. 적용할 사용자 정의 세트는 스키마 구성 요소와 관련된 중첩 요소로 구성된 XML
문서로 CodeGen에 전달된다. Listing 5는 간단한 예제이다.
Listing 5. 간단한 사용자 정의 예제
<schema prefer-inline="true" show-schema="false" enumeration-type="simple"
generate-all="false" includes="order item"/> |
Listing 5의 사용자 정의는 네임스페이스를 지정하지 않은 단일
스키마 요소로 구성되어 있으며, 여러 다양한 속성을 사용하여 적용할 특정 사용자 정의를
지정한다. (지금까지는 단일 스키마 정의만을 다루고 있기 때문에 이처럼 매우 간단한 형식의
사용자 정의를 사용할 수 있다. 이후부터는 여러 스키마를 다루기 위한 사용자 정의 예제를
설명한다.) 첫 번째 사용자 정의 속성 prefer-inline="true"는
CodeGen에게 한 번만 참조되는 스키마 정의를 별도의 클래스로 유지하는 기본 방법을 사용하지
않고 인라인 처리하도록 지시한다. 두 번째 속성 show-schema="false"는
스키마 정의를 클래스 Javadoc에 포함하지 않도록 지시한다. enumeration-type="simple"은
Java 5 열거형 대신 간단한 typesafe 열거형을 생성한다.
마지막 속성 쌍은 함께 작동한다. 기본적으로 CodeGen은 각 complexType에
대해 생성된 JiBX 바인딩에 있는 해당 추상 맵핑과 함께 입력으로 지정된 스키마에 있는 모든
전역 유형 정의에 대해 별도의 최상위 레벨 클래스를 생성한다. generate-all="false"
속성은 이 기본 작동을 수행하지 않고 포함된 유형에서 구체적으로 포함 또는 참조된 complexType만을
명시적으로 생성한다. 그런 다음 includes="order item" 속성은 생성할 이름을
제공한다. 여기에서는 테스트 프로그램과의 호환성을 유지하기 위해 이 이름을 사용한다. <order>
요소는 인스턴스 문서의 루트 요소이기 때문에 필요하고, complexType 항목은
테스트 프로그램에서 주문 총계를 합산할 때 이 유형에 대한 별도의 최상위 레벨 클래스를 찾기 때문에 필요하다.
codegen 태스크 대신 Ant custgen 태스크를 사용하여
이러한 사용자 정의를 수행할 수 있다. (또는 full 태스크를 사용하여 전체 대상
시퀀스인 clean custgen compile bind run을 실행할 수 있다). Listing 6에서는 생성된
코드 중 일부를 보여 주며, 이 코드를 Listing 2에 표시된 생성된 기본 코드와 비교해 볼 수 있다.
이때 가장 큰 차이점(Javadoc이 간소화되었다는
점 외에)은 Customer 클래스가 인라인 처리되고
Shipping 클래스가 사용자 정의 typesafe 열거형 클래스를 사용하는 내부 클래스라는 것이다.
Listing 6. 사용자 정의를 통해 생성된 코드
/**
* Order information.
*/
public class Order
{
private long orderNumber;
private long customerCustomerNumber;
private String customerFirstName;
private String customerLastName;
private Address billTo;
private Shipping shipping;
private Address shipTo;
private List<Item> itemList = new ArrayList<Item>();
private Date orderDate;
private Date shipDate;
private Float total;
...
/**
* Supported shipment methods. The "INTERNATIONAL" shipment methods can only be used
for orders with shipping addresses outside the U.S., and one of these methods is
required in this case.
*/
public static class Shipping
{
private final String value;
public static final Shipping STANDARD_MAIL = new Shipping(
"STANDARD_MAIL");
public static final Shipping PRIORITY_MAIL = new Shipping(
"PRIORITY_MAIL");
public static final Shipping INTERNATIONAL_MAIL = new Shipping(
"INTERNATIONAL_MAIL");
public static final Shipping DOMESTIC_EXPRESS = new Shipping(
"DOMESTIC_EXPRESS");
public static final Shipping INTERNATIONAL_EXPRESS = new Shipping(
"INTERNATIONAL_EXPRESS");
private static final String[] values = new String[]{"DOMESTIC_EXPRESS",
"INTERNATIONAL_EXPRESS", "INTERNATIONAL_MAIL", "PRIORITY_MAIL",
"STANDARD_MAIL"};
private static final Shipping[] instances = new Shipping[]{
DOMESTIC_EXPRESS, INTERNATIONAL_EXPRESS, INTERNATIONAL_MAIL,
PRIORITY_MAIL, STANDARD_MAIL};
private Shipping(String value) {
this.value = value;
}
public String toString() {
return value;
}
public static Shipping convert(String value) {
int index = java.util.Arrays.binarySearch(values, value);
if (index >= 0) {
return instances[index];
} else {
return null;
}
}
public static Shipping fromValue(String text) {
Shipping value = convert(text);
if (value == null) {
throw new IllegalArgumentException("Value \'" + text
+ "\' is not allowed");
} else {
return value;
}
}
}
} |
CodeGen을 사용하면 다른 여러 가지 사용자 정의도 사용할 수 있다. 이 튜토리얼의 이후
부분에서 몇 가지 예제를 보여 주기는 하지만 사용자 정의에 대한 이해도를 높이려면 좀 더
복잡한 스키마를 살펴보아야 한다.
|  |
|