001/**
002 * Copyright 2005-2016 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 */
016package org.kuali.rice.kew.documentoperation.web;
017
018import org.apache.commons.lang.StringUtils;
019import org.apache.struts.action.ActionForm;
020import org.apache.struts.action.ActionForward;
021import org.apache.struts.action.ActionMapping;
022import org.apache.struts.action.ActionMessage;
023import org.apache.struts.action.ActionMessages;
024import org.kuali.rice.core.api.util.RiceConstants;
025import org.kuali.rice.core.api.util.RiceKeyConstants;
026import org.kuali.rice.kew.actionitem.ActionItem;
027import org.kuali.rice.kew.actionlist.service.ActionListService;
028import org.kuali.rice.kew.actionrequest.ActionRequestValue;
029import org.kuali.rice.kew.actionrequest.service.ActionRequestService;
030import org.kuali.rice.kew.api.document.DocumentOrchestrationQueue;
031import org.kuali.rice.kew.api.document.DocumentProcessingOptions;
032import org.kuali.rice.kew.api.document.DocumentRefreshQueue;
033import org.kuali.rice.kew.api.action.ActionInvocation;
034import org.kuali.rice.kew.api.action.ActionInvocationQueue;
035import org.kuali.rice.kew.actiontaken.ActionTakenValue;
036import org.kuali.rice.kew.actiontaken.service.ActionTakenService;
037import org.kuali.rice.kew.api.KewApiServiceLocator;
038import org.kuali.rice.kew.api.WorkflowDocument;
039import org.kuali.rice.kew.api.WorkflowDocumentFactory;
040import org.kuali.rice.kew.api.WorkflowRuntimeException;
041import org.kuali.rice.kew.api.action.ActionType;
042import org.kuali.rice.kew.api.document.DocumentProcessingQueue;
043import org.kuali.rice.kew.api.document.OrchestrationConfig;
044import org.kuali.rice.kew.api.document.attribute.DocumentAttributeIndexingQueue;
045import org.kuali.rice.kew.doctype.bo.DocumentType;
046import org.kuali.rice.kew.doctype.service.DocumentTypeService;
047import org.kuali.rice.kew.engine.node.Branch;
048import org.kuali.rice.kew.engine.node.BranchState;
049import org.kuali.rice.kew.engine.node.NodeState;
050import org.kuali.rice.kew.engine.node.RouteNodeInstance;
051import org.kuali.rice.kew.engine.node.service.BranchService;
052import org.kuali.rice.kew.engine.node.service.RouteNodeService;
053import org.kuali.rice.kew.exception.WorkflowServiceErrorException;
054import org.kuali.rice.kew.exception.WorkflowServiceErrorImpl;
055import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
056import org.kuali.rice.kew.routeheader.service.RouteHeaderService;
057import org.kuali.rice.kew.rule.bo.RuleTemplateBo;
058import org.kuali.rice.kew.service.KEWServiceLocator;
059import org.kuali.rice.kew.api.KewApiConstants;
060import org.kuali.rice.kew.web.KewKualiAction;
061import org.kuali.rice.kim.api.identity.principal.Principal;
062import org.kuali.rice.kim.api.services.KimApiServiceLocator;
063import org.kuali.rice.krad.util.GlobalVariables;
064
065import javax.servlet.ServletException;
066import javax.servlet.http.HttpServletRequest;
067import javax.servlet.http.HttpServletResponse;
068import java.io.IOException;
069import java.sql.Timestamp;
070import java.text.ParseException;
071import java.util.ArrayList;
072import java.util.HashMap;
073import java.util.HashSet;
074import java.util.Iterator;
075import java.util.List;
076import java.util.Map;
077import java.util.Set;
078import 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 */
086public 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}