001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (https://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: https://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: https://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.file.CmsGroup; 031import org.opencms.file.CmsObject; 032import org.opencms.file.CmsProperty; 033import org.opencms.file.CmsPropertyDefinition; 034import org.opencms.file.CmsResource; 035import org.opencms.file.CmsResourceFilter; 036import org.opencms.jsp.CmsJspActionElement; 037import org.opencms.lock.CmsLockActionRecord; 038import org.opencms.lock.CmsLockActionRecord.LockChange; 039import org.opencms.lock.CmsLockUtil; 040import org.opencms.main.CmsException; 041import org.opencms.main.CmsIllegalArgumentException; 042import org.opencms.main.CmsLog; 043import org.opencms.main.OpenCms; 044import org.opencms.security.CmsAccessControlEntry; 045import org.opencms.security.CmsPermissionSet; 046import org.opencms.security.I_CmsPrincipal; 047import org.opencms.util.CmsStringUtil; 048import org.opencms.widgets.CmsCalendarWidget; 049import org.opencms.workplace.CmsMultiDialog; 050import org.opencms.workplace.CmsWorkplace; 051import org.opencms.workplace.CmsWorkplaceSettings; 052 053import java.text.ParseException; 054import java.util.ArrayList; 055import java.util.Collection; 056import java.util.HashMap; 057import java.util.Iterator; 058import java.util.List; 059import java.util.Map; 060 061import org.apache.commons.logging.Log; 062 063import jakarta.servlet.http.HttpServletRequest; 064import jakarta.servlet.http.HttpServletResponse; 065import jakarta.servlet.jsp.JspException; 066import jakarta.servlet.jsp.PageContext; 067 068/** 069 * Provides methods for the resource availability/notification dialog.<p> 070 * 071 * The following files use this class: 072 * <ul> 073 * <li>/commons/availability.jsp 074 * </ul> 075 * <p> 076 * 077 * @since 6.0.0 078 */ 079public class CmsAvailability extends CmsMultiDialog { 080 081 /** The dialog type. */ 082 public static final String DIALOG_TYPE = "availability"; 083 084 /** Request parameter name for the activation of the notification. */ 085 public static final String PARAM_ENABLE_NOTIFICATION = "enablenotification"; 086 087 /** Request parameter name for the expire date. */ 088 public static final String PARAM_EXPIREDATE = "expiredate"; 089 090 /** Request parameter name for the leave expire. */ 091 public static final String PARAM_LEAVEEXPIRE = "leaveexpire"; 092 093 /** Request parameter name for the leave release. */ 094 public static final String PARAM_LEAVERELEASE = "leaverelease"; 095 096 /** Request parameter name for the include siblings flag. */ 097 public static final String PARAM_MODIFY_SIBLINGS = "modifysiblings"; 098 099 /** Request parameter name for the activation of the notification. */ 100 public static final String PARAM_NOTIFICATION_INTERVAL = "notificationinterval"; 101 102 /** Request parameter name for the recursive flag. */ 103 public static final String PARAM_RECURSIVE = "recursive"; 104 105 /** Request parameter name for the release date. */ 106 public static final String PARAM_RELEASEDATE = "releasedate"; 107 108 /** Request parameter name for the reset expire. */ 109 public static final String PARAM_RESETEXPIRE = "resetexpire"; 110 111 /** Request parameter name for the reset release. */ 112 public static final String PARAM_RESETRELEASE = "resetrelease"; 113 114 /** The log object for this class. */ 115 private static final Log LOG = CmsLog.getLog(CmsAvailability.class); 116 117 /** A parameter of this dialog. */ 118 private String m_paramEnablenotification; 119 120 /** A parameter of this dialog. */ 121 private String m_paramExpiredate; 122 123 /** A parameter of this dialog. */ 124 private String m_paramLeaveexpire; 125 126 /** A parameter of this dialog. */ 127 private String m_paramModifysiblings; 128 129 /** A parameter of this dialog. */ 130 private String m_paramNotificationinterval; 131 132 /** A parameter of this dialog. */ 133 private String m_paramRecursive; 134 135 /** A parameter of this dialog. */ 136 private String m_paramReleasedate; 137 138 /** A parameter of this dialog. */ 139 private String m_paramResetexpire; 140 141 /** A parameter of this dialog. */ 142 private String m_paramResetrelease; 143 144 /** 145 * Public constructor.<p> 146 * 147 * @param jsp an initialized JSP action element 148 */ 149 public CmsAvailability(CmsJspActionElement jsp) { 150 151 super(jsp); 152 } 153 154 /** 155 * Public constructor with JSP variables.<p> 156 * 157 * @param context the JSP page context 158 * @param req the JSP request 159 * @param res the JSP response 160 */ 161 public CmsAvailability(PageContext context, HttpServletRequest req, HttpServletResponse res) { 162 163 this(new CmsJspActionElement(context, req, res)); 164 } 165 166 /** 167 * Performs the notification operations on a single resource.<p> 168 * 169 * @param cms the CMS context 170 * @param resName the VFS path of the resource 171 * @param enableNotification if the notification is activated 172 * @param notificationInterval the notification interval in days 173 * @param modifySiblings flag indicating to include resource siblings 174 * 175 * @throws CmsException if the availability and notification operations fail 176 */ 177 public static void performSingleResourceNotification( 178 CmsObject cms, 179 String resName, 180 boolean enableNotification, 181 int notificationInterval, 182 boolean modifySiblings) 183 throws CmsException { 184 185 List<CmsResource> resources = new ArrayList<CmsResource>(); 186 if (modifySiblings) { 187 // modify all siblings of a resource 188 resources = cms.readSiblings(resName, CmsResourceFilter.IGNORE_EXPIRATION); 189 } else { 190 // modify only resource without siblings 191 resources.add(cms.readResource(resName, CmsResourceFilter.IGNORE_EXPIRATION)); 192 } 193 Iterator<CmsResource> i = resources.iterator(); 194 while (i.hasNext()) { 195 CmsResource resource = i.next(); 196 String resourcePath = cms.getRequestContext().removeSiteRoot(resource.getRootPath()); 197 // lock resource if auto lock is enabled 198 CmsLockActionRecord lockRecord = CmsLockUtil.ensureLock(cms, resource); 199 try { 200 // write notification settings 201 writeProperty( 202 cms, 203 resourcePath, 204 CmsPropertyDefinition.PROPERTY_NOTIFICATION_INTERVAL, 205 String.valueOf(notificationInterval)); 206 writeProperty( 207 cms, 208 resourcePath, 209 CmsPropertyDefinition.PROPERTY_ENABLE_NOTIFICATION, 210 String.valueOf(enableNotification)); 211 } finally { 212 if (lockRecord.getChange() == LockChange.locked) { 213 cms.unlockResource(resource); 214 } 215 } 216 } 217 } 218 219 /** 220 * Writes a property value for a resource.<p> 221 * 222 * @param cms the cms context 223 * @param resourcePath the path of the resource 224 * @param propertyName the name of the property 225 * @param propertyValue the new value of the property 226 * 227 * @throws CmsException if something goes wrong 228 */ 229 public static void writeProperty(CmsObject cms, String resourcePath, String propertyName, String propertyValue) 230 throws CmsException { 231 232 if (CmsStringUtil.isEmpty(propertyValue)) { 233 propertyValue = CmsProperty.DELETE_VALUE; 234 } 235 236 CmsProperty newProp = new CmsProperty(); 237 newProp.setName(propertyName); 238 CmsProperty oldProp = cms.readPropertyObject(resourcePath, propertyName, false); 239 if (oldProp.isNullProperty()) { 240 // property value was not already set 241 if (OpenCms.getWorkplaceManager().isDefaultPropertiesOnStructure()) { 242 newProp.setStructureValue(propertyValue); 243 } else { 244 newProp.setResourceValue(propertyValue); 245 } 246 } else { 247 if (oldProp.getStructureValue() != null) { 248 newProp.setStructureValue(propertyValue); 249 newProp.setResourceValue(oldProp.getResourceValue()); 250 } else { 251 newProp.setResourceValue(propertyValue); 252 } 253 } 254 255 newProp.setAutoCreatePropertyDefinition(true); 256 257 String oldStructureValue = oldProp.getStructureValue(); 258 String newStructureValue = newProp.getStructureValue(); 259 if (CmsStringUtil.isEmpty(oldStructureValue)) { 260 oldStructureValue = CmsProperty.DELETE_VALUE; 261 } 262 if (CmsStringUtil.isEmpty(newStructureValue)) { 263 newStructureValue = CmsProperty.DELETE_VALUE; 264 } 265 266 String oldResourceValue = oldProp.getResourceValue(); 267 String newResourceValue = newProp.getResourceValue(); 268 if (CmsStringUtil.isEmpty(oldResourceValue)) { 269 oldResourceValue = CmsProperty.DELETE_VALUE; 270 } 271 if (CmsStringUtil.isEmpty(newResourceValue)) { 272 newResourceValue = CmsProperty.DELETE_VALUE; 273 } 274 275 // change property only if it has been changed 276 if (!oldResourceValue.equals(newResourceValue) || !oldStructureValue.equals(newStructureValue)) { 277 cms.writePropertyObject(resourcePath, newProp); 278 } 279 } 280 281 /** 282 * 283 * @see org.opencms.workplace.CmsDialog#actionCloseDialog() 284 */ 285 @Override 286 public void actionCloseDialog() throws JspException { 287 288 // so that the explorer will be shown, if dialog is opened from e-mail 289 getSettings().getFrameUris().put("body", CmsWorkplace.VFS_PATH_VIEWS + "explorer/explorer_fs.jsp"); 290 super.actionCloseDialog(); 291 } 292 293 /** 294 * Performs the resource operation, will be called by the JSP page.<p> 295 * 296 * @throws JspException if problems including sub-elements occur 297 */ 298 public void actionUpdate() throws JspException { 299 300 // save initialized instance of this class in request attribute for included sub-elements 301 getJsp().getRequest().setAttribute(SESSION_WORKPLACE_CLASS, this); 302 303 try { 304 if (performDialogOperation()) { 305 // if no exception is caused and "true" is returned the dialog operation was successful 306 actionCloseDialog(); 307 } else { 308 // "false" returned, display "please wait" screen 309 getJsp().include(FILE_DIALOG_SCREEN_WAIT); 310 } 311 } catch (Throwable e) { 312 includeErrorpage(this, e); 313 } 314 } 315 316 /** 317 * Creates the check box to enable content notification for a resource.<p> 318 * 319 * @return HTML code for the enable_notification check box. 320 */ 321 public String buildCheckboxEnableNotification() { 322 323 String propVal = null; 324 if (!isMultiOperation()) { 325 // get current settings for single resource dialog 326 try { 327 propVal = getCms().readPropertyObject( 328 getParamResource(), 329 CmsPropertyDefinition.PROPERTY_ENABLE_NOTIFICATION, 330 false).getValue(); 331 } catch (CmsException e) { 332 if (LOG.isInfoEnabled()) { 333 LOG.info(e.getLocalizedMessage()); 334 } 335 } 336 337 } 338 if (CmsStringUtil.isEmpty(propVal)) { 339 propVal = CmsStringUtil.FALSE; 340 } 341 StringBuffer result = new StringBuffer(512); 342 result.append("<input type=\"checkbox\" style=\"text-align:left\" name=\""); 343 result.append(PARAM_ENABLE_NOTIFICATION); 344 if (Boolean.valueOf(propVal).booleanValue()) { 345 result.append("\" checked=\"checked"); 346 } 347 result.append("\" value=\"true\">"); 348 return result.toString(); 349 } 350 351 /** 352 * Creates an the check box to modify all siblings.<p> 353 * 354 * If no siblings exist for this resource, an empty string will be returned. 355 * 356 * @return HTML code for the modify siblings check box. 357 */ 358 public String buildCheckboxModifySiblings() { 359 360 StringBuffer result = new StringBuffer(254); 361 try { 362 if (isMultiOperation() || (getCms().readSiblings(getParamResource(), CmsResourceFilter.ALL).size() > 1)) { 363 result.append("<tr>\n<td style=\"white-space:nowrap;\">"); 364 result.append(key(Messages.GUI_AVAILABILITY_MODIFY_SIBLINGS_0)); 365 result.append("</td>\n<td class=\"maxwidth\" style=\"padding-left: 5px;\">\n"); 366 result.append("<input type=\"checkbox\" name=\""); 367 result.append(PARAM_MODIFY_SIBLINGS); 368 result.append("\" value=\"true\" style=\"text-align:left\">\n</td>\n<td> </td></tr>"); 369 } 370 } catch (CmsException e) { 371 if (LOG.isInfoEnabled()) { 372 LOG.info(e.getLocalizedMessage(), e); 373 } 374 } 375 return result.toString(); 376 } 377 378 /** 379 * Creates the "recursive" check box for touching subresources of folders.<p> 380 * 381 * @return the String with the check box input field or an empty String for folders. 382 */ 383 public String buildCheckRecursive() { 384 385 StringBuffer result = new StringBuffer(256); 386 387 // show the check box only for operation(s) on folder(s) 388 if (isOperationOnFolder()) { 389 result.append(dialogBlockStart(key(Messages.GUI_AVAILABILITY_NOTIFICATION_SUBRES_0))); 390 result.append("<table border=\"0\">"); 391 result.append("<tr>\n\t<td style=\"white-space:nowrap;\">"); 392 result.append(key(Messages.GUI_TOUCH_MODIFY_SUBRESOURCES_0)); 393 result.append( 394 "</td><td class=\"maxwidth\" style=\"padding-left: 5px;\"><input type=\"checkbox\" style=\"text-align:left\" name=\""); 395 result.append(PARAM_RECURSIVE); 396 result.append("\" value=\"true\"> </td>\n<td> </td></tr>\n"); 397 result.append("</table>"); 398 result.append(dialogBlockEnd()); 399 result.append(dialogSpacer()); 400 } 401 return result.toString(); 402 } 403 404 /** 405 * Creates an input field for the notification interval.<p> 406 * 407 * @return HTML code for the notification interval input field. 408 */ 409 public String buildInputNotificationInterval() { 410 411 String propVal = null; 412 if (!isMultiOperation()) { 413 try { 414 propVal = getCms().readPropertyObject( 415 getParamResource(), 416 CmsPropertyDefinition.PROPERTY_NOTIFICATION_INTERVAL, 417 false).getValue(); 418 } catch (CmsException e) { 419 if (LOG.isInfoEnabled()) { 420 LOG.info(e.getLocalizedMessage()); 421 } 422 } 423 } 424 if (CmsStringUtil.isEmpty(propVal)) { 425 propVal = ""; 426 } 427 StringBuffer result = new StringBuffer(); 428 429 result.append("<input class=\"maxwidth\" type=\"text\" name=\""); 430 result.append(CmsAvailability.PARAM_NOTIFICATION_INTERVAL); 431 result.append("\" value=\""); 432 result.append(propVal); 433 result.append("\">"); 434 return result.toString(); 435 } 436 437 /** 438 * Builds a String with HTML code to display the responsibles of a resource.<p> 439 * 440 * @return HTML code for the responsibles of the current resource 441 */ 442 public String buildResponsibleList() { 443 444 if (isMultiOperation()) { 445 // show no responsibles list for multi operation 446 return ""; 447 } else { 448 // single resource operation, create list of responsibles 449 StringBuffer result = new StringBuffer(512); 450 result.append("<tr><td colspan=\"3\">"); 451 List<CmsResource> parentResources = new ArrayList<CmsResource>(); 452 Map<I_CmsPrincipal, String> responsibles = new HashMap<I_CmsPrincipal, String>(); 453 CmsObject cms = getCms(); 454 String resourceSitePath = cms.getRequestContext().removeSiteRoot(getParamResource()); 455 try { 456 // get all parent folders of the current file 457 parentResources = cms.readPath(getParamResource(), CmsResourceFilter.IGNORE_EXPIRATION); 458 } catch (CmsException e) { 459 // can usually be ignored 460 if (LOG.isInfoEnabled()) { 461 LOG.info(e.getLocalizedMessage()); 462 } 463 } 464 Iterator<CmsResource> i = parentResources.iterator(); 465 while (i.hasNext()) { 466 CmsResource resource = i.next(); 467 try { 468 String sitePath = cms.getRequestContext().removeSiteRoot(resource.getRootPath()); 469 Iterator<CmsAccessControlEntry> entries = cms.getAccessControlEntries(sitePath, false).iterator(); 470 while (entries.hasNext()) { 471 CmsAccessControlEntry ace = entries.next(); 472 if (ace.isResponsible()) { 473 I_CmsPrincipal principal = cms.lookupPrincipal(ace.getPrincipal()); 474 if (principal != null) { 475 responsibles.put(principal, resourceSitePath.equals(sitePath) ? null : sitePath); 476 } 477 } 478 } 479 } catch (CmsException e) { 480 // can usually be ignored 481 if (LOG.isInfoEnabled()) { 482 LOG.info(e.getLocalizedMessage()); 483 } 484 } 485 } 486 487 if (responsibles.size() == 0) { 488 // no responsibles found 489 result.append(key(Messages.GUI_AVAILABILITY_NO_RESPONSIBLES_0)); 490 } else { 491 // found responsibles, create list 492 result.append(dialogToggleStart(key(Messages.GUI_AVAILABILITY_RESPONSIBLES_0), "responsibles", false)); 493 Collection<String> parentFolders = new ArrayList<String>(responsibles.values()); 494 parentFolders.remove(null); 495 if (parentFolders.size() > 0) { 496 result.append("<table border=\"0\">\n<tr>\n\t<td>"); 497 result.append(key(Messages.GUI_PERMISSION_SELECT_VIEW_0)); 498 result.append("</td>\n<td><input type=\"button\" onclick=\"toggleInheritInfo();\" value=\""); 499 result.append(key(Messages.GUI_LABEL_DETAILS_0)); 500 result.append("\" id=\"button\"/></td></tr></table>"); 501 } 502 result.append(dialogWhiteBoxStart()); 503 Iterator<Map.Entry<I_CmsPrincipal, String>> it = responsibles.entrySet().iterator(); 504 for (int j = 0; it.hasNext(); j++) { 505 Map.Entry<I_CmsPrincipal, String> entry = it.next(); 506 I_CmsPrincipal principal = entry.getKey(); 507 String image = "user.png"; 508 String localizedType = getLocalizedType(CmsAccessControlEntry.ACCESS_FLAGS_USER); 509 if (principal instanceof CmsGroup) { 510 image = "group.png"; 511 localizedType = getLocalizedType(CmsAccessControlEntry.ACCESS_FLAGS_GROUP); 512 } 513 result.append("<div class=\"dialogrow\"><img src=\""); 514 result.append(getSkinUri()); 515 result.append("commons/"); 516 result.append(image); 517 result.append("\" class=\"noborder\" width=\"16\" height=\"16\" alt=\""); 518 result.append(localizedType); 519 result.append("\" title=\""); 520 result.append(localizedType); 521 result.append("\"> <span class=\"textbold\">"); 522 result.append(principal.getName()); 523 result.append("</span><div class=\"hide\" id=\"inheritinfo"); 524 result.append(j); 525 result.append("\"><div class=\"dialogpermissioninherit\">"); 526 String resourceName = entry.getValue(); 527 if (CmsStringUtil.isNotEmpty(resourceName)) { 528 result.append(key(Messages.GUI_PERMISSION_INHERITED_FROM_1, new Object[] {resourceName})); 529 } 530 result.append("</div></div></div>\n"); 531 } 532 result.append(dialogWhiteBoxEnd()); 533 result.append("</div>\n"); 534 result.append("</td></tr>"); 535 } 536 return result.toString(); 537 } 538 } 539 540 /** 541 * Returns the current date and time as String formatted in localized pattern.<p> 542 * 543 * @return the current date and time as String formatted in localized pattern 544 */ 545 public String getCurrentDateTime() { 546 547 // get the current date & time 548 return CmsCalendarWidget.getCalendarLocalizedTime(getLocale(), getMessages(), System.currentTimeMillis()); 549 } 550 551 /** 552 * Returns the current expire date as String formatted in localized pattern.<p> 553 * 554 * @return the current expire date as String formatted in localized pattern 555 */ 556 public String getCurrentExpireDate() { 557 558 // get the expiration date 559 if (isMultiOperation()) { 560 return CmsTouch.DEFAULT_DATE_STRING; 561 } else { 562 try { 563 CmsResource res = getCms().readResource(getParamResource(), CmsResourceFilter.IGNORE_EXPIRATION); 564 if (res.getDateExpired() == CmsResource.DATE_EXPIRED_DEFAULT) { 565 return CmsTouch.DEFAULT_DATE_STRING; 566 } else { 567 return CmsCalendarWidget.getCalendarLocalizedTime(getLocale(), getMessages(), res.getDateExpired()); 568 } 569 } catch (CmsException e) { 570 return CmsCalendarWidget.getCalendarLocalizedTime( 571 getLocale(), 572 getMessages(), 573 System.currentTimeMillis()); 574 } 575 } 576 } 577 578 /** 579 * Returns the current release date as String formatted in localized pattern.<p> 580 * 581 * @return the current release date as String formatted in localized pattern 582 */ 583 public String getCurrentReleaseDate() { 584 585 // get the release date 586 if (isMultiOperation()) { 587 return CmsTouch.DEFAULT_DATE_STRING; 588 } else { 589 try { 590 CmsResource res = getCms().readResource(getParamResource(), CmsResourceFilter.IGNORE_EXPIRATION); 591 if (res.getDateReleased() == CmsResource.DATE_RELEASED_DEFAULT) { 592 return CmsTouch.DEFAULT_DATE_STRING; 593 } else { 594 return CmsCalendarWidget.getCalendarLocalizedTime( 595 getLocale(), 596 getMessages(), 597 res.getDateReleased()); 598 } 599 } catch (CmsException e) { 600 return CmsCalendarWidget.getCalendarLocalizedTime( 601 getLocale(), 602 getMessages(), 603 System.currentTimeMillis()); 604 } 605 } 606 } 607 608 /** 609 * Returns the value of the enable_notification parameter.<p> 610 * 611 * The enable_notification parameter if content notification is enabled for this resource.<p> 612 * 613 * @return the value of the enable_notification parameter 614 */ 615 public String getParamEnablenotification() { 616 617 return m_paramEnablenotification; 618 } 619 620 /** 621 * Returns the value of the new expire date parameter, 622 * or null if this parameter was not provided.<p> 623 * 624 * @return the value of the new expire date parameter 625 */ 626 public String getParamExpiredate() { 627 628 return m_paramExpiredate; 629 } 630 631 /** 632 * Returns the value of the leave expire parameter.<p> 633 * 634 * @return the value of the leave expire parameter 635 */ 636 public String getParamLeaveexpire() { 637 638 return m_paramLeaveexpire; 639 } 640 641 /** 642 * Returns the value of the modify siblings parameter, 643 * or null if this parameter was not provided.<p> 644 * 645 * @return the value of the modify siblings 646 */ 647 public String getParamModifysiblings() { 648 649 return m_paramModifysiblings; 650 } 651 652 /** 653 * Returns the value of the notification interval parameter, 654 * or null if this parameter was not provided.<p> 655 * 656 * @return the value of the notification interval parameter 657 */ 658 public String getParamNotificationinterval() { 659 660 return m_paramNotificationinterval; 661 } 662 663 /** 664 * Returns the value of the recursive parameter, 665 * or null if this parameter was not provided.<p> 666 * 667 * The recursive parameter on folders decides if all subresources 668 * of the folder should be touched, too.<p> 669 * 670 * @return the value of the recursive parameter 671 */ 672 public String getParamRecursive() { 673 674 return m_paramRecursive; 675 } 676 677 /** 678 * Returns the value of the new release date parameter, 679 * or null if this parameter was not provided.<p> 680 * 681 * The release date parameter stores the new release date as String.<p> 682 * 683 * @return the value of the new release date parameter 684 */ 685 public String getParamReleasedate() { 686 687 return m_paramReleasedate; 688 } 689 690 /** 691 * Returns the value of the reset expire parameter.<p> 692 * 693 * @return the value of the reset expire parameter 694 */ 695 public String getParamResetexpire() { 696 697 return m_paramResetexpire; 698 } 699 700 /** 701 * Returns the value of the reset release parameter.<p> 702 * 703 * @return the value of the reset release parameter 704 */ 705 public String getParamResetrelease() { 706 707 return m_paramResetrelease; 708 } 709 710 /** 711 * Sets the value of the enable notification parameter.<p> 712 * 713 * @param value the value to set 714 */ 715 public void setParamEnablenotification(String value) { 716 717 m_paramEnablenotification = value; 718 } 719 720 /** 721 * Sets the value of the expire date.<p> 722 * 723 * @param value the value to set 724 */ 725 public void setParamExpiredate(String value) { 726 727 m_paramExpiredate = value; 728 } 729 730 /** 731 * Sets the value of the leave expire parameter.<p> 732 * 733 * @param paramLeaveexpire the value of the leave expire parameter 734 */ 735 public void setParamLeaveexpire(String paramLeaveexpire) { 736 737 m_paramLeaveexpire = paramLeaveexpire; 738 } 739 740 /** 741 * Sets the value of the modify siblings parameter.<p> 742 * 743 * @param value the value to set 744 */ 745 public void setParamModifysiblings(String value) { 746 747 m_paramModifysiblings = value; 748 } 749 750 /** 751 * Sets the value of the new time stamp parameter.<p> 752 * 753 * @param value the value to set 754 */ 755 public void setParamNotificationinterval(String value) { 756 757 m_paramNotificationinterval = value; 758 } 759 760 /** 761 * Sets the value of the recursive parameter.<p> 762 * 763 * @param value the value to set 764 */ 765 public void setParamRecursive(String value) { 766 767 m_paramRecursive = value; 768 } 769 770 /** 771 * Sets the value of the release date parameter.<p> 772 * 773 * @param value the value to set 774 */ 775 public void setParamReleasedate(String value) { 776 777 m_paramReleasedate = value; 778 } 779 780 /** 781 * Sets the value of the reset expire parameter.<p> 782 * 783 * @param paramResetexpire the value of the reset expire parameter 784 */ 785 public void setParamResetexpire(String paramResetexpire) { 786 787 m_paramResetexpire = paramResetexpire; 788 } 789 790 /** 791 * Sets the value of the reset release parameter.<p> 792 * 793 * @param paramResetrelease the value of the reset release parameter 794 */ 795 public void setParamResetrelease(String paramResetrelease) { 796 797 m_paramResetrelease = paramResetrelease; 798 } 799 800 /** 801 * Returns a localized String for "Group", if the flag of a group ACE, and the localization for "User" otherwise.<p> 802 * 803 * @param flags the flags of the ACE 804 * 805 * @return localization for "Group", if the flag belongs to a group ACE 806 */ 807 protected String getLocalizedType(int flags) { 808 809 if ((flags & CmsAccessControlEntry.ACCESS_FLAGS_USER) > 0) { 810 return key(Messages.GUI_LABEL_USER_0); 811 } else { 812 return key(Messages.GUI_LABEL_GROUP_0); 813 } 814 } 815 816 /** 817 * @see org.opencms.workplace.CmsWorkplace#initWorkplaceRequestValues(org.opencms.workplace.CmsWorkplaceSettings, jakarta.servlet.http.HttpServletRequest) 818 */ 819 @Override 820 protected void initWorkplaceRequestValues(CmsWorkplaceSettings settings, HttpServletRequest request) { 821 822 // fill the parameter values in the get/set methods 823 fillParamValues(request); 824 825 // check the required permissions to modify the resource 826 if (!checkResourcePermissions(CmsPermissionSet.ACCESS_WRITE, false)) { 827 // no write permissions for the resource, set cancel action to close dialog 828 setParamAction(DIALOG_CANCEL); 829 } 830 831 // set the dialog type 832 setParamDialogtype(DIALOG_TYPE); 833 834 // set the action for the JSP switch 835 if (DIALOG_TYPE.equals(getParamAction())) { 836 setAction(ACTION_OK); 837 } else if (DIALOG_WAIT.equals(getParamAction())) { 838 setAction(ACTION_WAIT); 839 } else if (DIALOG_LOCKS_CONFIRMED.equals(getParamAction())) { 840 setAction(ACTION_LOCKS_CONFIRMED); 841 } else if (DIALOG_CANCEL.equals(getParamAction())) { 842 setAction(ACTION_CANCEL); 843 } else { 844 setAction(ACTION_DEFAULT); 845 // build title for dialog 846 setDialogTitle( 847 Messages.GUI_AVAILABILITY_NOTIFICATION_SETTINGS_1, 848 Messages.GUI_AVAILABILITY_NOTIFICATION_MULTI_2); 849 } 850 } 851 852 /** 853 * Modifies the release and expire date of a resource, and changes the notification interval. <p> 854 * 855 * @return true, if the operation was performed, otherwise false 856 * @throws CmsException if modification is not successful 857 */ 858 @Override 859 protected boolean performDialogOperation() throws CmsException { 860 861 // check if the current resource is a folder for single operation 862 boolean isFolder = isOperationOnFolder(); 863 // on folder deletion or multi operation display "please wait" screen, not for simple file deletion 864 if ((isMultiOperation() || isFolder) && !DIALOG_WAIT.equals(getParamAction())) { 865 // return false, this will trigger the "please wait" screen 866 return false; 867 } 868 869 // get the new release date for the resource(s) from request parameter 870 long releaseDate = CmsResource.DATE_RELEASED_DEFAULT; 871 boolean resetReleaseDate = Boolean.valueOf(getParamResetrelease()).booleanValue(); 872 boolean leaveReleaseDate = false; 873 if (!resetReleaseDate) { 874 try { 875 if ((CmsStringUtil.isNotEmptyOrWhitespaceOnly(getParamReleasedate())) 876 && (!getParamReleasedate().startsWith(CmsTouch.DEFAULT_DATE_STRING))) { 877 releaseDate = CmsCalendarWidget.getCalendarDate(getMessages(), getParamReleasedate(), true); 878 } else { 879 leaveReleaseDate = true; 880 } 881 } catch (ParseException e) { 882 throw new CmsException( 883 Messages.get().container(Messages.ERR_PARSE_RELEASEDATE_1, getParamReleasedate()), 884 e); 885 } 886 } 887 888 // get the new expire date for the resource(s) from request parameter 889 long expireDate = CmsResource.DATE_EXPIRED_DEFAULT; 890 boolean resetExpireDate = Boolean.valueOf(getParamResetexpire()).booleanValue(); 891 boolean leaveExpireDate = false; 892 if (!resetExpireDate) { 893 try { 894 if ((CmsStringUtil.isNotEmptyOrWhitespaceOnly(getParamExpiredate())) 895 && (!getParamExpiredate().startsWith(CmsTouch.DEFAULT_DATE_STRING))) { 896 expireDate = CmsCalendarWidget.getCalendarDate(getMessages(), getParamExpiredate(), true); 897 } else { 898 leaveExpireDate = true; 899 } 900 } catch (ParseException e) { 901 throw new CmsException( 902 Messages.get().container(Messages.ERR_PARSE_EXPIREDATE_1, getParamExpiredate()), 903 e); 904 } 905 } 906 907 // get the flag if the operation is recursive from request parameter 908 boolean modifyRecursive = Boolean.valueOf(getParamRecursive()).booleanValue(); 909 910 // now iterate the resource(s) 911 Iterator<String> i = getResourceList().iterator(); 912 while (i.hasNext()) { 913 String resName = i.next(); 914 try { 915 performSingleResourceAvailability( 916 resName, 917 releaseDate, 918 expireDate, 919 leaveReleaseDate, 920 leaveExpireDate, 921 modifyRecursive); 922 } catch (CmsException e) { 923 // collect exceptions to create a detailed output 924 addMultiOperationException(e); 925 } 926 } 927 928 boolean notificationEnabled = Boolean.valueOf(getParamEnablenotification()).booleanValue(); 929 int notificationInterval = 0; 930 try { 931 notificationInterval = Integer.parseInt(getParamNotificationinterval()); 932 } catch (Throwable e) { 933 // ignore 934 } 935 936 // get the flag if the operation should be executed on resource siblings, too 937 boolean modifySiblings = Boolean.valueOf(getParamModifysiblings()).booleanValue(); 938 939 // now iterate the resource(s) 940 i = getResourceList().iterator(); 941 while (i.hasNext()) { 942 String resName = i.next(); 943 try { 944 performSingleResourceNotification( 945 getCms(), 946 resName, 947 notificationEnabled, 948 notificationInterval, 949 modifySiblings); 950 } catch (CmsException e) { 951 // collect exceptions to create a detailed output 952 addMultiOperationException(e); 953 } 954 } 955 checkMultiOperationException(Messages.get(), Messages.ERR_AVAILABILITY_MULTI_0); 956 957 return true; 958 } 959 960 /** 961 * Performs the availability operations on a single resource.<p> 962 * 963 * @param resName the VFS path of the resource 964 * @param releaseDate the new release date 965 * @param expireDate the new expiration date 966 * @param leaveRelease if the release date should be left untouched 967 * @param leaveExpire if the expiration date should be left untouched 968 * @param modifyRecursive flag indicating if the operation is recursive for folders 969 * 970 * @throws CmsException if the availability and notification operations fail 971 */ 972 protected void performSingleResourceAvailability( 973 String resName, 974 long releaseDate, 975 long expireDate, 976 boolean leaveRelease, 977 boolean leaveExpire, 978 boolean modifyRecursive) 979 throws CmsException { 980 981 CmsResource resource = getCms().readResource(resName, CmsResourceFilter.IGNORE_EXPIRATION); 982 if (leaveRelease) { 983 releaseDate = resource.getDateReleased(); 984 } 985 if (leaveExpire) { 986 expireDate = resource.getDateExpired(); 987 } 988 if (expireDate < releaseDate) { 989 throw new CmsIllegalArgumentException(Messages.get().container(Messages.ERR_AVAILABILITY_BAD_TIMEWINDOW_0)); 990 } 991 String resourcePath = getCms().getSitePath(resource); 992 // lock resource if auto lock is enabled 993 checkLock(resourcePath); 994 // modify release and expire date of the resource if needed 995 if (!leaveRelease) { 996 getCms().setDateReleased(resourcePath, releaseDate, modifyRecursive); 997 } 998 if (!leaveExpire) { 999 getCms().setDateExpired(resourcePath, expireDate, modifyRecursive); 1000 } 1001 } 1002}