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.util.CmsStringUtil; 032import org.opencms.workplace.CmsWorkplace; 033 034import java.util.ArrayList; 035import java.util.Iterator; 036import java.util.List; 037import java.util.Map; 038 039/** 040 * Displays an advanced search form over several columns.<p> 041 * 042 * @since 7.6 043 */ 044public class CmsListMultiSearchAction extends CmsListSearchAction { 045 046 /** The string to delimit key and value. */ 047 public static final String KEY_VAL_DELIM = "#"; 048 049 /** The string to delimit each column-value pair. */ 050 public static final String PARAM_DELIM = "|"; 051 052 /** the html id prefix for the input element of the search bar. */ 053 public static final String SEARCH_COL_INPUT_ID = "listColFilter"; 054 055 /** 056 * Default constructor.<p> 057 * 058 * @param column the first column to search in 059 * 060 * @see #addColumn(CmsListColumnDefinition) 061 */ 062 public CmsListMultiSearchAction(CmsListColumnDefinition column) { 063 064 super(column); 065 } 066 067 /** 068 * @see org.opencms.workplace.list.CmsListSearchAction#barHtml(org.opencms.workplace.CmsWorkplace) 069 */ 070 @Override 071 public String barHtml(CmsWorkplace wp) { 072 073 if (wp == null) { 074 wp = getWp(); 075 } 076 StringBuffer html = new StringBuffer(1024); 077 html.append("\t\t<input type='hidden' name='"); 078 html.append(SEARCH_BAR_INPUT_ID); 079 html.append("' id='"); 080 html.append(SEARCH_BAR_INPUT_ID); 081 html.append("' value='"); 082 String searchFilter = ""; 083 if (wp instanceof A_CmsListDialog) { 084 searchFilter = ((A_CmsListDialog)wp).getList().getSearchFilter(); 085 } 086 Map<String, String> colVals = CmsStringUtil.splitAsMap(searchFilter, PARAM_DELIM, KEY_VAL_DELIM); 087 // http://www.securityfocus.com/archive/1/490498: searchfilter cross site scripting vulnerability: 088 html.append(CmsStringUtil.escapeJavaScript(CmsEncoder.escapeXml(searchFilter))); 089 html.append("' >\n"); 090 Iterator<CmsListColumnDefinition> it = getColumns().iterator(); 091 while (it.hasNext()) { 092 CmsListColumnDefinition colDef = it.next(); 093 html.append("\t\t<input type='text' name='"); 094 html.append(SEARCH_COL_INPUT_ID).append(colDef.getId()); 095 html.append("' id='"); 096 html.append(SEARCH_COL_INPUT_ID).append(colDef.getId()); 097 html.append("' value='"); 098 String val = colVals.get(colDef.getId()); 099 if (val == null) { 100 val = ""; 101 } 102 html.append(CmsStringUtil.escapeJavaScript(CmsEncoder.escapeXml(val))); 103 html.append("' title='"); 104 html.append(CmsStringUtil.escapeJavaScript(colDef.getName().key(wp.getLocale()))); 105 html.append("' size='20' maxlength='245' style='vertical-align: bottom;' >\n"); 106 } 107 html.append(buttonHtml(wp)); 108 if (getShowAllAction() != null) { 109 html.append(" "); 110 html.append(getShowAllAction().buttonHtml()); 111 } 112 // load script 113 html.append("<script >\n"); 114 html.append("var LIST_SEARCH_DATA = {\n"); 115 html.append("SEARCH_BAR_INPUT_ID: \"").append(SEARCH_BAR_INPUT_ID).append("\",\n"); 116 html.append("FORM: \"").append(getListId() + "-form").append("\",\n"); 117 html.append("COLUMNS: ["); 118 it = getColumns().iterator(); 119 while (it.hasNext()) { 120 CmsListColumnDefinition colDef = it.next(); 121 html.append("\"").append(colDef.getId()).append("\""); 122 if (it.hasNext()) { 123 html.append(", "); 124 } 125 } 126 html.append("]\n"); 127 html.append("};\n"); 128 html.append("</script>\n"); 129 130 return html.toString(); 131 } 132 133 /** 134 * @see org.opencms.workplace.list.CmsListSearchAction#filter(java.util.List, java.lang.String) 135 */ 136 @Override 137 public List<CmsListItem> filter(List<CmsListItem> items, String searchFilter) { 138 139 if (CmsStringUtil.isEmptyOrWhitespaceOnly(searchFilter)) { 140 return items; 141 } 142 Map<String, String> colVals = CmsStringUtil.splitAsMap(searchFilter, PARAM_DELIM, KEY_VAL_DELIM); 143 List<CmsListItem> res = new ArrayList<CmsListItem>(); 144 Iterator<CmsListItem> itItems = items.iterator(); 145 while (itItems.hasNext()) { 146 CmsListItem item = itItems.next(); 147 if (res.contains(item)) { 148 continue; 149 } 150 boolean matched = true; 151 Iterator<CmsListColumnDefinition> itCols = getColumns().iterator(); 152 while (matched && itCols.hasNext()) { 153 CmsListColumnDefinition col = itCols.next(); 154 if (item.get(col.getId()) == null) { 155 matched = false; 156 continue; 157 } 158 String colFilter = colVals.get(col.getId()); 159 160 if ((colFilter != null) && (item.get(col.getId()).toString().indexOf(colFilter) < 0)) { 161 matched = false; 162 } 163 } 164 if (matched) { 165 res.add(item); 166 } 167 } 168 return res; 169 } 170}