1 /*******************************************************************************
2 * Copyright (c) 2010, 2013 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 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.tmf
.core
.parsers
.custom
;
15 import java
.io
.ByteArrayInputStream
;
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
;
23 import java
.util
.regex
.Pattern
;
24 import java
.util
.regex
.PatternSyntaxException
;
26 import javax
.xml
.parsers
.DocumentBuilder
;
27 import javax
.xml
.parsers
.DocumentBuilderFactory
;
28 import javax
.xml
.parsers
.ParserConfigurationException
;
29 import javax
.xml
.transform
.OutputKeys
;
30 import javax
.xml
.transform
.Transformer
;
31 import javax
.xml
.transform
.TransformerConfigurationException
;
32 import javax
.xml
.transform
.TransformerException
;
33 import javax
.xml
.transform
.TransformerFactory
;
34 import javax
.xml
.transform
.TransformerFactoryConfigurationError
;
35 import javax
.xml
.transform
.dom
.DOMSource
;
36 import javax
.xml
.transform
.stream
.StreamResult
;
38 import org
.eclipse
.linuxtools
.internal
.tmf
.core
.Activator
;
39 import org
.eclipse
.linuxtools
.tmf
.core
.project
.model
.TmfTraceType
;
40 import org
.w3c
.dom
.Document
;
41 import org
.w3c
.dom
.Element
;
42 import org
.w3c
.dom
.Node
;
43 import org
.w3c
.dom
.NodeList
;
44 import org
.xml
.sax
.EntityResolver
;
45 import org
.xml
.sax
.ErrorHandler
;
46 import org
.xml
.sax
.InputSource
;
47 import org
.xml
.sax
.SAXException
;
48 import org
.xml
.sax
.SAXParseException
;
51 * Trace definition for custom text traces.
53 * @author Patrick Tassé
56 public class CustomTxtTraceDefinition
extends CustomTraceDefinition
{
59 public List
<InputLine
> inputs
;
61 /** File name of the definition file */
62 protected static final String CUSTOM_TXT_TRACE_DEFINITIONS_FILE_NAME
= "custom_txt_parsers.xml"; //$NON-NLS-1$
64 /** Path of the definition file */
65 protected static final String CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME
=
66 Activator
.getDefault().getStateLocation().addTrailingSeparator().append(CUSTOM_TXT_TRACE_DEFINITIONS_FILE_NAME
).toString();
68 /** Legacy path to the XML definitions file (in the UI plug-in)
69 * TODO Remove once we feel the transition phase is over. */
70 private static final String CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME_LEGACY
=
71 Activator
.getDefault().getStateLocation().removeLastSegments(1).addTrailingSeparator()
72 .append("org.eclipse.linuxtools.tmf.ui") //$NON-NLS-1$
73 .append(CUSTOM_TXT_TRACE_DEFINITIONS_FILE_NAME
).toString();
75 private static final String CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT
= Messages
.CustomTxtTraceDefinition_definitionRootElement
;
76 private static final String DEFINITION_ELEMENT
= Messages
.CustomTxtTraceDefinition_definition
;
77 private static final String NAME_ATTRIBUTE
= Messages
.CustomTxtTraceDefinition_name
;
78 private static final String TIME_STAMP_OUTPUT_FORMAT_ELEMENT
= Messages
.CustomTxtTraceDefinition_timestampOutputFormat
;
79 private static final String INPUT_LINE_ELEMENT
= Messages
.CustomTxtTraceDefinition_inputLine
;
80 private static final String CARDINALITY_ELEMENT
= Messages
.CustomTxtTraceDefinition_cardinality
;
81 private static final String MIN_ATTRIBUTE
= Messages
.CustomTxtTraceDefinition_min
;
82 private static final String MAX_ATTRIBUTE
= Messages
.CustomTxtTraceDefinition_max
;
83 private static final String REGEX_ELEMENT
= Messages
.CustomTxtTraceDefinition_regEx
;
84 private static final String INPUT_DATA_ELEMENT
= Messages
.CustomTxtTraceDefinition_inputData
;
85 private static final String ACTION_ATTRIBUTE
= Messages
.CustomTxtTraceDefinition_action
;
86 private static final String FORMAT_ATTRIBUTE
= Messages
.CustomTxtTraceDefinition_format
;
87 private static final String OUTPUT_COLUMN_ELEMENT
= Messages
.CustomTxtTraceDefinition_outputColumn
;
90 * Default constructor.
92 public CustomTxtTraceDefinition() {
93 this("", new ArrayList
<InputLine
>(0), new ArrayList
<OutputColumn
>(0), ""); //$NON-NLS-1$ //$NON-NLS-2$
100 * Name of the trace type
104 * List of output columns
105 * @param timeStampOutputFormat
106 * The timestamp format to use
108 public CustomTxtTraceDefinition(String logtype
, List
<InputLine
> inputs
,
109 List
<OutputColumn
> outputs
, String timeStampOutputFormat
) {
110 this.definitionName
= logtype
;
111 this.inputs
= inputs
;
112 this.outputs
= outputs
;
113 this.timeStampOutputFormat
= timeStampOutputFormat
;
117 * Wrapper to store a line of the log file
119 public static class InputLine
{
121 /** Data columns of this line */
122 public List
<InputData
> columns
;
124 /** Cardinality of this line (see {@link Cardinality}) */
125 public Cardinality cardinality
;
128 public InputLine parentInput
;
130 /** Level of this line */
133 /** Next input line in the file */
134 public InputLine nextInput
;
136 /** Children of this line (if one "event" spans many lines) */
137 public List
<InputLine
> childrenInputs
;
139 private String regex
;
140 private Pattern pattern
;
143 * Default (empty) constructor.
145 public InputLine() {}
150 * @param cardinality Cardinality of this line.
152 * @param columns Columns to use
154 public InputLine(Cardinality cardinality
, String regex
, List
<InputData
> columns
) {
155 this.cardinality
= cardinality
;
157 this.columns
= columns
;
161 * Set the regex of this input line
166 public void setRegex(String regex
) {
172 * Get the current regex
174 * @return The current regex
176 public String
getRegex() {
181 * Get the Pattern object of this line's regex
183 * @return The Pattern
184 * @throws PatternSyntaxException
185 * If the regex does not parse correctly
187 public Pattern
getPattern() throws PatternSyntaxException
{
188 if (pattern
== null) {
189 pattern
= Pattern
.compile(regex
);
195 * Add a child line to this line.
198 * The child input line
200 public void addChild(InputLine input
) {
201 if (childrenInputs
== null) {
202 childrenInputs
= new ArrayList
<>(1);
203 } else if (childrenInputs
.size() > 0) {
204 InputLine last
= childrenInputs
.get(childrenInputs
.size() - 1);
205 last
.nextInput
= input
;
207 childrenInputs
.add(input
);
208 input
.parentInput
= this;
209 input
.level
= this.level
+ 1;
213 * Set the next input line.
216 * The next input line
218 public void addNext(InputLine input
) {
219 if (parentInput
!= null) {
220 int index
= parentInput
.childrenInputs
.indexOf(this);
221 parentInput
.childrenInputs
.add(index
+ 1, input
);
222 InputLine next
= nextInput
;
224 input
.nextInput
= next
;
226 input
.parentInput
= this.parentInput
;
227 input
.level
= this.level
;
231 * Move this line up in its parent's children.
233 public void moveUp() {
234 if (parentInput
!= null) {
235 int index
= parentInput
.childrenInputs
.indexOf(this);
237 parentInput
.childrenInputs
.add(index
- 1 , parentInput
.childrenInputs
.remove(index
));
238 parentInput
.childrenInputs
.get(index
).nextInput
= nextInput
;
239 nextInput
= parentInput
.childrenInputs
.get(index
);
245 * Move this line down in its parent's children.
247 public void moveDown() {
248 if (parentInput
!= null) {
249 int index
= parentInput
.childrenInputs
.indexOf(this);
250 if (index
< parentInput
.childrenInputs
.size() - 1) {
251 parentInput
.childrenInputs
.add(index
+ 1 , parentInput
.childrenInputs
.remove(index
));
252 nextInput
= parentInput
.childrenInputs
.get(index
).nextInput
;
253 parentInput
.childrenInputs
.get(index
).nextInput
= this;
259 * Add a data column to this line
264 public void addColumn(InputData column
) {
265 if (columns
== null) {
266 columns
= new ArrayList
<>(1);
272 * Get the next input lines.
275 * The map of line "sets".
276 * @return The next list of lines.
278 public List
<InputLine
> getNextInputs(Map
<InputLine
, Integer
> countMap
) {
279 List
<InputLine
> nextInputs
= new ArrayList
<>();
280 InputLine next
= nextInput
;
281 while (next
!= null) {
282 nextInputs
.add(next
);
283 if (next
.cardinality
.min
> 0) {
286 next
= next
.nextInput
;
288 if (parentInput
!= null && parentInput
.level
> 0) {
289 int parentCount
= countMap
.get(parentInput
);
290 if (parentCount
< parentInput
.getMaxCount()) {
291 nextInputs
.add(parentInput
);
293 if (parentCount
< parentInput
.getMinCount()) {
296 nextInputs
.addAll(parentInput
.getNextInputs(countMap
));
302 * Get the minimum possible amount of entries.
304 * @return The minimum
306 public int getMinCount() {
307 return cardinality
.min
;
311 * Get the maximum possible amount of entries.
313 * @return The maximum
315 public int getMaxCount() {
316 return cardinality
.max
;
320 public String
toString() {
321 return regex
+ " " + cardinality
; //$NON-NLS-1$
326 * Data column for input lines.
328 public static class InputData
{
330 /** Name of this column */
337 public String format
;
340 * Default (empty) constructor
342 public InputData() {}
348 * @param action Action
349 * @param format Format
351 public InputData(String name
, int action
, String format
) {
353 this.action
= action
;
354 this.format
= format
;
358 * Constructor with default format
361 * @param action Action
363 public InputData(String name
, int action
) {
365 this.action
= action
;
370 * Input line cardinality
372 public static class Cardinality
{
374 /** Representation of infinity */
375 public final static int INF
= Integer
.MAX_VALUE
;
377 /** Preset for [1, 1] */
378 public final static Cardinality ONE
= new Cardinality(1, 1);
380 /** Preset for [1, inf] */
381 public final static Cardinality ONE_OR_MORE
= new Cardinality(1, INF
);
383 /** Preset for [0, 1] */
384 public final static Cardinality ZERO_OR_ONE
= new Cardinality(0, 1);
386 /** Preset for [0, inf] */
387 public final static Cardinality ZERO_OR_MORE
= new Cardinality(0, INF
);
389 private final int min
;
390 private final int max
;
400 public Cardinality(int min
, int max
) {
406 public String
toString() {
407 return "(" + (min
>= 0 ? min
: "?") + "," + (max
== INF ?
"\u221E" : (max
>= 0 ? max
: "?")) + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
411 public int hashCode() {
412 final int prime
= 31;
414 result
= prime
* result
+ max
;
415 result
= prime
* result
+ min
;
420 public boolean equals(Object obj
) {
427 if (!(obj
instanceof Cardinality
)) {
430 Cardinality other
= (Cardinality
) obj
;
431 return (this.min
== other
.min
&& this.max
== other
.max
);
437 save(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME
);
441 public void save(String path
) {
443 DocumentBuilderFactory dbf
= DocumentBuilderFactory
.newInstance();
444 DocumentBuilder db
= dbf
.newDocumentBuilder();
446 // The following allows xml parsing without access to the dtd
447 EntityResolver resolver
= new EntityResolver() {
449 public InputSource
resolveEntity(String publicId
, String systemId
) {
450 String empty
= ""; //$NON-NLS-1$
451 ByteArrayInputStream bais
= new ByteArrayInputStream(empty
.getBytes());
452 return new InputSource(bais
);
455 db
.setEntityResolver(resolver
);
457 // The following catches xml parsing exceptions
458 db
.setErrorHandler(new ErrorHandler() {
460 public void error(SAXParseException saxparseexception
) throws SAXException
{}
463 public void warning(SAXParseException saxparseexception
) throws SAXException
{}
466 public void fatalError(SAXParseException saxparseexception
) throws SAXException
{
467 throw saxparseexception
;
472 File file
= new File(path
);
473 if (file
.canRead()) {
474 doc
= db
.parse(file
);
475 if (! doc
.getDocumentElement().getNodeName().equals(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT
)) {
479 doc
= db
.newDocument();
480 Node node
= doc
.createElement(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT
);
481 doc
.appendChild(node
);
484 Element root
= doc
.getDocumentElement();
486 NodeList nodeList
= root
.getChildNodes();
487 for (int i
= 0; i
< nodeList
.getLength(); i
++) {
488 Node node
= nodeList
.item(i
);
489 if (node
instanceof Element
&&
490 node
.getNodeName().equals(DEFINITION_ELEMENT
) &&
491 definitionName
.equals(((Element
) node
).getAttribute(NAME_ATTRIBUTE
))) {
492 root
.removeChild(node
);
495 Element definitionElement
= doc
.createElement(DEFINITION_ELEMENT
);
496 root
.appendChild(definitionElement
);
497 definitionElement
.setAttribute(NAME_ATTRIBUTE
, definitionName
);
499 Element formatElement
= doc
.createElement(TIME_STAMP_OUTPUT_FORMAT_ELEMENT
);
500 definitionElement
.appendChild(formatElement
);
501 formatElement
.appendChild(doc
.createTextNode(timeStampOutputFormat
));
503 if (inputs
!= null) {
504 for (InputLine inputLine
: inputs
) {
505 definitionElement
.appendChild(createInputLineElement(inputLine
, doc
));
509 if (outputs
!= null) {
510 for (OutputColumn output
: outputs
) {
511 Element outputColumnElement
= doc
.createElement(OUTPUT_COLUMN_ELEMENT
);
512 definitionElement
.appendChild(outputColumnElement
);
513 outputColumnElement
.setAttribute(NAME_ATTRIBUTE
, output
.name
);
517 Transformer transformer
= TransformerFactory
.newInstance().newTransformer();
518 transformer
.setOutputProperty(OutputKeys
.INDENT
, "yes"); //$NON-NLS-1$
520 //initialize StreamResult with File object to save to file
521 StreamResult result
= new StreamResult(new StringWriter());
522 DOMSource source
= new DOMSource(doc
);
523 transformer
.transform(source
, result
);
524 String xmlString
= result
.getWriter().toString();
526 try (FileWriter writer
= new FileWriter(file
);) {
527 writer
.write(xmlString
);
530 TmfTraceType
.getInstance().addCustomTraceType(TmfTraceType
.CUSTOM_TXT_CATEGORY
, definitionName
);
532 } catch (ParserConfigurationException e
) {
533 Activator
.logError("Error saving CustomTxtTraceDefinition: path=" + path
, e
); //$NON-NLS-1$
534 } catch (TransformerConfigurationException e
) {
535 Activator
.logError("Error saving CustomTxtTraceDefinition: path=" + path
, e
); //$NON-NLS-1$
536 } catch (TransformerFactoryConfigurationError e
) {
537 Activator
.logError("Error saving CustomTxtTraceDefinition: path=" + path
, e
); //$NON-NLS-1$
538 } catch (TransformerException e
) {
539 Activator
.logError("Error saving CustomTxtTraceDefinition: path=" + path
, e
); //$NON-NLS-1$
540 } catch (IOException e
) {
541 Activator
.logError("Error saving CustomTxtTraceDefinition: path=" + path
, e
); //$NON-NLS-1$
542 } catch (SAXException e
) {
543 Activator
.logError("Error saving CustomTxtTraceDefinition: path=" + path
, e
); //$NON-NLS-1$
547 private Element
createInputLineElement(InputLine inputLine
, Document doc
) {
548 Element inputLineElement
= doc
.createElement(INPUT_LINE_ELEMENT
);
550 Element cardinalityElement
= doc
.createElement(CARDINALITY_ELEMENT
);
551 inputLineElement
.appendChild(cardinalityElement
);
552 cardinalityElement
.setAttribute(MIN_ATTRIBUTE
, Integer
.toString(inputLine
.cardinality
.min
));
553 cardinalityElement
.setAttribute(MAX_ATTRIBUTE
, Integer
.toString(inputLine
.cardinality
.max
));
555 Element regexElement
= doc
.createElement(REGEX_ELEMENT
);
556 inputLineElement
.appendChild(regexElement
);
557 regexElement
.appendChild(doc
.createTextNode(inputLine
.regex
));
559 if (inputLine
.columns
!= null) {
560 for (InputData inputData
: inputLine
.columns
) {
561 Element inputDataElement
= doc
.createElement(INPUT_DATA_ELEMENT
);
562 inputLineElement
.appendChild(inputDataElement
);
563 inputDataElement
.setAttribute(NAME_ATTRIBUTE
, inputData
.name
);
564 inputDataElement
.setAttribute(ACTION_ATTRIBUTE
, Integer
.toString(inputData
.action
));
565 if (inputData
.format
!= null) {
566 inputDataElement
.setAttribute(FORMAT_ATTRIBUTE
, inputData
.format
);
571 if (inputLine
.childrenInputs
!= null) {
572 for (InputLine childInputLine
: inputLine
.childrenInputs
) {
573 inputLineElement
.appendChild(createInputLineElement(childInputLine
, doc
));
577 return inputLineElement
;
581 * Load the default text trace definitions file.
583 * @return The loaded trace definitions
585 public static CustomTxtTraceDefinition
[] loadAll() {
586 File defaultFile
= new File(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME
);
587 File legacyFile
= new File(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME_LEGACY
);
590 * If there is no file at the expected location, check the legacy
593 if (!defaultFile
.exists() && legacyFile
.exists()) {
594 CustomTxtTraceDefinition
[] oldDefs
= loadAll(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME_LEGACY
);
595 for (CustomTxtTraceDefinition def
: oldDefs
) {
596 /* Save in the new location */
601 return loadAll(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME
);
605 * Load a specific text trace definition file.
608 * The path to the file to load
609 * @return The loaded trace definitions
611 public static CustomTxtTraceDefinition
[] loadAll(String path
) {
613 DocumentBuilderFactory dbf
= DocumentBuilderFactory
.newInstance();
614 DocumentBuilder db
= dbf
.newDocumentBuilder();
616 // The following allows xml parsing without access to the dtd
617 EntityResolver resolver
= new EntityResolver() {
619 public InputSource
resolveEntity(String publicId
, String systemId
) {
620 String empty
= ""; //$NON-NLS-1$
621 ByteArrayInputStream bais
= new ByteArrayInputStream(empty
.getBytes());
622 return new InputSource(bais
);
625 db
.setEntityResolver(resolver
);
627 // The following catches xml parsing exceptions
628 db
.setErrorHandler(new ErrorHandler() {
630 public void error(SAXParseException saxparseexception
) throws SAXException
{}
633 public void warning(SAXParseException saxparseexception
) throws SAXException
{}
636 public void fatalError(SAXParseException saxparseexception
) throws SAXException
{
637 throw saxparseexception
;
641 File file
= new File(path
);
642 if (!file
.canRead()) {
643 return new CustomTxtTraceDefinition
[0];
645 Document doc
= db
.parse(file
);
647 Element root
= doc
.getDocumentElement();
648 if (! root
.getNodeName().equals(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT
)) {
649 return new CustomTxtTraceDefinition
[0];
652 ArrayList
<CustomTxtTraceDefinition
> defList
= new ArrayList
<>();
653 NodeList nodeList
= root
.getChildNodes();
654 for (int i
= 0; i
< nodeList
.getLength(); i
++) {
655 Node node
= nodeList
.item(i
);
656 if (node
instanceof Element
&& node
.getNodeName().equals(DEFINITION_ELEMENT
)) {
657 CustomTxtTraceDefinition def
= extractDefinition((Element
) node
);
663 return defList
.toArray(new CustomTxtTraceDefinition
[0]);
664 } catch (ParserConfigurationException e
) {
665 Activator
.logError("Error loading all in CustomTxtTraceDefinition: path=" + path
, e
); //$NON-NLS-1$
666 } catch (SAXException e
) {
667 Activator
.logError("Error loading all in CustomTxtTraceDefinition: path=" + path
, e
); //$NON-NLS-1$
668 } catch (IOException e
) {
669 Activator
.logError("Error loading all in CustomTxtTraceDefinition: path=" + path
, e
); //$NON-NLS-1$
671 return new CustomTxtTraceDefinition
[0];
675 * Load a single definition.
677 * @param definitionName
678 * Name of the definition to load
679 * @return The loaded trace definition
681 public static CustomTxtTraceDefinition
load(String definitionName
) {
683 DocumentBuilderFactory dbf
= DocumentBuilderFactory
.newInstance();
684 DocumentBuilder db
= dbf
.newDocumentBuilder();
686 // The following allows xml parsing without access to the dtd
687 EntityResolver resolver
= new EntityResolver() {
689 public InputSource
resolveEntity(String publicId
, String systemId
) {
690 String empty
= ""; //$NON-NLS-1$
691 ByteArrayInputStream bais
= new ByteArrayInputStream(empty
.getBytes());
692 return new InputSource(bais
);
695 db
.setEntityResolver(resolver
);
697 // The following catches xml parsing exceptions
698 db
.setErrorHandler(new ErrorHandler() {
700 public void error(SAXParseException saxparseexception
) throws SAXException
{}
703 public void warning(SAXParseException saxparseexception
) throws SAXException
{}
706 public void fatalError(SAXParseException saxparseexception
) throws SAXException
{
707 throw saxparseexception
;
711 File file
= new File(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME
);
712 Document doc
= db
.parse(file
);
714 Element root
= doc
.getDocumentElement();
715 if (! root
.getNodeName().equals(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT
)) {
719 NodeList nodeList
= root
.getChildNodes();
720 for (int i
= 0; i
< nodeList
.getLength(); i
++) {
721 Node node
= nodeList
.item(i
);
722 if (node
instanceof Element
&&
723 node
.getNodeName().equals(DEFINITION_ELEMENT
) &&
724 definitionName
.equals(((Element
) node
).getAttribute(NAME_ATTRIBUTE
))) {
725 return extractDefinition((Element
) node
);
728 } catch (ParserConfigurationException e
) {
729 Activator
.logError("Error loading CustomTxtTraceDefinition: definitionName=" + definitionName
, e
); //$NON-NLS-1$
730 } catch (SAXException e
) {
731 Activator
.logError("Error loading CustomTxtTraceDefinition: definitionName=" + definitionName
, e
); //$NON-NLS-1$
732 } catch (IOException e
) {
733 Activator
.logError("Error loading CustomTxtTraceDefinition: definitionName=" + definitionName
, e
); //$NON-NLS-1$
739 * Get the definition from a definition element.
741 * @param definitionElement
742 * The Element to extract from
743 * @return The loaded trace definition
745 public static CustomTxtTraceDefinition
extractDefinition(Element definitionElement
) {
746 CustomTxtTraceDefinition def
= new CustomTxtTraceDefinition();
748 def
.definitionName
= definitionElement
.getAttribute(NAME_ATTRIBUTE
);
749 if (def
.definitionName
== null) {
753 NodeList nodeList
= definitionElement
.getChildNodes();
754 for (int i
= 0; i
< nodeList
.getLength(); i
++) {
755 Node node
= nodeList
.item(i
);
756 String nodeName
= node
.getNodeName();
757 if (nodeName
.equals(TIME_STAMP_OUTPUT_FORMAT_ELEMENT
)) {
758 Element formatElement
= (Element
) node
;
759 def
.timeStampOutputFormat
= formatElement
.getTextContent();
760 } else if (nodeName
.equals(INPUT_LINE_ELEMENT
)) {
761 InputLine inputLine
= extractInputLine((Element
) node
);
762 if (inputLine
!= null) {
763 def
.inputs
.add(inputLine
);
765 } else if (nodeName
.equals(OUTPUT_COLUMN_ELEMENT
)) {
766 Element outputColumnElement
= (Element
) node
;
767 OutputColumn outputColumn
= new OutputColumn();
768 outputColumn
.name
= outputColumnElement
.getAttribute(NAME_ATTRIBUTE
);
769 def
.outputs
.add(outputColumn
);
775 private static InputLine
extractInputLine(Element inputLineElement
) {
776 InputLine inputLine
= new InputLine();
777 NodeList nodeList
= inputLineElement
.getChildNodes();
778 for (int i
= 0; i
< nodeList
.getLength(); i
++) {
779 Node node
= nodeList
.item(i
);
780 String nodeName
= node
.getNodeName();
781 if (nodeName
.equals(CARDINALITY_ELEMENT
)) {
782 Element cardinalityElement
= (Element
) node
;
784 int min
= Integer
.parseInt(cardinalityElement
.getAttribute(MIN_ATTRIBUTE
));
785 int max
= Integer
.parseInt(cardinalityElement
.getAttribute(MAX_ATTRIBUTE
));
786 inputLine
.cardinality
= new Cardinality(min
, max
);
787 } catch (NumberFormatException e
) {
790 } else if (nodeName
.equals(REGEX_ELEMENT
)) {
791 Element regexElement
= (Element
) node
;
792 inputLine
.regex
= regexElement
.getTextContent();
793 } else if (nodeName
.equals(INPUT_DATA_ELEMENT
)) {
794 Element inputDataElement
= (Element
) node
;
795 InputData inputData
= new InputData();
796 inputData
.name
= inputDataElement
.getAttribute(NAME_ATTRIBUTE
);
797 inputData
.action
= Integer
.parseInt(inputDataElement
.getAttribute(ACTION_ATTRIBUTE
));
798 inputData
.format
= inputDataElement
.getAttribute(FORMAT_ATTRIBUTE
);
799 inputLine
.addColumn(inputData
);
800 } else if (nodeName
.equals(INPUT_LINE_ELEMENT
)) {
801 Element childInputLineElement
= (Element
) node
;
802 InputLine childInputLine
= extractInputLine(childInputLineElement
);
803 if (childInputLine
!= null) {
804 inputLine
.addChild(childInputLine
);
812 * Delete a definition from the currently loaded ones.
814 * @param definitionName
815 * The name of the definition to delete
817 public static void delete(String definitionName
) {
819 DocumentBuilderFactory dbf
= DocumentBuilderFactory
.newInstance();
820 DocumentBuilder db
= dbf
.newDocumentBuilder();
822 // The following allows xml parsing without access to the dtd
823 EntityResolver resolver
= new EntityResolver() {
825 public InputSource
resolveEntity(String publicId
, String systemId
) {
826 String empty
= ""; //$NON-NLS-1$
827 ByteArrayInputStream bais
= new ByteArrayInputStream(empty
.getBytes());
828 return new InputSource(bais
);
831 db
.setEntityResolver(resolver
);
833 // The following catches xml parsing exceptions
834 db
.setErrorHandler(new ErrorHandler() {
836 public void error(SAXParseException saxparseexception
) throws SAXException
{}
839 public void warning(SAXParseException saxparseexception
) throws SAXException
{}
842 public void fatalError(SAXParseException saxparseexception
) throws SAXException
{
843 throw saxparseexception
;
847 File file
= new File(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME
);
848 Document doc
= db
.parse(file
);
850 Element root
= doc
.getDocumentElement();
851 if (! root
.getNodeName().equals(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT
)) {
855 NodeList nodeList
= root
.getChildNodes();
856 for (int i
= 0; i
< nodeList
.getLength(); i
++) {
857 Node node
= nodeList
.item(i
);
858 if (node
instanceof Element
&&
859 node
.getNodeName().equals(DEFINITION_ELEMENT
) &&
860 definitionName
.equals(((Element
) node
).getAttribute(NAME_ATTRIBUTE
))) {
861 root
.removeChild(node
);
865 Transformer transformer
= TransformerFactory
.newInstance().newTransformer();
866 transformer
.setOutputProperty(OutputKeys
.INDENT
, "yes"); //$NON-NLS-1$
868 //initialize StreamResult with File object to save to file
869 StreamResult result
= new StreamResult(new StringWriter());
870 DOMSource source
= new DOMSource(doc
);
871 transformer
.transform(source
, result
);
872 String xmlString
= result
.getWriter().toString();
874 try (FileWriter writer
= new FileWriter(file
);) {
875 writer
.write(xmlString
);
878 TmfTraceType
.getInstance().removeCustomTraceType(TmfTraceType
.CUSTOM_TXT_CATEGORY
, definitionName
);
880 } catch (ParserConfigurationException e
) {
881 Activator
.logError("Error deleting CustomTxtTraceDefinition: definitionName=" + definitionName
, e
); //$NON-NLS-1$
882 } catch (SAXException e
) {
883 Activator
.logError("Error deleting CustomTxtTraceDefinition: definitionName= " + definitionName
, e
); //$NON-NLS-1$
884 } catch (IOException e
) {
885 Activator
.logError("Error deleting CustomTxtTraceDefinition: definitionName= " + definitionName
, e
); //$NON-NLS-1$
886 } catch (TransformerConfigurationException e
) {
887 Activator
.logError("Error deleting CustomTxtTraceDefinition: definitionName= " + definitionName
, e
); //$NON-NLS-1$
888 } catch (TransformerFactoryConfigurationError e
) {
889 Activator
.logError("Error deleting CustomTxtTraceDefinition: definitionName= " + definitionName
, e
); //$NON-NLS-1$
890 } catch (TransformerException e
) {
891 Activator
.logError("Error deleting CustomTxtTraceDefinition: definitionName= " + definitionName
, e
); //$NON-NLS-1$