Remove unneeded checkNotNull() calls
[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;
142 default:
143 fForcedType = ITmfStateValue.Type.NULL;
144 }
145
146 /*
147 * Stack Actions : allow to define a stack with PUSH/POP/PEEK methods
148 */
0e4f957e 149 String stack = node.getAttribute(TmfXmlStrings.ATTRIBUTE_STACK);
1d7e62f9
GB
150 fStackType = ValueTypeStack.getTypeFromString(stack);
151 }
152
153 /**
154 * Initialize a {@link TmfXmlStateValueBase} object for the type and value
155 *
156 * @param modelFactory
157 * The factory used to create XML model elements
158 * @param node
159 * The state value XML element
160 * @return The internal state value type corresponding to this state value
161 */
162 protected TmfXmlStateValueBase initializeStateValue(ITmfXmlModelFactory modelFactory, Element node) {
163 return new TmfXmlStateValueNull();
164 }
165
166 /**
167 * Return the state system container this class is attached to
168 *
169 * @return The state system container
170 */
171 protected IXmlStateSystemContainer getSsContainer() {
172 return fContainer;
173 }
174
175 /**
176 * Get the state system associated with this value's container
177 *
178 * @return The state system associated with the state system container
179 */
12685851 180 protected @Nullable ITmfStateSystem getStateSystem() {
1d7e62f9
GB
181 return fContainer.getStateSystem();
182 }
183
184 /**
185 * Return whether this value is an increment of the previous value
186 *
187 * @return <code>true</code> if the value is an increment
188 */
189 protected boolean isIncrement() {
190 return fIncrement;
191 }
192
193 /**
194 * Get the stack type of this attribute. If the attribute is to be pushed or
195 * popped to a stack. The behavior of the stack attribute will depend on the
196 * implementation of the model.
197 *
198 * @return The stack type of the attribute
199 */
200 protected ValueTypeStack getStackType() {
201 return fStackType;
202 }
203
204 /**
205 * Get the forced type of the value. For example, if the value obtained from
206 * the attributes is not in this forced type, it will be converted to this.
207 *
208 * @return The desired type of the value
209 */
210 protected ITmfStateValue.Type getForcedType() {
211 return fForcedType;
212 }
213
214 /**
215 * Get the current {@link ITmfStateValue} of this state value for an event.
216 * It does not increment the value and does not any other processing of the
217 * value.
218 *
219 * @param event
220 * The current event, or <code>null</code> if no event available.
221 * @return the {@link ITmfStateValue}
222 * @throws AttributeNotFoundException
223 * May be thrown by the state system during the query
224 */
225 @Override
226 public ITmfStateValue getValue(@Nullable ITmfEvent event) throws AttributeNotFoundException {
227 return fStateValue.getValue(event);
228 }
229
230 /**
231 * Get the value of the event field that is the path of this state value
232 *
233 * @param event
234 * The current event
235 * @return the value of the event field
236 */
237 @Override
238 public ITmfStateValue getEventFieldValue(@NonNull ITmfEvent event) {
12685851
GB
239 String eventField = fEventField;
240 if (eventField == null) {
241 throw new IllegalStateException();
242 }
243 return getEventFieldValue(event, eventField);
1d7e62f9
GB
244 }
245
246 /**
247 * Get the value of an event field
248 *
249 * @param event
250 * The current event
251 * @param fieldName
252 * The name of the field of which to get the value
253 * @return The value of the event field
254 */
12685851 255 protected ITmfStateValue getEventFieldValue(ITmfEvent event, String fieldName) {
1d7e62f9
GB
256
257 ITmfStateValue value = TmfStateValue.nullValue();
258
259 final ITmfEventField content = event.getContent();
260
12685851
GB
261 /* Exception for "CPU", returns the source of this event */
262 /* FIXME : Nameclash if a eventfield have "cpu" for name. */
35f39420 263 if (fieldName.equals(TmfXmlStrings.CPU)) {
b3867ecc
MAL
264 Integer cpu = TmfTraceUtils.resolveIntEventAspectOfClassForEvent(event.getTrace(), TmfCpuAspect.class, event);
265 if (cpu != null) {
b1aad44e 266 return TmfStateValue.newValueInt(cpu.intValue());
35f39420
AM
267 }
268 }
6e9040a7
NE
269 /* Exception also for "TIMESTAMP", returns the timestamp of this event */
270 if (fieldName.equals(TmfXmlStrings.TIMESTAMP)) {
271 return TmfStateValue.newValueLong(event.getTimestamp().getValue());
272 }
1d7e62f9
GB
273 if (content.getField(fieldName) == null) {
274 return value;
275 }
276
277 Object field = content.getField(fieldName).getValue();
278
279 /*
280 * Try to find the right type. The type can be forced by
281 * "forcedType" argument.
282 */
283
284 if (field instanceof String) {
285 String fieldString = (String) field;
286
287 switch (fForcedType) {
288 case INTEGER:
289 value = TmfStateValue.newValueInt(Integer.parseInt(fieldString));
290 break;
291 case LONG:
292 value = TmfStateValue.newValueLong(Long.parseLong(fieldString));
293 break;
294 case DOUBLE:
295 value = TmfStateValue.newValueDouble(Double.parseDouble(fieldString));
296 break;
297 case NULL:
298 case STRING:
299 default:
300 value = TmfStateValue.newValueString(fieldString);
301 break;
302 }
303 } else if (field instanceof Long) {
304 Long fieldLong = (Long) field;
305
306 switch (fForcedType) {
307 case INTEGER:
308 value = TmfStateValue.newValueInt(fieldLong.intValue());
309 break;
310 case STRING:
311 value = TmfStateValue.newValueString(fieldLong.toString());
312 break;
313 case DOUBLE:
314 value = TmfStateValue.newValueDouble(fieldLong.doubleValue());
315 break;
316 case LONG:
317 case NULL:
318 default:
319 value = TmfStateValue.newValueLong(fieldLong);
320 break;
321 }
322 } else if (field instanceof Integer) {
323 Integer fieldInteger = (Integer) field;
324
325 switch (fForcedType) {
326 case LONG:
327 value = TmfStateValue.newValueLong(fieldInteger.longValue());
328 break;
329 case STRING:
330 value = TmfStateValue.newValueString(fieldInteger.toString());
331 break;
332 case DOUBLE:
333 value = TmfStateValue.newValueDouble(fieldInteger.doubleValue());
334 break;
335 case INTEGER:
336 case NULL:
337 default:
338 value = TmfStateValue.newValueInt(fieldInteger);
339 break;
340 }
341 } else if (field instanceof Double) {
342 Double fieldDouble = (Double) field;
343
344 switch (fForcedType) {
345 case LONG:
346 value = TmfStateValue.newValueLong(fieldDouble.longValue());
347 break;
348 case STRING:
349 value = TmfStateValue.newValueString(fieldDouble.toString());
350 break;
351 case INTEGER:
352 value = TmfStateValue.newValueInt(fieldDouble.intValue());
353 break;
354 case DOUBLE:
355 case NULL:
356 default:
357 value = TmfStateValue.newValueDouble(fieldDouble);
358 break;
359 }
360 }
361 return value;
362 }
363
364 /**
365 * Get the list of state attributes, the path to the state value
366 *
367 * @return the list of Attribute to have the path in the State System
368 */
369 @Override
370 public List<ITmfXmlStateAttribute> getAttributes() {
371 return fPath;
372 }
373
374 /**
375 * Handles an event, by setting the value of the attribute described by the
376 * state attribute path in the state system.
377 *
378 * @param event
379 * The event to process
380 * @throws AttributeNotFoundException
381 * Pass through the exception it received
382 * @throws TimeRangeException
383 * Pass through the exception it received
384 * @throws StateValueTypeException
385 * Pass through the exception it received
386 */
387 @Override
388 public void handleEvent(@NonNull ITmfEvent event) throws AttributeNotFoundException, StateValueTypeException, TimeRangeException {
389 int quark = IXmlStateSystemContainer.ROOT_QUARK;
390
391 for (ITmfXmlStateAttribute attribute : fPath) {
392 quark = attribute.getAttributeQuark(event, quark);
393 /* the query is not valid, we stop the state change */
394 if (quark == IXmlStateSystemContainer.ERROR_QUARK) {
446598f9 395 throw new AttributeNotFoundException("Not found XML attribute " + attribute); //$NON-NLS-1$
1d7e62f9
GB
396 }
397 }
398
399 long ts = event.getTimestamp().getValue();
400 fStateValue.handleEvent(event, quark, ts);
401 }
402
446598f9
GB
403 @Override
404 public String toString() {
cbac1ac1
JCK
405 StringBuilder builder = new StringBuilder("TmfXmlStateValue: "); //$NON-NLS-1$
406 if (fEventField != null) {
407 builder.append("Field=").append(fEventField).append("; "); //$NON-NLS-1$ //$NON-NLS-2$
408 } else if (!fPath.isEmpty()) {
409 builder.append("Path=").append(fPath).append("; "); //$NON-NLS-1$ //$NON-NLS-2$
410 }
411 builder.append(fStateValue);
412 return builder.toString();
446598f9
GB
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
cbac1ac1
JCK
509 @Override
510 public String toString() {
511 return "NULL"; //$NON-NLS-1$
512 }
1d7e62f9
GB
513 }
514
52293ccd 515}
This page took 0.106016 seconds and 5 git commands to generate.