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.CmsRuntimeException; 035import org.opencms.main.OpenCms; 036import org.opencms.search.CmsSearchManager; 037import org.opencms.search.fields.CmsLuceneField; 038import org.opencms.search.fields.CmsSearchField; 039import org.opencms.search.fields.CmsSearchFieldConfiguration; 040import org.opencms.search.fields.CmsSearchFieldMapping; 041import org.opencms.search.fields.I_CmsSearchFieldConfiguration; 042import org.opencms.search.fields.I_CmsSearchFieldMapping; 043import org.opencms.util.CmsStringUtil; 044import org.opencms.workplace.list.A_CmsListDialog; 045import org.opencms.workplace.list.CmsListColumnAlignEnum; 046import org.opencms.workplace.list.CmsListColumnDefinition; 047import org.opencms.workplace.list.CmsListDefaultAction; 048import org.opencms.workplace.list.CmsListDirectAction; 049import org.opencms.workplace.list.CmsListItem; 050import org.opencms.workplace.list.CmsListItemDetails; 051import org.opencms.workplace.list.CmsListItemDetailsFormatter; 052import org.opencms.workplace.list.CmsListMetadata; 053import org.opencms.workplace.list.CmsListMultiAction; 054import org.opencms.workplace.list.CmsListOrderEnum; 055import org.opencms.workplace.tools.CmsToolDialog; 056 057import java.io.IOException; 058import java.util.ArrayList; 059import java.util.HashMap; 060import java.util.Iterator; 061import java.util.LinkedList; 062import java.util.List; 063import java.util.Map; 064 065import javax.servlet.ServletException; 066import javax.servlet.http.HttpServletRequest; 067import javax.servlet.http.HttpServletResponse; 068import javax.servlet.jsp.PageContext; 069 070import org.apache.commons.logging.Log; 071 072/** 073 * A list that displays information about the <code>{@link org.opencms.search.fields.CmsLuceneFieldConfiguration}</code> 074 * that are members of the <code>{@link org.opencms.search.CmsSearchIndex}</code> 075 * in the current request scope (param "searchindex").<p> 076 * 077 * This list is stand-alone displayable (not to embed in another dialog) and 078 * offers single actions within the rows related to the current selected field configuration 079 * which has to be found by the <b>request parameter <code></code></b>. 080 * 081 * @since 6.5.5 082 */ 083public class CmsSearchFieldConfigurationList extends A_CmsListDialog { 084 085 /** list action id constant. */ 086 public static final String LIST_ACTION_DELETE = "ade"; 087 088 /** list action id constant. */ 089 public static final String LIST_ACTION_EDIT = "ae"; 090 091 /** list action id constant. */ 092 public static final String LIST_ACTION_FIELD = "af"; 093 094 /** list action id constant. */ 095 public static final String LIST_ACTION_OVERVIEW_FIELDCONFIGURATION = "aofc"; 096 097 /** list column id constant. */ 098 public static final String LIST_COLUMN_DELETE = "cde"; 099 100 /** list column id constant. */ 101 public static final String LIST_COLUMN_DESCRIPTION = "cd"; 102 103 /** list column id constant. */ 104 public static final String LIST_COLUMN_EDIT = "ce"; 105 106 /** list column id constant. */ 107 public static final String LIST_COLUMN_FIELD = "cf"; 108 109 /** list column id constant. */ 110 public static final String LIST_COLUMN_NAME = "cn"; 111 112 /** list item detail id constant. */ 113 public static final String LIST_DETAIL_FIELDCONFIGURATION = "df"; 114 115 /** list id constant. */ 116 public static final String LIST_ID = "lsfc"; 117 118 /** list action id constant. */ 119 public static final String LIST_MACTION_DELETECONFIGURATION = "mad"; 120 121 /** The path to the fieldconfiguration list icon. */ 122 protected static final String LIST_ICON_FIELDCONFIGURATION_EDIT = "tools/searchindex/icons/small/fieldconfiguration-edit.png"; 123 124 /** The log object for this class. */ 125 private static final Log LOG = CmsLog.getLog(CmsSearchFieldConfigurationList.class); 126 127 /** 128 * Public constructor.<p> 129 * 130 * @param jsp an initialized JSP action element 131 */ 132 public CmsSearchFieldConfigurationList(CmsJspActionElement jsp) { 133 134 this(jsp, LIST_ID, Messages.get().container(Messages.GUI_LIST_FIELDCONFIGURATIONS_NAME_0)); 135 } 136 137 /** 138 * Public constructor.<p> 139 * 140 * @param jsp an initialized JSP action element 141 * @param listId the id of the list 142 * @param listName the list name 143 */ 144 public CmsSearchFieldConfigurationList(CmsJspActionElement jsp, String listId, CmsMessageContainer listName) { 145 146 this(jsp, listId, listName, LIST_COLUMN_NAME, CmsListOrderEnum.ORDER_ASCENDING, null); 147 } 148 149 /** 150 * Public constructor.<p> 151 * 152 * @param jsp an initialized JSP action element 153 * @param listId the id of the displayed list 154 * @param listName the name of the list 155 * @param sortedColId the a priory sorted column 156 * @param sortOrder the order of the sorted column 157 * @param searchableColId the column to search into 158 */ 159 public CmsSearchFieldConfigurationList( 160 CmsJspActionElement jsp, 161 String listId, 162 CmsMessageContainer listName, 163 String sortedColId, 164 CmsListOrderEnum sortOrder, 165 String searchableColId) { 166 167 super(jsp, listId, listName, sortedColId, sortOrder, searchableColId); 168 169 } 170 171 /** 172 * Public constructor.<p> 173 * 174 * Public constructor with JSP variables.<p> 175 * 176 * @param context the JSP page context 177 * @param req the JSP request 178 * @param res the JSP response 179 */ 180 public CmsSearchFieldConfigurationList(PageContext context, HttpServletRequest req, HttpServletResponse res) { 181 182 this(new CmsJspActionElement(context, req, res)); 183 } 184 185 /** 186 * @see org.opencms.workplace.list.A_CmsListDialog#executeListMultiActions() 187 */ 188 @Override 189 public void executeListMultiActions() { 190 191 CmsSearchManager searchManager = OpenCms.getSearchManager(); 192 if (getParamListAction().equals(LIST_MACTION_DELETECONFIGURATION)) { 193 // execute the delete multiaction 194 Iterator<CmsListItem> itItems = getSelectedItems().iterator(); 195 CmsListItem listItem; 196 I_CmsSearchFieldConfiguration fieldconfig; 197 while (itItems.hasNext()) { 198 listItem = itItems.next(); 199 fieldconfig = searchManager.getFieldConfiguration((String)listItem.get(LIST_COLUMN_NAME)); 200 searchManager.removeSearchFieldConfiguration(fieldconfig); 201 } 202 refreshList(); 203 writeConfiguration(false); 204 } 205 listSave(); 206 } 207 208 /** 209 * @see org.opencms.workplace.list.A_CmsListDialog#executeListSingleActions() 210 */ 211 @Override 212 public void executeListSingleActions() throws IOException, ServletException, CmsRuntimeException { 213 214 String fieldConfiguration = getSelectedItem().getId(); 215 Map<String, String[]> params = new HashMap<String, String[]>(); 216 String action = getParamListAction(); 217 218 params.put(A_CmsFieldConfigurationDialog.PARAM_FIELDCONFIGURATION, new String[] {fieldConfiguration}); 219 params.put(PARAM_ACTION, new String[] {DIALOG_INITIAL}); 220 params.put(PARAM_STYLE, new String[] {CmsToolDialog.STYLE_NEW}); 221 if (action.equals(LIST_ACTION_EDIT)) { 222 // forward to the edit indexsource screen 223 getToolManager().jspForwardTool(this, "/searchindex/fieldconfigurations/fieldconfiguration/edit", params); 224 } else if (action.equals(LIST_ACTION_FIELD)) { 225 // forward to the new field screen 226 getToolManager().jspForwardTool( 227 this, 228 "/searchindex/fieldconfigurations/fieldconfiguration/newfield", 229 params); 230 } else if (action.equals(LIST_ACTION_DELETE)) { 231 // forward to the delete field configuration screen 232 getToolManager().jspForwardTool(this, "/searchindex/fieldconfigurations/fieldconfiguration/delete", params); 233 } else if (action.equals(LIST_ACTION_OVERVIEW_FIELDCONFIGURATION)) { 234 // forward to the field configuration overview screen 235 getToolManager().jspForwardTool(this, "/searchindex/fieldconfigurations/fieldconfiguration", params); 236 } 237 listSave(); 238 } 239 240 /** 241 * @see org.opencms.workplace.list.A_CmsListDialog#fillDetails(java.lang.String) 242 */ 243 @Override 244 protected void fillDetails(String detailId) { 245 246 // get content 247 List<CmsListItem> items = getList().getAllContent(); 248 Iterator<CmsListItem> itItems = items.iterator(); 249 CmsListItem item; 250 while (itItems.hasNext()) { 251 item = itItems.next(); 252 if (detailId.equals(LIST_DETAIL_FIELDCONFIGURATION)) { 253 fillDetailFieldConfiguration(item, detailId); 254 } 255 } 256 } 257 258 /** 259 * @see org.opencms.workplace.list.A_CmsListDialog#getListItems() 260 */ 261 @Override 262 protected List<CmsListItem> getListItems() { 263 264 List<CmsListItem> result = new ArrayList<CmsListItem>(); 265 CmsSearchManager manager = OpenCms.getSearchManager(); 266 267 // get content 268 List<CmsSearchFieldConfiguration> configs = new LinkedList<CmsSearchFieldConfiguration>( 269 manager.getFieldConfigurationsLucene()); 270 Iterator<CmsSearchFieldConfiguration> itConfigs = configs.iterator(); 271 CmsSearchFieldConfiguration config; 272 while (itConfigs.hasNext()) { 273 try { 274 config = itConfigs.next(); 275 CmsListItem item = getList().newItem(config.getName()); 276 item.set(LIST_COLUMN_NAME, config.getName()); 277 item.set(LIST_COLUMN_DESCRIPTION, config.getDescription()); 278 result.add(item); 279 } catch (Throwable g) { 280 CmsMessageContainer msg = Messages.get().container( 281 Messages.LOG_ERR_LIST_ITEM_SKIPPED_2, 282 getList().getName().key(getLocale()), 283 "Name"); 284 if (LOG.isWarnEnabled()) { 285 LOG.warn(msg.key(getLocale())); 286 } 287 } 288 } 289 return result; 290 } 291 292 /** 293 * @see org.opencms.workplace.list.A_CmsListDialog#setColumns(org.opencms.workplace.list.CmsListMetadata) 294 */ 295 @Override 296 protected void setColumns(CmsListMetadata metadata) { 297 298 // create column for edit 299 CmsListColumnDefinition editCol = new CmsListColumnDefinition(LIST_COLUMN_EDIT); 300 editCol.setName(Messages.get().container(Messages.GUI_LIST_FIELDCONFIGURATION_COL_EDIT_NAME_0)); 301 editCol.setHelpText(Messages.get().container(Messages.GUI_LIST_FIELDCONFIGURATION_COL_EDIT_NAME_HELP_0)); 302 editCol.setWidth("5"); 303 editCol.setAlign(CmsListColumnAlignEnum.ALIGN_LEFT); 304 editCol.setSorteable(false); 305 // add dummy icon 306 CmsListDirectAction editAction = new CmsListDirectAction(LIST_ACTION_EDIT); 307 editAction.setName(Messages.get().container(Messages.GUI_LIST_FIELDCONFIGURATION_ACTION_EDIT_NAME_0)); 308 editAction.setHelpText(Messages.get().container(Messages.GUI_LIST_FIELDCONFIGURATION_COL_EDIT_NAME_HELP_0)); 309 editAction.setIconPath(LIST_ICON_FIELDCONFIGURATION_EDIT); 310 editCol.addDirectAction(editAction); 311 // add it to the list definition 312 metadata.addColumn(editCol); 313 314 // create column for new field 315 CmsListColumnDefinition fieldCol = new CmsListColumnDefinition(LIST_COLUMN_FIELD); 316 fieldCol.setName(Messages.get().container(Messages.GUI_LIST_FIELDCONFIGURATION_COL_FIELD_NAME_0)); 317 fieldCol.setHelpText(Messages.get().container(Messages.GUI_LIST_FIELDCONFIGURATION_COL_FIELD_NAME_HELP_0)); 318 fieldCol.setWidth("5"); 319 fieldCol.setAlign(CmsListColumnAlignEnum.ALIGN_LEFT); 320 fieldCol.setSorteable(false); 321 // add dummy icon 322 CmsListDirectAction fieldAction = new CmsListDirectAction(LIST_ACTION_FIELD); 323 fieldAction.setName(Messages.get().container(Messages.GUI_LIST_FIELDCONFIGURATION_ACTION_FIELD_NAME_0)); 324 fieldAction.setHelpText(Messages.get().container(Messages.GUI_LIST_FIELDCONFIGURATION_COL_FIELD_NAME_HELP_0)); 325 fieldAction.setIconPath(ICON_ADD); 326 fieldCol.addDirectAction(fieldAction); 327 // add it to the list definition 328 metadata.addColumn(fieldCol); 329 330 // create column for deletion 331 CmsListColumnDefinition deleteCol = new CmsListColumnDefinition(LIST_COLUMN_DELETE); 332 deleteCol.setName(Messages.get().container(Messages.GUI_LIST_FIELDCONFIGURATION_COL_DELETE_NAME_0)); 333 deleteCol.setHelpText(Messages.get().container(Messages.GUI_GROUPS_FIELDCONFIGURATION_TOOL_DELETE_HELP_0)); 334 deleteCol.setWidth("10"); 335 deleteCol.setAlign(CmsListColumnAlignEnum.ALIGN_LEFT); 336 deleteCol.setSorteable(false); 337 // add delete action 338 CmsListDirectAction deleteAction = new CmsListDirectAction(LIST_ACTION_DELETE); 339 deleteAction.setName(Messages.get().container(Messages.GUI_LIST_FIELDCONFIGURATION_ACTION_DELETE_NAME_0)); 340 deleteAction.setHelpText(Messages.get().container(Messages.GUI_GROUPS_FIELDCONFIGURATION_TOOL_DELETE_HELP_0)); 341 deleteAction.setIconPath(ICON_DELETE); 342 deleteCol.addDirectAction(deleteAction); 343 // add it to the list definition 344 metadata.addColumn(deleteCol); 345 346 // add column for name 347 CmsListColumnDefinition nameCol = new CmsListColumnDefinition(LIST_COLUMN_NAME); 348 nameCol.setAlign(CmsListColumnAlignEnum.ALIGN_LEFT); 349 nameCol.setName(Messages.get().container(Messages.GUI_LIST_SEARCHINDEX_COL_NAME_0)); 350 nameCol.setWidth("50%"); 351 // add overview action 352 CmsListDefaultAction defEditAction = new CmsListDefaultAction(LIST_ACTION_OVERVIEW_FIELDCONFIGURATION); 353 defEditAction.setName(Messages.get().container(Messages.GUI_LIST_FIELDCONFIGURATION_COL_OVERVIEW_NAME_0)); 354 defEditAction.setHelpText( 355 Messages.get().container(Messages.GUI_LIST_FIELDCONFIGURATION_COL_OVERVIEW_NAME_HELP_0)); 356 nameCol.addDefaultAction(defEditAction); 357 metadata.addColumn(nameCol); 358 359 // add column for description 360 CmsListColumnDefinition descriptionCol = new CmsListColumnDefinition(LIST_COLUMN_DESCRIPTION); 361 descriptionCol.setAlign(CmsListColumnAlignEnum.ALIGN_LEFT); 362 descriptionCol.setName(Messages.get().container(Messages.GUI_LIST_FIELDCONFIGURATION_COL_DESCRIPTION_0)); 363 descriptionCol.setWidth("50%"); 364 metadata.addColumn(descriptionCol); 365 } 366 367 /** 368 * @see org.opencms.workplace.list.A_CmsListDialog#setIndependentActions(org.opencms.workplace.list.CmsListMetadata) 369 */ 370 @Override 371 protected void setIndependentActions(CmsListMetadata metadata) { 372 373 // add field configuration details 374 CmsListItemDetails configDetails = new CmsListItemDetails(LIST_DETAIL_FIELDCONFIGURATION); 375 configDetails.setAtColumn(LIST_COLUMN_NAME); 376 configDetails.setVisible(false); 377 configDetails.setShowActionName( 378 Messages.get().container(Messages.GUI_LIST_FIELDCONFIGURATION_DETAIL_FIELDS_SHOW_0)); 379 configDetails.setShowActionHelpText( 380 Messages.get().container(Messages.GUI_LIST_FIELDCONFIGURATION_DETAIL_FIELDS_SHOW_HELP_0)); 381 configDetails.setHideActionName( 382 Messages.get().container(Messages.GUI_LIST_FIELDCONFIGURATION_DETAIL_FIELDS_HIDE_0)); 383 configDetails.setHideActionHelpText( 384 Messages.get().container(Messages.GUI_LIST_FIELDCONFIGURATION_DETAIL_FIELDS_HIDE_HELP_0)); 385 configDetails.setName(Messages.get().container(Messages.GUI_LIST_FIELDCONFIGURATION_DETAIL_FIELDS_NAME_0)); 386 configDetails.setFormatter( 387 new CmsListItemDetailsFormatter( 388 Messages.get().container(Messages.GUI_LIST_FIELDCONFIGURATION_DETAIL_FIELDS_NAME_0))); 389 metadata.addItemDetails(configDetails); 390 } 391 392 /** 393 * @see org.opencms.workplace.list.A_CmsListDialog#setMultiActions(org.opencms.workplace.list.CmsListMetadata) 394 */ 395 @Override 396 protected void setMultiActions(CmsListMetadata metadata) { 397 398 // add add multi action 399 CmsListMultiAction deleteMultiAction = new CmsListMultiAction(LIST_MACTION_DELETECONFIGURATION); 400 deleteMultiAction.setName( 401 Messages.get().container(Messages.GUI_LIST_FIELDCONFIGURATION_MACTION_DELETECONFIGURATION_NAME_0)); 402 deleteMultiAction.setHelpText( 403 Messages.get().container(Messages.GUI_LIST_FIELDCONFIGURATION_MACTION_DELETECONFIGURATION_NAME_HELP_0)); 404 deleteMultiAction.setConfirmationMessage( 405 Messages.get().container(Messages.GUI_LIST_FIELDCONFIGURATION_MACTION_DELETECONFIGURATION_CONF_0)); 406 deleteMultiAction.setIconPath(ICON_MULTI_DELETE); 407 metadata.addMultiAction(deleteMultiAction); 408 } 409 410 /** 411 * Writes the updated search configuration back to the XML 412 * configuration file and refreshes the complete list.<p> 413 * 414 * @param refresh if true, the list items are refreshed 415 */ 416 protected void writeConfiguration(boolean refresh) { 417 418 // update the XML configuration 419 OpenCms.writeConfiguration(CmsSearchConfiguration.class); 420 if (refresh) { 421 refreshList(); 422 } 423 } 424 425 /** 426 * Fills details of the field configuration into the given item. <p> 427 * 428 * @param item the list item to fill 429 * @param detailId the id for the detail to fill 430 */ 431 private void fillDetailFieldConfiguration(CmsListItem item, String detailId) { 432 433 StringBuffer html = new StringBuffer(); 434 // search for the corresponding A_CmsSearchIndex: 435 String idxConfigName = (String)item.get(LIST_COLUMN_NAME); 436 437 I_CmsSearchFieldConfiguration idxFieldConfiguration = OpenCms.getSearchManager().getFieldConfiguration( 438 idxConfigName); 439 List<CmsSearchField> fields = idxFieldConfiguration.getFields(); 440 441 html.append("<ul>\n"); 442 Iterator<CmsSearchField> itFields = fields.iterator(); 443 while (itFields.hasNext()) { 444 CmsLuceneField field = (CmsLuceneField)itFields.next(); 445 String fieldName = field.getName(); 446 boolean fieldStore = field.isStored(); 447 String fieldIndex = field.getIndexed(); 448 boolean fieldExcerpt = field.isInExcerpt(); 449 String fieldDefault = field.getDefaultValue(); 450 451 html.append(" <li>\n").append(" "); 452 html.append("name=").append(fieldName); 453 if (fieldStore) { 454 html.append(", ").append("store=").append(fieldStore); 455 } 456 if (!fieldIndex.equals("false")) { 457 html.append(", ").append("index=").append(fieldIndex); 458 } 459 if (fieldExcerpt) { 460 html.append(", ").append("excerpt=").append(fieldExcerpt); 461 } 462 if (fieldDefault != null) { 463 html.append(", ").append("default=").append(field.getDefaultValue()); 464 } 465 html.append("\n").append(" <ul>\n"); 466 467 Iterator<I_CmsSearchFieldMapping> itMappings = field.getMappings().iterator(); 468 while (itMappings.hasNext()) { 469 CmsSearchFieldMapping mapping = (CmsSearchFieldMapping)itMappings.next(); 470 html.append(" <li>\n").append(" "); 471 html.append(mapping.getType().toString()); 472 if (CmsStringUtil.isNotEmpty(mapping.getParam())) { 473 html.append("=").append(mapping.getParam()).append("\n"); 474 } 475 html.append(" </li>"); 476 } 477 html.append(" </ul>\n"); 478 html.append(" </li>"); 479 } 480 html.append("</ul>\n"); 481 item.set(detailId, html.toString()); 482 } 483}