TMF: Introduce the XML state provider for data driven analysis
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.analysis.xml.core / src / org / eclipse / linuxtools / internal / tmf / analysis / xml / core / stateprovider / model / TmfXmlStateAttribute.java
CommitLineData
0f7276b6
GB
1/*******************************************************************************
2 * Copyright (c) 2014 Ecole Polytechnique de Montreal
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 * Contributors:
10 * Florian Wininger - Initial API and implementation
11 ******************************************************************************/
12
13package org.eclipse.linuxtools.internal.tmf.analysis.xml.core.stateprovider.model;
14
15import java.util.ArrayList;
16import java.util.List;
17
18import org.eclipse.linuxtools.internal.tmf.analysis.xml.core.Activator;
19import org.eclipse.linuxtools.tmf.analysis.xml.core.module.XmlUtils;
20import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.TmfXmlStrings;
21import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.XmlStateProvider;
22import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
23import org.eclipse.linuxtools.tmf.core.event.ITmfEventField;
24import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException;
25import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException;
26import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystemBuilder;
27import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue;
28import org.eclipse.linuxtools.tmf.core.statevalue.TmfStateValue;
29import org.w3c.dom.Element;
30
31/**
32 * This Class implements a single attribute value
33 *
34 * <pre>
35 * Examples:
36 * <stateAttribute type="constant" value="Threads" />
37 * <stateAttribute type="query" />
38 * <stateAttribute type="constant" value="CPUs" />
39 * <stateAttribute type="eventField" value="cpu" />
40 * <stateAttribute type="constant" value="Current_thread" />
41 * </attribute>
42 * </pre>
43 *
44 * @author Florian Wininger
45 */
46public class TmfXmlStateAttribute {
47
48 private enum StateAttributeType {
49 NONE,
50 CONSTANT,
51 EVENTFIELD,
52 QUERY,
53 LOCATION
54 }
55
56 /** Type of attribute */
57 private final StateAttributeType fType;
58
59 /** Attribute's name */
60 private final String fName;
61
62 /** List of attributes for a query */
63 private final List<TmfXmlStateAttribute> fQueryList = new ArrayList<>();
64
65 private final XmlStateProvider fProvider;
66
67 /**
68 * Constructor
69 *
70 * @param attribute
71 * XML element of the attribute
72 * @param provider
73 * The state provider this state attribute belongs to
74 */
75 public TmfXmlStateAttribute(Element attribute, XmlStateProvider provider) {
76 fProvider = provider;
77
78 switch (attribute.getAttribute(TmfXmlStrings.TYPE)) {
79 case TmfXmlStrings.TYPE_CONSTANT:
80 fType = StateAttributeType.CONSTANT;
81 fName = fProvider.getAttributeValue(attribute.getAttribute(TmfXmlStrings.VALUE));
82 break;
83 case TmfXmlStrings.EVENT_FIELD:
84 fType = StateAttributeType.EVENTFIELD;
85 fName = fProvider.getAttributeValue(attribute.getAttribute(TmfXmlStrings.VALUE));
86 break;
87 case TmfXmlStrings.TYPE_LOCATION:
88 fType = StateAttributeType.LOCATION;
89 fName = fProvider.getAttributeValue(attribute.getAttribute(TmfXmlStrings.VALUE));
90 break;
91 case TmfXmlStrings.TYPE_QUERY:
92 List<Element> childElements = XmlUtils.getChildElements(attribute);
93 for (Element subAttributeNode : childElements) {
94 TmfXmlStateAttribute subAttribute = new TmfXmlStateAttribute(subAttributeNode, fProvider);
95 fQueryList.add(subAttribute);
96 }
97 fType = StateAttributeType.QUERY;
98 fName = null;
99 break;
100 case TmfXmlStrings.NULL:
101 fType = StateAttributeType.NONE;
102 fName = null;
103 break;
104 default:
105 throw new IllegalArgumentException("TmfXmlStateAttribute constructor: The XML element is not of the right type"); //$NON-NLS-1$
106 }
107 }
108
109 /**
110 * This method gets the quark for this state attribute in the State System.
111 * The method use the ss.getQuarkRelativeAndAdd method in the State System.
112 *
113 * Unless this attribute is a location, in which case the quark must exist,
114 * the quark will be added to the state system.
115 *
116 * @param event
117 * The current event being handled
118 * @param startQuark
119 * root quark, use {@link XmlStateProvider#ROOT_QUARK} to search
120 * the full attribute tree
121 * @return the quark described by attribute or
122 * {@link XmlStateProvider#ERROR_QUARK} if quark cannot be found
123 */
124 public int getAttributeQuark(ITmfEvent event, int startQuark) {
125 final ITmfEventField content = event.getContent();
126
127 ITmfStateSystemBuilder ss = fProvider.getAssignedStateSystem();
128
129 try {
130 switch (fType) {
131 case CONSTANT: {
132 int quark;
133 if (startQuark == XmlStateProvider.ROOT_QUARK) {
134 quark = ss.getQuarkAbsoluteAndAdd(fName);
135 } else {
136 quark = ss.getQuarkRelativeAndAdd(startQuark, fName);
137 }
138 return quark;
139 }
140 case EVENTFIELD: {
141 int quark = XmlStateProvider.ERROR_QUARK;
142 /* special case if field is CPU which is not in the field */
143 if (fName.equals(TmfXmlStrings.CPU)) {
144 quark = ss.getQuarkRelativeAndAdd(startQuark, event.getSource());
145 } else {
146 /* stop if the event field doesn't exist */
147 if (content.getField(fName) == null) {
148 return XmlStateProvider.ERROR_QUARK;
149 }
150
151 Object field = content.getField(fName).getValue();
152
153 if (field instanceof String) {
154 String fieldString = (String) field;
155 quark = ss.getQuarkRelativeAndAdd(startQuark, fieldString);
156 } else if (field instanceof Long) {
157 Long fieldLong = (Long) field;
158 quark = ss.getQuarkRelativeAndAdd(startQuark, fieldLong.toString());
159 } else if (field instanceof Integer) {
160 Integer fieldInterger = (Integer) field;
161 quark = ss.getQuarkRelativeAndAdd(startQuark, fieldInterger.toString());
162 }
163 }
164 return quark;
165 }
166 case QUERY: {
167 int quark;
168 ITmfStateValue value = TmfStateValue.nullValue();
169 int quarkQuery = XmlStateProvider.ROOT_QUARK;
170
171 for (TmfXmlStateAttribute attrib : fQueryList) {
172 quarkQuery = attrib.getAttributeQuark(event, quarkQuery);
173 if (quarkQuery == XmlStateProvider.ERROR_QUARK) {
174 break;
175 }
176 }
177
178 // the query may fail: for example CurrentThread if there
179 // has not been a sched_switch event
180 if (quarkQuery != XmlStateProvider.ERROR_QUARK) {
181 value = ss.queryOngoingState(quarkQuery);
182 }
183
184 switch (value.getType()) {
185 case INTEGER: {
186 int result = value.unboxInt();
187 quark = ss.getQuarkRelativeAndAdd(startQuark, String.valueOf(result));
188 break;
189 }
190 case LONG: {
191 long result = value.unboxLong();
192 quark = ss.getQuarkRelativeAndAdd(startQuark, String.valueOf(result));
193 break;
194 }
195 case STRING: {
196 String result = value.unboxStr();
197 quark = ss.getQuarkRelativeAndAdd(startQuark, result);
198 break;
199 }
200 case DOUBLE:
201 case NULL:
202 default:
203 quark = XmlStateProvider.ERROR_QUARK; // error
204 break;
205 }
206 return quark;
207 }
208 case LOCATION: {
209 int quark = startQuark;
210 String idLocation = fName;
211
212 /* TODO: Add a fProvider.getLocation(id) method */
213 for (TmfXmlLocation location : fProvider.getLocations()) {
214 if (location.getId().equals(idLocation)) {
215 quark = location.getLocationQuark(event, quark);
216 if (quark == XmlStateProvider.ERROR_QUARK) {
217 break;
218 }
219 }
220 }
221 return quark;
222 }
223 case NONE:
224 default:
225 return startQuark;
226 }
227 } catch (AttributeNotFoundException ae) {
228 /*
229 * This can be happen before the creation of the node for a query in
230 * the state system. Example : current thread before a sched_switch
231 */
232 return XmlStateProvider.ERROR_QUARK;
233 } catch (StateValueTypeException e) {
234 /*
235 * This would happen if we were trying to push/pop attributes not of
236 * type integer. Which, once again, should never happen.
237 */
238 Activator.logError("StateValueTypeException", e); //$NON-NLS-1$
239 return XmlStateProvider.ERROR_QUARK;
240 }
241 }
242
243}
This page took 0.034702 seconds and 5 git commands to generate.