Commit | Line | Data |
---|---|---|
5d10d135 ASL |
1 | /******************************************************************************* |
2 | * Copyright (c) 2009 Ericsson | |
3 | * | |
4 | * All rights reserved. This program and the accompanying materials are | |
5 | * made 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 | * William Bourque (wbourque@gmail.com) - Initial API and implementation | |
11 | *******************************************************************************/ | |
12 | ||
5945cec9 | 13 | package org.eclipse.linuxtools.internal.lttng.core.event; |
5d10d135 | 14 | |
28b94d61 FC |
15 | import java.util.HashMap; |
16 | ||
0188b342 | 17 | import org.eclipse.linuxtools.lttng.jni.JniEvent; |
4c564a2d FC |
18 | import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; |
19 | import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; | |
20 | import org.eclipse.linuxtools.tmf.core.event.TmfEventField; | |
5d10d135 ASL |
21 | |
22 | /** | |
07d9e2ee FC |
23 | * <b><u>LttngEventContent</u></b><p> |
24 | * | |
25 | * Lttng specific implementation of the TmfEventContent.<p> | |
5d10d135 | 26 | */ |
4c564a2d FC |
27 | public class LttngEventContent extends TmfEventField { |
28 | ||
29 | private LttngEvent fParentEvent; | |
5d10d135 | 30 | |
28b94d61 | 31 | // Hash map that contain the (parsed) fields. This is the actual payload of the event. |
4c564a2d | 32 | private HashMap<String, LttngEventField> fFieldsMap = new HashMap<String, LttngEventField>(); |
28b94d61 | 33 | |
5d10d135 | 34 | /** |
28b94d61 | 35 | * Default constructor.<p> |
07d9e2ee | 36 | * |
5d10d135 | 37 | */ |
28b94d61 | 38 | public LttngEventContent() { |
a4115405 | 39 | super(ITmfEventField.ROOT_FIELD_ID, null); |
5d10d135 | 40 | } |
28b94d61 | 41 | |
5d10d135 | 42 | /** |
07d9e2ee | 43 | * Constructor with parameters.<p> |
5d10d135 | 44 | * |
28b94d61 FC |
45 | * @param thisParent Parent event for this content. |
46 | * | |
5945cec9 | 47 | * @see org.eclipse.linuxtools.internal.lttng.core.event.LttngEvent |
28b94d61 FC |
48 | */ |
49 | public LttngEventContent(LttngEvent thisParent) { | |
a4115405 | 50 | super(ITmfEventField.ROOT_FIELD_ID, null); |
4c564a2d | 51 | fParentEvent = thisParent; |
28b94d61 FC |
52 | } |
53 | ||
54 | /** | |
55 | * Constructor with parameters, with optional content.<p> | |
56 | * | |
57 | * @param thisParent Parent event for this content. | |
58 | * @param thisContent Already parsed content. | |
59 | * | |
5945cec9 | 60 | * @see org.eclipse.linuxtools.internal.lttng.core.event.LttngEvent |
5d10d135 | 61 | */ |
28b94d61 | 62 | public LttngEventContent(LttngEvent thisParent, HashMap<String, LttngEventField> thisContent) { |
a4115405 | 63 | super(ITmfEventField.ROOT_FIELD_ID, null); |
4c564a2d | 64 | fParentEvent = thisParent; |
28b94d61 | 65 | fFieldsMap = thisContent; |
5d10d135 ASL |
66 | } |
67 | ||
3fbd810a | 68 | /** |
07d9e2ee | 69 | * Copy Constructor.<p> |
3fbd810a | 70 | * |
07d9e2ee | 71 | * @param oldContent Content to copy from |
3fbd810a FC |
72 | */ |
73 | public LttngEventContent(LttngEventContent oldContent) { | |
4c564a2d | 74 | this((LttngEvent) oldContent.getEvent(), oldContent.getMapContent()); |
28b94d61 FC |
75 | } |
76 | ||
212550ba | 77 | public synchronized LttngEvent getEvent() { |
4c564a2d | 78 | return fParentEvent; |
28b94d61 FC |
79 | } |
80 | ||
212550ba | 81 | public synchronized void setEvent(LttngEvent newParent) { |
28b94d61 FC |
82 | fParentEvent = newParent; |
83 | } | |
84 | ||
85 | ||
86 | // *** VERIFY *** | |
87 | // These are not very useful, are they? | |
4c564a2d FC |
88 | |
89 | // public LttngEventType getType() { | |
90 | // return (LttngEventType)fParentEvent.getType(); | |
91 | // } | |
92 | ||
93 | // public void setType(LttngEventType newType) { | |
94 | // ((LttngEvent)fParentEvent).setType(newType); | |
95 | // } | |
3fbd810a | 96 | |
28b94d61 FC |
97 | |
98 | // ***TODO*** | |
99 | // Find a better way to ensure content is sane!! | |
100 | public void emptyContent() { | |
101 | fFieldsMap.clear(); | |
102 | } | |
103 | ||
104 | // ***VERIFY*** | |
0188b342 | 105 | // A bit weird to return the _currently_parsed fields (unlike all fields like getFields() ) |
28b94d61 | 106 | // Should we keep this? |
07d9e2ee | 107 | /** |
28b94d61 | 108 | * Return currently parsed fields in an object array format.<p> |
07d9e2ee | 109 | * |
28b94d61 | 110 | * @return Currently parsed fields. |
5d10d135 | 111 | */ |
5d3e8747 | 112 | public Object[] getRawContent() { |
4c564a2d | 113 | Object[] returnedContent = fFieldsMap.values().toArray(new Object[fFieldsMap.size()]); |
28b94d61 | 114 | return returnedContent; |
5d10d135 | 115 | } |
28b94d61 | 116 | |
07d9e2ee | 117 | /** |
28b94d61 | 118 | * Return currently parsed fields in the internal hashmap format.<p> |
07d9e2ee | 119 | * |
28b94d61 FC |
120 | * @return Currently parsed fields. |
121 | */ | |
5d3e8747 | 122 | public HashMap<String, LttngEventField> getMapContent() { |
28b94d61 FC |
123 | return fFieldsMap; |
124 | } | |
125 | ||
126 | // @SuppressWarnings("unchecked") | |
127 | // @Override | |
128 | // public LttngEventField[] getFields() { | |
129 | // LttngEventField tmpField = null; | |
130 | // | |
131 | // // *** TODO *** | |
132 | // // SLOW! SLOW! SLOW! We should prevent the user to use this!! | |
133 | // HashMap<String, Object> parsedContent = parseContent(); | |
134 | // | |
135 | // String contentKey = null; | |
136 | // Iterator<String> contentItr = parsedContent.keySet().iterator(); | |
137 | // while ( contentItr.hasNext() ) { | |
138 | // contentKey = contentItr.next(); | |
139 | // | |
140 | // tmpField = new LttngEventField(this, contentKey, parsedContent.get(contentKey)); | |
141 | // ((HashMap<String, LttngEventField>)fFields).put(contentKey, tmpField); | |
142 | // } | |
143 | // | |
144 | // return fFields.values().toArray(new LttngEventField[fFields.size()]); | |
145 | // } | |
146 | ||
147 | /** | |
148 | * Parse all fields and return them as an array of LttngFields.<p> | |
07d9e2ee | 149 | * |
28b94d61 | 150 | * Note : This function is heavy and should only be called if all fields are really needed. |
07d9e2ee | 151 | * |
28b94d61 | 152 | * @return All fields. |
07d9e2ee | 153 | * |
28b94d61 | 154 | * @see @see org.eclipse.linuxtools.lttng.event.LttngEventField |
5d10d135 ASL |
155 | */ |
156 | @Override | |
a55a769e | 157 | public synchronized LttngEventField[] getFields() { |
4c564a2d FC |
158 | int nbFields = fParentEvent.getType().getFieldNames().length; |
159 | ||
160 | if (fFieldsMap.size() < nbFields) { | |
0188b342 WB |
161 | LttngEventField tmpField = null; |
162 | LttngEventType tmpType = (LttngEventType)fParentEvent.getType(); | |
163 | ||
4c564a2d | 164 | for (int pos=0; pos < nbFields; pos++) { |
cbd4ad82 | 165 | String name = null; |
64fe8e8a FC |
166 | LttngEvent lttngTmpEvent = (LttngEvent)getEvent(); //added for easier debugging |
167 | JniEvent tmpEvent = (lttngTmpEvent).convertEventTmfToJni(); | |
0a8bb596 WB |
168 | |
169 | // tmpEvent == null probably mean there is a discrepancy between Eclipse and C library | |
170 | // An error was probably printed in convertEventTmfToJni() already, but keep in mind this is SERIOUS | |
171 | if ( tmpEvent != null ) { | |
4c564a2d FC |
172 | // try { |
173 | name = tmpType.getFieldName(pos); | |
0a8bb596 WB |
174 | |
175 | Object newValue = tmpEvent.parseFieldByName(name); | |
4c564a2d | 176 | tmpField = new LttngEventField(name, newValue, null); |
0a8bb596 | 177 | fFieldsMap.put(name, tmpField); |
4c564a2d FC |
178 | // } |
179 | // catch (TmfNoSuchFieldException e) { | |
180 | // System.out.println("Invalid field position requested : " + pos + ", ignoring (getFields)."); //$NON-NLS-1$//$NON-NLS-2$ | |
181 | // } | |
0188b342 WB |
182 | } |
183 | } | |
5d10d135 | 184 | } |
28b94d61 | 185 | return fFieldsMap.values().toArray(new LttngEventField[fFieldsMap.size()]); |
5d10d135 ASL |
186 | } |
187 | ||
188 | /** | |
28b94d61 | 189 | * Parse a single field from its given position.<p> |
07d9e2ee | 190 | * |
28b94d61 | 191 | * @return The parsed field or null. |
07d9e2ee | 192 | * |
28b94d61 | 193 | * @see @see org.eclipse.linuxtools.lttng.event.LttngEventField |
5d10d135 | 194 | */ |
28b94d61 | 195 | @Override |
212550ba | 196 | public synchronized LttngEventField getField(int position) { |
28b94d61 | 197 | LttngEventField returnedField = null; |
cbd4ad82 | 198 | String label = null; |
4c564a2d FC |
199 | // try { |
200 | label = fParentEvent.getType().getFieldName(position); | |
d86b9d98 | 201 | returnedField = (LttngEventField) this.getField(label); |
4c564a2d FC |
202 | // } |
203 | // catch (TmfNoSuchFieldException e) { | |
204 | // System.out.println("Invalid field position requested : " + position + ", ignoring (getField)."); //$NON-NLS-1$//$NON-NLS-2$ | |
205 | // } | |
88144d4a | 206 | |
28b94d61 | 207 | return returnedField; |
5d10d135 ASL |
208 | } |
209 | ||
210 | /** | |
28b94d61 | 211 | * Parse a single field from its given name.<p> |
07d9e2ee | 212 | * |
28b94d61 | 213 | * @return The parsed field or null. |
07d9e2ee | 214 | * |
28b94d61 | 215 | * @see @see org.eclipse.linuxtools.lttng.event.LttngEventField |
5d10d135 | 216 | */ |
28b94d61 | 217 | @Override |
5d3e8747 | 218 | public synchronized LttngEventField getField(String name) { |
4bf17f4a | 219 | |
220 | // Check for generic table header fields | |
4c564a2d | 221 | if (name.equals(LttngEventType.CONTENT_LABEL) || name.equals(ITmfEvent.EVENT_FIELD_CONTENT)) { |
219e0f6d | 222 | return new LttngEventField(LttngEventType.CONTENT_LABEL, toString()); |
4c564a2d | 223 | } else if (name.equals(LttngEventType.MARKER_LABEL) || name.equals(ITmfEvent.EVENT_FIELD_TYPE)) { |
219e0f6d | 224 | return new LttngEventField(LttngEventType.MARKER_LABEL, fParentEvent.getType().getName()); |
4c564a2d | 225 | } else if (name.equals(LttngEventType.TRACE_LABEL) || name.equals(ITmfEvent.EVENT_FIELD_REFERENCE)) { |
219e0f6d | 226 | return new LttngEventField(LttngEventType.TRACE_LABEL, fParentEvent.getReference()); |
4c564a2d | 227 | } else if (name.equals(LttngEventType.TIMESTAMP_LABEL) || name.equals(ITmfEvent.EVENT_FIELD_TIMESTAMP)) { |
219e0f6d | 228 | return new LttngEventField(LttngEventType.TIMESTAMP_LABEL, fParentEvent.getTimestamp().toString()); |
4c564a2d | 229 | } else if (name.equals(ITmfEvent.EVENT_FIELD_SOURCE)) { |
219e0f6d | 230 | return new LttngEventField(ITmfEvent.EVENT_FIELD_SOURCE, fParentEvent.getSource()); |
4bf17f4a | 231 | } |
d86b9d98 | 232 | |
e31e01e8 | 233 | // *** VERIFY *** |
28b94d61 FC |
234 | // Should we check if the field exists in LttngType before parsing? |
235 | // It could avoid calling parse for non-existent fields but would waste some cpu cycle on check? | |
236 | LttngEventField returnedField = fFieldsMap.get(name); | |
5d10d135 | 237 | |
28b94d61 FC |
238 | if ( returnedField == null ) { |
239 | // *** VERIFY *** | |
240 | // Should we really make sure we didn't get null before creating/inserting a field? | |
0188b342 WB |
241 | JniEvent tmpEvent = ((LttngEvent)getEvent()).convertEventTmfToJni(); |
242 | ||
243 | if ( tmpEvent != null) { | |
244 | Object newValue = tmpEvent.parseFieldByName(name); | |
245 | ||
246 | if ( newValue!= null ) { | |
4c564a2d | 247 | returnedField = new LttngEventField(name, newValue); |
0188b342 WB |
248 | fFieldsMap.put(name, returnedField ); |
249 | } | |
250 | } | |
5d10d135 | 251 | } |
28b94d61 | 252 | |
5d10d135 ASL |
253 | return returnedField; |
254 | } | |
255 | ||
4c564a2d FC |
256 | // // *** VERIFY *** |
257 | // // *** Is this even useful? | |
258 | // protected void parseContent() { | |
259 | // fSubfields = getFields(); | |
260 | // } | |
28b94d61 | 261 | |
5d10d135 | 262 | /** |
28b94d61 | 263 | * toString() method to print the content |
5d10d135 | 264 | * |
28b94d61 | 265 | * Note : this function parse all fields and so is very heavy to use. |
5d10d135 | 266 | */ |
6d848cce | 267 | @Override |
3b38ea61 | 268 | @SuppressWarnings("nls") |
28b94d61 | 269 | public String toString() { |
28b94d61 FC |
270 | LttngEventField[] allFields = getFields(); |
271 | ||
47e81b11 | 272 | StringBuffer strBuffer = new StringBuffer(); |
28b94d61 | 273 | for ( int pos=0; pos < allFields.length; pos++) { |
550d787e | 274 | if (pos != 0) strBuffer.append(","); |
47e81b11 | 275 | strBuffer.append(allFields[pos].toString()); |
28b94d61 FC |
276 | } |
277 | ||
47e81b11 | 278 | return strBuffer.toString(); |
5d10d135 | 279 | } |
1a971e96 FC |
280 | |
281 | @Override | |
282 | public LttngEventContent clone() { | |
283 | LttngEventContent clone = (LttngEventContent) super.clone(); | |
284 | LttngEventField[] fields = getFields(); | |
4c564a2d | 285 | LttngEventField[] subfields = new LttngEventField[fields.length]; |
1a971e96 | 286 | for (int i = 0; i < fields.length; i++) { |
4c564a2d | 287 | subfields[i] = (LttngEventField) fields[i].clone(); |
1a971e96 | 288 | } |
4c564a2d | 289 | clone.setValue(getValue(), subfields); |
1a971e96 FC |
290 | clone.fFieldsMap = new HashMap<String, LttngEventField>(); |
291 | for (String key : fFieldsMap.keySet()) { | |
212550ba | 292 | clone.fFieldsMap.put(key, ((LttngEventField) fFieldsMap.get(key)).clone()); |
1a971e96 FC |
293 | } |
294 | return clone; | |
295 | } | |
296 | ||
212550ba FC |
297 | /* (non-Javadoc) |
298 | * @see java.lang.Object#hashCode() | |
299 | */ | |
300 | @Override | |
301 | public int hashCode() { | |
302 | final int prime = 31; | |
303 | int result = super.hashCode(); | |
304 | result = prime * result + ((fFieldsMap == null) ? 0 : fFieldsMap.hashCode()); | |
305 | return result; | |
306 | } | |
307 | ||
308 | /* (non-Javadoc) | |
309 | * @see java.lang.Object#equals(java.lang.Object) | |
310 | */ | |
311 | @Override | |
312 | public boolean equals(Object obj) { | |
313 | if (this == obj) { | |
314 | return true; | |
315 | } | |
316 | if (!super.equals(obj)) { | |
317 | return false; | |
318 | } | |
319 | if (!(obj instanceof LttngEventContent)) { | |
320 | return false; | |
321 | } | |
322 | LttngEventContent other = (LttngEventContent) obj; | |
323 | if (fFieldsMap == null) { | |
324 | if (other.fFieldsMap != null) { | |
325 | return false; | |
326 | } | |
327 | } else if (!fFieldsMap.equals(other.fFieldsMap)) { | |
328 | return false; | |
329 | } | |
330 | return true; | |
331 | } | |
332 | ||
5d10d135 | 333 | } |