2008.02.25 株式会社四次元データ 森
8. Maven2 プラグインの作成
- 8.1. プラグインの概要
- 8.2. プラグインの作成準備
- 8.3. プラグインの作成
- 8.4. プラグインのテスト
- 8.5. プラグインの配備及び実行
8.3. プラグインの作成
8.3.1 プラグインへのパラメータ
実行メソッドを作成する前にパラメータの記述の仕方について考えます。これはコマンドラインでは
$ mvn $plugin:$goal -D<param-name>=<param-value>
一方プラグインを実行するプロジェクトの pom.xml においては
<plugins> <plugin> : <configurations> <param-name>param-value</param-name> </configurations> </plugin> :
といった形でプラグイン本体に渡される値の事を指します。
プラグイン作成時に設定ファイルを自分で準備する必要はありません。Maven が packaging の際に plugin.xml を準備してくれるためです。
プラグインのゴール指定を javadoc で記述したのと同様、プラグインに渡されるパラメータについてもクラスファイルで指定されたフィールドに javadoc を与えることで実現します。つまり
/** * @parameter */ private String param;
上のように @parameter という javadoc を指定することで、この param フィールドがパラメータとして扱われます。実行する際のコマンドラインやプロジェクト側の pom.xml で指定された値が自動的にこのフィールドに設定されます。パラメータの型は String 以外にも、File 型、boolean 型などを指定することが可能で、型変換は自動的に Maven 側で行ってくれますので、型については各々のプラグインで扱いやすいものを指定すればよいでしょう。 @parameter では以下のように追加でその振る舞いを指定できます。
@parameter alias="myAlias" | パラメータ名に myAlias を指定する。通常はフィールド名そのものをパラメータ名として利用する。 |
@parameter expression="${someExpression}" default-value="value" | パラメータ値に expression で指定した値を利用する。default-value を指定した場合、その値が利用される。 |
expression で指定された値は PluginParameterExpressionEvaluator で解決されます。maven-core の 2.0 時点でのものを抜き出してみますと以下のようになります。
localRepository | ArtifactRepository オブジェクト |
session | MavenSession オブジェクト |
reactorProjects | MavenProject の List |
reports | MavenReport の List |
project | MavenProject オブジェクト |
executedProject | MavenProject オブジェクト |
project.* | MavenProject のプロパティ |
plugin.* | PluginDescriptor のプロパティ |
settings | MavenSettings オブジェクト |
settings.* | MavenSettings のプロパティ |
basedir | 現在の実行ディレクトリのパス |
それ以外 | プロパティを検索 |
上記以外にも、パラメータには以下のような物が指定可能です。
@required | プラグイン実行時に必須であることを指定する。 |
@readonly | 読み込み専用であることを指定する。ユーザが指定することを意図しないようなパラメータに付与する。 |
@component | plexus のコンポーネントを指定する。 |
@component ですが、これは Maven 本体は plexus という DI コンテナを利用しており、そこに登録されているコンポーネントを取得する為のものです。通常はあまり利用しないものかもしれませんが、自作のクラスをインジェクションしたい場合や、Maven 本体で提供されているコンポーネントを利用したい場合に利用してください。これらの詳細については Maven - Maven 2.0 - Mojo API Specification の "The Descriptor and Annotations" を参照下さい。
8.3.2 実行部分の作成
パラメータを受け取る部分と、実行部を分けて作成します。CountlinesMojo.java でパラメータとしてディレクトリと拡張子の指定をし、CountlinesExecuter.java で指定されたディレクトリと拡張子を持つファイルに対して実行を、この場合は行数カウントを行うような設計にします。
execute メソッドは MojoExecutionException と MojoFailureException を throw します。前者は「予期しない問題」の発生時、後者は「予測可能な問題」の発生時に対応しています。前者はログとして「BUILD ERROR」、後者は「BUILD FAILURE」として報告されます。
ここで行うことは条件に合致するファイルの行数をカウントするだけです。"dir" というパラメータでディレクトリを、"ext" というパラメータで拡張子を指定します。複数拡張子も指定できるように、split メソッドを用いて配列として処理できるようにしました。 CountlinesMojo.java は以下のようにします。
/** * Count Lines of selected files * * @goal countlines */ public class CountlinesMojo extends AbstractMojo { /** * select directory. * * @parameter expression="${dir}" * @required */ private String dir; /** * select extension. * * @parameter expression="${ext}" * @required */ private String ext; public void execute() throws MojoExecutionException, MojoFailureException { File directory = new File(dir); String[] extensions = ext.split(","); if (!directory.isDirectory()) { throw new MojoFailureException("ディレクトリではないか、または存在しません。"); } // 指定されたディレクトリ以下の指定された拡張子の // ファイルの行数をカウントする CountExecuter executer = new CountExecuter(directory, extensions); try { executer.count(); } catch (IOException e) { throw new MojoExecutionException(e.getMessage()); } } }
行数カウントを行う CountlinesExecuter.java は以下のようになります。
import org.apache.commons.io.FileUtils; public class CountExecuter { private File directory; private String[] extensions; public CountExecuter(File directory, String[] extensions) { this.directory = directory; this.extensions = extensions; } @SuppressWarnings("unchecked") public void count() throws IOException { Collectionfiles = FileUtils.listFiles(directory, extensions,true); int count = 0; if ((files != null) && (!files.isEmpty())) { for (File f : files) { count += countLines(f); } } System.out.println("Total Linenumber is " + count + " ."); System.out.println("directory " + directory.getPath()); } private int countLines(File file) throws IOException { int linenum = 0; FileReader fr = null; BufferedReader br = null; try { fr = new FileReader(file); br = new BufferedReader(fr); @SuppressWarnings("unused") String line = null; while ((line = br.readLine()) != null) { linenum++; } } finally { IOUtils.closeQuietly(br); IOUtils.closeQuietly(fr); } return linenum; } }
FileReader と BufferedReader を用いてファイルを行単位で読み込みます。拡張子が合致するファイルの行数をファイルごとにカウントし、最後にそれらを加算した数を表示しています。
ここで注意するのは FileUtils クラスを commons-io から利用している点です。以下のようにプラグイン自体の pom.xml に依存関係を設定しておきます。
<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>1.2</version> </dependency>
また、総称型をサポートさせるため Maven 5.2.3 プロジェクトの設定 で行ったのと同じように java コンパイラの指定を 1.5 とするよう、pom.xml に追記します。
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin>