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