カスタムデータプロバイダーの作成
Liferay フォームのフィールドは、 データ プロバイダーを使用して入力できます。 初期設定のRESTデータプロバイダーは、ほとんどのRESTエンドポイントからデータを消費するための柔軟な方法を提供します。 詳細については、「 REST データ プロバイダーを使用してフォーム オプションを入力する 」を参照してください。
RESTデータプロバイダーが目的に合わない場合は、DDMDataProvider拡張ポイントを使用して、独自のデータプロバイダーを作成します。
!! 注 ここで示すサンプル データ プロバイダーは、 GeoDataSource™ ロケーション検索 Web サービスから XML データを使用します。 このサンプルには、Liferay社員のAPIキーがハードコードされています。 サンプルを使いすぎないようにしてください。 本番環境では絶対に使用しないでください。
カスタムデータプロバイダーをデプロイする
新しいLiferay インスタンスを起動し、以下を実行します。
docker run -it -m 8g -p 8080:8080 liferay/portal:7.4.3.132-ga132
http://localhost:8080でLiferayにサインインします。 メールアドレス test@liferay.com とパスワード testを使用してください。 プロンプトが表示されたら、パスワードを learnに変更します。
次に、以下の手順に従います。
-
Acme XML Data Providerをダウンロードし、解凍する。
curl https://resources.learn.liferay.com/examples/liferay-b4d8.zip -Ounzip liferay-b4d8.zip -
モジュールのルートから、ビルドおよびデプロイします。
./gradlew deploy -Ddeploy.docker.container.id=$(docker ps -lq)ヒントこのコマンドは、デプロイされたjarをDockerコンテナの/opt/liferay/osgi/modulesにコピーするのと同じです。
-
LiferayのDockerコンテナコンソールで各モジュールのデプロイを確認します。
STARTED com.acme.n4g6.impl_1.0.0
データプロバイダをテストする
フォームでデータプロバイダーを使用するには
-
データプロバイダーのインスタンスを追加します。
-
サイト メニューで、[コンテンツとデータ] → [フォーム] に移動します。
-
[データプロバイダー]タブを開き、追加ボタンをクリックします。

-
下記のように設定します:
- 名前: ダイアモンドバー(カリフォルニア州、米国)近郊の都市
- 説明: GeoDataSource の場所検索–Liferay 本社から 20 km 以内の都市を取得します。
- 出力
- ラベル: 市
- パス: 都市
- タイプ: リスト

-
[保存]をクリックします。
-
-
Diamond Bar付近のデータプロバイダーを使用するフォームを追加します。
-
サイト メニューで、[コンテンツとデータ] → [フォーム] に移動します。
-
[フォーム]タブで、[追加]ボタンをクリックします。
-
次の設定で[リストから選択]フィールドを追加します。
-
ラベル: Liferayの近くの都市を選択してください
-
リストを作成: データプロバイダーから
-
データプロバイダーを選択してください: ダイアモンドバー、カリフォルニア州 (米国) 近郊の都市
-
出力パラメータを選択してください: 都市
-
-
フォームを公開し、データプロバイダからリストが入力されていることを確認します。

-
これは良い例ですが、データプロバイダーのURLをハードコードしています。 URLを設定できるようにしておけば、この同じデータプロバイダーを他の都市や、XMLを提供する他のURLでも使用することができます。
B4D8 DDMデータプロバイダーについて
Acme B4D8 Implementation プロジェクトには、特定のURLからXMLを返すためのカスタムデータプロバイダが含まれています。 B4D8DDMDataProvider、 B4D8DDMDataProviderSettingsProovider、 B4D8DDMDataProviderSettingsの3つのクラスが含まれています。
DDMDataProviderの実装
データプロバイダクラスは、 com.liferay.dynamic.data.mapping.data.provider.DDMDaProvider インターフェースを実装し、getData と getSettingsの2つのメソッドをオーバーライドします。 これらのメソッド名は、設定に基づいてデータを提供するという、データプロバイダーの本質を捉えています(設定は任意です)。
インターフェースのメソッドを実装し、2つの @Component 設定を提供するだけで、データプロバイダをLiferay Formsアプリケーションに登録することができ、Liferayのデフォルトデータプロバイダと一緒にフォームUIに表示されます。
@Component(
property = "ddm.data.provider.type=b4d8", service = DDMDataProvider.class
)
public class B4D8DDMDataProvider implements DDMDataProvider {
@Override
public DDMDataProviderResponse getData(
DDMDataProviderRequest ddmDataProviderRequest)
throws DDMDataProviderException {
}
@Override
public Class<?> getSettings() {
}
}
getData メソッドがほとんどの作業を行います。 これは、Formsフレームワークが理解できる DDMDaProviderResponse を返さなければなりません。 B4D8のデータプロバイダーとしては、下記のような特徴があります。
- XMLデータソースのURLが構築されます。
String key = "LAOOBDZVQ5Z9HHYC4OCXHTGZGQLENMNA";
String url =
"https://api.geodatasource.com/cities?key=" + key +
"&format=xml&lat=33.9977&lng=-117.8145";
-
_createDDMDataProviderResponseメソッドが呼び出されます。 ここでは、レスポンスオブジェクトの構築が行われます。 このメソッドを呼び出すには、データプロバイダーの設定と、リモートAPIから返されたXMLドキュメントの2つのパラメータを与えます。 両者のロジックは別々のプライベートユーティリティーメソッドにあります。 重要なのは、HttpUtil.URLtoString(url)は、XMLを取得するためにURLを実行する呼び出しです。 -
これで、(データプロバイダのインスタンスの出力パラメータ設定に基づいて)条件付きでレスポンスを構築するための準備が整いました。 ロジックには以下が含まれます。
- 静的な内部
BuilderクラスのnewBuilderメソッドを使って、レスポンスの構築を開始します。
- 静的な内部
DDMDataProviderResponse.Builder builder =
DDMDataProviderResponse.Builder.newBuilder();
-
データプロバイダーの出力パラメータ設定をループします。 データプロバイダーのテスト では、1つの出力セット(3つのネストされたフィールド)のみを追加しました。データプロバイダ設定フォームのプラスボタンをクリックして、追加の出力を持つデータプロバイダを作成すると、このループは各出力を解析します。
-
各出力について、返されたXMLドキュメントのXMLノード、出力パラメータID、要求された出力データのタイプ(上記の例では[リスト]を選択)を取得します。
-
出力パラメータの種類を確認し、レスポンスビルダーの
withOutputメソッドを呼び出します。 各コールでは、出力パラメータIDとマッチするノード(リストが要求されている場合は、複数のノード)のコンテンツが提供されます。
for (DDMDataProviderOutputParametersSettings
ddmDataProviderOutputParametersSettings :
b4d8DDMDataProviderSettings.outputParameters()) {
NodeList nodeList = document.getElementsByTagName(
ddmDataProviderOutputParametersSettings.outputParameterPath());
String outputParameterId =
ddmDataProviderOutputParametersSettings.outputParameterId();
String outputParameterType =
ddmDataProviderOutputParametersSettings.outputParameterType();
if (Objects.equals(outputParameterType, "list")) {
List<KeyValuePair> keyValuePairs = new ArrayList<>();
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
keyValuePairs.add(
new KeyValuePair(
node.getTextContent(), node.getTextContent()));
}
builder.withOutput(outputParameterId, keyValuePairs);
}
else if (Objects.equals(outputParameterType, "number")) {
Node node = nodeList.item(0);
NumberFormat numberFormat = NumberFormat.getInstance();
builder.withOutput(
outputParameterId,
numberFormat.parse(node.getTextContent()));
}
else if (Objects.equals(outputParameterType, "text")) {
Node node = nodeList.item(0);
builder.withOutput(outputParameterId, node.getTextContent());
}
}
- メソッドの最後に、レスポンス
return builder.build()を返します。
DDMDataProviderSettingsで設定を定義します。
データプロバイダー設定クラスは、このデータプロバイダーが必要とする設定を2つの部分に分けて定義します。
- 設定フォーム自体のレイアウトは、
@DDMForm*クラスレベルのアノテーションを使って定義されます。
@DDMForm
@DDMFormLayout(
{
@DDMFormLayoutPage(
{
@DDMFormLayoutRow(
{
@DDMFormLayoutColumn(
size = 12, value = "outputParameters"
)
}
)
}
)
}
)
データプロバイダーを設定するフィールドは、この @DDMForm の設定フォームに追加する必要があります。 このスニペットは現在、継承済みの outputParameters フィールドのみを使用していますが。これは B4D8DDMDataProviderSettings クラスが DDMDataProviderParameterSettingsを継承しているため、アクセス可能です。 フォームにさらに設定を追加する方法については、「 データ プロバイダー設定の追加 」を参照してください。
- クラスの宣言とボディによって、どのようなフィールドが利用できるかが決まります。 現在、追加の設定は必要ありませんので、クラス本体は空白です。
public interface B4D8DDMDataProviderSettings
extends DDMDataProviderParameterSettings {
}
outputParameters フィールドに加えて、 inputParameters フィールドも DDMDataProviderParameterSettingsに用意されています。

現在、設定フォームには、Forms UIに表示されるすべてのデータプロバイダーが必要とするいくつかのデフォルトフィールドが含まれています。名前、説明、そして権限を定義するセクションです。 これらは、 _ddmDataProviderInstanceSettings.getSettings(...) の呼び出しで設定を追加することで得られます。 Outputsフィールドは、レイアウトに追加した outputParameters フィールドを継承したもので、実際にはLabel、Path、Typeで構成されるネストしたフィールドです。
DDMDataProviderSettingsProvider を実装する。
設定プロバイダークラスには getSettings というメソッドがあり、与えられたデータプロバイダーの DDMDataProviderSettings クラスを返します。 これは、データプロバイダーの設定クラスをインスタンス化するために使用されます。これにより、設定値を取得し、それに応じてデータプロバイダーを設定することができます。
B4D8DDMDataProviderSettingsProvider への参照を取得し、その getSettings メソッドを、データ プロバイダ クラスの同名の getSettings メソッドから呼び出します。
@Override
public Class<?> getSettings() {
return _ddmDataProviderSettingsProvider.getSettings();
}
@Reference(target = "(ddm.data.provider.type=b4d8)")
private DDMDataProviderSettingsProvider _ddmDataProviderSettingsProvider;
データプロバイダー設定を追加する
データプロバイダー設定を追加するには、 DataProviderSettings インターフェースにアノテーションフィールドを追加し、設定値に反応するように DataProvider クラスを更新します。
設定にURLフィールドを追加
-
まず、
URLフィールドをDataProviderSettingsに追加します。 クラス本体に、このアノテーション付きのメソッドを追加します。@DDMFormField( label = "%url", required = true, validationErrorMessage = "%please-enter-a-valid-url", validationExpression = "isURL(url)" ) public String url();それにはこのインポートが必要です。
import com.liferay.dynamic.data.mapping.annotations.DDMFormField; -
フォームのレイアウトを作成するクラスレベルのアノテーションでは、
@DDMFormLayoutColumnを次のように置き換えます。@DDMFormLayoutColumn( size = 12, value = {"url", "outputParameters"} )
これで、 DataProvider クラスで使用するための設定が整いました。
データプロバイダーの getData メソッドで設定を処理します。
ここで、 B4D8DDMDataProvider#getData メソッドを更新する必要があります。
- ハードコードされた文字列
url変数を削除します。 B4D8DDMDataProviderSettingsを先にインスタンス化して、URL設定を取得するようにメソッドをリファクタリングしています。- レスポンスにURLを設定します。
ローカルで編集する場合は、以下の説明文の下にある try ブロックを完全にコピーしてください。
-
ユーザー入力が可能になったことで、有効なURLを得ることができるようになりました。
キー変数—を定義している行を削除します。これで、URL 設定フィールドで設定できるようになります。String key = "LAOOBDZVQ5Z9HHYC4OCXHTGZGQLENMNA"; -
URLを定義している
文字列変数を、データプロバイダーの設定フィールドで入力されたHttp.Optionsで置き換えます。Http.Options options = new Http.Options(); options.setLocation(b4d8DDMDataProviderSettings.url()); -
新しい
オプションを、urlの代わりに使用して、return文の_createdDDMDataProviderResponseの呼び出しに使用します。 既存のreturn文を置き換える。return _createDDMDataProviderResponse( b4d8DDMDataProviderSettings, _toDocument(HttpUtil.URLtoString(options)));
上記の手順では、メソッドのリファクタリングを省略しています。 これらの手順をコンパイルしてテストするには、 try ブロック全体を getData メソッドで上書きします。
try {
B4D8DDMDataProviderSettings b4d8DDMDataProviderSettings =
_ddmDataProviderInstanceSettings.getSettings(
_getDDMDataProviderInstance(
ddmDataProviderRequest.getDDMDataProviderId()),
B4D8DDMDataProviderSettings.class);
Http.Options options = new Http.Options();
options.setLocation(b4d8DDMDataProviderSettings.url());
return _createDDMDataProviderResponse(
b4d8DDMDataProviderSettings,
_toDocument(HttpUtil.URLtoString(options)));
}
Liferayの Http クラスをインポートします。
import com.liferay.portal.kernel.util.Http;
これで、アップデートデータプロバイダをテストする準備が整いました。
更新されたデータプロバイダのデプロイとテスト
更新されたデータプロバイダーをフォームで使用するには
-
モジュールルートから、リビルドして再デプロイします。
./gradlew deploy -Ddeploy.docker.container.id=$(docker ps -lq) -
データプロバイダーのインスタンスを追加します。
- 名前: レシフェ近郊の都市、ペルナンブコ州(ブラジル)
- 説明: GeoDataSource の場所検索–Liferay のブラジル オフィスから 20 km 以内の都市を取得します。
- URL:
https://api.geodatasource.com/cities?key=LAOOBDZVQ5Z9HHYC4OCXHTGZGQLENMNA&format=xml&lat=-8.0342896&lng=-34.9239708 - 出力
- ラベル: 市
- パス: 都市
- タイプ: リスト
-
Cities Near Recife 付近のデータプロバイダを使用するフォームを追加します。
-
サイト メニューで、[コンテンツとデータ] → [フォーム] に移動します。
-
[フォーム]タブで、[追加]ボタンをクリックします。
-
次の設定で[リストから選択]フィールドを追加します。
-
ラベル: Liferay, BR の近くの都市を選択してください
-
リストを作成: データプロバイダーから
-
データプロバイダーを選択してください: レシフェ、ペルナンブコ州、(ブラジル)近郊の都市
-
出力パラメータを選択してください: 都市
-
-
フォームを公開し、データプロバイダからリストが入力されていることを確認します。

-