/* * The Kuali Financial System, a comprehensive financial management system for higher education. * * Copyright 2005-2014 The Kuali Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.kuali.kfs.gl.web.struts; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.beanutils.BeanComparator; import org.apache.commons.lang.StringUtils; import org.kuali.kfs.sys.context.SpringContext; import org.kuali.rice.kns.lookup.LookupResultsService; import org.kuali.rice.kns.lookup.LookupUtils; import org.kuali.rice.kns.lookup.Lookupable; import org.kuali.rice.kns.web.struts.form.LookupForm; import org.kuali.rice.kns.web.ui.Column; import org.kuali.rice.kns.web.ui.ResultRow; import org.kuali.rice.krad.service.SequenceAccessorService; import org.kuali.rice.krad.util.GlobalVariables; import org.kuali.rice.krad.util.KRADConstants; /** * This class serves as the struts action for implementing multiple value lookups */ public class BalanceInquiryLookupDisplayTagSurrogate implements LookupDisplayTagSurrogate { private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(BalanceInquiryLookupDisplayTagSurrogate.class); /** * If there is no app param defined for the # rows/page, then this value will be used for the default * * @see KualiMultipleValueLookupAction#getMaxRowsPerPage(MultipleValueLookupForm) */ public static final int DEFAULT_MAX_ROWS_PER_PAGE = 50; /** * @see LookupDisplayTagSurrogate#performMultipleValueLookup(LookupResultsSelectable,LookupForm,List,boolean) * * KRAD Conversion: Lookupable performs customization of the results setting the sort order. * * Fields are in data dictionary for bo Balance. */ public Collection performMultipleValueLookup(LookupResultsSelectable selectable, LookupForm form, List<ResultRow> resultTable, boolean bounded) { Lookupable lookupable = form.getLookupable(); Collection displayList = lookupable.performLookup(form, resultTable, bounded); List defaultSortColumns = lookupable.getDefaultSortColumns(); if (defaultSortColumns != null && !defaultSortColumns.isEmpty() && resultTable != null && !resultTable.isEmpty()) { // there's a default sort order, just find the first sort column, and we can't go wrong String firstSortColumn = (String) defaultSortColumns.get(0); // 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) int firstSortColumnIdx = -1; List<Column> columnsForFirstResultRow = resultTable.get(0).getColumns(); for (int i = 0; i < columnsForFirstResultRow.size(); i++) { if (StringUtils.equals(firstSortColumn, columnsForFirstResultRow.get(i).getPropertyName())) { firstSortColumnIdx = i; break; } } selectable.setColumnToSortIndex(firstSortColumnIdx); } else { // don't know how results were sorted, so we just say -1 selectable.setColumnToSortIndex(-1); } // we just performed the lookup, so we're on the first page (indexed from 0) selectable.jumpToFirstPage(resultTable.size(), getMaxRowsPerPage(selectable)); SequenceAccessorService sequenceAccessorService = SpringContext.getBean(SequenceAccessorService.class); String lookupResultsSequenceNumber = String.valueOf(sequenceAccessorService.getNextAvailableSequenceNumber(KRADConstants.LOOKUP_RESULTS_SEQUENCE)); selectable.setLookupResultsSequenceNumber(lookupResultsSequenceNumber); try { LookupResultsService lookupResultsService = SpringContext.getBean(LookupResultsService.class); lookupResultsService.persistResultsTable(lookupResultsSequenceNumber, resultTable, GlobalVariables.getUserSession().getPerson().getPrincipalId()); } catch (Exception e) { LOG.error("error occured trying to persist multiple lookup results", e); throw new RuntimeException("error occured trying to persist multiple lookup results"); } // since new search, nothing's checked selectable.setCompositeObjectIdMap(new HashMap<String, String>()); return displayList; } /** * @see LookupDisplayTagSurrogate#switchToPage(LookupResultsSelectable,int) * * KRAD Conversion: Lookupable performs retrieving the data. * * Fields are in data dictionary for bo Balance. */ public List<ResultRow> switchToPage(LookupResultsSelectable selectable, int maxRowsPerPage) { String lookupResultsSequenceNumber = selectable.getLookupResultsSequenceNumber(); List<ResultRow> resultTable = null; try { resultTable = SpringContext.getBean(LookupResultsService.class).retrieveResultsTable(lookupResultsSequenceNumber, GlobalVariables.getUserSession().getPerson().getPrincipalId()); } catch (Exception e) { LOG.error("error occured trying to retrieve multiple lookup results", e); throw new RuntimeException("error occured trying to retrieve multiple lookup results"); } selectable.jumpToPage(selectable.getSwitchToPageNumber(), resultTable.size(), maxRowsPerPage); selectable.setColumnToSortIndex(Integer.parseInt(selectable.getPreviouslySortedColumnIndex())); selectable.setCompositeObjectIdMap(LookupUtils.generateCompositeSelectedObjectIds(selectable.getPreviouslySelectedObjectIdSet(), selectable.getDisplayedObjectIdSet(), selectable.getSelectedObjectIdSet())); return resultTable; } /** * @see LookupDisplayTagSurrogate#sort(LookupResultsSelectable,int) * * KRAD Conversion: Lookupable performs retrieving the data and reverses the data if need to be sorted. * * Fields are in data dictionary for bo Balance. */ public List<ResultRow> sort(LookupResultsSelectable selectable, int maxRowsPerPage) { String lookupResultsSequenceNumber = selectable.getLookupResultsSequenceNumber(); LookupResultsService lookupResultsService = SpringContext.getBean(LookupResultsService.class); List<ResultRow> resultTable = null; try { resultTable = lookupResultsService.retrieveResultsTable(lookupResultsSequenceNumber, GlobalVariables.getUserSession().getPerson().getPrincipalId()); } catch (Exception e) { LOG.error("error occured trying to retrieve multiple lookup results", e); throw new RuntimeException("error occured trying to retrieve multiple lookup results"); } int columnToSortOn = selectable.getColumnToSortIndex(); int columnCurrentlySortedOn = Integer.parseInt(selectable.getPreviouslySortedColumnIndex()); // if columnCurrentlySortedOn is -1, that means that we don't know which column we were originally sorting on // after a search, it's hard to tell which of the columns we're sorted on, if (columnToSortOn == columnCurrentlySortedOn) { // we're already sorted on the same column that the user clicked on, so we reverse the list Collections.reverse(resultTable); } else { // sorting on a different column, so we have to sort // HACK ALERT for findBestValueComparatorForColumn, since there's no central place to know // which comparator we should use to compare values in a column Collections.sort(resultTable, new BeanComparator("columns[" + columnToSortOn + "].propertyValue", LookupUtils.findBestValueComparatorForColumn(resultTable, columnToSortOn))); } // repersist the list try { lookupResultsService.persistResultsTable(lookupResultsSequenceNumber, resultTable, GlobalVariables.getUserSession().getPerson().getPrincipalId()); } catch (Exception e) { LOG.error("error occured trying to persist multiple lookup results", e); throw new RuntimeException("error occured trying to persist multiple lookup results"); } // we just performed the sort, so go back to first page selectable.jumpToFirstPage(resultTable.size(), maxRowsPerPage); selectable.setCompositeObjectIdMap(LookupUtils.generateCompositeSelectedObjectIds(selectable.getPreviouslySelectedObjectIdSet(), selectable.getDisplayedObjectIdSet(), selectable.getSelectedObjectIdSet())); return resultTable; } /** * @see LookupDisplayTagSurrogate#prepareToReturnSelectedResultBOs(LookupResultsSelectable) */ public void prepareToReturnSelectedResultBOs(LookupResultsSelectable selectable) { String lookupResultsSequenceNumber = selectable.getLookupResultsSequenceNumber(); if (StringUtils.isBlank(lookupResultsSequenceNumber)) { // pressed return before searching return; } Map<String, String> compositeObjectIdMap = LookupUtils.generateCompositeSelectedObjectIds(selectable.getPreviouslySelectedObjectIdSet(), selectable.getDisplayedObjectIdSet(), selectable.getSelectedObjectIdSet()); Set<String> compositeObjectIds = compositeObjectIdMap.keySet(); try { LookupResultsService lookupResultsService = SpringContext.getBean(LookupResultsService.class); lookupResultsService.persistSelectedObjectIds(lookupResultsSequenceNumber, compositeObjectIds, GlobalVariables.getUserSession().getPerson().getPrincipalId()); } catch (Exception e) { LOG.error("error occured trying to retrieve selected multiple lookup results", e); throw new RuntimeException("error occured trying to retrieve selected multiple lookup results"); } } /** * @see LookupDisplayTagSurrogate#prepareToReturnNone(LookupResultsSelectable) */ public void prepareToReturnNone(LookupResultsSelectable selectable) { String lookupResultsSequenceNumber = selectable.getLookupResultsSequenceNumber(); try { if (StringUtils.isNotBlank(lookupResultsSequenceNumber)) { // we're returning nothing, so we try to get rid of stuff LookupResultsService lookupResultsService = SpringContext.getBean(LookupResultsService.class); lookupResultsService.clearPersistedLookupResults(lookupResultsSequenceNumber); } } catch (Exception e) { // not a big deal, continue on and purge w/ a batch job LOG.error("error occured trying to clear lookup results seq nbr " + lookupResultsSequenceNumber, e); } } /** * @see LookupDisplayTagSurrogate#prepareToExport(LookupResultsSelectable) * * KRAD Conversion: Lookupable performs retrieving the data. * * Fields are in data dictionary for bo Balance. */ public List<ResultRow> prepareToExport(LookupResultsSelectable selectable) { String lookupResultsSequenceNumber = selectable.getLookupResultsSequenceNumber(); List<ResultRow> resultTable = null; try { LookupResultsService lookupResultsService = SpringContext.getBean(LookupResultsService.class); resultTable = lookupResultsService.retrieveResultsTable(lookupResultsSequenceNumber, GlobalVariables.getUserSession().getPerson().getPrincipalId()); } catch (Exception e) { LOG.error("error occured trying to export multiple lookup results", e); throw new RuntimeException("error occured trying to export multiple lookup results"); } return resultTable; } /** * @see LookupDisplayTagSurrogate#getMaxRowsPerPage(LookupResultsSelectable) * * KRAD Conversion: Lookupable performs customization of the results. * * Fields are in data dictionary for bo Balance. */ public List<ResultRow> selectAll(LookupResultsSelectable selectable, int maxRowsPerPage) { String lookupResultsSequenceNumber = selectable.getLookupResultsSequenceNumber(); List<ResultRow> resultTable = null; try { LookupResultsService lookupResultsService = SpringContext.getBean(LookupResultsService.class); resultTable = lookupResultsService.retrieveResultsTable(lookupResultsSequenceNumber, GlobalVariables.getUserSession().getPerson().getPrincipalId()); } catch (Exception e) { LOG.error("error occured trying to export multiple lookup results", e); throw new RuntimeException("error occured trying to export multiple lookup results"); } Map<String, String> selectedObjectIds = new HashMap<String, String>(); for (ResultRow row : resultTable) { String objId = row.getObjectId(); selectedObjectIds.put(objId, objId); } selectable.jumpToPage(selectable.getViewedPageNumber(), resultTable.size(), maxRowsPerPage); selectable.setColumnToSortIndex(Integer.parseInt(selectable.getPreviouslySortedColumnIndex())); selectable.setCompositeObjectIdMap(selectedObjectIds); return resultTable; } /** * @see LookupDisplayTagSurrogate#getMaxRowsPerPage(LookupResultsSelectable) * * KRAD Conversion: Lookupable performs customization of the results. * * Fields are in data dictionary for bo Balance. */ public List<ResultRow> unselectAll(LookupResultsSelectable selectable, int maxRowsPerPage) { String lookupResultsSequenceNumber = selectable.getLookupResultsSequenceNumber(); List<ResultRow> resultTable = null; try { LookupResultsService lookupResultsService = SpringContext.getBean(LookupResultsService.class); resultTable = lookupResultsService.retrieveResultsTable(lookupResultsSequenceNumber, GlobalVariables.getUserSession().getPerson().getPrincipalId()); } catch (Exception e) { LOG.error("error occured trying to export multiple lookup results", e); throw new RuntimeException("error occured trying to export multiple lookup results"); } Map<String, String> selectedObjectIds = new HashMap<String, String>(); // keep map empty since we're not selecting anything selectable.jumpToPage(selectable.getViewedPageNumber(), resultTable.size(), maxRowsPerPage); selectable.setColumnToSortIndex(Integer.parseInt(selectable.getPreviouslySortedColumnIndex())); selectable.setCompositeObjectIdMap(selectedObjectIds); return resultTable; } /** * @see LookupDisplayTagSurrogate#getMaxRowsPerPage(LookupResultsSelectable) */ public int getMaxRowsPerPage(LookupResultsSelectable selectable) { Integer appMaxRowsPerPage = LookupUtils.getApplicationMaximumSearchResulsPerPageForMultipleValueLookups(); if (appMaxRowsPerPage == null) { LOG.warn("Couldn't find application results per page for MV lookups. Using default of " + DEFAULT_MAX_ROWS_PER_PAGE); appMaxRowsPerPage = new Integer(DEFAULT_MAX_ROWS_PER_PAGE); } return appMaxRowsPerPage; } }