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 * @throws AttributeNotFoundException
104 * Pass through the exception it received
105 * @throws TimeRangeException
106 * Pass through the exception it received
107 * @throws StateValueTypeException
108 * Pass through the exception it received
110 public void handleEvent(ITmfEvent event
) throws AttributeNotFoundException
, StateValueTypeException
, TimeRangeException
{
111 fChange
.handleEvent(event
);
115 public String
toString() {
116 return "TmfXmlStateChange: " + fChange
; //$NON-NLS-1$
119 /* Interface for both private classes to handle the event */
120 private interface IXmlStateChange
{
121 void handleEvent(ITmfEvent event
) throws AttributeNotFoundException
, StateValueTypeException
, TimeRangeException
;
125 * Conditional state change with a condition to verify
127 private class XmlConditionalChange
implements IXmlStateChange
{
128 private final TmfXmlCondition fCondition
;
129 private final TmfXmlStateChange fThenChange
;
130 private final @Nullable TmfXmlStateChange fElseChange
;
132 public XmlConditionalChange(ITmfXmlModelFactory modelFactory
, Element statechange
) {
134 * The if node exists, it has been verified before calling this
136 Node ifNode
= statechange
.getElementsByTagName(TmfXmlStrings
.IF
).item(0);
137 if (ifNode
== null) {
138 throw new IllegalArgumentException();
140 fCondition
= modelFactory
.createCondition((Element
) ifNode
, fContainer
);
142 Node thenNode
= statechange
.getElementsByTagName(TmfXmlStrings
.THEN
).item(0);
143 if (thenNode
== null) {
144 throw new IllegalArgumentException("Conditional state change: there should be a then clause."); //$NON-NLS-1$
146 fThenChange
= modelFactory
.createStateChange((Element
) thenNode
, fContainer
);
148 Node elseNode
= statechange
.getElementsByTagName(TmfXmlStrings
.ELSE
).item(0);
149 if (elseNode
!= null) {
150 fElseChange
= modelFactory
.createStateChange((Element
) elseNode
, fContainer
);
157 public void handleEvent(@NonNull ITmfEvent event
) throws AttributeNotFoundException
, StateValueTypeException
, TimeRangeException
{
158 TmfXmlStateChange toExecute
= fThenChange
;
160 if (!fCondition
.testForEvent(event
)) {
161 toExecute
= fElseChange
;
163 } catch (AttributeNotFoundException e
) {
165 * An attribute in the condition did not exist (yet), return
166 * from the state change
171 if (toExecute
== null) {
174 toExecute
.handleEvent(event
);
178 public String
toString() {
179 return "Condition: " + fCondition
; //$NON-NLS-1$
184 * State change with no condition
186 private class XmlStateValueChange
implements IXmlStateChange
{
187 private final ITmfXmlStateValue fValue
;
189 public XmlStateValueChange(ITmfXmlModelFactory modelFactory
, Element statechange
) {
190 List
<@Nullable Element
> childElements
= XmlUtils
.getChildElements(statechange
);
193 * Last child element is the state value, the others are attributes
194 * to reach to value to set
196 Element stateValueElement
= childElements
.remove(childElements
.size() - 1);
197 if (stateValueElement
== null) {
198 throw new IllegalStateException();
200 List
<ITmfXmlStateAttribute
> attributes
= new ArrayList
<>();
201 for (Element element
: childElements
) {
202 if (element
== null || !element
.getNodeName().equals(TmfXmlStrings
.STATE_ATTRIBUTE
)) {
203 throw new IllegalArgumentException("TmfXmlStateChange: a state change must have only TmfXmlStateAttribute elements before the state value"); //$NON-NLS-1$
205 ITmfXmlStateAttribute attribute
= modelFactory
.createStateAttribute(element
, fContainer
);
206 attributes
.add(attribute
);
208 if (attributes
.isEmpty()) {
209 throw new IllegalArgumentException("TmfXmlStateChange: a state change must have at least one TmfXmlStateAttribute element before the state value"); //$NON-NLS-1$
211 fValue
= modelFactory
.createStateValue(stateValueElement
, fContainer
, attributes
);
215 public void handleEvent(@NonNull ITmfEvent event
) throws AttributeNotFoundException
, StateValueTypeException
, TimeRangeException
{
216 fValue
.handleEvent(event
);
220 public String
toString() {
221 return "Value: " + fValue
; //$NON-NLS-1$