1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kew.rule.web;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.apache.struts.action.ActionForm;
20 import org.apache.struts.action.ActionForward;
21 import org.apache.struts.action.ActionMapping;
22 import org.apache.struts.action.ActionMessages;
23 import org.kuali.rice.kew.actionrequest.ActionRequestValue;
24 import org.kuali.rice.kew.api.KewApiConstants;
25 import org.kuali.rice.kew.api.action.ActionRequestStatus;
26 import org.kuali.rice.kew.doctype.bo.DocumentType;
27 import org.kuali.rice.kew.doctype.service.DocumentTypeService;
28 import org.kuali.rice.kew.engine.ActivationContext;
29 import org.kuali.rice.kew.engine.RouteContext;
30 import org.kuali.rice.kew.engine.node.RouteNode;
31 import org.kuali.rice.kew.engine.node.RouteNodeInstance;
32 import org.kuali.rice.kew.routeheader.AttributeDocumentContent;
33 import org.kuali.rice.kew.routeheader.DocumentContent;
34 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
35 import org.kuali.rice.kew.routelog.web.RouteLogAction;
36 import org.kuali.rice.kew.routelog.web.RouteLogForm;
37 import org.kuali.rice.kew.rule.FlexRM;
38 import org.kuali.rice.kew.rule.WorkflowRuleAttribute;
39 import org.kuali.rice.kew.rule.bo.RuleAttribute;
40 import org.kuali.rice.kew.rule.bo.RuleTemplateAttributeBo;
41 import org.kuali.rice.kew.rule.bo.RuleTemplateBo;
42 import org.kuali.rice.kew.rule.service.RuleTemplateService;
43 import org.kuali.rice.kew.rule.xmlrouting.GenericXMLRuleAttribute;
44 import org.kuali.rice.kew.service.KEWServiceLocator;
45 import org.kuali.rice.kew.api.KewApiConstants;
46 import org.kuali.rice.kew.web.KewKualiAction;
47 import org.kuali.rice.kns.web.ui.Field;
48 import org.kuali.rice.kns.web.ui.Row;
49 import org.kuali.rice.krad.UserSession;
50 import org.kuali.rice.krad.exception.ValidationException;
51 import org.kuali.rice.krad.util.GlobalVariables;
52
53 import javax.servlet.http.HttpServletRequest;
54 import javax.servlet.http.HttpServletResponse;
55 import java.sql.Timestamp;
56 import java.text.SimpleDateFormat;
57 import java.util.ArrayList;
58 import java.util.Calendar;
59 import java.util.Collections;
60 import java.util.Date;
61 import java.util.HashMap;
62 import java.util.HashSet;
63 import java.util.Iterator;
64 import java.util.List;
65 import java.util.Map;
66 import java.util.Set;
67
68
69
70
71
72
73
74 public class RoutingReportAction extends KewKualiAction {
75 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(RoutingReportAction.class);
76
77 public static final String DOC_TYPE_REPORTING = "documentType";
78 public static final String TEMPLATE_REPORTING = "template";
79
80 @Override
81 public ActionForward execute(ActionMapping mapping, ActionForm form,
82 HttpServletRequest request, HttpServletResponse response)
83 throws Exception {
84 this.initiateForm(request, form);
85 RoutingReportForm routingForm = (RoutingReportForm)form;
86 if (org.apache.commons.lang.StringUtils.isEmpty(routingForm.getDateRef())) {
87 SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
88 routingForm.setEffectiveHour("5");
89 routingForm.setEffectiveMinute("0");
90 routingForm.setAmPm("1");
91 routingForm.setDateRef(sdf.format(new Date()));
92 routingForm.setReportType(TEMPLATE_REPORTING);
93 }
94 if (DOC_TYPE_REPORTING.equals(routingForm.getReportType())) {
95 if (org.apache.commons.lang.StringUtils.isEmpty(routingForm.getDocumentTypeParam())) {
96 throw new RuntimeException("No document type was given");
97 }
98 if (org.apache.commons.lang.StringUtils.isEmpty(routingForm.getInitiatorPrincipalId())) {
99 throw new RuntimeException("No initiator principal id was given");
100 }
101 if (org.apache.commons.lang.StringUtils.isEmpty(routingForm.getDocumentContent())) {
102 throw new RuntimeException("No document content was given");
103 }
104 } else if (!(TEMPLATE_REPORTING.equals(routingForm.getReportType()))) {
105
106 throw new RuntimeException("The Routing Report type is not set");
107 }
108 return super.execute(mapping, form, request, response);
109 }
110
111 public ActionForward calculateRoute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
112 RoutingReportForm routingForm = (RoutingReportForm) form;
113
114 List errors = new ArrayList();
115
116 if (getDocumentTypeService().findByName(routingForm.getDocumentType()) == null) {
117 GlobalVariables.getMessageMap().putError("Document type is required.", "doctype.documenttypeservice.doctypename.required");
118 }
119 Timestamp date = null;
120 if (!org.apache.commons.lang.StringUtils.isEmpty(routingForm.getDateRef())) {
121 SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
122 try {
123 Calendar calendar = Calendar.getInstance();
124 calendar.setTime(sdf.parse(routingForm.getDateRef()));
125 calendar.set(Calendar.HOUR, Integer.parseInt(routingForm.getEffectiveHour()));
126 calendar.set(Calendar.MINUTE, Integer.parseInt(routingForm.getEffectiveMinute()));
127 calendar.set(Calendar.AM_PM, Integer.parseInt(routingForm.getAmPm()));
128 date = new Timestamp(calendar.getTimeInMillis());
129 } catch (Exception e) {
130 LOG.error("error parsing date", e);
131 GlobalVariables.getMessageMap().putError("Invalid date.", "routereport.effectiveDate.invalid");
132 }
133 }
134
135 if (!GlobalVariables.getMessageMap().hasNoErrors()) {
136 throw new ValidationException("Errors populating rule attributes.");
137 }
138
139 DocumentTypeService documentTypeService = (DocumentTypeService) KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_TYPE_SERVICE);
140 DocumentType docType = documentTypeService.findByName(routingForm.getDocumentType());
141
142 DocumentRouteHeaderValue routeHeader = new DocumentRouteHeaderValue();
143 routeHeader.setDocumentId("");
144 routeHeader.setDocumentTypeId(docType.getDocumentTypeId());
145 routeHeader.setDocRouteLevel(new Integer(0));
146 routeHeader.setDocVersion(new Integer(KewApiConstants.DocumentContentVersions.CURRENT));
147
148 List<RouteReportRuleTemplateContainer> ruleTemplateContainers = new ArrayList<RouteReportRuleTemplateContainer>();
149 if (routingForm.getReportType().equals(DOC_TYPE_REPORTING)) {
150
151 List routeNodes = KEWServiceLocator.getRouteNodeService().getFlattenedNodes(docType, true);
152 for (Iterator iter = routeNodes.iterator(); iter.hasNext();) {
153 RouteNode routeNode = (RouteNode) iter.next();
154 if (routeNode.isFlexRM()) {
155 RuleTemplateBo ruleTemplate = getRuleTemplateService().findByRuleTemplateName(routeNode.getRouteMethodName());
156 if (ruleTemplate != null) {
157 ruleTemplateContainers.add(new RouteReportRuleTemplateContainer(ruleTemplate, routeNode));
158 if (ruleTemplate.getDelegationTemplate() != null) {
159 ruleTemplateContainers.add(new RouteReportRuleTemplateContainer(ruleTemplate.getDelegationTemplate(), routeNode));
160 }
161 }
162 }
163 }
164 } else {
165 RuleTemplateBo ruleTemplate = getRuleTemplateService().findByRuleTemplateId(routingForm.getRuleTemplateId());
166 RouteNode routeNode = new RouteNode();
167 routeNode.setRouteNodeName(ruleTemplate.getName());
168 ruleTemplateContainers.add(new RouteReportRuleTemplateContainer(ruleTemplate, routeNode));
169 if (ruleTemplate.getDelegationTemplate() != null) {
170 ruleTemplateContainers.add(new RouteReportRuleTemplateContainer(ruleTemplate.getDelegationTemplate(), routeNode));
171 }
172 }
173
174 String xmlDocumentContent = routingForm.getDocumentContent();
175 if (routingForm.getReportType().equals(TEMPLATE_REPORTING)) {
176 List<WorkflowRuleAttribute> attributes = new ArrayList<WorkflowRuleAttribute>();
177 for (RouteReportRuleTemplateContainer ruleTemplateContainer : ruleTemplateContainers) {
178 RuleTemplateBo ruleTemplate = ruleTemplateContainer.ruleTemplate;
179 for (RuleTemplateAttributeBo ruleTemplateAttribute : ruleTemplate.getActiveRuleTemplateAttributes()) {
180 if (!ruleTemplateAttribute.isWorkflowAttribute()) {
181 continue;
182 }
183 WorkflowRuleAttribute workflowAttribute = ruleTemplateAttribute.getWorkflowAttribute();
184
185 RuleAttribute ruleAttribute = ruleTemplateAttribute.getRuleAttribute();
186 if (ruleAttribute.getType().equals(KewApiConstants.RULE_XML_ATTRIBUTE_TYPE)) {
187 ((GenericXMLRuleAttribute) workflowAttribute).setExtensionDefinition(RuleAttribute.to(ruleAttribute));
188 }
189 List attValidationErrors = workflowAttribute.validateRoutingData(routingForm.getFields());
190 if (attValidationErrors != null && !attValidationErrors.isEmpty()) {
191 errors.addAll(attValidationErrors);
192 }
193 attributes.add(workflowAttribute);
194 }
195 }
196
197 if (!GlobalVariables.getMessageMap().hasNoErrors()) {
198 throw new ValidationException("errors in search criteria");
199 }
200
201 DocumentContent docContent = new AttributeDocumentContent(attributes);
202 xmlDocumentContent = docContent.getDocContent();
203 }
204
205 routeHeader.setDocContent(xmlDocumentContent);
206 routeHeader.setInitiatorWorkflowId(getUserSession(request).getPrincipalId());
207 routeHeader.setDocRouteStatus(KewApiConstants.ROUTE_HEADER_INITIATED_CD);
208 routeHeader.setDocTitle("Routing Report");
209 routeHeader.setRoutingReport(true);
210 long magicCounter = 0;
211
212 FlexRM flexRM = new FlexRM(date);
213
214 int numberOfRules = 0;
215 int numberOfActionRequests = 0;
216 Set<String> alreadyProcessedRuleTemplateNames = new HashSet<String>();
217 for (Object element : ruleTemplateContainers) {
218
219 RouteContext context = RouteContext.createNewRouteContext();
220 context.setActivationContext(new ActivationContext(ActivationContext.CONTEXT_IS_SIMULATION));
221 try {
222 RouteReportRuleTemplateContainer ruleTemplateContainer = (RouteReportRuleTemplateContainer) element;
223 RuleTemplateBo ruleTemplate = ruleTemplateContainer.ruleTemplate;
224 RouteNode routeLevel = ruleTemplateContainer.routeNode;
225
226 if (!alreadyProcessedRuleTemplateNames.contains(ruleTemplate.getName())) {
227 alreadyProcessedRuleTemplateNames.add(ruleTemplate.getName());
228 List<ActionRequestValue> actionRequests = flexRM.getActionRequests(routeHeader, routeLevel, null, ruleTemplate.getName());
229
230 numberOfActionRequests += actionRequests.size();
231 numberOfRules += flexRM.getNumberOfMatchingRules();
232
233 magicCounter = populateActionRequestsWithRouteLevelInformationAndIterateMagicCounter(routeLevel, actionRequests, magicCounter);
234
235 routeHeader.getSimulatedActionRequests().addAll(actionRequests);
236 }
237 } finally {
238 RouteContext.clearCurrentRouteContext();
239 }
240 }
241
242 if (numberOfActionRequests == 0) {
243 if (numberOfRules == 0) {
244 GlobalVariables.getMessageMap().putError("*", "routereport.noRules");
245 } else {
246 GlobalVariables.getMessageMap().putError("*", "routereport.noMatchingRules");
247 }
248 if (GlobalVariables.getMessageMap().hasErrors()) {
249 throw new ValidationException("errors in search criteria");
250 }
251 }
252
253
254
255 RouteLogForm routeLogForm = new RouteLogForm();
256 routeLogForm.setShowFuture(true);
257 if (StringUtils.isNotBlank(routingForm.getBackUrl())) {
258 routeLogForm.setReturnUrlLocation(routingForm.getBackUrl());
259 }
260 LOG.debug("Value of getDisplayCloseButton " + routingForm.getShowCloseButton());
261 LOG.debug("Value of isDisplayCloseButton " + routingForm.isDisplayCloseButton());
262 routeLogForm.setShowCloseButton(routingForm.isDisplayCloseButton());
263 request.setAttribute("routeHeader", routeHeader);
264 new RouteLogAction().populateRouteLogFormActionRequests(routeLogForm, routeHeader);
265 request.setAttribute("KualiForm", routeLogForm);
266
267
268
269 return mapping.findForward("routeLog");
270 }
271
272 private class RouteReportRuleTemplateContainer {
273 public RuleTemplateBo ruleTemplate = null;
274 public RouteNode routeNode = null;
275 public RouteReportRuleTemplateContainer(RuleTemplateBo template, RouteNode node) {
276 this.ruleTemplate = template;
277 this.routeNode = node;
278 }
279 }
280
281 public long populateActionRequestsWithRouteLevelInformationAndIterateMagicCounter(RouteNode routeLevel, List<ActionRequestValue> actionRequests, long magicCounter) {
282
283 for (ActionRequestValue actionRequest : actionRequests) {
284 populateActionRequestsWithRouteLevelInformationAndIterateMagicCounter(routeLevel, actionRequest.getChildrenRequests(), magicCounter);
285 actionRequest.setStatus(ActionRequestStatus.INITIALIZED.getCode());
286
287 RouteNodeInstance routeNode = new RouteNodeInstance();
288 routeNode.setRouteNode(routeLevel);
289 actionRequest.setNodeInstance(routeNode);
290 actionRequest.setRouteLevel(new Integer(0));
291 magicCounter++;
292 actionRequest.setActionRequestId(String.valueOf(magicCounter));
293 }
294 return magicCounter;
295 }
296
297 @Override
298 public ActionForward refresh(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
299 return mapping.findForward("basic");
300 }
301
302 private ActionMessages initiateForm(HttpServletRequest request, ActionForm form) throws Exception {
303 RoutingReportForm routingReportForm = (RoutingReportForm) form;
304 if (routingReportForm.getReportType() == null) {
305
306 if ( (!org.apache.commons.lang.StringUtils.isEmpty(routingReportForm.getDocumentTypeParam())) ||
307 (!org.apache.commons.lang.StringUtils.isEmpty(routingReportForm.getInitiatorPrincipalId())) ||
308 (!org.apache.commons.lang.StringUtils.isEmpty(routingReportForm.getDocumentContent())) ) {
309
310 routingReportForm.setReportType(DOC_TYPE_REPORTING);
311 } else {
312
313 routingReportForm.setReportType(TEMPLATE_REPORTING);
314 }
315 }
316
317 if (routingReportForm.getReportType().equals(DOC_TYPE_REPORTING)) {
318 if (org.apache.commons.lang.StringUtils.isEmpty(routingReportForm.getDocumentTypeParam())) {
319 throw new RuntimeException("Document Type was not given");
320 } else {
321 DocumentType docType = getDocumentTypeService().findByName(routingReportForm.getDocumentTypeParam());
322 if (docType == null) {
323 throw new RuntimeException("Document Type is invalid");
324 }
325 }
326 if (org.apache.commons.lang.StringUtils.isEmpty(routingReportForm.getInitiatorPrincipalId())) {
327 throw new RuntimeException("Initiator Principal ID was not given");
328 } else {
329 KEWServiceLocator.getIdentityHelperService().getPrincipal(routingReportForm.getInitiatorPrincipalId());
330 }
331 if (org.apache.commons.lang.StringUtils.isEmpty(routingReportForm.getDocumentContent())) {
332 throw new RuntimeException("Document Content was not given");
333 }
334
335 if (!org.apache.commons.lang.StringUtils.isEmpty(routingReportForm.getDocumentType())) {
336 DocumentType docType = getDocumentTypeService().findByName(routingReportForm.getDocumentType());
337 if (docType == null) {
338 throw new RuntimeException("Document Type is missing or invalid");
339 }
340 routingReportForm.getRuleTemplateAttributes().clear();
341 List<RouteNode> routeNodes = KEWServiceLocator.getRouteNodeService().getFlattenedNodes(docType, true);
342 for (RouteNode routeNode : routeNodes) {
343 if (routeNode.isFlexRM()) {
344 RuleTemplateBo ruleTemplate = getRuleTemplateService().findByRuleTemplateName(routeNode.getRouteMethodName());
345 if (ruleTemplate != null) {
346 loadRuleTemplateOnForm(ruleTemplate, routingReportForm, request, false);
347 if (ruleTemplate.getDelegationTemplate() != null) {
348 loadRuleTemplateOnForm(ruleTemplate.getDelegationTemplate(), routingReportForm, request, true);
349 }
350 }
351 }
352 }
353 }
354
355 } else if (routingReportForm.getReportType().equals(TEMPLATE_REPORTING)) {
356 routingReportForm.setRuleTemplates(getRuleTemplateService().findAll());
357 if (routingReportForm.getRuleTemplateId() != null) {
358 RuleTemplateBo ruleTemplate = getRuleTemplateService().findByRuleTemplateId(routingReportForm.getRuleTemplateId());
359 routingReportForm.getRuleTemplateAttributes().clear();
360 loadRuleTemplateOnForm(ruleTemplate, routingReportForm, request, false);
361 if (ruleTemplate.getDelegationTemplate() != null) {
362 loadRuleTemplateOnForm(ruleTemplate.getDelegationTemplate(), routingReportForm, request, true);
363 }
364 }
365 }
366 return null;
367 }
368
369 private void loadRuleTemplateOnForm(RuleTemplateBo ruleTemplate, RoutingReportForm routingReportForm, HttpServletRequest request, boolean isDelegate) {
370
371 Map<String, String> fieldValues = new HashMap<String, String>();
372
373 List<RuleTemplateAttributeBo> ruleTemplateAttributes = ruleTemplate.getActiveRuleTemplateAttributes();
374 Collections.sort(ruleTemplateAttributes);
375
376 List<Row> rows = new ArrayList<Row>();
377 for (RuleTemplateAttributeBo ruleTemplateAttribute : ruleTemplateAttributes) {
378 if (!ruleTemplateAttribute.isWorkflowAttribute()) {
379 continue;
380 }
381 WorkflowRuleAttribute workflowAttribute = ruleTemplateAttribute.getWorkflowAttribute();
382
383 RuleAttribute ruleAttribute = ruleTemplateAttribute.getRuleAttribute();
384 if (ruleAttribute.getType().equals(KewApiConstants.RULE_XML_ATTRIBUTE_TYPE)) {
385 ((GenericXMLRuleAttribute) workflowAttribute).setExtensionDefinition(RuleAttribute.to(ruleAttribute));
386 }
387 for (Row row : workflowAttribute.getRoutingDataRows()) {
388
389 List<Field> fields = new ArrayList<Field>();
390 for (Object element2 : row.getFields()) {
391 Field field = (Field) element2;
392 if (request.getParameter(field.getPropertyName()) != null) {
393 field.setPropertyValue(request.getParameter(field.getPropertyName()));
394 } else if (routingReportForm.getFields() != null && !routingReportForm.getFields().isEmpty()) {
395 field.setPropertyValue((String) routingReportForm.getFields().get(field.getPropertyName()));
396 }
397 fields.add(field);
398 fieldValues.put(field.getPropertyName(), field.getPropertyValue());
399 }
400 }
401
402 workflowAttribute.validateRuleData(fieldValues);
403 List<Row> rdRows = workflowAttribute.getRoutingDataRows();
404 for (Row row : rdRows)
405 {
406 List<Field> fields = new ArrayList<Field>();
407 List<Field> rowFields = row.getFields();
408 for (Field field : rowFields )
409 {
410 if (request.getParameter(field.getPropertyName()) != null) {
411 field.setPropertyValue(request.getParameter(field.getPropertyName()));
412 } else if (routingReportForm.getFields() != null && !routingReportForm.getFields().isEmpty()) {
413 field.setPropertyValue((String) routingReportForm.getFields().get(field.getPropertyName()));
414 }
415 fields.add(field);
416 fieldValues.put(field.getPropertyName(), field.getPropertyValue());
417 }
418 row.setFields(fields);
419 rows.add(row);
420
421 }
422 }
423
424 routingReportForm.getFields().putAll(fieldValues);
425 routingReportForm.getRuleTemplateAttributes().addAll(rows);
426 routingReportForm.setShowFields(true);
427 routingReportForm.setShowViewResults(true);
428 }
429
430 public ActionForward loadTemplate(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
431 RoutingReportForm routingReportForm = (RoutingReportForm) form;
432 if (org.apache.commons.lang.StringUtils.isEmpty(routingReportForm.getDateRef())) {
433 SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
434 routingReportForm.setEffectiveHour("5");
435 routingReportForm.setEffectiveMinute("0");
436 routingReportForm.setAmPm("1");
437 routingReportForm.setDateRef(sdf.format(new Date()));
438 }
439 return mapping.findForward("basic");
440 }
441
442 private RuleTemplateService getRuleTemplateService() {
443 return (RuleTemplateService) KEWServiceLocator.getService(KEWServiceLocator.RULE_TEMPLATE_SERVICE);
444 }
445
446 private DocumentTypeService getDocumentTypeService() {
447 return (DocumentTypeService) KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_TYPE_SERVICE);
448 }
449
450 private UserSession getUserSession(HttpServletRequest request) {
451 return GlobalVariables.getUserSession();
452 }
453
454
455
456
457 }