001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (C) Alkacon Software (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.ade.sitemap.client.alias; 029 030import static org.opencms.ade.sitemap.client.alias.CmsAliasMessages.messagePage; 031import static org.opencms.ade.sitemap.client.alias.CmsAliasMessages.messagePermanentRedirect; 032import static org.opencms.ade.sitemap.client.alias.CmsAliasMessages.messageRedirect; 033import static org.opencms.ade.sitemap.client.alias.CmsAliasMessages.messageRowCount; 034 035import org.opencms.ade.sitemap.client.alias.rewrite.CmsRewriteAliasTable; 036import org.opencms.ade.sitemap.client.alias.simple.CmsAliasCellTable; 037import org.opencms.gwt.client.ui.CmsPopup; 038import org.opencms.gwt.client.ui.CmsPushButton; 039import org.opencms.gwt.client.ui.I_CmsButton; 040import org.opencms.gwt.client.ui.I_CmsButton.ButtonStyle; 041import org.opencms.gwt.client.ui.input.CmsSelectBox; 042import org.opencms.gwt.client.ui.input.CmsTextBox; 043import org.opencms.gwt.shared.alias.CmsAliasMode; 044import org.opencms.gwt.shared.alias.CmsAliasTableRow; 045import org.opencms.gwt.shared.alias.CmsRewriteAliasTableRow; 046import org.opencms.gwt.shared.alias.CmsRewriteAliasValidationReply; 047import org.opencms.util.CmsUUID; 048 049import java.util.ArrayList; 050import java.util.HashMap; 051import java.util.LinkedHashMap; 052import java.util.List; 053import java.util.Map; 054 055import com.google.gwt.core.client.GWT; 056import com.google.gwt.event.dom.client.ClickEvent; 057import com.google.gwt.uibinder.client.UiBinder; 058import com.google.gwt.uibinder.client.UiField; 059import com.google.gwt.uibinder.client.UiHandler; 060import com.google.gwt.user.cellview.client.ColumnSortEvent; 061import com.google.gwt.user.cellview.client.ColumnSortList; 062import com.google.gwt.user.client.ui.Composite; 063import com.google.gwt.user.client.ui.HasText; 064import com.google.gwt.user.client.ui.Panel; 065import com.google.gwt.user.client.ui.Widget; 066import com.google.gwt.view.client.RowCountChangeEvent; 067 068/** 069 * The widget containing the table and the buttons used for editing aliases.<p> 070 */ 071public class CmsAliasView extends Composite { 072 073 /** The UiBinder interface for this widget. */ 074 protected interface I_CmsAliasViewUiBinder extends UiBinder<Widget, CmsAliasView> { 075 // empty 076 } 077 078 /** The 'Cancel' button. */ 079 @UiField 080 protected CmsPushButton m_cancelButton; 081 082 /** The alias table controller. */ 083 protected CmsAliasTableController m_controller; 084 085 /** Text container for the row count. */ 086 @UiField 087 protected HasText m_countLabel; 088 089 /** The 'Delete' button. */ 090 @UiField 091 protected CmsPushButton m_deleteButton; 092 093 /** The 'Download' button. */ 094 @UiField 095 protected CmsPushButton m_downloadButton; 096 097 /** The text box for entering the path for a new alias. */ 098 @UiField 099 protected CmsTextBox m_newAliasPath; 100 101 /** The button for adding a new alias. */ 102 @UiField 103 protected CmsPushButton m_newButton; 104 105 /** The select box for selecting the mode of a new alias. */ 106 @UiField 107 protected CmsSelectBox m_newMode; 108 109 /** The text box for entering the resource path for a new alias. */ 110 @UiField 111 protected CmsTextBox m_newResourcePath; 112 113 /** The button for adding a new rewrite alias. */ 114 @UiField 115 protected CmsPushButton m_newRewriteButton; 116 117 /** The select box for selecting a mode for new rewrite aliases. */ 118 @UiField 119 protected CmsSelectBox m_newRewriteMode; 120 121 /** The text box for entering a new rewrite pattern. */ 122 @UiField 123 protected CmsTextBox m_newRewriteRegex; 124 125 /** The text box for entering a new rewrite replacement string. */ 126 @UiField 127 protected CmsTextBox m_newRewriteReplacement; 128 129 /** The button for deleting rewrite aliases. */ 130 @UiField 131 protected CmsPushButton m_rewriteDeleteButton; 132 133 /** 134 * The container for the rewrite table.<p> 135 */ 136 @UiField 137 protected Panel m_rewriteTableContainer; 138 139 /** The button for saving the alias table. */ 140 @UiField 141 protected CmsPushButton m_saveButton; 142 143 /** The panel containing the alias cell table. */ 144 @UiField 145 protected Panel m_tableContainer; 146 147 /** The button for importing alias CSV files. */ 148 @UiField 149 protected CmsPushButton m_uploadButton; 150 151 /** The popup in which this view is displayed. */ 152 private CmsPopup m_popup; 153 154 /** The cell table for editing rewrite aliases. */ 155 private CmsRewriteAliasTable m_rewriteTable; 156 157 /** The table containing the alias data. */ 158 private CmsAliasCellTable m_table; 159 160 /** 161 * Creates new view instance.<p> 162 * 163 * @param controller the controller for the view 164 */ 165 @SuppressWarnings("unchecked") 166 public CmsAliasView(CmsAliasTableController controller) { 167 168 initWidget(((UiBinder<Widget, CmsAliasView>)GWT.create(I_CmsAliasViewUiBinder.class)).createAndBindUi(this)); 169 Map<String, String> items = new LinkedHashMap<String, String>(); 170 items.put(CmsAliasMode.permanentRedirect.toString(), messagePermanentRedirect()); 171 items.put(CmsAliasMode.redirect.toString(), messageRedirect()); 172 items.put(CmsAliasMode.page.toString(), messagePage()); 173 m_newMode.setItems(items); 174 175 Map<String, String> rewriteItems = new LinkedHashMap<String, String>(); 176 rewriteItems.put(CmsAliasMode.permanentRedirect.toString(), messagePermanentRedirect()); 177 rewriteItems.put(CmsAliasMode.redirect.toString(), messageRedirect()); 178 rewriteItems.put(CmsAliasMode.passthrough.toString(), CmsAliasMessages.messagePassthrough()); 179 m_newRewriteMode.setItems(rewriteItems); 180 181 m_controller = controller; 182 m_deleteButton.setEnabled(false); 183 m_rewriteDeleteButton.setEnabled(false); 184 m_table = new CmsAliasCellTable(controller); 185 m_tableContainer.add(m_table); 186 m_rewriteTable = new CmsRewriteAliasTable(controller); 187 m_rewriteTableContainer.add(m_rewriteTable); 188 setNewButtonStyle(m_newButton); 189 setNewButtonStyle(m_newRewriteButton); 190 m_table.addRowCountChangeHandler(new RowCountChangeEvent.Handler() { 191 192 public void onRowCountChange(RowCountChangeEvent event) { 193 194 String message = messageRowCount(event.getNewRowCount()); 195 m_countLabel.setText(message); 196 } 197 }); 198 setWidth("100%"); //$NON-NLS-1$ 199 } 200 201 /** 202 * Clears the input fields used to add new aliases.<p> 203 */ 204 public void clearNew() { 205 206 m_newAliasPath.setFormValueAsString(""); //$NON-NLS-1$ 207 m_newAliasPath.setErrorMessage(null); 208 m_newResourcePath.setFormValueAsString(""); //$NON-NLS-1$ 209 m_newResourcePath.setErrorMessage(null); 210 } 211 212 /** 213 * Clears the text boxes for adding new rewrites.<p> 214 */ 215 public void clearRewriteNew() { 216 217 m_newRewriteRegex.setFormValueAsString(""); 218 m_newRewriteReplacement.setFormValueAsString(""); 219 } 220 221 /** 222 * Clears the validation errors for the text boxes used to add new aliases.<p> 223 */ 224 public void clearValidationsForNew() { 225 226 m_newResourcePath.setErrorMessage(null); 227 m_newAliasPath.setErrorMessage(null); 228 } 229 230 /** 231 * Hides the popup.<p> 232 */ 233 public void close() { 234 235 m_popup.hide(); 236 } 237 238 /** 239 * Gets the buttons which should be displayed in the button bar of the popup containing this view.<p> 240 * 241 * @return the buttons for the popup button bar 242 */ 243 public List<CmsPushButton> getButtonBar() { 244 245 List<CmsPushButton> buttons = new ArrayList<CmsPushButton>(); 246 buttons.add(m_cancelButton); 247 buttons.add(m_saveButton); 248 buttons.add(m_downloadButton); 249 buttons.add(m_uploadButton); 250 return buttons; 251 } 252 253 /** 254 * Gets the list of rows used by the data provider.<p> 255 * 256 * @return the list of rows used by the data provider 257 */ 258 public List<CmsAliasTableRow> getLiveData() { 259 260 return m_table.getLiveDataList(); 261 } 262 263 /** 264 * Gets the rewrite alias data.<p> 265 * 266 * @return the rewrite alias list 267 */ 268 public List<CmsRewriteAliasTableRow> getRewriteData() { 269 270 return m_rewriteTable.getLiveDataList(); 271 } 272 273 /** 274 * Gets the rewrite alias cell table.<p> 275 * 276 * @return the rewrite alias cell table 277 */ 278 public CmsRewriteAliasTable getRewriteTable() { 279 280 return m_rewriteTable; 281 } 282 283 /** 284 * Gets the cell table used to edit the alias data.<p> 285 * 286 * @return the alias cell table 287 */ 288 public CmsAliasCellTable getTable() { 289 290 return m_table; 291 } 292 293 /** 294 * Replaces the contents of the live data row list with another list of rows.<p> 295 * 296 * @param data the new list of rows to be placed into the live data list 297 * @param rewriteData the list of rewrite alias data 298 */ 299 public void setData(List<CmsAliasTableRow> data, List<CmsRewriteAliasTableRow> rewriteData) { 300 301 m_table.getLiveDataList().clear(); 302 m_table.getLiveDataList().addAll(data); 303 m_rewriteTable.getLiveDataList().clear(); 304 m_rewriteTable.getLiveDataList().addAll(rewriteData); 305 } 306 307 /** 308 * Enables or disables the delete button.<p> 309 * 310 * @param enabled if true, the delete button will be enabled, else disabled 311 */ 312 public void setDeleteButtonEnabled(boolean enabled) { 313 314 m_deleteButton.setEnabled(enabled); 315 } 316 317 /** 318 * Sets the validation error message for the alias path text box.<p> 319 * 320 * @param error the validation error message 321 */ 322 public void setNewAliasPathError(String error) { 323 324 m_newAliasPath.setErrorMessage(error); 325 326 } 327 328 /** 329 * Sets the validation error message for the resource path text box.<p> 330 * 331 * @param error the validation error message 332 */ 333 public void setNewAliasResourceError(String error) { 334 335 m_newResourcePath.setErrorMessage(error); 336 } 337 338 /** 339 * Sets the popup used to display this widget.<p> 340 * 341 * @param popup the popup instance 342 */ 343 public void setPopup(CmsPopup popup) { 344 345 m_popup = popup; 346 } 347 348 /** 349 * Enables or disables the delete button for rewrite aliases.<p> 350 * 351 * @param enabled true if the delete button should be enabled 352 */ 353 public void setRewriteDeleteButtonEnabled(boolean enabled) { 354 355 m_rewriteDeleteButton.setEnabled(enabled); 356 } 357 358 /** 359 * Enables or disables the save button.<p> 360 * 361 * @param enabled true if the save button should be enabled, false if it should be disabled 362 */ 363 public void setSaveButtonEnabled(boolean enabled) { 364 365 m_saveButton.setEnabled(enabled); 366 } 367 368 /** 369 * Ensures that rows with errors will be placed at the top of the table.<p> 370 */ 371 public void sortByErrors() { 372 373 ColumnSortList columnSort = m_table.getColumnSortList(); 374 columnSort.clear(); 375 columnSort.push(m_table.getErrorColumn()); 376 columnSort.push(m_table.getErrorColumn()); 377 ColumnSortEvent.fire(m_table, columnSort); 378 } 379 380 /** 381 * Updates the view after the rewrite aliases have been validated.<p> 382 * 383 * @param result the result of the rewrite alias validation 384 */ 385 public void update(CmsRewriteAliasValidationReply result) { 386 387 Map<CmsUUID, String> errors = result.getErrors(); 388 for (CmsRewriteAliasTableRow row : getRewriteData()) { 389 String error = errors.get(row.getId()); 390 row.setError(error); 391 } 392 m_rewriteTable.redraw(); 393 } 394 395 /** 396 * Updates the table data with a new list of rows.<p> 397 * 398 * Rows in the table for which a row with the same key is also contained in the 'data' parameter 399 * will be updated, the other rows from the 'data' list will be added.<p> 400 * 401 * @param data the list of rows to update 402 */ 403 public void update(List<CmsAliasTableRow> data) { 404 405 Map<String, CmsAliasTableRow> currentRowsByKey = new HashMap<String, CmsAliasTableRow>(); 406 for (CmsAliasTableRow row : m_table.getLiveDataList()) { 407 currentRowsByKey.put(row.getKey(), row); 408 } 409 List<CmsAliasTableRow> rowsToAdd = new ArrayList<CmsAliasTableRow>(); 410 for (CmsAliasTableRow updateRow : data) { 411 String key = updateRow.getKey(); 412 CmsAliasTableRow existingRow = currentRowsByKey.get(key); 413 if (existingRow != null) { 414 existingRow.update(updateRow); 415 } else { 416 rowsToAdd.add(updateRow); 417 } 418 } 419 m_table.getLiveDataList().addAll(rowsToAdd); 420 m_table.redraw(); 421 } 422 423 /** 424 * The event handler for the button to delete rewrite aliases.<p> 425 * 426 * @param e the click event 427 */ 428 @UiHandler("m_rewriteDeleteButton") 429 protected void onClickDeleteRewrite(ClickEvent e) { 430 431 List<CmsRewriteAliasTableRow> rowsToDelete = m_rewriteTable.getSelectedRows(); 432 m_controller.deleteRewrites(rowsToDelete); 433 } 434 435 /** 436 * The click handler for the 'Cancel' button.<p> 437 * 438 * @param e the click event 439 */ 440 @UiHandler("m_cancelButton") 441 void onClickCancel(ClickEvent e) { 442 443 m_popup.hide(); 444 } 445 446 /** 447 * The click handler for the 'Delete' button.<p> 448 * 449 * @param e the click event 450 */ 451 @UiHandler("m_deleteButton") 452 void onClickDelete(ClickEvent e) { 453 454 List<CmsAliasTableRow> rowsToDelete = m_table.getSelectedRows(); 455 m_controller.deleteRows(rowsToDelete); 456 } 457 458 /** 459 * The click handler for the 'Download' button.<p> 460 * 461 * @param e the click event 462 */ 463 @UiHandler("m_downloadButton") 464 void onClickDownload(ClickEvent e) { 465 466 m_controller.download(); 467 } 468 469 /** 470 * The click handler for the 'New' button.<p> 471 * 472 * @param e the click event 473 */ 474 @UiHandler("m_newButton") 475 void onClickNew(ClickEvent e) { 476 477 String aliasPath = m_newAliasPath.getText(); 478 String resourcePath = m_newResourcePath.getText(); 479 m_controller.editNewAlias(aliasPath, resourcePath, CmsAliasMode.valueOf(m_newMode.getFormValueAsString())); 480 } 481 482 /** 483 * The event handler for the button for adding new rewrite aliases.<p> 484 * 485 * @param e the click event 486 */ 487 @UiHandler("m_newRewriteButton") 488 void onClickNewRewrite(ClickEvent e) { 489 490 String rewriteRegex = m_newRewriteRegex.getText(); 491 String rewriteReplacement = m_newRewriteReplacement.getText(); 492 String mode = m_newRewriteMode.getFormValueAsString(); 493 m_controller.editNewRewrite(rewriteRegex, rewriteReplacement, CmsAliasMode.valueOf(mode)); 494 } 495 496 /** 497 * The click handler for the 'Save' button.<p> 498 * 499 * @param e the click event 500 */ 501 @UiHandler("m_saveButton") 502 void onClickSave(ClickEvent e) { 503 504 m_controller.save(); 505 } 506 507 /** 508 * The click handler for the upload button.<p> 509 * 510 * @param e the click handler for the upload button 511 */ 512 @UiHandler("m_uploadButton") 513 void onClickUpload(ClickEvent e) { 514 515 m_popup.hide(); 516 CmsImportView.showPopup(); 517 518 } 519 520 /** 521 * Styles a button for adding new aliases.<p> 522 * 523 * @param newButton the button to style 524 */ 525 private void setNewButtonStyle(CmsPushButton newButton) { 526 527 newButton.setImageClass(I_CmsButton.ADD_SMALL); 528 newButton.setButtonStyle(ButtonStyle.FONT_ICON, null); 529 } 530 531}