View Javadoc
1   /**
2    * Copyright 2005-2015 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.actiontaken.ActionTakenValue;
31  import org.kuali.rice.kew.actiontaken.service.ActionTakenService;
32  import org.kuali.rice.kew.api.KewApiConstants;
33  import org.kuali.rice.kew.api.KewApiServiceLocator;
34  import org.kuali.rice.kew.api.WorkflowDocument;
35  import org.kuali.rice.kew.api.WorkflowDocumentFactory;
36  import org.kuali.rice.kew.api.WorkflowRuntimeException;
37  import org.kuali.rice.kew.api.action.ActionInvocation;
38  import org.kuali.rice.kew.api.action.ActionInvocationQueue;
39  import org.kuali.rice.kew.api.action.ActionType;
40  import org.kuali.rice.kew.api.document.DocumentOrchestrationQueue;
41  import org.kuali.rice.kew.api.document.DocumentProcessingOptions;
42  import org.kuali.rice.kew.api.document.DocumentProcessingQueue;
43  import org.kuali.rice.kew.api.document.DocumentRefreshQueue;
44  import org.kuali.rice.kew.api.document.OrchestrationConfig;
45  import org.kuali.rice.kew.api.document.attribute.DocumentAttributeIndexingQueue;
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.notes.Note;
56  import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
57  import org.kuali.rice.kew.routeheader.service.RouteHeaderService;
58  import org.kuali.rice.kew.service.KEWServiceLocator;
59  import org.kuali.rice.kew.web.KewKualiAction;
60  import org.kuali.rice.kim.api.services.KimApiServiceLocator;
61  import org.kuali.rice.krad.data.DataObjectService;
62  import org.kuali.rice.krad.service.KRADServiceLocator;
63  import org.kuali.rice.krad.util.GlobalVariables;
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      private DataObjectService dataObjectService;
91  
92  	public ActionForward start(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
93  		return mapping.findForward("basic");
94  	}
95  
96  	public ActionForward getDocument(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
97  		DocumentOperationForm docForm = (DocumentOperationForm) form;
98  		String docId = null;
99  		
100 		// check if we have a plausible docId first
101 		if (StringUtils.isEmpty(docForm.getDocumentId())) {
102 			GlobalVariables.getMessageMap().putError("documentId", RiceKeyConstants.ERROR_REQUIRED, "Document ID");
103 		} else {
104 			try {
105 				docId = docForm.getDocumentId().trim();
106 			} catch (NumberFormatException nfe) {
107 				GlobalVariables.getMessageMap().putError("documentId", RiceKeyConstants.ERROR_NUMERIC, "Document ID");
108 			}
109 		}
110 
111 		if (docId != null) {
112 			//to clear Document Field first;
113 			docForm.resetOps();
114 			DocumentRouteHeaderValue routeHeader = getRouteHeaderService().getRouteHeader(docId);
115 			List routeNodeInstances=getRouteNodeService().findRouteNodeInstances(docId);
116 			Map branches1=new HashMap();
117 			List branches=new ArrayList();
118 
119 			if (routeHeader == null) {
120 				GlobalVariables.getMessageMap().putError("documentId", RiceKeyConstants.ERROR_EXISTENCE, "document");
121 			} else {
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 	public ActionForward clear(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
163 		DocumentOperationForm docForm = (DocumentOperationForm) form;
164 		docForm.setRouteHeader(new DocumentRouteHeaderValue());
165 		docForm.setDocumentId(null);
166 		return mapping.findForward("basic");
167 	}
168 
169 	public ActionMessages establishRequiredState(HttpServletRequest request, ActionForm form) throws Exception {
170 		return null;
171 	}
172 
173 	public ActionForward save(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
174 		DocumentOperationForm docForm = (DocumentOperationForm) form;
175 		boolean change = false;
176 
177 		String routeHeaderOp = docForm.getRouteHeaderOp();
178 		if (!KewApiConstants.UPDATE.equals(routeHeaderOp) && !KewApiConstants.NOOP.equals(routeHeaderOp)) {
179 			throw new WorkflowServiceErrorException("Document operation not defined", new WorkflowServiceErrorImpl("Document operation not defined", "docoperation.operation.invalid"));
180 		}
181 		if (KewApiConstants.UPDATE.equals(routeHeaderOp)) {
182 			setRouteHeaderTimestamps(docForm);
183 			DocumentRouteHeaderValue dHeader = docForm.getRouteHeader();
184             List<Note> docNotes = KEWServiceLocator.getNoteService().getNotesByDocumentId(dHeader.getDocumentId());
185 
186             if (docNotes != null && !docNotes.isEmpty()) {
187                 dHeader.setNotes(docNotes);
188             }
189             String initials=docForm.getInitialNodeInstances();
190 			List<RouteNodeInstance> lInitials = new ArrayList<RouteNodeInstance>();
191 			if (StringUtils.isNotEmpty(initials)){ 
192 				StringTokenizer tokenInitials=new StringTokenizer(initials,",");
193 				while (tokenInitials.hasMoreTokens()) {
194 					String instanceId = tokenInitials.nextToken().trim();
195 					LOG.debug(instanceId);
196 					RouteNodeInstance instance = getRouteNodeService().findRouteNodeInstanceById(instanceId);
197 					lInitials.add(instance);
198 				}
199 			}
200 			dHeader.setInitialRouteNodeInstances(lInitials);
201 			getRouteHeaderService().validateRouteHeader(docForm.getRouteHeader());
202 			DocumentRouteHeaderValue documentRouteHeaderValue = getRouteHeaderService().
203                                         saveRouteHeader(docForm.getRouteHeader());
204             docForm.setRouteHeader(documentRouteHeaderValue);
205 			change = true;
206 		}
207 
208 		for (Iterator actionRequestIter = docForm.getActionRequestOps().iterator(); actionRequestIter.hasNext();) {
209 			DocOperationIndexedParameter actionRequestOp = (DocOperationIndexedParameter) actionRequestIter.next();
210 			int index = actionRequestOp.getIndex().intValue();
211 			String opValue = actionRequestOp.getValue();
212 			ActionRequestValue actionRequest = docForm.getActionRequests().get(index);
213 			String createDateParamName = "actionRequestCreateDate" + index;
214 
215 			if (!KewApiConstants.UPDATE.equals(opValue) && !KewApiConstants.DELETE.equals(opValue) && !KewApiConstants.NOOP.equals(opValue)) {
216 				throw new WorkflowServiceErrorException("Action request operation not defined", new WorkflowServiceErrorImpl("Action request operation not defined", "docoperation.actionrequest.operation.invalid"));
217 			}
218 			if (KewApiConstants.UPDATE.equals(opValue)) {
219 				try {
220 					actionRequest.setCreateDate(new Timestamp(RiceConstants.getDefaultDateFormat().parse(request.getParameter(createDateParamName)).getTime()));
221 					actionRequest.setCreateDateString(RiceConstants.getDefaultDateFormat().format(actionRequest.getCreateDate()));
222 					actionRequest.setDocumentId(docForm.getRouteHeader().getDocumentId());
223 
224                     if (StringUtils.isNotBlank(actionRequest.getParentActionRequestId())) {
225                         actionRequest.setParentActionRequest(getActionRequestService().findByActionRequestId(actionRequest.getParentActionRequestId()));
226                     }
227 
228                     if (StringUtils.isNotBlank(actionRequest.getActionTakenId())) {
229 					    actionRequest.setActionTaken(getActionTakenService().findByActionTakenId(actionRequest.getActionTakenId()));
230                     }
231 
232 					if (actionRequest.getNodeInstance() != null && actionRequest.getNodeInstance().getRouteNodeInstanceId() == null) {
233 						actionRequest.setNodeInstance(null);
234 					} else if (actionRequest.getNodeInstance() != null && actionRequest.getNodeInstance().getRouteNodeInstanceId() != null) {
235 						actionRequest.setNodeInstance(KEWServiceLocator.getRouteNodeService().findRouteNodeInstanceById(actionRequest.getNodeInstance().getRouteNodeInstanceId()));
236 					}
237 					// getActionRequestService().validateActionRequest(actionRequest);
238 					actionRequest = getActionRequestService().saveActionRequest(actionRequest);
239 					change = true;
240 				} catch (ParseException pe) {
241 					throw new WorkflowServiceErrorException("Action request create date parsing error", new WorkflowServiceErrorImpl("Action request create date parsing error", "docoperation.actionrequests.dateparsing.error", actionRequest.getActionRequestId().toString()));
242 				}
243 
244 			}
245 			if (KewApiConstants.DELETE.equals(opValue)) {
246 			    getActionRequestService().deleteActionRequestGraphNoOutbox(actionRequest);
247 			    change = true;
248 			}
249 		}
250 
251 		for (Iterator actionTakenIter = docForm.getActionTakenOps().iterator(); actionTakenIter.hasNext();) {
252 			DocOperationIndexedParameter actionTakenOp = (DocOperationIndexedParameter) actionTakenIter.next();
253 			int index = actionTakenOp.getIndex().intValue();
254 			String opValue = actionTakenOp.getValue();
255 
256 			String actionDateParamName = "actionTakenActionDate" + index;
257             ActionTakenValue actionTaken = docForm.getActionsTaken().get(index);
258 			if (!KewApiConstants.UPDATE.equals(opValue) && !KewApiConstants.DELETE.equals(opValue) && !KewApiConstants.NOOP.equals(opValue)) {
259 				throw new WorkflowServiceErrorException("Action taken operation not defined", new WorkflowServiceErrorImpl("Action taken operation not defined", "docoperation.actiontaken.operation.invalid"));
260 			}
261 			if (KewApiConstants.UPDATE.equals(opValue)) {
262 				try {
263 					actionTaken.setActionDate(new Timestamp(RiceConstants.getDefaultDateFormat().parse(request.getParameter(actionDateParamName)).getTime()));
264 					actionTaken.setActionDateString(RiceConstants.getDefaultDateFormat().format(actionTaken.getActionDate()));
265 					actionTaken = getActionTakenService().saveActionTaken(actionTaken);
266 					change = true;
267 				} catch (ParseException pe) {
268 					throw new WorkflowServiceErrorException("Action taken action date parsing error", new WorkflowServiceErrorImpl("Action taken action date parse error", "docoperation.actionstaken.dateparsing.error", actionTaken.getActionTakenId().toString()));
269 				}
270 			}
271 			if (KewApiConstants.DELETE.equals(opValue)) {
272 				getActionTakenService().delete(actionTaken);
273 				change = true;
274 			}
275 		}
276 
277 		for (Iterator actionItemIter = docForm.getActionItemOps().iterator(); actionItemIter.hasNext();) {
278 			DocOperationIndexedParameter actionItemOp = (DocOperationIndexedParameter) actionItemIter.next();
279 			int index = actionItemOp.getIndex().intValue();
280 			String opValue = actionItemOp.getValue();
281 
282 			String dateAssignedParamName = "actionItemDateAssigned" + index;
283             ActionItem actionItem =  docForm.getActionItems().get(index);
284 
285             if (!KewApiConstants.UPDATE.equals(opValue) && !KewApiConstants.DELETE.equals(opValue) && !KewApiConstants.NOOP.equals(opValue)) {
286 				throw new WorkflowServiceErrorException("Action Item operation not defined", new WorkflowServiceErrorImpl("Action Item operation not defined", "docoperation.operation.invalid"));
287 			}
288 			if (KewApiConstants.UPDATE.equals(opValue)) {
289 				try {
290 					actionItem.setDateAssigned(new Timestamp(RiceConstants.getDefaultDateFormat().parse(request.getParameter(dateAssignedParamName)).getTime()));
291 					actionItem.setDateAssignedStringValue(RiceConstants.getDefaultDateFormat().format(actionItem.getDateAssigned()));
292 					actionItem.setDocumentId(docForm.getRouteHeader().getDocumentId());
293 					// getActionItemService().validateActionItem(actionItem);
294 					getActionListService().saveActionItem(actionItem);
295 					change = true;
296 				} catch (ParseException pe) {
297 					throw new WorkflowServiceErrorException("Action item date assigned parsing error", new WorkflowServiceErrorImpl("Action item date assigned parse error", "docoperation.actionitem.dateassignedparsing.error", actionItem.getId().toString()));
298 				}
299 			}
300 			if (KewApiConstants.DELETE.equals(opValue)) {
301                 try {
302                     actionItem.setDateAssigned(new Timestamp(RiceConstants.getDefaultDateFormat().parse(request.getParameter(dateAssignedParamName)).getTime()));
303                     actionItem.setDateAssignedStringValue(RiceConstants.getDefaultDateFormat().format(actionItem.getDateAssigned()));
304                     actionItem.setDocumentId(docForm.getRouteHeader().getDocumentId());
305                     getActionListService().deleteActionItem(actionItem);
306                     change = true;
307                 } catch (ParseException pe) {
308                     throw new WorkflowServiceErrorException("Action item date assigned parsing error", new WorkflowServiceErrorImpl("Action item date assigned parse error", "docoperation.actionitem.dateassignedparsing.error", actionItem.getId().toString()));
309                 }
310 			}
311 		}
312 
313 		List routeNodeInstances=(List)(request.getSession().getAttribute("routeNodeInstances"));
314 		String ids = (docForm.getNodeStatesDelete() != null) ? docForm.getNodeStatesDelete().trim() : null;
315 		List statesToBeDeleted=new ArrayList();
316 		if(ids!=null && !ids.equals("")){
317 		    StringTokenizer idSets=new StringTokenizer(ids);
318 		    while (idSets.hasMoreTokens()) {
319 		    	String id=idSets.nextToken().trim();
320 		    	statesToBeDeleted.add(Long.valueOf(id));
321 		     }
322 		}
323 
324 		for (Iterator routeNodeInstanceIter = docForm.getRouteNodeInstanceOps().iterator(); routeNodeInstanceIter.hasNext();) {
325 			DocOperationIndexedParameter routeNodeInstanceOp = (DocOperationIndexedParameter) routeNodeInstanceIter.next();
326 			int index = routeNodeInstanceOp.getIndex().intValue();
327 			String opValue = routeNodeInstanceOp.getValue();
328             LOG.debug(opValue);
329 			RouteNodeInstance routeNodeInstance = (RouteNodeInstance)(routeNodeInstances.get(index));
330 			RouteNodeInstance routeNodeInstanceNew = (RouteNodeInstance)(docForm.getRouteNodeInstance(index));
331 			if (!KewApiConstants.UPDATE.equals(opValue) && !KewApiConstants.DELETE.equals(opValue) && !KewApiConstants.NOOP.equals(opValue)) {
332 				throw new WorkflowServiceErrorException("Route Node Instance Operation not defined", new WorkflowServiceErrorImpl("Route Node Instance Operation not defined", "docoperation.routenodeinstance.operation.invalid"));
333 			}
334 			if (KewApiConstants.UPDATE.equals(opValue)) {
335 				//LOG.debug("saving routeNodeInstance:"+routeNodeInstance.getRouteNodeInstanceId());
336 				//getRouteNodeService().save(routeNodeInstance);
337 				routeNodeInstance.setActive(routeNodeInstanceNew.isActive());
338 				LOG.debug(Boolean.toString(routeNodeInstanceNew.isActive()));
339 				routeNodeInstance.setComplete(routeNodeInstanceNew.isComplete());
340 				routeNodeInstance.setInitial(routeNodeInstanceNew.isInitial());
341 				List nodeStates=routeNodeInstance.getState();
342 				List nodeStatesNew=routeNodeInstanceNew.getState();
343 
344 				if(nodeStates!=null){
345 					for(int i=0;i<nodeStates.size();i++){
346 					   NodeState nodeState=(NodeState)nodeStates.get(i);
347 					   NodeState nodeStateNew=(NodeState)nodeStatesNew.get(i);
348 					   if(nodeStateNew.getKey()!=null && ! nodeStateNew.getKey().trim().equals("")){
349 					   nodeState.setKey(nodeStateNew.getKey());
350 					   LOG.debug(nodeState.getKey());
351 					   nodeState.setValue(nodeStateNew.getValue());
352 					   LOG.debug(nodeState.getValue());
353 					   }
354 				    }
355 				}
356 				routeNodeInstance = getRouteNodeService().save(routeNodeInstance);
357 				LOG.debug("saved");
358 				change = true;
359 			}
360 
361 
362 			if (KewApiConstants.DELETE.equals(opValue)) {
363 				List nodeStates=routeNodeInstance.getState();
364 				List nodeStatesNew=routeNodeInstanceNew.getState();
365 
366 				if(nodeStates!=null){
367 					for(int i=0;i<nodeStates.size();i++){
368 					   NodeState nodeState=(NodeState)nodeStates.get(i);
369 					   NodeState nodeStateNew=(NodeState)nodeStatesNew.get(i);
370 					   if(nodeStateNew.getKey()==null || nodeStateNew.getKey().trim().equals("")){
371 					     statesToBeDeleted.remove(nodeState.getNodeStateId());
372 					   }
373 				    }
374 				}
375 				getRouteNodeService().deleteByRouteNodeInstance(routeNodeInstance);
376 				LOG.debug(routeNodeInstance.getRouteNodeInstanceId()+" is deleted");
377 				change = true;
378 				break;
379 			}
380 
381 			if (KewApiConstants.NOOP.equals(opValue)){
382 				routeNodeInstanceNew.setActive(routeNodeInstance.isActive());
383 				routeNodeInstanceNew.setComplete(routeNodeInstance.isComplete());
384 				routeNodeInstanceNew.setInitial(routeNodeInstance.isInitial());
385 				List nodeStates=routeNodeInstance.getState();
386 				List nodeStatesNew=routeNodeInstanceNew.getState();
387 				if(nodeStates!=null){
388 				   for(int i=0;i<nodeStates.size();i++){
389 					   NodeState nodeState=(NodeState)nodeStates.get(i);
390 					   NodeState nodeStateNew=(NodeState)nodeStatesNew.get(i);
391 					   if(nodeStateNew.getKey()==null || nodeStateNew.getKey().trim().equals("")){
392 						     statesToBeDeleted.remove(nodeState.getNodeStateId());
393 					   }
394 					   nodeStateNew.setKey(nodeState.getKey());
395 					   nodeStateNew.setValue(nodeState.getValue());
396 				   }
397 				}
398 			}
399 
400 			//((DocOperationIndexedParameter)(docForm.getRouteNodeInstanceOps().get(index))).setValue(KewApiConstants.NOOP);
401 		}
402 
403 		if(statesToBeDeleted!=null && statesToBeDeleted.size()>0){
404 			getRouteNodeService().deleteNodeStates(statesToBeDeleted);
405 		}
406 
407 
408 		List branches=(List)(request.getSession().getAttribute("branches"));
409 		String branchStateIds = (docForm.getBranchStatesDelete() != null) ? docForm.getBranchStatesDelete().trim() : null;
410 		List<Long> branchStatesToBeDeleted=new ArrayList<Long>();
411 		if(branchStateIds!=null && !branchStateIds.equals("")){
412 		    StringTokenizer idSets=new StringTokenizer(branchStateIds);
413 		    while (idSets.hasMoreTokens()) {
414 		    	String id=idSets.nextToken().trim();
415 		    	branchStatesToBeDeleted.add(Long.valueOf(id));
416 		    }
417 		}
418 
419 		for (Iterator branchesOpIter = docForm.getBranchOps().iterator(); branchesOpIter.hasNext();) {
420 			DocOperationIndexedParameter branchesOp = (DocOperationIndexedParameter) branchesOpIter.next();
421 			int index = branchesOp.getIndex().intValue();
422 			String opValue = branchesOp.getValue();
423             LOG.debug(opValue);
424 			Branch branch = (Branch)(branches.get(index));
425 			Branch branchNew = (Branch)(docForm.getBranche(index));
426 			if (!KewApiConstants.UPDATE.equals(opValue) && !KewApiConstants.NOOP.equals(opValue)) {
427 				throw new WorkflowServiceErrorException("Route Node Instance Operation not defined", new WorkflowServiceErrorImpl("Route Node Instance Operation not defined", "docoperation.routenodeinstance.operation.invalid"));
428 			}
429 			if (KewApiConstants.UPDATE.equals(opValue)) {
430 				//LOG.debug("saving routeNodeInstance:"+routeNodeInstance.getRouteNodeInstanceId());
431 				//getRouteNodeService().save(routeNodeInstance);
432 				branch.setName(branchNew.getName());
433 				List branchStates=branch.getBranchState();
434 				List branchStatesNew=branchNew.getBranchState();
435 				if(branchStates!=null){
436 				   for(int i=0;i<branchStates.size();i++){
437 					   BranchState branchState=(BranchState)branchStates.get(i);
438 					   if (i < branchStatesNew.size()) {
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 				}
449 				getBranchService().save(branch);
450 				LOG.debug("branch saved");
451 				change = true;
452 
453 			}
454 
455 
456 			if (KewApiConstants.NOOP.equals(opValue)){
457 				branchNew.setName(branch.getName());
458 				List branchStates=branch.getBranchState();
459 				List branchStatesNew=branchNew.getBranchState();
460 				if(branchStates!=null){
461 				   for(int i=0;i<branchStates.size();i++){
462 					   BranchState branchState=(BranchState)branchStates.get(i);
463 					   BranchState branchStateNew=(BranchState)branchStatesNew.get(i);
464 					   if(branchStateNew.getKey()==null || branchStateNew.getKey().trim().equals("")){
465 						   branchStatesToBeDeleted.remove(branchState.getBranchStateId());
466 					   }
467 					   branchStateNew.setKey(branchState.getKey());
468 					   LOG.debug(branchState.getKey());
469 					   branchStateNew.setValue(branchState.getValue());
470 					   LOG.debug(branchState.getValue());
471 				   }
472 				}
473 			}
474 			//((DocOperationIndexedParameter)(docForm.getBranchOps().get(index))).setValue(KewApiConstants.NOOP);
475 		}
476 
477 		if(branchStatesToBeDeleted!=null && branchStatesToBeDeleted.size()>0){
478             List<BranchState> branchStatesToDelete = new ArrayList<BranchState>();
479             List<String> branchStateIdsToBeDeleted =  new ArrayList<String>(branchStatesToBeDeleted.size());
480             //Converting a list of Long values to list of String values
481             for(Long branchStateToBeDeleted : branchStatesToBeDeleted){
482                 branchStateIdsToBeDeleted.add(String.valueOf(branchStateToBeDeleted));
483             }
484 
485             for(String branchStateId : branchStateIdsToBeDeleted){
486                 BranchState branchState = getDataObjectService().find(BranchState.class, branchStateId);
487                 branchStatesToDelete.add(branchState);
488             }
489 
490             getBranchService().deleteBranchStates(branchStatesToDelete);
491 		}
492 
493 		WorkflowDocument workflowDocument = WorkflowDocumentFactory.loadDocument(GlobalVariables.getUserSession().getPrincipalId(), docForm.getDocumentId());
494 
495 		String annotation = docForm.getAnnotation();
496 		if (StringUtils.isEmpty(annotation)) {
497 			annotation = DEFAULT_LOG_MSG;
498 		}
499 		workflowDocument.logAnnotation(annotation);
500 
501 		ActionMessages messages = new ActionMessages();
502 		String forward = null;
503 		if (change) {
504 			messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("docoperation.operation.saved"));
505 			docForm.setRouteHeader(getRouteHeaderService().getRouteHeader(docForm.getRouteHeader().getDocumentId()));
506 			forward = "summary";
507 		} else {
508 			messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("docoperation.operation.noop"));
509 			forward = "basic";
510 		}
511 		saveMessages(request, messages);
512 		return mapping.findForward(forward);
513 
514 	}
515 
516 	private RouteHeaderService getRouteHeaderService() {
517 		return (RouteHeaderService) KEWServiceLocator.getService(KEWServiceLocator.DOC_ROUTE_HEADER_SRV);
518 	}
519 
520 	private RouteNodeService getRouteNodeService(){
521 		return (RouteNodeService) KEWServiceLocator.getService(KEWServiceLocator.ROUTE_NODE_SERVICE);
522 	}
523 
524 	private ActionRequestService getActionRequestService() {
525 		return (ActionRequestService) KEWServiceLocator.getService(KEWServiceLocator.ACTION_REQUEST_SRV);
526 	}
527 
528 	private ActionTakenService getActionTakenService() {
529 		return (ActionTakenService) KEWServiceLocator.getService(KEWServiceLocator.ACTION_TAKEN_SRV);
530 	}
531 
532 	private ActionListService getActionListService() {
533 		return (ActionListService) KEWServiceLocator.getActionListService();
534 	}
535 
536 	private void setRouteHeaderTimestamps(DocumentOperationForm docForm) {
537 		if (docForm.getCreateDate() == null || docForm.getCreateDate().trim().equals("")) {
538 			throw new WorkflowServiceErrorException("Document create date empty", new WorkflowServiceErrorImpl("Document create date empty", "docoperation.routeheader.createdate.empty"));
539 		} else {
540 			try {
541 				
542 //				String a_pat = "yyyy-MM-dd hh:mm:ss";
543 //				SimpleDateFormat fmt = new SimpleDateFormat(a_pat);
544 //				
545 //				System.out.println("**********************new*******************");
546 //				System.out.println(docForm.getCreateDate());
547 //				System.out.println("**********************old*******************");
548 //				System.out.println(docForm.getRouteHeader().getCreateDate());
549 //				System.out.println("********************************************");
550 //	
551 	//			docForm.getRouteHeader().setCreateDate(new Timestamp(fmt.parse(docForm.getCreateDate()).getTime()));
552 
553 				docForm.getRouteHeader().setCreateDate(new Timestamp(RiceConstants.getDefaultDateAndTimeFormat().parse(docForm.getCreateDate()).getTime()));
554 			} catch (ParseException pe) {
555 				throw new WorkflowServiceErrorException("RouteHeader create date parsing error", new WorkflowServiceErrorImpl("Date parsing error", "docoperation.routeheader.createdate.invalid"));
556 			}
557 		}
558 
559 		if (docForm.getDateModified() == null || docForm.getDateModified().trim().equals("")) {
560 			throw new WorkflowServiceErrorException("Document doc status mod date empty", new WorkflowServiceErrorImpl("Document doc status mod date empty", "docoperation.routeheader.statusmoddate.empty"));
561 		} else {
562 			try {
563 				docForm.getRouteHeader().setDateModified(new Timestamp(
564                         RiceConstants.getDefaultDateAndTimeFormat().parse(docForm.getDateModified()).getTime()));
565 			} catch (ParseException pe) {
566 				throw new WorkflowServiceErrorException("Document doc status date parsing error", new WorkflowServiceErrorImpl("Document doc status mod date parsing error", "docoperation.routeheader.statusmoddate.invalid"));
567 			}
568 		}
569 
570 		if (docForm.getApprovedDate() != null && !docForm.getApprovedDate().trim().equals("")) {
571 			try {
572 				docForm.getRouteHeader().setApprovedDate(new Timestamp(RiceConstants.getDefaultDateAndTimeFormat().parse(docForm.getApprovedDate()).getTime()));
573 			} catch (ParseException pe) {
574 				throw new WorkflowServiceErrorException("Document approved date parsing error", new WorkflowServiceErrorImpl("Document approved date parsing error", "docoperation.routeheader.approveddate.invalid"));
575 			}
576 
577 		}
578 
579 		if (docForm.getFinalizedDate() != null && !docForm.getFinalizedDate().trim().equals("")) {
580 			try {
581 				docForm.getRouteHeader().setFinalizedDate(new Timestamp(RiceConstants.getDefaultDateAndTimeFormat().parse(docForm.getFinalizedDate()).getTime()));
582 			} catch (ParseException pe) {
583 				throw new WorkflowServiceErrorException("Document finalized date parsing error", new WorkflowServiceErrorImpl("Document finalized date parsing error", "docoperation.routeheader.finalizeddate.invalid"));
584 			}
585 		}
586 
587 		if (docForm.getRouteStatusDate() != null && !docForm.getRouteStatusDate().trim().equals("")) {
588 			try {
589 				docForm.getRouteHeader().setRouteStatusDate(new Timestamp(RiceConstants.getDefaultDateAndTimeFormat().parse(docForm.getRouteStatusDate()).getTime()));
590 			} catch (ParseException pe) {
591 				throw new WorkflowServiceErrorException("Document route status date parsing error", new WorkflowServiceErrorImpl("Document route status date parsing error", "docoperation.routeheader.routestatusdate.invalid"));
592 			}
593 
594 		}
595 	}
596 
597 	private void setRouteHeaderTimestampsToString(DocumentOperationForm docForm) {
598 		try {
599 			docForm.setCreateDate(RiceConstants.getDefaultDateAndTimeFormat().format(
600                     docForm.getRouteHeader().getCreateDate()));
601 			docForm.setDateModified(RiceConstants.getDefaultDateAndTimeFormat().format(
602                     docForm.getRouteHeader().getDateModified()));
603 			docForm.setApprovedDate(RiceConstants.getDefaultDateAndTimeFormat().format(
604                     docForm.getRouteHeader().getApprovedDate()));
605 			docForm.setFinalizedDate(RiceConstants.getDefaultDateAndTimeFormat().format(
606                     docForm.getRouteHeader().getFinalizedDate()));
607 			docForm.setRouteStatusDate(RiceConstants.getDefaultDateAndTimeFormat().format(
608                     docForm.getRouteHeader().getRouteStatusDate()));
609 
610 		} catch (Exception e) {
611 			LOG.info("One or more of the dates in routeHeader may be null");
612 		}
613 	}
614 
615 	public ActionForward refresh(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
616 		DocumentOperationForm docForm = (DocumentOperationForm) form;
617 		docForm.getRouteHeader().setDocumentId(docForm.getDocumentId());
618 		return mapping.findForward("basic");
619 	}
620 
621 	public ActionForward queueDocument(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
622 		try {
623 			DocumentOperationForm docForm = (DocumentOperationForm) form;
624             DocumentRouteHeaderValue document = docForm.getRouteHeader();
625             String applicationId = document.getDocumentType().getApplicationId();
626             DocumentProcessingQueue documentProcessingQueue = KewApiServiceLocator.getDocumentProcessingQueue(document.getDocumentId(), applicationId);
627 			documentProcessingQueue.process(docForm.getDocumentId());
628 			ActionMessages messages = new ActionMessages();
629 			messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("general.message", "Document was successfully queued"));
630 			saveMessages(request, messages);
631 			return mapping.findForward("basic");
632 		} catch (Exception e) {
633 			throw new WorkflowRuntimeException(e);
634 		}
635 	}
636 
637 	public ActionForward indexSearchableAttributes(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
638 		DocumentOperationForm docForm = (DocumentOperationForm) form;
639         DocumentAttributeIndexingQueue queue = KewApiServiceLocator.getDocumentAttributeIndexingQueue(docForm.getRouteHeader().getDocumentType().getApplicationId());
640         queue.indexDocument(docForm.getRouteHeader().getDocumentId());
641 		ActionMessages messages = new ActionMessages();
642 		messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("general.message", "Searchable Attribute Indexing was successfully scheduled"));
643 		saveMessages(request, messages);
644 		return mapping.findForward("basic");
645 	}
646 
647 	public ActionForward queueDocumentRefresh(ActionMapping mapping, ActionForm form, HttpServletRequest request,
648             HttpServletResponse response) throws IOException, ServletException {
649 		DocumentOperationForm docForm = (DocumentOperationForm) form;
650 		DocumentRefreshQueue docRequeue = KewApiServiceLocator.getDocumentRequeuerService(
651 		    docForm.getRouteHeader().getDocumentType().getApplicationId(), docForm.getRouteHeader().getDocumentId(), 0);
652 		docRequeue.refreshDocument(docForm.getRouteHeader().getDocumentId());
653 		ActionMessages messages = new ActionMessages();
654 		messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("general.message", "Document Requeuer was successfully scheduled"));
655 		saveMessages(request, messages);
656 		return mapping.findForward("basic");
657 	}
658 
659 	public ActionForward blanketApproveDocument(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
660 		try {
661 			DocumentOperationForm docForm = (DocumentOperationForm) form;
662             String blanketApproverUser = docForm.getBlanketApproveUser();
663             if (StringUtils.isBlank(blanketApproverUser)) {
664                 throw new WorkflowServiceErrorException("No user was provided in the Blanket Approve User field", new WorkflowServiceErrorImpl("No user was provided in the Blanket Approve User field", "docoperation.operation.invalid"));
665             }
666 			String principalId = KimApiServiceLocator.getPersonService().getPersonByPrincipalName(docForm.getBlanketApproveUser()).getPrincipalId();
667 			Set<String> nodeNames = new HashSet<String>();
668 			if (!StringUtils.isBlank(docForm.getBlanketApproveNodes())) {
669 				String[] nodeNameArray = docForm.getBlanketApproveNodes().split(",");
670 				for (String nodeName : nodeNameArray) {
671 					nodeNames.add(nodeName.trim());
672 				}
673 			}
674 			DocumentRouteHeaderValue document = docForm.getRouteHeader();
675             String applicationId = document.getDocumentType().getApplicationId();
676             DocumentOrchestrationQueue blanketApprove = KewApiServiceLocator.getDocumentOrchestrationQueue(
677                     document.getDocumentId(), applicationId);
678             OrchestrationConfig orchestrationConfig = OrchestrationConfig.create(docForm.getBlanketApproveActionTakenId(), nodeNames);
679             DocumentProcessingOptions options = DocumentProcessingOptions.createDefault();
680 			blanketApprove.orchestrateDocument(docForm.getRouteHeader().getDocumentId(), principalId,
681                     orchestrationConfig, options);
682 			ActionMessages messages = new ActionMessages();
683 			messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("general.message", "Blanket Approve Processor was successfully scheduled"));
684 			saveMessages(request, messages);
685 			return mapping.findForward("basic");
686 		} catch (Exception e) {
687 			throw new WorkflowRuntimeException(e);
688 		}
689 	}
690 	
691 	public ActionForward moveDocument(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
692 		try {
693 			DocumentOperationForm docForm = (DocumentOperationForm) form;
694 			String principalId = KEWServiceLocator.getIdentityHelperService().getIdForPrincipalName(docForm.getBlanketApproveUser());
695 			Set<String> nodeNames = new HashSet<String>();
696 			if (!StringUtils.isBlank(docForm.getBlanketApproveNodes())) {
697 				String[] nodeNameArray = docForm.getBlanketApproveNodes().split(",");
698 				for (String nodeName : nodeNameArray) {
699 					nodeNames.add(nodeName.trim());
700 				}
701 			}
702             DocumentRouteHeaderValue document = docForm.getRouteHeader();
703             String applicationId = document.getDocumentType().getApplicationId();
704             DocumentOrchestrationQueue orchestrationQueue = KewApiServiceLocator.getDocumentOrchestrationQueue(
705                     document.getDocumentId(), applicationId);
706             OrchestrationConfig orchestrationConfig = OrchestrationConfig.create(docForm.getBlanketApproveActionTakenId(), nodeNames);
707             DocumentProcessingOptions options = DocumentProcessingOptions.create(true, true, false);
708             orchestrationQueue.orchestrateDocument(docForm.getDocumentId(), principalId, orchestrationConfig, options);
709 
710             ActionMessages messages = new ActionMessages();
711 			messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("general.message", "Move Document Processor was successfully scheduled"));
712 			saveMessages(request, messages);
713 			return mapping.findForward("basic");
714 		} catch (Exception e) {
715 			throw new WorkflowRuntimeException(e);
716 		}
717 	}
718 
719 	public ActionForward queueActionInvocation(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
720 		try {
721 			DocumentOperationForm docForm = (DocumentOperationForm) form;
722 			String principalId = KEWServiceLocator.getIdentityHelperService().getIdForPrincipalName(docForm.getActionInvocationUser());
723 			ActionInvocation invocation = ActionInvocation.create(ActionType.fromCode(
724                     docForm.getActionInvocationActionCode()), docForm.getActionInvocationActionItemId());
725             DocumentRouteHeaderValue document = docForm.getRouteHeader();
726             String applicationId = document.getDocumentType().getApplicationId();
727 			ActionInvocationQueue actionInvocationQueue = KewApiServiceLocator.getActionInvocationProcessorService(
728 			    document.getDocumentId(), applicationId);
729 			actionInvocationQueue.invokeAction(principalId, docForm.getRouteHeader().getDocumentId(), invocation);
730 			ActionMessages messages = new ActionMessages();
731 			messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("general.message", "Action Invocation Processor was successfully scheduled"));
732 			saveMessages(request, messages);
733 			return mapping.findForward("basic");
734 		} catch (Exception e) {
735 			throw new WorkflowRuntimeException(e);
736 		}
737 	}
738 
739 	private DocumentTypeService getDocumentTypeService() {
740 		return (DocumentTypeService) KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_TYPE_SERVICE);
741 	}
742 
743 	private BranchService getBranchService(){
744 		return (BranchService) KEWServiceLocator.getService(KEWServiceLocator.BRANCH_SERVICE);
745 	}
746 
747     public DataObjectService getDataObjectService() {
748         if(dataObjectService == null) {
749             dataObjectService = KRADServiceLocator.getDataObjectService();
750         }
751         return dataObjectService;
752     }
753 }