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