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.commons; 029 030import org.opencms.db.CmsDbEntryNotFoundException; 031import org.opencms.file.CmsFile; 032import org.opencms.file.CmsObject; 033import org.opencms.file.CmsProject; 034import org.opencms.file.CmsResource; 035import org.opencms.file.CmsResourceFilter; 036import org.opencms.file.CmsVfsResourceNotFoundException; 037import org.opencms.file.history.CmsHistoryProject; 038import org.opencms.file.history.CmsHistoryResourceHandler; 039import org.opencms.file.history.I_CmsHistoryResource; 040import org.opencms.jsp.CmsJspActionElement; 041import org.opencms.main.CmsException; 042import org.opencms.main.CmsLog; 043import org.opencms.main.CmsRuntimeException; 044import org.opencms.main.OpenCms; 045import org.opencms.security.CmsPrincipal; 046import org.opencms.util.CmsStringUtil; 047import org.opencms.util.CmsUUID; 048import org.opencms.workplace.comparison.CmsHistoryListUtil; 049import org.opencms.workplace.list.A_CmsListDialog; 050import org.opencms.workplace.list.CmsListColumnAlignEnum; 051import org.opencms.workplace.list.CmsListColumnDefinition; 052import org.opencms.workplace.list.CmsListDirectAction; 053import org.opencms.workplace.list.CmsListItem; 054import org.opencms.workplace.list.CmsListItemActionIconComparator; 055import org.opencms.workplace.list.CmsListItemDetails; 056import org.opencms.workplace.list.CmsListItemDetailsFormatter; 057import org.opencms.workplace.list.CmsListItemSelectionAction; 058import org.opencms.workplace.list.CmsListMetadata; 059import org.opencms.workplace.list.CmsListOrderEnum; 060import org.opencms.workplace.list.CmsListRadioMultiAction; 061import org.opencms.workplace.list.CmsListResourceIconAction; 062import org.opencms.workplace.list.I_CmsListFormatter; 063import org.opencms.workplace.tools.CmsToolDialog; 064 065import java.io.IOException; 066import java.util.ArrayList; 067import java.util.Arrays; 068import java.util.HashMap; 069import java.util.Iterator; 070import java.util.List; 071import java.util.Locale; 072import java.util.Map; 073 074import javax.servlet.ServletException; 075import javax.servlet.http.HttpServletRequest; 076import javax.servlet.http.HttpServletResponse; 077import javax.servlet.jsp.JspException; 078import javax.servlet.jsp.PageContext; 079 080import org.apache.commons.logging.Log; 081 082/** 083 * Displays the history of a file.<p> 084 * 085 * @since 6.0.2 086 */ 087public class CmsHistoryList extends A_CmsListDialog { 088 089 /** 090 * Wrapper class for the version which is either an integer or the string "offline".<p> 091 */ 092 public static class CmsVersionWrapper implements Comparable<Object> { 093 094 /** the version. */ 095 private Integer m_version; 096 097 /** 098 * Constructs a new version wrapper.<p> 099 * 100 * @param version the version of the file 101 */ 102 public CmsVersionWrapper(int version) { 103 104 m_version = Integer.valueOf(version); 105 } 106 107 /** 108 * 109 * @see java.lang.Comparable#compareTo(java.lang.Object) 110 */ 111 public int compareTo(Object o) { 112 113 if (this == o) { 114 return 0; 115 } 116 if (o instanceof CmsVersionWrapper) { 117 CmsVersionWrapper version = (CmsVersionWrapper)o; 118 Integer v1 = m_version; 119 Integer v2 = version.getVersion(); 120 if (v1.intValue() < 0) { 121 v1 = Integer.valueOf(-1 * v1.intValue()); 122 } 123 if (v2.intValue() < 0) { 124 v2 = Integer.valueOf(-1 * v2.intValue()); 125 } 126 return v1.compareTo(v2); 127 } 128 return 0; 129 } 130 131 /** 132 * @see java.lang.Object#equals(java.lang.Object) 133 */ 134 @Override 135 public boolean equals(Object obj) { 136 137 if (this == obj) { 138 return true; 139 } 140 if (obj instanceof CmsVersionWrapper) { 141 CmsVersionWrapper version = (CmsVersionWrapper)obj; 142 return getVersion().equals(version.getVersion()); 143 } 144 return false; 145 } 146 147 /** 148 * Returns the version of the file.<p> 149 * 150 * @return the version of the file 151 */ 152 public Integer getVersion() { 153 154 return m_version; 155 } 156 157 /** 158 * @see java.lang.Object#hashCode() 159 */ 160 @Override 161 public int hashCode() { 162 163 return getVersion().hashCode(); 164 } 165 166 /** 167 * 168 * @see java.lang.Object#toString() 169 */ 170 @Override 171 public String toString() { 172 173 return m_version.toString(); 174 } 175 176 } 177 178 /** list item detail id constant. */ 179 public static final String GUI_LIST_HISTORY_DETAIL_PROJECT_0 = "lhdp"; 180 181 /** List action export. */ 182 public static final String LIST_ACTION_RESTORE = "ar"; 183 184 /** list action id constant. */ 185 public static final String LIST_ACTION_VIEW = "av"; 186 187 /** list column id constant. */ 188 public static final String LIST_COLUMN_DATE_LAST_MODIFIED = "cm"; 189 190 /** list column id constant. */ 191 public static final String LIST_COLUMN_DATE_PUBLISHED = "cdp"; 192 193 /** list column id constant. */ 194 public static final String LIST_COLUMN_FILE_TYPE = "ct"; 195 196 /** list column id constant. */ 197 public static final String LIST_COLUMN_ICON = "ci"; 198 199 /** list column id constant. */ 200 public static final String LIST_COLUMN_PUBLISH_TAG = "cbt"; 201 202 /** list column id constant. */ 203 public static final String LIST_COLUMN_RESOURCE_PATH = "crp"; 204 205 /** List column delete. */ 206 public static final String LIST_COLUMN_RESTORE = "cr"; 207 208 /** list column id constant. */ 209 public static final String LIST_COLUMN_SEL1 = "cs1"; 210 211 /** list column id constant. */ 212 public static final String LIST_COLUMN_SEL2 = "cs2"; 213 214 /** list column id constant. */ 215 public static final String LIST_COLUMN_SIZE = "cs"; 216 217 /** list column id constant. */ 218 public static final String LIST_COLUMN_STRUCTURE_ID = "csi"; 219 220 /** List column export. */ 221 public static final String LIST_COLUMN_USER = "cu"; 222 223 /** list column id constant. */ 224 public static final String LIST_COLUMN_VERSION = "cv"; 225 226 /** list column id constant. */ 227 public static final String LIST_COLUMN_VERSION_ENABLE = "cve"; 228 229 /** List column export. */ 230 public static final String LIST_COLUMN_VIEW = "cp"; 231 232 /** list id constant. */ 233 public static final String LIST_ID = "him"; 234 235 /** list independent action id constant. */ 236 public static final String LIST_RACTION_SEL1 = "rs1"; 237 238 /** list independent action id constant. */ 239 public static final String LIST_RACTION_SEL2 = "rs2"; 240 241 /** parameter for the path of the first resource. */ 242 public static final String PARAM_ID_1 = "id1"; 243 244 /** parameter for the path of the second resource. */ 245 public static final String PARAM_ID_2 = "id2"; 246 247 /** parameter for the version of the first resource. */ 248 public static final String PARAM_VERSION_1 = "version1"; 249 250 /** parameter for the version of the second resource. */ 251 public static final String PARAM_VERSION_2 = "version2"; 252 253 /** Path to the list buttons. */ 254 public static final String PATH_BUTTONS = "buttons/"; 255 256 /** list multi action id constant. */ 257 private static final String LIST_MACTION_COMPARE = "mc"; 258 259 /** The log object for this class. */ 260 private static final Log LOG = CmsLog.getLog(CmsHistoryList.class); 261 262 /** 263 * Public constructor.<p> 264 * 265 * @param jsp an initialized JSP action element 266 */ 267 public CmsHistoryList(CmsJspActionElement jsp) { 268 269 super( 270 jsp, 271 LIST_ID, 272 Messages.get().container(Messages.GUI_HISTORY_0), 273 LIST_COLUMN_VERSION, 274 CmsListOrderEnum.ORDER_DESCENDING, 275 null); 276 } 277 278 /** 279 * Public constructor with JSP variables.<p> 280 * 281 * @param context the JSP page context 282 * @param req the JSP request 283 * @param res the JSP response 284 */ 285 public CmsHistoryList(PageContext context, HttpServletRequest req, HttpServletResponse res) { 286 287 this(new CmsJspActionElement(context, req, res)); 288 } 289 290 /** 291 * @see org.opencms.workplace.list.A_CmsListDialog#actionDialog() 292 */ 293 @Override 294 public void actionDialog() throws JspException, ServletException, IOException { 295 296 super.actionDialog(); 297 // ensure the list is correcly sorted 298 if (CmsStringUtil.isEmptyOrWhitespaceOnly(getList().getSortedColumn())) { 299 getList().setSortedColumn(LIST_COLUMN_VERSION); 300 } 301 } 302 303 /** 304 * @see org.opencms.workplace.list.A_CmsListDialog#executeListMultiActions() 305 */ 306 @Override 307 public void executeListMultiActions() throws IOException, ServletException { 308 309 if (getParamListAction().equals(LIST_MACTION_COMPARE)) { 310 CmsListItem item1 = getSelectedItems().get(0); 311 CmsListItem item2 = getSelectedItems().get(1); 312 Map<String, String[]> params = new HashMap<String, String[]>(); 313 if (item2.get(LIST_COLUMN_VERSION) instanceof CmsVersionWrapper) { 314 CmsVersionWrapper ver = (CmsVersionWrapper)item2.get(LIST_COLUMN_VERSION); 315 if (ver.compareTo(item1.get(LIST_COLUMN_VERSION)) > 0) { 316 params.put(PARAM_VERSION_1, new String[] {item1.get(LIST_COLUMN_VERSION).toString()}); 317 params.put(PARAM_VERSION_2, new String[] {item2.get(LIST_COLUMN_VERSION).toString()}); 318 params.put(PARAM_ID_1, new String[] {item1.get(LIST_COLUMN_STRUCTURE_ID).toString()}); 319 params.put(PARAM_ID_2, new String[] {item2.get(LIST_COLUMN_STRUCTURE_ID).toString()}); 320 } 321 } 322 if (params.isEmpty()) { 323 params.put(PARAM_VERSION_1, new String[] {item2.get(LIST_COLUMN_VERSION).toString()}); 324 params.put(PARAM_VERSION_2, new String[] {item1.get(LIST_COLUMN_VERSION).toString()}); 325 params.put(PARAM_ID_1, new String[] {item2.get(LIST_COLUMN_STRUCTURE_ID).toString()}); 326 params.put(PARAM_ID_2, new String[] {item1.get(LIST_COLUMN_STRUCTURE_ID).toString()}); 327 } 328 params.put(PARAM_ACTION, new String[] {DIALOG_INITIAL}); 329 params.put(PARAM_STYLE, new String[] {CmsToolDialog.STYLE_NEW}); 330 params.put(PARAM_RESOURCE, new String[] {getParamResource()}); 331 getToolManager().jspForwardTool(this, "/history/comparison", params); 332 } 333 refreshList(); 334 } 335 336 /** 337 * @see org.opencms.workplace.list.A_CmsListDialog#executeListSingleActions() 338 */ 339 @Override 340 public void executeListSingleActions() throws IOException, ServletException { 341 342 if (getParamListAction().equals(LIST_ACTION_RESTORE)) { 343 try { 344 performRestoreOperation(); 345 Map<String, String[]> params = new HashMap<String, String[]>(); 346 params.put(PARAM_ACTION, new String[] {DIALOG_INITIAL}); 347 getToolManager().jspForwardPage(this, "/system/workplace/views/explorer/explorer_files.jsp", params); 348 } catch (CmsException e) { 349 LOG.error(e.getMessage(), e); 350 throw new CmsRuntimeException(e.getMessageContainer()); 351 } 352 } 353 refreshList(); 354 } 355 356 /** 357 * @see org.opencms.workplace.list.A_CmsListDialog#defaultActionHtmlStart() 358 */ 359 @Override 360 protected String defaultActionHtmlStart() { 361 362 return getList().listJs() + dialogContentStart(getParamTitle()); 363 } 364 365 /** 366 * @see org.opencms.workplace.list.A_CmsListDialog#fillDetails(java.lang.String) 367 */ 368 @Override 369 protected void fillDetails(String detailId) { 370 371 // get content 372 List<CmsListItem> items = getList().getAllContent(); 373 Iterator<CmsListItem> itItems = items.iterator(); 374 CmsListItem item; 375 while (itItems.hasNext()) { 376 item = itItems.next(); 377 if (detailId.equals(GUI_LIST_HISTORY_DETAIL_PROJECT_0)) { 378 fillDetailProject(item, detailId); 379 } 380 } 381 } 382 383 /** 384 * @see org.opencms.workplace.list.A_CmsListDialog#getListItems() 385 */ 386 @Override 387 protected List<CmsListItem> getListItems() throws CmsException { 388 389 List<CmsListItem> result = new ArrayList<CmsListItem>(); 390 391 List<I_CmsHistoryResource> historicalVersions = getCms().readAllAvailableVersions(getParamResource()); 392 Iterator<I_CmsHistoryResource> itVersions = historicalVersions.iterator(); 393 while (itVersions.hasNext()) { 394 I_CmsHistoryResource histRes = itVersions.next(); 395 396 // determine if the item actions should be enabled 397 // true, if the history file resource has its content 398 // false, if the history resource has no content, so no history dialog action can be performed 399 boolean isEnabled = true; 400 CmsResource resource = (CmsResource)getCms().readResource( 401 getCms().readResource(histRes.getStructureId(), CmsResourceFilter.IGNORE_EXPIRATION).getStructureId(), 402 histRes.getVersion()); 403 // not for folder 404 if (resource.isFile()) { 405 CmsFile file = getCms().readFile(resource); 406 byte[] content = file.getContents(); 407 // disable item actions, if the file has no content 408 if (content.length < 1) { 409 isEnabled = false; 410 } 411 } 412 413 // the publish tag for the history project 414 int publishTag = histRes.getPublishTag(); 415 416 CmsHistoryProject project = getCms().readHistoryProject(publishTag); 417 String filetype = String.valueOf(histRes.getTypeId()); 418 String dateLastModified = getMessages().getDateTime(histRes.getDateLastModified()); 419 String datePublished = getMessages().getDateTime(project.getPublishingDate()); 420 421 CmsListItem item = getList().newItem("" + histRes.getVersion()); 422 423 int factor = 1; 424 if (result.isEmpty() && !histRes.getState().isDeleted()) { 425 factor = -1; 426 } 427 CmsVersionWrapper version = new CmsVersionWrapper(factor * histRes.getVersion()); 428 429 //version 430 item.set(LIST_COLUMN_VERSION, version); 431 // publish date 432 item.set(LIST_COLUMN_DATE_PUBLISHED, datePublished); 433 // last modification date 434 item.set(LIST_COLUMN_DATE_LAST_MODIFIED, dateLastModified); 435 // resource type 436 item.set(LIST_COLUMN_FILE_TYPE, filetype); 437 // user 438 String user = histRes.getUserLastModified().toString(); 439 try { 440 user = CmsPrincipal.readPrincipalIncludingHistory(getCms(), histRes.getUserLastModified()).getName(); 441 } catch (CmsDbEntryNotFoundException e) { 442 // ignore 443 } 444 item.set(LIST_COLUMN_USER, user); 445 // path 446 item.set(LIST_COLUMN_RESOURCE_PATH, getCms().getRequestContext().removeSiteRoot(histRes.getRootPath())); 447 // size 448 item.set(LIST_COLUMN_SIZE, Integer.valueOf(histRes.getLength()).toString()); 449 // invisible publish tag (for reading history project in fillDetails) 450 item.set(LIST_COLUMN_PUBLISH_TAG, Integer.valueOf(publishTag)); 451 // invisible structure id 452 item.set(LIST_COLUMN_STRUCTURE_ID, histRes.getStructureId().toString()); 453 // invisible version flag: true if history version has content and actions should be enabled, false otherwise 454 item.set(LIST_COLUMN_VERSION_ENABLE, Boolean.valueOf(isEnabled)); 455 456 result.add(item); 457 } 458 459 if (result.isEmpty()) { 460 CmsResource onlineResource = null; 461 462 // this is to prevent problems after an update without keeping historical info 463 CmsProject project = getCms().getRequestContext().getCurrentProject(); 464 try { 465 getCms().getRequestContext().setCurrentProject(getCms().readProject(CmsProject.ONLINE_PROJECT_ID)); 466 onlineResource = getCms().readResource(getParamResource(), CmsResourceFilter.IGNORE_EXPIRATION); 467 468 CmsListItem item = getList().newItem("" + onlineResource.getVersion()); 469 //version 470 item.set(LIST_COLUMN_VERSION, new CmsVersionWrapper(-1 * onlineResource.getVersion())); 471 // publish date 472 item.set(LIST_COLUMN_DATE_PUBLISHED, "-"); 473 // last modification date 474 item.set( 475 LIST_COLUMN_DATE_LAST_MODIFIED, 476 getMessages().getDateTime(onlineResource.getDateLastModified())); 477 // resource type 478 item.set(LIST_COLUMN_FILE_TYPE, String.valueOf(onlineResource.getTypeId())); 479 // user 480 String user = onlineResource.getUserLastModified().toString(); 481 try { 482 user = CmsPrincipal.readPrincipalIncludingHistory( 483 getCms(), 484 onlineResource.getUserLastModified()).getName(); 485 } catch (CmsDbEntryNotFoundException e) { 486 // ignore 487 } 488 item.set(LIST_COLUMN_USER, user); 489 // size 490 item.set(LIST_COLUMN_SIZE, Integer.valueOf(onlineResource.getLength()).toString()); 491 // path 492 item.set(LIST_COLUMN_RESOURCE_PATH, getCms().getSitePath(onlineResource)); 493 // invisible structure id 494 item.set(LIST_COLUMN_STRUCTURE_ID, onlineResource.getStructureId().toString()); 495 // invisible version flag: true 496 item.set(LIST_COLUMN_VERSION_ENABLE, Boolean.valueOf(true)); 497 498 result.add(item); 499 } catch (CmsVfsResourceNotFoundException e) { 500 // ignore, most likely the file is new 501 } finally { 502 getCms().getRequestContext().setCurrentProject(project); 503 } 504 } 505 CmsResource offlineResource = getCms().readResource(getParamResource(), CmsResourceFilter.IGNORE_EXPIRATION); 506 507 // hide the size for folders 508 getList().getMetadata().getColumnDefinition(LIST_COLUMN_SIZE).setVisible(offlineResource.isFile()); 509 // hide the preview button for folders 510 getList().getMetadata().getColumnDefinition(LIST_COLUMN_ICON).setVisible(offlineResource.isFile()); 511 512 // display offline version, if state is not unchanged 513 if (!offlineResource.getState().isUnchanged()) { 514 CmsListItem item = getList().newItem("" + CmsHistoryResourceHandler.PROJECT_OFFLINE_VERSION); 515 //version 516 item.set(LIST_COLUMN_VERSION, new CmsVersionWrapper(CmsHistoryResourceHandler.PROJECT_OFFLINE_VERSION)); 517 // publish date 518 item.set(LIST_COLUMN_DATE_PUBLISHED, "-"); 519 // last modification date 520 item.set(LIST_COLUMN_DATE_LAST_MODIFIED, getMessages().getDateTime(offlineResource.getDateLastModified())); 521 // resource type 522 item.set(LIST_COLUMN_FILE_TYPE, String.valueOf(offlineResource.getTypeId())); 523 // user 524 String user = offlineResource.getUserLastModified().toString(); 525 try { 526 user = CmsPrincipal.readPrincipalIncludingHistory( 527 getCms(), 528 offlineResource.getUserLastModified()).getName(); 529 } catch (CmsDbEntryNotFoundException e) { 530 // ignore 531 } 532 item.set(LIST_COLUMN_USER, user); 533 // size 534 item.set(LIST_COLUMN_SIZE, Integer.valueOf(offlineResource.getLength()).toString()); 535 // path 536 item.set(LIST_COLUMN_RESOURCE_PATH, getCms().getSitePath(offlineResource)); 537 // invisible structure id 538 item.set(LIST_COLUMN_STRUCTURE_ID, offlineResource.getStructureId().toString()); 539 // invisible version flag: true 540 item.set(LIST_COLUMN_VERSION_ENABLE, Boolean.valueOf(true)); 541 542 result.add(item); 543 } 544 545 boolean comparable = (result.size() > 1); 546 getList().getMetadata().getColumnDefinition(LIST_COLUMN_SEL1).setVisible(comparable); 547 getList().getMetadata().getColumnDefinition(LIST_COLUMN_SEL2).setVisible(comparable); 548 getList().getMetadata().getMultiAction(LIST_MACTION_COMPARE).setVisible(comparable); 549 550 return result; 551 } 552 553 /** 554 * Restores a backed up resource version.<p> 555 * 556 * @throws CmsException if something goes wrong 557 */ 558 protected void performRestoreOperation() throws CmsException { 559 560 CmsUUID structureId = new CmsUUID(getSelectedItem().get(LIST_COLUMN_STRUCTURE_ID).toString()); 561 int version = Integer.parseInt(getSelectedItems().get(0).getId()); 562 if (version == CmsHistoryResourceHandler.PROJECT_OFFLINE_VERSION) { 563 // it is not possible to restore the offline version 564 return; 565 } 566 CmsResource res = getCms().readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 567 checkLock(getCms().getSitePath(res)); 568 getCms().restoreResourceVersion(res.getStructureId(), version); 569 } 570 571 /** 572 * @see org.opencms.workplace.list.A_CmsListDialog#setColumns(org.opencms.workplace.list.CmsListMetadata) 573 */ 574 @Override 575 protected void setColumns(CmsListMetadata metadata) { 576 577 CmsListColumnDefinition previewCol = new CmsListColumnDefinition(LIST_COLUMN_VIEW); 578 previewCol.setName(Messages.get().container(Messages.GUI_HISTORY_COLS_VIEW_0)); 579 previewCol.setWidth("20"); 580 previewCol.setVisible(false); 581 previewCol.setAlign(CmsListColumnAlignEnum.ALIGN_CENTER); 582 previewCol.setSorteable(false); 583 584 // create invisible coloumn for the version flag 585 CmsListColumnDefinition enableItemCol = new CmsListColumnDefinition(LIST_COLUMN_VERSION_ENABLE); 586 enableItemCol.setSorteable(false); 587 enableItemCol.setVisible(false); 588 metadata.addColumn(enableItemCol); 589 590 // create column for icon 591 CmsListColumnDefinition restoreCol = new CmsListColumnDefinition(LIST_COLUMN_RESTORE); 592 restoreCol.setName(Messages.get().container(Messages.GUI_HISTORY_COLS_RESTORE_0)); 593 restoreCol.setWidth("20"); 594 restoreCol.setAlign(CmsListColumnAlignEnum.ALIGN_CENTER); 595 restoreCol.setListItemComparator(new CmsListItemActionIconComparator()); 596 restoreCol.setSorteable(false); 597 598 // add icon action 599 CmsListDirectAction restoreAction = new CmsListDirectAction(LIST_ACTION_RESTORE) { 600 601 /** 602 * @see org.opencms.workplace.tools.I_CmsHtmlIconButton#getIconPath() 603 */ 604 @Override 605 public String getIconPath() { 606 607 Boolean isEnabled = (Boolean)getItem().get(LIST_COLUMN_VERSION_ENABLE); 608 if (isEnabled.booleanValue()) { 609 return "tools/ex_history/buttons/restore.png"; 610 } 611 return "buttons/publish_in.png"; 612 } 613 614 /** 615 * @see org.opencms.workplace.tools.I_CmsHtmlIconButton#isEnabled() 616 */ 617 @Override 618 public boolean isEnabled() { 619 620 Boolean isEnabled = (Boolean)getItem().get(LIST_COLUMN_VERSION_ENABLE); 621 if (isEnabled.booleanValue()) { 622 return true; 623 } 624 return false; 625 } 626 }; 627 restoreAction.setName(Messages.get().container(Messages.GUI_HISTORY_RESTORE_VERSION_0)); 628 restoreAction.setConfirmationMessage(Messages.get().container(Messages.GUI_HISTORY_CONFIRMATION_0)); 629 630 restoreCol.addDirectAction(restoreAction); 631 // add it to the list definition 632 metadata.addColumn(restoreCol); 633 634 // create column for icon 635 CmsListColumnDefinition iconCol = new CmsListColumnDefinition(LIST_COLUMN_ICON); 636 iconCol.setName(Messages.get().container(Messages.GUI_HISTORY_COLS_VIEW_0)); 637 iconCol.setWidth("20"); 638 iconCol.setAlign(CmsListColumnAlignEnum.ALIGN_CENTER); 639 iconCol.setListItemComparator(new CmsListItemActionIconComparator()); 640 641 // add icon action 642 CmsListDirectAction fileAction = new CmsListResourceIconAction( 643 LIST_ACTION_VIEW, 644 LIST_COLUMN_FILE_TYPE, 645 getCms()) { 646 647 /** 648 * @see org.opencms.workplace.list.CmsListResourceIconAction#defButtonHtml(CmsObject, java.lang.String, java.lang.String, java.lang.String, java.lang.String, boolean, java.lang.String, java.lang.String, java.lang.String, boolean) 649 */ 650 @Override 651 public String defButtonHtml( 652 CmsObject cms, 653 String id, 654 String helpId, 655 String name, 656 String helpText, 657 boolean enabled, 658 String iconPath, 659 String confirmationMessage, 660 String onClick, 661 boolean singleHelp) { 662 663 StringBuffer jsCode = new StringBuffer(512); 664 jsCode.append("window.open('"); 665 CmsVersionWrapper version = (CmsVersionWrapper)getItem().get(LIST_COLUMN_VERSION); 666 667 // is the resource already a sibling already deleted? 668 jsCode.append( 669 OpenCms.getLinkManager().substituteLink( 670 cms, 671 CmsHistoryListUtil.getHistoryLink( 672 cms, 673 new CmsUUID(getItem().get(LIST_COLUMN_STRUCTURE_ID).toString()), 674 version.toString()))); 675 jsCode.append("','version','scrollbars=yes, resizable=yes, width=800, height=600')"); 676 return super.defButtonHtml( 677 cms, 678 id, 679 helpId, 680 name, 681 helpText, 682 enabled, 683 iconPath, 684 confirmationMessage, 685 jsCode.toString(), 686 singleHelp); 687 } 688 689 /** 690 * @see org.opencms.workplace.tools.I_CmsHtmlIconButton#getIconPath() 691 */ 692 @Override 693 public String getIconPath() { 694 695 Boolean isEnabled = (Boolean)getItem().get(LIST_COLUMN_VERSION_ENABLE); 696 if (!isEnabled.booleanValue()) { 697 return "filetypes/plain.gif"; 698 } 699 return super.getIconPath(); 700 701 } 702 703 /** 704 * @see org.opencms.workplace.tools.I_CmsHtmlIconButton#isEnabled() 705 */ 706 @Override 707 public boolean isEnabled() { 708 709 Boolean isEnabled = (Boolean)getItem().get(LIST_COLUMN_VERSION_ENABLE); 710 if (isEnabled.booleanValue()) { 711 return true; 712 } 713 return false; 714 } 715 }; 716 fileAction.setName(Messages.get().container(Messages.GUI_HISTORY_PREVIEW_0)); 717 iconCol.addDirectAction(fileAction); 718 // add it to the list definition 719 metadata.addColumn(iconCol); 720 iconCol.setPrintable(false); 721 722 // add column for version 723 CmsListColumnDefinition versionCol = new CmsListColumnDefinition(LIST_COLUMN_VERSION); 724 versionCol.setName(Messages.get().container(Messages.GUI_HISTORY_COLS_VERSION_0)); 725 versionCol.setWidth("5%"); 726 versionCol.setAlign(CmsListColumnAlignEnum.ALIGN_CENTER); 727 versionCol.setFormatter(new I_CmsListFormatter() { 728 729 /** 730 * @see org.opencms.workplace.list.I_CmsListFormatter#format(java.lang.Object, java.util.Locale) 731 */ 732 public String format(Object data, Locale locale) { 733 734 if ((data == null) || !(data instanceof CmsVersionWrapper)) { 735 return ""; 736 } 737 CmsVersionWrapper version = (CmsVersionWrapper)data; 738 return CmsHistoryListUtil.getDisplayVersion(version.toString(), locale); 739 } 740 741 }); 742 metadata.addColumn(versionCol); 743 744 // add column for file type 745 CmsListColumnDefinition groupCol = new CmsListColumnDefinition(LIST_COLUMN_FILE_TYPE); 746 groupCol.setVisible(false); 747 metadata.addColumn(groupCol); 748 749 // add column for resource path 750 CmsListColumnDefinition pathCol = new CmsListColumnDefinition(LIST_COLUMN_RESOURCE_PATH); 751 pathCol.setName(Messages.get().container(Messages.GUI_HISTORY_COLS_RESOURCE_PATH_0)); 752 pathCol.setAlign(CmsListColumnAlignEnum.ALIGN_LEFT); 753 pathCol.setWidth("40%"); 754 metadata.addColumn(pathCol); 755 756 // add column for date published 757 CmsListColumnDefinition datePublishedCol = new CmsListColumnDefinition(LIST_COLUMN_DATE_PUBLISHED); 758 datePublishedCol.setName(Messages.get().container(Messages.GUI_HISTORY_COLS_DATE_PUBLISHED_0)); 759 datePublishedCol.setWidth("20%"); 760 datePublishedCol.setAlign(CmsListColumnAlignEnum.ALIGN_LEFT); 761 metadata.addColumn(datePublishedCol); 762 763 // add column for date last modified 764 CmsListColumnDefinition nicenameCol = new CmsListColumnDefinition(LIST_COLUMN_DATE_LAST_MODIFIED); 765 nicenameCol.setName(Messages.get().container(Messages.GUI_HISTORY_COLS_DATE_LAST_MODIFIED_0)); 766 nicenameCol.setWidth("20%"); 767 nicenameCol.setAlign(CmsListColumnAlignEnum.ALIGN_LEFT); 768 metadata.addColumn(nicenameCol); 769 770 // add column for user modified 771 CmsListColumnDefinition userCol = new CmsListColumnDefinition(LIST_COLUMN_USER); 772 userCol.setName(Messages.get().container(Messages.GUI_HISTORY_COLS_USER_0)); 773 userCol.setWidth("30%"); 774 userCol.setAlign(CmsListColumnAlignEnum.ALIGN_LEFT); 775 metadata.addColumn(userCol); 776 777 // add column for date last modified 778 CmsListColumnDefinition sizeCol = new CmsListColumnDefinition(LIST_COLUMN_SIZE); 779 sizeCol.setName(Messages.get().container(Messages.GUI_HISTORY_COLS_SIZE_0)); 780 sizeCol.setWidth("10%"); 781 sizeCol.setAlign(CmsListColumnAlignEnum.ALIGN_LEFT); 782 metadata.addColumn(sizeCol); 783 784 // create column for radio button 1 785 CmsListColumnDefinition radioSel1Col = new CmsListColumnDefinition(LIST_COLUMN_SEL1); 786 radioSel1Col.setName(Messages.get().container(Messages.GUI_HISTORY_COLS_VERSION1_0)); 787 radioSel1Col.setWidth("20"); 788 radioSel1Col.setAlign(CmsListColumnAlignEnum.ALIGN_CENTER); 789 radioSel1Col.setSorteable(false); 790 791 // add item selection action 792 CmsListItemSelectionAction sel1Action = new CmsListItemSelectionAction(LIST_RACTION_SEL1, LIST_MACTION_COMPARE); 793 sel1Action.setName(Messages.get().container(Messages.GUI_HISTORY_FIRST_VERSION_0)); 794 sel1Action.setEnabled(true); 795 radioSel1Col.addDirectAction(sel1Action); 796 metadata.addColumn(radioSel1Col); 797 798 // create column for radio button 2 799 CmsListColumnDefinition radioSel2Col = new CmsListColumnDefinition(LIST_COLUMN_SEL2); 800 radioSel2Col.setName(Messages.get().container(Messages.GUI_HISTORY_COLS_VERSION2_0)); 801 radioSel2Col.setWidth("20"); 802 radioSel2Col.setAlign(CmsListColumnAlignEnum.ALIGN_CENTER); 803 radioSel2Col.setSorteable(false); 804 805 // add item selection action 806 CmsListItemSelectionAction sel2Action = new CmsListItemSelectionAction(LIST_RACTION_SEL2, LIST_MACTION_COMPARE); 807 sel2Action.setName(Messages.get().container(Messages.GUI_HISTORY_SECOND_VERSION_0)); 808 sel2Action.setEnabled(true); 809 radioSel2Col.addDirectAction(sel2Action); 810 metadata.addColumn(radioSel2Col); 811 812 // create invisible publish tag column to allow fillDetails to be able to read the proper 813 // historical project 814 CmsListColumnDefinition publishTagCol = new CmsListColumnDefinition(LIST_COLUMN_PUBLISH_TAG); 815 publishTagCol.setSorteable(false); 816 publishTagCol.setVisible(false); 817 metadata.addColumn(publishTagCol); 818 819 // create invisible strcuture id column 820 CmsListColumnDefinition strIdCol = new CmsListColumnDefinition(LIST_COLUMN_STRUCTURE_ID); 821 strIdCol.setSorteable(false); 822 strIdCol.setVisible(false); 823 metadata.addColumn(strIdCol); 824 } 825 826 /** 827 * @see org.opencms.workplace.list.A_CmsListDialog#setIndependentActions(org.opencms.workplace.list.CmsListMetadata) 828 */ 829 @Override 830 protected void setIndependentActions(CmsListMetadata metadata) { 831 832 // add index source details 833 CmsListItemDetails indexDetails = new CmsListItemDetails(GUI_LIST_HISTORY_DETAIL_PROJECT_0); 834 indexDetails.setAtColumn(LIST_COLUMN_VERSION); 835 indexDetails.setVisible(false); 836 indexDetails.setShowActionName(Messages.get().container(Messages.GUI_LIST_HISTORY_DETAIL_PROJECT_NAME_SHOW_0)); 837 indexDetails.setShowActionHelpText( 838 Messages.get().container(Messages.GUI_LIST_HISTORY_DETAIL_PROJECT_SHOW_HELP_0)); 839 indexDetails.setHideActionName(Messages.get().container(Messages.GUI_LIST_HISTORY_DETAIL_PROJECT_NAME_HIDE_0)); 840 indexDetails.setHideActionHelpText( 841 Messages.get().container(Messages.GUI_LIST_HISTORY_DETAIL_PROJECT_HIDE_HELP_0)); 842 indexDetails.setName(Messages.get().container(Messages.GUI_LIST_HISTORY_DETAIL_PROJECT_INFO_0)); 843 indexDetails.setFormatter( 844 new CmsListItemDetailsFormatter(Messages.get().container(Messages.GUI_LIST_HISTORY_DETAIL_PROJECT_INFO_0))); 845 metadata.addItemDetails(indexDetails); 846 } 847 848 /** 849 * @see org.opencms.workplace.list.A_CmsListDialog#setMultiActions(org.opencms.workplace.list.CmsListMetadata) 850 */ 851 @Override 852 protected void setMultiActions(CmsListMetadata metadata) { 853 854 // add compare action 855 CmsListRadioMultiAction compareAction = new CmsListRadioMultiAction( 856 LIST_MACTION_COMPARE, 857 Arrays.asList(new String[] {LIST_RACTION_SEL1, LIST_RACTION_SEL2})); 858 compareAction.setName(Messages.get().container(Messages.GUI_HISTORY_COMPARE_0)); 859 compareAction.setIconPath("tools/ex_history/buttons/compare.png"); 860 metadata.addMultiAction(compareAction); 861 } 862 863 /** 864 * Fills details of the project into the given item. <p> 865 * 866 * @param item the list item to fill 867 * 868 * @param detailId the id for the detail to fill 869 * 870 */ 871 private void fillDetailProject(CmsListItem item, String detailId) { 872 873 StringBuffer html = new StringBuffer(); 874 875 // search /read for the corresponding history project: it's tag id transmitted from getListItems() 876 // in a hidden column 877 Object tagIdObj = item.get(LIST_COLUMN_PUBLISH_TAG); 878 if (tagIdObj != null) { 879 // it is null if the offline version with changes is shown here: now history project available then 880 int tagId = ((Integer)tagIdObj).intValue(); 881 try { 882 CmsHistoryProject project = getCms().readHistoryProject(tagId); 883 // output of project info 884 html.append(project.getName()).append("<br/>").append(project.getDescription()); 885 } catch (CmsException cmse) { 886 html.append(cmse.getMessageContainer().key(getLocale())); 887 } 888 } 889 item.set(detailId, html.toString()); 890 } 891}