package org.n3r.quartz.glass.web.controller;
import org.n3r.quartz.glass.configuration.Configuration;
import org.n3r.quartz.glass.job.annotation.JobArgumentBean;
import org.n3r.quartz.glass.job.annotation.JobBean;
import org.n3r.quartz.glass.job.util.JobDataMapUtils;
import org.n3r.quartz.glass.log.execution.JobExecutions;
import org.n3r.quartz.glass.util.Keys;
import org.n3r.quartz.glass.util.Query;
import org.n3r.quartz.glass.web.form.JobForm;
import org.n3r.quartz.glass.web.form.NewJobForm;
import org.n3r.quartz.glass.web.util.JobPathScanner;
import org.n3r.quartz.glass.web.util.JobWrapperForView;
import org.n3r.quartz.glass.web.util.TriggerWrapperForView;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* All currently defined jobs and services around form list.
*/
@Controller
public class JobsController {
@Autowired
protected Scheduler scheduler;
@Autowired
protected Configuration configuration;
@Autowired
protected JobPathScanner jobPathScanner;
@Autowired
protected JobExecutions executions;
@RequestMapping("/jobs")
public String jobs(Model model) throws SchedulerException {
List<JobWrapperForView> jobWrapperForViews = new ArrayList<JobWrapperForView>();
List<String> groups = scheduler.getJobGroupNames();
for (String group : groups) {
for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher.<JobKey>groupEquals(group))) {
jobWrapperForViews.add(new JobWrapperForView(scheduler, jobKey));
}
}
// order triggerNum desc, group, name
Collections.sort(jobWrapperForViews, new Comparator<JobWrapperForView>() {
@Override
public int compare(JobWrapperForView o1, JobWrapperForView o2) {
int diff = o2.getTriggersNum() - o1.getTriggersNum();
if (diff != 0) return diff;
return o1.getGroup().equals(o2.getGroup())
? o1.getName().compareTo(o2.getName())
: o1.getGroup().compareTo(o2.getGroup());
}
});
model.addAttribute("jobs", jobWrapperForViews);
return "jobs";
}
@RequestMapping("/jobs/{group}/{name}")
public String job(@PathVariable String group,
@PathVariable String name, Model model) throws SchedulerException {
JobDetail job = scheduler.getJobDetail(new JobKey(name, group));
if (job == null) return "redirect:/glass/jobs";
model.addAttribute("job", new JobWrapperForView(job));
JobBean jobBean = JobBean.fromClass(job);
model.addAttribute("jobBean", jobBean);
model.addAttribute("jobArguments", jobBean.getArguments());
model.addAttribute("dataMap", JobDataMapUtils.toProperties(job.getJobDataMap()));
List<? extends Trigger> triggers = scheduler.getTriggersOfJob(job.getKey());
model.addAttribute("triggers", TriggerWrapperForView.fromList(triggers, scheduler));
model.addAttribute("history", executions.find(group, name, Query.index(0).withSize(100)));
return "job";
}
@RequestMapping("/jobs/new")
public String createJob(Model model) throws SchedulerException {
return form(model, new NewJobForm());
}
@RequestMapping(value = "/jobs/new", method = RequestMethod.POST)
public String postCreateJob(@Valid @ModelAttribute("form") NewJobForm form,
BindingResult bindingResult, Model model) throws SchedulerException {
if (bindingResult.hasErrors()) return form(model, form);
scheduler.addJob(form.getJobDetails(), true);
return "redirect:/glass/jobs/" + form.getGroup() + "/" + form.getName();
}
@RequestMapping("/jobs/{group}/{name}/edit")
public String updateJob(@PathVariable String group,
@PathVariable String name, Model model) throws SchedulerException {
JobDetail job = scheduler.getJobDetail(new JobKey(name, group));
if (job == null) return "redirect:/glass/jobs";
return form(model, new JobForm(job), job.getJobClass());
}
@RequestMapping(value = "/jobs/{group}/{name}/edit", method = RequestMethod.POST)
public String postUpdateJob(@PathVariable String group, @PathVariable String name,
@Valid @ModelAttribute("form") JobForm form,
BindingResult bindingResult, Model model) throws SchedulerException {
JobDetail job = scheduler.getJobDetail(new JobKey(name, group));
if (job == null) return "redirect:/glass/jobs";
if (bindingResult.hasErrors()) return form(model, form, job.getJobClass());
scheduler.addJob(form.getJobDetails(job), true);
return "redirect:/glass/jobs/{group}/{name}";
}
@RequestMapping("/jobs/{group}/{name}/delete")
public String delete(@PathVariable String group, @PathVariable String name) throws SchedulerException {
JobDetail job = scheduler.getJobDetail(new JobKey(name, group));
if (job == null) return "redirect:/glass/jobs";
scheduler.deleteJob(job.getKey());
return "redirect:/glass/jobs";
}
@RequestMapping(value = "/jobs/{group}/{name}/fire", method = RequestMethod.POST)
public String fire(HttpServletRequest request,
@PathVariable String group, @PathVariable String name) throws SchedulerException {
JobKey jobKey = new JobKey(name, group);
JobDetail job = scheduler.getJobDetail(jobKey);
if (job == null) return "redirect:/glass/jobs";
String fireJobMap = request.getParameter("fireJobMap");
// scheduler.triggerJob(job.getKey());
Trigger trigger = TriggerBuilder.newTrigger()
.forJob(jobKey)
.withIdentity(Keys.getFireKey(), job.getKey().getGroup())
.usingJobData(JobDataMapUtils.fromDataMapStr(fireJobMap))
.startNow()
.build();
scheduler.scheduleJob(trigger);
return "redirect:/glass/jobs/{group}/{name}";
}
private String form(Model model, NewJobForm form) {
List<Class<?>> jobClasses = new ArrayList<Class<?>>();
for (String jobPath : jobPathScanner.getJobsPaths()) {
try {
jobClasses.add(Class.forName(jobPath));
} catch (ClassNotFoundException e) {
continue;
}
}
model.addAttribute("jobClasses", jobClasses);
model.addAttribute("jobBean", JobBean.fromClass(form.getClazz()));
model.addAttribute("jobArguments", JobArgumentBean.fromClass(form.getClazz()));
model.addAttribute("form", form);
return "new_job_form";
}
private String form(Model model, JobForm form, Class<?> jobClass) {
model.addAttribute("jobClass", jobClass);
model.addAttribute("jobBean", JobBean.fromClass(jobClass));
model.addAttribute("jobArguments", JobArgumentBean.fromClass(jobClass));
model.addAttribute("form", form);
return "job_form";
}
}