001 /** 002 * Copyright 2005-2011 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.kuali.rice.kns.web.struts.action; 017 018 import org.apache.commons.beanutils.BeanComparator; 019 import org.apache.commons.lang.StringUtils; 020 import org.apache.struts.action.ActionForm; 021 import org.apache.struts.action.ActionForward; 022 import org.apache.struts.action.ActionMapping; 023 import org.kuali.rice.core.api.util.RiceConstants; 024 import org.kuali.rice.kns.lookup.HtmlData; 025 import org.kuali.rice.kns.lookup.LookupResultsService; 026 import org.kuali.rice.kns.lookup.LookupUtils; 027 import org.kuali.rice.kns.lookup.Lookupable; 028 import org.kuali.rice.kns.service.KNSServiceLocator; 029 import org.kuali.rice.kns.web.struts.form.MultipleValueLookupForm; 030 import org.kuali.rice.kns.web.ui.Column; 031 import org.kuali.rice.kns.web.ui.ResultRow; 032 import org.kuali.rice.krad.lookup.CollectionIncomplete; 033 import org.kuali.rice.krad.service.KRADServiceLocator; 034 import org.kuali.rice.krad.service.SequenceAccessorService; 035 import org.kuali.rice.krad.util.GlobalVariables; 036 import org.kuali.rice.krad.util.KRADConstants; 037 import org.kuali.rice.krad.util.UrlFactory; 038 039 import javax.servlet.ServletException; 040 import javax.servlet.http.HttpServletRequest; 041 import javax.servlet.http.HttpServletResponse; 042 import java.io.IOException; 043 import java.util.ArrayList; 044 import java.util.Collection; 045 import java.util.Collections; 046 import java.util.HashMap; 047 import java.util.List; 048 import java.util.Map; 049 import java.util.Properties; 050 import java.util.Set; 051 052 /** 053 * This class serves as the struts action for implementing multiple value lookups 054 */ 055 public class KualiMultipleValueLookupAction extends KualiLookupAction implements KualiTableRenderAction { 056 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(KualiMultipleValueLookupAction.class); 057 058 /** 059 * If there is no app param defined for the # rows/page, then this value 060 * will be used for the default 061 * 062 * @see KualiMultipleValueLookupAction#getMaxRowsPerPage(MultipleValueLookupForm) 063 */ 064 public static final int DEFAULT_MAX_ROWS_PER_PAGE = 50; 065 066 067 /** 068 * This method performs the search, and will be responsible for persisting the results via the LookupResultsService. 069 * This overrides the superclass's search action method b/c of the differences in how the results are generated and it populates 070 * certain attributes that are specific to MultipleValueLookupForm 071 * 072 * @param mapping 073 * @param form must be an instance of MultipleValueLookupForm 074 * @param request 075 * @param response 076 */ 077 @Override 078 public ActionForward search(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 079 MultipleValueLookupForm multipleValueLookupForm = (MultipleValueLookupForm) form; 080 081 // If this is a new search, clear out the old search results. 082 String methodToCall = findMethodToCall(form, request); 083 if (methodToCall.equalsIgnoreCase("search")) { 084 GlobalVariables.getUserSession().removeObjectsByPrefix(KRADConstants.SEARCH_METHOD); 085 } 086 087 Lookupable kualiLookupable = multipleValueLookupForm.getLookupable(); 088 if (kualiLookupable == null) { 089 LOG.error("Lookupable is null."); 090 throw new RuntimeException("Lookupable is null."); 091 } 092 093 Collection displayList = new ArrayList(); 094 ArrayList<ResultRow> resultTable = new ArrayList<ResultRow>(); 095 096 // validate search parameters 097 kualiLookupable.validateSearchParameters(multipleValueLookupForm.getFields()); 098 099 boolean bounded = true; 100 101 displayList = performMultipleValueLookup(multipleValueLookupForm, resultTable, getMaxRowsPerPage(multipleValueLookupForm), bounded); 102 if (kualiLookupable.isSearchUsingOnlyPrimaryKeyValues()) { 103 multipleValueLookupForm.setSearchUsingOnlyPrimaryKeyValues(true); 104 multipleValueLookupForm.setPrimaryKeyFieldLabels(kualiLookupable.getPrimaryKeyFieldLabels()); 105 } 106 else { 107 multipleValueLookupForm.setSearchUsingOnlyPrimaryKeyValues(false); 108 multipleValueLookupForm.setPrimaryKeyFieldLabels(KRADConstants.EMPTY_STRING); 109 } 110 111 //request.setAttribute("reqSearchResultsActualSize", ((CollectionIncomplete) displayList).getActualSizeIfTruncated()); 112 113 if ( displayList instanceof CollectionIncomplete ){ 114 request.setAttribute("reqSearchResultsActualSize", ((CollectionIncomplete) displayList).getActualSizeIfTruncated()); 115 } else { 116 request.setAttribute("reqSearchResultsActualSize", displayList.size() ); 117 } 118 119 request.setAttribute("reqSearchResults", resultTable); 120 121 //multipleValueLookupForm.setResultsActualSize((int) ((CollectionIncomplete) displayList).getActualSizeIfTruncated().longValue()); 122 123 if ( displayList instanceof CollectionIncomplete ){ 124 multipleValueLookupForm.setResultsActualSize((int) ((CollectionIncomplete) displayList).getActualSizeIfTruncated().longValue()); 125 } else { 126 multipleValueLookupForm.setResultsActualSize(displayList.size()); 127 } 128 129 130 multipleValueLookupForm.setResultsLimitedSize(resultTable.size()); 131 132 if (request.getParameter(KRADConstants.SEARCH_LIST_REQUEST_KEY) != null) { 133 GlobalVariables.getUserSession().removeObject(request.getParameter(KRADConstants.SEARCH_LIST_REQUEST_KEY)); 134 } 135 request.setAttribute(KRADConstants.SEARCH_LIST_REQUEST_KEY, GlobalVariables.getUserSession().addObjectWithGeneratedKey(resultTable, KRADConstants.SEARCH_LIST_KEY_PREFIX)); 136 137 request.getParameter(KRADConstants.REFRESH_CALLER); 138 139 return mapping.findForward(RiceConstants.MAPPING_BASIC); 140 } 141 142 /** 143 * This method switches to another page on a multi-value lookup 144 * 145 * @param mapping 146 * @param form must be an instance of MultipleValueLookupForm 147 * @param request 148 * @param response 149 * @return 150 * @throws Exception 151 */ 152 @Override 153 public ActionForward switchToPage(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 154 MultipleValueLookupForm multipleValueLookupForm = (MultipleValueLookupForm) form; 155 List<ResultRow> resultTable = switchToPage(multipleValueLookupForm, getMaxRowsPerPage(multipleValueLookupForm)); 156 request.setAttribute("reqSearchResults", resultTable); 157 return mapping.findForward(RiceConstants.MAPPING_BASIC); 158 } 159 160 /** 161 * This method sorts a column. If the page is currently sorted on a certain column, 162 * and the same column is selected to be sorted again, then the results will be 163 * reversed. After the search method is called, it is difficult to determine the sort 164 * order of the result table, so no column is considered sorted. So, after a search, we were 165 * to click sort on an already sorted column, it would appear to have no effect. Subsequent clicks 166 * would tell you 167 * 168 * @param mapping 169 * @param form must be an instance of MultipleValueLookupForm 170 * @param request 171 * @param response 172 * @return 173 * @throws Exception 174 */ 175 @Override 176 public ActionForward sort(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 177 MultipleValueLookupForm multipleValueLookupForm = (MultipleValueLookupForm) form; 178 List<ResultRow> resultTable = sort(multipleValueLookupForm, getMaxRowsPerPage(multipleValueLookupForm)); 179 request.setAttribute("reqSearchResults", resultTable); 180 return mapping.findForward(RiceConstants.MAPPING_BASIC); 181 } 182 183 /** 184 * This method does the processing necessary to return selected results and sends a redirect back to the lookup caller 185 * 186 * @param mapping 187 * @param form must be an instance of MultipleValueLookupForm 188 * @param request 189 * @param response 190 * @return 191 * @throws Exception 192 */ 193 public ActionForward prepareToReturnSelectedResults(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 194 MultipleValueLookupForm multipleValueLookupForm = (MultipleValueLookupForm) form; 195 if (StringUtils.isBlank(multipleValueLookupForm.getLookupResultsSequenceNumber())) { 196 // no search was executed 197 return prepareToReturnNone(mapping, form, request, response); 198 } 199 200 prepareToReturnSelectedResultBOs(multipleValueLookupForm); 201 202 // build the parameters for the refresh url 203 Properties parameters = new Properties(); 204 parameters.put(KRADConstants.LOOKUP_RESULTS_BO_CLASS_NAME, multipleValueLookupForm.getBusinessObjectClassName()); 205 parameters.put(KRADConstants.LOOKUP_RESULTS_SEQUENCE_NUMBER, multipleValueLookupForm.getLookupResultsSequenceNumber()); 206 parameters.put(KRADConstants.DOC_FORM_KEY, multipleValueLookupForm.getFormKey()); 207 parameters.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, KRADConstants.RETURN_METHOD_TO_CALL); 208 parameters.put(KRADConstants.REFRESH_CALLER, KRADConstants.MULTIPLE_VALUE); 209 parameters.put(KRADConstants.ANCHOR, multipleValueLookupForm.getLookupAnchor()); 210 parameters.put(KRADConstants.LOOKED_UP_COLLECTION_NAME, multipleValueLookupForm.getLookedUpCollectionName()); 211 if(multipleValueLookupForm.getDocNum() != null){ 212 parameters.put(KRADConstants.DOC_NUM, multipleValueLookupForm.getDocNum()); 213 } 214 215 216 String backUrl = UrlFactory.parameterizeUrl(multipleValueLookupForm.getBackLocation(), parameters); 217 return new ActionForward(backUrl, true); 218 } 219 220 /** 221 * This method selects all results across all pages 222 * @param mapping 223 * @param form must be an instance of MultipleValueLookupForm 224 * @param request 225 * @param response 226 * @return 227 * @throws Exception 228 */ 229 public ActionForward selectAll(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 230 MultipleValueLookupForm multipleValueLookupForm = (MultipleValueLookupForm) form; 231 List<ResultRow> resultTable = selectAll(multipleValueLookupForm, getMaxRowsPerPage(multipleValueLookupForm)); 232 request.setAttribute("reqSearchResults", resultTable); 233 return mapping.findForward(RiceConstants.MAPPING_BASIC); 234 } 235 236 /** 237 * This method unselects all results across all pages 238 * 239 * @param mapping 240 * @param form must be an instance of MultipleValueLookupForm 241 * @param request 242 * @param response 243 * @return 244 * @throws Exception 245 */ 246 public ActionForward unselectAll(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 247 MultipleValueLookupForm multipleValueLookupForm = (MultipleValueLookupForm) form; 248 List<ResultRow> resultTable = unselectAll(multipleValueLookupForm, getMaxRowsPerPage(multipleValueLookupForm)); 249 request.setAttribute("reqSearchResults", resultTable); 250 return mapping.findForward(RiceConstants.MAPPING_BASIC); 251 } 252 253 /** 254 * This method overrides the super class cancel method because it is basically equivalent to clicking prepare to return none 255 * 256 * @see KualiLookupAction#cancel(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) 257 */ 258 @Override 259 public ActionForward cancel(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 260 return prepareToReturnNone(mapping, form, request, response); 261 } 262 263 264 /** 265 * This method returns none of the selected results and redirects back to the lookup caller. 266 * @param mapping 267 * @param form must be an instance of MultipleValueLookupForm 268 * @param request 269 * @param response 270 * @return 271 * @throws Exception 272 */ 273 public ActionForward prepareToReturnNone(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 274 MultipleValueLookupForm multipleValueLookupForm = (MultipleValueLookupForm) form; 275 prepareToReturnNone(multipleValueLookupForm); 276 277 // build the parameters for the refresh url 278 Properties parameters = new Properties(); 279 parameters.put(KRADConstants.DOC_FORM_KEY, multipleValueLookupForm.getFormKey()); 280 parameters.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, KRADConstants.RETURN_METHOD_TO_CALL); 281 parameters.put(KRADConstants.REFRESH_CALLER, KRADConstants.MULTIPLE_VALUE); 282 parameters.put(KRADConstants.ANCHOR, multipleValueLookupForm.getLookupAnchor()); 283 if(multipleValueLookupForm.getDocNum() != null){ 284 parameters.put(KRADConstants.DOC_NUM, multipleValueLookupForm.getDocNum()); 285 } 286 String backUrl = UrlFactory.parameterizeUrl(multipleValueLookupForm.getBackLocation(), parameters); 287 return new ActionForward(backUrl, true); 288 } 289 290 /** 291 * This method prepares to export results. Note: this method will not look for any rows selected since the last page view, so it is best 292 * that exporting opens in a new browser window. 293 * 294 * @param mapping 295 * @param form must be an instance of MultipleValueLookupForm 296 * @param request 297 * @param response 298 * @return 299 * @throws Exception 300 */ 301 public ActionForward export(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 302 MultipleValueLookupForm multipleValueLookupForm = (MultipleValueLookupForm) form; 303 List<ResultRow> resultTable = prepareToExport(multipleValueLookupForm); 304 request.setAttribute("reqSearchResults", resultTable); 305 return mapping.findForward(RiceConstants.MAPPING_BASIC); 306 } 307 308 /** 309 * This method performs the lookup and returns a collection of lookup items. Also initializes values in the form 310 * that will allow the multiple value lookup page to render 311 * 312 * @param multipleValueLookupForm 313 * @param resultTable a list of result rows (used to generate what's shown in the UI). This list will be modified by this method 314 * @param maxRowsPerPage 315 * @param bounded whether the results will be bounded 316 * @return the list of result BOs, possibly bounded by size 317 */ 318 protected Collection performMultipleValueLookup(MultipleValueLookupForm multipleValueLookupForm, List<ResultRow> resultTable, int maxRowsPerPage, boolean bounded) { 319 Lookupable lookupable = multipleValueLookupForm.getLookupable(); 320 Collection displayList = lookupable.performLookup(multipleValueLookupForm, resultTable, bounded); 321 322 List defaultSortColumns = lookupable.getDefaultSortColumns(); 323 if (defaultSortColumns != null && !defaultSortColumns.isEmpty() && resultTable != null && !resultTable.isEmpty()) { 324 // there's a default sort order, just find the first sort column, and we can't go wrong 325 String firstSortColumn = (String) defaultSortColumns.get(0); 326 327 // go thru the first result row to find the index of the column (more efficient than calling lookupable.getColumns since we don't have to recreate column list) 328 int firstSortColumnIdx = -1; 329 List<Column> columnsForFirstResultRow = resultTable.get(0).getColumns(); 330 for (int i = 0; i < columnsForFirstResultRow.size(); i++) { 331 if (StringUtils.equals(firstSortColumn, columnsForFirstResultRow.get(i).getPropertyName())) { 332 firstSortColumnIdx = i; 333 break; 334 } 335 } 336 multipleValueLookupForm.setColumnToSortIndex(firstSortColumnIdx); 337 } 338 else { 339 // don't know how results were sorted, so we just say -1 340 multipleValueLookupForm.setColumnToSortIndex(-1); 341 } 342 343 // we just performed the lookup, so we're on the first page (indexed from 0) 344 multipleValueLookupForm.jumpToFirstPage(resultTable.size(), maxRowsPerPage); 345 346 SequenceAccessorService sas = KRADServiceLocator.getSequenceAccessorService(); 347 Long nextSeq = sas.getNextAvailableSequenceNumber(KRADConstants.LOOKUP_RESULTS_SEQUENCE); 348 String lookupResultsSequenceNumber = nextSeq.toString(); 349 multipleValueLookupForm.setLookupResultsSequenceNumber(lookupResultsSequenceNumber); 350 try { 351 LookupResultsService lookupResultsService = KNSServiceLocator.getLookupResultsService(); 352 lookupResultsService.persistResultsTable(lookupResultsSequenceNumber, resultTable, 353 GlobalVariables.getUserSession().getPerson().getPrincipalId()); 354 } 355 catch (Exception e) { 356 LOG.error("error occured trying to persist multiple lookup results", e); 357 throw new RuntimeException("error occured trying to persist multiple lookup results"); 358 } 359 360 // since new search, nothing's checked 361 multipleValueLookupForm.setCompositeObjectIdMap(new HashMap<String, String>()); 362 363 return displayList; 364 } 365 366 /** 367 * This method performs the operations necessary for a multiple value lookup to switch to another page of results and rerender the page 368 * @param multipleValueLookupForm 369 * @param maxRowsPerPage 370 * @return a list of result rows, used by the UI to render the page 371 */ 372 protected List<ResultRow> switchToPage(MultipleValueLookupForm multipleValueLookupForm, int maxRowsPerPage) { 373 String lookupResultsSequenceNumber = multipleValueLookupForm.getLookupResultsSequenceNumber(); 374 375 List<ResultRow> resultTable = null; 376 try { 377 resultTable = KNSServiceLocator.getLookupResultsService().retrieveResultsTable(lookupResultsSequenceNumber, GlobalVariables.getUserSession().getPerson().getPrincipalId()); 378 } 379 catch (Exception e) { 380 LOG.error("error occured trying to retrieve multiple lookup results", e); 381 throw new RuntimeException("error occured trying to retrieve multiple lookup results"); 382 } 383 384 multipleValueLookupForm.jumpToPage(multipleValueLookupForm.getSwitchToPageNumber(), resultTable.size(), maxRowsPerPage); 385 386 multipleValueLookupForm.setColumnToSortIndex(Integer.parseInt(multipleValueLookupForm.getPreviouslySortedColumnIndex())); 387 multipleValueLookupForm.setCompositeObjectIdMap(LookupUtils.generateCompositeSelectedObjectIds(multipleValueLookupForm.getPreviouslySelectedObjectIdSet(), 388 multipleValueLookupForm.getDisplayedObjectIdSet(), multipleValueLookupForm.getSelectedObjectIdSet())); 389 return resultTable; 390 } 391 392 /** 393 * This method performs the operations necessary for a multiple value lookup to sort results and rerender the page 394 * 395 * @param multipleValueLookupForm 396 * @param maxRowsPerPage 397 * @return a list of result rows, used by the UI to render the page 398 */ 399 protected List<ResultRow> sort(MultipleValueLookupForm multipleValueLookupForm, int maxRowsPerPage) { 400 String lookupResultsSequenceNumber = multipleValueLookupForm.getLookupResultsSequenceNumber(); 401 402 LookupResultsService lookupResultsService = KNSServiceLocator.getLookupResultsService(); 403 404 List<ResultRow> resultTable = null; 405 try { 406 resultTable = lookupResultsService.retrieveResultsTable(lookupResultsSequenceNumber, GlobalVariables.getUserSession().getPerson().getPrincipalId()); 407 } 408 catch (Exception e) { 409 LOG.error("error occured trying to retrieve multiple lookup results", e); 410 throw new RuntimeException("error occured trying to retrieve multiple lookup results"); 411 } 412 413 int columnToSortOn = multipleValueLookupForm.getColumnToSortIndex(); 414 int columnCurrentlySortedOn = Integer.parseInt(multipleValueLookupForm.getPreviouslySortedColumnIndex()); 415 416 // if columnCurrentlySortedOn is -1, that means that we don't know which column we were originally sorting on 417 // after a search, it's hard to tell which of the columns we're sorted on, 418 419 if (columnToSortOn == columnCurrentlySortedOn) { 420 // we're already sorted on the same column that the user clicked on, so we reverse the list 421 Collections.reverse(resultTable); 422 } 423 else { 424 // sorting on a different column, so we have to sort 425 426 // HACK ALERT for findBestValueComparatorForColumn, since there's no central place to know 427 // which comparator we should use to compare values in a column 428 Collections.sort(resultTable, new BeanComparator("columns[" + columnToSortOn + "].propertyValue", LookupUtils.findBestValueComparatorForColumn(resultTable, columnToSortOn))); 429 } 430 431 // repersist the list 432 try { 433 lookupResultsService.persistResultsTable(lookupResultsSequenceNumber, resultTable, 434 GlobalVariables.getUserSession().getPerson().getPrincipalId()); 435 } 436 catch (Exception e) { 437 LOG.error("error occured trying to persist multiple lookup results", e); 438 throw new RuntimeException("error occured trying to persist multiple lookup results"); 439 } 440 441 // we just performed the sort, so go back to first page 442 multipleValueLookupForm.jumpToFirstPage(resultTable.size(), maxRowsPerPage); 443 444 multipleValueLookupForm.setCompositeObjectIdMap(LookupUtils.generateCompositeSelectedObjectIds(multipleValueLookupForm.getPreviouslySelectedObjectIdSet(), 445 multipleValueLookupForm.getDisplayedObjectIdSet(), multipleValueLookupForm.getSelectedObjectIdSet())); 446 return resultTable; 447 } 448 449 /** 450 * This method performs the operations necessary for a multiple value lookup keep track of which results have been selected to be returned 451 * to the calling document. Note, this method does not actually requery for the results. 452 * 453 * @param multipleValueLookupForm 454 */ 455 protected void prepareToReturnSelectedResultBOs(MultipleValueLookupForm multipleValueLookupForm) { 456 String lookupResultsSequenceNumber = multipleValueLookupForm.getLookupResultsSequenceNumber(); 457 if (StringUtils.isBlank(lookupResultsSequenceNumber)) { 458 // pressed return before searching 459 return; 460 } 461 Map<String, String> compositeObjectIdMap = LookupUtils.generateCompositeSelectedObjectIds(multipleValueLookupForm.getPreviouslySelectedObjectIdSet(), 462 multipleValueLookupForm.getDisplayedObjectIdSet(), multipleValueLookupForm.getSelectedObjectIdSet()); 463 Set<String> compositeObjectIds = compositeObjectIdMap.keySet(); 464 try { 465 LookupResultsService lookupResultsService = KNSServiceLocator.getLookupResultsService(); 466 lookupResultsService.persistSelectedObjectIds(lookupResultsSequenceNumber, compositeObjectIds, 467 GlobalVariables.getUserSession().getPerson().getPrincipalId()); 468 } 469 catch (Exception e) { 470 LOG.error("error occured trying to retrieve selected multiple lookup results", e); 471 throw new RuntimeException("error occured trying to retrieve selected multiple lookup results"); 472 } 473 } 474 475 /** 476 * This method performs the operations necessary for a multiple value lookup to return no results to the calling page 477 * 478 * @param multipleValueLookupForm 479 */ 480 protected void prepareToReturnNone(MultipleValueLookupForm multipleValueLookupForm) { 481 String lookupResultsSequenceNumber = multipleValueLookupForm.getLookupResultsSequenceNumber(); 482 try { 483 if (StringUtils.isNotBlank(lookupResultsSequenceNumber)) { 484 // we're returning nothing, so we try to get rid of stuff 485 LookupResultsService lookupResultsService = KNSServiceLocator.getLookupResultsService(); 486 lookupResultsService.clearPersistedLookupResults(lookupResultsSequenceNumber); 487 multipleValueLookupForm.setLookupResultsSequenceNumber(null); 488 } 489 } 490 catch (Exception e) { 491 // not a big deal, continue on and purge w/ a batch job 492 LOG.error("error occured trying to clear lookup results seq nbr " + lookupResultsSequenceNumber, e); 493 } 494 } 495 496 /** 497 * This method performs the operations necessary for a multiple value lookup to export the rows via display tag 498 * 499 * Note: this method assumes that the export will be opened in a new browser window, therefore, persisting the selected 500 * checkboxes will not be needed. 501 * 502 * @param multipleValueLookupForm 503 * @return a list of result rows, to be used by display tag to render the results 504 */ 505 protected List<ResultRow> prepareToExport(MultipleValueLookupForm multipleValueLookupForm) { 506 String lookupResultsSequenceNumber = multipleValueLookupForm.getLookupResultsSequenceNumber(); 507 508 List<ResultRow> resultTable = null; 509 try { 510 LookupResultsService lookupResultsService = KNSServiceLocator.getLookupResultsService(); 511 resultTable = lookupResultsService.retrieveResultsTable(lookupResultsSequenceNumber, GlobalVariables.getUserSession().getPerson().getPrincipalId()); 512 } 513 catch (Exception e) { 514 LOG.error("error occured trying to export multiple lookup results", e); 515 throw new RuntimeException("error occured trying to export multiple lookup results"); 516 } 517 return resultTable; 518 } 519 520 521 /** 522 * This method performs the operations necessary for a multiple value lookup to select all of the results and rerender the page 523 * @param multipleValueLookupForm 524 * @param maxRowsPerPage 525 * @return a list of result rows, used by the UI to render the page 526 */ 527 protected List<ResultRow> selectAll(MultipleValueLookupForm multipleValueLookupForm, int maxRowsPerPage) { 528 String lookupResultsSequenceNumber = multipleValueLookupForm.getLookupResultsSequenceNumber(); 529 530 List<ResultRow> resultTable = null; 531 try { 532 LookupResultsService lookupResultsService = KNSServiceLocator.getLookupResultsService(); 533 resultTable = lookupResultsService.retrieveResultsTable(lookupResultsSequenceNumber, GlobalVariables.getUserSession().getPerson().getPrincipalId()); 534 } 535 catch (Exception e) { 536 LOG.error("error occured trying to export multiple lookup results", e); 537 throw new RuntimeException("error occured trying to export multiple lookup results"); 538 } 539 540 Map<String, String> selectedObjectIds = new HashMap<String, String>(); 541 for (ResultRow row : resultTable) { 542 String objId = row.getObjectId(); 543 HtmlData.InputHtmlData returnUrl = (HtmlData.InputHtmlData) row.getReturnUrlHtmlData(); 544 returnUrl.setChecked(HtmlData.InputHtmlData.CHECKBOX_CHECKED_VALUE); 545 row.setReturnUrl(returnUrl.constructCompleteHtmlTag()); 546 if(objId != null){ 547 selectedObjectIds.put(objId, objId); 548 } 549 } 550 551 multipleValueLookupForm.jumpToPage(multipleValueLookupForm.getViewedPageNumber(), resultTable.size(), maxRowsPerPage); 552 multipleValueLookupForm.setColumnToSortIndex(Integer.parseInt(multipleValueLookupForm.getPreviouslySortedColumnIndex())); 553 multipleValueLookupForm.setCompositeObjectIdMap(selectedObjectIds); 554 555 return resultTable; 556 } 557 558 @Override 559 public ActionForward clearValues(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { 560 MultipleValueLookupForm multipleValueLookupForm = (MultipleValueLookupForm) form; 561 562 // call the following methods to clear the persisted results 563 prepareToReturnNone(multipleValueLookupForm); 564 565 return super.clearValues(mapping, form, request, response); 566 } 567 568 /** 569 * This method performs the operations necessary for a multiple value lookup to unselect all of the results and rerender the page 570 * @param multipleValueLookupForm 571 * @param maxRowsPerPage 572 * @return a list of result rows, used by the UI to render the page 573 */ 574 protected List<ResultRow> unselectAll(MultipleValueLookupForm multipleValueLookupForm, int maxRowsPerPage) { 575 String lookupResultsSequenceNumber = multipleValueLookupForm.getLookupResultsSequenceNumber(); 576 577 List<ResultRow> resultTable = null; 578 try { 579 LookupResultsService lookupResultsService = KNSServiceLocator.getLookupResultsService(); 580 resultTable = lookupResultsService.retrieveResultsTable(lookupResultsSequenceNumber, GlobalVariables.getUserSession().getPerson().getPrincipalId()); 581 } 582 catch (Exception e) { 583 LOG.error("error occured trying to export multiple lookup results", e); 584 throw new RuntimeException("error occured trying to export multiple lookup results"); 585 } 586 587 Map<String, String> selectedObjectIds = new HashMap<String, String>(); 588 // keep map empty since we're not selecting anything 589 590 multipleValueLookupForm.jumpToPage(multipleValueLookupForm.getViewedPageNumber(), resultTable.size(), maxRowsPerPage); 591 multipleValueLookupForm.setColumnToSortIndex(Integer.parseInt(multipleValueLookupForm.getPreviouslySortedColumnIndex())); 592 multipleValueLookupForm.setCompositeObjectIdMap(selectedObjectIds); 593 594 return resultTable; 595 } 596 597 /** 598 * This method computes the max number of rows that should be rendered per page for a multiple value lookup. 599 * 600 * This method first looks for an application parameter in FS_PARM_T, group SYSTEM, multipleValueLookupResultsPerPage 601 * 602 * if someone wants to implement something where a user can decide how many results to display per page, 603 * this method is the place to do it. Make this method read form values to determine the max rows per page based on the user inputs 604 * 605 * @see org.kuali.rice.krad.util.KRADConstants.SystemGroupParameterNames#MULTIPLE_VALUE_LOOKUP_RESULTS_PER_PAGE 606 * @see #DEFAULT_MAX_ROWS_PER_PAGE 607 * @param multipleValueLookupForm the form 608 * @return 609 */ 610 protected int getMaxRowsPerPage(MultipleValueLookupForm multipleValueLookupForm) { 611 Integer appMaxRowsPerPage = LookupUtils.getApplicationMaximumSearchResulsPerPageForMultipleValueLookups(); 612 if (appMaxRowsPerPage == null) { 613 LOG.warn("Couldn't find application results per page for MV lookups. Using default of " + DEFAULT_MAX_ROWS_PER_PAGE); 614 appMaxRowsPerPage = new Integer(DEFAULT_MAX_ROWS_PER_PAGE); 615 } 616 return appMaxRowsPerPage; 617 } 618 } 619