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, 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.ui.apps.searchindex; 029 030import org.opencms.search.I_CmsSearchIndex; 031import org.opencms.ui.A_CmsUI; 032import org.opencms.ui.CmsCssIcon; 033import org.opencms.ui.CmsVaadinUtils; 034import org.opencms.ui.apps.Messages; 035import org.opencms.ui.components.CmsBasicDialog; 036import org.opencms.ui.components.CmsBasicDialog.DialogWidth; 037import org.opencms.ui.components.OpenCmsTheme; 038import org.opencms.ui.contextmenu.CmsContextMenu; 039import org.opencms.ui.contextmenu.CmsMenuItemVisibilityMode; 040import org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry; 041 042import java.util.ArrayList; 043import java.util.HashSet; 044import java.util.List; 045import java.util.Locale; 046import java.util.Set; 047 048import com.vaadin.event.MouseEvents; 049import com.vaadin.server.Resource; 050import com.vaadin.shared.MouseEventDetails.MouseButton; 051import com.vaadin.ui.Button; 052import com.vaadin.ui.Button.ClickEvent; 053import com.vaadin.ui.Button.ClickListener; 054import com.vaadin.ui.UI; 055import com.vaadin.ui.Window; 056import com.vaadin.ui.themes.ValoTheme; 057import com.vaadin.v7.data.Item; 058import com.vaadin.v7.data.util.IndexedContainer; 059import com.vaadin.v7.event.ItemClickEvent; 060import com.vaadin.v7.event.ItemClickEvent.ItemClickListener; 061import com.vaadin.v7.ui.Table; 062 063/** 064 * Class for the vaadin table to show the indexes.<p> 065 */ 066public class CmsSearchIndexTable extends Table { 067 068 /** 069 * The edit project context menu entry.<p> 070 */ 071 class EntryRebuild implements I_CmsSimpleContextMenuEntry<Set<String>> { 072 073 /** 074 * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#executeAction(java.lang.Object) 075 */ 076 public void executeAction(Set<String> data) { 077 078 final Window window = CmsBasicDialog.prepareWindow(DialogWidth.max); 079 CmsBasicDialog dialog = new CmsBasicDialog(); 080 081 dialog.setContent(new CmsSearchindexRebuild(m_manager, data)); 082 Button closeButton = new Button(CmsVaadinUtils.messageClose()); 083 closeButton.addClickListener(new ClickListener() { 084 085 private static final long serialVersionUID = -1043776488459785433L; 086 087 public void buttonClick(ClickEvent event) { 088 089 window.close(); 090 091 } 092 093 }); 094 dialog.addButton(closeButton, true); 095 window.setContent(dialog); 096 097 window.setCaption(CmsVaadinUtils.getMessageText(Messages.GUI_SEARCHINDEX_ADMIN_TOOL_NAME_SHORT_0)); 098 A_CmsUI.get().addWindow(window); 099 window.center(); 100 } 101 102 /** 103 * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getTitle(java.util.Locale) 104 */ 105 public String getTitle(Locale locale) { 106 107 return CmsVaadinUtils.getMessageText(Messages.GUI_SEARCHINDEX_REBUILD_0); 108 } 109 110 /** 111 * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getVisibility(java.lang.Object) 112 */ 113 public CmsMenuItemVisibilityMode getVisibility(Set<String> data) { 114 115 return CmsMenuItemVisibilityMode.VISIBILITY_ACTIVE; 116 } 117 } 118 119 /** 120 * Menu entry for show variations option.<p> 121 */ 122 class EntrySources implements I_CmsSimpleContextMenuEntry<Set<String>>, I_CmsSimpleContextMenuEntry.I_HasCssStyles { 123 124 /** 125 * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#executeAction(java.lang.Object) 126 */ 127 public void executeAction(Set<String> data) { 128 129 String resource = data.iterator().next(); 130 showSourcesWindow(resource); 131 } 132 133 /** 134 * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry.I_HasCssStyles#getStyles() 135 */ 136 public String getStyles() { 137 138 return ValoTheme.LABEL_BOLD; 139 } 140 141 /** 142 * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getTitle(java.util.Locale) 143 */ 144 public String getTitle(Locale locale) { 145 146 return CmsVaadinUtils.getMessageText(Messages.GUI_SEARCHINDEX_INDEXSOURCE_SHOW_0); 147 } 148 149 /** 150 * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getVisibility(java.lang.Object) 151 */ 152 public CmsMenuItemVisibilityMode getVisibility(Set<String> data) { 153 154 return (data != null) && (data.size() == 1) 155 ? CmsMenuItemVisibilityMode.VISIBILITY_ACTIVE 156 : CmsMenuItemVisibilityMode.VISIBILITY_INVISIBLE; 157 } 158 } 159 160 /** 161 * All table properties.<p> 162 */ 163 enum TableProperty { 164 165 /**Field configuration column. */ 166 FieldConfig(Messages.GUI_SEARCHINDEX_COL_CONFIGURATION_0, String.class, "", false), 167 168 /**Icon column.*/ 169 Icon(null, Resource.class, new CmsCssIcon(OpenCmsTheme.ICON_DATABASE), false), 170 171 /**Locale column. */ 172 Locale(Messages.GUI_SEARCHINDEX_COL_LOCALE_0, String.class, "", false), 173 174 /**name column. */ 175 Name(Messages.GUI_SEARCHINDEX_COL_NAME_0, String.class, "", false), 176 177 /**Project column.*/ 178 Project(Messages.GUI_SEARCHINDEX_COL_PROJECT_0, String.class, "", false), 179 180 /**Rebuild column.*/ 181 Rebuild(Messages.GUI_SEARCHINDEX_COL_REBUILDMODE_0, String.class, "", false); 182 183 /**Indicates if column is collapsable.*/ 184 private boolean m_collapsable; 185 186 /**Default value for column.*/ 187 private Object m_defaultValue; 188 189 /**Header Message key.*/ 190 private String m_headerMessage; 191 192 /**Type of column property.*/ 193 private Class<?> m_type; 194 195 /** 196 * constructor. 197 * 198 * @param headerMessage key 199 * @param type to property 200 * @param defaultValue of column 201 * @param collapsable should this column be collapsable? 202 */ 203 TableProperty(String headerMessage, Class<?> type, Object defaultValue, boolean collapsable) { 204 205 m_headerMessage = headerMessage; 206 m_type = type; 207 m_defaultValue = defaultValue; 208 m_collapsable = collapsable; 209 } 210 211 /** 212 * Returns list of all properties with non-empty header.<p> 213 * 214 * @return list of properties 215 */ 216 static List<TableProperty> withHeader() { 217 218 List<TableProperty> props = new ArrayList<TableProperty>(); 219 220 for (TableProperty prop : TableProperty.values()) { 221 if (prop.m_headerMessage != null) { 222 props.add(prop); 223 } 224 } 225 return props; 226 } 227 228 /** 229 * Returns the default value of property.<p> 230 * 231 * @return object 232 */ 233 Object getDefaultValue() { 234 235 return m_defaultValue; 236 } 237 238 /** 239 * Returns localized header.<p> 240 * 241 * @return string for header 242 */ 243 String getLocalizedMessage() { 244 245 if (m_headerMessage == null) { 246 return ""; 247 } 248 return CmsVaadinUtils.getMessageText(m_headerMessage); 249 } 250 251 /** 252 * Returns tye of value for given property.<p> 253 * 254 * @return type 255 */ 256 Class<?> getType() { 257 258 return m_type; 259 } 260 261 /** 262 * Indicates if column is collapsable.<p> 263 * 264 * @return boolean, true = is collapsable 265 */ 266 boolean isCollapsable() { 267 268 return m_collapsable; 269 } 270 271 } 272 273 /**vaadin serial id.*/ 274 private static final long serialVersionUID = 5764331446498958798L; 275 276 /**the calling instance.*/ 277 protected CmsSearchindexApp m_manager; 278 279 /**Indexed container. */ 280 private IndexedContainer m_container; 281 282 /** The context menu. */ 283 private CmsContextMenu m_menu; 284 285 /** The available menu entries. */ 286 private List<I_CmsSimpleContextMenuEntry<Set<String>>> m_menuEntries; 287 288 /** 289 * Constructor.<p> 290 * 291 * @param manager instance of the calling app 292 */ 293 public CmsSearchIndexTable(CmsSearchindexApp manager) { 294 295 m_manager = manager; 296 m_container = new IndexedContainer(); 297 298 setContainerDataSource(m_container); 299 300 for (TableProperty prop : TableProperty.values()) { 301 m_container.addContainerProperty(prop, prop.getType(), prop.getDefaultValue()); 302 setColumnHeader(prop, prop.getLocalizedMessage()); 303 } 304 305 m_menu = new CmsContextMenu(); 306 m_menu.setAsTableContextMenu(this); 307 setVisibleColumns( 308 TableProperty.Name, 309 TableProperty.FieldConfig, 310 TableProperty.Rebuild, 311 TableProperty.Project, 312 TableProperty.Locale); 313 setItemIconPropertyId(TableProperty.Icon); 314 setRowHeaderMode(RowHeaderMode.ICON_ONLY); 315 setColumnWidth(null, 40); 316 317 addItemClickListener(new ItemClickListener() { 318 319 /**vaadin serial id.*/ 320 private static final long serialVersionUID = -3595150969741628374L; 321 322 public void itemClick(ItemClickEvent event) { 323 324 onItemClick(event, event.getItemId(), event.getPropertyId()); 325 } 326 327 }); 328 329 setSelectable(true); 330 setMultiSelect(true); 331 332 setCellStyleGenerator(new CellStyleGenerator() { 333 334 private static final long serialVersionUID = 1L; 335 336 public String getStyle(Table source, Object itemId, Object propertyId) { 337 338 if (TableProperty.Name.equals(propertyId)) { 339 return " " + OpenCmsTheme.HOVER_COLUMN; 340 } 341 return null; 342 } 343 }); 344 345 } 346 347 /** 348 * (Re)loads the table.<p> 349 */ 350 public void loadTable() { 351 352 m_container.removeAllItems(); 353 List<I_CmsSearchIndex> indexes = m_manager.getAllElements(); 354 355 for (I_CmsSearchIndex index : indexes) { 356 if (index.isEnabled()) { 357 Item item = m_container.addItem(index); 358 item.getItemProperty(TableProperty.Name).setValue(index.getName()); 359 item.getItemProperty(TableProperty.FieldConfig).setValue(index.getFieldConfiguration().getName()); 360 item.getItemProperty(TableProperty.Locale).setValue(index.getLocale().getDisplayName()); 361 item.getItemProperty(TableProperty.Project).setValue(index.getProject()); 362 item.getItemProperty(TableProperty.Rebuild).setValue(index.getRebuildMode()); 363 } 364 } 365 } 366 367 /** 368 * Returns the available menu entries.<p> 369 * 370 * @return the menu entries 371 */ 372 List<I_CmsSimpleContextMenuEntry<Set<String>>> getMenuEntries() { 373 374 if (m_menuEntries == null) { 375 m_menuEntries = new ArrayList<I_CmsSimpleContextMenuEntry<Set<String>>>(); 376 m_menuEntries.add(new EntrySources()); //Option for show Sources of index 377 m_menuEntries.add(new EntryRebuild()); 378 } 379 return m_menuEntries; 380 } 381 382 /** 383 * Handles the table item clicks, including clicks on images inside of a table item.<p> 384 * 385 * @param event the click event 386 * @param itemId of the clicked row 387 * @param propertyId column id 388 */ 389 void onItemClick(MouseEvents.ClickEvent event, Object itemId, Object propertyId) { 390 391 if (!event.isCtrlKey() && !event.isShiftKey()) { 392 393 changeValueIfNotMultiSelect(itemId); 394 395 // don't interfere with multi-selection using control key 396 if (event.getButton().equals(MouseButton.RIGHT) || (propertyId == null)) { 397 m_menu.setEntries(getMenuEntries(), getSearchIndexNames()); 398 m_menu.openForTable(event, itemId, propertyId, this); 399 } else if (event.getButton().equals(MouseButton.LEFT) && TableProperty.Name.equals(propertyId)) { 400 showSourcesWindow(((I_CmsSearchIndex)((Set<?>)getValue()).iterator().next()).getName()); 401 } 402 } 403 } 404 405 /** 406 * Shows dialog for variations of given resource.<p> 407 * 408 * @param resource to show variations for 409 */ 410 void showSourcesWindow(String resource) { 411 412 final Window window = CmsBasicDialog.prepareWindow(DialogWidth.wide); 413 CmsSourceDialog sourceDialog = new CmsSourceDialog(m_manager, new Runnable() { 414 415 public void run() { 416 417 window.close(); 418 } 419 }); 420 sourceDialog.setSource(resource); 421 window.setCaption(CmsVaadinUtils.getMessageText(Messages.GUI_SEARCHINDEX_INDEXSOURCE_SHOW_1, resource)); 422 window.setContent(sourceDialog); 423 UI.getCurrent().addWindow(window); 424 } 425 426 /** 427 * Checks value of table and sets it new if needed:<p> 428 * if multiselect: new itemId is in current Value? -> no change of value<p> 429 * no multiselect and multiselect, but new item not selected before: set value to new item<p> 430 * 431 * @param itemId if of clicked item 432 */ 433 private void changeValueIfNotMultiSelect(Object itemId) { 434 435 @SuppressWarnings("unchecked") 436 Set<String> value = (Set<String>)getValue(); 437 if (value == null) { 438 select(itemId); 439 } else if (!value.contains(itemId)) { 440 setValue(null); 441 select(itemId); 442 } 443 } 444 445 /** 446 * Returns a list with the names of all searchindexes.<p> 447 * 448 * @return List of search index names 449 */ 450 private Set<String> getSearchIndexNames() { 451 452 Set<String> names = new HashSet<String>(); 453 @SuppressWarnings("unchecked") 454 Set<I_CmsSearchIndex> indexes = (Set<I_CmsSearchIndex>)getValue(); 455 for (I_CmsSearchIndex index : indexes) { 456 names.add(index.getName()); 457 } 458 return names; 459 } 460}