Cloud Software Group, Inc. EBX®
ドキュメント>開発者ガイド
ナビゲーションモードドキュメント>開発者ガイド

ワークフローモデル

ワークフローには、「ライブラリ」または「特定」の2種類のステップがあります。

「ライブラリ」は module.xml で定義されている Bean であり、再利用できます。'library' Bean を使用すると、人間工学が向上します。パラメーターは定義画面に動的に表示されます。

「特定の」オブジェクトは、そのクラス名によってのみ定義されるBeanです。この場合、表示は動的ではありません。

Beanカテゴリ

ステップ

ライブラリ

スペシフィック

スクリプト

ScriptTaskBean

ScriptTask

条件

ConditionBean

Condition

ユーザータスク

UserTask

ScriptTaskの例

Javaコード

次の例のように、スクリプトタスクはメソッドexecuteをオーバーライドする必要があります。

public class NppScriptTask_CreateWorkingBranch extends ScriptTask
{
    public void executeScript(ScriptTaskContext aContext) throws OperationException
    {
        Repository repository = aContext.getRepository();
        String initialBranchString = aContext.getVariableString("initialBranch");
        AdaptationHome initialBranch = repository.lookupHome(HomeKey.forBranchName(initialBranchString));
        if (initialBranch == null)
            throw OperationException.createError("Null value for initialBranch");

        HomeCreationSpec spec = new HomeCreationSpec();
        spec.setParent(initialBranch);
        spec.setKey(HomeKey.forBranchName("Name"));
        spec.setOwner(Profile.EVERYONE);
        spec.setHomeToCopyPermissionsFrom(initialBranch);
        AdaptationHome newHome = repository.createHome(spec, aContext.getSession());
                //feeds dataContext
        aContext.setVariableString("workingBranch", newHome.getKey().getName());
    }
}
以下も参照してください。

ScriptTaskBeanの例

Javaコード

スクリプトタスクBeanは、次の例のように、メソッドexecuteScriptをオーバーライドする必要があります。

public class ScriptTaskBean_CreateBranch extends ScriptTaskBean
{
    private String initialBranchName;

    private String newBranch;

    public String getInitialBranchName()
    {
        return this.initialBranchName;
    }

    public void setInitialBranchName(String initialBranchName)
    {
        this.initialBranchName = initialBranchName;
    }

    public String getNewBranch()
    {
        return this.newBranch;
    }

    public void setNewBranch(String newBranch)
    {
        this.newBranch = newBranch;
    }

    public void executeScript(ScriptTaskBeanContext aContext) throws OperationException
    {
        final Repository repository = aContext.getRepository();

        String initialBranchName = this.getInitialBranchName();
        final AdaptationHome initialBranch = repository.lookupHome(HomeKey.forBranchName(initialBranchName));
        final HomeCreationSpec spec = new HomeCreationSpec();
        spec.setParent(initialBranch);
        spec.setKey(HomeKey.forBranchName(XsFormats.SINGLETON.formatDateTime(new Date())));
        spec.setOwner(Profile.EVERYONE);
        spec.setHomeToCopyPermissionsFrom(initialBranch);
        final AdaptationHome branchCreate = repository.createHome(spec, aContext.getSession());
        this.setNewBranch(branchCreate.getKey().getName());
    }
}
以下も参照してください。

module.xmlによる構成

スクリプトタスクBeanは、module.xmlで宣言する必要があります。

<module>
    <beans>
        <bean className="com.orchestranetworks.workflow.genericScriptTask.ScriptTaskBean_CreateBranch">
            <documentation xml:lang="fr-FR">
                <label>Créer une branche</label>
                <description>
                    Ce script permet de créer une branche
                </description>
            </documentation>
            <documentation xml:lang="en-US">
                <label>Create a branch</label>
                <description>
                    This script creates a branch
                </description>
            </documentation>
            <properties>
                <property name="initialBranchName" input="true">
                    <documentation xml:lang="fr-FR">
                        <label>Branche initiale</label>
                        <description>
                            Nom de la branche initiale.
                        </description>
                    </documentation>
                    <documentation xml:lang="en-US">
                        <label>Initial branch</label>
                        <description>
                            Initial branch name.
                        </description>
                    </documentation>
                </property>
                <property name="newBranch" output="true">
                    <documentation xml:lang="fr-FR">
                        <label>Nouvelle branche</label>
                        <description>
                            Nom de la branche créée
                        </description>
                    </documentation>
                    <documentation xml:lang="en-US">
                        <label>New branch</label>
                        <description>
                            Created branch name.
                        </description>
                    </documentation>
                </property>
            </properties>
        </bean>
    </beans>
</module>

UserTaskの例

module.xmlによるサービス宣言

ビルトインサービスを module.xml で宣言し、ユーザータスクの定義で使用することができます。

 <services>
 	<service name="ServiceModule">
	    <resourcePath>/service.jsp</resourcePath>
	    <type>branch</type>
       	<documentation xml:lang="fr-FR">
           	<label>Workflow service</label>
               <description>
               	Ce service permet de ...
               </description>
		</documentation>
           <documentation xml:lang="en-US">
           	<label>Service workflow</label>
               <description>
               	The purpose of this service is ...
               </description>
		</documentation>
           <properties>
         		<property name="param1" input="true">
                <documentation xml:lang="fr-FR">
                    <label>Param1</label>
                    <description>Param1 ...</description>
                </documentation>
           </property>
           <property name="param2" output="true">
           </property>
       </properties>
	</service>
    <serviceLink serviceName="adaptationService">
        <importFromSchema>
            /WEB-INF/ebx/schema/schema.xsd
        </importFromSchema>
    </serviceLink>
</services>

より複雑なUserTask

GUIは上記の例と非常によく似ています。「UserTask」を拡張して呼び出すクラスを定義するには、フィールド「Rule」に入力する必要があります。

public class NppUserTask_ValidateProduct extends UserTask
{
    public void handleWorkItemCompletion(UserTaskWorkItemCompletionContext context)
        throws OperationException
    {
        if (context.getCompletedWorkItem().isRejected())
        {
            context.setVariableString(NppConstants.VAR_VALIDATION, "KO");
            context.completeUserTask();
        }
        else if (context.checkAllWorkItemMatchStrategy())
        {
            context.setVariableString(NppConstants.VAR_VALIDATION, "OK");
            context.completeUserTask();
        }
    }

    public void handleCreate(UserTaskCreationContext context) throws OperationException
    {
        CreationWorkItemSpec spec = CreationWorkItemSpec.forOfferring(NppConstants.ROLE_PVALIDATOR);
        spec.setNotificationMail("1");
        context.createWorkItem(spec);
        context.setVariableString(NppConstants.VAR_VALIDATION, "validating");
    }
}
以下も参照してください。

条件の例

Javaコード

メソッドevaluateはオーバーライドする必要があります。

public class NppCondition_IsValidationOK extends Condition
{
    public boolean evaluateCondition(ConditionContext context) throws OperationException
    {
        String validation = context.getVariableString("validationResult");
        boolean hasError = "KO".equals(validation);
        return !hasError;
    }
}
以下も参照してください。

ConditionBeanの例

Javaコード

次の例のように、メソッドEvaluationConditionをオーバーライドする必要があります。

public class ConditionBean_IsBranchValid extends ConditionBean
{
    private String branchName;

    public String getBranchName()
    {
        return this.branchName;
    }

    public void setBranchName(String branchName)
    {
        this.branchName = branchName;
    }

    public boolean evaluateCondition(ConditionBeanContext aContext) throws OperationException
    {
        final Repository repository = aContext.getRepository();
        Severity severityForValidation = Severity.ERROR;
        String branchToTestName = this.getBranchName();
        final AdaptationHome branchToTest = repository.lookupHome(HomeKey.forBranchName(branchToTestName));
        if (branchToTest.getValidationReportsMap(severityForValidation) != null
            && branchToTest.getValidationReportsMap(severityForValidation).size() > 0)
        {
            return false;
        }
        return true;
    }
}
以下も参照してください。

module.xmlによる構成

条件Beanは、module.xmlで宣言する必要があります。

<module>
    <beans>
        <bean className="com.orchestranetworks.workflow.genericScriptTask.ConditionBean_IsBranchValid">
            <documentation xml:lang="fr-FR">
                <label>Branche valide ?</label>
                <description>
                    Ce script permet de tester si une branche est valide.
                </description>
            </documentation>
            <documentation xml:lang="en-US">
                <label>Branch valid ?</label>
                <description>
                    This script allows to check if a branch is valid.
                </description>
            </documentation>
            <properties>
                <property name="branchName" input="true">
                    <documentation xml:lang="fr-FR">
                        <label>Branche à contrôler</label>
                        <description>
                            Nom de la branche à valider.
                        </description>
                    </documentation>
                    <documentation xml:lang="en-US">
                        <label>Branch to check</label>
                        <description>
                            Branch name to check.
                        </description>
                    </documentation>
                </property>
            </properties>
        </bean>
    </beans>
</module>

SubWorkflowsInvocationBeanの例

Javaコード

public class MySubWorkflowsInvocationBean extends SubWorkflowsInvocationBean
{
	@Override
	public void handleCreateSubWorkflows(SubWorkflowsCreationContext aContext)
		throws OperationException
	{
		final ProcessLauncher subWorkflow1 = aContext.registerSubWorkflow(
			AdaptationName.forName("validateProduct"),
			"validateProduct1");
		subWorkflow1.setLabel(UserMessage.createInfo("Validate the new product by marketing"));
		subWorkflow1.setInputParameter("workingBranch", aContext.getVariableString("workingBranch"));
		subWorkflow1.setInputParameter("code", aContext.getVariableString("code"));
		subWorkflow1.setInputParameter("service", aContext.getVariableString("marketing"));

		final ProcessLauncher subWorkflow2 = aContext.registerSubWorkflow(
			AdaptationName.forName("validateProduct"),
			"validateProduct2");
		subWorkflow2.setLabel(UserMessage.createInfo("Validate the new product by direction"));
		subWorkflow2.setInputParameter("workingBranch", aContext.getVariableString("workingBranch"));
		subWorkflow2.setInputParameter("code", aContext.getVariableString("code"));
		subWorkflow2.setInputParameter("service", aContext.getVariableString("direction"));

		// Conditional launching.
		if (aContext.getVariableString("productType").equals("book"))
		{
			final ProcessLauncher subWorkflow3 = aContext.registerSubWorkflow(
				AdaptationName.forName("generateISBN"),
				"generateISBN");
			subWorkflow3.setLabel(UserMessage.createInfo("Generate ISBN"));
			subWorkflow3.setInputParameter(
				"workingBranch",
				aContext.getVariableString("workingBranch"));
			subWorkflow3.setInputParameter("code", aContext.getVariableString("code"));
		}

		aContext.launchSubWorkflows();
	}
	@Override
	public void handleCompleteAllSubWorkflows(SubWorkflowsCompletionContext aContext)
		throws OperationException
	{
		aContext.getCompletedSubWorkflows();
		final ProcessInstance validateProductMarketing = aContext.getCompletedSubWorkflow("validateProduct1");
		final ProcessInstance validateProductDirection = aContext.getCompletedSubWorkflow("validateProduct2");
		if (aContext.getVariableString("productType").equals("book"))
		{
			final ProcessInstance generateISBN = aContext.getCompletedSubWorkflow("generateISBN");
			aContext.setVariableString("isbn", generateISBN.getDataContext().getVariableString(
				"newCode"));
		}

		if (validateProductMarketing.getDataContext().getVariableString("Accepted").equals("true")
			&& validateProductDirection.getDataContext().getVariableString("Accepted").equals(
				"true"))
			aContext.setVariableString("validation", "ok");
	}
}
以下も参照してください。

module.xmlによる構成

SubWorkflowsInvocationBean Beanは、module.xmlで宣言する必要があります。

<module>
    <beans>
        <bean className="com.orchestranetworks.workflow.test.MySubWorkflowsInvocationBean"/>
    </beans>
</module>

WaitTaskBeanの例

Javaコード

public class MyWaitTaskBean extends WaitTaskBean
{
	@Override
	public void onStart(WaitTaskOnStartContext aContext)
	{
		Map<String, String> params = new HashMap<String, String>();
		params.put("resumeId", aContext.getResumeId());
		myMethod.callWebService(params);
	}

	@Override
	public void onResume(WaitTaskOnResumeContext aContext) throws OperationException
	{
		// Defines a specific mapping.
		aContext.setVariableString("code", aContext.getOutputParameters().get("isbn"));
		aContext.setVariableString("comment", aContext.getOutputParameters().get("isbnComment"));
	}
}
以下も参照してください。

module.xmlによる構成

WaitTaskBean Beanは、module.xmlで宣言する必要があります。

<module>
    <beans>
        <bean className="com.orchestranetworks.workflow.test.MyWaitTaskBean"/>
    </beans>
</module>

ActionPermissionsOnWorkflowの例

Javaコード

package com.orchestranetworks.workflow.test;

import com.orchestranetworks.service.*;
import com.orchestranetworks.workflow.*;
import com.orchestranetworks.workflow.ProcessExecutionContext.*;

/**
 */
public class MyDynamicPermissions extends ActionPermissionsOnWorkflow
{

    public ActionPermission getActionPermission(
        WorkflowPermission aWorkflowAction,
        ActionPermissionsOnWorkflowContext aContext)
    {
        if (WorkflowPermission.VIEW.equals(aWorkflowAction)
            || WorkflowPermission.CREATE_PROCESS.equals(aWorkflowAction))
            return ActionPermission.getEnabled();
        return ActionPermission.getDisabled();
    }

}
以下も参照してください。

module.xmlによる構成

ActionPermissionsOnWorkflow Beanは、module.xmlで宣言する必要があります。

<module>
    <beans>
        <bean className="com.orchestranetworks.workflow.test.MyDynamicPermissions"/>
    </beans>
</module>

WorkflowTriggerBeanの例

Javaコード

public class MyWorkflowTriggerBean extends WorkflowTriggerBean
{
	@Override
	public void handleAfterProcessInstanceStart(
		WorkflowTriggerAfterProcessInstanceStartContext aContext) throws OperationException
	{
		final DisplayPolicy policy = DisplayPolicyFactory.getPolicyForSession(aContext.getSession());
		final MailSpec spec = aContext.createMailSpec();
		spec.notify(NotificationType.TO, "supervisor@mail.com");

		spec.setSubject("[TRIGGER] After process instance start");
		spec.setBody("The workflow '"
			+ policy.formatUserMessage(aContext.getProcessInstance().getLabel())
			+ "' has been created.");

		spec.sendMail(Locale.US);
	}

	@Override
	public void handleBeforeProcessInstanceTermination(
		WorkflowTriggerBeforeProcessInstanceTerminationContext aContext) throws OperationException
	{
		final DisplayPolicy policy = DisplayPolicyFactory.getPolicyForSession(aContext.getSession());

		final MailSpec spec = aContext.createMailSpec();
		spec.notify(NotificationType.TO, "supervisor@mail.com");

		spec.setSubject("[TRIGGER] Before process instance termination");
		spec.setBody("The workflow '"
			+ policy.formatUserMessage(aContext.getProcessInstance().getLabel())
			+ "' has been completed. The created product is: '"
			+ aContext.getVariableString(NppConstants.VAR_CODE) + "'.");

		spec.sendMail(Locale.US);
	}

	@Override
	public void handleAfterWorkItemCreation(WorkflowTriggerAfterWorkItemCreationContext aContext)
		throws OperationException
	{
		DisplayPolicy policy = DisplayPolicyFactory.getPolicyForSession(aContext.getSession());

		MailSpec spec = aContext.createMailSpec();
		spec.notify(NotificationType.TO, "supervisor@mail.com");

		spec.setSubject("[TRIGGER] After work item creation");
		WorkItem workItem = aContext.getWorkItem();
		State state = workItem.getState();
		String body = "The work item '" + policy.formatUserMessage(workItem.getLabel())
			+ "' has been created. \n The step id is : " + aContext.getCurrentStepId()
			+ ". \n The work item is in state : " + policy.formatUserMessage(state.getLabel());

		if (workItem.getOfferedTo() != null)
			body += "\n The role is :" + workItem.getOfferedTo().format();
		if (workItem.getUserReference() != null)
			body += "\n The user is :" + workItem.getUserReference().format();

		spec.setBody(body);

		spec.sendMail(Locale.US);
	}

	@Override
	public void handleBeforeWorkItemStart(WorkflowTriggerBeforeWorkItemStartContext aContext)
		throws OperationException
	{
		DisplayPolicy policy = DisplayPolicyFactory.getPolicyForSession(aContext.getSession());

		MailSpec spec = aContext.createMailSpec();
		spec.notify(NotificationType.TO, "supervisor@mail.com");

		spec.setSubject("[TRIGGER] Before work item start");
		spec.setBody("The work item '"
			+ policy.formatUserMessage(aContext.getWorkItem().getLabel())
			+ "' has been started. \n  The current step id is : "
			+ aContext.getCurrentStepId()
			+ ". \n The work item user is: '"
			+ DirectoryHandler.getInstance(aContext.getRepository()).displayUser(
				aContext.getWorkItem().getUserReference(),
				aContext.getSession().getLocale()) + "'.");

		spec.sendMail(Locale.US);
	}

	@Override
	public void handleBeforeWorkItemAllocation(
		WorkflowTriggerBeforeWorkItemAllocationContext aContext) throws OperationException
	{
		DisplayPolicy policy = DisplayPolicyFactory.getPolicyForSession(aContext.getSession());

		MailSpec spec = aContext.createMailSpec();
		spec.notify(NotificationType.TO, "supervisor@mail.com");

		spec.setSubject("[TRIGGER] Before work item allocation");
		spec.setBody("The work item '"
			+ policy.formatUserMessage(aContext.getWorkItem().getLabel())
			+ "' has been allocated. \n  The current step id is: "
			+ aContext.getCurrentStepId()
			+ ". \n  The work item user is: '"
			+ DirectoryHandler.getInstance(aContext.getRepository()).displayUser(
				aContext.getUserReference(),
				aContext.getSession().getLocale()) + "'.");

		spec.sendMail(Locale.US);
	}

	@Override
	public void handleBeforeWorkItemDeallocation(
		WorkflowTriggerBeforeWorkItemDeallocationContext aContext) throws OperationException
	{
		DisplayPolicy policy = DisplayPolicyFactory.getPolicyForSession(aContext.getSession());

		MailSpec spec = aContext.createMailSpec();
		spec.notify(NotificationType.TO, "supervisor@mail.com");

		spec.setSubject("[TRIGGER] Before work item deallocation");
		spec.setBody("The work item '"
			+ policy.formatUserMessage(aContext.getWorkItem().getLabel())
			+ "' has been deallocated. \n  The current step id is: "
			+ aContext.getCurrentStepId()
			+ ". \n  The old work item user is: '"
			+ DirectoryHandler.getInstance(aContext.getRepository()).displayUser(
				aContext.getWorkItem().getUserReference(),
				aContext.getSession().getLocale()) + ".");

		spec.sendMail(Locale.US);

	}

	@Override
	public void handleBeforeWorkItemReallocation(
		WorkflowTriggerBeforeWorkItemReallocationContext aContext) throws OperationException
	{
		DisplayPolicy policy = DisplayPolicyFactory.getPolicyForSession(aContext.getSession());

		MailSpec spec = aContext.createMailSSec();
		spec.notify(NotificationType.TO, "supervisor@mail.com");

		spec.setSubject("[TRIGGER] Before work item reallocation");
		spec.setBody("The work item '"
			+ policy.formatUserMessage(aContext.getWorkItem().getLabel())
			+ "' has been reallocated. \n  The current step id is: "
			+ aContext.getCurrentStepId()
			+ ". \n  The work item user is: '"
			+ DirectoryHandler.getInstance(aContext.getRepository()).displayUser(
				aContext.getUserReference(),
				aContext.getSession().getLocale())
			+ "'. The old work item user is: '"
			+ DirectoryHandler.getInstance(aContext.getRepository()).displayUser(
				aContext.getWorkItem().getUserReference(),
				aContext.getSession().getLocale()) + "'.");

		spec.sendMail(Locale.US);

	}
	@Override
	public void handleBeforeWorkItemTermination(
		WorkflowTriggerBeforeWorkItemTerminationContext aContext) throws OperationException
	{
		DisplayPolicy policy = DisplayPolicyFactory.getPolicyForSession(aContext.getSession());

		MailSpec spec = aContext.createMailSpec();
		spec.notify(NotificationType.TO, "supervisor@mail.com");

		spec.setSubject("[TRIGGER] Before work item termination");
		spec.setBody("The work item '"
			+ policy.formatUserMessage(aContext.getWorkItem().getLabel())
			+ "' has been terminated. \n  The current step id is: " + aContext.getCurrentStepId()
			+ ". \n  The work item has been accepted ? " + aContext.isAccepted());

		spec.sendMail(Locale.US);
	}
}
以下も参照してください。

module.xmlによる構成

WorkflowTriggerBean Beanは、module.xmlで宣言する必要があります。

<module>
    <beans>
        <bean className="com.orchestranetworks.workflow.test.MyWorkflowTriggerBean"/>
    </beans>
</module>

プロセスインスタンスを開始するトリガーの例

public class TriggerWorkflow extends TableTrigger
{
    public void handleAfterModify(AfterModifyOccurrenceContext aContext) throws OperationException
    {
        ValueContext currentRecord = aContext.getOccurrenceContext();
        String code = (String) currentRecord.getValue(Path.parse("/code"));

        //Get published process
        PublishedProcessKey processPublishedKey = PublishedProcessKey.forName("productProcess");

        //Defines process instance
        WorkflowEngine engine = WorkflowEngine.getFromProcedureContext(aContext.getProcedureContext());
        ProcessLauncher launcher = engine.getProcessLauncher(processPublishedKey);

        //initialize Data Context
        launcher.setInputParameter("code", "/root/Client[./code=\"" + code + "\"]");
        launcher.setInputParameter("workingBranch", aContext.getAdaptationHome().getKey().getName());

        //Starts process
        launcher.launchProcess();

    }
      //...
}
ドキュメント>開発者ガイド