1 /*******************************************************************************
2 * Copyright (c) 2016 Ecole Polytechnique de Montreal, Ericsson
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
8 ******************************************************************************/
9 package org
.eclipse
.tracecompass
.tmf
.analysis
.xml
.core
.model
;
11 import java
.util
.List
;
13 import org
.eclipse
.jdt
.annotation
.Nullable
;
14 import org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
;
15 import org
.eclipse
.tracecompass
.internal
.tmf
.analysis
.xml
.core
.Activator
;
16 import org
.eclipse
.tracecompass
.internal
.tmf
.analysis
.xml
.core
.pattern
.stateprovider
.XmlPatternStateProvider
;
17 import org
.eclipse
.tracecompass
.statesystem
.core
.ITmfStateSystem
;
18 import org
.eclipse
.tracecompass
.tmf
.analysis
.xml
.core
.module
.IXmlStateSystemContainer
;
19 import org
.eclipse
.tracecompass
.tmf
.analysis
.xml
.core
.module
.XmlUtils
;
20 import org
.eclipse
.tracecompass
.tmf
.analysis
.xml
.core
.stateprovider
.TmfXmlStrings
;
21 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEvent
;
22 import org
.w3c
.dom
.Element
;
25 * This Class implements a timestamp condition tree in the XML-defined state
28 * @author Jean-Christian Kouame
31 public class TmfXmlTimestampCondition
implements ITmfXmlCondition
{
33 private enum TimeRangeOperator
{
39 private enum ElapsedTimeOperator
{
46 private static final long US
= 1000l;
47 private final IXmlTimestampsCondition fTimestampsCondition
;
48 private final IXmlStateSystemContainer fParent
;
54 * The factory used to create XML model elements
56 * The XML root of this timestamp condition
58 * The state system container this timestamp condition belongs to
60 public TmfXmlTimestampCondition(ITmfXmlModelFactory modelFactory
, Element node
, IXmlStateSystemContainer container
) {
62 String type
= node
.getNodeName();
64 case TmfXmlStrings
.TIME_RANGE
:
65 fTimestampsCondition
= new TmfXmlTimeRangeCondition(modelFactory
, node
, fParent
);
67 case TmfXmlStrings
.ELAPSED_TIME
:
68 fTimestampsCondition
= new TmfXmlElapsedTimeCondition(modelFactory
, node
, fParent
);
71 throw new IllegalArgumentException("Invalid timestampsChecker declaration in XML : Type should be timeRange or elapsedTime"); //$NON-NLS-1$
76 * Normalize the value into a nanosecond time value
81 * The initial unit of the timestamp
82 * @return The value of the timestamp in nanoseconds
84 public static long valueToNanoseconds(long timestamp
, String unit
) {
86 case TmfXmlStrings
.NS
:
88 case TmfXmlStrings
.US
:
89 return timestamp
* US
;
90 case TmfXmlStrings
.MS
:
91 return timestamp
* US
* US
;
93 return timestamp
* US
* US
* US
;
95 throw new IllegalArgumentException("The time unit is not yet supporting."); //$NON-NLS-1$
104 * @param scenarioInfo
105 * The active scenario details. The value should be null if there
107 * @return True if the test succeed, false otherwise
110 public boolean test(ITmfEvent event
,@Nullable TmfXmlScenarioInfo scenarioInfo
) {
111 return fTimestampsCondition
.test(event
, scenarioInfo
);
114 private interface IXmlTimestampsCondition
extends ITmfXmlCondition
{
117 private class TmfXmlTimeRangeCondition
implements IXmlTimestampsCondition
{
119 private final TimeRangeOperator fType
;
120 private final String fUnit
;
121 private final String fBegin
;
122 private final String fEnd
;
123 private final IXmlStateSystemContainer fContainer
;
128 * @param modelFactory
129 * The factory used to create XML model elements
131 * The XML root of this time range condition transition
133 * The state system container this time range condition
136 public TmfXmlTimeRangeCondition(ITmfXmlModelFactory modelFactory
, Element node
, IXmlStateSystemContainer container
) {
137 fContainer
= container
;
138 String unit
= node
.getAttribute(TmfXmlStrings
.UNIT
);
140 List
<@Nullable Element
> childElements
= NonNullUtils
.checkNotNull(XmlUtils
.getChildElements(node
));
141 if (childElements
.size() != 1) {
142 throw new IllegalArgumentException("Invalid timestampsChecker declaration in XML : Only one timing condition is allowed"); //$NON-NLS-1$
144 final Element firstElement
= NonNullUtils
.checkNotNull(childElements
.get(0));
145 String type
= firstElement
.getNodeName();
147 case TmfXmlStrings
.IN
:
148 fType
= TimeRangeOperator
.IN
;
150 case TmfXmlStrings
.OUT
:
151 fType
= TimeRangeOperator
.OUT
;
154 fType
= TimeRangeOperator
.OTHER
;
158 final String begin
= firstElement
.getAttribute(TmfXmlStrings
.BEGIN
);
159 final String end
= firstElement
.getAttribute(TmfXmlStrings
.END
);
165 public boolean test(ITmfEvent event
, @Nullable TmfXmlScenarioInfo scenarioInfo
) {
166 ITmfStateSystem ss
= fContainer
.getStateSystem();
169 begin
= valueToNanoseconds(Long
.parseLong(fBegin
), fUnit
);
172 end
= valueToNanoseconds(Long
.parseLong(fEnd
), fUnit
);
174 // swap the value if begin > end
181 begin
= Math
.max(ss
.getStartTime(), begin
);
182 end
= Math
.min(ss
.getCurrentEndTime(), end
);
183 begin
= Math
.min(begin
, end
);
185 long ts
= event
.getTimestamp().toNanos();
188 return intersects(begin
, end
, ts
);
190 return !intersects(begin
, end
, ts
);
197 private boolean intersects(long begin
, long end
, long ts
) {
198 return ts
>= begin
&& ts
<= end
;
203 private class TmfXmlElapsedTimeCondition
implements IXmlTimestampsCondition
{
205 private final IXmlStateSystemContainer fContainer
;
206 private final ElapsedTimeOperator fType
;
207 private final String fUnit
;
208 private final String fValue
;
209 private final String fReferenceState
;
214 * @param modelFactory
215 * The factory used to create XML model elements
217 * The XML root of this elapsed time condition
219 * The state system container this elapsed time condition
222 public TmfXmlElapsedTimeCondition(ITmfXmlModelFactory modelFactory
, Element node
, IXmlStateSystemContainer container
) {
223 fContainer
= container
;
224 String unit
= node
.getAttribute(TmfXmlStrings
.UNIT
);
226 List
<@Nullable Element
> childElements
= XmlUtils
.getChildElements(node
);
227 if (childElements
.size() != 1) {
228 throw new IllegalArgumentException("Invalid timestampsChecker declaration in XML : Only one timing condition is allowed"); //$NON-NLS-1$
230 final Element firstElement
= NonNullUtils
.checkNotNull(childElements
.get(0));
231 String type
= firstElement
.getNodeName();
233 case TmfXmlStrings
.LESS
:
234 fType
= ElapsedTimeOperator
.LESS
;
236 case TmfXmlStrings
.EQUAL
:
237 fType
= ElapsedTimeOperator
.EQUAL
;
239 case TmfXmlStrings
.MORE
:
240 fType
= ElapsedTimeOperator
.MORE
;
243 fType
= ElapsedTimeOperator
.NONE
;
246 final String reference
= firstElement
.getAttribute(TmfXmlStrings
.SINCE
);
247 final String value
= firstElement
.getAttribute(TmfXmlStrings
.VALUE
);
248 fReferenceState
= reference
;
253 public boolean test(ITmfEvent event
, @Nullable TmfXmlScenarioInfo scenarioInfo
) {
254 if (scenarioInfo
== null) {
255 Activator
.logError("Elapse time conditions require scenarioInfos and scenarioInfos is null"); //$NON-NLS-1$
259 long ts
= event
.getTimestamp().toNanos();
260 long referenceTimestamps
= ((XmlPatternStateProvider
) fContainer
).getHistoryBuilder().getSpecificStateStartTime(fContainer
, fReferenceState
, scenarioInfo
, event
);
261 if (ts
< referenceTimestamps
) {
262 throw new IllegalArgumentException("Timestamp is inferior to reference time"); //$NON-NLS-1$
266 success
= (ts
- referenceTimestamps
) < valueToNanoseconds(Long
.parseLong(fValue
), fUnit
);
269 success
= (ts
- referenceTimestamps
) == valueToNanoseconds(Long
.parseLong(fValue
), fUnit
);
272 success
= (ts
- referenceTimestamps
) > valueToNanoseconds(Long
.parseLong(fValue
), fUnit
);