tmf: Enhance TmfEventField.toString() to also print sub-fields
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / event / TmfEventField.java
1 /*******************************************************************************
2 * Copyright (c) 2009, 2012 Ericsson
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 * Francois Chouinard - Initial API and implementation
11 * Francois Chouinard - Updated as per TMF Event Model 1.0
12 *******************************************************************************/
13
14 package org.eclipse.linuxtools.tmf.core.event;
15
16 import java.util.Arrays;
17 import java.util.HashMap;
18 import java.util.Map;
19
20 /**
21 * A basic implementation of ITmfEventField.
22 * <p>
23 * Non-value fields are structural (i.e. used to represent the event structure
24 * including optional fields) while the valued fields are actual event fields.
25 *
26 * @version 1.0
27 * @author Francois Chouinard
28 *
29 * @see ITmfEvent
30 * @see ITmfEventType
31 */
32 public class TmfEventField implements ITmfEventField, Cloneable {
33
34 // ------------------------------------------------------------------------
35 // Attributes
36 // ------------------------------------------------------------------------
37
38 private String fName;
39 private Object fValue;
40 private ITmfEventField[] fFields;
41
42 private String[] fFieldNames;
43 private Map<String, ITmfEventField> fNameMapping;
44
45 // ------------------------------------------------------------------------
46 // Constructors
47 // ------------------------------------------------------------------------
48
49 /**
50 * Default constructor
51 */
52 @SuppressWarnings("unused")
53 private TmfEventField() {
54 }
55
56 /**
57 * Constructor for a structural field
58 *
59 * @param name the event field id
60 * @param fields the list of subfields
61 */
62 public TmfEventField(final String name, final ITmfEventField[] fields) {
63 this(name, null, fields);
64 }
65
66 /**
67 * Constructor for a terminal field (no subfields)
68 *
69 * @param name the event field id
70 * @param value the event field value
71 */
72 public TmfEventField(final String name, final Object value) {
73 this(name, value, null);
74 }
75
76 /**
77 * Full constructor
78 *
79 * @param name the event field id
80 * @param value the event field value
81 * @param fields the list of subfields
82 */
83 public TmfEventField(final String name, final Object value, final ITmfEventField[] fields) {
84 if (name == null) {
85 throw new IllegalArgumentException();
86 }
87 fName = name;
88 fValue = value;
89 fFields = (fields != null) ? Arrays.copyOf(fields, fields.length) : null;
90 populateStructs();
91 }
92
93 /**
94 * Copy constructor
95 *
96 * @param field the other event field
97 */
98 public TmfEventField(final TmfEventField field) {
99 if (field == null) {
100 throw new IllegalArgumentException();
101 }
102 fName = field.fName;
103 fValue = field.fValue;
104 fFields = field.fFields;
105 fFieldNames = field.fFieldNames;
106 populateStructs();
107 }
108
109 // ------------------------------------------------------------------------
110 // ITmfEventField
111 // ------------------------------------------------------------------------
112
113 /* (non-Javadoc)
114 * @see org.eclipse.linuxtools.tmf.core.event.ITmfEventField#getName()
115 */
116 @Override
117 public String getName() {
118 return fName;
119 }
120
121 /* (non-Javadoc)
122 * @see org.eclipse.linuxtools.tmf.core.event.ITmfEventField#getValue()
123 */
124 @Override
125 public Object getValue() {
126 return fValue;
127 }
128
129 /* (non-Javadoc)
130 * @see org.eclipse.linuxtools.tmf.core.event.ITmfEventField#getFieldNames()
131 */
132 @Override
133 public String[] getFieldNames() {
134 return Arrays.copyOf(fFieldNames, fFieldNames.length);
135 }
136
137 /* (non-Javadoc)
138 * @see org.eclipse.linuxtools.tmf.core.event.ITmfEventField#getFieldName(int)
139 */
140 @Override
141 public String getFieldName(final int index) {
142 final ITmfEventField field = getField(index);
143 if (field != null) {
144 return field.getName();
145 }
146 return null;
147 }
148
149 /* (non-Javadoc)
150 * @see org.eclipse.linuxtools.tmf.core.event.ITmfEventField#getFields()
151 */
152 @Override
153 public ITmfEventField[] getFields() {
154 return (fFields != null) ? Arrays.copyOf(fFields, fFields.length) : new ITmfEventField[0];
155 }
156
157 /* (non-Javadoc)
158 * @see org.eclipse.linuxtools.tmf.core.event.ITmfEventField#getField(java.lang.String)
159 */
160 @Override
161 public ITmfEventField getField(final String name) {
162 return fNameMapping.get(name);
163 }
164
165 /* (non-Javadoc)
166 * @see org.eclipse.linuxtools.tmf.core.event.ITmfEventField#getField(int)
167 */
168 @Override
169 public ITmfEventField getField(final int index) {
170 if (fFields != null && index >= 0 && index < fFields.length) {
171 return fFields[index];
172 }
173 return null;
174 }
175
176 // ------------------------------------------------------------------------
177 // Convenience setters
178 // ------------------------------------------------------------------------
179
180 /**
181 * @param value new field raw value
182 * @param fields the corresponding fields
183 */
184 protected void setValue(final Object value, final ITmfEventField[] fields) {
185 fValue = value;
186 fFields = (fields != null) ? Arrays.copyOf(fields, fields.length) : null;
187 populateStructs();
188 }
189
190 // ------------------------------------------------------------------------
191 // Operations
192 // ------------------------------------------------------------------------
193
194 /**
195 * Create a root field from a list of labels.
196 *
197 * @param labels the list of labels
198 * @return the (flat) root list
199 */
200 public final static ITmfEventField makeRoot(final String[] labels) {
201 final ITmfEventField[] fields = new ITmfEventField[labels.length];
202 for (int i = 0; i < labels.length; i++) {
203 fields[i] = new TmfEventField(labels[i], null);
204 }
205 // Return a new root field;
206 return new TmfEventField(ITmfEventField.ROOT_FIELD_ID, fields);
207 }
208
209 /*
210 * Populate the subfield names and the name map
211 */
212 private void populateStructs() {
213 final int nbFields = (fFields != null) ? fFields.length : 0;
214 fFieldNames = new String[nbFields];
215 fNameMapping = new HashMap<String, ITmfEventField>();
216 for (int i = 0; i < nbFields; i++) {
217 final String name = fFields[i].getName();
218 fFieldNames[i] = name;
219 fNameMapping.put(name, fFields[i]);
220 }
221 }
222
223 // ------------------------------------------------------------------------
224 // Cloneable
225 // ------------------------------------------------------------------------
226
227 /* (non-Javadoc)
228 * @see java.lang.Object#clone()
229 */
230 @Override
231 public TmfEventField clone() {
232 TmfEventField clone = null;
233 try {
234 clone = (TmfEventField) super.clone();
235 clone.fName = fName;
236 clone.fValue = fValue;
237 clone.fFields = (fFields != null) ? fFields.clone() : null;
238 clone.populateStructs();
239 } catch (final CloneNotSupportedException e) {
240 }
241 return clone;
242 }
243
244 // ------------------------------------------------------------------------
245 // Object
246 // ------------------------------------------------------------------------
247
248 /* (non-Javadoc)
249 * @see java.lang.Object#hashCode()
250 */
251 @Override
252 public int hashCode() {
253 final int prime = 31;
254 int result = 1;
255 result = prime * result + fName.hashCode();
256 result = prime * result + ((fValue == null) ? 0 : fValue.hashCode());
257 return result;
258 }
259
260 /* (non-Javadoc)
261 * @see java.lang.Object#equals(java.lang.Object)
262 */
263 @Override
264 public boolean equals(final Object obj) {
265 if (this == obj) {
266 return true;
267 }
268 if (obj == null) {
269 return false;
270 }
271 if (!(obj instanceof TmfEventField)) {
272 return false;
273 }
274 final TmfEventField other = (TmfEventField) obj;
275 if (!fName.equals(other.fName)) {
276 return false;
277 }
278 if (fValue == null) {
279 if (other.fValue != null) {
280 return false;
281 }
282 } else if (!fValue.equals(other.fValue)) {
283 return false;
284 }
285 return true;
286 }
287
288 /* (non-Javadoc)
289 * @see java.lang.Object#toString()
290 */
291 @Override
292 public String toString() {
293 StringBuilder ret = new StringBuilder();
294 if (fName.equals(ITmfEventField.ROOT_FIELD_ID)) {
295 /*
296 * If this field is a top-level "field container", we will print its
297 * sub-fields directly.
298 */
299 appendSubFields(ret);
300
301 } else {
302 /* The field has its own values */
303 ret.append(fName);
304 ret.append('=');
305 ret.append(fValue);
306
307 if (fFields != null && fFields.length > 0) {
308 /*
309 * In addition to its own name/value, this field also has
310 * sub-fields.
311 */
312 ret.append(" ["); //$NON-NLS-1$
313 appendSubFields(ret);
314 ret.append(']');
315 }
316 }
317 return ret.toString();
318 }
319
320 private void appendSubFields(StringBuilder sb) {
321 ITmfEventField field;
322 for (int i = 0; i < getFields().length; i++) {
323 field = getFields()[i];
324 if (i != 0) {
325 sb.append(", ");//$NON-NLS-1$
326 }
327 sb.append(field.toString());
328 }
329 }
330
331 }
This page took 0.036933 seconds and 5 git commands to generate.