summaryrefslogtreecommitdiff
path: root/base/src/main/java/bjc/utils/services
diff options
context:
space:
mode:
authorBen Culkin <scorpress@gmail.com>2022-09-27 19:21:16 -0400
committerBen Culkin <scorpress@gmail.com>2022-09-27 19:21:16 -0400
commit4a96d9cad446ea405b51dfeebb01a1b6d7f6fb2b (patch)
tree9aac0b901b53e99fbd06f59461519367bf4ca8ec /base/src/main/java/bjc/utils/services
parenta3d2728f84375566da3da560b3faad018d34005d (diff)
Add some interesting new things
Adds a number of things based off of some of the notes I've made over time, plus a few papers I've read. More details to come later, whenever I decide to actually get serious about documentation and examples and the like
Diffstat (limited to 'base/src/main/java/bjc/utils/services')
-rw-r--r--base/src/main/java/bjc/utils/services/Bordello.java53
-rw-r--r--base/src/main/java/bjc/utils/services/Implementor.java24
-rw-r--r--base/src/main/java/bjc/utils/services/package-info.java1
3 files changed, 78 insertions, 0 deletions
diff --git a/base/src/main/java/bjc/utils/services/Bordello.java b/base/src/main/java/bjc/utils/services/Bordello.java
new file mode 100644
index 0000000..104c4ab
--- /dev/null
+++ b/base/src/main/java/bjc/utils/services/Bordello.java
@@ -0,0 +1,53 @@
+package bjc.utils.services;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * A place to retrieve services from
+ *
+ * @author bjcul
+ *
+ */
+public class Bordello {
+ private static final Map<Class<?>, Object> services = new ConcurrentHashMap<>();
+
+ /**
+ * Retrieve the implementation of a given service.
+ *
+ * @param <T> The type of the service.
+ *
+ * @param interfaceClass The class of the service.
+ *
+ * @return The default implementation of the service.
+ */
+ public static <T> T get(Class<T> interfaceClass) {
+ synchronized (interfaceClass) {
+ Object service = services.get(interfaceClass);
+ if (service == null) {
+ try {
+ Class<?> implementor = interfaceClass.getAnnotation(Implementor.class).value();
+ service = implementor.getDeclaredConstructor().newInstance();
+ services.put(interfaceClass, implementor);
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ return interfaceClass.cast(service);
+ }
+ }
+
+ /**
+ * Set an implementation for a given service to be something other than the default.
+ *
+ * @param <T> The type of the service
+ *
+ * @param interfaceClass The class of the service
+ * @param implementor The alternate implementation for the service.
+ */
+ public static <T> void set(Class<T> interfaceClass, T implementor) {
+ synchronized (interfaceClass) {
+ services.put(interfaceClass, implementor);
+ }
+ }
+}
diff --git a/base/src/main/java/bjc/utils/services/Implementor.java b/base/src/main/java/bjc/utils/services/Implementor.java
new file mode 100644
index 0000000..3dac860
--- /dev/null
+++ b/base/src/main/java/bjc/utils/services/Implementor.java
@@ -0,0 +1,24 @@
+package bjc.utils.services;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.*;
+
+/**
+ * Indicates the default implementation for a given service.
+ *
+ * @author bjcul
+ *
+ */
+@Documented
+@Retention(RUNTIME)
+@Target(TYPE)
+public @interface Implementor {
+ /**
+ * The default implementation for the service this annotates.
+ *
+ * @return The default impl. for the service this annotates
+ */
+ Class<?> value();
+}
diff --git a/base/src/main/java/bjc/utils/services/package-info.java b/base/src/main/java/bjc/utils/services/package-info.java
new file mode 100644
index 0000000..24f6855
--- /dev/null
+++ b/base/src/main/java/bjc/utils/services/package-info.java
@@ -0,0 +1 @@
+package bjc.utils.services; \ No newline at end of file