diff --git a/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiApplicationRunner.java b/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiApplicationRunner.java index e5e930b..5665522 100644 --- a/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiApplicationRunner.java +++ b/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiApplicationRunner.java @@ -12,11 +12,6 @@ public class DiApplicationRunner implements ApplicationRunner { @Override public void run(ApplicationArguments args) throws Exception { - this.scanAndRegisterTasks(); - } - - // scan tasks - private void scanAndRegisterTasks() { - System.out.println("DiApplicationRunner.scanAndRegisterTasks()"); + this.device.getTaskManager().scanTaskClasses("com.my.graphiteDigesterBg.task"); } } diff --git a/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiDevice.java b/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiDevice.java index 712a5ef..f8f8109 100644 --- a/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiDevice.java +++ b/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiDevice.java @@ -7,6 +7,8 @@ public class DiDevice { private DiDeviceIOManager io; // actuator manager private DiDeviceActuatorManager actuators; + // task manager + private DiTaskManager taskManager; // task executor private DiTaskExecutor taskExecutor; @@ -14,6 +16,7 @@ public class DiDevice { public void init() { this.io = new DiDeviceIOManager(this); this.actuators = new DiDeviceActuatorManager(this); + this.taskManager = new DiTaskManager(); this.taskExecutor = new DiTaskExecutor(this); } @@ -31,4 +34,9 @@ public class DiDevice { public DiTaskExecutor getTaskExecutor() { return this.taskExecutor; } + + // get task manager + public DiTaskManager getTaskManager() { + return this.taskManager; + } } \ No newline at end of file diff --git a/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiTask.java b/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiTask.java index 191ccd1..73df5db 100644 --- a/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiTask.java +++ b/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiTask.java @@ -1,5 +1,8 @@ package com.my.graphiteDigesterBg.diframe; public interface DiTask { + // set parameter + void setParameter(Object parameter); + // run void run(); } diff --git a/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiTaskBase.java b/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiTaskBase.java index 98e431b..fb8af7a 100644 --- a/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiTaskBase.java +++ b/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiTaskBase.java @@ -1,15 +1,21 @@ package com.my.graphiteDigesterBg.diframe; import java.util.List; import java.util.Map; -abstract public class DiTaskBase { +abstract public class DiTaskBase implements DiTask { // parameter - private Map parameter; + private Object parameter; // steps private List steps; // step index private Integer stepIndex; + @Override + public void setParameter(Object parameter) { + this.parameter = parameter; + } + // run + @Override public void run() { // do something } diff --git a/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiTaskManager.java b/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiTaskManager.java new file mode 100644 index 0000000..38d5c16 --- /dev/null +++ b/src/src/main/java/com/my/graphiteDigesterBg/diframe/DiTaskManager.java @@ -0,0 +1,59 @@ +package com.my.graphiteDigesterBg.diframe; +import com.my.graphiteDigesterBg.diframe.util.ClassHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +public class DiTaskManager { + // logger + public static final Logger LOG = LoggerFactory.getLogger(DiTaskManager.class); + // task classes + private Map> taskClasses; + + // constructor + public DiTaskManager() { + this.taskClasses = new HashMap<>(); + } + + // get scan task classes + public void scanTaskClasses( String packageName ) { + List> taskClasses = ClassHelper.getAllClassesInPackage(packageName); + for ( Class taskClass : taskClasses ) { + if ( DiTaskBase.class.isAssignableFrom(taskClass) ) { + Task task = taskClass.getAnnotation(Task.class); + if ( task != null ) { + this.taskClasses.put(task.name(), taskClass); + LOG.info("(Task) {} => {}", task.name(), taskClass.getName()); + } + } + } + } + + // generate task + public DiTask generateTask( String name, Object parameter ) { + Class taskClass = this.taskClasses.get(name); + if (null == taskClass) { + throw new RuntimeException("Task not found: " + name); + } + + Constructor taskConstructor = null; + try { + taskConstructor = taskClass.getDeclaredConstructor(); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } + + DiTask task = null; + try { + task = (DiTask) taskConstructor.newInstance(); + } catch (InvocationTargetException | InstantiationException | IllegalAccessException e) { + throw new RuntimeException(e); + } + + task.setParameter(parameter); + return task; + } +} diff --git a/src/src/main/java/com/my/graphiteDigesterBg/diframe/Task.java b/src/src/main/java/com/my/graphiteDigesterBg/diframe/Task.java new file mode 100644 index 0000000..15ea984 --- /dev/null +++ b/src/src/main/java/com/my/graphiteDigesterBg/diframe/Task.java @@ -0,0 +1,9 @@ +package com.my.graphiteDigesterBg.diframe; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +@Retention(RetentionPolicy.RUNTIME) +@Target({java.lang.annotation.ElementType.TYPE}) +public @interface Task { + String name(); +} diff --git a/src/src/main/java/com/my/graphiteDigesterBg/diframe/util/ClassHelper.java b/src/src/main/java/com/my/graphiteDigesterBg/diframe/util/ClassHelper.java new file mode 100644 index 0000000..8114c9c --- /dev/null +++ b/src/src/main/java/com/my/graphiteDigesterBg/diframe/util/ClassHelper.java @@ -0,0 +1,46 @@ +package com.my.graphiteDigesterBg.diframe.util; +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +public class ClassHelper { + // get all classes in package + public static List> getAllClassesInPackage(String packageName) { + List> classes = new ArrayList<>(); + try { + String packagePath = packageName.replace(".", "/"); + List resources = Collections.list(Thread.currentThread().getContextClassLoader().getResources(packagePath)); + for (URL resource : resources) { + if ( "file".equals(resource.getProtocol()) ) { + ClassHelper.getClassListByGivenFilePath(packageName,resource.getFile(), classes); + } else { + throw new RuntimeException("Unsupported protocol: " + resource.getProtocol()); + } + } + } catch (IOException e) { + throw new RuntimeException(e); + } + return classes; + } + + // get class list by given file path + private static void getClassListByGivenFilePath( String packageName, String filePath, List> classes ) { + File file = new File(filePath); + if ( file.isDirectory() ) { + for ( File subFile : file.listFiles() ) { + ClassHelper.getClassListByGivenFilePath(packageName + "." + subFile.getName(), subFile.getAbsolutePath(), classes); + } + } else { + if ( file.getName().endsWith(".class") ) { + try { + String className = packageName.substring(0, packageName.length() - 6); + classes.add(Class.forName(className)); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + } + } +} diff --git a/src/src/main/java/com/my/graphiteDigesterBg/task/TaskDigestion.java b/src/src/main/java/com/my/graphiteDigesterBg/task/TaskDigestion.java index 4d4de9d..750a11a 100644 --- a/src/src/main/java/com/my/graphiteDigesterBg/task/TaskDigestion.java +++ b/src/src/main/java/com/my/graphiteDigesterBg/task/TaskDigestion.java @@ -1,5 +1,7 @@ package com.my.graphiteDigesterBg.task; import com.my.graphiteDigesterBg.diframe.DiTaskBase; +import com.my.graphiteDigesterBg.diframe.Task; +@Task(name="digestion") public class TaskDigestion extends DiTaskBase { @Override public void run() {