ss: Replace AttributeNotFoundException with IOOBE for quark parameters
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.analysis.xml.core / src / org / eclipse / tracecompass / internal / tmf / analysis / xml / core / model / TmfXmlScenarioHistoryBuilder.java
1 /*******************************************************************************
2 * Copyright (c) 2016 Ecole Polytechnique de Montreal, Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 ******************************************************************************/
9 package org.eclipse.tracecompass.internal.tmf.analysis.xml.core.model;
10
11 import java.util.HashMap;
12 import java.util.Map;
13
14 import org.eclipse.jdt.annotation.Nullable;
15 import org.eclipse.tracecompass.common.core.NonNullUtils;
16 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.Activator;
17 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.module.IXmlStateSystemContainer;
18 import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.stateprovider.TmfXmlStrings;
19 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
20 import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
21 import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
22 import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
23 import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
24 import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
25 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
26 import org.eclipse.tracecompass.tmf.core.statesystem.TmfAttributePool;
27
28 import com.google.common.collect.BiMap;
29 import com.google.common.collect.ImmutableBiMap;
30
31 /**
32 * This class is responsible for creating scenarios, updating their status and
33 * data, and saving the scenario data to the state system
34 */
35 public class TmfXmlScenarioHistoryBuilder {
36
37 /** The string 'status' */
38 public static final String STATUS = "status"; //$NON-NLS-1$
39 /** The string for "nbScenarios" */
40 public static final String SCENARIO_COUNT = "nbScenarios"; //$NON-NLS-1$
41
42 /** The string for start time */
43 private static final String START_TIME = "startTime"; //$NON-NLS-1$
44 /** Error message */
45 private static final String ERROR_MESSAGE = "The state system is null"; //$NON-NLS-1$
46
47 private final Map<String, TmfAttributePool> fFsmPools = new HashMap<>();
48
49 /**
50 * All possible types of status for a scenario
51 */
52 public enum ScenarioStatusType {
53 /**
54 * scenario pending for start point
55 */
56 PENDING,
57 /**
58 * scenario in progress
59 */
60 IN_PROGRESS,
61 /**
62 * scenario abandoned
63 */
64 ABANDONED,
65 /**
66 * scenario match with the pattern
67 */
68 MATCHED
69 }
70
71 /**
72 * Cache the available status in a map
73 */
74 protected static final BiMap<ScenarioStatusType, ITmfStateValue> STATUS_MAP = NonNullUtils.checkNotNull(ImmutableBiMap.of(
75 ScenarioStatusType.PENDING, TmfStateValue.newValueInt(0),
76 ScenarioStatusType.IN_PROGRESS, TmfStateValue.newValueInt(1),
77 ScenarioStatusType.MATCHED, TmfStateValue.newValueInt(2),
78 ScenarioStatusType.ABANDONED, TmfStateValue.newValueInt(3)));
79
80 /**
81 * Get the scenario matched process start time
82 *
83 * @param container
84 * The state system container this class use
85 * @param info
86 * The scenario details
87 * @param event
88 * The current event
89 *
90 * @return The start time of the matching process for the specified scenario
91 */
92 public long getStartTime(final IXmlStateSystemContainer container, final TmfXmlScenarioInfo info, final ITmfEvent event) {
93 ITmfStateSystemBuilder ss = (ITmfStateSystemBuilder) container.getStateSystem();
94 long ts = getTimestamp(event, ss);
95 try {
96 int attributeQuark = getQuarkRelativeAndAdd(ss, info.getQuark(), START_TIME);
97 ITmfStateInterval state = ss.querySingleState(ts, attributeQuark);
98 return state.getStartTime();
99 } catch (StateSystemDisposedException e) {
100 Activator.logError("failed to get the start time of the scenario", e); //$NON-NLS-1$
101 }
102 return -1L;
103 }
104
105 /**
106 * Save the stored fields
107 *
108 * @param container
109 * The state system container this class use
110 * @param attributeName
111 * The name of the attribute to save
112 * @param value
113 * The value of the attribute to save
114 * @param info
115 * The scenario details
116 * @param event
117 * The current event
118 */
119 public void updateStoredFields(final IXmlStateSystemContainer container, final String attributeName, final ITmfStateValue value, final TmfXmlScenarioInfo info, final ITmfEvent event) {
120 ITmfStateSystemBuilder ss = (ITmfStateSystemBuilder) container.getStateSystem();
121 long ts = getTimestamp(event, ss);
122 try {
123 int attributeQuark = getQuarkRelativeAndAdd(ss, info.getQuark(), TmfXmlStrings.STORED_FIELDS, attributeName);
124 ss.modifyAttribute(ts, value, attributeQuark);
125 } catch (StateValueTypeException e) {
126 Activator.logError("failed to save the stored field " + attributeName, e); //$NON-NLS-1$
127 }
128 }
129
130 /**
131 * Clear the special fields
132 *
133 * @param container
134 * The state system container this class use
135 * @param attributeName
136 * The name of the attribute to save
137 * @param info
138 * The scenario details
139 * @param event
140 * The current event
141 */
142 public void resetStoredFields(final IXmlStateSystemContainer container, final String attributeName, final TmfXmlScenarioInfo info, final ITmfEvent event) {
143 ITmfStateSystemBuilder ss = (ITmfStateSystemBuilder) container.getStateSystem();
144 long ts = getTimestamp(event, ss);
145 ITmfStateValue value = TmfStateValue.nullValue();
146 try {
147 int attributeQuark = getQuarkRelativeAndAdd(ss, info.getQuark(), TmfXmlStrings.STORED_FIELDS, attributeName);
148 ss.modifyAttribute(ts, value, attributeQuark);
149 } catch (StateValueTypeException e) {
150 Activator.logError("failed to clear the stored fields", e); //$NON-NLS-1$
151 }
152 }
153
154 /**
155 * Get the value of a special field in the state system
156 *
157 * @param container
158 * The state system container this class use
159 * @param attributeName
160 * The attribute name of the special field
161 * @param info
162 * The scenario details
163 * @param event
164 * The current event
165 *
166 * @return The value of a special field saved into the state system
167 */
168 public ITmfStateValue getStoredFieldValue(IXmlStateSystemContainer container, String attributeName, final TmfXmlScenarioInfo info, ITmfEvent event) {
169 ITmfStateSystemBuilder ss = (ITmfStateSystemBuilder) container.getStateSystem();
170 long ts = event.getTimestamp().toNanos();
171 ITmfStateInterval state = null;
172 try {
173 int attributeQuark = getQuarkRelativeAndAdd(ss, info.getQuark(), TmfXmlStrings.STORED_FIELDS, attributeName);
174 state = ss.querySingleState(ts, attributeQuark);
175 } catch (StateSystemDisposedException e) {
176 Activator.logError("failed to get the value of the stored field " + attributeName, e); //$NON-NLS-1$
177 }
178 return (state != null) ? NonNullUtils.checkNotNull(state.getStateValue()) : TmfStateValue.nullValue();
179 }
180
181 /**
182 * Get the attribute pool for this fsm
183 *
184 * @param container
185 * The state system container
186 * @param fsmId
187 * The ID of the FSM
188 * @return The attribute pool associated with this FSM
189 */
190 protected TmfAttributePool getPoolFor(IXmlStateSystemContainer container, String fsmId) {
191 TmfAttributePool pool = fFsmPools.get(fsmId);
192 if (pool != null) {
193 return pool;
194 }
195 ITmfStateSystemBuilder ss = NonNullUtils.checkNotNull((ITmfStateSystemBuilder) container.getStateSystem());
196 String[] fsmPath = new String[] { TmfXmlStrings.SCENARIOS, fsmId };
197 int quark = getQuarkAbsoluteAndAdd(ss, fsmPath);
198 pool = new TmfAttributePool(ss, quark);
199 fFsmPools.put(fsmId, pool);
200 return pool;
201 }
202
203 /**
204 * Get the scenario quark
205 *
206 * @param container
207 * The state system container this class use
208 * @param fsmId
209 * Id of the fsm this scenario is associated to
210 * @return The scenario quark
211 */
212 public int assignScenarioQuark(IXmlStateSystemContainer container, String fsmId) {
213 TmfAttributePool pool = getPoolFor(container, fsmId);
214 return pool.getAvailable();
215 }
216
217 /**
218 * Get the scenario status quark
219 *
220 * @param container
221 * The state system container this class use
222 * @param scenarioQuark
223 * The scenario quark
224 * @return The scenario quark
225 */
226 public int getScenarioStatusQuark(IXmlStateSystemContainer container, int scenarioQuark) {
227 ITmfStateSystemBuilder ss = (ITmfStateSystemBuilder) container.getStateSystem();
228 return getQuarkRelativeAndAdd(ss, scenarioQuark, STATUS);
229 }
230
231 /**
232 * Get the start time of a specific state of the scenario
233 *
234 * @param container
235 * The state system container this class use
236 * @param stateName
237 * The name of the current state of the scenario
238 * @param info
239 * The scenario details
240 * @param event
241 * The current event
242 *
243 * @return The start time for the specified state
244 */
245 public long getSpecificStateStartTime(final IXmlStateSystemContainer container, final String stateName, final TmfXmlScenarioInfo info, final ITmfEvent event) {
246 long ts = event.getTimestamp().getValue();
247 ITmfStateSystemBuilder ss = (ITmfStateSystemBuilder) container.getStateSystem();
248 try {
249 int attributeQuark = getQuarkRelativeAndAdd(ss, info.getQuark(), TmfXmlStrings.STATE, stateName, START_TIME);
250 ITmfStateInterval state = ss.querySingleState(ts, attributeQuark);
251 return state.getStartTime();
252 } catch (StateSystemDisposedException e) {
253 Activator.logError("failed the start time of the state " + stateName, e); //$NON-NLS-1$
254 }
255 return -1l;
256 }
257
258 /**
259 * Basic quark-retrieving method. Pass an attribute in parameter as an array
260 * of strings, the matching quark will be returned. If the attribute does
261 * not exist, it will add the quark to the state system if the context
262 * allows it.
263 *
264 * See {@link ITmfStateSystemBuilder#getQuarkAbsoluteAndAdd(String...)}
265 *
266 * @param ss
267 * The state system the attribute belongs to
268 * @param path
269 * Full path to the attribute
270 * @return The quark for this attribute
271 */
272 private static int getQuarkAbsoluteAndAdd(@Nullable ITmfStateSystemBuilder ss, String... path) {
273 if (ss == null) {
274 throw new NullPointerException(ERROR_MESSAGE);
275 }
276 return ss.getQuarkAbsoluteAndAdd(path);
277 }
278
279 /**
280 * Quark-retrieving method, but the attribute is queried starting from the
281 * startNodeQuark. If the attribute does not exist, it will add it to the
282 * state system if the context allows it.
283 *
284 * See {@link ITmfStateSystemBuilder#getQuarkRelativeAndAdd(int, String...)}
285 *
286 ** @param ss
287 * The state system the attribute belongs to
288 * @param startNodeQuark
289 * The quark of the attribute from which 'path' originates.
290 * @param path
291 * Relative path to the attribute
292 * @return The quark for this attribute
293 */
294 private static int getQuarkRelativeAndAdd(@Nullable ITmfStateSystemBuilder ss, int startNodeQuark, String... path) {
295 if (ss == null) {
296 throw new NullPointerException(ERROR_MESSAGE);
297 }
298 return ss.getQuarkRelativeAndAdd(startNodeQuark, path);
299 }
300
301 /**
302 * Update the scenario internal data
303 *
304 * @param container
305 * The state system container this class use
306 * @param info
307 * The scenario details
308 * @param event
309 * The current event
310 */
311 public void update(final IXmlStateSystemContainer container, final TmfXmlScenarioInfo info, final @Nullable ITmfEvent event) {
312 updateScenarioSpecificStateStartTime(event, container, info);
313 updateScenarioState(event, container, info);
314 updateScenarioStatus(event, container, info);
315 }
316
317 private static void updateScenarioStatus(@Nullable ITmfEvent event, IXmlStateSystemContainer container, final TmfXmlScenarioInfo info) {
318 ITmfStateSystemBuilder ss = (ITmfStateSystemBuilder) container.getStateSystem();
319 long ts = getTimestamp(event, ss);
320 ITmfStateValue value;
321 try {
322 // save the status
323 switch (info.getStatus()) {
324 case IN_PROGRESS:
325 value = STATUS_MAP.get(ScenarioStatusType.IN_PROGRESS);
326 break;
327 case ABANDONED:
328 value = STATUS_MAP.get(ScenarioStatusType.ABANDONED);
329 break;
330 case MATCHED:
331 value = STATUS_MAP.get(ScenarioStatusType.MATCHED);
332 break;
333 case PENDING:
334 value = STATUS_MAP.get(ScenarioStatusType.PENDING);
335 break;
336 default:
337 value = TmfStateValue.nullValue();
338 break;
339 }
340 ss.modifyAttribute(ts, value, info.getStatusQuark());
341 } catch (StateValueTypeException e) {
342 Activator.logError("failed to update scenario status"); //$NON-NLS-1$
343 }
344 }
345
346 private static long getTimestamp(@Nullable ITmfEvent event, @Nullable ITmfStateSystemBuilder ss) {
347 if (event != null) {
348 return event.getTimestamp().toNanos();
349 }
350 if (ss != null) {
351 return ss.getCurrentEndTime();
352 }
353 throw new IllegalArgumentException("Event and state system cannot be null at the same time."); //$NON-NLS-1$
354 }
355
356 private static void updateScenarioState(final @Nullable ITmfEvent event, final IXmlStateSystemContainer container, final TmfXmlScenarioInfo info) {
357 ITmfStateSystemBuilder ss = (ITmfStateSystemBuilder) container.getStateSystem();
358 long ts = getTimestamp(event, ss);
359 try {
360 // save the status
361 ITmfStateValue value = TmfStateValue.newValueString(info.getActiveState());
362 int attributeQuark = ss.getQuarkRelativeAndAdd(info.getQuark(), TmfXmlStrings.STATE);
363 ss.modifyAttribute(ts, value, attributeQuark);
364 } catch (StateValueTypeException e) {
365 Activator.logError("failed to update scenario state"); //$NON-NLS-1$
366 }
367 }
368
369 /**
370 * Update the start time of specified state
371 *
372 * @param event
373 * The current event
374 * @param container
375 * The state system container this class use
376 * @param info
377 * The scenario details
378 */
379 private static void updateScenarioSpecificStateStartTime(final @Nullable ITmfEvent event, final IXmlStateSystemContainer container, final TmfXmlScenarioInfo info) {
380 ITmfStateSystemBuilder ss = (ITmfStateSystemBuilder) container.getStateSystem();
381 long ts = getTimestamp(event, ss);
382 try {
383 int stateQuark = ss.getQuarkRelativeAndAdd(info.getQuark(), TmfXmlStrings.STATE);
384 String activeState = ss.queryOngoingState(stateQuark).unboxStr();
385 if (activeState.compareTo(info.getActiveState()) != 0) {
386 int attributeQuark = ss.getQuarkRelativeAndAdd(stateQuark, info.getActiveState(), START_TIME);
387 ITmfStateValue value = TmfStateValue.newValueLong(ts);
388 ss.modifyAttribute(ts, value, attributeQuark);
389 }
390 } catch (StateValueTypeException e) {
391 Activator.logError("failed to update the start time of the state"); //$NON-NLS-1$
392 }
393 }
394
395 /**
396 * Start the scenario, sets the start time for the time of the event
397 *
398 * @param container
399 * The state system container this class use
400 * @param info
401 * The scenario details. The value should be null if there is no
402 * scenario
403 * @param event
404 * The active event
405 */
406 public void startScenario(final IXmlStateSystemContainer container, final TmfXmlScenarioInfo info, final ITmfEvent event) {
407 ITmfStateSystemBuilder ss = (ITmfStateSystemBuilder) container.getStateSystem();
408 long ts = getTimestamp(event, ss);
409 try {
410 // save the status
411 ITmfStateValue value = TmfStateValue.newValueLong(ts);
412 int attributeQuark = ss.getQuarkRelativeAndAdd(info.getQuark(), START_TIME);
413 ss.modifyAttribute(ts, value, attributeQuark);
414 } catch (StateValueTypeException e) {
415 Activator.logError("failed to update the start time of the scenario"); //$NON-NLS-1$
416 }
417 }
418
419 /**
420 * Set the end time of the scenario to the time of the event, or current
421 * state system end time if null, and recycle the attribute quark
422 *
423 * @param container
424 * The state system container this class use
425 * @param info
426 * The scenario details. The value should be null if there is no
427 * scenario
428 * @param event
429 * The active event
430 */
431 public void completeScenario(final IXmlStateSystemContainer container, final TmfXmlScenarioInfo info, final @Nullable ITmfEvent event) {
432 ITmfStateSystemBuilder ss = (ITmfStateSystemBuilder) container.getStateSystem();
433 long ts = getTimestamp(event, ss);
434 TmfAttributePool pool = getPoolFor(container, info.getFsmId());
435 pool.recycle(info.getQuark(), ts);
436 }
437 }
This page took 0.041592 seconds and 5 git commands to generate.