ワークフロー機能の拡張 extending-workflow-functionality
このトピックでは、ワークフロー用のカスタムステップコンポーネントを作成する方法や、プログラムによってワークフローを操作する方法について説明します。
カスタムワークフローステップの作成では、以下の作業を行います。
- ワークフローステップコンポーネントを作成
- ステップ機能を OSGi サービスまたは ECMA スクリプトとして実装
プログラムおよびスクリプトからワークフローを操作することもできます。
ワークフローステップコンポーネント - 基本 workflow-step-components-the-basics
ワークフローステップコンポーネントは、ワークフローモデルを作成する際に、次のようにステップの表示方法と動作を定義するものです。
- ワークフローのサイドキックのカテゴリとステップ名
- ワークフローモデルのステップの表示方法
- コンポーネントのプロパティを設定する編集ダイアログ
- ランタイムに実行されるサービスまたはスクリプト
すべてのコンポーネントと同様、ワークフローステップコンポーネントは、sling:resourceSuperType プロパティに指定されたコンポーネントから継承します。次の図は、すべてのワークフローステップコンポーネントの基礎を形成する cq:component ノードの階層を示しています。この図には、プロセスステップ、参加者ステップ および 動的参加者ステップ コンポーネントも含まれています。これらのコンポーネントは、カスタムステップコンポーネント作成の最も一般的で基本的な出発点になります。
/libs パス内の設定は 一切 変更しないでください。/libs コンテンツは、インスタンスを次回アップグレードするとき(場合によってはホットフィックスまたは機能パックを適用したとき)に上書きされるからです。- 必要な項目(
/libs内に存在)を、/appsの下で再作成します。 /apps内で必要な変更を加えます
/libs/cq/workflow/components/model/step コンポーネントは、プロセスステップ、参加者ステップ および 動的参加者ステップ の各コンポーネントの最も近い共通の上位です。これらのコンポーネントはすべて、次の項目を継承します。
-
step.jspstep.jspスクリプトは、ステップコンポーネントがモデルに追加されると、そのタイトルをレンダリングします。
-
ダイアログには以下のタブがあります。
- 共通:タイトルと説明の編集用。
- 詳細:メール通知プロパティの編集用。
note note NOTE ステップコンポーネントの編集ダイアログのタブがこのデフォルトの外観と一致しない場合、ステップコンポーネントには、これらの継承されたタブをオーバーライドするスクリプト、ノードプロパティまたはダイアログタブが定義されています。
ECMA スクリプト ecma-scripts
次のオブジェクトは(ステップタイプに応じて)ECMA スクリプト内で使用できます。
-
WorkItem workItem
-
WorkflowSession workflowSession
-
WorkflowData workflowData
-
args:プロセスの引数を格納する配列 -
sling:他の OSGi サービスへのアクセス用 -
jcrSession
MetaDataMaps metadatamaps
ワークフローメタデータを使用すると、ワークフローの有効期間中に必要とされる情報を保持できます。ワークフローステップの一般的な要件は、そのワークフローで以降に使用するデータを保持したり、保持されているデータを取得することです。
MetaDataMap オブジェクトには、Workflow オブジェクト、WorkflowData オブジェクトおよび WorkItem オブジェクトの 3 タイプがあります。いずれも、メタデータを保存するという同じ目的があります。
WorkItem には、作業項目(ステップなど)の実行中にのみ使用できる固有の MetaDataMap があります。
Workflow MetaDataMap と WorkflowData MetaDataMap は両方とも、ワークフロー全体で共有されます。このような場合は、WorkflowData MetaDataMap のみを使用することをお勧めします。
カスタムワークフローステップコンポーネントの作成 creating-custom-workflow-step-components
ワークフローステップコンポーネントは、その他のコンポーネントと同じ方法で作成できます。
(既存の)ベースステップコンポーネントのいずれかから継承するには、次のプロパティを cq:Component ノードに追加します。
-
名前:
sling:resourceSuperType -
型:
String -
値:ベースコンポーネントに解決される次のパスのいずれか
cq/workflow/components/model/processcq/workflow/components/model/participantcq/workflow/components/model/dynamic_participant
ステップインスタンスのデフォルトのタイトルおよび説明の指定 specifying-the-default-title-and-description-for-step-instances
次の手順を使用して、「共通」タブの「タイトル」フィールドと「説明」フィールドのデフォルト値を指定します。
-
ステップの編集ダイアログが次の場所にタイトルと説明を保存している。
-
./jcr:title -
./jcr:descriptionの場所この要件が満たされるのは、ステップの編集ダイアログが、
/libs/cq/flow/components/step/stepコンポーネントが実装する「共通」タブを使用しているときです。 -
ステップコンポーネントまたはそのコンポーネントの上位が、
/libs/cq/flow/components/step/stepコンポーネントが実装するstep.jspスクリプトをオーバーライドしていない。
-
cq:Componentノードの下に、次のノードを追加します。- 名前:
cq:editConfig - 型:
cq:EditConfig
note note NOTE cq:editConfig ノードについて詳しくは、 コンポーネントの編集動作の設定 を参照してください。 - 名前:
-
cq:EditConfigノードの下に、次のノードを追加します。- 名前:
cq:formParameters - 型:
nt:unstructured
- 名前:
-
次の名前の
Stringプロパティをcq:formParametersノードに追加します。jcr:title:この値が「共通」タブの「タイトル」フィールドに設定されます。jcr:description:この値が「共通」タブの「説明」フィールドに設定されます。
ワークフローメタデータにプロパティ値を保存 saving-property-values-in-workflow-metadata
cq:Widget 項目の name プロパティで、ウィジェットの値を保存する JCR ノードを指定します。ワークフローステップコンポーネントのダイアログ内のウィジェットが ./metaData ノードに値を保存すると、ワークフロー MetaDataMap に値が追加されます。
例えば、ダイアログのテキストフィールドは、次のプロパティを持つ cq:Widget ノードです。
xtypeStringtextareanameString./metaData/subjectfieldLabelStringEmail Subjectこのテキストフィールドに指定された値がワークフローインスタンスの [MetaDataMap](#metadatamaps) オブジェクトに追加され、subject キーに関連付けられます。
PROCESS_ARGS の場合、この値は args 変数を使用して ECMA スクリプト実装ですぐに使用できます。この場合、name プロパティの値は ./metaData/PROCESS_ARGS.ステップ実装のオーバーライド overriding-the-step-implementation
ワークフローモデルの開発者は、デザイン時に、ベースステップコンポーネントごとに次の主要機能を設定できます。
- プロセスステップ:実行時に実行されるサービスまたは ECMA スクリプト。
- 参加者ステップ:生成された作業項目を割り当てるユーザーの ID。
- 動的参加者ステップ:作業項目を割り当てるユーザーの ID を選択するサービスまたは ECMA スクリプト。
コンポーネントを特定のワークフローシナリオ専用にするために、デザイン時に設定した主な機能をモデル開発者が変更できないようにします。
-
cq:component ノードの下に、次のノードを追加します。
- 名前:
cq:editConfig - 型:
cq:EditConfig
cq:editConfig ノードについて詳しくは、 コンポーネントの編集動作の設定 を参照してください。
- 名前:
-
cq:EditConfig ノードの下に、次のノードを追加します。
- 名前:
cq:formParameters - 型:
nt:unstructured
- 名前:
-
Stringプロパティをcq:formParametersノードに追加します。コンポーネントのスーパータイプによって、プロパティの名前が次のように決定されます。- プロセスステップ:
PROCESS - 参加者ステップ:
PARTICIPANT - 動的参加者ステップ:
DYNAMIC_PARTICIPANT
- プロセスステップ:
-
プロパティの値を次のように指定します。
PROCESS:ステップの動作を実装する ECMA スクリプトへのパスまたはサービスの PID。PARTICIPANT:作業項目を割り当てられたユーザーの ID。DYNAMIC_PARTICIPANT:作業項目を割り当てるユーザーを選択する ECMA スクリプトへのパスまたはサービスの PID。
-
モデル開発者がプロパティ値を変更できないようにするために、コンポーネントのスーパータイプのダイアログをオーバーライドします。
フォームとダイアログを参加者ステップに追加 adding-forms-and-dialogs-to-participant-steps
参加者ステップコンポーネントをカスタマイズして、次に示すフォーム参加者ステップコンポーネントとダイアログ参加者ステップコンポーネントの機能を提供するようにします。
- 生成された作業項目を開いたときに、フォームを表示する
- 生成された作業項目を完了したときに、カスタムダイアログを表示する
新しいコンポーネントに対して、以下の手順を実行します(カスタムワークフローステップコンポーネントの作成を参照)。
-
cq:Componentノードの下に、次のノードを追加します。- 名前:
cq:editConfig - 型:
cq:EditConfig
cq:editConfig ノードについて詳しくは、 コンポーネントの編集動作の設定 を参照してください。
- 名前:
-
cq:EditConfig ノードの下に、次のノードを追加します。
- 名前:
cq:formParameters - 型:
nt:unstructured
- 名前:
-
作業項目を開くとフォームが表示されるようにするには、次のプロパティを
cq:formParametersノードに追加します。- 名前:
FORM_PATH - 型:
String - 値:フォームに解決されるパス
- 名前:
-
作業項目を完了するとカスタムダイアログが表示されるようにするには、次のプロパティを
cq:formParametersノードに追加します。- 名前:
DIALOG_PATH - 型:
String - 値:ダイアログに解決されるパス
- 名前:
ワークフローステップの実行時の動作の設定 configuring-the-workflow-step-runtime-behavior
cq:Component ノードの下に、cq:EditConfig ノードを追加します。その下に、nt:unstructured ノードを(必ず cq:formParameters という名前で)追加し、そのノードに次のプロパティを追加してください。
-
名前:
PROCESS_AUTO_ADVANCE-
型:
Boolean -
値:
trueに設定した場合、ワークフローはそのステップを実行して続行します。これはデフォルト値であり、推奨もされています。falseに設定した場合、ワークフローはそのステップを実行して停止します。これには追加の処理が必要なので、trueに設定することをお勧めします。
-
-
名前:
DO_NOTIFY- 型:
Boolean - 値:ユーザー参加ステップについて、メール通知を送信する必要があるかどうかを示します(メールサーバーが正しく設定されていると想定しています)。
- 型:
データの保持とアクセス persisting-and-accessing-data
後続のワークフローステップのためのデータ保持 persisting-data-for-subsequent-workflow-steps
ワークフローメタデータを使用して、ワークフローの有効期間中およびステップ間で必要な情報を保持できます。ワークフローステップの一般的な要件は、以降に使用するデータを保持したり、以前のステップから保持されているデータを取得したりすることです。
ワークフローメタデータは、MetaDataMap オブジェクトに保存されます。Java API が提供する Workflow.getWorkflowData メソッドは、適切な MetaDataMap オブジェクトを提供する WorkflowData オブジェクトを返します。この WorkflowData MetaDataMap オブジェクトは、ステップコンポーネントの OSGi サービスまたは ECMA スクリプトで使用できます。
Java java
WorkflowProcess 実装の実行メソッドは、WorkItem オブジェクトに渡されます。このオブジェクトを使用して、現在のワークフローインスタンスの WorkflowData オブジェクトを取得します。次の例では、ワークフローの MetaDataMap オブジェクトに項目を追加してから、各項目を記録しています。("mykey", "My Step Value") 項目は、ワークフローの後続ステップで使用可能です。
public void execute(WorkItem item, WorkflowSession session, MetaDataMap args) throws WorkflowException {
MetaDataMap wfd = item.getWorkflow().getWorkflowData().getMetaDataMap();
wfd.put("mykey", "My Step Value");
Set<String> keyset = wfd.keySet();
Iterator<String> i = keyset.iterator();
while (i.hasNext()){
Object key = i.next();
log.info("The workflow medata includes key {} and value {}",key.toString(),wfd.get(key).toString());
}
}
ECMA スクリプト ecma-script
graniteWorkItem 変数は、現在の WorkItem Java オブジェクトの ECMA スクリプト表現です。したがって、graniteWorkItem 変数を使用して、ワークフローメタデータを取得できます。次の ECMA スクリプトを使用すると、ワークフローの MetaDataMap オブジェクトに項目を追加してから各項目を記録する プロセスステップ を実装できます。その後、これらの項目は、ワークフローの後続ステップで使用可能です。
metaData 変数は、ステップのメタデータです。ステップのメタデータは、ワークフローのメタデータとは異なります。var currentDateInMillis = new Date().getTime();
graniteWorkItem.getWorkflowData().getMetaDataMap().put("hardcodedKey","theKey");
graniteWorkItem.getWorkflowData().getMetaDataMap().put("currentDateInMillisKey",currentDateInMillis);
var iterator = graniteWorkItem.getWorkflowData().getMetaDataMap().keySet().iterator();
while (iterator.hasNext()){
var key = iterator.next();
log.info("Workflow metadata key, value = " + key.toString() + ", " + graniteWorkItem.getWorkflowData().getMetaDataMap().get(key));
}
実行時のダイアログプロパティ値へのアクセス accessing-dialog-property-values-at-runtime
ワークフローインスタンスの MetaDataMap オブジェクトは、ワークフローの有効期間全体を通したデータの保存と取得に役立ちます。ワークフローステップコンポーネントの実装では、特に実行時のコンポーネントプロパティ値を取得するときに MetaDataMap が役立ちます。
ワークフローの MetaDataMap は、Java および ECMA スクリプトプロセス実装で次のように使用できます。
-
WorkflowProcess インターフェイスの Java 実装では、
argsパラメーターがワークフローのMetaDataMapオブジェクトです。 -
ECMA スクリプト実装では、
args変数とmetadata変数を使用して値を利用できます。
例:プロセスステップコンポーネントの引数の取得 example-retrieving-the-arguments-of-the-process-step-component
プロセスステップ コンポーネントの編集ダイアログには、Arguments プロパティが含まれます。 引数 プロパティの値はワークフローメタデータに保存され、PROCESS_ARGS キーと関連付けられます。
次の図では、引数 プロパティの値は argument1, argument2 です。
Java java-1
次の Java コードは、WorkflowProcess 実装の execute メソッドです。このメソッドは、PROCESS_ARGS キーと関連付けられている args MetaDataMap に値を記録します。
public void execute(WorkItem item, WorkflowSession session, MetaDataMap args) throws WorkflowException {
if (args.containsKey("PROCESS_ARGS")){
log.info("workflow metadata for key PROCESS_ARGS and value {}",args.get("PROCESS_ARGS","string").toString());
}
}
この Java 実装を使用するプロセスステップが実行されると、ログに次のエントリが記録されます。
16.02.2018 12:07:39.566 *INFO* [JobHandler: /var/workflow/instances/server0/2018-02-16/model_855140139900189:/content/we-retail/de] com.adobe.example.workflow.impl.process.LogArguments workflow metadata for key PROCESS_ARGS and value argument1, argument2
ECMA スクリプト ecma-script-1
次の ECMA スクリプトは、プロセスステップ のプロセスとして使用されます。このスクリプトは、引数の数と値を記録します。
var iterator = graniteWorkItem.getWorkflowData().getMetaDataMap().keySet().iterator();
while (iterator.hasNext()){
var key = iterator.next();
log.info("Workflow metadata key, value = " + key.toString() + ", " + graniteWorkItem.getWorkflowData().getMetaDataMap().get(key));
}
log.info("hardcodedKey "+ graniteWorkItem.getWorkflowData().getMetaDataMap().get("hardcodedKey"));
log.info("currentDateInMillisKey "+ graniteWorkItem.getWorkflowData().getMetaDataMap().get("currentDateInMillisKey"));
スクリプトとプロセスの引数 scripts-and-process-arguments
プロセスステップ コンポーネント用のスクリプト内で、引数は args オブジェクトを通して使用できます。
カスタムステップコンポーネントを作成するときには、スクリプト内で metaData オブジェクトを使用できます。このオブジェクトの使用は、単一の文字列引数に限定されます。
プロセスステップ実装の作成 developing-process-step-implementations
ワークフローのプロセスでプロセスステップが開始されると、そのステップは OSGi サービスにリクエストを送信するか、ECMA スクリプトを実行します。ワークフローで必要なアクションを実行するサービスまたは ECMA スクリプトを作成します。
Java クラスを使用したプロセスステップの実装 implementing-a-process-step-with-a-java-class
OSGI サービスコンポーネント(Java バンドル)としてプロセスステップを定義するには:
-
バンドルを作成して、OSGI コンテナにデプロイします。CRXDE Lite、または Eclipse を使用したバンドルの作成に関するドキュメントを参照してください。
note note NOTE OSGI コンポーネントでは、 WorkflowProcessインターフェイスをそのexecute()メソッドを使用して実装する必要があります。以下のコード例を参照してください。note note NOTE パッケージ名は、 maven-bundle-plugin設定の<*Private-Package*>セクションに追加する必要があります。 -
SCR プロパティ
process.labelを追加し、必要な値を設定してください。これは、汎用の プロセスステップ コンポーネントを使用するときに、プロセスステップがリストされる名前になります。下の例を参照してください。 -
モデル エディターで、汎用の プロセスステップ コンポーネントを使用して、プロセスステップをワークフローに追加します。
-
(プロセスステップ の)編集ダイアログで、プロセス タブに移動してから、プロセスの実装を選択してください。
-
コード内で引数を使用する場合は、プロセスの引数 を設定します。例:false。
-
ステップとワークフローモデルの両方に対する変更を保存します(モデルエディターの左上隅)。
Java メソッド(それぞれ実行可能な Java メソッドを実装するクラス)は、OSGi サービスとして登録され、実行時にいつでもメソッドを追加することができます。
次の OSGI コンポーネントは、ペイロードがページの場合、プロパティapprovedをページコンテンツノードに追加します。
package com.adobe.example.workflow.impl.process;
import com.adobe.granite.workflow.WorkflowException;
import com.adobe.granite.workflow.WorkflowSession;
import com.adobe.granite.workflow.exec.WorkItem;
import com.adobe.granite.workflow.exec.WorkflowData;
import com.adobe.granite.workflow.exec.WorkflowProcess;
import com.adobe.granite.workflow.metadata.MetaDataMap;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import org.osgi.framework.Constants;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
/**
* Sample workflow process that sets an <code>approve</code> property to the payload based on the process argument value.
*/
@Component
@Service
public class MyProcess implements WorkflowProcess {
@Property(value = "An example workflow process implementation.")
static final String DESCRIPTION = Constants.SERVICE_DESCRIPTION;
@Property(value = "Adobe")
static final String VENDOR = Constants.SERVICE_VENDOR;
@Property(value = "My Sample Workflow Process")
static final String LABEL="process.label";
private static final String TYPE_JCR_PATH = "JCR_PATH";
public void execute(WorkItem item, WorkflowSession session, MetaDataMap args) throws WorkflowException {
WorkflowData workflowData = item.getWorkflowData();
if (workflowData.getPayloadType().equals(TYPE_JCR_PATH)) {
String path = workflowData.getPayload().toString() + "/jcr:content";
try {
Session jcrSession = session.adaptTo(Session.class);
Node node = (Node) jcrSession.getItem(path);
if (node != null) {
node.setProperty("approved", readArgument(args));
jcrSession.save();
}
} catch (RepositoryException e) {
throw new WorkflowException(e.getMessage(), e);
}
}
}
private boolean readArgument(MetaDataMap args) {
String argument = args.get("PROCESS_ARGS", "false");
return argument.equalsIgnoreCase("true");
}
}
ECMAScript の使用 using-ecmascript
スクリプト開発者は、ECMA スクリプトを使用してプロセスステップを実装できます。スクリプトは JCR リポジトリに配置され、そこから実行されます。
スクリプトの処理にすぐに使用でき、ワークフロー Java API のオブジェクトへのアクセスを提供する変数を以下の表に示します。
com.adobe.granite.workflow.exec.WorkItemgraniteWorkItemcom.adobe.granite.workflow.WorkflowSessiongraniteWorkflowSessionString[](プロセス引数を含む)argscom.adobe.granite.workflow.metadata.MetaDataMapmetaDataorg.apache.sling.scripting.core.impl.InternalScriptHelpersling次のサンプルスクリプトは、ワークフローのペイロードを表す JCR ノードにアクセスする方法を示しています。graniteWorkflowSession変数を JCR セッション変数に適応させます。この変数を使用して、ペイロードパスからノードを取得します。
var workflowData = graniteWorkItem.getWorkflowData();
if (workflowData.getPayloadType() == "JCR_PATH") {
var path = workflowData.getPayload().toString();
var jcrsession = graniteWorkflowSession.adaptTo(Packages.javax.jcr.Session);
var node = jcrsession.getNode(path);
if (node.hasProperty("approved")){
node.setProperty("approved", args[0] == "true" ? true : false);
node.save();
}
}
次のスクリプトは、ペイロードが画像(.png ファイル)かどうかをチェックして、その画像から白黒の画像を作成し、兄弟ノードとして保存します。
var workflowData = graniteWorkItem.getWorkflowData();
if (workflowData.getPayloadType() == "JCR_PATH") {
var path = workflowData.getPayload().toString();
var jcrsession = graniteWorkflowSession.adaptTo(Packages.javax.jcr.Session);
var node = jcrsession.getRootNode().getNode(path.substring(1));
if (node.isNodeType("nt:file") && node.getProperty("jcr:content/jcr:mimeType").getString().indexOf("image/") == 0) {
var is = node.getProperty("jcr:content/jcr:data").getStream();
var layer = new Packages.com.day.image.Layer(is);
layer.grayscale();
var parent = node.getParent();
var gn = parent.addNode("grey" + node.getName(), "nt:file");
var content = gn.addNode("jcr:content", "nt:resource");
content.setProperty("jcr:mimeType","image/png");
var cal = Packages.java.util.Calendar.getInstance();
content.setProperty("jcr:lastModified",cal);
var f = Packages.java.io.File.createTempFile("test",".png");
var tout = new Packages.java.io.FileOutputStream(f);
layer.write("image/png", 1.0, tout);
var fis = new Packages.java.io.FileInputStream(f);
content.setProperty("jcr:data", fis);
parent.save();
tout.close();
fis.close();
is.close();
f.deleteOnExit();
}
}
スクリプトを使用するには:
-
(例えば、CRXDE Lite で)スクリプトを作成して、リポジトリ内の
//apps/workflow/scripts/の下に保存します。 -
プロセスステップ の編集ダイアログでスクリプトを識別するタイトルを指定するには、次のプロパティをスクリプトの
jcr:contentノードに追加します。table 0-row-3 1-row-3 2-row-3 名前 タイプ 値 jcr:mixinTypesName[]mix:titlejcr:titleString編集ダイアログに表示される名前。 -
プロセスステップ インスタンスを編集し、使用するスクリプトを指定します。
参加者選択の作成 developing-participant-choosers
動的参加者ステップ コンポーネント用の参加者選択を作成できます。
ワークフローの途中で 動的参加者ステップ が開始されると、生成された作業項目を割り当てることのできる参加者をステップが判断する必要があります。そのためには、ステップで次のいずれかを実行します。
- OSGi サービスにリクエストを送信
- 参加者を選択する ECMA スクリプトを実行
ワークフローの要件に従って参加者を選択するサービスまたは ECMA スクリプトを作成できます。
Java クラスを使用した参加者選択の作成 developing-a-participant-chooser-using-a-java-class
参加者ステップを OSGI サービスコンポーネント(Java クラス)として定義するには:
-
OSGI コンポーネントは、
getParticipant()メソッドを使用してParticipantStepChooserインターフェースを実装する必要があります。以下のコード例を参照してください。バンドルを作成して、OSGI コンテナにデプロイします。
-
SCR プロパティ
chooser.labelを追加し、必要に応じて値を設定します。これは、動的参加者ステップ コンポーネントを使用して、参加者選択に列挙される名前となります。次に例を示します。code language-java package com.adobe.example.workflow.impl.process; import com.adobe.granite.workflow.WorkflowException; import com.adobe.granite.workflow.WorkflowSession; import com.adobe.granite.workflow.exec.ParticipantStepChooser; import com.adobe.granite.workflow.exec.WorkItem; import com.adobe.granite.workflow.exec.WorkflowData; import com.adobe.granite.workflow.metadata.MetaDataMap; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Property; import org.apache.felix.scr.annotations.Service; import org.osgi.framework.Constants; /** * Sample dynamic participant step that determines the participant based on a path given as argument. */ @Component @Service public class MyDynamicParticipant implements ParticipantStepChooser { @Property(value = "An example implementation of a dynamic participant chooser.") static final String DESCRIPTION = Constants.SERVICE_DESCRIPTION; @Property(value = "Adobe") static final String VENDOR = Constants.SERVICE_VENDOR; @Property(value = "Dynamic Participant Chooser Process") static final String LABEL=ParticipantStepChooser.SERVICE_PROPERTY_LABEL; private static final String TYPE_JCR_PATH = "JCR_PATH"; public String getParticipant(WorkItem workItem, WorkflowSession workflowSession, MetaDataMap args) throws WorkflowException { WorkflowData workflowData = workItem.getWorkflowData(); if (workflowData.getPayloadType().equals(TYPE_JCR_PATH)) { String path = workflowData.getPayload().toString(); String pathFromArgument = args.get("PROCESS_ARGS", String.class); if (pathFromArgument != null && path.startsWith(pathFromArgument)) { return "admin"; } } return "administrators"; } } -
モデル エディターで、汎用の 動的参加者ステップ コンポーネントを使用して、動的参加者ステップをワークフローに追加します。
-
編集ダイアログで、参加者選択 タブを選択してから、選択の実装を選択してください。
-
コード内で引数を使用する場合は、プロセスの引数 を設定します。この例の場合は
/content/we-retail/deです。 -
ステップとワークフローモデルの両方に対する変更を保存します。
ECMA スクリプトを使用した参加者選択の開発 developing-a-participant-chooser-using-an-ecma-script
参加者ステップ で生成れた作業項目の割り当て先となるユーザーを選択する ECMA スクリプトを作成できます。スクリプトには、getParticipantという関数を含める必要があります。この関数は引数が不要で、ユーザーまたはグループの ID を格納したStringを返します。
スクリプトは JCR リポジトリに配置され、そこから実行されます。
以下の表に、スクリプト内のワークフロー Java オブジェクトに即座にアクセスできる変数を示します。
com.adobe.granite.workflow.exec.WorkItemgraniteWorkItemcom.adobe.granite.workflow.WorkflowSessiongraniteWorkflowSessionString[](プロセスの引数を格納)argscom.adobe.granite.workflow.metadata.MetaDataMapmetaDataorg.apache.sling.scripting.core.impl.InternalScriptHelperslingfunction getParticipant() {
var workflowData = graniteWorkItem.getWorkflowData();
if (workflowData.getPayloadType() == "JCR_PATH") {
var path = workflowData.getPayload().toString();
if (path.indexOf("/content/we-retail/de") == 0) {
return "admin";
} else {
return "administrators";
}
}
}
-
(例えば、CRXDE Lite で)スクリプトを作成して、リポジトリ内の
//apps/workflow/scriptsの下に保存します。 -
プロセスステップ の編集ダイアログでスクリプトを識別するタイトルを指定するには、次のプロパティをスクリプトの
jcr:contentノードに追加します。table 0-row-3 1-row-3 2-row-3 名前 タイプ 値 jcr:mixinTypesName[]mix:titlejcr:titleString編集ダイアログに表示される名前。 -
動的参加者ステップインスタンスを編集し、使用するスクリプトを指定してください。
ワークフローパッケージの処理 handling-workflow-packages
ワークフローパッケージをワークフローに渡して処理することができます。ワークフローパッケージには、ページやアセットなどのリソースへの参照が含まれています。
パッケージリソースを取得して処理するワークフローステップを作成できます。com.day.cq.workflow.collectionパッケージの以下の構成要素は、ワークフローパッケージへのアクセスを可能にします。
ResourceCollection:ワークフローパッケージクラスです。ResourceCollectionUtil:ResourceCollection オブジェクトの取得に使用されます。ResourceCollectionManager:コレクションを作成および取得します。実装は、OSGi サービスとしてデプロイされます。
次の Java クラスの例は、パッケージリソースの取得方法を示しています。
package com.adobe.example;
import java.util.ArrayList;
import java.util.List;
import com.day.cq.workflow.WorkflowException;
import com.day.cq.workflow.WorkflowSession;
import com.day.cq.workflow.collection.ResourceCollection;
import com.day.cq.workflow.collection.ResourceCollectionManager;
import com.day.cq.workflow.collection.ResourceCollectionUtil;
import com.day.cq.workflow.exec.WorkItem;
import com.day.cq.workflow.exec.WorkflowData;
import com.day.cq.workflow.exec.WorkflowProcess;
import com.day.cq.workflow.metadata.MetaDataMap;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import org.apache.felix.scr.annotations.Reference;
import org.osgi.framework.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
@Component
@Service
public class LaunchBulkActivate implements WorkflowProcess {
private static final Logger log = LoggerFactory.getLogger(LaunchBulkActivate.class);
@Property(value="Bulk Activate for Launches")
static final String PROCESS_NAME ="process.label";
@Property(value="A sample workflow process step to support Launches bulk activation of pages")
static final String SERVICE_DESCRIPTION = Constants.SERVICE_DESCRIPTION;
@Reference
private ResourceCollectionManager rcManager;
public void execute(WorkItem workItem, WorkflowSession workflowSession) throws Exception {
Session session = workflowSession.getSession();
WorkflowData data = workItem.getWorkflowData();
String path = null;
String type = data.getPayloadType();
if (type.equals(TYPE_JCR_PATH) && data.getPayload() != null) {
String payloadData = (String) data.getPayload();
if (session.itemExists(payloadData)) {
path = payloadData;
}
} else if (data.getPayload() != null && type.equals(TYPE_JCR_UUID)) {
Node node = session.getNodeByUUID((String) data.getPayload());
path = node.getPath();
}
// CUSTOMIZED CODE IF REQUIRED....
if (path != null) {
// check for resource collection
ResourceCollection rcCollection = ResourceCollectionUtil.getResourceCollection((Node)session.getItem(path), rcManager);
// get list of paths to replicate (no resource collection: size == 1
// otherwise size >= 1
List<String> paths = getPaths(path, rcCollection);
for (String aPath: paths) {
// CUSTOMIZED CODE....
}
} else {
log.warn("Cannot process because path is null for this " + "workitem: " + workItem.toString());
}
}
/**
* helper
*/
private List<String> getPaths(String path, ResourceCollection rcCollection) {
List<String> paths = new ArrayList<String>();
if (rcCollection == null) {
paths.add(path);
} else {
log.debug("ResourceCollection detected " + rcCollection.getPath());
// this is a resource collection. the collection itself is not
// replicated. only its members
try {
List<Node> members = rcCollection.list(new String[]{"cq:Page", "dam:Asset"});
for (Node member: members) {
String mPath = member.getPath();
paths.add(mPath);
}
} catch(RepositoryException re) {
log.error("Cannot build path list out of the resource collection " + rcCollection.getPath());
}
}
return paths;
}
}
例:カスタムステップの作成 example-creating-a-custom-step
独自のカスタムステップを作成する場合は、以下の場所から既存のステップをコピーする方法が簡単です。
/libs/cq/workflow/components/model
基本的なステップの作成 creating-the-basic-step
-
以下の例のように、/apps の下にパスを再作成します。
/apps/cq/workflow/components/model新しいフォルダーのタイプは
nt:folderです。code language-xml - apps - cq - workflow (nt:folder) - components (nt:folder) - model (nt:folder)note note NOTE このステップは、クラシック UI モデルエディターには適用されません。 -
次の例のように、コピーしたステップを /apps フォルダーに配置します。
/apps/cq/workflow/components/model/myCustomStepこの結果、カスタマイズしたステップの例を示すと次のようになります。
note caution CAUTION 標準 UI ではカードに表示されるのはタイトルのみで、説明は表示されないので、クラシック UI エディター用の details.jspは不要です。 -
このノードに次のプロパティを適用します。
/apps/cq/workflow/components/model/myCustomStep対象プロパティ:
-
sling:resourceSuperType既存のステップから継承する必要があります。
この例では、
cq/workflow/components/model/stepの基本ステップから継承していますが、participantやprocessなどの他のスーパータイプも使用できます。 -
jcr:titleコンポーネントがステップブラウザー(ワークフローモデルエディターの左側のパネル)に一覧表示されたときに表示されるタイトルです。
-
cq:iconステップの Coral アイコンを指定するために使用されます。
-
componentGroup次のいずれかを指定する必要があります。
- コラボレーションワークフロー
- DAM ワークフロー
- Forms のワークフロー
- プロジェクト
- WCM ワークフロー
- ワークフロー
-
-
以上でワークフローを開いて編集できるようになります。ステップブラウザーで、フィルターを適用して カスタムステップ を表示できます。
カスタムステップ をモデルにドラッグすると、カードが表示されます。
このステップで
cq:iconが定義されていない場合は、タイトルの最初の 2 文字を使用したデフォルトのアイコンが表示されます。例:
ステップ設定ダイアログの定義 defining-the-step-configure-dialog
基本ステップを作成した後に、次の手順に従ってステップの 設定 ダイアログを定義します。
-
ノード
cq:editConfigのプロパティを次のように設定します。対象プロパティ:
-
cq:inherittrueに設定すると、ステップコンポーネントはsling:resourceSuperTypeで指定したステップのプロパティを継承します。 -
cq:disableTargeting必要に応じて設定します。
-
-
ノード
cq:formsParameterのプロパティを次のように設定します。対象プロパティ:
-
jcr:titleモデルマップのステップカードと、カスタム - ステップのプロパティ 設定ダイアログの タイトル フィールドに、デフォルトのタイトルを設定します。
-
独自のカスタムプロパティも定義できます。
-
-
ノード
cq:listenersのプロパティを設定します。cq:listenerノードとそのプロパティを利用すると、ステップをモデルページにドラッグしたり、ステップのプロパティを編集したりして、タッチ操作対応 UI のモデルエディターでイベントに対処するイベントハンドラーを設定できます。対象プロパティ:
afterMove: REFRESH_PAGEafterdelete: CQ.workflow.flow.Step.afterDeleteafteredit: CQ.workflow.flow.Step.afterEditafterinsert: CQ.workflow.flow.Step.afterInsert
この設定は、エディターを適切に機能させるために必要です。ほとんどの場合、この設定は変更しないでください。
ただし、
cq:inheritを true に設定(上記のようにcq:editConfigノードで設定)するとこの設定を継承できるので、ステップの定義に明示的に含める必要はありません。継承されない場合は、次のプロパティと値を指定したこのノードを追加する必要があります。この例では継承が有効になっているので、
cq:listenersノードを削除できます。削除しても、ステップは正常に機能します。
-
これで、ステップのインスタンスをワークフローモデルに追加できます。ステップを 設定 する際は、次のダイアログが表示されます。
この例で使用するマークアップのサンプル sample-markup-used-in-this-example
カスタムステップのマークアップは、コンポーネントのルートノードの .content.xml で表現されます。この例で使用する .content.xml のサンプルは次のとおりです。
/apps/cq/workflow/components/model/myCustomStep/.content.xml
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="https://sling.apache.org/jcr/sling/1.0" xmlns:cq="https://www.day.com/jcr/cq/1.0" xmlns:jcr="https://www.jcp.org/jcr/1.0"
cq:icon="bell"
jcr:primaryType="cq:Component"
jcr:title="My Custom Step"
sling:resourceSuperType="cq/workflow/components/model/process"
allowedParents="[*/parsys]"
componentGroup="Workflow"/>
この例で使用する _cq_editConfig.xml のサンプルは次のとおりです。
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:cq="https://www.day.com/jcr/cq/1.0" xmlns:jcr="https://www.jcp.org/jcr/1.0" xmlns:nt="https://www.jcp.org/jcr/nt/1.0"
cq:disableTargeting="{Boolean}true"
cq:inherit="{Boolean}true"
jcr:primaryType="cq:EditConfig">
<cq:formParameters
jcr:primaryType="nt:unstructured"
jcr:title="My Custom Step Card"
SAMPLE_PROPERY="sample value"/>
<cq:listeners
jcr:primaryType="cq:EditListenersConfig"
afterdelete="CQ.workflow.flow.Step.afterDelete"
afteredit="CQ.workflow.flow.Step.afterEdit"
afterinsert="CQ.workflow.flow.Step.afterInsert"
afterMove="REFRESH_PAGE"/>
</jcr:root>
この例で使用する _cq_dialog/.content.xml のサンプルは次のとおりです。
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="https://sling.apache.org/jcr/sling/1.0" xmlns:cq="https://www.day.com/jcr/cq/1.0" xmlns:jcr="https://www.jcp.org/jcr/1.0" xmlns:nt="https://www.jcp.org/jcr/nt/1.0"
jcr:primaryType="nt:unstructured"
jcr:title="My Custom - Step Properties"
sling:resourceType="cq/gui/components/authoring/dialog">
<content
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/tabs">
<items jcr:primaryType="nt:unstructured">
<common
cq:hideOnEdit="true"
jcr:primaryType="nt:unstructured"
jcr:title="Common"
sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns"/>
<process
cq:hideOnEdit="true"
jcr:primaryType="nt:unstructured"
jcr:title="Process"
sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns"/>
<mycommon
jcr:primaryType="nt:unstructured"
jcr:title="Common"
sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns">
<items jcr:primaryType="nt:unstructured">
<columns
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<title
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
fieldLabel="Title"
name="./jcr:title"/>
<description
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textarea"
fieldLabel="Description"
name="./jcr:description"/>
</items>
</columns>
</items>
</mycommon>
<advanced
jcr:primaryType="nt:unstructured"
jcr:title="Advanced"
sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns">
<items jcr:primaryType="nt:unstructured">
<columns
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<email
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/checkbox"
fieldDescription="Notify user via email."
fieldLabel="Email"
name="./metaData/PROCESS_AUTO_ADVANCE"
text="Notify user via email."
value="true"/>
</items>
</columns>
</items>
</advanced>
</items>
</content>
</jcr:root>
sling:resourceSuperType : cq/workflow/components/model/process-
アップグレードしたダイアログが空の場合は、同様の機能を持つ
/libsのダイアログを解決策の例として参考にできます。例: -
/libs/cq/workflow/components/model -
/libs/cq/workflow/components/workflow -
/libs/dam/components -
/libs/wcm/workflow/components/autoassign -
/libs/cq/projects/libs内の設定は例として参考にするだけで、編集しないでください。既存のステップを使用する場合は、/appsにコピーし、そこで編集を加えます。