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.tools.searchindex; 029 030import org.opencms.configuration.CmsSearchConfiguration; 031import org.opencms.i18n.CmsMessageContainer; 032import org.opencms.jsp.CmsJspActionElement; 033import org.opencms.main.CmsLog; 034import org.opencms.main.OpenCms; 035import org.opencms.search.CmsSearchManager; 036import org.opencms.search.fields.CmsLuceneField; 037import org.opencms.search.fields.CmsSearchField; 038import org.opencms.search.fields.CmsSearchFieldMapping; 039import org.opencms.search.fields.I_CmsSearchFieldConfiguration; 040import org.opencms.search.fields.I_CmsSearchFieldMapping; 041import org.opencms.workplace.list.CmsListColumnAlignEnum; 042import org.opencms.workplace.list.CmsListColumnDefinition; 043import org.opencms.workplace.list.CmsListDefaultAction; 044import org.opencms.workplace.list.CmsListDirectAction; 045import org.opencms.workplace.list.CmsListItem; 046import org.opencms.workplace.list.CmsListMetadata; 047import org.opencms.workplace.list.CmsListMultiAction; 048import org.opencms.workplace.list.CmsListOrderEnum; 049import org.opencms.workplace.tools.CmsToolDialog; 050 051import java.io.IOException; 052import java.util.ArrayList; 053import java.util.Collections; 054import java.util.HashMap; 055import java.util.Iterator; 056import java.util.List; 057import java.util.Map; 058 059import javax.servlet.ServletException; 060 061import org.apache.commons.logging.Log; 062 063/** 064 * A list that displays the mappings of a request parameter given 065 * <code>{@link org.opencms.search.fields.CmsLuceneField}</code> ("field"). 066 * 067 * This list is no stand-alone page but has to be embedded in another dialog 068 * (see <code> {@link org.opencms.workplace.tools.searchindex.A_CmsEmbeddedListDialog}</code>. <p> 069 * 070 * @since 6.5.5 071 */ 072public class CmsMappingsList extends A_CmsEmbeddedListDialog { 073 074 /** list column id constant. */ 075 public static final String LIST_ACTION_EDIT = "ae"; 076 077 /** list column id constant. */ 078 public static final String LIST_ACTION_EDITTYPE = "aet"; 079 080 /** list column id constant. */ 081 public static final String LIST_ACTION_EDITVALUE = "aev"; 082 083 /** list column id constant. */ 084 public static final String LIST_COLUMN_DEFAULT = "cd"; 085 086 /** list column id constant. */ 087 public static final String LIST_COLUMN_ICON = "ci"; 088 089 /** list column id constant. */ 090 public static final String LIST_COLUMN_TYPE = "ct"; 091 092 /** list column id constant. */ 093 public static final String LIST_COLUMN_VALUE = "cv"; 094 095 /** list id constant. */ 096 public static final String LIST_ID = "lsfcfm"; 097 098 /** list action id constant. */ 099 public static final String LIST_MACTION_DELETEMAPPING = "mad"; 100 101 /** The path to the field configuration list icon. */ 102 protected static final String LIST_ICON_MAPPING = "tools/searchindex/icons/small/fieldconfiguration-mapping.png"; 103 104 /** The log object for this class. */ 105 private static final Log LOG = CmsLog.getLog(CmsMappingsList.class); 106 107 /** Stores the value of the request parameter for the field. */ 108 private String m_paramField; 109 110 /** Stores the value of the request parameter for the field configuration. */ 111 private String m_paramFieldconfiguration; 112 113 /** 114 * Public constructor.<p> 115 * 116 * @param jsp an initialized JSP action element 117 */ 118 public CmsMappingsList(CmsJspActionElement jsp) { 119 120 this(jsp, LIST_ID, Messages.get().container(Messages.GUI_LIST_MAPPINGS_NAME_0)); 121 } 122 123 /** 124 * Public constructor.<p> 125 * 126 * @param jsp an initialized JSP action element 127 * @param listId the id of the list 128 * @param listName the list name 129 */ 130 public CmsMappingsList(CmsJspActionElement jsp, String listId, CmsMessageContainer listName) { 131 132 this(jsp, listId, listName, LIST_COLUMN_TYPE, CmsListOrderEnum.ORDER_ASCENDING, null); 133 } 134 135 /** 136 * Public constructor.<p> 137 * 138 * @param jsp an initialized JSP action element 139 * @param listId the id of the displayed list 140 * @param listName the name of the list 141 * @param sortedColId the a priory sorted column 142 * @param sortOrder the order of the sorted column 143 * @param searchableColId the column to search into 144 */ 145 public CmsMappingsList( 146 CmsJspActionElement jsp, 147 String listId, 148 CmsMessageContainer listName, 149 String sortedColId, 150 CmsListOrderEnum sortOrder, 151 String searchableColId) { 152 153 super(jsp, listId, listName, sortedColId, sortOrder, searchableColId); 154 } 155 156 /** 157 * @see org.opencms.workplace.list.A_CmsListDialog#executeListMultiActions() 158 */ 159 @Override 160 public void executeListMultiActions() { 161 162 CmsSearchManager searchManager = OpenCms.getSearchManager(); 163 if (getParamListAction().equals(LIST_MACTION_DELETEMAPPING)) { 164 // execute the delete multi action, first search for the field to edit 165 List<CmsSearchField> fields = searchManager.getFieldConfiguration(m_paramFieldconfiguration).getFields(); 166 Iterator<CmsSearchField> itFields = fields.iterator(); 167 while (itFields.hasNext()) { 168 CmsLuceneField curField = (CmsLuceneField)itFields.next(); 169 if (curField.getName().equals(m_paramField)) { 170 // we found the field to edit 171 List<I_CmsSearchFieldMapping> deleteMappings = new ArrayList<I_CmsSearchFieldMapping>(); 172 Iterator<CmsListItem> itItems = getSelectedItems().iterator(); 173 while (itItems.hasNext()) { 174 // iterate all selected mappings 175 CmsListItem listItem = itItems.next(); 176 Iterator<I_CmsSearchFieldMapping> itMappings = curField.getMappings().iterator(); 177 while (itMappings.hasNext()) { 178 // iterate all field mappings 179 CmsSearchFieldMapping curMapping = (CmsSearchFieldMapping)itMappings.next(); 180 String itemValue = (String)listItem.get(LIST_COLUMN_VALUE); 181 String itemType = (String)listItem.get(LIST_COLUMN_TYPE); 182 // match the selected mapping 183 if (curMapping.getType().toString().equals(itemType) 184 && (((curMapping.getParam() == null) && (itemValue == null)) 185 || (curMapping.getParam().equals(itemValue)))) { 186 // mark for deletion 187 deleteMappings.add(curMapping); 188 } 189 } 190 } 191 // delete the marked mappings 192 Iterator<I_CmsSearchFieldMapping> itMappings = deleteMappings.iterator(); 193 while (itMappings.hasNext()) { 194 CmsSearchFieldMapping mapping = (CmsSearchFieldMapping)itMappings.next(); 195 searchManager.removeSearchFieldMapping(curField, mapping); 196 } 197 break; 198 } 199 } 200 201 refreshList(); 202 writeConfiguration(false); 203 } 204 listSave(); 205 } 206 207 /** 208 * @see org.opencms.workplace.list.A_CmsListDialog#executeListSingleActions() 209 */ 210 @Override 211 public void executeListSingleActions() throws ServletException, IOException { 212 213 CmsListItem item = getSelectedItem(); 214 Map<String, String[]> params = new HashMap<String, String[]>(); 215 String action = getParamListAction(); 216 217 params.put(A_CmsMappingDialog.PARAM_FIELD, new String[] {m_paramField}); 218 params.put(A_CmsMappingDialog.PARAM_FIELDCONFIGURATION, new String[] {m_paramFieldconfiguration}); 219 params.put(A_CmsMappingDialog.PARAM_TYPE, new String[] {item.get(LIST_COLUMN_TYPE).toString()}); 220 params.put(A_CmsMappingDialog.PARAM_PARAM, new String[] {item.get(LIST_COLUMN_VALUE).toString()}); 221 222 params.put(PARAM_ACTION, new String[] {DIALOG_INITIAL}); 223 params.put(PARAM_STYLE, new String[] {CmsToolDialog.STYLE_NEW}); 224 225 if (action.equals(LIST_ACTION_EDIT) 226 || action.equals(LIST_ACTION_EDITTYPE) 227 || action.equals(LIST_ACTION_EDITVALUE)) { 228 // forward to the edit mapping screen 229 getToolManager().jspForwardTool( 230 this, 231 "/searchindex/fieldconfigurations/fieldconfiguration/field/editmapping", 232 params); 233 } 234 listSave(); 235 } 236 237 /** 238 * Returns the request parameter "field".<p> 239 * 240 * @return the request parameter "field" 241 */ 242 public String getParamField() { 243 244 return m_paramField; 245 } 246 247 /** 248 * Returns the request parameter "fieldconfiguration".<p> 249 * 250 * @return the request parameter "fieldconfiguration" 251 */ 252 public String getParamFieldconfiguration() { 253 254 return m_paramFieldconfiguration; 255 } 256 257 /** 258 * Sets the request parameter "field". <p> 259 * 260 * Method intended for workplace-proprietary automatic filling of 261 * request parameter values to dialogs, not for manual invocation. <p> 262 * 263 * @param field the request parameter "field" to set 264 */ 265 public void setParamField(String field) { 266 267 m_paramField = field; 268 } 269 270 /** 271 * Sets the request parameter "fieldconfiguration". <p> 272 * 273 * Method intended for workplace-proprietary automatic filling of 274 * request parameter values to dialogs, not for manual invocation. <p> 275 * 276 * @param fieldconfiguration the request parameter "fieldconfiguration" to set 277 */ 278 public void setParamFieldconfiguration(String fieldconfiguration) { 279 280 m_paramFieldconfiguration = fieldconfiguration; 281 } 282 283 /** 284 * @see org.opencms.workplace.list.A_CmsListDialog#fillDetails(java.lang.String) 285 */ 286 @Override 287 protected void fillDetails(String detailId) { 288 289 // noop 290 } 291 292 /** 293 * @see org.opencms.workplace.list.A_CmsListDialog#getListItems() 294 */ 295 @Override 296 protected List<CmsListItem> getListItems() { 297 298 List<CmsListItem> result = new ArrayList<CmsListItem>(); 299 // get content 300 List<I_CmsSearchFieldMapping> mappings = getMappings(); 301 Iterator<I_CmsSearchFieldMapping> itMappings = mappings.iterator(); 302 CmsSearchFieldMapping mapping; 303 while (itMappings.hasNext()) { 304 mapping = (CmsSearchFieldMapping)itMappings.next(); 305 CmsListItem item = getList().newItem(mapping.getType().toString()); 306 String defaultValue = mapping.getDefaultValue(); 307 String param = mapping.getParam(); 308 if (defaultValue == null) { 309 defaultValue = "-"; 310 } 311 if (param == null) { 312 param = "-"; 313 } 314 item.set(LIST_COLUMN_VALUE, param); 315 item.set(LIST_COLUMN_TYPE, mapping.getType().toString()); 316 item.set(LIST_COLUMN_DEFAULT, defaultValue); 317 result.add(item); 318 } 319 return result; 320 } 321 322 /** 323 * @see org.opencms.workplace.list.A_CmsListDialog#setColumns(org.opencms.workplace.list.CmsListMetadata) 324 */ 325 @Override 326 protected void setColumns(CmsListMetadata metadata) { 327 328 // create dummy column for corporate design reasons 329 CmsListColumnDefinition dummyCol = new CmsListColumnDefinition(LIST_COLUMN_ICON); 330 dummyCol.setName(Messages.get().container(Messages.GUI_LIST_FIELD_COL_MAPPING_0)); 331 dummyCol.setHelpText(Messages.get().container(Messages.GUI_LIST_MAPPING_COL_EDIT_NAME_HELP_0)); 332 dummyCol.setWidth("20"); 333 dummyCol.setAlign(CmsListColumnAlignEnum.ALIGN_LEFT); 334 dummyCol.setSorteable(false); 335 // add dummy icon 336 CmsListDirectAction editAction = new CmsListDirectAction(LIST_ACTION_EDIT); 337 editAction.setName(Messages.get().container(Messages.GUI_LIST_MAPPING_COL_EDIT_NAME_0)); 338 editAction.setHelpText(Messages.get().container(Messages.GUI_LIST_MAPPING_COL_EDIT_NAME_HELP_0)); 339 editAction.setIconPath(LIST_ICON_MAPPING); 340 dummyCol.addDirectAction(editAction); 341 // add it to the list definition 342 metadata.addColumn(dummyCol); 343 344 // add column for value 345 CmsListColumnDefinition valueCol = new CmsListColumnDefinition(LIST_COLUMN_VALUE); 346 valueCol.setAlign(CmsListColumnAlignEnum.ALIGN_LEFT); 347 valueCol.setName(Messages.get().container(Messages.GUI_LIST_MAPPING_COL_VALUE_0)); 348 valueCol.setWidth("33%"); 349 valueCol.setSorteable(true); 350 CmsListDefaultAction editValueAction = new CmsListDefaultAction(LIST_ACTION_EDITVALUE); 351 editValueAction.setName(Messages.get().container(Messages.GUI_LIST_FIELD_COL_MAPPING_0)); 352 editValueAction.setHelpText(Messages.get().container(Messages.GUI_LIST_MAPPING_COL_EDIT_NAME_HELP_0)); 353 valueCol.addDefaultAction(editValueAction); 354 metadata.addColumn(valueCol); 355 356 // add column for type 357 CmsListColumnDefinition typeCol = new CmsListColumnDefinition(LIST_COLUMN_TYPE); 358 typeCol.setAlign(CmsListColumnAlignEnum.ALIGN_CENTER); 359 typeCol.setName(Messages.get().container(Messages.GUI_LIST_MAPPING_COL_TYPE_0)); 360 typeCol.setWidth("33%"); 361 CmsListDefaultAction editTypeAction = new CmsListDefaultAction(LIST_ACTION_EDITTYPE); 362 editTypeAction.setName(Messages.get().container(Messages.GUI_LIST_FIELD_COL_MAPPING_0)); 363 editTypeAction.setHelpText(Messages.get().container(Messages.GUI_LIST_MAPPING_COL_EDIT_NAME_HELP_0)); 364 typeCol.addDefaultAction(editTypeAction); 365 metadata.addColumn(typeCol); 366 367 // add column for default 368 CmsListColumnDefinition defaultCol = new CmsListColumnDefinition(LIST_COLUMN_DEFAULT); 369 defaultCol.setAlign(CmsListColumnAlignEnum.ALIGN_CENTER); 370 defaultCol.setName(Messages.get().container(Messages.GUI_LIST_MAPPING_COL_DEFAULT_0)); 371 defaultCol.setWidth("33%"); 372 metadata.addColumn(defaultCol); 373 } 374 375 /** 376 * @see org.opencms.workplace.list.A_CmsListDialog#setIndependentActions(org.opencms.workplace.list.CmsListMetadata) 377 */ 378 @Override 379 protected void setIndependentActions(CmsListMetadata metadata) { 380 381 // empty 382 } 383 384 /** 385 * @see org.opencms.workplace.list.A_CmsListDialog#setMultiActions(org.opencms.workplace.list.CmsListMetadata) 386 */ 387 @Override 388 protected void setMultiActions(CmsListMetadata metadata) { 389 390 // add add multi action 391 CmsListMultiAction deleteMultiAction = new CmsListMultiAction(LIST_MACTION_DELETEMAPPING); 392 deleteMultiAction.setName(Messages.get().container(Messages.GUI_LIST_FIELD_MACTION_DELETEMAPPING_NAME_0)); 393 deleteMultiAction.setHelpText( 394 Messages.get().container(Messages.GUI_LIST_FIELD_MACTION_DELETEMAPPING_NAME_HELP_0)); 395 deleteMultiAction.setConfirmationMessage( 396 Messages.get().container(Messages.GUI_LIST_FIELD_MACTION_DELETEMAPPING_CONF_0)); 397 deleteMultiAction.setIconPath(ICON_MULTI_DELETE); 398 metadata.addMultiAction(deleteMultiAction); 399 } 400 401 /** 402 * Writes the updated search configuration back to the XML 403 * configuration file and refreshes the complete list.<p> 404 * 405 * @param refresh if true, the list items are refreshed 406 */ 407 protected void writeConfiguration(boolean refresh) { 408 409 // update the XML configuration 410 OpenCms.writeConfiguration(CmsSearchConfiguration.class); 411 if (refresh) { 412 refreshList(); 413 } 414 } 415 416 /** 417 * Returns the configured mappings of the current field. 418 * 419 * @return the configured mappings of the current field 420 */ 421 private List<I_CmsSearchFieldMapping> getMappings() { 422 423 CmsSearchManager manager = OpenCms.getSearchManager(); 424 I_CmsSearchFieldConfiguration fieldConfig = manager.getFieldConfiguration(getParamFieldconfiguration()); 425 CmsLuceneField field; 426 List<I_CmsSearchFieldMapping> result = null; 427 Iterator<CmsSearchField> itFields; 428 if (fieldConfig != null) { 429 itFields = fieldConfig.getFields().iterator(); 430 while (itFields.hasNext()) { 431 field = (CmsLuceneField)itFields.next(); 432 if (field.getName().equals(getParamField())) { 433 result = field.getMappings(); 434 } 435 } 436 } else { 437 result = Collections.emptyList(); 438 if (LOG.isErrorEnabled()) { 439 LOG.error( 440 Messages.get().getBundle().key( 441 Messages.ERR_SEARCHINDEX_EDIT_MISSING_PARAM_1, 442 A_CmsFieldConfigurationDialog.PARAM_FIELDCONFIGURATION)); 443 } 444 } 445 return result; 446 } 447}