cancel
Showing results for 
Search instead for 
Did you mean: 

Custom extension - access properties in definition

steve1
Champ on-the-rise
Champ on-the-rise
This is my first post,
so first, thanks to JBPM4 and now Activiti5 developers.

I made a custom extension with the aid of the user guide, and works well.

Now, how can I access these properties in the process definition?

I can use activity definition via getDeployedProcessDefinition and getActivities,
but there is no custom properties in the ActivityImpl.getProperties.

I investigated source code, and found some.

1. ActivityImpl.getActivityBehavior returns ClassDelegate (MultiInstanceActivityBehavior in case of multi-instance).

2. ClassDelegate has internal field of fieldDeclarations which have custom properties, but no getter.

3. MultiInstanceActivityBehavior has internal field of innerActivityBehavior which has original ActivityBehavior (=ClassDelegate), but no getter.

If these getters are added, I can access and use custom properties in the process definition.

Is this correct approach?

Thanks.
11 REPLIES 11

steve1
Champ on-the-rise
Champ on-the-rise
Noboby is instrested in this topic?


There will be many use-cases in using the Workflow/BPM system.

One case is that, an application(like Alfresco) needs to do task management and processing complicated UI form and business logic, but others like designing proess definition and processing flow will be done by the Activiti.

Some custom extensions will be needed to make things simple such as specifying predefined custom properties will lead to the corresponding UI form and business logic.

When deploying the process flow, the application will be needed to investigate the custom properties to configure what kind of UI form and processing is required with that process.

The application can check also if that process flow does not match with the application, because the specified properties does not meet the required properties, and throwing exception to redploy the correct process definition.

So I need to check the custom properties in the process definition with the method that is described in the posting above.


Any comment will be appreciated.

trademak
Star Contributor
Star Contributor
Hi,

Can you tell a bit more about your custom extension? Maybe show some code as well?

Best regards,

steve1
Champ on-the-rise
Champ on-the-rise
Ok, here is my code.

1. designer custom extension code

@Runtime(delegationClass="com.test.runtime.MyTask")
@Help(displayHelpShort=HELP_COMP_SHORT, displayHelpLong=HELP_COMP_LONG)
public class MyTask extends AbstractCustomServiceTask {

@Property(type=PropertyType.COMBOBOX_CHOICE, displayName=TITLE_TYPE, required=true)
@Help(displayHelpShort=HELP_TYPE_SHORT, displayHelpLong=HELP_TYPE_LONG)
@PropertyItems({"TYPE1", "TYPE2"})
private String taskType;

@Property(type=PropertyType.BOOLEAN_CHOICE, displayName=TITLE_SCOPE, required=true)
@Help(displayHelpShort=HELP_SCOPE_SHORT, displayHelpLong=HELP_SCOPE_LONG)
private String multiScope;
}

2. custom extension rutime class

private Expression taskType;
private Expression multiScope;

@Override
public void execute(ActivityExecution execution) throws Exception {
  String valTaskType = taskType == null ? null : (String) taskType.getValue(execution);
  boolean valMultiScope = multiScope == null ? false : ("true".equals(multiScope.getValue(execution)) ? true : false);
}

3. my application : access custom properties in the process definition

  ReadOnlyProcessDefinition roProcDef = ((RepositoryServiceImpl)repositoryService).getDeployedProcessDefinition(wfDefinitionId);

  List<ActivityImpl> activities = (List<ActivityImpl>)roProcDef.getActivities();

  for(ActivityImpl activity : activities) {

   String type = (String)activity.getProperty("type");

   if("serviceTask".equals(type)) {

    if(activity.getActivityBehavior() instanceof ClassDelegate) {
     ClassDelegate delegate = (ClassDelegate) activity.getActivityBehavior();
     List<FieldDeclaration> fields = delegate.getFieldDeclarations();

     for(FieldDeclaration field : fields) {
      if("taskType".equals(field.getName()))
       taskType = value.getExpressionText();
      else if("multiScope".equals(field.getName())) {
       multiScope = "true".equals(value.getExpressionText()) ? true : false;
     }
    }
    else if(activity.getActivityBehavior() instanceof MultiInstanceActivityBehavior) {
     MultiInstanceActivityBehavior behavior = (MultiInstanceActivityBehavior) activity.getActivityBehavior();

     ClassDelegate delegate = (ClassDelegate) behavior.getInnerActivityBehavior();
     List<FieldDeclaration> fields = delegate.getFieldDeclarations();
     // same code
    }

As you can see in list 3, I want to access custom properties that are defined in the custom extension.

I can access defined activities by ReadOnlyProcessDefinition.getActivities().
If the activity is a serviceTask, then I need to check custom properties.

ClassDelegate.getFieldDeclarations() is what I want to be done.
If this getter is provided, I can access my custom field.

Also, MultiInstanceActivityBehavior.getInnerActivityBehavior() is needed to get original ActivityBehavior(=ClassDelegate above).

I don't know deeply about Activiti source code, but this is just what I've investigated.

If this is a correct approach, I need these getters supported.

Thanks.

trademak
Star Contributor
Star Contributor
Hi,

Okay with the code I can understand your question a bit better.
Why don't you use the MyTask custom extension class to get the custom property info.
I don't understand why you want to read the property information from the process definition itself.
Can you explain this?

Best regards,

steve1
Champ on-the-rise
Champ on-the-rise
Sure, I'll explain my application a bit more.

My application has two parts with regard to BPM.

One part is a administration part and the other is a user part.

As you said, I can use custom properties in the custom runtime class in a user part.

Administration part has some functions like deploying process definition and configuring system with that process information.

One example is that when deploying process definition, I can check whether the process definition contains correct custom properties, so that it can run without problem in a user part.

Another example will be the authorization management based on the custom properties.  Application administrator will configure some authorization rules based on the custom properties, so that a user can use this application with this pre-defined authorization.

More appropriate example will be the task management by the application, not by Activiti. Administrator will configure task definition based on the activity ID and custom properties. When a process instance starts, custom runtime class will request this definition with it's ID, and a task will be created. Also a user will be assigned by the definition. If the user loggs in, he can find todo task, and work on the predefined task view and business logic based on the task definition.

My English is not good, but this is what I can describe.

Thanks.

trademak
Star Contributor
Star Contributor
Hi,

I think a good option would be to use a BpmnParseListener.
You can configure a pre or post parse listener which is invoked when a new process definition is deployed.
In this parse listener you get the raw XML elements, so you can validate whatever you would like.
It's possible to configure a pre or post parse listener in the Activiti process engine configuration.
For an example you can take a look at the HistoryParseListener implemented in the Activiti Engine.

Best regards,

steve1
Champ on-the-rise
Champ on-the-rise
Thank you for your recommendation.

I'll check that option.

Thank you. Smiley Very Happy

steve1
Champ on-the-rise
Champ on-the-rise
Hi,

Before investigating the BpmnParseListener, I think there can ce some problems with this option.

1. It will be asychronous, so administrator UI would be separated to two parts: one for deployment, and the other for custom task definition. This is not serious, and I can have additional field to check if parsing was succeeeded before handling custom task definition.

2. My application will be needed to have duplicate copy of the activity definition which already exists in Activiti. I just want to call Activiti to get activity definition without copying them in my application storage.

3. Parsing the process definition will give full information about the process, but if I don't need any additional properties, parsing will be another duplicate job that is already done by Activiti.

So, I think that just two or mote getters will make things simple.

How do you think about that?

Anyway, the BpmnParseListener is a good information for me if I need additional properties about the process definition.

Your comment will be appreciated.

steve1
Champ on-the-rise
Champ on-the-rise
No more comments, so I'll close this topic.

Until now, I have two options.

1. Change Activiti source code, and use my own build of Activiti, waiting somday when two getters will be supported.
This is what I have done already, but not good solution.

2. Use BpmnParseListener, make some additional code, and use original build of Activiti.
The way to go.

Thanks. Smiley Happy