2010-11-09 Francois Chouinard <fchouinard@gmail.com> Contribution for Bug315307
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / parsers / custom / CustomXmlTraceDefinition.java
1 /*******************************************************************************
2 * Copyright (c) 2010 Ericsson
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.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.tmf.ui.TmfUiPlugin;
36 import org.w3c.dom.Document;
37 import org.w3c.dom.Element;
38 import org.w3c.dom.Node;
39 import org.w3c.dom.NodeList;
40 import org.xml.sax.EntityResolver;
41 import org.xml.sax.ErrorHandler;
42 import org.xml.sax.InputSource;
43 import org.xml.sax.SAXException;
44 import org.xml.sax.SAXParseException;
45
46 public class CustomXmlTraceDefinition extends CustomTraceDefinition {
47
48 protected static final String CUSTOM_XML_TRACE_DEFINITIONS_FILE_NAME = "custom_xml_parsers.xml"; //$NON-NLS-1$
49 protected static final String CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME =
50 TmfUiPlugin.getDefault().getStateLocation().addTrailingSeparator().append(CUSTOM_XML_TRACE_DEFINITIONS_FILE_NAME).toString();
51
52 public static final String TAG_IGNORE = Messages.CustomXmlTraceDefinition_ignoreTag;
53
54 private static final String CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT = Messages.CustomXmlTraceDefinition_definitionRootElement;
55 private static final String DEFINITION_ELEMENT = Messages.CustomXmlTraceDefinition_definition;
56 private static final String NAME_ATTRIBUTE = Messages.CustomXmlTraceDefinition_name;
57 private static final String LOG_ENTRY_ATTRIBUTE = Messages.CustomXmlTraceDefinition_logEntry;
58 private static final String TIME_STAMP_OUTPUT_FORMAT_ELEMENT = Messages.CustomXmlTraceDefinition_timestampOutputFormat;
59 private static final String INPUT_ELEMENT_ELEMENT = Messages.CustomXmlTraceDefinition_inputElement;
60 private static final String ATTRIBUTE_ELEMENT = Messages.CustomXmlTraceDefinition_attribute;
61 private static final String INPUT_DATA_ELEMENT = Messages.CustomXmlTraceDefinition_inputData;
62 private static final String ACTION_ATTRIBUTE = Messages.CustomXmlTraceDefinition_action;
63 private static final String FORMAT_ATTRIBUTE = Messages.CustomXmlTraceDefinition_format;
64 private static final String OUTPUT_COLUMN_ELEMENT = Messages.CustomXmlTraceDefinition_outputColumn;
65
66 public InputElement rootInputElement;
67
68 public CustomXmlTraceDefinition() {
69 this("", null, new ArrayList<OutputColumn>(), ""); //$NON-NLS-1$ //$NON-NLS-2$
70 };
71
72 public CustomXmlTraceDefinition(String logtype, InputElement rootElement, List<OutputColumn> outputs, String timeStampOutputFormat) {
73 this.definitionName = logtype;
74 this.rootInputElement = rootElement;
75 this.outputs = outputs;
76 this.timeStampOutputFormat = timeStampOutputFormat;
77 }
78
79 public static class InputElement {
80 public String elementName;
81 public boolean logEntry;
82 public String inputName;
83 public int inputAction;
84 public String inputFormat;
85 public List<InputAttribute> attributes;
86 public InputElement parentElement;
87 public InputElement nextElement;
88 public List<InputElement> childElements;
89
90 public InputElement() {};
91
92 public InputElement(String elementName, boolean logEntry, String inputName, int inputAction, String inputFormat, List<InputAttribute> attributes) {
93 this.elementName = elementName;
94 this.logEntry = logEntry;
95 this.inputName = inputName;
96 this.inputAction = inputAction;
97 this.inputFormat = inputFormat;
98 this.attributes = attributes;
99 }
100
101 public void addAttribute(InputAttribute attribute) {
102 if (attributes == null) {
103 attributes = new ArrayList<InputAttribute>(1);
104 }
105 attributes.add(attribute);
106 }
107
108 public void addChild(InputElement input) {
109 if (childElements == null) {
110 childElements = new ArrayList<InputElement>(1);
111 } else if (childElements.size() > 0) {
112 InputElement last = childElements.get(childElements.size() - 1);
113 last.nextElement = input;
114 }
115 childElements.add(input);
116 input.parentElement = this;
117 }
118
119 public void addNext(InputElement input) {
120 if (parentElement != null) {
121 int index = parentElement.childElements.indexOf(this);
122 parentElement.childElements.add(index + 1, input);
123 InputElement next = nextElement;
124 nextElement = input;
125 input.nextElement = next;
126 }
127 input.parentElement = this.parentElement;
128 }
129
130 public void moveUp() {
131 if (parentElement != null) {
132 int index = parentElement.childElements.indexOf(this);
133 if (index > 0) {
134 parentElement.childElements.add(index - 1 , parentElement.childElements.remove(index));
135 parentElement.childElements.get(index).nextElement = nextElement;
136 nextElement = parentElement.childElements.get(index);
137 }
138 }
139 }
140
141 public void moveDown() {
142 if (parentElement != null) {
143 int index = parentElement.childElements.indexOf(this);
144 if (index < parentElement.childElements.size() - 1) {
145 parentElement.childElements.add(index + 1 , parentElement.childElements.remove(index));
146 nextElement = parentElement.childElements.get(index).nextElement;
147 parentElement.childElements.get(index).nextElement = this;
148 }
149 }
150 }
151
152 }
153
154 public static class InputAttribute {
155 public String attributeName;
156 public String inputName;
157 public int inputAction;
158 public String inputFormat;
159
160 public InputAttribute() {};
161
162 public InputAttribute(String attributeName, String inputName, int inputAction, String inputFormat) {
163 this.attributeName = attributeName;
164 this.inputName = inputName;
165 this.inputAction = inputAction;
166 this.inputFormat = inputFormat;
167 }
168 }
169
170 @Override
171 public void save() {
172 save(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME);
173 }
174
175 @Override
176 public void save(String path) {
177 try {
178 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
179 DocumentBuilder db = dbf.newDocumentBuilder();
180
181 // The following allows xml parsing without access to the dtd
182 EntityResolver resolver = new EntityResolver () {
183 @Override
184 public InputSource resolveEntity (String publicId, String systemId) {
185 String empty = ""; //$NON-NLS-1$
186 ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes());
187 return new InputSource(bais);
188 }
189 };
190 db.setEntityResolver(resolver);
191
192 // The following catches xml parsing exceptions
193 db.setErrorHandler(new ErrorHandler(){
194 @Override
195 public void error(SAXParseException saxparseexception) throws SAXException {}
196 @Override
197 public void warning(SAXParseException saxparseexception) throws SAXException {}
198 @Override
199 public void fatalError(SAXParseException saxparseexception) throws SAXException {
200 throw saxparseexception;
201 }});
202
203 Document doc = null;
204 File file = new File(path);
205 if (file.canRead()) {
206 doc = db.parse(file);
207 if (! doc.getDocumentElement().getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT)) {
208 return;
209 }
210 } else {
211 doc = db.newDocument();
212 Node node = doc.createElement(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT);
213 doc.appendChild(node);
214 }
215
216 Element root = doc.getDocumentElement();
217
218 NodeList nodeList = root.getChildNodes();
219 for (int i = 0; i < nodeList.getLength(); i++) {
220 Node node = nodeList.item(i);
221 if (node instanceof Element &&
222 node.getNodeName().equals(DEFINITION_ELEMENT) &&
223 definitionName.equals(((Element) node).getAttribute(NAME_ATTRIBUTE))) {
224 root.removeChild(node);
225 }
226 }
227 Element definitionElement = doc.createElement(DEFINITION_ELEMENT);
228 root.appendChild(definitionElement);
229 definitionElement.setAttribute(NAME_ATTRIBUTE, definitionName);
230
231 Element formatElement = doc.createElement(TIME_STAMP_OUTPUT_FORMAT_ELEMENT);
232 definitionElement.appendChild(formatElement);
233 formatElement.appendChild(doc.createTextNode(timeStampOutputFormat));
234
235 if (rootInputElement != null) {
236 definitionElement.appendChild(createInputElementElement(rootInputElement, doc));
237 }
238
239 if (outputs != null) {
240 for (OutputColumn output : outputs) {
241 Element outputColumnElement = doc.createElement(OUTPUT_COLUMN_ELEMENT);
242 definitionElement.appendChild(outputColumnElement);
243 outputColumnElement.setAttribute(NAME_ATTRIBUTE, output.name);
244 }
245 }
246
247 Transformer transformer = TransformerFactory.newInstance().newTransformer();
248 transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
249
250 //initialize StreamResult with File object to save to file
251 StreamResult result = new StreamResult(new StringWriter());
252 DOMSource source = new DOMSource(doc);
253 transformer.transform(source, result);
254 String xmlString = result.getWriter().toString();
255
256 FileWriter writer = new FileWriter(file);
257 writer.write(xmlString);
258 writer.close();
259 } catch (ParserConfigurationException e) {
260 e.printStackTrace();
261 } catch (TransformerConfigurationException e) {
262 e.printStackTrace();
263 } catch (TransformerFactoryConfigurationError e) {
264 e.printStackTrace();
265 } catch (TransformerException e) {
266 e.printStackTrace();
267 } catch (IOException e) {
268 e.printStackTrace();
269 } catch (SAXException e) {
270 e.printStackTrace();
271 }
272 }
273
274 private Element createInputElementElement(InputElement inputElement, Document doc) {
275 Element inputElementElement = doc.createElement(INPUT_ELEMENT_ELEMENT);
276 inputElementElement.setAttribute(NAME_ATTRIBUTE, inputElement.elementName);
277
278 if (inputElement.logEntry) {
279 inputElementElement.setAttribute(LOG_ENTRY_ATTRIBUTE, Boolean.toString(inputElement.logEntry));
280 }
281
282 if (inputElement.parentElement != null) {
283 Element inputDataElement = doc.createElement(INPUT_DATA_ELEMENT);
284 inputElementElement.appendChild(inputDataElement);
285 inputDataElement.setAttribute(NAME_ATTRIBUTE, inputElement.inputName);
286 inputDataElement.setAttribute(ACTION_ATTRIBUTE, Integer.toString(inputElement.inputAction));
287 if (inputElement.inputFormat != null) {
288 inputDataElement.setAttribute(FORMAT_ATTRIBUTE, inputElement.inputFormat);
289 }
290 }
291
292 if (inputElement.attributes != null) {
293 for (InputAttribute attribute : inputElement.attributes) {
294 Element inputAttributeElement = doc.createElement(ATTRIBUTE_ELEMENT);
295 inputElementElement.appendChild(inputAttributeElement);
296 inputAttributeElement.setAttribute(NAME_ATTRIBUTE, attribute.attributeName);
297 Element inputDataElement = doc.createElement(INPUT_DATA_ELEMENT);
298 inputAttributeElement.appendChild(inputDataElement);
299 inputDataElement.setAttribute(NAME_ATTRIBUTE, attribute.inputName);
300 inputDataElement.setAttribute(ACTION_ATTRIBUTE, Integer.toString(attribute.inputAction));
301 if (attribute.inputFormat != null) {
302 inputDataElement.setAttribute(FORMAT_ATTRIBUTE, attribute.inputFormat);
303 }
304 }
305 }
306
307 if (inputElement.childElements != null) {
308 for (InputElement childInputElement : inputElement.childElements) {
309 inputElementElement.appendChild(createInputElementElement(childInputElement, doc));
310 }
311 }
312
313 return inputElementElement;
314 }
315
316 public static CustomXmlTraceDefinition[] loadAll() {
317 return loadAll(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME);
318 }
319
320 public static CustomXmlTraceDefinition[] loadAll(String path) {
321 try {
322 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
323 DocumentBuilder db = dbf.newDocumentBuilder();
324
325 // The following allows xml parsing without access to the dtd
326 EntityResolver resolver = new EntityResolver () {
327 @Override
328 public InputSource resolveEntity (String publicId, String systemId) {
329 String empty = ""; //$NON-NLS-1$
330 ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes());
331 return new InputSource(bais);
332 }
333 };
334 db.setEntityResolver(resolver);
335
336 // The following catches xml parsing exceptions
337 db.setErrorHandler(new ErrorHandler(){
338 @Override
339 public void error(SAXParseException saxparseexception) throws SAXException {}
340 @Override
341 public void warning(SAXParseException saxparseexception) throws SAXException {}
342 @Override
343 public void fatalError(SAXParseException saxparseexception) throws SAXException {
344 throw saxparseexception;
345 }});
346
347 File file = new File(path);
348 if (!file.canRead()) {
349 return new CustomXmlTraceDefinition[0];
350 }
351 Document doc = db.parse(file);
352
353 Element root = doc.getDocumentElement();
354 if (! root.getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT)) {
355 return new CustomXmlTraceDefinition[0];
356 }
357
358 ArrayList<CustomXmlTraceDefinition> defList = new ArrayList<CustomXmlTraceDefinition>();
359 NodeList nodeList = root.getChildNodes();
360 for (int i = 0; i < nodeList.getLength(); i++) {
361 Node node = nodeList.item(i);
362 if (node instanceof Element && node.getNodeName().equals(DEFINITION_ELEMENT)) {
363 CustomXmlTraceDefinition def = extractDefinition((Element) node);
364 if (def != null) {
365 defList.add(def);
366 }
367 }
368 }
369 return defList.toArray(new CustomXmlTraceDefinition[0]);
370 } catch (ParserConfigurationException e) {
371 e.printStackTrace();
372 } catch (SAXException e) {
373 e.printStackTrace();
374 } catch (IOException e) {
375 e.printStackTrace();
376 }
377 return new CustomXmlTraceDefinition[0];
378 }
379
380 public static CustomXmlTraceDefinition load(String definitionName) {
381 try {
382 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
383 DocumentBuilder db = dbf.newDocumentBuilder();
384
385 // The following allows xml parsing without access to the dtd
386 EntityResolver resolver = new EntityResolver () {
387 @Override
388 public InputSource resolveEntity (String publicId, String systemId) {
389 String empty = ""; //$NON-NLS-1$
390 ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes());
391 return new InputSource(bais);
392 }
393 };
394 db.setEntityResolver(resolver);
395
396 // The following catches xml parsing exceptions
397 db.setErrorHandler(new ErrorHandler(){
398 @Override
399 public void error(SAXParseException saxparseexception) throws SAXException {}
400 @Override
401 public void warning(SAXParseException saxparseexception) throws SAXException {}
402 @Override
403 public void fatalError(SAXParseException saxparseexception) throws SAXException {
404 throw saxparseexception;
405 }});
406
407 File file = new File(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME);
408 Document doc = db.parse(file);
409
410 Element root = doc.getDocumentElement();
411 if (! root.getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT)) {
412 return null;
413 }
414
415 NodeList nodeList = root.getChildNodes();
416 for (int i = 0; i < nodeList.getLength(); i++) {
417 Node node = nodeList.item(i);
418 if (node instanceof Element &&
419 node.getNodeName().equals(DEFINITION_ELEMENT) &&
420 definitionName.equals(((Element) node).getAttribute(NAME_ATTRIBUTE))) {
421 return extractDefinition((Element) node);
422 }
423 }
424 } catch (ParserConfigurationException e) {
425 e.printStackTrace();
426 } catch (SAXException e) {
427 e.printStackTrace();
428 } catch (IOException e) {
429 e.printStackTrace();
430 }
431 return null;
432 }
433
434 public static CustomXmlTraceDefinition extractDefinition(Element definitionElement) {
435 CustomXmlTraceDefinition def = new CustomXmlTraceDefinition();
436
437 def.definitionName = definitionElement.getAttribute(NAME_ATTRIBUTE);
438 if (def.definitionName == null) return null;
439
440 NodeList nodeList = definitionElement.getChildNodes();
441 for (int i = 0; i < nodeList.getLength(); i++) {
442 Node node = nodeList.item(i);
443 String nodeName = node.getNodeName();
444 if (nodeName.equals(TIME_STAMP_OUTPUT_FORMAT_ELEMENT)) {
445 Element formatElement = (Element) node;
446 def.timeStampOutputFormat = formatElement.getTextContent();
447 } else if (nodeName.equals(INPUT_ELEMENT_ELEMENT)) {
448 InputElement inputElement = extractInputElement((Element) node);
449 if (inputElement != null) {
450 if (def.rootInputElement == null) {
451 def.rootInputElement = inputElement;
452 } else {
453 return null;
454 }
455 }
456 } else if (nodeName.equals(OUTPUT_COLUMN_ELEMENT)) {
457 Element outputColumnElement = (Element) node;
458 OutputColumn outputColumn = new OutputColumn();
459 outputColumn.name = outputColumnElement.getAttribute(NAME_ATTRIBUTE);
460 def.outputs.add(outputColumn);
461 }
462 }
463 return def;
464 }
465
466 private static InputElement extractInputElement(Element inputElementElement) {
467 InputElement inputElement = new InputElement();
468 inputElement.elementName = inputElementElement.getAttribute(NAME_ATTRIBUTE);
469 inputElement.logEntry = (Boolean.toString(true).equals(inputElementElement.getAttribute(LOG_ENTRY_ATTRIBUTE))) ? true : false;
470 NodeList nodeList = inputElementElement.getChildNodes();
471 for (int i = 0; i < nodeList.getLength(); i++) {
472 Node node = nodeList.item(i);
473 String nodeName = node.getNodeName();
474 if (nodeName.equals(INPUT_DATA_ELEMENT)) {
475 Element inputDataElement = (Element) node;
476 inputElement.inputName = inputDataElement.getAttribute(NAME_ATTRIBUTE);
477 inputElement.inputAction = Integer.parseInt(inputDataElement.getAttribute(ACTION_ATTRIBUTE));
478 inputElement.inputFormat = inputDataElement.getAttribute(FORMAT_ATTRIBUTE);
479 } else if (nodeName.equals(ATTRIBUTE_ELEMENT)) {
480 Element attributeElement = (Element) node;
481 InputAttribute attribute = new InputAttribute();
482 attribute.attributeName = attributeElement.getAttribute(NAME_ATTRIBUTE);
483 NodeList attributeNodeList = attributeElement.getChildNodes();
484 for (int j = 0; j < attributeNodeList.getLength(); j++) {
485 Node attributeNode = attributeNodeList.item(j);
486 String attributeNodeName = attributeNode.getNodeName();
487 if (attributeNodeName.equals(INPUT_DATA_ELEMENT)) {
488 Element inputDataElement = (Element) attributeNode;
489 attribute.inputName = inputDataElement.getAttribute(NAME_ATTRIBUTE);
490 attribute.inputAction = Integer.parseInt(inputDataElement.getAttribute(ACTION_ATTRIBUTE));
491 attribute.inputFormat = inputDataElement.getAttribute(FORMAT_ATTRIBUTE);
492 }
493 }
494 inputElement.addAttribute(attribute);
495 } else if (nodeName.equals(INPUT_ELEMENT_ELEMENT)) {
496 Element childInputElementElement = (Element) node;
497 InputElement childInputElement = extractInputElement(childInputElementElement);
498 if (childInputElement != null) {
499 inputElement.addChild(childInputElement);
500 }
501 }
502 }
503 return inputElement;
504 }
505
506 public static void delete(String definitionName) {
507 try {
508 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
509 DocumentBuilder db = dbf.newDocumentBuilder();
510
511 // The following allows xml parsing without access to the dtd
512 EntityResolver resolver = new EntityResolver () {
513 @Override
514 public InputSource resolveEntity (String publicId, String systemId) {
515 String empty = ""; //$NON-NLS-1$
516 ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes());
517 return new InputSource(bais);
518 }
519 };
520 db.setEntityResolver(resolver);
521
522 // The following catches xml parsing exceptions
523 db.setErrorHandler(new ErrorHandler(){
524 @Override
525 public void error(SAXParseException saxparseexception) throws SAXException {}
526 @Override
527 public void warning(SAXParseException saxparseexception) throws SAXException {}
528 @Override
529 public void fatalError(SAXParseException saxparseexception) throws SAXException {
530 throw saxparseexception;
531 }});
532
533 File file = new File(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME);
534 Document doc = db.parse(file);
535
536 Element root = doc.getDocumentElement();
537 if (! root.getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT)) {
538 return;
539 }
540
541 NodeList nodeList = root.getChildNodes();
542 for (int i = 0; i < nodeList.getLength(); i++) {
543 Node node = nodeList.item(i);
544 if (node instanceof Element &&
545 node.getNodeName().equals(DEFINITION_ELEMENT) &&
546 definitionName.equals(((Element) node).getAttribute(NAME_ATTRIBUTE))) {
547 root.removeChild(node);
548 }
549 }
550
551 Transformer transformer = TransformerFactory.newInstance().newTransformer();
552 transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
553
554 //initialize StreamResult with File object to save to file
555 StreamResult result = new StreamResult(new StringWriter());
556 DOMSource source = new DOMSource(doc);
557 transformer.transform(source, result);
558 String xmlString = result.getWriter().toString();
559
560 FileWriter writer = new FileWriter(file);
561 writer.write(xmlString);
562 writer.close();
563 } catch (ParserConfigurationException e) {
564 e.printStackTrace();
565 } catch (SAXException e) {
566 e.printStackTrace();
567 } catch (IOException e) {
568 e.printStackTrace();
569 } catch (TransformerConfigurationException e) {
570 e.printStackTrace();
571 } catch (TransformerFactoryConfigurationError e) {
572 e.printStackTrace();
573 } catch (TransformerException e) {
574 e.printStackTrace();
575 }
576 }
577 }
This page took 0.044179 seconds and 5 git commands to generate.