1 /*******************************************************************************
2 * Copyright (c) 2014 École Polytechnique de Montréal
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
10 * Geneviève Bastien - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.tracecompass
.tmf
.analysis
.xml
.core
.model
.readwrite
;
15 import java
.util
.ArrayList
;
16 import java
.util
.List
;
18 import org
.eclipse
.tracecompass
.internal
.tmf
.analysis
.xml
.core
.Activator
;
19 import org
.eclipse
.tracecompass
.statesystem
.core
.ITmfStateSystem
;
20 import org
.eclipse
.tracecompass
.statesystem
.core
.ITmfStateSystemBuilder
;
21 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.AttributeNotFoundException
;
22 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.StateValueTypeException
;
23 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.TimeRangeException
;
24 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.ITmfStateValue
;
25 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.TmfStateValue
;
26 import org
.eclipse
.tracecompass
.tmf
.analysis
.xml
.core
.model
.ITmfXmlModelFactory
;
27 import org
.eclipse
.tracecompass
.tmf
.analysis
.xml
.core
.model
.ITmfXmlStateAttribute
;
28 import org
.eclipse
.tracecompass
.tmf
.analysis
.xml
.core
.model
.TmfXmlStateValue
;
29 import org
.eclipse
.tracecompass
.tmf
.analysis
.xml
.core
.module
.IXmlStateSystemContainer
;
30 import org
.eclipse
.tracecompass
.tmf
.analysis
.xml
.core
.module
.XmlUtils
;
31 import org
.eclipse
.tracecompass
.tmf
.analysis
.xml
.core
.stateprovider
.TmfXmlStrings
;
32 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEvent
;
33 import org
.w3c
.dom
.Element
;
36 * Implements a state value in a read write mode. See {@link TmfXmlStateValue}
37 * for the syntax of the state value.
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
42 * @author Geneviève Bastien
44 public class TmfXmlReadWriteStateValue
extends TmfXmlStateValue
{
47 * Constructor where the path to the value is a list of state attributes
50 * The factory used to create XML model elements
52 * The state value XML element
54 * The state system container this state value belongs to
56 * The attributes representing the path to this value
58 public TmfXmlReadWriteStateValue(TmfXmlReadWriteModelFactory modelFactory
, Element node
, IXmlStateSystemContainer container
, List
<ITmfXmlStateAttribute
> attributes
) {
59 this(modelFactory
, node
, container
, attributes
, null);
63 * Constructor where the path to the value is an event field
66 * The factory used to create XML model elements
68 * The state value XML element
70 * The state system container this state value belongs to
72 * The event field where to get the value
74 public TmfXmlReadWriteStateValue(TmfXmlReadWriteModelFactory modelFactory
, Element node
, IXmlStateSystemContainer container
, String eventField
) {
75 this(modelFactory
, node
, container
, new ArrayList
<ITmfXmlStateAttribute
>(), eventField
);
78 private TmfXmlReadWriteStateValue(ITmfXmlModelFactory modelFactory
, Element node
, IXmlStateSystemContainer container
, List
<ITmfXmlStateAttribute
> attributes
, String eventField
) {
79 super(modelFactory
, node
, container
, attributes
, eventField
);
83 protected ITmfStateSystemBuilder
getStateSystem() {
84 return (ITmfStateSystemBuilder
) super.getStateSystem();
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
));
95 case TmfXmlStrings
.TYPE_INT
: {
97 ITmfStateValue stateValue
= TmfStateValue
.newValueInt(Integer
.parseInt(value
));
98 stateValueType
= new TmfXmlStateValueTmf(stateValue
);
101 case TmfXmlStrings
.TYPE_LONG
: {
103 ITmfStateValue stateValue
= TmfStateValue
.newValueLong(Long
.parseLong(value
));
104 stateValueType
= new TmfXmlStateValueTmf(stateValue
);
107 case TmfXmlStrings
.TYPE_STRING
: {
109 ITmfStateValue stateValue
= TmfStateValue
.newValueString(value
);
110 stateValueType
= new TmfXmlStateValueTmf(stateValue
);
113 case TmfXmlStrings
.TYPE_NULL
: {
115 ITmfStateValue stateValue
= TmfStateValue
.nullValue();
116 stateValueType
= new TmfXmlStateValueTmf(stateValue
);
119 case TmfXmlStrings
.EVENT_FIELD
:
121 stateValueType
= new TmfXmlStateValueEventField(value
);
123 case TmfXmlStrings
.TYPE_EVENT_NAME
:
124 /* The value is the event name */
125 stateValueType
= new TmfXmlStateValueEventName();
127 case TmfXmlStrings
.TYPE_DELETE
:
128 /* Deletes the value of an attribute */
129 stateValueType
= new TmfXmlStateValueDelete();
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
);
139 stateValueType
= new TmfXmlStateValueQuery(childAttributes
);
142 throw new IllegalArgumentException(String
.format("TmfXmlStateValue constructor: unexpected element %s for stateValue type", type
)); //$NON-NLS-1$
144 return stateValueType
;
147 // ----------------------------------------------------------
148 // Internal state value classes for the different types
149 // ----------------------------------------------------------
152 * Base class for all state value. Contain default methods to handle event,
153 * process or increment the value
155 protected abstract class TmfXmlStateValueTypeReadWrite
extends TmfXmlStateValueBase
{
158 public final void handleEvent(ITmfEvent event
, int quark
, long timestamp
) throws StateValueTypeException
, TimeRangeException
, AttributeNotFoundException
{
160 incrementValue(event
, quark
, timestamp
);
162 ITmfStateValue value
= getValue(event
);
163 processValue(quark
, timestamp
, value
);
168 protected void processValue(int quark
, long timestamp
, ITmfStateValue value
) throws AttributeNotFoundException
, TimeRangeException
, StateValueTypeException
{
169 switch (getStackType()) {
171 getStateSystem().popAttribute(timestamp
, quark
);
174 getStateSystem().pushAttribute(timestamp
, value
, quark
);
179 getStateSystem().modifyAttribute(timestamp
, value
, quark
);
185 protected void incrementValue(ITmfEvent event
, int quark
, long timestamp
) throws StateValueTypeException
, TimeRangeException
, AttributeNotFoundException
{
186 getStateSystem().incrementAttribute(timestamp
, quark
);
190 /* This state value uses a constant value, defined in the XML */
191 private class TmfXmlStateValueTmf
extends TmfXmlStateValueTypeReadWrite
{
193 private final ITmfStateValue fValue
;
195 public TmfXmlStateValueTmf(ITmfStateValue value
) {
200 public ITmfStateValue
getValue(ITmfEvent event
) {
205 public void incrementValue(ITmfEvent event
, int quark
, long timestamp
) throws StateValueTypeException
, TimeRangeException
, AttributeNotFoundException
{
206 ITmfStateSystem ss
= getStateSystem();
207 switch (fValue
.getType()) {
209 long incrementLong
= fValue
.unboxLong();
210 ITmfStateValue currentState
= ss
.queryOngoingState(quark
);
211 long currentValue
= (currentState
.isNull() ?
0 : currentState
.unboxLong());
212 ITmfStateValue value
= TmfStateValue
.newValueLong(incrementLong
+ currentValue
);
213 processValue(quark
, timestamp
, value
);
217 int increment
= fValue
.unboxInt();
218 ITmfStateValue currentState
= ss
.queryOngoingState(quark
);
219 int currentValue
= (currentState
.isNull() ?
0 : currentState
.unboxInt());
220 ITmfStateValue value
= TmfStateValue
.newValueInt(increment
+ currentValue
);
221 processValue(quark
, timestamp
, value
);
228 Activator
.logWarning("TmfXmlStateValue: The increment value is not a number type"); //$NON-NLS-1$
234 /* The state value uses the value of an event field */
235 private class TmfXmlStateValueEventField
extends TmfXmlStateValueTypeReadWrite
{
237 private final String fFieldName
;
239 public TmfXmlStateValueEventField(String field
) {
244 public ITmfStateValue
getValue(ITmfEvent event
) {
246 Activator
.logWarning("XML State value: requested an event field, but event is null"); //$NON-NLS-1$
247 return TmfStateValue
.nullValue();
249 return getEventFieldValue(event
, fFieldName
);
253 public void incrementValue(ITmfEvent event
, int quark
, long timestamp
) throws StateValueTypeException
, TimeRangeException
, AttributeNotFoundException
{
254 ITmfStateSystem ss
= getSsContainer().getStateSystem();
255 ITmfStateValue incrementValue
= getValue(event
);
256 switch (incrementValue
.getType()) {
258 int increment
= incrementValue
.unboxInt();
259 int currentValue
= ss
.queryOngoingState(quark
).unboxInt();
260 ITmfStateValue value
= TmfStateValue
.newValueInt(increment
+ currentValue
);
261 processValue(quark
, timestamp
, value
);
265 long incrementLong
= incrementValue
.unboxLong();
266 long currentValue
= ss
.queryOngoingState(quark
).unboxLong();
267 ITmfStateValue value
= TmfStateValue
.newValueLong(incrementLong
+ currentValue
);
268 processValue(quark
, timestamp
, value
);
275 Activator
.logWarning(String
.format("TmfXmlStateValue: The event field increment %s is not a number type but a %s", fFieldName
, incrementValue
.getType())); //$NON-NLS-1$
281 /* The state value is the event name */
282 private class TmfXmlStateValueEventName
extends TmfXmlStateValueTypeReadWrite
{
285 public ITmfStateValue
getValue(ITmfEvent event
) {
287 Activator
.logWarning("XML State value: request event name, but event is null"); //$NON-NLS-1$
288 return TmfStateValue
.nullValue();
290 return TmfStateValue
.newValueString(event
.getType().getName());
295 /* The state value deletes an attribute */
296 private class TmfXmlStateValueDelete
extends TmfXmlStateValueTypeReadWrite
{
299 public ITmfStateValue
getValue(ITmfEvent event
) throws AttributeNotFoundException
{
300 return TmfStateValue
.nullValue();
304 protected void processValue(int quark
, long timestamp
, ITmfStateValue value
) throws TimeRangeException
, AttributeNotFoundException
{
305 ITmfStateSystem ss
= getStateSystem();
306 if (!(ss
instanceof ITmfStateSystemBuilder
)) {
307 throw new IllegalStateException("incrementValue should never be called when not building the state system"); //$NON-NLS-1$
309 ITmfStateSystemBuilder builder
= (ITmfStateSystemBuilder
) ss
;
310 builder
.removeAttribute(timestamp
, quark
);
315 /* The state value uses the result of a query */
316 private class TmfXmlStateValueQuery
extends TmfXmlStateValueTypeReadWrite
{
318 private final List
<ITmfXmlStateAttribute
> fQueryValue
;
320 public TmfXmlStateValueQuery(List
<ITmfXmlStateAttribute
> childAttributes
) {
321 fQueryValue
= childAttributes
;
325 public ITmfStateValue
getValue(ITmfEvent event
) throws AttributeNotFoundException
{
326 /* Query the state system for the value */
327 ITmfStateValue value
= TmfStateValue
.nullValue();
328 int quarkQuery
= IXmlStateSystemContainer
.ROOT_QUARK
;
329 ITmfStateSystem ss
= getStateSystem();
331 for (ITmfXmlStateAttribute attribute
: fQueryValue
) {
332 quarkQuery
= attribute
.getAttributeQuark(event
, quarkQuery
);
333 if (quarkQuery
== IXmlStateSystemContainer
.ERROR_QUARK
) {
334 /* the query is not valid, we stop the state change */
339 * the query can fail : for example, if a value is requested but has
342 if (quarkQuery
!= IXmlStateSystemContainer
.ERROR_QUARK
) {
343 value
= ss
.queryOngoingState(quarkQuery
);
349 public void incrementValue(ITmfEvent event
, int quark
, long timestamp
) throws StateValueTypeException
, TimeRangeException
, AttributeNotFoundException
{
350 ITmfStateSystem ss
= getStateSystem();
351 ITmfStateValue incrementValue
= getValue(event
);
352 switch (incrementValue
.getType()) {
354 int increment
= incrementValue
.unboxInt();
355 int currentValue
= ss
.queryOngoingState(quark
).unboxInt();
356 ITmfStateValue value
= TmfStateValue
.newValueInt(increment
+ currentValue
);
357 processValue(quark
, timestamp
, value
);
361 long incrementLong
= incrementValue
.unboxLong();
362 long currentValue
= ss
.queryOngoingState(quark
).unboxLong();
363 ITmfStateValue value
= TmfStateValue
.newValueLong(incrementLong
+ currentValue
);
364 processValue(quark
, timestamp
, value
);
371 Activator
.logWarning("TmfXmlStateValue: The query result increment is not a number type"); //$NON-NLS-1$