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.CmsIllegalStateException; 034import org.opencms.main.CmsLog; 035import org.opencms.main.OpenCms; 036import org.opencms.search.CmsSearchDocumentType; 037import org.opencms.search.CmsSearchException; 038import org.opencms.search.CmsSearchIndexSource; 039import org.opencms.search.CmsSearchManager; 040import org.opencms.search.I_CmsSearchIndex; 041import org.opencms.workplace.CmsWorkplaceSettings; 042import org.opencms.workplace.list.CmsListColumnAlignEnum; 043import org.opencms.workplace.list.CmsListColumnDefinition; 044import org.opencms.workplace.list.CmsListDefaultAction; 045import org.opencms.workplace.list.CmsListDirectAction; 046import org.opencms.workplace.list.CmsListItem; 047import org.opencms.workplace.list.CmsListItemDetails; 048import org.opencms.workplace.list.CmsListItemDetailsFormatter; 049import org.opencms.workplace.list.CmsListMetadata; 050import org.opencms.workplace.list.CmsListMultiAction; 051import org.opencms.workplace.list.CmsListOrderEnum; 052import org.opencms.workplace.tools.CmsToolDialog; 053 054import java.io.IOException; 055import java.util.ArrayList; 056import java.util.HashMap; 057import java.util.Iterator; 058import java.util.LinkedList; 059import java.util.List; 060import java.util.Map; 061 062import javax.servlet.ServletException; 063import javax.servlet.http.HttpServletRequest; 064import javax.servlet.http.HttpServletResponse; 065import javax.servlet.jsp.PageContext; 066 067import org.apache.commons.logging.Log; 068 069/** 070 * A list that displays the <code>{@link org.opencms.search.CmsSearchIndexSource}</code> 071 * instances that are not members of the <code>{@link org.opencms.search.CmsSearchIndex}</code> 072 * in the current request scope (param "searchindex" and allows to add them to the index.<p> 073 * 074 * This list is no stand-alone page but has to be embedded in another dialog 075 * (see <code> {@link org.opencms.workplace.tools.searchindex.A_CmsEmbeddedListDialog}</code>. <p> 076 * 077 * @since 6.0.0 078 */ 079public class CmsSearchIndexSourceAddList extends A_CmsEmbeddedListDialog { 080 081 /** list action dummy id constant. */ 082 public static final String LIST_ACTION_ADDSOURCE = "a"; 083 084 /** list action dummy id constant. */ 085 public static final String LIST_ACTION_NONE = "n"; 086 087 /** list column id constant. */ 088 public static final String LIST_COLUMN_ADDSOURCE = "cas"; 089 090 /** list column id constant. */ 091 public static final String LIST_COLUMN_ADDSOURCE2 = LIST_COLUMN_ADDSOURCE + "2"; 092 093 /** list column id constant. */ 094 public static final String LIST_COLUMN_ICON = "ci"; 095 096 /** list column id constant. */ 097 public static final String LIST_COLUMN_INDEXER = "ca"; 098 099 /** list column id constant. */ 100 public static final String LIST_COLUMN_NAME = "cn"; 101 102 /** list item detail id constant. */ 103 public static final String LIST_DETAIL_DOCTYPES = "dd"; 104 105 /** list item detail id constant. */ 106 public static final String LIST_DETAIL_RESOURCES = "dr"; 107 108 /** list id constant. */ 109 public static final String LIST_ID = "lssisa"; 110 111 /** list action id constant. */ 112 public static final String LIST_MACTION_ADDSOURCE = "maa"; 113 114 /** The log object for this class. */ 115 private static final Log LOG = CmsLog.getLog(CmsSearchIndexSourceAddList.class); 116 117 /** Stores the value of the request parameter for the search index Name. */ 118 private String m_paramIndexName; 119 120 /** 121 * Public constructor.<p> 122 * 123 * @param jsp an initialized JSP action element 124 */ 125 public CmsSearchIndexSourceAddList(CmsJspActionElement jsp) { 126 127 this(jsp, LIST_ID, Messages.get().container(Messages.GUI_LIST_INDEXSOURCES_AVAIL_NAME_0)); 128 } 129 130 /** 131 * Public constructor.<p> 132 * 133 * @param jsp an initialized JSP action element 134 * @param listId the id of the list 135 * @param listName the list name 136 */ 137 public CmsSearchIndexSourceAddList(CmsJspActionElement jsp, String listId, CmsMessageContainer listName) { 138 139 this(jsp, listId, listName, LIST_COLUMN_NAME, CmsListOrderEnum.ORDER_ASCENDING, null); 140 } 141 142 /** 143 * Public constructor.<p> 144 * 145 * @param jsp an initialized JSP action element 146 * @param listId the id of the displayed list 147 * @param listName the name of the list 148 * @param sortedColId the a priory sorted column 149 * @param sortOrder the order of the sorted column 150 * @param searchableColId the column to search into 151 */ 152 public CmsSearchIndexSourceAddList( 153 CmsJspActionElement jsp, 154 String listId, 155 CmsMessageContainer listName, 156 String sortedColId, 157 CmsListOrderEnum sortOrder, 158 String searchableColId) { 159 160 super(jsp, listId, listName, sortedColId, sortOrder, searchableColId); 161 162 } 163 164 /** 165 * Public constructor.<p> 166 * 167 * Public constructor with JSP variables.<p> 168 * 169 * @param context the JSP page context 170 * @param req the JSP request 171 * @param res the JSP response 172 */ 173 public CmsSearchIndexSourceAddList(PageContext context, HttpServletRequest req, HttpServletResponse res) { 174 175 this(new CmsJspActionElement(context, req, res)); 176 } 177 178 /** 179 * @see org.opencms.workplace.list.A_CmsListDialog#executeListMultiActions() 180 */ 181 @Override 182 public void executeListMultiActions() { 183 184 CmsSearchManager searchManager = OpenCms.getSearchManager(); 185 CmsListItem item = getSelectedItem(); 186 if (getParamListAction().equals(LIST_MACTION_ADDSOURCE)) { 187 // execute the delete multiaction 188 Iterator<CmsListItem> itItems = getSelectedItems().iterator(); 189 String indexSource; 190 I_CmsSearchIndex idx = searchManager.getIndex(getParamIndexName()); 191 while (itItems.hasNext()) { 192 item = itItems.next(); 193 indexSource = (String)item.get(LIST_COLUMN_NAME); 194 idx.addSourceName(indexSource); 195 } 196 try { 197 idx.initialize(); 198 } catch (CmsSearchException e) { 199 if (LOG.isErrorEnabled()) { 200 LOG.error(e.getLocalizedMessage(), e); 201 } 202 } 203 writeConfiguration(false); 204 refreshList(); 205 } 206 207 listSave(); 208 } 209 210 /** 211 * @see org.opencms.workplace.list.A_CmsListDialog#executeListSingleActions() 212 */ 213 @Override 214 public void executeListSingleActions() throws IOException, ServletException { 215 216 CmsSearchManager searchManager = OpenCms.getSearchManager(); 217 CmsListItem item = getSelectedItem(); 218 String indexsourceName = (String)item.get(LIST_COLUMN_NAME); 219 String action = getParamListAction(); 220 if (action.equals(LIST_ACTION_ADDSOURCE) || action.equals(LIST_COLUMN_ADDSOURCE2)) { 221 222 I_CmsSearchIndex idx = searchManager.getIndex(getParamIndexName()); 223 idx.addSourceName(indexsourceName); 224 try { 225 idx.initialize(); 226 } catch (CmsSearchException e) { 227 if (LOG.isErrorEnabled()) { 228 LOG.error(e.getLocalizedMessage(), e); 229 } 230 } 231 refreshList(); 232 writeConfiguration(false); 233 } else if (action.equals(CmsSearchIndexSourceControlList.LIST_ACTION_OVERVIEW_INDEXSOURCE)) { 234 235 // action currently unused (not triggered by a column any more) 236 Map<String, String[]> params = new HashMap<String, String[]>(); 237 // forward to the edit indexsource screen 238 params.put(A_CmsEditIndexSourceDialog.PARAM_INDEXSOURCE, new String[] {indexsourceName}); 239 params.put(PARAM_STYLE, new String[] {CmsToolDialog.STYLE_NEW}); 240 getToolManager().jspForwardTool(this, "/searchindex/indexsources/indexsource", params); 241 242 } 243 } 244 245 /** 246 * Returns the request parameter mapped to member <code>m_searchindex</code> 247 * or null if no one was received. <p> 248 * 249 * @return the request parameter mapped to member <code>m_searchindex</code> 250 * or null if no one was received 251 */ 252 public String getParamIndexName() { 253 254 return m_paramIndexName; 255 } 256 257 /** 258 * Maps the request parameter to member <code>m_searchindex</code>. <p> 259 * 260 * @param paramSearchIndex the request parameter <code>searchindex</code> 261 * that is filled using this method. 262 */ 263 public void setParamIndexName(String paramSearchIndex) { 264 265 m_paramIndexName = paramSearchIndex; 266 } 267 268 /** 269 * @see org.opencms.workplace.list.A_CmsListDialog#fillDetails(java.lang.String) 270 */ 271 @Override 272 protected void fillDetails(String detailId) { 273 274 // get content 275 List<CmsListItem> items = getList().getAllContent(); 276 if (detailId.equals(LIST_DETAIL_DOCTYPES)) { 277 for (CmsListItem item : items) { 278 fillDetailDocTypes(item, detailId); 279 280 } 281 } else if (detailId.equals(LIST_DETAIL_RESOURCES)) { 282 for (CmsListItem item : items) { 283 fillDetailResources(item, detailId); 284 285 } 286 } 287 } 288 289 /** 290 * @see org.opencms.workplace.list.A_CmsListDialog#getListItems() 291 */ 292 @Override 293 protected List<CmsListItem> getListItems() { 294 295 List<CmsListItem> result = new ArrayList<CmsListItem>(); 296 // get content 297 // cannot use the returned map: unmodifyable 298 List<CmsSearchIndexSource> allSources = new LinkedList<CmsSearchIndexSource>( 299 OpenCms.getSearchManager().getSearchIndexSources().values()); 300 allSources.removeAll(searchIndexSources()); 301 Iterator<CmsSearchIndexSource> itSources = allSources.iterator(); 302 CmsSearchIndexSource source; 303 while (itSources.hasNext()) { 304 source = itSources.next(); 305 CmsListItem item = getList().newItem(source.getName()); 306 item.set(LIST_COLUMN_NAME, source.getName()); 307 item.set(LIST_COLUMN_INDEXER, source.getIndexer().getClass().getName()); 308 result.add(item); 309 } 310 return result; 311 } 312 313 /** 314 * @see org.opencms.workplace.CmsWorkplace#initMessages() 315 */ 316 @Override 317 protected void initMessages() { 318 319 // add specific dialog resource bundle 320 addMessages(Messages.get().getBundleName()); 321 // add default resource bundles 322 super.initMessages(); 323 } 324 325 /** 326 * @see org.opencms.workplace.list.A_CmsListDialog#initWorkplaceRequestValues(org.opencms.workplace.CmsWorkplaceSettings, javax.servlet.http.HttpServletRequest) 327 */ 328 @Override 329 protected void initWorkplaceRequestValues(CmsWorkplaceSettings settings, HttpServletRequest request) { 330 331 super.initWorkplaceRequestValues(settings, request); 332 } 333 334 /** 335 * @see org.opencms.workplace.list.A_CmsListDialog#setColumns(org.opencms.workplace.list.CmsListMetadata) 336 */ 337 @Override 338 protected void setColumns(CmsListMetadata metadata) { 339 340 // create dummy column for icon 341 CmsListColumnDefinition editCol = new CmsListColumnDefinition(LIST_COLUMN_ICON); 342 editCol.setName(Messages.get().container(Messages.GUI_LIST_INDEXSOURCE_COL_ICON_NAME_0)); 343 editCol.setHelpText(Messages.get().container(Messages.GUI_LIST_INDEXSOURCE_COL_ICON_NAME_HELP_0)); 344 editCol.setWidth("5"); 345 editCol.setAlign(CmsListColumnAlignEnum.ALIGN_LEFT); 346 editCol.setSorteable(false); 347 // add dummy icon 348 CmsListDirectAction editAction = new CmsListDirectAction(LIST_ACTION_NONE); 349 editAction.setName(Messages.get().container(Messages.GUI_LIST_INDEXSOURCE_COL_ICON_NAME_0)); 350 editAction.setHelpText(Messages.get().container(Messages.GUI_LIST_INDEXSOURCE_COL_ICON_NAME_HELP_0)); 351 editAction.setIconPath(CmsSearchIndexList.LIST_ICON_INDEXSOURCE); 352 // disable! 353 editAction.setEnabled(false); 354 editCol.addDirectAction(editAction); 355 // add it to the list definition 356 metadata.addColumn(editCol); 357 358 // add column for add action 359 CmsListColumnDefinition addCol = new CmsListColumnDefinition(LIST_COLUMN_ADDSOURCE); 360 addCol.setName(Messages.get().container(Messages.GUI_LIST_INDEXSOURCE_COL_ADDSOURCE_NAME_0)); 361 addCol.setHelpText(Messages.get().container(Messages.GUI_LIST_INDEXSOURCE_COL_ADDSOURCE_NAME_HELP_0)); 362 addCol.setWidth("5"); 363 addCol.setAlign(CmsListColumnAlignEnum.ALIGN_LEFT); 364 addCol.setSorteable(false); 365 // add add action 366 CmsListDirectAction addAction = new CmsListDirectAction(LIST_ACTION_ADDSOURCE); 367 addAction.setName(Messages.get().container(Messages.GUI_LIST_INDEXSOURCE_COL_ADDSOURCE_NAME_0)); 368 addAction.setHelpText(Messages.get().container(Messages.GUI_LIST_SEARCHINDEX_ACTION_ADDSOURCE_NAME_0)); 369 addAction.setIconPath(ICON_ADD); 370 addCol.addDirectAction(addAction); 371 // add it to the list definition 372 metadata.addColumn(addCol); 373 374 // add column for name 375 CmsListColumnDefinition nameCol = new CmsListColumnDefinition(LIST_COLUMN_NAME); 376 nameCol.setAlign(CmsListColumnAlignEnum.ALIGN_LEFT); 377 nameCol.setName(Messages.get().container(Messages.GUI_LIST_SEARCHINDEX_COL_NAME_0)); 378 nameCol.setWidth("55%"); 379 // add second add action, see how action id has to be different.... 380 CmsListDefaultAction addAction2 = new CmsListDefaultAction(LIST_COLUMN_ADDSOURCE2); 381 addAction2.setName(Messages.get().container(Messages.GUI_LIST_INDEXSOURCE_COL_ADDSOURCE_NAME_0)); 382 addAction2.setHelpText(Messages.get().container(Messages.GUI_LIST_SEARCHINDEX_ACTION_ADDSOURCE_NAME_0)); 383 nameCol.addDefaultAction(addAction2); 384 metadata.addColumn(nameCol); 385 386 // add column for analyzer 387 CmsListColumnDefinition analyzerCol = new CmsListColumnDefinition(LIST_COLUMN_INDEXER); 388 analyzerCol.setAlign(CmsListColumnAlignEnum.ALIGN_LEFT); 389 analyzerCol.setName(Messages.get().container(Messages.GUI_LIST_INDEXSOURCE_COL_INDEXER_0)); 390 analyzerCol.setWidth("30%"); 391 metadata.addColumn(analyzerCol); 392 393 } 394 395 /** 396 * @see org.opencms.workplace.list.A_CmsListDialog#setIndependentActions(org.opencms.workplace.list.CmsListMetadata) 397 */ 398 @Override 399 protected void setIndependentActions(CmsListMetadata metadata) { 400 401 // add document types of index source detail help 402 CmsListItemDetails doctypeDetails = new CmsListItemDetails(LIST_DETAIL_DOCTYPES); 403 doctypeDetails.setAtColumn(LIST_COLUMN_NAME); 404 doctypeDetails.setVisible(false); 405 doctypeDetails.setShowActionName(Messages.get().container(Messages.GUI_LIST_INDEXSOURCE_DETAIL_DOCTYPE_NAME_0)); 406 doctypeDetails.setShowActionHelpText( 407 Messages.get().container(Messages.GUI_LIST_INDEXSOURCE_DETAIL_DOCTYPE_SHOW_HELP_0)); 408 doctypeDetails.setHideActionName(Messages.get().container(Messages.GUI_LIST_INDEXSOURCE_DETAIL_DOCTYPE_NAME_0)); 409 doctypeDetails.setHideActionHelpText( 410 Messages.get().container(Messages.GUI_LIST_INDEXSOURCE_DETAIL_DOCTYPE_HIDE_HELP_0)); 411 doctypeDetails.setName(Messages.get().container(Messages.GUI_LIST_INDEXSOURCE_DETAIL_DOCTYPE_NAME_0)); 412 doctypeDetails.setFormatter( 413 new CmsListItemDetailsFormatter( 414 Messages.get().container(Messages.GUI_LIST_INDEXSOURCE_DETAIL_DOCTYPE_NAME_0))); 415 metadata.addItemDetails(doctypeDetails); 416 417 // add resources of index source detail help 418 CmsListItemDetails resourceDetails = new CmsListItemDetails(LIST_DETAIL_RESOURCES); 419 resourceDetails.setAtColumn(LIST_COLUMN_NAME); 420 resourceDetails.setVisible(false); 421 resourceDetails.setShowActionName( 422 Messages.get().container(Messages.GUI_LIST_INDEXSOURCE_DETAIL_RESOURCE_NAME_0)); 423 resourceDetails.setShowActionHelpText( 424 Messages.get().container(Messages.GUI_LIST_INDEXSOURCE_DETAIL_RESOURCE_SHOW_HELP_0)); 425 resourceDetails.setHideActionName( 426 Messages.get().container(Messages.GUI_LIST_INDEXSOURCE_DETAIL_RESOURCE_NAME_0)); 427 resourceDetails.setHideActionHelpText( 428 Messages.get().container(Messages.GUI_LIST_INDEXSOURCE_DETAIL_RESOURCE_HIDE_HELP_0)); 429 resourceDetails.setName(Messages.get().container(Messages.GUI_LIST_INDEXSOURCE_DETAIL_RESOURCE_NAME_0)); 430 resourceDetails.setFormatter( 431 new CmsListItemDetailsFormatter( 432 Messages.get().container(Messages.GUI_LIST_INDEXSOURCE_DETAIL_RESOURCE_NAME_0))); 433 metadata.addItemDetails(resourceDetails); 434 435 } 436 437 /** 438 * @see org.opencms.workplace.list.A_CmsListDialog#setMultiActions(org.opencms.workplace.list.CmsListMetadata) 439 */ 440 @Override 441 protected void setMultiActions(CmsListMetadata metadata) { 442 443 // add add multi action 444 CmsListMultiAction addMultiAction = new CmsListMultiAction(LIST_MACTION_ADDSOURCE); 445 addMultiAction.setName(Messages.get().container(Messages.GUI_LIST_SEARCHINDEX_MACTION_ADDSOURCE_NAME_0)); 446 addMultiAction.setHelpText( 447 Messages.get().container(Messages.GUI_LIST_SEARCHINDEX_MACTION_ADDSOURCE_NAME_HELP_0)); 448 addMultiAction.setIconPath(ICON_MULTI_ADD); 449 metadata.addMultiAction(addMultiAction); 450 } 451 452 /** 453 * @see org.opencms.workplace.list.A_CmsListDialog#validateParamaters() 454 */ 455 @Override 456 protected void validateParamaters() throws Exception { 457 458 // test the needed parameters 459 if (getParamIndexName() == null) { 460 throw new CmsIllegalStateException( 461 Messages.get().container( 462 Messages.ERR_SEARCHINDEX_EDIT_MISSING_PARAM_1, 463 A_CmsEditSearchIndexDialog.PARAM_INDEXNAME)); 464 } 465 } 466 467 /** 468 * Writes the updated search configuration back to the XML 469 * configuration file and refreshes the complete list.<p> 470 * 471 * @param refresh if true, the list items are refreshed 472 */ 473 protected void writeConfiguration(boolean refresh) { 474 475 // update the XML configuration 476 OpenCms.writeConfiguration(CmsSearchConfiguration.class); 477 if (refresh) { 478 refreshList(); 479 } 480 } 481 482 /** 483 * Fills details about document types of the index source into the given item. <p> 484 * 485 * @param item the list item to fill 486 * @param detailId the id for the detail to fill 487 * 488 */ 489 private void fillDetailDocTypes(CmsListItem item, String detailId) { 490 491 CmsSearchManager searchManager = OpenCms.getSearchManager(); 492 StringBuffer html = new StringBuffer(); 493 494 // search for the corresponding CmsSearchIndexSource: 495 String idxSourceName = (String)item.get(LIST_COLUMN_NAME); 496 CmsSearchIndexSource idxSource = searchManager.getIndexSource(idxSourceName); 497 498 // get the index sources doc types 499 List<String> docTypes = idxSource.getDocumentTypes(); 500 // output of found index sources 501 Iterator<String> itDocTypes = docTypes.iterator(); 502 CmsSearchDocumentType docType; 503 html.append("<ul>\n"); 504 while (itDocTypes.hasNext()) { 505 // get the instance (instead of plain name) for more detail in future... 506 docType = searchManager.getDocumentTypeConfig(itDocTypes.next()); 507 // harden against unconfigured doctypes that are refferred to by indexsource nodes 508 if (docType != null) { 509 510 html.append(" <li>\n").append(" ").append(docType.getName()).append("\n"); 511 html.append(" </li>"); 512 } 513 } 514 515 html.append("</ul>\n"); 516 item.set(detailId, html.toString()); 517 } 518 519 /** 520 * Fills details about resource paths of the index source into the given item. <p> 521 * 522 * @param item the list item to fill 523 * @param detailId the id for the detail to fill 524 * 525 */ 526 private void fillDetailResources(CmsListItem item, String detailId) { 527 528 CmsSearchManager searchManager = OpenCms.getSearchManager(); 529 StringBuffer html = new StringBuffer(); 530 531 // search for the corresponding CmsSearchIndexSource: 532 String idxSourceName = (String)item.get(LIST_COLUMN_NAME); 533 CmsSearchIndexSource idxSource = searchManager.getIndexSource(idxSourceName); 534 535 // get the index sources resource strings 536 List<String> resources = idxSource.getResourcesNames(); 537 // output of found index sources 538 Iterator<String> itResources = resources.iterator(); 539 html.append("<ul>\n"); 540 while (itResources.hasNext()) { 541 542 html.append(" <li>\n").append(" ").append(itResources.next()).append("\n"); 543 html.append(" </li>"); 544 } 545 546 html.append("</ul>\n"); 547 548 item.set(detailId, html.toString()); 549 } 550 551 /** 552 * Returns the available search indexes of this installation. 553 * 554 * @return the available search indexes of this installation 555 */ 556 private List<CmsSearchIndexSource> searchIndexSources() { 557 558 CmsSearchManager manager = OpenCms.getSearchManager(); 559 I_CmsSearchIndex index = manager.getIndex(getParamIndexName()); 560 List<CmsSearchIndexSource> sources = index.getSources(); 561 return sources; 562 } 563 564}