View Javadoc

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