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.tools.scheduler; 029 030import org.opencms.configuration.CmsSchedulerConfiguration; 031import org.opencms.jsp.CmsJspActionElement; 032import org.opencms.main.CmsContextInfo; 033import org.opencms.main.OpenCms; 034import org.opencms.monitor.CmsMemoryMonitor; 035import org.opencms.notification.CmsContentNotificationJob; 036import org.opencms.relations.CmsExternalLinksValidator; 037import org.opencms.relations.CmsInternalRelationsValidationJob; 038import org.opencms.scheduler.CmsScheduledJobInfo; 039import org.opencms.scheduler.jobs.CmsCreateImageSizeJob; 040import org.opencms.scheduler.jobs.CmsDeleteExpiredResourcesJob; 041import org.opencms.scheduler.jobs.CmsHistoryClearJob; 042import org.opencms.scheduler.jobs.CmsImageCacheCleanupJob; 043import org.opencms.scheduler.jobs.CmsPublishJob; 044import org.opencms.scheduler.jobs.CmsStaticExportJob; 045import org.opencms.scheduler.jobs.CmsUnsubscribeDeletedResourcesJob; 046import org.opencms.search.CmsSearchManager; 047import org.opencms.util.CmsDateUtil; 048import org.opencms.util.CmsStringUtil; 049import org.opencms.widgets.CmsCheckboxWidget; 050import org.opencms.widgets.CmsComboWidget; 051import org.opencms.widgets.CmsDisplayWidget; 052import org.opencms.widgets.CmsInputWidget; 053import org.opencms.widgets.CmsSelectWidgetOption; 054import org.opencms.widgets.CmsUserWidget; 055import org.opencms.widgets.CmsVfsFileWidget; 056import org.opencms.workplace.CmsDialog; 057import org.opencms.workplace.CmsWidgetDialog; 058import org.opencms.workplace.CmsWidgetDialogParameter; 059import org.opencms.workplace.CmsWorkplaceSettings; 060 061import java.text.DateFormat; 062import java.util.ArrayList; 063import java.util.Date; 064import java.util.List; 065import java.util.Map; 066 067import javax.servlet.http.HttpServletRequest; 068import javax.servlet.http.HttpServletResponse; 069import javax.servlet.jsp.PageContext; 070 071/** 072 * Dialog to edit new and existing scheduled jobs in the administration view.<p> 073 * 074 * @since 6.0.0 075 */ 076public class CmsEditScheduledJobInfoDialog extends CmsWidgetDialog { 077 078 /** The action to copy a job to edit. */ 079 public static final String DIALOG_COPYJOB = "copyjob"; 080 081 /** Defines which pages are valid for this dialog. */ 082 public static final String[] PAGES = {"page1", "page2"}; 083 084 /** Request parameter name for the job id. */ 085 public static final String PARAM_JOBID = "jobid"; 086 087 /** The job info object that is edited on this dialog. */ 088 protected CmsScheduledJobInfo m_jobInfo; 089 090 /** Stores the value of the request parameter for the job id. */ 091 protected String m_paramJobid; 092 093 /** formatted current server time. */ 094 protected String m_serverTime; 095 096 /** 097 * Public constructor with JSP action element.<p> 098 * 099 * @param jsp an initialized JSP action element 100 */ 101 public CmsEditScheduledJobInfoDialog(CmsJspActionElement jsp) { 102 103 super(jsp); 104 } 105 106 /** 107 * Public constructor with JSP variables.<p> 108 * 109 * @param context the JSP page context 110 * @param req the JSP request 111 * @param res the JSP response 112 */ 113 public CmsEditScheduledJobInfoDialog(PageContext context, HttpServletRequest req, HttpServletResponse res) { 114 115 this(new CmsJspActionElement(context, req, res)); 116 } 117 118 /** 119 * Commits the edited scheduled job to the scheduler.<p> 120 */ 121 @Override 122 public void actionCommit() { 123 124 List<Throwable> errors = new ArrayList<Throwable>(); 125 126 try { 127 // schedule the edited job 128 OpenCms.getScheduleManager().scheduleJob(getCms(), m_jobInfo); 129 // update the XML configuration 130 OpenCms.writeConfiguration(CmsSchedulerConfiguration.class); 131 // refresh the list 132 Map<?, ?> objects = (Map<?, ?>)getSettings().getListObject(); 133 if (objects != null) { 134 objects.remove(CmsSchedulerList.class.getName()); 135 } 136 } catch (Throwable t) { 137 errors.add(t); 138 } 139 // set the list of errors to display when saving failed 140 setCommitErrors(errors); 141 } 142 143 /** 144 * Returns the job id parameter value.<p> 145 * 146 * @return the job id parameter value 147 */ 148 public String getParamJobid() { 149 150 return m_paramJobid; 151 } 152 153 /** 154 * Returns the server Time.<p> 155 * 156 * @return the server Time 157 */ 158 public String getServerTime() { 159 160 if (m_serverTime == null) { 161 m_serverTime = CmsDateUtil.getDateTime(new Date(), DateFormat.LONG, getLocale()); 162 } 163 return m_serverTime; 164 } 165 166 /** 167 * Sets the job id parameter value.<p> 168 * 169 * @param jobid the job id parameter value 170 */ 171 public void setParamJobid(String jobid) { 172 173 m_paramJobid = jobid; 174 } 175 176 /** 177 * Sets the server Time.<p> 178 * 179 * @param serverTime the server Time to set 180 */ 181 public void setServerTime(String serverTime) { 182 183 m_serverTime = serverTime; 184 } 185 186 /** 187 * Creates the dialog HTML for all defined widgets of the named dialog (page).<p> 188 * 189 * This overwrites the method from the super class to create a layout variation for the widgets.<p> 190 * 191 * @param dialog the dialog (page) to get the HTML for 192 * @return the dialog HTML for all defined widgets of the named dialog (page) 193 */ 194 @Override 195 protected String createDialogHtml(String dialog) { 196 197 StringBuffer result = new StringBuffer(1024); 198 199 // create widget table 200 result.append(createWidgetTableStart()); 201 202 // show error header once if there were validation errors 203 result.append(createWidgetErrorHeader()); 204 205 if (dialog.equals(PAGES[0])) { 206 // create the widgets for the first dialog page 207 result.append(createWidgetBlockStart(key(Messages.GUI_EDITOR_LABEL_SERVERTIME_BLOCK_0))); 208 result.append(createDialogRowsHtml(0, 0)); 209 result.append(createWidgetBlockEnd()); 210 result.append(createWidgetBlockStart(key(Messages.GUI_EDITOR_LABEL_JOBSETTINGS_BLOCK_0))); 211 result.append(createDialogRowsHtml(1, 5)); 212 result.append(createWidgetBlockEnd()); 213 result.append(createWidgetBlockStart(key(Messages.GUI_EDITOR_LABEL_CONTEXTINFO_BLOCK_0))); 214 result.append(createDialogRowsHtml(6, 12)); 215 result.append(createWidgetBlockEnd()); 216 } else if (dialog.equals(PAGES[1])) { 217 // create the widget for the second dialog page 218 result.append(createWidgetBlockStart(key(Messages.GUI_EDITOR_LABEL_PARAMETERS_BLOCK_0))); 219 result.append(createDialogRowsHtml(13, 13)); 220 result.append(createWidgetBlockEnd()); 221 } 222 223 // close widget table 224 result.append(createWidgetTableEnd()); 225 226 return result.toString(); 227 } 228 229 /** 230 * Creates the list of widgets for this dialog.<p> 231 */ 232 @Override 233 protected void defineWidgets() { 234 235 // initialize the scheduled job object to use for the dialog 236 initScheduledJobObject(); 237 238 // required to read the default values for the optional context parameters for the widgets 239 CmsContextInfo dC = new CmsContextInfo(); 240 241 // add current server time 242 addWidget(new CmsWidgetDialogParameter(this, "serverTime", PAGES[0], new CmsDisplayWidget())); 243 // widgets to display on the first dialog page 244 addWidget(new CmsWidgetDialogParameter(m_jobInfo, "jobName", PAGES[0], new CmsInputWidget())); 245 addWidget( 246 new CmsWidgetDialogParameter(m_jobInfo, "className", PAGES[0], new CmsComboWidget(getComboClasses()))); 247 addWidget( 248 new CmsWidgetDialogParameter( 249 m_jobInfo, 250 "cronExpression", 251 PAGES[0], 252 new CmsComboWidget(getComboCronExpressions()))); 253 addWidget(new CmsWidgetDialogParameter(m_jobInfo, "reuseInstance", PAGES[0], new CmsCheckboxWidget())); 254 addWidget(new CmsWidgetDialogParameter(m_jobInfo, "active", PAGES[0], new CmsCheckboxWidget())); 255 addWidget( 256 new CmsWidgetDialogParameter(m_jobInfo, "contextInfo.userName", PAGES[0], new CmsUserWidget(null, null))); 257 addWidget(new CmsWidgetDialogParameter(m_jobInfo, "contextInfo.projectName", PAGES[0], new CmsInputWidget())); 258 addWidget( 259 new CmsWidgetDialogParameter( 260 m_jobInfo, 261 "contextInfo.siteRoot", 262 dC.getSiteRoot(), 263 PAGES[0], 264 new CmsVfsFileWidget(), 265 0, 266 1)); 267 addWidget( 268 new CmsWidgetDialogParameter( 269 m_jobInfo, 270 "contextInfo.requestedUri", 271 dC.getRequestedUri(), 272 PAGES[0], 273 new CmsVfsFileWidget(), 274 0, 275 1)); 276 addWidget( 277 new CmsWidgetDialogParameter( 278 m_jobInfo, 279 "contextInfo.localeName", 280 dC.getLocaleName(), 281 PAGES[0], 282 new CmsInputWidget(), 283 0, 284 1)); 285 addWidget( 286 new CmsWidgetDialogParameter( 287 m_jobInfo, 288 "contextInfo.encoding", 289 dC.getEncoding(), 290 PAGES[0], 291 new CmsInputWidget(), 292 0, 293 1)); 294 addWidget( 295 new CmsWidgetDialogParameter( 296 m_jobInfo, 297 "contextInfo.remoteAddr", 298 dC.getRemoteAddr(), 299 PAGES[0], 300 new CmsInputWidget(), 301 0, 302 1)); 303 304 // widget to display on the second dialog page 305 addWidget(new CmsWidgetDialogParameter(m_jobInfo, "parameters", PAGES[1], new CmsInputWidget())); 306 } 307 308 /** 309 * Returns the example cron class names to show in the combo box.<p> 310 * 311 * The result list elements are of type <code>{@link org.opencms.widgets.CmsSelectWidgetOption}</code>.<p> 312 * 313 * @return the example cron class names to show in the combo box 314 */ 315 protected List<CmsSelectWidgetOption> getComboClasses() { 316 317 List<CmsSelectWidgetOption> result = new ArrayList<CmsSelectWidgetOption>(16); 318 result.add( 319 new CmsSelectWidgetOption( 320 CmsInternalRelationsValidationJob.class.getName(), 321 false, 322 null, 323 key(Messages.GUI_EDITOR_CRONCLASS_INTERNALVALIDATION_0))); 324 result.add( 325 new CmsSelectWidgetOption( 326 CmsPublishJob.class.getName(), 327 false, 328 null, 329 key(Messages.GUI_EDITOR_CRONCLASS_PUBLISH_0))); 330 result.add( 331 new CmsSelectWidgetOption( 332 CmsStaticExportJob.class.getName(), 333 false, 334 null, 335 key(Messages.GUI_EDITOR_CRONCLASS_STATICEXPORT_0))); 336 result.add( 337 new CmsSelectWidgetOption( 338 CmsExternalLinksValidator.class.getName(), 339 false, 340 null, 341 key(Messages.GUI_EDITOR_CRONCLASS_POINTERVALIDATION_0))); 342 result.add( 343 new CmsSelectWidgetOption( 344 CmsMemoryMonitor.class.getName(), 345 false, 346 null, 347 key(Messages.GUI_EDITOR_CRONCLASS_MEMORYMONITOR_0))); 348 result.add( 349 new CmsSelectWidgetOption( 350 CmsSearchManager.class.getName(), 351 false, 352 null, 353 key(Messages.GUI_EDITOR_CRONCLASS_SEARCHINDEX_0))); 354 result.add( 355 new CmsSelectWidgetOption( 356 CmsContentNotificationJob.class.getName(), 357 false, 358 null, 359 key(Messages.GUI_EDITOR_CRONCLASS_CONTENTNOTIFICATION_0))); 360 result.add( 361 new CmsSelectWidgetOption( 362 CmsCreateImageSizeJob.class.getName(), 363 false, 364 null, 365 key(Messages.GUI_EDITOR_CRONCLASS_IMAGESIZE_0))); 366 result.add( 367 new CmsSelectWidgetOption( 368 CmsImageCacheCleanupJob.class.getName(), 369 false, 370 null, 371 key(Messages.GUI_EDITOR_CRONCLASS_IMAGE_CACHECLEAN_0))); 372 result.add( 373 new CmsSelectWidgetOption( 374 CmsHistoryClearJob.class.getName(), 375 false, 376 null, 377 key(Messages.GUI_EDITOR_CRONCLASS_CLEARHISTORY_0))); 378 result.add( 379 new CmsSelectWidgetOption( 380 CmsDeleteExpiredResourcesJob.class.getName(), 381 false, 382 null, 383 key(Messages.GUI_EDITOR_CRONCLASS_DELETEEXPIRED_0))); 384 result.add( 385 new CmsSelectWidgetOption( 386 CmsUnsubscribeDeletedResourcesJob.class.getName(), 387 false, 388 null, 389 key(Messages.GUI_EDITOR_CRONCLASS_UNSUBSCRIBEDELETED_0))); 390 return result; 391 } 392 393 /** 394 * Returns the example cron expressions to show in the combo box.<p> 395 * 396 * The result list elements are of type <code>{@link org.opencms.widgets.CmsSelectWidgetOption}</code>.<p> 397 * 398 * @return the example cron expressions to show in the combo box 399 */ 400 protected List<CmsSelectWidgetOption> getComboCronExpressions() { 401 402 List<CmsSelectWidgetOption> result = new ArrayList<CmsSelectWidgetOption>(); 403 404 // 0 0 3 * * ? (daily at 3 am) 405 result.add(new CmsSelectWidgetOption("0 0 3 * * ?", false, null, key(Messages.GUI_EDITOR_CRONJOB_EXAMPLE1_0))); 406 // 0 0/30 * * * ? (daily every thirty minutes) 407 result.add( 408 new CmsSelectWidgetOption("0 0/30 * * * ?", false, null, key(Messages.GUI_EDITOR_CRONJOB_EXAMPLE2_0))); 409 // 0 30 8 ? * 4 (every Wednesday at 8:30 am) 410 result.add(new CmsSelectWidgetOption("0 30 8 ? * 4", false, null, key(Messages.GUI_EDITOR_CRONJOB_EXAMPLE3_0))); 411 // 0 15 18 15 * ? (on the 20th day of the month at 6:15 pm) 412 result.add( 413 new CmsSelectWidgetOption("0 15 18 20 * ?", false, null, key(Messages.GUI_EDITOR_CRONJOB_EXAMPLE4_0))); 414 // 0 45 15 ? * 1 2007-2009 (every Sunday from the year 2007 to 2009 at 3:45 pm) 415 result.add( 416 new CmsSelectWidgetOption( 417 "0 45 15 ? * 1 2007-2009", 418 false, 419 null, 420 key(Messages.GUI_EDITOR_CRONJOB_EXAMPLE5_0))); 421 return result; 422 } 423 424 /** 425 * @see org.opencms.workplace.CmsWidgetDialog#getPageArray() 426 */ 427 @Override 428 protected String[] getPageArray() { 429 430 return PAGES; 431 } 432 433 /** 434 * @see org.opencms.workplace.CmsWorkplace#initMessages() 435 */ 436 @Override 437 protected void initMessages() { 438 439 // add specific dialog resource bundle 440 addMessages(Messages.get().getBundleName()); 441 // add default resource bundles 442 super.initMessages(); 443 } 444 445 /** 446 * Initializes the scheduled job object to work with depending on the dialog state and request parameters.<p> 447 * 448 * Three initializations of the scheduled job object on first dialog call are possible: 449 * <ul> 450 * <li>edit an existing scheduled job</li> 451 * <li>create a new scheduled job</li> 452 * <li>copy an existing scheduled job and edit it</li> 453 * </ul> 454 */ 455 protected void initScheduledJobObject() { 456 457 Object o; 458 459 boolean setActive = false; 460 461 if (CmsStringUtil.isEmpty(getParamAction()) 462 || CmsDialog.DIALOG_INITIAL.equals(getParamAction()) 463 || DIALOG_COPYJOB.equals(getParamAction())) { 464 // this is the initial dialog call 465 if (CmsStringUtil.isNotEmpty(getParamJobid())) { 466 // edit or copy an existing job, get the job object from manager 467 CmsScheduledJobInfo job = OpenCms.getScheduleManager().getJob(getParamJobid()); 468 // clone resets the active flag! 469 o = job.clone(); 470 setActive = job.isActive(); 471 } else { 472 // create a new job for the new job dialog 473 o = null; 474 } 475 } else { 476 // this is not the initial call, get the job object from session 477 o = getDialogObject(); 478 } 479 480 if (!(o instanceof CmsScheduledJobInfo)) { 481 // create a new job info object 482 m_jobInfo = new CmsScheduledJobInfo(); 483 m_jobInfo.setContextInfo(new CmsContextInfo()); 484 } else { 485 // reuse job info object stored in session 486 m_jobInfo = (CmsScheduledJobInfo)o; 487 } 488 489 if (setActive) { 490 // initial call of edit an existing job, set active state of cloned job 491 m_jobInfo.setActive(true); 492 } 493 494 if (DIALOG_COPYJOB.equals(getParamAction())) { 495 // initial call of copy job action, clear the job id of the cloned job 496 m_jobInfo.clearId(); 497 } 498 } 499 500 /** 501 * @see org.opencms.workplace.CmsWorkplace#initWorkplaceRequestValues(org.opencms.workplace.CmsWorkplaceSettings, javax.servlet.http.HttpServletRequest) 502 */ 503 @Override 504 protected void initWorkplaceRequestValues(CmsWorkplaceSettings settings, HttpServletRequest request) { 505 506 // initialize parameters and dialog actions in super implementation 507 super.initWorkplaceRequestValues(settings, request); 508 509 // save the current state of the job (may be changed because of the widget values) 510 setDialogObject(m_jobInfo); 511 } 512 513 /** 514 * Checks if the new job dialog has to be displayed.<p> 515 * 516 * @return <code>true</code> if the new job dialog has to be displayed 517 */ 518 protected boolean isNewJob() { 519 520 return getCurrentToolPath().equals("/scheduler/new"); 521 } 522 523 /** 524 * @see org.opencms.workplace.CmsWidgetDialog#validateParamaters() 525 */ 526 @Override 527 protected void validateParamaters() throws Exception { 528 529 if (!isNewJob()) { 530 // test if params are available 531 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(getParamJobid())) { 532 // validate the params 533 if (OpenCms.getScheduleManager().getJob(getParamJobid()) != null) { 534 // params are ok! 535 return; 536 } 537 } 538 // params are no valid 539 throw new Exception(); 540 } 541 } 542}