レイアウトポートレットについて

レイアウトポートレットについて

Jetspeed2のレイアウトは、jetspeed-layout ポートレットに管理されています。ここでいうレイアウトは、ページ内でポートレットを1列で表示してみたり、2列で表示してみたり、という感じで、ポートレットの配置に関するレイアウトを指します。ここでは、どのようにそれが定義されているか、新しいレイアウトを追加するにはどうしたらよいかを見ていきます。

設定ファイルについて

レイアウトポートレットは、ソースコード上では、layout-portlets/ 以下に置かれています。J2をビルドすると、jetspeed-layout.warが配備されます(J2 の内部的には、jetspeed-で始まるポートレットアプリケーションは、J2用の特殊なポートレットとして認識されます。ですので、PALMポートレットで確認すると、<local>と出ると思います)。そこに置かれているファイルを見るとわかりますが、レイアウトポートレットも基本的には、普通のポートレットと同様に作られているのがわかると思います。

ソースコードを見ると、LayoutPortlet と MultiColumnPortlet の2つしかないのがわかります。これらがポートレットの配置をコントロールし、その配置は、portlet.xml から渡されるパラメータにより、2列で表示したり、3列で表示したり、しています。ですので、新たな配置方法を利用したい場合は、portlet.xml に追加することになります(斬新なレイアウトを追加したい場合は、MultiColumnPortletと同様な新たなポートレットを追加すれば良いと思います(^^))。

レイアウトの追加

layout-portlets/src/webapp/WEB-INF/portlet.xml を見ると、現在、使える配置方法がわかります。ですので、これらの配置方法を適用したい場合は、使用したいものの portlet-name を psml 内で記述すると適用されます。

いろいろな配置があると思いますが、もし、左側が 75% と右側 25% の2列で表示したい場合は、以下のようなポートレットの定義を portlet.xml に追加すればよいと思います。

<portlet id="VelocityTwoColumns7525">
<portlet-name>VelocityTwoColumns7525</portlet-name>
<display-name>75/25 Two Columns Layout Using Velocity</display-name>
<init-param>
<name>ViewPage</name>
<value>columns</value>
</init-param>
<init-param>
<name>MaxPage</name>
<value>maximized</value>
</init-param>
<init-param>
<name>columns</name>
<value>2</value>
</init-param>
<init-param>
<name>sizes</name>
<value>75%,25%</value>
</init-param>
<init-param>
<name>layoutType</name>
<value>TwoColumns</value>
</init-param>
<portlet-class>org.apache.jetspeed.portlets.layout.MultiColumnPortlet</portlet-class>
<expiration-cache>-1</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
<portlet-mode>edit</portlet-mode>
<portlet-mode>help</portlet-mode>
</supports>
<portlet-info>
<title>VelocityTwoColumns7525NoActions</title>
<short-title>VelocityTwoColumns7525NoActions</short-title>
</portlet-info>
</portlet>

ぜひ、いろいろなレイアウトを試してみてください。

ポートレットの作成

ポートレットの作成

ここでは、JSR 168 に準拠したポートレットの作成を説明します。HelloWorld的なポートレットを作成して、作成したものを Jetspeed2 に追加してみます。

準備

早速、ポートレットを作っていきましょう。今回、作成するポートレットは、入力フォームを持ち、値を入力すると、その入力された値を表示するポートレットです。ビルドする上で、javac や ant などで実行すると、依存関係の解決など少々面倒なので、簡単にするためにも、maven でビルドするプロジェクトを作成します。まずは、ディレクトリを作成します。

$ cd
$ mkdir -p Projects/helloworld
$ cd Projects/helloworld/

この helloworld ポートレットプロジェクトでは、次のファイルを作成します。

project.properties
project.xml
src/webapp/WEB-INF/portlet.xml
src/webapp/WEB-INF/web.xml
src/webapp/WEB-INF/view/helloworld.jsp
src/java/com/marevol/portlet/helloworld/resources/HelloWorldResources_ja.properties
src/java/com/marevol/portlet/helloworld/resources/HelloWorldResources.properties
src/java/com/marevol/portlet/helloworld/HelloWorldPortlet.java

project.properties および project.xml は、Maven のプロジェクトファイルです。そして、それ以外のファイルが、ポートレットを構築・実行する上で必要になるファイルになります。helloworld ポートレットに関する一連のファイルは、ここ からダウンロードできます。

Mavenプロジェクトファイル

それでは、順に構成ファイルについてみていきましょう。

まずは、プロジェクトを Maven で利用できるようにするための project.properties と project.xml です。これらのファイルについては、通常の Maven プロジェクトと同様に作成しています。ですので、ポートレット用に特殊な設定などはしていません。

project.properties には、maven.xdoc.dateプロパティを設定していますが、maven xdoc を実行しなければ、利用されることはないので、今回のポートレットのビルドには一切関係はありません。ですので、project.propertiesには何も設定されていないのと同じと考えて良いでしょう。

./project.properties
# -------------------------------------------------------------------
# Copyright 2001-2004 The Apache Software Foundation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# -------------------------------------------------------------------
maven.xdoc.date=left
## maven.xdoc.version=${pom.currentVersion}

projext.xml は、普通の Maven プロジェクトのものと同様に記述しています。ポートレット用にビルドするために、依存関係に portlet-api を指定しておけば、ポートレットを作成することができます。あとは、今回の helloworld ポートレットでは、ビューに JSP を利用して、JSTL を利用しているので、それに必要な依存関係を追加しています。もし、独自にポートレットを作成する場合には、必要なライブラリがあれば、追加してください。

./project.xml

<project>
<pomVersion>3</pomVersion>
<id>helloworld</id>
<name>Hello World Portlet</name>
<currentVersion>1.0</currentVersion>
<organization>
<name>MAREVOL.COM</name>
<url>http://www.marevol.com/</url>
</organization>
<inceptionYear>2002</inceptionYear>
<package>com.marevol.portlet.helloworld</package>
<description>Sample Portlet to say "Hello" to you</description>
<repository/>
<mailingLists/>
<developers>
<developer>
<name>Shinsuke Sugaya</name>
<id>shinsuke</id>
<email>shinsuke at yahoo.co.jp</email>
<roles>
<role>Java Developer</role>
</roles>
<timezone>+9</timezone>
</developer>
</developers>
<dependencies>
<dependency>
<id>portlet-api</id>
<groupId>portlet-api</groupId>
<version>1.0</version>
<properties>
<war.bundle>false</war.bundle>
</properties>
</dependency>
<dependency>
<id>jstl</id>
<version>1.1.2</version>
<properties>
<war.bundle>true</war.bundle>
</properties>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
<properties>
<war.bundle>true</war.bundle>
</properties>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/java</sourceDirectory>
<unitTestSourceDirectory>src/test</unitTestSourceDirectory>
<unitTest>
<includes>
<include>**/*Test.java</include>
</includes>
<excludes>
<exclude>**/NaughtyTest.java</exclude>
</excludes>
</unitTest>
<resources>
<resource>
<directory>src/java</directory>
<includes>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
</build>
</project>

ポートレットの構成ファイル

ここからがポートレットを作成する上で必要になってくるファイルです。基本的には、Servlet Specification 2.3, SRV.9 で定義されている Web アプリケーションの構成と同じで、サーブレット、JSP、HTMLページ、クラスなどのファイルを含み、それらに加えて、ポートレットのクラスファイルとポートレット配備記述子(portlet.xml)を含みます(簡単に言うと、普通に Java で Web アプリケーションを作るときと同じで、portlet.xml が追加されたものです)。ポートレットアプリケーションについては、JSR 168 の PLT.19 で定義されています。

まず、portlet.xml について見てみましょう。portlet.xml は、ポートレットのリソースについて定義しています。ですので、ポートレットの構成情報などがいろいろと記述されています。portlet.xml のスキーマなどの詳細の情報は、JSR 168 の PLT.21.5 や PLT.21.6 を参照してみてください。

portlet.xml では、ルートノードに portlet-app 要素があり、その下に portlet 要素を複数定義できます。1つのポートレットの定義が1つの portlet 要素に対応しているので、portlet.xml に portlet 要素を複数記述することで、複数のポートレットを定義することもできます。

次に、portlet 要素の下にある要素について見ていきましょう。portlet-name 要素は、ポートレットの名前になります。これは、このポートレットアプリケーション内でユニークな値である必要があります。display-name 要素と、次の description 要素は、ポートレットに関する簡単な名前と説明になります。これらの値は、たとえば、ポータルサーバーのポートレット管理ツールなどで表示される値になります。そのツール上で日本語の名前を出したいような場合には、xml:lang 属性を追加して、記述します。portlet.xml では、display-name と description については、xml:lang 属性を用いて、複数定義することができます。portlet-class 要素は、実行するポートレットのクラス指定します。expiration-cache 要素は、キャッシュの有効期限を秒単位で指定します。-1 は無期限を意味します。supports 要素では、サポートする MIME タイプやポートレットモードを指定しています。supported-locale 要素は、サポートしているロケールを記述します。resource-bundle 要素では、ポートレットで利用するリソースバンドルを指定します。指定したリソースバンドルは、PortletConfig#getResourceBundle() で取得することができます。 portlet-info 要素では、ポートレットで表示されるタイトルなどを指定しています。タイトルを国際化するためには、resource-bundle 要素で指定したリソースバンドル内に記述する必要があります。

./src/webapp/WEB-INF/portlet.xml

<portlet-app id="helloworld" version="1.0">
<portlet id="HelloWorld">
<portlet-name>HelloWorld</portlet-name>
<display-name>Hello World</display-name>
<display-name xml:lang="ja">ハローワールド</display-name>
<description>HelloWorld is a portlet for testing</description>
<description xml:lang="ja">HelloWorld はテスト用ポートレットです</description>
<portlet-class>com.marevol.portlet.helloworld.HelloWorldPortlet</portlet-class>
<expiration-cache>-1</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>VIEW</portlet-mode>
</supports>
<supported-locale>en</supported-locale>
<supported-locale>ja</supported-locale>
<resource-bundle>com.marevol.portlet.helloworld.resources.HelloWorldResources</resource-bundle>
<portlet-info>
<title>Hello World</title>
<short-title>This is a portlet for testing</short-title>
<keywords>Hello,Test</keywords>
</portlet-info>
</portlet>
</portlet-app>

web.xml は、通常の Web アプリケーションと同様に、Web アプリケーションのリソースなどを指定しています。今回は、特に指定することもないので、display-name と description 要素にこのポートレットについてを記述するだけになっています。

./src/webapp/WEB-INF/web.xml


"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>HelloWorld Portlet</display-name>
<description>HelloWorld Portlet</description>
</web-app>

HelloWorldPortlet は、portlet.xml で portlet-class 要素で指定したポートレットのクラスです。ポートレットにアクセスすると、このクラスが呼ばれ、必要な処理を実行します。ポートレットは、 javax.portlet.Portletインターフェース実装したクラスになります。今回は、そのインターフェースを実装した javax.portlet.GenericPortlet を継承して作成されます。また、Jetspeed2 には、GenericPortlet を拡張した GenericServletPortlet や GenericVelocityPortlet などのクラスもいくつかあるので、必要に応じて利用するとポートレットの作成が楽になるかもしれません(今回は、それらのクラスについてはこれ以上ふれません。そのうち機会があれば、GenericVelocityPortlet などを説明するかもしれません。ビューに Velocity を使うと結構、楽な気がするので・・・)。今回は、スタンダードな方法で GenericPortlet を利用しています。

この HelloWorldPortlet は、init, doView, processAction3つのメソッドを持っています。まず、init はその名の通り、ポートレットの初期化を行います。たとえば、portlet.xml で値を与えている場合などには、ここで取得するのが良いでしょう。今回は、特に何もすることがないので、親に渡しているだけです。

次に doView と processAction ですが、Portletインターフェースには、processActionとrenderメソッドが定義されています。つまり、ポートレットの処理は、アクションの処理と表示の処理が完全に分かれていて、processAction でアクションの処理を行い、表示などは、render メソッドで行われます。GenericPortletの render メソッドでは、ポートレットのタイトルを設定して、doDispatchメソッドに渡されています。そして、その doDispatch メソッドでポートレットのモードによって、処理を振り分けています。たとえば、普通に表示する表示モードでは doView、ポートレットの右上にある編集ボタンを押したときなどになる編集モードの描画処理を行う場合は doEdit などです。今回のポートレットでは、表示モードしか扱わないので、doView だけを追加しておきます。

doView メソッドでは、RenderRequest と RenderResponse を利用し、まず、コンテンツタイプを設定してから(コンテンツタイプを指定しないと Exception が投げられます)、与えられた YOUR_NAME_KEY キーの値を取得して、helloworld.jsp に渡す処理をしています。

processAction では、ActionRequest と ActionResponse を持っています。このメソッドでは、helloworld.jsp で送信された値を ActionResponse に渡しているのがわかります。ところで、このRender~やAction~は何なのでしょうか?これらは、名前の通り、表示のためのRender~であり、アクションを処理するためのAction~です。つまり、processAction で jsp などからの様々な入力値を処理して、ActionResponse の setRenderParameter で RenderRequest に渡します。つまり、jsp からの入力は、doView の RenderRequest で取得できないということになります。ですので、doView などでは、本当に表示だけの処理に専念することになります。これの意味を考えるためには、次のような状況を考えてください。ポートレットは、1つのページに複数のポートレットを表示することになります。各ポートレットは独立していて、ほとんどの場合、複数の中の1つだけに入力データなどを送信して処理することになります。その対象のポートレットでは、processAction が呼ばれ、doView が呼ばれることになるでしょう。それ以外のポートレットではどうでしょうか?他のポートレットでは、ページが更新されますが、表示内容はその更新に関係なく、同じ内容を表示しなければなりません(たとえば、他のページで一覧を表示していて見ていたのに、他のポートレットで処理したらメニューに戻るなどあったら困ります)。ですので、ページが更新されたとしても、アクションの処理の対象でなければ、表示の内容を維持する必要があるので、アクションに関係なく、Render~で独立したパラメータを持つことになります。こういうことから、processAction の Action~からデータを取得して処理し、表示用のパラメータを設定して、setRenderParameterなどで、Render~に渡すという処理の流れになります。

./src/java/com/marevol/portlet/helloworld/HelloWorldPortlet.java
/*
* Copyright 2000-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.marevol.portlet.helloworld;
import java.io.IOException;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.GenericPortlet;
import javax.portlet.PortletConfig;
import javax.portlet.PortletContext;
import javax.portlet.PortletException;
import javax.portlet.PortletRequestDispatcher;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
/**
* HelloWorldPortlet is a portlet to say "Hello!"
*
* @author Shinsuke Sugaya
*/
public class HelloWorldPortlet extends GenericPortlet
{
public static final String YOUR_NAME_KEY = "yourName";
/* (non-Javadoc)
* @see javax.portlet.Portlet#init(javax.portlet.PortletConfig)
*/
public void init(PortletConfig config) throws PortletException
{
super.init(config);
}
/* (non-Javadoc)
* @see javax.portlet.GenericPortlet#doView(javax.portlet.RenderRequest, javax.portlet.RenderResponse)
*/
protected void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException
{
response.setContentType("text/html");
PortletContext context = getPortletContext();
String yourName = request.getParameter(YOUR_NAME_KEY);
if (yourName == null)
{
yourName = "";
}
request.setAttribute(YOUR_NAME_KEY, yourName);
PortletRequestDispatcher rd = context.getRequestDispatcher("/WEB-INF/view/helloworld.jsp");
rd.include(request, response);
}
/* (non-Javadoc)
* @see javax.portlet.Portlet#processAction(javax.portlet.ActionRequest, javax.portlet.ActionResponse)
*/
public void processAction(ActionRequest request, ActionResponse response) throws PortletException, IOException
{
String yourName = request.getParameter(YOUR_NAME_KEY);
if (yourName != null)
{
response.setRenderParameter(YOUR_NAME_KEY, yourName);
}
}
}

helloworld.jsp は、今回のポートレットのビューの部分にあたります。この JSP ファイルは、HelloWorldPortlet クラスから呼ばれて、実行されます。ここでは、入力フォームを表示して、送信ボタンをクリックすると、そのメッセージが表示される処理を実行します。

この helloworld.jsp では、2つのタグライブラリを読み込んでいますが、ポートレットで利用されるのが http://java.sun.com/portlet のタグライブラリです。taglib uri=… でこのタブライブラリを宣言しておいて、<portlet:defineObjects/> を記述すると、それ以降で、renderRequest などのパラメータを利用することができるようになります。また、このタグライブラリには、<portlet:actionURL /> などの URL を作成するタグもあるので、ビューで JSP を利用するときには、通常、このタブライブラリは使うことになると思います。このタグライブラリに関する詳細は、PLT.22 を参照してください。

fmt のタグライブラリの方は、一般的な JSTL のものですので、そちらの方のドキュメントなどを参照してください。今回は、メッセージを国際化するためだけに利用しています。

./src/webapp/WEB-INF/view/helloworld.jsp
<%--
Copyright 2004 The Apache Software Foundation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
    • %>
<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %> <%@ taglib uri="http://java.sun.com/jstl/fmt" prefix="fmt" %> <fmt:setBundle basename="com.marevol.portlet.helloworld.resources.HelloWorldResources" /> <portlet:defineObjects/>
<fmt:message key="helloworld.lable.Hello"/> <%= renderRequest.getAttribute("yourName") %>
<fmt:message key="helloworld.lable.YourName"/>
"/>

最後に、HelloWorldResources プロパティファイルについてです。今回は、デフォルトのものと、…_ja.properties の日本語用のものを作成しています。このリソースは、portlet.xml と helloworld.jsp で指定されています。

デフォルトのものと日本語用を比べると、日本語用には、javax.portlet で始まるプロパティが追加されているのがわかると思います。これらは、portlet.xml の portlet-info 要素以下にあったものにそれぞれが対応しています。たとえば、ポートレットの上部に表示されるタイトルで日本語のタイトルを表示したいといった場合などは、javax.portlet.title プロパティを portlet.xml の resouce-bundle 要素で指定したプロパティふぃあるに追加しておけば、このタイトルが表示されます。short-title と keywordsも同様に、日本語が表示したい場合には、プロパティファイルに加えておきます(short-title はその名の通り、本来は、短いタイトルです。ここでは、長くなってしまっていますが・・・。これはたとえば、携帯電話などで通常より短いタイトルが良いような場合に利用されることになると思います)。

./src/java/com/marevol/portlet/helloworld/resources/HelloWorldResources_ja.properties
# Copyright 2004 The Apache Software Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# $Id: HelloWorldResources_ja.properties,v 1.2 2004/09/24 06:14:57 shinsuke Exp $
#
# portlet info
javax.portlet.title=\u30CF\u30ED\u30FC\u30EF\u30FC\u30EB\u30C9
javax.portlet.short-title=\u3053\u308C\u306F\u3001\u300C\u3053\u3093\u306B\
\u3061\u306F\u300D\u3068\u8A00\u3046\u30DD\u30FC\u30C8\u30EC\u30C3\u30C8\u3067\
\u3059\u3002
javax.portlet.keywords=\u30C6\u30B9\u30C8,\u30CF\u30ED\u30FC
# helloworld.jsp
helloworld.lable.Hello=\u3053\u3093\u306B\u3061\u306F\u3001
helloworld.lable.YourName=\u540D\u524D:
helloworld.lable.Submit=\u9001\u4FE1
./src/java/com/marevol/portlet/helloworld/resources/HelloWorldResources.properties
# Copyright 2004 The Apache Software Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# $Id: HelloWorldResources.properties,v 1.2 2004/09/24 06:14:57 shinsuke Exp $
#
# helloworld.jsp
helloworld.lable.Hello=Hello!
helloworld.lable.YourName=Your Name:
helloworld.lable.Submit=Submit

ポートレットのビルド

必要なものが一通り用意できたので、ビルドして、ポートレットアプリケーションの war ファイルを作成してみましょう。ビルド方法は、非常に簡単です(もちろん Maven を実行できる環境が用意済みであることを想定しています)。

$ ls
project.properties  project.xml  src
$ maven war
__  __
|  \/  |__ _Apache__ ___
| |\/| / _` \ V / -_) ' \  ~ intelligent projects ~
|_|  |_\__,_|\_/\___|_||_|  v. 1.0.2
.
.
.

Maven の war プラグインの war ゴールをそのまま利用できるので、それを使用しています。このことからも、基本的には、普通の Web アプリケーションと同じであることがわかると思います。ビルドに成功していると、target ディレクトリの下に helloworld.war が作成されていると思います。

$ ls target/helloworld.war
target/helloworld.war

これで、JSR 168 に準拠しているポートレットを作成できたことになります。これを、Jetspeed に限らず、JSR 168 に準拠しているポータルサーバー上に持っていき、そのポータルサーバーの配備手順に従って、配備すれば、動きます。

Jetspeed2 への配備

配備するポートレットが作成できたので、早速、Jetspeed2 上で動かすことにしましょう。Jetspeed2 では、どのページにどのポートレットを表示するかという情報は、PSML ファイルに記述されています。ですので、helloworld ポートレットを表示するページを作成する必要があります(Portal Site Manager を使えば、できるようになると思うのですが、現在、バグがあるっぽいのと、管理系のポートレットを変えるような動きがあるので、手動でファイルを置くことにします)。

まず、Jetspeed2 を Tomcat へ配備して、Tomcat の startup.sh をすれば、Jetspeed2 が起動できる状態にしてください(ビルド方法でいうと、maven quickStart までが完了した状態)。準備ができたら、helloworld ポートレットを表示するためにページを作成します。作成するファイルは、webapps/jetspeed/WEB- INF/pages/helloworld.psml になります。

$ cd
$ cd apache/jakarta-tomcat-5.0.30
$ vi webapps/jetspeed/WEB-INF/pages/helloworld.psml

ファイルの内容は以下のようになります。ルートノードが page 要素で、以下にある defaults 要素の造成でポートレットとページ自体のデザインを決めています。Jetspeed2 ではデフォルトのデザインは、tigris デコレータを適用しています。

ページのタイトルは、英語環境でアクセスすると、Hello World for Jetspeed 2 が表示されますが、日本語環境で表示すると、Jetspeed2用ハローワールドと表示されます。

helloworldポートレットは、fragment 要素の id が hw-11 で指定されたところに定義されています。fragment要素の ID が hw-1 の jetspeed-layouts ポートレットは、その名前の通り、レイアウトを管理していて、このポートレットが、それ以下の要素にあるポートレットのレイアウトを決めています。

<page>
<defaults
skin="orange"
layout-decorator="tigris"
portlet-decorator="tigris"
/>
<title>Hello World for Jetspeed 2</title>
<metadata name="title" xml:lang="ja">
Jetspeed2用ハローワールド
</metadata>
<fragment id="hw-1" type="layout" name="jetspeed-layouts::VelocityOneColumn">
<fragment id="hw-11" type="portlet" name="helloworld::HelloWorld">
<property layout="OneColumn" name="column" value="0" />
</fragment>
</fragment>
<security-constraints>
<security-constraints-ref>public-view</security-constraints-ref>
</security-constraints>
</page>

では、ページを作成したところで、Jetspeed2 を起動してみましょう。

$ ./bin/startup.sh

Jetspeed2 が起動したら、http://localhost:8080/jetspeed/portal/helloworld.psml にアクセスしてみてください。どうでしょう?エラーが表示されているのではないでしょうか?そうです。まだ、helloworld.war を Jetspeed2 に配備していないので、エラーが表示されます。ということですので、helloworld.war を配備しましょう。

Jetspeed2 のポートレットの配備は、非常に簡単で、/WEB-INF/deploy/ に war ファイルを置くだけです。そのディレクトリに置いておけば、しばらくすると自動的にJetspeed2 に配備されます。早速、コピーしてみましょう。

$ cp ~/Projects/helloworld/target/helloworld.war webapps/jetspeed/WEB-INF/deploy/

コピーしたら、しばらく待ち、再度、先ほどのページにアクセスしてみてください。今度は、どうでしょう?表示されたでしょうか?このように、 Jetspeed2 でのポートレットの配備は、動的に行ってくれるので、非常に簡単です。配備を解除したい場合は、admin でログインして、PLAM ポートレットで行うことができます。PLAM ポートレットでは、現在、配備中のポートレットも確認できるので、一度、見てみると良いと思います。

JSR 168 準拠のポートレットの作成と、Jetspeed2 への配備方法を一通り、見てきました。これを機にいろいろなポートレット作成にぜひ、チャレンジしてみてください♪

ビルド方法

ビルド方法

ここでは、Apache にある Subversion のリポジトリから Jetspeed2 のソースコードを取得して、そのビルド方法を説明します。

ソースコードの取得

Apache では、従来の CVS 管理のリポジトリに加え、様々なプロジェクトで CVS から Subversion への移行が進んできます。Jetspeed も、現在、CVS から移行しています。ですので、CVS も読み込みだけができる状態でアクセスすることが可能です。最新のソースコードを入手するためには、Subversion のリポジトリから取得する必要があります。

では、早速、チェックアウトしていきましょう。チェックアウトするにはもちろん Subversion が必要になるので、http://subversion.tigris.org/ から入手してください。

$ cd
$ mkdir svn
$ cd svn/
$ svn checkout http://svn.apache.org/repos/asf/portals/jetspeed-2/trunk/ jetspeed-2

指定する URL には、http と https の2種類がありますが、ビルドして利用するだけなら、http の方で問題ありません。https の方は、コミッターが編集をコミットするときなどに利用します。

ビルド環境の準備

ビルド・配備をしていくには、以下のものが必要になります。各サイトよりダウンロードしてください。

表:ビルド・配備に必要なもの
名前 	バージョン
Maven 	1.0 以上
Java 	1.4.2_02 以上
Servlet API(Tomcat)
2.3 以上
(Tomcat 5.0.30 以上またはTomcat 5.5.8以上)

今回は、Maven 1.0.2 でビルドを実行して、Tomcat 5.0.30 に配備します。Jetspeed 2 では、Tomcat 4.x をサポートしていないので、注意してください。

$ cd
$ mkdir apache
$ cd apache/
$ tar zxvf ../jakarta-tomcat-5.0.30.tar.gz
$ tar zxvf ../maven-1.0.2.tar.gz

$HOME/apache 以下に展開したので、次に Maven を利用するために環境変数を設定しておきます(Java は /usr/java にインストールしてあるものとします)。たとえば、.bashrc などに

export JAVA_HOME=/usr/java/
export MAVEN_HOME=$HOME/apache/maven-1.0.2
export PATH=$JAVA_HOME/bin:$MAVEN_HOME/bin:$PATH

として、

$ . ~/.bashrc

を実行して、その設定を有効にします(次回のログインしたときには、有効になっているので、これは行う必要はありません)。Maven でビルドしていく前に、Maven が正しくインストールされているか確認するために、

$ maven -v
__  __
|  \/  |__ _Apache__ ___
| |\/| / _` \ V / -_) ' \  ~ intelligent projects ~
|_|  |_\__,_|\_/\___|_||_|  v. 1.0.2

で Maven が実行できることを確認してください。以上のようにバージョン情報が表示されれば、問題ありません。

プロパティの設定

Jetspeed2 をビルド・配備するためには必要なプロパティをいくつかあります。その設定は Maven で利用されるプロパティであり、それらを設定するためには、${USER_HOME}/build.properties ファイルを作成して、以下のプロパティを環境に応じて、build.properties に記述してください。

JETSPEED2 のビルドに必要な設定 プロパティ 	説明
org.apache.jetspeed.project.home 	チェックアウトした Jetspeed2 のソースコードの場所を指定します。
org.apache.jetspeed.server.home 	インストールしたTomcatサーバーのルート
org.apache.jetspeed.catalina.version.major 	Tomcatのバージョン:Tomcat 5.0.x (5を指定) または 5.5.x? (5.5を指定) (4.x 系はサポートしていません)
org.apache.jetspeed.server.shared 	インストールしたTomcatの共有するJarファイルを置く場所
org.apache.jetspeed.deploy.war.dir 	Tomcat内でWebアプリケーションを配備する場所
org.apache.jetspeed.services.autodeployment.user 	manager ロールをもつTomcatユーザー。 Tomcat設定の章を参照してください。
org.apache.jetspeed.services.autodeployment.password 	Tomcat の manager ユーザーのパスワード。

Jetspeed2 では、デフォルトでは HSQL を利用していますが、それ以外にも MySQL などの様々なデータベースを利用することができます。デフォルトで利用されるHSQL以外のデータベースでJetspeedを開発実行するためには、データベース設定 のプロパティ設定を参照してください。

以上のプロパティ値を設定すると、たとえば、以下のようになります。ここでは、ユーザー名を taro として、そのホームディレクトリを /export/home/taro としています。

org.apache.jetspeed.project.home=/export/home/taro/svn/jetspeed-2
org.apache.jetspeed.server.home = /export/home/taro/apache/jakarta-tomcat-5.0.30/
org.apache.jetspeed.catalina.version.major=5
org.apache.jetspeed.server.shared = ${org.apache.jetspeed.server.home}/shared/lib
org.apache.jetspeed.deploy.war.dir = ${org.apache.jetspeed.server.home}/webapps/
org.apache.jetspeed.services.autodeployment.user=j2deployer
org.apache.jetspeed.services.autodeployment.password=j2deployer

Tomcat 設定

次に Tomcat を設定します。Jetspeed2 は、ポートレットライフサイクルマネージャポートレットを利用してポートレットを管理するために、Tomcatマネージャアプリケーションを利用することができます。 それを利用するためには、${CATALINA_HOME}/conf/tomcat-users.xml で manager ロールを設定して、そのロールを持つ Tomcat のユーザーが必要になります。

manager ロールを持つ、j2deployer ユーザーをパスワードを j2deployer として設定した場合、そのtomcat-users.xml は次のようになります。


<tomcat-users>
<role rolename="manager"/>
<user username="j2deployer" password="j2deployer" roles="manager"/>
</tomcat-users>

以上の設定は設定例であるので、実際に運用する場合などには、より適切なユーザー名とパスワードを使用してください。

上のように設定した場合は、build.properties に次のプロパティが必要になるので、tomcat-users.xml のユーザー名とパスワードを変更している場合は、前節で保存した build.properties にある値も併せて変更してください。

org.apache.jetspeed.services.autodeployment.user=j2deployer
org.apache.jetspeed.services.autodeployment.password=j2deployer

Jetspeed2 のビルド

いよいよ、Jetspeed2 をビルドしていきます。Jetspeed2 は複数のコンポーネントから構成されているので、ビルドは、Maven の reactor を用いて、各コンポーネントを呼び出しビルドを実行しています。Jetspeed2 をビルドするために使われるゴールは、主に initMavenPlugin、allClean と allBuild の3つです。initMavenPlugin は Jetspeed2 のビルドで利用されるゴールをまとめたもので(将来、Maven2 に移行するために各ゴールの処理をプラグインに集約しています)、allClean は、その名の通り、各コンポーネントの clean を呼び出し、allBuild で各コンポーネントのビルドを実行しています。

Jetspeed2のポータルサーバー自身とすべてのコンポーネントを構築していくには、次のコマンドを実行します(すっきりビルドさせるために、allBuild する前に allClean を実行しておきます)。

$ maven initMavenPlugin allClean allBuild

initMavenPlugin で一度、Jetspeed2プラグインを Maven にインストールされれば、2回目以降は、allClean allBuild だけでも問題ありません。

マシンのスペックにもよりますが、ビルドには数分かかると思います。Maven を初めて実行する場合には、依存する多くの jar ファイルを Maven のリモートリポジトリからダウンロードするため、少し多く時間がかかるかもしれません。一度、Maven のローカルリポジトリに保存されると、次回以降の実行では、リモートリポジトリに取りに行くことはないので、安心してください(*- SNAPSHOT.jarはその対象から除かれているので、再度取得しにいきます)。あまりにダウンロードに時間がかかるような場合は、リモートリポジトリを用意して、build.properties に maven.repo.remote を設定して対応するのがよいでしょう。

現在では、デフォルトでテストをスキップするようになっています。その設定は、jetspeed-2 ディレクトリの project.properties 内で maven.test.skip プロパティで設定されています。もし、その値を false とした場合は、テスト用にデータベースを起動する必要があります(デフォルトでは、テストはスキップされるので起動する必要はありません)。HSQLを使用する場合は、allBuild ゴールの実行する前にHSQLを実行します。start.test.serverゴールを別の端末で実行してください。

$ maven j2:start.test.server

実行後、maven allClean allBuild の実行で、テストとビルドが実行されます。

TomcatへJetspeed2の配備

それでは、Jetspeed2 を配備していきましょう。Jetspeed2 は、Tomcat 5 または Tomcat 5.5 へ配備することができます。HSQL を使用しないなら、ステップ1は省略可能です。

1. HSQLを使用している場合は、次のゴールを実行して、HSQLを起動します。

$ maven j2:start.production.server
__  __
|  \/  |__ _Apache__ ___
| |\/| / _` \ V / -_) ' \  ~ intelligent projects ~
|_|  |_\__,_|\_/\___|_||_|  v. 1.0.2
build:start:
start.production.server:
[echo] ====================================
[echo]   Production/Deployment Database
[echo] ====================================
[java] server.properties not found, using command line or default properties
[java] Opening database: ./src/database/hsql/Production
[java] HSQLDB server 1.7.1 is running
[java] Use SHUTDOWN to close normally. Use [Ctrl]+[C] to abort abruptly
[java] Sat Jun 11 08:55:15 JST 2005 Listening for connections ...

2. (別のウィンドウまたは端末で)ビルドされたものを Tomcat に配備します。

$ cd
$ cd svn/jetspeed-2
$ maven j2:quickStart

quickStart ゴールの実行で、必要なデータベースが作成されます。今回の場合は、HSQL の src/database/hsql/Production に必要な情報が書き込まれます。

3. Tomcatを起動して、ブラウザで次のURLにアクセスします。

http://localhost:8080/jetspeed

Jetspeed2 の配備後、初めてアクセスする場合には、各ポートレットの配備が実行されます。ポートレットが配備されるまでは、ポートレットが表示されませんので、しばらくおいて(1分くらい)再度、アクセスしてください。

4. Jetspeed2にログインするためには、ユーザー名: admin, パスワード: admin を利用してください。

最新の Jetspeed2 をビルド・実行はできたでしょうか?開発中のものを Subersion のリポジトリより取得しているので、場合によっては、ビルドエラーなどにあうかもしれません。そのときには、Apache の Jetspeed のメーリングリストなどを確認してみてください。または、jetspeed@yahoogroups.jp に日本語で投げてもらってもかまいません(^^)