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