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