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