Search in sources :

Example 1 with QueryCriteria

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);
}
Also used : TaskVariableImpl(org.jbpm.services.task.audit.impl.model.TaskVariableImpl) TaskImpl(org.jbpm.services.task.impl.model.TaskImpl) QueryCriteria(org.jbpm.query.jpa.data.QueryCriteria) Predicate(javax.persistence.criteria.Predicate)

Example 2 with QueryCriteria

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();
                }
            }
        }
    }
}
Also used : HashMap(java.util.HashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) QueryCriteria(org.jbpm.query.jpa.data.QueryCriteria) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List)

Example 3 with QueryCriteria

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);
        }
    }
}
Also used : QueryCriteria(org.jbpm.query.jpa.data.QueryCriteria) LinkedList(java.util.LinkedList)

Example 4 with QueryCriteria

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;
                }
            }
        }
    }
}
Also used : QueryCriteria(org.jbpm.query.jpa.data.QueryCriteria)

Example 5 with QueryCriteria

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;
}
Also used : QueryCriteria(org.jbpm.query.jpa.data.QueryCriteria)

Aggregations

QueryCriteria (org.jbpm.query.jpa.data.QueryCriteria)9 ArrayList (java.util.ArrayList)3 LinkedList (java.util.LinkedList)3 Predicate (javax.persistence.criteria.Predicate)3 HashMap (java.util.HashMap)1 List (java.util.List)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 QueryAndParameterAppender (org.jbpm.query.jpa.impl.QueryAndParameterAppender)1 TaskVariableImpl (org.jbpm.services.task.audit.impl.model.TaskVariableImpl)1 TaskImpl (org.jbpm.services.task.impl.model.TaskImpl)1