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
.internal
.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
.module
.IXmlStateSystemContainer
;
17 import org
.eclipse
.tracecompass
.internal
.tmf
.analysis
.xml
.core
.module
.XmlUtils
;
18 import org
.eclipse
.tracecompass
.internal
.tmf
.analysis
.xml
.core
.pattern
.stateprovider
.XmlPatternStateProvider
;
19 import org
.eclipse
.tracecompass
.internal
.tmf
.analysis
.xml
.core
.stateprovider
.TmfXmlStrings
;
20 import org
.eclipse
.tracecompass
.statesystem
.core
.ITmfStateSystem
;
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
30 public class TmfXmlTimestampCondition
implements ITmfXmlCondition
{
32 private enum TimeRangeOperator
{
38 private enum ElapsedTimeOperator
{
45 private static final long US
= 1000l;
46 private final IXmlTimestampsCondition fTimestampsCondition
;
47 private final IXmlStateSystemContainer fParent
;
53 * The factory used to create XML model elements
55 * The XML root of this timestamp condition
57 * The state system container this timestamp condition belongs to
59 public TmfXmlTimestampCondition(ITmfXmlModelFactory modelFactory
, Element node
, IXmlStateSystemContainer container
) {
61 String type
= node
.getNodeName();
63 case TmfXmlStrings
.TIME_RANGE
:
64 fTimestampsCondition
= new TmfXmlTimeRangeCondition(modelFactory
, node
, fParent
);
66 case TmfXmlStrings
.ELAPSED_TIME
:
67 fTimestampsCondition
= new TmfXmlElapsedTimeCondition(modelFactory
, node
, fParent
);
70 throw new IllegalArgumentException("Invalid timestampsChecker declaration in XML : Type should be timeRange or elapsedTime"); //$NON-NLS-1$
75 * Normalize the value into a nanosecond time value
80 * The initial unit of the timestamp
81 * @return The value of the timestamp in nanoseconds
83 public static long valueToNanoseconds(long timestamp
, String unit
) {
85 case TmfXmlStrings
.NS
:
87 case TmfXmlStrings
.US
:
88 return timestamp
* US
;
89 case TmfXmlStrings
.MS
:
90 return timestamp
* US
* US
;
92 return timestamp
* US
* US
* US
;
94 throw new IllegalArgumentException("The time unit is not yet supporting."); //$NON-NLS-1$
103 * @param scenarioInfo
104 * The active scenario details. The value should be null if there
106 * @return True if the test succeed, false otherwise
109 public boolean test(ITmfEvent event
,@Nullable TmfXmlScenarioInfo scenarioInfo
) {
110 return fTimestampsCondition
.test(event
, scenarioInfo
);
113 private interface IXmlTimestampsCondition
extends ITmfXmlCondition
{
116 private class TmfXmlTimeRangeCondition
implements IXmlTimestampsCondition
{
118 private final TimeRangeOperator fType
;
119 private final String fUnit
;
120 private final String fBegin
;
121 private final String fEnd
;
122 private final IXmlStateSystemContainer fContainer
;
127 * @param modelFactory
128 * The factory used to create XML model elements
130 * The XML root of this time range condition transition
132 * The state system container this time range condition
135 public TmfXmlTimeRangeCondition(ITmfXmlModelFactory modelFactory
, Element node
, IXmlStateSystemContainer container
) {
136 fContainer
= container
;
137 String unit
= node
.getAttribute(TmfXmlStrings
.UNIT
);
139 List
<@Nullable Element
> childElements
= NonNullUtils
.checkNotNull(XmlUtils
.getChildElements(node
));
140 if (childElements
.size() != 1) {
141 throw new IllegalArgumentException("Invalid timestampsChecker declaration in XML : Only one timing condition is allowed"); //$NON-NLS-1$
143 final Element firstElement
= NonNullUtils
.checkNotNull(childElements
.get(0));
144 String type
= firstElement
.getNodeName();
146 case TmfXmlStrings
.IN
:
147 fType
= TimeRangeOperator
.IN
;
149 case TmfXmlStrings
.OUT
:
150 fType
= TimeRangeOperator
.OUT
;
153 fType
= TimeRangeOperator
.OTHER
;
157 final String begin
= firstElement
.getAttribute(TmfXmlStrings
.BEGIN
);
158 final String end
= firstElement
.getAttribute(TmfXmlStrings
.END
);
164 public boolean test(ITmfEvent event
, @Nullable TmfXmlScenarioInfo scenarioInfo
) {
165 ITmfStateSystem ss
= fContainer
.getStateSystem();
168 begin
= valueToNanoseconds(Long
.parseLong(fBegin
), fUnit
);
171 end
= valueToNanoseconds(Long
.parseLong(fEnd
), fUnit
);
173 // swap the value if begin > end
180 begin
= Math
.max(ss
.getStartTime(), begin
);
181 end
= Math
.min(ss
.getCurrentEndTime(), end
);
182 begin
= Math
.min(begin
, end
);
184 long ts
= event
.getTimestamp().toNanos();
187 return intersects(begin
, end
, ts
);
189 return !intersects(begin
, end
, ts
);
196 private boolean intersects(long begin
, long end
, long ts
) {
197 return ts
>= begin
&& ts
<= end
;
202 private class TmfXmlElapsedTimeCondition
implements IXmlTimestampsCondition
{
204 private final IXmlStateSystemContainer fContainer
;
205 private final ElapsedTimeOperator fType
;
206 private final String fUnit
;
207 private final String fValue
;
208 private final String fReferenceState
;
213 * @param modelFactory
214 * The factory used to create XML model elements
216 * The XML root of this elapsed time condition
218 * The state system container this elapsed time condition
221 public TmfXmlElapsedTimeCondition(ITmfXmlModelFactory modelFactory
, Element node
, IXmlStateSystemContainer container
) {
222 fContainer
= container
;
223 String unit
= node
.getAttribute(TmfXmlStrings
.UNIT
);
225 List
<@Nullable Element
> childElements
= XmlUtils
.getChildElements(node
);
226 if (childElements
.size() != 1) {
227 throw new IllegalArgumentException("Invalid timestampsChecker declaration in XML : Only one timing condition is allowed"); //$NON-NLS-1$
229 final Element firstElement
= NonNullUtils
.checkNotNull(childElements
.get(0));
230 String type
= firstElement
.getNodeName();
232 case TmfXmlStrings
.LESS
:
233 fType
= ElapsedTimeOperator
.LESS
;
235 case TmfXmlStrings
.EQUAL
:
236 fType
= ElapsedTimeOperator
.EQUAL
;
238 case TmfXmlStrings
.MORE
:
239 fType
= ElapsedTimeOperator
.MORE
;
242 fType
= ElapsedTimeOperator
.NONE
;
245 final String reference
= firstElement
.getAttribute(TmfXmlStrings
.SINCE
);
246 final String value
= firstElement
.getAttribute(TmfXmlStrings
.VALUE
);
247 fReferenceState
= reference
;
252 public boolean test(ITmfEvent event
, @Nullable TmfXmlScenarioInfo scenarioInfo
) {
253 if (scenarioInfo
== null) {
254 Activator
.logError("Elapse time conditions require scenarioInfos and scenarioInfos is null"); //$NON-NLS-1$
258 long ts
= event
.getTimestamp().toNanos();
259 long referenceTimestamps
= ((XmlPatternStateProvider
) fContainer
).getHistoryBuilder().getSpecificStateStartTime(fContainer
, fReferenceState
, scenarioInfo
, event
);
260 if (ts
< referenceTimestamps
) {
261 throw new IllegalArgumentException("Timestamp is inferior to reference time"); //$NON-NLS-1$
265 success
= (ts
- referenceTimestamps
) < valueToNanoseconds(Long
.parseLong(fValue
), fUnit
);
268 success
= (ts
- referenceTimestamps
) == valueToNanoseconds(Long
.parseLong(fValue
), fUnit
);
271 success
= (ts
- referenceTimestamps
) > valueToNanoseconds(Long
.parseLong(fValue
), fUnit
);