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
.tracecompass
.statesystem
.core
.exceptions
.AttributeNotFoundException
;
20 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.StateValueTypeException
;
21 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.TimeRangeException
;
22 import org
.eclipse
.tracecompass
.tmf
.analysis
.xml
.core
.module
.IXmlStateSystemContainer
;
23 import org
.eclipse
.tracecompass
.tmf
.analysis
.xml
.core
.module
.XmlUtils
;
24 import org
.eclipse
.tracecompass
.tmf
.analysis
.xml
.core
.stateprovider
.TmfXmlStrings
;
25 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEvent
;
26 import org
.w3c
.dom
.Element
;
27 import org
.w3c
.dom
.Node
;
30 * This Class implement a State Change in the XML-defined state system
33 * example 1: Simple state change
35 * <stateAttribute type="location" value="CurrentThread" />
36 * <stateAttribute type="constant" value="System_call" />
37 * <stateValue type="null" />
40 * example 2: Conditional state change
44 * <stateAttribute type="location" value="CurrentThread" />
45 * <stateAttribute type="constant" value="System_call" />
46 * <stateValue type="null" />
50 * <stateAttribute type="location" value="CurrentThread" />
51 * <stateAttribute type="constant" value="Status" />
52 * <stateValue int="$PROCESS_STATUS_RUN_USERMODE"/>
55 * <stateAttribute type="location" value="CurrentThread" />
56 * <stateAttribute type="constant" value="Status" />
57 * <stateValue int="$PROCESS_STATUS_RUN_SYSCALL"/>
62 * @author Florian Wininger
64 public class TmfXmlStateChange
{
66 private final IXmlStateChange fChange
;
67 private final IXmlStateSystemContainer fContainer
;
73 * The factory used to create XML model elements
75 * XML node root of this state change
77 * The state system container this state change belongs to
79 public TmfXmlStateChange(ITmfXmlModelFactory modelFactory
, Element statechange
, IXmlStateSystemContainer container
) {
80 fContainer
= container
;
83 * child nodes is either a list of TmfXmlStateAttributes and
84 * TmfXmlStateValues, or an if-then-else series of nodes.
86 Node ifNode
= statechange
.getElementsByTagName(TmfXmlStrings
.IF
).item(0);
88 /* the state change has a condition */
89 fChange
= new XmlConditionalChange(modelFactory
, statechange
);
91 /* the state change does not have a condition */
92 fChange
= new XmlStateValueChange(modelFactory
, statechange
);
97 * Execute the state change for an event. If necessary, it validates the
98 * condition and executes the required change.
101 * The event to process
102 * @throws AttributeNotFoundException
103 * Pass through the exception it received
104 * @throws TimeRangeException
105 * Pass through the exception it received
106 * @throws StateValueTypeException
107 * Pass through the exception it received
109 public void handleEvent(@NonNull ITmfEvent event
) throws AttributeNotFoundException
, StateValueTypeException
, TimeRangeException
{
110 fChange
.handleEvent(event
);
114 public String
toString() {
115 return "TmfXmlStateChange: " + fChange
; //$NON-NLS-1$
118 /* Interface for both private classes to handle the event */
119 private interface IXmlStateChange
{
120 void handleEvent(@NonNull ITmfEvent event
) throws AttributeNotFoundException
, StateValueTypeException
, TimeRangeException
;
124 * Conditional state change with a condition to verify
126 private class XmlConditionalChange
implements IXmlStateChange
{
127 private final TmfXmlCondition fCondition
;
128 private final TmfXmlStateChange fThenChange
;
129 private final TmfXmlStateChange fElseChange
;
131 public XmlConditionalChange(ITmfXmlModelFactory modelFactory
, Element statechange
) {
133 * The if node exists, it has been verified before calling this
135 Node ifNode
= statechange
.getElementsByTagName(TmfXmlStrings
.IF
).item(0);
136 fCondition
= modelFactory
.createCondition((Element
) ifNode
, fContainer
);
138 Node thenNode
= statechange
.getElementsByTagName(TmfXmlStrings
.THEN
).item(0);
139 if (thenNode
== null) {
140 throw new IllegalArgumentException("Conditional state change: there should be a then clause."); //$NON-NLS-1$
142 fThenChange
= modelFactory
.createStateChange((Element
) thenNode
, fContainer
);
144 Node elseNode
= statechange
.getElementsByTagName(TmfXmlStrings
.ELSE
).item(0);
145 if (elseNode
!= null) {
146 fElseChange
= modelFactory
.createStateChange((Element
) elseNode
, fContainer
);
153 public void handleEvent(@NonNull ITmfEvent event
) throws AttributeNotFoundException
, StateValueTypeException
, TimeRangeException
{
154 TmfXmlStateChange toExecute
= fThenChange
;
156 if (!fCondition
.testForEvent(event
)) {
157 toExecute
= fElseChange
;
159 } catch (AttributeNotFoundException e
) {
161 * An attribute in the condition did not exist (yet), return
162 * from the state change
167 if (toExecute
== null) {
170 toExecute
.handleEvent(event
);
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
<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 List
<ITmfXmlStateAttribute
> attributes
= new ArrayList
<>();
194 for (Element element
: childElements
) {
195 if (!element
.getNodeName().equals(TmfXmlStrings
.STATE_ATTRIBUTE
)) {
196 throw new IllegalArgumentException("TmfXmlStateChange: a state change must have only TmfXmlStateAttribute elements before the state value"); //$NON-NLS-1$
198 ITmfXmlStateAttribute attribute
= modelFactory
.createStateAttribute(element
, fContainer
);
199 attributes
.add(attribute
);
201 if (attributes
.isEmpty()) {
202 throw new IllegalArgumentException("TmfXmlStateChange: a state change must have at least one TmfXmlStateAttribute element before the state value"); //$NON-NLS-1$
204 fValue
= modelFactory
.createStateValue(stateValueElement
, fContainer
, attributes
);
208 public void handleEvent(@NonNull ITmfEvent event
) throws AttributeNotFoundException
, StateValueTypeException
, TimeRangeException
{
209 fValue
.handleEvent(event
);
213 public String
toString() {
214 return "Value: " + fValue
; //$NON-NLS-1$