tmf : Add latency statistics view for the pattern analysis
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.analysis.xml.core / src / org / eclipse / tracecompass / tmf / analysis / xml / core / model / TmfXmlPatternSegmentBuilder.java
CommitLineData
2e1183f8
JCK
1/*******************************************************************************
2 * Copyright (c) 2016 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 ******************************************************************************/
9package org.eclipse.tracecompass.tmf.analysis.xml.core.model;
10
11import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
12
13import java.util.ArrayList;
14import java.util.HashMap;
15import java.util.List;
16import java.util.Map;
17
18import org.eclipse.jdt.annotation.Nullable;
19import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.Activator;
38e2a2e9 20import org.eclipse.tracecompass.internal.tmf.analysis.xml.core.pattern.stateprovider.XmlPatternStateProvider;
2e1183f8
JCK
21import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
22import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
23import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
24import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
25import org.eclipse.tracecompass.tmf.analysis.xml.core.module.IXmlStateSystemContainer;
26import org.eclipse.tracecompass.tmf.analysis.xml.core.segment.TmfXmlPatternSegment;
27import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings;
28import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
29import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
30import org.w3c.dom.Element;
31import org.w3c.dom.NodeList;
32
33/**
34 * This class defines a pattern segment builder. It will use the XML description
35 * of the pattern segment to generate it at runtime.
36 *
37 * @author Jean-Christian Kouame
38 * @since 2.0
39 *
40 */
41public class TmfXmlPatternSegmentBuilder {
42
43 /**
44 * The string unknown
45 */
46 public static final String UNKNOWN_STRING = "unknown"; //$NON-NLS-1$
47 /**
48 * Prefix for the pattern segment name
49 */
50 public static final String PATTERN_SEGMENT_NAME_PREFIX = "seg_"; //$NON-NLS-1$
51 private final ITmfXmlModelFactory fModelFactory;
52 private final IXmlStateSystemContainer fContainer;
53 private final List<TmfXmlPatternSegmentField> fFields = new ArrayList<>();
54 private final TmfXmlPatternSegmentType fSegmentType;
55
56 /**
57 * @param modelFactory
58 * The factory used to create XML model elements
59 * @param node
60 * XML element of the pattern segment builder
61 * @param parent
62 * The state system container this pattern segment builder
63 * belongs to
64 */
65 public TmfXmlPatternSegmentBuilder(ITmfXmlModelFactory modelFactory, Element node, IXmlStateSystemContainer parent) {
66 fModelFactory = modelFactory;
67 fContainer = parent;
68
69 //Set the XML type of the segment
70 NodeList nodesSegmentType = node.getElementsByTagName(TmfXmlStrings.SEGMENT_TYPE);
71 Element element = (Element) nodesSegmentType.item(0);
72 if (element == null) {
73 throw new IllegalArgumentException();
74 }
75 fSegmentType = new TmfXmlPatternSegmentType(element);
76
77 //Set the XML content of the segment
78 NodeList nodesSegmentContent = node.getElementsByTagName(TmfXmlStrings.SEGMENT_CONTENT);
79 Element fContentElement = (Element) nodesSegmentContent.item(0);
80 if (fContentElement != null) {
81 NodeList nodesSegmentField = fContentElement.getElementsByTagName(TmfXmlStrings.SEGMENT_FIELD);
82 for (int i = 0; i < nodesSegmentField.getLength(); i++) {
83 fFields.add(new TmfXmlPatternSegmentField(checkNotNull((Element) nodesSegmentField.item(i))));
84 }
85 }
86 }
87
88 /**
89 * Generate a pattern segment
90 *
91 * @param event
92 * The active event
93 * @param start
94 * Start time of the pattern segment to generate
95 * @param end
96 * End time of the pattern segment to generate
97 * @return The pattern segment generated
98 */
99 public TmfXmlPatternSegment generatePatternSegment(ITmfEvent event, ITmfTimestamp start, ITmfTimestamp end) {
100 int scale = event.getTimestamp().getScale();
16801c72
MK
101 long startValue = start.toNanos();
102 long endValue = end.toNanos();
2e1183f8
JCK
103 String segmentName = getPatternSegmentName(event);
104 Map<String, ITmfStateValue> fields = new HashMap<>();
105 setPatternSegmentContent(event, start, end, fields);
38e2a2e9
JCK
106 TmfXmlPatternSegment segment = new TmfXmlPatternSegment(startValue, endValue, scale, segmentName, fields);
107 if (fContainer instanceof XmlPatternStateProvider) {
108 ((XmlPatternStateProvider) fContainer).getListener().onNewSegment(segment);
109 }
110 return segment;
2e1183f8
JCK
111 }
112
113 /**
114 * Get the pattern segment name
115 *
116 * @param event
117 * The active event
118 * @return The name of the segment
119 */
120 private String getPatternSegmentName(ITmfEvent event) {
121 return fSegmentType.getName(event);
122 }
123
124 /**
125 * Compute all the fields and their values for this pattern segment. The
126 * fields could be constant values or values queried from the state system.
127 *
128 * @param event
129 * The current event
130 * @param start
131 * The start timestamp of this segment
132 * @param end
133 * The end timestamp of this segment
134 * @param fields
135 * The map that will contained all the fields
136 */
137 private void setPatternSegmentContent(ITmfEvent event, ITmfTimestamp start, ITmfTimestamp end, Map<String, ITmfStateValue> fields) {
138 for (TmfXmlPatternSegmentField field : fFields) {
139 fields.put(field.getName(), field.getValue(event));
140 }
141 }
142
143 private static ITmfStateValue getStateValueFromConstant(String constantValue, String type) {
144 switch (type) {
145 case TmfXmlStrings.TYPE_INT:
146 return TmfStateValue.newValueInt(Integer.parseInt(constantValue));
147 case TmfXmlStrings.TYPE_LONG:
148 return TmfStateValue.newValueLong(Long.parseLong(constantValue));
149 case TmfXmlStrings.TYPE_STRING:
150 return TmfStateValue.newValueString(constantValue);
151 case TmfXmlStrings.TYPE_NULL:
152 return TmfStateValue.nullValue();
153 default:
154 throw new IllegalArgumentException("Invalid type of field : " + type); //$NON-NLS-1$
155 }
156 }
157
158 private static void getNameFromXmlStateValue(ITmfEvent event, StringBuilder builder, ITmfXmlStateValue xmlStateValue) {
159 try {
160 ITmfStateValue value = xmlStateValue.getValue(event);
161 switch (value.getType()) {
162 case DOUBLE:
163 builder.append(value.unboxDouble());
164 break;
165 case INTEGER:
166 builder.append(value.unboxInt());
167 break;
168 case LONG:
169 builder.append(value.unboxLong());
170 break;
171 case NULL:
172 builder.append(UNKNOWN_STRING);
173 break;
174 case STRING:
175 builder.append(value.unboxStr());
176 break;
177 default:
178 throw new StateValueTypeException("Invalid type of state value"); //$NON-NLS-1$
179 }
180 } catch (AttributeNotFoundException e) {
181 Activator.logInfo("Impossible to get the state value", e); //$NON-NLS-1$
182 }
183 }
184
185 /**
186 * This class represents the segment fields described in the XML. The real
187 * value of the field will be set at runtime using the active event.
188 *
189 * @author Jean-Christian Kouame
190 *
191 */
192 private class TmfXmlPatternSegmentField {
193 private final String fName;
194 private final String fType;
195 private final @Nullable ITmfStateValue fStateValue;
196 private final @Nullable ITmfXmlStateValue fXmlStateValue;
197
198 /**
199 * Constructor
200 *
201 * @param element
202 * The pattern segment field node
203 */
204 public TmfXmlPatternSegmentField(Element element) {
205 // The name, the type and the value of each field could respectively
206 // be found from the attributes name, type and value. If the value
207 // attribute is not available, try to find it from the child state
208 // value.
209 fName = element.getAttribute(TmfXmlStrings.NAME);
210 fType = element.getAttribute(TmfXmlStrings.TYPE);
211 String constantValue = element.getAttribute(TmfXmlStrings.VALUE);
212 if (constantValue.isEmpty() && !fType.equals(TmfXmlStrings.TYPE_NULL)) {
213 fStateValue = null;
214 Element elementFieldStateValue = (Element) element.getElementsByTagName(TmfXmlStrings.STATE_VALUE).item(0);
215 if (elementFieldStateValue == null) {
216 throw new IllegalArgumentException("The value of the field " + fName + " is missing"); //$NON-NLS-1$ //$NON-NLS-2$
217 }
218 fXmlStateValue = fModelFactory.createStateValue(elementFieldStateValue, fContainer, new ArrayList<>());
219 } else {
220 fStateValue = getStateValueFromConstant(constantValue, fType);
221 fXmlStateValue = null;
222 }
223 }
224
225 /**
226 * Get the real value of the XML pattern segment field
227 *
228 * @param event
229 * The active event
230 * @return The state value representing the value of the XML pattern
231 * segment field
232 */
233 public ITmfStateValue getValue(ITmfEvent event) {
234 if (fStateValue != null) {
235 return fStateValue;
236 }
237 try {
238 return checkNotNull(fXmlStateValue).getValue(event);
239 } catch (AttributeNotFoundException e) {
240 Activator.logError("Failed to get the state value", e); //$NON-NLS-1$
241 }
242 throw new IllegalStateException("Failed to get the value for the segment field " + fName); //$NON-NLS-1$
243 }
244
245 /**
246 * Get the name of the XML pattern segment field
247 *
248 * @return The name
249 */
250 public String getName() {
251 return fName;
252 }
253 }
254
255 /**
256 * This class represents the segment type described in XML.
257 *
258 * @author Jean-Christian Kouame
259 *
260 */
261 private class TmfXmlPatternSegmentType {
262 private final String fSegmentNameAttribute;
263 private final @Nullable ITmfXmlStateValue fNameStateValue;
264
265 /**
266 * Constructor
267 *
268 * @param element
269 * The pattern segment type node
270 */
271 public TmfXmlPatternSegmentType(Element element) {
272 // Try to find the segment name from the name attribute. If
273 // attribute not available, try to find it from the child state value
274 fSegmentNameAttribute = element.getAttribute(TmfXmlStrings.SEGMENT_NAME);
275 if (!fSegmentNameAttribute.isEmpty()) {
276 fNameStateValue = null;
277 } else {
278 Element elementSegmentNameStateValue = (Element) element.getElementsByTagName(TmfXmlStrings.STATE_VALUE).item(0);
279 if (elementSegmentNameStateValue == null) {
280 throw new IllegalArgumentException("Failed to get the segment name. A state value is needed."); //$NON-NLS-1$
281 }
282 fNameStateValue = fModelFactory.createStateValue(elementSegmentNameStateValue, fContainer, new ArrayList<>());
283 }
284 }
285
286 /**
287 * Get the name of the segment
288 *
289 * @param event
290 * The active event
291 * @return The segment name
292 */
293 public String getName(ITmfEvent event) {
294 StringBuilder name = new StringBuilder(PATTERN_SEGMENT_NAME_PREFIX);
295 if (fNameStateValue != null) {
296 getNameFromXmlStateValue(event, name, fNameStateValue);
297 } else {
298 name.append(fSegmentNameAttribute);
299 }
300 return name.toString();
301 }
302 }
303}
This page took 0.03658 seconds and 5 git commands to generate.