レポートを追加するプラグインの作成
前項の解説でプラグインの基本的な作成方法がわかったと思います。では、どのようなプラグインを作成すれば独自のレポートを出力することができるのでしょうか。引き続き解説していきます。
mavenのドキュメント生成過程
mavenを活用したプロジェクトでは、標準のドキュメントの作成はsiteゴールを用いて行われます。siteゴールの機能はhtmlなどのドキュメントを作成するための「雛形」をレポートごとに生成し、次にその「雛形」を元にwebサイトを作成します。このような2段階の手順を踏む理由は、その「雛形」を、標準以外のレイアウトを持つwebサイトや、pdfなどのその他の種類のドキュメントと共有できるようにするためです。
さらに「雛形」は、雛形レポートをデザインするための「スタイルシート」と、「スタイルシート」に入れる具体的な値や設定を集めた「コンテンツ」とを組み合わせることで、生成されます。
この過程を実現するには次のような役割が必要になります。
- 個別のプロジェクトから「コンテンツ」を収集、作成する役割
- 「スタイルシート」と、「雛形」生成の命令(ゴール)を保持する役割
- 「スタイルシート」と「コンテンツ」を組み合わせて「雛形」を作成する役割
- 「雛形」を特定のドキュメントに作り変える役割
- 1.から4.までの流れをコントロールする役割
これら全てを一から作るのは大変ですが、mavenには標準で3.の役割を持ったプラグインと、webサイト用のドキュメントを生成するための4.と5.の役割を持ったプラグインがインストールされています。つまり、webサイト用ドキュメントを生成するプラグインを作るためには、1.と2.の役割を果たす機能を実装すればいいのです。特に、プロジェクトの進捗に沿って変化する情報(例えば、バグの情報など)を扱わないレポートであれば、2.の機能を実装するだけでもよいでしょう(下図参照)。
以下の例では、上記2.の機能を実装する方法を見ていきます。
2.の機能を実装するには、特定のゴールを持つプラグインの作成と、作成するレポートのデザインを示すスタイルシートの作成を行います。
レポートを生成するゴールの作成
「雛形」を生成するプラグインには、次の表にあるゴールを含める必要があります。
ゴール名 | 説明 |
プラグイン名:report | レポートを生成するためのゴール。 |
プラグイン名:register | mavenが生成するドキュメントに、このレポートを登録するためのゴール。 |
プラグイン名:deregister | mavenが生成するドキュメントから、このレポートを除外するためのゴール。 |
以下に実装例と、解説を述べます。
<project xmlns:doc="doc"> ... <goal name="maven-sample-plugin:report"> <doc:jsl input="${maven.build.dir}/ROLE_sample.xml" output="sample-report.xml" stylesheet="${plugin.resources}/sample.jsl" outputMode="xml" prettyPrint="true" /> </goal> <goal name="maven-sample-plugin:register"> <doc:registerReport name="Sample" pluginName="maven-sample-plugin" link="sample-report" description="Sample report." /> </goal> <goal name="maven-sample-plugin:deregister"> <doc:deregisterReport name="Sample"/> </goal> ... </project>
ここで出てきたタグの機能を以下の表にまとめます。
要素名 | 説明 |
<doc:jsl> | 「スタイルシート」と「コンテンツ」を組み合わせて「雛形」を作る。ここでは、input 属性にある「ROLE_sample.xml」ファイルを取り込み、stylesheet 属性にある「sample.jsl」ファイルを用いて、output 属性にある「sample-report.xml」ファイルを出力する。この「sample-report.xml」ファイルが「雛形」となる。 |
<doc:registerReport> | name 属性に与えられた名前でレポートをドキュメントに登録する。また、pluginName 属性でプラグイン名、link 属性でwebドキュメント上のURL、description 属性で説明、などの情報を与えることができる。 |
<doc:deregisterReport> | name 属性に与えられた名前のレポートをドキュメントからはずす。 |
docタグライブラリは、実際は、mavenが標準で備えるプラグインの1つ、maven-xdoc-pluginプラグインの中に定義されています。siteゴールはこのmaven-xdoc-pluginプラグインにあるゴールを経由して、各プラグインの「プラグイン名:report」ゴールなどのドキュメント生成に必要なゴールを実行しています。
maven上のプラグインやプロジェクトの中のxml文書の中で、しばしばディレクトリを「${プロパティ名}」(例:${maven.build.dir})というように、プロパティを利用して表します。以下に、その有用なものを表にまとめます。
プロパティ名 | 説明 | デフォルト |
basedir | カレントディレクトリ(プロジェクトでmavenを使う以上、基本的にはプロジェクトルートと同じ) | - |
maven.build.dir | プロジェクトのビルド対象のディレクトリ | カレントディレクトリ/target |
maven.src.dir | プロジェクトのソースファイルのあるディレクトリ | カレントディレクトリ/src |
maven.docs.dest | プロジェクトのドキュメントの出力先 | カレントディレクトリ/target/docs |
maven.conf.dir | プロジェクトの設定用のディレクトリ | カレントディレクトリ/conf |
maven.repo.remote | プロジェクトのリモートリポジトリ | http://www.ibiblio.org/maven |
maven.home | mavenのインストールディレクトリ | - |
plugin.dir | プラグインのルートディレクトリ | - |
plugin.resources | プラグインのリソースのあるディレクトリ | プラグインルート/plugin-resources |
スタイルシートの作成
次に「スタイルシート」を作成します。「スタイルシート」は「plugin.jelly」に記述したとおり、プラグインのリソースディレクトリ(サンプルでは「プラグインルート/plugin-resources」)直下に配置します。以下に「スタイルシート」と「スタイルシート」で解析される「コンテンツ」の例を示します。
<?xml version="1.0"?> <jsl:stylesheet select="$doc" xmlns:jsl="jelly:jsl" xmlns:j="jelly:core" xmlns:x="jelly:xml"> <jsl:template match="roles"> <document> <properties> <title>Role</title> </properties> <body> <section name="Role"> <table summary="Role List"> <thead> <tr> <th>Name</th> <th>shortName</th> <th>Description</th> </tr> </thead> <tbody> <x:set var="roles" select="./role"/> <j:forEach var="role" items="${roles}"> <j:set var="name" value="${role.attribute('name').value}"/> <j:set var="shortName" value="${role.attribute('shortName').value}"/> <j:set var="detail" value="${role.text}"/> <tr> <td>${name}</td> <td>${shortName}</td> <j:if test="${detail == null or detail == ''}"> <td>NO DATA</td> </j:if> <j:if test="${detail != null and detail != ''}"> <td>${detail}</td> </j:if> </tr> </j:forEach> </tbody> </table> </section> </body> </document> </jsl:template> </jsl:stylesheet>
<?xml version="1.0" encoding="UTF-8"?> <roles> <role name="Chief Project Manager" shortName="CPM">プロジェクトの最高責任者。複数のPMを指揮する</role> <role name="Project Manager" shortName="PM">プロジェクト内のサブパートごとの責任者。 サブパートごとのDEVを指揮する</role> <role name="Developer" shortName="DEV">開発者</role> <role name="Part Timer" shortName="PART"></role> <role name="etc." shortName="etc."/> </roles>
この例では、プロジェクトで使用する役職の名前と説明を列挙しています。Name
、Short Name
、Description
の3つのカラムを持つテーブルに、ループを使って「コンテンツ」にあるレコードを挿入しています。その際に、Description
カラムに入れるレコードがない場合は、「NO DATA」を入れるように分岐処理をしています。
「sample.jsl」もJellyスクリプトとして処理されます。Jellyではhtml調のデザイン定義に加え、変数の定義、ループ処理、分岐処理など簡単なプログラミングを行うことができます。これらはJellyタグライブラリの「jelly:core」ライブラリに定義されています(以下の解説では、名前空間の宣言を「xmlns:j="jelly:core"
」としています)。Jellyの詳しい文法については扱いませんが、ここではJellyの変数定義、ループ処理、分岐処理に的を絞って、以下の表に解説します。
処理 | 説明 |
変数定義 | <j:set> タグを利用する。var 属性に変数名、value 属性に値を指定する。プラグイン名:report。 |
ループ処理 | <j:forEach> タグを利用する。items 属性に入っている要素の数だけループする。ループごとに取り出されるitems 属性に入っている要素は、var 属性に宣言した変数名で取り出すことができる。 |
分岐処理 | <j:if> タグを利用する。test 属性に条件を指定する。 |
スタイルシートを扱うためのjelly:jslタグライブラリ(名前空間の宣言は「xmlns:jsl="jelly:jsl"
」)と、xmlドキュメントを扱うためのjelly:xmlタグライブラリ(名前空間の宣言は「xmlns:x="jelly:xml"
」)について、上記サンプルの理解の助けとなるよう、簡単に補足します。
タグ | 説明 |
<jsl:template> | match 属性に入る値で「コンテンツ」にある全てのノードをマッチングする。例ではroles でマッチングしているため、「ROLE_sample.xml」中の<roles> タグ内の要素を「コンテンツ」として取り入れる。 |
<x:set> | xml要素のセットをもつ変数を宣言する。var 属性に変数名、select 属性にはセットを構成するxPathを指定する。例では、xPathは「./role」(現在のノード内にあるrole ノード)でセットを構成している(xPathについての参考ページは末尾に記載)。 |
また、xmlのノードに対して次のように記述することで、ノードにある各種の情報を取得できます。
取得できる情報 | 記述方法 |
ノードの各属性値 | ${「ノードを保持する変数名」.attribute('「属性名」').value} |
ノードのもつテキストノード | ${「ノードを保持する変数名」.text} |
「雛形」として作成しなければならないファイルのフォーマットは非常にシンプルです。ここでは、基本的なフォーマットを示します。詳しくは、mavenサイトのサイト生成に関するページなどを参照してください。
<document> <properties> <author email="eメールアドレス">作者名</author> <title>ページのタイトル(タイトルバーに表示)</title> </properties> <body> <!-- bodyタグの中には複数のセクションを含めることができる --> <section name="セクション名"> <!-- セクションの中ではXHTMLタグ(例えば、 パラグラフを表す<p>タグや、テーブルを扱うための<table>タグ、 <tr>タグ、<td>タグなど)が使える --> <p>パラグラフ</p> <!-- セクションの中に複数のサブセクションを含めることができる --> <subsection name="サブセクション名"> <!-- サブセクションの中でもセクションの中同様、 XHTMLタグが使える --> </subsection> </section> <section name="セクション名"> ... </section> ... </body> </document>
プロジェクトへのレポートの追加とドキュメント作成
本稿で作成したプラグインのレポートを、プロジェクトのドキュメントとして使用する場合は「project.xml」で次のように記述します。
<?xml version="1.0" encoding="UTF-8"?> <project> ... <reports> <report>maven-sample-plugin</report> <report>...</report> <report>...</report> ... </reports> ... </project>
プロジェクトがどのレポートを使用するか、<reports>
タグ内の<report>
タグにプラグイン名を指定することで定義します。<reports>
タグ以下がない場合は、JavaDoc、単体テストの結果などのmaven標準のレポートがドキュメント化されます。
また、今回のプラグインで作るレポートに日本語が含まれるので、プロジェクトの「project.properties」で以下のように設定を追加してください。
maven.docs.outputencoding=UTF-8
以上の作業ができたら以下のように、プラグインをインストールし直し、プロジェクトのsiteゴールを実行してください。
>cd c:\dev\maven-sample-plugin >maven plugin:install ... BUILD SUCCESSFUL ... >cd c:\dev\sample >maven site ... BUILD SUCCESSFUL ...
実行したら、「プロジェクトルート/target/generated-xdocs」ディレクトリ直下に「sample-report.xml」という「雛形」と、「プロジェクトルート/target/docs」内にwebサイトが生成されていることを確認してください。
以下は、生成された「プロジェクトルート/target/docs」ディレクトリ以下を、Apacheサーバの「htdocs」ディレクトリ直下に配置し、「http://localhost/docs」にアクセスした例です。
ここで左のメニューから「Project Reports」を選択すると、「Sample」ドキュメントが追加されています。
まとめ
今回は、mavenのプラグイン作成方法と、mavenが自動生成するドキュメントの追加方法を見てきました。非常に簡単なステップでプラグインの作成、およびドキュメントの追加が行えたと思います。ここで説明されたことを活用し、独自のプラグインを作成したり、あるいは3rdベンダから提供されているプラグインを導入することで、よりあなたのプロジェクトに合致したmavenの活用が可能となるでしょう。
参考資料
- Apache Maven Project
- @IT 『技術者のためのXML再入門 第8回 XML文書内の位置を正確に指し示すXPath』 吉田稔・青木秀起 著、2002年6月