ss: Move plugins to Trace Compass namespace
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / event / TmfEventField.java
1 /*******************************************************************************
2 * Copyright (c) 2009, 2014 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 *******************************************************************************/
14
15 package org.eclipse.linuxtools.tmf.core.event;
16
17 import java.util.Collection;
18
19 import org.eclipse.jdt.annotation.NonNull;
20 import org.eclipse.jdt.annotation.Nullable;
21
22 import com.google.common.base.Joiner;
23 import com.google.common.collect.ImmutableMap;
24
25 /**
26 * A basic implementation of ITmfEventField.
27 * <p>
28 * Non-value fields are structural (i.e. used to represent the event structure
29 * including optional fields) while the valued fields are actual event fields.
30 *
31 * @version 1.0
32 * @author Francois Chouinard
33 *
34 * @see ITmfEvent
35 * @see ITmfEventType
36 */
37 public class TmfEventField implements ITmfEventField {
38
39 // ------------------------------------------------------------------------
40 // Attributes
41 // ------------------------------------------------------------------------
42
43 private final @NonNull String fName;
44 private final @Nullable Object fValue;
45 private final @NonNull ImmutableMap<String, ITmfEventField> fFields;
46
47 // ------------------------------------------------------------------------
48 // Constructors
49 // ------------------------------------------------------------------------
50
51 /**
52 * Full constructor
53 *
54 * @param name
55 * the event field id
56 * @param value
57 * the event field value
58 * @param fields
59 * the list of subfields
60 * @throws IllegalArgumentException
61 * If 'name' is null, or if 'fields' has duplicate field names.
62 */
63 @SuppressWarnings("null") /* ImmutableMap methods do not return @NonNull */
64 public TmfEventField(String name, @Nullable Object value, @Nullable ITmfEventField[] fields) {
65 if (name == null) {
66 throw new IllegalArgumentException();
67 }
68 fName = name;
69 fValue = value;
70
71 if (fields == null) {
72 fFields = ImmutableMap.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 = 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 /**
113 * @since 3.0
114 */
115 @Override
116 public Collection<String> getFieldNames() {
117 return fFields.keySet();
118 }
119
120 /**
121 * @since 3.0
122 */
123 @Override
124 public Collection<ITmfEventField> getFields() {
125 return fFields.values();
126 }
127
128 @Override
129 public ITmfEventField getField(final String name) {
130 return fFields.get(name);
131 }
132
133 /**
134 * @since 3.0
135 */
136 @Override
137 public ITmfEventField getSubField(final String... names) {
138 ITmfEventField field = this;
139 for (String name : names) {
140 field = field.getField(name);
141 if (field == null) {
142 return null;
143 }
144 }
145 return field;
146 }
147
148 // ------------------------------------------------------------------------
149 // Operations
150 // ------------------------------------------------------------------------
151
152 /**
153 * Create a root field from a list of labels.
154 *
155 * @param labels the list of labels
156 * @return the (flat) root list
157 */
158 public final static ITmfEventField makeRoot(final String[] labels) {
159 final ITmfEventField[] fields = new ITmfEventField[labels.length];
160 for (int i = 0; i < labels.length; i++) {
161 fields[i] = new TmfEventField(labels[i], null, null);
162 }
163 // Return a new root field;
164 return new TmfEventField(ITmfEventField.ROOT_FIELD_ID, null, fields);
165 }
166
167 // ------------------------------------------------------------------------
168 // Object
169 // ------------------------------------------------------------------------
170
171 @Override
172 public int hashCode() {
173 Object value = fValue;
174 final int prime = 31;
175 int result = 1;
176 result = prime * result + fName.hashCode();
177 result = prime * result + ((value == null) ? 0 : value.hashCode());
178 result = prime * result + fFields.hashCode();
179 return result;
180 }
181
182 @Override
183 public boolean equals(final Object obj) {
184 if (this == obj) {
185 return true;
186 }
187 if (obj == null) {
188 return false;
189 }
190 if (!(obj instanceof TmfEventField)) {
191 return false;
192 }
193
194 final TmfEventField other = (TmfEventField) obj;
195
196 /* Check that 'fName' is the same */
197 if (!fName.equals(other.fName)) {
198 return false;
199 }
200
201 /* Check that 'fValue' is the same */
202 Object value = this.fValue;
203 if (value == null) {
204 if (other.fValue != null) {
205 return false;
206 }
207 } else if (!value.equals(other.fValue)) {
208 return false;
209 }
210
211 /* Check that 'fFields' are the same */
212 if (!fFields.equals(other.fFields)) {
213 return false;
214 }
215
216 return true;
217 }
218
219 @Override
220 public String toString() {
221 StringBuilder ret = new StringBuilder();
222 if (fName.equals(ITmfEventField.ROOT_FIELD_ID)) {
223 /*
224 * If this field is a top-level "field container", we will print its
225 * sub-fields directly.
226 */
227 appendSubFields(ret);
228
229 } else {
230 /* The field has its own values */
231 ret.append(fName);
232 ret.append('=');
233 ret.append(fValue);
234
235 if (!fFields.isEmpty()) {
236 /*
237 * In addition to its own name/value, this field also has
238 * sub-fields.
239 */
240 ret.append(" ["); //$NON-NLS-1$
241 appendSubFields(ret);
242 ret.append(']');
243 }
244 }
245 return ret.toString();
246 }
247
248 private void appendSubFields(StringBuilder sb) {
249 Joiner joiner = Joiner.on(", ").skipNulls(); //$NON-NLS-1$
250 sb.append(joiner.join(getFields()));
251 }
252
253 /**
254 * @since 2.0
255 */
256 @Override
257 public String getFormattedValue() {
258 return getValue().toString();
259 }
260
261 }
This page took 0.037521 seconds and 5 git commands to generate.