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