カスタムデータプロバイダーの作成
Liferay Formsのフィールドは、 データプロバイダーを使用して入力することができます。 初期設定のRESTデータプロバイダーは、ほとんどのRESTエンドポイントからデータを消費するための柔軟な方法を提供します。 詳しくは、 RESTデータプロバイダーを使用してフォームオプションを入力する をご覧ください。
RESTデータプロバイダーが目的に合わない場合は、DDMDataProvider
拡張ポイントを使用して、独自のデータプロバイダーを作成します。
このデータプロバイダーの例では、 GeoDataSource™ Location Search Web Service からXMLデータを消費します。 このサンプルには、Liferay社員のAPIキーがハードコードされています。 サンプルを使いすぎないようにしてください。 本番環境では絶対に使用しないでください。
カスタムデータプロバイダーをデプロイする
新しいLiferay インスタンスを起動し、以下を実行します。
docker run -it -m 8g -p 8080:8080 liferay/portal:7.4.3.112-ga112。
http://localhost:8080でLiferayへのサインインします。 メールアドレス test@liferay.com とパスワード test を使用してください。 プロンプトが表示されたら、パスワードを learn に変更します。
次に、以下の手順を実行します。
-
Acme XML Data Provider をダウンロードし、解凍する。
curl https://resources.learn.liferay.com/dxp/latest/en/process-automation/forms/developer-guide/liferay-b4d8.zip -O
unzip liferay-b4d8.zip
-
モジュールのルートから、ビルドおよびデプロイします。
./gradlew deploy -Ddeploy.docker.container.id=$(docker ps -lq)
Tipこのコマンドは、デプロイされたjarをDockerコンテナの/opt/liferay/osgi/modulesにコピーするのと同じです。
-
LiferayのDockerコンテナコンソールで各モジュールのデプロイを確認します。
STARTED com.acme.n4g6.impl_1.0.0
データプロバイダをテストする
フォームでデータプロバイダーを使用するには
-
データプロバイダーのインスタンスを追加します。
-
サイトメニューの[コンテンツとデータ] → [フォーム]を選択します。
-
[データプロバイダー]タブを開き、 追加 ボタンをクリックします。
-
下記のように設定します:
- 名前: Cites Near Diamond Bar, CA (USA)
- 説明: GeoDataSource Location Search- Liferay本社の20キロ内の都市を取得します。
- 出力
- ラベル: 都市
- パス: 都市
- タイプ: リスト
-
[保存] をクリックします。
-
-
Diamond Bar付近のデータプロバイダーを使用するフォームを追加します。
-
サイトメニューの[コンテンツとデータ] → [フォーム]を選択します。
-
[フォーム]タブで、[追加]ボタンをクリックします。
-
次の設定で[リストから選択]フィールドを追加します。
-
ラベル: Liferay周辺の都市を選択してください。
-
リストの作成: データプロバイダーから
-
データ・プロバイダーを選択してください。 Diamond Bar, CA (USA)周辺の都市
-
出力パラメータを選択: 都市
-
-
フォームを公開し、データプロバイダからリストが入力されていることを確認します。
-
これは良い例ですが、データプロバイダーの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を得ることができるようになりました。
key
変数を定義している行を削除しました—これは現在、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)
-
データプロバイダーのインスタンスを追加します。
- 名前: Cites Near Recife, Pernambuco (Brazil)
- 説明: GeoDataSource Location Search–Liferayのブラジルオフィスから20km以内の都市を取得します。
- URL:
https://api.geodatasource.com/cities?key=LAOOBDZVQ5Z9HHYC4OCXHTGZGQLENMNA&format=xml&lat=-8.0342896&lng=-34.9239708
- 出力
- ラベル: 都市
- パス: 都市
- タイプ: リスト
-
Cities Near Recife 付近のデータプロバイダを使用するフォームを追加します。
-
サイトメニューの[コンテンツとデータ] → [フォーム]を選択します。
-
[フォーム]タブで、[追加]ボタンをクリックします。
-
次の設定で[リストから選択]フィールドを追加します。
-
ラベル: Liferay, BRの近くの都市を選択してください。
-
リストの作成: データプロバイダーから
-
データプロバイダーを選択: レシフェ(ペルナンブコ州、ブラジル)に近い都市
-
出力パラメータを選択: 都市
-
-
フォームを公開し、データプロバイダからリストが入力されていることを確認します。
-