Commit | Line | Data |
---|---|---|
be222f56 | 1 | /******************************************************************************* |
c8422608 | 2 | * Copyright (c) 2010, 2013 Ericsson |
be222f56 PT |
3 | * |
4 | * All rights reserved. This program and the accompanying materials are | |
5 | * made available under the terms of the Eclipse Public License v1.0 which | |
6 | * accompanies this distribution, and is available at | |
7 | * http://www.eclipse.org/legal/epl-v10.html | |
8 | * | |
9 | * Contributors: | |
10 | * Patrick Tasse - Initial API and implementation | |
11 | *******************************************************************************/ | |
12 | ||
13 | package org.eclipse.linuxtools.internal.tmf.ui.parsers.custom; | |
14 | ||
15 | import java.io.ByteArrayInputStream; | |
16 | import java.io.File; | |
17 | import java.io.FileWriter; | |
18 | import java.io.IOException; | |
19 | import java.io.StringWriter; | |
20 | import java.util.ArrayList; | |
21 | import java.util.List; | |
22 | ||
23 | import javax.xml.parsers.DocumentBuilder; | |
24 | import javax.xml.parsers.DocumentBuilderFactory; | |
25 | import javax.xml.parsers.ParserConfigurationException; | |
26 | import javax.xml.transform.OutputKeys; | |
27 | import javax.xml.transform.Transformer; | |
28 | import javax.xml.transform.TransformerConfigurationException; | |
29 | import javax.xml.transform.TransformerException; | |
30 | import javax.xml.transform.TransformerFactory; | |
31 | import javax.xml.transform.TransformerFactoryConfigurationError; | |
32 | import javax.xml.transform.dom.DOMSource; | |
33 | import javax.xml.transform.stream.StreamResult; | |
34 | ||
35 | import org.eclipse.linuxtools.internal.tmf.ui.Activator; | |
36 | import org.eclipse.linuxtools.internal.tmf.ui.Messages; | |
37 | import org.w3c.dom.Document; | |
38 | import org.w3c.dom.Element; | |
39 | import org.w3c.dom.Node; | |
40 | import org.w3c.dom.NodeList; | |
41 | import org.xml.sax.EntityResolver; | |
42 | import org.xml.sax.ErrorHandler; | |
43 | import org.xml.sax.InputSource; | |
44 | import org.xml.sax.SAXException; | |
45 | import org.xml.sax.SAXParseException; | |
46 | ||
a0a88f65 AM |
47 | /** |
48 | * Trace definition for custom XML traces. | |
49 | * | |
50 | * @author Patrick Tassé | |
51 | */ | |
be222f56 PT |
52 | public class CustomXmlTraceDefinition extends CustomTraceDefinition { |
53 | ||
a0a88f65 AM |
54 | /** "ignore" tag */ |
55 | public static final String TAG_IGNORE = Messages.CustomXmlTraceDefinition_ignoreTag; | |
56 | ||
57 | /** Name of the XML definitions file */ | |
be222f56 | 58 | protected static final String CUSTOM_XML_TRACE_DEFINITIONS_FILE_NAME = "custom_xml_parsers.xml"; //$NON-NLS-1$ |
a0a88f65 AM |
59 | |
60 | /** Path to the XML definitions file */ | |
be222f56 PT |
61 | protected static final String CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME = |
62 | Activator.getDefault().getStateLocation().addTrailingSeparator().append(CUSTOM_XML_TRACE_DEFINITIONS_FILE_NAME).toString(); | |
63 | ||
be222f56 PT |
64 | private static final String CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT = Messages.CustomXmlTraceDefinition_definitionRootElement; |
65 | private static final String DEFINITION_ELEMENT = Messages.CustomXmlTraceDefinition_definition; | |
66 | private static final String NAME_ATTRIBUTE = Messages.CustomXmlTraceDefinition_name; | |
67 | private static final String LOG_ENTRY_ATTRIBUTE = Messages.CustomXmlTraceDefinition_logEntry; | |
68 | private static final String TIME_STAMP_OUTPUT_FORMAT_ELEMENT = Messages.CustomXmlTraceDefinition_timestampOutputFormat; | |
69 | private static final String INPUT_ELEMENT_ELEMENT = Messages.CustomXmlTraceDefinition_inputElement; | |
70 | private static final String ATTRIBUTE_ELEMENT = Messages.CustomXmlTraceDefinition_attribute; | |
71 | private static final String INPUT_DATA_ELEMENT = Messages.CustomXmlTraceDefinition_inputData; | |
72 | private static final String ACTION_ATTRIBUTE = Messages.CustomXmlTraceDefinition_action; | |
73 | private static final String FORMAT_ATTRIBUTE = Messages.CustomXmlTraceDefinition_format; | |
74 | private static final String OUTPUT_COLUMN_ELEMENT = Messages.CustomXmlTraceDefinition_outputColumn; | |
75 | ||
a0a88f65 | 76 | /** Top-level input element */ |
be222f56 PT |
77 | public InputElement rootInputElement; |
78 | ||
a0a88f65 AM |
79 | /** |
80 | * Default constructor | |
81 | */ | |
be222f56 PT |
82 | public CustomXmlTraceDefinition() { |
83 | this("", null, new ArrayList<OutputColumn>(), ""); //$NON-NLS-1$ //$NON-NLS-2$ | |
84 | } | |
85 | ||
a0a88f65 AM |
86 | /** |
87 | * Full constructor | |
88 | * | |
89 | * @param logtype | |
90 | * Type of trace type | |
91 | * @param rootElement | |
92 | * The top-level XML element | |
93 | * @param outputs | |
94 | * The list of output columns | |
95 | * @param timeStampOutputFormat | |
96 | * The timestamp format to use | |
97 | */ | |
98 | public CustomXmlTraceDefinition(String logtype, InputElement rootElement, | |
99 | List<OutputColumn> outputs, String timeStampOutputFormat) { | |
be222f56 PT |
100 | this.definitionName = logtype; |
101 | this.rootInputElement = rootElement; | |
102 | this.outputs = outputs; | |
103 | this.timeStampOutputFormat = timeStampOutputFormat; | |
104 | } | |
105 | ||
a0a88f65 AM |
106 | /** |
107 | * Wrapper for input XML elements | |
108 | */ | |
be222f56 | 109 | public static class InputElement { |
a0a88f65 AM |
110 | |
111 | /** Name of the element */ | |
be222f56 | 112 | public String elementName; |
a0a88f65 AM |
113 | |
114 | /** Indicates if this is a log entry */ | |
be222f56 | 115 | public boolean logEntry; |
a0a88f65 AM |
116 | |
117 | /** Name of the input element */ | |
be222f56 | 118 | public String inputName; |
a0a88f65 AM |
119 | |
120 | /** Input action */ | |
be222f56 | 121 | public int inputAction; |
a0a88f65 AM |
122 | |
123 | /** Input format */ | |
be222f56 | 124 | public String inputFormat; |
a0a88f65 AM |
125 | |
126 | /** XML attributes of this element */ | |
be222f56 | 127 | public List<InputAttribute> attributes; |
a0a88f65 AM |
128 | |
129 | /** Parent element */ | |
be222f56 | 130 | public InputElement parentElement; |
a0a88f65 AM |
131 | |
132 | /** Following element in the file */ | |
be222f56 | 133 | public InputElement nextElement; |
a0a88f65 AM |
134 | |
135 | /** Child elements */ | |
be222f56 PT |
136 | public List<InputElement> childElements; |
137 | ||
a0a88f65 AM |
138 | /** |
139 | * Default (empty) constructor | |
140 | */ | |
be222f56 PT |
141 | public InputElement() {} |
142 | ||
a0a88f65 AM |
143 | /** |
144 | * Constructor | |
145 | * | |
146 | * @param elementName | |
147 | * Element name | |
148 | * @param logEntry | |
149 | * If this element is a log entry | |
150 | * @param inputName | |
151 | * Name of the the input | |
152 | * @param inputAction | |
153 | * Input action | |
154 | * @param inputFormat | |
155 | * Input format | |
156 | * @param attributes | |
157 | * XML attributes of this element | |
158 | */ | |
159 | public InputElement(String elementName, boolean logEntry, | |
160 | String inputName, int inputAction, String inputFormat, | |
161 | List<InputAttribute> attributes) { | |
be222f56 PT |
162 | this.elementName = elementName; |
163 | this.logEntry = logEntry; | |
164 | this.inputName = inputName; | |
165 | this.inputAction = inputAction; | |
166 | this.inputFormat = inputFormat; | |
167 | this.attributes = attributes; | |
168 | } | |
169 | ||
a0a88f65 AM |
170 | /** |
171 | * Add a XML attribute to the element | |
172 | * | |
173 | * @param attribute | |
174 | * The attribute to add | |
175 | */ | |
be222f56 PT |
176 | public void addAttribute(InputAttribute attribute) { |
177 | if (attributes == null) { | |
178 | attributes = new ArrayList<InputAttribute>(1); | |
179 | } | |
180 | attributes.add(attribute); | |
181 | } | |
182 | ||
a0a88f65 AM |
183 | /** |
184 | * Add a child element to this one. | |
185 | * | |
186 | * @param input | |
187 | * The input element to add as child | |
188 | */ | |
be222f56 PT |
189 | public void addChild(InputElement input) { |
190 | if (childElements == null) { | |
191 | childElements = new ArrayList<InputElement>(1); | |
192 | } else if (childElements.size() > 0) { | |
193 | InputElement last = childElements.get(childElements.size() - 1); | |
194 | last.nextElement = input; | |
195 | } | |
196 | childElements.add(input); | |
197 | input.parentElement = this; | |
198 | } | |
199 | ||
a0a88f65 AM |
200 | /** |
201 | * Set the following input element. | |
202 | * | |
203 | * @param input | |
204 | * The input element to add as next element | |
205 | */ | |
be222f56 PT |
206 | public void addNext(InputElement input) { |
207 | if (parentElement != null) { | |
208 | int index = parentElement.childElements.indexOf(this); | |
209 | parentElement.childElements.add(index + 1, input); | |
210 | InputElement next = nextElement; | |
211 | nextElement = input; | |
212 | input.nextElement = next; | |
213 | } | |
214 | input.parentElement = this.parentElement; | |
215 | } | |
216 | ||
a0a88f65 AM |
217 | /** |
218 | * Move this element up in its parent's list of children. | |
219 | */ | |
be222f56 PT |
220 | public void moveUp() { |
221 | if (parentElement != null) { | |
222 | int index = parentElement.childElements.indexOf(this); | |
223 | if (index > 0) { | |
224 | parentElement.childElements.add(index - 1 , parentElement.childElements.remove(index)); | |
225 | parentElement.childElements.get(index).nextElement = nextElement; | |
226 | nextElement = parentElement.childElements.get(index); | |
227 | } | |
228 | } | |
229 | } | |
230 | ||
a0a88f65 AM |
231 | /** |
232 | * Move this element down in its parent's list of children. | |
233 | */ | |
be222f56 PT |
234 | public void moveDown() { |
235 | if (parentElement != null) { | |
236 | int index = parentElement.childElements.indexOf(this); | |
237 | if (index < parentElement.childElements.size() - 1) { | |
238 | parentElement.childElements.add(index + 1 , parentElement.childElements.remove(index)); | |
239 | nextElement = parentElement.childElements.get(index).nextElement; | |
240 | parentElement.childElements.get(index).nextElement = this; | |
241 | } | |
242 | } | |
243 | } | |
244 | ||
245 | } | |
246 | ||
a0a88f65 AM |
247 | /** |
248 | * Wrapper for XML element attributes | |
249 | */ | |
be222f56 | 250 | public static class InputAttribute { |
a0a88f65 AM |
251 | |
252 | /** Name of the XML attribute */ | |
be222f56 | 253 | public String attributeName; |
a0a88f65 AM |
254 | |
255 | /** Input name */ | |
be222f56 | 256 | public String inputName; |
a0a88f65 AM |
257 | |
258 | /** Input action */ | |
be222f56 | 259 | public int inputAction; |
a0a88f65 AM |
260 | |
261 | /** Input format */ | |
be222f56 PT |
262 | public String inputFormat; |
263 | ||
a0a88f65 AM |
264 | /** |
265 | * Default (empty) constructor | |
266 | */ | |
be222f56 PT |
267 | public InputAttribute() {} |
268 | ||
a0a88f65 AM |
269 | /** |
270 | * Constructor | |
271 | * | |
272 | * @param attributeName | |
273 | * Name of the XML attribute | |
274 | * @param inputName | |
275 | * Input name | |
276 | * @param inputAction | |
277 | * Input action | |
278 | * @param inputFormat | |
279 | * Input format | |
280 | */ | |
281 | public InputAttribute(String attributeName, String inputName, | |
282 | int inputAction, String inputFormat) { | |
be222f56 PT |
283 | this.attributeName = attributeName; |
284 | this.inputName = inputName; | |
285 | this.inputAction = inputAction; | |
286 | this.inputFormat = inputFormat; | |
287 | } | |
288 | } | |
289 | ||
a0a88f65 | 290 | @Override |
be222f56 PT |
291 | public void save() { |
292 | save(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME); | |
293 | } | |
294 | ||
295 | @Override | |
296 | public void save(String path) { | |
297 | try { | |
298 | DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); | |
299 | DocumentBuilder db = dbf.newDocumentBuilder(); | |
300 | ||
301 | // The following allows xml parsing without access to the dtd | |
a0a88f65 | 302 | EntityResolver resolver = new EntityResolver() { |
be222f56 | 303 | @Override |
a0a88f65 | 304 | public InputSource resolveEntity(String publicId, String systemId) { |
be222f56 PT |
305 | String empty = ""; //$NON-NLS-1$ |
306 | ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes()); | |
307 | return new InputSource(bais); | |
308 | } | |
309 | }; | |
310 | db.setEntityResolver(resolver); | |
311 | ||
312 | // The following catches xml parsing exceptions | |
a0a88f65 | 313 | db.setErrorHandler(new ErrorHandler() { |
be222f56 | 314 | @Override |
a0a88f65 AM |
315 | public void error(SAXParseException saxparseexception) throws SAXException {} |
316 | ||
be222f56 | 317 | @Override |
a0a88f65 AM |
318 | public void warning(SAXParseException saxparseexception) throws SAXException {} |
319 | ||
be222f56 | 320 | @Override |
a0a88f65 | 321 | public void fatalError(SAXParseException saxparseexception) throws SAXException { |
be222f56 | 322 | throw saxparseexception; |
a0a88f65 AM |
323 | } |
324 | }); | |
be222f56 PT |
325 | |
326 | Document doc = null; | |
327 | File file = new File(path); | |
328 | if (file.canRead()) { | |
329 | doc = db.parse(file); | |
330 | if (! doc.getDocumentElement().getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT)) { | |
331 | return; | |
332 | } | |
333 | } else { | |
334 | doc = db.newDocument(); | |
335 | Node node = doc.createElement(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT); | |
336 | doc.appendChild(node); | |
337 | } | |
338 | ||
339 | Element root = doc.getDocumentElement(); | |
340 | ||
341 | NodeList nodeList = root.getChildNodes(); | |
342 | for (int i = 0; i < nodeList.getLength(); i++) { | |
343 | Node node = nodeList.item(i); | |
344 | if (node instanceof Element && | |
345 | node.getNodeName().equals(DEFINITION_ELEMENT) && | |
346 | definitionName.equals(((Element) node).getAttribute(NAME_ATTRIBUTE))) { | |
347 | root.removeChild(node); | |
348 | } | |
349 | } | |
350 | Element definitionElement = doc.createElement(DEFINITION_ELEMENT); | |
351 | root.appendChild(definitionElement); | |
352 | definitionElement.setAttribute(NAME_ATTRIBUTE, definitionName); | |
353 | ||
354 | Element formatElement = doc.createElement(TIME_STAMP_OUTPUT_FORMAT_ELEMENT); | |
355 | definitionElement.appendChild(formatElement); | |
356 | formatElement.appendChild(doc.createTextNode(timeStampOutputFormat)); | |
357 | ||
358 | if (rootInputElement != null) { | |
359 | definitionElement.appendChild(createInputElementElement(rootInputElement, doc)); | |
360 | } | |
361 | ||
362 | if (outputs != null) { | |
363 | for (OutputColumn output : outputs) { | |
364 | Element outputColumnElement = doc.createElement(OUTPUT_COLUMN_ELEMENT); | |
365 | definitionElement.appendChild(outputColumnElement); | |
366 | outputColumnElement.setAttribute(NAME_ATTRIBUTE, output.name); | |
367 | } | |
368 | } | |
369 | ||
370 | Transformer transformer = TransformerFactory.newInstance().newTransformer(); | |
371 | transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ | |
372 | ||
373 | //initialize StreamResult with File object to save to file | |
374 | StreamResult result = new StreamResult(new StringWriter()); | |
375 | DOMSource source = new DOMSource(doc); | |
376 | transformer.transform(source, result); | |
377 | String xmlString = result.getWriter().toString(); | |
378 | ||
379 | FileWriter writer = new FileWriter(file); | |
380 | writer.write(xmlString); | |
381 | writer.close(); | |
382 | } catch (ParserConfigurationException e) { | |
383 | Activator.getDefault().logError("Error saving CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$ | |
384 | } catch (TransformerConfigurationException e) { | |
385 | Activator.getDefault().logError("Error saving CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$ | |
386 | } catch (TransformerFactoryConfigurationError e) { | |
387 | Activator.getDefault().logError("Error saving CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$ | |
388 | } catch (TransformerException e) { | |
389 | Activator.getDefault().logError("Error saving CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$ | |
390 | } catch (IOException e) { | |
391 | Activator.getDefault().logError("Error saving CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$ | |
392 | } catch (SAXException e) { | |
393 | Activator.getDefault().logError("Error saving CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$ | |
394 | } | |
395 | } | |
396 | ||
397 | private Element createInputElementElement(InputElement inputElement, Document doc) { | |
398 | Element inputElementElement = doc.createElement(INPUT_ELEMENT_ELEMENT); | |
399 | inputElementElement.setAttribute(NAME_ATTRIBUTE, inputElement.elementName); | |
400 | ||
401 | if (inputElement.logEntry) { | |
402 | inputElementElement.setAttribute(LOG_ENTRY_ATTRIBUTE, Boolean.toString(inputElement.logEntry)); | |
403 | } | |
404 | ||
405 | if (inputElement.parentElement != null) { | |
406 | Element inputDataElement = doc.createElement(INPUT_DATA_ELEMENT); | |
407 | inputElementElement.appendChild(inputDataElement); | |
408 | inputDataElement.setAttribute(NAME_ATTRIBUTE, inputElement.inputName); | |
409 | inputDataElement.setAttribute(ACTION_ATTRIBUTE, Integer.toString(inputElement.inputAction)); | |
410 | if (inputElement.inputFormat != null) { | |
411 | inputDataElement.setAttribute(FORMAT_ATTRIBUTE, inputElement.inputFormat); | |
412 | } | |
413 | } | |
414 | ||
415 | if (inputElement.attributes != null) { | |
416 | for (InputAttribute attribute : inputElement.attributes) { | |
417 | Element inputAttributeElement = doc.createElement(ATTRIBUTE_ELEMENT); | |
418 | inputElementElement.appendChild(inputAttributeElement); | |
419 | inputAttributeElement.setAttribute(NAME_ATTRIBUTE, attribute.attributeName); | |
420 | Element inputDataElement = doc.createElement(INPUT_DATA_ELEMENT); | |
421 | inputAttributeElement.appendChild(inputDataElement); | |
422 | inputDataElement.setAttribute(NAME_ATTRIBUTE, attribute.inputName); | |
423 | inputDataElement.setAttribute(ACTION_ATTRIBUTE, Integer.toString(attribute.inputAction)); | |
424 | if (attribute.inputFormat != null) { | |
425 | inputDataElement.setAttribute(FORMAT_ATTRIBUTE, attribute.inputFormat); | |
426 | } | |
427 | } | |
428 | } | |
429 | ||
430 | if (inputElement.childElements != null) { | |
431 | for (InputElement childInputElement : inputElement.childElements) { | |
432 | inputElementElement.appendChild(createInputElementElement(childInputElement, doc)); | |
433 | } | |
434 | } | |
435 | ||
436 | return inputElementElement; | |
437 | } | |
438 | ||
a0a88f65 AM |
439 | /** |
440 | * Load all the XML trace definitions in the default definitions file. | |
441 | * | |
442 | * @return The loaded trace definitions | |
443 | */ | |
be222f56 PT |
444 | public static CustomXmlTraceDefinition[] loadAll() { |
445 | return loadAll(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME); | |
446 | } | |
447 | ||
a0a88f65 AM |
448 | /** |
449 | * Load all the XML trace definitions in the given definitions file. | |
450 | * | |
451 | * @param path | |
452 | * Path to the definitions file to load | |
453 | * @return The loaded trace definitions | |
454 | */ | |
be222f56 PT |
455 | public static CustomXmlTraceDefinition[] loadAll(String path) { |
456 | try { | |
457 | DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); | |
458 | DocumentBuilder db = dbf.newDocumentBuilder(); | |
459 | ||
460 | // The following allows xml parsing without access to the dtd | |
a0a88f65 | 461 | EntityResolver resolver = new EntityResolver() { |
be222f56 | 462 | @Override |
a0a88f65 | 463 | public InputSource resolveEntity(String publicId, String systemId) { |
be222f56 PT |
464 | String empty = ""; //$NON-NLS-1$ |
465 | ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes()); | |
466 | return new InputSource(bais); | |
467 | } | |
468 | }; | |
469 | db.setEntityResolver(resolver); | |
470 | ||
471 | // The following catches xml parsing exceptions | |
a0a88f65 | 472 | db.setErrorHandler(new ErrorHandler() { |
be222f56 | 473 | @Override |
a0a88f65 AM |
474 | public void error(SAXParseException saxparseexception) throws SAXException {} |
475 | ||
be222f56 | 476 | @Override |
a0a88f65 AM |
477 | public void warning(SAXParseException saxparseexception) throws SAXException {} |
478 | ||
be222f56 | 479 | @Override |
a0a88f65 | 480 | public void fatalError(SAXParseException saxparseexception) throws SAXException { |
be222f56 | 481 | throw saxparseexception; |
a0a88f65 AM |
482 | } |
483 | }); | |
be222f56 PT |
484 | |
485 | File file = new File(path); | |
486 | if (!file.canRead()) { | |
487 | return new CustomXmlTraceDefinition[0]; | |
488 | } | |
489 | Document doc = db.parse(file); | |
490 | ||
491 | Element root = doc.getDocumentElement(); | |
492 | if (! root.getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT)) { | |
493 | return new CustomXmlTraceDefinition[0]; | |
494 | } | |
495 | ||
496 | ArrayList<CustomXmlTraceDefinition> defList = new ArrayList<CustomXmlTraceDefinition>(); | |
497 | NodeList nodeList = root.getChildNodes(); | |
498 | for (int i = 0; i < nodeList.getLength(); i++) { | |
499 | Node node = nodeList.item(i); | |
500 | if (node instanceof Element && node.getNodeName().equals(DEFINITION_ELEMENT)) { | |
501 | CustomXmlTraceDefinition def = extractDefinition((Element) node); | |
502 | if (def != null) { | |
503 | defList.add(def); | |
504 | } | |
505 | } | |
506 | } | |
507 | return defList.toArray(new CustomXmlTraceDefinition[0]); | |
508 | } catch (ParserConfigurationException e) { | |
509 | Activator.getDefault().logError("Error loading all in CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$ | |
510 | } catch (SAXException e) { | |
511 | Activator.getDefault().logError("Error loading all in CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$ | |
512 | } catch (IOException e) { | |
513 | Activator.getDefault().logError("Error loading all in CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$ | |
514 | } | |
515 | return new CustomXmlTraceDefinition[0]; | |
516 | } | |
517 | ||
a0a88f65 AM |
518 | /** |
519 | * Load the given trace definition. | |
520 | * | |
521 | * @param definitionName | |
522 | * Name of the XML trace definition to load | |
523 | * @return The loaded trace definition | |
524 | */ | |
be222f56 PT |
525 | public static CustomXmlTraceDefinition load(String definitionName) { |
526 | try { | |
527 | DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); | |
528 | DocumentBuilder db = dbf.newDocumentBuilder(); | |
529 | ||
530 | // The following allows xml parsing without access to the dtd | |
a0a88f65 | 531 | EntityResolver resolver = new EntityResolver() { |
be222f56 | 532 | @Override |
a0a88f65 | 533 | public InputSource resolveEntity(String publicId, String systemId) { |
be222f56 PT |
534 | String empty = ""; //$NON-NLS-1$ |
535 | ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes()); | |
536 | return new InputSource(bais); | |
537 | } | |
538 | }; | |
539 | db.setEntityResolver(resolver); | |
540 | ||
541 | // The following catches xml parsing exceptions | |
a0a88f65 | 542 | db.setErrorHandler(new ErrorHandler() { |
be222f56 | 543 | @Override |
a0a88f65 AM |
544 | public void error(SAXParseException saxparseexception) throws SAXException {} |
545 | ||
be222f56 | 546 | @Override |
a0a88f65 AM |
547 | public void warning(SAXParseException saxparseexception) throws SAXException {} |
548 | ||
be222f56 | 549 | @Override |
a0a88f65 | 550 | public void fatalError(SAXParseException saxparseexception) throws SAXException { |
be222f56 | 551 | throw saxparseexception; |
a0a88f65 AM |
552 | } |
553 | }); | |
be222f56 PT |
554 | |
555 | File file = new File(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME); | |
556 | Document doc = db.parse(file); | |
557 | ||
558 | Element root = doc.getDocumentElement(); | |
559 | if (! root.getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT)) { | |
560 | return null; | |
561 | } | |
562 | ||
563 | NodeList nodeList = root.getChildNodes(); | |
564 | for (int i = 0; i < nodeList.getLength(); i++) { | |
565 | Node node = nodeList.item(i); | |
566 | if (node instanceof Element && | |
567 | node.getNodeName().equals(DEFINITION_ELEMENT) && | |
568 | definitionName.equals(((Element) node).getAttribute(NAME_ATTRIBUTE))) { | |
569 | return extractDefinition((Element) node); | |
570 | } | |
571 | } | |
572 | } catch (ParserConfigurationException e) { | |
573 | Activator.getDefault().logError("Error loading CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$ | |
574 | } catch (SAXException e) { | |
575 | Activator.getDefault().logError("Error loading CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$ | |
576 | } catch (IOException e) { | |
577 | Activator.getDefault().logError("Error loading CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$ | |
578 | } | |
579 | return null; | |
580 | } | |
581 | ||
a0a88f65 AM |
582 | /** |
583 | * Extract a trace definition from an XML element. | |
584 | * | |
585 | * @param definitionElement | |
586 | * Definition element | |
587 | * @return The extracted trace definition | |
588 | */ | |
be222f56 PT |
589 | public static CustomXmlTraceDefinition extractDefinition(Element definitionElement) { |
590 | CustomXmlTraceDefinition def = new CustomXmlTraceDefinition(); | |
591 | ||
592 | def.definitionName = definitionElement.getAttribute(NAME_ATTRIBUTE); | |
593 | if (def.definitionName == null) { | |
594 | return null; | |
595 | } | |
596 | ||
597 | NodeList nodeList = definitionElement.getChildNodes(); | |
598 | for (int i = 0; i < nodeList.getLength(); i++) { | |
599 | Node node = nodeList.item(i); | |
600 | String nodeName = node.getNodeName(); | |
601 | if (nodeName.equals(TIME_STAMP_OUTPUT_FORMAT_ELEMENT)) { | |
602 | Element formatElement = (Element) node; | |
603 | def.timeStampOutputFormat = formatElement.getTextContent(); | |
604 | } else if (nodeName.equals(INPUT_ELEMENT_ELEMENT)) { | |
605 | InputElement inputElement = extractInputElement((Element) node); | |
606 | if (inputElement != null) { | |
607 | if (def.rootInputElement == null) { | |
608 | def.rootInputElement = inputElement; | |
609 | } else { | |
610 | return null; | |
611 | } | |
612 | } | |
613 | } else if (nodeName.equals(OUTPUT_COLUMN_ELEMENT)) { | |
614 | Element outputColumnElement = (Element) node; | |
615 | OutputColumn outputColumn = new OutputColumn(); | |
616 | outputColumn.name = outputColumnElement.getAttribute(NAME_ATTRIBUTE); | |
617 | def.outputs.add(outputColumn); | |
618 | } | |
619 | } | |
620 | return def; | |
621 | } | |
622 | ||
623 | private static InputElement extractInputElement(Element inputElementElement) { | |
624 | InputElement inputElement = new InputElement(); | |
625 | inputElement.elementName = inputElementElement.getAttribute(NAME_ATTRIBUTE); | |
626 | inputElement.logEntry = (Boolean.toString(true).equals(inputElementElement.getAttribute(LOG_ENTRY_ATTRIBUTE))) ? true : false; | |
627 | NodeList nodeList = inputElementElement.getChildNodes(); | |
628 | for (int i = 0; i < nodeList.getLength(); i++) { | |
629 | Node node = nodeList.item(i); | |
630 | String nodeName = node.getNodeName(); | |
631 | if (nodeName.equals(INPUT_DATA_ELEMENT)) { | |
632 | Element inputDataElement = (Element) node; | |
633 | inputElement.inputName = inputDataElement.getAttribute(NAME_ATTRIBUTE); | |
634 | inputElement.inputAction = Integer.parseInt(inputDataElement.getAttribute(ACTION_ATTRIBUTE)); | |
635 | inputElement.inputFormat = inputDataElement.getAttribute(FORMAT_ATTRIBUTE); | |
636 | } else if (nodeName.equals(ATTRIBUTE_ELEMENT)) { | |
637 | Element attributeElement = (Element) node; | |
638 | InputAttribute attribute = new InputAttribute(); | |
639 | attribute.attributeName = attributeElement.getAttribute(NAME_ATTRIBUTE); | |
640 | NodeList attributeNodeList = attributeElement.getChildNodes(); | |
641 | for (int j = 0; j < attributeNodeList.getLength(); j++) { | |
642 | Node attributeNode = attributeNodeList.item(j); | |
643 | String attributeNodeName = attributeNode.getNodeName(); | |
644 | if (attributeNodeName.equals(INPUT_DATA_ELEMENT)) { | |
645 | Element inputDataElement = (Element) attributeNode; | |
646 | attribute.inputName = inputDataElement.getAttribute(NAME_ATTRIBUTE); | |
647 | attribute.inputAction = Integer.parseInt(inputDataElement.getAttribute(ACTION_ATTRIBUTE)); | |
648 | attribute.inputFormat = inputDataElement.getAttribute(FORMAT_ATTRIBUTE); | |
649 | } | |
650 | } | |
651 | inputElement.addAttribute(attribute); | |
652 | } else if (nodeName.equals(INPUT_ELEMENT_ELEMENT)) { | |
653 | Element childInputElementElement = (Element) node; | |
654 | InputElement childInputElement = extractInputElement(childInputElementElement); | |
655 | if (childInputElement != null) { | |
656 | inputElement.addChild(childInputElement); | |
657 | } | |
658 | } | |
659 | } | |
660 | return inputElement; | |
661 | } | |
662 | ||
a0a88f65 AM |
663 | /** |
664 | * Delete the given trace definition from the list of currently loaded ones. | |
665 | * | |
666 | * @param definitionName | |
667 | * Name of the trace definition to delete | |
668 | */ | |
be222f56 PT |
669 | public static void delete(String definitionName) { |
670 | try { | |
671 | DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); | |
672 | DocumentBuilder db = dbf.newDocumentBuilder(); | |
673 | ||
674 | // The following allows xml parsing without access to the dtd | |
a0a88f65 | 675 | EntityResolver resolver = new EntityResolver() { |
be222f56 | 676 | @Override |
a0a88f65 | 677 | public InputSource resolveEntity(String publicId, String systemId) { |
be222f56 PT |
678 | String empty = ""; //$NON-NLS-1$ |
679 | ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes()); | |
680 | return new InputSource(bais); | |
681 | } | |
682 | }; | |
683 | db.setEntityResolver(resolver); | |
684 | ||
685 | // The following catches xml parsing exceptions | |
a0a88f65 | 686 | db.setErrorHandler(new ErrorHandler() { |
be222f56 | 687 | @Override |
a0a88f65 AM |
688 | public void error(SAXParseException saxparseexception) throws SAXException {} |
689 | ||
be222f56 | 690 | @Override |
a0a88f65 AM |
691 | public void warning(SAXParseException saxparseexception) throws SAXException {} |
692 | ||
be222f56 | 693 | @Override |
a0a88f65 | 694 | public void fatalError(SAXParseException saxparseexception) throws SAXException { |
be222f56 | 695 | throw saxparseexception; |
a0a88f65 AM |
696 | } |
697 | }); | |
be222f56 PT |
698 | |
699 | File file = new File(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME); | |
700 | Document doc = db.parse(file); | |
701 | ||
702 | Element root = doc.getDocumentElement(); | |
703 | if (! root.getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT)) { | |
704 | return; | |
705 | } | |
706 | ||
707 | NodeList nodeList = root.getChildNodes(); | |
708 | for (int i = 0; i < nodeList.getLength(); i++) { | |
709 | Node node = nodeList.item(i); | |
710 | if (node instanceof Element && | |
711 | node.getNodeName().equals(DEFINITION_ELEMENT) && | |
712 | definitionName.equals(((Element) node).getAttribute(NAME_ATTRIBUTE))) { | |
713 | root.removeChild(node); | |
714 | } | |
715 | } | |
716 | ||
717 | Transformer transformer = TransformerFactory.newInstance().newTransformer(); | |
718 | transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ | |
719 | ||
720 | //initialize StreamResult with File object to save to file | |
721 | StreamResult result = new StreamResult(new StringWriter()); | |
722 | DOMSource source = new DOMSource(doc); | |
723 | transformer.transform(source, result); | |
724 | String xmlString = result.getWriter().toString(); | |
725 | ||
726 | FileWriter writer = new FileWriter(file); | |
727 | writer.write(xmlString); | |
728 | writer.close(); | |
729 | } catch (ParserConfigurationException e) { | |
730 | Activator.getDefault().logError("Error deleteing CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$ | |
731 | } catch (SAXException e) { | |
732 | Activator.getDefault().logError("Error deleteing CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$ | |
733 | } catch (IOException e) { | |
734 | Activator.getDefault().logError("Error deleteing CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$ | |
735 | } catch (TransformerConfigurationException e) { | |
736 | Activator.getDefault().logError("Error deleteing CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$ | |
737 | } catch (TransformerFactoryConfigurationError e) { | |
738 | Activator.getDefault().logError("Error deleteing CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$ | |
739 | } catch (TransformerException e) { | |
740 | Activator.getDefault().logError("Error deleteing CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$ | |
741 | } | |
742 | } | |
743 | } |