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