Move alltests plugin to the Trace Compass namespace
[deliverable/tracecompass.git] / org.eclipse.tracecompass.tmf.analysis.xml.core / src / org / eclipse / linuxtools / tmf / analysis / xml / core / 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
1d7e62f9 13package org.eclipse.linuxtools.tmf.analysis.xml.core.model;
0f7276b6 14
1d7e62f9 15import java.util.LinkedList;
0f7276b6
GB
16import java.util.List;
17
1d7e62f9 18import org.eclipse.jdt.annotation.Nullable;
0f7276b6 19import org.eclipse.linuxtools.internal.tmf.analysis.xml.core.Activator;
bcec0116
AM
20import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem;
21import org.eclipse.linuxtools.statesystem.core.ITmfStateSystemBuilder;
22import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException;
23import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException;
24import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue;
25import org.eclipse.linuxtools.statesystem.core.statevalue.TmfStateValue;
1d7e62f9 26import org.eclipse.linuxtools.tmf.analysis.xml.core.module.IXmlStateSystemContainer;
0f7276b6
GB
27import org.eclipse.linuxtools.tmf.analysis.xml.core.module.XmlUtils;
28import org.eclipse.linuxtools.tmf.analysis.xml.core.stateprovider.TmfXmlStrings;
0f7276b6
GB
29import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
30import org.eclipse.linuxtools.tmf.core.event.ITmfEventField;
0f7276b6
GB
31import org.w3c.dom.Element;
32
33/**
1d7e62f9
GB
34 * This Class implements a single attribute value in the XML-defined state
35 * system.
0f7276b6
GB
36 *
37 * <pre>
38 * Examples:
39 * <stateAttribute type="constant" value="Threads" />
40 * <stateAttribute type="query" />
41 * <stateAttribute type="constant" value="CPUs" />
42 * <stateAttribute type="eventField" value="cpu" />
43 * <stateAttribute type="constant" value="Current_thread" />
44 * </attribute>
45 * </pre>
46 *
47 * @author Florian Wininger
48 */
1d7e62f9 49public abstract class TmfXmlStateAttribute implements ITmfXmlStateAttribute {
0f7276b6
GB
50
51 private enum StateAttributeType {
52 NONE,
53 CONSTANT,
54 EVENTFIELD,
55 QUERY,
1d7e62f9
GB
56 LOCATION,
57 SELF
0f7276b6
GB
58 }
59
60 /** Type of attribute */
61 private final StateAttributeType fType;
62
63 /** Attribute's name */
64 private final String fName;
65
66 /** List of attributes for a query */
1d7e62f9 67 private final List<ITmfXmlStateAttribute> fQueryList = new LinkedList<>();
0f7276b6 68
1d7e62f9 69 private final IXmlStateSystemContainer fContainer;
0f7276b6
GB
70
71 /**
72 * Constructor
73 *
1d7e62f9
GB
74 * @param modelFactory
75 * The factory used to create XML model elements
0f7276b6
GB
76 * @param attribute
77 * XML element of the attribute
1d7e62f9
GB
78 * @param container
79 * The state system container this state attribute belongs to
0f7276b6 80 */
1d7e62f9
GB
81 protected TmfXmlStateAttribute(ITmfXmlModelFactory modelFactory, Element attribute, IXmlStateSystemContainer container) {
82 fContainer = container;
0f7276b6
GB
83
84 switch (attribute.getAttribute(TmfXmlStrings.TYPE)) {
85 case TmfXmlStrings.TYPE_CONSTANT:
86 fType = StateAttributeType.CONSTANT;
1d7e62f9 87 fName = fContainer.getAttributeValue(attribute.getAttribute(TmfXmlStrings.VALUE));
0f7276b6
GB
88 break;
89 case TmfXmlStrings.EVENT_FIELD:
90 fType = StateAttributeType.EVENTFIELD;
1d7e62f9 91 fName = fContainer.getAttributeValue(attribute.getAttribute(TmfXmlStrings.VALUE));
0f7276b6
GB
92 break;
93 case TmfXmlStrings.TYPE_LOCATION:
94 fType = StateAttributeType.LOCATION;
1d7e62f9 95 fName = fContainer.getAttributeValue(attribute.getAttribute(TmfXmlStrings.VALUE));
0f7276b6
GB
96 break;
97 case TmfXmlStrings.TYPE_QUERY:
98 List<Element> childElements = XmlUtils.getChildElements(attribute);
99 for (Element subAttributeNode : childElements) {
1d7e62f9 100 ITmfXmlStateAttribute subAttribute = modelFactory.createStateAttribute(subAttributeNode, fContainer);
0f7276b6
GB
101 fQueryList.add(subAttribute);
102 }
103 fType = StateAttributeType.QUERY;
104 fName = null;
105 break;
106 case TmfXmlStrings.NULL:
107 fType = StateAttributeType.NONE;
108 fName = null;
109 break;
1d7e62f9
GB
110 case TmfXmlStrings.TYPE_SELF:
111 fType = StateAttributeType.SELF;
112 fName = null;
113 break;
0f7276b6
GB
114 default:
115 throw new IllegalArgumentException("TmfXmlStateAttribute constructor: The XML element is not of the right type"); //$NON-NLS-1$
116 }
117 }
118
119 /**
120 * This method gets the quark for this state attribute in the State System.
0f7276b6
GB
121 *
122 * Unless this attribute is a location, in which case the quark must exist,
1d7e62f9
GB
123 * the quark will be added to the state system if the state system is in
124 * builder mode.
0f7276b6 125 *
0f7276b6 126 * @param startQuark
1d7e62f9
GB
127 * root quark, use {@link IXmlStateSystemContainer#ROOT_QUARK} to
128 * search the full attribute tree
0f7276b6 129 * @return the quark described by attribute or
1d7e62f9
GB
130 * {@link IXmlStateSystemContainer#ERROR_QUARK} if quark cannot be
131 * found
132 */
133 @Override
134 public int getAttributeQuark(int startQuark) {
135 return getAttributeQuark(null, startQuark);
136 }
137
138 /**
139 * Basic quark-retrieving method. Pass an attribute in parameter as an array
140 * of strings, the matching quark will be returned. If the attribute does
141 * not exist, it will add the quark to the state system if the context
142 * allows it.
143 *
144 * See {@link ITmfStateSystemBuilder#getQuarkAbsoluteAndAdd(String...)}
145 *
146 * @param path
147 * Full path to the attribute
148 * @return The quark for this attribute
149 * @throws AttributeNotFoundException
150 * The attribute does not exist and cannot be added
151 */
152 protected abstract int getQuarkAbsoluteAndAdd(String... path) throws AttributeNotFoundException;
153
154 /**
155 * Quark-retrieving method, but the attribute is queried starting from the
156 * startNodeQuark. If the attribute does not exist, it will add it to the
157 * state system if the context allows it.
158 *
159 * See {@link ITmfStateSystemBuilder#getQuarkRelativeAndAdd(int, String...)}
160 *
161 * @param startNodeQuark
162 * The quark of the attribute from which 'path' originates.
163 * @param path
164 * Relative path to the attribute
165 * @return The quark for this attribute
166 * @throws AttributeNotFoundException
167 * The attribute does not exist and cannot be added
168 */
169 protected abstract int getQuarkRelativeAndAdd(int startNodeQuark, String... path) throws AttributeNotFoundException;
170
171 /**
172 * Get the state system associated with this attribute's container
173 *
174 * @return The state system associated with this state attribute
0f7276b6 175 */
1d7e62f9
GB
176 protected ITmfStateSystem getStateSystem() {
177 return fContainer.getStateSystem();
178 }
0f7276b6 179
1d7e62f9
GB
180 /**
181 * This method gets the quark for this state attribute in the State System.
182 *
183 * Unless this attribute is a location, in which case the quark must exist,
184 * the quark will be added to the state system if the state system is in
185 * builder mode.
186 *
187 * @param event
188 * The current event being handled, or <code>null</code> if no
189 * event available in the context
190 * @param startQuark
191 * root quark, use {@link IXmlStateSystemContainer#ROOT_QUARK} to
192 * search the full attribute tree
193 * @return the quark described by attribute or
194 * {@link IXmlStateSystemContainer#ERROR_QUARK} if quark cannot be
195 * found
196 */
197 @Override
198 public int getAttributeQuark(@Nullable ITmfEvent event, int startQuark) {
199 ITmfStateSystem ss = getStateSystem();
0f7276b6
GB
200
201 try {
202 switch (fType) {
203 case CONSTANT: {
204 int quark;
1d7e62f9
GB
205 if (startQuark == IXmlStateSystemContainer.ROOT_QUARK) {
206 quark = getQuarkAbsoluteAndAdd(fName);
0f7276b6 207 } else {
1d7e62f9 208 quark = getQuarkRelativeAndAdd(startQuark, fName);
0f7276b6
GB
209 }
210 return quark;
211 }
212 case EVENTFIELD: {
1d7e62f9
GB
213 int quark = IXmlStateSystemContainer.ERROR_QUARK;
214 if (event == null) {
215 Activator.logWarning("XML State attribute: looking for an event field, but event is null"); //$NON-NLS-1$
216 return quark;
217 }
0f7276b6
GB
218 /* special case if field is CPU which is not in the field */
219 if (fName.equals(TmfXmlStrings.CPU)) {
1d7e62f9 220 quark = getQuarkRelativeAndAdd(startQuark, event.getSource());
0f7276b6 221 } else {
1d7e62f9 222 final ITmfEventField content = event.getContent();
0f7276b6
GB
223 /* stop if the event field doesn't exist */
224 if (content.getField(fName) == null) {
1d7e62f9 225 return IXmlStateSystemContainer.ERROR_QUARK;
0f7276b6
GB
226 }
227
228 Object field = content.getField(fName).getValue();
229
230 if (field instanceof String) {
231 String fieldString = (String) field;
1d7e62f9 232 quark = getQuarkRelativeAndAdd(startQuark, fieldString);
0f7276b6
GB
233 } else if (field instanceof Long) {
234 Long fieldLong = (Long) field;
1d7e62f9 235 quark = getQuarkRelativeAndAdd(startQuark, fieldLong.toString());
0f7276b6
GB
236 } else if (field instanceof Integer) {
237 Integer fieldInterger = (Integer) field;
1d7e62f9 238 quark = getQuarkRelativeAndAdd(startQuark, fieldInterger.toString());
0f7276b6
GB
239 }
240 }
241 return quark;
242 }
243 case QUERY: {
244 int quark;
245 ITmfStateValue value = TmfStateValue.nullValue();
1d7e62f9 246 int quarkQuery = IXmlStateSystemContainer.ROOT_QUARK;
0f7276b6 247
1d7e62f9 248 for (ITmfXmlStateAttribute attrib : fQueryList) {
0f7276b6 249 quarkQuery = attrib.getAttributeQuark(event, quarkQuery);
1d7e62f9 250 if (quarkQuery == IXmlStateSystemContainer.ERROR_QUARK) {
0f7276b6
GB
251 break;
252 }
253 }
254
255 // the query may fail: for example CurrentThread if there
256 // has not been a sched_switch event
1d7e62f9 257 if (quarkQuery != IXmlStateSystemContainer.ERROR_QUARK) {
0f7276b6
GB
258 value = ss.queryOngoingState(quarkQuery);
259 }
260
261 switch (value.getType()) {
262 case INTEGER: {
263 int result = value.unboxInt();
1d7e62f9 264 quark = getQuarkRelativeAndAdd(startQuark, String.valueOf(result));
0f7276b6
GB
265 break;
266 }
267 case LONG: {
268 long result = value.unboxLong();
1d7e62f9 269 quark = getQuarkRelativeAndAdd(startQuark, String.valueOf(result));
0f7276b6
GB
270 break;
271 }
272 case STRING: {
273 String result = value.unboxStr();
1d7e62f9 274 quark = getQuarkRelativeAndAdd(startQuark, result);
0f7276b6
GB
275 break;
276 }
277 case DOUBLE:
278 case NULL:
279 default:
1d7e62f9 280 quark = IXmlStateSystemContainer.ERROR_QUARK; // error
0f7276b6
GB
281 break;
282 }
283 return quark;
284 }
285 case LOCATION: {
286 int quark = startQuark;
287 String idLocation = fName;
288
1d7e62f9
GB
289 /* TODO: Add a fContainer.getLocation(id) method */
290 for (TmfXmlLocation location : fContainer.getLocations()) {
0f7276b6
GB
291 if (location.getId().equals(idLocation)) {
292 quark = location.getLocationQuark(event, quark);
1d7e62f9 293 if (quark == IXmlStateSystemContainer.ERROR_QUARK) {
0f7276b6
GB
294 break;
295 }
296 }
297 }
298 return quark;
299 }
1d7e62f9
GB
300 case SELF:
301 return startQuark;
0f7276b6
GB
302 case NONE:
303 default:
304 return startQuark;
305 }
306 } catch (AttributeNotFoundException ae) {
307 /*
308 * This can be happen before the creation of the node for a query in
309 * the state system. Example : current thread before a sched_switch
310 */
1d7e62f9 311 return IXmlStateSystemContainer.ERROR_QUARK;
0f7276b6
GB
312 } catch (StateValueTypeException e) {
313 /*
314 * This would happen if we were trying to push/pop attributes not of
315 * type integer. Which, once again, should never happen.
316 */
317 Activator.logError("StateValueTypeException", e); //$NON-NLS-1$
1d7e62f9 318 return IXmlStateSystemContainer.ERROR_QUARK;
0f7276b6
GB
319 }
320 }
321
446598f9
GB
322 @Override
323 public String toString() {
324 return "TmfXmlStateAttribute " + fType + ": " + fName; //$NON-NLS-1$ //$NON-NLS-2$
325 }
326
0f7276b6 327}
This page took 0.068638 seconds and 5 git commands to generate.