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
.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
.linuxtools
.statesystem
.core
.exceptions
.AttributeNotFoundException
;
20 import org
.eclipse
.linuxtools
.statesystem
.core
.exceptions
.StateValueTypeException
;
21 import org
.eclipse
.linuxtools
.statesystem
.core
.exceptions
.TimeRangeException
;
22 import org
.eclipse
.linuxtools
.tmf
.analysis
.xml
.core
.module
.IXmlStateSystemContainer
;
23 import org
.eclipse
.linuxtools
.tmf
.analysis
.xml
.core
.module
.XmlUtils
;
24 import org
.eclipse
.linuxtools
.tmf
.analysis
.xml
.core
.stateprovider
.TmfXmlStrings
;
25 import org
.eclipse
.linuxtools
.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
);
113 /* Interface for both private classes to handle the event */
114 private interface IXmlStateChange
{
115 void handleEvent(@NonNull ITmfEvent event
) throws AttributeNotFoundException
, StateValueTypeException
, TimeRangeException
;
119 * Conditional state change with a condition to verify
121 private class XmlConditionalChange
implements IXmlStateChange
{
122 private final TmfXmlCondition fCondition
;
123 private final TmfXmlStateChange fThenChange
;
124 private final TmfXmlStateChange fElseChange
;
126 public XmlConditionalChange(ITmfXmlModelFactory modelFactory
, Element statechange
) {
128 * The if node exists, it has been verified before calling this
130 Node ifNode
= statechange
.getElementsByTagName(TmfXmlStrings
.IF
).item(0);
131 fCondition
= modelFactory
.createCondition((Element
) ifNode
, fContainer
);
133 Node thenNode
= statechange
.getElementsByTagName(TmfXmlStrings
.THEN
).item(0);
134 if (thenNode
== null) {
135 throw new IllegalArgumentException("Conditional state change: there should be a then clause."); //$NON-NLS-1$
137 fThenChange
= modelFactory
.createStateChange((Element
) thenNode
, fContainer
);
139 Node elseNode
= statechange
.getElementsByTagName(TmfXmlStrings
.ELSE
).item(0);
140 if (elseNode
!= null) {
141 fElseChange
= modelFactory
.createStateChange((Element
) elseNode
, fContainer
);
148 public void handleEvent(@NonNull ITmfEvent event
) throws AttributeNotFoundException
, StateValueTypeException
, TimeRangeException
{
149 TmfXmlStateChange toExecute
= fThenChange
;
151 if (!fCondition
.testForEvent(event
)) {
152 toExecute
= fElseChange
;
154 } catch (AttributeNotFoundException e
) {
156 * An attribute in the condition did not exist (yet), return
157 * from the state change
162 if (toExecute
== null) {
165 toExecute
.handleEvent(event
);
170 * State change with no condition
172 private class XmlStateValueChange
implements IXmlStateChange
{
173 private final ITmfXmlStateValue fValue
;
175 public XmlStateValueChange(ITmfXmlModelFactory modelFactory
, Element statechange
) {
176 List
<Element
> childElements
= XmlUtils
.getChildElements(statechange
);
179 * Last child element is the state value, the others are attributes
180 * to reach to value to set
182 Element stateValueElement
= childElements
.remove(childElements
.size() - 1);
183 List
<ITmfXmlStateAttribute
> attributes
= new ArrayList
<>();
184 for (Element element
: childElements
) {
185 if (!element
.getNodeName().equals(TmfXmlStrings
.STATE_ATTRIBUTE
)) {
186 throw new IllegalArgumentException("TmfXmlStateChange: a state change must have only TmfXmlStateAttribute elements before the state value"); //$NON-NLS-1$
188 ITmfXmlStateAttribute attribute
= modelFactory
.createStateAttribute(element
, fContainer
);
189 attributes
.add(attribute
);
191 if (attributes
.isEmpty()) {
192 throw new IllegalArgumentException("TmfXmlStateChange: a state change must have at least one TmfXmlStateAttribute element before the state value"); //$NON-NLS-1$
194 fValue
= modelFactory
.createStateValue(stateValueElement
, fContainer
, attributes
);
198 public void handleEvent(@NonNull ITmfEvent event
) throws AttributeNotFoundException
, StateValueTypeException
, TimeRangeException
{
199 fValue
.handleEvent(event
);