View Javadoc

1   /*
2    * Copyright 2005-2007 The Kuali Foundation
3    *
4    *
5    * Licensed under the Educational Community License, Version 2.0 (the "License");
6    * you may not use this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    *
9    * http://www.opensource.org/licenses/ecl2.php
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.kuali.rice.kew.documentoperation.web;
18  
19  import org.apache.commons.lang.StringUtils;
20  import org.apache.struts.action.ActionForm;
21  import org.apache.struts.action.ActionForward;
22  import org.apache.struts.action.ActionMapping;
23  import org.apache.struts.action.ActionMessage;
24  import org.apache.struts.action.ActionMessages;
25  import org.kuali.rice.core.util.RiceConstants;
26  import org.kuali.rice.core.util.RiceKeyConstants;
27  import org.kuali.rice.kew.actionitem.ActionItem;
28  import org.kuali.rice.kew.actionlist.service.ActionListService;
29  import org.kuali.rice.kew.actionrequest.ActionRequestValue;
30  import org.kuali.rice.kew.actionrequest.service.ActionRequestService;
31  import org.kuali.rice.kew.actionrequest.service.DocumentRequeuerService;
32  import org.kuali.rice.kew.actions.asyncservices.ActionInvocation;
33  import org.kuali.rice.kew.actions.asyncservices.ActionInvocationService;
34  import org.kuali.rice.kew.actions.asyncservices.BlanketApproveProcessorService;
35  import org.kuali.rice.kew.actions.asyncservices.MoveDocumentService;
36  import org.kuali.rice.kew.actiontaken.ActionTakenValue;
37  import org.kuali.rice.kew.actiontaken.service.ActionTakenService;
38  import org.kuali.rice.kew.api.WorkflowDocument;
39  import org.kuali.rice.kew.api.WorkflowDocumentFactory;
40  import org.kuali.rice.kew.api.WorkflowRuntimeException;
41  import org.kuali.rice.kew.docsearch.service.SearchableAttributeProcessingService;
42  import org.kuali.rice.kew.doctype.bo.DocumentType;
43  import org.kuali.rice.kew.doctype.service.DocumentTypeService;
44  import org.kuali.rice.kew.engine.node.Branch;
45  import org.kuali.rice.kew.engine.node.BranchState;
46  import org.kuali.rice.kew.engine.node.NodeState;
47  import org.kuali.rice.kew.engine.node.RouteNodeInstance;
48  import org.kuali.rice.kew.engine.node.service.BranchService;
49  import org.kuali.rice.kew.engine.node.service.RouteNodeService;
50  import org.kuali.rice.kew.exception.WorkflowServiceErrorException;
51  import org.kuali.rice.kew.exception.WorkflowServiceErrorImpl;
52  import org.kuali.rice.kew.messaging.MessageServiceNames;
53  import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
54  import org.kuali.rice.kew.routeheader.service.RouteHeaderService;
55  import org.kuali.rice.kew.rule.bo.RuleTemplate;
56  import org.kuali.rice.kew.service.KEWServiceLocator;
57  import org.kuali.rice.kew.util.KEWConstants;
58  import org.kuali.rice.kew.web.KewKualiAction;
59  import org.kuali.rice.kim.api.identity.principal.Principal;
60  import org.kuali.rice.kim.api.services.KimApiServiceLocator;
61  import org.kuali.rice.krad.util.GlobalVariables;
62  import org.kuali.rice.ksb.messaging.service.KSBXMLService;
63  
64  import javax.servlet.ServletException;
65  import javax.servlet.http.HttpServletRequest;
66  import javax.servlet.http.HttpServletResponse;
67  import java.io.IOException;
68  import java.sql.Timestamp;
69  import java.text.ParseException;
70  import java.util.ArrayList;
71  import java.util.HashMap;
72  import java.util.HashSet;
73  import java.util.Iterator;
74  import java.util.List;
75  import java.util.Map;
76  import java.util.Set;
77  import java.util.StringTokenizer;
78  
79  
80  /**
81   * Struts Action for doing editing of workflow documents.
82   *
83   * @author Kuali Rice Team (rice.collab@kuali.org)
84   */
85  public class DocumentOperationAction extends KewKualiAction {
86  	private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DocumentOperationAction.class);
87  	private static final String DEFAULT_LOG_MSG = "Admin change via document operation";
88  
89  	public ActionForward start(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
90  		return mapping.findForward("basic");
91  	}
92  
93  	public ActionForward getDocument(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
94  		DocumentOperationForm docForm = (DocumentOperationForm) form;
95  		String docId = null;
96  		
97  		// check if we have a plausible docId first
98  		if (StringUtils.isEmpty(docForm.getDocumentId())) {
99  			GlobalVariables.getMessageMap().putError("documentId", RiceKeyConstants.ERROR_REQUIRED, "Document ID");
100 		} else {
101 			try {
102 				docId = docForm.getDocumentId().trim();
103 			} catch (NumberFormatException nfe) {
104 				GlobalVariables.getMessageMap().putError("documentId", RiceKeyConstants.ERROR_NUMERIC, "Document ID");
105 			}
106 		}
107 
108 		if (docId != null) {
109 			//to clear Document Field first;
110 			docForm.resetOps();
111 			DocumentRouteHeaderValue routeHeader = getRouteHeaderService().getRouteHeader(docId);
112 			List routeNodeInstances=getRouteNodeService().findRouteNodeInstances(docId);
113 			Map branches1=new HashMap();
114 			List branches=new ArrayList();
115 
116 			if (routeHeader == null) {
117 				GlobalVariables.getMessageMap().putError("documentId", RiceKeyConstants.ERROR_EXISTENCE, "document");
118 			} else {
119 				materializeDocument(routeHeader);
120 				docForm.setRouteHeader(routeHeader);
121 				setRouteHeaderTimestampsToString(docForm);
122 				docForm.setRouteHeaderOp(KEWConstants.NOOP);
123 				docForm.setDocumentId(docForm.getDocumentId().trim());
124 				String initials="";
125 				for(Iterator lInitials=routeHeader.getInitialRouteNodeInstances().iterator();lInitials.hasNext();){
126 					String initial=((RouteNodeInstance)lInitials.next()).getRouteNodeInstanceId();
127 					LOG.debug(initial);
128 					initials=initials+initial+", ";
129 				}
130 				if(initials.trim().length()>1){
131 					initials=initials.substring(0,initials.lastIndexOf(","));
132 				}
133 				docForm.setInitialNodeInstances(initials);
134 				request.getSession().setAttribute("routeNodeInstances",routeNodeInstances);
135 				docForm.setRouteNodeInstances(routeNodeInstances);
136 				if(routeNodeInstances!=null){
137 					Iterator routeNodeInstanceIter=routeNodeInstances.iterator();
138 					while(routeNodeInstanceIter.hasNext()){
139 						RouteNodeInstance routeNodeInstance=(RouteNodeInstance) routeNodeInstanceIter.next();
140 						Branch branch=routeNodeInstance.getBranch();
141 						if (! branches1.containsKey(branch.getName())){
142 							branches1.put(branch.getName(),branch);
143 							branches.add(branch);
144 							LOG.debug(branch.getName()+"; "+branch.getBranchState());
145 						}
146 					}
147 					if(branches.size()<1){
148 						branches=null;
149 					}
150 				}
151 				branches1.clear();
152 				request.getSession().setAttribute("branches",branches);
153 				docForm.setBranches(branches);
154 			}
155 		}
156 			
157 		return mapping.findForward("basic");
158 	}
159 
160 	/**
161 	 * Sets up various objects on the document which are required for use inside of the Struts and JSP framework.
162 	 *
163 	 * Specifically, if a document has action requests with null RouteNodeInstances, it will create empty node instance
164 	 * objects.
165 	 */
166 	private void materializeDocument(DocumentRouteHeaderValue document) {
167 		for (Iterator iterator = document.getActionRequests().iterator(); iterator.hasNext();) {
168 			ActionRequestValue request = (ActionRequestValue) iterator.next();
169 			if (request.getNodeInstance() == null) {
170 				request.setNodeInstance(new RouteNodeInstance());
171 			}
172 		}
173 	}
174 
175 	public ActionForward clear(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
176 		DocumentOperationForm docForm = (DocumentOperationForm) form;
177 		docForm.setRouteHeader(new DocumentRouteHeaderValue());
178 		docForm.setDocumentId(null);
179 		return mapping.findForward("basic");
180 	}
181 
182 	public ActionMessages establishRequiredState(HttpServletRequest request, ActionForm form) throws Exception {
183 		return null;
184 	}
185 
186 	public ActionForward flushRuleCache(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
187 	    KEWServiceLocator.getRuleService().flushRuleCache();
188 	    return mapping.findForward("basic");
189 	}
190 
191 	public ActionForward save(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
192 		DocumentOperationForm docForm = (DocumentOperationForm) form;
193 		boolean change = false;
194 
195 		String routeHeaderOp = docForm.getRouteHeaderOp();
196 		if (!KEWConstants.UPDATE.equals(routeHeaderOp) && !KEWConstants.NOOP.equals(routeHeaderOp)) {
197 			throw new WorkflowServiceErrorException("Document operation not defined", new WorkflowServiceErrorImpl("Document operation not defined", "docoperation.operation.invalid"));
198 		}
199 		if (KEWConstants.UPDATE.equals(routeHeaderOp)) {
200 			setRouteHeaderTimestamps(docForm);
201 			DocumentRouteHeaderValue dHeader = docForm.getRouteHeader();
202 			String initials=docForm.getInitialNodeInstances();
203 			List<RouteNodeInstance> lInitials = new ArrayList<RouteNodeInstance>();
204 			if (StringUtils.isNotEmpty(initials)){ 
205 				StringTokenizer tokenInitials=new StringTokenizer(initials,",");
206 				while (tokenInitials.hasMoreTokens()) {
207 					String instanceId = tokenInitials.nextToken().trim();
208 					LOG.debug(instanceId);
209 					RouteNodeInstance instance = getRouteNodeService().findRouteNodeInstanceById(instanceId);
210 					lInitials.add(instance);
211 				}
212 			}
213 			dHeader.setInitialRouteNodeInstances(lInitials);
214 			getRouteHeaderService().validateRouteHeader(docForm.getRouteHeader());
215 			getRouteHeaderService().saveRouteHeader(docForm.getRouteHeader());
216 			change = true;
217 		}
218 
219 		for (Iterator actionRequestIter = docForm.getActionRequestOps().iterator(); actionRequestIter.hasNext();) {
220 			DocOperationIndexedParameter actionRequestOp = (DocOperationIndexedParameter) actionRequestIter.next();
221 			int index = actionRequestOp.getIndex().intValue();
222 			String opValue = actionRequestOp.getValue();
223 			ActionRequestValue actionRequest = docForm.getRouteHeader().getDocActionRequest(index);
224 			String createDateParamName = "actionRequestCreateDate" + index;
225 
226 			if (!KEWConstants.UPDATE.equals(opValue) && !KEWConstants.DELETE.equals(opValue) && !KEWConstants.NOOP.equals(opValue)) {
227 				throw new WorkflowServiceErrorException("Action request operation not defined", new WorkflowServiceErrorImpl("Action request operation not defined", "docoperation.actionrequest.operation.invalid"));
228 			}
229 			if (KEWConstants.UPDATE.equals(opValue)) {
230 				try {
231 					actionRequest.setCreateDate(new Timestamp(RiceConstants.getDefaultDateFormat().parse(request.getParameter(createDateParamName)).getTime()));
232 					actionRequest.setCreateDateString(RiceConstants.getDefaultDateFormat().format(actionRequest.getCreateDate()));
233 					actionRequest.setDocumentId(docForm.getRouteHeader().getDocumentId());
234 					actionRequest.setParentActionRequest(getActionRequestService().findByActionRequestId(actionRequest.getParentActionRequestId()));
235 					actionRequest.setActionTaken(getActionTakenService().findByActionTakenId(actionRequest.getActionTakenId()));
236 					if (actionRequest.getNodeInstance() != null && actionRequest.getNodeInstance().getRouteNodeInstanceId() == null) {
237 						actionRequest.setNodeInstance(null);
238 					} else if (actionRequest.getNodeInstance() != null && actionRequest.getNodeInstance().getRouteNodeInstanceId() != null) {
239 						actionRequest.setNodeInstance(KEWServiceLocator.getRouteNodeService().findRouteNodeInstanceById(actionRequest.getNodeInstance().getRouteNodeInstanceId()));
240 					}
241 					// getActionRequestService().validateActionRequest(actionRequest);
242 					getActionRequestService().saveActionRequest(actionRequest);
243 					change = true;
244 				} catch (ParseException pe) {
245 					throw new WorkflowServiceErrorException("Action request create date parsing error", new WorkflowServiceErrorImpl("Action request create date parsing error", "docoperation.actionrequests.dateparsing.error", actionRequest.getActionRequestId().toString()));
246 				}
247 
248 			}
249 			if (KEWConstants.DELETE.equals(opValue)) {
250 			    getActionRequestService().deleteActionRequestGraph(actionRequest);
251 			    change = true;
252 			}
253 		}
254 
255 		for (Iterator actionTakenIter = docForm.getActionTakenOps().iterator(); actionTakenIter.hasNext();) {
256 			DocOperationIndexedParameter actionTakenOp = (DocOperationIndexedParameter) actionTakenIter.next();
257 			int index = actionTakenOp.getIndex().intValue();
258 			String opValue = actionTakenOp.getValue();
259 
260 			String actionDateParamName = "actionTakenActionDate" + index;
261 			ActionTakenValue actionTaken = docForm.getRouteHeader().getDocActionTaken(index);
262 			if (!KEWConstants.UPDATE.equals(opValue) && !KEWConstants.DELETE.equals(opValue) && !KEWConstants.NOOP.equals(opValue)) {
263 				throw new WorkflowServiceErrorException("Action taken operation not defined", new WorkflowServiceErrorImpl("Action taken operation not defined", "docoperation.actiontaken.operation.invalid"));
264 			}
265 			if (KEWConstants.UPDATE.equals(opValue)) {
266 				try {
267 					actionTaken.setActionDate(new Timestamp(RiceConstants.getDefaultDateFormat().parse(request.getParameter(actionDateParamName)).getTime()));
268 					actionTaken.setActionDateString(RiceConstants.getDefaultDateFormat().format(actionTaken.getActionDate()));
269 					// getActionTakenService().validateActionTaken(actionTaken);
270 					getActionTakenService().saveActionTaken(actionTaken);
271 					change = true;
272 				} catch (ParseException pe) {
273 					throw new WorkflowServiceErrorException("Action taken action date parsing error", new WorkflowServiceErrorImpl("Action taken action date parse error", "docoperation.actionstaken.dateparsing.error", actionTaken.getActionTakenId().toString()));
274 				}
275 			}
276 			if (KEWConstants.DELETE.equals(opValue)) {
277 				getActionTakenService().delete(actionTaken);
278 				change = true;
279 			}
280 		}
281 
282 		for (Iterator actionItemIter = docForm.getActionItemOps().iterator(); actionItemIter.hasNext();) {
283 			DocOperationIndexedParameter actionItemOp = (DocOperationIndexedParameter) actionItemIter.next();
284 			int index = actionItemOp.getIndex().intValue();
285 			String opValue = actionItemOp.getValue();
286 
287 			String dateAssignedParamName = "actionItemDateAssigned" + index;
288 			ActionItem actionItem = docForm.getRouteHeader().getDocActionItem(index);
289 			if (!KEWConstants.UPDATE.equals(opValue) && !KEWConstants.DELETE.equals(opValue) && !KEWConstants.NOOP.equals(opValue)) {
290 				throw new WorkflowServiceErrorException("Action Item operation not defined", new WorkflowServiceErrorImpl("Action Item operation not defined", "docoperation.operation.invalid"));
291 			}
292 			if (KEWConstants.UPDATE.equals(opValue)) {
293 				try {
294 					actionItem.setDateAssigned(new Timestamp(RiceConstants.getDefaultDateFormat().parse(request.getParameter(dateAssignedParamName)).getTime()));
295 					actionItem.setDateAssignedString(RiceConstants.getDefaultDateFormat().format(actionItem.getDateAssigned()));
296 					actionItem.setDocumentId(docForm.getRouteHeader().getDocumentId());
297 					// getActionItemService().validateActionItem(actionItem);
298 					getActionListService().saveActionItem(actionItem);
299 					change = true;
300 				} catch (ParseException pe) {
301 					throw new WorkflowServiceErrorException("Action item date assigned parsing error", new WorkflowServiceErrorImpl("Action item date assigned parse error", "docoperation.actionitem.dateassignedparsing.error", actionItem.getActionItemId().toString()));
302 				}
303 			}
304 			if (KEWConstants.DELETE.equals(opValue)) {
305 				getActionListService().deleteActionItem(actionItem);
306 				change = true;
307 			}
308 		}
309 
310 		List routeNodeInstances=(List)(request.getSession().getAttribute("routeNodeInstances"));
311 		String ids = (docForm.getNodeStatesDelete() != null) ? docForm.getNodeStatesDelete().trim() : null;
312 		List statesToBeDeleted=new ArrayList();
313 		if(ids!=null && !ids.equals("")){
314 		    StringTokenizer idSets=new StringTokenizer(ids);
315 		    while (idSets.hasMoreTokens()) {
316 		    	String id=idSets.nextToken().trim();
317 		    	statesToBeDeleted.add(Long.valueOf(id));
318 		     }
319 		}
320 
321 		for (Iterator routeNodeInstanceIter = docForm.getRouteNodeInstanceOps().iterator(); routeNodeInstanceIter.hasNext();) {
322 			DocOperationIndexedParameter routeNodeInstanceOp = (DocOperationIndexedParameter) routeNodeInstanceIter.next();
323 			int index = routeNodeInstanceOp.getIndex().intValue();
324 			String opValue = routeNodeInstanceOp.getValue();
325             LOG.debug(opValue);
326 			RouteNodeInstance routeNodeInstance = (RouteNodeInstance)(routeNodeInstances.get(index));
327 			RouteNodeInstance routeNodeInstanceNew = (RouteNodeInstance)(docForm.getRouteNodeInstance(index));
328 			if (!KEWConstants.UPDATE.equals(opValue) && !KEWConstants.DELETE.equals(opValue) && !KEWConstants.NOOP.equals(opValue)) {
329 				throw new WorkflowServiceErrorException("Route Node Instance Operation not defined", new WorkflowServiceErrorImpl("Route Node Instance Operation not defined", "docoperation.routenodeinstance.operation.invalid"));
330 			}
331 			if (KEWConstants.UPDATE.equals(opValue)) {
332 				//LOG.debug("saving routeNodeInstance:"+routeNodeInstance.getRouteNodeInstanceId());
333 				//getRouteNodeService().save(routeNodeInstance);
334 				routeNodeInstance.setActive(routeNodeInstanceNew.isActive());
335 				LOG.debug(Boolean.toString(routeNodeInstanceNew.isActive()));
336 				routeNodeInstance.setComplete(routeNodeInstanceNew.isComplete());
337 				routeNodeInstance.setInitial(routeNodeInstanceNew.isInitial());
338 				List nodeStates=routeNodeInstance.getState();
339 				List nodeStatesNew=routeNodeInstanceNew.getState();
340 
341 				if(nodeStates!=null){
342 					for(int i=0;i<nodeStates.size();i++){
343 					   NodeState nodeState=(NodeState)nodeStates.get(i);
344 					   NodeState nodeStateNew=(NodeState)nodeStatesNew.get(i);
345 					   if(nodeStateNew.getKey()!=null && ! nodeStateNew.getKey().trim().equals("")){
346 					   nodeState.setKey(nodeStateNew.getKey());
347 					   LOG.debug(nodeState.getKey());
348 					   nodeState.setValue(nodeStateNew.getValue());
349 					   LOG.debug(nodeState.getValue());
350 					   }
351 				    }
352 				}
353 				getRouteNodeService().save(routeNodeInstance);
354 				LOG.debug("saved");
355 				change = true;
356 			}
357 
358 
359 			if (KEWConstants.DELETE.equals(opValue)) {
360 				List nodeStates=routeNodeInstance.getState();
361 				List nodeStatesNew=routeNodeInstanceNew.getState();
362 
363 				if(nodeStates!=null){
364 					for(int i=0;i<nodeStates.size();i++){
365 					   NodeState nodeState=(NodeState)nodeStates.get(i);
366 					   NodeState nodeStateNew=(NodeState)nodeStatesNew.get(i);
367 					   if(nodeStateNew.getKey()==null || nodeStateNew.getKey().trim().equals("")){
368 					     statesToBeDeleted.remove(nodeState.getNodeStateId());
369 					   }
370 				    }
371 				}
372 				getRouteNodeService().deleteByRouteNodeInstance(routeNodeInstance);
373 				LOG.debug(routeNodeInstance.getRouteNodeInstanceId()+" is deleted");
374 				change = true;
375 				break;
376 			}
377 
378 			if (KEWConstants.NOOP.equals(opValue)){
379 				routeNodeInstanceNew.setActive(routeNodeInstance.isActive());
380 				routeNodeInstanceNew.setComplete(routeNodeInstance.isComplete());
381 				routeNodeInstanceNew.setInitial(routeNodeInstance.isInitial());
382 				List nodeStates=routeNodeInstance.getState();
383 				List nodeStatesNew=routeNodeInstanceNew.getState();
384 				if(nodeStates!=null){
385 				   for(int i=0;i<nodeStates.size();i++){
386 					   NodeState nodeState=(NodeState)nodeStates.get(i);
387 					   NodeState nodeStateNew=(NodeState)nodeStatesNew.get(i);
388 					   if(nodeStateNew.getKey()==null || nodeStateNew.getKey().trim().equals("")){
389 						     statesToBeDeleted.remove(nodeState.getNodeStateId());
390 					   }
391 					   nodeStateNew.setKey(nodeState.getKey());
392 					   nodeStateNew.setValue(nodeState.getValue());
393 				   }
394 				}
395 			}
396 
397 			//((DocOperationIndexedParameter)(docForm.getRouteNodeInstanceOps().get(index))).setValue(KEWConstants.NOOP);
398 		}
399 
400 		if(statesToBeDeleted!=null && statesToBeDeleted.size()>0){
401 			getRouteNodeService().deleteNodeStates(statesToBeDeleted);
402 		}
403 
404 
405 		List branches=(List)(request.getSession().getAttribute("branches"));
406 		String branchStateIds = (docForm.getBranchStatesDelete() != null) ? docForm.getBranchStatesDelete().trim() : null;
407 		List branchStatesToBeDeleted=new ArrayList();
408 		if(branchStateIds!=null && !branchStateIds.equals("")){
409 		    StringTokenizer idSets=new StringTokenizer(branchStateIds);
410 		    while (idSets.hasMoreTokens()) {
411 		    	String id=idSets.nextToken().trim();
412 		    	branchStatesToBeDeleted.add(Long.valueOf(id));
413 		    }
414 		}
415 
416 		for (Iterator branchesOpIter = docForm.getBranchOps().iterator(); branchesOpIter.hasNext();) {
417 			DocOperationIndexedParameter branchesOp = (DocOperationIndexedParameter) branchesOpIter.next();
418 			int index = branchesOp.getIndex().intValue();
419 			String opValue = branchesOp.getValue();
420             LOG.debug(opValue);
421 			Branch branch = (Branch)(branches.get(index));
422 			Branch branchNew = (Branch)(docForm.getBranche(index));
423 			if (!KEWConstants.UPDATE.equals(opValue) && !KEWConstants.NOOP.equals(opValue)) {
424 				throw new WorkflowServiceErrorException("Route Node Instance Operation not defined", new WorkflowServiceErrorImpl("Route Node Instance Operation not defined", "docoperation.routenodeinstance.operation.invalid"));
425 			}
426 			if (KEWConstants.UPDATE.equals(opValue)) {
427 				//LOG.debug("saving routeNodeInstance:"+routeNodeInstance.getRouteNodeInstanceId());
428 				//getRouteNodeService().save(routeNodeInstance);
429 				branch.setName(branchNew.getName());
430 				List branchStates=branch.getBranchState();
431 				List branchStatesNew=branchNew.getBranchState();
432 				if(branchStates!=null){
433 				   for(int i=0;i<branchStates.size();i++){
434 					   BranchState branchState=(BranchState)branchStates.get(i);
435 					   BranchState branchStateNew=(BranchState)branchStatesNew.get(i);
436 					   if(branchStateNew.getKey()!=null && ! branchStateNew.getKey().trim().equals("")){
437 					   branchState.setKey(branchStateNew.getKey());
438 					   LOG.debug(branchState.getKey());
439 					   branchState.setValue(branchStateNew.getValue());
440 					   LOG.debug(branchState.getValue());
441 					   }
442 				   }
443 				}
444 				getBranchService().save(branch);
445 				LOG.debug("branch saved");
446 				change = true;
447 
448 			}
449 
450 
451 			if (KEWConstants.NOOP.equals(opValue)){
452 				branchNew.setName(branch.getName());
453 				List branchStates=branch.getBranchState();
454 				List branchStatesNew=branchNew.getBranchState();
455 				if(branchStates!=null){
456 				   for(int i=0;i<branchStates.size();i++){
457 					   BranchState branchState=(BranchState)branchStates.get(i);
458 					   BranchState branchStateNew=(BranchState)branchStatesNew.get(i);
459 					   if(branchStateNew.getKey()==null || branchStateNew.getKey().trim().equals("")){
460 						   branchStatesToBeDeleted.remove(branchState.getBranchStateId());
461 					   }
462 					   branchStateNew.setKey(branchState.getKey());
463 					   LOG.debug(branchState.getKey());
464 					   branchStateNew.setValue(branchState.getValue());
465 					   LOG.debug(branchState.getValue());
466 				   }
467 				}
468 			}
469 			//((DocOperationIndexedParameter)(docForm.getBranchOps().get(index))).setValue(KEWConstants.NOOP);
470 		}
471 
472 		if(branchStatesToBeDeleted!=null && branchStatesToBeDeleted.size()>0){
473 			getBranchService().deleteBranchStates(branchStatesToBeDeleted);
474 		}
475 
476 		WorkflowDocument workflowDocument = WorkflowDocumentFactory.loadDocument(GlobalVariables.getUserSession().getPrincipalId(), docForm.getDocumentId());
477 
478 		String annotation = docForm.getAnnotation();
479 		if (StringUtils.isEmpty(annotation)) {
480 			annotation = DEFAULT_LOG_MSG;
481 		}
482 		workflowDocument.logAnnotation(annotation);
483 
484 		ActionMessages messages = new ActionMessages();
485 		String forward = null;
486 		if (change) {
487 			messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("docoperation.operation.saved"));
488 			docForm.setRouteHeader(getRouteHeaderService().getRouteHeader(docForm.getRouteHeader().getDocumentId()));
489 			forward = "summary";
490 		} else {
491 			messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("docoperation.operation.noop"));
492 			forward = "basic";
493 		}
494 		saveMessages(request, messages);
495 		return mapping.findForward(forward);
496 
497 	}
498 
499 	private RouteHeaderService getRouteHeaderService() {
500 		return (RouteHeaderService) KEWServiceLocator.getService(KEWServiceLocator.DOC_ROUTE_HEADER_SRV);
501 	}
502 
503 	private RouteNodeService getRouteNodeService(){
504 		return (RouteNodeService) KEWServiceLocator.getService(KEWServiceLocator.ROUTE_NODE_SERVICE);
505 	}
506 
507 	private ActionRequestService getActionRequestService() {
508 		return (ActionRequestService) KEWServiceLocator.getService(KEWServiceLocator.ACTION_REQUEST_SRV);
509 	}
510 
511 	private ActionTakenService getActionTakenService() {
512 		return (ActionTakenService) KEWServiceLocator.getService(KEWServiceLocator.ACTION_TAKEN_SRV);
513 	}
514 
515 	private ActionListService getActionListService() {
516 		return (ActionListService) KEWServiceLocator.getActionListService();
517 	}
518 
519 	private void setRouteHeaderTimestamps(DocumentOperationForm docForm) {
520 		if (docForm.getCreateDate() == null || docForm.getCreateDate().trim().equals("")) {
521 			throw new WorkflowServiceErrorException("Document create date empty", new WorkflowServiceErrorImpl("Document create date empty", "docoperation.routeheader.createdate.empty"));
522 		} else {
523 			try {
524 				
525 //				String a_pat = "yyyy-MM-dd hh:mm:ss";
526 //				SimpleDateFormat fmt = new SimpleDateFormat(a_pat);
527 //				
528 //				System.out.println("**********************new*******************");
529 //				System.out.println(docForm.getCreateDate());
530 //				System.out.println("**********************old*******************");
531 //				System.out.println(docForm.getRouteHeader().getCreateDate());
532 //				System.out.println("********************************************");
533 //	
534 	//			docForm.getRouteHeader().setCreateDate(new Timestamp(fmt.parse(docForm.getCreateDate()).getTime()));
535 
536 				docForm.getRouteHeader().setCreateDate(new Timestamp(RiceConstants.getDefaultDateAndTimeFormat().parse(docForm.getCreateDate()).getTime()));
537 			} catch (ParseException pe) {
538 				throw new WorkflowServiceErrorException("RouteHeader create date parsing error", new WorkflowServiceErrorImpl("Date parsing error", "docoperation.routeheader.createdate.invalid"));
539 			}
540 		}
541 
542 		if (docForm.getStatusModDate() == null || docForm.getStatusModDate().trim().equals("")) {
543 			throw new WorkflowServiceErrorException("Document doc status mod date empty", new WorkflowServiceErrorImpl("Document doc status mod date empty", "docoperation.routeheader.statusmoddate.empty"));
544 		} else {
545 			try {
546 				docForm.getRouteHeader().setStatusModDate(new Timestamp(RiceConstants.getDefaultDateAndTimeFormat().parse(docForm.getStatusModDate()).getTime()));
547 			} catch (ParseException pe) {
548 				throw new WorkflowServiceErrorException("Document doc status date parsing error", new WorkflowServiceErrorImpl("Document doc status mod date parsing error", "docoperation.routeheader.statusmoddate.invalid"));
549 			}
550 		}
551 
552 		if (docForm.getApprovedDate() != null && !docForm.getApprovedDate().trim().equals("")) {
553 			try {
554 				docForm.getRouteHeader().setApprovedDate(new Timestamp(RiceConstants.getDefaultDateAndTimeFormat().parse(docForm.getApprovedDate()).getTime()));
555 			} catch (ParseException pe) {
556 				throw new WorkflowServiceErrorException("Document approved date parsing error", new WorkflowServiceErrorImpl("Document approved date parsing error", "docoperation.routeheader.approveddate.invalid"));
557 			}
558 
559 		}
560 
561 		if (docForm.getFinalizedDate() != null && !docForm.getFinalizedDate().trim().equals("")) {
562 			try {
563 				docForm.getRouteHeader().setFinalizedDate(new Timestamp(RiceConstants.getDefaultDateAndTimeFormat().parse(docForm.getFinalizedDate()).getTime()));
564 			} catch (ParseException pe) {
565 				throw new WorkflowServiceErrorException("Document finalized date parsing error", new WorkflowServiceErrorImpl("Document finalized date parsing error", "docoperation.routeheader.finalizeddate.invalid"));
566 			}
567 		}
568 
569 		if (docForm.getRouteStatusDate() != null && !docForm.getRouteStatusDate().trim().equals("")) {
570 			try {
571 				docForm.getRouteHeader().setRouteStatusDate(new Timestamp(RiceConstants.getDefaultDateAndTimeFormat().parse(docForm.getRouteStatusDate()).getTime()));
572 			} catch (ParseException pe) {
573 				throw new WorkflowServiceErrorException("Document route status date parsing error", new WorkflowServiceErrorImpl("Document route status date parsing error", "docoperation.routeheader.routestatusdate.invalid"));
574 			}
575 
576 		}
577 
578 		if (docForm.getRouteLevelDate() != null && !docForm.getRouteLevelDate().trim().equals("")) {
579 			try {
580 				docForm.getRouteHeader().setRouteLevelDate(new Timestamp(RiceConstants.getDefaultDateAndTimeFormat().parse(docForm.getRouteLevelDate()).getTime()));
581 			} catch (ParseException pe) {
582 				throw new WorkflowServiceErrorException("Document route level date parsing error", new WorkflowServiceErrorImpl("Document route level date parsing error", "docoperation.routeheader.routeleveldate.invalid"));
583 			}
584 		}
585 	}
586 
587 	private void setRouteHeaderTimestampsToString(DocumentOperationForm docForm) {
588 		try {
589 			docForm.setCreateDate(RiceConstants.getDefaultDateAndTimeFormat().format(docForm.getRouteHeader().getCreateDate()));
590 			docForm.setStatusModDate(RiceConstants.getDefaultDateAndTimeFormat().format(docForm.getRouteHeader().getStatusModDate()));
591 			docForm.setApprovedDate(RiceConstants.getDefaultDateAndTimeFormat().format(docForm.getRouteHeader().getApprovedDate()));
592 			docForm.setFinalizedDate(RiceConstants.getDefaultDateAndTimeFormat().format(docForm.getRouteHeader().getFinalizedDate()));
593 			docForm.setRouteStatusDate(RiceConstants.getDefaultDateAndTimeFormat().format(docForm.getRouteHeader().getRouteStatusDate()));
594 			docForm.setRouteLevelDate(RiceConstants.getDefaultDateAndTimeFormat().format(docForm.getRouteHeader().getRouteLevelDate()));
595 
596 		} catch (Exception e) {
597 			LOG.info("One or more of the dates in routeHeader may be null");
598 		}
599 	}
600 
601 	public ActionForward refresh(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
602 		DocumentOperationForm docForm = (DocumentOperationForm) form;
603 		String lookupInvocationModule = docForm.getLookupInvocationModule();
604 		docForm.getRouteHeader().setDocumentId(docForm.getDocumentId());
605 
606 		if (lookupInvocationModule != null && !lookupInvocationModule.trim().equals("")) {
607 			String lookupField = docForm.getLookupInvocationField();
608 			int lookupIndex = new Integer(docForm.getLookupInvocationIndex()).intValue();
609 			String networkId = request.getParameter("networkId");
610 			String principalId = KEWServiceLocator.getIdentityHelperService().getIdForPrincipalName(networkId);
611 
612 			if (lookupInvocationModule.equals("RouteHeader")) {
613 				DocumentRouteHeaderValue routeHeader = docForm.getRouteHeader();
614 				if ("initiatorWorkflowId".equals(lookupField)) {
615 					routeHeader.setInitiatorWorkflowId(principalId);
616 				}
617 				if ("documentTypeId".equals(lookupField)) {
618 					DocumentType docType = getDocumentTypeService().findByName(request.getParameter("docTypeFullName"));
619 					routeHeader.setDocumentTypeId(docType.getDocumentTypeId());
620 				}
621 			}
622 
623 			if (lookupInvocationModule.equals("ActionRequest")) {
624 				ActionRequestValue actionRequest = docForm.getRouteHeader().getDocActionRequest(lookupIndex);
625 				if ("routeMethodName".equals(lookupField)) {
626 //					actionRequest.setRouteMethodName(null);
627 					String id = request.getParameter("ruleTemplate.ruleTemplateId");
628 					if (id != null && !"".equals(id.trim())) {
629 						RuleTemplate ruleTemplate = KEWServiceLocator.getRuleTemplateService().findByRuleTemplateId(id);
630 //						if (ruleTemplate != null) {
631 //							actionRequest.setRouteMethodName(ruleTemplate.getName());
632 //						}
633 					}
634 				}
635 				if ("workflowId".equals(lookupField)) {
636 					actionRequest.setPrincipalId(principalId);
637 				}
638 				if ("workgroupId".equals(lookupField)) {
639 					if (request.getParameter("workgroupId") != null && !"".equals(request.getParameter("workgroupId").trim())) {
640 						actionRequest.setGroupId(request.getParameter("workgroupId"));
641 					} else {
642 						actionRequest.setGroupId(null);
643 					}
644 				}
645 				if ("roleName".equals(lookupField)) {
646 					actionRequest.setRoleName(request.getParameter("roleName"));
647 				}
648 			}
649 			if (lookupInvocationModule.equals("ActionTaken")) {
650 				ActionTakenValue actionTaken = docForm.getRouteHeader().getDocActionTaken(lookupIndex);
651 				if ("workflowId".equals(lookupField)) {
652 					Principal principal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName(networkId);
653 					if (principal != null) {
654 						actionTaken.setPrincipalId(principal.getPrincipalId());
655 					} else {
656 						LOG.info("action taken user not found");
657 						actionTaken.setPrincipalId(null);
658 					}
659 				}
660 				if ("delegatorWorkflowId".equals(lookupField)) {
661 					Principal principal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName(networkId);
662 					if (principal != null) {
663 						actionTaken.setDelegatorPrincipalId(principal.getPrincipalId());
664 					} else {
665 						LOG.info("action taken delegator user not found");
666 						actionTaken.setDelegatorPrincipalId(null);
667 					}
668 				}
669 				if ("delegatorGroupId".equals(lookupField)) {
670 					if (request.getParameter("workgroupId") != null && !"".equals(request.getParameter("workgroupId").trim())) {
671 						actionTaken.setDelegatorGroupId(request.getParameter("workgroupId"));
672 					} else {
673 						actionTaken.setDelegatorGroupId(null);
674 					}
675 				}
676 			}
677 
678 			if (lookupInvocationModule.equals("ActionItem")) {
679 				ActionItem actionItem = docForm.getRouteHeader().getDocActionItem(lookupIndex);
680 				if ("workflowId".equals(lookupField)) {
681 					Principal principal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName(networkId);
682 					if (principal != null) {
683 						actionItem.setPrincipalId(principal.getPrincipalId());
684 					} else {
685 						LOG.info("action item user not found");
686 						actionItem.setPrincipalId(null);
687 					}
688 				}
689 
690 				if ("workgroupId".equals(lookupField)) {
691 					if (request.getParameter("workgroupId") != null && !"".equals(request.getParameter("workgroupId").trim())) {
692 						actionItem.setGroupId(request.getParameter("workgroupId"));
693 					} else {
694 						actionItem.setGroupId(null);
695 					}
696 				}
697 				if ("roleName".equals(lookupField)) {
698 					actionItem.setRoleName(request.getParameter("roleName"));
699 				}
700 				if ("delegatorWorkflowId".equals(lookupField)) {
701 					Principal principal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName(networkId);
702 					if (principal != null) {
703 						actionItem.setDelegatorWorkflowId(principal.getPrincipalId());
704 					} else {
705 						LOG.info("action item delegator user not found");
706 						actionItem.setDelegatorWorkflowId(null);
707 					}
708 				}
709 				if ("delegatorGroupId".equals(lookupField)) {
710 					if (request.getParameter("workgroupId") != null && !"".equals(request.getParameter("workgroupId").trim())) {
711 						actionItem.setDelegatorGroupId(request.getParameter("workgroupId"));
712 					} else {
713 						actionItem.setDelegatorGroupId(null);
714 					}
715 				}
716 				if ("docName".equals(lookupField)) {
717 					DocumentType docType = getDocumentTypeService().findByName(request.getParameter("docTypeFullName"));
718 					actionItem.setDocName(docType.getName());
719 					actionItem.setDocLabel(docType.getLabel());
720 					actionItem.setDocHandlerURL(docType.getDocHandlerUrl());
721 				}
722 			}
723 		}
724 
725 		return mapping.findForward("basic");
726 	}
727 
728 	public ActionForward queueDocument(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
729 		try {
730 			DocumentOperationForm docForm = (DocumentOperationForm) form;
731 			KSBXMLService routeDoc = MessageServiceNames.getRouteDocumentMessageService(docForm.getRouteHeader());
732 			routeDoc.invoke(docForm.getDocumentId());
733 			ActionMessages messages = new ActionMessages();
734 			messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("general.message", "Document was successfully queued"));
735 			saveMessages(request, messages);
736 			return mapping.findForward("basic");
737 		} catch (Exception e) {
738 			throw new WorkflowRuntimeException(e);
739 		}
740 	}
741 
742 	public ActionForward indexSearchableAttributes(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
743 		DocumentOperationForm docForm = (DocumentOperationForm) form;
744 		SearchableAttributeProcessingService searchableAttributeService = MessageServiceNames.getSearchableAttributeService(docForm.getRouteHeader());
745 		searchableAttributeService.indexDocument(docForm.getRouteHeader().getDocumentId());
746 		ActionMessages messages = new ActionMessages();
747 		messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("general.message", "Searchable Attribute Indexing was successfully scheduled"));
748 		saveMessages(request, messages);
749 		return mapping.findForward("basic");
750 	}
751 
752 	public ActionForward queueDocumentRequeuer(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
753 		DocumentOperationForm docForm = (DocumentOperationForm) form;
754 		DocumentRequeuerService docRequeue = MessageServiceNames.getDocumentRequeuerService(docForm.getRouteHeader().getDocumentType().getApplicationId(), docForm.getRouteHeader().getDocumentId(), 0);
755 		docRequeue.requeueDocument(docForm.getRouteHeader().getDocumentId());
756 		ActionMessages messages = new ActionMessages();
757 		messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("general.message", "Document Requeuer was successfully scheduled"));
758 		saveMessages(request, messages);
759 		return mapping.findForward("basic");
760 	}
761 
762 	public ActionForward blanketApproveDocument(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
763 		try {
764 			DocumentOperationForm docForm = (DocumentOperationForm) form;
765 			String principalId = KimApiServiceLocator.getPersonService().getPersonByPrincipalName(docForm.getBlanketApproveUser()).getPrincipalId();
766 			Set<String> nodeNames = new HashSet<String>();
767 			if (!StringUtils.isBlank(docForm.getBlanketApproveNodes())) {
768 				String[] nodeNameArray = docForm.getBlanketApproveNodes().split(",");
769 				for (String nodeName : nodeNameArray) {
770 					nodeNames.add(nodeName.trim());
771 				}
772 			}
773 			BlanketApproveProcessorService blanketApprove = MessageServiceNames.getBlanketApproveProcessorService(docForm.getRouteHeader());
774 			blanketApprove.doBlanketApproveWork(docForm.getRouteHeader().getDocumentId(), principalId, docForm.getBlanketApproveActionTakenId(), nodeNames, true);
775 			ActionMessages messages = new ActionMessages();
776 			messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("general.message", "Blanket Approve Processor was successfully scheduled"));
777 			saveMessages(request, messages);
778 			return mapping.findForward("basic");
779 		} catch (Exception e) {
780 			throw new WorkflowRuntimeException(e);
781 		}
782 	}
783 	
784 	public ActionForward moveDocument(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
785 		try {
786 			DocumentOperationForm docForm = (DocumentOperationForm) form;
787 			String principalId = KEWServiceLocator.getIdentityHelperService().getIdForPrincipalName(docForm.getBlanketApproveUser());
788 			Set<String> nodeNames = new HashSet<String>();
789 			if (!StringUtils.isBlank(docForm.getBlanketApproveNodes())) {
790 				String[] nodeNameArray = docForm.getBlanketApproveNodes().split(",");
791 				for (String nodeName : nodeNameArray) {
792 					nodeNames.add(nodeName.trim());
793 				}
794 			}
795 			ActionTakenValue actionTaken = KEWServiceLocator.getActionTakenService().findByActionTakenId(docForm.getBlanketApproveActionTakenId());
796 			MoveDocumentService moveService = MessageServiceNames.getMoveDocumentProcessorService(docForm.getRouteHeader());
797 			moveService.moveDocument(principalId, docForm.getRouteHeader(), actionTaken, nodeNames);
798 			ActionMessages messages = new ActionMessages();
799 			messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("general.message", "Move Document Processor was successfully scheduled"));
800 			saveMessages(request, messages);
801 			return mapping.findForward("basic");
802 		} catch (Exception e) {
803 			throw new WorkflowRuntimeException(e);
804 		}
805 	}
806 
807 	public ActionForward queueActionInvocation(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
808 		try {
809 			DocumentOperationForm docForm = (DocumentOperationForm) form;
810 			String principalId = KEWServiceLocator.getIdentityHelperService().getIdForPrincipalName(docForm.getActionInvocationUser());
811 			ActionInvocation invocation = new ActionInvocation(docForm.getActionInvocationActionItemId(), docForm.getActionInvocationActionCode());
812 			ActionInvocationService actionInvocationService = MessageServiceNames.getActionInvocationProcessorService(docForm.getRouteHeader());
813 			actionInvocationService.invokeAction(principalId, docForm.getRouteHeader().getDocumentId(), invocation);
814 			ActionMessages messages = new ActionMessages();
815 			messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("general.message", "Action Invocation Processor was successfully scheduled"));
816 			saveMessages(request, messages);
817 			return mapping.findForward("basic");
818 		} catch (Exception e) {
819 			throw new WorkflowRuntimeException(e);
820 		}
821 	}
822 
823 	private DocumentTypeService getDocumentTypeService() {
824 		return (DocumentTypeService) KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_TYPE_SERVICE);
825 	}
826 
827 	private BranchService getBranchService(){
828 		return (BranchService) KEWServiceLocator.getService(KEWServiceLocator.BRANCH_SERVICE);
829 	}
830 }