blob: 17ba5cde97e8dbb7aee930b8b4501ba10e85889f [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.click.examples.page.quartz;
import java.util.Collections;
import java.util.List;
import javax.servlet.ServletContext;
import org.apache.cayenne.query.Ordering;
import org.apache.click.ActionListener;
import org.apache.click.Context;
import org.apache.click.Control;
import org.apache.click.control.ActionButton;
import org.apache.click.control.ActionLink;
import org.apache.click.control.Column;
import org.apache.click.control.Decorator;
import org.apache.click.control.PageLink;
import org.apache.click.control.Table;
import org.apache.click.examples.page.BorderPage;
import org.apache.click.examples.quartz.JobAndSimpleTrigger;
import org.apache.click.examples.quartz.SchedulerService;
import org.apache.click.util.HtmlStringBuffer;
import org.quartz.Trigger;
import org.quartz.ee.servlet.QuartzInitializerListener;
import org.quartz.impl.StdSchedulerFactory;
/**
* Provides a Quartz Job Schedule search page.
*/
public class QuartzJobSchedulerPage extends BorderPage {
private static final long serialVersionUID = 1L;
private static final String DATE_FORMAT = "{0,date,hh:mm a d MMM yy }";
/** The auto bound refresh button. */
private ActionButton refresh = new ActionButton("refresh");
// Private Variables ------------------------------------------------------
private Table table = new Table("table");
private PageLink editLink = new PageLink("edit", QuartzJobAndTriggerPage.class);
private ActionLink pauseLink = new ActionLink("pause");
private ActionLink resumeLink = new ActionLink("resume");
private ActionLink triggerLink = new ActionLink("trigger");
private ActionLink interruptLink = new ActionLink("interrupt");
private ActionLink deleteLink = new ActionLink("delete");
private ActionButton newJob = new ActionButton("newJob");
private SchedulerService schedulerService;
// Constructor ------------------------------------------------------------
public QuartzJobSchedulerPage() {
// Add button
addControl(refresh);
// Table
addControl(table);
table.setAttribute("class", Table.CLASS_SIMPLE);
table.setSortable(true);
table.setStyle("margin-left", "0.25em;");
// Define columns
Column column = new Column("job.name", "Job Name");
column.setTitleProperty("job.description");
table.addColumn(column);
final Column statusColumn = new Column("triggerStateAsString", "Status");
statusColumn.setEscapeHtml(false);
statusColumn.setDecorator(new Decorator() {
public String render(Object row, Context context) {
JobAndSimpleTrigger jobAndTrigger = (JobAndSimpleTrigger) row;
switch(jobAndTrigger.getTriggerState()){
case Trigger.STATE_NONE:
return "<span style='color:red'>None</span>";
case Trigger.STATE_NORMAL:
return "<span style='color:blue'>Normal</span>";
case Trigger.STATE_PAUSED:
return "<span style='color:red'>Paused</span>";
case Trigger.STATE_BLOCKED:
return "<span style='color:green'>Running</span>";
case Trigger.STATE_COMPLETE:
return "<span style='color:black'>Complete</span>";
case Trigger.STATE_ERROR:
return "<span style='color:red'>Error</span>";
}
return "Unknown";
}
});
table.addColumn(statusColumn);
table.addColumn(new Column("interval"));
column = new Column("trigger.nextFireTime", "Next Run");
column.setFormat(DATE_FORMAT);
table.addColumn(column);
column = new Column("trigger.startTime", "First Run");
column.setFormat(DATE_FORMAT);
table.addColumn(column);
column = new Column("trigger.previousFireTime", "Last Run");
column.setFormat(DATE_FORMAT);
table.addColumn(column);
// Initialized action column links
editLink.setAttribute("class", "actionIcon");
editLink.setTitle("Edit Job");
addControl(editLink);
pauseLink.setAttribute("class", "actionIcon");
pauseLink.setTitle("Pause Job");
pauseLink.setActionListener(new ActionListener(){
private static final long serialVersionUID = 1L;
public boolean onAction(Control source) {
String name = pauseLink.getValue();
getSchedulerService().pauseJob(name);
setFlashMessage("Paused job '" + name + "'");
return true;
}
});
addControl(pauseLink);
interruptLink.setAttribute("class", "actionIcon");
interruptLink.setTitle("Interrupt Running Job");
interruptLink.setActionListener(new ActionListener(){
private static final long serialVersionUID = 1L;
public boolean onAction(Control source) {
String name = interruptLink.getValue();
if (getSchedulerService().interruptJob(name)) {
setFlashMessage("Interrupted job '" + name + "'");
} else {
setFlashMessage("Could not interrupt job '" + name + "'");
}
return true;
}
});
addControl(interruptLink);
triggerLink.setAttribute("class", "actionIcon");
triggerLink.setTitle("Trigger Job");
triggerLink.setActionListener(new ActionListener(){
private static final long serialVersionUID = 1L;
public boolean onAction(Control source) {
String name = triggerLink.getValue();
getSchedulerService().triggerJob(name);
setFlashMessage("Triggered job '" + name + "'");
return true;
}
});
addControl(triggerLink);
resumeLink.setAttribute("class", "actionIcon");
resumeLink.setTitle("Resume Job");
resumeLink.setActionListener(new ActionListener(){
private static final long serialVersionUID = 1L;
public boolean onAction(Control source) {
String name = resumeLink.getValue();
getSchedulerService().resumeJob(name);
setFlashMessage("Resumed job '" + name + "'");
return true;
}
});
addControl(resumeLink);
deleteLink.setAttribute("class", "actionIcon");
deleteLink.setTitle("Delete Job");
String confirmMessage = getMessage("deleteConfirm", "Job");
deleteLink.setAttribute("onclick", "return window.confirm('" + confirmMessage + "')");
deleteLink.setActionListener(new ActionListener(){
private static final long serialVersionUID = 1L;
public boolean onAction(Control source) {
String name = deleteLink.getValue();
if (getSchedulerService().deleteJob(name)) {
setFlashMessage("Deleted job '" + name + "'");
} else {
setFlashMessage("Could not delete " + name);
}
return true;
}
});
addControl(deleteLink);
// Add table action column if user has edit or delete permissions
final Column actionColumn = new Column("action");
// Render action controls based on users permission
actionColumn.setDecorator(new Decorator() {
public String render(Object object, Context context) {
JobAndSimpleTrigger jobAndTrigger = (JobAndSimpleTrigger) object;
HtmlStringBuffer buffer = new HtmlStringBuffer();
editLink.setParameter("job.name", jobAndTrigger.getJob().getName());
editLink.render(buffer);
buffer.append(" | ");
deleteLink.setValue(jobAndTrigger.getJob().getName());
deleteLink.render(buffer);
if (!getSchedulerService().isPaused()) {
if (jobAndTrigger.getTriggerState() == Trigger.STATE_PAUSED) {
buffer.append(" | ");
resumeLink.setValue(jobAndTrigger.getJob().getName());
resumeLink.render(buffer);
} else {
buffer.append(" | ");
pauseLink.setValue(jobAndTrigger.getJob().getName());
pauseLink.render(buffer);
}
buffer.append(" | ");
triggerLink.setValue(jobAndTrigger.getJob().getName());
triggerLink.render(buffer);
if (jobAndTrigger.getTriggerState() == Trigger.STATE_BLOCKED) {
buffer.append(" | ");
interruptLink.setValue(jobAndTrigger.getJob().getName());
interruptLink.render(buffer);
}
}
return buffer.toString();
}
});
actionColumn.setSortable(false);
table.addColumn(actionColumn);
// Add Control Buttons.
newJob.setActionListener(new ActionListener(){
private static final long serialVersionUID = 1L;
public boolean onAction(Control source) {
setRedirect(QuartzJobAndTriggerPage.class);
return false;
}
});
addControl(newJob);
}
// Event Handlers ---------------------------------------------------------
@Override
public void onInit() {
super.onInit();
if (getSchedulerService() == null) {
setFlashMessage(getMessage("jobSchedulerNotAvailableMsg"));
newJob.setDisabled(true);
}
}
@Override
public void onRender() {
super.onRender();
if (getSchedulerService() != null) {
List<JobAndSimpleTrigger> rowList = getSchedulerService().getJobAndTriggerList();
Collections.sort(rowList, new Ordering("job.name", Ordering.ASC));
table.setRowList(rowList);
}
}
// Protected Methods ------------------------------------------------------
/**
* Set a flash attribute message with the given message string.
*
* @param message the flash attribute message to display
*/
protected void setFlashMessage(String message) {
getContext().setFlashAttribute("flash", message);
}
/**
* Return the scheduler service.
*
* @return the scheduler service
*/
protected SchedulerService getSchedulerService() {
if (schedulerService == null) {
ServletContext servletContext = getContext().getServletContext();
StdSchedulerFactory schedulerFactory = (StdSchedulerFactory)
servletContext.getAttribute(QuartzInitializerListener.QUARTZ_FACTORY_KEY);
if (schedulerFactory != null) {
schedulerService = new SchedulerService(schedulerFactory);
}
}
return schedulerService;
}
}