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