tmf : Add latency statistics view for the pattern analysis
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.analysis.xml.core / src / org / eclipse / tracecompass / tmf / analysis / xml / core / model / TmfXmlStateValue.java
1 /*******************************************************************************
2 * Copyright (c) 2014, 2015 Ecole Polytechnique de Montreal
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
13 package org.eclipse.tracecompass.tmf.analysis.xml.core.model;
14
15 import java.util.List;
16
17 import org.eclipse.jdt.annotation.NonNull;
18 import org.eclipse.jdt.annotation.Nullable;
19 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
20 import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
21 import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
22 import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
23 import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
24 import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
25 import org.eclipse.tracecompass.tmf.analysis.xml.core.module.IXmlStateSystemContainer;
26 import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings;
27 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
28 import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
29 import org.eclipse.tracecompass.tmf.core.event.aspect.TmfCpuAspect;
30 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
31 import 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 */
47 public 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 */
54 private final @Nullable String fEventField;
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 */
113 protected TmfXmlStateValue(ITmfXmlModelFactory modelFactory, Element node, IXmlStateSystemContainer container, List<ITmfXmlStateAttribute> attributes, @Nullable String eventField) {
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;
142 case TmfXmlStrings.TYPE_DOUBLE:
143 fForcedType = ITmfStateValue.Type.DOUBLE;
144 break;
145 default:
146 fForcedType = ITmfStateValue.Type.NULL;
147 }
148
149 /*
150 * Stack Actions : allow to define a stack with PUSH/POP/PEEK methods
151 */
152 String stack = node.getAttribute(TmfXmlStrings.ATTRIBUTE_STACK);
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 */
183 protected @Nullable ITmfStateSystem getStateSystem() {
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 /**
218 * Get the current {@link ITmfStateValue} of this state value for an event.
219 * It does not increment the value and does not any other processing of the
220 * value.
221 *
222 * @param event
223 * The current event, or <code>null</code> if no event available.
224 * @return the {@link ITmfStateValue}
225 * @throws AttributeNotFoundException
226 * May be thrown by the state system during the query
227 */
228 @Override
229 public ITmfStateValue getValue(@Nullable ITmfEvent event) throws AttributeNotFoundException {
230 return fStateValue.getValue(event);
231 }
232
233 /**
234 * Get the value of the event field that is the path of this state value
235 *
236 * @param event
237 * The current event
238 * @return the value of the event field
239 */
240 @Override
241 public ITmfStateValue getEventFieldValue(@NonNull ITmfEvent event) {
242 String eventField = fEventField;
243 if (eventField == null) {
244 throw new IllegalStateException();
245 }
246 return getEventFieldValue(event, eventField);
247 }
248
249 /**
250 * Get the value of an event field
251 *
252 * @param event
253 * The current event
254 * @param fieldName
255 * The name of the field of which to get the value
256 * @return The value of the event field
257 */
258 protected ITmfStateValue getEventFieldValue(ITmfEvent event, String fieldName) {
259
260 ITmfStateValue value = TmfStateValue.nullValue();
261
262 final ITmfEventField content = event.getContent();
263
264 /* Exception for "CPU", returns the source of this event */
265 /* FIXME : Nameclash if a eventfield have "cpu" for name. */
266 if (fieldName.equals(TmfXmlStrings.CPU)) {
267 Integer cpu = TmfTraceUtils.resolveIntEventAspectOfClassForEvent(event.getTrace(), TmfCpuAspect.class, event);
268 if (cpu != null) {
269 return TmfStateValue.newValueInt(cpu.intValue());
270 }
271 }
272 /* Exception also for "TIMESTAMP", returns the timestamp of this event */
273 if (fieldName.equals(TmfXmlStrings.TIMESTAMP)) {
274 return TmfStateValue.newValueLong(event.getTimestamp().getValue());
275 }
276 if (content.getField(fieldName) == null) {
277 return value;
278 }
279
280 Object field = content.getField(fieldName).getValue();
281
282 /*
283 * Try to find the right type. The type can be forced by
284 * "forcedType" argument.
285 */
286
287 if (field instanceof String) {
288 String fieldString = (String) field;
289
290 switch (fForcedType) {
291 case INTEGER:
292 value = TmfStateValue.newValueInt(Integer.parseInt(fieldString));
293 break;
294 case LONG:
295 value = TmfStateValue.newValueLong(Long.parseLong(fieldString));
296 break;
297 case DOUBLE:
298 value = TmfStateValue.newValueDouble(Double.parseDouble(fieldString));
299 break;
300 case NULL:
301 case STRING:
302 default:
303 value = TmfStateValue.newValueString(fieldString);
304 break;
305 }
306 } else if (field instanceof Long) {
307 Long fieldLong = (Long) field;
308
309 switch (fForcedType) {
310 case INTEGER:
311 value = TmfStateValue.newValueInt(fieldLong.intValue());
312 break;
313 case STRING:
314 value = TmfStateValue.newValueString(fieldLong.toString());
315 break;
316 case DOUBLE:
317 value = TmfStateValue.newValueDouble(fieldLong.doubleValue());
318 break;
319 case LONG:
320 case NULL:
321 default:
322 value = TmfStateValue.newValueLong(fieldLong);
323 break;
324 }
325 } else if (field instanceof Integer) {
326 Integer fieldInteger = (Integer) field;
327
328 switch (fForcedType) {
329 case LONG:
330 value = TmfStateValue.newValueLong(fieldInteger.longValue());
331 break;
332 case STRING:
333 value = TmfStateValue.newValueString(fieldInteger.toString());
334 break;
335 case DOUBLE:
336 value = TmfStateValue.newValueDouble(fieldInteger.doubleValue());
337 break;
338 case INTEGER:
339 case NULL:
340 default:
341 value = TmfStateValue.newValueInt(fieldInteger);
342 break;
343 }
344 } else if (field instanceof Double) {
345 Double fieldDouble = (Double) field;
346
347 switch (fForcedType) {
348 case LONG:
349 value = TmfStateValue.newValueLong(fieldDouble.longValue());
350 break;
351 case STRING:
352 value = TmfStateValue.newValueString(fieldDouble.toString());
353 break;
354 case INTEGER:
355 value = TmfStateValue.newValueInt(fieldDouble.intValue());
356 break;
357 case DOUBLE:
358 case NULL:
359 default:
360 value = TmfStateValue.newValueDouble(fieldDouble);
361 break;
362 }
363 }
364 return value;
365 }
366
367 /**
368 * Get the list of state attributes, the path to the state value
369 *
370 * @return the list of Attribute to have the path in the State System
371 */
372 @Override
373 public List<ITmfXmlStateAttribute> getAttributes() {
374 return fPath;
375 }
376
377 /**
378 * Handles an event, by setting the value of the attribute described by the
379 * state attribute path in the state system.
380 *
381 * @param event
382 * The event to process
383 * @throws AttributeNotFoundException
384 * Pass through the exception it received
385 * @throws TimeRangeException
386 * Pass through the exception it received
387 * @throws StateValueTypeException
388 * Pass through the exception it received
389 */
390 @Override
391 public void handleEvent(@NonNull ITmfEvent event) throws AttributeNotFoundException, StateValueTypeException, TimeRangeException {
392 int quark = IXmlStateSystemContainer.ROOT_QUARK;
393
394 for (ITmfXmlStateAttribute attribute : fPath) {
395 quark = attribute.getAttributeQuark(event, quark);
396 /* the query is not valid, we stop the state change */
397 if (quark == IXmlStateSystemContainer.ERROR_QUARK) {
398 throw new AttributeNotFoundException("Not found XML attribute " + attribute); //$NON-NLS-1$
399 }
400 }
401
402 long ts = event.getTimestamp().getValue();
403 fStateValue.handleEvent(event, quark, ts);
404 }
405
406 @Override
407 public String toString() {
408 StringBuilder builder = new StringBuilder("TmfXmlStateValue: "); //$NON-NLS-1$
409 if (fEventField != null) {
410 builder.append("Field=").append(fEventField).append("; "); //$NON-NLS-1$ //$NON-NLS-2$
411 } else if (!fPath.isEmpty()) {
412 builder.append("Path=").append(fPath).append("; "); //$NON-NLS-1$ //$NON-NLS-2$
413 }
414 builder.append(fStateValue);
415 return builder.toString();
416 }
417
418 /**
419 * Base class for all state values. Contain default methods to handle event,
420 * process or increment the value
421 */
422 protected abstract class TmfXmlStateValueBase {
423
424 /**
425 * Get the value associated with this state value.
426 *
427 * @param event
428 * The event which can be used to retrieve the value if
429 * necessary. The event can be <code>null</code> if no event
430 * is required.
431 * @return The state value corresponding to this XML state value
432 * @throws AttributeNotFoundException
433 * Pass through the exception it received
434 */
435 public abstract ITmfStateValue getValue(@Nullable ITmfEvent event) throws AttributeNotFoundException;
436
437 /**
438 * Do something with the state value, possibly using an event
439 *
440 * @param event
441 * The event being handled. If there is no event is
442 * available, use <code>null</code>.
443 * @param quark
444 * The quark for this value
445 * @param timestamp
446 * The timestamp of the event
447 * @throws StateValueTypeException
448 * Pass through the exception it received
449 * @throws TimeRangeException
450 * Pass through the exception it received
451 * @throws AttributeNotFoundException
452 * Pass through the exception it received
453 */
454 public void handleEvent(ITmfEvent event, int quark, long timestamp) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException {
455 if (fIncrement) {
456 incrementValue(event, quark, timestamp);
457 } else {
458 ITmfStateValue value = getValue(event);
459 processValue(quark, timestamp, value);
460 }
461 }
462
463 /**
464 * Set the value of a quark at a given timestamp.
465 *
466 * @param quark
467 * The quark for this value
468 * @param timestamp
469 * The timestamp
470 * @param value
471 * The value of this state value
472 * @throws TimeRangeException
473 * Pass through the exception it received
474 * @throws StateValueTypeException
475 * Pass through the exception it received
476 * @throws AttributeNotFoundException
477 * Pass through the exception it received
478 */
479 @SuppressWarnings("unused")
480 protected void processValue(int quark, long timestamp, ITmfStateValue value) throws TimeRangeException, StateValueTypeException, AttributeNotFoundException {
481 }
482
483 /**
484 * Increments the value of the parameter
485 *
486 * @param event
487 * The event being handled
488 * @param quark
489 * The quark for this value
490 * @param timestamp
491 * The timestamp of the event
492 * @throws StateValueTypeException
493 * Pass through the exception it received
494 * @throws TimeRangeException
495 * Pass through the exception it received
496 * @throws AttributeNotFoundException
497 * Pass through the exception it received
498 */
499 @SuppressWarnings("unused")
500 protected void incrementValue(ITmfEvent event, int quark, long timestamp) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException {
501 }
502 }
503
504 /* This state value uses a constant value, defined in the XML */
505 private class TmfXmlStateValueNull extends TmfXmlStateValueBase {
506
507 @Override
508 public ITmfStateValue getValue(@Nullable ITmfEvent event) throws AttributeNotFoundException {
509 return TmfStateValue.nullValue();
510 }
511
512 @Override
513 public String toString() {
514 return "NULL"; //$NON-NLS-1$
515 }
516 }
517
518 }
This page took 0.063365 seconds and 5 git commands to generate.