linux: make KernelStateProvider handle aggregate prev_states of sched_switch
[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;
20import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
21import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
22import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
23import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
24import org.eclipse.tracecompass.tmf.analysis.xml.core.module.IXmlStateSystemContainer;
25import org.eclipse.tracecompass.tmf.analysis.xml.core.segment.TmfXmlPatternSegment;
26import org.eclipse.tracecompass.tmf.analysis.xml.core.stateprovider.TmfXmlStrings;
27import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
28import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
29import org.w3c.dom.Element;
30import org.w3c.dom.NodeList;
31
32/**
33 * This class defines a pattern segment builder. It will use the XML description
34 * of the pattern segment to generate it at runtime.
35 *
36 * @author Jean-Christian Kouame
37 * @since 2.0
38 *
39 */
40public 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 * @return The pattern segment generated
97 */
98 public TmfXmlPatternSegment generatePatternSegment(ITmfEvent event, ITmfTimestamp start, ITmfTimestamp end) {
99 int scale = event.getTimestamp().getScale();
100 long startValue = start.normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
101 long endValue = end.normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
102 String segmentName = getPatternSegmentName(event);
103 Map<String, ITmfStateValue> fields = new HashMap<>();
104 setPatternSegmentContent(event, start, end, fields);
105 return new TmfXmlPatternSegment(startValue, endValue, scale, segmentName, fields);
106 }
107
108 /**
109 * Get the pattern segment name
110 *
111 * @param event
112 * The active event
113 * @return The name of the segment
114 */
115 private String getPatternSegmentName(ITmfEvent event) {
116 return fSegmentType.getName(event);
117 }
118
119 /**
120 * Compute all the fields and their values for this pattern segment. The
121 * fields could be constant values or values queried from the state system.
122 *
123 * @param event
124 * The current event
125 * @param start
126 * The start timestamp of this segment
127 * @param end
128 * The end timestamp of this segment
129 * @param fields
130 * The map that will contained all the fields
131 */
132 private void setPatternSegmentContent(ITmfEvent event, ITmfTimestamp start, ITmfTimestamp end, Map<String, ITmfStateValue> fields) {
133 for (TmfXmlPatternSegmentField field : fFields) {
134 fields.put(field.getName(), field.getValue(event));
135 }
136 }
137
138 private static ITmfStateValue getStateValueFromConstant(String constantValue, String type) {
139 switch (type) {
140 case TmfXmlStrings.TYPE_INT:
141 return TmfStateValue.newValueInt(Integer.parseInt(constantValue));
142 case TmfXmlStrings.TYPE_LONG:
143 return TmfStateValue.newValueLong(Long.parseLong(constantValue));
144 case TmfXmlStrings.TYPE_STRING:
145 return TmfStateValue.newValueString(constantValue);
146 case TmfXmlStrings.TYPE_NULL:
147 return TmfStateValue.nullValue();
148 default:
149 throw new IllegalArgumentException("Invalid type of field : " + type); //$NON-NLS-1$
150 }
151 }
152
153 private static void getNameFromXmlStateValue(ITmfEvent event, StringBuilder builder, ITmfXmlStateValue xmlStateValue) {
154 try {
155 ITmfStateValue value = xmlStateValue.getValue(event);
156 switch (value.getType()) {
157 case DOUBLE:
158 builder.append(value.unboxDouble());
159 break;
160 case INTEGER:
161 builder.append(value.unboxInt());
162 break;
163 case LONG:
164 builder.append(value.unboxLong());
165 break;
166 case NULL:
167 builder.append(UNKNOWN_STRING);
168 break;
169 case STRING:
170 builder.append(value.unboxStr());
171 break;
172 default:
173 throw new StateValueTypeException("Invalid type of state value"); //$NON-NLS-1$
174 }
175 } catch (AttributeNotFoundException e) {
176 Activator.logInfo("Impossible to get the state value", e); //$NON-NLS-1$
177 }
178 }
179
180 /**
181 * This class represents the segment fields described in the XML. The real
182 * value of the field will be set at runtime using the active event.
183 *
184 * @author Jean-Christian Kouame
185 *
186 */
187 private class TmfXmlPatternSegmentField {
188 private final String fName;
189 private final String fType;
190 private final @Nullable ITmfStateValue fStateValue;
191 private final @Nullable ITmfXmlStateValue fXmlStateValue;
192
193 /**
194 * Constructor
195 *
196 * @param element
197 * The pattern segment field node
198 */
199 public TmfXmlPatternSegmentField(Element element) {
200 // The name, the type and the value of each field could respectively
201 // be found from the attributes name, type and value. If the value
202 // attribute is not available, try to find it from the child state
203 // value.
204 fName = element.getAttribute(TmfXmlStrings.NAME);
205 fType = element.getAttribute(TmfXmlStrings.TYPE);
206 String constantValue = element.getAttribute(TmfXmlStrings.VALUE);
207 if (constantValue.isEmpty() && !fType.equals(TmfXmlStrings.TYPE_NULL)) {
208 fStateValue = null;
209 Element elementFieldStateValue = (Element) element.getElementsByTagName(TmfXmlStrings.STATE_VALUE).item(0);
210 if (elementFieldStateValue == null) {
211 throw new IllegalArgumentException("The value of the field " + fName + " is missing"); //$NON-NLS-1$ //$NON-NLS-2$
212 }
213 fXmlStateValue = fModelFactory.createStateValue(elementFieldStateValue, fContainer, new ArrayList<>());
214 } else {
215 fStateValue = getStateValueFromConstant(constantValue, fType);
216 fXmlStateValue = null;
217 }
218 }
219
220 /**
221 * Get the real value of the XML pattern segment field
222 *
223 * @param event
224 * The active event
225 * @return The state value representing the value of the XML pattern
226 * segment field
227 */
228 public ITmfStateValue getValue(ITmfEvent event) {
229 if (fStateValue != null) {
230 return fStateValue;
231 }
232 try {
233 return checkNotNull(fXmlStateValue).getValue(event);
234 } catch (AttributeNotFoundException e) {
235 Activator.logError("Failed to get the state value", e); //$NON-NLS-1$
236 }
237 throw new IllegalStateException("Failed to get the value for the segment field " + fName); //$NON-NLS-1$
238 }
239
240 /**
241 * Get the name of the XML pattern segment field
242 *
243 * @return The name
244 */
245 public String getName() {
246 return fName;
247 }
248 }
249
250 /**
251 * This class represents the segment type described in XML.
252 *
253 * @author Jean-Christian Kouame
254 *
255 */
256 private class TmfXmlPatternSegmentType {
257 private final String fSegmentNameAttribute;
258 private final @Nullable ITmfXmlStateValue fNameStateValue;
259
260 /**
261 * Constructor
262 *
263 * @param element
264 * The pattern segment type node
265 */
266 public TmfXmlPatternSegmentType(Element element) {
267 // Try to find the segment name from the name attribute. If
268 // attribute not available, try to find it from the child state value
269 fSegmentNameAttribute = element.getAttribute(TmfXmlStrings.SEGMENT_NAME);
270 if (!fSegmentNameAttribute.isEmpty()) {
271 fNameStateValue = null;
272 } else {
273 Element elementSegmentNameStateValue = (Element) element.getElementsByTagName(TmfXmlStrings.STATE_VALUE).item(0);
274 if (elementSegmentNameStateValue == null) {
275 throw new IllegalArgumentException("Failed to get the segment name. A state value is needed."); //$NON-NLS-1$
276 }
277 fNameStateValue = fModelFactory.createStateValue(elementSegmentNameStateValue, fContainer, new ArrayList<>());
278 }
279 }
280
281 /**
282 * Get the name of the segment
283 *
284 * @param event
285 * The active event
286 * @return The segment name
287 */
288 public String getName(ITmfEvent event) {
289 StringBuilder name = new StringBuilder(PATTERN_SEGMENT_NAME_PREFIX);
290 if (fNameStateValue != null) {
291 getNameFromXmlStateValue(event, name, fNameStateValue);
292 } else {
293 name.append(fSegmentNameAttribute);
294 }
295 return name.toString();
296 }
297 }
298}
This page took 0.045577 seconds and 5 git commands to generate.