You are not logged in. Click here to log in.

codebeamer Application Lifecycle Management (ALM)

Search In Project

Search inClear

Tags:  not added yet

Custom state transition predicates

A state transition predicate implements a Condition (Filter) for State Transitions, that checks, whether a specific state transition is applicable for a specific tracker item in a specific context.

Developing own/custom predicates in Java requires a Java 7 or newer Standard Edition (SE) Java Development Kit (JDK) plus the following frameworks/libraries:

Framework/LibraryComponentVersion
org.apache.commonscommons-lang33.4
org.springframeworkspring-core3.2.x
org.springframeworkspring-context3.2.x
org.springframeworkspring-beans3.2.x

You also need cb.jar from the directory ~/CB-../tomcat/webapps/cb/WEB-INF/lib of the CodeBeamer 7.8.0 or newer installation, you want to develop new custom transition predicates for.



A predicate is simply a method of a Java class.

For example:

package com.intland.codebeamer.example.predicates;

import org.springframework.stereotype.Component;

import com.intland.codebeamer.manager.workflow.TransitionPredicate;
import com.intland.codebeamer.manager.workflow.TransitionApplicable;
import com.intland.codebeamer.persistence.dto.TrackerItemDto;
import com.intland.codebeamer.persistence.dto.WorkflowTransitionDto;

@Component("customPredicate")
@TransitionPredicate("customPredicate")
public class CustomPredicate {

   @TransitionApplicable
   public boolean isApplicable(WorkflowTransitionDto transition, TrackerItemDto item) {
      boolean result = ...

      return result;
   }
}

We recommend, that the package of your custom predicates should be a sub-package of com.intland.codebeamer, e.g.
com.intland.codebeamer.<mycompany>.predicates

You can use any package name, but when using a sub-package of com.intland.codebeamer, your new predicate can be automatically detected and deployed by the Component scan during CodeBeamer startup:


package com.intland.codebeamer.example.predicates;

import org.springframework.stereotype.Component;

@Component("customPredicate")
public class CustomPredicate {
   ...
}
The component id/name (if any) should be the same than the @TransitionPredicate id/name (see below).


If your custom transition predicate is not a Component in a sub-package of com.intland.codebeamer, then you must provide extra <bean> configuration for your custom predicate in

~/CB-../tomcat/webapps/cb/WEB-INF/classes/my-ApplicationContext.xml


Java classes providing state transition predicates must be annotated as @TransitionPredicate.

import com.intland.codebeamer.manager.workflow.TransitionPredicate;

@TransitionPredicate("customPredicate")
public class CustomPredicate {
  ...
}

The @TransitionPredicate annotation has only one parameter:

  • value
    the unique id/name of the predicate.
    This value must not be changed over the lifetime of a predicate, otherwise configured state transitions conditions for this predicate will not longer work!.

There is no special interface to implement or base class to extend.

But each class annotated as @TransitionPredicate, must have (at least) one method annotated with @TransitionApplicable:

package com.intland.codebeamer.example.predicates;

import com.intland.codebeamer.manager.workflow.TransitionPredicate;
import com.intland.codebeamer.manager.workflow.TransitionApplicable;
import com.intland.codebeamer.persistence.dto.TrackerItemDto;
import com.intland.codebeamer.persistence.dto.WorkflowTransitionDto;

@TransitionPredicate("customPredicate")
public class CustomPredicate {

   @TransitionApplicable
   public boolean isApplicable(WorkflowTransitionDto transition, TrackerItemDto item) {
      boolean result = ...

      return result;
   }
}


Methods annotated as @TransitionApplicable must be

  • Public
  • Deterministic
  • Stateless
  • Thread-safe
  • Return boolean true if the specified transition is applicable for the specified tracker item (in the specified context), false otherwise.


Context specific information required by the method in order to make it's decision, must be declared as method parameters.

The following context information is available:

  • UserDto, to receive the user, that wants to execute the state transition on the item
  • HttpServletRequest, to receive the current request.
  • WorkflowTransitionDto, to receive the state transition to be applied to the item
  • TrackerItemDto, to receive the tracker item where the state transition should be applied to
  • ProjectDto, to receive the context project
  • TrackerDto, to receive the context tracker
  • TrackerTypeDto is the type of the context tracker
  • TrackerTypeDto.Kind is the kind of the context tracker
    • Tracker for work items
    • Category for configuration items
    • Repository for source code commits/pushs

Context specific predicates

If your custom state transition predicate is only applicable in a specific context, e.g. only for trackers/items of a specific type, then the implementing class should declare an additional predicate/method annotated with @PredicateApplicable. E.g.


package com.intland.codebeamer.example.predicates;

import com.intland.codebeamer.manager.workflow.TransitionPredicate;
import com.intland.codebeamer.manager.workflow.PredicateApplicable;
import com.intland.codebeamer.persistence.dto.TrackerDto;
import com.intland.codebeamer.persistence.dto.TrackerTypeDto;

@TransitionPredicate("customPredicate")
public class CustomPredicate {

   @PredicateApplicable
   public boolean isApplicable(TrackerDto tracker) {
      return tracker.isA(TackerTypeDto.REQUIREMENT, TrackerTypeDto.USERSTORY);
   }
}

Methods annotated with @PredicateApplicable must be


The method must declare parameters for all required context information, that it needs to make it's decision.

The following context information is available:
  • ProjectDto is the project, where to configure state transitions
  • TrackerDto is the tracker, where to configure state transitions
  • TrackerTypeDto is the type of the tracker, where to configure state transitions
  • TrackerTypeDto.Kind is the kind of tracker, where to configure state transitions
    • Tracker for work items
    • Category for configuration items
    • Repository for source code commits/pushs

Deploying state transition predicates

To deploy your custom predicates, the Java code must be compiled and the resulting *.class file must be uploaded to the appropriate sub-directory under ~/CB-.../tomcat/webapps/cb/WEB-INF/classes/..., where the sub-directory is the equivalent of the predicates's package name.

If you have multiple custom predicates (along with custom workflow actions, Wiki Plugins, etc.), you may choose to pack all your custom classes (along with your custom language resource files) into one Java archive (*.jar) and put that into ~/CB-.../tomcat/webapps/cb/WEB-INF/lib.

For actions not under com.intland.codebeamer, or not annotated as @Component, you must also provide extra <bean> configurations in

~/CB-../tomcat/webapps/cb/WEB-INF/classes/my-ApplicationContext.xml

Finally you have to restart CodeBeamer, for your newly deployed predicates to get loaded.


Caution!
Old pre-CB-7.8 state transition predicates implementing StateTransitionPredicate or derived from DefaultStateTransitionPredicate are not longer supported in CB-7.8 or newer!

Any attempt to deploy such old predicates via ~/CB-.../tomcat/webapps/cb/WEB-INF/classes/my-applicationContext.xml will cause the CodeBeamer startup to fail.

If you had developed custom predicates, you should first check, whether the default Expression predicate can now be used for this task.
Only if that is not possible, you should try to migrate your custom predicate.