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