Fix some null warnings
[deliverable/tracecompass.git] / ctf / org.eclipse.tracecompass.tmf.ctf.core / src / org / eclipse / tracecompass / tmf / ctf / core / event / CtfTmfEventField.java
1 /*******************************************************************************
2 * Copyright (c) 2011, 2014 Ericsson, École Polytechnique de Montréal
3 *
4 * All rights reserved. This program and the accompanying materials are made
5 * 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 * Matthew Khouzam - Initial API and implementation
11 * Alexandre Montplaisir - Initial API and implementation, extend TmfEventField
12 * Bernd Hufmann - Add Enum field handling
13 * Geneviève Bastien - Add Struct and Variant field handling
14 * Jean-Christian Kouame - Correct handling of unsigned integer fields
15 * François Doray - Add generic array field type
16 *******************************************************************************/
17
18 package org.eclipse.tracecompass.tmf.ctf.core.event;
19
20 import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
21
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.Collection;
25 import java.util.List;
26
27 import org.eclipse.jdt.annotation.NonNull;
28 import org.eclipse.tracecompass.ctf.core.event.types.AbstractArrayDefinition;
29 import org.eclipse.tracecompass.ctf.core.event.types.CompoundDeclaration;
30 import org.eclipse.tracecompass.ctf.core.event.types.Definition;
31 import org.eclipse.tracecompass.ctf.core.event.types.EnumDefinition;
32 import org.eclipse.tracecompass.ctf.core.event.types.FloatDefinition;
33 import org.eclipse.tracecompass.ctf.core.event.types.ICompositeDefinition;
34 import org.eclipse.tracecompass.ctf.core.event.types.IDeclaration;
35 import org.eclipse.tracecompass.ctf.core.event.types.IDefinition;
36 import org.eclipse.tracecompass.ctf.core.event.types.IntegerDeclaration;
37 import org.eclipse.tracecompass.ctf.core.event.types.IntegerDefinition;
38 import org.eclipse.tracecompass.ctf.core.event.types.StringDefinition;
39 import org.eclipse.tracecompass.ctf.core.event.types.VariantDefinition;
40 import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
41 import org.eclipse.tracecompass.tmf.core.event.TmfEventField;
42 import org.eclipse.tracecompass.tmf.ctf.core.CtfEnumPair;
43
44 /**
45 * The CTF implementation of the TMF event field model
46 *
47 * @version 2.0
48 * @author Matthew Khouzam
49 * @author Alexandre Montplaisir
50 */
51 public abstract class CtfTmfEventField extends TmfEventField {
52
53 // ------------------------------------------------------------------------
54 // Constructor
55 // ------------------------------------------------------------------------
56
57 /**
58 * Standard constructor. Only to be used internally, call parseField() to
59 * generate a new field object.
60 *
61 * @param name
62 * The name of this field
63 * @param value
64 * The value of this field. Its type should match the field type.
65 * @param fields
66 * The children fields. Useful for composite fields
67 */
68 protected CtfTmfEventField(@NonNull String name, Object value, ITmfEventField[] fields) {
69 super(/* Strip the underscore from the field name if there is one */
70 name.startsWith("_") ? checkNotNull(name.substring(1)) : name, //$NON-NLS-1$
71 value,
72 fields);
73 }
74
75 // ------------------------------------------------------------------------
76 // Operations
77 // ------------------------------------------------------------------------
78
79 /**
80 * Factory method to instantiate CtfTmfEventField objects.
81 *
82 * @param fieldDef
83 * The CTF Definition of this event field
84 * @param fieldName
85 * String The name to assign to this field
86 * @return The resulting CtfTmfEventField object
87 * @deprecated use {@link CtfTmfEventField#parseField(IDefinition, String)}
88 */
89 @Deprecated
90 public static CtfTmfEventField parseField(Definition fieldDef,
91 @NonNull String fieldName) {
92 return parseField((IDefinition) fieldDef, fieldName);
93 }
94
95 /**
96 * Factory method to instantiate CtfTmfEventField objects.
97 *
98 * @param fieldDef
99 * The CTF Definition of this event field
100 * @param fieldName
101 * String The name to assign to this field
102 * @return The resulting CtfTmfEventField object
103 */
104 public static @NonNull CtfTmfEventField parseField(IDefinition fieldDef,
105 @NonNull String fieldName) {
106 CtfTmfEventField field = null;
107
108 /* Determine the Definition type */
109 if (fieldDef instanceof IntegerDefinition) {
110 IntegerDefinition intDef = (IntegerDefinition) fieldDef;
111 int base = intDef.getDeclaration().getBase();
112 field = new CTFIntegerField(fieldName, intDef.getValue(), base, intDef.getDeclaration().isSigned());
113
114 } else if (fieldDef instanceof EnumDefinition) {
115 EnumDefinition enumDef = (EnumDefinition) fieldDef;
116 field = new CTFEnumField(fieldName, new CtfEnumPair(enumDef.getValue(), enumDef.getIntegerValue()));
117
118 } else if (fieldDef instanceof StringDefinition) {
119 field = new CTFStringField(fieldName, ((StringDefinition) fieldDef).getValue());
120
121 } else if (fieldDef instanceof FloatDefinition) {
122 FloatDefinition floatDef = (FloatDefinition) fieldDef;
123 field = new CTFFloatField(fieldName, floatDef.getValue());
124
125 } else if (fieldDef instanceof AbstractArrayDefinition) {
126 AbstractArrayDefinition arrayDef = (AbstractArrayDefinition) fieldDef;
127 IDeclaration decl = arrayDef.getDeclaration();
128 if (!(decl instanceof CompoundDeclaration)) {
129 throw new IllegalArgumentException("Array definitions should only come from sequence or array declarations"); //$NON-NLS-1$
130 }
131 CompoundDeclaration arrDecl = (CompoundDeclaration) decl;
132 IDeclaration elemType = null;
133 Collection<Definition> definitions = arrayDef.getDefinitions();
134 elemType = arrDecl.getElementType();
135 if (elemType instanceof IntegerDeclaration) {
136 /*
137 * Array of integers => CTFIntegerArrayField, unless it's a
138 * CTFStringField
139 */
140 IntegerDeclaration elemIntType = (IntegerDeclaration) elemType;
141 /* Are the integers characters and encoded? */
142 if (elemIntType.isCharacter()) {
143 /* it's a CTFStringField */
144 field = new CTFStringField(fieldName, arrayDef.toString());
145 } else {
146 /* it's a CTFIntegerArrayField */
147 int size = arrayDef.getDefinitions().size();
148 long[] values = new long[size];
149 for (int i = 0; i < size; i++) {
150 IDefinition elem = arrayDef.getDefinitions().get(i);
151 if (elem == null) {
152 break;
153 }
154 values[i] = ((IntegerDefinition) elem).getValue();
155 }
156 field = new CTFIntegerArrayField(fieldName, values,
157 elemIntType.getBase(),
158 elemIntType.isSigned());
159 }
160 } else {
161 /* Arrays of elements of any other type */
162 CtfTmfEventField[] elements = new CtfTmfEventField[arrayDef.getLength()];
163 /* Parse the elements of the array. */
164 int i = 0;
165 for (IDefinition definition : definitions) {
166 CtfTmfEventField curField = CtfTmfEventField.parseField(
167 definition, fieldName + '[' + i + ']');
168 elements[i] = curField;
169 i++;
170 }
171
172 field = new CTFArrayField(fieldName, elements);
173 }
174 } else if (fieldDef instanceof ICompositeDefinition) {
175 ICompositeDefinition strDef = (ICompositeDefinition) fieldDef;
176
177 List<ITmfEventField> list = new ArrayList<>();
178 /* Recursively parse the fields */
179 for (String curFieldName : strDef.getFieldNames()) {
180 String fn = checkNotNull(curFieldName);
181 list.add(CtfTmfEventField.parseField((IDefinition) strDef.getDefinition(fn), fn));
182 }
183 field = new CTFStructField(fieldName, list.toArray(new CtfTmfEventField[list.size()]));
184
185 } else if (fieldDef instanceof VariantDefinition) {
186 VariantDefinition varDef = (VariantDefinition) fieldDef;
187
188 String curFieldName = checkNotNull(varDef.getCurrentFieldName());
189 IDefinition curFieldDef = varDef.getCurrentField();
190 if (curFieldDef != null) {
191 CtfTmfEventField subField = CtfTmfEventField.parseField(curFieldDef, curFieldName);
192 field = new CTFVariantField(fieldName, subField);
193 } else {
194 /* A safe-guard, but curFieldDef should never be null */
195 field = new CTFStringField(curFieldName, ""); //$NON-NLS-1$
196 }
197
198 } else {
199 /*
200 * Safe-guard, to avoid null exceptions later, field is expected not
201 * to be null
202 */
203 field = new CTFStringField(fieldName, Messages.CtfTmfEventField_UnsupportedType + fieldDef.getClass().toString());
204 }
205 return field;
206 }
207
208 @Override
209 public String toString() {
210 return getName() + '=' + getFormattedValue();
211 }
212
213 }
214
215 /**
216 * The CTF field implementation for integer fields.
217 *
218 * @author alexmont
219 */
220 final class CTFIntegerField extends CtfTmfEventField {
221
222 private final int fBase;
223 private final boolean fSigned;
224
225 /**
226 * A CTF "IntegerDefinition" can be an integer of any byte size, so in the
227 * Java parser this is interpreted as a long.
228 *
229 * @param name
230 * The name of this field
231 * @param longValue
232 * The integer value of this field
233 * @param signed
234 * Is the value signed or not
235 */
236 CTFIntegerField(@NonNull String name, long longValue, int base, boolean signed) {
237 super(name, longValue, null);
238 fSigned = signed;
239 fBase = base;
240 }
241
242 @Override
243 public Long getValue() {
244 return (Long) super.getValue();
245 }
246
247 @Override
248 public String getFormattedValue() {
249 return IntegerDefinition.formatNumber(getValue(), fBase, fSigned);
250 }
251
252 }
253
254 /**
255 * The CTF field implementation for string fields
256 *
257 * @author alexmont
258 */
259 final class CTFStringField extends CtfTmfEventField {
260
261 /**
262 * Constructor for CTFStringField.
263 *
264 * @param strValue
265 * The string value of this field
266 * @param name
267 * The name of this field
268 */
269 CTFStringField(@NonNull String name, String strValue) {
270 super(name, strValue, null);
271 }
272
273 @Override
274 public String getValue() {
275 return (String) super.getValue();
276 }
277 }
278
279 /**
280 * CTF field implementation for arrays of integers.
281 *
282 * @author alexmont
283 */
284 final class CTFIntegerArrayField extends CtfTmfEventField {
285
286 private final int fBase;
287 private final boolean fSigned;
288 private String fFormattedValue = null;
289
290 /**
291 * Constructor for CTFIntegerArrayField.
292 *
293 * @param name
294 * The name of this field
295 * @param longValues
296 * The array of integers (as longs) that compose this field's
297 * value
298 * @param signed
299 * Are the values in the array signed or not
300 */
301 CTFIntegerArrayField(@NonNull String name, long[] longValues, int base, boolean signed) {
302 super(name, longValues, null);
303 fBase = base;
304 fSigned = signed;
305 }
306
307 @Override
308 public long[] getValue() {
309 return (long[]) super.getValue();
310 }
311
312 @Override
313 public synchronized String getFormattedValue() {
314 if (fFormattedValue == null) {
315 List<String> strings = new ArrayList<>();
316 for (long value : getValue()) {
317 strings.add(IntegerDefinition.formatNumber(value, fBase, fSigned));
318 }
319 fFormattedValue = strings.toString();
320 }
321 return fFormattedValue;
322 }
323
324 }
325
326 /**
327 * CTF field implementation for arrays of arbitrary types.
328 *
329 * @author fdoray
330 */
331 final class CTFArrayField extends CtfTmfEventField {
332
333 private String fFormattedValue = null;
334
335 /**
336 * Constructor for CTFArrayField.
337 *
338 * @param name
339 * The name of this field
340 * @param elements
341 * The array elements of this field
342 */
343 CTFArrayField(@NonNull String name, CtfTmfEventField[] elements) {
344 super(name, elements, elements);
345 }
346
347 @Override
348 public CtfTmfEventField[] getValue() {
349 return (CtfTmfEventField[]) super.getValue();
350 }
351
352 @Override
353 public synchronized String getFormattedValue() {
354 if (fFormattedValue == null) {
355 List<String> strings = new ArrayList<>();
356 for (CtfTmfEventField element : getValue()) {
357 strings.add(element.getFormattedValue());
358 }
359 fFormattedValue = strings.toString();
360 }
361 return fFormattedValue;
362 }
363 }
364
365 /**
366 * CTF field implementation for floats.
367 *
368 * @author emathko
369 */
370 final class CTFFloatField extends CtfTmfEventField {
371
372 /**
373 * Constructor for CTFFloatField.
374 *
375 * @param value
376 * The float value (actually a double) of this field
377 * @param name
378 * The name of this field
379 */
380 protected CTFFloatField(@NonNull String name, double value) {
381 super(name, value, null);
382 }
383
384 @Override
385 public Double getValue() {
386 return (Double) super.getValue();
387 }
388 }
389
390 /**
391 * The CTF field implementation for Enum fields
392 *
393 * @author Bernd Hufmann
394 */
395 final class CTFEnumField extends CtfTmfEventField {
396
397 /**
398 * Constructor for CTFEnumField.
399 *
400 * @param enumValue
401 * The Enum value consisting of a pair of Enum value name and its
402 * long value
403 * @param name
404 * The name of this field
405 */
406 CTFEnumField(@NonNull String name, CtfEnumPair enumValue) {
407 super(name, new CtfEnumPair(enumValue.getFirst(),
408 enumValue.getSecond()), null);
409 }
410
411 @Override
412 public CtfEnumPair getValue() {
413 return (CtfEnumPair) super.getValue();
414 }
415 }
416
417 /**
418 * The CTF field implementation for struct fields with sub-fields
419 *
420 * @author gbastien
421 */
422 final class CTFStructField extends CtfTmfEventField {
423
424 /**
425 * Constructor for CTFStructField.
426 *
427 * @param fields
428 * The children of this field
429 * @param name
430 * The name of this field
431 */
432 CTFStructField(@NonNull String name, CtfTmfEventField[] fields) {
433 super(name, fields, fields);
434 }
435
436 @Override
437 public CtfTmfEventField[] getValue() {
438 return (CtfTmfEventField[]) super.getValue();
439 }
440
441 @Override
442 public String getFormattedValue() {
443 return Arrays.toString(getValue());
444 }
445
446 }
447
448 /**
449 * The CTF field implementation for variant fields its child
450 *
451 * @author gbastien
452 */
453 final class CTFVariantField extends CtfTmfEventField {
454
455 /**
456 * Constructor for CTFVariantField.
457 *
458 * @param field
459 * The field selected for this variant
460 * @param name
461 * The name of this field
462 */
463 CTFVariantField(@NonNull String name, CtfTmfEventField field) {
464 super(name, field, new CtfTmfEventField[] { field });
465 }
466
467 @Override
468 public CtfTmfEventField getValue() {
469 return (CtfTmfEventField) super.getValue();
470 }
471
472 }
473
474 /* Implement other possible fields types here... */
This page took 0.0595 seconds and 5 git commands to generate.