package com.mossle.core.spring;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ScheduledFuture;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.ScheduledMethodRunnable;
public class ProxyTaskScheduler implements TaskScheduler, InitializingBean,
DisposableBean {
private static Logger logger = LoggerFactory
.getLogger(ProxyTaskScheduler.class);
private boolean enabled = true;
private ThreadPoolTaskScheduler instance;
private Properties properties;
private Map<String, Boolean> skipMap = new HashMap<String, Boolean>();
private String prefix = "scheduler.";
public void afterPropertiesSet() {
if (properties != null) {
for (Map.Entry<Object, Object> entry : properties.entrySet()) {
String key = (String) entry.getKey();
String value = (String) entry.getValue();
if ("scheduler.enabled".equals(key)) {
continue;
}
if (key.startsWith(prefix)) {
String name = key.substring(prefix.length());
skipMap.put(name, Boolean.valueOf(value));
logger.info("{} : {}", name, skipMap.get(name));
}
}
}
if (enabled) {
instance = new ThreadPoolTaskScheduler();
instance.afterPropertiesSet();
}
}
public void destroy() {
if (instance != null) {
instance.destroy();
}
}
public ScheduledFuture<?> schedule(Runnable task, Trigger trigger) {
if (!enabled) {
logger.debug("skip : {}", task);
return null;
}
ScheduledFuture<?> future = instance.schedule(task, trigger);
String runnableKey = findRunnableKey(task);
if (Boolean.FALSE.equals(skipMap.get(runnableKey))) {
future.cancel(true);
}
return future;
}
public ScheduledFuture<?> schedule(Runnable task, Date startTime) {
if (!enabled) {
logger.debug("skip : {}", task);
return null;
}
ScheduledFuture<?> future = instance.schedule(task, startTime);
String runnableKey = findRunnableKey(task);
if (Boolean.FALSE.equals(skipMap.get(runnableKey))) {
future.cancel(true);
}
return future;
}
public ScheduledFuture<?> scheduleAtFixedRate(Runnable task,
Date startTime, long period) {
if (!enabled) {
logger.debug("skip : {}", task);
return null;
}
ScheduledFuture<?> future = instance.scheduleAtFixedRate(task,
startTime, period);
String runnableKey = findRunnableKey(task);
if (Boolean.FALSE.equals(skipMap.get(runnableKey))) {
future.cancel(true);
}
return future;
}
public ScheduledFuture<?> scheduleAtFixedRate(Runnable task, long period) {
if (!enabled) {
logger.debug("skip : {}", task);
return null;
}
ScheduledFuture<?> future = instance.scheduleAtFixedRate(task, period);
String runnableKey = findRunnableKey(task);
if (Boolean.FALSE.equals(skipMap.get(runnableKey))) {
future.cancel(true);
}
return future;
}
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable task,
Date startTime, long delay) {
if (!enabled) {
logger.debug("skip : {}", task);
return null;
}
ScheduledFuture<?> future = instance.scheduleWithFixedDelay(task,
startTime, delay);
String runnableKey = findRunnableKey(task);
if (Boolean.FALSE.equals(skipMap.get(runnableKey))) {
future.cancel(true);
}
return future;
}
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, long delay) {
if (!enabled) {
logger.debug("skip : {}", task);
return null;
}
ScheduledFuture<?> future = instance
.scheduleWithFixedDelay(task, delay);
String runnableKey = findRunnableKey(task);
if (Boolean.FALSE.equals(skipMap.get(runnableKey))) {
future.cancel(true);
}
return future;
}
public String findRunnableKey(Runnable runnable) {
logger.info("findRunnableKey : {}", runnable);
if (runnable instanceof ScheduledMethodRunnable) {
ScheduledMethodRunnable scheduledMethodRunnable = (ScheduledMethodRunnable) runnable;
Method method = scheduledMethodRunnable.getMethod();
Class clz = method.getDeclaringClass();
logger.info("{}.{}", clz.getCanonicalName(), method.getName());
return clz.getCanonicalName() + "." + method.getName();
} else {
return runnable.toString();
}
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
}