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