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
.linuxtools
.internal
.tmf
.analysis
.xml
.core
.stateprovider
.model
;
15 import java
.util
.ArrayList
;
16 import java
.util
.List
;
18 import org
.eclipse
.jdt
.annotation
.NonNull
;
19 import org
.eclipse
.linuxtools
.tmf
.analysis
.xml
.core
.module
.XmlUtils
;
20 import org
.eclipse
.linuxtools
.tmf
.analysis
.xml
.core
.stateprovider
.TmfXmlStrings
;
21 import org
.eclipse
.linuxtools
.tmf
.analysis
.xml
.core
.stateprovider
.XmlStateProvider
;
22 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEvent
;
23 import org
.eclipse
.linuxtools
.tmf
.core
.exceptions
.AttributeNotFoundException
;
24 import org
.eclipse
.linuxtools
.tmf
.core
.exceptions
.StateValueTypeException
;
25 import org
.eclipse
.linuxtools
.tmf
.core
.exceptions
.TimeRangeException
;
26 import org
.w3c
.dom
.Element
;
27 import org
.w3c
.dom
.Node
;
30 * This Class implement a State Change in the XML state provider
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 XmlStateProvider fProvider
;
73 * XML node root of this state change
75 * The state provider this state change belongs to
77 public TmfXmlStateChange(Element statechange
, XmlStateProvider provider
) {
81 * child nodes is either a list of TmfXmlStateAttributes and
82 * TmfXmlStateValues, or an if-then-else series of nodes.
84 Node ifNode
= statechange
.getElementsByTagName(TmfXmlStrings
.IF
).item(0);
86 /* the state change has a condition */
87 fChange
= new XmlConditionalChange(statechange
);
89 /* the state change does not have a condition */
90 fChange
= new XmlStateValueChange(statechange
);
95 * Execute the state change for an event. If necessary, it validates the
96 * condition and executes the required change.
99 * The event to process
100 * @throws AttributeNotFoundException
101 * Pass through the exception it received
102 * @throws TimeRangeException
103 * Pass through the exception it received
104 * @throws StateValueTypeException
105 * Pass through the exception it received
107 public void handleEvent(@NonNull ITmfEvent event
) throws AttributeNotFoundException
, StateValueTypeException
, TimeRangeException
{
108 fChange
.handleEvent(event
);
111 /* Interface for both private classes to handle the event */
112 private interface IXmlStateChange
{
113 void handleEvent(@NonNull ITmfEvent event
) throws AttributeNotFoundException
, StateValueTypeException
, TimeRangeException
;
117 * Conditional state change with a condition to verify
119 private class XmlConditionalChange
implements IXmlStateChange
{
120 private final TmfXmlCondition fCondition
;
121 private final TmfXmlStateChange fThenChange
;
122 private final TmfXmlStateChange fElseChange
;
124 public XmlConditionalChange(Element statechange
) {
126 * The if node exists, it has been verified before calling this
128 Node ifNode
= statechange
.getElementsByTagName(TmfXmlStrings
.IF
).item(0);
129 fCondition
= new TmfXmlCondition((Element
) ifNode
, fProvider
);
131 Node thenNode
= statechange
.getElementsByTagName(TmfXmlStrings
.THEN
).item(0);
132 if (thenNode
== null) {
133 throw new IllegalArgumentException("Conditional state change: there should be a then clause."); //$NON-NLS-1$
135 fThenChange
= new TmfXmlStateChange((Element
) thenNode
, fProvider
);
137 Node elseNode
= statechange
.getElementsByTagName(TmfXmlStrings
.ELSE
).item(0);
138 if (elseNode
!= null) {
139 fElseChange
= new TmfXmlStateChange((Element
) elseNode
, fProvider
);
146 public void handleEvent(ITmfEvent event
) throws AttributeNotFoundException
, StateValueTypeException
, TimeRangeException
{
147 TmfXmlStateChange toExecute
= fThenChange
;
149 if (!fCondition
.testForEvent(event
)) {
150 toExecute
= fElseChange
;
152 } catch (AttributeNotFoundException e
) {
154 * An attribute in the condition did not exist (yet), return
155 * from the state change
160 if (toExecute
== null) {
163 toExecute
.handleEvent(event
);
168 * State change with no condition
170 private class XmlStateValueChange
implements IXmlStateChange
{
171 private final TmfXmlStateValue fValue
;
173 public XmlStateValueChange(Element statechange
) {
174 List
<Element
> childElements
= XmlUtils
.getChildElements(statechange
);
177 * Last child element is the state value, the others are attributes
178 * to reach to value to set
180 Element stateValueElement
= childElements
.remove(childElements
.size() - 1);
181 List
<TmfXmlStateAttribute
> attributes
= new ArrayList
<>();
182 for (Element element
: childElements
) {
183 if (!element
.getNodeName().equals(TmfXmlStrings
.STATE_ATTRIBUTE
)) {
184 throw new IllegalArgumentException("TmfXmlStateChange: a state change must have only TmfXmlStateAttribute elements before the state value"); //$NON-NLS-1$
186 TmfXmlStateAttribute attribute
= new TmfXmlStateAttribute(element
, fProvider
);
187 attributes
.add(attribute
);
189 if (attributes
.isEmpty()) {
190 throw new IllegalArgumentException("TmfXmlStateChange: a state change must have at least one TmfXmlStateAttribute element before the state value"); //$NON-NLS-1$
192 fValue
= new TmfXmlStateValue(stateValueElement
, fProvider
, attributes
);
196 public void handleEvent(ITmfEvent event
) throws AttributeNotFoundException
, StateValueTypeException
, TimeRangeException
{
197 fValue
.handleEvent(event
);