b79d6e258f6a7a54b1e1d26d3aec180b5c9604d9
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.analysis.xml.core / src / org / eclipse / tracecompass / internal / tmf / analysis / xml / core / model / TmfXmlTimestampCondition.java
1 /*******************************************************************************
2 * Copyright (c) 2016 Ecole Polytechnique de Montreal, Ericsson
3 *
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;
10
11 import java.util.List;
12
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;
23
24 /**
25 * This Class implements a timestamp condition tree in the XML-defined state
26 * system.
27 *
28 * @author Jean-Christian Kouame
29 */
30 public class TmfXmlTimestampCondition implements ITmfXmlCondition {
31
32 private enum TimeRangeOperator {
33 IN,
34 OUT,
35 OTHER
36 }
37
38 private enum ElapsedTimeOperator {
39 LESS,
40 EQUAL,
41 MORE,
42 NONE
43 }
44
45 private static final long US = 1000l;
46 private final IXmlTimestampsCondition fTimestampsCondition;
47 private final IXmlStateSystemContainer fParent;
48
49 /**
50 * Constructor
51 *
52 * @param modelFactory
53 * The factory used to create XML model elements
54 * @param node
55 * The XML root of this timestamp condition
56 * @param container
57 * The state system container this timestamp condition belongs to
58 */
59 public TmfXmlTimestampCondition(ITmfXmlModelFactory modelFactory, Element node, IXmlStateSystemContainer container) {
60 fParent = container;
61 String type = node.getNodeName();
62 switch (type) {
63 case TmfXmlStrings.TIME_RANGE:
64 fTimestampsCondition = new TmfXmlTimeRangeCondition(modelFactory, node, fParent);
65 break;
66 case TmfXmlStrings.ELAPSED_TIME:
67 fTimestampsCondition = new TmfXmlElapsedTimeCondition(modelFactory, node, fParent);
68 break;
69 default:
70 throw new IllegalArgumentException("Invalid timestampsChecker declaration in XML : Type should be timeRange or elapsedTime"); //$NON-NLS-1$
71 }
72 }
73
74 /**
75 * Normalize the value into a nanosecond time value
76 *
77 * @param timestamp
78 * The timestamp value
79 * @param unit
80 * The initial unit of the timestamp
81 * @return The value of the timestamp in nanoseconds
82 */
83 public static long valueToNanoseconds(long timestamp, String unit) {
84 switch (unit) {
85 case TmfXmlStrings.NS:
86 return timestamp;
87 case TmfXmlStrings.US:
88 return timestamp * US;
89 case TmfXmlStrings.MS:
90 return timestamp * US * US;
91 case TmfXmlStrings.S:
92 return timestamp * US * US * US;
93 default:
94 throw new IllegalArgumentException("The time unit is not yet supporting."); //$NON-NLS-1$
95 }
96 }
97
98 /**
99 * Validate the event
100 *
101 * @param event
102 * The current event
103 * @param scenarioInfo
104 * The active scenario details. The value should be null if there
105 * is no scenario
106 * @return True if the test succeed, false otherwise
107 */
108 @Override
109 public boolean test(ITmfEvent event,@Nullable TmfXmlScenarioInfo scenarioInfo) {
110 return fTimestampsCondition.test(event, scenarioInfo);
111 }
112
113 private interface IXmlTimestampsCondition extends ITmfXmlCondition {
114 }
115
116 private class TmfXmlTimeRangeCondition implements IXmlTimestampsCondition {
117
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;
123
124 /**
125 * Constructor
126 *
127 * @param modelFactory
128 * The factory used to create XML model elements
129 * @param node
130 * The XML root of this time range condition transition
131 * @param container
132 * The state system container this time range condition
133 * belongs to
134 */
135 public TmfXmlTimeRangeCondition(ITmfXmlModelFactory modelFactory, Element node, IXmlStateSystemContainer container) {
136 fContainer = container;
137 String unit = node.getAttribute(TmfXmlStrings.UNIT);
138 fUnit = 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$
142 }
143 final Element firstElement = NonNullUtils.checkNotNull(childElements.get(0));
144 String type = firstElement.getNodeName();
145 switch (type) {
146 case TmfXmlStrings.IN:
147 fType = TimeRangeOperator.IN;
148 break;
149 case TmfXmlStrings.OUT:
150 fType = TimeRangeOperator.OUT;
151 break;
152 default:
153 fType = TimeRangeOperator.OTHER;
154 break;
155 }
156
157 final String begin = firstElement.getAttribute(TmfXmlStrings.BEGIN);
158 final String end = firstElement.getAttribute(TmfXmlStrings.END);
159 fBegin = begin;
160 fEnd = end;
161 }
162
163 @Override
164 public boolean test(ITmfEvent event, @Nullable TmfXmlScenarioInfo scenarioInfo) {
165 ITmfStateSystem ss = fContainer.getStateSystem();
166
167 long begin;
168 begin = valueToNanoseconds(Long.parseLong(fBegin), fUnit);
169
170 long end;
171 end = valueToNanoseconds(Long.parseLong(fEnd), fUnit);
172
173 // swap the value if begin > end
174 if (begin > end) {
175 begin = begin ^ end;
176 end = begin ^ end;
177 begin = begin ^ end;
178 }
179
180 begin = Math.max(ss.getStartTime(), begin);
181 end = Math.min(ss.getCurrentEndTime(), end);
182 begin = Math.min(begin, end);
183
184 long ts = event.getTimestamp().toNanos();
185 switch (fType) {
186 case IN:
187 return intersects(begin, end, ts);
188 case OUT:
189 return !intersects(begin, end, ts);
190 case OTHER:
191 default:
192 return false;
193 }
194 }
195
196 private boolean intersects(long begin, long end, long ts) {
197 return ts >= begin && ts <= end;
198 }
199
200 }
201
202 private class TmfXmlElapsedTimeCondition implements IXmlTimestampsCondition {
203
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;
209
210 /**
211 * Constructor
212 *
213 * @param modelFactory
214 * The factory used to create XML model elements
215 * @param node
216 * The XML root of this elapsed time condition
217 * @param container
218 * The state system container this elapsed time condition
219 * belongs to
220 */
221 public TmfXmlElapsedTimeCondition(ITmfXmlModelFactory modelFactory, Element node, IXmlStateSystemContainer container) {
222 fContainer = container;
223 String unit = node.getAttribute(TmfXmlStrings.UNIT);
224 fUnit = 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$
228 }
229 final Element firstElement = NonNullUtils.checkNotNull(childElements.get(0));
230 String type = firstElement.getNodeName();
231 switch (type) {
232 case TmfXmlStrings.LESS:
233 fType = ElapsedTimeOperator.LESS;
234 break;
235 case TmfXmlStrings.EQUAL:
236 fType = ElapsedTimeOperator.EQUAL;
237 break;
238 case TmfXmlStrings.MORE:
239 fType = ElapsedTimeOperator.MORE;
240 break;
241 default:
242 fType = ElapsedTimeOperator.NONE;
243 break;
244 }
245 final String reference = firstElement.getAttribute(TmfXmlStrings.SINCE);
246 final String value = firstElement.getAttribute(TmfXmlStrings.VALUE);
247 fReferenceState = reference;
248 fValue = value;
249 }
250
251 @Override
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$
255 return false;
256 }
257 boolean success;
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$
262 }
263 switch (fType) {
264 case LESS:
265 success = (ts - referenceTimestamps) < valueToNanoseconds(Long.parseLong(fValue), fUnit);
266 break;
267 case EQUAL:
268 success = (ts - referenceTimestamps) == valueToNanoseconds(Long.parseLong(fValue), fUnit);
269 break;
270 case MORE:
271 success = (ts - referenceTimestamps) > valueToNanoseconds(Long.parseLong(fValue), fUnit);
272 break;
273 case NONE:
274 default:
275 success = false;
276 break;
277 }
278 return success;
279 }
280
281 }
282 }
This page took 0.037397 seconds and 4 git commands to generate.