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