001    /**
002     * Copyright 2005-2014 The Kuali Foundation
003     *
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.opensource.org/licenses/ecl2.php
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.rice.kew.documentoperation.web;
017    
018    import org.apache.commons.lang.StringUtils;
019    import org.apache.struts.action.ActionForm;
020    import org.apache.struts.action.ActionForward;
021    import org.apache.struts.action.ActionMapping;
022    import org.apache.struts.action.ActionMessage;
023    import org.apache.struts.action.ActionMessages;
024    import org.kuali.rice.core.api.util.RiceConstants;
025    import org.kuali.rice.core.api.util.RiceKeyConstants;
026    import org.kuali.rice.kew.actionitem.ActionItem;
027    import org.kuali.rice.kew.actionlist.service.ActionListService;
028    import org.kuali.rice.kew.actionrequest.ActionRequestValue;
029    import org.kuali.rice.kew.actionrequest.service.ActionRequestService;
030    import org.kuali.rice.kew.actiontaken.ActionTakenValue;
031    import org.kuali.rice.kew.actiontaken.service.ActionTakenService;
032    import org.kuali.rice.kew.api.KewApiConstants;
033    import org.kuali.rice.kew.api.KewApiServiceLocator;
034    import org.kuali.rice.kew.api.WorkflowDocument;
035    import org.kuali.rice.kew.api.WorkflowDocumentFactory;
036    import org.kuali.rice.kew.api.WorkflowRuntimeException;
037    import org.kuali.rice.kew.api.action.ActionInvocation;
038    import org.kuali.rice.kew.api.action.ActionInvocationQueue;
039    import org.kuali.rice.kew.api.action.ActionType;
040    import org.kuali.rice.kew.api.document.DocumentOrchestrationQueue;
041    import org.kuali.rice.kew.api.document.DocumentProcessingOptions;
042    import org.kuali.rice.kew.api.document.DocumentProcessingQueue;
043    import org.kuali.rice.kew.api.document.DocumentRefreshQueue;
044    import org.kuali.rice.kew.api.document.OrchestrationConfig;
045    import org.kuali.rice.kew.api.document.attribute.DocumentAttributeIndexingQueue;
046    import org.kuali.rice.kew.doctype.service.DocumentTypeService;
047    import org.kuali.rice.kew.engine.node.Branch;
048    import org.kuali.rice.kew.engine.node.BranchState;
049    import org.kuali.rice.kew.engine.node.NodeState;
050    import org.kuali.rice.kew.engine.node.RouteNodeInstance;
051    import org.kuali.rice.kew.engine.node.service.BranchService;
052    import org.kuali.rice.kew.engine.node.service.RouteNodeService;
053    import org.kuali.rice.kew.exception.WorkflowServiceErrorException;
054    import org.kuali.rice.kew.exception.WorkflowServiceErrorImpl;
055    import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
056    import org.kuali.rice.kew.routeheader.service.RouteHeaderService;
057    import org.kuali.rice.kew.service.KEWServiceLocator;
058    import org.kuali.rice.kew.web.KewKualiAction;
059    import org.kuali.rice.kim.api.services.KimApiServiceLocator;
060    import org.kuali.rice.krad.util.GlobalVariables;
061    
062    import javax.servlet.ServletException;
063    import javax.servlet.http.HttpServletRequest;
064    import javax.servlet.http.HttpServletResponse;
065    import java.io.IOException;
066    import java.sql.Timestamp;
067    import java.text.ParseException;
068    import java.util.ArrayList;
069    import java.util.HashMap;
070    import java.util.HashSet;
071    import java.util.Iterator;
072    import java.util.List;
073    import java.util.Map;
074    import java.util.Set;
075    import java.util.StringTokenizer;
076    
077    
078    /**
079     * Struts Action for doing editing of workflow documents.
080     *
081     * @author Kuali Rice Team (rice.collab@kuali.org)
082     */
083    public class DocumentOperationAction extends KewKualiAction {
084            private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DocumentOperationAction.class);
085            private static final String DEFAULT_LOG_MSG = "Admin change via document operation";
086    
087            public ActionForward start(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
088                    return mapping.findForward("basic");
089            }
090    
091            public ActionForward getDocument(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
092                    DocumentOperationForm docForm = (DocumentOperationForm) form;
093                    String docId = null;
094                    
095                    // check if we have a plausible docId first
096                    if (StringUtils.isEmpty(docForm.getDocumentId())) {
097                            GlobalVariables.getMessageMap().putError("documentId", RiceKeyConstants.ERROR_REQUIRED, "Document ID");
098                    } else {
099                            try {
100                                    docId = docForm.getDocumentId().trim();
101                            } catch (NumberFormatException nfe) {
102                                    GlobalVariables.getMessageMap().putError("documentId", RiceKeyConstants.ERROR_NUMERIC, "Document ID");
103                            }
104                    }
105    
106                    if (docId != null) {
107                            //to clear Document Field first;
108                            docForm.resetOps();
109                            DocumentRouteHeaderValue routeHeader = getRouteHeaderService().getRouteHeader(docId);
110                            List routeNodeInstances=getRouteNodeService().findRouteNodeInstances(docId);
111                            Map branches1=new HashMap();
112                            List branches=new ArrayList();
113    
114                            if (routeHeader == null) {
115                                    GlobalVariables.getMessageMap().putError("documentId", RiceKeyConstants.ERROR_EXISTENCE, "document");
116                            } else {
117                                    materializeDocument(routeHeader);
118                                    docForm.setRouteHeader(routeHeader);
119                                    setRouteHeaderTimestampsToString(docForm);
120                                    docForm.setRouteHeaderOp(KewApiConstants.NOOP);
121                                    docForm.setDocumentId(docForm.getDocumentId().trim());
122                                    String initials="";
123                                    for(Iterator lInitials=routeHeader.getInitialRouteNodeInstances().iterator();lInitials.hasNext();){
124                                            String initial=((RouteNodeInstance)lInitials.next()).getRouteNodeInstanceId();
125                                            LOG.debug(initial);
126                                            initials=initials+initial+", ";
127                                    }
128                                    if(initials.trim().length()>1){
129                                            initials=initials.substring(0,initials.lastIndexOf(","));
130                                    }
131                                    docForm.setInitialNodeInstances(initials);
132                                    request.getSession().setAttribute("routeNodeInstances",routeNodeInstances);
133                                    docForm.setRouteNodeInstances(routeNodeInstances);
134                                    if(routeNodeInstances!=null){
135                                            Iterator routeNodeInstanceIter=routeNodeInstances.iterator();
136                                            while(routeNodeInstanceIter.hasNext()){
137                                                    RouteNodeInstance routeNodeInstance=(RouteNodeInstance) routeNodeInstanceIter.next();
138                                                    Branch branch=routeNodeInstance.getBranch();
139                                                    if (! branches1.containsKey(branch.getName())){
140                                                            branches1.put(branch.getName(),branch);
141                                                            branches.add(branch);
142                                                            LOG.debug(branch.getName()+"; "+branch.getBranchState());
143                                                    }
144                                            }
145                                            if(branches.size()<1){
146                                                    branches=null;
147                                            }
148                                    }
149                                    branches1.clear();
150                                    request.getSession().setAttribute("branches",branches);
151                                    docForm.setBranches(branches);
152                            }
153                    }
154                            
155                    return mapping.findForward("basic");
156            }
157    
158            /**
159             * Sets up various objects on the document which are required for use inside of the Struts and JSP framework.
160             *
161             * Specifically, if a document has action requests with null RouteNodeInstances, it will create empty node instance
162             * objects.
163             */
164            private void materializeDocument(DocumentRouteHeaderValue document) {
165                    for (Iterator iterator = document.getActionRequests().iterator(); iterator.hasNext();) {
166                            ActionRequestValue request = (ActionRequestValue) iterator.next();
167                            if (request.getNodeInstance() == null) {
168                                    request.setNodeInstance(new RouteNodeInstance());
169                            }
170                    }
171            }
172    
173            public ActionForward clear(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
174                    DocumentOperationForm docForm = (DocumentOperationForm) form;
175                    docForm.setRouteHeader(new DocumentRouteHeaderValue());
176                    docForm.setDocumentId(null);
177                    return mapping.findForward("basic");
178            }
179    
180            public ActionMessages establishRequiredState(HttpServletRequest request, ActionForm form) throws Exception {
181                    return null;
182            }
183    
184            public ActionForward save(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
185                    DocumentOperationForm docForm = (DocumentOperationForm) form;
186                    boolean change = false;
187    
188                    String routeHeaderOp = docForm.getRouteHeaderOp();
189                    if (!KewApiConstants.UPDATE.equals(routeHeaderOp) && !KewApiConstants.NOOP.equals(routeHeaderOp)) {
190                            throw new WorkflowServiceErrorException("Document operation not defined", new WorkflowServiceErrorImpl("Document operation not defined", "docoperation.operation.invalid"));
191                    }
192                    if (KewApiConstants.UPDATE.equals(routeHeaderOp)) {
193                            setRouteHeaderTimestamps(docForm);
194                            DocumentRouteHeaderValue dHeader = docForm.getRouteHeader();
195                            String initials=docForm.getInitialNodeInstances();
196                            List<RouteNodeInstance> lInitials = new ArrayList<RouteNodeInstance>();
197                            if (StringUtils.isNotEmpty(initials)){ 
198                                    StringTokenizer tokenInitials=new StringTokenizer(initials,",");
199                                    while (tokenInitials.hasMoreTokens()) {
200                                            String instanceId = tokenInitials.nextToken().trim();
201                                            LOG.debug(instanceId);
202                                            RouteNodeInstance instance = getRouteNodeService().findRouteNodeInstanceById(instanceId);
203                                            lInitials.add(instance);
204                                    }
205                            }
206                            dHeader.setInitialRouteNodeInstances(lInitials);
207                            getRouteHeaderService().validateRouteHeader(docForm.getRouteHeader());
208                            DocumentRouteHeaderValue documentRouteHeaderValue = getRouteHeaderService().
209                                            saveRouteHeader(docForm.getRouteHeader());
210                docForm.setRouteHeader(documentRouteHeaderValue);
211                            change = true;
212                    }
213    
214                    for (Iterator actionRequestIter = docForm.getActionRequestOps().iterator(); actionRequestIter.hasNext();) {
215                            DocOperationIndexedParameter actionRequestOp = (DocOperationIndexedParameter) actionRequestIter.next();
216                            int index = actionRequestOp.getIndex().intValue();
217                            String opValue = actionRequestOp.getValue();
218                            ActionRequestValue actionRequest = docForm.getActionRequests().get(index);
219                            String createDateParamName = "actionRequestCreateDate" + index;
220    
221                            if (!KewApiConstants.UPDATE.equals(opValue) && !KewApiConstants.DELETE.equals(opValue) && !KewApiConstants.NOOP.equals(opValue)) {
222                                    throw new WorkflowServiceErrorException("Action request operation not defined", new WorkflowServiceErrorImpl("Action request operation not defined", "docoperation.actionrequest.operation.invalid"));
223                            }
224                            if (KewApiConstants.UPDATE.equals(opValue)) {
225                                    try {
226                                            actionRequest.setCreateDate(new Timestamp(RiceConstants.getDefaultDateFormat().parse(request.getParameter(createDateParamName)).getTime()));
227                                            actionRequest.setCreateDateString(RiceConstants.getDefaultDateFormat().format(actionRequest.getCreateDate()));
228                                            actionRequest.setDocumentId(docForm.getRouteHeader().getDocumentId());
229                                            actionRequest.setParentActionRequest(getActionRequestService().findByActionRequestId(actionRequest.getParentActionRequestId()));
230                                            actionRequest.setActionTaken(getActionTakenService().findByActionTakenId(actionRequest.getActionTakenId()));
231                                            if (actionRequest.getNodeInstance() != null && actionRequest.getNodeInstance().getRouteNodeInstanceId() == null) {
232                                                    actionRequest.setNodeInstance(null);
233                                            } else if (actionRequest.getNodeInstance() != null && actionRequest.getNodeInstance().getRouteNodeInstanceId() != null) {
234                                                    actionRequest.setNodeInstance(KEWServiceLocator.getRouteNodeService().findRouteNodeInstanceById(actionRequest.getNodeInstance().getRouteNodeInstanceId()));
235                                            }
236                                            // getActionRequestService().validateActionRequest(actionRequest);
237                                            actionRequest = getActionRequestService().saveActionRequest(actionRequest);
238                                            change = true;
239                                    } catch (ParseException pe) {
240                                            throw new WorkflowServiceErrorException("Action request create date parsing error", new WorkflowServiceErrorImpl("Action request create date parsing error", "docoperation.actionrequests.dateparsing.error", actionRequest.getActionRequestId().toString()));
241                                    }
242    
243                            }
244                            if (KewApiConstants.DELETE.equals(opValue)) {
245                                getActionRequestService().deleteActionRequestGraphNoOutbox(actionRequest);
246                                change = true;
247                            }
248                    }
249    
250                    for (Iterator actionTakenIter = docForm.getActionTakenOps().iterator(); actionTakenIter.hasNext();) {
251                            DocOperationIndexedParameter actionTakenOp = (DocOperationIndexedParameter) actionTakenIter.next();
252                            int index = actionTakenOp.getIndex().intValue();
253                            String opValue = actionTakenOp.getValue();
254    
255                            String actionDateParamName = "actionTakenActionDate" + index;
256                ActionTakenValue actionTaken = docForm.getActionsTaken().get(index);
257                            if (!KewApiConstants.UPDATE.equals(opValue) && !KewApiConstants.DELETE.equals(opValue) && !KewApiConstants.NOOP.equals(opValue)) {
258                                    throw new WorkflowServiceErrorException("Action taken operation not defined", new WorkflowServiceErrorImpl("Action taken operation not defined", "docoperation.actiontaken.operation.invalid"));
259                            }
260                            if (KewApiConstants.UPDATE.equals(opValue)) {
261                                    try {
262                                            actionTaken.setActionDate(new Timestamp(RiceConstants.getDefaultDateFormat().parse(request.getParameter(actionDateParamName)).getTime()));
263                                            actionTaken.setActionDateString(RiceConstants.getDefaultDateFormat().format(actionTaken.getActionDate()));
264                                            actionTaken = getActionTakenService().saveActionTaken(actionTaken);
265                                            change = true;
266                                    } catch (ParseException pe) {
267                                            throw new WorkflowServiceErrorException("Action taken action date parsing error", new WorkflowServiceErrorImpl("Action taken action date parse error", "docoperation.actionstaken.dateparsing.error", actionTaken.getActionTakenId().toString()));
268                                    }
269                            }
270                            if (KewApiConstants.DELETE.equals(opValue)) {
271                                    getActionTakenService().delete(actionTaken);
272                                    change = true;
273                            }
274                    }
275    
276                    for (Iterator actionItemIter = docForm.getActionItemOps().iterator(); actionItemIter.hasNext();) {
277                            DocOperationIndexedParameter actionItemOp = (DocOperationIndexedParameter) actionItemIter.next();
278                            int index = actionItemOp.getIndex().intValue();
279                            String opValue = actionItemOp.getValue();
280    
281                            String dateAssignedParamName = "actionItemDateAssigned" + index;
282                ActionItem actionItem =  docForm.getActionItems().get(index);
283    
284                if (!KewApiConstants.UPDATE.equals(opValue) && !KewApiConstants.DELETE.equals(opValue) && !KewApiConstants.NOOP.equals(opValue)) {
285                                    throw new WorkflowServiceErrorException("Action Item operation not defined", new WorkflowServiceErrorImpl("Action Item operation not defined", "docoperation.operation.invalid"));
286                            }
287                            if (KewApiConstants.UPDATE.equals(opValue)) {
288                                    try {
289                                            actionItem.setDateAssigned(new Timestamp(RiceConstants.getDefaultDateFormat().parse(request.getParameter(dateAssignedParamName)).getTime()));
290                                            actionItem.setDateAssignedStringValue(RiceConstants.getDefaultDateFormat().format(actionItem.getDateAssigned()));
291                                            actionItem.setDocumentId(docForm.getRouteHeader().getDocumentId());
292                                            // getActionItemService().validateActionItem(actionItem);
293                                            getActionListService().saveActionItem(actionItem);
294                                            change = true;
295                                    } catch (ParseException pe) {
296                                            throw new WorkflowServiceErrorException("Action item date assigned parsing error", new WorkflowServiceErrorImpl("Action item date assigned parse error", "docoperation.actionitem.dateassignedparsing.error", actionItem.getId().toString()));
297                                    }
298                            }
299                            if (KewApiConstants.DELETE.equals(opValue)) {
300                    try {
301                        actionItem.setDateAssigned(new Timestamp(RiceConstants.getDefaultDateFormat().parse(request.getParameter(dateAssignedParamName)).getTime()));
302                        actionItem.setDateAssignedStringValue(RiceConstants.getDefaultDateFormat().format(actionItem.getDateAssigned()));
303                        actionItem.setDocumentId(docForm.getRouteHeader().getDocumentId());
304                        getActionListService().deleteActionItem(actionItem);
305                        change = true;
306                    } catch (ParseException pe) {
307                        throw new WorkflowServiceErrorException("Action item date assigned parsing error", new WorkflowServiceErrorImpl("Action item date assigned parse error", "docoperation.actionitem.dateassignedparsing.error", actionItem.getId().toString()));
308                    }
309                            }
310                    }
311    
312                    List routeNodeInstances=(List)(request.getSession().getAttribute("routeNodeInstances"));
313                    String ids = (docForm.getNodeStatesDelete() != null) ? docForm.getNodeStatesDelete().trim() : null;
314                    List statesToBeDeleted=new ArrayList();
315                    if(ids!=null && !ids.equals("")){
316                        StringTokenizer idSets=new StringTokenizer(ids);
317                        while (idSets.hasMoreTokens()) {
318                            String id=idSets.nextToken().trim();
319                            statesToBeDeleted.add(Long.valueOf(id));
320                         }
321                    }
322    
323                    for (Iterator routeNodeInstanceIter = docForm.getRouteNodeInstanceOps().iterator(); routeNodeInstanceIter.hasNext();) {
324                            DocOperationIndexedParameter routeNodeInstanceOp = (DocOperationIndexedParameter) routeNodeInstanceIter.next();
325                            int index = routeNodeInstanceOp.getIndex().intValue();
326                            String opValue = routeNodeInstanceOp.getValue();
327                LOG.debug(opValue);
328                            RouteNodeInstance routeNodeInstance = (RouteNodeInstance)(routeNodeInstances.get(index));
329                            RouteNodeInstance routeNodeInstanceNew = (RouteNodeInstance)(docForm.getRouteNodeInstance(index));
330                            if (!KewApiConstants.UPDATE.equals(opValue) && !KewApiConstants.DELETE.equals(opValue) && !KewApiConstants.NOOP.equals(opValue)) {
331                                    throw new WorkflowServiceErrorException("Route Node Instance Operation not defined", new WorkflowServiceErrorImpl("Route Node Instance Operation not defined", "docoperation.routenodeinstance.operation.invalid"));
332                            }
333                            if (KewApiConstants.UPDATE.equals(opValue)) {
334                                    //LOG.debug("saving routeNodeInstance:"+routeNodeInstance.getRouteNodeInstanceId());
335                                    //getRouteNodeService().save(routeNodeInstance);
336                                    routeNodeInstance.setActive(routeNodeInstanceNew.isActive());
337                                    LOG.debug(Boolean.toString(routeNodeInstanceNew.isActive()));
338                                    routeNodeInstance.setComplete(routeNodeInstanceNew.isComplete());
339                                    routeNodeInstance.setInitial(routeNodeInstanceNew.isInitial());
340                                    List nodeStates=routeNodeInstance.getState();
341                                    List nodeStatesNew=routeNodeInstanceNew.getState();
342    
343                                    if(nodeStates!=null){
344                                            for(int i=0;i<nodeStates.size();i++){
345                                               NodeState nodeState=(NodeState)nodeStates.get(i);
346                                               NodeState nodeStateNew=(NodeState)nodeStatesNew.get(i);
347                                               if(nodeStateNew.getKey()!=null && ! nodeStateNew.getKey().trim().equals("")){
348                                               nodeState.setKey(nodeStateNew.getKey());
349                                               LOG.debug(nodeState.getKey());
350                                               nodeState.setValue(nodeStateNew.getValue());
351                                               LOG.debug(nodeState.getValue());
352                                               }
353                                        }
354                                    }
355                                    routeNodeInstance = getRouteNodeService().save(routeNodeInstance);
356                                    LOG.debug("saved");
357                                    change = true;
358                            }
359    
360    
361                            if (KewApiConstants.DELETE.equals(opValue)) {
362                                    List nodeStates=routeNodeInstance.getState();
363                                    List nodeStatesNew=routeNodeInstanceNew.getState();
364    
365                                    if(nodeStates!=null){
366                                            for(int i=0;i<nodeStates.size();i++){
367                                               NodeState nodeState=(NodeState)nodeStates.get(i);
368                                               NodeState nodeStateNew=(NodeState)nodeStatesNew.get(i);
369                                               if(nodeStateNew.getKey()==null || nodeStateNew.getKey().trim().equals("")){
370                                                 statesToBeDeleted.remove(nodeState.getNodeStateId());
371                                               }
372                                        }
373                                    }
374                                    getRouteNodeService().deleteByRouteNodeInstance(routeNodeInstance);
375                                    LOG.debug(routeNodeInstance.getRouteNodeInstanceId()+" is deleted");
376                                    change = true;
377                                    break;
378                            }
379    
380                            if (KewApiConstants.NOOP.equals(opValue)){
381                                    routeNodeInstanceNew.setActive(routeNodeInstance.isActive());
382                                    routeNodeInstanceNew.setComplete(routeNodeInstance.isComplete());
383                                    routeNodeInstanceNew.setInitial(routeNodeInstance.isInitial());
384                                    List nodeStates=routeNodeInstance.getState();
385                                    List nodeStatesNew=routeNodeInstanceNew.getState();
386                                    if(nodeStates!=null){
387                                       for(int i=0;i<nodeStates.size();i++){
388                                               NodeState nodeState=(NodeState)nodeStates.get(i);
389                                               NodeState nodeStateNew=(NodeState)nodeStatesNew.get(i);
390                                               if(nodeStateNew.getKey()==null || nodeStateNew.getKey().trim().equals("")){
391                                                         statesToBeDeleted.remove(nodeState.getNodeStateId());
392                                               }
393                                               nodeStateNew.setKey(nodeState.getKey());
394                                               nodeStateNew.setValue(nodeState.getValue());
395                                       }
396                                    }
397                            }
398    
399                            //((DocOperationIndexedParameter)(docForm.getRouteNodeInstanceOps().get(index))).setValue(KewApiConstants.NOOP);
400                    }
401    
402                    if(statesToBeDeleted!=null && statesToBeDeleted.size()>0){
403                            getRouteNodeService().deleteNodeStates(statesToBeDeleted);
404                    }
405    
406    
407                    List branches=(List)(request.getSession().getAttribute("branches"));
408                    String branchStateIds = (docForm.getBranchStatesDelete() != null) ? docForm.getBranchStatesDelete().trim() : null;
409                    List branchStatesToBeDeleted=new ArrayList();
410                    if(branchStateIds!=null && !branchStateIds.equals("")){
411                        StringTokenizer idSets=new StringTokenizer(branchStateIds);
412                        while (idSets.hasMoreTokens()) {
413                            String id=idSets.nextToken().trim();
414                            branchStatesToBeDeleted.add(Long.valueOf(id));
415                        }
416                    }
417    
418                    for (Iterator branchesOpIter = docForm.getBranchOps().iterator(); branchesOpIter.hasNext();) {
419                            DocOperationIndexedParameter branchesOp = (DocOperationIndexedParameter) branchesOpIter.next();
420                            int index = branchesOp.getIndex().intValue();
421                            String opValue = branchesOp.getValue();
422                LOG.debug(opValue);
423                            Branch branch = (Branch)(branches.get(index));
424                            Branch branchNew = (Branch)(docForm.getBranche(index));
425                            if (!KewApiConstants.UPDATE.equals(opValue) && !KewApiConstants.NOOP.equals(opValue)) {
426                                    throw new WorkflowServiceErrorException("Route Node Instance Operation not defined", new WorkflowServiceErrorImpl("Route Node Instance Operation not defined", "docoperation.routenodeinstance.operation.invalid"));
427                            }
428                            if (KewApiConstants.UPDATE.equals(opValue)) {
429                                    //LOG.debug("saving routeNodeInstance:"+routeNodeInstance.getRouteNodeInstanceId());
430                                    //getRouteNodeService().save(routeNodeInstance);
431                                    branch.setName(branchNew.getName());
432                                    List branchStates=branch.getBranchState();
433                                    List branchStatesNew=branchNew.getBranchState();
434                                    if(branchStates!=null){
435                                       for(int i=0;i<branchStates.size();i++){
436                                               BranchState branchState=(BranchState)branchStates.get(i);
437                                               if (i < branchStatesNew.size()) {
438                                                    BranchState branchStateNew=(BranchState)branchStatesNew.get(i);
439                                                    if(branchStateNew.getKey()!=null && ! branchStateNew.getKey().trim().equals("")){
440                                                        branchState.setKey(branchStateNew.getKey());
441                                                        LOG.debug(branchState.getKey());
442                                                        branchState.setValue(branchStateNew.getValue());
443                                                        LOG.debug(branchState.getValue());
444                                }
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.getDateModified() == null || docForm.getDateModified().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().setDateModified(new Timestamp(
551                            RiceConstants.getDefaultDateAndTimeFormat().parse(docForm.getDateModified()).getTime()));
552                            } catch (ParseException pe) {
553                                    throw new WorkflowServiceErrorException("Document doc status date parsing error", new WorkflowServiceErrorImpl("Document doc status mod date parsing error", "docoperation.routeheader.statusmoddate.invalid"));
554                            }
555                    }
556    
557                    if (docForm.getApprovedDate() != null && !docForm.getApprovedDate().trim().equals("")) {
558                            try {
559                                    docForm.getRouteHeader().setApprovedDate(new Timestamp(RiceConstants.getDefaultDateAndTimeFormat().parse(docForm.getApprovedDate()).getTime()));
560                            } catch (ParseException pe) {
561                                    throw new WorkflowServiceErrorException("Document approved date parsing error", new WorkflowServiceErrorImpl("Document approved date parsing error", "docoperation.routeheader.approveddate.invalid"));
562                            }
563    
564                    }
565    
566                    if (docForm.getFinalizedDate() != null && !docForm.getFinalizedDate().trim().equals("")) {
567                            try {
568                                    docForm.getRouteHeader().setFinalizedDate(new Timestamp(RiceConstants.getDefaultDateAndTimeFormat().parse(docForm.getFinalizedDate()).getTime()));
569                            } catch (ParseException pe) {
570                                    throw new WorkflowServiceErrorException("Document finalized date parsing error", new WorkflowServiceErrorImpl("Document finalized date parsing error", "docoperation.routeheader.finalizeddate.invalid"));
571                            }
572                    }
573    
574                    if (docForm.getRouteStatusDate() != null && !docForm.getRouteStatusDate().trim().equals("")) {
575                            try {
576                                    docForm.getRouteHeader().setRouteStatusDate(new Timestamp(RiceConstants.getDefaultDateAndTimeFormat().parse(docForm.getRouteStatusDate()).getTime()));
577                            } catch (ParseException pe) {
578                                    throw new WorkflowServiceErrorException("Document route status date parsing error", new WorkflowServiceErrorImpl("Document route status date parsing error", "docoperation.routeheader.routestatusdate.invalid"));
579                            }
580    
581                    }
582            }
583    
584            private void setRouteHeaderTimestampsToString(DocumentOperationForm docForm) {
585                    try {
586                            docForm.setCreateDate(RiceConstants.getDefaultDateAndTimeFormat().format(
587                        docForm.getRouteHeader().getCreateDate()));
588                            docForm.setDateModified(RiceConstants.getDefaultDateAndTimeFormat().format(
589                        docForm.getRouteHeader().getDateModified()));
590                            docForm.setApprovedDate(RiceConstants.getDefaultDateAndTimeFormat().format(
591                        docForm.getRouteHeader().getApprovedDate()));
592                            docForm.setFinalizedDate(RiceConstants.getDefaultDateAndTimeFormat().format(
593                        docForm.getRouteHeader().getFinalizedDate()));
594                            docForm.setRouteStatusDate(RiceConstants.getDefaultDateAndTimeFormat().format(
595                        docForm.getRouteHeader().getRouteStatusDate()));
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                    docForm.getRouteHeader().setDocumentId(docForm.getDocumentId());
605                    return mapping.findForward("basic");
606            }
607    
608            public ActionForward queueDocument(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
609                    try {
610                            DocumentOperationForm docForm = (DocumentOperationForm) form;
611                DocumentRouteHeaderValue document = docForm.getRouteHeader();
612                String applicationId = document.getDocumentType().getApplicationId();
613                DocumentProcessingQueue documentProcessingQueue = KewApiServiceLocator.getDocumentProcessingQueue(document.getDocumentId(), applicationId);
614                            documentProcessingQueue.process(docForm.getDocumentId());
615                            ActionMessages messages = new ActionMessages();
616                            messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("general.message", "Document was successfully queued"));
617                            saveMessages(request, messages);
618                            return mapping.findForward("basic");
619                    } catch (Exception e) {
620                            throw new WorkflowRuntimeException(e);
621                    }
622            }
623    
624            public ActionForward indexSearchableAttributes(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
625                    DocumentOperationForm docForm = (DocumentOperationForm) form;
626            DocumentAttributeIndexingQueue queue = KewApiServiceLocator.getDocumentAttributeIndexingQueue(docForm.getRouteHeader().getDocumentType().getApplicationId());
627            queue.indexDocument(docForm.getRouteHeader().getDocumentId());
628                    ActionMessages messages = new ActionMessages();
629                    messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("general.message", "Searchable Attribute Indexing was successfully scheduled"));
630                    saveMessages(request, messages);
631                    return mapping.findForward("basic");
632            }
633    
634            public ActionForward queueDocumentRefresh(ActionMapping mapping, ActionForm form, HttpServletRequest request,
635                HttpServletResponse response) throws IOException, ServletException {
636                    DocumentOperationForm docForm = (DocumentOperationForm) form;
637                    DocumentRefreshQueue docRequeue = KewApiServiceLocator.getDocumentRequeuerService(
638                        docForm.getRouteHeader().getDocumentType().getApplicationId(), docForm.getRouteHeader().getDocumentId(), 0);
639                    docRequeue.refreshDocument(docForm.getRouteHeader().getDocumentId());
640                    ActionMessages messages = new ActionMessages();
641                    messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("general.message", "Document Requeuer was successfully scheduled"));
642                    saveMessages(request, messages);
643                    return mapping.findForward("basic");
644            }
645    
646            public ActionForward blanketApproveDocument(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
647                    try {
648                            DocumentOperationForm docForm = (DocumentOperationForm) form;
649                String blanketApproverUser = docForm.getBlanketApproveUser();
650                if (StringUtils.isBlank(blanketApproverUser)) {
651                    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"));
652                }
653                            String principalId = KimApiServiceLocator.getPersonService().getPersonByPrincipalName(docForm.getBlanketApproveUser()).getPrincipalId();
654                            Set<String> nodeNames = new HashSet<String>();
655                            if (!StringUtils.isBlank(docForm.getBlanketApproveNodes())) {
656                                    String[] nodeNameArray = docForm.getBlanketApproveNodes().split(",");
657                                    for (String nodeName : nodeNameArray) {
658                                            nodeNames.add(nodeName.trim());
659                                    }
660                            }
661                            DocumentRouteHeaderValue document = docForm.getRouteHeader();
662                String applicationId = document.getDocumentType().getApplicationId();
663                DocumentOrchestrationQueue blanketApprove = KewApiServiceLocator.getDocumentOrchestrationQueue(
664                        document.getDocumentId(), applicationId);
665                OrchestrationConfig orchestrationConfig = OrchestrationConfig.create(docForm.getBlanketApproveActionTakenId(), nodeNames);
666                DocumentProcessingOptions options = DocumentProcessingOptions.createDefault();
667                            blanketApprove.orchestrateDocument(docForm.getRouteHeader().getDocumentId(), principalId,
668                        orchestrationConfig, options);
669                            ActionMessages messages = new ActionMessages();
670                            messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("general.message", "Blanket Approve Processor was successfully scheduled"));
671                            saveMessages(request, messages);
672                            return mapping.findForward("basic");
673                    } catch (Exception e) {
674                            throw new WorkflowRuntimeException(e);
675                    }
676            }
677            
678            public ActionForward moveDocument(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
679                    try {
680                            DocumentOperationForm docForm = (DocumentOperationForm) form;
681                            String principalId = KEWServiceLocator.getIdentityHelperService().getIdForPrincipalName(docForm.getBlanketApproveUser());
682                            Set<String> nodeNames = new HashSet<String>();
683                            if (!StringUtils.isBlank(docForm.getBlanketApproveNodes())) {
684                                    String[] nodeNameArray = docForm.getBlanketApproveNodes().split(",");
685                                    for (String nodeName : nodeNameArray) {
686                                            nodeNames.add(nodeName.trim());
687                                    }
688                            }
689                DocumentRouteHeaderValue document = docForm.getRouteHeader();
690                String applicationId = document.getDocumentType().getApplicationId();
691                DocumentOrchestrationQueue orchestrationQueue = KewApiServiceLocator.getDocumentOrchestrationQueue(
692                        document.getDocumentId(), applicationId);
693                OrchestrationConfig orchestrationConfig = OrchestrationConfig.create(docForm.getBlanketApproveActionTakenId(), nodeNames);
694                DocumentProcessingOptions options = DocumentProcessingOptions.create(true, true, false);
695                orchestrationQueue.orchestrateDocument(docForm.getDocumentId(), principalId, orchestrationConfig, options);
696    
697                ActionMessages messages = new ActionMessages();
698                            messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("general.message", "Move Document Processor was successfully scheduled"));
699                            saveMessages(request, messages);
700                            return mapping.findForward("basic");
701                    } catch (Exception e) {
702                            throw new WorkflowRuntimeException(e);
703                    }
704            }
705    
706            public ActionForward queueActionInvocation(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
707                    try {
708                            DocumentOperationForm docForm = (DocumentOperationForm) form;
709                            String principalId = KEWServiceLocator.getIdentityHelperService().getIdForPrincipalName(docForm.getActionInvocationUser());
710                            ActionInvocation invocation = ActionInvocation.create(ActionType.fromCode(
711                        docForm.getActionInvocationActionCode()), docForm.getActionInvocationActionItemId());
712                DocumentRouteHeaderValue document = docForm.getRouteHeader();
713                String applicationId = document.getDocumentType().getApplicationId();
714                            ActionInvocationQueue actionInvocationQueue = KewApiServiceLocator.getActionInvocationProcessorService(
715                                document.getDocumentId(), applicationId);
716                            actionInvocationQueue.invokeAction(principalId, docForm.getRouteHeader().getDocumentId(), invocation);
717                            ActionMessages messages = new ActionMessages();
718                            messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("general.message", "Action Invocation Processor was successfully scheduled"));
719                            saveMessages(request, messages);
720                            return mapping.findForward("basic");
721                    } catch (Exception e) {
722                            throw new WorkflowRuntimeException(e);
723                    }
724            }
725    
726            private DocumentTypeService getDocumentTypeService() {
727                    return (DocumentTypeService) KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_TYPE_SERVICE);
728            }
729    
730            private BranchService getBranchService(){
731                    return (BranchService) KEWServiceLocator.getService(KEWServiceLocator.BRANCH_SERVICE);
732            }
733    }