Commit | Line | Data |
---|---|---|
8c8bf09f | 1 | /******************************************************************************* |
bbc1c411 | 2 | * Copyright (c) 2009, 2012 Ericsson |
306dc902 | 3 | * |
cbbcc354 | 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 | |
8c8bf09f ASL |
6 | * accompanies this distribution, and is available at |
7 | * http://www.eclipse.org/legal/epl-v10.html | |
306dc902 | 8 | * |
8c8bf09f | 9 | * Contributors: |
1f506a43 | 10 | * Francois Chouinard - Initial API and implementation |
bbc1c411 | 11 | * Francois Chouinard - Updated as per TMF Event Model 1.0 |
80349bf7 | 12 | * Alexandre Montplaisir - Removed Cloneable, made immutable |
8c8bf09f ASL |
13 | *******************************************************************************/ |
14 | ||
6c13869b | 15 | package org.eclipse.linuxtools.tmf.core.event; |
8c8bf09f | 16 | |
4c564a2d FC |
17 | import java.util.HashMap; |
18 | import java.util.Map; | |
19 | ||
8c8bf09f | 20 | /** |
b9e37ffd | 21 | * A basic implementation of ITmfEventField. |
8c8bf09f | 22 | * <p> |
b9e37ffd FC |
23 | * Non-value fields are structural (i.e. used to represent the event structure |
24 | * including optional fields) while the valued fields are actual event fields. | |
306dc902 | 25 | * |
b9e37ffd FC |
26 | * @version 1.0 |
27 | * @author Francois Chouinard | |
306dc902 | 28 | * |
b9e37ffd | 29 | * @see ITmfEvent |
f7703ed6 | 30 | * @see ITmfEventType |
8c8bf09f | 31 | */ |
80349bf7 | 32 | public class TmfEventField implements ITmfEventField { |
8c8bf09f | 33 | |
cbd4ad82 | 34 | // ------------------------------------------------------------------------ |
8c8bf09f | 35 | // Attributes |
cbd4ad82 | 36 | // ------------------------------------------------------------------------ |
8c8bf09f | 37 | |
80349bf7 AM |
38 | private final String fName; |
39 | private final Object fValue; | |
40 | private final ITmfEventField[] fFields; | |
8c8bf09f | 41 | |
80349bf7 AM |
42 | private final String[] fFieldNames; |
43 | private final Map<String, ITmfEventField> fNameMapping; | |
085d898f | 44 | |
cbd4ad82 | 45 | // ------------------------------------------------------------------------ |
8c8bf09f | 46 | // Constructors |
cbd4ad82 FC |
47 | // ------------------------------------------------------------------------ |
48 | ||
4c564a2d | 49 | /** |
75d42a16 | 50 | * Constructor for a structural field |
306dc902 | 51 | * |
4c564a2d | 52 | * @param name the event field id |
0d9a6d76 | 53 | * @param fields the list of subfields |
4c564a2d | 54 | */ |
085d898f | 55 | public TmfEventField(final String name, final ITmfEventField[] fields) { |
75d42a16 | 56 | this(name, null, fields); |
4c564a2d FC |
57 | } |
58 | ||
59 | /** | |
f7703ed6 | 60 | * Constructor for a terminal field (no subfields) |
306dc902 | 61 | * |
4c564a2d | 62 | * @param name the event field id |
75d42a16 | 63 | * @param value the event field value |
4c564a2d | 64 | */ |
085d898f | 65 | public TmfEventField(final String name, final Object value) { |
75d42a16 | 66 | this(name, value, null); |
4c564a2d FC |
67 | } |
68 | ||
8c8bf09f | 69 | /** |
cbbcc354 | 70 | * Full constructor |
306dc902 | 71 | * |
4c564a2d | 72 | * @param name the event field id |
cbbcc354 | 73 | * @param value the event field value |
0d9a6d76 | 74 | * @param fields the list of subfields |
8c8bf09f | 75 | */ |
085d898f | 76 | public TmfEventField(final String name, final Object value, final ITmfEventField[] fields) { |
b9e37ffd | 77 | if (name == null) { |
cbbcc354 | 78 | throw new IllegalArgumentException(); |
b9e37ffd | 79 | } |
4c564a2d | 80 | fName = name; |
cbbcc354 | 81 | fValue = value; |
80349bf7 AM |
82 | fFields = fields; |
83 | ||
84 | /* Fill the fFieldNames and fNameMapping structures */ | |
85 | final int nbFields = (fFields != null) ? fFields.length : 0; | |
86 | fFieldNames = new String[nbFields]; | |
87 | fNameMapping = new HashMap<String, ITmfEventField>(); | |
88 | ||
89 | for (int i = 0; i < nbFields; i++) { | |
90 | final String curName = fFields[i].getName(); | |
91 | fFieldNames[i] = curName; | |
92 | fNameMapping.put(curName, fFields[i]); | |
93 | } | |
28b94d61 FC |
94 | } |
95 | ||
96 | /** | |
cbbcc354 | 97 | * Copy constructor |
306dc902 | 98 | * |
cbbcc354 | 99 | * @param field the other event field |
28b94d61 | 100 | */ |
085d898f | 101 | public TmfEventField(final TmfEventField field) { |
b9e37ffd | 102 | if (field == null) { |
085d898f | 103 | throw new IllegalArgumentException(); |
b9e37ffd | 104 | } |
085d898f FC |
105 | fName = field.fName; |
106 | fValue = field.fValue; | |
107 | fFields = field.fFields; | |
108 | fFieldNames = field.fFieldNames; | |
80349bf7 | 109 | fNameMapping = field.fNameMapping; |
28b94d61 FC |
110 | } |
111 | ||
cbd4ad82 | 112 | // ------------------------------------------------------------------------ |
cbbcc354 | 113 | // ITmfEventField |
cbd4ad82 | 114 | // ------------------------------------------------------------------------ |
8c8bf09f | 115 | |
d7dbf09a FC |
116 | /* (non-Javadoc) |
117 | * @see org.eclipse.linuxtools.tmf.core.event.ITmfEventField#getName() | |
118 | */ | |
119 | @Override | |
4c564a2d FC |
120 | public String getName() { |
121 | return fName; | |
28b94d61 FC |
122 | } |
123 | ||
d7dbf09a FC |
124 | /* (non-Javadoc) |
125 | * @see org.eclipse.linuxtools.tmf.core.event.ITmfEventField#getValue() | |
126 | */ | |
127 | @Override | |
8c8bf09f ASL |
128 | public Object getValue() { |
129 | return fValue; | |
130 | } | |
131 | ||
d7dbf09a FC |
132 | /* (non-Javadoc) |
133 | * @see org.eclipse.linuxtools.tmf.core.event.ITmfEventField#getFieldNames() | |
134 | */ | |
135 | @Override | |
4c564a2d | 136 | public String[] getFieldNames() { |
80349bf7 | 137 | return fFieldNames; |
4c564a2d FC |
138 | } |
139 | ||
d7dbf09a FC |
140 | /* (non-Javadoc) |
141 | * @see org.eclipse.linuxtools.tmf.core.event.ITmfEventField#getFieldName(int) | |
142 | */ | |
143 | @Override | |
085d898f FC |
144 | public String getFieldName(final int index) { |
145 | final ITmfEventField field = getField(index); | |
b9e37ffd | 146 | if (field != null) { |
4c564a2d | 147 | return field.getName(); |
b9e37ffd | 148 | } |
4c564a2d FC |
149 | return null; |
150 | } | |
151 | ||
d7dbf09a FC |
152 | /* (non-Javadoc) |
153 | * @see org.eclipse.linuxtools.tmf.core.event.ITmfEventField#getFields() | |
154 | */ | |
155 | @Override | |
4c564a2d | 156 | public ITmfEventField[] getFields() { |
80349bf7 | 157 | return (fFields != null) ? fFields : new ITmfEventField[0]; |
4c564a2d FC |
158 | } |
159 | ||
d7dbf09a FC |
160 | /* (non-Javadoc) |
161 | * @see org.eclipse.linuxtools.tmf.core.event.ITmfEventField#getField(java.lang.String) | |
162 | */ | |
163 | @Override | |
085d898f | 164 | public ITmfEventField getField(final String name) { |
4c564a2d FC |
165 | return fNameMapping.get(name); |
166 | } | |
167 | ||
d7dbf09a FC |
168 | /* (non-Javadoc) |
169 | * @see org.eclipse.linuxtools.tmf.core.event.ITmfEventField#getField(int) | |
170 | */ | |
171 | @Override | |
085d898f | 172 | public ITmfEventField getField(final int index) { |
b9e37ffd | 173 | if (fFields != null && index >= 0 && index < fFields.length) { |
4c564a2d | 174 | return fFields[index]; |
b9e37ffd | 175 | } |
4c564a2d | 176 | return null; |
cbbcc354 | 177 | } |
178 | ||
4c564a2d FC |
179 | // ------------------------------------------------------------------------ |
180 | // Operations | |
181 | // ------------------------------------------------------------------------ | |
182 | ||
183 | /** | |
184 | * Create a root field from a list of labels. | |
306dc902 | 185 | * |
4c564a2d FC |
186 | * @param labels the list of labels |
187 | * @return the (flat) root list | |
188 | */ | |
085d898f FC |
189 | public final static ITmfEventField makeRoot(final String[] labels) { |
190 | final ITmfEventField[] fields = new ITmfEventField[labels.length]; | |
b9e37ffd | 191 | for (int i = 0; i < labels.length; i++) { |
4c564a2d | 192 | fields[i] = new TmfEventField(labels[i], null); |
b9e37ffd FC |
193 | } |
194 | // Return a new root field; | |
195 | return new TmfEventField(ITmfEventField.ROOT_FIELD_ID, fields); | |
4c564a2d FC |
196 | } |
197 | ||
cbd4ad82 FC |
198 | // ------------------------------------------------------------------------ |
199 | // Object | |
200 | // ------------------------------------------------------------------------ | |
8c8bf09f | 201 | |
d7dbf09a FC |
202 | /* (non-Javadoc) |
203 | * @see java.lang.Object#hashCode() | |
204 | */ | |
28b94d61 | 205 | @Override |
cbd4ad82 | 206 | public int hashCode() { |
cbbcc354 | 207 | final int prime = 31; |
208 | int result = 1; | |
75d42a16 | 209 | result = prime * result + fName.hashCode(); |
cbbcc354 | 210 | result = prime * result + ((fValue == null) ? 0 : fValue.hashCode()); |
2fb2eb37 | 211 | return result; |
cbd4ad82 FC |
212 | } |
213 | ||
d7dbf09a FC |
214 | /* (non-Javadoc) |
215 | * @see java.lang.Object#equals(java.lang.Object) | |
216 | */ | |
cbbcc354 | 217 | @Override |
085d898f | 218 | public boolean equals(final Object obj) { |
b9e37ffd | 219 | if (this == obj) { |
cbbcc354 | 220 | return true; |
b9e37ffd FC |
221 | } |
222 | if (obj == null) { | |
cbbcc354 | 223 | return false; |
b9e37ffd FC |
224 | } |
225 | if (!(obj instanceof TmfEventField)) { | |
cbbcc354 | 226 | return false; |
b9e37ffd | 227 | } |
085d898f | 228 | final TmfEventField other = (TmfEventField) obj; |
b9e37ffd | 229 | if (!fName.equals(other.fName)) { |
cbbcc354 | 230 | return false; |
b9e37ffd | 231 | } |
cbbcc354 | 232 | if (fValue == null) { |
b9e37ffd | 233 | if (other.fValue != null) { |
cbbcc354 | 234 | return false; |
b9e37ffd FC |
235 | } |
236 | } else if (!fValue.equals(other.fValue)) { | |
cbbcc354 | 237 | return false; |
b9e37ffd | 238 | } |
cbbcc354 | 239 | return true; |
28b94d61 FC |
240 | } |
241 | ||
d7dbf09a FC |
242 | /* (non-Javadoc) |
243 | * @see java.lang.Object#toString() | |
244 | */ | |
82b08e62 | 245 | @Override |
cbbcc354 | 246 | public String toString() { |
306dc902 AM |
247 | StringBuilder ret = new StringBuilder(); |
248 | if (fName.equals(ITmfEventField.ROOT_FIELD_ID)) { | |
249 | /* | |
250 | * If this field is a top-level "field container", we will print its | |
251 | * sub-fields directly. | |
252 | */ | |
253 | appendSubFields(ret); | |
254 | ||
255 | } else { | |
256 | /* The field has its own values */ | |
257 | ret.append(fName); | |
258 | ret.append('='); | |
259 | ret.append(fValue); | |
260 | ||
261 | if (fFields != null && fFields.length > 0) { | |
262 | /* | |
263 | * In addition to its own name/value, this field also has | |
264 | * sub-fields. | |
265 | */ | |
266 | ret.append(" ["); //$NON-NLS-1$ | |
267 | appendSubFields(ret); | |
268 | ret.append(']'); | |
269 | } | |
270 | } | |
271 | return ret.toString(); | |
272 | } | |
273 | ||
274 | private void appendSubFields(StringBuilder sb) { | |
275 | ITmfEventField field; | |
276 | for (int i = 0; i < getFields().length; i++) { | |
277 | field = getFields()[i]; | |
278 | if (i != 0) { | |
279 | sb.append(", ");//$NON-NLS-1$ | |
280 | } | |
281 | sb.append(field.toString()); | |
282 | } | |
8c8bf09f | 283 | } |
1f506a43 | 284 | |
cbbcc354 | 285 | } |