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 | ||
13 | package org.eclipse.linuxtools.lttng.event; | |
14 | ||
15 | import java.util.HashMap; | |
16 | ||
17 | import org.eclipse.linuxtools.lttng.jni.JniEvent; | |
18 | import org.eclipse.linuxtools.tmf.event.TmfEventContent; | |
19 | import org.eclipse.linuxtools.tmf.event.TmfNoSuchFieldException; | |
20 | ||
21 | /** | |
22 | * <b><u>LttngEventContent</u></b><p> | |
23 | * | |
24 | * Lttng specific implementation of the TmfEventContent.<p> | |
25 | */ | |
26 | public class LttngEventContent extends TmfEventContent { | |
27 | ||
28 | // Hash map that contain the (parsed) fields. This is the actual payload of the event. | |
29 | HashMap<String, LttngEventField> fFieldsMap = new HashMap<String, LttngEventField>(); | |
30 | ||
31 | /** | |
32 | * Default constructor.<p> | |
33 | * | |
34 | * | |
35 | */ | |
36 | public LttngEventContent() { | |
37 | super(null, null); | |
38 | } | |
39 | ||
40 | /** | |
41 | * Constructor with parameters.<p> | |
42 | * | |
43 | * @param thisParent Parent event for this content. | |
44 | * | |
45 | * @see org.eclipse.linuxtools.lttng.event.LttngEvent | |
46 | */ | |
47 | public LttngEventContent(LttngEvent thisParent) { | |
48 | super(thisParent, null); | |
49 | } | |
50 | ||
51 | /** | |
52 | * Constructor with parameters, with optional content.<p> | |
53 | * | |
54 | * @param thisParent Parent event for this content. | |
55 | * @param thisContent Already parsed content. | |
56 | * | |
57 | * @see org.eclipse.linuxtools.lttng.event.LttngEvent | |
58 | */ | |
59 | public LttngEventContent(LttngEvent thisParent, HashMap<String, LttngEventField> thisContent) { | |
60 | super(thisParent, null); | |
61 | ||
62 | fFieldsMap = thisContent; | |
63 | } | |
64 | ||
65 | /** | |
66 | * Copy Constructor.<p> | |
67 | * | |
68 | * @param oldContent Content to copy from | |
69 | */ | |
70 | public LttngEventContent(LttngEventContent oldContent) { | |
71 | this((LttngEvent)oldContent.getEvent(), oldContent.getRawContent() ); | |
72 | } | |
73 | ||
74 | ||
75 | @Override | |
76 | public LttngEvent getEvent() { | |
77 | return (LttngEvent)fParentEvent; | |
78 | } | |
79 | ||
80 | public void setEvent(LttngEvent newParent) { | |
81 | fParentEvent = newParent; | |
82 | } | |
83 | ||
84 | ||
85 | // *** VERIFY *** | |
86 | // These are not very useful, are they? | |
87 | @Override | |
88 | public LttngEventType getType() { | |
89 | return (LttngEventType)fParentEvent.getType(); | |
90 | } | |
91 | public void setType(LttngEventType newType) { | |
92 | ((LttngEvent)fParentEvent).setType(newType); | |
93 | } | |
94 | ||
95 | ||
96 | // ***TODO*** | |
97 | // Find a better way to ensure content is sane!! | |
98 | public void emptyContent() { | |
99 | fFieldsMap.clear(); | |
100 | } | |
101 | ||
102 | // ***VERIFY*** | |
103 | // A bit weird to return the _currently_parsed fields (unlike all fields like getFields() ) | |
104 | // Should we keep this? | |
105 | /** | |
106 | * Return currently parsed fields in an object array format.<p> | |
107 | * | |
108 | * @return Currently parsed fields. | |
109 | */ | |
110 | @Override | |
111 | public Object[] getContent() { | |
112 | Object[] returnedContent = fFieldsMap.values().toArray( new Object[fFieldsMap.size()] ); | |
113 | ||
114 | return returnedContent; | |
115 | } | |
116 | ||
117 | /** | |
118 | * Return currently parsed fields in the internal hashmap format.<p> | |
119 | * | |
120 | * @return Currently parsed fields. | |
121 | */ | |
122 | public HashMap<String, LttngEventField> getRawContent() { | |
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> | |
149 | * | |
150 | * Note : This function is heavy and should only be called if all fields are really needed. | |
151 | * | |
152 | * @return All fields. | |
153 | * | |
154 | * @see @see org.eclipse.linuxtools.lttng.event.LttngEventField | |
155 | */ | |
156 | @Override | |
157 | public synchronized LttngEventField[] getFields() { | |
158 | if ( fFieldsMap.size() < fParentEvent.getType().getNbFields() ) { | |
159 | LttngEventField tmpField = null; | |
160 | LttngEventType tmpType = (LttngEventType)fParentEvent.getType(); | |
161 | ||
162 | for ( int pos=0; pos<tmpType.getNbFields(); pos++ ) { | |
163 | String name = null; | |
164 | JniEvent tmpEvent = ((LttngEvent)getEvent()).convertEventTmfToJni(); | |
165 | ||
166 | // tmpEvent == null probably mean there is a discrepancy between Eclipse and C library | |
167 | // An error was probably printed in convertEventTmfToJni() already, but keep in mind this is SERIOUS | |
168 | if ( tmpEvent != null ) { | |
169 | try { | |
170 | name = tmpType.getLabel(pos); | |
171 | ||
172 | Object newValue = tmpEvent.parseFieldByName(name); | |
173 | tmpField = new LttngEventField(this, name, newValue ); | |
174 | fFieldsMap.put(name, tmpField); | |
175 | } | |
176 | catch (TmfNoSuchFieldException e) { | |
177 | System.out.println("Invalid field position requested : " + pos + ", ignoring (getFields)."); | |
178 | } | |
179 | } | |
180 | } | |
181 | } | |
182 | return fFieldsMap.values().toArray(new LttngEventField[fFieldsMap.size()]); | |
183 | } | |
184 | ||
185 | /** | |
186 | * Parse a single field from its given position.<p> | |
187 | * | |
188 | * @return The parsed field or null. | |
189 | * | |
190 | * @see @see org.eclipse.linuxtools.lttng.event.LttngEventField | |
191 | */ | |
192 | @Override | |
193 | public LttngEventField getField(int position) { | |
194 | LttngEventField returnedField = null; | |
195 | String label = null; | |
196 | try { | |
197 | label = fParentEvent.getType().getLabel(position); | |
198 | ||
199 | returnedField = this.getField(label); | |
200 | } | |
201 | catch (TmfNoSuchFieldException e) { | |
202 | System.out.println("Invalid field position requested : " + position + ", ignoring (getField)."); | |
203 | } | |
204 | ||
205 | return returnedField; | |
206 | } | |
207 | ||
208 | /** | |
209 | * Parse a single field from its given name.<p> | |
210 | * | |
211 | * @return The parsed field or null. | |
212 | * | |
213 | * @see @see org.eclipse.linuxtools.lttng.event.LttngEventField | |
214 | */ | |
215 | @Override | |
216 | public synchronized LttngEventField getField(String name) { | |
217 | // *** VERIFY *** | |
218 | // Should we check if the field exists in LttngType before parsing? | |
219 | // It could avoid calling parse for non-existent fields but would waste some cpu cycle on check? | |
220 | LttngEventField returnedField = fFieldsMap.get(name); | |
221 | ||
222 | if ( returnedField == null ) { | |
223 | // *** VERIFY *** | |
224 | // Should we really make sure we didn't get null before creating/inserting a field? | |
225 | JniEvent tmpEvent = ((LttngEvent)getEvent()).convertEventTmfToJni(); | |
226 | ||
227 | if ( tmpEvent != null) { | |
228 | Object newValue = tmpEvent.parseFieldByName(name); | |
229 | ||
230 | if ( newValue!= null ) { | |
231 | returnedField = new LttngEventField(this, name, newValue); | |
232 | fFieldsMap.put(name, returnedField ); | |
233 | } | |
234 | } | |
235 | } | |
236 | ||
237 | return returnedField; | |
238 | } | |
239 | ||
240 | // *** VERIFY *** | |
241 | // *** Is this even useful? | |
242 | @Override | |
243 | protected void parseContent() { | |
244 | fFields = getFields(); | |
245 | } | |
246 | ||
247 | /** | |
248 | * toString() method to print the content | |
249 | * | |
250 | * Note : this function parse all fields and so is very heavy to use. | |
251 | */ | |
252 | @Override | |
253 | public String toString() { | |
254 | LttngEventField[] allFields = getFields(); | |
255 | ||
256 | StringBuffer strBuffer = new StringBuffer(); | |
257 | for ( int pos=0; pos < allFields.length; pos++) { | |
9aae0442 | 258 | if (pos != 0) strBuffer.append(","); |
5d10d135 ASL |
259 | strBuffer.append(allFields[pos].toString()); |
260 | } | |
261 | ||
262 | return strBuffer.toString(); | |
263 | ||
264 | } | |
265 | } |