001/**
002 * Copyright 2005-2016 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.kew.rule.dao.impl;
017
018import org.apache.commons.collections.CollectionUtils;
019import org.apache.commons.lang.StringUtils;
020import org.kuali.rice.core.api.exception.RiceRuntimeException;
021import org.kuali.rice.kew.api.KewApiConstants;
022import org.kuali.rice.kew.rule.RuleBaseValues;
023import org.kuali.rice.kew.rule.RuleDelegationBo;
024import org.kuali.rice.kew.rule.RuleExtensionBo;
025import org.kuali.rice.kew.rule.RuleResponsibilityBo;
026import org.kuali.rice.kew.rule.dao.RuleDelegationDAO;
027import org.kuali.rice.kim.api.identity.principal.Principal;
028import org.kuali.rice.kim.api.services.KimApiServiceLocator;
029import org.kuali.rice.krad.data.DataObjectService;
030import org.springframework.beans.factory.annotation.Required;
031
032import javax.persistence.EntityManager;
033import javax.persistence.TypedQuery;
034import javax.persistence.criteria.CriteriaBuilder;
035import javax.persistence.criteria.CriteriaQuery;
036import javax.persistence.criteria.Expression;
037import javax.persistence.criteria.Root;
038import javax.persistence.criteria.Subquery;
039import java.util.ArrayList;
040import java.util.Collection;
041import java.util.HashSet;
042import java.util.List;
043import java.util.Map;
044
045import static org.kuali.rice.core.api.criteria.PredicateFactory.equal;
046
047public class RuleDelegationDAOJpa implements RuleDelegationDAO {
048
049        private EntityManager entityManager;
050    private DataObjectService dataObjectService;
051
052    public List<RuleDelegationBo> findByDelegateRuleId(String ruleId) {
053        org.kuali.rice.core.api.criteria.QueryByCriteria.Builder builder =
054                org.kuali.rice.core.api.criteria.QueryByCriteria.Builder.create();
055        builder.setPredicates(equal("delegateRuleId",ruleId));
056        return getDataObjectService().findMatching(RuleDelegationBo.class,builder.build()).getResults();
057    }
058
059    public void save(RuleDelegationBo ruleDelegation) {
060        getDataObjectService().save(ruleDelegation);
061    }
062
063    public List<RuleDelegationBo> findAllCurrentRuleDelegations(){
064        org.kuali.rice.core.api.criteria.QueryByCriteria.Builder builder =
065                org.kuali.rice.core.api.criteria.QueryByCriteria.Builder.create();
066        builder.setPredicates(equal("delegationRule.currentInd",true));
067        return getDataObjectService().findMatching(RuleDelegationBo.class,builder.build()).getResults();
068    }
069
070    public RuleDelegationBo findByRuleDelegationId(String ruleDelegationId){
071        return getDataObjectService().find(RuleDelegationBo.class, ruleDelegationId);
072
073    }
074    public void delete(String ruleDelegationId){
075        getDataObjectService().delete(findByRuleDelegationId(ruleDelegationId));
076    }
077
078
079    public List<RuleDelegationBo> findByResponsibilityIdWithCurrentRule(String responsibilityId) {
080        if (StringUtils.isBlank(responsibilityId)){
081            return null;
082        }
083
084        org.kuali.rice.core.api.criteria.QueryByCriteria.Builder builder =
085                    org.kuali.rice.core.api.criteria.QueryByCriteria.Builder.create();
086        builder.setPredicates(equal("delegationRule.currentInd",true),
087                    equal("responsibilityId",responsibilityId));
088        return getDataObjectService().findMatching(RuleDelegationBo.class,builder.build()).getResults();
089    }
090
091    /**
092     * Method that returns a subquery that selects rule id from rule responsibility table based on certain criteria
093     * @param ruleResponsibilityName is the responsibility name
094     * @param query is he criteria query
095     * @return a subquery that selects the rule id from rule responsibility table where responsibility name equals the rule responsibility name that is passed in as parameter to this method
096     */
097    private Subquery<RuleResponsibilityBo> getResponsibilitySubQuery(String ruleResponsibilityName, CriteriaQuery<RuleBaseValues> query){
098        CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
099        Subquery<RuleResponsibilityBo> ruleResponsibilitySubquery = query.subquery(RuleResponsibilityBo.class);
100        Root fromResp = ruleResponsibilitySubquery.from(RuleResponsibilityBo.class);
101        ruleResponsibilitySubquery.where(criteriaBuilder.equal(fromResp.get("ruleResponsibilityName"),ruleResponsibilityName));
102        ruleResponsibilitySubquery.select(fromResp.get("ruleBaseValuesId"));
103
104        return ruleResponsibilitySubquery;
105    }
106
107    private Subquery<RuleResponsibilityBo> getResponsibilitySubQuery(CriteriaQuery<RuleBaseValues> query, Collection<String> kimGroupIds, String principalId, Boolean searchUser, Boolean searchUserInWorkgroups) {
108        Collection<String> workgroupIdStrings = new ArrayList<String>();
109
110        for (String workgroupId : kimGroupIds) {
111            workgroupIdStrings.add(workgroupId.toString());
112        }
113
114        return getResponsibilitySubQuery(query, workgroupIdStrings,principalId,new ArrayList<String>(), searchUser, searchUserInWorkgroups);
115    }
116
117    /**
118     * Method that returns a subquery which rule id from rule responsibility table based on certain criteria
119     * @param query is the criteria query
120     * @param workgroupIds is collection of group ids
121     * @param principalId is the principal id of the user to whom the rule is delegated to
122     * @param actionRequestCodes is the collection of action requested codes
123     * @param searchUser is a boolean value
124     * @param searchUserInWorkgroups is a bolean value
125     * @return a subquery which satisfies the following conditions:
126      * If actionRequestCodes is not null or not empty then obtain its values from rule responsibility table based on the value that is passed in as parameter to this method
127      * If principalId is not null then search for rules specific to user or at least one group id exists hence search on workgroups
128      * If workgroupIds is not null or empty then search for rules based on workgroupId
129     */
130    private Subquery<RuleResponsibilityBo> getResponsibilitySubQuery(CriteriaQuery<RuleBaseValues> query, Collection<String> workgroupIds, String principalId, Collection actionRequestCodes, Boolean searchUser, Boolean searchUserInWorkgroups) {
131        CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
132        Subquery<RuleResponsibilityBo> ruleResponsibilityBoSubquery = query.subquery(RuleResponsibilityBo.class);
133        Root fromResp = ruleResponsibilityBoSubquery.from(RuleResponsibilityBo.class);
134
135        List<javax.persistence.criteria.Predicate> respPredicates = new
136                ArrayList<javax.persistence.criteria.Predicate>();
137
138        List<javax.persistence.criteria.Predicate> ruleRespNamePredicates = new
139                ArrayList<javax.persistence.criteria.Predicate>();
140
141        List<javax.persistence.criteria.Predicate> userNamePreds =
142                new ArrayList<javax.persistence.criteria.Predicate>();
143
144        List<javax.persistence.criteria.Predicate> workgroupPreds =
145                new ArrayList<javax.persistence.criteria.Predicate>();
146
147        if (actionRequestCodes != null && !actionRequestCodes.isEmpty()) {
148            Expression<String> exp = fromResp.get("actionRequestedCd");
149            javax.persistence.criteria.Predicate actionRequestPredicate = exp.in(actionRequestCodes);
150
151            respPredicates.add(actionRequestPredicate);
152        }
153
154        if (!StringUtils.isEmpty(principalId)) {
155            // workflow user id exists
156            if (searchUser != null && searchUser) {
157                // searching user wishes to search for rules specific to user
158                userNamePreds.add(criteriaBuilder.like(fromResp.get("ruleResponsibilityName"),principalId));
159                userNamePreds.add(criteriaBuilder.equal(fromResp.get("ruleResponsibilityType"), KewApiConstants.RULE_RESPONSIBILITY_WORKFLOW_ID));
160
161                javax.persistence.criteria.Predicate[] preds = userNamePreds.toArray(new javax.persistence.criteria.Predicate[userNamePreds.size()]);
162                ruleRespNamePredicates.add(criteriaBuilder.and(preds));
163
164            }
165            if ((searchUserInWorkgroups != null && searchUserInWorkgroups) && workgroupIds != null && !workgroupIds.isEmpty()) {
166                // at least one workgroup id exists and user wishes to search on workgroups
167                Expression<String> exp = fromResp.get("ruleResponsibilityName");
168                javax.persistence.criteria.Predicate groupIdPredicate = exp.in(workgroupIds);
169                workgroupPreds.add(groupIdPredicate);
170                workgroupPreds.add(criteriaBuilder.equal(fromResp.get("ruleResponsibilityType"),
171                        KewApiConstants.RULE_RESPONSIBILITY_GROUP_ID));
172                javax.persistence.criteria.Predicate[] preds = workgroupPreds.toArray(new javax.persistence.criteria.Predicate[workgroupPreds.size()]);
173                ruleRespNamePredicates.add(criteriaBuilder.and(preds));
174            }
175        } else if ( (workgroupIds != null) && (workgroupIds.size() == 1) ) {
176            // no user and one workgroup id
177            workgroupPreds.add(criteriaBuilder.like(fromResp.get("ruleResponsibilityName"),
178                    workgroupIds.iterator().next()));
179            workgroupPreds.add(criteriaBuilder.equal(fromResp.get("ruleResponsibilityType"),
180                    KewApiConstants.RULE_RESPONSIBILITY_GROUP_ID));
181            javax.persistence.criteria.Predicate[] preds = workgroupPreds.toArray(new javax.persistence.criteria.Predicate[workgroupPreds.size()]);
182            ruleRespNamePredicates.add(criteriaBuilder.and(preds));
183
184        } else if ((workgroupIds != null) && (workgroupIds.size() > 1) ) {
185            // no user and more than one workgroup id
186            Expression<String> exp = fromResp.get("ruleResponsibilityName");
187            javax.persistence.criteria.Predicate groupIdPredicate = exp.in(workgroupIds);
188            workgroupPreds.add(criteriaBuilder.equal(fromResp.get("ruleResponsibilityType"),
189                    KewApiConstants.RULE_RESPONSIBILITY_GROUP_ID));
190            javax.persistence.criteria.Predicate[] preds = workgroupPreds.toArray(new javax.persistence.criteria.Predicate[workgroupPreds.size()]);
191            ruleRespNamePredicates.add(criteriaBuilder.and(preds));
192        }
193
194        if (!ruleRespNamePredicates.isEmpty()) {
195            javax.persistence.criteria.Predicate[] preds = ruleRespNamePredicates.toArray(new javax.persistence.criteria.Predicate[ruleRespNamePredicates.size()]);
196            respPredicates.add(criteriaBuilder.or(preds));
197        }
198
199        if (!respPredicates.isEmpty()) {
200
201            javax.persistence.criteria.Predicate[] preds = respPredicates.toArray(
202                    new javax.persistence.criteria.Predicate[respPredicates.size()]);
203            ruleResponsibilityBoSubquery.where(preds);
204            ruleResponsibilityBoSubquery.select(fromResp.get("ruleBaseValuesId"));
205
206            return ruleResponsibilityBoSubquery;
207        }
208        return null;
209    }
210
211    /**
212     * Method that returns rule id from rule table based on certain criteria
213     * @param docTypeName is the document type name associated with a rule
214     * @param ruleTemplateId is the rule template id associated with a rule
215     * @param ruleDescription is the description of a rule
216     * @param workgroupIds is a collection of group ids
217     * @param principalId is the principal id
218     * @param activeInd is a boolean value determining if the rule is active or not
219     * @param extensionValues is a map of string  values
220     * @param actionRequestCodes is the collection of action requested codes
221     * @param query is the criteria query
222     * @return a subquery selects the rule id from rule table where delegateRule index is true and subquery is return value of getResponsibility subquery
223     */
224    private Subquery<RuleBaseValues> getRuleBaseValuesSubQuery(String docTypeName, String ruleTemplateId, String ruleDescription, Collection<String> workgroupIds,
225            String principalId, Boolean activeInd,
226            Map<String, String> extensionValues, Collection actionRequestCodes,CriteriaQuery<RuleDelegationBo> query){
227        CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
228        CriteriaQuery<RuleBaseValues> criteriaQuery = criteriaBuilder.createQuery(RuleBaseValues.class);
229        Subquery<RuleBaseValues> ruleBaseValuesSubquery = query.subquery(RuleBaseValues.class);
230        Root root = ruleBaseValuesSubquery.from(RuleBaseValues.class);
231        List<javax.persistence.criteria.Predicate> predicates = getSearchCriteria(root,criteriaQuery,docTypeName, ruleTemplateId, ruleDescription, activeInd, extensionValues);
232        Subquery<RuleResponsibilityBo> subquery = getResponsibilitySubQuery(criteriaQuery,workgroupIds, principalId, actionRequestCodes, (principalId != null), ((workgroupIds != null) && !workgroupIds.isEmpty()));
233        predicates.add(criteriaBuilder.in(root.get("id")).value(subquery));
234        ruleBaseValuesSubquery.where(criteriaBuilder.equal(root.get("delegateRule"),Boolean.TRUE));
235        ruleBaseValuesSubquery.select(root.get("id"));
236
237        return ruleBaseValuesSubquery;
238
239    }
240
241    /**
242     * Method that returns subquery that selects the rule id from rule table based on certain criteria
243     * @param docTypeName is the document type name associated with a rule
244     * @param ruleId is the primary key for a rule
245     * @param ruleTemplateId is the rule template id associated with a rule
246     * @param ruleDescription is the description of a rule
247     * @param workgroupId is a collection of group ids
248     * @param principalId is the principal id
249     * @param activeInd is a boolean value determining if the rule is active or not
250     * @param extensionValues is a map of string  values
251     * @param query is the criteria query
252     * @return a subquery based on the following conditions:
253      * If rule id is not null then add it to list of predicates where id is equal to the value of rule id passed in as parameter to this method
254      * If group id is not null then add it to list of predicates where id is equal to the return value of getResponsibilitySubQuery
255      * If principalId is not null or group id is not null then add it to list of predicates where id is equal to return value of getResponsibilitySubQuery
256     */
257    private Subquery<RuleBaseValues> getRuleBaseValuesSubQuery(String docTypeName, String ruleId, String ruleTemplateId, String ruleDescription, String workgroupId, String principalId, Boolean activeInd, Map<String, String> extensionValues, String workflowIdDirective,CriteriaQuery<RuleDelegationBo> query){
258        CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
259        CriteriaQuery<RuleBaseValues> criteriaQuery = criteriaBuilder.createQuery(RuleBaseValues.class);
260        Subquery<RuleBaseValues> ruleBaseValuesSubquery = query.subquery(RuleBaseValues.class);
261        Root fromResp = ruleBaseValuesSubquery.from(RuleBaseValues.class);
262        List<javax.persistence.criteria.Predicate> predicates = getSearchCriteria(fromResp,criteriaQuery,docTypeName, ruleTemplateId, ruleDescription, activeInd, extensionValues);
263
264        if (ruleId != null) {
265            predicates.add(criteriaBuilder.equal(fromResp.get("id"),ruleId));
266        }
267
268        if (workgroupId != null) {
269            predicates.add(criteriaBuilder.in(fromResp.get("id")).value(getResponsibilitySubQuery(workgroupId, criteriaQuery)));
270        }
271
272        Collection<String> kimGroupIds = new HashSet<String>();
273        Boolean searchUser = Boolean.FALSE;
274        Boolean searchUserInWorkgroups = Boolean.FALSE;
275
276        if ("group".equals(workflowIdDirective)) {
277            searchUserInWorkgroups = Boolean.TRUE;
278        } else if (StringUtils.isBlank(workflowIdDirective)) {
279            searchUser = Boolean.TRUE;
280            searchUserInWorkgroups = Boolean.TRUE;
281        } else {
282            searchUser = Boolean.TRUE;
283        }
284        if (!StringUtils.isEmpty(principalId) && searchUserInWorkgroups) {
285            Principal principal = null;
286
287            principal = KimApiServiceLocator.getIdentityService().getPrincipal(principalId);
288
289            if (principal == null) {
290                throw new RiceRuntimeException("Failed to locate user for the given principal id: " + principalId);
291            }
292
293            kimGroupIds = KimApiServiceLocator.getGroupService().getGroupIdsByPrincipalId(principalId);
294        }
295        Subquery<RuleResponsibilityBo> subquery = getResponsibilitySubQuery(criteriaQuery,kimGroupIds, principalId, searchUser, searchUserInWorkgroups);
296        if (CollectionUtils.isNotEmpty(kimGroupIds) || StringUtils.isNotBlank(principalId)) {
297            predicates.add(criteriaBuilder.in(fromResp.get("id")).value(subquery));
298        }
299
300        predicates.add(criteriaBuilder.equal(fromResp.get("delegateRule"),Boolean.TRUE));
301        javax.persistence.criteria.Predicate[] preds = predicates.toArray(new javax.persistence.criteria.Predicate[predicates.size()]);
302        ruleBaseValuesSubquery.where(preds);
303        ruleBaseValuesSubquery.select(fromResp.get("id"));
304
305        return ruleBaseValuesSubquery;
306
307    }
308
309    /**
310     * Method that selects the responsibility id from rule responsibility table where rule id is equal to the value that is passed as parameter to this method
311     * @param ruleBaseValuesId is the rule id
312     * @param query is the criteria query
313     * @return a subquery
314     */
315    private Subquery<RuleResponsibilityBo> getRuleResponsibilitySubQuery(Long ruleBaseValuesId, CriteriaQuery<RuleDelegationBo> query){
316        CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
317        Subquery<RuleResponsibilityBo> ruleResponsibilityBoSubquery = query.subquery(RuleResponsibilityBo.class);
318        Root fromResp = ruleResponsibilityBoSubquery.from(RuleResponsibilityBo.class);
319        ruleResponsibilityBoSubquery.where(criteriaBuilder.equal(fromResp.get("ruleBaseValuesId"),ruleBaseValuesId));
320        ruleResponsibilityBoSubquery.select(fromResp.get("responsibilityId"));
321
322        return ruleResponsibilityBoSubquery;
323    }
324
325    private List<javax.persistence.criteria.Predicate> getSearchCriteria(Root<RuleBaseValues> root,CriteriaQuery<RuleBaseValues> query,
326            String docTypeName, String ruleTemplateId,
327            String ruleDescription, Boolean activeInd, Map<String,String> extensionValues) {
328        List<javax.persistence.criteria.Predicate> predicates = new ArrayList<javax.persistence.criteria.Predicate>();
329        CriteriaBuilder criteribaBuilder = getEntityManager().getCriteriaBuilder();
330
331        predicates.add(criteribaBuilder.equal(root.get("currentInd"),Boolean.TRUE));
332        predicates.add(criteribaBuilder.equal(root.get("templateRuleInd"), Boolean.FALSE));
333        if (activeInd != null) {
334            predicates.add(criteribaBuilder.equal(root.get("active"),activeInd));
335        }
336        if (docTypeName != null) {
337            predicates.add(criteribaBuilder.like(criteribaBuilder.upper(root.<String>get("docTypeName")), docTypeName.toUpperCase()));
338        }
339        if (ruleDescription != null && !ruleDescription.trim().equals("")) {
340            predicates.add(criteribaBuilder.like(criteribaBuilder.upper(root.<String>get("description")),ruleDescription.toUpperCase()));
341        }
342        if (ruleTemplateId != null) {
343            predicates.add(criteribaBuilder.equal(root.get("ruleTemplateId"),ruleTemplateId));
344        }
345
346        if (extensionValues != null && !extensionValues.isEmpty()) {
347            for (Map.Entry<String,String> entry : extensionValues.entrySet()) {
348                if (!StringUtils.isEmpty(entry.getValue())) {
349                    Subquery ruleExtSubQuery = query.subquery(RuleExtensionBo.class);
350                    Root<RuleExtensionBo> ruleExtRoot = ruleExtSubQuery.from(RuleExtensionBo.class);
351                    javax.persistence.criteria.Predicate predAnd = criteribaBuilder.and(
352                            criteribaBuilder.equal(ruleExtRoot.get("extensionValues").get("key"),entry.getKey()),
353                            criteribaBuilder.like(ruleExtRoot.get("extensionValues").<String>get("value"),
354                                    ("%" + (String) entry.getValue() + "%").toUpperCase()));
355                    ruleExtSubQuery.where(predAnd);
356                    ruleExtSubQuery.select(ruleExtRoot.get("ruleBaseValuesId"));
357
358                    predicates.add(criteribaBuilder.in(root.get("id")).value(ruleExtSubQuery));
359                }
360            }
361        }
362        return predicates;
363    }
364
365    /**
366     * This overridden method ...
367     *
368     * @see org.kuali.rice.kew.rule.dao.RuleDelegationDAO#search(String, Long, Long, String, String, String, String, Boolean, java.util.Map, String)
369     */
370    @Override
371    public List<RuleDelegationBo> search(String parentRuleBaseVaueId, String parentResponsibilityId, String docTypeName, String ruleId,
372            String ruleTemplateId, String ruleDescription, String workgroupId,
373            String principalId, String delegationType, Boolean activeInd,
374            Map extensionValues, String workflowIdDirective) {
375        // TODO jjhanso - THIS METHOD NEEDS JAVADOCS
376        CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
377        CriteriaQuery<RuleDelegationBo> criteriaQuery = criteriaBuilder.createQuery(RuleDelegationBo.class);
378        Root<RuleDelegationBo> root = criteriaQuery.from(RuleDelegationBo.class);
379        List<javax.persistence.criteria.Predicate> predicates = new ArrayList<javax.persistence.criteria.Predicate>();
380        if (StringUtils.isNotBlank(delegationType) && !delegationType.equals(KewApiConstants.DELEGATION_BOTH)) {
381            predicates.add(criteriaBuilder.equal(root.get("delegationTypeCode"), delegationType));
382        }
383        if (StringUtils.isNotBlank(parentResponsibilityId) && StringUtils.isNumeric(parentResponsibilityId)) {
384            predicates.add(criteriaBuilder.equal(root.get("responsibilityId"),parentResponsibilityId));
385        }
386
387        if (StringUtils.isNotBlank(parentRuleBaseVaueId) && StringUtils.isNumeric(parentRuleBaseVaueId)) {
388            predicates.add(criteriaBuilder.in(root.get("responsibilityId")).value(getRuleResponsibilitySubQuery(new Long(parentRuleBaseVaueId),criteriaQuery)));
389        }
390        Subquery<RuleBaseValues> ruleBaseValuesSubQuery = getRuleBaseValuesSubQuery(docTypeName, ruleId, ruleTemplateId, ruleDescription, workgroupId,principalId, activeInd,extensionValues, workflowIdDirective,criteriaQuery);
391        if(ruleBaseValuesSubQuery != null){
392            predicates.add(criteriaBuilder.in(root.get("delegateRuleId")).value(ruleBaseValuesSubQuery));
393        }
394        criteriaQuery.distinct(true);
395        javax.persistence.criteria.Predicate[] preds = predicates.toArray(
396                new javax.persistence.criteria.Predicate[predicates.size()]);
397        criteriaQuery.where(preds);
398        TypedQuery<RuleDelegationBo> typedQuery = getEntityManager().createQuery(criteriaQuery);
399        typedQuery.setMaxResults(KewApiConstants.DELEGATE_RULE_LOOKUP_MAX_ROWS_RETURNED);
400
401        return typedQuery.getResultList();
402    }
403
404    /**
405     * This overridden method ...
406     *
407     * @see org.kuali.rice.kew.rule.dao.RuleDelegationDAO#search(String, Long, String, java.util.Collection, String, String, Boolean, java.util.Map, java.util.Collection)
408     */
409    public List<RuleDelegationBo> search(String parentRuleBaseVaueId, String parentResponsibilityId, String docTypeName, String ruleTemplateId,
410            String ruleDescription, Collection<String> workgroupIds,
411            String principalId, String delegationType, Boolean activeInd,
412            Map extensionValues, Collection actionRequestCodes) {
413        // TODO jjhanso - THIS METHOD NEEDS JAVADOCS
414        CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
415        CriteriaQuery<RuleDelegationBo> criteriaQuery = criteriaBuilder.createQuery(RuleDelegationBo.class);
416        Root<RuleDelegationBo> root = criteriaQuery.from(RuleDelegationBo.class);
417        List<javax.persistence.criteria.Predicate> predicates = new ArrayList<javax.persistence.criteria.Predicate>();
418        if (StringUtils.isNotBlank(delegationType) && !delegationType.equals(KewApiConstants.DELEGATION_BOTH)) {
419            predicates.add(criteriaBuilder.equal(root.get("delegationTypeCode"), delegationType));
420        }
421        if (StringUtils.isNotBlank(parentResponsibilityId) && StringUtils.isNumeric(parentResponsibilityId)) {
422            predicates.add(criteriaBuilder.equal(root.get("responsibilityId"),parentResponsibilityId));
423        }
424
425        if (StringUtils.isNotBlank(parentRuleBaseVaueId) && StringUtils.isNumeric(parentRuleBaseVaueId)) {
426            predicates.add(criteriaBuilder.in(root.get("responsibilityId")).value(getRuleResponsibilitySubQuery(new Long(parentRuleBaseVaueId),criteriaQuery)));
427        }
428        Subquery<RuleBaseValues> ruleBaseValuesSubQuery = getRuleBaseValuesSubQuery(docTypeName, ruleTemplateId, ruleDescription, workgroupIds,principalId, activeInd,extensionValues,actionRequestCodes,criteriaQuery);
429        if(ruleBaseValuesSubQuery != null){
430            predicates.add(criteriaBuilder.in(root.get("delegateRuleId")).value(ruleBaseValuesSubQuery));
431        }
432        criteriaQuery.distinct(true);
433        TypedQuery<RuleDelegationBo> typedQuery = getEntityManager().createQuery(criteriaQuery);
434        typedQuery.setMaxResults(KewApiConstants.DELEGATE_RULE_LOOKUP_MAX_ROWS_RETURNED);
435
436        return typedQuery.getResultList();
437    }
438
439    public DataObjectService getDataObjectService() {
440        return dataObjectService;
441    }
442
443    @Required
444    public void setDataObjectService(DataObjectService dataObjectService) {
445        this.dataObjectService = dataObjectService;
446    }
447
448    public EntityManager getEntityManager() {
449        return this.entityManager;
450    }
451
452    public void setEntityManager(EntityManager entityManager) {
453        this.entityManager = entityManager;
454    }
455
456
457}