#Liferay7/DXP - Workflow/ワークフロー Scriptからのカスタムサービス・標準サービスのコール方法
Liferayの強力な機能のうちの1つに、ワークフローがある。ワークフローは管理画面のKaleo Designerを利用して、グラフィカルに設定を作成することができるが、実際の案件では標準機能だけではなく、スクリプト(Groovy, Javascript)を利用して、動的に承認者の選択・通知を行うことがよくある。
その際に、Liferay組み込みのサービスや、自身が開発したカスタムサービスを利用することが多いが、dev.liferay.comにある標準サービスコールが古い6.2のLocalServiceUtilを利用した方法のままで、これは間違った方法なので、以下にサンプルを作成してみた。
Liferay7/DXPからアーキテクチャーがOSGiに移行し、6.2の時からサービスのコール方法が変わっている。OSGiのフレームワークに対して問い合わせをして、必要なサービスを取ってくる、という形になる。
普通にJavaコード内からサービスを呼び出す場合は、https://github.com/liferay/liferay-portal 内のLiferayコアにあるサービス群のコーディングを参考にしてもらえばわかるように、@Referenceアノテーションを利用して
###Javaコード内でのサービス取得方法(liferay-portalコードから抜粋)
@Reference(unbind = "-")
protected void setWSRPConsumerPortletLocalService(
WSRPConsumerPortletLocalService wSRPConsumerPortletLocalService) {
_wSRPConsumerPortletLocalService = wSRPConsumerPortletLocalService;
}
private static WSRPConsumerPortletLocalService
_wSRPConsumerPortletLocalService;
のように書けるが、Workflow内のscripted-assignmentなどのタグ内では以下のように記載する。
###Scriptページ/Workflow内でのサービス取得・利用方法
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTracker
import com.liferay.portal.scripting.groovy.internal.GroovyExecutor
def st = null
try {
Bundle bundle = FrameworkUtil.getBundle(GroovyExecutor.class);
st = new ServiceTracker(bundle.getBundleContext(), "com.liferay.journal.service.JournalArticleLocalService", null);
st.open();
if (!st.isEmpty()) {
def service = st.getService();
def articles = service.getArticles();
for (def article: articles) {
System.out.println("article Name:${article.getUrlTitle()}");
}
}
} catch(Exception e) {
System.out.println("Handle error here appropriately")
e.printStackTrace()
} finally {
if (st != null) {
st.close()
}
}
これはWorkflow定義に記載してもらっても動作するが、簡単に試したい場合は、何かWebコンテンツを作成したあとに、Control Panel -> Configuration -> Server Administration -> Scriptから、Groovyを選択してもらい、Scriptフィールドに上記のコードを貼り付けてもらうと、作成したWebコンテンツのタイトルが表示される。
OSGiのお作法に則り、FrameworkUtil.getBundleで起点となるバンドルを指定(この場合はGroovy Scriptエンジンを利用しているので、GroovyExecutor.classを指定している)次にServiceTrackerで対象となるサービスを取得してきている。