Skip to content

Commit 756d657

Browse files
committed
Editing for core.pipeline
- Add javadocs - Tighten access where appropiate - Add check for non-public metric methods in the Pipeline
1 parent 5f69992 commit 756d657

5 files changed

Lines changed: 123 additions & 10 deletions

File tree

src/main/java/nl/rug/jbi/jsm/core/pipeline/HandlerExecutor.java

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package nl.rug.jbi.jsm.core.pipeline;
22

33
import com.google.common.base.Objects;
4-
import com.google.common.base.Preconditions;
54
import nl.rug.jbi.jsm.core.calculator.BaseMetric;
65
import nl.rug.jbi.jsm.core.calculator.MetricScope;
76
import nl.rug.jbi.jsm.core.calculator.MetricState;
@@ -10,23 +9,46 @@
109
import java.lang.reflect.InvocationTargetException;
1110
import java.lang.reflect.Method;
1211

12+
import static com.google.common.base.Preconditions.checkNotNull;
13+
14+
/**
15+
* This class encapsulates a object-method pair accepting a certain data-type, derived from a metric.
16+
* As data becomes available it gets sent through this object together with the associated MetricState to mutate that
17+
* state using the method.
18+
*
19+
* @author David van Leusen
20+
* @since 2014-06-02
21+
*/
1322
public class HandlerExecutor {
1423
private final Method eventMethod;
1524
private final BaseMetric metricCalculator;
1625

17-
public HandlerExecutor(final Method eventMethod, final BaseMetric metricCalculator) {
18-
this.eventMethod = Preconditions.checkNotNull(eventMethod);
19-
this.metricCalculator = Preconditions.checkNotNull(metricCalculator);
26+
HandlerExecutor(final Method eventMethod, final BaseMetric metricCalculator) {
27+
this.eventMethod = checkNotNull(eventMethod);
28+
this.metricCalculator = checkNotNull(metricCalculator);
2029
}
2130

31+
/**
32+
* @return The metric class this handler is built from.
33+
*/
2234
public Class getMetricClass() {
2335
return this.metricCalculator.getClass();
2436
}
2537

38+
/**
39+
* @return The scope in which this handler gets executed.
40+
*/
2641
public MetricScope getScope() {
2742
return this.metricCalculator.getScope();
2843
}
2944

45+
/**
46+
* Applies the internal method to the given data and state, mutating the state to progress to the result.
47+
*
48+
* @param obj Data to publish
49+
* @param state External state associated with the data-source.
50+
* @throws MetricExecutionException If an exception occurs whilst executing the method.
51+
*/
3052
public void emitEvent(final Object obj, final MetricState state) throws MetricExecutionException {
3153
try {
3254
this.eventMethod.invoke(this.metricCalculator, state, obj);

src/main/java/nl/rug/jbi/jsm/core/pipeline/HandlerMap.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,23 @@
88
import java.util.List;
99
import java.util.Map;
1010

11+
/**
12+
* Container for a set of handlers, associating data-types to a list of {@link nl.rug.jbi.jsm.core.pipeline.HandlerExecutor}.
13+
*
14+
* @author David van Leusen
15+
* @since 2014-06-02
16+
*/
1117
public class HandlerMap {
1218
private final static List<HandlerExecutor> EMPTY_LIST = ImmutableList.of();
1319
private final Map<Class, List<HandlerExecutor>> handlers = Maps.newIdentityHashMap();
1420

21+
/**
22+
* Get the list of handlers for the given data-type.
23+
* Will always return a list even if there are no handlers for the given data-type.
24+
*
25+
* @param dataType data-type to retrieve the handlers for.
26+
* @return List of handlers for the given data-type, never returns NULL.
27+
*/
1528
public List<HandlerExecutor> getHandlers(final Class dataType) {
1629
final List<HandlerExecutor> ret = this.handlers.get(dataType);
1730
return ret != null ? ret : EMPTY_LIST;

src/main/java/nl/rug/jbi/jsm/core/pipeline/MetricPreparationException.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
package nl.rug.jbi.jsm.core.pipeline;
22

3+
/**
4+
* Exception thrown is there is an issue with the definition or registration of a metric.
5+
* The error message will always contain the reason for the exception.
6+
*
7+
* @author David van Leusen
8+
* @since 2014-06-02
9+
*/
310
public class MetricPreparationException extends Exception {
411
public MetricPreparationException(final String msg) {
512
super(msg);

src/main/java/nl/rug/jbi/jsm/core/pipeline/Pipeline.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,19 @@
1414

1515
import java.lang.reflect.InvocationTargetException;
1616
import java.lang.reflect.Method;
17+
import java.lang.reflect.Modifier;
1718
import java.util.*;
1819

1920
import static com.google.common.base.Preconditions.checkArgument;
2021
import static com.google.common.base.Preconditions.checkNotNull;
2122

2223
/**
24+
* The pipeline encapsulates the planned execution order of metrics, when data is available and what metrics to finalize
25+
* when. It does this by creating chains of {@link nl.rug.jbi.jsm.core.pipeline.PipelineFrame} for each scope, with each
26+
* frame building upon the data produced by the last frame.
2327
*
28+
* @author David van Leusen
29+
* @since 2014-06-02
2430
*/
2531
public class Pipeline {
2632
private final static Logger logger = LogManager.getLogger(Pipeline.class);
@@ -59,6 +65,13 @@ public Pipeline() {
5965
this.frameMap.put(MetricScope.COLLECTION, new PipelineFrame(MetricScope.COLLECTION));
6066
}
6167

68+
/**
69+
* To be used in conjunction with {@link nl.rug.jbi.jsm.core.execution.PipelineExecutor#setClassVisitorFactory(nl.rug.jbi.jsm.core.execution.ClassVisitorFactory)}
70+
* to set up a custom ClassLoader with custom initial data. This method needs to be called any instances of this
71+
* class are created to prevent exceptions related to unknown data-types.
72+
*
73+
* @param dataType The data-type to register within the initial CLASS frame.
74+
*/
6275
public static void registerNewBaseData(final Class dataType) {
6376
Pipeline.BASE_DATA_CLASSES.add(dataType);
6477
}
@@ -75,6 +88,14 @@ private Pair<Class, HandlerExecutor> processMethod(final Method listener, final
7588
));
7689
}
7790

91+
//Method has to be set to public.
92+
if ((listener.getModifiers() & Modifier.PUBLIC) == 0) {
93+
throw new MetricPreparationException(String.format(
94+
"'%s' isn't set to public",
95+
listener
96+
));
97+
}
98+
7899
//The first parameter is always of type MetricState
79100
if (!MetricState.class.equals(params[0])) {
80101
throw new MetricPreparationException(String.format(
@@ -160,6 +181,15 @@ public Class apply(Pair<Class, HandlerExecutor> classHandlerExecutorPair) {
160181
}
161182
}
162183

184+
/**
185+
* Registers a metric to be evaluated within this pipeline, it will be validated and then placed within a frame
186+
* where all the data required by the metric is available. Metrics registered need to subclass
187+
* {@link nl.rug.jbi.jsm.core.calculator.IsolatedMetric} or {@link nl.rug.jbi.jsm.core.calculator.SharedMetric}.ø
188+
*
189+
* @param metric Metric to registered to this pipeline.
190+
* @throws MetricPreparationException If there is an issue with the metric definition or its requirements, see the
191+
* associated error for more information.
192+
*/
163193
public void registerMetric(final BaseMetric metric) throws MetricPreparationException {
164194
if (!(metric instanceof IsolatedMetric || metric instanceof SharedMetric)) {
165195
throw new MetricPreparationException("A metric needs to be a subclass of IsolatedMetric or SharedMetric");
@@ -168,10 +198,16 @@ public void registerMetric(final BaseMetric metric) throws MetricPreparationExce
168198
}
169199
}
170200

201+
/**
202+
* @return An unmodifiable map containing all scopes and the listeners for those scopes.
203+
*/
171204
public Map<MetricScope, HandlerMap> getHandlerMaps() {
172205
return Collections.unmodifiableMap(this.handlerMaps);
173206
}
174207

208+
/**
209+
* @return An unmodifiable map containing all scopes and the execution frames for those scopes.
210+
*/
175211
public Map<MetricScope, PipelineFrame> getPipelineFrames() {
176212
return Collections.unmodifiableMap(this.frameMap);
177213
}

src/main/java/nl/rug/jbi/jsm/core/pipeline/PipelineFrame.java

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@
1111

1212
import static com.google.common.base.Preconditions.checkNotNull;
1313

14+
/**
15+
* A frame of execution, it describes a set of data that is available within this frame and contains lists of metrics
16+
* that are ready for finalization within this frame. Each frame represents a frame of execution in
17+
* {@link nl.rug.jbi.jsm.core.execution.PipelineExecutor}.
18+
*
19+
* @author David van Leusen
20+
* @since 2014-06-02
21+
*/
1422
public class PipelineFrame {
1523
private final MetricScope scope;
1624
private final Set<Class> availableData = Sets.newHashSet();
@@ -19,38 +27,56 @@ public class PipelineFrame {
1927
private final List<ProducerMetric> producerMetrics = Lists.newLinkedList();
2028
private PipelineFrame nextFrame = null;
2129

22-
public PipelineFrame(final MetricScope scope) {
30+
PipelineFrame(final MetricScope scope) {
2331
this.scope = checkNotNull(scope);
2432
}
2533

26-
public PipelineFrame(final MetricScope scope, final Set<Class> initData) {
34+
PipelineFrame(final MetricScope scope, final Set<Class> initData) {
2735
this(scope);
2836
this.availableData.addAll(
2937
checkNotNull(initData)
3038
);
3139
}
3240

33-
public PipelineFrame(final PipelineFrame previousFrame) {
34-
this(checkNotNull(previousFrame).getScope());
35-
this.availableData.addAll(previousFrame.availableData);
41+
PipelineFrame(final PipelineFrame previousFrame) {
42+
this(checkNotNull(previousFrame).getScope(), previousFrame.availableData);
3643
previousFrame.setNextFrame(this);
3744
}
3845

46+
/**
47+
* Adds a type of data that will be available in this frame AND all subsequent frames.
48+
*
49+
* @param dataClass Data to register
50+
*/
3951
public void addDataClass(final Class dataClass) {
4052
this.availableData.add(dataClass);
4153
if (this.nextFrame != null) {
4254
this.nextFrame.addDataClass(dataClass);
4355
}
4456
}
4557

58+
/**
59+
* @return The scope in which this frame will be evaluated.
60+
*/
4661
public MetricScope getScope() {
4762
return this.scope;
4863
}
4964

65+
/**
66+
* Checks whether this frame has all the given data available. The set of data available in this frame is determined
67+
* by the base set of data in {@link nl.rug.jbi.jsm.core.pipeline.Pipeline} and the results of any producers in
68+
* previous frames.
69+
*
70+
* @param requiredData The set of data that needs to be available.
71+
* @return Whether said data is available.
72+
*/
5073
public boolean checkAvailableData(final Set<Class> requiredData) {
5174
return this.availableData.containsAll(requiredData);
5275
}
5376

77+
/**
78+
* @return The next frame of execution, can be NULL.
79+
*/
5480
public PipelineFrame getNextFrame() {
5581
return this.nextFrame;
5682
}
@@ -59,19 +85,28 @@ private void setNextFrame(final PipelineFrame nextFrame) {
5985
this.nextFrame = nextFrame;
6086
}
6187

88+
/**
89+
* @return Unmodifiable list of all isolated metrics that are finished in this frame.
90+
*/
6291
public List<IsolatedMetric> getIsolatedMetrics() {
6392
return Collections.unmodifiableList(this.isolatedMetrics);
6493
}
6594

95+
/**
96+
* @return Unmodifiable list of all shared metrics that are finished in this frame.
97+
*/
6698
public List<SharedMetric> getSharedMetrics() {
6799
return Collections.unmodifiableList(this.sharedMetrics);
68100
}
69101

102+
/**
103+
* @return Unmodifiable list of all producers that are finished in this frame.
104+
*/
70105
public List<ProducerMetric> getProducerMetrics() {
71106
return Collections.unmodifiableList(this.producerMetrics);
72107
}
73108

74-
public void registerMetric(final BaseMetric metric) throws MetricPreparationException {
109+
void registerMetric(final BaseMetric metric) throws MetricPreparationException {
75110
if (metric instanceof IsolatedMetric) {
76111
this.isolatedMetrics.add((IsolatedMetric) metric);
77112
} else if (metric instanceof SharedMetric) {

0 commit comments

Comments
 (0)