tmf xml: Add a few package-info to tmf.analysis.xml.core.model.*
[deliverable/tracecompass.git] / org.eclipse.tracecompass.tmf.analysis.xml.core / src / org / eclipse / tracecompass / tmf / analysis / xml / core / model / TmfXmlStateValue.java
CommitLineData
1d7e62f9
GB
1/*******************************************************************************
2 * Copyright (c) 2014 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
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;
142 default:
143 fForcedType = ITmfStateValue.Type.NULL;
144 }
145
146 /*
147 * Stack Actions : allow to define a stack with PUSH/POP/PEEK methods
148 */
12685851
GB
149 @SuppressWarnings("null")
150 @NonNull String stack = node.getAttribute(TmfXmlStrings.ATTRIBUTE_STACK);
1d7e62f9
GB
151 fStackType = ValueTypeStack.getTypeFromString(stack);
152 }
153
154 /**
155 * Initialize a {@link TmfXmlStateValueBase} object for the type and value
156 *
157 * @param modelFactory
158 * The factory used to create XML model elements
159 * @param node
160 * The state value XML element
161 * @return The internal state value type corresponding to this state value
162 */
163 protected TmfXmlStateValueBase initializeStateValue(ITmfXmlModelFactory modelFactory, Element node) {
164 return new TmfXmlStateValueNull();
165 }
166
167 /**
168 * Return the state system container this class is attached to
169 *
170 * @return The state system container
171 */
172 protected IXmlStateSystemContainer getSsContainer() {
173 return fContainer;
174 }
175
176 /**
177 * Get the state system associated with this value's container
178 *
179 * @return The state system associated with the state system container
180 */
12685851 181 protected @Nullable ITmfStateSystem getStateSystem() {
1d7e62f9
GB
182 return fContainer.getStateSystem();
183 }
184
185 /**
186 * Return whether this value is an increment of the previous value
187 *
188 * @return <code>true</code> if the value is an increment
189 */
190 protected boolean isIncrement() {
191 return fIncrement;
192 }
193
194 /**
195 * Get the stack type of this attribute. If the attribute is to be pushed or
196 * popped to a stack. The behavior of the stack attribute will depend on the
197 * implementation of the model.
198 *
199 * @return The stack type of the attribute
200 */
201 protected ValueTypeStack getStackType() {
202 return fStackType;
203 }
204
205 /**
206 * Get the forced type of the value. For example, if the value obtained from
207 * the attributes is not in this forced type, it will be converted to this.
208 *
209 * @return The desired type of the value
210 */
211 protected ITmfStateValue.Type getForcedType() {
212 return fForcedType;
213 }
214
215 /**
216 * Get the current {@link ITmfStateValue} of this state value for an event.
217 * It does not increment the value and does not any other processing of the
218 * value.
219 *
220 * @param event
221 * The current event, or <code>null</code> if no event available.
222 * @return the {@link ITmfStateValue}
223 * @throws AttributeNotFoundException
224 * May be thrown by the state system during the query
225 */
226 @Override
227 public ITmfStateValue getValue(@Nullable ITmfEvent event) throws AttributeNotFoundException {
228 return fStateValue.getValue(event);
229 }
230
231 /**
232 * Get the value of the event field that is the path of this state value
233 *
234 * @param event
235 * The current event
236 * @return the value of the event field
237 */
238 @Override
239 public ITmfStateValue getEventFieldValue(@NonNull ITmfEvent event) {
12685851
GB
240 String eventField = fEventField;
241 if (eventField == null) {
242 throw new IllegalStateException();
243 }
244 return getEventFieldValue(event, eventField);
1d7e62f9
GB
245 }
246
247 /**
248 * Get the value of an event field
249 *
250 * @param event
251 * The current event
252 * @param fieldName
253 * The name of the field of which to get the value
254 * @return The value of the event field
255 */
12685851 256 protected ITmfStateValue getEventFieldValue(ITmfEvent event, String fieldName) {
1d7e62f9
GB
257
258 ITmfStateValue value = TmfStateValue.nullValue();
259
260 final ITmfEventField content = event.getContent();
261
12685851
GB
262 /* Exception for "CPU", returns the source of this event */
263 /* FIXME : Nameclash if a eventfield have "cpu" for name. */
35f39420
AM
264 if (fieldName.equals(TmfXmlStrings.CPU)) {
265 /* See if the event advertises a CPU aspect */
266 Iterable<TmfCpuAspect> cpuAspects = TmfTraceUtils.getEventAspectsOfClass(
267 event.getTrace(), TmfCpuAspect.class);
268 for (TmfCpuAspect aspect : cpuAspects) {
269 /* We will just pick the first valid one we find */
52293ccd
GB
270 Integer cpu = aspect.resolve(event);
271 if (!cpu.equals(TmfCpuAspect.CPU_UNAVAILABLE)) {
272 return TmfStateValue.newValueInt(cpu.intValue());
35f39420
AM
273 }
274 }
275 }
6e9040a7
NE
276 /* Exception also for "TIMESTAMP", returns the timestamp of this event */
277 if (fieldName.equals(TmfXmlStrings.TIMESTAMP)) {
278 return TmfStateValue.newValueLong(event.getTimestamp().getValue());
279 }
1d7e62f9
GB
280 if (content.getField(fieldName) == null) {
281 return value;
282 }
283
284 Object field = content.getField(fieldName).getValue();
285
286 /*
287 * Try to find the right type. The type can be forced by
288 * "forcedType" argument.
289 */
290
291 if (field instanceof String) {
292 String fieldString = (String) field;
293
294 switch (fForcedType) {
295 case INTEGER:
296 value = TmfStateValue.newValueInt(Integer.parseInt(fieldString));
297 break;
298 case LONG:
299 value = TmfStateValue.newValueLong(Long.parseLong(fieldString));
300 break;
301 case DOUBLE:
302 value = TmfStateValue.newValueDouble(Double.parseDouble(fieldString));
303 break;
304 case NULL:
305 case STRING:
306 default:
307 value = TmfStateValue.newValueString(fieldString);
308 break;
309 }
310 } else if (field instanceof Long) {
311 Long fieldLong = (Long) field;
312
313 switch (fForcedType) {
314 case INTEGER:
315 value = TmfStateValue.newValueInt(fieldLong.intValue());
316 break;
317 case STRING:
318 value = TmfStateValue.newValueString(fieldLong.toString());
319 break;
320 case DOUBLE:
321 value = TmfStateValue.newValueDouble(fieldLong.doubleValue());
322 break;
323 case LONG:
324 case NULL:
325 default:
326 value = TmfStateValue.newValueLong(fieldLong);
327 break;
328 }
329 } else if (field instanceof Integer) {
330 Integer fieldInteger = (Integer) field;
331
332 switch (fForcedType) {
333 case LONG:
334 value = TmfStateValue.newValueLong(fieldInteger.longValue());
335 break;
336 case STRING:
337 value = TmfStateValue.newValueString(fieldInteger.toString());
338 break;
339 case DOUBLE:
340 value = TmfStateValue.newValueDouble(fieldInteger.doubleValue());
341 break;
342 case INTEGER:
343 case NULL:
344 default:
345 value = TmfStateValue.newValueInt(fieldInteger);
346 break;
347 }
348 } else if (field instanceof Double) {
349 Double fieldDouble = (Double) field;
350
351 switch (fForcedType) {
352 case LONG:
353 value = TmfStateValue.newValueLong(fieldDouble.longValue());
354 break;
355 case STRING:
356 value = TmfStateValue.newValueString(fieldDouble.toString());
357 break;
358 case INTEGER:
359 value = TmfStateValue.newValueInt(fieldDouble.intValue());
360 break;
361 case DOUBLE:
362 case NULL:
363 default:
364 value = TmfStateValue.newValueDouble(fieldDouble);
365 break;
366 }
367 }
368 return value;
369 }
370
371 /**
372 * Get the list of state attributes, the path to the state value
373 *
374 * @return the list of Attribute to have the path in the State System
375 */
376 @Override
377 public List<ITmfXmlStateAttribute> getAttributes() {
378 return fPath;
379 }
380
381 /**
382 * Handles an event, by setting the value of the attribute described by the
383 * state attribute path in the state system.
384 *
385 * @param event
386 * The event to process
387 * @throws AttributeNotFoundException
388 * Pass through the exception it received
389 * @throws TimeRangeException
390 * Pass through the exception it received
391 * @throws StateValueTypeException
392 * Pass through the exception it received
393 */
394 @Override
395 public void handleEvent(@NonNull ITmfEvent event) throws AttributeNotFoundException, StateValueTypeException, TimeRangeException {
396 int quark = IXmlStateSystemContainer.ROOT_QUARK;
397
398 for (ITmfXmlStateAttribute attribute : fPath) {
399 quark = attribute.getAttributeQuark(event, quark);
400 /* the query is not valid, we stop the state change */
401 if (quark == IXmlStateSystemContainer.ERROR_QUARK) {
446598f9 402 throw new AttributeNotFoundException("Not found XML attribute " + attribute); //$NON-NLS-1$
1d7e62f9
GB
403 }
404 }
405
406 long ts = event.getTimestamp().getValue();
407 fStateValue.handleEvent(event, quark, ts);
408 }
409
446598f9
GB
410 @Override
411 public String toString() {
412 return "TmfXmlStateValue: " + fStateValue; //$NON-NLS-1$
413 }
414
1d7e62f9
GB
415 /**
416 * Base class for all state values. Contain default methods to handle event,
417 * process or increment the value
418 */
419 protected abstract class TmfXmlStateValueBase {
420
421 /**
422 * Get the value associated with this state value.
423 *
424 * @param event
425 * The event which can be used to retrieve the value if
426 * necessary. The event can be <code>null</code> if no event
427 * is required.
428 * @return The state value corresponding to this XML state value
429 * @throws AttributeNotFoundException
430 * Pass through the exception it received
431 */
432 public abstract ITmfStateValue getValue(@Nullable ITmfEvent event) throws AttributeNotFoundException;
433
434 /**
435 * Do something with the state value, possibly using an event
436 *
437 * @param event
438 * The event being handled. If there is no event is
439 * available, use <code>null</code>.
440 * @param quark
441 * The quark for this value
442 * @param timestamp
443 * The timestamp of the event
444 * @throws StateValueTypeException
445 * Pass through the exception it received
446 * @throws TimeRangeException
447 * Pass through the exception it received
448 * @throws AttributeNotFoundException
449 * Pass through the exception it received
450 */
12685851 451 public void handleEvent(ITmfEvent event, int quark, long timestamp) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException {
1d7e62f9
GB
452 if (fIncrement) {
453 incrementValue(event, quark, timestamp);
454 } else {
455 ITmfStateValue value = getValue(event);
456 processValue(quark, timestamp, value);
457 }
458 }
459
460 /**
461 * Set the value of a quark at a given timestamp.
462 *
463 * @param quark
464 * The quark for this value
465 * @param timestamp
466 * The timestamp
467 * @param value
468 * The value of this state value
469 * @throws TimeRangeException
470 * Pass through the exception it received
471 * @throws StateValueTypeException
472 * Pass through the exception it received
473 * @throws AttributeNotFoundException
474 * Pass through the exception it received
475 */
476 @SuppressWarnings("unused")
477 protected void processValue(int quark, long timestamp, ITmfStateValue value) throws TimeRangeException, StateValueTypeException, AttributeNotFoundException {
478 }
479
480 /**
481 * Increments the value of the parameter
482 *
483 * @param event
484 * The event being handled
485 * @param quark
486 * The quark for this value
487 * @param timestamp
488 * The timestamp of the event
489 * @throws StateValueTypeException
490 * Pass through the exception it received
491 * @throws TimeRangeException
492 * Pass through the exception it received
493 * @throws AttributeNotFoundException
494 * Pass through the exception it received
495 */
496 @SuppressWarnings("unused")
497 protected void incrementValue(ITmfEvent event, int quark, long timestamp) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException {
498 }
499 }
500
501 /* This state value uses a constant value, defined in the XML */
502 private class TmfXmlStateValueNull extends TmfXmlStateValueBase {
503
504 @Override
505 public ITmfStateValue getValue(@Nullable ITmfEvent event) throws AttributeNotFoundException {
506 return TmfStateValue.nullValue();
507 }
508
509 }
510
52293ccd 511}
This page took 0.091388 seconds and 5 git commands to generate.