001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software GmbH & Co. KG, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.workplace.list; 029 030import org.opencms.i18n.CmsEncoder; 031import org.opencms.i18n.CmsMessageContainer; 032import org.opencms.util.CmsStringUtil; 033import org.opencms.workplace.CmsWorkplace; 034 035import java.util.ArrayList; 036import java.util.Collections; 037import java.util.Iterator; 038import java.util.List; 039 040/** 041 * Default implementation for a search action in an html list.<p> 042 * 043 * It allows to search in several columns, including item details.<p> 044 * 045 * @since 6.0.0 046 */ 047public class CmsListSearchAction extends A_CmsListSearchAction { 048 049 /** the html id for the input element of the search bar. */ 050 public static final String SEARCH_BAR_INPUT_ID = "listSearchFilter"; 051 052 /** Signals whether the search is case sensitive or not. */ 053 private boolean m_caseInSensitive; 054 055 /** Ids of Columns to search into. */ 056 private final List<CmsListColumnDefinition> m_columns = new ArrayList<CmsListColumnDefinition>(); 057 058 /** 059 * Default Constructor.<p> 060 * 061 * @param column the column to search into 062 */ 063 public CmsListSearchAction(CmsListColumnDefinition column) { 064 065 super(); 066 useDefaultShowAllAction(); 067 m_columns.add(column); 068 } 069 070 /** 071 * Adds a column to search into.<p> 072 * 073 * @param column the additional column to search into 074 */ 075 public void addColumn(CmsListColumnDefinition column) { 076 077 m_columns.add(column); 078 } 079 080 /** 081 * Returns the html code for the search bar.<p> 082 * 083 * @param wp the workplace context 084 * 085 * @return html code 086 */ 087 public String barHtml(CmsWorkplace wp) { 088 089 if (wp == null) { 090 wp = getWp(); 091 } 092 StringBuffer html = new StringBuffer(1024); 093 html.append("\t\t<input type='text' name='"); 094 html.append(SEARCH_BAR_INPUT_ID); 095 html.append("' id='"); 096 html.append(SEARCH_BAR_INPUT_ID); 097 html.append("' value='"); 098 if (wp instanceof A_CmsListDialog) { 099 // http://www.securityfocus.com/archive/1/490498: searchfilter cross site scripting vulnerability: 100 html.append( 101 CmsStringUtil.escapeJavaScript( 102 CmsEncoder.escapeXml(((A_CmsListDialog)wp).getList().getSearchFilter()))); 103 } 104 html.append("' size='20' maxlength='245' style='vertical-align: bottom;' >\n"); 105 html.append(buttonHtml(wp)); 106 if (getShowAllAction() != null) { 107 html.append(" "); 108 html.append(getShowAllAction().buttonHtml()); 109 } 110 return html.toString(); 111 } 112 113 /** 114 * @see org.opencms.workplace.list.A_CmsListSearchAction#buttonHtml(org.opencms.workplace.CmsWorkplace) 115 */ 116 @Override 117 public String buttonHtml(CmsWorkplace wp) { 118 119 // delay the composition of the help text as much as possible 120 if (getHelpText() == EMPTY_MESSAGE) { 121 String columns = ""; 122 Iterator<CmsListColumnDefinition> it = m_columns.iterator(); 123 while (it.hasNext()) { 124 CmsListColumnDefinition col = it.next(); 125 columns += "${key." + col.getName().getKey() + "}"; 126 if (it.hasNext()) { 127 columns += ", "; 128 } 129 } 130 if (columns.lastIndexOf(", ") > 0) { 131 columns = columns.substring(0, columns.lastIndexOf(", ")) 132 + " and " 133 + columns.substring(columns.lastIndexOf(", ") + 2); 134 } 135 setHelpText( 136 new CmsMessageContainer( 137 Messages.get(), 138 Messages.GUI_LIST_ACTION_SEARCH_HELP_1, 139 new Object[] {columns})); 140 } 141 return super.buttonHtml(wp); 142 } 143 144 /** 145 * Returns a sublist of the given items, that match the given filter string.<p> 146 * 147 * @param items the items to filter 148 * @param filter the string to filter 149 * 150 * @return the filtered sublist 151 */ 152 public List<CmsListItem> filter(List<CmsListItem> items, String filter) { 153 154 if (CmsStringUtil.isEmptyOrWhitespaceOnly(filter)) { 155 return items; 156 } 157 String filterCriteria = filter; 158 if (m_caseInSensitive) { 159 filterCriteria = filter.toLowerCase(); 160 } 161 162 List<CmsListItem> res = new ArrayList<CmsListItem>(); 163 Iterator<CmsListItem> itItems = items.iterator(); 164 while (itItems.hasNext()) { 165 CmsListItem item = itItems.next(); 166 if (res.contains(item)) { 167 continue; 168 } 169 Iterator<CmsListColumnDefinition> itCols = m_columns.iterator(); 170 while (itCols.hasNext()) { 171 CmsListColumnDefinition col = itCols.next(); 172 if (item.get(col.getId()) == null) { 173 continue; 174 } 175 String columnValue = item.get(col.getId()).toString(); 176 if (m_caseInSensitive) { 177 columnValue = columnValue.toLowerCase(); 178 } 179 if (columnValue.indexOf(filterCriteria) > -1) { 180 res.add(item); 181 break; 182 } 183 } 184 } 185 return res; 186 } 187 188 /** 189 * Returns the list of columns to be searched.<p> 190 * 191 * @return a list of {@link CmsListColumnDefinition} objects 192 */ 193 public List<CmsListColumnDefinition> getColumns() { 194 195 return Collections.unmodifiableList(m_columns); 196 } 197 198 /** 199 * Returns the caseInSensitive.<p> 200 * 201 * @return the caseInSensitive 202 */ 203 public boolean isCaseInSensitive() { 204 205 return m_caseInSensitive; 206 } 207 208 /** 209 * Sets the caseInSensitive.<p> 210 * 211 * @param caseInSensitive the caseInSensitive to set 212 */ 213 public void setCaseInSensitive(boolean caseInSensitive) { 214 215 m_caseInSensitive = caseInSensitive; 216 } 217 218 /** 219 * Sets the current search filter.<p> 220 * 221 * @param filter the current search filter 222 * 223 * @deprecated use {@link CmsHtmlList#setSearchFilter(String)} instead 224 */ 225 @Deprecated 226 public void setSearchFilter(String filter) { 227 228 // empty 229 } 230 231 /** 232 * @see org.opencms.workplace.list.I_CmsListAction#setWp(org.opencms.workplace.list.A_CmsListDialog) 233 */ 234 @Override 235 public void setWp(A_CmsListDialog wp) { 236 237 super.setWp(wp); 238 if (getShowAllAction() != null) { 239 getShowAllAction().setWp(wp); 240 } 241 } 242}