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 java
.util
.ArrayList
;
17 import java
.util
.Collections
;
18 import java
.util
.List
;
20 import org
.eclipse
.jdt
.annotation
.NonNull
;
21 import org
.eclipse
.jdt
.annotation
.Nullable
;
22 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEventField
;
25 * Implementation of ITmfEventField for Text Traces.
27 public class TextTraceEventContent
implements ITmfEventField
{
29 private final @NonNull String fName
;
30 private final @NonNull List
<TextTraceEventContent
> fFields
;
32 private @Nullable Object fValue
;
34 // ------------------------------------------------------------------------
36 // ------------------------------------------------------------------------
39 * Constructor for a root event content. Subfields with the specified field
40 * names are created and initialized with a null value.
43 * the array of non-null field names
44 * @throws IllegalArgumentException
45 * if any one of the field names is null
47 public TextTraceEventContent(String
@NonNull [] fieldNames
) {
48 fName
= ITmfEventField
.ROOT_FIELD_ID
;
50 fFields
= new ArrayList
<>(fieldNames
.length
);
51 for (String fieldName
: fieldNames
) {
52 if (fieldName
== null) {
53 throw new IllegalArgumentException("Null field name not allowed"); //$NON-NLS-1$
55 fFields
.add(new TextTraceEventContent(fieldName
));
60 * Constructor for an initial capacity. This should be the expected number
63 * @param initialCapacity
64 * the initial capacity of the field list
67 public TextTraceEventContent(int initialCapacity
) {
68 fName
= ITmfEventField
.ROOT_FIELD_ID
;
70 fFields
= new ArrayList
<>(initialCapacity
);
74 * Constructor for a subfield
79 private TextTraceEventContent(@NonNull String fieldName
) {
82 fFields
= Collections
.EMPTY_LIST
;
85 // ------------------------------------------------------------------------
87 // ------------------------------------------------------------------------
90 public String
getName() {
95 public Object
getValue() {
100 public List
<String
> getFieldNames() {
101 List
<String
> fieldNames
= new ArrayList
<>(fFields
.size());
102 for (TextTraceEventContent field
: fFields
) {
103 fieldNames
.add(field
.getName());
109 public List
<TextTraceEventContent
> getFields() {
110 return new ArrayList
<>(fFields
);
114 public ITmfEventField
getField(String
... path
) {
115 if (path
.length
== 0) {
118 // There are no sub fields
119 if (path
.length
== 1) {
120 for (TextTraceEventContent field
: fFields
) {
121 if (field
.getName().equals(path
[0])) {
130 public String
getFormattedValue() {
131 Object value
= fValue
;
135 return value
.toString();
138 // ------------------------------------------------------------------------
139 // Convenience getters and setters
140 // ------------------------------------------------------------------------
143 * Get a field name by index.
146 * The index of the field
147 * @return The name of the field at that index
149 public String
getFieldName(int index
) {
150 if (index
>= 0 && index
< fFields
.size()) {
151 return fFields
.get(index
).getName();
157 * Get a field by index.
160 * The index of the field
161 * @return The field object at the requested index
163 public ITmfEventField
getField(int index
) {
164 if (index
>= 0 && index
< fFields
.size()) {
165 return fFields
.get(index
);
171 * Get a subfield value by name.
175 * @return field value object
177 public Object
getFieldValue(@NonNull String name
) {
178 for (int i
= 0; i
< fFields
.size(); i
++) {
179 if (fFields
.get(i
).getName().equals(name
)) {
180 return fFields
.get(i
).getValue();
187 * Get a subfield value by index.
191 * @return field value object
193 public Object
getFieldValue(int index
) {
194 if (index
>= 0 && index
< fFields
.size()) {
195 return fFields
.get(index
).getValue();
201 * Set the content value.
206 public void setValue(Object value
) {
211 * Set a subfield value by name. Adds the subfield if it is new.
218 public void setFieldValue(@NonNull String name
, Object value
) {
219 TextTraceEventContent field
= null;
220 for (int i
= 0; i
< fFields
.size(); i
++) {
221 if (fFields
.get(i
).getName().equals(name
)) {
222 field
= fFields
.get(i
);
223 field
.setValue(value
);
227 field
= new TextTraceEventContent(name
);
228 field
.setValue(value
);
234 * Set a subfield value by index.
241 public void setFieldValue(int index
, Object value
) {
242 if (index
>= 0 && index
< fFields
.size()) {
243 fFields
.get(index
).fValue
= value
;
248 * Add a new subfield unconditionally and set its value. Note: This can
249 * create a duplicate subfield. If the subfield already exists, use
250 * {@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();