View Javadoc
1   /**
2    * Copyright 2005-2014 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.lang.StringUtils;
19  import org.apache.log4j.Logger;
20  import org.joda.time.DateTime;
21  import org.kuali.rice.core.api.criteria.Predicate;
22  import org.kuali.rice.core.api.criteria.QueryByCriteria;
23  import org.kuali.rice.core.api.criteria.QueryResults;
24  import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
25  import org.kuali.rice.core.api.exception.RiceIllegalStateException;
26  import org.kuali.rice.kew.api.KewApiServiceLocator;
27  import org.kuali.rice.kew.api.doctype.DocumentTypeService;
28  import org.kuali.rice.kew.api.rule.Rule;
29  import org.kuali.rice.kew.api.rule.RuleDelegation;
30  import org.kuali.rice.kew.api.rule.RuleQueryResults;
31  import org.kuali.rice.kew.api.rule.RuleReportCriteria;
32  import org.kuali.rice.kew.api.rule.RuleResponsibility;
33  import org.kuali.rice.kew.api.rule.RuleService;
34  import org.kuali.rice.kew.api.rule.RuleTemplate;
35  import org.kuali.rice.kew.api.rule.RuleTemplateQueryResults;
36  import org.kuali.rice.kew.rule.RuleBaseValues;
37  import org.kuali.rice.kew.rule.RuleDelegationBo;
38  import org.kuali.rice.kew.rule.RuleResponsibilityBo;
39  import org.kuali.rice.kew.rule.bo.RuleTemplateBo;
40  import org.kuali.rice.kew.service.KEWServiceLocator;
41  import org.kuali.rice.kim.impl.common.attribute.AttributeTransform;
42  import org.kuali.rice.krad.data.DataObjectService;
43  
44  import javax.jws.WebParam;
45  import java.util.ArrayList;
46  import java.util.Collection;
47  import java.util.List;
48  
49  import static org.kuali.rice.core.api.criteria.PredicateFactory.*;
50  
51  
52  /**
53   *
54   * @author Kuali Rice Team (rice.collab@kuali.org)
55   *
56   */
57  public class RuleServiceImpl implements RuleService {
58  
59      private static final Logger LOG = Logger.getLogger(RuleServiceImpl.class);
60  
61      private DataObjectService dataObjectService;
62  
63      @Override
64      public Rule getRule(String id) throws RiceIllegalArgumentException, RiceIllegalStateException{
65          incomingParamCheck("id", id);
66          RuleBaseValues rbv = getDataObjectService().find(RuleBaseValues.class, id);
67          if (rbv == null) {
68              throw new RiceIllegalStateException("Rule with specified id: " + id + " does not exist");
69          }
70          return RuleBaseValues.to(rbv);
71      }
72  
73      @Override
74      public Rule getRuleByName(String name) {
75          incomingParamCheck("name", name);
76          QueryByCriteria.Builder builder = QueryByCriteria.Builder.create();
77          builder.setPredicates(
78                  equal("name", name),
79                  equal("currentInd", Boolean.TRUE)
80          );
81          QueryResults<RuleBaseValues> results = getDataObjectService().findMatching(RuleBaseValues.class, builder.build());
82          if (results.getResults().isEmpty()) {
83              throw new RiceIllegalStateException("Rule with specified name: " + name + " does not exist");
84          }
85          if (results.getResults().size() > 1) {
86              throw new RiceIllegalStateException("Found more than one current rule with specified name " + name);
87          }
88          return RuleBaseValues.to(results.getResults().get(0));
89      }
90  
91      @Override
92      public List<Rule> getRulesByTemplateId(
93              @WebParam(name = "templateId") String templateId) throws RiceIllegalArgumentException {
94          incomingParamCheck("templateId", templateId);
95          QueryByCriteria.Builder builder = QueryByCriteria.Builder.create();
96          builder.setPredicates(equal("ruleTemplateId", templateId), equal("currentInd", Boolean.TRUE));
97          QueryResults<RuleBaseValues> results = getDataObjectService().findMatching(RuleBaseValues.class, builder.build());
98          final List<Rule> rules = new ArrayList<Rule>();
99          for (RuleBaseValues bo : results.getResults()) {
100             rules.add(Rule.Builder.create(bo).build());
101         }
102         return rules;
103     }
104 
105     @Override
106     public List<Rule> getRulesByTemplateNameAndDocumentTypeName(String templateName, String documentTypeName) {
107         return getRulesByTemplateNameAndDocumentTypeNameAndEffectiveDate(templateName, documentTypeName, null);
108     }
109 
110     @Override
111     public List<Rule> getRulesByTemplateNameAndDocumentTypeNameAndEffectiveDate(String templateName, String documentTypeName,
112             DateTime effectiveDate)
113             throws RiceIllegalArgumentException {
114         QueryByCriteria.Builder query = QueryByCriteria.Builder.create();
115         List<Predicate> predicates = new ArrayList<Predicate>();
116         predicates.add(equal("ruleTemplate.name", templateName));
117 
118         // Check all document types in ancestry
119         DocumentTypeService documentTypeService = KewApiServiceLocator.getDocumentTypeService();
120         org.kuali.rice.kew.api.doctype.DocumentType dt = documentTypeService.getDocumentTypeByName(documentTypeName);
121         List<String> documentTypeAncestryNames = new ArrayList<String>();
122         while (dt != null) {
123             documentTypeAncestryNames.add(dt.getName());
124             dt = dt.getParentId() == null ? null : documentTypeService.getDocumentTypeById(dt.getParentId());
125         }
126         predicates.add(in("docTypeName", documentTypeAncestryNames.toArray(
127                 new String[documentTypeAncestryNames.size()])));
128         DateTime currentTime = new DateTime();
129         predicates.add(and(
130                            or(isNull("fromDateValue"), lessThanOrEqual("fromDateValue", currentTime)),
131                            or(isNull("toDateValue"), greaterThan("toDateValue", currentTime))
132                       ));
133         predicates.add(equal("active", Boolean.TRUE));
134         predicates.add(equal("delegateRule", Boolean.FALSE));
135         predicates.add(equal("templateRuleInd", Boolean.FALSE));
136         if (effectiveDate != null) {
137             predicates.add(
138                     and(
139                         or(isNull("activationDate"), lessThanOrEqual("activationDate", effectiveDate)),
140                         or(isNull("deactivationDate"), greaterThan("deactivationDate", effectiveDate))
141                     ));
142         } else {
143             predicates.add(equal("currentInd", Boolean.TRUE));
144         }
145         Predicate p = and(predicates.toArray(new Predicate[]{}));
146         query.setPredicates(p);
147         return KewApiServiceLocator.getRuleService().findRules(query.build()).getResults();
148     }
149 
150     @Override
151     public RuleQueryResults findRules(QueryByCriteria queryByCriteria) {
152         if (queryByCriteria == null) {
153             throw new RiceIllegalArgumentException("queryByCriteria is null");
154         }
155 
156         QueryResults<RuleBaseValues> results = dataObjectService.findMatching(RuleBaseValues.class,
157                 AttributeTransform.getInstance().apply(queryByCriteria));
158 
159         RuleQueryResults.Builder builder = RuleQueryResults.Builder.create();
160         builder.setMoreResultsAvailable(results.isMoreResultsAvailable());
161         builder.setTotalRowCount(results.getTotalRowCount());
162 
163         final List<Rule.Builder> ims = new ArrayList<Rule.Builder>();
164         for (RuleBaseValues bo : results.getResults()) {
165             ims.add(Rule.Builder.create(RuleBaseValues.to(bo)));
166         }
167 
168         builder.setResults(ims);
169         return builder.build();
170     }
171 
172     @Override
173     public List<Rule> ruleReport(RuleReportCriteria ruleReportCriteria) {
174         incomingParamCheck(ruleReportCriteria, "ruleReportCriteria");
175         if ( LOG.isDebugEnabled() ) {
176         	LOG.debug("Executing rule report [responsibleUser=" + ruleReportCriteria.getResponsiblePrincipalId() + ", responsibleWorkgroup=" +
177                     ruleReportCriteria.getResponsibleGroupId() + "]");
178         }
179         Collection<RuleBaseValues> rulesFound = KEWServiceLocator.getRuleService().searchByTemplate(
180                 ruleReportCriteria.getDocumentTypeName(), ruleReportCriteria.getRuleTemplateName(),
181                 ruleReportCriteria.getRuleDescription(), ruleReportCriteria.getResponsibleGroupId(),
182                 ruleReportCriteria.getResponsiblePrincipalId(), Boolean.valueOf(ruleReportCriteria.isConsiderGroupMembership()),
183                 Boolean.valueOf(ruleReportCriteria.isIncludeDelegations()), Boolean.valueOf(ruleReportCriteria.isActive()), ruleReportCriteria.getRuleExtensions(),
184                 ruleReportCriteria.getActionRequestCodes());
185         List<org.kuali.rice.kew.api.rule.Rule> returnableRules = new ArrayList<Rule>(rulesFound.size());
186         for (RuleBaseValues rule : rulesFound) {
187             returnableRules.add(RuleBaseValues.to(rule));
188         }
189         return returnableRules;
190     }
191 
192     @Override
193     public RuleTemplate getRuleTemplate(@WebParam(name = "id") String id) {
194         incomingParamCheck("id", id);
195         RuleTemplateBo template = dataObjectService.find(RuleTemplateBo.class, id);
196         if (template == null) {
197             throw new RiceIllegalStateException("RuleTemplate with specified id: " + id + " does not exist");
198         }
199         return RuleTemplateBo.to(template);
200     }
201 
202     @Override
203     public RuleTemplate getRuleTemplateByName(@WebParam(name = "name") String name) {
204         incomingParamCheck("name", name);
205         QueryByCriteria.Builder builder = QueryByCriteria.Builder.create();
206         builder.setPredicates(equal("name", name));
207         QueryResults<RuleTemplateBo> results = dataObjectService.findMatching(RuleTemplateBo.class, builder.build());
208         if (results.getResults().isEmpty()) {
209             throw new RiceIllegalStateException("Rule Template with specified name: " + name + " does not exist");
210         }
211         if (results.getResults().size() > 1) {
212             throw new RiceIllegalStateException("Found more than one rule template with specified name " + name);
213         }
214         return RuleTemplateBo.to(results.getResults().get(0));
215     }
216 
217     @Override
218     public RuleTemplateQueryResults findRuleTemplates(
219             @WebParam(name = "query") QueryByCriteria queryByCriteria) throws RiceIllegalArgumentException {
220         if (queryByCriteria == null) {
221             throw new RiceIllegalArgumentException("queryByCriteria is null");
222         }
223 
224         QueryResults<RuleTemplateBo> results = dataObjectService.findMatching(RuleTemplateBo.class,
225                 AttributeTransform.getInstance().apply(queryByCriteria));
226 
227         RuleTemplateQueryResults.Builder builder = RuleTemplateQueryResults.Builder.create();
228         builder.setMoreResultsAvailable(results.isMoreResultsAvailable());
229         builder.setTotalRowCount(results.getTotalRowCount());
230 
231         final List<RuleTemplate.Builder> ims = new ArrayList<RuleTemplate.Builder>();
232         for (RuleTemplateBo bo : results.getResults()) {
233             ims.add(RuleTemplate.Builder.create(RuleTemplateBo.to(bo)));
234         }
235 
236         builder.setResults(ims);
237         return builder.build();
238     }
239 
240     @Override
241     public RuleResponsibility getRuleResponsibility(String responsibilityId) {
242         incomingParamCheck("responsibilityId", responsibilityId);
243         QueryByCriteria.Builder builder = QueryByCriteria.Builder.create();
244         builder.setPredicates(equal("responsibilityId", responsibilityId));
245         QueryResults<RuleResponsibilityBo> results = dataObjectService.findMatching(RuleResponsibilityBo.class, builder.build());
246         if (results.getResults().isEmpty()) {
247             throw new RiceIllegalStateException("RuleResponsibility with specified id: " + responsibilityId + " does not exist");
248         }
249         if (results.getResults().size() > 1) {
250             throw new RiceIllegalStateException("Found more than one rule responsibility with responsibility id: " + responsibilityId);
251         }
252         return RuleResponsibilityBo.to(results.getResults().get(0));
253     }
254 
255     @Override
256     public List<RuleDelegation> getRuleDelegationsByResponsibiltityId(
257             @WebParam(name = "id") String id) throws RiceIllegalArgumentException, RiceIllegalStateException {
258         incomingParamCheck("id", id);
259         QueryByCriteria.Builder builder = QueryByCriteria.Builder.create();
260         builder.setPredicates(
261                 equal("responsibilityId", id),
262                 equal("delegationRule.currentInd", Boolean.TRUE)
263         );
264         QueryResults<RuleDelegationBo> results = dataObjectService.findMatching(RuleDelegationBo.class, builder.build());
265         List<RuleDelegation> ruleDelegations = new ArrayList<RuleDelegation>();
266         for (RuleDelegationBo bo : results.getResults()) {
267             ruleDelegations.add(RuleDelegationBo.to(bo));
268         }
269     	return ruleDelegations;
270     }
271 
272     private void incomingParamCheck(Object object, String name) {
273         if (object == null) {
274             throw new RiceIllegalArgumentException(name + " was null");
275         } else if (object instanceof String
276                 && StringUtils.isBlank((String) object)) {
277             throw new RiceIllegalArgumentException(name + " was blank");
278         }
279     }
280 
281     public DataObjectService getDataObjectService() {
282         return dataObjectService;
283     }
284 
285     public void setDataObjectService(DataObjectService dataObjectService) {
286         this.dataObjectService = dataObjectService;
287     }
288 
289 }