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