Re-structure LTTng sub-project as per the Linux Tools guidelines
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / parsers / custom / CustomXmlTrace.java
CommitLineData
c3c5c786
FC
1/*******************************************************************************\r
2 * Copyright (c) 2010 Ericsson\r
3 * \r
4 * All rights reserved. This program and the accompanying materials are\r
5 * made available under the terms of the Eclipse Public License v1.0 which\r
6 * accompanies this distribution, and is available at\r
7 * http://www.eclipse.org/legal/epl-v10.html\r
8 * \r
9 * Contributors:\r
10 * Patrick Tasse - Initial API and implementation\r
11 *******************************************************************************/\r
12\r
13package org.eclipse.linuxtools.tmf.ui.parsers.custom;\r
14\r
15import java.io.ByteArrayInputStream;\r
16import java.io.File;\r
17import java.io.FileNotFoundException;\r
18import java.io.IOException;\r
19import java.io.RandomAccessFile;\r
20\r
21import javax.xml.parsers.DocumentBuilder;\r
22import javax.xml.parsers.DocumentBuilderFactory;\r
23import javax.xml.parsers.ParserConfigurationException;\r
24\r
6c13869b
FC
25import org.eclipse.linuxtools.tmf.core.event.TmfEvent;\r
26import org.eclipse.linuxtools.tmf.core.event.TmfEventReference;\r
27import org.eclipse.linuxtools.tmf.core.event.TmfEventSource;\r
28import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp;\r
29import org.eclipse.linuxtools.tmf.core.io.BufferedRandomAccessFile;\r
30import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;\r
31import org.eclipse.linuxtools.tmf.core.trace.ITmfLocation;\r
32import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;\r
33import org.eclipse.linuxtools.tmf.core.trace.TmfContext;\r
34import org.eclipse.linuxtools.tmf.core.trace.TmfLocation;\r
35import org.eclipse.linuxtools.tmf.core.trace.TmfTrace;\r
c3c5c786
FC
36import org.eclipse.linuxtools.tmf.ui.parsers.custom.CustomXmlTraceDefinition.InputAttribute;\r
37import org.eclipse.linuxtools.tmf.ui.parsers.custom.CustomXmlTraceDefinition.InputElement;\r
38import org.w3c.dom.Document;\r
39import org.w3c.dom.Element;\r
40import org.w3c.dom.Node;\r
41import org.w3c.dom.NodeList;\r
42import org.xml.sax.EntityResolver;\r
43import org.xml.sax.ErrorHandler;\r
44import org.xml.sax.InputSource;\r
45import org.xml.sax.SAXException;\r
46import org.xml.sax.SAXParseException;\r
47\r
48public class CustomXmlTrace extends TmfTrace<CustomXmlEvent> {\r
49\r
d7fcacc9
FC
50 private static final TmfLocation<Long> NULL_LOCATION = new TmfLocation<Long>((Long) null);\r
51 \r
c3c5c786 52 private CustomXmlTraceDefinition fDefinition;\r
d7fcacc9 53 private CustomXmlEventType fEventType;\r
c3c5c786
FC
54 private InputElement fRecordInputElement;\r
55 \r
4bf17f4a 56 public CustomXmlTrace(CustomXmlTraceDefinition definition) {\r
57 fDefinition = definition;\r
58 fEventType = new CustomXmlEventType(fDefinition);\r
59 fRecordInputElement = getRecordInputElement(fDefinition.rootInputElement);\r
60 }\r
61\r
c3c5c786
FC
62 public CustomXmlTrace(String name, CustomXmlTraceDefinition definition, String path, int cacheSize) throws FileNotFoundException {\r
63 super(name, CustomXmlEvent.class, path, cacheSize);\r
64 fDefinition = definition;\r
d7fcacc9 65 fEventType = new CustomXmlEventType(fDefinition);\r
c3c5c786
FC
66 fRecordInputElement = getRecordInputElement(fDefinition.rootInputElement);\r
67 }\r
68\r
69 @Override\r
70 public TmfContext seekLocation(ITmfLocation<?> location) {\r
71 //System.out.println(Thread.currentThread().getName() + "::" + getName() + " seekLocation(" + ((location == null || location.getLocation() == null) ? "null" : location) + ")");\r
72 //new Throwable().printStackTrace();\r
d7fcacc9
FC
73 CustomXmlTraceContext context = new CustomXmlTraceContext(NULL_LOCATION, ITmfContext.INITIAL_RANK);\r
74 if (NULL_LOCATION.equals(location) || !new File(getPath()).isFile()) {\r
c3c5c786
FC
75 return context;\r
76 }\r
77 try {\r
d7fcacc9 78 context.raFile = new BufferedRandomAccessFile(getPath(), "r"); //$NON-NLS-1$\r
c3c5c786
FC
79 if (location != null && location.getLocation() instanceof Long) {\r
80 context.raFile.seek((Long)location.getLocation());\r
81 }\r
82 \r
83 String line;\r
3b38ea61 84 String recordElementStart = "<" + fRecordInputElement.elementName; //$NON-NLS-1$\r
c3c5c786
FC
85 long rawPos = context.raFile.getFilePointer();\r
86 \r
d7fcacc9 87 while ((line = context.raFile.getNextLine()) != null) {\r
c3c5c786
FC
88 int idx = line.indexOf(recordElementStart); \r
89 if (idx != -1) {\r
90 context.setLocation(new TmfLocation<Long>(rawPos + idx));\r
91 return context;\r
92 }\r
93 rawPos = context.raFile.getFilePointer();\r
94 }\r
95 return context;\r
96 } catch (FileNotFoundException e) {\r
97 e.printStackTrace();\r
98 return context;\r
99 } catch (IOException e) {\r
100 e.printStackTrace();\r
101 return context;\r
102 }\r
103 \r
104 }\r
105\r
c76c54bb
FC
106 @Override\r
107 public TmfContext seekLocation(double ratio) {\r
108 try {\r
a79913eb
FC
109 BufferedRandomAccessFile raFile = new BufferedRandomAccessFile(getPath(), "r"); //$NON-NLS-1$\r
110 long pos = (long) (ratio * raFile.length());\r
111 while (pos > 0) {\r
112 raFile.seek(pos - 1);\r
113 if (raFile.read() == '\n') break;\r
114 pos--;\r
115 }\r
116 ITmfLocation<?> location = new TmfLocation<Long>(new Long(pos));\r
c76c54bb
FC
117 TmfContext context = seekLocation(location);\r
118 context.setRank(ITmfContext.UNKNOWN_RANK);\r
119 return context;\r
120 } catch (FileNotFoundException e) {\r
121 e.printStackTrace();\r
122 return new CustomXmlTraceContext(NULL_LOCATION, ITmfContext.INITIAL_RANK);\r
123 } catch (IOException e) {\r
124 e.printStackTrace();\r
125 return new CustomXmlTraceContext(NULL_LOCATION, ITmfContext.INITIAL_RANK);\r
126 }\r
127 }\r
128\r
129 @Override\r
130 public double getLocationRatio(ITmfLocation<?> location) {\r
131 try {\r
132 if (location.getLocation() instanceof Long) {\r
133 RandomAccessFile raFile = new RandomAccessFile(getPath(), "r"); //$NON-NLS-1$\r
134 return (double) ((Long) location.getLocation()) / raFile.length();\r
135 }\r
136 } catch (FileNotFoundException e) {\r
137 e.printStackTrace();\r
138 } catch (IOException e) {\r
139 e.printStackTrace();\r
140 }\r
141 return 0;\r
142 }\r
143\r
d4011df2 144 @Override\r
12c155f5
FC
145 @SuppressWarnings({ "rawtypes", "unchecked" })\r
146 public ITmfTrace copy() {\r
c3c5c786
FC
147 // TODO Auto-generated method stub\r
148 return null;\r
149 }\r
150 \r
151 @Override\r
152 public ITmfLocation<?> getCurrentLocation() {\r
a79913eb
FC
153 // TODO Auto-generated method stub\r
154 return null;\r
c3c5c786
FC
155 }\r
156\r
157 @Override\r
158 public synchronized TmfEvent getNextEvent(TmfContext context) {\r
159 ITmfContext savedContext = context.clone();\r
160 TmfEvent event = parseEvent(context);\r
161 if (event != null) {\r
162 updateIndex(savedContext, savedContext.getRank(), event.getTimestamp());\r
163 context.updateRank(1);\r
164 }\r
165 return event;\r
166 }\r
167\r
168 @Override\r
169 public TmfEvent parseEvent(TmfContext tmfContext) {\r
170 //System.out.println(Thread.currentThread().getName() + ":: " + getName() + " parseEvent(" + tmfContext.getRank() + " @ " + (tmfContext.getLocation().getLocation() == null ? "null" : tmfContext.getLocation()));\r
171 if (!(tmfContext instanceof CustomXmlTraceContext)) {\r
172 return null;\r
173 }\r
174 \r
175 CustomXmlTraceContext context = (CustomXmlTraceContext) tmfContext;\r
d7fcacc9 176 if (!(context.getLocation().getLocation() instanceof Long) || NULL_LOCATION.equals(context.getLocation())) {\r
c3c5c786
FC
177 return null;\r
178 }\r
179\r
180 synchronized (context.raFile) {\r
181 CustomXmlEvent event = null;\r
182 try {\r
183 if (context.raFile.getFilePointer() != (Long)context.getLocation().getLocation() + 1) {\r
184 context.raFile.seek((Long)context.getLocation().getLocation() + 1); // +1 is for the <\r
185 }\r
3b38ea61 186 StringBuffer elementBuffer = new StringBuffer("<"); //$NON-NLS-1$\r
c3c5c786
FC
187 readElement(elementBuffer, context.raFile);\r
188 Element element = parseElementBuffer(elementBuffer);\r
189 \r
190 event = extractEvent(element, fRecordInputElement);\r
d7fcacc9 191 ((StringBuffer) event.getContent().getContent()).append(elementBuffer);\r
c3c5c786
FC
192 \r
193 String line;\r
3b38ea61 194 String recordElementStart = "<" + fRecordInputElement.elementName; //$NON-NLS-1$\r
c3c5c786
FC
195 long rawPos = context.raFile.getFilePointer();\r
196 \r
d7fcacc9 197 while ((line = context.raFile.getNextLine()) != null) {\r
c3c5c786
FC
198 int idx = line.indexOf(recordElementStart); \r
199 if (idx != -1) {\r
200 context.setLocation(new TmfLocation<Long>(rawPos + idx));\r
201 return event;\r
202 }\r
203 rawPos = context.raFile.getFilePointer();\r
204 }\r
205 } catch (IOException e) {\r
206 e.printStackTrace();\r
207 }\r
d7fcacc9 208 context.setLocation(NULL_LOCATION);\r
c3c5c786
FC
209 return event;\r
210 }\r
211 }\r
212\r
213 private Element parseElementBuffer(StringBuffer elementBuffer) {\r
214 try {\r
215 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();\r
216 DocumentBuilder db = dbf.newDocumentBuilder();\r
217\r
218 // The following allows xml parsing without access to the dtd\r
219 EntityResolver resolver = new EntityResolver () {\r
d4011df2
FC
220 @Override\r
221 public InputSource resolveEntity (String publicId, String systemId) {\r
3b38ea61 222 String empty = ""; //$NON-NLS-1$\r
c3c5c786
FC
223 ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes());\r
224 return new InputSource(bais);\r
225 }\r
226 };\r
227 db.setEntityResolver(resolver);\r
228\r
229 // The following catches xml parsing exceptions\r
230 db.setErrorHandler(new ErrorHandler(){\r
d4011df2
FC
231 @Override\r
232 public void error(SAXParseException saxparseexception) throws SAXException {}\r
233 @Override\r
234 public void warning(SAXParseException saxparseexception) throws SAXException {}\r
235 @Override\r
236 public void fatalError(SAXParseException saxparseexception) throws SAXException {\r
c3c5c786
FC
237 throw saxparseexception;\r
238 }});\r
239 \r
240 Document doc = db.parse(new ByteArrayInputStream(elementBuffer.toString().getBytes()));\r
241 return doc.getDocumentElement();\r
242 } catch (ParserConfigurationException e) {\r
243 e.printStackTrace();\r
244 } catch (SAXException e) {\r
245 e.printStackTrace();\r
246 } catch (IOException e) {\r
247 e.printStackTrace();\r
248 }\r
249 return null;\r
250 }\r
251\r
252 private void readElement(StringBuffer buffer, RandomAccessFile raFile) {\r
253 try {\r
254 int numRead = 0;\r
255 boolean startTagClosed = false;\r
256 int i;\r
257 while ((i = raFile.read()) != -1) {\r
258 numRead++;\r
259 char c = (char)i;\r
260 buffer.append(c);\r
261 if (c == '"') {\r
262 readQuote(buffer, raFile, '"');\r
263 } else if (c == '\'') {\r
264 readQuote(buffer, raFile, '\'');\r
265 } else if (c == '<') {\r
266 readElement(buffer, raFile);\r
267 } else if (c == '/' && numRead == 1) {\r
268 break; // found "</"\r
3b38ea61 269 } else if (c == '-' && numRead == 3 && buffer.substring(buffer.length() - 3, buffer.length() - 1).equals("!-")) { //$NON-NLS-1$\r
c3c5c786
FC
270 readComment(buffer, raFile); // found "<!--"\r
271 } else if (i == '>') {\r
272 if (buffer.charAt(buffer.length() - 2) == '/') {\r
273 break; // found "/>"\r
274 } else if (startTagClosed) {\r
275 break; // found "<...>...</...>"\r
276 } else {\r
277 startTagClosed = true; // found "<...>"\r
278 }\r
279 }\r
280 }\r
281 return;\r
282 } catch (IOException e) {\r
283 return;\r
284 }\r
285 }\r
286\r
287 private void readQuote(StringBuffer buffer, RandomAccessFile raFile, char eq) {\r
288 try {\r
289 int i;\r
290 while ((i = raFile.read()) != -1) {\r
291 char c = (char)i;\r
292 buffer.append(c);\r
293 if (c == eq) {\r
294 break; // found matching end-quote\r
295 }\r
296 }\r
297 return;\r
298 } catch (IOException e) {\r
299 return;\r
300 }\r
301 }\r
302\r
303 private void readComment(StringBuffer buffer, RandomAccessFile raFile) {\r
304 try {\r
305 int numRead = 0;\r
306 int i;\r
307 while ((i = raFile.read()) != -1) {\r
308 numRead++;\r
309 char c = (char)i;\r
310 buffer.append(c);\r
3b38ea61 311 if (c == '>' && numRead >= 2 && buffer.substring(buffer.length() - 3, buffer.length() - 1).equals("--")) { //$NON-NLS-1$\r
c3c5c786
FC
312 break; // found "-->"\r
313 }\r
314 }\r
315 return;\r
316 } catch (IOException e) {\r
317 return;\r
318 }\r
319 }\r
320\r
321 public static StringBuffer parseElement(Element parentElement, StringBuffer buffer) {\r
322 NodeList nodeList = parentElement.getChildNodes();\r
323 String separator = null;\r
324 for (int i = 0; i < nodeList.getLength(); i++) {\r
325 Node node = nodeList.item(i);\r
326 if (node.getNodeType() == Node.ELEMENT_NODE) {\r
327 if (separator == null) {\r
3b38ea61 328 separator = " | "; //$NON-NLS-1$\r
c3c5c786
FC
329 } else {\r
330 buffer.append(separator);\r
331 }\r
332 Element element = (Element) node;\r
333 if (element.hasChildNodes() == false) {\r
334 buffer.append(element.getNodeName());\r
335 } else if (element.getChildNodes().getLength() == 1 && element.getFirstChild().getNodeType() == Node.TEXT_NODE) {\r
3b38ea61 336 buffer.append(element.getNodeName() + ":" + element.getFirstChild().getNodeValue().trim()); //$NON-NLS-1$\r
c3c5c786
FC
337 } else {\r
338 buffer.append(element.getNodeName());\r
3b38ea61 339 buffer.append(" [ "); //$NON-NLS-1$\r
c3c5c786 340 parseElement(element, buffer);\r
3b38ea61 341 buffer.append(" ]"); //$NON-NLS-1$\r
c3c5c786
FC
342 }\r
343 } else if (node.getNodeType() == Node.TEXT_NODE) {\r
344 if (node.getNodeValue().trim().length() != 0) {\r
345 buffer.append(node.getNodeValue().trim());\r
346 }\r
347 }\r
348 }\r
349 return buffer;\r
350 }\r
351\r
352 public InputElement getRecordInputElement(InputElement inputElement) {\r
353 if (inputElement.logEntry) {\r
354 return inputElement;\r
355 } else if (inputElement.childElements != null) {\r
356 for (InputElement childInputElement : inputElement.childElements) {\r
357 InputElement recordInputElement = getRecordInputElement(childInputElement);\r
358 if (recordInputElement != null) {\r
359 return recordInputElement;\r
360 }\r
361 }\r
362 }\r
363 return null;\r
364 }\r
365 \r
366 public CustomXmlEvent extractEvent(Element element, InputElement inputElement) {\r
4bf17f4a 367 CustomXmlEvent event = new CustomXmlEvent(fDefinition, this, TmfTimestamp.Zero, new TmfEventSource(""), fEventType, new TmfEventReference("")); //$NON-NLS-1$ //$NON-NLS-2$\r
d7fcacc9 368 event.setContent(new CustomEventContent(event, new StringBuffer()));\r
c3c5c786
FC
369 parseElement(element, event, inputElement);\r
370 return event;\r
371 }\r
372 \r
373 private void parseElement(Element element, CustomXmlEvent event, InputElement inputElement) {\r
374 if (inputElement.inputName != null && !inputElement.inputName.equals(CustomXmlTraceDefinition.TAG_IGNORE)) {\r
375 event.parseInput(parseElement(element, new StringBuffer()).toString(), inputElement.inputName, inputElement.inputAction, inputElement.inputFormat);\r
376 }\r
377 if (inputElement.attributes != null) {\r
378 for (InputAttribute attribute : inputElement.attributes) {\r
379 event.parseInput(element.getAttribute(attribute.attributeName), attribute.inputName, attribute.inputAction, attribute.inputFormat);\r
380 }\r
381 }\r
382 NodeList childNodes = element.getChildNodes();\r
383 if (inputElement.childElements != null) {\r
384 for (int i = 0; i < childNodes.getLength(); i++) {\r
385 Node node = childNodes.item(i);\r
386 if (node instanceof Element) {\r
387 for (InputElement child : inputElement.childElements) {\r
388 if (node.getNodeName().equals(child.elementName)) {\r
389 parseElement((Element) node, event, child);\r
390 break;\r
391 }\r
392 }\r
393 }\r
394 }\r
395 }\r
396 return;\r
397 }\r
398\r
399 public CustomTraceDefinition getDefinition() {\r
400 return fDefinition;\r
401 }\r
402}\r
This page took 0.044278 seconds and 5 git commands to generate.