diff --git a/pom.xml b/pom.xml
index 0adf674..28528bf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
- nl.andrewlalis
+ nl.andrewl
simply-scheduled
1.0-SNAPSHOT
jar
@@ -42,15 +42,16 @@
11
-
-
-
- org.apache.maven.plugins
- maven-surefire-plugin
- 3.0.0-M5
-
-
-
+
+
+ ossrh
+ https://s01.oss.sonatype.org/content/repositories/snapshots
+
+
+ ossrh
+ https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/
+
+
@@ -73,4 +74,54 @@
test
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.0.0-M5
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+ 3.0.1
+
+
+ sign-artifacts
+ verify
+
+ sign
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 3.3.0
+
+
+ attach-javadocs
+
+ jar
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 3.2.1
+
+
+ attach-sources
+
+ jar-no-fork
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
index 5735d78..1359d8f 100644
--- a/src/main/java/module-info.java
+++ b/src/main/java/module-info.java
@@ -1,6 +1,10 @@
+/**
+ * The SimplyScheduled module.
+ */
module simply_scheduled {
- exports nl.andrewlalis.simply_scheduled;
- exports nl.andrewlalis.simply_scheduled.schedule;
+ exports nl.andrewl.simply_scheduled;
+ exports nl.andrewl.simply_scheduled.schedule;
- opens nl.andrewlalis.simply_scheduled;
+ // Needed for JUnit testing.
+ opens nl.andrewl.simply_scheduled;
}
\ No newline at end of file
diff --git a/src/main/java/nl/andrewlalis/simply_scheduled/BasicScheduler.java b/src/main/java/nl/andrewl/simply_scheduled/BasicScheduler.java
similarity index 85%
rename from src/main/java/nl/andrewlalis/simply_scheduled/BasicScheduler.java
rename to src/main/java/nl/andrewl/simply_scheduled/BasicScheduler.java
index 49517e1..ecb516f 100644
--- a/src/main/java/nl/andrewlalis/simply_scheduled/BasicScheduler.java
+++ b/src/main/java/nl/andrewl/simply_scheduled/BasicScheduler.java
@@ -1,6 +1,6 @@
-package nl.andrewlalis.simply_scheduled;
+package nl.andrewl.simply_scheduled;
-import nl.andrewlalis.simply_scheduled.schedule.Task;
+import nl.andrewl.simply_scheduled.schedule.Task;
import java.time.Clock;
import java.time.Instant;
@@ -20,12 +20,22 @@ public class BasicScheduler extends Thread implements Scheduler {
private final ExecutorService executorService;
private boolean running = false;
+ /**
+ * Constructs the scheduler using the given clock and executor service. This
+ * constructor is most useful for test cases where a custom clock is used.
+ * @param clock The clock to use.
+ * @param executorService The executor service to use.
+ */
public BasicScheduler(Clock clock, ExecutorService executorService) {
this.clock = clock;
this.tasks = new PriorityBlockingQueue<>();
this.executorService = executorService;
}
+ /**
+ * Constructs the scheduler using the system's default clock, and a new
+ * work-stealing thread pool.
+ */
public BasicScheduler() {
this(Clock.systemDefaultZone(), Executors.newWorkStealingPool());
}
diff --git a/src/main/java/nl/andrewlalis/simply_scheduled/Demo.java b/src/main/java/nl/andrewl/simply_scheduled/Demo.java
similarity index 67%
rename from src/main/java/nl/andrewlalis/simply_scheduled/Demo.java
rename to src/main/java/nl/andrewl/simply_scheduled/Demo.java
index bab9205..d92627d 100644
--- a/src/main/java/nl/andrewlalis/simply_scheduled/Demo.java
+++ b/src/main/java/nl/andrewl/simply_scheduled/Demo.java
@@ -1,11 +1,14 @@
-package nl.andrewlalis.simply_scheduled;
+package nl.andrewl.simply_scheduled;
-import nl.andrewlalis.simply_scheduled.schedule.RepeatingSchedule;
-import nl.andrewlalis.simply_scheduled.schedule.Schedule;
+import nl.andrewl.simply_scheduled.schedule.RepeatingSchedule;
+import nl.andrewl.simply_scheduled.schedule.Schedule;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
+/**
+ * Simple demonstration of scheduling functionality.
+ */
public class Demo {
public static void main(String[] args) {
Scheduler scheduler = new BasicScheduler();
diff --git a/src/main/java/nl/andrewlalis/simply_scheduled/Scheduler.java b/src/main/java/nl/andrewl/simply_scheduled/Scheduler.java
similarity index 88%
rename from src/main/java/nl/andrewlalis/simply_scheduled/Scheduler.java
rename to src/main/java/nl/andrewl/simply_scheduled/Scheduler.java
index ff253b3..5796935 100644
--- a/src/main/java/nl/andrewlalis/simply_scheduled/Scheduler.java
+++ b/src/main/java/nl/andrewl/simply_scheduled/Scheduler.java
@@ -1,7 +1,7 @@
-package nl.andrewlalis.simply_scheduled;
+package nl.andrewl.simply_scheduled;
-import nl.andrewlalis.simply_scheduled.schedule.Schedule;
-import nl.andrewlalis.simply_scheduled.schedule.Task;
+import nl.andrewl.simply_scheduled.schedule.Task;
+import nl.andrewl.simply_scheduled.schedule.Schedule;
/**
* A scheduler is responsible for storing and executing tasks as defined by each
diff --git a/src/main/java/nl/andrewlalis/simply_scheduled/schedule/DailySchedule.java b/src/main/java/nl/andrewl/simply_scheduled/schedule/DailySchedule.java
similarity index 57%
rename from src/main/java/nl/andrewlalis/simply_scheduled/schedule/DailySchedule.java
rename to src/main/java/nl/andrewl/simply_scheduled/schedule/DailySchedule.java
index 9e61d60..5b4fc0b 100644
--- a/src/main/java/nl/andrewlalis/simply_scheduled/schedule/DailySchedule.java
+++ b/src/main/java/nl/andrewl/simply_scheduled/schedule/DailySchedule.java
@@ -1,4 +1,4 @@
-package nl.andrewlalis.simply_scheduled.schedule;
+package nl.andrewl.simply_scheduled.schedule;
import java.time.*;
import java.util.Optional;
@@ -11,10 +11,21 @@ public class DailySchedule implements Schedule {
private final ZoneId zoneId;
private final LocalTime time;
+ /**
+ * Constructs a new schedule that will execute at the given time, using the
+ * system's default time zone.
+ * @param time The time at which to execute any tasks using this schedule.
+ */
public DailySchedule(LocalTime time) {
this(time, ZoneId.systemDefault());
}
+ /**
+ * Constructs a new schedule that will execute at the given time, using the
+ * given zone id for time zone information.
+ * @param time The time at which to execute any tasks using this schedule.
+ * @param zoneId The time zone id.
+ */
public DailySchedule(LocalTime time, ZoneId zoneId) {
this.time = time;
this.zoneId = zoneId;
@@ -23,9 +34,9 @@ public class DailySchedule implements Schedule {
@Override
public Optional getNextExecutionTime(Instant referenceInstant) {
ZonedDateTime currentTime = referenceInstant.atZone(this.zoneId);
- LocalDate currentDay = LocalDate.from(referenceInstant);
+ LocalDate currentDay = LocalDate.ofInstant(referenceInstant, this.zoneId);
ZonedDateTime sameDayExecution = currentDay.atTime(this.time).atZone(this.zoneId);
- if (sameDayExecution.isBefore(currentTime)) {
+ if (sameDayExecution.isAfter(currentTime)) {
return Optional.of(sameDayExecution.toInstant());
}
return Optional.of(sameDayExecution.plusDays(1).toInstant());
diff --git a/src/main/java/nl/andrewlalis/simply_scheduled/schedule/HourlySchedule.java b/src/main/java/nl/andrewl/simply_scheduled/schedule/HourlySchedule.java
similarity index 95%
rename from src/main/java/nl/andrewlalis/simply_scheduled/schedule/HourlySchedule.java
rename to src/main/java/nl/andrewl/simply_scheduled/schedule/HourlySchedule.java
index 5db9b1e..720a2c6 100644
--- a/src/main/java/nl/andrewlalis/simply_scheduled/schedule/HourlySchedule.java
+++ b/src/main/java/nl/andrewl/simply_scheduled/schedule/HourlySchedule.java
@@ -1,4 +1,4 @@
-package nl.andrewlalis.simply_scheduled.schedule;
+package nl.andrewl.simply_scheduled.schedule;
import java.time.Instant;
import java.time.ZoneId;
diff --git a/src/main/java/nl/andrewlalis/simply_scheduled/schedule/RepeatingSchedule.java b/src/main/java/nl/andrewl/simply_scheduled/schedule/RepeatingSchedule.java
similarity index 97%
rename from src/main/java/nl/andrewlalis/simply_scheduled/schedule/RepeatingSchedule.java
rename to src/main/java/nl/andrewl/simply_scheduled/schedule/RepeatingSchedule.java
index 1f1cb8c..69b292d 100644
--- a/src/main/java/nl/andrewlalis/simply_scheduled/schedule/RepeatingSchedule.java
+++ b/src/main/java/nl/andrewl/simply_scheduled/schedule/RepeatingSchedule.java
@@ -1,4 +1,4 @@
-package nl.andrewlalis.simply_scheduled.schedule;
+package nl.andrewl.simply_scheduled.schedule;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
diff --git a/src/main/java/nl/andrewlalis/simply_scheduled/schedule/Schedule.java b/src/main/java/nl/andrewl/simply_scheduled/schedule/Schedule.java
similarity index 93%
rename from src/main/java/nl/andrewlalis/simply_scheduled/schedule/Schedule.java
rename to src/main/java/nl/andrewl/simply_scheduled/schedule/Schedule.java
index e1b5a5c..e07accb 100644
--- a/src/main/java/nl/andrewlalis/simply_scheduled/schedule/Schedule.java
+++ b/src/main/java/nl/andrewl/simply_scheduled/schedule/Schedule.java
@@ -1,6 +1,6 @@
-package nl.andrewlalis.simply_scheduled.schedule;
+package nl.andrewl.simply_scheduled.schedule;
-import nl.andrewlalis.simply_scheduled.Scheduler;
+import nl.andrewl.simply_scheduled.Scheduler;
import java.time.Instant;
import java.util.Optional;
diff --git a/src/main/java/nl/andrewlalis/simply_scheduled/schedule/SpecificInstantSchedule.java b/src/main/java/nl/andrewl/simply_scheduled/schedule/SpecificInstantSchedule.java
similarity index 95%
rename from src/main/java/nl/andrewlalis/simply_scheduled/schedule/SpecificInstantSchedule.java
rename to src/main/java/nl/andrewl/simply_scheduled/schedule/SpecificInstantSchedule.java
index 57b3bc9..10e6068 100644
--- a/src/main/java/nl/andrewlalis/simply_scheduled/schedule/SpecificInstantSchedule.java
+++ b/src/main/java/nl/andrewl/simply_scheduled/schedule/SpecificInstantSchedule.java
@@ -1,4 +1,4 @@
-package nl.andrewlalis.simply_scheduled.schedule;
+package nl.andrewl.simply_scheduled.schedule;
import java.time.Instant;
import java.time.ZonedDateTime;
diff --git a/src/main/java/nl/andrewlalis/simply_scheduled/schedule/Task.java b/src/main/java/nl/andrewl/simply_scheduled/schedule/Task.java
similarity index 78%
rename from src/main/java/nl/andrewlalis/simply_scheduled/schedule/Task.java
rename to src/main/java/nl/andrewl/simply_scheduled/schedule/Task.java
index b563a81..381bd15 100644
--- a/src/main/java/nl/andrewlalis/simply_scheduled/schedule/Task.java
+++ b/src/main/java/nl/andrewl/simply_scheduled/schedule/Task.java
@@ -1,4 +1,4 @@
-package nl.andrewlalis.simply_scheduled.schedule;
+package nl.andrewl.simply_scheduled.schedule;
import java.time.Clock;
import java.time.Instant;
@@ -52,6 +52,15 @@ public class Task implements Comparable{
return schedule;
}
+ /**
+ * Compares this task to another. This imposes a natural ordering of tasks
+ * according to their schedule's next planned execution time, such that
+ * tasks are ordered starting with those with the nearest execution time, to
+ * those whose execution time is further in the future.
+ * @param o The task to compare to.
+ * @return -1 if this task's next execution time is before the other task's,
+ * 1 if this task's next execution time is after the other, and 0 otherwise.
+ */
@Override
public int compareTo(Task o) {
Instant now = clock.instant();
diff --git a/src/test/java/nl/andrewlalis/simply_scheduled/BasicSchedulerTest.java b/src/test/java/nl/andrewl/simply_scheduled/BasicSchedulerTest.java
similarity index 91%
rename from src/test/java/nl/andrewlalis/simply_scheduled/BasicSchedulerTest.java
rename to src/test/java/nl/andrewl/simply_scheduled/BasicSchedulerTest.java
index 7f7f478..67e3418 100644
--- a/src/test/java/nl/andrewlalis/simply_scheduled/BasicSchedulerTest.java
+++ b/src/test/java/nl/andrewl/simply_scheduled/BasicSchedulerTest.java
@@ -1,8 +1,8 @@
-package nl.andrewlalis.simply_scheduled;
+package nl.andrewl.simply_scheduled;
-import nl.andrewlalis.simply_scheduled.schedule.RepeatingSchedule;
-import nl.andrewlalis.simply_scheduled.schedule.Schedule;
-import nl.andrewlalis.simply_scheduled.schedule.Task;
+import nl.andrewl.simply_scheduled.schedule.Task;
+import nl.andrewl.simply_scheduled.schedule.RepeatingSchedule;
+import nl.andrewl.simply_scheduled.schedule.Schedule;
import org.junit.jupiter.api.Test;
import java.time.Clock;
diff --git a/src/test/java/nl/andrewl/simply_scheduled/schedule/DailyScheduleTest.java b/src/test/java/nl/andrewl/simply_scheduled/schedule/DailyScheduleTest.java
new file mode 100644
index 0000000..1cc18bd
--- /dev/null
+++ b/src/test/java/nl/andrewl/simply_scheduled/schedule/DailyScheduleTest.java
@@ -0,0 +1,40 @@
+package nl.andrewl.simply_scheduled.schedule;
+
+import java.time.*;
+import java.util.stream.Stream;
+
+/**
+ * Tests the ability of the {@link DailySchedule} to reliably give the correct
+ * next execution time.
+ */
+public class DailyScheduleTest extends ScheduleTest {
+ @Override
+ protected Stream getTestCases() {
+ var utc = ZoneOffset.UTC;
+ // For this test, we use a fixed clock at 12:30:45 on August 6, 2021, UTC.
+ Clock clock = Clock.fixed(ZonedDateTime.of(2021, 8, 6, 12, 30, 45, 0, utc).toInstant(), utc);
+ ZonedDateTime time = ZonedDateTime.ofInstant(clock.instant(), utc);
+ return Stream.of(
+ new TestCase( // A daily schedule whose time has already passed will be scheduled for tomorrow.
+ new DailySchedule(LocalTime.of(12, 0), utc),
+ clock.instant(),
+ time.plusDays(1).toLocalDate().atTime(12, 0).toInstant(utc)
+ ),
+ new TestCase( // A daily schedule whose time has not yet passed will be scheduled for today.
+ new DailySchedule(LocalTime.of(18, 44, 3), utc),
+ clock.instant(),
+ time.toLocalDate().atTime(18, 44, 3).toInstant(utc)
+ ),
+ new TestCase( // Account for a time zone which introduces some offset.
+ new DailySchedule(LocalTime.of(10, 30), ZoneOffset.ofHours(-5)),
+ clock.instant(),
+ time.toLocalDate().atTime(15, 30).toInstant(utc)
+ ),
+ new TestCase( // Account for a time zone whose offset makes it such that the next event is scheduled for tomorrow, in UTC.
+ new DailySchedule(LocalTime.of(10, 30), ZoneOffset.ofHours(-1)),
+ clock.instant(),
+ time.plusDays(1).toLocalDate().atTime(11, 30).toInstant(utc)
+ )
+ );
+ }
+}
diff --git a/src/test/java/nl/andrewl/simply_scheduled/schedule/ScheduleTest.java b/src/test/java/nl/andrewl/simply_scheduled/schedule/ScheduleTest.java
new file mode 100644
index 0000000..0ddc35d
--- /dev/null
+++ b/src/test/java/nl/andrewl/simply_scheduled/schedule/ScheduleTest.java
@@ -0,0 +1,43 @@
+package nl.andrewl.simply_scheduled.schedule;
+
+import org.junit.jupiter.api.Test;
+
+import java.time.Instant;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * Abstract test class which can be extended to test the functionality of a
+ * particular schedule's {@link Schedule#getNextExecutionTime(Instant)} method.
+ */
+public abstract class ScheduleTest {
+ protected static class TestCase {
+ public final Schedule schedule;
+ public final Instant referenceInstant;
+ public final Instant expectedNextExecution;
+ public TestCase(Schedule schedule, Instant referenceInstant, Instant expectedNextExecution) {
+ this.schedule = schedule;
+ this.referenceInstant = referenceInstant;
+ this.expectedNextExecution = expectedNextExecution;
+ }
+ }
+
+ @Test
+ public void testGetNextExecutionTime() {
+ var cases = getTestCases().collect(Collectors.toList());
+ for (int i = 0; i < cases.size(); i++) {
+ var testCase = cases.get(i);
+ var r = testCase.schedule.getNextExecutionTime(testCase.referenceInstant);
+ if (testCase.expectedNextExecution == null) {
+ assertTrue(r.isEmpty(), "Case " + i + ": next execution time is not empty when it should be.");
+ } else {
+ assertTrue(r.isPresent(), "Case " + i + ": next execution time is not present when it should be.");
+ assertEquals(testCase.expectedNextExecution, r.get(), "Case " + i + ": expected next execution time does not match expected.");
+ }
+ }
+ }
+
+ protected abstract Stream getTestCases();
+}