use of org.jbpm.query.jpa.data.QueryCriteria in project jbpm by kiegroup.
the class TaskAuditQueryModificationService method createPredicate.
/*
* (non-Javadoc)
* @see org.jbpm.query.jpa.service.QueryModificationService#createPredicate(org.jbpm.query.jpa.data.QueryCriteria, javax.persistence.criteria.CriteriaQuery, javax.persistence.criteria.CriteriaBuilder)
*/
public <R> Predicate createPredicate(QueryCriteria criteria, CriteriaQuery<R> query, CriteriaBuilder builder) {
// subquery and root
Root<TaskImpl> taskRoot = getRoot(query, TaskImpl.class);
Subquery<Long> subQuery = query.subquery(Long.class);
Root<TaskVariableImpl> taskVarRoot = subQuery.from(TaskVariableImpl.class);
subQuery.select(taskVarRoot.get(TaskVariableImpl_.taskId));
// task variable predicate (in subquery)
Predicate taskVariablePredicate = null;
String listId = criteria.getListId();
if (TASK_VARIABLE_COMBINED_ID.equals(listId)) {
List<QueryCriteria> taskVarSubCriteriaList = criteria.getCriteria();
int size = taskVarSubCriteriaList.size();
Predicate[] taskVarSubPredicates = new Predicate[size];
for (int i = 0; i < size; ++i) {
taskVarSubPredicates[i] = createSingleTaskVariableCriteriaPredicate(builder, taskVarRoot, taskVarSubCriteriaList.get(i));
}
taskVariablePredicate = builder.and(taskVarSubPredicates);
} else {
taskVariablePredicate = createSingleTaskVariableCriteriaPredicate(builder, taskVarRoot, criteria);
}
// add predicate to subquery
subQuery.where(taskVariablePredicate);
// create predicate for actual query that references subquery
return taskRoot.get(TaskImpl_.id).in(subQuery);
}
use of org.jbpm.query.jpa.data.QueryCriteria in project jbpm by kiegroup.
the class QueryCriteriaUtil method combineIntersectingRangeCriteria.
/**
* When there are multiple range criteria in a query (in the same group), it is more efficient to
* submit a JPA "between" criteria than 2 different criteria.
*
* @param intersectionCriteria A {@link List} of {@link QueryCriteria} instances that are range criteria
*/
@SuppressWarnings("unchecked")
private void combineIntersectingRangeCriteria(List<QueryCriteria> intersectionCriteria) {
Map<String, QueryCriteria> intersectingRangeCriteria = new HashMap<String, QueryCriteria>();
Iterator<QueryCriteria> iter = intersectionCriteria.iterator();
while (iter.hasNext()) {
QueryCriteria criteria = iter.next();
if (QueryCriteriaType.RANGE.equals(criteria.getType())) {
QueryCriteria previousCriteria = intersectingRangeCriteria.put(criteria.getListId(), criteria);
if (previousCriteria != null) {
Object[] prevCritValues, thisCritValues;
assert previousCriteria.hasValues() || previousCriteria.hasDateValues() : "Previous criteria has neither values nor date values!";
assert !(previousCriteria.hasValues() && previousCriteria.hasDateValues()) : "Previous criteria has BOTH values and date values!";
assert (previousCriteria.hasValues() && criteria.hasValues()) || (previousCriteria.hasDateValues() && criteria.hasDateValues()) : "Previous and current criteria should have either both have values or both have date values!";
boolean dateValues = false;
if (previousCriteria.hasValues()) {
prevCritValues = previousCriteria.getValues().toArray();
thisCritValues = criteria.getValues().toArray();
} else {
dateValues = true;
prevCritValues = previousCriteria.getDateValues().toArray();
thisCritValues = criteria.getDateValues().toArray();
}
List values = dateValues ? previousCriteria.getDateValues() : previousCriteria.getValues();
if (prevCritValues[0] == null && thisCritValues[1] == null) {
values.set(0, thisCritValues[0]);
intersectingRangeCriteria.put(previousCriteria.getListId(), previousCriteria);
iter.remove();
} else if (prevCritValues[1] == null && thisCritValues[0] == null) {
values.set(1, thisCritValues[1]);
intersectingRangeCriteria.put(previousCriteria.getListId(), previousCriteria);
iter.remove();
}
}
}
}
}
use of org.jbpm.query.jpa.data.QueryCriteria in project jbpm by kiegroup.
the class JPAAuditLogService method checkVarValCriteria.
public static void checkVarValCriteria(QueryWhere queryWhere, List<Object[]> varValCriteriaList) {
List<QueryCriteria> varValCriteria = new LinkedList<QueryCriteria>();
Iterator<QueryCriteria> iter = queryWhere.getCriteria().iterator();
while (iter.hasNext()) {
QueryCriteria criteria = iter.next();
if (criteria.getListId().equals(VAR_VALUE_ID_LIST)) {
varValCriteria.add(criteria);
iter.remove();
}
}
if (varValCriteria.isEmpty()) {
return;
}
for (QueryCriteria criteria : varValCriteria) {
for (Object varVal : criteria.getParameters()) {
String[] parts = ((String) varVal).split(VAR_VAL_SEPARATOR, 2);
String varId = parts[1].substring(0, Integer.parseInt(parts[0]));
String val = parts[1].substring(Integer.parseInt(parts[0]) + 1);
int type = (criteria.isUnion() ? 0 : 1) + (criteria.getType().equals(QueryCriteriaType.REGEXP) ? 2 : 0);
Object[] varValCrit = { type, varId, val };
varValCriteriaList.add(varValCrit);
}
}
}
use of org.jbpm.query.jpa.data.QueryCriteria in project jbpm by kiegroup.
the class TaskAuditQueryModificationService method optimizeCriteria.
/**
* This method combines multiple intersecting {@link TaskVariableImpl} criteria in order
* to make sure that the number of ({@link TaskVariableImpl}) subqueries created is minimal.
* </p>
* The following logic is applied:
* </p>
* Go through the given list of {@link QueryCriteria} and if an intersecting group or criteria
* contains multiple {@link TaskVariableImpl} criteria, then replace those task variable criteria
* with a single "combined" task variable criteria. This is then later processed correctly so as to create
* only one subquery.
* </p>
* Obviously, if we run into a group criteria, recurse.
* </p>
* Continue to go through the criteria list until we've reached the end of the list: the loop
* might have broken off earlier because it hit a union criteria and stopped to process group of intersecting
* task variable criteria that had already been found. With the successive loops, all intersecting groups
* containing task variable criteria will have been removed, allowing the last loop to reach the end
* of the list.
*
* @param criteriaList The list of {@link QueryCriteria} to process
*/
public void optimizeCriteria(List<QueryCriteria> criteriaList) {
// we don't expect subqueries with task variable criteria
Set<QueryCriteria> optimizedCriteria = Collections.newSetFromMap(new IdentityHashMap<QueryCriteria, Boolean>(1));
boolean endOfListNotYetReached = true;
while (endOfListNotYetReached) {
Set<QueryCriteria> taskVarCriteria = Collections.newSetFromMap(new IdentityHashMap<QueryCriteria, Boolean>(2));
boolean endOfListReached = true;
for (QueryCriteria criteria : criteriaList) {
if (!criteria.isFirst() && criteria.isUnion()) {
if (taskVarCriteria.size() > 1) {
endOfListReached = false;
break;
}
taskVarCriteria.clear();
}
// if group, recurse
if (criteria.isGroupCriteria()) {
if (optimizedCriteria.add(criteria)) {
optimizeCriteria(criteria.getCriteria());
}
continue;
}
String listId = criteria.getListId();
if (listId.equals(TASK_VARIABLE_NAME_ID_LIST) || listId.equals(TASK_VARIABLE_VALUE_ID_LIST)) {
taskVarCriteria.add(criteria);
}
}
if (endOfListReached) {
endOfListNotYetReached = false;
}
if (taskVarCriteria.size() > 1) {
Iterator<QueryCriteria> criteriaIter = criteriaList.iterator();
QueryCriteria combinedTaskVarCriteria = null;
while (criteriaIter.hasNext()) {
QueryCriteria criteria = criteriaIter.next();
if (taskVarCriteria.contains(criteria)) {
if (combinedTaskVarCriteria == null) {
combinedTaskVarCriteria = criteria;
criteria = new QueryCriteria(criteria);
// combined criteria replaces the original, and thus:
// 1. KEEPS the original union flag!
// 2. KEEPS the original first flag!
combinedTaskVarCriteria.setListId(TASK_VARIABLE_COMBINED_ID);
combinedTaskVarCriteria.setType(QueryCriteriaType.NORMAL);
combinedTaskVarCriteria.getValues().clear();
combinedTaskVarCriteria.getDateValues().clear();
// processed as a normal, even though it's group
combinedTaskVarCriteria.addCriteria(criteria);
} else {
combinedTaskVarCriteria.addCriteria(criteria);
criteriaIter.remove();
}
}
if (combinedTaskVarCriteria != null && criteria.isUnion()) {
break;
}
}
}
}
}
use of org.jbpm.query.jpa.data.QueryCriteria in project jbpm by kiegroup.
the class VarInstLogQueryBuilderImpl method last.
@Override
public VariableInstanceLogQueryBuilder last() {
List<QueryCriteria> criteriaList = queryWhere.getCriteria();
QueryCriteria lastVariableInstanceLogCriteria = null;
for (QueryCriteria criteria : criteriaList) {
if (LAST_VARIABLE_LIST.equals(criteria.getListId())) {
lastVariableInstanceLogCriteria = criteria;
break;
}
}
if (lastVariableInstanceLogCriteria == null) {
queryWhere.addParameter(LAST_VARIABLE_LIST, true);
}
return this;
}
Aggregations