SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

mavenのプラグインを作成して独自のレポートを追加する

mavenのドキュメント生成機能のカスタマイズ


  • X ポスト
  • このエントリーをはてなブックマークに追加

レポートを追加するプラグインの作成

 前項の解説でプラグインの基本的な作成方法がわかったと思います。では、どのようなプラグインを作成すれば独自のレポートを出力することができるのでしょうか。引き続き解説していきます。

mavenのドキュメント生成過程

 mavenを活用したプロジェクトでは、標準のドキュメントの作成はsiteゴールを用いて行われます。siteゴールの機能はhtmlなどのドキュメントを作成するための「雛形」をレポートごとに生成し、次にその「雛形」を元にwebサイトを作成します。このような2段階の手順を踏む理由は、その「雛形」を、標準以外のレイアウトを持つwebサイトや、pdfなどのその他の種類のドキュメントと共有できるようにするためです。

 さらに「雛形」は、雛形レポートをデザインするための「スタイルシート」と、「スタイルシート」に入れる具体的な値や設定を集めた「コンテンツ」とを組み合わせることで、生成されます。

 この過程を実現するには次のような役割が必要になります。

  1. 個別のプロジェクトから「コンテンツ」を収集、作成する役割
  2. 「スタイルシート」と、「雛形」生成の命令(ゴール)を保持する役割
  3. 「スタイルシート」と「コンテンツ」を組み合わせて「雛形」を作成する役割
  4. 「雛形」を特定のドキュメントに作り変える役割
  5. 1.から4.までの流れをコントロールする役割

 これら全てを一から作るのは大変ですが、mavenには標準で3.の役割を持ったプラグインと、webサイト用のドキュメントを生成するための4.5.の役割を持ったプラグインがインストールされています。つまり、webサイト用ドキュメントを生成するプラグインを作るためには、1.2.の役割を果たす機能を実装すればいいのです。特に、プロジェクトの進捗に沿って変化する情報(例えば、バグの情報など)を扱わないレポートであれば、2.の機能を実装するだけでもよいでしょう(下図参照)。

ドキュメントができる過程
ドキュメントができる過程

 以下の例では、上記2.の機能を実装する方法を見ていきます。

 2.の機能を実装するには、特定のゴールを持つプラグインの作成と、作成するレポートのデザインを示すスタイルシートの作成を行います。

レポートを生成するゴールの作成

 「雛形」を生成するプラグインには、次の表にあるゴールを含める必要があります。

「雛形」生成に必要なゴール
ゴール名説明
プラグイン名:reportレポートを生成するためのゴール。
プラグイン名:registermavenが生成するドキュメントに、このレポートを登録するためのゴール。
プラグイン名:deregistermavenが生成するドキュメントから、このレポートを除外するためのゴール。
 「プラグイン名:deregister」の実装は任意ですが、プラグインを柔軟に使用できるようにするには重要な機能です。

 以下に実装例と、解説を述べます。

plugin.jelly
<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>

 ここで出てきたタグの機能を以下の表にまとめます。

「plugin.jelly」で使用した要素2
要素名説明
<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属性に与えられた名前のレポートをドキュメントからはずす。
補足説明
 「plugin.jelly」の<project>タグ内の名前空間の宣言で、docタグライブラリを取得していますが、このタグライブラリはmavenにインストールされていません。このため、「maven-sample-plugin:report」ゴールをmavenコマンドから直接呼ぶことはできません。
 docタグライブラリは、実際は、mavenが標準で備えるプラグインの1つ、maven-xdoc-pluginプラグインの中に定義されています。siteゴールはこのmaven-xdoc-pluginプラグインにあるゴールを経由して、各プラグインの「プラグイン名:report」ゴールなどのドキュメント生成に必要なゴールを実行しています。

 maven上のプラグインやプロジェクトの中のxml文書の中で、しばしばディレクトリを「${プロパティ名}」(例:${maven.build.dir})というように、プロパティを利用して表します。以下に、その有用なものを表にまとめます。

maven上で使えるディレクトリに関するプロパティ
プロパティ名説明デフォルト
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.homemavenのインストールディレクトリ-
plugin.dirプラグインのルートディレクトリ-
plugin.resourcesプラグインのリソースのあるディレクトリプラグインルート/plugin-resources

スタイルシートの作成

 次に「スタイルシート」を作成します。「スタイルシート」は「plugin.jelly」に記述したとおり、プラグインのリソースディレクトリ(サンプルでは「プラグインルート/plugin-resources」)直下に配置します。以下に「スタイルシート」と「スタイルシート」で解析される「コンテンツ」の例を示します。

sample.jsl(スタイルシート)
<?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>
ROLE_sample.xml(コンテンツ)
<?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>

 この例では、プロジェクトで使用する役職の名前と説明を列挙しています。NameShort NameDescriptionの3つのカラムを持つテーブルに、ループを使って「コンテンツ」にあるレコードを挿入しています。その際に、Descriptionカラムに入れるレコードがない場合は、「NO DATA」を入れるように分岐処理をしています。

 「sample.jsl」もJellyスクリプトとして処理されます。Jellyではhtml調のデザイン定義に加え、変数の定義、ループ処理、分岐処理など簡単なプログラミングを行うことができます。これらはJellyタグライブラリの「jelly:core」ライブラリに定義されています(以下の解説では、名前空間の宣言を「xmlns:j="jelly:core"」としています)。Jellyの詳しい文法については扱いませんが、ここではJellyの変数定義、ループ処理、分岐処理に的を絞って、以下の表に解説します。

「sample.jsl」の解説
処理説明
変数定義<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"」)について、上記サンプルの理解の助けとなるよう、簡単に補足します。

sample.jslの補足解説
タグ説明
<jsl:template>match属性に入る値で「コンテンツ」にある全てのノードをマッチングする。例ではrolesでマッチングしているため、「ROLE_sample.xml」中の<roles>タグ内の要素を「コンテンツ」として取り入れる。
<x:set>xml要素のセットをもつ変数を宣言する。var属性に変数名、select属性にはセットを構成するxPathを指定する。例では、xPathは「./role」(現在のノード内にあるroleノード)でセットを構成している(xPathについての参考ページは末尾に記載)。

 また、xmlのノードに対して次のように記述することで、ノードにある各種の情報を取得できます。

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」で次のように記述します。

プロジェクトの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」で以下のように設定を追加してください。

プロジェクトの「project.properties」
maven.docs.outputencoding=UTF-8

 以上の作業ができたら以下のように、プラグインをインストールし直し、プロジェクトのsiteゴールを実行してください。

プラグインのインストールと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」ドキュメントが追加されています。

プラグインで作成されたサイト1
プラグインで作成されたサイト1
プラグインで作成されたサイト2
プラグインで作成されたサイト2

まとめ

 今回は、mavenのプラグイン作成方法と、mavenが自動生成するドキュメントの追加方法を見てきました。非常に簡単なステップでプラグインの作成、およびドキュメントの追加が行えたと思います。ここで説明されたことを活用し、独自のプラグインを作成したり、あるいは3rdベンダから提供されているプラグインを導入することで、よりあなたのプロジェクトに合致したmavenの活用が可能となるでしょう。

参考資料

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
特集記事連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト 渕 幸雄(フチ ユキオ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/254 2006/10/11 19:36

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング