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.file.CmsFile; 031import org.opencms.file.CmsObject; 032import org.opencms.file.CmsResource; 033import org.opencms.file.CmsResourceFilter; 034import org.opencms.jsp.CmsJspActionElement; 035import org.opencms.main.CmsException; 036import org.opencms.security.CmsPermissionSet; 037import org.opencms.util.CmsStringUtil; 038import org.opencms.widgets.CmsCalendarWidget; 039import org.opencms.workplace.CmsMultiDialog; 040import org.opencms.workplace.CmsWorkplaceSettings; 041 042import java.text.ParseException; 043import java.util.Iterator; 044 045import javax.servlet.http.HttpServletRequest; 046import javax.servlet.http.HttpServletResponse; 047import javax.servlet.jsp.JspException; 048import javax.servlet.jsp.PageContext; 049 050/** 051 * Provides methods for the touch resource(s) dialog.<p> 052 * 053 * The following files use this class: 054 * <ul> 055 * <li>/commons/touch.jsp 056 * </ul> 057 * <p> 058 * 059 * @since 6.0.0 060 */ 061public class CmsTouch extends CmsMultiDialog { 062 063 /** Value for the action: touch. */ 064 public static final int ACTION_TOUCH = 100; 065 066 /** Default value for date last modified, the release and expire date. */ 067 public static final String DEFAULT_DATE_STRING = "-"; 068 069 /** The dialog type. */ 070 public static final String DIALOG_TYPE = "touch"; 071 072 /** Request parameter name for the content flag. */ 073 public static final String PARAM_CONTENT = "content"; 074 075 /** Request parameter name for timestamp. */ 076 public static final String PARAM_NEWTIMESTAMP = "newtimestamp"; 077 078 /** Request parameter name for the recursive flag. */ 079 public static final String PARAM_RECURSIVE = "recursive"; 080 081 /** Content parameter. */ 082 private String m_paramContent; 083 084 /** Timestamp parameter. */ 085 private String m_paramNewtimestamp; 086 087 /** Recursive parameter. */ 088 private String m_paramRecursive; 089 090 /** 091 * Public constructor.<p> 092 * 093 * @param jsp an initialized JSP action element 094 */ 095 public CmsTouch(CmsJspActionElement jsp) { 096 097 super(jsp); 098 } 099 100 /** 101 * Public constructor with JSP variables.<p> 102 * 103 * @param context the JSP page context 104 * @param req the JSP request 105 * @param res the JSP response 106 */ 107 public CmsTouch(PageContext context, HttpServletRequest req, HttpServletResponse res) { 108 109 this(new CmsJspActionElement(context, req, res)); 110 } 111 112 /** 113 * Performs a touch operation for a single resource.<p> 114 * 115 * @param resourceName the resource name of the resource to touch 116 * @param timeStamp the new time stamp 117 * @param recursive the flag if the touch operation is recursive 118 * @param correctDate the flag if the new time stamp is a correct date 119 * @param touchContent if the content has to be rewritten 120 * 121 * @throws CmsException if touching the resource fails 122 */ 123 public static void touchSingleResource( 124 CmsObject cms, 125 String resourceName, 126 long timeStamp, 127 boolean recursive, 128 boolean correctDate, 129 boolean touchContent) throws CmsException { 130 131 CmsResource sourceRes = cms.readResource(resourceName, CmsResourceFilter.ALL); 132 if (!correctDate) { 133 // no date value entered, use current resource modification date 134 timeStamp = sourceRes.getDateLastModified(); 135 } 136 cms.setDateLastModified(resourceName, timeStamp, recursive); 137 138 if (touchContent) { 139 if (sourceRes.isFile()) { 140 hardTouch(cms, sourceRes); 141 } else if (recursive) { 142 Iterator<CmsResource> it = cms.readResources(resourceName, CmsResourceFilter.ALL, true).iterator(); 143 while (it.hasNext()) { 144 CmsResource subRes = it.next(); 145 if (subRes.isFile()) { 146 hardTouch(cms, subRes); 147 } 148 } 149 } 150 } 151 } 152 153 /** 154 * Rewrites the content of the given file.<p> 155 * 156 * @param resource the resource to rewrite the content for 157 * 158 * @throws CmsException if something goes wrong 159 */ 160 private static void hardTouch(CmsObject cms, CmsResource resource) throws CmsException { 161 162 CmsFile file = cms.readFile(resource); 163 file.setContents(file.getContents()); 164 cms.writeFile(file); 165 } 166 167 /** 168 * Performs the resource touching, will be called by the JSP page.<p> 169 * 170 * @throws JspException if problems including sub-elements occur 171 */ 172 public void actionTouch() throws JspException { 173 174 // save initialized instance of this class in request attribute for included sub-elements 175 getJsp().getRequest().setAttribute(SESSION_WORKPLACE_CLASS, this); 176 try { 177 if (performDialogOperation()) { 178 // if no exception is caused and "true" is returned the touch operation was successful 179 actionCloseDialog(); 180 } else { 181 // "false" returned, display "please wait" screen 182 getJsp().include(FILE_DIALOG_SCREEN_WAIT); 183 } 184 } catch (Throwable e) { 185 includeErrorpage(this, e); 186 } 187 } 188 189 /** 190 * Creates the "rewrite content" checkbox.<p> 191 * 192 * @return the String with the checkbox input field 193 */ 194 public String buildCheckContent() { 195 196 StringBuffer retValue = new StringBuffer(256); 197 198 retValue.append("<tr>\n\t<td colspan=\"3\" style=\"white-space: nowrap;\" unselectable=\"on\">"); 199 retValue.append("<input type=\"checkbox\" name=\""); 200 retValue.append(PARAM_CONTENT); 201 retValue.append("\" value=\"true\"> "); 202 retValue.append(key(Messages.GUI_TOUCH_MODIFY_CONTENT_0)); 203 retValue.append("</td>\n</tr>\n"); 204 return retValue.toString(); 205 } 206 207 /** 208 * Creates the "recursive" checkbox for touching subresources of folders.<p> 209 * 210 * @return the String with the checkbox input field or an empty String for folders. 211 */ 212 public String buildCheckRecursive() { 213 214 StringBuffer retValue = new StringBuffer(256); 215 216 // show the checkbox only for folders 217 if (isOperationOnFolder()) { 218 retValue.append("<tr>\n\t<td colspan=\"3\" style=\"white-space: nowrap;\" unselectable=\"on\">"); 219 retValue.append("<input type=\"checkbox\" name=\""); 220 retValue.append(PARAM_RECURSIVE); 221 retValue.append("\" value=\"true\"> "); 222 retValue.append(key(Messages.GUI_TOUCH_MODIFY_SUBRESOURCES_0)); 223 retValue.append("</td>\n</tr>\n"); 224 } 225 return retValue.toString(); 226 } 227 228 /** 229 * Creates the HTML JavaScript and stylesheet includes required by the calendar for the head of the page.<p> 230 * 231 * @return the necessary HTML code for the js and stylesheet includes 232 * 233 * @deprecated use {@link CmsCalendarWidget#calendarIncludes(java.util.Locale)}, this is just here so that old JSP still work 234 */ 235 @Deprecated 236 public String calendarIncludes() { 237 238 return CmsCalendarWidget.calendarIncludes(getLocale()); 239 } 240 241 /** 242 * Generates the HTML to initialize the JavaScript calendar element on the end of a page.<p> 243 * 244 * @param inputFieldId the ID of the input field where the date is pasted to 245 * @param triggerButtonId the ID of the button which triggers the calendar 246 * @param align initial position of the calendar popup element 247 * @param singleClick if true, a single click selects a date and closes the calendar, otherwise calendar is closed by doubleclick 248 * @param weekNumbers show the week numbers in the calendar or not 249 * @param mondayFirst show monday as first day of week 250 * @param dateStatusFunc name of the function which determines if/how a date should be disabled 251 * @param showTime true if the time selector should be shown, otherwise false 252 * @return the HTML code to initialize a calendar poup element 253 * 254 * @deprecated use {@link CmsCalendarWidget#calendarInit(org.opencms.i18n.CmsMessages, String, String, String, boolean, boolean, boolean, String, boolean)}, this is just here so that old JSP still work 255 */ 256 @Deprecated 257 public String calendarInit( 258 String inputFieldId, 259 String triggerButtonId, 260 String align, 261 boolean singleClick, 262 boolean weekNumbers, 263 boolean mondayFirst, 264 String dateStatusFunc, 265 boolean showTime) { 266 267 return CmsCalendarWidget.calendarInit( 268 getMessages(), 269 inputFieldId, 270 triggerButtonId, 271 align, 272 singleClick, 273 weekNumbers, 274 mondayFirst, 275 dateStatusFunc, 276 showTime); 277 } 278 279 /** 280 * Returns the current date and time as String formatted in localized pattern.<p> 281 * 282 * @return the current date and time as String formatted in localized pattern 283 */ 284 public String getCurrentDateTime() { 285 286 // get the current date & time 287 return CmsCalendarWidget.getCalendarLocalizedTime(getLocale(), getMessages(), System.currentTimeMillis()); 288 } 289 290 /** 291 * Returns the value of the content parameter, 292 * or null if this parameter was not provided.<p> 293 * 294 * The content parameter on files decides if also the content is rewritten.<p> 295 * 296 * @return the value of the content parameter 297 */ 298 public String getParamContent() { 299 300 return m_paramContent; 301 } 302 303 /** 304 * Returns the value of the new timestamp parameter, 305 * or null if this parameter was not provided.<p> 306 * 307 * The timestamp parameter stores the new timestamp as String.<p> 308 * 309 * @return the value of the new timestamp parameter 310 */ 311 public String getParamNewtimestamp() { 312 313 return m_paramNewtimestamp; 314 } 315 316 /** 317 * Returns the value of the recursive parameter, 318 * or null if this parameter was not provided.<p> 319 * 320 * The recursive parameter on folders decides if all subresources 321 * of the folder should be touched, too.<p> 322 * 323 * @return the value of the recursive parameter 324 */ 325 public String getParamRecursive() { 326 327 return m_paramRecursive; 328 } 329 330 /** 331 * Sets the value of the content parameter.<p> 332 * 333 * @param value the value to set 334 */ 335 public void setParamContent(String value) { 336 337 m_paramContent = value; 338 } 339 340 /** 341 * Sets the value of the new timestamp parameter.<p> 342 * 343 * @param value the value to set 344 */ 345 public void setParamNewtimestamp(String value) { 346 347 m_paramNewtimestamp = value; 348 } 349 350 /** 351 * Sets the value of the recursive parameter.<p> 352 * 353 * @param value the value to set 354 */ 355 public void setParamRecursive(String value) { 356 357 m_paramRecursive = value; 358 } 359 360 /** 361 * @see org.opencms.workplace.CmsWorkplace#initWorkplaceRequestValues(org.opencms.workplace.CmsWorkplaceSettings, javax.servlet.http.HttpServletRequest) 362 */ 363 @Override 364 protected void initWorkplaceRequestValues(CmsWorkplaceSettings settings, HttpServletRequest request) { 365 366 // fill the parameter values in the get/set methods 367 fillParamValues(request); 368 369 // check the required permissions to touch the resource 370 if (!checkResourcePermissions(CmsPermissionSet.ACCESS_WRITE, false)) { 371 // no write permissions for the resource, set cancel action to close dialog 372 setParamAction(DIALOG_CANCEL); 373 } 374 375 // set the dialog type 376 setParamDialogtype(DIALOG_TYPE); 377 378 // set the action for the JSP switch 379 if (DIALOG_TYPE.equals(getParamAction())) { 380 setAction(ACTION_TOUCH); 381 } else if (DIALOG_WAIT.equals(getParamAction())) { 382 setAction(ACTION_WAIT); 383 } else if (DIALOG_CANCEL.equals(getParamAction())) { 384 setAction(ACTION_CANCEL); 385 } else if (DIALOG_LOCKS_CONFIRMED.equals(getParamAction())) { 386 setAction(ACTION_LOCKS_CONFIRMED); 387 } else { 388 setAction(ACTION_DEFAULT); 389 // build title for touch dialog 390 setDialogTitle(Messages.GUI_TOUCH_RESOURCE_1, Messages.GUI_TOUCH_MULTI_2); 391 } 392 } 393 394 /** 395 * Performs the resource touching.<p> 396 * 397 * @return true, if the resource was touched, otherwise false 398 * @throws CmsException if touching is not successful 399 */ 400 @Override 401 protected boolean performDialogOperation() throws CmsException { 402 403 // on folder touch or multi resource operation display "please wait" screen, not for simple file copy 404 if (!DIALOG_WAIT.equals(getParamAction())) { 405 // check if the "please wait" screen has to be shown 406 if (isMultiOperation()) { 407 // show please wait for every multi resource operation 408 return false; 409 } else { 410 // check if the single resource is a folder 411 CmsResource sourceRes = getCms().readResource(getParamResource(), CmsResourceFilter.ALL); 412 if (sourceRes.isFolder()) { 413 return false; 414 } 415 } 416 } 417 418 // get the new timestamp for the resource(s) from request parameter 419 long timeStamp = 0; 420 boolean correctDate = false; 421 try { 422 if (CmsStringUtil.isNotEmpty(getParamNewtimestamp())) { 423 timeStamp = CmsCalendarWidget.getCalendarDate(getMessages(), getParamNewtimestamp(), true); 424 correctDate = true; 425 } 426 } catch (ParseException e) { 427 throw new CmsException(Messages.get().container(Messages.ERR_PARSE_TIMESTAMP_1, getParamNewtimestamp()), e); 428 } 429 430 // get the flag if the touch is recursive from request parameter 431 boolean touchRecursive = Boolean.valueOf(getParamRecursive()).booleanValue(); 432 // get the flag to the touch the content from request parameter 433 boolean touchContent = Boolean.valueOf(getParamContent()).booleanValue(); 434 435 // now touch the resource(s) 436 Iterator<String> i = getResourceList().iterator(); 437 while (i.hasNext()) { 438 String resName = i.next(); 439 try { 440 // lock resource if autolock is enabled 441 checkLock(resName); 442 touchSingleResource(getCms(), resName, timeStamp, touchRecursive, correctDate, touchContent); 443 } catch (CmsException e) { 444 // collect exceptions to create a detailed output 445 addMultiOperationException(e); 446 } 447 } 448 checkMultiOperationException(Messages.get(), Messages.ERR_TOUCH_MULTI_0); 449 450 return true; 451 } 452}