1 /*******************************************************************************
2 * Copyright (c) 2014 Ecole Polytechnique de Montreal
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 * Florian Wininger - Initial API and implementation
11 ******************************************************************************/
13 package org
.eclipse
.tracecompass
.tmf
.analysis
.xml
.core
.model
;
15 import java
.util
.ArrayList
;
16 import java
.util
.List
;
18 import org
.eclipse
.jdt
.annotation
.NonNull
;
19 import org
.eclipse
.jdt
.annotation
.Nullable
;
20 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.AttributeNotFoundException
;
21 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.StateValueTypeException
;
22 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.TimeRangeException
;
23 import org
.eclipse
.tracecompass
.tmf
.analysis
.xml
.core
.module
.IXmlStateSystemContainer
;
24 import org
.eclipse
.tracecompass
.tmf
.analysis
.xml
.core
.module
.XmlUtils
;
25 import org
.eclipse
.tracecompass
.tmf
.analysis
.xml
.core
.stateprovider
.TmfXmlStrings
;
26 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEvent
;
27 import org
.w3c
.dom
.Element
;
28 import org
.w3c
.dom
.Node
;
31 * This Class implement a State Change in the XML-defined state system
34 * example 1: Simple state change
36 * <stateAttribute type="location" value="CurrentThread" />
37 * <stateAttribute type="constant" value="System_call" />
38 * <stateValue type="null" />
41 * example 2: Conditional state change
45 * <stateAttribute type="location" value="CurrentThread" />
46 * <stateAttribute type="constant" value="System_call" />
47 * <stateValue type="null" />
51 * <stateAttribute type="location" value="CurrentThread" />
52 * <stateAttribute type="constant" value="Status" />
53 * <stateValue int="$PROCESS_STATUS_RUN_USERMODE"/>
56 * <stateAttribute type="location" value="CurrentThread" />
57 * <stateAttribute type="constant" value="Status" />
58 * <stateValue int="$PROCESS_STATUS_RUN_SYSCALL"/>
63 * @author Florian Wininger
65 public class TmfXmlStateChange
{
67 private final IXmlStateChange fChange
;
68 private final IXmlStateSystemContainer fContainer
;
74 * The factory used to create XML model elements
76 * XML node root of this state change
78 * The state system container this state change belongs to
80 public TmfXmlStateChange(ITmfXmlModelFactory modelFactory
, Element statechange
, IXmlStateSystemContainer container
) {
81 fContainer
= container
;
84 * child nodes is either a list of TmfXmlStateAttributes and
85 * TmfXmlStateValues, or an if-then-else series of nodes.
87 Node ifNode
= statechange
.getElementsByTagName(TmfXmlStrings
.IF
).item(0);
89 /* the state change has a condition */
90 fChange
= new XmlConditionalChange(modelFactory
, statechange
);
92 /* the state change does not have a condition */
93 fChange
= new XmlStateValueChange(modelFactory
, statechange
);
98 * Execute the state change for an event. If necessary, it validates the
99 * condition and executes the required change.
102 * The event to process
103 * @param scenarioInfo
104 * The active scenario details. The value should be null if there
106 * @throws AttributeNotFoundException
107 * Pass through the exception it received
108 * @throws TimeRangeException
109 * Pass through the exception it received
110 * @throws StateValueTypeException
111 * Pass through the exception it received
114 public void handleEvent(ITmfEvent event
, @Nullable TmfXmlScenarioInfo scenarioInfo
) throws AttributeNotFoundException
, StateValueTypeException
, TimeRangeException
{
115 fChange
.handleEvent(event
, scenarioInfo
);
119 public String
toString() {
120 return "TmfXmlStateChange: " + fChange
; //$NON-NLS-1$
123 /* Interface for both private classes to handle the event */
124 private interface IXmlStateChange
{
125 void handleEvent(ITmfEvent event
, @Nullable TmfXmlScenarioInfo scenarioInfo
) throws AttributeNotFoundException
, StateValueTypeException
, TimeRangeException
;
129 * Conditional state change with a condition to verify
131 private class XmlConditionalChange
implements IXmlStateChange
{
132 private final ITmfXmlCondition fCondition
;
133 private final TmfXmlStateChange fThenChange
;
134 private final @Nullable TmfXmlStateChange fElseChange
;
136 public XmlConditionalChange(ITmfXmlModelFactory modelFactory
, Element statechange
) {
138 * The if node exists, it has been verified before calling this
140 Node ifNode
= statechange
.getElementsByTagName(TmfXmlStrings
.IF
).item(0);
141 if (ifNode
== null) {
142 throw new IllegalArgumentException();
144 fCondition
= modelFactory
.createCondition((Element
) ifNode
, fContainer
);
146 Node thenNode
= statechange
.getElementsByTagName(TmfXmlStrings
.THEN
).item(0);
147 if (thenNode
== null) {
148 throw new IllegalArgumentException("Conditional state change: there should be a then clause."); //$NON-NLS-1$
150 fThenChange
= modelFactory
.createStateChange((Element
) thenNode
, fContainer
);
152 Node elseNode
= statechange
.getElementsByTagName(TmfXmlStrings
.ELSE
).item(0);
153 if (elseNode
!= null) {
154 fElseChange
= modelFactory
.createStateChange((Element
) elseNode
, fContainer
);
161 public void handleEvent(@NonNull ITmfEvent event
, @Nullable TmfXmlScenarioInfo scenarioInfo
) throws AttributeNotFoundException
, StateValueTypeException
, TimeRangeException
{
162 TmfXmlStateChange toExecute
= fThenChange
;
163 if (!fCondition
.test(event
, scenarioInfo
)) {
164 toExecute
= fElseChange
;
167 if (toExecute
== null) {
170 toExecute
.handleEvent(event
, scenarioInfo
);
174 public String
toString() {
175 return "Condition: " + fCondition
; //$NON-NLS-1$
180 * State change with no condition
182 private class XmlStateValueChange
implements IXmlStateChange
{
183 private final ITmfXmlStateValue fValue
;
185 public XmlStateValueChange(ITmfXmlModelFactory modelFactory
, Element statechange
) {
186 List
<@Nullable Element
> childElements
= XmlUtils
.getChildElements(statechange
);
189 * Last child element is the state value, the others are attributes
190 * to reach to value to set
192 Element stateValueElement
= childElements
.remove(childElements
.size() - 1);
193 if (stateValueElement
== null) {
194 throw new IllegalStateException();
196 List
<ITmfXmlStateAttribute
> attributes
= new ArrayList
<>();
197 for (Element element
: childElements
) {
198 if (element
== null || !element
.getNodeName().equals(TmfXmlStrings
.STATE_ATTRIBUTE
)) {
199 throw new IllegalArgumentException("TmfXmlStateChange: a state change must have only TmfXmlStateAttribute elements before the state value"); //$NON-NLS-1$
201 ITmfXmlStateAttribute attribute
= modelFactory
.createStateAttribute(element
, fContainer
);
202 attributes
.add(attribute
);
204 if (attributes
.isEmpty()) {
205 throw new IllegalArgumentException("TmfXmlStateChange: a state change must have at least one TmfXmlStateAttribute element before the state value"); //$NON-NLS-1$
207 fValue
= modelFactory
.createStateValue(stateValueElement
, fContainer
, attributes
);
211 public void handleEvent(@NonNull ITmfEvent event
, @Nullable TmfXmlScenarioInfo scenarioInfo
) throws AttributeNotFoundException
, StateValueTypeException
, TimeRangeException
{
212 fValue
.handleEvent(event
, scenarioInfo
);
216 public String
toString() {
217 return "Value: " + fValue
; //$NON-NLS-1$