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(String
@NonNull [] 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
69 public TextTraceEventContent(int initialCapacity
) {
70 fName
= ITmfEventField
.ROOT_FIELD_ID
;
72 fFields
= new ArrayList
<>(initialCapacity
);
76 * Constructor for a subfield
81 private TextTraceEventContent(@NonNull String fieldName
) {
84 fFields
= checkNotNull(Collections
.EMPTY_LIST
);
87 // ------------------------------------------------------------------------
89 // ------------------------------------------------------------------------
92 public String
getName() {
97 public Object
getValue() {
102 public List
<String
> getFieldNames() {
103 List
<String
> fieldNames
= new ArrayList
<>(fFields
.size());
104 for (TextTraceEventContent field
: fFields
) {
105 fieldNames
.add(field
.getName());
111 public List
<TextTraceEventContent
> getFields() {
112 return new ArrayList
<>(fFields
);
116 public ITmfEventField
getField(String
... path
) {
117 if (path
.length
== 0) {
120 // There are no sub fields
121 if (path
.length
== 1) {
122 for (TextTraceEventContent field
: fFields
) {
123 if (field
.getName().equals(path
[0])) {
132 public String
getFormattedValue() {
133 Object value
= fValue
;
137 return value
.toString();
140 // ------------------------------------------------------------------------
141 // Convenience getters and setters
142 // ------------------------------------------------------------------------
145 * Get a field name by index.
148 * The index of the field
149 * @return The name of the field at that index
151 public String
getFieldName(int index
) {
152 if (index
>= 0 && index
< fFields
.size()) {
153 return fFields
.get(index
).getName();
159 * Get a field by index.
162 * The index of the field
163 * @return The field object at the requested index
165 public ITmfEventField
getField(int index
) {
166 if (index
>= 0 && index
< fFields
.size()) {
167 return fFields
.get(index
);
173 * Get a subfield value by name.
177 * @return field value object
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();
189 * Get a subfield value by index.
193 * @return field value object
195 public Object
getFieldValue(int index
) {
196 if (index
>= 0 && index
< fFields
.size()) {
197 return fFields
.get(index
).getValue();
203 * Set the content value.
208 public void setValue(Object value
) {
213 * Set a subfield value by name. Adds the subfield if it is new.
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
);
229 field
= new TextTraceEventContent(name
);
230 field
.setValue(value
);
236 * Set a subfield value by index.
243 public void setFieldValue(int index
, Object value
) {
244 if (index
>= 0 && index
< fFields
.size()) {
245 fFields
.get(index
).fValue
= value
;
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.
260 public void addField(@NonNull String name
, Object value
) {
261 TextTraceEventContent field
= new TextTraceEventContent(name
);
262 field
.setValue(value
);
266 // ------------------------------------------------------------------------
268 // ------------------------------------------------------------------------
271 public int hashCode() {
272 final int prime
= 31;
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
;
279 if (value
instanceof StringBuffer
) {
280 tmpHash
= value
.toString().hashCode();
282 tmpHash
= value
.hashCode();
285 result
= prime
* result
+ tmpHash
;
290 public boolean equals(Object obj
) {
297 if (getClass() != obj
.getClass()) {
300 TextTraceEventContent other
= (TextTraceEventContent
) obj
;
301 if (!fFields
.equals(other
.fFields
)) {
304 if (!fName
.equals(other
.fName
)) {
308 Object value
= fValue
;
310 if (other
.fValue
!= null) {
314 if ((value
instanceof StringBuffer
) && (other
.fValue
instanceof StringBuffer
)) {
315 Object otherValue
= other
.getValue();
316 if (otherValue
== null) {
319 if (!value
.toString().equals(otherValue
.toString())) {
322 } else if (!value
.equals(other
.fValue
)) {
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
);
336 sb
.append(", "); //$NON-NLS-1$
338 sb
.append(field
.toString());
345 return sb
.toString();