tmf : Add parameters to XML core methods
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.analysis.xml.core / src / org / eclipse / tracecompass / tmf / analysis / xml / core / model / TmfXmlStateValue.java
CommitLineData
1d7e62f9 1/*******************************************************************************
ed902a2b 2 * Copyright (c) 2014, 2015 Ecole Polytechnique de Montreal
1d7e62f9
GB
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 * Contributors:
10 * Florian Wininger - Initial API and implementation
11 ******************************************************************************/
12
2bdf0193 13package org.eclipse.tracecompass.tmf.analysis.xml.core.model;
1d7e62f9
GB
14
15import java.util.List;
16
17import org.eclipse.jdt.annotation.NonNull;
18import org.eclipse.jdt.annotation.Nullable;
e894a508
AM
19import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
20import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
21import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
22import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
23import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
24import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
2bdf0193
AM
25import org.eclipse.tracecompass.tmf.analysis.xml.core.module.IXmlStateSystemContainer;
26import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings;
27import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
28import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
35f39420
AM
29import org.eclipse.tracecompass.tmf.core.event.aspect.TmfCpuAspect;
30import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
1d7e62f9
GB
31import org.w3c.dom.Element;
32
33/**
34 * This Class implements a State Value in the XML-defined state system, along
35 * with the path to get to the value (either a list of state attributes or an
36 * event field)
37 *
38 * <pre>
39 * Example:
40 * <stateAttribute type="location" value="CurrentThread" />
41 * <stateAttribute type="constant" value="System_call" />
42 * <stateValue type="null" />
43 * </pre>
44 *
45 * @author Florian Wininger
46 */
47public abstract class TmfXmlStateValue implements ITmfXmlStateValue {
48
49 private final TmfXmlStateValueBase fStateValue;
50
51 /* Path in the State System */
52 private final List<ITmfXmlStateAttribute> fPath;
53 /* Event field to match with this state value */
12685851 54 private final @Nullable String fEventField;
1d7e62f9
GB
55
56 /* Whether this state value is an increment of the previous value */
57 private final boolean fIncrement;
58 /* Stack value */
59 private final ValueTypeStack fStackType;
60 /* Forced value type */
61 private final ITmfStateValue.Type fForcedType;
62
63 private final IXmlStateSystemContainer fContainer;
64
65 /**
66 * Different behaviors of an attribute that is to be stacked
67 */
68 protected enum ValueTypeStack {
69 /** Not stacked */
70 NULL,
71 /** Peek at the value at the top of the stack */
72 PEEK,
73 /** Take the value at the top of the stack */
74 POP,
75 /** Push the value on the stack */
76 PUSH;
77
78 /**
79 * Get the type stack value corresponding to a string
80 *
81 * @param input
82 * The string to match to a value
83 * @return The ValueTypeStack value
84 */
85 public static ValueTypeStack getTypeFromString(String input) {
86 switch (input) {
87 case TmfXmlStrings.STACK_PUSH:
88 return PUSH;
89 case TmfXmlStrings.STACK_POP:
90 return POP;
91 case TmfXmlStrings.STACK_PEEK:
92 return PEEK;
93 default:
94 return NULL;
95 }
96 }
97 }
98
99 /**
100 * Constructor
101 *
102 * @param modelFactory
103 * The factory used to create XML model elements
104 * @param node
105 * The state value XML element
106 * @param container
107 * The state system container this state value belongs to
108 * @param eventField
109 * The event field where to get the value
110 * @param attributes
111 * The attributes representing the path to this value
112 */
12685851 113 protected TmfXmlStateValue(ITmfXmlModelFactory modelFactory, Element node, IXmlStateSystemContainer container, List<ITmfXmlStateAttribute> attributes, @Nullable String eventField) {
1d7e62f9
GB
114 fPath = attributes;
115 fContainer = container;
116 fEventField = eventField;
117 if (!node.getNodeName().equals(TmfXmlStrings.STATE_VALUE)) {
118 throw new IllegalArgumentException("TmfXmlStateValue constructor: Element is not a stateValue"); //$NON-NLS-1$
119 }
120
121 /* Check if there is an increment for the value */
122 fIncrement = Boolean.parseBoolean(node.getAttribute(TmfXmlStrings.INCREMENT));
123
124 /* Process the XML Element state value */
125 fStateValue = initializeStateValue(modelFactory, node);
126
127 /*
128 * Forced type allows to convert the value to a certain type : For
129 * example, a process's TID in an event field may arrive with a LONG
130 * format but we want to store the data in an INT
131 */
132 switch (node.getAttribute(TmfXmlStrings.FORCED_TYPE)) {
133 case TmfXmlStrings.TYPE_STRING:
134 fForcedType = ITmfStateValue.Type.STRING;
135 break;
136 case TmfXmlStrings.TYPE_INT:
137 fForcedType = ITmfStateValue.Type.INTEGER;
138 break;
139 case TmfXmlStrings.TYPE_LONG:
140 fForcedType = ITmfStateValue.Type.LONG;
141 break;
425e1cfa
BH
142 case TmfXmlStrings.TYPE_DOUBLE:
143 fForcedType = ITmfStateValue.Type.DOUBLE;
144 break;
1d7e62f9
GB
145 default:
146 fForcedType = ITmfStateValue.Type.NULL;
147 }
148
149 /*
150 * Stack Actions : allow to define a stack with PUSH/POP/PEEK methods
151 */
0e4f957e 152 String stack = node.getAttribute(TmfXmlStrings.ATTRIBUTE_STACK);
1d7e62f9
GB
153 fStackType = ValueTypeStack.getTypeFromString(stack);
154 }
155
156 /**
157 * Initialize a {@link TmfXmlStateValueBase} object for the type and value
158 *
159 * @param modelFactory
160 * The factory used to create XML model elements
161 * @param node
162 * The state value XML element
163 * @return The internal state value type corresponding to this state value
164 */
165 protected TmfXmlStateValueBase initializeStateValue(ITmfXmlModelFactory modelFactory, Element node) {
166 return new TmfXmlStateValueNull();
167 }
168
169 /**
170 * Return the state system container this class is attached to
171 *
172 * @return The state system container
173 */
174 protected IXmlStateSystemContainer getSsContainer() {
175 return fContainer;
176 }
177
178 /**
179 * Get the state system associated with this value's container
180 *
181 * @return The state system associated with the state system container
182 */
12685851 183 protected @Nullable ITmfStateSystem getStateSystem() {
1d7e62f9
GB
184 return fContainer.getStateSystem();
185 }
186
187 /**
188 * Return whether this value is an increment of the previous value
189 *
190 * @return <code>true</code> if the value is an increment
191 */
192 protected boolean isIncrement() {
193 return fIncrement;
194 }
195
196 /**
197 * Get the stack type of this attribute. If the attribute is to be pushed or
198 * popped to a stack. The behavior of the stack attribute will depend on the
199 * implementation of the model.
200 *
201 * @return The stack type of the attribute
202 */
203 protected ValueTypeStack getStackType() {
204 return fStackType;
205 }
206
207 /**
208 * Get the forced type of the value. For example, if the value obtained from
209 * the attributes is not in this forced type, it will be converted to this.
210 *
211 * @return The desired type of the value
212 */
213 protected ITmfStateValue.Type getForcedType() {
214 return fForcedType;
215 }
216
217 /**
0b563c20 218 * @since 2.0
1d7e62f9
GB
219 */
220 @Override
0b563c20
JCK
221 public ITmfStateValue getValue(@Nullable ITmfEvent event, @Nullable TmfXmlScenarioInfo scenarioInfo) throws AttributeNotFoundException {
222 return fStateValue.getValue(event, scenarioInfo);
1d7e62f9
GB
223 }
224
225 /**
226 * Get the value of the event field that is the path of this state value
227 *
228 * @param event
229 * The current event
230 * @return the value of the event field
231 */
232 @Override
233 public ITmfStateValue getEventFieldValue(@NonNull ITmfEvent event) {
12685851
GB
234 String eventField = fEventField;
235 if (eventField == null) {
236 throw new IllegalStateException();
237 }
238 return getEventFieldValue(event, eventField);
1d7e62f9
GB
239 }
240
241 /**
242 * Get the value of an event field
243 *
244 * @param event
245 * The current event
246 * @param fieldName
247 * The name of the field of which to get the value
248 * @return The value of the event field
249 */
12685851 250 protected ITmfStateValue getEventFieldValue(ITmfEvent event, String fieldName) {
1d7e62f9
GB
251
252 ITmfStateValue value = TmfStateValue.nullValue();
253
254 final ITmfEventField content = event.getContent();
255
12685851
GB
256 /* Exception for "CPU", returns the source of this event */
257 /* FIXME : Nameclash if a eventfield have "cpu" for name. */
35f39420 258 if (fieldName.equals(TmfXmlStrings.CPU)) {
b3867ecc
MAL
259 Integer cpu = TmfTraceUtils.resolveIntEventAspectOfClassForEvent(event.getTrace(), TmfCpuAspect.class, event);
260 if (cpu != null) {
b1aad44e 261 return TmfStateValue.newValueInt(cpu.intValue());
35f39420
AM
262 }
263 }
6e9040a7
NE
264 /* Exception also for "TIMESTAMP", returns the timestamp of this event */
265 if (fieldName.equals(TmfXmlStrings.TIMESTAMP)) {
266 return TmfStateValue.newValueLong(event.getTimestamp().getValue());
267 }
1d7e62f9
GB
268 if (content.getField(fieldName) == null) {
269 return value;
270 }
271
272 Object field = content.getField(fieldName).getValue();
273
274 /*
275 * Try to find the right type. The type can be forced by
276 * "forcedType" argument.
277 */
278
279 if (field instanceof String) {
280 String fieldString = (String) field;
281
282 switch (fForcedType) {
283 case INTEGER:
284 value = TmfStateValue.newValueInt(Integer.parseInt(fieldString));
285 break;
286 case LONG:
287 value = TmfStateValue.newValueLong(Long.parseLong(fieldString));
288 break;
289 case DOUBLE:
290 value = TmfStateValue.newValueDouble(Double.parseDouble(fieldString));
291 break;
292 case NULL:
293 case STRING:
294 default:
295 value = TmfStateValue.newValueString(fieldString);
296 break;
297 }
298 } else if (field instanceof Long) {
299 Long fieldLong = (Long) field;
300
301 switch (fForcedType) {
302 case INTEGER:
303 value = TmfStateValue.newValueInt(fieldLong.intValue());
304 break;
305 case STRING:
306 value = TmfStateValue.newValueString(fieldLong.toString());
307 break;
308 case DOUBLE:
309 value = TmfStateValue.newValueDouble(fieldLong.doubleValue());
310 break;
311 case LONG:
312 case NULL:
313 default:
314 value = TmfStateValue.newValueLong(fieldLong);
315 break;
316 }
317 } else if (field instanceof Integer) {
318 Integer fieldInteger = (Integer) field;
319
320 switch (fForcedType) {
321 case LONG:
322 value = TmfStateValue.newValueLong(fieldInteger.longValue());
323 break;
324 case STRING:
325 value = TmfStateValue.newValueString(fieldInteger.toString());
326 break;
327 case DOUBLE:
328 value = TmfStateValue.newValueDouble(fieldInteger.doubleValue());
329 break;
330 case INTEGER:
331 case NULL:
332 default:
333 value = TmfStateValue.newValueInt(fieldInteger);
334 break;
335 }
336 } else if (field instanceof Double) {
337 Double fieldDouble = (Double) field;
338
339 switch (fForcedType) {
340 case LONG:
341 value = TmfStateValue.newValueLong(fieldDouble.longValue());
342 break;
343 case STRING:
344 value = TmfStateValue.newValueString(fieldDouble.toString());
345 break;
346 case INTEGER:
347 value = TmfStateValue.newValueInt(fieldDouble.intValue());
348 break;
349 case DOUBLE:
350 case NULL:
351 default:
352 value = TmfStateValue.newValueDouble(fieldDouble);
353 break;
354 }
355 }
356 return value;
357 }
358
359 /**
360 * Get the list of state attributes, the path to the state value
361 *
362 * @return the list of Attribute to have the path in the State System
363 */
364 @Override
365 public List<ITmfXmlStateAttribute> getAttributes() {
366 return fPath;
367 }
368
369 /**
0b563c20 370 * @since 2.0
1d7e62f9
GB
371 */
372 @Override
0b563c20 373 public void handleEvent(@NonNull ITmfEvent event, @Nullable TmfXmlScenarioInfo scenarioInfo) throws AttributeNotFoundException, StateValueTypeException, TimeRangeException {
1d7e62f9
GB
374 int quark = IXmlStateSystemContainer.ROOT_QUARK;
375
376 for (ITmfXmlStateAttribute attribute : fPath) {
0b563c20 377 quark = attribute.getAttributeQuark(event, quark, scenarioInfo);
1d7e62f9
GB
378 /* the query is not valid, we stop the state change */
379 if (quark == IXmlStateSystemContainer.ERROR_QUARK) {
446598f9 380 throw new AttributeNotFoundException("Not found XML attribute " + attribute); //$NON-NLS-1$
1d7e62f9
GB
381 }
382 }
383
384 long ts = event.getTimestamp().getValue();
0b563c20 385 fStateValue.handleEvent(event, quark, ts, scenarioInfo);
1d7e62f9
GB
386 }
387
446598f9
GB
388 @Override
389 public String toString() {
cbac1ac1
JCK
390 StringBuilder builder = new StringBuilder("TmfXmlStateValue: "); //$NON-NLS-1$
391 if (fEventField != null) {
392 builder.append("Field=").append(fEventField).append("; "); //$NON-NLS-1$ //$NON-NLS-2$
393 } else if (!fPath.isEmpty()) {
394 builder.append("Path=").append(fPath).append("; "); //$NON-NLS-1$ //$NON-NLS-2$
395 }
396 builder.append(fStateValue);
397 return builder.toString();
446598f9
GB
398 }
399
1d7e62f9
GB
400 /**
401 * Base class for all state values. Contain default methods to handle event,
402 * process or increment the value
403 */
404 protected abstract class TmfXmlStateValueBase {
405
406 /**
407 * Get the value associated with this state value.
408 *
409 * @param event
410 * The event which can be used to retrieve the value if
411 * necessary. The event can be <code>null</code> if no event
412 * is required.
0b563c20
JCK
413 * @param scenarioInfo
414 * The active scenario details. The value should be null if
415 * there no scenario.
1d7e62f9
GB
416 * @return The state value corresponding to this XML state value
417 * @throws AttributeNotFoundException
418 * Pass through the exception it received
0b563c20 419 * @since 2.0
1d7e62f9 420 */
0b563c20 421 public abstract ITmfStateValue getValue(@Nullable ITmfEvent event, @Nullable TmfXmlScenarioInfo scenarioInfo) throws AttributeNotFoundException;
1d7e62f9
GB
422
423 /**
424 * Do something with the state value, possibly using an event
425 *
426 * @param event
427 * The event being handled. If there is no event is
428 * available, use <code>null</code>.
429 * @param quark
430 * The quark for this value
431 * @param timestamp
432 * The timestamp of the event
0b563c20
JCK
433 * @param scenarioInfo
434 * The active scenario details. The value should be null if
435 * there no scenario.
1d7e62f9
GB
436 * @throws StateValueTypeException
437 * Pass through the exception it received
438 * @throws TimeRangeException
439 * Pass through the exception it received
440 * @throws AttributeNotFoundException
441 * Pass through the exception it received
0b563c20 442 * @since 2.0
1d7e62f9 443 */
0b563c20 444 public void handleEvent(ITmfEvent event, int quark, long timestamp, @Nullable TmfXmlScenarioInfo scenarioInfo) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException {
1d7e62f9 445 if (fIncrement) {
0b563c20 446 incrementValue(event, quark, timestamp, scenarioInfo);
1d7e62f9 447 } else {
0b563c20 448 ITmfStateValue value = getValue(event, scenarioInfo);
1d7e62f9
GB
449 processValue(quark, timestamp, value);
450 }
451 }
452
453 /**
454 * Set the value of a quark at a given timestamp.
455 *
456 * @param quark
457 * The quark for this value
458 * @param timestamp
459 * The timestamp
460 * @param value
461 * The value of this state value
462 * @throws TimeRangeException
463 * Pass through the exception it received
464 * @throws StateValueTypeException
465 * Pass through the exception it received
466 * @throws AttributeNotFoundException
467 * Pass through the exception it received
468 */
469 @SuppressWarnings("unused")
470 protected void processValue(int quark, long timestamp, ITmfStateValue value) throws TimeRangeException, StateValueTypeException, AttributeNotFoundException {
471 }
472
473 /**
474 * Increments the value of the parameter
475 *
476 * @param event
477 * The event being handled
478 * @param quark
479 * The quark for this value
480 * @param timestamp
481 * The timestamp of the event
0b563c20
JCK
482 * @param scenarioInfo
483 * The active scenario details. The value should be null if
484 * there no scenario.
1d7e62f9
GB
485 * @throws StateValueTypeException
486 * Pass through the exception it received
487 * @throws TimeRangeException
488 * Pass through the exception it received
489 * @throws AttributeNotFoundException
490 * Pass through the exception it received
0b563c20 491 * @since 2.0
1d7e62f9
GB
492 */
493 @SuppressWarnings("unused")
0b563c20 494 protected void incrementValue(ITmfEvent event, int quark, long timestamp, @Nullable TmfXmlScenarioInfo scenarioInfo) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException {
1d7e62f9
GB
495 }
496 }
497
498 /* This state value uses a constant value, defined in the XML */
499 private class TmfXmlStateValueNull extends TmfXmlStateValueBase {
500
501 @Override
0b563c20 502 public ITmfStateValue getValue(@Nullable ITmfEvent event, @Nullable TmfXmlScenarioInfo scenarioInfo) throws AttributeNotFoundException {
1d7e62f9
GB
503 return TmfStateValue.nullValue();
504 }
505
cbac1ac1
JCK
506 @Override
507 public String toString() {
508 return "NULL"; //$NON-NLS-1$
509 }
1d7e62f9
GB
510 }
511
52293ccd 512}
This page took 0.104441 seconds and 5 git commands to generate.