View Javadoc
1   /**
2    * Copyright 2005-2016 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.kew.impl.rule;
17  
18  import org.apache.commons.collections.CollectionUtils;
19  import org.apache.commons.lang.StringUtils;
20  import org.apache.log4j.Logger;
21  import org.joda.time.DateTime;
22  import org.kuali.rice.core.api.criteria.CriteriaLookupService;
23  import org.kuali.rice.core.api.criteria.GenericQueryResults;
24  import org.kuali.rice.core.api.criteria.LookupCustomizer;
25  import org.kuali.rice.core.api.criteria.Predicate;
26  import org.kuali.rice.core.api.criteria.QueryByCriteria;
27  import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
28  import org.kuali.rice.core.api.exception.RiceIllegalStateException;
29  import org.kuali.rice.core.api.util.jaxb.DateTimeAdapter;
30  import org.kuali.rice.kew.api.KewApiServiceLocator;
31  import org.kuali.rice.kew.api.doctype.DocumentTypeService;
32  import org.kuali.rice.kew.api.rule.Rule;
33  import org.kuali.rice.kew.api.rule.RuleDelegation;
34  import org.kuali.rice.kew.api.rule.RuleQueryResults;
35  import org.kuali.rice.kew.api.rule.RuleReportCriteria;
36  import org.kuali.rice.kew.api.rule.RuleResponsibility;
37  import org.kuali.rice.kew.api.rule.RuleService;
38  import org.kuali.rice.kew.api.rule.RuleTemplate;
39  import org.kuali.rice.kew.api.rule.RuleTemplateQueryResults;
40  import org.kuali.rice.kew.doctype.bo.DocumentType;
41  import org.kuali.rice.kew.rule.RuleBaseValues;
42  import org.kuali.rice.kew.rule.RuleDelegationBo;
43  import org.kuali.rice.kew.rule.RuleResponsibilityBo;
44  import org.kuali.rice.kew.rule.bo.RuleTemplateBo;
45  import org.kuali.rice.kew.service.KEWServiceLocator;
46  import org.kuali.rice.kim.impl.common.attribute.AttributeTransform;
47  import org.kuali.rice.krad.service.BusinessObjectService;
48  
49  import javax.jws.WebParam;
50  import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
51  import java.sql.Timestamp;
52  import java.util.ArrayList;
53  import java.util.Calendar;
54  import java.util.Collection;
55  import java.util.Collections;
56  import java.util.HashMap;
57  import java.util.List;
58  import java.util.Map;
59  
60  import static org.kuali.rice.core.api.criteria.PredicateFactory.*;
61  import static org.kuali.rice.core.api.criteria.PredicateFactory.and;
62  
63  /**
64   *
65   * @author Kuali Rice Team (rice.collab@kuali.org)
66   *
67   */
68  public class RuleServiceImpl implements RuleService {
69      private static final Logger LOG = Logger.getLogger(RuleServiceImpl.class);
70      //private RuleDAO ruleDAO;
71      private BusinessObjectService businessObjectService;
72      private CriteriaLookupService criteriaLookupService;
73  
74      @Override
75      public Rule getRule(String id) throws RiceIllegalArgumentException, RiceIllegalStateException{
76          incomingParamCheck("id", id);
77          Map<String, String> criteria = Collections.singletonMap("id", id);
78          RuleBaseValues rbv = this.businessObjectService.findByPrimaryKey(RuleBaseValues.class, criteria);
79          if (rbv == null) {
80              throw new RiceIllegalStateException("Rule with specified id: " + id + " does not exist");
81          }
82          return RuleBaseValues.to(rbv);
83      }
84  
85      @Override
86      public Rule getRuleByName(String name) {
87          incomingParamCheck("name", name);
88          Map<String, Object> criteria = new HashMap<String, Object>(2);
89          criteria.put("name", name);
90          criteria.put("currentInd", Boolean.TRUE);
91          RuleBaseValues rbv = this.businessObjectService.findByPrimaryKey(RuleBaseValues.class, criteria);
92          if (rbv == null) {
93              throw new RiceIllegalStateException("Rule with specified name: " + name + " does not exist");
94          }
95          return RuleBaseValues.to(rbv);
96      }
97  
98      @Override
99      public List<Rule> getRulesByTemplateId(
100             @WebParam(name = "templateId") String templateId) throws RiceIllegalArgumentException {
101         incomingParamCheck("templateId", templateId);
102         Map<String, Object> criteria = new HashMap<String, Object>();
103         criteria.put("ruleTemplateId", templateId);
104         criteria.put("currentInd", Boolean.TRUE);
105         Collection<RuleBaseValues> ruleValues = this.businessObjectService.findMatching(RuleBaseValues.class, criteria);
106 
107         final List<Rule> rules = new ArrayList<Rule>();
108         for (RuleBaseValues bo : ruleValues) {
109             rules.add(Rule.Builder.create(bo).build());
110         }
111         return rules;
112     }
113 
114     @Override
115     public List<Rule> getRulesByTemplateNameAndDocumentTypeName(String templateName, String documentTypeName) {
116         return getRulesByTemplateNameAndDocumentTypeNameAndEffectiveDate(templateName, documentTypeName, null);
117     }
118 
119     @Override
120     public List<Rule> getRulesByTemplateNameAndDocumentTypeNameAndEffectiveDate(String templateName, String documentTypeName,
121             DateTime effectiveDate)
122             throws RiceIllegalArgumentException {
123         QueryByCriteria.Builder query = QueryByCriteria.Builder.create();
124         List<Predicate> predicates = new ArrayList<Predicate>();
125         predicates.add(equal("ruleTemplate.name", templateName));
126 
127         // Check all document types in ancestry
128         DocumentTypeService documentTypeService = KewApiServiceLocator.getDocumentTypeService();
129         org.kuali.rice.kew.api.doctype.DocumentType dt = documentTypeService.getDocumentTypeByName(documentTypeName);
130         List<String> documentTypeAncestryNames = new ArrayList<String>();
131         while (dt != null) {
132             documentTypeAncestryNames.add(dt.getName());
133             dt = dt.getParentId() == null ? null : documentTypeService.getDocumentTypeById(dt.getParentId());
134         }
135         predicates.add(in("docTypeName", documentTypeAncestryNames.toArray(
136                 new String[documentTypeAncestryNames.size()])));
137         DateTime currentTime = new DateTime();
138         predicates.add(and(
139                            or(isNull("fromDateValue"), lessThanOrEqual("fromDateValue", currentTime)),
140                            or(isNull("toDateValue"), greaterThan("toDateValue", currentTime))
141                       ));
142         predicates.add(equal("active", new Integer(1))); //true
143         predicates.add(equal("delegateRule", new Integer(0)));  //false
144         predicates.add(equal("templateRuleInd", new Integer(0))); //false
145         if (effectiveDate != null) {
146             predicates.add(
147                     and(
148                         or(isNull("activationDate"), lessThanOrEqual("activationDate", effectiveDate)),
149                         or(isNull("deactivationDate"), greaterThan("deactivationDate", effectiveDate))
150                     ));
151         } else {
152             predicates.add(equal("currentInd", new Integer(1))); //true
153         }
154         Predicate p = and(predicates.toArray(new Predicate[]{}));
155         query.setPredicates(p);
156         return KewApiServiceLocator.getRuleService().findRules(query.build()).getResults();
157     }
158 
159     @Override
160     public RuleQueryResults findRules(QueryByCriteria queryByCriteria) {
161         if (queryByCriteria == null) {
162             throw new RiceIllegalArgumentException("queryByCriteria is null");
163         }
164 
165         LookupCustomizer.Builder<RuleBaseValues> lc = LookupCustomizer.Builder.create();
166         lc.setPredicateTransform(AttributeTransform.getInstance());
167 
168         GenericQueryResults<RuleBaseValues> results = criteriaLookupService.lookup(RuleBaseValues.class, queryByCriteria, lc.build());
169 
170         RuleQueryResults.Builder builder = RuleQueryResults.Builder.create();
171         builder.setMoreResultsAvailable(results.isMoreResultsAvailable());
172         builder.setTotalRowCount(results.getTotalRowCount());
173 
174         final List<Rule.Builder> ims = new ArrayList<Rule.Builder>();
175         for (RuleBaseValues bo : results.getResults()) {
176             ims.add(Rule.Builder.create(RuleBaseValues.to(bo)));
177         }
178 
179         builder.setResults(ims);
180         return builder.build();
181     }
182 
183     @Override
184     public List<Rule> ruleReport(RuleReportCriteria ruleReportCriteria) {
185         incomingParamCheck(ruleReportCriteria, "ruleReportCriteria");
186         if ( LOG.isDebugEnabled() ) {
187         	LOG.debug("Executing rule report [responsibleUser=" + ruleReportCriteria.getResponsiblePrincipalId() + ", responsibleWorkgroup=" +
188                     ruleReportCriteria.getResponsibleGroupId() + "]");
189         }
190         Collection<RuleBaseValues> rulesFound = KEWServiceLocator.getRuleService().searchByTemplate(
191                 ruleReportCriteria.getDocumentTypeName(), ruleReportCriteria.getRuleTemplateName(),
192                 ruleReportCriteria.getRuleDescription(), ruleReportCriteria.getResponsibleGroupId(),
193                 ruleReportCriteria.getResponsiblePrincipalId(), Boolean.valueOf(ruleReportCriteria.isConsiderGroupMembership()),
194                 Boolean.valueOf(ruleReportCriteria.isIncludeDelegations()), Boolean.valueOf(ruleReportCriteria.isActive()), ruleReportCriteria.getRuleExtensions(),
195                 ruleReportCriteria.getActionRequestCodes());
196         List<org.kuali.rice.kew.api.rule.Rule> returnableRules = new ArrayList<Rule>(rulesFound.size());
197         for (RuleBaseValues rule : rulesFound) {
198             returnableRules.add(RuleBaseValues.to(rule));
199         }
200         return returnableRules;
201     }
202 
203     @Override
204     public RuleTemplate getRuleTemplate(@WebParam(name = "id") String id) {
205         incomingParamCheck("id", id);
206         Map<String, String> criteria = Collections.singletonMap("id", id);
207         RuleTemplateBo template = this.businessObjectService.findByPrimaryKey(RuleTemplateBo.class, criteria);
208         if (template == null) {
209             throw new RiceIllegalStateException("RuleTemplate with specified id: " + id + " does not exist");
210         }
211         return RuleTemplateBo.to(template);
212     }
213 
214     @Override
215     public RuleTemplate getRuleTemplateByName(@WebParam(name = "name") String name) {
216         incomingParamCheck("name", name);
217         Map<String, Object> criteria = new HashMap<String, Object>(2);
218         criteria.put("name", name);
219         RuleTemplateBo template = this.businessObjectService.findByPrimaryKey(RuleTemplateBo.class, criteria);
220         if (template == null) {
221             throw new RiceIllegalStateException("RuleTemplate with specified name: " + name + " does not exist");
222         }
223         return RuleTemplateBo.to(template);
224     }
225 
226     @Override
227     public RuleTemplateQueryResults findRuleTemplates(
228             @WebParam(name = "query") QueryByCriteria queryByCriteria) throws RiceIllegalArgumentException {
229         if (queryByCriteria == null) {
230             throw new RiceIllegalArgumentException("queryByCriteria is null");
231         }
232 
233         LookupCustomizer.Builder<RuleTemplateBo> lc = LookupCustomizer.Builder.create();
234         lc.setPredicateTransform(AttributeTransform.getInstance());
235 
236         GenericQueryResults<RuleTemplateBo> results = criteriaLookupService.lookup(RuleTemplateBo.class, queryByCriteria, lc.build());
237 
238         RuleTemplateQueryResults.Builder builder = RuleTemplateQueryResults.Builder.create();
239         builder.setMoreResultsAvailable(results.isMoreResultsAvailable());
240         builder.setTotalRowCount(results.getTotalRowCount());
241 
242         final List<RuleTemplate.Builder> ims = new ArrayList<RuleTemplate.Builder>();
243         for (RuleTemplateBo bo : results.getResults()) {
244             ims.add(RuleTemplate.Builder.create(RuleTemplateBo.to(bo)));
245         }
246 
247         builder.setResults(ims);
248         return builder.build();
249     }
250 
251     @Override
252     public RuleResponsibility getRuleResponsibility(String responsibilityId) {
253         incomingParamCheck("responsibilityId", responsibilityId);
254         Map<String, String> criteria = Collections.singletonMap("responsibilityId", responsibilityId);
255         RuleResponsibilityBo responsibility = this.businessObjectService.findByPrimaryKey(RuleResponsibilityBo.class, criteria);
256         if (responsibility == null) {
257             throw new RiceIllegalStateException("RuleResponsibility with specified id: " + responsibilityId + " does not exist");
258         }
259         return RuleResponsibilityBo.to(responsibility);
260     }
261 
262     @Override
263     public List<RuleDelegation> getRuleDelegationsByResponsibiltityId(
264             @WebParam(name = "id") String id) throws RiceIllegalArgumentException, RiceIllegalStateException {
265         incomingParamCheck("id", id);
266         Map<String, Object> criteria = new HashMap<String, Object>(2);
267     	criteria.put("responsibilityId", id);
268     	criteria.put("delegationRule.currentInd", Boolean.TRUE);
269     	Collection<RuleDelegationBo> delegations = this.businessObjectService.findMatching(RuleDelegationBo.class,
270                 criteria);
271         List<RuleDelegation> ruleDelegations = new ArrayList<RuleDelegation>();
272         if (CollectionUtils.isNotEmpty(delegations)) {
273             for (RuleDelegationBo bo : delegations) {
274                 ruleDelegations.add(RuleDelegationBo.to(bo));
275             }
276         }
277 
278     	return ruleDelegations;
279 
280     }
281 
282     private void incomingParamCheck(Object object, String name) {
283         if (object == null) {
284             throw new RiceIllegalArgumentException(name + " was null");
285         } else if (object instanceof String
286                 && StringUtils.isBlank((String) object)) {
287             throw new RiceIllegalArgumentException(name + " was blank");
288         }
289     }
290 
291     public BusinessObjectService getBusinessObjectService() {
292         return this.businessObjectService;
293     }
294 
295     public void setBusinessObjectService(BusinessObjectService businessObjectService) {
296         this.businessObjectService = businessObjectService;
297     }
298 
299     public CriteriaLookupService getCriteriaLookupService() {
300         return this.criteriaLookupService;
301     }
302 
303     public void setCriteriaLookupService(CriteriaLookupService criteriaLookupService) {
304         this.criteriaLookupService = criteriaLookupService;
305     }
306 }