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
.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
.StateSystemBuilderUtils
;
23 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.AttributeNotFoundException
;
24 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.StateValueTypeException
;
25 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.TimeRangeException
;
26 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.ITmfStateValue
;
27 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.TmfStateValue
;
28 import org
.eclipse
.tracecompass
.tmf
.analysis
.xml
.core
.model
.ITmfXmlModelFactory
;
29 import org
.eclipse
.tracecompass
.tmf
.analysis
.xml
.core
.model
.ITmfXmlStateAttribute
;
30 import org
.eclipse
.tracecompass
.tmf
.analysis
.xml
.core
.model
.TmfXmlStateValue
;
31 import org
.eclipse
.tracecompass
.tmf
.analysis
.xml
.core
.module
.IXmlStateSystemContainer
;
32 import org
.eclipse
.tracecompass
.tmf
.analysis
.xml
.core
.module
.XmlUtils
;
33 import org
.eclipse
.tracecompass
.tmf
.analysis
.xml
.core
.stateprovider
.TmfXmlStrings
;
34 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEvent
;
35 import org
.w3c
.dom
.Element
;
38 * Implements a state value in a read write mode. See {@link TmfXmlStateValue}
39 * for the syntax of the state value.
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
44 * @author Geneviève Bastien
46 public class TmfXmlReadWriteStateValue
extends TmfXmlStateValue
{
48 private static final String ILLEGAL_STATE_EXCEPTION_MESSAGE
= "The state system hasn't been initialized yet"; //$NON-NLS-1$
51 * Constructor where the path to the value is a list of state attributes
54 * The factory used to create XML model elements
56 * The state value XML element
58 * The state system container this state value belongs to
60 * The attributes representing the path to this value
62 public TmfXmlReadWriteStateValue(TmfXmlReadWriteModelFactory modelFactory
, Element node
, IXmlStateSystemContainer container
, List
<ITmfXmlStateAttribute
> attributes
) {
63 this(modelFactory
, node
, container
, attributes
, null);
67 * Constructor where the path to the value is an event field
70 * The factory used to create XML model elements
72 * The state value XML element
74 * The state system container this state value belongs to
76 * The event field where to get the value
78 public TmfXmlReadWriteStateValue(TmfXmlReadWriteModelFactory modelFactory
, Element node
, IXmlStateSystemContainer container
, String eventField
) {
79 this(modelFactory
, node
, container
, new ArrayList
<ITmfXmlStateAttribute
>(), eventField
);
82 private TmfXmlReadWriteStateValue(ITmfXmlModelFactory modelFactory
, Element node
, IXmlStateSystemContainer container
, List
<ITmfXmlStateAttribute
> attributes
, @Nullable String eventField
) {
83 super(modelFactory
, node
, container
, attributes
, eventField
);
87 protected @Nullable ITmfStateSystemBuilder
getStateSystem() {
88 return (ITmfStateSystemBuilder
) super.getStateSystem();
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
));
98 throw new IllegalStateException();
102 case TmfXmlStrings
.TYPE_INT
: {
104 ITmfStateValue stateValue
= TmfStateValue
.newValueInt(Integer
.parseInt(value
));
105 stateValueType
= new TmfXmlStateValueTmf(stateValue
);
108 case TmfXmlStrings
.TYPE_LONG
: {
110 ITmfStateValue stateValue
= TmfStateValue
.newValueLong(Long
.parseLong(value
));
111 stateValueType
= new TmfXmlStateValueTmf(stateValue
);
114 case TmfXmlStrings
.TYPE_STRING
: {
116 ITmfStateValue stateValue
= TmfStateValue
.newValueString(value
);
117 stateValueType
= new TmfXmlStateValueTmf(stateValue
);
120 case TmfXmlStrings
.TYPE_NULL
: {
122 ITmfStateValue stateValue
= TmfStateValue
.nullValue();
123 stateValueType
= new TmfXmlStateValueTmf(stateValue
);
126 case TmfXmlStrings
.EVENT_FIELD
:
128 stateValueType
= new TmfXmlStateValueEventField(value
);
130 case TmfXmlStrings
.TYPE_EVENT_NAME
:
131 /* The value is the event name */
132 stateValueType
= new TmfXmlStateValueEventName();
134 case TmfXmlStrings
.TYPE_DELETE
:
135 /* Deletes the value of an attribute */
136 stateValueType
= new TmfXmlStateValueDelete();
138 case TmfXmlStrings
.TYPE_QUERY
:
139 /* Value is the result of a query */
140 List
<@Nullable Element
> children
= XmlUtils
.getChildElements(node
);
141 List
<ITmfXmlStateAttribute
> childAttributes
= new ArrayList
<>();
142 for (Element child
: children
) {
146 ITmfXmlStateAttribute queryAttribute
= modelFactory
.createStateAttribute(child
, getSsContainer());
147 childAttributes
.add(queryAttribute
);
149 stateValueType
= new TmfXmlStateValueQuery(childAttributes
);
152 throw new IllegalArgumentException(String
.format("TmfXmlStateValue constructor: unexpected element %s for stateValue type", type
)); //$NON-NLS-1$
154 return stateValueType
;
157 // ----------------------------------------------------------
158 // Internal state value classes for the different types
159 // ----------------------------------------------------------
162 * Base class for all state value. Contain default methods to handle event,
163 * process or increment the value
165 protected abstract class TmfXmlStateValueTypeReadWrite
extends TmfXmlStateValueBase
{
168 public final void handleEvent(ITmfEvent event
, int quark
, long timestamp
) throws StateValueTypeException
, TimeRangeException
, AttributeNotFoundException
{
170 incrementValue(event
, quark
, timestamp
);
172 ITmfStateValue value
= getValue(event
);
173 processValue(quark
, timestamp
, value
);
178 protected void processValue(int quark
, long timestamp
, ITmfStateValue value
) throws AttributeNotFoundException
, TimeRangeException
, StateValueTypeException
{
179 ITmfStateSystemBuilder ss
= getStateSystem();
181 throw new IllegalStateException(ILLEGAL_STATE_EXCEPTION_MESSAGE
);
183 switch (getStackType()) {
185 ss
.popAttribute(timestamp
, quark
);
188 ss
.pushAttribute(timestamp
, value
, quark
);
193 ss
.modifyAttribute(timestamp
, value
, quark
);
199 protected void incrementValue(ITmfEvent event
, int quark
, long timestamp
) throws StateValueTypeException
, TimeRangeException
, AttributeNotFoundException
{
200 ITmfStateSystemBuilder ss
= getStateSystem();
202 throw new IllegalStateException(ILLEGAL_STATE_EXCEPTION_MESSAGE
);
204 StateSystemBuilderUtils
.incrementAttributeInt(ss
, timestamp
, quark
, 1);
208 private static @Nullable ITmfStateValue
incrementByType(int quark
, ITmfStateSystem ss
, ITmfStateValue stateValue
) throws AttributeNotFoundException
{
209 ITmfStateValue value
= null;
210 switch (stateValue
.getType()) {
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
);
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
);
233 /* This state value uses a constant value, defined in the XML */
234 private class TmfXmlStateValueTmf
extends TmfXmlStateValueTypeReadWrite
{
236 private final ITmfStateValue fValue
;
238 public TmfXmlStateValueTmf(ITmfStateValue value
) {
243 public ITmfStateValue
getValue(@Nullable ITmfEvent event
) {
248 public void incrementValue(ITmfEvent event
, int quark
, long timestamp
) throws StateValueTypeException
, TimeRangeException
, AttributeNotFoundException
{
249 ITmfStateSystem ss
= getStateSystem();
251 throw new IllegalStateException(ILLEGAL_STATE_EXCEPTION_MESSAGE
);
253 ITmfStateValue value
= incrementByType(quark
, ss
, fValue
);
255 processValue(quark
, timestamp
, value
);
257 Activator
.logWarning("TmfXmlStateValue: The increment value is not a number type"); //$NON-NLS-1$
262 public String
toString() {
263 return "Value=" + fValue
; //$NON-NLS-1$
268 /* The state value uses the value of an event field */
269 private class TmfXmlStateValueEventField
extends TmfXmlStateValueTypeReadWrite
{
271 private final String fFieldName
;
273 public TmfXmlStateValueEventField(String field
) {
278 public ITmfStateValue
getValue(@Nullable ITmfEvent event
) {
280 Activator
.logWarning("XML State value: requested an event field, but event is null"); //$NON-NLS-1$
281 return TmfStateValue
.nullValue();
283 return getEventFieldValue(event
, fFieldName
);
287 public void incrementValue(ITmfEvent event
, int quark
, long timestamp
) throws StateValueTypeException
, TimeRangeException
, AttributeNotFoundException
{
288 ITmfStateSystem ss
= getSsContainer().getStateSystem();
290 throw new IllegalStateException(ILLEGAL_STATE_EXCEPTION_MESSAGE
);
292 ITmfStateValue incrementValue
= getValue(event
);
293 ITmfStateValue value
= incrementByType(quark
, ss
, incrementValue
);
295 processValue(quark
, timestamp
, value
);
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$
302 public String
toString() {
303 return "Event Field=" + fFieldName
; //$NON-NLS-1$
307 /* The state value is the event name */
308 private class TmfXmlStateValueEventName
extends TmfXmlStateValueTypeReadWrite
{
311 public ITmfStateValue
getValue(@Nullable ITmfEvent event
) {
313 Activator
.logWarning("XML State value: request event name, but event is null"); //$NON-NLS-1$
314 return TmfStateValue
.nullValue();
316 return TmfStateValue
.newValueString(event
.getName());
320 public String
toString() {
321 return "Event name"; //$NON-NLS-1$
326 /* The state value deletes an attribute */
327 private class TmfXmlStateValueDelete
extends TmfXmlStateValueTypeReadWrite
{
330 public ITmfStateValue
getValue(@Nullable ITmfEvent event
) throws AttributeNotFoundException
{
331 return TmfStateValue
.nullValue();
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$
340 ITmfStateSystemBuilder builder
= (ITmfStateSystemBuilder
) ss
;
341 builder
.removeAttribute(timestamp
, quark
);
345 public String
toString() {
346 return "Delete"; //$NON-NLS-1$
350 /* The state value uses the result of a query */
351 private class TmfXmlStateValueQuery
extends TmfXmlStateValueTypeReadWrite
{
353 private final List
<ITmfXmlStateAttribute
> fQueryValue
;
355 public TmfXmlStateValueQuery(List
<ITmfXmlStateAttribute
> childAttributes
) {
356 fQueryValue
= childAttributes
;
360 public ITmfStateValue
getValue(@Nullable ITmfEvent event
) throws AttributeNotFoundException
{
361 /* Query the state system for the value */
362 ITmfStateValue value
= TmfStateValue
.nullValue();
363 int quarkQuery
= IXmlStateSystemContainer
.ROOT_QUARK
;
364 ITmfStateSystem ss
= getStateSystem();
366 throw new IllegalStateException(ILLEGAL_STATE_EXCEPTION_MESSAGE
);
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 */
377 * the query can fail : for example, if a value is requested but has
380 if (quarkQuery
!= IXmlStateSystemContainer
.ERROR_QUARK
) {
381 value
= ss
.queryOngoingState(quarkQuery
);
383 throw new IllegalStateException();
390 public void incrementValue(ITmfEvent event
, int quark
, long timestamp
) throws StateValueTypeException
, TimeRangeException
, AttributeNotFoundException
{
391 ITmfStateSystem ss
= getStateSystem();
393 throw new IllegalStateException(ILLEGAL_STATE_EXCEPTION_MESSAGE
);
396 ITmfStateValue incrementValue
= getValue(event
);
397 ITmfStateValue value
= incrementByType(quark
, ss
, incrementValue
);
399 processValue(quark
, timestamp
, value
);
401 Activator
.logWarning("TmfXmlStateValue: The query result increment is not a number type"); //$NON-NLS-1$
406 public String
toString() {
407 return "Query=" + fQueryValue
; //$NON-NLS-1$