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]; | |
67 | fNameMapping = new HashMap<String, ITmfEventField>(); | |
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 | ||
4c564a2d FC |
138 | // ------------------------------------------------------------------------ |
139 | // Operations | |
140 | // ------------------------------------------------------------------------ | |
141 | ||
142 | /** | |
143 | * Create a root field from a list of labels. | |
306dc902 | 144 | * |
4c564a2d FC |
145 | * @param labels the list of labels |
146 | * @return the (flat) root list | |
147 | */ | |
085d898f FC |
148 | public final static ITmfEventField makeRoot(final String[] labels) { |
149 | final ITmfEventField[] fields = new ITmfEventField[labels.length]; | |
b9e37ffd | 150 | for (int i = 0; i < labels.length; i++) { |
214cc822 | 151 | fields[i] = new TmfEventField(labels[i], null, null); |
b9e37ffd FC |
152 | } |
153 | // Return a new root field; | |
214cc822 | 154 | return new TmfEventField(ITmfEventField.ROOT_FIELD_ID, null, fields); |
4c564a2d FC |
155 | } |
156 | ||
cbd4ad82 FC |
157 | // ------------------------------------------------------------------------ |
158 | // Object | |
159 | // ------------------------------------------------------------------------ | |
8c8bf09f | 160 | |
28b94d61 | 161 | @Override |
cbd4ad82 | 162 | public int hashCode() { |
cbbcc354 | 163 | final int prime = 31; |
164 | int result = 1; | |
75d42a16 | 165 | result = prime * result + fName.hashCode(); |
cbbcc354 | 166 | result = prime * result + ((fValue == null) ? 0 : fValue.hashCode()); |
2fb2eb37 | 167 | return result; |
cbd4ad82 FC |
168 | } |
169 | ||
cbbcc354 | 170 | @Override |
085d898f | 171 | public boolean equals(final Object obj) { |
b9e37ffd | 172 | if (this == obj) { |
cbbcc354 | 173 | return true; |
b9e37ffd FC |
174 | } |
175 | if (obj == null) { | |
cbbcc354 | 176 | return false; |
b9e37ffd FC |
177 | } |
178 | if (!(obj instanceof TmfEventField)) { | |
cbbcc354 | 179 | return false; |
b9e37ffd | 180 | } |
085d898f | 181 | final TmfEventField other = (TmfEventField) obj; |
b9e37ffd | 182 | if (!fName.equals(other.fName)) { |
cbbcc354 | 183 | return false; |
b9e37ffd | 184 | } |
cbbcc354 | 185 | if (fValue == null) { |
b9e37ffd | 186 | if (other.fValue != null) { |
cbbcc354 | 187 | return false; |
b9e37ffd FC |
188 | } |
189 | } else if (!fValue.equals(other.fValue)) { | |
cbbcc354 | 190 | return false; |
b9e37ffd | 191 | } |
cbbcc354 | 192 | return true; |
28b94d61 FC |
193 | } |
194 | ||
82b08e62 | 195 | @Override |
cbbcc354 | 196 | public String toString() { |
306dc902 AM |
197 | StringBuilder ret = new StringBuilder(); |
198 | if (fName.equals(ITmfEventField.ROOT_FIELD_ID)) { | |
199 | /* | |
200 | * If this field is a top-level "field container", we will print its | |
201 | * sub-fields directly. | |
202 | */ | |
203 | appendSubFields(ret); | |
204 | ||
205 | } else { | |
206 | /* The field has its own values */ | |
207 | ret.append(fName); | |
208 | ret.append('='); | |
209 | ret.append(fValue); | |
210 | ||
211 | if (fFields != null && fFields.length > 0) { | |
212 | /* | |
213 | * In addition to its own name/value, this field also has | |
214 | * sub-fields. | |
215 | */ | |
216 | ret.append(" ["); //$NON-NLS-1$ | |
217 | appendSubFields(ret); | |
218 | ret.append(']'); | |
219 | } | |
220 | } | |
221 | return ret.toString(); | |
222 | } | |
223 | ||
224 | private void appendSubFields(StringBuilder sb) { | |
225 | ITmfEventField field; | |
226 | for (int i = 0; i < getFields().length; i++) { | |
227 | field = getFields()[i]; | |
228 | if (i != 0) { | |
229 | sb.append(", ");//$NON-NLS-1$ | |
230 | } | |
231 | sb.append(field.toString()); | |
232 | } | |
8c8bf09f | 233 | } |
1f506a43 | 234 | |
8f86c552 GB |
235 | /** |
236 | * @since 2.0 | |
237 | */ | |
238 | @Override | |
239 | public String getFormattedValue() { | |
240 | return getValue().toString(); | |
241 | } | |
242 | ||
cbbcc354 | 243 | } |