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 / readwrite / TmfXmlReadWriteStateValue.java
CommitLineData
1d7e62f9
GB
1/*******************************************************************************
2 * Copyright (c) 2014 École Polytechnique de Montréal
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 * Geneviève Bastien - Initial API and implementation
11 *******************************************************************************/
12
2bdf0193 13package org.eclipse.tracecompass.tmf.analysis.xml.core.model.readwrite;
1d7e62f9
GB
14
15import java.util.ArrayList;
16import java.util.List;
17
0b563c20 18import org.eclipse.jdt.annotation.NonNull;
9411fd5b 19import org.eclipse.jdt.annotation.Nullable;
2bdf0193 20import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.Activator;
e894a508
AM
21import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
22import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
acec47ce 23import org.eclipse.tracecompass.statesystem.core.StateSystemBuilderUtils;
e894a508
AM
24import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
25import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
26import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
27import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
28import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
2bdf0193
AM
29import org.eclipse.tracecompass.tmf.analysis.xml.core.model.ITmfXmlModelFactory;
30import org.eclipse.tracecompass.tmf.analysis.xml.core.model.ITmfXmlStateAttribute;
0b563c20 31import org.eclipse.tracecompass.tmf.analysis.xml.core.model.TmfXmlScenarioInfo;
2bdf0193
AM
32import org.eclipse.tracecompass.tmf.analysis.xml.core.model.TmfXmlStateValue;
33import org.eclipse.tracecompass.tmf.analysis.xml.core.module.IXmlStateSystemContainer;
34import org.eclipse.tracecompass.tmf.analysis.xml.core.module.XmlUtils;
35import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings;
36import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
1d7e62f9
GB
37import org.w3c.dom.Element;
38
39/**
40 * Implements a state value in a read write mode. See {@link TmfXmlStateValue}
41 * for the syntax of the state value.
42 *
43 * In read/write mode, a state value can be considered as an assignation where
44 * the state value is assigned to the quark represented by the state attributes
45 *
46 * @author Geneviève Bastien
47 */
b1ebf44e 48public class TmfXmlReadWriteStateValue extends TmfXmlStateValue {
1d7e62f9 49
a194b17a
JCK
50 private static final String ILLEGAL_STATE_EXCEPTION_MESSAGE = "The state system hasn't been initialized yet"; //$NON-NLS-1$
51
1d7e62f9
GB
52 /**
53 * Constructor where the path to the value is a list of state attributes
54 *
55 * @param modelFactory
56 * The factory used to create XML model elements
57 * @param node
58 * The state value XML element
59 * @param container
60 * The state system container this state value belongs to
61 * @param attributes
62 * The attributes representing the path to this value
63 */
b1ebf44e 64 public TmfXmlReadWriteStateValue(TmfXmlReadWriteModelFactory modelFactory, Element node, IXmlStateSystemContainer container, List<ITmfXmlStateAttribute> attributes) {
1d7e62f9
GB
65 this(modelFactory, node, container, attributes, null);
66 }
67
68 /**
69 * Constructor where the path to the value is an event field
70 *
71 * @param modelFactory
72 * The factory used to create XML model elements
73 * @param node
74 * The state value XML element
75 * @param container
76 * The state system container this state value belongs to
77 * @param eventField
78 * The event field where to get the value
79 */
b1ebf44e 80 public TmfXmlReadWriteStateValue(TmfXmlReadWriteModelFactory modelFactory, Element node, IXmlStateSystemContainer container, String eventField) {
1d7e62f9
GB
81 this(modelFactory, node, container, new ArrayList<ITmfXmlStateAttribute>(), eventField);
82 }
83
12685851 84 private TmfXmlReadWriteStateValue(ITmfXmlModelFactory modelFactory, Element node, IXmlStateSystemContainer container, List<ITmfXmlStateAttribute> attributes, @Nullable String eventField) {
1d7e62f9
GB
85 super(modelFactory, node, container, attributes, eventField);
86 }
87
88 @Override
12685851 89 protected @Nullable ITmfStateSystemBuilder getStateSystem() {
1d7e62f9
GB
90 return (ITmfStateSystemBuilder) super.getStateSystem();
91 }
92
93 @Override
94 protected TmfXmlStateValueBase initializeStateValue(ITmfXmlModelFactory modelFactory, Element node) {
95 TmfXmlStateValueBase stateValueType = null;
96 /* Process the XML Element state value */
97 String type = node.getAttribute(TmfXmlStrings.TYPE);
98 String value = getSsContainer().getAttributeValue(node.getAttribute(TmfXmlStrings.VALUE));
12685851
GB
99 if (value == null) {
100 throw new IllegalStateException();
101 }
1d7e62f9
GB
102
103 switch (type) {
104 case TmfXmlStrings.TYPE_INT: {
105 /* Integer value */
106 ITmfStateValue stateValue = TmfStateValue.newValueInt(Integer.parseInt(value));
107 stateValueType = new TmfXmlStateValueTmf(stateValue);
108 break;
109 }
110 case TmfXmlStrings.TYPE_LONG: {
111 /* Long value */
112 ITmfStateValue stateValue = TmfStateValue.newValueLong(Long.parseLong(value));
113 stateValueType = new TmfXmlStateValueTmf(stateValue);
114 break;
115 }
116 case TmfXmlStrings.TYPE_STRING: {
117 /* String value */
118 ITmfStateValue stateValue = TmfStateValue.newValueString(value);
119 stateValueType = new TmfXmlStateValueTmf(stateValue);
120 break;
121 }
122 case TmfXmlStrings.TYPE_NULL: {
123 /* Null value */
124 ITmfStateValue stateValue = TmfStateValue.nullValue();
125 stateValueType = new TmfXmlStateValueTmf(stateValue);
126 break;
127 }
128 case TmfXmlStrings.EVENT_FIELD:
129 /* Event field */
130 stateValueType = new TmfXmlStateValueEventField(value);
131 break;
132 case TmfXmlStrings.TYPE_EVENT_NAME:
133 /* The value is the event name */
134 stateValueType = new TmfXmlStateValueEventName();
135 break;
136 case TmfXmlStrings.TYPE_DELETE:
137 /* Deletes the value of an attribute */
138 stateValueType = new TmfXmlStateValueDelete();
139 break;
140 case TmfXmlStrings.TYPE_QUERY:
141 /* Value is the result of a query */
4c4e2816 142 List<@Nullable Element> children = XmlUtils.getChildElements(node);
1d7e62f9
GB
143 List<ITmfXmlStateAttribute> childAttributes = new ArrayList<>();
144 for (Element child : children) {
12685851
GB
145 if (child == null) {
146 continue;
147 }
1d7e62f9
GB
148 ITmfXmlStateAttribute queryAttribute = modelFactory.createStateAttribute(child, getSsContainer());
149 childAttributes.add(queryAttribute);
150 }
151 stateValueType = new TmfXmlStateValueQuery(childAttributes);
152 break;
153 default:
154 throw new IllegalArgumentException(String.format("TmfXmlStateValue constructor: unexpected element %s for stateValue type", type)); //$NON-NLS-1$
155 }
156 return stateValueType;
157 }
158
159 // ----------------------------------------------------------
160 // Internal state value classes for the different types
161 // ----------------------------------------------------------
162
163 /**
164 * Base class for all state value. Contain default methods to handle event,
165 * process or increment the value
166 */
167 protected abstract class TmfXmlStateValueTypeReadWrite extends TmfXmlStateValueBase {
168
169 @Override
0b563c20 170 public final void handleEvent(ITmfEvent event, int quark, long timestamp, @Nullable TmfXmlScenarioInfo scenarioInfo) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException {
1d7e62f9 171 if (isIncrement()) {
0b563c20 172 incrementValue(event, quark, timestamp, scenarioInfo);
1d7e62f9 173 } else {
0b563c20 174 ITmfStateValue value = getValue(event, scenarioInfo);
1d7e62f9
GB
175 processValue(quark, timestamp, value);
176 }
177 }
178
179 @Override
180 protected void processValue(int quark, long timestamp, ITmfStateValue value) throws AttributeNotFoundException, TimeRangeException, StateValueTypeException {
12685851
GB
181 ITmfStateSystemBuilder ss = getStateSystem();
182 if (ss == null) {
a194b17a 183 throw new IllegalStateException(ILLEGAL_STATE_EXCEPTION_MESSAGE);
12685851 184 }
1d7e62f9
GB
185 switch (getStackType()) {
186 case POP:
12685851 187 ss.popAttribute(timestamp, quark);
1d7e62f9
GB
188 break;
189 case PUSH:
12685851 190 ss.pushAttribute(timestamp, value, quark);
1d7e62f9
GB
191 break;
192 case NULL:
193 case PEEK:
194 default:
12685851 195 ss.modifyAttribute(timestamp, value, quark);
1d7e62f9
GB
196 break;
197 }
198 }
199
200 @Override
0b563c20 201 protected void incrementValue(ITmfEvent event, int quark, long timestamp, @Nullable TmfXmlScenarioInfo scenarioInfo) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException {
12685851
GB
202 ITmfStateSystemBuilder ss = getStateSystem();
203 if (ss == null) {
a194b17a 204 throw new IllegalStateException(ILLEGAL_STATE_EXCEPTION_MESSAGE);
12685851 205 }
acec47ce 206 StateSystemBuilderUtils.incrementAttributeInt(ss, timestamp, quark, 1);
1d7e62f9
GB
207 }
208 }
209
b1e4ea44 210 private static @Nullable ITmfStateValue incrementByType(int quark, ITmfStateSystem ss, ITmfStateValue stateValue) throws AttributeNotFoundException {
9411fd5b
MK
211 ITmfStateValue value = null;
212 switch (stateValue.getType()) {
213 case LONG: {
214 long incrementLong = stateValue.unboxLong();
215 ITmfStateValue currentState = ss.queryOngoingState(quark);
216 long currentValue = (currentState.isNull() ? 0 : currentState.unboxLong());
217 value = TmfStateValue.newValueLong(incrementLong + currentValue);
218 return value;
219 }
220 case INTEGER: {
221 int increment = stateValue.unboxInt();
222 ITmfStateValue currentState = ss.queryOngoingState(quark);
223 int currentValue = (currentState.isNull() ? 0 : currentState.unboxInt());
224 value = TmfStateValue.newValueInt(increment + currentValue);
225 return value;
226 }
227 case DOUBLE:
228 case NULL:
229 case STRING:
230 default:
231 }
232 return value;
233 }
234
1d7e62f9
GB
235 /* This state value uses a constant value, defined in the XML */
236 private class TmfXmlStateValueTmf extends TmfXmlStateValueTypeReadWrite {
237
238 private final ITmfStateValue fValue;
239
240 public TmfXmlStateValueTmf(ITmfStateValue value) {
241 fValue = value;
242 }
243
244 @Override
0b563c20 245 public ITmfStateValue getValue(@Nullable ITmfEvent event, @Nullable TmfXmlScenarioInfo scenarioInfo) {
1d7e62f9
GB
246 return fValue;
247 }
248
249 @Override
0b563c20 250 public void incrementValue(ITmfEvent event, int quark, long timestamp, @Nullable TmfXmlScenarioInfo scenarioInfo) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException {
1d7e62f9 251 ITmfStateSystem ss = getStateSystem();
12685851 252 if (ss == null) {
a194b17a 253 throw new IllegalStateException(ILLEGAL_STATE_EXCEPTION_MESSAGE);
12685851 254 }
b1e4ea44 255 ITmfStateValue value = incrementByType(quark, ss, fValue);
9411fd5b 256 if (value != null) {
1d7e62f9 257 processValue(quark, timestamp, value);
9411fd5b 258 } else {
1d7e62f9 259 Activator.logWarning("TmfXmlStateValue: The increment value is not a number type"); //$NON-NLS-1$
1d7e62f9
GB
260 }
261 }
9411fd5b 262
cbac1ac1
JCK
263 @Override
264 public String toString() {
265 return "Value=" + fValue; //$NON-NLS-1$
266 }
267
1d7e62f9
GB
268 }
269
270 /* The state value uses the value of an event field */
271 private class TmfXmlStateValueEventField extends TmfXmlStateValueTypeReadWrite {
272
273 private final String fFieldName;
274
275 public TmfXmlStateValueEventField(String field) {
276 fFieldName = field;
277 }
278
279 @Override
0b563c20 280 public ITmfStateValue getValue(@Nullable ITmfEvent event, @Nullable TmfXmlScenarioInfo scenarioInfo) {
1d7e62f9
GB
281 if (event == null) {
282 Activator.logWarning("XML State value: requested an event field, but event is null"); //$NON-NLS-1$
283 return TmfStateValue.nullValue();
284 }
285 return getEventFieldValue(event, fFieldName);
286 }
287
288 @Override
0b563c20 289 public void incrementValue(ITmfEvent event, int quark, long timestamp, @Nullable TmfXmlScenarioInfo scenarioInfo) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException {
1d7e62f9 290 ITmfStateSystem ss = getSsContainer().getStateSystem();
12685851 291 if (ss == null) {
a194b17a 292 throw new IllegalStateException(ILLEGAL_STATE_EXCEPTION_MESSAGE);
12685851 293 }
0b563c20 294 ITmfStateValue incrementValue = getValue(event, scenarioInfo);
b1e4ea44 295 ITmfStateValue value = incrementByType(quark, ss, incrementValue);
9411fd5b 296 if (value != null) {
1d7e62f9 297 processValue(quark, timestamp, value);
9411fd5b 298 } else {
1d7e62f9 299 Activator.logWarning(String.format("TmfXmlStateValue: The event field increment %s is not a number type but a %s", fFieldName, incrementValue.getType())); //$NON-NLS-1$
1d7e62f9
GB
300 }
301 }
cbac1ac1
JCK
302
303 @Override
304 public String toString() {
305 return "Event Field=" + fFieldName; //$NON-NLS-1$
306 }
1d7e62f9
GB
307 }
308
309 /* The state value is the event name */
310 private class TmfXmlStateValueEventName extends TmfXmlStateValueTypeReadWrite {
311
312 @Override
0b563c20 313 public @NonNull ITmfStateValue getValue(@Nullable ITmfEvent event, @Nullable TmfXmlScenarioInfo scenarioInfo) throws AttributeNotFoundException {
1d7e62f9
GB
314 if (event == null) {
315 Activator.logWarning("XML State value: request event name, but event is null"); //$NON-NLS-1$
316 return TmfStateValue.nullValue();
317 }
578716e6 318 return TmfStateValue.newValueString(event.getName());
1d7e62f9
GB
319 }
320
cbac1ac1
JCK
321 @Override
322 public String toString() {
323 return "Event name"; //$NON-NLS-1$
324 }
1d7e62f9
GB
325 }
326
327 /* The state value deletes an attribute */
328 private class TmfXmlStateValueDelete extends TmfXmlStateValueTypeReadWrite {
329
330 @Override
0b563c20 331 public @NonNull ITmfStateValue getValue(@Nullable ITmfEvent event, @Nullable TmfXmlScenarioInfo scenarioInfo) throws AttributeNotFoundException {
1d7e62f9
GB
332 return TmfStateValue.nullValue();
333 }
334
335 @Override
336 protected void processValue(int quark, long timestamp, ITmfStateValue value) throws TimeRangeException, AttributeNotFoundException {
337 ITmfStateSystem ss = getStateSystem();
338 if (!(ss instanceof ITmfStateSystemBuilder)) {
339 throw new IllegalStateException("incrementValue should never be called when not building the state system"); //$NON-NLS-1$
340 }
341 ITmfStateSystemBuilder builder = (ITmfStateSystemBuilder) ss;
342 builder.removeAttribute(timestamp, quark);
343 }
344
cbac1ac1
JCK
345 @Override
346 public String toString() {
347 return "Delete"; //$NON-NLS-1$
348 }
1d7e62f9
GB
349 }
350
351 /* The state value uses the result of a query */
352 private class TmfXmlStateValueQuery extends TmfXmlStateValueTypeReadWrite {
353
354 private final List<ITmfXmlStateAttribute> fQueryValue;
355
356 public TmfXmlStateValueQuery(List<ITmfXmlStateAttribute> childAttributes) {
357 fQueryValue = childAttributes;
358 }
359
360 @Override
0b563c20 361 public ITmfStateValue getValue(@Nullable ITmfEvent event, @Nullable TmfXmlScenarioInfo scenarioInfo) throws AttributeNotFoundException {
1d7e62f9
GB
362 /* Query the state system for the value */
363 ITmfStateValue value = TmfStateValue.nullValue();
364 int quarkQuery = IXmlStateSystemContainer.ROOT_QUARK;
365 ITmfStateSystem ss = getStateSystem();
12685851 366 if (ss == null) {
a194b17a 367 throw new IllegalStateException(ILLEGAL_STATE_EXCEPTION_MESSAGE);
12685851 368 }
1d7e62f9
GB
369
370 for (ITmfXmlStateAttribute attribute : fQueryValue) {
0b563c20 371 quarkQuery = attribute.getAttributeQuark(event, quarkQuery, scenarioInfo);
1d7e62f9
GB
372 if (quarkQuery == IXmlStateSystemContainer.ERROR_QUARK) {
373 /* the query is not valid, we stop the state change */
374 break;
375 }
376 }
377 /*
378 * the query can fail : for example, if a value is requested but has
379 * not been set yet
380 */
381 if (quarkQuery != IXmlStateSystemContainer.ERROR_QUARK) {
382 value = ss.queryOngoingState(quarkQuery);
383 }
384 return value;
385 }
386
387 @Override
0b563c20 388 public void incrementValue(ITmfEvent event, int quark, long timestamp, @Nullable TmfXmlScenarioInfo scenarioInfo) throws StateValueTypeException, TimeRangeException, AttributeNotFoundException {
1d7e62f9 389 ITmfStateSystem ss = getStateSystem();
12685851 390 if (ss == null) {
a194b17a 391 throw new IllegalStateException(ILLEGAL_STATE_EXCEPTION_MESSAGE);
12685851
GB
392 }
393
0b563c20 394 ITmfStateValue incrementValue = getValue(event, scenarioInfo);
b1e4ea44 395 ITmfStateValue value = incrementByType(quark, ss, incrementValue);
9411fd5b 396 if (value != null) {
1d7e62f9 397 processValue(quark, timestamp, value);
9411fd5b 398 } else {
1d7e62f9 399 Activator.logWarning("TmfXmlStateValue: The query result increment is not a number type"); //$NON-NLS-1$
1d7e62f9
GB
400 }
401 }
cbac1ac1
JCK
402
403 @Override
404 public String toString() {
405 return "Query=" + fQueryValue; //$NON-NLS-1$
406 }
1d7e62f9
GB
407 }
408
409}
This page took 0.079773 seconds and 5 git commands to generate.