1 /*******************************************************************************
2 * Copyright (c) 2010, 2014 Ericsson
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
10 * Patrick Tasse - Initial API and implementation
11 * Matthew Khouzam - Add support for default xml parsers
12 *******************************************************************************/
14 package org
.eclipse
.linuxtools
.tmf
.core
.parsers
.custom
;
16 import java
.io
.ByteArrayInputStream
;
18 import java
.io
.FileInputStream
;
19 import java
.io
.FileWriter
;
20 import java
.io
.IOException
;
21 import java
.io
.InputStream
;
22 import java
.io
.StringWriter
;
23 import java
.util
.ArrayList
;
24 import java
.util
.Arrays
;
25 import java
.util
.Comparator
;
26 import java
.util
.List
;
28 import java
.util
.TreeSet
;
30 import javax
.xml
.parsers
.DocumentBuilder
;
31 import javax
.xml
.parsers
.DocumentBuilderFactory
;
32 import javax
.xml
.parsers
.ParserConfigurationException
;
33 import javax
.xml
.transform
.OutputKeys
;
34 import javax
.xml
.transform
.Transformer
;
35 import javax
.xml
.transform
.TransformerException
;
36 import javax
.xml
.transform
.TransformerFactory
;
37 import javax
.xml
.transform
.TransformerFactoryConfigurationError
;
38 import javax
.xml
.transform
.dom
.DOMSource
;
39 import javax
.xml
.transform
.stream
.StreamResult
;
41 import org
.eclipse
.core
.runtime
.Platform
;
42 import org
.eclipse
.linuxtools
.internal
.tmf
.core
.Activator
;
43 import org
.eclipse
.linuxtools
.tmf
.core
.project
.model
.TmfTraceType
;
44 import org
.w3c
.dom
.Document
;
45 import org
.w3c
.dom
.Element
;
46 import org
.w3c
.dom
.Node
;
47 import org
.w3c
.dom
.NodeList
;
48 import org
.xml
.sax
.EntityResolver
;
49 import org
.xml
.sax
.ErrorHandler
;
50 import org
.xml
.sax
.InputSource
;
51 import org
.xml
.sax
.SAXException
;
52 import org
.xml
.sax
.SAXParseException
;
55 * Trace definition for custom XML traces.
57 * @author Patrick Tassé
60 public class CustomXmlTraceDefinition
extends CustomTraceDefinition
{
63 public static final String TAG_IGNORE
= Messages
.CustomXmlTraceDefinition_ignoreTag
;
65 /** Name of the default XML definitions file */
66 protected static final String CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_FILE_NAME
= "custom_xml_default_parsers.xml"; //$NON-NLS-1$
68 /** Name of the XML definitions file */
69 protected static final String CUSTOM_XML_TRACE_DEFINITIONS_FILE_NAME
= "custom_xml_parsers.xml"; //$NON-NLS-1$
71 /** Path to the XML definitions file */
72 protected static final String CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_PATH_NAME
=
73 Platform
.getInstallLocation().getURL().getPath() + "templates/org.eclipse.linuxtools.tmf.core/" + //$NON-NLS-1$
74 CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_FILE_NAME
;
76 /** Path to the XML definitions file */
77 protected static final String CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME
=
78 Activator
.getDefault().getStateLocation().addTrailingSeparator().append(CUSTOM_XML_TRACE_DEFINITIONS_FILE_NAME
).toString();
81 * Legacy path to the XML definitions file (in the UI plug-in) TODO Remove
82 * once we feel the transition phase is over.
84 private static final String CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME_LEGACY
=
85 Activator
.getDefault().getStateLocation().removeLastSegments(1).addTrailingSeparator()
86 .append("org.eclipse.linuxtools.tmf.ui") //$NON-NLS-1$
87 .append(CUSTOM_XML_TRACE_DEFINITIONS_FILE_NAME
).toString();
89 // TODO: These strings should not be externalized
90 private static final String CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT
= Messages
.CustomXmlTraceDefinition_definitionRootElement
;
91 private static final String DEFINITION_ELEMENT
= Messages
.CustomXmlTraceDefinition_definition
;
92 private static final String CATEGORY_ATTRIBUTE
= Messages
.CustomXmlTraceDefinition_category
;
93 private static final String NAME_ATTRIBUTE
= Messages
.CustomXmlTraceDefinition_name
;
94 private static final String LOG_ENTRY_ATTRIBUTE
= Messages
.CustomXmlTraceDefinition_logEntry
;
95 private static final String TIME_STAMP_OUTPUT_FORMAT_ELEMENT
= Messages
.CustomXmlTraceDefinition_timestampOutputFormat
;
96 private static final String INPUT_ELEMENT_ELEMENT
= Messages
.CustomXmlTraceDefinition_inputElement
;
97 private static final String ATTRIBUTE_ELEMENT
= Messages
.CustomXmlTraceDefinition_attribute
;
98 private static final String INPUT_DATA_ELEMENT
= Messages
.CustomXmlTraceDefinition_inputData
;
99 private static final String ACTION_ATTRIBUTE
= Messages
.CustomXmlTraceDefinition_action
;
100 private static final String FORMAT_ATTRIBUTE
= Messages
.CustomXmlTraceDefinition_format
;
101 private static final String OUTPUT_COLUMN_ELEMENT
= Messages
.CustomXmlTraceDefinition_outputColumn
;
103 /** Top-level input element */
104 public InputElement rootInputElement
;
107 * Default constructor
109 public CustomXmlTraceDefinition() {
110 this(TmfTraceType
.CUSTOM_XML_CATEGORY
, "", null, new ArrayList
<OutputColumn
>(), ""); //$NON-NLS-1$ //$NON-NLS-2$
117 * Name of the trace type
119 * The top-level XML element
121 * The list of output columns
122 * @param timeStampOutputFormat
123 * The timestamp format to use
124 * @deprecated Use {@link #CustomXmlTraceDefinition(String, String, InputElement, List, String)}
127 public CustomXmlTraceDefinition(String traceType
, InputElement rootElement
,
128 List
<OutputColumn
> outputs
, String timeStampOutputFormat
) {
129 this.definitionName
= traceType
;
130 this.rootInputElement
= rootElement
;
131 this.outputs
= outputs
;
132 this.timeStampOutputFormat
= timeStampOutputFormat
;
139 * Category of the trace type
141 * Name of the trace type
143 * The top-level XML element
145 * The list of output columns
146 * @param timeStampOutputFormat
147 * The timestamp format to use
150 public CustomXmlTraceDefinition(String category
, String traceType
, InputElement rootElement
,
151 List
<OutputColumn
> outputs
, String timeStampOutputFormat
) {
152 this.categoryName
= category
;
153 this.definitionName
= traceType
;
154 this.rootInputElement
= rootElement
;
155 this.outputs
= outputs
;
156 this.timeStampOutputFormat
= timeStampOutputFormat
;
160 * Wrapper for input XML elements
162 public static class InputElement
{
164 /** Name of the element */
165 public String elementName
;
167 /** Indicates if this is a log entry */
168 public boolean logEntry
;
170 /** Name of the input element */
171 public String inputName
;
174 public int inputAction
;
177 public String inputFormat
;
179 /** XML attributes of this element */
180 public List
<InputAttribute
> attributes
;
182 /** Parent element */
183 public InputElement parentElement
;
185 /** Following element in the file */
186 public InputElement nextElement
;
188 /** Child elements */
189 public List
<InputElement
> childElements
;
192 * Default (empty) constructor
194 public InputElement() {
203 * If this element is a log entry
205 * Name of the the input
211 * XML attributes of this element
213 public InputElement(String elementName
, boolean logEntry
,
214 String inputName
, int inputAction
, String inputFormat
,
215 List
<InputAttribute
> attributes
) {
216 this.elementName
= elementName
;
217 this.logEntry
= logEntry
;
218 this.inputName
= inputName
;
219 this.inputAction
= inputAction
;
220 this.inputFormat
= inputFormat
;
221 this.attributes
= attributes
;
225 * Add a XML attribute to the element
228 * The attribute to add
230 public void addAttribute(InputAttribute attribute
) {
231 if (attributes
== null) {
232 attributes
= new ArrayList
<>(1);
234 attributes
.add(attribute
);
238 * Add a child element to this one.
241 * The input element to add as child
243 public void addChild(InputElement input
) {
244 if (childElements
== null) {
245 childElements
= new ArrayList
<>(1);
246 } else if (childElements
.size() > 0) {
247 InputElement last
= childElements
.get(childElements
.size() - 1);
248 last
.nextElement
= input
;
250 childElements
.add(input
);
251 input
.parentElement
= this;
255 * Set the following input element.
258 * The input element to add as next element
260 public void addNext(InputElement input
) {
261 if (parentElement
!= null) {
262 int index
= parentElement
.childElements
.indexOf(this);
263 parentElement
.childElements
.add(index
+ 1, input
);
264 InputElement next
= nextElement
;
266 input
.nextElement
= next
;
268 input
.parentElement
= this.parentElement
;
272 * Move this element up in its parent's list of children.
274 public void moveUp() {
275 if (parentElement
!= null) {
276 int index
= parentElement
.childElements
.indexOf(this);
278 parentElement
.childElements
.add(index
- 1, parentElement
.childElements
.remove(index
));
279 parentElement
.childElements
.get(index
).nextElement
= nextElement
;
280 nextElement
= parentElement
.childElements
.get(index
);
286 * Move this element down in its parent's list of children.
288 public void moveDown() {
289 if (parentElement
!= null) {
290 int index
= parentElement
.childElements
.indexOf(this);
291 if (index
< parentElement
.childElements
.size() - 1) {
292 parentElement
.childElements
.add(index
+ 1, parentElement
.childElements
.remove(index
));
293 nextElement
= parentElement
.childElements
.get(index
).nextElement
;
294 parentElement
.childElements
.get(index
).nextElement
= this;
302 * Wrapper for XML element attributes
304 public static class InputAttribute
{
306 /** Name of the XML attribute */
307 public String attributeName
;
310 public String inputName
;
313 public int inputAction
;
316 public String inputFormat
;
319 * Default (empty) constructor
321 public InputAttribute() {
327 * @param attributeName
328 * Name of the XML attribute
336 public InputAttribute(String attributeName
, String inputName
,
337 int inputAction
, String inputFormat
) {
338 this.attributeName
= attributeName
;
339 this.inputName
= inputName
;
340 this.inputAction
= inputAction
;
341 this.inputFormat
= inputFormat
;
347 save(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME
);
351 public void save(String path
) {
353 DocumentBuilderFactory dbf
= DocumentBuilderFactory
.newInstance();
354 DocumentBuilder db
= dbf
.newDocumentBuilder();
356 // The following allows xml parsing without access to the dtd
357 db
.setEntityResolver(createEmptyEntityResolver());
359 // The following catches xml parsing exceptions
360 db
.setErrorHandler(createErrorHandler());
363 File file
= new File(path
);
364 if (file
.canRead()) {
365 doc
= db
.parse(file
);
366 if (!doc
.getDocumentElement().getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT
)) {
370 doc
= db
.newDocument();
371 Node node
= doc
.createElement(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT
);
372 doc
.appendChild(node
);
375 Element root
= doc
.getDocumentElement();
377 Element oldDefinitionElement
= findDefinitionElement(root
, categoryName
, definitionName
);
378 if (oldDefinitionElement
!= null) {
379 root
.removeChild(oldDefinitionElement
);
381 Element definitionElement
= doc
.createElement(DEFINITION_ELEMENT
);
382 root
.appendChild(definitionElement
);
383 definitionElement
.setAttribute(CATEGORY_ATTRIBUTE
, categoryName
);
384 definitionElement
.setAttribute(NAME_ATTRIBUTE
, definitionName
);
386 Element formatElement
= doc
.createElement(TIME_STAMP_OUTPUT_FORMAT_ELEMENT
);
387 definitionElement
.appendChild(formatElement
);
388 formatElement
.appendChild(doc
.createTextNode(timeStampOutputFormat
));
390 if (rootInputElement
!= null) {
391 definitionElement
.appendChild(createInputElementElement(rootInputElement
, doc
));
394 if (outputs
!= null) {
395 for (OutputColumn output
: outputs
) {
396 Element outputColumnElement
= doc
.createElement(OUTPUT_COLUMN_ELEMENT
);
397 definitionElement
.appendChild(outputColumnElement
);
398 outputColumnElement
.setAttribute(NAME_ATTRIBUTE
, output
.name
);
402 Transformer transformer
= TransformerFactory
.newInstance().newTransformer();
403 transformer
.setOutputProperty(OutputKeys
.INDENT
, "yes"); //$NON-NLS-1$
405 // initialize StreamResult with File object to save to file
406 StreamResult result
= new StreamResult(new StringWriter());
407 DOMSource source
= new DOMSource(doc
);
408 transformer
.transform(source
, result
);
409 String xmlString
= result
.getWriter().toString();
411 try (FileWriter writer
= new FileWriter(file
);) {
412 writer
.write(xmlString
);
415 TmfTraceType
.addCustomTraceType(CustomXmlTrace
.class, categoryName
, definitionName
);
417 } catch (ParserConfigurationException
| TransformerFactoryConfigurationError
| TransformerException
| IOException
| SAXException e
) {
418 Activator
.logError("Error saving CustomXmlTraceDefinition: path=" + path
, e
); //$NON-NLS-1$
422 private Element
createInputElementElement(InputElement inputElement
, Document doc
) {
423 Element inputElementElement
= doc
.createElement(INPUT_ELEMENT_ELEMENT
);
424 inputElementElement
.setAttribute(NAME_ATTRIBUTE
, inputElement
.elementName
);
426 if (inputElement
.logEntry
) {
427 inputElementElement
.setAttribute(LOG_ENTRY_ATTRIBUTE
, Boolean
.toString(inputElement
.logEntry
));
430 if (inputElement
.parentElement
!= null) {
431 Element inputDataElement
= doc
.createElement(INPUT_DATA_ELEMENT
);
432 inputElementElement
.appendChild(inputDataElement
);
433 inputDataElement
.setAttribute(NAME_ATTRIBUTE
, inputElement
.inputName
);
434 inputDataElement
.setAttribute(ACTION_ATTRIBUTE
, Integer
.toString(inputElement
.inputAction
));
435 if (inputElement
.inputFormat
!= null) {
436 inputDataElement
.setAttribute(FORMAT_ATTRIBUTE
, inputElement
.inputFormat
);
440 if (inputElement
.attributes
!= null) {
441 for (InputAttribute attribute
: inputElement
.attributes
) {
442 Element inputAttributeElement
= doc
.createElement(ATTRIBUTE_ELEMENT
);
443 inputElementElement
.appendChild(inputAttributeElement
);
444 inputAttributeElement
.setAttribute(NAME_ATTRIBUTE
, attribute
.attributeName
);
445 Element inputDataElement
= doc
.createElement(INPUT_DATA_ELEMENT
);
446 inputAttributeElement
.appendChild(inputDataElement
);
447 inputDataElement
.setAttribute(NAME_ATTRIBUTE
, attribute
.inputName
);
448 inputDataElement
.setAttribute(ACTION_ATTRIBUTE
, Integer
.toString(attribute
.inputAction
));
449 if (attribute
.inputFormat
!= null) {
450 inputDataElement
.setAttribute(FORMAT_ATTRIBUTE
, attribute
.inputFormat
);
455 if (inputElement
.childElements
!= null) {
456 for (InputElement childInputElement
: inputElement
.childElements
) {
457 inputElementElement
.appendChild(createInputElementElement(childInputElement
, doc
));
461 return inputElementElement
;
465 * Load all custom XML trace definitions, including the user-defined and
466 * default (built-in) parsers.
468 * @return The loaded trace definitions
470 public static CustomXmlTraceDefinition
[] loadAll() {
471 return loadAll(true);
475 * Load all custom XML trace definitions, including the user-defined and,
476 * optionally, the default (built-in) parsers.
478 * @param includeDefaults
479 * if true, the default (built-in) parsers are included
481 * @return The loaded trace definitions
484 public static CustomXmlTraceDefinition
[] loadAll(boolean includeDefaults
) {
485 File defaultFile
= new File(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME
);
486 File legacyFile
= new File(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME_LEGACY
);
489 * If there is no file at the expected location, check the legacy
492 if (!defaultFile
.exists() && legacyFile
.exists()) {
493 CustomXmlTraceDefinition
[] oldDefs
= loadAll(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME_LEGACY
);
494 for (CustomXmlTraceDefinition def
: oldDefs
) {
495 /* Save in the new location */
500 Set
<CustomXmlTraceDefinition
> defs
= new TreeSet
<>(new Comparator
<CustomXmlTraceDefinition
>() {
502 public int compare(CustomXmlTraceDefinition o1
, CustomXmlTraceDefinition o2
) {
503 int result
= o1
.categoryName
.compareTo(o2
.categoryName
);
507 return o1
.definitionName
.compareTo(o2
.definitionName
);
510 defs
.addAll(Arrays
.asList(loadAll(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME
)));
511 if (includeDefaults
) {
512 defs
.addAll(Arrays
.asList(loadAll(CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_PATH_NAME
)));
514 return defs
.toArray(new CustomXmlTraceDefinition
[0]);
518 * Load all the XML trace definitions in the given definitions file.
521 * Path to the definitions file to load
522 * @return The loaded trace definitions
524 public static CustomXmlTraceDefinition
[] loadAll(String path
) {
525 File file
= new File(path
);
526 if (!file
.canRead()) {
527 return new CustomXmlTraceDefinition
[0];
529 try (FileInputStream fis
= new FileInputStream(file
);) {
531 } catch (IOException e
) {
532 Activator
.logError("Error loading all in CustomXmlTraceDefinition: path=" + path
, e
); //$NON-NLS-1$
534 return new CustomXmlTraceDefinition
[0];
538 * Load all the XML trace definitions from the given stream
541 * An input stream from which to read the definitions
542 * @return The loaded trace definitions
545 public static CustomXmlTraceDefinition
[] loadAll(InputStream stream
) {
547 DocumentBuilderFactory dbf
= DocumentBuilderFactory
.newInstance();
548 DocumentBuilder db
= dbf
.newDocumentBuilder();
550 // The following allows xml parsing without access to the dtd
551 db
.setEntityResolver(createEmptyEntityResolver());
553 // The following catches xml parsing exceptions
554 db
.setErrorHandler(createErrorHandler());
556 Document doc
= db
.parse(stream
);
557 Element root
= doc
.getDocumentElement();
558 if (!root
.getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT
)) {
559 return new CustomXmlTraceDefinition
[0];
562 ArrayList
<CustomXmlTraceDefinition
> defList
= new ArrayList
<>();
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
&& node
.getNodeName().equals(DEFINITION_ELEMENT
)) {
567 CustomXmlTraceDefinition def
= extractDefinition((Element
) node
);
573 return defList
.toArray(new CustomXmlTraceDefinition
[0]);
574 } catch (ParserConfigurationException
| SAXException
| IOException e
) {
575 Activator
.logError("Error loading all in CustomXmlTraceDefinition: path=" + stream
, e
); //$NON-NLS-1$
577 return new CustomXmlTraceDefinition
[0];
581 * Load the given trace definition.
583 * @param definitionName
584 * Name of the XML trace definition to load
585 * @return The loaded trace definition
586 * @deprecated Use {@link #load(String, String)}
589 public static CustomXmlTraceDefinition
load(String definitionName
) {
590 return load(TmfTraceType
.CUSTOM_XML_CATEGORY
, definitionName
);
594 * Load the given trace definition.
596 * @param categoryName
597 * Category of the definition to load
598 * @param definitionName
599 * Name of the XML trace definition to load
600 * @return The loaded trace definition
603 public static CustomXmlTraceDefinition
load(String categoryName
, String definitionName
) {
605 DocumentBuilderFactory dbf
= DocumentBuilderFactory
.newInstance();
606 DocumentBuilder db
= dbf
.newDocumentBuilder();
608 // The following allows xml parsing without access to the dtd
609 EntityResolver resolver
= new EntityResolver() {
611 public InputSource
resolveEntity(String publicId
, String systemId
) {
612 String empty
= ""; //$NON-NLS-1$
613 ByteArrayInputStream bais
= new ByteArrayInputStream(empty
.getBytes());
614 return new InputSource(bais
);
617 db
.setEntityResolver(resolver
);
619 // The following catches xml parsing exceptions
620 db
.setErrorHandler(new ErrorHandler() {
622 public void error(SAXParseException saxparseexception
) throws SAXException
{
626 public void warning(SAXParseException saxparseexception
) throws SAXException
{
630 public void fatalError(SAXParseException saxparseexception
) throws SAXException
{
631 throw saxparseexception
;
635 CustomXmlTraceDefinition value
= lookupXmlDefinition(categoryName
, definitionName
, db
, CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME
);
637 value
= lookupXmlDefinition(categoryName
, definitionName
, db
, CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_PATH_NAME
);
640 } catch (ParserConfigurationException
| SAXException
| IOException e
) {
641 Activator
.logError("Error loading CustomXmlTraceDefinition: definitionName=" + definitionName
, e
); //$NON-NLS-1$
646 private static CustomXmlTraceDefinition
lookupXmlDefinition(String categoryName
, String definitionName
, DocumentBuilder db
, String source
) throws SAXException
, IOException
{
647 File file
= new File(source
);
648 if (!file
.exists()) {
652 Document doc
= db
.parse(file
);
654 Element root
= doc
.getDocumentElement();
655 if (!root
.getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT
)) {
659 Element definitionElement
= findDefinitionElement(root
, categoryName
, definitionName
);
660 if (definitionElement
!= null) {
661 return extractDefinition(definitionElement
);
666 private static Element
findDefinitionElement(Element root
, String categoryName
, String definitionName
) {
667 NodeList nodeList
= root
.getChildNodes();
668 for (int i
= 0; i
< nodeList
.getLength(); i
++) {
669 Node node
= nodeList
.item(i
);
670 if (node
instanceof Element
&& node
.getNodeName().equals(DEFINITION_ELEMENT
)) {
671 Element element
= (Element
) node
;
672 String categoryAttribute
= element
.getAttribute(CATEGORY_ATTRIBUTE
);
673 if (categoryAttribute
.isEmpty()) {
674 categoryAttribute
= TmfTraceType
.CUSTOM_XML_CATEGORY
;
676 String nameAttribute
= element
.getAttribute(NAME_ATTRIBUTE
);
677 if (categoryName
.equals(categoryAttribute
) &&
678 definitionName
.equals(nameAttribute
)) {
687 * Extract a trace definition from an XML element.
689 * @param definitionElement
691 * @return The extracted trace definition
693 public static CustomXmlTraceDefinition
extractDefinition(Element definitionElement
) {
694 CustomXmlTraceDefinition def
= new CustomXmlTraceDefinition();
696 def
.categoryName
= definitionElement
.getAttribute(CATEGORY_ATTRIBUTE
);
697 if (def
.categoryName
.isEmpty()) {
698 def
.categoryName
= TmfTraceType
.CUSTOM_XML_CATEGORY
;
700 def
.definitionName
= definitionElement
.getAttribute(NAME_ATTRIBUTE
);
701 if (def
.definitionName
.isEmpty()) {
705 NodeList nodeList
= definitionElement
.getChildNodes();
706 for (int i
= 0; i
< nodeList
.getLength(); i
++) {
707 Node node
= nodeList
.item(i
);
708 String nodeName
= node
.getNodeName();
709 if (nodeName
.equals(TIME_STAMP_OUTPUT_FORMAT_ELEMENT
)) {
710 Element formatElement
= (Element
) node
;
711 def
.timeStampOutputFormat
= formatElement
.getTextContent();
712 } else if (nodeName
.equals(INPUT_ELEMENT_ELEMENT
)) {
713 InputElement inputElement
= extractInputElement((Element
) node
);
714 if (inputElement
!= null) {
715 if (def
.rootInputElement
== null) {
716 def
.rootInputElement
= inputElement
;
721 } else if (nodeName
.equals(OUTPUT_COLUMN_ELEMENT
)) {
722 Element outputColumnElement
= (Element
) node
;
723 OutputColumn outputColumn
= new OutputColumn();
724 outputColumn
.name
= outputColumnElement
.getAttribute(NAME_ATTRIBUTE
);
725 def
.outputs
.add(outputColumn
);
731 private static InputElement
extractInputElement(Element inputElementElement
) {
732 InputElement inputElement
= new InputElement();
733 inputElement
.elementName
= inputElementElement
.getAttribute(NAME_ATTRIBUTE
);
734 inputElement
.logEntry
= (Boolean
.toString(true).equals(inputElementElement
.getAttribute(LOG_ENTRY_ATTRIBUTE
))) ?
true : false;
735 NodeList nodeList
= inputElementElement
.getChildNodes();
736 for (int i
= 0; i
< nodeList
.getLength(); i
++) {
737 Node node
= nodeList
.item(i
);
738 String nodeName
= node
.getNodeName();
739 if (nodeName
.equals(INPUT_DATA_ELEMENT
)) {
740 Element inputDataElement
= (Element
) node
;
741 inputElement
.inputName
= inputDataElement
.getAttribute(NAME_ATTRIBUTE
);
742 inputElement
.inputAction
= Integer
.parseInt(inputDataElement
.getAttribute(ACTION_ATTRIBUTE
));
743 inputElement
.inputFormat
= inputDataElement
.getAttribute(FORMAT_ATTRIBUTE
);
744 } else if (nodeName
.equals(ATTRIBUTE_ELEMENT
)) {
745 Element attributeElement
= (Element
) node
;
746 InputAttribute attribute
= new InputAttribute();
747 attribute
.attributeName
= attributeElement
.getAttribute(NAME_ATTRIBUTE
);
748 NodeList attributeNodeList
= attributeElement
.getChildNodes();
749 for (int j
= 0; j
< attributeNodeList
.getLength(); j
++) {
750 Node attributeNode
= attributeNodeList
.item(j
);
751 String attributeNodeName
= attributeNode
.getNodeName();
752 if (attributeNodeName
.equals(INPUT_DATA_ELEMENT
)) {
753 Element inputDataElement
= (Element
) attributeNode
;
754 attribute
.inputName
= inputDataElement
.getAttribute(NAME_ATTRIBUTE
);
755 attribute
.inputAction
= Integer
.parseInt(inputDataElement
.getAttribute(ACTION_ATTRIBUTE
));
756 attribute
.inputFormat
= inputDataElement
.getAttribute(FORMAT_ATTRIBUTE
);
759 inputElement
.addAttribute(attribute
);
760 } else if (nodeName
.equals(INPUT_ELEMENT_ELEMENT
)) {
761 Element childInputElementElement
= (Element
) node
;
762 InputElement childInputElement
= extractInputElement(childInputElementElement
);
763 if (childInputElement
!= null) {
764 inputElement
.addChild(childInputElement
);
772 * Delete a definition from the currently loaded ones.
774 * @param definitionName
775 * The name of the definition to delete
776 * @deprecated Use {@link #delete(String, String)}
779 public static void delete(String definitionName
) {
780 delete(TmfTraceType
.CUSTOM_XML_CATEGORY
, definitionName
);
784 * Delete a definition from the currently loaded ones.
786 * @param categoryName
787 * The category of the definition to delete
788 * @param definitionName
789 * The name of the definition to delete
792 public static void delete(String categoryName
, String definitionName
) {
794 DocumentBuilderFactory dbf
= DocumentBuilderFactory
.newInstance();
795 DocumentBuilder db
= dbf
.newDocumentBuilder();
797 // The following allows xml parsing without access to the dtd
798 EntityResolver resolver
= new EntityResolver() {
800 public InputSource
resolveEntity(String publicId
, String systemId
) {
801 String empty
= ""; //$NON-NLS-1$
802 ByteArrayInputStream bais
= new ByteArrayInputStream(empty
.getBytes());
803 return new InputSource(bais
);
806 db
.setEntityResolver(resolver
);
808 // The following catches xml parsing exceptions
809 db
.setErrorHandler(new ErrorHandler() {
811 public void error(SAXParseException saxparseexception
) throws SAXException
{
815 public void warning(SAXParseException saxparseexception
) throws SAXException
{
819 public void fatalError(SAXParseException saxparseexception
) throws SAXException
{
820 throw saxparseexception
;
824 File file
= new File(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME
);
825 Document doc
= db
.parse(file
);
827 Element root
= doc
.getDocumentElement();
828 if (!root
.getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT
)) {
832 Element definitionElement
= findDefinitionElement(root
, categoryName
, definitionName
);
833 if (definitionElement
!= null) {
834 root
.removeChild(definitionElement
);
837 Transformer transformer
= TransformerFactory
.newInstance().newTransformer();
838 transformer
.setOutputProperty(OutputKeys
.INDENT
, "yes"); //$NON-NLS-1$
840 // initialize StreamResult with File object to save to file
841 StreamResult result
= new StreamResult(new StringWriter());
842 DOMSource source
= new DOMSource(doc
);
843 transformer
.transform(source
, result
);
844 String xmlString
= result
.getWriter().toString();
846 try (FileWriter writer
= new FileWriter(file
);) {
847 writer
.write(xmlString
);
850 TmfTraceType
.removeCustomTraceType(CustomXmlTrace
.class, categoryName
, definitionName
);
851 // Check if default definition needs to be reloaded
852 TmfTraceType
.addCustomTraceType(CustomXmlTrace
.class, categoryName
, definitionName
);
854 } catch (ParserConfigurationException
| SAXException
| IOException
| TransformerFactoryConfigurationError
| TransformerException e
) {
855 Activator
.logError("Error deleteing CustomXmlTraceDefinition: definitionName=" + definitionName
, e
); //$NON-NLS-1$