連載
» 2004年07月13日 10時00分 公開

JavaTips 〜Apache/Jakarta編:antcallやantでプロパティをまとめて指定する

[BULL,@IT]

 プログラムでは、同一の処理を複数個所に記述してしまうと、可読性やメンテナンス性が低くなってしまいます。そのため、複数個所で同一の処理を利用する場合は、同一の処理を1つのサブルーチンとして記述しておき、必要な個所でそのサブルーチンを呼び出すのが一般的です。同様に、Antスクリプトでも、サブルーチンをtargetとして記述し、antcallタスクやantタスクを使用して呼び出すことが可能です。

 しかし、Antでサブルーチンを呼び出すときには注意が必要です。antcallやantのinheritAll属性値を“true”(デフォルト値)にしてtargetを呼び出すと、呼び出し元で参照可能な全プロパティが呼び出し先からも参照できてしまうからです。通常、一度設定されたプロパティは再設定することができないため、呼び出し先で定義しようとしているプロパティが呼び出し元ですでに定義されていた場合、予期しない動作を起こしてしまう可能性があります。

 これまでは、この問題を解決するために、inheritAll属性値を“false”にして、呼び出し先から参照させたいプロパティだけをantcallやantの子要素であるparam要素やproperty要素で個別に指定する必要がありました。しかし、Ant 1.6以降からは、propertyset要素とpropertyref要素を使用して、参照されるプロパティをまとめて指定できるようになりました。

 propertyset要素はantcallまたはantの子要素で、子要素である複数のpropertyref要素または複数のmapper要素をまとめる働きをします。propertyref要素は、呼び出し先から参照させるプロパティの条件指定に使用します。propertyref要素で使用できる主な属性を以下に示します。いずれか1つの属性が必須です。

propertyref要素で使用できる主な属性
属性名 説明
name 1つのプロパティ名。この属性値と同名のプロパティが呼び出し先から参照可能となる
prefix プロパティ名の先頭文字。先頭文字がこの属性値となる全プロパティが呼び出し先から参照可能となる
regexp プロパティ名の正規表現。この属性値の正規表現にマッチするプロパティ名を持つ全プロパティが呼び出し先から参照可能となる

 プロパティ名がa.x、a.y、b.x、b.yとなるプロパティが定義されており、propertyref要素の属性としてname="a.x"、prefix="a."、regexp=".*x"をそれぞれ指定した場合、呼び出し先から参照できるプロパティは以下のようになります。

propertyref要素の属性値による参照可能なプロパティの関係
プロパティ名/属性 name="a.x" prefix="a." regexp=".*x"
a.x
a.y × ×
b.x × ×
b.y × × ×

 propertyset要素の子要素として使用されるmapper要素は、呼び出し先から参照されるプロパティ名を変換するために使用します。

 propertyset要素とpropertyref要素を使ったサンプルスクリプトを以下に示します。

<?xml version="1.0" encoding="Shift_JIS"?>
<project name="PropertySet" default="PropertySetSample">
 
  <target name="sub">
    <echo message="a.x=${a.x} a.y=${a.y} a.z=${a.z}"/>
  </target>
 
  <target name="PropertySetSample">
    <property name="a.x" value="1"/>
    <property name="a.y" value="2"/>
    <property name="a.z" value="3"/>
    <property name="b.x" value="11"/>
    <property name="b.y" value="22"/>
    <property name="b.z" value="33"/>
 
    <!--従来の方法。個別に指定する必要がある-->
    <antcall target="sub" inheritAll="false">
      <param name="a.x" value="${a.x}"/>
      <param name="a.y" value="${a.y}"/>
      <param name="a.z" value="${a.z}"/>
    </antcall>
 
    <!--「a.」で始まる全プロパティをantcall先で参照可能にする-->
    <antcall target="sub" inheritAll="false">
      <propertyset>
        <propertyref prefix="a." />
      </propertyset>
    </antcall>
 
    <!--「b.」で始まる全プロパティを「a.」で始まる名前に変換し、
         antcall先で参照可能にする-->
    <antcall target="sub" inheritAll="false">
      <propertyset>
        <propertyref prefix="b" />
        <mapper type="glob" from="b.*" to="a.*"/>
      </propertyset>
    </antcall>
  </target>
</project>

 このサンプルスクリプトを実行すると、以下のような結果になります。

Buildfile: build.xml
 
PropertySetSample:
 
sub:
     [echo] a.x=1 a.y=2 a.z=3
 
sub:
     [echo] a.x=1 a.y=2 a.z=3
 
sub:
     [echo] a.x=11 a.y=22 a.z=33
 
BUILD SUCCESSFUL
Total time: 1 second

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。