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.apache.ojb.broker.query.Criteria;
021import org.apache.ojb.broker.query.QueryByCriteria;
022import org.apache.ojb.broker.query.QueryFactory;
023import org.apache.ojb.broker.query.ReportQueryByCriteria;
024import org.kuali.rice.core.api.exception.RiceRuntimeException;
025import org.kuali.rice.kew.rule.RuleBaseValues;
026import org.kuali.rice.kew.rule.RuleDelegationBo;
027import org.kuali.rice.kew.rule.RuleExtensionBo;
028import org.kuali.rice.kew.rule.RuleResponsibilityBo;
029import org.kuali.rice.kew.rule.dao.RuleDelegationDAO;
030import org.kuali.rice.kew.api.KewApiConstants;
031import org.kuali.rice.kim.api.identity.principal.Principal;
032import org.kuali.rice.kim.api.services.KimApiServiceLocator;
033import org.springmodules.orm.ojb.support.PersistenceBrokerDaoSupport;
034
035import java.util.ArrayList;
036import java.util.Collection;
037import java.util.HashSet;
038import java.util.List;
039import java.util.Map;
040import java.util.Set;
041
042
043public class RuleDelegationDAOOjbImpl extends PersistenceBrokerDaoSupport implements RuleDelegationDAO {
044
045    public List<RuleDelegationBo> findByDelegateRuleId(String ruleId) {
046        Criteria crit = new Criteria();
047        crit.addEqualTo("delegateRuleId", ruleId);
048        return (List) this.getPersistenceBrokerTemplate().getCollectionByQuery(new QueryByCriteria(RuleDelegationBo.class, crit));
049    }
050
051    public void save(RuleDelegationBo ruleDelegation) {
052        this.getPersistenceBrokerTemplate().store(ruleDelegation);
053    }
054    public List<RuleDelegationBo> findAllCurrentRuleDelegations(){
055        Criteria crit = new Criteria();
056        crit.addEqualTo("delegationRule.currentInd", true);
057        return (List) this.getPersistenceBrokerTemplate().getCollectionByQuery(new QueryByCriteria(RuleDelegationBo.class, crit));
058    }
059
060    public RuleDelegationBo findByRuleDelegationId(String ruleDelegationId){
061        Criteria crit = new Criteria();
062        crit.addEqualTo("ruleDelegationId", ruleDelegationId);
063        return (RuleDelegationBo) this.getPersistenceBrokerTemplate().getObjectByQuery(new QueryByCriteria(RuleDelegationBo.class, crit));
064
065    }
066    public void delete(String ruleDelegationId){
067        this.getPersistenceBrokerTemplate().delete(findByRuleDelegationId(ruleDelegationId));
068    }
069
070    public List<RuleDelegationBo> findByResponsibilityIdWithCurrentRule(String responsibilityId) {
071        Criteria crit = new Criteria();
072        crit.addEqualTo("responsibilityId", responsibilityId);
073        crit.addEqualTo("delegationRule.currentInd", true);
074        Collection delegations = getPersistenceBrokerTemplate().getCollectionByQuery(new QueryByCriteria(RuleDelegationBo.class, crit));
075        return new ArrayList<RuleDelegationBo>(delegations);
076    }
077
078    /**
079     * This overridden method ...
080     *
081     * @see org.kuali.rice.kew.rule.dao.RuleDelegationDAO#search(java.lang.String, java.lang.Long, java.lang.Long, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.Boolean, java.util.Map, java.lang.String)
082     */
083    public List<RuleDelegationBo> search(String parentRuleBaseVaueId, String parentResponsibilityId, String docTypeName, String ruleId,
084            String ruleTemplateId, String ruleDescription, String workgroupId,
085            String principalId, String delegationType, Boolean activeInd,
086            Map extensionValues, String workflowIdDirective) {
087        Criteria crit = new Criteria(); //getSearchCriteria(docTypeName, ruleTemplateId, ruleDescription, delegationType, activeInd, extensionValues);
088
089        if (StringUtils.isNotBlank(delegationType) && !delegationType.equals(KewApiConstants.DELEGATION_BOTH)) {
090                crit.addEqualTo("delegationType", delegationType);
091        }
092        
093        if (StringUtils.isNotBlank(parentRuleBaseVaueId) && StringUtils.isNumeric(parentRuleBaseVaueId)) {
094            crit.addIn("responsibilityId", this.getRuleResponsibilitySubQuery(new Long(parentRuleBaseVaueId)));
095        }
096
097        if (StringUtils.isNotBlank(parentResponsibilityId) && StringUtils.isNumeric(parentResponsibilityId)) {
098            crit.addEqualTo("responsibilityId", parentResponsibilityId);
099        }
100
101        crit.addIn("delegateRuleId", getRuleBaseValuesSubQuery(docTypeName, ruleId,
102                                                               ruleTemplateId, ruleDescription, workgroupId,
103                                                               principalId, activeInd,
104                                                               extensionValues, workflowIdDirective));
105
106        QueryByCriteria query = new QueryByCriteria(RuleDelegationBo.class, crit, true);
107        query.setEndAtIndex(KewApiConstants.DELEGATE_RULE_LOOKUP_MAX_ROWS_RETURNED);
108
109        return (List<RuleDelegationBo>) this.getPersistenceBrokerTemplate().getCollectionByQuery(query);
110    }
111
112    /**
113     * This overridden method ...
114     *
115     * @see org.kuali.rice.kew.rule.dao.RuleDelegationDAO#search(java.lang.String, java.lang.Long, java.lang.String, java.util.Collection, java.lang.String, java.lang.String, java.lang.Boolean, java.util.Map, java.util.Collection)
116     */
117    public List<RuleDelegationBo> search(String parentRuleBaseVaueId, String parentResponsibilityId, String docTypeName, String ruleTemplateId,
118            String ruleDescription, Collection<String> workgroupIds,
119            String workflowId, String delegationType, Boolean activeInd,
120            Map extensionValues, Collection actionRequestCodes) {
121        Criteria crit = new Criteria();
122        
123        if (StringUtils.isNotBlank(delegationType) && !delegationType.equals(KewApiConstants.DELEGATION_BOTH)) {
124                crit.addEqualTo("delegationType", delegationType);
125        }
126        
127        if (StringUtils.isNotBlank(parentRuleBaseVaueId) && StringUtils.isNumeric(parentRuleBaseVaueId)) {
128            crit.addIn("responsibilityId", this.getRuleResponsibilitySubQuery(new Long(parentRuleBaseVaueId)));
129        }
130
131        if (StringUtils.isNotBlank(parentResponsibilityId) && StringUtils.isNumeric(parentResponsibilityId)) {
132            crit.addEqualTo("responsibilityId", parentResponsibilityId);
133        }
134
135        crit.addIn("delegateRuleId", getRuleBaseValuesSubQuery(docTypeName, ruleTemplateId,
136                                                               ruleDescription, workgroupIds,
137                                                               workflowId, activeInd,
138                                                               extensionValues, actionRequestCodes));
139
140        QueryByCriteria query = new QueryByCriteria(RuleDelegationBo.class, crit, true);
141        query.setEndAtIndex(KewApiConstants.DELEGATE_RULE_LOOKUP_MAX_ROWS_RETURNED);
142
143        return (List) this.getPersistenceBrokerTemplate().getCollectionByQuery(query);
144    }
145
146    private ReportQueryByCriteria getResponsibilitySubQuery(String ruleResponsibilityName) {
147        Criteria responsibilityCrit = new Criteria();
148        responsibilityCrit.addLike("ruleResponsibilityName", ruleResponsibilityName);
149        ReportQueryByCriteria query = QueryFactory.newReportQuery(RuleResponsibilityBo.class, responsibilityCrit);
150        query.setAttributes(new String[] { "ruleBaseValuesId" });
151        return query;
152    }
153
154    private ReportQueryByCriteria getWorkgroupResponsibilitySubQuery(Set<Long> workgroupIds) {
155            Set<String> workgroupIdStrings = new HashSet<String>();
156            for (Long workgroupId : workgroupIds) {
157                workgroupIdStrings.add(workgroupId.toString());
158            }
159        Criteria responsibilityCrit = new Criteria();
160        responsibilityCrit.addIn("ruleResponsibilityName", workgroupIds);
161        responsibilityCrit.addEqualTo("ruleResponsibilityType", KewApiConstants.RULE_RESPONSIBILITY_GROUP_ID);
162        ReportQueryByCriteria query = QueryFactory.newReportQuery(RuleResponsibilityBo.class, responsibilityCrit);
163        query.setAttributes(new String[] { "ruleBaseValuesId" });
164        return query;
165    }
166
167    private ReportQueryByCriteria getRuleBaseValuesSubQuery(String docTypeName, String ruleTemplateId,
168            String ruleDescription, Collection<String> workgroupIds,
169            String workflowId, Boolean activeInd,
170            Map<String, String> extensionValues, Collection actionRequestCodes) {
171        Criteria crit = getSearchCriteria(docTypeName, ruleTemplateId, ruleDescription, activeInd, extensionValues);
172        crit.addIn("responsibilities.ruleBaseValuesId", getResponsibilitySubQuery(workgroupIds, workflowId, actionRequestCodes, (workflowId != null), ((workgroupIds != null) && !workgroupIds.isEmpty())));
173        crit.addEqualTo("delegateRule", 1);
174        ReportQueryByCriteria query = QueryFactory.newReportQuery(RuleBaseValues.class, crit);
175        query.setAttributes(new String[] { "id" });
176        return query;
177    }
178
179    private ReportQueryByCriteria getRuleBaseValuesSubQuery(String docTypeName, String ruleId,
180            String ruleTemplateId, String ruleDescription, String workgroupId,
181            String principalId, Boolean activeInd,
182            Map<String, String> extensionValues, String workflowIdDirective) {
183        Criteria crit = getSearchCriteria(docTypeName, ruleTemplateId, ruleDescription, activeInd, extensionValues);
184        if (ruleId != null) {
185            crit.addEqualTo("id", ruleId);
186        }
187        if (workgroupId != null) {
188            crit.addIn("ruleResponsibilities.ruleBaseValuesId", getResponsibilitySubQuery(workgroupId));
189        }
190        List<String> workgroupIds = new ArrayList<String>();
191        Boolean searchUser = Boolean.FALSE;
192        Boolean searchUserInWorkgroups = Boolean.FALSE;
193        if (workflowIdDirective != null) {
194            if ("group".equals(workflowIdDirective)) {
195                searchUserInWorkgroups = Boolean.TRUE;
196            } else if ("".equals(workflowIdDirective)) {
197                searchUser = Boolean.TRUE;
198                searchUserInWorkgroups = Boolean.TRUE;
199            } else {
200                searchUser = Boolean.TRUE;
201            }
202        }
203        if (!org.apache.commons.lang.StringUtils.isEmpty(principalId) && searchUserInWorkgroups)
204        {
205            Principal principal = KimApiServiceLocator.getIdentityService().getPrincipal(principalId);
206
207            if (principal == null)
208            {
209                throw new RiceRuntimeException("Failed to locate user for the given workflow id: " + principalId);
210            }
211            workgroupIds = KimApiServiceLocator.getGroupService().getGroupIdsByPrincipalId(principalId);
212        }
213        if (CollectionUtils.isNotEmpty(workgroupIds) || StringUtils.isNotBlank(principalId)) {
214            crit.addIn("ruleResponsibilities.ruleBaseValuesId", getResponsibilitySubQuery(workgroupIds, principalId, searchUser, searchUserInWorkgroups));
215        }
216        crit.addEqualTo("delegateRule", 1);
217        ReportQueryByCriteria query = QueryFactory.newReportQuery(RuleBaseValues.class, crit);
218        query.setAttributes(new String[] { "id" });
219        return query;
220        //return (List<RuleDelegation>) this.getPersistenceBrokerTemplate().getCollectionByQuery(new QueryByCriteria(RuleDelegation.class, crit, true));
221    }
222
223    private ReportQueryByCriteria getRuleResponsibilitySubQuery(Long ruleBaseValuesId) {
224        Criteria crit = new Criteria();
225        crit.addEqualTo("ruleBaseValuesId", ruleBaseValuesId);
226        ReportQueryByCriteria query = QueryFactory.newReportQuery(RuleResponsibilityBo.class, crit);
227        query.setAttributes(new String[] { "responsibilityId" });
228        return query;
229        //return getResponsibilitySubQuery(workgroupIdStrings,workflowId,new ArrayList<String>(), searchUser, searchUserInWorkgroups);
230    }
231
232    private ReportQueryByCriteria getResponsibilitySubQuery(List<String> workgroupIds, String workflowId, Boolean searchUser, Boolean searchUserInWorkgroups) {
233        Collection<String> workgroupIdStrings = new ArrayList<String>();
234        for (String workgroupId : workgroupIds) {
235            workgroupIdStrings.add(workgroupId);
236        }
237        return getResponsibilitySubQuery(workgroupIdStrings,workflowId,new ArrayList<String>(), searchUser, searchUserInWorkgroups);
238    }
239
240    private ReportQueryByCriteria getResponsibilitySubQuery(Collection<String> workgroupIds, String workflowId, Collection<String> actionRequestCodes, Boolean searchUser, Boolean searchUserInWorkgroups) {
241        Criteria responsibilityCrit = new Criteria();
242        if ( (actionRequestCodes != null) && (!actionRequestCodes.isEmpty()) ) {
243            responsibilityCrit.addIn("actionRequestedCd", actionRequestCodes);
244        }
245
246        Criteria ruleResponsibilityNameCrit = null;
247        if (!org.apache.commons.lang.StringUtils.isEmpty(workflowId)) {
248            // workflow user id exists
249            if (searchUser != null && searchUser) {
250                // searching user wishes to search for rules specific to user
251                ruleResponsibilityNameCrit = new Criteria();
252                ruleResponsibilityNameCrit.addLike("ruleResponsibilityName", workflowId);
253                ruleResponsibilityNameCrit.addEqualTo("ruleResponsibilityType", KewApiConstants.RULE_RESPONSIBILITY_WORKFLOW_ID);
254            }
255            if ( (searchUserInWorkgroups != null && searchUserInWorkgroups) && (workgroupIds != null) && (!workgroupIds.isEmpty()) ) {
256                // at least one workgroup id exists and user wishes to search on workgroups
257                if (ruleResponsibilityNameCrit == null) {
258                    ruleResponsibilityNameCrit = new Criteria();
259                }
260                Criteria workgroupCrit = new Criteria();
261                workgroupCrit.addIn("ruleResponsibilityName", workgroupIds);
262                workgroupCrit.addEqualTo("ruleResponsibilityType", KewApiConstants.RULE_RESPONSIBILITY_GROUP_ID);
263                ruleResponsibilityNameCrit.addOrCriteria(workgroupCrit);
264            }
265        } else if ( (workgroupIds != null) && (workgroupIds.size() == 1) ) {
266            // no user and one workgroup id
267            ruleResponsibilityNameCrit = new Criteria();
268            ruleResponsibilityNameCrit.addLike("ruleResponsibilityName", workgroupIds.iterator().next());
269            ruleResponsibilityNameCrit.addEqualTo("ruleResponsibilityType", KewApiConstants.RULE_RESPONSIBILITY_GROUP_ID);
270        } else if ( (workgroupIds != null) && (workgroupIds.size() > 1) ) {
271            // no user and more than one workgroup id
272            ruleResponsibilityNameCrit = new Criteria();
273            ruleResponsibilityNameCrit.addIn("ruleResponsibilityName", workgroupIds);
274            ruleResponsibilityNameCrit.addEqualTo("ruleResponsibilityType", KewApiConstants.RULE_RESPONSIBILITY_GROUP_ID);
275        }
276        if (ruleResponsibilityNameCrit != null) {
277            responsibilityCrit.addAndCriteria(ruleResponsibilityNameCrit);
278        }
279
280        ReportQueryByCriteria query = QueryFactory.newReportQuery(RuleResponsibilityBo.class, responsibilityCrit);
281        query.setAttributes(new String[] { "ruleBaseValuesId" });
282        return query;
283    }
284
285
286    private Criteria getSearchCriteria(String docTypeName, String ruleTemplateId, String ruleDescription, Boolean activeInd, Map<String, String> extensionValues) {
287        Criteria crit = new Criteria();
288        crit.addEqualTo("currentInd", Boolean.TRUE);
289        crit.addEqualTo("templateRuleInd", Boolean.FALSE);
290        if (activeInd != null) {
291            crit.addEqualTo("active", activeInd);
292        }
293        if (docTypeName != null) {
294            crit.addLike("UPPER(docTypeName)", docTypeName.toUpperCase());
295        }
296        if (ruleDescription != null && !ruleDescription.trim().equals("")) {
297            crit.addLike("UPPER(description)", ruleDescription.toUpperCase());
298        }
299        if (ruleTemplateId != null) {
300            crit.addEqualTo("ruleTemplateId", ruleTemplateId);
301        }
302        if (extensionValues != null && !extensionValues.isEmpty()) {
303            for (Map.Entry<String,String> entry : extensionValues.entrySet()) {
304                if (!org.apache.commons.lang.StringUtils.isEmpty(entry.getValue())) {
305                    // Criteria extensionCrit = new Criteria();
306                    // extensionCrit.addEqualTo("extensionValues.key",
307                    // entry.getKey());
308                    // extensionCrit.addLike("extensionValues.value",
309                    // "%"+(String) entry.getValue()+"%");
310
311                    Criteria extensionCrit2 = new Criteria();
312                    extensionCrit2.addEqualTo("extensionValues.key", entry.getKey());
313                    extensionCrit2.addLike("UPPER(extensionValues.value)", ("%" + (String) entry.getValue() + "%").toUpperCase());
314
315                    // Criteria extensionCrit3 = new Criteria();
316                    // extensionCrit3.addEqualTo("extensionValues.key",
317                    // entry.getKey());
318                    // extensionCrit3.addLike("extensionValues.value",
319                    // ("%"+(String) entry.getValue()+"%").toLowerCase());
320
321                    // extensionCrit.addOrCriteria(extensionCrit2);
322                    // extensionCrit.addOrCriteria(extensionCrit3);
323                    ReportQueryByCriteria query = QueryFactory.newReportQuery(RuleExtensionBo.class, extensionCrit2);
324                    query.setAttributes(new String[] { "ruleBaseValuesId" });
325                    crit.addIn("ruleExtensions.ruleBaseValuesId", query);
326                }
327            }
328        }
329        return crit;
330    }
331}