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