現在表示中:

このトピックでは、ワークフロー用のカスタムステップコンポーネントを作成する方法や、プログラムによってワークフローとやり取りする方法について説明します。

カスタムワークフローステップの作成では、次の作業をおこないます。

  • ワークフローステップコンポーネントを作成する
  • ステップ機能を OSGi サービスまたは ECMA スクリプトとして実装する 

ワークフローステップコンポーネント - 基本

ワークフローステップコンポーネントは、ワークフローモデルの作成時にステップの外観と動作を定義するものです。

  • ワークフローのサイドキックのカテゴリとステップ名
  • ワークフローモデルのステップの外観
  • コンポーネントのプロパティを設定する編集ダイアログ
  • 実行時に実行されるサービスまたはスクリプト

他のあらゆるコンポーネントと同様、ワークフローステップコンポーネントは、sling:resourceSuperType プロパティに指定されたコンポーネントから継承します。次の図は、すべてのワークフローステップコンポーネントの基礎を形成する cq:component ノードの階層を示しています。この図には、プロセスステップ参加者ステップおよび動的参加者ステップコンポーネントも含まれています。これらのコンポーネントは、カスタムステップコンポーネント作成の最も一般的で基本的な出発点になります。

chlimage_1

警告:

/libs パス内の設定は一切変更しないでください。

/libs のコンテンツは、インスタンスを次回アップグレードするとき(場合によってはホットフィックスまたは機能パックを適用したとき)に上書きされるからです。

設定およびその他の変更に推奨される方法は次のとおりです。

1. 必要な項目(/libs 内に存在)を、/apps の下に再作成します。
2. /apps 内で変更作業をおこないます。

/libs/cq/workflow/components/model/step コンポーネントは、プロセスステップ参加者ステップおよび動的参加者ステップコンポーネントの最も近い共通の上位です。これらのコンポーネントはすべて、次の項目を継承します。

  • step.jsp

    step.jsp スクリプトは、ステップコンポーネントがモデルに追加されると、そのタイトルと説明をレンダリングします。デフォルトのタイトルと説明は、それぞれ「タイトルを入力するにはダブルクリックします」と「説明を入力するにはダブルクリックします」です。

    chlimage_1
  • details.jsp

    details.jsp スクリプトは、モデルエディターでステップの下部に表示されるテキストをレンダリングします。デフォルトでは、詳細のテキストはありません。

  • ダイアログ

    ダイアログには次のタブがあります。

    • 共通:タイトルと説明の編集用です。
    • 詳細:電子メール通知プロパティの編集用です。
    chlimage_1
    chlimage_1

    注意:

    ステップコンポーネントの編集ダイアログのタブがこのデフォルトの外観と一致しない場合、ステップコンポーネントには、これらの継承されたタブをオーバーライドするスクリプト、ノードプロパティまたはダイアログタブが定義されています。

ECMA スクリプト

次のオブジェクトは(ステップタイプに応じて)ECMA スクリプト内で使用できます。

  • WorkItem 作業項目
  • WorkflowSession ワークフローセッション
  • WorkflowData ワークフローデータ
  • args:プロセスの引数を格納する配列
  • Sling:他の OSGi サービスへのアクセス用
  • jcrSession

MetaDataMap

ワークフローメタデータを使用すると、ワークフローの有効期間中に必要とされる情報を保持できます。ワークフローステップの一般的な要件は、そのワークフローで以降に使用するデータを保持したり、保持されているデータを取得することです。 

MetaDataMap オブジェクトには、Workflow オブジェクト、WorkflowData オブジェクトおよび WorkItem オブジェクトの 3 タイプがあります。いずれも、メタデータを保存するという同じ目的があります。

WorkItem には、作業項目(ステップなど)の実行中にのみ使用できる固有の MetaDataMap があります。

Workflow MetaDataMap と WorkflowData MetaDataMap は両方とも、ワークフロー全体で共有されます。このような場合は、WorkflowData MetaDataMap だけを使用することをお勧めします。

カスタムワークフローステップコンポーネントの作成

ワークフローステップコンポーネントは、その他のコンポーネントと同じ方法で作成できます。

注意:

ワークフローモデルエディターはクラシック UI でしか使用できません。そのため、ワークフローステップコンポーネントはクラシック UI 用に開発する必要があります。

(既存の)ベースステップコンポーネントのいずれかから継承するには、次のプロパティを cq:Component ノードに追加します。

  • 名前:sling:resourceSuperType
  • タイプ:String
  • 値:ベースコンポーネントに解決される次のパスのいずれか
    • cq/workflow/components/model/process
    • cq/workflow/components/model/participant
    • cq/workflow/components/model/dynamic_participant

ステップインスタンスのデフォルトのタイトルおよび説明の指定

ワークフローモデルエディターで、ステップのグラフィック表現には、ステップインスタンスと共に保存されるタイトルと説明が含まれます。タイトルと説明は、編集ダイアログの「共通」タブにある「タイトル」フィールドと「説明」フィールドから取得されます。ただし、インスタンスに「タイトル」または「説明」フィールドの値がない場合は、代わりに次のデフォルトテキストが表示されます。

  • タイトルを入力するにはダブルクリックします。
  • 説明を入力するにはダブルクリックします。
chlimage_1

共通」タブの「タイトル」フィールドと「説明」フィールドのデフォルト値を指定するには、以下の手順を実行します。

注意:

以下の要件が両方とも満たされる場合に、フィールド値がステップインスタンスに表示されます。

  • ステップの編集ダイアログが次の場所にタイトルと説明を保存している。
    • ./jcr:title
    • ./jcr:description
    この要件が満たされるのは、ステップの編集ダイアログが、/libs/cq/flow/components/step/step コンポーネントが実装する「共通」タブを使用しているときです。
  • ステップコンポーネントまたはそのコンポーネントの上位が、/libs/cq/flow/components/step/step コンポーネントが実装する step.jsp スクリプトをオーバーライドしていない。

  1. cq:Component ノードの下に、次のノードを追加します。

    • 名前:cq:editConfig
    • タイプ:cq:EditConfig

    注意:

    cq:editConfig ノードについて詳しくは、コンポーネントの編集動作の設定を参照してください。

  2. cq:EditConfig ノードの下に、次のノードを追加します。

    • 名前:cq:formParameters
    • タイプ:nt:unstructured
  3. 次の名前の String プロパティを cq:formParameters ノードに追加します。

    • jcr:title:この値が「共通」タブの「タイトル」フィールドに設定されます。
    • jcr:description:この値が「共通」タブの「説明」フィールドに設定されます。

ステップインスタンスの詳細情報の追加

ステップインスタンスをワークフローモデルに追加したときに表示される詳細情報を追加します。

注意:

この設定の例を確認するには、CRXDE Lite を使用して /libs/cq/workflow/components/model/process コンポーネントを参照してください。

注意:

以下の手順は、ステップコンポーネントまたはそのコンポーネントの上位が、/libs/cq/flow/components/step/step コンポーネントが実装する step.jsp スクリプトをオーバーライドしていないことが前提となります。

  1. 次のノードを cq:Component ノードの下に追加します。

    • 名前:details.jsp
    • タイプ:nt:file
  2. details.jsp ファイルを編集し、詳細情報を HTML コードとして生成するようにします。

ワークフローメタデータにプロパティ値を保存

注意:

データの保持とアクセスを参照してください。特に、実行時のプロパティ値へのアクセスについては、実行時のダイアログプロパティ値へのアクセスを参照してください。

cq:Widget 項目の name プロパティで、ウィジェットの値を保存する JCR ノードを指定します。ワークフローステップコンポーネントのダイアログのウィジェットが ./metaData ノードの下に値を保存すると、その値がワークフローの MetaDataMap に追加されます。

例えば、ダイアログのテキストフィールドは、次のプロパティを持つ cq:Widget ノードです。

名前 タイプ
xtype String textarea
name String ./metaData/subject
fieldLabel String Email Subject

このテキストフィールドに指定された値がワークフローインスタンスの MetaDataMap オブジェクトに追加され、subject キーに関連付けられます。

注意:

キーが PROCESS_ARGS の場合、この値は args 変数を使用して ECMA スクリプト実装ですぐに使用できます。この場合、name プロパティの値は ./metaData/PROCESS_ARGS になります。

ステップ実装のオーバーライド

ワークフローモデルの開発者は、デザイン時に、ベースステップコンポーネントごとに次の主要機能を設定できます。

  • プロセスステップ:実行時に実行されるサービスまたは ECMA スクリプト。 
  • 参加者ステップ:生成された作業項目を割り当てるユーザーの ID。 
  • 動的参加者ステップ:作業項目を割り当てるユーザーの ID を選択するサービスまたは ECMA スクリプト。

コンポーネントを特定のワークフローシナリオ専用にするために、デザイン時に設定した主要機能をモデル開発者が変更できないようにします。

  1. cq:Component ノードの下に、次のノードを追加します。

    • 名前:cq:editConfig
    • タイプ:cq:EditConfig

    cq:editConfig ノードについて詳しくは、コンポーネントの編集動作の設定を参照してください。

  2. cq:EditConfig ノードの下に、次のノードを追加します。

    • 名前:cq:formParameters
    • タイプ:nt:unstructured
  3. cq:formParameters ノードに String プロパティを追加します。コンポーネントのスーパータイプによって、プロパティの名前が次のように決定されます。

    • プロセスステップ:PROCESS
    • 参加者ステップ:PARTICIPANT
    • 動的参加者ステップ:DYNAMIC_PARTICIPANT
  4. プロパティの値を次のように指定します。

    • PROCESS:ステップの動作を実装する ECMA スクリプトへのパスまたはサービスの PID。
    • PARTICIPANT:作業項目を割り当てるユーザーの ID。
    • DYNAMIC_PARTICIPANT:作業項目を割り当てるユーザーを選択する ECMA スクリプトへのパスまたはサービスの PID。
  5. モデル開発者がプロパティ値を変更できないようにするために、コンポーネントのスーパータイプのダイアログをオーバーライドします。編集ダイアログのオーバーライドで説明しているように、コンポーネントのダイアログを定義します。

フォームとダイアログを参加者ステップに追加

参加者ステップコンポーネントをカスタマイズして、次に示すフォーム参加者ステップコンポーネントとダイアログ参加者ステップコンポーネントの機能を提供するようにします。

  • 生成された作業項目を開いたときに、フォームを表示する 
  • 生成された作業項目を完了したときに、カスタムダイアログを表示する

新しいコンポーネントに対して、以下の手順を実行します(カスタムワークフローステップコンポーネントの作成を参照)。

  1. cq:Component ノードの下に、次のノードを追加します。

    • 名前:cq:editConfig
    • タイプ:cq:EditConfig

    cq:editConfig ノードについて詳しくは、コンポーネントの編集動作の設定を参照してください。

  2. cq:EditConfig ノードの下に、次のノードを追加します。

    • 名前:cq:formParameters
    • タイプ:nt:unstructured
  3. 作業項目を開くとフォームが表示されるようにするには、次のプロパティを cq:formParameters ノードに追加します。

    • 名前:FORM_PATH
    • タイプ:String
    • 値:フォームに解決されるパス
  4. 作業項目を完了するとカスタムダイアログが表示されるようにするには、次のプロパティを cq:formParameters ノードに追加します。

    • 名前:DIALOG_PATH
    • タイプ:String
    • 値:ダイアログに解決されるパス

ワークフローステップの実行時の動作の設定

cq:Component ノードの下に、cq:EditConfig ノードを追加します。その下に、nt:unstructured ノードを(必ず cq:formParameters という名前で)追加し、そのノードに次のプロパティを追加します。

  • 名前:PROCESS_AUTO_ADVANCE 
  • タイプ:Boolean
  • 値: 
    • true に設定した場合、ワークフローはそのステップを実行して続行します。これはデフォルト値であり、推奨もされています。
    • false に設定した場合、ワークフローはそのステップを実行して停止します。これには追加の処理が必要なので、true に設定することをお勧めします。

 

  • 名前:DO_NOTIFY
  • タイプ:Boolean
  • 値:ユーザー参加ステップについて電子メール通知を送信するかどうかを示します(メールサーバーが正しく設定されていると想定しています)。

データの保持とアクセス

後続のワークフローステップのためのデータ保持

ワークフローメタデータを使用して、ワークフローの有効期間中およびステップの間で必要とされる情報を保持できます。ワークフローステップの一般的な要件は、以降に使用するデータを保持したり、以前のステップから保持されているデータを取得したりすることです。 

ワークフローメタデータは、MetaDataMap オブジェクトに保存されます。Java API が提供する Workflow.getWorkflowData メソッドは、適切な MetaDataMap オブジェクトを提供する WorkflowData オブジェクトを返します。この WorkflowData MetaDataMap オブジェクトは、ステップコンポーネントの OSGi サービスまたは ECMA スクリプトで使用できます。

Java

WorkflowProcess 実装の execute メソッドは、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 スクリプト

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));
}

実行時のダイアログプロパティ値へのアクセス

ワークフローインスタンスの MetaDataMap オブジェクトは、ワークフローの有効期間全体を通じてデータを保存および取得する場合に役立ちます。ワークフローステップコンポーネントの実装では、特に実行時のコンポーネントプロパティ値を取得するときに MetaDataMap が役立ちます。

注意:

プロパティをワークフローメタデータとして保存するコンポーネントダイアログの設定については、ワークフローメタデータへのプロパティ値の保存を参照してください。

ワークフローの MetaDataMap は、Java および ECMA スクリプトプロセス実装で次のように使用できます。

  • WorkflowProcess インターフェイスの Java 実装では、args パラメーターがワークフローの MetaDataMap オブジェクトです。
  • ECMA スクリプト実装では、args 変数と metadata 変数を使用して値を利用できます。

例:プロセスステップコンポーネントの引数の取得

プロセスステップコンポーネントの編集ダイアログには、Arguments プロパティが含まれます。Arguments プロパティの値はワークフローメタデータに保存され、PROCESS_ARGS キーと関連付けられます。

次の図では、Arguments プロパティの値は argument1, argument2 です。

Java

次の 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.2017 12:07:39.566 *INFO* [JobHandler: /etc/workflow/instances/2017-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 スクリプトは、プロセスステップのプロセスとして使用されます。このスクリプトは、引数の数と値を記録します。

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"));

注意:

この節では、プロセスステップの引数の使用方法について説明します。この情報は、動的参加者選択にも適用されます。

 

注意:

ワークフローメタデータにコンポーネントのプロパティを保存するもう 1 つの例については、例:ロガーワークフローステップの作成を参照してください。この例では、メタデータ値を PROCESS_ARGS 以外のキーと関連付けるダイアログについて説明しています。

スクリプトとプロセスの引数

プロセスステップコンポーネント用のスクリプト内で、引数は args オブジェクトを通して使用できます。

カスタムステップコンポーネントを作成するときには、スクリプト内で metaData オブジェクトを使用できます。このオブジェクトの使用は、単一の文字列引数に限定されます。

プロセスステップ実装の作成

ワークフローのプロセスでプロセスステップが開始されると、そのステップは OSGi サービスにリクエストを送信するか、ECMA スクリプトを実行します。そのため、ワークフローに必要なアクションを実行するサービスまたは ECMA スクリプトを作成します。

注意:

プロセスステップコンポーネントとサービスまたはスクリプトの関連付けについては、プロセスステップまたはステップ実装のオーバーライドを参照してください。

Java クラスを使用したプロセスステップの実装

OSGI サービスコンポーネント(Java バンドル)としてプロセスステップを定義する

  1. バンドルを作成して、OSGI コンテナにデプロイします。CRXDE Lite または Eclipse を使用したバンドルの作成に関するドキュメントを参照してください。

    注意:

    OSGI コンポーネントでは、WorkflowProcess インターフェイスをその execute() メソッドを使用して実装する必要があります。以下のコード例を参照してください。

    注意:

    パッケージ名を maven-bundle-plugin 設定の <Private-Package> セクションに追加する必要があります。

  2. SCR プロパティ process.label を追加し、必要な値を設定します。これは、汎用のプロセスステップコンポーネントを使用するときに列挙されるプロセスステップの名前となります。下の例を参照してください。

  3. モデルエディターで、汎用のプロセスステップコンポーネントを使用して、プロセスステップをワークフローに追加します。

  4. プロセスステップの)編集ダイアログで、「プロセス」タブに移動して、プロセスの実装を選択します。

  5. コード内で引数を使用する場合は、プロセスの引数を設定します。例えば、false を設定します。

  6. ステップとワークフローモデルの両方に対する変更を保存します(モデルエディターの左上隅)。

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");
	}
}

注意:

プロセスが連続して 3 回失敗した場合は、ワークフロー管理者のインボックスに 1 つのアイテムが配置されます。

ECMAScript の使用

スクリプト開発者は、ECMA スクリプトを使用してプロセスステップを実装できます。スクリプトは JCR リポジトリ内に配置され、そこから実行されます。

スクリプトの処理にすぐに使用でき、ワークフロー Java API のオブジェクトへのアクセスを提供する変数を以下の表に示します。

Java クラス スクリプト変数名 説明
com.adobe.granite.workflow.exec.WorkItem graniteWorkItem 現在のステップインスタンス。
com.adobe.granite.workflow.WorkflowSession graniteWorkflowSession 現在のステップインスタンスのワークフローセッション。
String[] (プロセスの引数を格納) args ステップの引数。
com.adobe.granite.workflow.metadata.MetaDataMap metaData 現在のステップインスタンスのメタデータ。
org.apache.sling.scripting.core.impl.InternalScriptHelper sling Sling ランタイム環境へのアクセスを可能にします。

次のサンプルスクリプトは、ワークフローのペイロードを表す 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();
    }
}

スクリプトを使用するには:

  1. (例えば、CRXDE Lite で)スクリプトを作成して、リポジトリ内の /etc/workflow/scripts の下に保存します。

  2. プロセスステップの編集ダイアログでスクリプトを識別するタイトルを指定するには、次のプロパティをスクリプトの jcr:content ノードに追加します。

    名前 タイプ
    jcr:mixinTypes Name[] mix:title
    jcr:title String 編集ダイアログに表示される名前。
  3. プロセスステップインスタンスを編集し、使用するスクリプトを指定します。

参加者選択の作成

動的参加者ステップコンポーネント用の参加者選択を作成できます。

ワークフローの途中で動的参加者ステップが開始されると、生成された作業項目を割り当てることのできる参加者をステップが判断する必要があります。そのためには、ステップで次のいずれかを実行します。

  • OSGi サービスにリクエストを送信する
  • 参加者を選択する ECMA スクリプトを実行する

ワークフローの要件に応じて参加者を選択するサービスまたは ECMA スクリプトを作成できます。

注意:

動的参加者ステップコンポーネントとサービスまたはスクリプトの関連付けについては、動的参加者ステップまたはステップ実装のオーバーライドを参照してください。

Java クラスを使用した参加者選択の作成

参加者ステップを OSGI サービスコンポーネント(Java クラス)として定義する

  1. OSGI コンポーネントでは、ParticipantStepChooser インターフェイスをその getParticipant() メソッドを使用して実装する必要があります。以下のコード例を参照してください。

    バンドルを作成して、OSGI コンテナにデプロイします。

  2. SCR プロパティ chooser.label を追加し、必要に応じて値を設定します。これは、動的参加者ステップコンポーネントを使用して、参加者選択に列挙される名前となります。次に例を示します。

    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";
        }
    }
  3. モデルエディターで、汎用の動的参加者ステップコンポーネントを使用して、動的参加者ステップをワークフローに追加します。

  4. 編集ダイアログで、「参加者選択」タブを選択し、選択の実装を選択します。

  5. コード内で引数を使用する場合は、プロセスの引数を設定します。この例の場合、/content/we-retail/de を設定します。

  6. ステップとワークフローモデルの両方に対する変更を保存します。

ECMA スクリプトを使用した参加者選択の作成

参加者ステップで生成される作業項目を割り当てるユーザーを選択する ECMA スクリプトを作成できます。スクリプトには、getParticipant という関数を含める必要があります。この関数は引数が不要で、ユーザーまたはグループの ID を格納した String を返します。

スクリプトは JCR リポジトリ内に配置され、そこから実行されます。

スクリプト内のワークフロー Java オブジェクトにすぐにアクセスできる変数を以下の表に示します。

Java クラス スクリプト変数名
com.adobe.granite.workflow.exec.WorkItem graniteWorkItem
com.adobe.granite.workflow.WorkflowSession graniteWorkflowSession
String[](プロセスの引数を格納) args
com.adobe.granite.workflow.metadata.MetaDataMap metaData
org.apache.sling.scripting.core.impl.InternalScriptHelper sling
function 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";
        }
    }
}
  1. (例えば、CRXDE Lite で)スクリプトを作成して、リポジトリ内の /etc/workflow/scripts の下に保存します。

  2. プロセスステップの編集ダイアログでスクリプトを識別するタイトルを指定するには、次のプロパティをスクリプトの jcr:content ノードに追加します。

    名前 タイプ
    jcr:mixinTypes Name[] mix:title
    jcr:title String 編集ダイアログに表示される名前。
  3. 動的参加者ステップインスタンスを編集し、使用するスクリプトを指定します。

ワークフローパッケージの処理

ワークフローパッケージをワークフローに渡して処理することができます。ワークフローパッケージには、ページやアセットなどのリソースへの参照が含まれます。

注意:

次のワークフロープロセスステップは、一括ページアクティベーション用のワークフローパッケージを受け入れます。

パッケージリソースを取得して処理するワークフローステップを作成できます。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;
}
}

例:ロガーワークフローステップの作成

以下の手順では、ワークフローに関連する情報を AEM ログに送信するサンプルワークフローステップを作成します。一般的に、カスタムステップコンポーネントを作成するには、操作なしステップコンポーネントのコピーを作成する方法が最も簡単です。操作なしステップコンポーネントには、編集ダイアログ、プロセスの引数、フォームと共にプロセスを使用するためのパラメーターを定義するノードが含まれます。このコンポーネントをコピーしてから、UI に表示されるいくつかのタイトルおよび説明のプロパティを変更し、ステップの動作を実装するクラスを指定する必要があります。

ステップコンポーネントの作成

モデル作成者が 2 つのプロセス引数を設定できるようにするカスタムステップコンポーネントを作成します。操作なしコンポーネントをアプリケーションにコピーして、ノードプロパティを変更します。

  1. CRXDE Lite を使用して、/content/apps フォルダーの下に mycompany という名前のフォルダーを作成します。続けて次のパスのフォルダーを作成します。

    /content/apps/mycompany/components/workflow

  2. /libs/cq/workflow/components/workflow/noopprocess にある noopprocess を /apps/mycompany/components/workflow フォルダーにコピーします。ノードの名前を「loggerprocess」に変更します。

  3. /apps/mycompany/components/workflow/loggerprocess ノードの次のプロパティを変更します。

    • jcr:titleLogger
    • jcr:description:ワークフロー情報をログファイルに書き込みます。

    これらのプロパティによって、モデルエディターのサイドキックでステップコンポーネントを識別します。

  4. loggerprocess/cq:editConfig/cq:formParameters ノードを選択して、次のプロパティ値を変更します。

    • jcr:titleLogger Process
    • jcr:description:ワークフローの値をログに記録します。
    • PROCESScom.adobe.example.workflow.impl.process.LoggerProcess

    これらのプロパティによって、フォームと共に使用する場合にワークフローコンポーネントと実装を識別します。

  5. loggerprocess/dialog ノードを選択して、title プロパティの値を Logger Process - Step Properties に変更します。

    dialog ノードがこのコンポーネントの編集ダイアログを定義します。

  6. loggerprocess/dialog/items/tabs/items/processargs ノードを選択して、path プロパティの値を次の値に変更します。

    /apps/mycompany/components/workflow/loggerprocess/processargs.infinity.json

    loggerprocess/processargs ノードの下に定義されるウィジェットがダイアログに表示されます。

  7. 引数ウィジェットをコンポーネントに追加するには、/apps/mycompany/components/workflow/loggerprocess/processargs/items/arguments/items ノードの下にタイプ cq:Widget のノードを 2 つ追加します。次のノード名を使用してください。

    • singlearg
    • multiarg
  8. 次のプロパティを singlearg ノードに追加します。

    名前 タイプ
    xtype String textfield
    name String ./metaData/argSingle
    fieldLabel String 単一の引数
  9. 次のプロパティを multiarg ノードに追加します。

    名前 タイプ
    xtype String multifield
    name String ./metaData/argMulti
    fieldLabel String 複数の引数

Logger Process コンポーネントがモデルエディターのサイドキックに追加されます。

Logger Process ステップコンポーネントの編集ダイアログには、singlearg ノードと multiarg ノードが定義するウィジェットが含まれます。

screen_shot_2012-02-01at20808pm

ステップ実装の作成

com.adobe.example.workflow.impl.process.LoggerProcess 実装を作成します。これは、loggerprocess/cq:editConfig/cq:formParameters ノードの PROCESS プロパティ用に指定したクラスです。

注意:

Multimodule-content-package-archetype アーキタイプを使用して Maven プロジェクトを作成します。コンテンツパッケージをインストールするには、次のコマンドを使用します。

mvn clean install -P autoInstallPackage

Java ベースのプロセスステップの作成について詳しくは、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.WorkItem;
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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import java.util.Arrays;
 
/**
 * Sample workflow process that logs arguments into the logfile.
 */
@Component
@Service

public class LoggerProcess implements WorkflowProcess {
 
	@Property(value = "Logger process implementation.")
	static final String DESCRIPTION = Constants.SERVICE_DESCRIPTION; 
    @Property(value = "Adobe")
    static final String VENDOR = Constants.SERVICE_VENDOR;
    @Property(value = "Logger Process")
    static final String LABEL="process.label";
	
	
   private static final Logger log = LoggerFactory.getLogger(LoggerProcess.class);
 
    public void execute(WorkItem item, WorkflowSession session, MetaDataMap args) throws WorkflowException {
        String singleValue = args.get("argSingle", "not set");
        String[] multiValue = args.get("argMulti", new String[]{"not set"});
 
        log.info("-- Workflow Paramter - Single Value: {}", singleValue);
        log.info("-- Workflow Paramter - Multi Value: {}", Arrays.toString(multiValue));
    }
}

LoggerProcess Maven の依存関係

Multimodule-content-package-archetype アーキタイプを使用して Maven プロジェクトを作成する場合、LoggerProcess クラスをサポートするには、次の依存関係を pom.xml ファイルに追加する必要があります。

警告:

以下は単なる例です。使用する前に、インスタンスに必要なバージョンを確認してください。次のように、Web コンソールを使用して確認できます。

http://localhost:4502/system/console/depfinder

  • <dependency>
    	<groupId>com.adobe.granite</groupId>
    	<artifactId>com.adobe.granite.workflow.api</artifactId>
    	<version>1.0.0</version>
    	<scope>provided</scope>
    </dependency>
    <dependency>
    	<groupId>org.apache.sling</groupId>
    	<artifactId>org.apache.sling.jcr.jcr-wrapper</artifactId>
    	<version>2.0.0</version>
    	<scope>provided</scope>
    </dependency>
  • また、slf4j-api アーティファクトの依存関係が正しいことを確認します。


本作品は Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License によってライセンス許可を受けています。  Twitter™ および Facebook の投稿には、Creative Commons の規約内容は適用されません。

法律上の注意   |   プライバシーポリシー