1 | package de.uka.ipd.sdq.prototype.framework; |
2 | |
3 | import java.util.Collection; |
4 | import java.util.Iterator; |
5 | |
6 | import javax.management.RuntimeErrorException; |
7 | |
8 | import de.uka.ipd.sdq.sensorframework.entities.ExperimentRun; |
9 | import de.uka.ipd.sdq.sensorframework.entities.Sensor; |
10 | import de.uka.ipd.sdq.sensorframework.entities.TimeSpanSensor; |
11 | |
12 | /** |
13 | * Manages the time span sensors and measurements. |
14 | * |
15 | * @author Steffen Becker, Sebastian Lehrig, Thomas Zolynski |
16 | * |
17 | */ |
18 | public class ExperimentManager { |
19 | |
20 | /** |
21 | * Suffix for ProtoCom sensors, as seen in the diagrams |
22 | */ |
23 | private static final String PROTOCOM_SENSOR_SUFFIX = " (ProtoCom)"; |
24 | |
25 | protected static org.apache.log4j.Logger logger = org.apache.log4j.Logger.getRootLogger(); |
26 | |
27 | private static de.uka.ipd.sdq.sensorframework.entities.Experiment exp = null; |
28 | |
29 | |
30 | public static de.uka.ipd.sdq.sensorframework.entities.Experiment getExperiment() { |
31 | return exp; |
32 | } |
33 | |
34 | public static void setExperiment(de.uka.ipd.sdq.sensorframework.entities.Experiment exp) { |
35 | ExperimentManager.exp = exp; |
36 | } |
37 | |
38 | /** |
39 | * Adds a new experiment run to the experiment. Current date is used for |
40 | * as date. |
41 | * |
42 | * @return the newly created experiment run |
43 | */ |
44 | public static ExperimentRun addExperimentRun() { |
45 | if (exp == null) { |
46 | logger.error("Experiment not set"); |
47 | throw new RuntimeErrorException(null, "Experiment not set"); |
48 | } |
49 | |
50 | return exp.addExperimentRun(new java.util.Date().toString()); |
51 | } |
52 | |
53 | |
54 | /** |
55 | * Restored this from an older version. |
56 | * Will be changed eventually. |
57 | * @return |
58 | */ |
59 | public static long takeStartTimeForInnerMeasurement() { |
60 | return System.nanoTime(); |
61 | } |
62 | |
63 | /** |
64 | * Takes a measurement (from start time till current time) on the given sensor |
65 | * |
66 | * @param start start time |
67 | * @param experimentRun |
68 | * @param timeSpanSensor sensor |
69 | */ |
70 | public static void takeMeasurement(long start, ExperimentRun experimentRun, TimeSpanSensor timeSpanSensor) { |
71 | |
72 | logger.info("Take measurement of " + timeSpanSensor.getSensorName()); |
73 | |
74 | long now = System.nanoTime(); |
75 | double measuredTimeSpan = (now - start) / Math.pow(10, 9); |
76 | |
77 | experimentRun.addTimeSpanMeasurement(timeSpanSensor, now / Math.pow(10, 9), measuredTimeSpan); |
78 | } |
79 | |
80 | /** |
81 | * Returns a {@link TimeSpanSensor} in the experiment that has the name |
82 | * sensorName. Creates a new sensor and returns it of no sensor with this |
83 | * name exists. The reuse is required because the EJB container may decide |
84 | * at times to create new instances of the components, so for one component |
85 | * type and one signature, this method may be called multiple times during |
86 | * the measurements. We want to store all results per component type into |
87 | * one sensor, though. |
88 | * |
89 | * @param sensorName |
90 | * The sensor name to match |
91 | * @return The {@link TimeSpanSensor} with the passed name or a new |
92 | * {@link TimeSpanSensor} with that name that is then also added to |
93 | * the experiment. |
94 | */ |
95 | public static TimeSpanSensor createOrReuseTimeSpanSensor(String sensorName) { |
96 | |
97 | Collection<Sensor> existingSesors = ExperimentManager.exp.getSensors(); |
98 | for (Sensor sensor : existingSesors) { |
99 | if (sensor instanceof TimeSpanSensor && sensor.getSensorName().equals(sensorName + ExperimentManager.PROTOCOM_SENSOR_SUFFIX)) { |
100 | return (TimeSpanSensor) sensor; |
101 | } |
102 | } |
103 | |
104 | TimeSpanSensor tss = getExperiment().addTimeSpanSensor(sensorName + ExperimentManager.PROTOCOM_SENSOR_SUFFIX); |
105 | return tss; |
106 | } |
107 | |
108 | |
109 | /** |
110 | * Returns the newest experiment run instance. If no one exists, a new experiment run |
111 | * will be created. Note that the experiment run usually should be created explicitly |
112 | * and not here. This one is just a (quick) fix to get measurements from sensors running |
113 | * on instances different from the usage scenario. |
114 | * |
115 | * @return latest experiment run instance or a new one |
116 | */ |
117 | public static ExperimentRun getLatestExperimentRun() { |
118 | if (getExperiment().getExperimentRuns().isEmpty()) { |
119 | addExperimentRun(); |
120 | } |
121 | |
122 | Collection<ExperimentRun> runs = getExperiment().getExperimentRuns(); |
123 | Iterator<ExperimentRun> it = runs.iterator(); |
124 | |
125 | ExperimentRun experimentRun = null; |
126 | |
127 | while (it.hasNext()) { |
128 | experimentRun = (ExperimentRun) it.next(); |
129 | } |
130 | |
131 | return experimentRun; |
132 | } |
133 | } |