summaryrefslogtreecommitdiffstats
path: root/chain/src/main/java/com/yahoo/component/chain/ChainedComponent.java
diff options
context:
space:
mode:
Diffstat (limited to 'chain/src/main/java/com/yahoo/component/chain/ChainedComponent.java')
-rw-r--r--chain/src/main/java/com/yahoo/component/chain/ChainedComponent.java100
1 files changed, 100 insertions, 0 deletions
diff --git a/chain/src/main/java/com/yahoo/component/chain/ChainedComponent.java b/chain/src/main/java/com/yahoo/component/chain/ChainedComponent.java
new file mode 100644
index 00000000000..3a31b07adb7
--- /dev/null
+++ b/chain/src/main/java/com/yahoo/component/chain/ChainedComponent.java
@@ -0,0 +1,100 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.component.chain;
+
+import com.yahoo.component.AbstractComponent;
+import com.yahoo.component.ComponentId;
+import com.yahoo.component.chain.dependencies.After;
+import com.yahoo.component.chain.dependencies.Before;
+import com.yahoo.component.chain.dependencies.Dependencies;
+import com.yahoo.component.chain.dependencies.Provides;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Component with dependencies.
+ *
+ * @author tonytv
+ */
+public abstract class ChainedComponent extends AbstractComponent {
+
+ /** The immutable set of dependencies of this. NOTE: the default is only for unit testing. */
+ private Dependencies dependencies = getDefaultAnnotatedDependencies();
+
+ public ChainedComponent(ComponentId id) {
+ super(id);
+ }
+
+ protected ChainedComponent() {}
+
+ /**
+ * Called by the container to assign the full set of dependencies to this class (configured and declared).
+ * This is called once before this is started.
+ * @param dependencies The configured dependencies, that this method will merge with annotated dependencies.
+ */
+ public void initDependencies(Dependencies dependencies) {
+ this.dependencies = dependencies.union(getDefaultAnnotatedDependencies());
+ }
+
+ /** Returns the configured and declared dependencies of this chainedcomponent */
+ public Dependencies getDependencies() { return dependencies; }
+
+ /** This method is here only for legacy reasons, do not override. */
+ protected Dependencies getDefaultAnnotatedDependencies() {
+ Dependencies dependencies = getAnnotatedDependencies(com.yahoo.yolean.chain.Provides.class, com.yahoo.yolean.chain.Before.class, com.yahoo.yolean.chain.After.class);
+ Dependencies legacyDependencies = getAnnotatedDependencies(Provides.class, Before.class, After.class);
+
+ return dependencies.union(legacyDependencies);
+ }
+
+ /**
+ * @param providesClass The annotation class representing 'provides'.
+ * @param beforeClass The annotation class representing 'before'.
+ * @param afterClass The annotation class representing 'after'.
+ * @return a new {@link Dependencies} created from the annotations given in this component's class.
+ */
+ protected Dependencies getAnnotatedDependencies(Class<? extends Annotation> providesClass,
+ Class<? extends Annotation> beforeClass,
+ Class<? extends Annotation> afterClass) {
+ return new Dependencies(
+ allOf(getSymbols(this, providesClass), this.getClass().getSimpleName(), this.getClass().getName()),
+ getSymbols(this, beforeClass),
+ getSymbols(this, afterClass));
+ }
+
+ // TODO: move to vespajlib.
+ private static List<String> allOf(List<String> symbols, String... otherSymbols) {
+ List<String> result = new ArrayList<>(symbols);
+ result.addAll(Arrays.asList(otherSymbols));
+ return result;
+ }
+
+
+ private static List<String> getSymbols(ChainedComponent component, Class<? extends Annotation> annotationClass) {
+ List<String> result = new ArrayList<>();
+
+ result.addAll(annotationSymbols(component, annotationClass));
+ return result;
+ }
+
+ private static Collection<String> annotationSymbols(ChainedComponent component, Class<? extends Annotation> annotationClass) {
+
+ try {
+ Annotation annotation = component.getClass().getAnnotation(annotationClass);
+ if (annotation != null) {
+ Object values = annotationClass.getMethod("value").invoke(annotation);
+ return Arrays.asList((String[])values);
+ }
+ return Collections.emptyList();
+
+ } catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+}