Documentation

ワークフローコンテクストの利用

Liferayのワークフロー は、承認プロセスとして使用されます。 プロセスの各ステップにおいて、ワークフローは、 Map<String, Serializable> オブジェクトで利用可能な特定のデータを持っており、スクリプトやカスタムコードでは workflowContextとして参照されます。 ワークフローコンテキスト情報は、Liferayのワークフローエンジンが正しく機能するために重要です。 これを理解することで、カスタムコードやワークフロースクリプトでどのように使用するのが最適かを判断することができます。

例えば、ワークフローのコンテキストでは、以下のことができます。

注釈

ServiceContextを使用して、workflowContextが利用できないコンテキストの属性を設定します。 例えば、カスタムコードで BrosEntryLocalService#addEntry を呼び出す場合には、ServiceContext オブジェクトを提供する必要があります。 ServiceContext#setAttributeを使って、ワークフローの中でアクセスしたいデータを渡すことができます。

workflowContextを扱う際には、いくつかの注意点があります。

  • 修正可能でなければならないので、スレッドセーフではありません。 並列実行のコンテクストでは注意が必要です。

    例えば、フォークノードを持つワークフローにおいて、ワークフローの両方のフォークで workflowContext を更新することは推奨されません。

  • その最初の型のパラメータ(属性の キー )は、Stringです。 これは、2番目の属性に格納されている値を検索するために使用されます。

  • その2番目の型パラメータ(各属性の )は、データベースに保存されているため、 Serializable となっています。 これにより、ワークフローのすべてのステップでアクセスできるようになります。

任意のワークフローノードのワークフローコンテキストキーと値を印刷するには、次のようなスクリプトアクションを追加します。

<actions>
    <action>
        <name>print-workflow-context</name>
        <script>
            <![CDATA[
            for (Map.Entry<String, Serializable> mapEntry :
                workflowContext.entrySet()) {
                    out.println(mapEntry.getKey(), mapEntry.getValue());
            }
            ]]>
        </script>
        <script-language>groovy</script-language>
        <execution-type>onEntry</execution-type>
    </action>
</actions>

ノードが入力されると、ログに出力されます。

entryType, Blogs Entry
companyId, 37401
entryClassPK, 40226
entryClassName, com.liferay.blogs.model.BlogsEntry
groupId, 37441
taskComments, 
userPortraitURL, /image/user_portrait?img_id=0&img_id_token=IpLU58ogLTDf%2FDIfo8Ukg0YxiUE%3D&t=1626283728181
serviceContext, [email protected]
userId, 37448
url, http://localhost:8080/group/guest/~/control_panel/manage?p_p_id=com_liferay_blogs_web_portlet_BlogsAdminPortlet&p_p_lifecycle=0&p_p_state=maximized&_com_liferay_blogs_web_portlet_BlogsAdminPortlet_mvcRenderCommandName=%2Fblogs%2Fview_entry&_com_liferay_blogs_web_portlet_BlogsAdminPortlet_entryId=40226&p_p_auth=rRDR0ncV
userURL, http://localhost:8080/web/test

ワークフロー定義のワークフローコンテキスト属性へのアクセス

アクセスするには workflowContext の属性フォーム <script> にアクセスするには、Map#get 方法をで取得します。

import com.liferay.portal.kernel.workflow.WorkflowConstants;

String className = (String)workflowContext.get(WorkflowConstants.CONTEXT_ENTRY_CLASS_NAME);

上記の例では String を取得していますが、workflowContext の属性の中には、long として使用しなければならないものがあります(例えば、メソッドのパラメータとして渡される場合など)。 これには、 GetterUtil ユーティリティクラスが役立ちます。

import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.workflow.WorkflowConstants;

long classPK = GetterUtil.getLong((String)workflowContext.get(WorkflowConstants.CONTEXT_ENTRY_CLASS_PK));

WorkflowConstants オブジェクトフィールドを使用することで、エラーになりやすい文字列リテラルを避けることができます。 workflowContext フィールドの前には、すべて CONTEXT が付けられます(例: CONTEXT_COMPANY_ID)。

ワークフロー定義でのワークフローコンテキスト属性の設定

workflowContextに属性を設定する場合は、 Map#put 方式を使用します。 この例では、 assetTitleを設定しています。

import com.liferay.asset.kernel.model.AssetRenderer;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.workflow.WorkflowConstants;
import com.liferay.portal.kernel.workflow.WorkflowHandler;
import com.liferay.portal.kernel.workflow.WorkflowHandlerRegistryUtil;

String className = (String)workflowContext.get(WorkflowConstants.CONTEXT_ENTRY_CLASS_NAME);

WorkflowHandler workflowHandler = WorkflowHandlerRegistryUtil.getWorkflowHandler(className);

long classPK = GetterUtil.getLong((String)workflowContext.get(WorkflowConstants.CONTEXT_ENTRY_CLASS_PK));

AssetRenderer assetRenderer = workflowHandler.getAssetRenderer(classPK);

String assetTitle = assetRenderer.getAssetObject().getTitle();

workflowContext.put("assetTitle", assetTitle);

ちなみに

上記のコードは、アセットが getTitle メソッドを持っている場合のみ動作します(例:JournalArticle)。

ワークフロー定義でアクセス用のサービスコンテキスト属性を設定する

カスタムのJavaコードで、ワークフロー定義に情報を渡す必要がありますが、workflowContextがない場合があります。 例えば、ブログのエントリーを追加するコードを書いている場合、 BlogsEntryLocalService#addEntry メソッドのいずれかを呼び出すことができます。 workflowContextはこれらのメソッドのパラメータではありませんが、ServiceContextはパラメータです。 サービスコンテキストに新しい属性を追加します。

serviceContext.setAttribute("customAttributeKey", "customAttributeValue");

ワークフロー定義内の属性を取得するには、 ServiceContext を、 workflowContextから取得し、そのキーを使って属性を取得します。

import com.liferay.portal.kernel.service.ServiceContext;
import com.liferay.portal.kernel.workflow.WorkflowConstants;

ServiceContext serviceContext = (ServiceContext)workflowContext.get(WorkflowConstants.CONTEXT_SERVICE_CONTEXT);

serviceContext.getAttribute("customAttributeKey");