1 24 package org.riotfamily.riot.job.support; 25 26 import java.util.Date ; 27 28 import org.apache.commons.logging.Log; 29 import org.apache.commons.logging.LogFactory; 30 import org.riotfamily.riot.job.Job; 31 import org.riotfamily.riot.job.JobInterruptedException; 32 import org.riotfamily.riot.job.context.TaskJobContext; 33 import org.riotfamily.riot.job.persistence.JobDao; 34 import org.riotfamily.riot.job.persistence.JobDetail; 35 import org.riotfamily.riot.job.persistence.JobLogEntry; 36 import org.riotfamily.riot.job.ui.JobUIUpdater; 37 import org.springframework.dao.DataAccessException; 38 39 40 public class JobTask implements Runnable { 41 42 private static Log log = LogFactory.getLog(JobTask.class); 43 44 private Job job; 45 46 private JobDetail detail; 47 48 private JobDao dao; 49 50 private JobUIUpdater uiUpdater; 51 52 private TaskList taskList; 53 54 private Log jobLog; 55 56 private Thread thread; 57 58 private boolean interrupted; 59 60 61 public JobTask(Job job, JobDetail detail, JobDao dao, 62 JobUIUpdater uiUpdater, TaskList taskList) { 63 64 this.job = job; 65 this.detail = detail; 66 this.dao = dao; 67 this.uiUpdater = uiUpdater; 68 this.taskList = taskList; 69 70 jobLog = LogFactory.getLog(job.getClass()); 71 } 72 73 public void interrupt() { 74 if (interrupted) { 75 return; 76 } 77 interrupted = true; 78 if (thread != null) { 79 thread.interrupt(); 80 try { 81 synchronized (thread) { 82 thread.wait(10000); 83 } 84 } 85 catch (InterruptedException e) { 86 } 87 if (detail.getState() < JobDetail.INTERRUPTED) { 88 log.warn("Job did not interrupt its work within 10 seconds."); 89 } 90 } 91 } 92 93 public boolean isInterrupted() { 94 Thread.yield(); 95 return interrupted; 96 } 97 98 public void run() { 99 if (interrupted) { 100 return; 101 } 102 thread = Thread.currentThread(); 103 try { 104 jobStarted(); 105 job.execute(new TaskJobContext(this)); 106 } 107 catch (JobInterruptedException e) { 108 } 109 catch (Exception e) { 110 interrupted = true; 111 logError(e.getMessage()); 112 log.error("Job aborted due to exception", e); 113 } 114 jobStoped(!interrupted); 115 synchronized (thread) { 116 thread.notifyAll(); 117 } 118 } 119 120 public JobDetail getDetail() { 121 return this.detail; 122 } 123 124 128 public void stepCompleted() throws JobInterruptedException { 129 if (detail.getStepsTotal() > 0) { 130 detail.stepCompleted(); 131 dao.updateJobDetail(detail); 132 uiUpdater.updateJob(detail); 133 } 134 if (isInterrupted()) { 135 throw new JobInterruptedException(); 136 } 137 } 138 139 public void updateExecutionTime() { 140 detail.updateExecutionTime(); 141 dao.updateJobDetail(detail); 142 } 143 144 public void updateDescription(String description) { 145 detail.setDescription(description); 146 dao.updateJobDetail(detail); 147 uiUpdater.updateJob(detail); 148 } 149 150 public void updateStepsTotal(int stepsTotal) { 151 detail.setStepsTotal(stepsTotal); 152 dao.updateJobDetail(detail); 153 uiUpdater.updateJob(detail); 154 } 155 156 159 public void logInfo(String message) { 160 jobLog.info(message); 161 log(message, JobLogEntry.INFO); 162 } 163 164 167 public void logError(String message) { 168 jobLog.error(message); 169 log(message, JobLogEntry.ERROR); 170 } 171 172 175 protected void log(String message, int priority) { 176 JobLogEntry entry = new JobLogEntry(detail, priority, message); 177 try { 178 dao.log(entry); 179 } 180 catch (DataAccessException e) { 181 log.error("Can't save log entry: " + entry.getMessage()); 182 } 183 uiUpdater.log(entry); 184 } 185 186 private void jobStarted() { 187 taskList.addTask(this); 188 if (detail.getStartDate() == null) { 189 detail.setStartDate(new Date ()); 190 logInfo("Job started"); 191 } 192 else { 193 logInfo("Job resumed"); 194 } 195 detail.setState(JobDetail.STARTED); 196 dao.updateJobDetail(detail); 197 uiUpdater.updateJob(detail); 198 } 199 200 private void jobStoped(boolean completed) { 201 taskList.removeTask(this); 202 if (completed) { 203 job.tearDown(detail.getObjectId()); 204 detail.setState(JobDetail.COMPLETED); 205 detail.setEndDate(new Date ()); 206 logInfo("Job completed"); 207 } 208 else { 209 detail.setState(JobDetail.INTERRUPTED); 210 } 211 dao.updateJobDetail(detail); 212 uiUpdater.updateJob(detail); 213 } 214 215 } | Popular Tags |