/**
  * Adds the filter sort descriptor criterias and the subset policy
  *
  * @param query
  * @param options
  */
 public static void addCriterias(Query query, Options options) {
   addDescriptorPolicy(options, query);
   addSortCriteria(query, options);
   addFilterCriteria(query, options);
   SubsetPolicy subsetPolicy = new SubsetPolicy(options.pageSize, options.skip, true);
   query.setPolicy(HistoricalStatesPolicy.WITH_LAST_USER_PERFORMER);
   query.setPolicy(subsetPolicy);
 }
  /**
   * @param query
   * @param options
   */
  public static void addSortCriteria(Query query, Options options) {
    boolean worklistQuery = query instanceof WorklistQuery;

    if (options.visibleDescriptorColumns.contains(options.orderBy)) {
      Map<String, DataPath> allDescriptors = ProcessDefinitionUtils.getAllDescriptors(false);
      String descriptorName = options.orderBy;
      if (allDescriptors.containsKey(descriptorName)) {
        DescriptorUtils.applyDescriptorPolicy(query, options);
        String columnName = DescriptorUtils.getDescriptorColumnName(descriptorName, allDescriptors);
        if (CommonDescriptorUtils.isStructuredData(allDescriptors.get(descriptorName))) {
          query.orderBy(
              new DataOrder(
                  columnName,
                  DescriptorUtils.getXpathName(descriptorName, allDescriptors),
                  options.asc));
        } else {
          query.orderBy(new DataOrder(columnName, options.asc));
        }
      }
    } else if (COL_ACTIVITY_NAME.equals(options.orderBy)) {
      query.orderBy(ActivityInstanceQuery.ACTIVITY_NAME.ascendig(options.asc));
    } else if (COL_ACTIVITY_INSTANCE_OID.equals(options.orderBy)) {
      query.orderBy(
          worklistQuery ? WorklistQuery.ACTIVITY_INSTANCE_OID : ActivityInstanceQuery.OID,
          options.asc);
    } else if (COL_START_TIME.equals(options.orderBy)) {
      query.orderBy(
          worklistQuery ? WorklistQuery.START_TIME : ActivityInstanceQuery.START_TIME, options.asc);
    } else if (COL_LAST_MODIFICATION_TIME.equals(options.orderBy)) {
      query.orderBy(
          worklistQuery
              ? WorklistQuery.LAST_MODIFICATION_TIME
              : ActivityInstanceQuery.LAST_MODIFICATION_TIME,
          options.asc);
    } else if (COL_PRIOIRTY.equals(options.orderBy)) {
      query.orderBy(
          worklistQuery
              ? WorklistQuery.PROCESS_INSTANCE_PRIORITY
              : ActivityInstanceQuery.PROCESS_INSTANCE_PRIORITY,
          options.asc);
    } else if (COL_CRITICALITY.equals(options.orderBy)) {
      query.orderBy(
          worklistQuery
              ? WorklistQuery.ACTIVITY_INSTANCE_CRITICALITY
              : ActivityInstanceQuery.CRITICALITY,
          options.asc);
    } else if (COL_PROCESS_OID.equals(options.orderBy)) {
      query.orderBy(
          worklistQuery
              ? WorklistQuery.PROCESS_INSTANCE_OID
              : ActivityInstanceQuery.PROCESS_INSTANCE_OID,
          options.asc);
    } else if (COL_BENCHMARK.equals(options.orderBy)) {
      query.orderBy(ActivityInstanceQuery.BENCHMARK_VALUE, options.asc);
    }
  }
 /**
  * Add descriptor policy
  *
  * @param options
  * @param query
  */
 public static void addDescriptorPolicy(Options options, Query query) {
   if (options.allDescriptorsVisible) {
     query.setPolicy(DescriptorPolicy.WITH_DESCRIPTORS);
   } else if (CollectionUtils.isNotEmpty(options.visibleDescriptorColumns)) {
     query.setPolicy(
         DescriptorPolicy.withIds(new HashSet<String>(options.visibleDescriptorColumns)));
   } else {
     query.setPolicy(DescriptorPolicy.NO_DESCRIPTORS);
   }
 }
  /**
   * Adds filter criteria to the query
   *
   * @param query Query
   * @param options Options
   */
  public static void addFilterCriteria(Query query, Options options) {

    WorklistFilterDTO filterDTO = (WorklistFilterDTO) options.filter;

    if (filterDTO == null) {
      return;
    }

    FilterAndTerm filter = query.getFilter().addAndTerm();

    boolean worklistQuery = query instanceof WorklistQuery;

    // Activity ID
    if (null != filterDTO.activityOID) {
      if (null != filterDTO.activityOID.from) {
        filter.and(
            (worklistQuery ? WorklistQuery.ACTIVITY_INSTANCE_OID : ActivityInstanceQuery.OID)
                .greaterOrEqual(filterDTO.activityOID.from));
      }
      if (null != filterDTO.activityOID.to) {
        filter.and(
            (worklistQuery ? WorklistQuery.ACTIVITY_INSTANCE_OID : ActivityInstanceQuery.OID)
                .lessOrEqual(filterDTO.activityOID.to));
      }
    }
    // Process Instance Oid
    if (null != filterDTO.processOID) {
      if (null != filterDTO.processOID.from) {
        filter.and(
            (worklistQuery
                    ? WorklistQuery.PROCESS_INSTANCE_OID
                    : ActivityInstanceQuery.PROCESS_INSTANCE_OID)
                .greaterOrEqual(filterDTO.processOID.from));
      }
      if (null != filterDTO.processOID.to) {
        filter.and(
            (worklistQuery
                    ? WorklistQuery.PROCESS_INSTANCE_OID
                    : ActivityInstanceQuery.PROCESS_INSTANCE_OID)
                .lessOrEqual(filterDTO.processOID.to));
      }
    }
    // Start Filter
    if (null != filterDTO.startTime) {

      if (filterDTO.startTime.from != null) {
        Date fromDate = new Date(filterDTO.startTime.from);
        filter.and(
            (worklistQuery ? WorklistQuery.START_TIME : ActivityInstanceQuery.START_TIME)
                .greaterOrEqual(fromDate.getTime()));
      }

      if (filterDTO.startTime.to != null) {
        Date toDate = new Date(filterDTO.startTime.to);
        filter.and(
            (worklistQuery ? WorklistQuery.START_TIME : ActivityInstanceQuery.START_TIME)
                .lessOrEqual(toDate.getTime()));
      }
    }
    // Modified Filter
    if (null != filterDTO.lastModified) {

      if (filterDTO.lastModified.from != null) {
        Date fromDate = new Date(filterDTO.lastModified.from);

        filter.and(
            (worklistQuery
                    ? WorklistQuery.LAST_MODIFICATION_TIME
                    : ActivityInstanceQuery.LAST_MODIFICATION_TIME)
                .greaterOrEqual(fromDate.getTime()));
      }

      if (filterDTO.lastModified.to != null) {
        Date toDate = new Date(filterDTO.lastModified.to);

        filter.and(
            (worklistQuery
                    ? WorklistQuery.LAST_MODIFICATION_TIME
                    : ActivityInstanceQuery.LAST_MODIFICATION_TIME)
                .lessOrEqual(toDate.getTime()));
      }
    }
    // Status Filter
    if (null != filterDTO.status) {
      FilterOrTerm or = filter.addOrTerm();
      for (String status : filterDTO.status.like) {
        Integer actState = Integer.parseInt(status);
        if (!worklistQuery) {
          or.add(ActivityInstanceQuery.STATE.isEqual(Long.parseLong(status.toString())));
        } else if (worklistQuery) {
          // Worklist Query uses ActivityStateFilter.
          or.add(new ActivityStateFilter(ActivityInstanceState.getState(actState)));
        }
      }
    }
    // Priority Filter
    if (null != filterDTO.priority) {
      FilterOrTerm or = filter.addOrTerm();
      for (String priority : filterDTO.priority.like) {
        or.or(
            (worklistQuery
                    ? WorklistQuery.PROCESS_INSTANCE_PRIORITY
                    : ActivityInstanceQuery.PROCESS_INSTANCE_PRIORITY)
                .isEqual(Integer.valueOf(priority)));
      }
    }
    // Criticality Filter
    if (null != filterDTO.criticality) {
      FilterOrTerm or = filter.addOrTerm();
      for (RangeDTO criticality : filterDTO.criticality.rangeLike) {
        or.or(
            (worklistQuery
                    ? WorklistQuery.ACTIVITY_INSTANCE_CRITICALITY
                    : ActivityInstanceQuery.CRITICALITY)
                .between(
                    (criticality.from / PORTAL_CRITICALITY_MUL_FACTOR),
                    criticality.to / PORTAL_CRITICALITY_MUL_FACTOR));
      }
    }
    // Activities Filter
    if (null != filterDTO.activityName) {

      if (!CollectionUtils.isEmpty(filterDTO.activityName.activities)) {
        FilterOrTerm or = filter.addOrTerm();
        if (!filterDTO.activityName.activities.contains("-1")) {
          for (String activity : filterDTO.activityName.activities) {

            or.add(ActivityFilter.forAnyProcess(activity));
          }
        }
      }

      if (!CollectionUtils.isEmpty(filterDTO.activityName.processes)) {
        FilterOrTerm or = filter.addOrTerm();
        if (!filterDTO.activityName.processes.contains("-1")) {
          for (String processQId : filterDTO.activityName.processes) {
            or.add(new ProcessDefinitionFilter(processQId, false));
          }
        }
      }
    }
    // Process Filter
    if (null != filterDTO.processName) {
      FilterOrTerm or = filter.addOrTerm();
      if (!filterDTO.processName.processes.contains("-1")) {
        for (String processQId : filterDTO.processName.processes) {
          or.add(new ProcessDefinitionFilter(processQId, false));
        }
      }
    }
    // Assigned To
    if (null != filterDTO.assignedTo) {
      FilterOrTerm or = filter.addOrTerm();
      for (ParticipantDTO participant : filterDTO.assignedTo.participants) {

        if (ParticipantType.USER.toString().equals(participant.type)) {

          or.add(
              new org.eclipse.stardust.engine.api.query.PerformingUserFilter(
                  Long.valueOf(participant.OID)));
        } else if (ParticipantType.ROLE.toString().endsWith(participant.type)) {
          RoleInfoDetails roleInfo = new RoleInfoDetails(participant.qualifiedId);
          or.add(
              org.eclipse.stardust.engine.api.query.PerformingParticipantFilter.forParticipant(
                  roleInfo));
        } else if (ParticipantType.ORGANIZATION.toString().equals(participant.type)) {

          OrganizationInfoDetails organizationInfo =
              new OrganizationInfoDetails(participant.qualifiedId);
          or.add(
              org.eclipse.stardust.engine.api.query.PerformingParticipantFilter.forParticipant(
                  organizationInfo));
        } else if (ParticipantSearchComponent.PerformerTypeUI.Department.name()
            .equals(participant.type)) {

          DepartmentInfo departmentInfo =
              new DepartmentInfoDetails(
                  participant.OID,
                  participant.id,
                  participant.name,
                  participant.runtimeOrganizationOid);
          or.add(
              org.eclipse.stardust.engine.api.query.ParticipantAssociationFilter.forDepartment(
                  departmentInfo));
        }
      }
    }
    // Completed By
    if (null != filterDTO.completedBy) {
      FilterOrTerm or = filter.addOrTerm();
      for (ParticipantDTO user : filterDTO.completedBy.participants) {
        or.add(new org.eclipse.stardust.engine.api.query.PerformedByUserFilter(user.OID));
      }
    }
    addDescriptorFilters(query, filterDTO);
  }