tmf: Annotate methods in ITmfEventField
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / tmf / core / event / TmfEventField.java
1 /*******************************************************************************
2 * Copyright (c) 2009, 2015 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 * Alexandre Montplaisir - Removed Cloneable, made immutable
13 * Patrick Tasse - Remove getSubField
14 *******************************************************************************/
15
16 package org.eclipse.tracecompass.tmf.core.event;
17
18 import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
19
20 import java.util.Collection;
21 import java.util.Map;
22
23 import org.eclipse.jdt.annotation.NonNull;
24 import org.eclipse.jdt.annotation.Nullable;
25
26 import com.google.common.base.Joiner;
27 import com.google.common.collect.ImmutableMap;
28
29 /**
30 * A basic implementation of ITmfEventField.
31 * <p>
32 * Non-value fields are structural (i.e. used to represent the event structure
33 * including optional fields) while the valued fields are actual event fields.
34 *
35 * @version 1.0
36 * @author Francois Chouinard
37 *
38 * @see ITmfEvent
39 * @see ITmfEventType
40 */
41 public class TmfEventField implements ITmfEventField {
42
43 // ------------------------------------------------------------------------
44 // Attributes
45 // ------------------------------------------------------------------------
46
47 private final @NonNull String fName;
48 private final @Nullable Object fValue;
49 private final @NonNull Map<String, ITmfEventField> fFields;
50
51 // ------------------------------------------------------------------------
52 // Constructors
53 // ------------------------------------------------------------------------
54
55 /**
56 * Full constructor
57 *
58 * @param name
59 * the event field id
60 * @param value
61 * the event field value
62 * @param fields
63 * the list of subfields
64 * @throws IllegalArgumentException
65 * If 'name' is null, or if 'fields' has duplicate field names.
66 */
67 public TmfEventField(@NonNull String name, @Nullable Object value, @Nullable ITmfEventField[] fields) {
68 fName = name;
69 fValue = value;
70
71 if (fields == null) {
72 fFields = checkNotNull(ImmutableMap.<String, ITmfEventField> of());
73 } else {
74 /* Java 8 streams will make this even more simple! */
75 ImmutableMap.Builder<String, ITmfEventField> mapBuilder = new ImmutableMap.Builder<>();
76 for (ITmfEventField field : fields) {
77 final String curName = field.getName();
78 mapBuilder.put(curName, field);
79 }
80 fFields = checkNotNull(mapBuilder.build());
81 }
82 }
83
84 /**
85 * Copy constructor
86 *
87 * @param field the other event field
88 */
89 public TmfEventField(final TmfEventField field) {
90 if (field == null) {
91 throw new IllegalArgumentException();
92 }
93 fName = field.fName;
94 fValue = field.fValue;
95 fFields = field.fFields;
96 }
97
98 // ------------------------------------------------------------------------
99 // ITmfEventField
100 // ------------------------------------------------------------------------
101
102 @Override
103 public String getName() {
104 return fName;
105 }
106
107 @Override
108 public Object getValue() {
109 return fValue;
110 }
111
112 @Override
113 public Collection<String> getFieldNames() {
114 return checkNotNull(fFields.keySet());
115 }
116
117 @Override
118 public Collection<ITmfEventField> getFields() {
119 return checkNotNull(fFields.values());
120 }
121
122 @Override
123 public ITmfEventField getField(final String... path) {
124 if (path.length == 1) {
125 return fFields.get(path[0]);
126 }
127 ITmfEventField field = this;
128 for (String name : path) {
129 field = field.getField(name);
130 if (field == null) {
131 return null;
132 }
133 }
134 return field;
135 }
136
137 // ------------------------------------------------------------------------
138 // Operations
139 // ------------------------------------------------------------------------
140
141 /**
142 * Create a root field from a list of labels.
143 *
144 * @param labels the list of labels
145 * @return the (flat) root list
146 */
147 public static final ITmfEventField makeRoot(final String[] labels) {
148 final ITmfEventField[] fields = new ITmfEventField[labels.length];
149 for (int i = 0; i < labels.length; i++) {
150 String label = checkNotNull(labels[i]);
151 fields[i] = new TmfEventField(label, null, null);
152 }
153 // Return a new root field;
154 return new TmfEventField(ITmfEventField.ROOT_FIELD_ID, null, fields);
155 }
156
157 // ------------------------------------------------------------------------
158 // Object
159 // ------------------------------------------------------------------------
160
161 @Override
162 public int hashCode() {
163 Object value = fValue;
164 final int prime = 31;
165 int result = 1;
166 result = prime * result + fName.hashCode();
167 result = prime * result + ((value == null) ? 0 : value.hashCode());
168 result = prime * result + fFields.hashCode();
169 return result;
170 }
171
172 @Override
173 public boolean equals(final Object obj) {
174 if (this == obj) {
175 return true;
176 }
177 if (obj == null) {
178 return false;
179 }
180 if (!(obj instanceof TmfEventField)) {
181 return false;
182 }
183
184 final TmfEventField other = (TmfEventField) obj;
185
186 /* Check that 'fName' is the same */
187 if (!fName.equals(other.fName)) {
188 return false;
189 }
190
191 /* Check that 'fValue' is the same */
192 Object value = this.fValue;
193 if (value == null) {
194 if (other.fValue != null) {
195 return false;
196 }
197 } else if (!value.equals(other.fValue)) {
198 return false;
199 }
200
201 /* Check that 'fFields' are the same */
202 if (!fFields.equals(other.fFields)) {
203 return false;
204 }
205
206 return true;
207 }
208
209 @Override
210 public String toString() {
211 StringBuilder ret = new StringBuilder();
212 if (fName.equals(ITmfEventField.ROOT_FIELD_ID)) {
213 /*
214 * If this field is a top-level "field container", we will print its
215 * sub-fields directly.
216 */
217 appendSubFields(ret);
218
219 } else {
220 /* The field has its own values */
221 ret.append(fName);
222 ret.append('=');
223 ret.append(fValue);
224
225 if (!fFields.isEmpty()) {
226 /*
227 * In addition to its own name/value, this field also has
228 * sub-fields.
229 */
230 ret.append(" ["); //$NON-NLS-1$
231 appendSubFields(ret);
232 ret.append(']');
233 }
234 }
235 return ret.toString();
236 }
237
238 private void appendSubFields(StringBuilder sb) {
239 Joiner joiner = Joiner.on(", ").skipNulls(); //$NON-NLS-1$
240 sb.append(joiner.join(getFields()));
241 }
242
243 @Override
244 public String getFormattedValue() {
245 return getValue().toString();
246 }
247
248 }
This page took 0.037428 seconds and 5 git commands to generate.