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