Skip to content

Commit d64b3f1

Browse files
author
Dev-Bjorn
committed
V1.2.0: Constructor Dependency Retriever Added
1 parent 7164274 commit d64b3f1

File tree

11 files changed

+336
-41
lines changed

11 files changed

+336
-41
lines changed

README.md

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Add this to your `pom.xml`.
1717
<dependency>
1818
<groupId>nl.devoxist</groupId>
1919
<artifactId>module-scheduler</artifactId>
20-
<version>1.1.0</version>
20+
<version>1.2.0</version>
2121
</dependency>
2222
```
2323

@@ -61,8 +61,12 @@ public class ModuleA implements Module {
6161
}
6262
```
6363

64-
To mark a dependency link to another module use the `@Dependency` annotation above the class of the `Module`. This
65-
annotation is needed to order the Modules.
64+
To mark a dependency to another module use the `@Dependency` annotation above the class of the `Module`. And/Or the
65+
dependencies can be added in a constructor. If the dependency is added in any constructor, then the annotation is not
66+
required and vice versa. The dependencies in the constructor and the value of the annotation need to be extended by
67+
the `Module` class. Only the constructor parameters that are extended by the `Module` class will be injected by the
68+
system, others parameters that are not extended need to be delivered by through the registers,
69+
`ModuleSchedulerSettings#addRegisters`. These dependencies manipulate the order in which the modules are getting runned.
6670

6771
```java
6872

@@ -81,15 +85,19 @@ public class ModuleB implements Module {
8185
}
8286
```
8387

84-
To mark a multiple dependency links to another module use the `@Dependency` annotation above the class of the `Module`.
85-
This annotation is needed to order the Modules.
88+
If a module has multiple dependencies, add the dependencies in the `@Dependency` annotation like an array. And/Or add
89+
the dependencies in a constructor. These dependencies can be added in multiple constructors. Like in the example below.
8690

8791
```java
8892

8993
@Dependency({ModuleB.class, ModuleA.class})
9094
public class ModuleC implements Module {
9195

92-
public ModuleC(ModuleA moduleA, ModuleB moduleB) {
96+
public ModuleC(ModuleA moduleA) {
97+
// Put here your stuff
98+
}
99+
100+
public ModuleC(ModuleB moduleB) {
93101
// Put here your stuff
94102
}
95103

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
<groupId>nl.devoxist</groupId>
3030
<artifactId>module-scheduler</artifactId>
3131
<packaging>jar</packaging>
32-
<version>1.1.0</version>
32+
<version>1.2.0</version>
3333

3434
<name>Module Scheduler</name>
3535
<description>An API to order tasks in the correct order</description>
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright (c) 2023 Devoxist, Dev-Bjorn
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in all
12+
* copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
* SOFTWARE.
21+
*/
22+
23+
package nl.devoxist.modulescheduler.collection;
24+
25+
import nl.devoxist.modulescheduler.resolvers.DependencyRetriever;
26+
import org.jetbrains.annotations.NotNull;
27+
28+
import java.lang.reflect.Array;
29+
30+
/**
31+
* {@link Arrays} is an object that has functions that manipulate an {@link Array}.
32+
*
33+
* @author Dev-Bjorn
34+
* @version 1.2.0
35+
* @since 1.2.0
36+
*/
37+
public class Arrays {
38+
39+
/**
40+
* Construct a new {@link DependencyRetriever} object. This always fails, because the class is a static class.
41+
* So it only contains static objects. Thus, it throws an {@link IllegalAccessException}.
42+
*
43+
* @throws IllegalAccessException If the {@link DependencyRetriever} was try to construct the class. The
44+
* construction of this class is not possible, because this is a static class.
45+
* @since 1.2.0
46+
*/
47+
private Arrays() throws IllegalAccessException {
48+
throw new IllegalAccessException("This class is a static class, so the construction is not accessible.");
49+
}
50+
51+
/**
52+
* Merge two arrays into one array.
53+
*
54+
* @param firstArray The first array that going to be merged with the second array.
55+
* @param secondArray The second array that will be merged into the first array.
56+
* @param <T> The type of the arrays.
57+
*
58+
* @return The merged array.
59+
*
60+
* @since 1.2.0
61+
*/
62+
public static <T> T @NotNull [] concatArrays(T[] firstArray, T @NotNull [] secondArray) {
63+
T[] result = java.util.Arrays.copyOf(firstArray, firstArray.length + secondArray.length);
64+
System.arraycopy(secondArray, 0, result, firstArray.length, secondArray.length);
65+
return result;
66+
}
67+
}

src/main/java/nl/devoxist/modulescheduler/console/Formatter.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@
2929
* {@link java.util.logging.Formatter}.
3030
*
3131
* @author Dev-Bjorn
32-
* @version 1.0.0
32+
* @version 1.2.0
3333
* @see Formatter
3434
* @since 1.1.0
3535
*/
36-
public class Formatter extends java.util.logging.Formatter {
37-
36+
public final class Formatter extends java.util.logging.Formatter {
37+
3838
/**
3939
* Format the given log record and return the formatted string.
4040
* <p>

src/main/java/nl/devoxist/modulescheduler/path/PathCyclePrinter.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@
3636
* dependencies.
3737
*
3838
* @author Dev-Bjorn
39-
* @version 1.1.0
39+
* @version 1.2.0
4040
* @since 1.0.0
4141
*/
42-
public class PathCyclePrinter extends Thread {
42+
public final class PathCyclePrinter extends Thread {
4343
/**
4444
* The start path of the resolver.
4545
*
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
* Copyright (c) 2023 Devoxist, Dev-Bjorn
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in all
12+
* copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
* SOFTWARE.
21+
*/
22+
23+
package nl.devoxist.modulescheduler.resolvers;
24+
25+
import nl.devoxist.modulescheduler.Module;
26+
import nl.devoxist.modulescheduler.annotation.Dependency;
27+
import nl.devoxist.modulescheduler.collection.Arrays;
28+
import org.jetbrains.annotations.Contract;
29+
import org.jetbrains.annotations.NotNull;
30+
31+
import java.util.stream.Stream;
32+
33+
/**
34+
* {@link DependencyRetriever} is an object that is responsible for retrieving the dependencies of the {@link Module}s
35+
*
36+
* @author Dev-Bjorn
37+
* @version 1.2.0
38+
* @since 1.2.0
39+
*/
40+
public final class DependencyRetriever {
41+
42+
/**
43+
* Construct a new {@link DependencyRetriever} object. This always fails, because the class is a static class.
44+
* So it only contains static objects. Thus, it throws an {@link IllegalAccessException}.
45+
*
46+
* @throws IllegalAccessException If the {@link DependencyRetriever} was try to construct the class. The
47+
* construction of this class is not possible, because this is a static class.
48+
* @since 1.2.0
49+
*/
50+
@Contract(pure = true)
51+
private DependencyRetriever() throws IllegalAccessException {
52+
throw new IllegalAccessException("This class is a static class, so the construction is not accessible.");
53+
}
54+
55+
/**
56+
* Get the dependencies of a {@link Module} class. These dependencies can be retrieved by the {@link Dependency}
57+
* annotation or the constructors of the given class.
58+
*
59+
* @param moduleCls The class of which the dependencies are retrieved from.
60+
*
61+
* @return The dependencies of the given {@link Module} class. If there is no {@link Dependency} annotation or
62+
* constructor present in the given class it will return an empty array of {@link Module} classes.
63+
*
64+
* @since 1.2.0
65+
*/
66+
public static Class<? extends Module>[] getDependencies(
67+
@NotNull Class<? extends Module> moduleCls
68+
) {
69+
return Arrays.concatArrays(
70+
getDependenciesByAnnotation(moduleCls),
71+
getDependenciesByConstructor(moduleCls)
72+
);
73+
}
74+
75+
76+
/**
77+
* Get the dependencies of a {@link Module} class by the parameters of the constructors of the given class.
78+
*
79+
* @param moduleCls The class of which the dependencies are retrieved from.
80+
*
81+
* @return The dependencies of the given {@link Module} class. If there are no constructors present in the given
82+
* class, the return will be an empty array.
83+
*
84+
* @since 1.2.0
85+
*/
86+
@SuppressWarnings("unchecked")
87+
private static Class<? extends Module> @NotNull [] getDependenciesByConstructor(@NotNull Class<? extends Module> moduleCls) {
88+
return (Class<? extends Module>[]) Stream.of(moduleCls.getDeclaredConstructors())
89+
.flatMap((declaredConstructor) -> Stream.of(declaredConstructor.getParameterTypes()))
90+
.filter(Module.class::isAssignableFrom)
91+
.distinct()
92+
.toArray(Class<?>[]::new);
93+
}
94+
95+
/**
96+
* Get the dependencies of a {@link Module} class by the annotation {@link Dependency}. If the {@link Dependency} is
97+
* not present on the class it will return an empty array of {@link Module} classes.
98+
*
99+
* @param moduleCls The class of which the dependencies are retrieved from.
100+
*
101+
* @return The dependencies of the given {@link Module} class. If the {@link Dependency} is not present on the class it will
102+
* return an empty array of {@link Module} classes.
103+
*
104+
* @since 1.2.0
105+
*/
106+
@SuppressWarnings("unchecked")
107+
private static Class<? extends Module>[] getDependenciesByAnnotation(@NotNull Class<? extends Module> moduleCls) {
108+
if (!moduleCls.isAnnotationPresent(Dependency.class)) {
109+
return (Class<? extends Module>[]) new Class<?>[0];
110+
}
111+
Dependency dependency = moduleCls.getAnnotation(Dependency.class);
112+
return dependency.value();
113+
}
114+
}

src/main/java/nl/devoxist/modulescheduler/resolvers/ModuleInformationResolver.java

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
package nl.devoxist.modulescheduler.resolvers;
2424

2525
import nl.devoxist.modulescheduler.Module;
26-
import nl.devoxist.modulescheduler.annotation.Dependency;
2726
import nl.devoxist.modulescheduler.settings.ModuleInformation;
2827
import org.jetbrains.annotations.Contract;
2928
import org.jetbrains.annotations.NotNull;
@@ -35,7 +34,7 @@
3534
* ({@link ModuleInformation}).
3635
*
3736
* @author Dev-Bjorn
38-
* @version 1.0.0
37+
* @version 1.2.0
3938
* @since 1.0.0
4039
*/
4140
public final class ModuleInformationResolver {
@@ -71,7 +70,7 @@ private ModuleInformationResolver() throws IllegalAccessException {
7170
) {
7271
ModuleInformation<?> moduleInformation = getModuleInformation(moduleCls, moduleInformationMap);
7372

74-
Class<? extends Module>[] dependencies = getDependencies(moduleCls);
73+
Class<? extends Module>[] dependencies = DependencyRetriever.getDependencies(moduleCls);
7574

7675
for (Class<? extends Module> dependency : dependencies) {
7776
addDependsOnInformation(moduleInformation, dependency, moduleInformationMap);
@@ -127,24 +126,4 @@ private static void addDependsOnInformation(
127126
ModuleInformation<?> dependentModuleInformation = getModuleInformation(dependentOfModule, moduleInformationMap);
128127
dependentModuleInformation.addDependsOn(moduleInformation);
129128
}
130-
131-
/**
132-
* Get the dependencies of a {@link Module} class. If the {@link Dependency} is not present on the class it will
133-
* return an empty array of {@link Module} classes.
134-
*
135-
* @param moduleCls The class of which the dependencies are retrieved from.
136-
*
137-
* @return The dependencies of the given {@link Module} class. If the {@link Dependency} is not present on the class it will
138-
* return an empty array of {@link Module} classes.
139-
*
140-
* @since 1.0.0
141-
*/
142-
@SuppressWarnings("unchecked")
143-
private static Class<? extends Module>[] getDependencies(@NotNull Class<? extends Module> moduleCls) {
144-
if (!moduleCls.isAnnotationPresent(Dependency.class)) {
145-
return (Class<Module>[]) new Class<?>[0];
146-
}
147-
Dependency dependency = moduleCls.getAnnotation(Dependency.class);
148-
return dependency.value();
149-
}
150129
}

src/main/java/nl/devoxist/modulescheduler/runner/StageRunner.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@
3737
* The process of loading the {@link Module}s.
3838
*
3939
* @author Dev-Bjorn
40-
* @version 1.0.0
40+
* @version 1.2.0
4141
* @since 1.0.0
4242
*/
43-
public class StageRunner extends Thread {
43+
public final class StageRunner extends Thread {
4444
/**
4545
* The settings of the current running {@link ModuleScheduler}.
4646
*

src/main/java/nl/devoxist/modulescheduler/settings/ModuleSchedulerInformation.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@
3535
* {@link ModuleScheduler}.
3636
*
3737
* @author Dev-Bjorn
38-
* @version 1.0.0
38+
* @version 1.2.0
3939
* @since 1.0.0
4040
*/
41-
public class ModuleSchedulerInformation {
41+
public final class ModuleSchedulerInformation {
4242
/**
4343
* The settings of the current running {@link ModuleScheduler}.
4444
*

src/main/java/nl/devoxist/modulescheduler/settings/ModuleSchedulerSettings.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@
3636
* This object gives the options to manipulate the process.
3737
*
3838
* @author Dev-Bjorn
39-
* @version 1.0.0
39+
* @version 1.2.0
4040
* @since 1.0.0
4141
*/
42-
public class ModuleSchedulerSettings {
42+
public final class ModuleSchedulerSettings implements Cloneable {
4343
/**
4444
* {@link Set} of modules that need to be loaded.
4545
*

0 commit comments

Comments
 (0)