Commit | Line | Data |
---|---|---|
8c8bf09f | 1 | /******************************************************************************* |
61759503 | 2 | * Copyright (c) 2009, 2013 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 | ||
8c8bf09f | 49 | /** |
cbbcc354 | 50 | * Full constructor |
306dc902 | 51 | * |
4c564a2d | 52 | * @param name the event field id |
cbbcc354 | 53 | * @param value the event field value |
0d9a6d76 | 54 | * @param fields the list of subfields |
8c8bf09f | 55 | */ |
085d898f | 56 | public TmfEventField(final String name, final Object value, final ITmfEventField[] fields) { |
b9e37ffd | 57 | if (name == null) { |
cbbcc354 | 58 | throw new IllegalArgumentException(); |
b9e37ffd | 59 | } |
4c564a2d | 60 | fName = name; |
cbbcc354 | 61 | fValue = value; |
80349bf7 AM |
62 | fFields = fields; |
63 | ||
64 | /* Fill the fFieldNames and fNameMapping structures */ | |
65 | final int nbFields = (fFields != null) ? fFields.length : 0; | |
66 | fFieldNames = new String[nbFields]; | |
a4524c1b | 67 | fNameMapping = new HashMap<>(); |
80349bf7 AM |
68 | |
69 | for (int i = 0; i < nbFields; i++) { | |
70 | final String curName = fFields[i].getName(); | |
71 | fFieldNames[i] = curName; | |
72 | fNameMapping.put(curName, fFields[i]); | |
73 | } | |
28b94d61 FC |
74 | } |
75 | ||
76 | /** | |
cbbcc354 | 77 | * Copy constructor |
306dc902 | 78 | * |
cbbcc354 | 79 | * @param field the other event field |
28b94d61 | 80 | */ |
085d898f | 81 | public TmfEventField(final TmfEventField field) { |
b9e37ffd | 82 | if (field == null) { |
085d898f | 83 | throw new IllegalArgumentException(); |
b9e37ffd | 84 | } |
085d898f FC |
85 | fName = field.fName; |
86 | fValue = field.fValue; | |
87 | fFields = field.fFields; | |
88 | fFieldNames = field.fFieldNames; | |
80349bf7 | 89 | fNameMapping = field.fNameMapping; |
28b94d61 FC |
90 | } |
91 | ||
cbd4ad82 | 92 | // ------------------------------------------------------------------------ |
cbbcc354 | 93 | // ITmfEventField |
cbd4ad82 | 94 | // ------------------------------------------------------------------------ |
8c8bf09f | 95 | |
d7dbf09a | 96 | @Override |
4c564a2d FC |
97 | public String getName() { |
98 | return fName; | |
28b94d61 FC |
99 | } |
100 | ||
d7dbf09a | 101 | @Override |
8c8bf09f ASL |
102 | public Object getValue() { |
103 | return fValue; | |
104 | } | |
105 | ||
d7dbf09a | 106 | @Override |
4c564a2d | 107 | public String[] getFieldNames() { |
80349bf7 | 108 | return fFieldNames; |
4c564a2d FC |
109 | } |
110 | ||
d7dbf09a | 111 | @Override |
085d898f FC |
112 | public String getFieldName(final int index) { |
113 | final ITmfEventField field = getField(index); | |
b9e37ffd | 114 | if (field != null) { |
4c564a2d | 115 | return field.getName(); |
b9e37ffd | 116 | } |
4c564a2d FC |
117 | return null; |
118 | } | |
119 | ||
d7dbf09a | 120 | @Override |
4c564a2d | 121 | public ITmfEventField[] getFields() { |
80349bf7 | 122 | return (fFields != null) ? fFields : new ITmfEventField[0]; |
4c564a2d FC |
123 | } |
124 | ||
d7dbf09a | 125 | @Override |
085d898f | 126 | public ITmfEventField getField(final String name) { |
4c564a2d FC |
127 | return fNameMapping.get(name); |
128 | } | |
129 | ||
d7dbf09a | 130 | @Override |
085d898f | 131 | public ITmfEventField getField(final int index) { |
b9e37ffd | 132 | if (fFields != null && index >= 0 && index < fFields.length) { |
4c564a2d | 133 | return fFields[index]; |
b9e37ffd | 134 | } |
4c564a2d | 135 | return null; |
cbbcc354 | 136 | } |
137 | ||
6c204912 GB |
138 | /** |
139 | * @since 3.0 | |
140 | */ | |
141 | @Override | |
142 | public ITmfEventField getSubField(final String[] names) { | |
143 | ITmfEventField field = this; | |
144 | for (String name : names) { | |
145 | field = field.getField(name); | |
146 | if (field == null) { | |
147 | return null; | |
148 | } | |
149 | } | |
150 | return field; | |
151 | } | |
152 | ||
4c564a2d FC |
153 | // ------------------------------------------------------------------------ |
154 | // Operations | |
155 | // ------------------------------------------------------------------------ | |
156 | ||
157 | /** | |
158 | * Create a root field from a list of labels. | |
306dc902 | 159 | * |
4c564a2d FC |
160 | * @param labels the list of labels |
161 | * @return the (flat) root list | |
162 | */ | |
085d898f FC |
163 | public final static ITmfEventField makeRoot(final String[] labels) { |
164 | final ITmfEventField[] fields = new ITmfEventField[labels.length]; | |
b9e37ffd | 165 | for (int i = 0; i < labels.length; i++) { |
214cc822 | 166 | fields[i] = new TmfEventField(labels[i], null, null); |
b9e37ffd FC |
167 | } |
168 | // Return a new root field; | |
214cc822 | 169 | return new TmfEventField(ITmfEventField.ROOT_FIELD_ID, null, fields); |
4c564a2d FC |
170 | } |
171 | ||
cbd4ad82 FC |
172 | // ------------------------------------------------------------------------ |
173 | // Object | |
174 | // ------------------------------------------------------------------------ | |
8c8bf09f | 175 | |
28b94d61 | 176 | @Override |
cbd4ad82 | 177 | public int hashCode() { |
cbbcc354 | 178 | final int prime = 31; |
179 | int result = 1; | |
75d42a16 | 180 | result = prime * result + fName.hashCode(); |
cbbcc354 | 181 | result = prime * result + ((fValue == null) ? 0 : fValue.hashCode()); |
2fb2eb37 | 182 | return result; |
cbd4ad82 FC |
183 | } |
184 | ||
cbbcc354 | 185 | @Override |
085d898f | 186 | public boolean equals(final Object obj) { |
b9e37ffd | 187 | if (this == obj) { |
cbbcc354 | 188 | return true; |
b9e37ffd FC |
189 | } |
190 | if (obj == null) { | |
cbbcc354 | 191 | return false; |
b9e37ffd FC |
192 | } |
193 | if (!(obj instanceof TmfEventField)) { | |
cbbcc354 | 194 | return false; |
b9e37ffd | 195 | } |
085d898f | 196 | final TmfEventField other = (TmfEventField) obj; |
b9e37ffd | 197 | if (!fName.equals(other.fName)) { |
cbbcc354 | 198 | return false; |
b9e37ffd | 199 | } |
cbbcc354 | 200 | if (fValue == null) { |
b9e37ffd | 201 | if (other.fValue != null) { |
cbbcc354 | 202 | return false; |
b9e37ffd FC |
203 | } |
204 | } else if (!fValue.equals(other.fValue)) { | |
cbbcc354 | 205 | return false; |
b9e37ffd | 206 | } |
cbbcc354 | 207 | return true; |
28b94d61 FC |
208 | } |
209 | ||
82b08e62 | 210 | @Override |
cbbcc354 | 211 | public String toString() { |
306dc902 AM |
212 | StringBuilder ret = new StringBuilder(); |
213 | if (fName.equals(ITmfEventField.ROOT_FIELD_ID)) { | |
214 | /* | |
215 | * If this field is a top-level "field container", we will print its | |
216 | * sub-fields directly. | |
217 | */ | |
218 | appendSubFields(ret); | |
219 | ||
220 | } else { | |
221 | /* The field has its own values */ | |
222 | ret.append(fName); | |
223 | ret.append('='); | |
224 | ret.append(fValue); | |
225 | ||
226 | if (fFields != null && fFields.length > 0) { | |
227 | /* | |
228 | * In addition to its own name/value, this field also has | |
229 | * sub-fields. | |
230 | */ | |
231 | ret.append(" ["); //$NON-NLS-1$ | |
232 | appendSubFields(ret); | |
233 | ret.append(']'); | |
234 | } | |
235 | } | |
236 | return ret.toString(); | |
237 | } | |
238 | ||
239 | private void appendSubFields(StringBuilder sb) { | |
240 | ITmfEventField field; | |
241 | for (int i = 0; i < getFields().length; i++) { | |
242 | field = getFields()[i]; | |
243 | if (i != 0) { | |
244 | sb.append(", ");//$NON-NLS-1$ | |
245 | } | |
246 | sb.append(field.toString()); | |
247 | } | |
8c8bf09f | 248 | } |
1f506a43 | 249 | |
8f86c552 GB |
250 | /** |
251 | * @since 2.0 | |
252 | */ | |
253 | @Override | |
254 | public String getFormattedValue() { | |
255 | return getValue().toString(); | |
256 | } | |
257 | ||
cbbcc354 | 258 | } |