001    /**
002     * Copyright 2005-2013 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.api.document.DocumentOrchestrationQueue;
031    import org.kuali.rice.kew.api.document.DocumentProcessingOptions;
032    import org.kuali.rice.kew.api.document.DocumentRefreshQueue;
033    import org.kuali.rice.kew.api.action.ActionInvocation;
034    import org.kuali.rice.kew.api.action.ActionInvocationQueue;
035    import org.kuali.rice.kew.actiontaken.ActionTakenValue;
036    import org.kuali.rice.kew.actiontaken.service.ActionTakenService;
037    import org.kuali.rice.kew.api.KewApiServiceLocator;
038    import org.kuali.rice.kew.api.WorkflowDocument;
039    import org.kuali.rice.kew.api.WorkflowDocumentFactory;
040    import org.kuali.rice.kew.api.WorkflowRuntimeException;
041    import org.kuali.rice.kew.api.action.ActionType;
042    import org.kuali.rice.kew.api.document.DocumentProcessingQueue;
043    import org.kuali.rice.kew.api.document.OrchestrationConfig;
044    import org.kuali.rice.kew.api.document.attribute.DocumentAttributeIndexingQueue;
045    import org.kuali.rice.kew.doctype.bo.DocumentType;
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.rule.bo.RuleTemplateBo;
058    import org.kuali.rice.kew.service.KEWServiceLocator;
059    import org.kuali.rice.kew.api.KewApiConstants;
060    import org.kuali.rice.kew.web.KewKualiAction;
061    import org.kuali.rice.kim.api.identity.principal.Principal;
062    import org.kuali.rice.kim.api.services.KimApiServiceLocator;
063    import org.kuali.rice.krad.util.GlobalVariables;
064    
065    import javax.servlet.ServletException;
066    import javax.servlet.http.HttpServletRequest;
067    import javax.servlet.http.HttpServletResponse;
068    import java.io.IOException;
069    import java.sql.Timestamp;
070    import java.text.ParseException;
071    import java.util.ArrayList;
072    import java.util.HashMap;
073    import java.util.HashSet;
074    import java.util.Iterator;
075    import java.util.List;
076    import java.util.Map;
077    import java.util.Set;
078    import java.util.StringTokenizer;
079    
080    
081    /**
082     * Struts Action for doing editing of workflow documents.
083     *
084     * @author Kuali Rice Team (rice.collab@kuali.org)
085     */
086    public class DocumentOperationAction extends KewKualiAction {
087            private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DocumentOperationAction.class);
088            private static final String DEFAULT_LOG_MSG = "Admin change via document operation";
089    
090            public ActionForward start(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
091                    return mapping.findForward("basic");
092            }
093    
094            public ActionForward getDocument(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
095                    DocumentOperationForm docForm = (DocumentOperationForm) form;
096                    String docId = null;
097                    
098                    // check if we have a plausible docId first
099                    if (StringUtils.isEmpty(docForm.getDocumentId())) {
100                            GlobalVariables.getMessageMap().putError("documentId", RiceKeyConstants.ERROR_REQUIRED, "Document ID");
101                    } else {
102                            try {
103                                    docId = docForm.getDocumentId().trim();
104                            } catch (NumberFormatException nfe) {
105                                    GlobalVariables.getMessageMap().putError("documentId", RiceKeyConstants.ERROR_NUMERIC, "Document ID");
106                            }
107                    }
108    
109                    if (docId != null) {
110                            //to clear Document Field first;
111                            docForm.resetOps();
112                            DocumentRouteHeaderValue routeHeader = getRouteHeaderService().getRouteHeader(docId);
113                            List routeNodeInstances=getRouteNodeService().findRouteNodeInstances(docId);
114                            Map branches1=new HashMap();
115                            List branches=new ArrayList();
116    
117                            if (routeHeader == null) {
118                                    GlobalVariables.getMessageMap().putError("documentId", RiceKeyConstants.ERROR_EXISTENCE, "document");
119                            } else {
120                                    materializeDocument(routeHeader);
121                                    docForm.setRouteHeader(routeHeader);
122                                    setRouteHeaderTimestampsToString(docForm);
123                                    docForm.setRouteHeaderOp(KewApiConstants.NOOP);
124                                    docForm.setDocumentId(docForm.getDocumentId().trim());
125                                    String initials="";
126                                    for(Iterator lInitials=routeHeader.getInitialRouteNodeInstances().iterator();lInitials.hasNext();){
127                                            String initial=((RouteNodeInstance)lInitials.next()).getRouteNodeInstanceId();
128                                            LOG.debug(initial);
129                                            initials=initials+initial+", ";
130                                    }
131                                    if(initials.trim().length()>1){
132                                            initials=initials.substring(0,initials.lastIndexOf(","));
133                                    }
134                                    docForm.setInitialNodeInstances(initials);
135                                    request.getSession().setAttribute("routeNodeInstances",routeNodeInstances);
136                                    docForm.setRouteNodeInstances(routeNodeInstances);
137                                    if(routeNodeInstances!=null){
138                                            Iterator routeNodeInstanceIter=routeNodeInstances.iterator();
139                                            while(routeNodeInstanceIter.hasNext()){
140                                                    RouteNodeInstance routeNodeInstance=(RouteNodeInstance) routeNodeInstanceIter.next();
141                                                    Branch branch=routeNodeInstance.getBranch();
142                                                    if (! branches1.containsKey(branch.getName())){
143                                                            branches1.put(branch.getName(),branch);
144                                                            branches.add(branch);
145                                                            LOG.debug(branch.getName()+"; "+branch.getBranchState());
146                                                    }
147                                            }
148                                            if(branches.size()<1){
149                                                    branches=null;
150                                            }
151                                    }
152                                    branches1.clear();
153                                    request.getSession().setAttribute("branches",branches);
154                                    docForm.setBranches(branches);
155                            }
156                    }
157                            
158                    return mapping.findForward("basic");
159            }
160    
161            /**
162             * Sets up various objects on the document which are required for use inside of the Struts and JSP framework.
163             *
164             * Specifically, if a document has action requests with null RouteNodeInstances, it will create empty node instance
165             * objects.
166             */
167            private void materializeDocument(DocumentRouteHeaderValue document) {
168                    for (Iterator iterator = document.getActionRequests().iterator(); iterator.hasNext();) {
169                            ActionRequestValue request = (ActionRequestValue) iterator.next();
170                            if (request.getNodeInstance() == null) {
171                                    request.setNodeInstance(new RouteNodeInstance());
172                            }
173                    }
174            }
175    
176            public ActionForward clear(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
177                    DocumentOperationForm docForm = (DocumentOperationForm) form;
178                    docForm.setRouteHeader(new DocumentRouteHeaderValue());
179                    docForm.setDocumentId(null);
180                    return mapping.findForward("basic");
181            }
182    
183            public ActionMessages establishRequiredState(HttpServletRequest request, ActionForm form) throws Exception {
184                    return null;
185            }
186    
187            public ActionForward save(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
188                    DocumentOperationForm docForm = (DocumentOperationForm) form;
189                    boolean change = false;
190    
191                    String routeHeaderOp = docForm.getRouteHeaderOp();
192                    if (!KewApiConstants.UPDATE.equals(routeHeaderOp) && !KewApiConstants.NOOP.equals(routeHeaderOp)) {
193                            throw new WorkflowServiceErrorException("Document operation not defined", new WorkflowServiceErrorImpl("Document operation not defined", "docoperation.operation.invalid"));
194                    }
195                    if (KewApiConstants.UPDATE.equals(routeHeaderOp)) {
196                            setRouteHeaderTimestamps(docForm);
197                            DocumentRouteHeaderValue dHeader = docForm.getRouteHeader();
198                            String initials=docForm.getInitialNodeInstances();
199                            List<RouteNodeInstance> lInitials = new ArrayList<RouteNodeInstance>();
200                            if (StringUtils.isNotEmpty(initials)){ 
201                                    StringTokenizer tokenInitials=new StringTokenizer(initials,",");
202                                    while (tokenInitials.hasMoreTokens()) {
203                                            String instanceId = tokenInitials.nextToken().trim();
204                                            LOG.debug(instanceId);
205                                            RouteNodeInstance instance = getRouteNodeService().findRouteNodeInstanceById(instanceId);
206                                            lInitials.add(instance);
207                                    }
208                            }
209                            dHeader.setInitialRouteNodeInstances(lInitials);
210                            getRouteHeaderService().validateRouteHeader(docForm.getRouteHeader());
211                            getRouteHeaderService().saveRouteHeader(docForm.getRouteHeader());
212                            change = true;
213                    }
214    
215                    for (Iterator actionRequestIter = docForm.getActionRequestOps().iterator(); actionRequestIter.hasNext();) {
216                            DocOperationIndexedParameter actionRequestOp = (DocOperationIndexedParameter) actionRequestIter.next();
217                            int index = actionRequestOp.getIndex().intValue();
218                            String opValue = actionRequestOp.getValue();
219                            ActionRequestValue actionRequest = docForm.getActionRequests().get(index);
220                            String createDateParamName = "actionRequestCreateDate" + index;
221    
222                            if (!KewApiConstants.UPDATE.equals(opValue) && !KewApiConstants.DELETE.equals(opValue) && !KewApiConstants.NOOP.equals(opValue)) {
223                                    throw new WorkflowServiceErrorException("Action request operation not defined", new WorkflowServiceErrorImpl("Action request operation not defined", "docoperation.actionrequest.operation.invalid"));
224                            }
225                            if (KewApiConstants.UPDATE.equals(opValue)) {
226                                    try {
227                                            actionRequest.setCreateDate(new Timestamp(RiceConstants.getDefaultDateFormat().parse(request.getParameter(createDateParamName)).getTime()));
228                                            actionRequest.setCreateDateString(RiceConstants.getDefaultDateFormat().format(actionRequest.getCreateDate()));
229                                            actionRequest.setDocumentId(docForm.getRouteHeader().getDocumentId());
230                                            actionRequest.setParentActionRequest(getActionRequestService().findByActionRequestId(actionRequest.getParentActionRequestId()));
231                                            actionRequest.setActionTaken(getActionTakenService().findByActionTakenId(actionRequest.getActionTakenId()));
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                                            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().deleteActionRequestGraph(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                                            // getActionTakenService().validateActionTaken(actionTaken);
266                                            getActionTakenService().saveActionTaken(actionTaken);
267                                            change = true;
268                                    } catch (ParseException pe) {
269                                            throw new WorkflowServiceErrorException("Action taken action date parsing error", new WorkflowServiceErrorImpl("Action taken action date parse error", "docoperation.actionstaken.dateparsing.error", actionTaken.getActionTakenId().toString()));
270                                    }
271                            }
272                            if (KewApiConstants.DELETE.equals(opValue)) {
273                                    getActionTakenService().delete(actionTaken);
274                                    change = true;
275                            }
276                    }
277    
278                    for (Iterator actionItemIter = docForm.getActionItemOps().iterator(); actionItemIter.hasNext();) {
279                            DocOperationIndexedParameter actionItemOp = (DocOperationIndexedParameter) actionItemIter.next();
280                            int index = actionItemOp.getIndex().intValue();
281                            String opValue = actionItemOp.getValue();
282    
283                            String dateAssignedParamName = "actionItemDateAssigned" + index;
284                ActionItem actionItem =  docForm.getActionItems().get(index);
285    
286                if (!KewApiConstants.UPDATE.equals(opValue) && !KewApiConstants.DELETE.equals(opValue) && !KewApiConstants.NOOP.equals(opValue)) {
287                                    throw new WorkflowServiceErrorException("Action Item operation not defined", new WorkflowServiceErrorImpl("Action Item operation not defined", "docoperation.operation.invalid"));
288                            }
289                            if (KewApiConstants.UPDATE.equals(opValue)) {
290                                    try {
291                                            actionItem.setDateAssigned(new Timestamp(RiceConstants.getDefaultDateFormat().parse(request.getParameter(dateAssignedParamName)).getTime()));
292                                            actionItem.setDateAssignedStringValue(RiceConstants.getDefaultDateFormat().format(actionItem.getDateAssigned()));
293                                            actionItem.setDocumentId(docForm.getRouteHeader().getDocumentId());
294                                            // getActionItemService().validateActionItem(actionItem);
295                                            getActionListService().saveActionItem(actionItem);
296                                            change = true;
297                                    } catch (ParseException pe) {
298                                            throw new WorkflowServiceErrorException("Action item date assigned parsing error", new WorkflowServiceErrorImpl("Action item date assigned parse error", "docoperation.actionitem.dateassignedparsing.error", actionItem.getId().toString()));
299                                    }
300                            }
301                            if (KewApiConstants.DELETE.equals(opValue)) {
302                    try {
303                        actionItem.setDateAssigned(new Timestamp(RiceConstants.getDefaultDateFormat().parse(request.getParameter(dateAssignedParamName)).getTime()));
304                        actionItem.setDateAssignedStringValue(RiceConstants.getDefaultDateFormat().format(actionItem.getDateAssigned()));
305                        actionItem.setDocumentId(docForm.getRouteHeader().getDocumentId());
306                        getActionListService().deleteActionItem(actionItem);
307                        change = true;
308                    } catch (ParseException pe) {
309                        throw new WorkflowServiceErrorException("Action item date assigned parsing error", new WorkflowServiceErrorImpl("Action item date assigned parse error", "docoperation.actionitem.dateassignedparsing.error", actionItem.getId().toString()));
310                    }
311                            }
312                    }
313    
314                    List routeNodeInstances=(List)(request.getSession().getAttribute("routeNodeInstances"));
315                    String ids = (docForm.getNodeStatesDelete() != null) ? docForm.getNodeStatesDelete().trim() : null;
316                    List statesToBeDeleted=new ArrayList();
317                    if(ids!=null && !ids.equals("")){
318                        StringTokenizer idSets=new StringTokenizer(ids);
319                        while (idSets.hasMoreTokens()) {
320                            String id=idSets.nextToken().trim();
321                            statesToBeDeleted.add(Long.valueOf(id));
322                         }
323                    }
324    
325                    for (Iterator routeNodeInstanceIter = docForm.getRouteNodeInstanceOps().iterator(); routeNodeInstanceIter.hasNext();) {
326                            DocOperationIndexedParameter routeNodeInstanceOp = (DocOperationIndexedParameter) routeNodeInstanceIter.next();
327                            int index = routeNodeInstanceOp.getIndex().intValue();
328                            String opValue = routeNodeInstanceOp.getValue();
329                LOG.debug(opValue);
330                            RouteNodeInstance routeNodeInstance = (RouteNodeInstance)(routeNodeInstances.get(index));
331                            RouteNodeInstance routeNodeInstanceNew = (RouteNodeInstance)(docForm.getRouteNodeInstance(index));
332                            if (!KewApiConstants.UPDATE.equals(opValue) && !KewApiConstants.DELETE.equals(opValue) && !KewApiConstants.NOOP.equals(opValue)) {
333                                    throw new WorkflowServiceErrorException("Route Node Instance Operation not defined", new WorkflowServiceErrorImpl("Route Node Instance Operation not defined", "docoperation.routenodeinstance.operation.invalid"));
334                            }
335                            if (KewApiConstants.UPDATE.equals(opValue)) {
336                                    //LOG.debug("saving routeNodeInstance:"+routeNodeInstance.getRouteNodeInstanceId());
337                                    //getRouteNodeService().save(routeNodeInstance);
338                                    routeNodeInstance.setActive(routeNodeInstanceNew.isActive());
339                                    LOG.debug(Boolean.toString(routeNodeInstanceNew.isActive()));
340                                    routeNodeInstance.setComplete(routeNodeInstanceNew.isComplete());
341                                    routeNodeInstance.setInitial(routeNodeInstanceNew.isInitial());
342                                    List nodeStates=routeNodeInstance.getState();
343                                    List nodeStatesNew=routeNodeInstanceNew.getState();
344    
345                                    if(nodeStates!=null){
346                                            for(int i=0;i<nodeStates.size();i++){
347                                               NodeState nodeState=(NodeState)nodeStates.get(i);
348                                               NodeState nodeStateNew=(NodeState)nodeStatesNew.get(i);
349                                               if(nodeStateNew.getKey()!=null && ! nodeStateNew.getKey().trim().equals("")){
350                                               nodeState.setKey(nodeStateNew.getKey());
351                                               LOG.debug(nodeState.getKey());
352                                               nodeState.setValue(nodeStateNew.getValue());
353                                               LOG.debug(nodeState.getValue());
354                                               }
355                                        }
356                                    }
357                                    getRouteNodeService().save(routeNodeInstance);
358                                    LOG.debug("saved");
359                                    change = true;
360                            }
361    
362    
363                            if (KewApiConstants.DELETE.equals(opValue)) {
364                                    List nodeStates=routeNodeInstance.getState();
365                                    List nodeStatesNew=routeNodeInstanceNew.getState();
366    
367                                    if(nodeStates!=null){
368                                            for(int i=0;i<nodeStates.size();i++){
369                                               NodeState nodeState=(NodeState)nodeStates.get(i);
370                                               NodeState nodeStateNew=(NodeState)nodeStatesNew.get(i);
371                                               if(nodeStateNew.getKey()==null || nodeStateNew.getKey().trim().equals("")){
372                                                 statesToBeDeleted.remove(nodeState.getNodeStateId());
373                                               }
374                                        }
375                                    }
376                                    getRouteNodeService().deleteByRouteNodeInstance(routeNodeInstance);
377                                    LOG.debug(routeNodeInstance.getRouteNodeInstanceId()+" is deleted");
378                                    change = true;
379                                    break;
380                            }
381    
382                            if (KewApiConstants.NOOP.equals(opValue)){
383                                    routeNodeInstanceNew.setActive(routeNodeInstance.isActive());
384                                    routeNodeInstanceNew.setComplete(routeNodeInstance.isComplete());
385                                    routeNodeInstanceNew.setInitial(routeNodeInstance.isInitial());
386                                    List nodeStates=routeNodeInstance.getState();
387                                    List nodeStatesNew=routeNodeInstanceNew.getState();
388                                    if(nodeStates!=null){
389                                       for(int i=0;i<nodeStates.size();i++){
390                                               NodeState nodeState=(NodeState)nodeStates.get(i);
391                                               NodeState nodeStateNew=(NodeState)nodeStatesNew.get(i);
392                                               if(nodeStateNew.getKey()==null || nodeStateNew.getKey().trim().equals("")){
393                                                         statesToBeDeleted.remove(nodeState.getNodeStateId());
394                                               }
395                                               nodeStateNew.setKey(nodeState.getKey());
396                                               nodeStateNew.setValue(nodeState.getValue());
397                                       }
398                                    }
399                            }
400    
401                            //((DocOperationIndexedParameter)(docForm.getRouteNodeInstanceOps().get(index))).setValue(KewApiConstants.NOOP);
402                    }
403    
404                    if(statesToBeDeleted!=null && statesToBeDeleted.size()>0){
405                            getRouteNodeService().deleteNodeStates(statesToBeDeleted);
406                    }
407    
408    
409                    List branches=(List)(request.getSession().getAttribute("branches"));
410                    String branchStateIds = (docForm.getBranchStatesDelete() != null) ? docForm.getBranchStatesDelete().trim() : null;
411                    List branchStatesToBeDeleted=new ArrayList();
412                    if(branchStateIds!=null && !branchStateIds.equals("")){
413                        StringTokenizer idSets=new StringTokenizer(branchStateIds);
414                        while (idSets.hasMoreTokens()) {
415                            String id=idSets.nextToken().trim();
416                            branchStatesToBeDeleted.add(Long.valueOf(id));
417                        }
418                    }
419    
420                    for (Iterator branchesOpIter = docForm.getBranchOps().iterator(); branchesOpIter.hasNext();) {
421                            DocOperationIndexedParameter branchesOp = (DocOperationIndexedParameter) branchesOpIter.next();
422                            int index = branchesOp.getIndex().intValue();
423                            String opValue = branchesOp.getValue();
424                LOG.debug(opValue);
425                            Branch branch = (Branch)(branches.get(index));
426                            Branch branchNew = (Branch)(docForm.getBranche(index));
427                            if (!KewApiConstants.UPDATE.equals(opValue) && !KewApiConstants.NOOP.equals(opValue)) {
428                                    throw new WorkflowServiceErrorException("Route Node Instance Operation not defined", new WorkflowServiceErrorImpl("Route Node Instance Operation not defined", "docoperation.routenodeinstance.operation.invalid"));
429                            }
430                            if (KewApiConstants.UPDATE.equals(opValue)) {
431                                    //LOG.debug("saving routeNodeInstance:"+routeNodeInstance.getRouteNodeInstanceId());
432                                    //getRouteNodeService().save(routeNodeInstance);
433                                    branch.setName(branchNew.getName());
434                                    List branchStates=branch.getBranchState();
435                                    List branchStatesNew=branchNew.getBranchState();
436                                    if(branchStates!=null){
437                                       for(int i=0;i<branchStates.size();i++){
438                                               BranchState branchState=(BranchState)branchStates.get(i);
439                                               if (i < branchStatesNew.size()) {
440                                                    BranchState branchStateNew=(BranchState)branchStatesNew.get(i);
441                                                    if(branchStateNew.getKey()!=null && ! branchStateNew.getKey().trim().equals("")){
442                                                        branchState.setKey(branchStateNew.getKey());
443                                                        LOG.debug(branchState.getKey());
444                                                        branchState.setValue(branchStateNew.getValue());
445                                                        LOG.debug(branchState.getValue());
446                                }
447                                               }
448                                       }
449                                    }
450                                    getBranchService().save(branch);
451                                    LOG.debug("branch saved");
452                                    change = true;
453    
454                            }
455    
456    
457                            if (KewApiConstants.NOOP.equals(opValue)){
458                                    branchNew.setName(branch.getName());
459                                    List branchStates=branch.getBranchState();
460                                    List branchStatesNew=branchNew.getBranchState();
461                                    if(branchStates!=null){
462                                       for(int i=0;i<branchStates.size();i++){
463                                               BranchState branchState=(BranchState)branchStates.get(i);
464                                               BranchState branchStateNew=(BranchState)branchStatesNew.get(i);
465                                               if(branchStateNew.getKey()==null || branchStateNew.getKey().trim().equals("")){
466                                                       branchStatesToBeDeleted.remove(branchState.getBranchStateId());
467                                               }
468                                               branchStateNew.setKey(branchState.getKey());
469                                               LOG.debug(branchState.getKey());
470                                               branchStateNew.setValue(branchState.getValue());
471                                               LOG.debug(branchState.getValue());
472                                       }
473                                    }
474                            }
475                            //((DocOperationIndexedParameter)(docForm.getBranchOps().get(index))).setValue(KewApiConstants.NOOP);
476                    }
477    
478                    if(branchStatesToBeDeleted!=null && branchStatesToBeDeleted.size()>0){
479                            getBranchService().deleteBranchStates(branchStatesToBeDeleted);
480                    }
481    
482                    WorkflowDocument workflowDocument = WorkflowDocumentFactory.loadDocument(GlobalVariables.getUserSession().getPrincipalId(), docForm.getDocumentId());
483    
484                    String annotation = docForm.getAnnotation();
485                    if (StringUtils.isEmpty(annotation)) {
486                            annotation = DEFAULT_LOG_MSG;
487                    }
488                    workflowDocument.logAnnotation(annotation);
489    
490                    ActionMessages messages = new ActionMessages();
491                    String forward = null;
492                    if (change) {
493                            messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("docoperation.operation.saved"));
494                            docForm.setRouteHeader(getRouteHeaderService().getRouteHeader(docForm.getRouteHeader().getDocumentId()));
495                            forward = "summary";
496                    } else {
497                            messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("docoperation.operation.noop"));
498                            forward = "basic";
499                    }
500                    saveMessages(request, messages);
501                    return mapping.findForward(forward);
502    
503            }
504    
505            private RouteHeaderService getRouteHeaderService() {
506                    return (RouteHeaderService) KEWServiceLocator.getService(KEWServiceLocator.DOC_ROUTE_HEADER_SRV);
507            }
508    
509            private RouteNodeService getRouteNodeService(){
510                    return (RouteNodeService) KEWServiceLocator.getService(KEWServiceLocator.ROUTE_NODE_SERVICE);
511            }
512    
513            private ActionRequestService getActionRequestService() {
514                    return (ActionRequestService) KEWServiceLocator.getService(KEWServiceLocator.ACTION_REQUEST_SRV);
515            }
516    
517            private ActionTakenService getActionTakenService() {
518                    return (ActionTakenService) KEWServiceLocator.getService(KEWServiceLocator.ACTION_TAKEN_SRV);
519            }
520    
521            private ActionListService getActionListService() {
522                    return (ActionListService) KEWServiceLocator.getActionListService();
523            }
524    
525            private void setRouteHeaderTimestamps(DocumentOperationForm docForm) {
526                    if (docForm.getCreateDate() == null || docForm.getCreateDate().trim().equals("")) {
527                            throw new WorkflowServiceErrorException("Document create date empty", new WorkflowServiceErrorImpl("Document create date empty", "docoperation.routeheader.createdate.empty"));
528                    } else {
529                            try {
530                                    
531    //                              String a_pat = "yyyy-MM-dd hh:mm:ss";
532    //                              SimpleDateFormat fmt = new SimpleDateFormat(a_pat);
533    //                              
534    //                              System.out.println("**********************new*******************");
535    //                              System.out.println(docForm.getCreateDate());
536    //                              System.out.println("**********************old*******************");
537    //                              System.out.println(docForm.getRouteHeader().getCreateDate());
538    //                              System.out.println("********************************************");
539    //      
540            //                      docForm.getRouteHeader().setCreateDate(new Timestamp(fmt.parse(docForm.getCreateDate()).getTime()));
541    
542                                    docForm.getRouteHeader().setCreateDate(new Timestamp(RiceConstants.getDefaultDateAndTimeFormat().parse(docForm.getCreateDate()).getTime()));
543                            } catch (ParseException pe) {
544                                    throw new WorkflowServiceErrorException("RouteHeader create date parsing error", new WorkflowServiceErrorImpl("Date parsing error", "docoperation.routeheader.createdate.invalid"));
545                            }
546                    }
547    
548                    if (docForm.getDateModified() == null || docForm.getDateModified().trim().equals("")) {
549                            throw new WorkflowServiceErrorException("Document doc status mod date empty", new WorkflowServiceErrorImpl("Document doc status mod date empty", "docoperation.routeheader.statusmoddate.empty"));
550                    } else {
551                            try {
552                                    docForm.getRouteHeader().setDateModified(new Timestamp(
553                            RiceConstants.getDefaultDateAndTimeFormat().parse(docForm.getDateModified()).getTime()));
554                            } catch (ParseException pe) {
555                                    throw new WorkflowServiceErrorException("Document doc status date parsing error", new WorkflowServiceErrorImpl("Document doc status mod date parsing error", "docoperation.routeheader.statusmoddate.invalid"));
556                            }
557                    }
558    
559                    if (docForm.getApprovedDate() != null && !docForm.getApprovedDate().trim().equals("")) {
560                            try {
561                                    docForm.getRouteHeader().setApprovedDate(new Timestamp(RiceConstants.getDefaultDateAndTimeFormat().parse(docForm.getApprovedDate()).getTime()));
562                            } catch (ParseException pe) {
563                                    throw new WorkflowServiceErrorException("Document approved date parsing error", new WorkflowServiceErrorImpl("Document approved date parsing error", "docoperation.routeheader.approveddate.invalid"));
564                            }
565    
566                    }
567    
568                    if (docForm.getFinalizedDate() != null && !docForm.getFinalizedDate().trim().equals("")) {
569                            try {
570                                    docForm.getRouteHeader().setFinalizedDate(new Timestamp(RiceConstants.getDefaultDateAndTimeFormat().parse(docForm.getFinalizedDate()).getTime()));
571                            } catch (ParseException pe) {
572                                    throw new WorkflowServiceErrorException("Document finalized date parsing error", new WorkflowServiceErrorImpl("Document finalized date parsing error", "docoperation.routeheader.finalizeddate.invalid"));
573                            }
574                    }
575    
576                    if (docForm.getRouteStatusDate() != null && !docForm.getRouteStatusDate().trim().equals("")) {
577                            try {
578                                    docForm.getRouteHeader().setRouteStatusDate(new Timestamp(RiceConstants.getDefaultDateAndTimeFormat().parse(docForm.getRouteStatusDate()).getTime()));
579                            } catch (ParseException pe) {
580                                    throw new WorkflowServiceErrorException("Document route status date parsing error", new WorkflowServiceErrorImpl("Document route status date parsing error", "docoperation.routeheader.routestatusdate.invalid"));
581                            }
582    
583                    }
584            }
585    
586            private void setRouteHeaderTimestampsToString(DocumentOperationForm docForm) {
587                    try {
588                            docForm.setCreateDate(RiceConstants.getDefaultDateAndTimeFormat().format(
589                        docForm.getRouteHeader().getCreateDate()));
590                            docForm.setDateModified(RiceConstants.getDefaultDateAndTimeFormat().format(
591                        docForm.getRouteHeader().getDateModified()));
592                            docForm.setApprovedDate(RiceConstants.getDefaultDateAndTimeFormat().format(
593                        docForm.getRouteHeader().getApprovedDate()));
594                            docForm.setFinalizedDate(RiceConstants.getDefaultDateAndTimeFormat().format(
595                        docForm.getRouteHeader().getFinalizedDate()));
596                            docForm.setRouteStatusDate(RiceConstants.getDefaultDateAndTimeFormat().format(
597                        docForm.getRouteHeader().getRouteStatusDate()));
598    
599                    } catch (Exception e) {
600                            LOG.info("One or more of the dates in routeHeader may be null");
601                    }
602            }
603    
604            public ActionForward refresh(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
605                    DocumentOperationForm docForm = (DocumentOperationForm) form;
606                    docForm.getRouteHeader().setDocumentId(docForm.getDocumentId());
607                    return mapping.findForward("basic");
608            }
609    
610            public ActionForward queueDocument(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
611                    try {
612                            DocumentOperationForm docForm = (DocumentOperationForm) form;
613                DocumentRouteHeaderValue document = docForm.getRouteHeader();
614                String applicationId = document.getDocumentType().getApplicationId();
615                DocumentProcessingQueue documentProcessingQueue = KewApiServiceLocator.getDocumentProcessingQueue(document.getDocumentId(), applicationId);
616                            documentProcessingQueue.process(docForm.getDocumentId());
617                            ActionMessages messages = new ActionMessages();
618                            messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("general.message", "Document was successfully queued"));
619                            saveMessages(request, messages);
620                            return mapping.findForward("basic");
621                    } catch (Exception e) {
622                            throw new WorkflowRuntimeException(e);
623                    }
624            }
625    
626            public ActionForward indexSearchableAttributes(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
627                    DocumentOperationForm docForm = (DocumentOperationForm) form;
628            DocumentAttributeIndexingQueue queue = KewApiServiceLocator.getDocumentAttributeIndexingQueue(docForm.getRouteHeader().getDocumentType().getApplicationId());
629            queue.indexDocument(docForm.getRouteHeader().getDocumentId());
630                    ActionMessages messages = new ActionMessages();
631                    messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("general.message", "Searchable Attribute Indexing was successfully scheduled"));
632                    saveMessages(request, messages);
633                    return mapping.findForward("basic");
634            }
635    
636            public ActionForward queueDocumentRefresh(ActionMapping mapping, ActionForm form, HttpServletRequest request,
637                HttpServletResponse response) throws IOException, ServletException {
638                    DocumentOperationForm docForm = (DocumentOperationForm) form;
639                    DocumentRefreshQueue docRequeue = KewApiServiceLocator.getDocumentRequeuerService(
640                        docForm.getRouteHeader().getDocumentType().getApplicationId(), docForm.getRouteHeader().getDocumentId(), 0);
641                    docRequeue.refreshDocument(docForm.getRouteHeader().getDocumentId());
642                    ActionMessages messages = new ActionMessages();
643                    messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("general.message", "Document Requeuer was successfully scheduled"));
644                    saveMessages(request, messages);
645                    return mapping.findForward("basic");
646            }
647    
648            public ActionForward blanketApproveDocument(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
649                    try {
650                            DocumentOperationForm docForm = (DocumentOperationForm) form;
651                String blanketApproverUser = docForm.getBlanketApproveUser();
652                if (StringUtils.isBlank(blanketApproverUser)) {
653                    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"));
654                }
655                            String principalId = KimApiServiceLocator.getPersonService().getPersonByPrincipalName(docForm.getBlanketApproveUser()).getPrincipalId();
656                            Set<String> nodeNames = new HashSet<String>();
657                            if (!StringUtils.isBlank(docForm.getBlanketApproveNodes())) {
658                                    String[] nodeNameArray = docForm.getBlanketApproveNodes().split(",");
659                                    for (String nodeName : nodeNameArray) {
660                                            nodeNames.add(nodeName.trim());
661                                    }
662                            }
663                            DocumentRouteHeaderValue document = docForm.getRouteHeader();
664                String applicationId = document.getDocumentType().getApplicationId();
665                DocumentOrchestrationQueue blanketApprove = KewApiServiceLocator.getDocumentOrchestrationQueue(
666                        document.getDocumentId(), applicationId);
667                OrchestrationConfig orchestrationConfig = OrchestrationConfig.create(docForm.getBlanketApproveActionTakenId(), nodeNames);
668                DocumentProcessingOptions options = DocumentProcessingOptions.createDefault();
669                            blanketApprove.orchestrateDocument(docForm.getRouteHeader().getDocumentId(), principalId,
670                        orchestrationConfig, options);
671                            ActionMessages messages = new ActionMessages();
672                            messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("general.message", "Blanket Approve Processor was successfully scheduled"));
673                            saveMessages(request, messages);
674                            return mapping.findForward("basic");
675                    } catch (Exception e) {
676                            throw new WorkflowRuntimeException(e);
677                    }
678            }
679            
680            public ActionForward moveDocument(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
681                    try {
682                            DocumentOperationForm docForm = (DocumentOperationForm) form;
683                            String principalId = KEWServiceLocator.getIdentityHelperService().getIdForPrincipalName(docForm.getBlanketApproveUser());
684                            Set<String> nodeNames = new HashSet<String>();
685                            if (!StringUtils.isBlank(docForm.getBlanketApproveNodes())) {
686                                    String[] nodeNameArray = docForm.getBlanketApproveNodes().split(",");
687                                    for (String nodeName : nodeNameArray) {
688                                            nodeNames.add(nodeName.trim());
689                                    }
690                            }
691                DocumentRouteHeaderValue document = docForm.getRouteHeader();
692                String applicationId = document.getDocumentType().getApplicationId();
693                DocumentOrchestrationQueue orchestrationQueue = KewApiServiceLocator.getDocumentOrchestrationQueue(
694                        document.getDocumentId(), applicationId);
695                OrchestrationConfig orchestrationConfig = OrchestrationConfig.create(docForm.getBlanketApproveActionTakenId(), nodeNames);
696                DocumentProcessingOptions options = DocumentProcessingOptions.create(true, true, false);
697                orchestrationQueue.orchestrateDocument(docForm.getDocumentId(), principalId, orchestrationConfig, options);
698    
699                ActionMessages messages = new ActionMessages();
700                            messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("general.message", "Move Document Processor was successfully scheduled"));
701                            saveMessages(request, messages);
702                            return mapping.findForward("basic");
703                    } catch (Exception e) {
704                            throw new WorkflowRuntimeException(e);
705                    }
706            }
707    
708            public ActionForward queueActionInvocation(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
709                    try {
710                            DocumentOperationForm docForm = (DocumentOperationForm) form;
711                            String principalId = KEWServiceLocator.getIdentityHelperService().getIdForPrincipalName(docForm.getActionInvocationUser());
712                            ActionInvocation invocation = ActionInvocation.create(ActionType.fromCode(
713                        docForm.getActionInvocationActionCode()), docForm.getActionInvocationActionItemId());
714                DocumentRouteHeaderValue document = docForm.getRouteHeader();
715                String applicationId = document.getDocumentType().getApplicationId();
716                            ActionInvocationQueue actionInvocationQueue = KewApiServiceLocator.getActionInvocationProcessorService(
717                                document.getDocumentId(), applicationId);
718                            actionInvocationQueue.invokeAction(principalId, docForm.getRouteHeader().getDocumentId(), invocation);
719                            ActionMessages messages = new ActionMessages();
720                            messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("general.message", "Action Invocation Processor was successfully scheduled"));
721                            saveMessages(request, messages);
722                            return mapping.findForward("basic");
723                    } catch (Exception e) {
724                            throw new WorkflowRuntimeException(e);
725                    }
726            }
727    
728            private DocumentTypeService getDocumentTypeService() {
729                    return (DocumentTypeService) KEWServiceLocator.getService(KEWServiceLocator.DOCUMENT_TYPE_SERVICE);
730            }
731    
732            private BranchService getBranchService(){
733                    return (BranchService) KEWServiceLocator.getService(KEWServiceLocator.BRANCH_SERVICE);
734            }
735    }