769c29c3a56289abbab02b44a69d8849c7af163d
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / tmf / core / trace / text / TextTraceEventContent.java
1 /*******************************************************************************
2 * Copyright (c) 2012, 2015 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 *
9 * Contributors:
10 * Patrick Tasse - Initial API and implementation
11 * Bernd Hufmann - Updated equals, clone and hashCode to consider StringBuffer values
12 *******************************************************************************/
13
14 package org.eclipse.tracecompass.tmf.core.trace.text;
15
16 import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
17
18 import java.util.ArrayList;
19 import java.util.Collections;
20 import java.util.List;
21
22 import org.eclipse.jdt.annotation.NonNull;
23 import org.eclipse.jdt.annotation.Nullable;
24 import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
25
26 /**
27 * Implementation of ITmfEventField for Text Traces.
28 */
29 public class TextTraceEventContent implements ITmfEventField {
30
31 private final @NonNull String fName;
32 private final @NonNull List<TextTraceEventContent> fFields;
33
34 private @Nullable Object fValue;
35
36 // ------------------------------------------------------------------------
37 // Constructors
38 // ------------------------------------------------------------------------
39
40 /**
41 * Constructor for a root event content. Subfields with the specified field
42 * names are created and initialized with a null value.
43 *
44 * @param fieldNames
45 * the array of non-null field names
46 * @throws IllegalArgumentException
47 * if any one of the field names is null
48 */
49 public TextTraceEventContent(String @NonNull [] fieldNames) {
50 fName = ITmfEventField.ROOT_FIELD_ID;
51 fValue = null;
52 fFields = new ArrayList<>(fieldNames.length);
53 for (String fieldName : fieldNames) {
54 if (fieldName == null) {
55 throw new IllegalArgumentException("Null field name not allowed"); //$NON-NLS-1$
56 }
57 fFields.add(new TextTraceEventContent(fieldName));
58 }
59 }
60
61 /**
62 * Constructor for an initial capacity. This should be the expected number
63 * of fields.
64 *
65 * @param initialCapacity
66 * the initial capacity of the field list
67 * @since 1.0
68 */
69 public TextTraceEventContent(int initialCapacity) {
70 fName = ITmfEventField.ROOT_FIELD_ID;
71 fValue = null;
72 fFields = new ArrayList<>(initialCapacity);
73 }
74
75 /**
76 * Constructor for a subfield
77 *
78 * @param fieldName
79 * the subfield name
80 */
81 private TextTraceEventContent(@NonNull String fieldName) {
82 fName = fieldName;
83 fValue = null;
84 fFields = checkNotNull(Collections.EMPTY_LIST);
85 }
86
87 // ------------------------------------------------------------------------
88 // ITmfEventField
89 // ------------------------------------------------------------------------
90
91 @Override
92 public String getName() {
93 return fName;
94 }
95
96 @Override
97 public Object getValue() {
98 return fValue;
99 }
100
101 @Override
102 public List<String> getFieldNames() {
103 List<String> fieldNames = new ArrayList<>(fFields.size());
104 for (TextTraceEventContent field : fFields) {
105 fieldNames.add(field.getName());
106 }
107 return fieldNames;
108 }
109
110 @Override
111 public List<TextTraceEventContent> getFields() {
112 return new ArrayList<>(fFields);
113 }
114
115 @Override
116 public ITmfEventField getField(String... path) {
117 if (path.length == 0) {
118 return this;
119 }
120 // There are no sub fields
121 if (path.length == 1) {
122 for (TextTraceEventContent field : fFields) {
123 if (field.getName().equals(path[0])) {
124 return field;
125 }
126 }
127 }
128 return null;
129 }
130
131 @Override
132 public String getFormattedValue() {
133 Object value = fValue;
134 if (value == null) {
135 return null;
136 }
137 return value.toString();
138 }
139
140 // ------------------------------------------------------------------------
141 // Convenience getters and setters
142 // ------------------------------------------------------------------------
143
144 /**
145 * Get a field name by index.
146 *
147 * @param index
148 * The index of the field
149 * @return The name of the field at that index
150 */
151 public String getFieldName(int index) {
152 if (index >= 0 && index < fFields.size()) {
153 return fFields.get(index).getName();
154 }
155 return null;
156 }
157
158 /**
159 * Get a field by index.
160 *
161 * @param index
162 * The index of the field
163 * @return The field object at the requested index
164 */
165 public ITmfEventField getField(int index) {
166 if (index >= 0 && index < fFields.size()) {
167 return fFields.get(index);
168 }
169 return null;
170 }
171
172 /**
173 * Get a subfield value by name.
174 *
175 * @param name
176 * a subfield name
177 * @return field value object
178 */
179 public Object getFieldValue(@NonNull String name) {
180 for (int i = 0; i < fFields.size(); i++) {
181 if (fFields.get(i).getName().equals(name)) {
182 return fFields.get(i).getValue();
183 }
184 }
185 return null;
186 }
187
188 /**
189 * Get a subfield value by index.
190 *
191 * @param index
192 * a subfield index
193 * @return field value object
194 */
195 public Object getFieldValue(int index) {
196 if (index >= 0 && index < fFields.size()) {
197 return fFields.get(index).getValue();
198 }
199 return null;
200 }
201
202 /**
203 * Set the content value.
204 *
205 * @param value
206 * the content value
207 */
208 public void setValue(Object value) {
209 fValue = value;
210 }
211
212 /**
213 * Set a subfield value by name. Adds the subfield if it is new.
214 *
215 * @param name
216 * a subfield name
217 * @param value
218 * the subfield value
219 */
220 public void setFieldValue(@NonNull String name, Object value) {
221 TextTraceEventContent field = null;
222 for (int i = 0; i < fFields.size(); i++) {
223 if (fFields.get(i).getName().equals(name)) {
224 field = fFields.get(i);
225 field.setValue(value);
226 }
227 }
228 if (field == null) {
229 field = new TextTraceEventContent(name);
230 field.setValue(value);
231 fFields.add(field);
232 }
233 }
234
235 /**
236 * Set a subfield value by index.
237 *
238 * @param index
239 * a subfield index
240 * @param value
241 * the subfield value
242 */
243 public void setFieldValue(int index, Object value) {
244 if (index >= 0 && index < fFields.size()) {
245 fFields.get(index).fValue = value;
246 }
247 }
248
249 /**
250 * Add a new subfield unconditionally and set its value. Note: This can
251 * create a duplicate subfield. If the subfield already exists, use
252 * {@link #setFieldValue(String, Object)} instead.
253 *
254 * @param name
255 * a subfield name
256 * @param value
257 * the subfield value
258 * @since 1.0
259 */
260 public void addField(@NonNull String name, Object value) {
261 TextTraceEventContent field = new TextTraceEventContent(name);
262 field.setValue(value);
263 fFields.add(field);
264 }
265
266 // ------------------------------------------------------------------------
267 // Object
268 // ------------------------------------------------------------------------
269
270 @Override
271 public int hashCode() {
272 final int prime = 31;
273 int result = 1;
274 result = prime * result + fFields.hashCode();
275 result = prime * result + fName.hashCode();
276 int tmpHash = 0; // initialize for fValue equals null;
277 Object value = fValue;
278 if (value != null) {
279 if (value instanceof StringBuffer) {
280 tmpHash = value.toString().hashCode();
281 } else {
282 tmpHash = value.hashCode();
283 }
284 }
285 result = prime * result + tmpHash;
286 return result;
287 }
288
289 @Override
290 public boolean equals(Object obj) {
291 if (this == obj) {
292 return true;
293 }
294 if (obj == null) {
295 return false;
296 }
297 if (getClass() != obj.getClass()) {
298 return false;
299 }
300 TextTraceEventContent other = (TextTraceEventContent) obj;
301 if (!fFields.equals(other.fFields)) {
302 return false;
303 }
304 if (!fName.equals(other.fName)) {
305 return false;
306 }
307
308 Object value = fValue;
309 if (value == null) {
310 if (other.fValue != null) {
311 return false;
312 }
313 } else {
314 if ((value instanceof StringBuffer) && (other.fValue instanceof StringBuffer)) {
315 Object otherValue = other.getValue();
316 if (otherValue == null) {
317 return false;
318 }
319 if (!value.toString().equals(otherValue.toString())) {
320 return false;
321 }
322 } else if (!value.equals(other.fValue)) {
323 return false;
324 }
325 }
326 return true;
327 }
328
329 @Override
330 public String toString() {
331 StringBuilder sb = new StringBuilder();
332 if (fName == ITmfEventField.ROOT_FIELD_ID) {
333 for (int i = 0; i < getFields().size(); i++) {
334 ITmfEventField field = getFields().get(i);
335 if (i != 0) {
336 sb.append(", "); //$NON-NLS-1$
337 }
338 sb.append(field.toString());
339 }
340 } else {
341 sb.append(fName);
342 sb.append('=');
343 sb.append(fValue);
344 }
345 return sb.toString();
346 }
347
348 }
This page took 0.055917 seconds and 4 git commands to generate.