1 /*******************************************************************************
2 * Copyright (c) 2012, 2015 Ericsson
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
10 * Patrick Tasse - Initial API and implementation
11 * Bernd Hufmann - Updated equals, clone and hashCode to consider StringBuffer values
12 *******************************************************************************/
14 package org
.eclipse
.tracecompass
.tmf
.core
.trace
.text
;
16 import static org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
.checkNotNull
;
18 import java
.util
.ArrayList
;
19 import java
.util
.Collections
;
20 import java
.util
.List
;
22 import org
.eclipse
.jdt
.annotation
.NonNull
;
23 import org
.eclipse
.jdt
.annotation
.Nullable
;
24 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEventField
;
27 * Implementation of ITmfEventField for Text Traces.
29 public class TextTraceEventContent
implements ITmfEventField
{
31 private final @NonNull String fName
;
32 private final @NonNull List
<TextTraceEventContent
> fFields
;
34 private @Nullable Object fValue
;
36 // ------------------------------------------------------------------------
38 // ------------------------------------------------------------------------
41 * Constructor for a root event content. Subfields with the specified field
42 * names are created and initialized with a null value.
45 * the array of non-null field names
46 * @throws IllegalArgumentException
47 * if any one of the field names is null
49 public TextTraceEventContent(@NonNull String
[] fieldNames
) {
50 fName
= ITmfEventField
.ROOT_FIELD_ID
;
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$
57 fFields
.add(new TextTraceEventContent(fieldName
));
62 * Constructor for an initial capacity. This should be the expected number
65 * @param initialCapacity
66 * the initial capacity of the field list
68 public TextTraceEventContent(int initialCapacity
) {
69 fName
= ITmfEventField
.ROOT_FIELD_ID
;
71 fFields
= new ArrayList
<>(initialCapacity
);
75 * Constructor for a subfield
80 private TextTraceEventContent(@NonNull String fieldName
) {
83 fFields
= checkNotNull(Collections
.EMPTY_LIST
);
86 // ------------------------------------------------------------------------
88 // ------------------------------------------------------------------------
91 public String
getName() {
96 public Object
getValue() {
101 public List
<String
> getFieldNames() {
102 List
<String
> fieldNames
= new ArrayList
<>(fFields
.size());
103 for (TextTraceEventContent field
: fFields
) {
104 fieldNames
.add(field
.getName());
110 public List
<TextTraceEventContent
> getFields() {
111 return new ArrayList
<>(fFields
);
115 public ITmfEventField
getField(String
... path
) {
116 if (path
.length
== 0) {
119 // There are no sub fields
120 if (path
.length
== 1) {
121 for (TextTraceEventContent field
: fFields
) {
122 if (field
.getName().equals(path
[0])) {
131 public String
getFormattedValue() {
132 Object value
= fValue
;
136 return value
.toString();
139 // ------------------------------------------------------------------------
140 // Convenience getters and setters
141 // ------------------------------------------------------------------------
144 * Get a field name by index.
147 * The index of the field
148 * @return The name of the field at that index
150 public String
getFieldName(int index
) {
151 if (index
>= 0 && index
< fFields
.size()) {
152 return fFields
.get(index
).getName();
158 * Get a field by index.
161 * The index of the field
162 * @return The field object at the requested index
164 public ITmfEventField
getField(int index
) {
165 if (index
>= 0 && index
< fFields
.size()) {
166 return fFields
.get(index
);
172 * Get a subfield value by name.
176 * @return field value object
178 public Object
getFieldValue(@NonNull String name
) {
179 for (int i
= 0; i
< fFields
.size(); i
++) {
180 if (fFields
.get(i
).getName().equals(name
)) {
181 return fFields
.get(i
).getValue();
188 * Get a subfield value by index.
192 * @return field value object
194 public Object
getFieldValue(int index
) {
195 if (index
>= 0 && index
< fFields
.size()) {
196 return fFields
.get(index
).getValue();
202 * Set the content value.
207 public void setValue(Object value
) {
212 * Set a subfield value by name. Adds the subfield if it is new.
219 public void setFieldValue(@NonNull String name
, Object value
) {
220 TextTraceEventContent field
= null;
221 for (int i
= 0; i
< fFields
.size(); i
++) {
222 if (fFields
.get(i
).getName().equals(name
)) {
223 field
= fFields
.get(i
);
224 field
.setValue(value
);
228 field
= new TextTraceEventContent(name
);
229 field
.setValue(value
);
235 * Set a subfield value by index.
242 public void setFieldValue(int index
, Object value
) {
243 if (index
>= 0 && index
< fFields
.size()) {
244 fFields
.get(index
).fValue
= value
;
249 * Add a new subfield unconditionally and set its value. Note: This can
250 * create a duplicate subfield. If the subfield already exists, use
251 * {@link #setFieldValue(String, Object)} instead.
258 public void addField(@NonNull String name
, Object value
) {
259 TextTraceEventContent field
= new TextTraceEventContent(name
);
260 field
.setValue(value
);
264 // ------------------------------------------------------------------------
266 // ------------------------------------------------------------------------
269 public int hashCode() {
270 final int prime
= 31;
272 result
= prime
* result
+ fFields
.hashCode();
273 result
= prime
* result
+ fName
.hashCode();
274 int tmpHash
= 0; // initialize for fValue equals null;
275 Object value
= fValue
;
277 if (value
instanceof StringBuffer
) {
278 tmpHash
= value
.toString().hashCode();
280 tmpHash
= value
.hashCode();
283 result
= prime
* result
+ tmpHash
;
288 public boolean equals(Object obj
) {
295 if (getClass() != obj
.getClass()) {
298 TextTraceEventContent other
= (TextTraceEventContent
) obj
;
299 if (!fFields
.equals(other
.fFields
)) {
302 if (!fName
.equals(other
.fName
)) {
306 Object value
= fValue
;
308 if (other
.fValue
!= null) {
312 if ((value
instanceof StringBuffer
) && (other
.fValue
instanceof StringBuffer
)) {
313 Object otherValue
= other
.getValue();
314 if (otherValue
== null) {
317 if (!value
.toString().equals(otherValue
.toString())) {
320 } else if (!value
.equals(other
.fValue
)) {
328 public String
toString() {
329 StringBuilder sb
= new StringBuilder();
330 if (fName
== ITmfEventField
.ROOT_FIELD_ID
) {
331 for (int i
= 0; i
< getFields().size(); i
++) {
332 ITmfEventField field
= getFields().get(i
);
334 sb
.append(", "); //$NON-NLS-1$
336 sb
.append(field
.toString());
343 return sb
.toString();