/** * Copyright (c) 2009--2014 Red Hat, Inc. * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package com.redhat.rhn.frontend.taglibs.helpers; import com.redhat.rhn.common.db.datasource.DataResult; import com.redhat.rhn.frontend.struts.RequestContext; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; /** * Makes it easier to work with the list view code * * @version $Rev $ */ public class ListViewHelper { private static final String DEFAULT_DISPLAY_NAME = "pageList"; private RequestContext ctx = null; private DataResult result = null; private String filterByField = null; private DataResult filteredResult = null; private boolean isFiltering = false; private int pageSize = -1; /** * Initializes the helper. A new helper instance should be created for each * request. Caching helpers is strongly discouraged. * @param requestContext current request * @param filterField name of the DTO/Map field which will be filtered * For example, if the DTO has a <code>getLabel</code> method, then the * field name would be label. */ public ListViewHelper(RequestContext requestContext, String filterField) { this.ctx = requestContext; this.filterByField = filterField; // Default to the User's page size. Can be overriden by calling setPageSize() this.pageSize = requestContext.getCurrentUser().getPageSize(); } /** * Sets the DataResult reference * @param data data to drive the list view */ public void setData(DataResult data) { this.result = data; } /** * Indicate if the data result can be filtered * @param flag on/off toggle */ public void isFiltering(boolean flag) { this.isFiltering = flag; } /** * Gets the filter parameter specified by the user * @return the value of the request parameter filter_string */ public String getFilterParam() { String retval = this.ctx.getParam("filter_string", false); if (retval != null && retval.length() == 0) { retval = null; } else if (retval != null) { retval = retval.trim(); } return retval; } /** * Gets the filter parameter specified by the user on the immediately prior request * @return the value of the request parameter filter_string */ public String getPreviousFilterParam() { String retval = this.ctx.getParam("prev_filter_value", false); if (retval != null && retval.length() == 0) { retval = null; } else if (retval != null) { retval = retval.trim(); } return retval; } /** * Sets up the environment for list view processing * This should be called immediately before rendering the page containing * the list view */ public void prepare() { prepare(DEFAULT_DISPLAY_NAME); } /** * Sets up the environment for list view processing * This should be called immediately before rendering the page containing * the list view * @param displayName the name to store the list view's data under */ public void prepare(String displayName) { if (this.result == null) { return; } this.result.setFilter(this.isFiltering); if (getFilterParam() != null) { filterData(); } processPagination(); if (this.filteredResult != null) { this.ctx.getRequest().setAttribute(displayName, this.filteredResult); } else { this.ctx.getRequest().setAttribute(displayName, this.result); } } /** * Set number of items per page * @param size number of items on page */ public void setItemsPerPage(int size) { this.pageSize = size; } /** * Number of items on page * @return items on page */ public int getItemsPerPage() { return this.pageSize; } private void processPagination() { String rawStart = ctx.processPagination(); if (hasFilterCriteriaReset()) { rawStart = "1"; } else if (rawStart == null) { rawStart = "1"; } int start = Integer.parseInt(rawStart); int end = start + this.pageSize; if (this.filteredResult != null) { DataResult tmp = this.filteredResult.slice(start - 1, end - 1); tmp.setFilterData(getFilterParam()); tmp.setFilter(true); this.filteredResult = tmp; this.filteredResult.setStart(start); this.filteredResult.setEnd((start + this.filteredResult.size()) - 1); } else { this.result = this.result.slice(start - 1, end - 1); this.result.setStart(start); this.result.setEnd((start + this.result.size()) - 1); } } private void filterData() { if (result.size() == 0 || getFilterParam() == null) { return; } List filteredData = new LinkedList(); Object datum = result.get(0); if (datum instanceof Map) { filterMaps(filteredData); } else { filterDtos(filteredData); } this.filteredResult = new DataResult(filteredData); this.filteredResult.setTotalSize(this.filteredResult.size()); this.filteredResult.setStart(1); this.filteredResult.setFilter(true); this.filteredResult.setFilterData(getFilterParam()); } private void filterMaps(List accum) { String filterValue = getFilterParam(); for (Iterator iter = this.result.iterator(); iter.hasNext();) { Map row = (Map) iter.next(); String value = (String) row.get(this.filterByField); if (value != null && value.contains(filterValue)) { accum.add(row); } } } private void filterDtos(List accum) { String filterValue = getFilterParam(); Object dto = this.result.get(0); Method method = locateFilterMethod(dto); if (method == null) { return; } for (Iterator iter = this.result.iterator(); iter.hasNext();) { Object o = iter.next(); try { String value = (String) method.invoke(o, (Object[])null); if (value.contains(filterValue)) { accum.add(o); } } catch (IllegalAccessException e) { e.printStackTrace(); continue; } catch (IllegalArgumentException e) { e.printStackTrace(); continue; } catch (InvocationTargetException e) { e.printStackTrace(); continue; } } } private Method locateFilterMethod(Object dto) { Method retval = null; String methodName = this.filterByField; methodName = "get" + methodName.substring(0, 1).toUpperCase() + methodName.substring(1); Method[] methods = dto.getClass().getMethods(); for (int x = 0; x < methods.length; x++) { if (methods[x].getName().equals(methodName)) { retval = methods[x]; break; } } return retval; } private boolean hasFilterCriteriaReset() { boolean retval = false; String prevFilter = getPreviousFilterParam(); String currentFilter = getFilterParam(); if ((prevFilter != null && currentFilter != null) && !prevFilter.equals(currentFilter)) { retval = true; } else if ((prevFilter == null && currentFilter != null) || prevFilter != null && currentFilter == null) { retval = true; } return retval; } }