Stardust services are provided to filter for activities, processes, users etc. The following sections describe how these filters work.
For a detailed description on how to use filter criteria efficiently please refer to the section Using Filter Criteria efficiently.
This filter restricts the resulting items to the ones related to a specific activity. The search can be further restricted to certain models by passing in a collection of model OIDs. Please refer to the Javadoc of the ActivityFilter for detailed information.
This is a filter criterion for matching specific activity instances. Please refer to the Javadoc of the ActivityInstanceFilter for detailed information.
This is a predefined filter matching activity instances being in states other than a list of given states. Please refer to the Javadoc of the ActivityStateFilter for detailed information.
This filter restricts the resulting items to the ones related to a specific process definition. Please refer to the Javadoc of the ProcessDefinitionFilter for detailed information.
This is a filter criterion for matching specific process instances. Please refer to the Javadoc of the ProcessInstanceFilter for detailed information.
Filter for finding process instances in a given state. Please refer to the Javadoc of the ProcessStateFilter for detailed information.
The following data filters are provided:
The DataFilter
will filter all process instances from the scope, whereas the SubprocessDataFilter
(mode "Subprocesses") retrieves all subprocesses of qualifying scope process
instances and the HierarchyDataFilter (mode "AllFromHierarchy") all the
sub- and super-processes of qualifying scope process instances.
A set of methods provide different filter functionality for matching workflow data:
public static DataFilter isEqual(String dataID, Serializable value)
public static DataFilter isEqual(String dataID, String value, boolean caseSensitive)
public static DataFilter isEqual(String dataID, String attributeName, Serializable value)
public static DataFilter isEqual(String dataID, String attributeName,
String value, boolean caseSensitive)
To filter for matching workflow data being not equal with a given value, use
method notEqual.
public static DataFilter notEqual(String dataID, Serializable value) public static DataFilter notEqual(String dataID, String attributeName, Serializable value)
public static DataFilter lessThan(String dataID, Serializable value) public static DataFilter lessThan(String dataID, String attributeName, Serializable value)
public static DataFilter lessOrEqual(String dataID, Serializable value) public static DataFilter lessOrEqual(String dataID, String attributeName, Serializable value)
public static DataFilter greaterOrEqual(String dataID, Serializable value) public static DataFilter greaterOrEqual(String dataID, String attributeName, Serializable value)
public static DataFilter greaterThan(String dataID, Serializable value) public static DataFilter greaterThan(String dataID, String attributeName, Serializable value)
public static DataFilter like(String dataID, String value)
public static DataFilter like(String dataID, String value, boolean caseSensitive)
public static DataFilter like(String dataID, String attributeName, String value)
public static DataFilter like(String dataID, String attributeName, String value,
boolean caseSensitive)
public static DataFilter in(String dataID, Collection values) public static DataFilter in(String dataID, String attributeName, Collection values)
public static DataFilter notIn(String dataID, Collection values) public static DataFilter notIn(String dataID, String attributeName, Collection values)
This DataFilter notAnyOf is applicable for Structured Data Type list
values only. Structured Data Types are defined as lists via a cardinality, which is set
to one or more or zero or more. For details on Structured Data Type
lists refer to section
Composite Types of chapter
Defining Structured Types.
public static DataFilter notAnyOf(String dataID, String attributeName, Collection values)
Hereby, dataID determines the ID of the workflow data to be matched against.
Parameter attributeName specifies the name of the data attribute to search for
(XPath, etc.). Note that only Structured Data value list nodes are supported.
The last parameter provides a list of values to match with, which will be excluded from
the result set.
The resulting SQL adds for each applied filter an additional OUTER JOIN.
For example for DataFilter.notAnyOf("SD1", "list", listWithXYZ):
from process_instance pi
OUTER JOIN structured_data_value sdv on (pi.oid and sdv.string_value in ('X', 'Y', 'Z'))
As DataFilter.notAnyOf() is used to exclude process and activity instances,
which have any value mentioned in the list argument in their corresponding Structured Data
Value entries, the corresponding WHERE clause will select for NULL entries
as shown below:
WHERE sdv.oid is null
OUTER JOIN is used because it generates NULL values for lines which do not
match the join condition.
The following example shows the usage of the notAnyOf DataFilter with three process instances piABC, piKLM, piXYZ having a Structured Data Type list element with ID SD1. The values of this list element for each process instance are as in the following table:
| Process Instance | Values in List Element SD1 |
|---|---|
| piABC | A, B, C |
| piKLM | K, L, M |
| piXYZ | X, Y, Z |
The following table shows some example queries with these process instances and the according results:
| Query (Pseudo Java) | Result | SQL (Pseudo) |
|---|---|---|
| DataFilter.notAnyOf("SD1", "list", [X]) | piABC, piKLM (note that piXYZ is excluded as it matches) | from process_instance pi
OUTER JOIN structured_data_value sdv on (pi.oid and sdv.string_value in ('X'))
WHERE sdv.oid is null |
| DataFilter.notAnyOf("SD1", "list", [Y]) | piABC, piKLM | from process_instance pi
OUTER JOIN structured_data_value sdv on (pi.oid and sdv.string_value in ('Y'))
WHERE sdv.oid is null |
| DataFilter.notAnyOf("SD1", "list", [Z]) | piABC, piKLM | |
| DataFilter.notAnyOf("SD1", "list", [U]) | piABC, piKLM, piXYZ (none excluded as U has no match) |
|
| DataFilter.notAnyOf("SD1", "list", [A,X]) | piKLM (piABC and piXYZ are excluded as both match) | from process_instance pi
OUTER JOIN structured_data_value sdv on (pi.oid and sdv.string_value in ('A', 'X'))
WHERE sdv.oid is null |
| DataFilter.notAnyOf("SD1", "list", [A,Y]) | piKLM | |
| DataFilter.notAnyOf("SD1", "list", [A,X,Z]) | piKLM | |
| DataFilter.notAnyOf("SD1", "list", [A,X,M]) | <empty> | from process_instance pi
OUTER JOIN structured_data_value sdv on (pi.oid and sdv.string_value in ('A', 'X', 'M'))
WHERE sdv.oid is null |
Now we use three process instances piABC, piALM, piAYZ also having the Structured Data Type list element with ID SD1, but with the following values:
| Process Instance | Values in List Element SD1 |
|---|---|
| piABC | A, B, C |
| piALM | A, L, M |
| piAYZ | A, Y, Z |
See some example queries and the according results for these process instances, which all have
A as value in their list element, in the table below:
| Query (Pseudo Java) | Result | SQL (Pseudo) |
|---|---|---|
| DataFilter.notAnyOf("SD1", "list", [A]) | <empty> (all excluded as all match A) |
|
| DataFilter.notAnyOf("SD1", "list", [A,B]) | <empty> (all excludes as all match A even if they do not match B) |
|
| DataFilter.notAnyOf("SD1", "list", [A]) AND DataFilter.notAnyOf("SD1", "list", [B]) |
<empty> (See Match Matrix table) |
from process_instance pi
OUTER JOIN structured_data_value sdvA on (pi.oid and sdvA.string_value in ('A'))
OUTER JOIN structured_data_value sdvB on (pi.oid and sdvB.string_value in ('B'))
WHERE sdvA.oid is null AND sdvB.oid is null |
| DataFilter.notAnyOf("SD1", "list", [A]) OR DataFilter.notAnyOf("SD1", "list", [B]) |
piALM, piAYZ (See Match Matrix table) | from process_instance pi
OUTER JOIN structured_data_value sdvA on (pi.oid and sdvA.string_value in ('A'))
OUTER JOIN structured_data_value sdvB on (pi.oid and sdvB.string_value in ('B'))
WHERE sdvA.oid is null OR sdvB.oid is null |
The following table provides a matching matrix for combinations of list values and
process instances when using AND and OR operators:
| PI | sdvA.oid | sdvB.oid | AND
|
OR
|
|---|---|---|---|---|
| piABC | A | B | excluded | excluded |
| piALM | A | null | excluded | included |
| piAYZ | A | null | excluded | included |
public static DataFilter between(String dataID, Serializable lowerBound,
Serializable upperBound)
public static DataFilter between(String dataID, String attributeName, Serializable lowerBound,
Serializable upperBound)
public static DataFilter equalsCaseDescriptor(String id, Object value) public static DataFilter likeCaseDescriptor(String id, Object value)
Please note that MySQL always performs a case sensitive String comparison, so
the usage of the Boolean parameter caseSensitive for a String comparison in a
DataFilter
query using MySQL will have no affect.
The ParticipantAssociationFilter will query for fetching workflow users matching specific criteria. Use one of the following kinds:
inUserGroup(String groupID) to
construct a filter criterion matching the user group identified by the given id.
Whereby groupID is the ID of the user group to filter for.forModelParticipant(String
participantID, boolean recursively) to construct a filter criterion matching the
closure of the given model participant. Whereby participantID is the ID of
the model participant to filter for. The closure will be calculated according to
worklist rules.forUser(String account) to construct a filter criterion
matching the user identified by the given account. Whereby account is the
account of the user to filter for.forTeamLeader(String roleId) to construct a
filter criterion which can be used for UserQueries and will return all users of the
team the given role (roleId) is team leader of. This comprises:
forDepartment(DepartmentInfo department) to
construct a filter criterion
matching the department identified by the given department instance.
Whereby department is the department users have to assigned to.
It may be null which means the default department.The PerformingParticipantFilter filter retrieves items performed by any participant (roles, organizations or user groups) associated with the calling user. Finding such participants will perform a deep search. Use one of the following kinds:
Use forParticipant(ParticipantInfo participant) to construct
a filter criterion matching the participant identified by the given
participant info. You can also use
forParticipant(ParticipantInfo participant, boolean recursively),
with recursively as flag to indicate that evaluation
of this filter should traverse the participant hierarchy.
Please refer to the Javadoc of the PerformingParticipantFilter for detailed information.
This filter indicates a match against the currently logged in user. Please refer to the Javadoc of the PerformedByUserFilter for detailed information.
The PerformingUserFilter is a predefined filter indicating a match against the currently logged in user.
The PerformingOnBehalfOfFilter filter will get all activity instances for that you have an appropriate permission, including those which are in a different user worklist. Use one of the following kinds:
Use one of the following methods to construct a filter criterion matching the participant identified by the given participant info:
forParticipant(ParticipantInfo participant)forParticipant(ParticipantInfo participant, boolean recursively)forParticipants(Set< ? extends ParticipantInfo> participants)Please refer to the Javadoc of the PerformingOnBehalfOfFilter for detailed information.
Note
Note that the PerformingOnBehalfOfFilter is only
evaluated in case the property
Carnot.AuditTrail.ActivityInstanceHistory.Enabled is
set to true, as
it requires the values ONBEHALFOFKIND,
ONBEHALFOF and ONBEHALFOFDEPARTMENT
from the ACT_INST_HISTORY table.
If the property is set to false, the query throws an
org.eclipse.stardust.engine.api.runtime.IllegalOperationException.
This is a filter for finding processes started by a specific user. Please refer to the Javadoc of the StartingUserFilter for detailed information.
The UserStateFilter is a filter that reduces the query result to users with the given status.
To create a filter matching the currently logged in users, use:
UserQuery query = new UserQuery(); query.getFilter().add(UserStateFilter.forLoggedInUsers());
This will return all users which are currently logged on.
There is a basic performance difference between criteria directly targeting attributes of the queried type and complex criteria.
Filter criteria against attributes are applied by using the Attribute
-constants defined for each Query subclass. For example, common attributes are
the runtime object ID, provided as an OID attribute and the appropriate model element
object ID, provided as ACTIVITY_OID attribute or PROCESS_DEFINITION_OID
attribute. As Attribute is a specialization of FilterableAttribute , it
provides various methods for creating a concrete FilterCriterion instances, like
isEqual() for matching a specific value or between()for matching a range
of values. Most common SQL search condition operators are supported.
Complex filter criteria are all high-level filters like ProcessDefinitionFilter,
ProcessInstanceFilter and most prominently DataFilter, as well as the SubprocessDataFilter
and the HierarchyDataFilter. The sole purpose of those complex filters is
providing a programmers friendly API for doing such complex things like hierarchy
unrolling, versioning and finding the right joins.
From a performance point of view, Attribute filter criteria are very
efficient as evaluation never requires any join or sub-select. On the downside, using those
criteria requires giving up a certain level of abstraction when creating queries. For
example, as the application developer will have to use numeric OIDs to search for
instances of model elements, the application has to take special care in multi model
version scenarios.
Complex filters on the other hand allow for more abstract queries, but evaluating those filters usually involves additional preprocessing and, depending on context, join operations.
A very typical use case is finding activity instances or process instances by
process instance OID: while in general such queries will be performed by using an instance
of ProcessInstanceFilter , some scenarios may allow for using
ActivityInstanceQuery. PROCESS_INSTANCE_OID , or ProcessInstanceQuery.OID
respectively instead, making use of additionally available context information. Especially
if the process in question does not involve subprocesses, or even in case of process
hierarchies, the exact process instance is known in advance. Filtering against the OID
attribute will prevent process hierarchy preprocessing needed in the generic case and
potentially reduce query evaluation to one database call. Similar considerations apply for
ProcessDefinitionFilter, where the direct use of ProcessInstanceQuery.PROCESS_DEFINITION_OID
may lead to considerable performance improvements.
By creating and providing a filter provider class, you can control the viewing of a user's worklist depending on
specific criteria. This filter class needs to implement the IFilterProvider.
You can reference a custom filter provider either in your
carnot.properties file or in the Portal configuration. For details please refer to section
Portal Properties of chapter
Client Side Properties and to chapter
Configuring Worklists
in the
Portal Documentation.
Find below an example filter provider class LocationFilter.java, which filters for an attribute
Location of a structured data SupportCaseData with specific values depending on the
grant of the logged-in user.
package com.filters;
import java.util.Iterator;
import java.util.List;
import org.eclipse.stardust.engine.api.web.jsf.common.beans.SessionContext;
import org.eclipse.stardust.engine.api.web.jsf.processportal.spi.AbstractFilterProvider;
import org.eclipse.stardust.engine.api.query.DataFilter;
import org.eclipse.stardust.engine.api.query.FilterAndTerm;
import org.eclipse.stardust.engine.api.query.FilterOrTerm;
import org.eclipse.stardust.engine.api.query.Query;
import org.eclipse.stardust.engine.api.runtime.Grant;
import org.eclipse.stardust.engine.api.runtime.User;
public class LocationFilter extends AbstractFilterProvider
{
private static final long serialVersionUID = 1L;
/* (non-Javadoc)
* @see org.eclipse.stardust.ui.web.client.common.spi.IFilterProvider#applyFilter(org.eclipse.stardust.engine.api.query.Query)
*/
public void applyFilter(Query query)
{
System.out.println("Applying Filter Provider - LocationFilter.applyFilter()");
User user = SessionContext.findSessionContext().getUser();
boolean puneCenter = false;
boolean mumbaiCenter = false;
List<Grant> grants = (List<Grant>) user.getAllGrants();
Iterator<Grant> iterator = grants.iterator();
while (iterator.hasNext())
{
Grant grant = iterator.next();
if (grant.getId().equalsIgnoreCase("PuneCenter"))
{
puneCenter = true;
}
if (grant.getId().equalsIgnoreCase("MumbaiCenter"))
{
mumbaiCenter = true;
}
}
System.out.println("puneCenter = " + puneCenter + ":: mumbaiCenter = " + mumbaiCenter);
if (puneCenter && mumbaiCenter)
{
FilterOrTerm filter = query.getFilter().addOrTerm();
filter.add(DataFilter.like("SupportCaseData", "Location", "%Pune%", false));
filter.add(DataFilter.like("SupportCaseData", "Location", "%Mumbai%", false));
}
else if (puneCenter)
{
FilterAndTerm filter = query.getFilter().addAndTerm();
filter.add(DataFilter.like("SupportCaseData", "Location", "%Pune%", false));
}
else if (mumbaiCenter)
{
FilterAndTerm filter = query.getFilter().addAndTerm();
filter.add(DataFilter.like("SupportCaseData", "Location", "%Mumbai%", false));
}
else
{
System.out.println("NOT Applying any Filter");
}
}
}
This example filter works as follows:
PuneCenter and MumbaiCenter, the worklist filter
filters for all values of attribute SupportCaseData.Location that contain the terms
Pune or Mumbai.PuneCenter, the worklist filter
filters for all values of attribute SupportCaseData.Location that contain the term
Pune.MumbaiCenter, the worklist filter
filters for all values of attribute SupportCaseData.Location that contain the term
Mumbai.PuneCenter nor grant MumbaiCenter, no
filter is applied.Please refer to chapter Creating and Applying a Worklist Filter in our Tutorial Guide Creating and Applying a Worklist Filter in our Tutorial Guide for more examples and details.