倭マン's BLOG

くだらない日々の日記書いてます。 たまにプログラミング関連の記事書いてます。 書いてます。

プラグインを作ろう! (13) -- プロジェクトの構成要素を取得する

プロジェクトの構成要素の取得方法


以前の記事で、パラメータ(JavaDoc アノテーション「@parameter」を付加したフィールド)に値を代入するには引数 expression を付加ればいいというのを見ました:

/**
 * @parameter expression="${project.packaging}"
 */
private String packaging;

この例では、POM ファイルの「project/packaging」要素下の子テキスト(jar や pom など)がフィールドに設定されます。

同様の方法で、プロジェクトの構成要素をパラメータとして取得することができます。 例えば、プロジェクト自体を取得したい場合、

/**
 * @parameter expression="${project}"
 */
private Object project;

とすると、project フィールドに Maven2 プロジェクトをモデル化したクラス「org.apache.maven.project.MavenProject」のインスタンスがセットされます*1

プロジェクトをモデル化した API


上記のように、プロジェクトを Object 型として扱うのは面倒なので、Maven2 プロジェクトをオブジェクト・モデルに落とし込んだ API を使用できるようにしましょう。 これには、作成しているプラグイン・プロジェクトに対して、以下に示すプロジェクトの成果物への依存性を付加する必要があります。

少し注意しなければならないのは、POM ファイルのルート要素 <project> に対応する org.apache.maven.project.MavenProject と、その子要素・孫要素等々として現れる構成要素(例えば <plugin> や <dependency> など)は別々のプロジェクトとして開発されていることです。

<project> 要素を使わない場合は、「Maven Model」プロジェクトの成果物を使用します(JavaDocこちら):

<dependency>
  <groupId>org.apache.maven</groupId>
  <artifactId>maven-model</artifactId>
  <version>2.0.8</version>
</dependency>

一方、<project> 要素を使用する場合は「Maven Project」プロジェクトの成果物が必要です(JavaDocこちら):

<dependency>
  <groupId>org.apache.maven</groupId>
  <artifactId>maven-project</artifactId>
  <version>2.0.8</version>
</dependency>

ちなみに、「Maven Project」への依存性を指定すると間接的に「Maven Model」への依存性も付加されるので、「Maven Model」への依存性を明示的に指定する必要はありません。

expression 引数の書き方


要素名だけを辿ってその要素に一意にたどり着く場合*2、その要素名をピリオド (.) で区切って指定すれば、その要素に対応するオブジェクトが取得できます。 例えば、

<project>
  ...
  <build>
    ...
  </build>
</project>

となっている場合、

/**
 * @parameter expression="${project.build}"
 */
private Build build;

とすれば、build フィールドに org.apache.maven.model.Build オブジェクトがセットされます。

一方、<plugins> 要素下に <plugin> 要素が複数あるなど、同名の要素が、その複数形の要素下に複数ある場合、複数形の要素を指定すれば、その子要素に対応するオブジェクトが保持されたリストが取得できます。 例えば、

<project>
  ...
  <build>
    <plugins>
      <plugin>...</plugin>
      <plugin>...</plugin>
    </plugins>
    ...
  </build>
</project>

となっている場合、

/**
 * @parameter expression="${project.build.plugins}"
 */
private List<Plugin> plugins;

とすれば、plugins フィールドに org.apache.maven.model.Plugin オブジェクトを保持した java.util.List オブジェクトがセットされます。

*1:実際には、この方法は非推奨になっているようです。 代わりに @component アノテーションを用いてオブジェクトを取得する方法が推奨されているようです。

*2:例えば、<project> 要素の子要素である <packaging> 要素など。 <plugins> 要素下の <plugin> 要素などは、その子要素の <artifactId> などを見ないと識別できないので、この方法では取得できません。