1 /*******************************************************************************
2 * Copyright (c) 2010, 2016 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
.tracecompass
.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
.Collection
;
26 import java
.util
.Comparator
;
27 import java
.util
.List
;
28 import java
.util
.Map
.Entry
;
30 import java
.util
.TreeSet
;
32 import javax
.xml
.parsers
.DocumentBuilder
;
33 import javax
.xml
.parsers
.DocumentBuilderFactory
;
34 import javax
.xml
.parsers
.ParserConfigurationException
;
35 import javax
.xml
.transform
.OutputKeys
;
36 import javax
.xml
.transform
.Transformer
;
37 import javax
.xml
.transform
.TransformerException
;
38 import javax
.xml
.transform
.TransformerFactory
;
39 import javax
.xml
.transform
.TransformerFactoryConfigurationError
;
40 import javax
.xml
.transform
.dom
.DOMSource
;
41 import javax
.xml
.transform
.stream
.StreamResult
;
43 import org
.eclipse
.core
.runtime
.Platform
;
44 import org
.eclipse
.jdt
.annotation
.NonNull
;
45 import org
.eclipse
.tracecompass
.internal
.tmf
.core
.Activator
;
46 import org
.eclipse
.tracecompass
.tmf
.core
.project
.model
.TmfTraceType
;
47 import org
.w3c
.dom
.Document
;
48 import org
.w3c
.dom
.Element
;
49 import org
.w3c
.dom
.Node
;
50 import org
.w3c
.dom
.NodeList
;
51 import org
.xml
.sax
.EntityResolver
;
52 import org
.xml
.sax
.ErrorHandler
;
53 import org
.xml
.sax
.InputSource
;
54 import org
.xml
.sax
.SAXException
;
55 import org
.xml
.sax
.SAXParseException
;
58 * Trace definition for custom XML traces.
60 * @author Patrick Tassé
62 public class CustomXmlTraceDefinition
extends CustomTraceDefinition
{
65 * @deprecated Use {@link org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTraceDefinition.Tag#IGNORE} instead. */
67 public static final String TAG_IGNORE
= Messages
.CustomXmlTraceDefinition_ignoreTag
;
70 * Custom XML label used internally and therefore should not be externalized
72 public static final String CUSTOM_XML_CATEGORY
= "Custom XML"; //$NON-NLS-1$
75 /** Name of the default XML definitions file */
76 protected static final String CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_FILE_NAME
= "custom_xml_default_parsers.xml"; //$NON-NLS-1$
78 /** Name of the XML definitions file */
79 protected static final String CUSTOM_XML_TRACE_DEFINITIONS_FILE_NAME
= "custom_xml_parsers.xml"; //$NON-NLS-1$
81 /** Path to the XML definitions file */
82 protected static final String CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_PATH_NAME
=
83 Platform
.getInstallLocation().getURL().getPath() + "templates/org.eclipse.linuxtools.tmf.core/" + //$NON-NLS-1$
84 CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_FILE_NAME
;
86 /** Path to the XML definitions file */
87 protected static final String CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME
=
88 Activator
.getDefault().getStateLocation().addTrailingSeparator().append(CUSTOM_XML_TRACE_DEFINITIONS_FILE_NAME
).toString();
91 * Legacy path to the XML definitions file (in the UI plug-in of linux tools) TODO Remove
92 * once we feel the transition phase is over.
94 private static final String CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME_LEGACY_UI
=
95 Activator
.getDefault().getStateLocation().removeLastSegments(1).addTrailingSeparator()
96 .append("org.eclipse.linuxtools.tmf.ui") //$NON-NLS-1$
97 .append(CUSTOM_XML_TRACE_DEFINITIONS_FILE_NAME
).toString();
100 * Legacy path to the XML definitions file (in the core plug-in of linux tools) TODO Remove
101 * once we feel the transition phase is over.
103 private static final String CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME_LEGACY_CORE
=
104 Activator
.getDefault().getStateLocation().removeLastSegments(1).addTrailingSeparator()
105 .append("org.eclipse.linuxtools.tmf.core") //$NON-NLS-1$
106 .append(CUSTOM_XML_TRACE_DEFINITIONS_FILE_NAME
).toString();
108 // TODO: These strings should not be externalized
109 private static final String CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT
= Messages
.CustomXmlTraceDefinition_definitionRootElement
;
110 private static final String DEFINITION_ELEMENT
= Messages
.CustomXmlTraceDefinition_definition
;
111 private static final String CATEGORY_ATTRIBUTE
= Messages
.CustomXmlTraceDefinition_category
;
112 private static final String TAG_ATTRIBUTE
= Messages
.CustomXmlTraceDefinition_tag
;
113 private static final String NAME_ATTRIBUTE
= Messages
.CustomXmlTraceDefinition_name
;
114 private static final String LOG_ENTRY_ATTRIBUTE
= Messages
.CustomXmlTraceDefinition_logEntry
;
115 private static final String EVENT_TYPE_ATTRIBUTE
= Messages
.CustomXmlTraceDefinition_eventType
;
116 private static final String TIME_STAMP_OUTPUT_FORMAT_ELEMENT
= Messages
.CustomXmlTraceDefinition_timestampOutputFormat
;
117 private static final String INPUT_ELEMENT_ELEMENT
= Messages
.CustomXmlTraceDefinition_inputElement
;
118 private static final String ATTRIBUTE_ELEMENT
= Messages
.CustomXmlTraceDefinition_attribute
;
119 private static final String INPUT_DATA_ELEMENT
= Messages
.CustomXmlTraceDefinition_inputData
;
120 private static final String ACTION_ATTRIBUTE
= Messages
.CustomXmlTraceDefinition_action
;
121 private static final String FORMAT_ATTRIBUTE
= Messages
.CustomXmlTraceDefinition_format
;
122 private static final String OUTPUT_COLUMN_ELEMENT
= Messages
.CustomXmlTraceDefinition_outputColumn
;
125 * This is the value that the extension sets for traceContentType to be able
126 * to load an XML parser
128 private static final String TRACE_CONTENT_TYPE_ATTRIBUTE_VALUE
= "xml"; //$NON-NLS-1$
130 /** Top-level input element */
131 public CustomXmlInputElement rootInputElement
;
134 * Default constructor
136 public CustomXmlTraceDefinition() {
137 this(CUSTOM_XML_CATEGORY
, "", null, new ArrayList
<OutputColumn
>(), ""); //$NON-NLS-1$ //$NON-NLS-2$
144 * Category of the trace type
146 * Name of the trace type
148 * The top-level XML element
150 * The list of output columns
151 * @param timeStampOutputFormat
152 * The timestamp format to use
154 public CustomXmlTraceDefinition(String category
, String traceType
, CustomXmlInputElement rootElement
,
155 List
<OutputColumn
> outputs
, String timeStampOutputFormat
) {
156 this.categoryName
= category
;
157 this.definitionName
= traceType
;
158 this.rootInputElement
= rootElement
;
159 this.outputs
= outputs
;
160 this.timeStampOutputFormat
= timeStampOutputFormat
;
165 save(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME
);
169 public void save(String path
) {
171 DocumentBuilderFactory dbf
= DocumentBuilderFactory
.newInstance();
172 DocumentBuilder db
= dbf
.newDocumentBuilder();
174 // The following allows xml parsing without access to the dtd
175 db
.setEntityResolver(createEmptyEntityResolver());
177 // The following catches xml parsing exceptions
178 db
.setErrorHandler(createErrorHandler());
181 File file
= new File(path
);
182 if (file
.canRead()) {
183 doc
= db
.parse(file
);
184 if (!doc
.getDocumentElement().getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT
)) {
185 Activator
.logError(String
.format("Error saving CustomXmlTraceDefinition: path=%s is not a valid custom parser file", path
)); //$NON-NLS-1$
189 doc
= db
.newDocument();
190 Node node
= doc
.createElement(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT
);
191 doc
.appendChild(node
);
194 Element root
= doc
.getDocumentElement();
196 Element oldDefinitionElement
= findDefinitionElement(root
, categoryName
, definitionName
);
197 if (oldDefinitionElement
!= null) {
198 root
.removeChild(oldDefinitionElement
);
200 Element definitionElement
= doc
.createElement(DEFINITION_ELEMENT
);
201 root
.appendChild(definitionElement
);
202 definitionElement
.setAttribute(CATEGORY_ATTRIBUTE
, categoryName
);
203 definitionElement
.setAttribute(NAME_ATTRIBUTE
, definitionName
);
205 if (timeStampOutputFormat
!= null && !timeStampOutputFormat
.isEmpty()) {
206 Element formatElement
= doc
.createElement(TIME_STAMP_OUTPUT_FORMAT_ELEMENT
);
207 definitionElement
.appendChild(formatElement
);
208 formatElement
.appendChild(doc
.createTextNode(timeStampOutputFormat
));
211 if (rootInputElement
!= null) {
212 definitionElement
.appendChild(createInputElementElement(rootInputElement
, doc
));
215 if (outputs
!= null) {
216 for (OutputColumn output
: outputs
) {
217 Element outputColumnElement
= doc
.createElement(OUTPUT_COLUMN_ELEMENT
);
218 definitionElement
.appendChild(outputColumnElement
);
219 outputColumnElement
.setAttribute(TAG_ATTRIBUTE
, output
.tag
.name());
220 outputColumnElement
.setAttribute(NAME_ATTRIBUTE
, output
.name
);
224 Transformer transformer
= TransformerFactory
.newInstance().newTransformer();
225 transformer
.setOutputProperty(OutputKeys
.INDENT
, "yes"); //$NON-NLS-1$
227 // initialize StreamResult with File object to save to file
228 StreamResult result
= new StreamResult(new StringWriter());
229 DOMSource source
= new DOMSource(doc
);
230 transformer
.transform(source
, result
);
231 String xmlString
= result
.getWriter().toString();
233 try (FileWriter writer
= new FileWriter(file
);) {
234 writer
.write(xmlString
);
237 TmfTraceType
.addCustomTraceType(CustomXmlTrace
.class, categoryName
, definitionName
);
239 } catch (ParserConfigurationException
| TransformerFactoryConfigurationError
| TransformerException
| IOException
| SAXException e
) {
240 Activator
.logError("Error saving CustomXmlTraceDefinition: path=" + path
, e
); //$NON-NLS-1$
244 private Element
createInputElementElement(CustomXmlInputElement inputElement
, Document doc
) {
245 Element inputElementElement
= doc
.createElement(INPUT_ELEMENT_ELEMENT
);
246 inputElementElement
.setAttribute(NAME_ATTRIBUTE
, inputElement
.getElementName());
248 if (inputElement
.isLogEntry()) {
249 inputElementElement
.setAttribute(LOG_ENTRY_ATTRIBUTE
, Boolean
.toString(inputElement
.isLogEntry()));
252 if (inputElement
.getEventType() != null) {
253 inputElementElement
.setAttribute(EVENT_TYPE_ATTRIBUTE
, inputElement
.getEventType());
256 if (inputElement
.getParentElement() != null) {
257 Element inputDataElement
= doc
.createElement(INPUT_DATA_ELEMENT
);
258 inputElementElement
.appendChild(inputDataElement
);
259 inputDataElement
.setAttribute(TAG_ATTRIBUTE
, inputElement
.getInputTag().name());
260 inputDataElement
.setAttribute(NAME_ATTRIBUTE
, inputElement
.getInputName());
261 inputDataElement
.setAttribute(ACTION_ATTRIBUTE
, Integer
.toString(inputElement
.getInputAction()));
262 String inputFormat
= inputElement
.getInputFormat();
263 if (inputFormat
!= null && !inputFormat
.isEmpty()) {
264 inputDataElement
.setAttribute(FORMAT_ATTRIBUTE
, inputFormat
);
268 if (inputElement
.getAttributes() != null) {
269 for (CustomXmlInputAttribute attribute
: inputElement
.getAttributes()) {
270 Element inputAttributeElement
= doc
.createElement(ATTRIBUTE_ELEMENT
);
271 inputElementElement
.appendChild(inputAttributeElement
);
272 inputAttributeElement
.setAttribute(NAME_ATTRIBUTE
, attribute
.getAttributeName());
273 Element inputDataElement
= doc
.createElement(INPUT_DATA_ELEMENT
);
274 inputAttributeElement
.appendChild(inputDataElement
);
275 inputDataElement
.setAttribute(TAG_ATTRIBUTE
, attribute
.getInputTag().name());
276 inputDataElement
.setAttribute(NAME_ATTRIBUTE
, attribute
.getInputName());
277 inputDataElement
.setAttribute(ACTION_ATTRIBUTE
, Integer
.toString(attribute
.getInputAction()));
278 String inputFormat
= attribute
.getInputFormat();
279 if (inputFormat
!= null && !inputFormat
.isEmpty()) {
280 inputDataElement
.setAttribute(FORMAT_ATTRIBUTE
, inputFormat
);
285 if (inputElement
.getChildElements() != null) {
286 for (CustomXmlInputElement childInputElement
: inputElement
.getChildElements()) {
287 inputElementElement
.appendChild(createInputElementElement(childInputElement
, doc
));
291 return inputElementElement
;
295 * Load all custom XML trace definitions, including the user-defined and
296 * default (built-in) parsers.
298 * @return The loaded trace definitions
300 public static CustomXmlTraceDefinition
[] loadAll() {
301 return loadAll(true);
305 * Load all custom XML trace definitions, including the user-defined and,
306 * optionally, the default (built-in) parsers.
308 * @param includeDefaults
309 * if true, the default (built-in) parsers are included
311 * @return The loaded trace definitions
313 public static CustomXmlTraceDefinition
[] loadAll(boolean includeDefaults
) {
314 File defaultFile
= new File(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME
);
315 File legacyFileUI
= new File(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME_LEGACY_UI
);
316 File legacyFileCore
= new File(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME_LEGACY_CORE
);
319 * If there is no file at the expected location, check the legacy
322 if (!defaultFile
.exists()) {
323 if (legacyFileCore
.exists()) {
324 transferDefinitions(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME_LEGACY_CORE
);
325 } else if (legacyFileUI
.exists()) {
326 transferDefinitions(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME_LEGACY_UI
);
330 Set
<CustomXmlTraceDefinition
> defs
= new TreeSet
<>(new Comparator
<CustomXmlTraceDefinition
>() {
332 public int compare(CustomXmlTraceDefinition o1
, CustomXmlTraceDefinition o2
) {
333 int result
= o1
.categoryName
.compareTo(o2
.categoryName
);
337 return o1
.definitionName
.compareTo(o2
.definitionName
);
340 defs
.addAll(Arrays
.asList(loadAll(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME
)));
341 if (includeDefaults
) {
342 defs
.addAll(Arrays
.asList(loadAll(CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_PATH_NAME
)));
344 // Also load definitions contributed by extensions
345 Collection
<String
> paths
= getExtensionDefinitionsPaths(TRACE_CONTENT_TYPE_ATTRIBUTE_VALUE
);
346 for (String customTraceDefinitionPath
: paths
) {
347 defs
.addAll(Arrays
.asList(loadAll(customTraceDefinitionPath
)));
350 return defs
.toArray(new CustomXmlTraceDefinition
[0]);
353 private static void transferDefinitions(String defFile
) {
354 CustomXmlTraceDefinition
[] oldDefs
= loadAll(defFile
);
355 for (CustomXmlTraceDefinition def
: oldDefs
) {
356 /* Save in the new location */
363 * Load all the XML trace definitions in the given definitions file.
366 * Path to the definitions file to load
367 * @return The loaded trace definitions
369 public static CustomXmlTraceDefinition
[] loadAll(String path
) {
370 File file
= new File(path
);
371 if (!file
.canRead()) {
372 return new CustomXmlTraceDefinition
[0];
374 try (FileInputStream fis
= new FileInputStream(file
);) {
376 } catch (IOException e
) {
377 Activator
.logError("Error loading all in CustomXmlTraceDefinition: path=" + path
, e
); //$NON-NLS-1$
379 return new CustomXmlTraceDefinition
[0];
383 * Load all the XML trace definitions from the given stream
386 * An input stream from which to read the definitions
387 * @return The loaded trace definitions
389 public static CustomXmlTraceDefinition
[] loadAll(InputStream stream
) {
391 DocumentBuilderFactory dbf
= DocumentBuilderFactory
.newInstance();
392 DocumentBuilder db
= dbf
.newDocumentBuilder();
394 // The following allows xml parsing without access to the dtd
395 db
.setEntityResolver(createEmptyEntityResolver());
397 // The following catches xml parsing exceptions
398 db
.setErrorHandler(createErrorHandler());
400 Document doc
= db
.parse(stream
);
401 Element root
= doc
.getDocumentElement();
402 if (!root
.getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT
)) {
403 return new CustomXmlTraceDefinition
[0];
406 ArrayList
<CustomXmlTraceDefinition
> defList
= new ArrayList
<>();
407 NodeList nodeList
= root
.getChildNodes();
408 for (int i
= 0; i
< nodeList
.getLength(); i
++) {
409 Node node
= nodeList
.item(i
);
410 if (node
instanceof Element
&& node
.getNodeName().equals(DEFINITION_ELEMENT
)) {
411 CustomXmlTraceDefinition def
= extractDefinition((Element
) node
);
417 return defList
.toArray(new CustomXmlTraceDefinition
[0]);
418 } catch (ParserConfigurationException
| SAXException
| IOException e
) {
419 Activator
.logError("Error loading all in CustomXmlTraceDefinition: path=" + stream
, e
); //$NON-NLS-1$
421 return new CustomXmlTraceDefinition
[0];
425 * Load the given trace definition.
427 * @param categoryName
428 * Category of the definition to load
429 * @param definitionName
430 * Name of the XML trace definition to load
431 * @return The loaded trace definition
433 public static CustomXmlTraceDefinition
load(String categoryName
, String definitionName
) {
435 DocumentBuilderFactory dbf
= DocumentBuilderFactory
.newInstance();
436 DocumentBuilder db
= dbf
.newDocumentBuilder();
438 // The following allows xml parsing without access to the dtd
439 EntityResolver resolver
= new EntityResolver() {
441 public InputSource
resolveEntity(String publicId
, String systemId
) {
442 String empty
= ""; //$NON-NLS-1$
443 ByteArrayInputStream bais
= new ByteArrayInputStream(empty
.getBytes());
444 return new InputSource(bais
);
447 db
.setEntityResolver(resolver
);
449 // The following catches xml parsing exceptions
450 db
.setErrorHandler(new ErrorHandler() {
452 public void error(SAXParseException saxparseexception
) throws SAXException
{
456 public void warning(SAXParseException saxparseexception
) throws SAXException
{
460 public void fatalError(SAXParseException saxparseexception
) throws SAXException
{
461 throw saxparseexception
;
465 CustomXmlTraceDefinition value
= lookupXmlDefinition(categoryName
, definitionName
, db
, CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME
);
467 value
= lookupXmlDefinition(categoryName
, definitionName
, db
, CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_PATH_NAME
);
470 } catch (ParserConfigurationException
| SAXException
| IOException e
) {
471 Activator
.logError("Error loading CustomXmlTraceDefinition: definitionName=" + definitionName
, e
); //$NON-NLS-1$
476 private static CustomXmlTraceDefinition
lookupXmlDefinition(String categoryName
, String definitionName
, DocumentBuilder db
, String source
) throws SAXException
, IOException
{
477 File file
= new File(source
);
478 if (!file
.exists()) {
482 Document doc
= db
.parse(file
);
484 Element root
= doc
.getDocumentElement();
485 if (!root
.getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT
)) {
489 Element definitionElement
= findDefinitionElement(root
, categoryName
, definitionName
);
490 if (definitionElement
!= null) {
491 return extractDefinition(definitionElement
);
496 private static Element
findDefinitionElement(Element root
, String categoryName
, String definitionName
) {
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 Element element
= (Element
) node
;
502 String categoryAttribute
= element
.getAttribute(CATEGORY_ATTRIBUTE
);
503 if (categoryAttribute
.isEmpty()) {
504 categoryAttribute
= CUSTOM_XML_CATEGORY
;
506 String nameAttribute
= element
.getAttribute(NAME_ATTRIBUTE
);
507 if (categoryName
.equals(categoryAttribute
) &&
508 definitionName
.equals(nameAttribute
)) {
517 * Extract a trace definition from an XML element.
519 * @param definitionElement
521 * @return The extracted trace definition
523 public static CustomXmlTraceDefinition
extractDefinition(Element definitionElement
) {
524 CustomXmlTraceDefinition def
= new CustomXmlTraceDefinition();
526 def
.categoryName
= definitionElement
.getAttribute(CATEGORY_ATTRIBUTE
);
527 if (def
.categoryName
.isEmpty()) {
528 def
.categoryName
= CUSTOM_XML_CATEGORY
;
530 def
.definitionName
= definitionElement
.getAttribute(NAME_ATTRIBUTE
);
531 if (def
.definitionName
.isEmpty()) {
535 NodeList nodeList
= definitionElement
.getChildNodes();
536 for (int i
= 0; i
< nodeList
.getLength(); i
++) {
537 Node node
= nodeList
.item(i
);
538 String nodeName
= node
.getNodeName();
539 if (nodeName
.equals(TIME_STAMP_OUTPUT_FORMAT_ELEMENT
)) {
540 Element formatElement
= (Element
) node
;
541 def
.timeStampOutputFormat
= formatElement
.getTextContent();
542 } else if (nodeName
.equals(INPUT_ELEMENT_ELEMENT
)) {
543 CustomXmlInputElement inputElement
= extractInputElement((Element
) node
);
544 if (inputElement
!= null) {
545 if (def
.rootInputElement
== null) {
546 def
.rootInputElement
= inputElement
;
551 } else if (nodeName
.equals(OUTPUT_COLUMN_ELEMENT
)) {
552 Element outputColumnElement
= (Element
) node
;
553 Entry
<@NonNull Tag
, @NonNull String
> entry
= extractTagAndName(outputColumnElement
, TAG_ATTRIBUTE
, NAME_ATTRIBUTE
);
554 OutputColumn outputColumn
= new OutputColumn(entry
.getKey(), entry
.getValue());
555 def
.outputs
.add(outputColumn
);
561 private static CustomXmlInputElement
extractInputElement(Element inputElementElement
) {
562 CustomXmlInputElement inputElement
= new CustomXmlInputElement();
563 inputElement
.setElementName(inputElementElement
.getAttribute(NAME_ATTRIBUTE
));
564 inputElement
.setLogEntry((Boolean
.toString(true).equals(inputElementElement
.getAttribute(LOG_ENTRY_ATTRIBUTE
))) ?
true : false);
565 String eventType
= inputElementElement
.getAttribute(EVENT_TYPE_ATTRIBUTE
);
566 inputElement
.setEventType(eventType
.isEmpty() ?
null : eventType
);
567 NodeList nodeList
= inputElementElement
.getChildNodes();
568 for (int i
= 0; i
< nodeList
.getLength(); i
++) {
569 Node node
= nodeList
.item(i
);
570 String nodeName
= node
.getNodeName();
571 if (nodeName
.equals(INPUT_DATA_ELEMENT
)) {
572 Element inputDataElement
= (Element
) node
;
573 Entry
<@NonNull Tag
, @NonNull String
> entry
= extractTagAndName(inputDataElement
, TAG_ATTRIBUTE
, NAME_ATTRIBUTE
);
574 inputElement
.setInputTag(entry
.getKey());
575 inputElement
.setInputName(entry
.getValue());
576 inputElement
.setInputAction(Integer
.parseInt(inputDataElement
.getAttribute(ACTION_ATTRIBUTE
)));
577 inputElement
.setInputFormat(inputDataElement
.getAttribute(FORMAT_ATTRIBUTE
));
578 } else if (nodeName
.equals(ATTRIBUTE_ELEMENT
)) {
579 Element attributeElement
= (Element
) node
;
581 String attributeName
= attributeElement
.getAttribute(NAME_ATTRIBUTE
);
582 NodeList attributeNodeList
= attributeElement
.getChildNodes();
583 for (int j
= 0; j
< attributeNodeList
.getLength(); j
++) {
584 Node attributeNode
= attributeNodeList
.item(j
);
585 String attributeNodeName
= attributeNode
.getNodeName();
586 if (attributeNodeName
.equals(INPUT_DATA_ELEMENT
)) {
587 Element inputDataElement
= (Element
) attributeNode
;
588 Entry
<@NonNull Tag
, @NonNull String
> entry
= extractTagAndName(inputDataElement
, TAG_ATTRIBUTE
, NAME_ATTRIBUTE
);
589 int action
= Integer
.parseInt(inputDataElement
.getAttribute(ACTION_ATTRIBUTE
));
590 String format
= inputDataElement
.getAttribute(FORMAT_ATTRIBUTE
);
591 inputElement
.addAttribute(new CustomXmlInputAttribute(attributeName
, entry
.getKey(), entry
.getValue(), action
, format
));
595 } else if (nodeName
.equals(INPUT_ELEMENT_ELEMENT
)) {
596 Element childInputElementElement
= (Element
) node
;
597 CustomXmlInputElement childInputElement
= extractInputElement(childInputElementElement
);
598 if (childInputElement
!= null) {
599 inputElement
.addChild(childInputElement
);
607 * Delete a definition from the currently loaded ones.
609 * @param categoryName
610 * The category of the definition to delete
611 * @param definitionName
612 * The name of the definition to delete
614 public static void delete(String categoryName
, String definitionName
) {
616 DocumentBuilderFactory dbf
= DocumentBuilderFactory
.newInstance();
617 DocumentBuilder db
= dbf
.newDocumentBuilder();
619 // The following allows xml parsing without access to the dtd
620 EntityResolver resolver
= new EntityResolver() {
622 public InputSource
resolveEntity(String publicId
, String systemId
) {
623 String empty
= ""; //$NON-NLS-1$
624 ByteArrayInputStream bais
= new ByteArrayInputStream(empty
.getBytes());
625 return new InputSource(bais
);
628 db
.setEntityResolver(resolver
);
630 // The following catches xml parsing exceptions
631 db
.setErrorHandler(new ErrorHandler() {
633 public void error(SAXParseException saxparseexception
) throws SAXException
{
637 public void warning(SAXParseException saxparseexception
) throws SAXException
{
641 public void fatalError(SAXParseException saxparseexception
) throws SAXException
{
642 throw saxparseexception
;
646 File file
= new File(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME
);
647 Document doc
= db
.parse(file
);
649 Element root
= doc
.getDocumentElement();
650 if (!root
.getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT
)) {
654 Element definitionElement
= findDefinitionElement(root
, categoryName
, definitionName
);
655 if (definitionElement
!= null) {
656 root
.removeChild(definitionElement
);
659 Transformer transformer
= TransformerFactory
.newInstance().newTransformer();
660 transformer
.setOutputProperty(OutputKeys
.INDENT
, "yes"); //$NON-NLS-1$
662 // initialize StreamResult with File object to save to file
663 StreamResult result
= new StreamResult(new StringWriter());
664 DOMSource source
= new DOMSource(doc
);
665 transformer
.transform(source
, result
);
666 String xmlString
= result
.getWriter().toString();
668 try (FileWriter writer
= new FileWriter(file
);) {
669 writer
.write(xmlString
);
672 TmfTraceType
.removeCustomTraceType(CustomXmlTrace
.class, categoryName
, definitionName
);
673 // Check if default definition needs to be reloaded
674 TmfTraceType
.addCustomTraceType(CustomXmlTrace
.class, categoryName
, definitionName
);
676 } catch (ParserConfigurationException
| SAXException
| IOException
| TransformerFactoryConfigurationError
| TransformerException e
) {
677 Activator
.logError("Error deleteing CustomXmlTraceDefinition: definitionName=" + definitionName
, e
); //$NON-NLS-1$