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