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.configuration.CmsSchedulerConfiguration; 031import org.opencms.file.CmsObject; 032import org.opencms.file.CmsProject; 033import org.opencms.file.CmsResource; 034import org.opencms.jsp.CmsJspActionElement; 035import org.opencms.lock.CmsLock; 036import org.opencms.main.CmsContextInfo; 037import org.opencms.main.CmsException; 038import org.opencms.main.OpenCms; 039import org.opencms.scheduler.CmsScheduledJobInfo; 040import org.opencms.scheduler.jobs.CmsPublishScheduledJob; 041import org.opencms.security.CmsAccessControlEntry; 042import org.opencms.security.CmsPermissionSet; 043import org.opencms.security.CmsRole; 044import org.opencms.util.CmsDateUtil; 045import org.opencms.util.CmsStringUtil; 046import org.opencms.util.CmsUUID; 047import org.opencms.workplace.CmsDialog; 048import org.opencms.workplace.CmsWorkplace; 049import org.opencms.workplace.CmsWorkplaceAction; 050import org.opencms.workplace.CmsWorkplaceSettings; 051 052import java.text.DateFormat; 053import java.text.ParseException; 054import java.util.Calendar; 055import java.util.Date; 056import java.util.SortedMap; 057import java.util.TreeMap; 058 059import javax.servlet.http.HttpServletRequest; 060import javax.servlet.http.HttpServletResponse; 061import javax.servlet.jsp.JspException; 062import javax.servlet.jsp.PageContext; 063 064/** 065 * Provides methods for the publish scheduled dialog.<p> 066 * 067 * The following files use this class: 068 * <ul> 069 * <li>/commons/publishscheduled.jsp 070 * </ul> 071 * <p> 072 * 073 * @since 7.5.1 074 */ 075public class CmsPublishScheduled extends CmsDialog { 076 077 /** The dialog type. */ 078 public static final String DIALOG_TYPE = "publishscheduled"; 079 080 /** Request parameter name for the activation of the notification. */ 081 public static final String PARAM_ENABLE_NOTIFICATION = "enablenotification"; 082 083 /** Request parameter name for the publish date. */ 084 public static final String PARAM_PUBLISHSCHEDULEDDATE = "publishscheduleddate"; 085 086 /** Request parameter name for the reset publish date. */ 087 public static final String PARAM_RESETPUBLISHSCHEDULED = "resetpublishscheduled"; 088 089 /** The parameter for publish scheduled date. */ 090 private String m_paramPublishscheduleddate; 091 092 /** 093 * Public constructor.<p> 094 * 095 * @param jsp an initialized JSP action element 096 */ 097 public CmsPublishScheduled(CmsJspActionElement jsp) { 098 099 super(jsp); 100 } 101 102 /** 103 * Public constructor with JSP variables.<p> 104 * 105 * @param context the JSP page context 106 * @param req the JSP request 107 * @param res the JSP response 108 */ 109 public CmsPublishScheduled(PageContext context, HttpServletRequest req, HttpServletResponse res) { 110 111 this(new CmsJspActionElement(context, req, res)); 112 } 113 114 /** 115 * 116 * @see org.opencms.workplace.CmsDialog#actionCloseDialog() 117 */ 118 @Override 119 public void actionCloseDialog() throws JspException { 120 121 // so that the explorer will be shown, if dialog is opened from e-mail 122 getSettings().getFrameUris().put("body", CmsWorkplace.VFS_PATH_VIEWS + "explorer/explorer_fs.jsp"); 123 super.actionCloseDialog(); 124 } 125 126 /** 127 * Performs the resource operation, will be called by the JSP page.<p> 128 * 129 * @throws JspException if problems including sub-elements occur 130 */ 131 public void actionUpdate() throws JspException { 132 133 // save initialized instance of this class in request attribute for included sub-elements 134 getJsp().getRequest().setAttribute(SESSION_WORKPLACE_CLASS, this); 135 136 try { 137 // prepare the publish scheduled resource 138 performDialogOperation(); 139 // close the dialog 140 actionCloseDialog(); 141 } catch (Throwable e) { 142 // show the error page 143 includeErrorpage(this, e); 144 } 145 } 146 147 /** 148 * Returns the value of the publish scheduled date.<p> 149 * 150 * @return the value of the publish scheduled date 151 */ 152 public String getParamPublishscheduleddate() { 153 154 return m_paramPublishscheduleddate; 155 } 156 157 /** 158 * Sets the title of the dialog.<p> 159 * 160 * @param singleKey the key for the single operation 161 */ 162 public void setDialogTitle(String singleKey) { 163 164 // generate title using the resource name as parameter for the key 165 String resourceName = CmsStringUtil.formatResourceName(getParamResource(), 50); 166 setParamTitle(key(singleKey, new Object[] {resourceName})); 167 } 168 169 /** 170 * Sets the value of the reset expire parameter.<p> 171 * 172 * @param paramPublishscheduleddate the value of the publish scheduled date 173 */ 174 public void setParamPublishscheduleddate(String paramPublishscheduleddate) { 175 176 m_paramPublishscheduleddate = paramPublishscheduleddate; 177 } 178 179 /** 180 * Creates the publish project's name for a given root path and publish date.<p> 181 * 182 * @param rootPath the publish resource's root path 183 * @param date the publish date 184 * 185 * @return the publish project name 186 */ 187 protected String computeProjectName(String rootPath, Date date) { 188 189 // create the temporary project, which is deleted after publishing 190 // the publish scheduled date in project name 191 String dateTime = CmsDateUtil.getDateTime(date, DateFormat.SHORT, getLocale()); 192 // the resource name to publish scheduled 193 String projectName = key(Messages.GUI_PUBLISH_SCHEDULED_PROJECT_NAME_2, new Object[] {rootPath, dateTime}); 194 // the HTML encoding for slashes is necessary because of the slashes in english date time format 195 // in project names slahes are not allowed, because these are separators for organizaional units 196 projectName = projectName.replace("/", "/"); 197 return projectName; 198 } 199 200 /** 201 * Returns a localized String for "Group", if the flag of a group ACE, and the localization for "User" otherwise.<p> 202 * 203 * @param flags the flags of the ACE 204 * 205 * @return localization for "Group", if the flag belongs to a group ACE 206 */ 207 protected String getLocalizedType(int flags) { 208 209 if ((flags & CmsAccessControlEntry.ACCESS_FLAGS_USER) > 0) { 210 return key(Messages.GUI_LABEL_USER_0); 211 } else { 212 return key(Messages.GUI_LABEL_GROUP_0); 213 } 214 } 215 216 /** 217 * @see org.opencms.workplace.CmsWorkplace#initWorkplaceRequestValues(org.opencms.workplace.CmsWorkplaceSettings, javax.servlet.http.HttpServletRequest) 218 */ 219 @Override 220 protected void initWorkplaceRequestValues(CmsWorkplaceSettings settings, HttpServletRequest request) { 221 222 // fill the parameter values in the get/set methods 223 fillParamValues(request); 224 225 // check the required permissions to modify the resource 226 if (!checkResourcePermissions(CmsPermissionSet.ACCESS_WRITE, false)) { 227 // no write permissions for the resource, set cancel action to close dialog 228 setParamAction(DIALOG_CANCEL); 229 } 230 231 // set the dialog type 232 setParamDialogtype(DIALOG_TYPE); 233 234 // set the action for the JSP switch 235 if (DIALOG_TYPE.equals(getParamAction())) { 236 setAction(ACTION_OK); 237 } else if (DIALOG_WAIT.equals(getParamAction())) { 238 setAction(ACTION_WAIT); 239 } else if (DIALOG_LOCKS_CONFIRMED.equals(getParamAction())) { 240 setAction(ACTION_LOCKS_CONFIRMED); 241 } else if (DIALOG_CANCEL.equals(getParamAction())) { 242 setAction(ACTION_CANCEL); 243 } else { 244 setAction(ACTION_DEFAULT); 245 // build title for dialog 246 setDialogTitle(Messages.GUI_PUBLISH_SCHEDULED_SETTINGS_1); 247 } 248 } 249 250 /** 251 * Modifies the time shift publish date of a resource. <p> 252 * 253 * @return true, if the operation was performed, otherwise false 254 * 255 * @throws CmsException if something goes wrong 256 * @throws ParseException if something goes wrong 257 */ 258 protected boolean performDialogOperation() throws CmsException, ParseException { 259 260 // get the request parameters for resource and publish scheduled date 261 String resource = getParamResource(); 262 String publishScheduledDate = getParamPublishscheduleddate(); 263 String userName = getCms().getRequestContext().getCurrentUser().getName(); 264 265 // get the java date format 266 // DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, getLocale()); 267 // dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm"); 268 // Date date = dateFormat.parse(publishScheduledDate); 269 long lDate = org.opencms.widgets.CmsCalendarWidget.getCalendarDate(getMessages(), publishScheduledDate, true); 270 Date date = new Date(lDate); 271 272 // check if the selected date is in the future 273 if (date.getTime() < new Date().getTime()) { 274 // the selected date in in the past, this is not possible 275 throw new CmsException(Messages.get().container(Messages.ERR_PUBLISH_SCHEDULED_DATE_IN_PAST_1, date)); 276 } 277 278 // make copies from the admin cmsobject and the user cmsobject 279 // get the admin cms object 280 CmsWorkplaceAction action = CmsWorkplaceAction.getInstance(); 281 CmsObject cmsAdmin = action.getCmsAdminObject(); 282 // get the user cms object 283 CmsObject cms = OpenCms.initCmsObject(getCms()); 284 285 // set the current user site to the admin cms object 286 cmsAdmin.getRequestContext().setSiteRoot(cms.getRequestContext().getSiteRoot()); 287 288 String rootPath = getCms().getRequestContext().addSiteRoot(resource); 289 String projectName = computeProjectName(rootPath, date); 290 CmsProject tmpProject = null; 291 try { 292 // create the project 293 tmpProject = cmsAdmin.createProject( 294 projectName, 295 "", 296 CmsRole.WORKPLACE_USER.getGroupName(), 297 CmsRole.PROJECT_MANAGER.getGroupName(), 298 CmsProject.PROJECT_TYPE_TEMPORARY); 299 } catch (CmsException e) { 300 String resName = CmsResource.getName(rootPath); 301 if (resName.length() > 64) { 302 resName = resName.substring(0, 64) + "..."; 303 } 304 // use UUID to make sure the project name is still unique 305 projectName = computeProjectName(resName, date) + " [" + new CmsUUID() + "]"; 306 // create the project 307 tmpProject = cmsAdmin.createProject( 308 projectName, 309 "", 310 CmsRole.WORKPLACE_USER.getGroupName(), 311 CmsRole.PROJECT_MANAGER.getGroupName(), 312 CmsProject.PROJECT_TYPE_TEMPORARY); 313 } 314 // make the project invisible for all users 315 tmpProject.setHidden(true); 316 // write the project to the database 317 cmsAdmin.writeProject(tmpProject); 318 // set project as current project 319 cmsAdmin.getRequestContext().setCurrentProject(tmpProject); 320 cms.getRequestContext().setCurrentProject(tmpProject); 321 322 // copy the resource to the project 323 cmsAdmin.copyResourceToProject(resource); 324 325 // lock the resource in the current project 326 CmsLock lock = cms.getLock(resource); 327 // prove is current lock from current but not in current project 328 if ((lock != null) 329 && lock.isOwnedBy(cms.getRequestContext().getCurrentUser()) 330 && !lock.isOwnedInProjectBy( 331 cms.getRequestContext().getCurrentUser(), 332 cms.getRequestContext().getCurrentProject())) { 333 // file is locked by current user but not in current project 334 // change the lock from this file 335 cms.changeLock(resource); 336 } 337 // lock resource from current user in current project 338 cms.lockResource(resource); 339 // get current lock 340 lock = cms.getLock(resource); 341 342 // create a new scheduled job 343 CmsScheduledJobInfo job = new CmsScheduledJobInfo(); 344 // the job name 345 String jobName = projectName; 346 // set the job parameters 347 job.setJobName(jobName); 348 job.setClassName("org.opencms.scheduler.jobs.CmsPublishScheduledJob"); 349 // create the cron expression 350 Calendar calendar = Calendar.getInstance(); 351 calendar.setTime(date); 352 String cronExpr = "" 353 + calendar.get(Calendar.SECOND) 354 + " " 355 + calendar.get(Calendar.MINUTE) 356 + " " 357 + calendar.get(Calendar.HOUR_OF_DAY) 358 + " " 359 + calendar.get(Calendar.DAY_OF_MONTH) 360 + " " 361 + (calendar.get(Calendar.MONTH) + 1) 362 + " " 363 + "?" 364 + " " 365 + calendar.get(Calendar.YEAR); 366 // set the cron expression 367 job.setCronExpression(cronExpr); 368 // set the job active 369 job.setActive(true); 370 // create the context info 371 CmsContextInfo contextInfo = new CmsContextInfo(); 372 contextInfo.setProjectName(projectName); 373 contextInfo.setUserName(cmsAdmin.getRequestContext().getCurrentUser().getName()); 374 // create the job schedule parameter 375 SortedMap<String, String> params = new TreeMap<String, String>(); 376 // the user to send mail to 377 params.put(CmsPublishScheduledJob.PARAM_USER, userName); 378 // the job name 379 params.put(CmsPublishScheduledJob.PARAM_JOBNAME, jobName); 380 // the link check 381 params.put(CmsPublishScheduledJob.PARAM_LINKCHECK, "true"); 382 // add the job schedule parameter 383 job.setParameters(params); 384 // add the context info to the scheduled job 385 job.setContextInfo(contextInfo); 386 // add the job to the scheduled job list 387 OpenCms.getScheduleManager().scheduleJob(cmsAdmin, job); 388 // update the XML configuration 389 OpenCms.writeConfiguration(CmsSchedulerConfiguration.class); 390 return true; 391 } 392}