Coverage Report - org.kuali.rice.kew.actionlist.web.ActionListAction
 
Classes in this File Line Coverage Branch Coverage Complexity
ActionListAction
0%
0/428
0%
0/256
5.706
ActionListAction$ActionItemComparator
0%
0/23
0%
0/14
5.706
ActionListAction$PartitionKey
0%
0/18
0%
0/4
5.706
 
 1  
 /**
 2  
  * Copyright 2005-2011 The Kuali Foundation
 3  
  *
 4  
  * Licensed under the Educational Community License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  * http://www.opensource.org/licenses/ecl2.php
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 package org.kuali.rice.kew.actionlist.web;
 17  
 
 18  
 import java.util.ArrayList;
 19  
 import java.util.Arrays;
 20  
 import java.util.Collection;
 21  
 import java.util.Collections;
 22  
 import java.util.Comparator;
 23  
 import java.util.HashSet;
 24  
 import java.util.Iterator;
 25  
 import java.util.LinkedHashMap;
 26  
 import java.util.List;
 27  
 import java.util.Map;
 28  
 import java.util.Set;
 29  
 
 30  
 import javax.servlet.http.HttpServletRequest;
 31  
 import javax.servlet.http.HttpServletResponse;
 32  
 
 33  
 import org.apache.commons.collections.CollectionUtils;
 34  
 import org.apache.commons.collections.ComparatorUtils;
 35  
 import org.apache.commons.lang.StringUtils;
 36  
 import org.apache.commons.lang.builder.EqualsBuilder;
 37  
 import org.apache.commons.lang.builder.HashCodeBuilder;
 38  
 import org.apache.struts.action.ActionForm;
 39  
 import org.apache.struts.action.ActionForward;
 40  
 import org.apache.struts.action.ActionMapping;
 41  
 import org.apache.struts.action.ActionMessage;
 42  
 import org.apache.struts.action.ActionMessages;
 43  
 import org.displaytag.pagination.PaginatedList;
 44  
 import org.displaytag.properties.SortOrderEnum;
 45  
 import org.displaytag.util.LookupUtil;
 46  
 import org.kuali.rice.core.api.config.property.ConfigContext;
 47  
 import org.kuali.rice.core.api.delegation.DelegationType;
 48  
 import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
 49  
 import org.kuali.rice.core.api.exception.RiceRuntimeException;
 50  
 import org.kuali.rice.kew.actionitem.ActionItem;
 51  
 import org.kuali.rice.kew.actionitem.ActionItemActionListExtension;
 52  
 import org.kuali.rice.kew.actionlist.ActionListFilter;
 53  
 import org.kuali.rice.kew.actionlist.ActionToTake;
 54  
 import org.kuali.rice.kew.actionlist.CustomActionListAttribute;
 55  
 import org.kuali.rice.kew.actionlist.PaginatedActionList;
 56  
 import org.kuali.rice.kew.actionlist.service.ActionListService;
 57  
 import org.kuali.rice.kew.actionrequest.Recipient;
 58  
 import org.kuali.rice.kew.api.WorkflowRuntimeException;
 59  
 import org.kuali.rice.kew.api.action.ActionInvocation;
 60  
 import org.kuali.rice.kew.api.action.ActionSet;
 61  
 import org.kuali.rice.kew.api.action.ActionType;
 62  
 import org.kuali.rice.kew.api.exception.WorkflowException;
 63  
 import org.kuali.rice.kew.api.extension.ExtensionDefinition;
 64  
 import org.kuali.rice.kew.framework.KewFrameworkServiceLocator;
 65  
 import org.kuali.rice.kew.framework.actionlist.ActionListCustomizationHandlerService;
 66  
 import org.kuali.rice.kew.framework.document.security.DocumentSecurityDirective;
 67  
 import org.kuali.rice.kew.framework.document.security.DocumentSecurityHandlerService;
 68  
 import org.kuali.rice.kew.api.preferences.Preferences;
 69  
 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
 70  
 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValueActionListExtension;
 71  
 import org.kuali.rice.kew.service.KEWServiceLocator;
 72  
 import org.kuali.rice.kew.api.KewApiConstants;
 73  
 import org.kuali.rice.kew.util.PerformanceLogger;
 74  
 import org.kuali.rice.kim.api.identity.Person;
 75  
 import org.kuali.rice.kim.api.identity.principal.Principal;
 76  
 import org.kuali.rice.kim.api.identity.principal.PrincipalContract;
 77  
 import org.kuali.rice.kns.web.struts.action.KualiAction;
 78  
 import org.kuali.rice.kns.web.ui.ExtraButton;
 79  
 import org.kuali.rice.krad.UserSession;
 80  
 import org.kuali.rice.krad.exception.AuthorizationException;
 81  
 import org.kuali.rice.krad.util.GlobalVariables;
 82  
 import org.springframework.util.LinkedMultiValueMap;
 83  
 import org.springframework.util.MultiValueMap;
 84  
 
 85  
 
 86  
 /**
 87  
  * Action doing Action list stuff
 88  
  *
 89  
  * @author Kuali Rice Team (rice.collab@kuali.org)a
 90  
  *
 91  
  */
 92  0
 public class ActionListAction extends KualiAction {
 93  
 
 94  0
         private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ActionListAction.class);
 95  
 
 96  
     private static final String ACTION_LIST_KEY = "actionList";
 97  
     private static final String ACTION_LIST_PAGE_KEY = "actionListPage";
 98  
     private static final String ACTION_LIST_USER_KEY = "actionList.user";
 99  
     private static final String REQUERY_ACTION_LIST_KEY = "requeryActionList";
 100  
 
 101  
     private static final String ACTIONREQUESTCD_PROP = "actionRequestCd";
 102  
     private static final String CUSTOMACTIONLIST_PROP = "customActionList";
 103  
     private static final String ACTIONITEM_PROP = "actionitem";
 104  
     private static final String HELPDESK_ACTIONLIST_USERNAME = "helpDeskActionListUserName";
 105  
 
 106  
     private static final String ACTIONITEM_ACTIONREQUESTCD_INVALID_ERRKEY = "actionitem.actionrequestcd.invalid";
 107  
     private static final String ACTIONLIST_BAD_CUSTOM_ACTION_LIST_ITEMS_ERRKEY = "actionlist.badCustomActionListItems";
 108  
         private static final String ACTIONLIST_BAD_ACTION_ITEMS_ERRKEY = "actionlist.badActionItems";
 109  
         private static final String HELPDESK_LOGIN_EMPTY_ERRKEY = "helpdesk.login.empty";
 110  
         private static final String HELPDESK_LOGIN_INVALID_ERRKEY = "helpdesk.login.invalid";
 111  
 
 112  
 
 113  
         @Override
 114  
         public ActionForward execute(ActionMapping mapping, ActionForm actionForm, HttpServletRequest request, HttpServletResponse response) throws Exception {
 115  0
             ActionListForm frm = (ActionListForm)actionForm;
 116  0
             request.setAttribute("Constants", getServlet().getServletContext().getAttribute("KewApiConstants"));
 117  0
             request.setAttribute("preferences", getUserSession().retrieveObject(KewApiConstants.PREFERENCES));
 118  0
             frm.setHeaderButtons(getHeaderButtons());
 119  0
             return super.execute(mapping, actionForm, request, response);
 120  
     }
 121  
 
 122  
     private List<ExtraButton> getHeaderButtons(){
 123  0
             List<ExtraButton> headerButtons = new ArrayList<ExtraButton>();
 124  0
             ExtraButton eb = new ExtraButton();
 125  0
             String krBaseUrl = ConfigContext.getCurrentContextConfig().getKRBaseURL();
 126  0
             eb.setExtraButtonSource( krBaseUrl + "/images/tinybutton-preferences.gif");
 127  0
             eb.setExtraButtonOnclick("Preferences.do?returnMapping=viewActionList");
 128  
 
 129  0
             headerButtons.add(eb);
 130  0
             eb = new ExtraButton();
 131  0
             eb.setExtraButtonSource(krBaseUrl + "/images/tinybutton-refresh.gif");
 132  0
             eb.setExtraButtonProperty("methodToCall.start");
 133  
 
 134  0
             headerButtons.add(eb);
 135  0
             eb = new ExtraButton();
 136  0
             eb.setExtraButtonSource(krBaseUrl + "/images/tinybutton-filter.gif");
 137  0
             eb.setExtraButtonOnclick("javascript: window.open('ActionListFilter.do?methodToCall=start');");
 138  0
             headerButtons.add(eb);
 139  
 
 140  
 
 141  0
             return headerButtons;
 142  
     }
 143  
 
 144  
 
 145  
 
 146  
         @Override
 147  
         protected ActionForward defaultDispatch(ActionMapping mapping,
 148  
                         ActionForm form, HttpServletRequest request,
 149  
                         HttpServletResponse response) throws Exception {
 150  0
                 return start(mapping, form, request, response);
 151  
         }
 152  
 
 153  
         public ActionForward start(ActionMapping mapping, ActionForm actionForm, HttpServletRequest request, HttpServletResponse response) throws Exception {
 154  0
         PerformanceLogger plog = new PerformanceLogger();
 155  0
         plog.log("Starting ActionList fetch");
 156  0
         ActionListForm form = (ActionListForm) actionForm;
 157  0
         ActionListService actionListSrv = KEWServiceLocator.getActionListService();
 158  
 
 159  
 
 160  
         // process display tag parameters
 161  0
         Integer page = form.getPage();
 162  0
         String sortCriterion = form.getSort();
 163  0
         SortOrderEnum sortOrder = SortOrderEnum.ASCENDING;
 164  0
         final UserSession uSession = getUserSession();
 165  
         
 166  0
         if (form.getDir() != null) {
 167  0
                 sortOrder = parseSortOrder(form.getDir());
 168  
         }
 169  0
         else if ( !StringUtils.isEmpty((String) uSession.retrieveObject(KewApiConstants.SORT_ORDER_ATTR_NAME)))     {
 170  0
                 sortOrder = parseSortOrder((String) uSession.retrieveObject(KewApiConstants.SORT_ORDER_ATTR_NAME));
 171  
         }
 172  
         // if both the page and the sort criteria are null, that means its the first entry into the page, use defaults
 173  0
         if (page == null && sortCriterion == null) {
 174  0
                 page = Integer.valueOf(1);
 175  0
                 sortCriterion = ActionItemComparator.DOCUMENT_ID;
 176  
         }
 177  0
         else if ( !StringUtils.isEmpty((String) uSession.retrieveObject(KewApiConstants.SORT_CRITERIA_ATTR_NAME)))     {
 178  0
                 sortCriterion = (String) uSession.retrieveObject(KewApiConstants.SORT_CRITERIA_ATTR_NAME);
 179  
         }
 180  
         // if the page is still null, that means the user just performed a sort action, pull the currentPage off of the form
 181  0
         if (page == null) {
 182  0
                 page = form.getCurrentPage();
 183  
         }
 184  
 
 185  
         // update the values of the "current" display tag parameters
 186  0
         form.setCurrentPage(page);
 187  0
         if (!StringUtils.isEmpty(sortCriterion)) {
 188  0
                 form.setCurrentSort(sortCriterion);
 189  0
                 form.setCurrentDir(getSortOrderValue(sortOrder));
 190  
         }
 191  
 
 192  
         // reset the default action on the form
 193  0
         form.setDefaultActionToTake("NONE");
 194  
 
 195  0
         boolean freshActionList = true;
 196  
         // retrieve cached action list
 197  0
         List<ActionItem> actionList = (List<ActionItem>)request.getSession().getAttribute(ACTION_LIST_KEY);
 198  0
         plog.log("Time to initialize");
 199  
         try {
 200  
             //UserSession uSession = getUserSession(request);
 201  0
             String principalId = null;
 202  0
             if (uSession.retrieveObject(KewApiConstants.ACTION_LIST_FILTER_ATTR_NAME) == null) {
 203  0
                 ActionListFilter filter = new ActionListFilter();
 204  0
                 filter.setDelegationType(DelegationType.SECONDARY.getCode());
 205  0
                 filter.setExcludeDelegationType(true);
 206  0
                 uSession.addObject(KewApiConstants.ACTION_LIST_FILTER_ATTR_NAME, filter);
 207  
             }
 208  
 
 209  0
             final ActionListFilter filter = (ActionListFilter) uSession.retrieveObject(KewApiConstants.ACTION_LIST_FILTER_ATTR_NAME);
 210  
             /* 'forceListRefresh' variable used to signify that the action list filter has changed
 211  
              * any time the filter changes the action list must be refreshed or filter may not take effect on existing
 212  
              * list items... only exception is if action list has not loaded previous and fetching of the list has not
 213  
              * occurred yet
 214  
              */
 215  0
             boolean forceListRefresh = request.getSession().getAttribute(REQUERY_ACTION_LIST_KEY) != null;
 216  0
             if (uSession.retrieveObject(KewApiConstants.HELP_DESK_ACTION_LIST_PRINCIPAL_ATTR_NAME) != null) {
 217  0
                     principalId = ((PrincipalContract) uSession.retrieveObject(KewApiConstants.HELP_DESK_ACTION_LIST_PRINCIPAL_ATTR_NAME)).getPrincipalId();
 218  
             } else {
 219  0
                 if (!StringUtils.isEmpty(form.getDocType())) {
 220  0
                         filter.setDocumentType(form.getDocType());
 221  0
                         filter.setExcludeDocumentType(false);
 222  0
                     forceListRefresh = true;
 223  
                 }
 224  0
                 principalId = uSession.getPerson().getPrincipalId();
 225  
             }
 226  
 
 227  0
             final Preferences preferences = (Preferences) getUserSession().retrieveObject(KewApiConstants.PREFERENCES);
 228  
 
 229  0
             if (!StringUtils.isEmpty(form.getDelegationId())) {
 230  0
                     if (!KewApiConstants.DELEGATION_DEFAULT.equals(form.getDelegationId())) {
 231  
                             // If the user can filter by both primary and secondary delegation, and both drop-downs have non-default values assigned,
 232  
                             // then reset the primary delegation drop-down's value when the primary delegation drop-down's value has remained unaltered
 233  
                             // but the secondary drop-down's value has been altered; but if one of these alteration situations does not apply, reset the
 234  
                             // secondary delegation drop-down.
 235  0
                             if (StringUtils.isNotBlank(form.getPrimaryDelegateId()) && !KewApiConstants.PRIMARY_DELEGATION_DEFAULT.equals(form.getPrimaryDelegateId())){
 236  0
                                     if (form.getPrimaryDelegateId().equals(request.getParameter("oldPrimaryDelegateId")) &&
 237  
                                                     !form.getDelegationId().equals(request.getParameter("oldDelegationId"))) {
 238  0
                                             form.setPrimaryDelegateId(KewApiConstants.PRIMARY_DELEGATION_DEFAULT);
 239  
                                     } else {
 240  0
                                             form.setDelegationId(KewApiConstants.DELEGATION_DEFAULT);
 241  
                                     }
 242  0
                             } else if (StringUtils.isNotBlank(filter.getPrimaryDelegateId()) &&
 243  
                                             !KewApiConstants.PRIMARY_DELEGATION_DEFAULT.equals(filter.getPrimaryDelegateId())) {
 244  
                                     // If the primary delegation drop-down is invisible but a primary delegation filter is in place, and if the secondary delegation
 245  
                                     // drop-down has a non-default value selected, then reset the primary delegation filtering.
 246  0
                                     filter.setPrimaryDelegateId(KewApiConstants.PRIMARY_DELEGATION_DEFAULT);
 247  
                             }
 248  
                     }
 249  
                     // Enable the secondary delegation filtering.
 250  0
                            filter.setDelegatorId(form.getDelegationId());
 251  0
                            filter.setExcludeDelegatorId(false);
 252  0
                            actionList = null;
 253  
             }
 254  
 
 255  0
             if (!StringUtils.isEmpty(form.getPrimaryDelegateId())) {
 256  
                     // If the secondary delegation drop-down is invisible but a secondary delegation filter is in place, and if the primary delegation
 257  
                     // drop-down has a non-default value selected, then reset the secondary delegation filtering.
 258  0
                     if (StringUtils.isBlank(form.getDelegationId()) && !KewApiConstants.PRIMARY_DELEGATION_DEFAULT.equals(form.getPrimaryDelegateId()) &&
 259  
                                     StringUtils.isNotBlank(filter.getDelegatorId()) &&
 260  
                                                     !KewApiConstants.DELEGATION_DEFAULT.equals(filter.getDelegatorId())) {
 261  0
                             filter.setDelegatorId(KewApiConstants.DELEGATION_DEFAULT);
 262  
                     }
 263  
                     // Enable the primary delegation filtering.
 264  0
                     filter.setPrimaryDelegateId(form.getPrimaryDelegateId());
 265  0
                     filter.setExcludeDelegatorId(false);
 266  0
                     actionList = null;
 267  
             }
 268  
             
 269  
             // if the user has changed, we need to refresh the action list
 270  0
             if (!principalId.equals(request.getSession().getAttribute(ACTION_LIST_USER_KEY))) {
 271  0
                 actionList = null;
 272  
             }
 273  
 
 274  0
             if (isOutboxMode(form, request, preferences)) {
 275  0
                     actionList = new ArrayList<ActionItem>(actionListSrv.getOutbox(principalId, filter));
 276  0
                     form.setOutBoxEmpty(actionList.isEmpty());
 277  
             } else {
 278  0
                 if (actionList == null) {
 279  
                         //clear out old User Option records if they exist
 280  0
                         actionListSrv.refreshActionList(getUserSession().getPerson().getPrincipalId());
 281  
                         // fetch the action list
 282  0
                     actionList = new ArrayList<ActionItem>(actionListSrv.getActionList(principalId, filter));
 283  0
                     request.getSession().setAttribute(ACTION_LIST_USER_KEY, principalId);
 284  0
                 } else if (forceListRefresh) {
 285  
                         // force a refresh... usually based on filter change or parameter specifying refresh needed
 286  0
                     actionList = new ArrayList<ActionItem>(actionListSrv.getActionList(principalId, filter));
 287  0
                     request.getSession().setAttribute(ACTION_LIST_USER_KEY, principalId);
 288  0
                 } else if (actionListSrv.refreshActionList(getUserSession().getPerson().getPrincipalId())) {
 289  0
                     actionList = new ArrayList<ActionItem>(actionListSrv.getActionList(principalId, filter));
 290  0
                     request.getSession().setAttribute(ACTION_LIST_USER_KEY, principalId);
 291  
                 } else {
 292  0
                         Boolean update = (Boolean) uSession.retrieveObject(KewApiConstants.UPDATE_ACTION_LIST_ATTR_NAME);
 293  0
                         if (update == null || !update) {
 294  0
                                 freshActionList = false;
 295  
                         }
 296  
                 }
 297  0
                 request.getSession().setAttribute(ACTION_LIST_KEY, actionList);
 298  
             }
 299  
             // reset the requery action list key
 300  0
             request.getSession().setAttribute(REQUERY_ACTION_LIST_KEY, null);
 301  
 
 302  
             // build the drop-down of delegators
 303  0
             if (KewApiConstants.DELEGATORS_ON_ACTION_LIST_PAGE.equalsIgnoreCase(preferences.getDelegatorFilter())) {
 304  0
                 Collection delegators = actionListSrv.findUserSecondaryDelegators(principalId);
 305  0
                 form.setDelegators(ActionListUtil.getWebFriendlyRecipients(delegators));
 306  0
                 form.setDelegationId(filter.getDelegatorId());
 307  
             }
 308  
 
 309  
             // Build the drop-down of primary delegates.
 310  0
             if (KewApiConstants.PRIMARY_DELEGATES_ON_ACTION_LIST_PAGE.equalsIgnoreCase(preferences.getPrimaryDelegateFilter())) {
 311  0
                     Collection<Recipient> pDelegates = actionListSrv.findUserPrimaryDelegations(principalId);
 312  0
                     form.setPrimaryDelegates(ActionListUtil.getWebFriendlyRecipients(pDelegates));
 313  0
                     form.setPrimaryDelegateId(filter.getPrimaryDelegateId());
 314  
             }
 315  
             
 316  0
             form.setFilterLegend(filter.getFilterLegend());
 317  0
             plog.log("Setting attributes");
 318  
 
 319  0
             int pageSize = getPageSize(preferences);
 320  
             // initialize the action list if necessary
 321  0
             if (freshActionList) {
 322  0
                     plog.log("calling initializeActionList");
 323  0
                     initializeActionList(actionList, preferences);
 324  0
                     plog.log("done w/ initializeActionList");
 325  
                     // put this in to resolve EN-112 (http://beatles.uits.indiana.edu:8081/jira/browse/EN-112)
 326  
                 // if the action list gets "refreshed" in between page switches, we need to be sure and re-sort it, even though we don't have sort criteria on the request
 327  0
                     if (sortCriterion == null) {
 328  0
                             sortCriterion = form.getCurrentSort();
 329  0
                             sortOrder = parseSortOrder(form.getCurrentDir());
 330  
                     }
 331  
             }
 332  
             // sort the action list if necessary
 333  0
             if (sortCriterion != null) {
 334  0
                     sortActionList(actionList, sortCriterion, sortOrder);
 335  
             }
 336  
             
 337  0
             plog.log("calling buildCurrentPage");
 338  0
             PaginatedList currentPage = buildCurrentPage(actionList, form.getCurrentPage(), form.getCurrentSort(), 
 339  
                                     form.getCurrentDir(), pageSize, preferences, form);
 340  0
             plog.log("done w/ buildCurrentPage");
 341  0
             request.setAttribute(ACTION_LIST_PAGE_KEY, currentPage);
 342  0
             uSession.addObject(KewApiConstants.UPDATE_ACTION_LIST_ATTR_NAME, Boolean.FALSE);
 343  0
             uSession.addObject(KewApiConstants.CURRENT_PAGE_ATTR_NAME, form.getCurrentPage());
 344  0
             uSession.addObject(KewApiConstants.SORT_CRITERIA_ATTR_NAME, form.getSort());
 345  0
             uSession.addObject(KewApiConstants.SORT_ORDER_ATTR_NAME, form.getCurrentDir());
 346  0
             plog.log("finished setting attributes, finishing action list fetch");
 347  0
         } catch (Exception e) {
 348  0
             LOG.error("Error loading action list.", e);
 349  0
         }
 350  
 
 351  0
         LOG.debug("end start ActionListAction");
 352  0
         return mapping.findForward("viewActionList");
 353  
     }
 354  
 
 355  
     private SortOrderEnum parseSortOrder(String dir) throws WorkflowException {
 356  0
             if ("asc".equals(dir)) {
 357  0
                     return SortOrderEnum.ASCENDING;
 358  0
             } else if ("desc".equals(dir)) {
 359  0
                     return SortOrderEnum.DESCENDING;
 360  
             }
 361  0
             throw new WorkflowException("Invalid sort direction: " + dir);
 362  
     }
 363  
 
 364  
     private String getSortOrderValue(SortOrderEnum sortOrder) {
 365  0
             if (SortOrderEnum.ASCENDING.equals(sortOrder)) {
 366  0
                     return "asc";
 367  0
             } else if (SortOrderEnum.DESCENDING.equals(sortOrder)) {
 368  0
                     return "desc";
 369  
             }
 370  0
             return null;
 371  
     }
 372  
 
 373  
     private static final String OUT_BOX_MODE = "_OUT_BOX_MODE";
 374  
 
 375  
     /**
 376  
      * this method is setting 2 props on the {@link ActionListForm} that controls outbox behavior.
 377  
      *  alForm.setViewOutbox("false"); -> this is set by user preferences and the actionlist.outbox.off config prop
 378  
      *  alForm.setShowOutbox(false); -> this is set by user action clicking the ActionList vs. Outbox links.
 379  
      *
 380  
      * @param alForm
 381  
      * @param request
 382  
      * @return boolean indication whether the outbox should be fetched
 383  
      */
 384  
     private boolean isOutboxMode(ActionListForm alForm, HttpServletRequest request, Preferences preferences) {
 385  
 
 386  0
         boolean outBoxView = false;
 387  
 
 388  0
         if (! preferences.isUsingOutbox() || ! ConfigContext.getCurrentContextConfig().getOutBoxOn()) {
 389  0
             request.getSession().setAttribute(OUT_BOX_MODE, Boolean.valueOf(false));
 390  0
             alForm.setViewOutbox("false");
 391  0
             alForm.setShowOutbox(false);
 392  0
             return false;
 393  
         }
 394  
 
 395  0
         alForm.setShowOutbox(true);
 396  0
         if (StringUtils.isNotEmpty(alForm.getViewOutbox())) {
 397  0
             if (!Boolean.valueOf(alForm.getViewOutbox())) {
 398  0
                 request.getSession().setAttribute(OUT_BOX_MODE, Boolean.valueOf(false));
 399  0
                 outBoxView = false;
 400  
             } else {
 401  0
                 request.getSession().setAttribute(OUT_BOX_MODE, Boolean.valueOf(true));
 402  0
                 outBoxView = true;
 403  
             }
 404  
         } else {
 405  
 
 406  0
             if (request.getSession().getAttribute(OUT_BOX_MODE) == null) {
 407  0
                 outBoxView = false;
 408  
             } else {
 409  0
                 outBoxView = (Boolean) request.getSession().getAttribute(OUT_BOX_MODE);
 410  
             }
 411  
         }
 412  0
         if (outBoxView) {
 413  0
             alForm.setViewOutbox("true");
 414  
         } else {
 415  0
             alForm.setViewOutbox("false");
 416  
         }
 417  0
         return outBoxView;
 418  
     }
 419  
 
 420  
     private void sortActionList(List<ActionItem> actionList, String sortName, SortOrderEnum sortOrder) {
 421  0
             if (StringUtils.isEmpty(sortName)) {
 422  0
                     return;
 423  
             }
 424  0
             Comparator comparator = new ActionItemComparator(sortName);
 425  0
             if (SortOrderEnum.DESCENDING.equals(sortOrder)) {
 426  0
                     comparator = ComparatorUtils.reversedComparator(comparator);
 427  
             }
 428  0
             Collections.sort(actionList, comparator);
 429  
             // re-index the action items
 430  0
             int index = 0;
 431  0
             for (ActionItem actionItem : actionList) {
 432  0
                         actionItem.setActionItemIndex(Integer.valueOf(index++));
 433  
                 }
 434  0
     }
 435  
 
 436  
     private void initializeActionList(List actionList, Preferences preferences) throws WorkflowException {
 437  0
             List actionItemProblemIds = new ArrayList();
 438  0
             Map<String,DocumentRouteHeaderValue> routeHeaders = KEWServiceLocator.getRouteHeaderService().getRouteHeadersForActionItems(org.kuali.rice.kew.actionitem.ActionItem.to(actionList));
 439  
 
 440  0
             int index = 0;
 441  0
             generateActionItemErrors(actionList);
 442  
             //RouteHeaderService routeHeaderService = KEWServiceLocator.getRouteHeaderService();
 443  0
             for (Iterator iterator = actionList.iterator(); iterator.hasNext();) {
 444  0
                     ActionItemActionListExtension actionItem = (ActionItemActionListExtension)iterator.next();
 445  0
                     if (actionItem.getDocumentId() == null) {
 446  0
                             LOG.error("Somehow there exists an ActionItem with a null document id!  actionItemId=" + actionItem.getId());
 447  0
                             iterator.remove();
 448  0
                             continue;
 449  
                     }
 450  
                     try {
 451  0
                             actionItem.initialize(preferences);
 452  0
                             DocumentRouteHeaderValue routeHeader = routeHeaders.get(actionItem.getDocumentId());
 453  
                             //DocumentRouteHeaderValue routeHeader = routeHeaderService.getRouteHeader(actionItem.getDocumentId());
 454  0
                             DocumentRouteHeaderValueActionListExtension routeHeaderExtension = toDocumentRouteHeaderValueActionListExtension(routeHeader);
 455  0
                             routeHeaderExtension.setActionListInitiatorPrincipal(routeHeaderExtension.getInitiatorPrincipal());
 456  0
                             actionItem.setActionItemIndex(Integer.valueOf(index));
 457  0
                             actionItem.setRouteHeader(routeHeaderExtension);
 458  
                             //set background colors for document statuses
 459  0
                             if (KewApiConstants.ROUTE_HEADER_CANCEL_CD.equalsIgnoreCase(routeHeader.getDocRouteStatus())) {
 460  0
                                     actionItem.setRowStyleClass(KewApiConstants.ACTION_LIST_COLOR_PALETTE.get(preferences.getColorCanceled()));
 461  0
                             } else if (KewApiConstants.ROUTE_HEADER_DISAPPROVED_CD.equalsIgnoreCase(routeHeader.getDocRouteStatus())) {
 462  0
                                     actionItem.setRowStyleClass(KewApiConstants.ACTION_LIST_COLOR_PALETTE.get(preferences.getColorDisapproved()));
 463  0
                             } else if (KewApiConstants.ROUTE_HEADER_ENROUTE_CD.equalsIgnoreCase(routeHeader.getDocRouteStatus())) {
 464  0
                                     actionItem.setRowStyleClass(KewApiConstants.ACTION_LIST_COLOR_PALETTE.get(preferences.getColorEnroute()));
 465  0
                             } else if (KewApiConstants.ROUTE_HEADER_EXCEPTION_CD.equalsIgnoreCase(routeHeader.getDocRouteStatus())) {
 466  0
                                     actionItem.setRowStyleClass(KewApiConstants.ACTION_LIST_COLOR_PALETTE.get(preferences.getColorException()));
 467  0
                             } else if (KewApiConstants.ROUTE_HEADER_FINAL_CD.equalsIgnoreCase(routeHeader.getDocRouteStatus())) {
 468  0
                                     actionItem.setRowStyleClass(KewApiConstants.ACTION_LIST_COLOR_PALETTE.get(preferences.getColorFinal()));
 469  0
                             } else if (KewApiConstants.ROUTE_HEADER_INITIATED_CD.equalsIgnoreCase(routeHeader.getDocRouteStatus())) {
 470  0
                                     actionItem.setRowStyleClass(KewApiConstants.ACTION_LIST_COLOR_PALETTE.get(preferences.getColorInitiated()));
 471  0
                             } else if (KewApiConstants.ROUTE_HEADER_PROCESSED_CD.equalsIgnoreCase(routeHeader.getDocRouteStatus())) {
 472  0
                                     actionItem.setRowStyleClass(KewApiConstants.ACTION_LIST_COLOR_PALETTE.get(preferences.getColorProcessed()));
 473  0
                             } else if (KewApiConstants.ROUTE_HEADER_SAVED_CD.equalsIgnoreCase(routeHeader.getDocRouteStatus())) {
 474  0
                                     actionItem.setRowStyleClass(KewApiConstants.ACTION_LIST_COLOR_PALETTE.get(preferences.getColorSaved()));
 475  
                             }
 476  0
                             index++;
 477  0
                     } catch (Exception e) {
 478  
                             // if there's a problem loading the action item, we don't want to blow out the whole screen but we will remove it from the list
 479  
                             // and display an approriate error message to the user
 480  0
                             LOG.error("Error loading action list for action item " + actionItem.getId(), e);
 481  0
                             iterator.remove();
 482  0
                             actionItemProblemIds.add(actionItem.getDocumentId());
 483  0
                     }
 484  0
             }
 485  0
             generateActionItemErrors(ACTIONITEM_PROP, ACTIONLIST_BAD_ACTION_ITEMS_ERRKEY, actionItemProblemIds);
 486  0
     }
 487  
 
 488  
     private DocumentRouteHeaderValueActionListExtension toDocumentRouteHeaderValueActionListExtension(
 489  
                         DocumentRouteHeaderValue routeHeader) {
 490  
 
 491  0
                 if(routeHeader==null){
 492  0
                         return null;
 493  
                 }
 494  
                 
 495  0
                 DocumentRouteHeaderValueActionListExtension extension = new DocumentRouteHeaderValueActionListExtension();
 496  
                 
 497  0
                 extension.setDocumentId(routeHeader.getDocumentId());
 498  0
                 extension.setDocumentTypeId(routeHeader.getDocumentTypeId());
 499  0
                 extension.setDocRouteStatus(routeHeader.getDocRouteStatus());
 500  0
                 extension.setDocRouteLevel(routeHeader.getDocRouteLevel());
 501  0
                 extension.setStatusModDate(routeHeader.getStatusModDate());
 502  0
                 extension.setCreateDate(routeHeader.getCreateDate());
 503  0
                 extension.setApprovedDate(routeHeader.getApprovedDate());
 504  0
                 extension.setFinalizedDate(routeHeader.getFinalizedDate());
 505  0
                 extension.setRouteStatusDate(routeHeader.getRouteStatusDate());
 506  0
                 extension.setRouteLevelDate(routeHeader.getRouteLevelDate());
 507  0
                 extension.setDocTitle(routeHeader.getDocTitle());
 508  0
                 extension.setAppDocId(routeHeader.getAppDocId());
 509  0
                 extension.setDocVersion(routeHeader.getDocVersion());
 510  0
                 extension.setInitiatorWorkflowId(routeHeader.getInitiatorWorkflowId());
 511  0
                 extension.setVersionNumber(routeHeader.getVersionNumber());
 512  0
                 extension.setAppDocStatus(routeHeader.getAppDocStatus());
 513  0
                 extension.setAppDocStatusDate(routeHeader.getAppDocStatusDate());
 514  
 
 515  0
                 return extension;
 516  
         }
 517  
     
 518  
     /**
 519  
      * Gets the page size of the Action List.  Uses the user's preferences for page size unless the action list
 520  
      * has been throttled by an application constant, in which case it uses the smaller of the two values.
 521  
      */
 522  
     protected int getPageSize(Preferences preferences) {
 523  0
             return Integer.parseInt(preferences.getPageSize());
 524  
     }
 525  
 
 526  
     protected PaginatedList buildCurrentPage(List actionList, Integer page, String sortCriterion, String sortDirection, 
 527  
                     int pageSize, Preferences preferences, ActionListForm form) throws WorkflowException {
 528  0
             List currentPage = new ArrayList(pageSize);
 529  0
             boolean haveFyis = false;
 530  0
             boolean haveApproves = false;
 531  0
             boolean haveAcknowledges = false;
 532  0
             boolean haveCancels = false;
 533  0
             boolean haveDisapproves = false;
 534  0
             boolean haveCustomActions = false;
 535  0
             boolean haveDisplayParameters = false;
 536  0
             List customActionListProblemIds = new ArrayList();
 537  0
             SortOrderEnum sortOrder = parseSortOrder(sortDirection);
 538  0
             int startIndex = (page.intValue() - 1) * pageSize;
 539  0
             int endIndex = startIndex + pageSize;
 540  0
             generateActionItemErrors(actionList);
 541  0
             Map<String,DocumentRouteHeaderValue> routeHeaders = KEWServiceLocator.getRouteHeaderService().getRouteHeadersForActionItems(org.kuali.rice.kew.actionitem.ActionItem.to(actionList));
 542  0
             for (int index = startIndex; index < endIndex && index < actionList.size(); index++) {
 543  0
                     ActionItemActionListExtension actionItem = (ActionItemActionListExtension)actionList.get(index);
 544  
                     // evaluate custom action list component for mass actions
 545  
                     try {
 546  0
                             boolean itemHasApproves = false;
 547  0
                             boolean itemHasDisapproves = false;
 548  0
                             boolean itemHasCancels = false;
 549  0
                             boolean itemHasAcknowledges = false;
 550  0
                             boolean itemHasFyis = false;
 551  0
                             boolean itemHasCustomActions = false;
 552  
                             // TODO see DocumentSecurityServiceImpl.checkAuthorizations to see how the Handler replaces the Attribute
 553  0
                             CustomActionListAttribute customActionListAttribute = routeHeaders.get(actionItem.getDocumentId()).getCustomActionListAttribute();
 554  0
                             if (customActionListAttribute != null) {
 555  0
                                     Map customActions = new LinkedHashMap();
 556  0
                                     customActions.put("NONE", "NONE");
 557  0
                                     ActionSet legalActions = customActionListAttribute.getLegalActions(getUserSession().getPrincipalId(), ActionItem.to(actionItem));
 558  0
                                     if (legalActions != null && legalActions.hasApprove() && isActionCompatibleRequest(actionItem, KewApiConstants.ACTION_TAKEN_APPROVED_CD)) {
 559  0
                                             customActions.put(KewApiConstants.ACTION_TAKEN_APPROVED_CD, KewApiConstants.ACTION_REQUEST_APPROVE_REQ_LABEL);
 560  0
                                             itemHasApproves = true;
 561  
                                     }
 562  0
                                     if (legalActions != null && legalActions.hasDisapprove() && isActionCompatibleRequest(actionItem, KewApiConstants.ACTION_TAKEN_DENIED_CD)) {
 563  0
                                             customActions.put(KewApiConstants.ACTION_TAKEN_DENIED_CD, KewApiConstants.ACTION_REQUEST_DISAPPROVE_LABEL);
 564  0
                                             itemHasDisapproves = true;
 565  
                                     }
 566  0
                                     if (legalActions != null && legalActions.hasCancel() && isActionCompatibleRequest(actionItem, KewApiConstants.ACTION_TAKEN_CANCELED_CD)) {
 567  0
                                             customActions.put(KewApiConstants.ACTION_TAKEN_CANCELED_CD, KewApiConstants.ACTION_REQUEST_CANCEL_REQ_LABEL);
 568  0
                                             itemHasCancels = true;
 569  
                                     }
 570  0
                                     if (legalActions != null && legalActions.hasAcknowledge() && isActionCompatibleRequest(actionItem, KewApiConstants.ACTION_TAKEN_ACKNOWLEDGED_CD)) {
 571  0
                                             customActions.put(KewApiConstants.ACTION_TAKEN_ACKNOWLEDGED_CD, KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ_LABEL);
 572  0
                                             itemHasAcknowledges = true;
 573  
                                     }
 574  0
                                     if (legalActions != null && legalActions.hasFyi() && isActionCompatibleRequest(actionItem, KewApiConstants.ACTION_TAKEN_FYI_CD) && KewApiConstants.PREFERENCES_YES_VAL.equalsIgnoreCase(preferences.getShowClearFyi())) {
 575  0
                                             customActions.put(KewApiConstants.ACTION_TAKEN_FYI_CD, KewApiConstants.ACTION_REQUEST_FYI_REQ_LABEL);
 576  0
                                             itemHasFyis = true;
 577  
                                     }
 578  0
                                     if (customActions.size() > 1) {
 579  0
                                             actionItem.setCustomActions(customActions);
 580  0
                                             itemHasCustomActions = true;
 581  
                                     }
 582  0
                                     actionItem.setDisplayParameters(customActionListAttribute.getDocHandlerDisplayParameters(getUserSession().getPrincipalId(), ActionItem.to(actionItem)));
 583  0
                                     haveApproves = haveApproves || itemHasApproves;
 584  0
                                     haveAcknowledges = haveAcknowledges || itemHasAcknowledges;
 585  0
                                     haveFyis = haveFyis || itemHasFyis;
 586  0
                                     haveDisapproves = haveDisapproves || itemHasDisapproves;
 587  0
                                     haveCancels = haveCancels || itemHasCancels;
 588  0
                                     haveCustomActions = haveCustomActions || itemHasCustomActions;
 589  0
                                     haveDisplayParameters = haveDisplayParameters || (actionItem.getDisplayParameters() != null);
 590  
                             }
 591  0
                     } catch (Exception e) {
 592  
                             // if there's a problem loading the custom action list attribute, let's go ahead and display the vanilla action item
 593  0
                             LOG.error("Problem loading custom action list attribute", e);
 594  0
                             customActionListProblemIds.add(actionItem.getDocumentId());
 595  0
                     }
 596  0
                     currentPage.add(actionItem);
 597  
             }
 598  
 
 599  
             // configure custom actions on form
 600  0
             form.setHasCustomActions(Boolean.valueOf(haveCustomActions));
 601  0
             Map defaultActions = new LinkedHashMap();
 602  0
             defaultActions.put("NONE", "NONE");
 603  0
             if (haveApproves) {
 604  0
                     defaultActions.put(KewApiConstants.ACTION_TAKEN_APPROVED_CD, KewApiConstants.ACTION_REQUEST_APPROVE_REQ_LABEL);
 605  0
                     form.setCustomActionList(Boolean.TRUE);
 606  
             }
 607  0
             if (haveDisapproves) {
 608  0
                     defaultActions.put(KewApiConstants.ACTION_TAKEN_DENIED_CD, KewApiConstants.ACTION_REQUEST_DISAPPROVE_LABEL);
 609  0
                     form.setCustomActionList(Boolean.TRUE);
 610  
             }
 611  0
             if (haveCancels) {
 612  0
                     defaultActions.put(KewApiConstants.ACTION_TAKEN_CANCELED_CD, KewApiConstants.ACTION_REQUEST_CANCEL_REQ_LABEL);
 613  0
                     form.setCustomActionList(Boolean.TRUE);
 614  
             }
 615  0
             if (haveAcknowledges) {
 616  0
                     defaultActions.put(KewApiConstants.ACTION_TAKEN_ACKNOWLEDGED_CD, KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ_LABEL);
 617  0
                     form.setCustomActionList(Boolean.TRUE);
 618  
             }
 619  
             //clearing FYI's can be done in any action list not just a customized one
 620  0
             if (haveFyis && KewApiConstants.PREFERENCES_YES_VAL.equalsIgnoreCase(preferences.getShowClearFyi())) {
 621  0
                     defaultActions.put(KewApiConstants.ACTION_TAKEN_FYI_CD, KewApiConstants.ACTION_REQUEST_FYI_REQ_LABEL);
 622  
             }
 623  0
             if (defaultActions.size() > 1) {
 624  0
                     form.setDefaultActions(defaultActions);
 625  
             }
 626  
 
 627  0
                    form.setHasDisplayParameters(haveDisplayParameters);
 628  
             
 629  0
             generateActionItemErrors(CUSTOMACTIONLIST_PROP, ACTIONLIST_BAD_CUSTOM_ACTION_LIST_ITEMS_ERRKEY, customActionListProblemIds);
 630  0
             return new PaginatedActionList(currentPage, actionList.size(), page.intValue(), pageSize, "actionList", sortCriterion, sortOrder);
 631  
     }
 632  
 
 633  
     private void generateActionItemErrors(String propertyName, String errorKey, List documentIds) {
 634  0
             if (!documentIds.isEmpty()) {
 635  0
                     String documentIdsString = StringUtils.join(documentIds.iterator(), ", ");
 636  0
                     GlobalVariables.getMessageMap().putError(propertyName, errorKey, documentIdsString);
 637  
             }
 638  0
     }
 639  
     
 640  
     private void generateActionItemErrors(List actionList) {
 641  0
             for (Iterator iterator = actionList.iterator(); iterator.hasNext();) {
 642  0
                     ActionItemActionListExtension actionItem = (ActionItemActionListExtension)iterator.next();
 643  
                     
 644  
                     // removing this check for the time being, it hinders action list performance. (KULRICE-2931)
 645  
 //                    if (KEWServiceLocator.getRouteHeaderService().getRouteHeader(actionItem.getDocumentId()) == null) {
 646  
 //                            GlobalVariables.getErrorMap().putError(ROUTEHEADERID_PROP, ACTIONITEM_ROUTEHEADERID_INVALID_ERRKEY,actionItem.getId()+"");
 647  
 //                    }
 648  
                     
 649  0
                     if(!KewApiConstants.ACTION_REQUEST_CODES.containsKey(actionItem.getActionRequestCd())) {
 650  0
                             GlobalVariables.getMessageMap().putError(ACTIONREQUESTCD_PROP,ACTIONITEM_ACTIONREQUESTCD_INVALID_ERRKEY,actionItem.getId()+"");
 651  
                     }
 652  0
              }
 653  0
     }
 654  
 
 655  
 
 656  
     public ActionForward takeMassActions(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
 657  0
         ActionListForm actionListForm = (ActionListForm) form;
 658  0
         List actionList = (List) request.getSession().getAttribute(ACTION_LIST_KEY);
 659  0
         if (actionList == null) {
 660  0
             return start(mapping, new ActionListForm(), request, response);
 661  
         }
 662  0
         ActionMessages messages = new ActionMessages();
 663  0
         List invocations = new ArrayList();
 664  0
         int index = 0;
 665  0
         for (Object element : actionListForm.getActionsToTake()) {
 666  0
                 ActionToTake actionToTake = (ActionToTake) element;
 667  0
                 if (actionToTake != null && actionToTake.getActionTakenCd() != null &&
 668  
                                 !"".equals(actionToTake.getActionTakenCd()) &&
 669  
                                 !"NONE".equalsIgnoreCase(actionToTake.getActionTakenCd()) &&
 670  
                                 actionToTake.getActionItemId() != null) {
 671  0
                         ActionItem actionItem = getActionItemFromActionList(actionList, actionToTake.getActionItemId());
 672  0
                         if (actionItem == null) {
 673  0
                                 LOG.warn("Could not locate the ActionItem to take mass action against in the action list: " + actionToTake.getActionItemId());
 674  0
                                 continue;
 675  
                         }
 676  0
                     invocations.add(ActionInvocation.create(ActionType.fromCode(actionToTake.getActionTakenCd()), actionItem.getId()));
 677  
             }
 678  0
                 index++;
 679  0
                 }
 680  0
         KEWServiceLocator.getWorkflowDocumentService().takeMassActions(getUserSession().getPrincipalId(), invocations);
 681  0
         messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("general.routing.processed"));
 682  0
         saveMessages(request, messages);
 683  0
         ActionListForm cleanForm = new ActionListForm();
 684  0
         request.setAttribute(mapping.getName(), cleanForm);
 685  0
         request.getSession().setAttribute(REQUERY_ACTION_LIST_KEY, "true");
 686  0
         return start(mapping, cleanForm, request, response);
 687  
     }
 688  
 
 689  
     protected ActionItem getActionItemFromActionList(List<ActionItem> actionList, String actionItemId) {
 690  0
             for (ActionItem actionItem : actionList) {
 691  0
                         if (actionItem.getId().equals(actionItemId)) {
 692  0
                                 return actionItem;
 693  
                         }
 694  
                 }
 695  0
             return null;
 696  
     }
 697  
 
 698  
     public ActionForward helpDeskActionListLogin(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
 699  0
         ActionListForm actionListForm = (ActionListForm) form;
 700  0
         String name = actionListForm.getHelpDeskActionListUserName();
 701  0
         if (!"true".equals(request.getAttribute("helpDeskActionList"))) {
 702  0
                 throw new AuthorizationException(getUserSession().getPrincipalId(), "helpDeskActionListLogin", getClass().getSimpleName());
 703  
         }
 704  
         try
 705  
         {
 706  0
                 final Principal helpDeskActionListPrincipal = KEWServiceLocator.getIdentityHelperService().getPrincipalByPrincipalName(name);
 707  0
                 final Person helpDeskActionListPerson = KEWServiceLocator.getIdentityHelperService().getPersonByPrincipalName(name);
 708  
                 
 709  0
                 GlobalVariables.getUserSession().addObject(KewApiConstants.HELP_DESK_ACTION_LIST_PRINCIPAL_ATTR_NAME, helpDeskActionListPrincipal);
 710  0
                 GlobalVariables.getUserSession().addObject(KewApiConstants.HELP_DESK_ACTION_LIST_PERSON_ATTR_NAME, helpDeskActionListPerson);
 711  
         }
 712  0
         catch (RiceRuntimeException rre)
 713  
         {
 714  0
                 GlobalVariables.getMessageMap().putError(HELPDESK_ACTIONLIST_USERNAME, HELPDESK_LOGIN_INVALID_ERRKEY, name);
 715  
         }
 716  0
         catch (RiceIllegalArgumentException e) {
 717  0
                 GlobalVariables.getMessageMap().putError(HELPDESK_ACTIONLIST_USERNAME, HELPDESK_LOGIN_INVALID_ERRKEY, name);
 718  
         }
 719  0
         catch (NullPointerException npe)
 720  
         {
 721  0
                 GlobalVariables.getMessageMap().putError("null", HELPDESK_LOGIN_EMPTY_ERRKEY, name);
 722  0
         }
 723  0
             actionListForm.setDelegator(null);
 724  0
         request.getSession().setAttribute(REQUERY_ACTION_LIST_KEY, "true");
 725  0
         return start(mapping, form, request, response);
 726  
     }
 727  
 
 728  
     public ActionForward clearFilter(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
 729  0
         LOG.debug("clearFilter ActionListAction");
 730  0
         final org.kuali.rice.krad.UserSession commonUserSession = getUserSession();
 731  0
         commonUserSession.removeObject(KewApiConstants.ACTION_LIST_FILTER_ATTR_NAME);
 732  0
         request.getSession().setAttribute(REQUERY_ACTION_LIST_KEY, "true");
 733  0
         KEWServiceLocator.getActionListService().saveRefreshUserOption(commonUserSession.getPrincipalId());
 734  0
         LOG.debug("end clearFilter ActionListAction");
 735  0
         return start(mapping, form, request, response);
 736  
     }
 737  
 
 738  
     public ActionForward clearHelpDeskActionListUser(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
 739  0
         LOG.debug("clearHelpDeskActionListUser ActionListAction");
 740  0
             GlobalVariables.getUserSession().removeObject(KewApiConstants.HELP_DESK_ACTION_LIST_PRINCIPAL_ATTR_NAME);
 741  0
             GlobalVariables.getUserSession().removeObject(KewApiConstants.HELP_DESK_ACTION_LIST_PERSON_ATTR_NAME);
 742  0
         LOG.debug("end clearHelpDeskActionListUser ActionListAction");
 743  0
         return start(mapping, form, request, response);
 744  
     }
 745  
 
 746  
     /**
 747  
      * Generates an Action List count.
 748  
      */
 749  
     public ActionForward count(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
 750  0
             ActionListForm alForm = (ActionListForm)form;
 751  0
             Person user = getUserSession().getPerson();
 752  0
             alForm.setCount(KEWServiceLocator.getActionListService().getCount(user.getPrincipalId()));
 753  0
             LOG.info("Fetched Action List count of " + alForm.getCount() + " for user " + user.getPrincipalName());
 754  0
             return mapping.findForward("count");
 755  
     }
 756  
 
 757  
     public ActionForward removeOutboxItems(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
 758  0
         ActionListForm alForm = (ActionListForm)form;
 759  0
         if (alForm.getOutboxItems() != null) {
 760  0
             KEWServiceLocator.getActionListService().removeOutboxItems(getUserSession().getPrincipalId(), Arrays.asList(alForm.getOutboxItems()));
 761  
         }
 762  
 
 763  0
         alForm.setViewOutbox("true");
 764  0
         return start(mapping, form, request, response);
 765  
     }
 766  
 
 767  
     /**
 768  
      * Navigate to the Action List Filter page, preserving any newly-modified primary/secondary delegation filters as necessary.
 769  
      */
 770  
     public ActionForward viewFilter(ActionMapping mapping, ActionForm actionForm, HttpServletRequest request, HttpServletResponse response) throws Exception {
 771  0
             start(mapping, actionForm, request, response);
 772  0
             return mapping.findForward("viewFilter");
 773  
     }
 774  
     
 775  
     /**
 776  
      * Navigate to the user's Preferences page, preserving any newly-modified primary/secondary delegation filters as necessary.
 777  
      */
 778  
     public ActionForward viewPreferences(ActionMapping mapping, ActionForm actionForm, HttpServletRequest request, HttpServletResponse response) throws Exception {
 779  0
             start(mapping, actionForm, request, response);
 780  0
             return mapping.findForward("viewPreferences");
 781  
     }
 782  
     
 783  
     private boolean isActionCompatibleRequest(ActionItemActionListExtension actionItem, String actionTakenCode) {
 784  0
         boolean actionCompatible = false;
 785  0
         String requestCd = actionItem.getActionRequestCd();
 786  
 
 787  
         //FYI request matches FYI
 788  0
         if (KewApiConstants.ACTION_REQUEST_FYI_REQ.equals(requestCd) && KewApiConstants.ACTION_TAKEN_FYI_CD.equals(actionTakenCode)) {
 789  0
             actionCompatible = true || actionCompatible;
 790  
         }
 791  
 
 792  
         // ACK request matches ACK
 793  0
         if (KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ.equals(requestCd) && KewApiConstants.ACTION_TAKEN_ACKNOWLEDGED_CD.equals(actionTakenCode)) {
 794  0
             actionCompatible = true || actionCompatible;
 795  
         }
 796  
 
 797  
         // APPROVE request matches all but FYI and ACK
 798  0
         if (KewApiConstants.ACTION_REQUEST_APPROVE_REQ.equals(requestCd) && !(KewApiConstants.ACTION_TAKEN_FYI_CD.equals(actionTakenCode) || KewApiConstants.ACTION_TAKEN_ACKNOWLEDGED_CD.equals(actionTakenCode))) {
 799  0
             actionCompatible = true || actionCompatible;
 800  
         }
 801  
 
 802  
         // COMPLETE request matches all but FYI and ACK
 803  0
         if (KewApiConstants.ACTION_REQUEST_COMPLETE_REQ.equals(requestCd) && !(KewApiConstants.ACTION_TAKEN_FYI_CD.equals(actionTakenCode) || KewApiConstants.ACTION_TAKEN_ACKNOWLEDGED_CD.equals(actionTakenCode))) {
 804  0
             actionCompatible = true || actionCompatible;
 805  
         }
 806  
 
 807  0
         return actionCompatible;
 808  
     }
 809  
 
 810  
         private UserSession getUserSession(){
 811  0
                 return GlobalVariables.getUserSession();
 812  
         }
 813  
 
 814  0
     private static class ActionItemComparator implements Comparator<ActionItem> {
 815  
 
 816  
             private static final String DOCUMENT_ID = "documentId";
 817  
 
 818  
             private final String sortName;
 819  
 
 820  0
             public ActionItemComparator(String sortName) {
 821  0
                     if (StringUtils.isEmpty(sortName)) {
 822  0
                             sortName = DOCUMENT_ID;
 823  
                     }
 824  0
                     this.sortName = sortName;
 825  0
             }
 826  
 
 827  
                 @Override
 828  
                 public int compare(ActionItem object1, ActionItem object2) {
 829  
                         try {
 830  0
                                 ActionItem actionItem1 = object1;
 831  0
                                 ActionItem actionItem2 = object2;
 832  
                                 // invoke the power of the lookup functionality provided by the display tag library, this LookupUtil method allows for us
 833  
                                 // to evaulate nested bean properties (like workgroup.groupNameId.nameId) in a null-safe manner.  For example, in the
 834  
                                 // example if workgroup evaluated to NULL then LookupUtil.getProperty would return null rather than blowing an exception
 835  0
                                 Object property1 = LookupUtil.getProperty(actionItem1, sortName);
 836  0
                                 Object property2 = LookupUtil.getProperty(actionItem2, sortName);
 837  0
                                 if (property1 == null && property2 == null) {
 838  0
                                         return 0;
 839  0
                                 } else if (property1 == null) {
 840  0
                                         return -1;
 841  0
                                 } else if (property2 == null) {
 842  0
                                         return 1;
 843  
                                 }
 844  0
                                 if (property1 instanceof Comparable) {
 845  0
                                         return ((Comparable)property1).compareTo(property2);
 846  
                                 }
 847  0
                                 return property1.toString().compareTo(property2.toString());
 848  0
                         } catch (Exception e) {
 849  0
                                 if (e instanceof RuntimeException) {
 850  0
                                         throw (RuntimeException) e;
 851  
                                 }
 852  0
                                 throw new RuntimeException("Could not sort for the given sort name: " + sortName, e);
 853  
                         }
 854  
                 }
 855  
     }
 856  
     
 857  
     protected void processActionListCustomizations(String principalId, List<ActionItem> actionItems){
 858  0
         if (CollectionUtils.isNotEmpty(actionItems)) {
 859  0
             LOG.info("Beginning processing of Action List Customizations (total: "
 860  
                     + actionItems.size()
 861  
                     + " Action Items)");
 862  0
             long start = System.currentTimeMillis();
 863  0
             MultiValueMap<PartitionKey, ActionItem> partitions = partitionActionItems(actionItems);
 864  
             
 865  
             // TODO fill this out - DocumentSecurityServiceImpl.processDocumentRequiringExtensionProcessing
 866  
     
 867  0
             long end = System.currentTimeMillis();
 868  0
             LOG.info("Finished processing of Action List Customizations (total time: "
 869  
                     + (start - end)
 870  
                     + ")");
 871  
         }
 872  0
     }
 873  
     
 874  
     protected MultiValueMap<PartitionKey,ActionItem> partitionActionItems(List<ActionItem> actionItems){
 875  
         // TODO fill this out - see DocumentSecurityServiceImpl.partitionDocumentsForSecurity
 876  0
         MultiValueMap<PartitionKey, ActionItem> partitions = new LinkedMultiValueMap<PartitionKey, ActionItem>();
 877  
 
 878  0
         return partitions;
 879  
     }
 880  
      
 881  
     protected ActionListCustomizationHandlerService loadActionListCustomizationHandler(String applicationId){
 882  0
         ActionListCustomizationHandlerService service = KewFrameworkServiceLocator.getActionListCustomizationHandlerService(applicationId);
 883  0
         if (service == null) {
 884  0
             throw new WorkflowRuntimeException(
 885  
                     "Failed to locate ActionListCustomizationHandlerService for applicationId: " + applicationId);
 886  
         }
 887  0
         return service;
 888  
     }
 889  
     
 890  
     /**
 891  
      * Simple class which defines the key of a partition of Action Items associated with an Application ID.
 892  
      *
 893  
      * <p>This class allows direct field access since it is intended for internal use only.</p>
 894  
      */
 895  0
     private static final class PartitionKey {
 896  
         String applicationId;
 897  
         Set<String> customActionListAttributeNames;
 898  
 
 899  0
         PartitionKey(String applicationId, Collection<ExtensionDefinition> extensionDefinitions) {
 900  0
             this.applicationId = applicationId;
 901  0
             this.customActionListAttributeNames = new HashSet<String>();
 902  0
             for (ExtensionDefinition extensionDefinition : extensionDefinitions) {
 903  0
                 this.customActionListAttributeNames.add(extensionDefinition.getName());
 904  
             }
 905  0
         }
 906  
 
 907  
         List<String> getCustomActionListAttributeNameList() {
 908  0
             return new ArrayList<String>(customActionListAttributeNames);
 909  
         }
 910  
 
 911  
         @Override
 912  
         public boolean equals(Object o) {
 913  0
             if (!(o instanceof PartitionKey)) {
 914  0
                 return false;
 915  
             }
 916  0
             PartitionKey key = (PartitionKey) o;
 917  0
             EqualsBuilder builder = new EqualsBuilder();
 918  0
             builder.append(applicationId, key.applicationId);
 919  0
             builder.append(customActionListAttributeNames, key.customActionListAttributeNames);
 920  0
             return builder.isEquals();
 921  
         }
 922  
 
 923  
         @Override
 924  
         public int hashCode() {
 925  0
             HashCodeBuilder builder = new HashCodeBuilder();
 926  0
             builder.append(applicationId);
 927  0
             builder.append(customActionListAttributeNames);
 928  0
             return builder.hashCode();
 929  
         }
 930  
     }
 931  
 }