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 parsers
12 *******************************************************************************/
14 package org
.eclipse
.linuxtools
.tmf
.core
.parsers
.custom
;
16 import java
.io
.ByteArrayInputStream
;
18 import java
.io
.FileWriter
;
19 import java
.io
.IOException
;
20 import java
.io
.StringWriter
;
21 import java
.util
.ArrayList
;
22 import java
.util
.Arrays
;
23 import java
.util
.Comparator
;
24 import java
.util
.List
;
27 import java
.util
.TreeSet
;
28 import java
.util
.regex
.Pattern
;
29 import java
.util
.regex
.PatternSyntaxException
;
31 import javax
.xml
.parsers
.DocumentBuilder
;
32 import javax
.xml
.parsers
.DocumentBuilderFactory
;
33 import javax
.xml
.parsers
.ParserConfigurationException
;
34 import javax
.xml
.transform
.OutputKeys
;
35 import javax
.xml
.transform
.Transformer
;
36 import javax
.xml
.transform
.TransformerConfigurationException
;
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
.linuxtools
.internal
.tmf
.core
.Activator
;
45 import org
.eclipse
.linuxtools
.tmf
.core
.project
.model
.TmfTraceType
;
46 import org
.w3c
.dom
.Document
;
47 import org
.w3c
.dom
.Element
;
48 import org
.w3c
.dom
.Node
;
49 import org
.w3c
.dom
.NodeList
;
50 import org
.xml
.sax
.EntityResolver
;
51 import org
.xml
.sax
.ErrorHandler
;
52 import org
.xml
.sax
.InputSource
;
53 import org
.xml
.sax
.SAXException
;
54 import org
.xml
.sax
.SAXParseException
;
57 * Trace definition for custom text traces.
59 * @author Patrick Tassé
62 public class CustomTxtTraceDefinition
extends CustomTraceDefinition
{
65 public List
<InputLine
> inputs
;
67 /** File name of the default definition file */
68 protected static final String CUSTOM_TXT_TRACE_DEFINITIONS_DEFAULT_FILE_NAME
= "custom_txt_default_parsers.xml"; //$NON-NLS-1$
69 /** File name of the definition file */
70 protected static final String CUSTOM_TXT_TRACE_DEFINITIONS_FILE_NAME
= "custom_txt_parsers.xml"; //$NON-NLS-1$
72 /** Path of the definition file */
73 protected static final String CUSTOM_TXT_TRACE_DEFINITIONS_DEFAULT_PATH_NAME
=
74 Platform
.getInstallLocation().getURL().getPath() +
75 "templates/org.eclipse.linuxtools.tmf.core/" + //$NON-NLS-1$
76 CUSTOM_TXT_TRACE_DEFINITIONS_DEFAULT_FILE_NAME
;
77 /** Path of the definition file */
78 protected static final String CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME
=
79 Activator
.getDefault().getStateLocation().addTrailingSeparator().append(CUSTOM_TXT_TRACE_DEFINITIONS_FILE_NAME
).toString();
81 /** Legacy path to the XML definitions file (in the UI plug-in)
82 * TODO Remove once we feel the transition phase is over. */
83 private static final String CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME_LEGACY
=
84 Activator
.getDefault().getStateLocation().removeLastSegments(1).addTrailingSeparator()
85 .append("org.eclipse.linuxtools.tmf.ui") //$NON-NLS-1$
86 .append(CUSTOM_TXT_TRACE_DEFINITIONS_FILE_NAME
).toString();
88 private static final String CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT
= Messages
.CustomTxtTraceDefinition_definitionRootElement
;
89 private static final String DEFINITION_ELEMENT
= Messages
.CustomTxtTraceDefinition_definition
;
90 private static final String NAME_ATTRIBUTE
= Messages
.CustomTxtTraceDefinition_name
;
91 private static final String TIME_STAMP_OUTPUT_FORMAT_ELEMENT
= Messages
.CustomTxtTraceDefinition_timestampOutputFormat
;
92 private static final String INPUT_LINE_ELEMENT
= Messages
.CustomTxtTraceDefinition_inputLine
;
93 private static final String CARDINALITY_ELEMENT
= Messages
.CustomTxtTraceDefinition_cardinality
;
94 private static final String MIN_ATTRIBUTE
= Messages
.CustomTxtTraceDefinition_min
;
95 private static final String MAX_ATTRIBUTE
= Messages
.CustomTxtTraceDefinition_max
;
96 private static final String REGEX_ELEMENT
= Messages
.CustomTxtTraceDefinition_regEx
;
97 private static final String INPUT_DATA_ELEMENT
= Messages
.CustomTxtTraceDefinition_inputData
;
98 private static final String ACTION_ATTRIBUTE
= Messages
.CustomTxtTraceDefinition_action
;
99 private static final String FORMAT_ATTRIBUTE
= Messages
.CustomTxtTraceDefinition_format
;
100 private static final String OUTPUT_COLUMN_ELEMENT
= Messages
.CustomTxtTraceDefinition_outputColumn
;
103 * Default constructor.
105 public CustomTxtTraceDefinition() {
106 this("", new ArrayList
<InputLine
>(0), new ArrayList
<OutputColumn
>(0), ""); //$NON-NLS-1$ //$NON-NLS-2$
113 * Name of the trace type
117 * List of output columns
118 * @param timeStampOutputFormat
119 * The timestamp format to use
121 public CustomTxtTraceDefinition(String logtype
, List
<InputLine
> inputs
,
122 List
<OutputColumn
> outputs
, String timeStampOutputFormat
) {
123 this.definitionName
= logtype
;
124 this.inputs
= inputs
;
125 this.outputs
= outputs
;
126 this.timeStampOutputFormat
= timeStampOutputFormat
;
130 * Wrapper to store a line of the log file
132 public static class InputLine
{
134 /** Data columns of this line */
135 public List
<InputData
> columns
;
137 /** Cardinality of this line (see {@link Cardinality}) */
138 public Cardinality cardinality
;
141 public InputLine parentInput
;
143 /** Level of this line */
146 /** Next input line in the file */
147 public InputLine nextInput
;
149 /** Children of this line (if one "event" spans many lines) */
150 public List
<InputLine
> childrenInputs
;
152 private String regex
;
153 private Pattern pattern
;
156 * Default (empty) constructor.
158 public InputLine() {}
163 * @param cardinality Cardinality of this line.
165 * @param columns Columns to use
167 public InputLine(Cardinality cardinality
, String regex
, List
<InputData
> columns
) {
168 this.cardinality
= cardinality
;
170 this.columns
= columns
;
174 * Set the regex of this input line
179 public void setRegex(String regex
) {
185 * Get the current regex
187 * @return The current regex
189 public String
getRegex() {
194 * Get the Pattern object of this line's regex
196 * @return The Pattern
197 * @throws PatternSyntaxException
198 * If the regex does not parse correctly
200 public Pattern
getPattern() throws PatternSyntaxException
{
201 if (pattern
== null) {
202 pattern
= Pattern
.compile(regex
);
208 * Add a child line to this line.
211 * The child input line
213 public void addChild(InputLine input
) {
214 if (childrenInputs
== null) {
215 childrenInputs
= new ArrayList
<>(1);
216 } else if (childrenInputs
.size() > 0) {
217 InputLine last
= childrenInputs
.get(childrenInputs
.size() - 1);
218 last
.nextInput
= input
;
220 childrenInputs
.add(input
);
221 input
.parentInput
= this;
222 input
.level
= this.level
+ 1;
226 * Set the next input line.
229 * The next input line
231 public void addNext(InputLine input
) {
232 if (parentInput
!= null) {
233 int index
= parentInput
.childrenInputs
.indexOf(this);
234 parentInput
.childrenInputs
.add(index
+ 1, input
);
235 InputLine next
= nextInput
;
237 input
.nextInput
= next
;
239 input
.parentInput
= this.parentInput
;
240 input
.level
= this.level
;
244 * Move this line up in its parent's children.
246 public void moveUp() {
247 if (parentInput
!= null) {
248 int index
= parentInput
.childrenInputs
.indexOf(this);
250 parentInput
.childrenInputs
.add(index
- 1, parentInput
.childrenInputs
.remove(index
));
251 parentInput
.childrenInputs
.get(index
).nextInput
= nextInput
;
252 nextInput
= parentInput
.childrenInputs
.get(index
);
258 * Move this line down in its parent's children.
260 public void moveDown() {
261 if (parentInput
!= null) {
262 int index
= parentInput
.childrenInputs
.indexOf(this);
263 if (index
< parentInput
.childrenInputs
.size() - 1) {
264 parentInput
.childrenInputs
.add(index
+ 1, parentInput
.childrenInputs
.remove(index
));
265 nextInput
= parentInput
.childrenInputs
.get(index
).nextInput
;
266 parentInput
.childrenInputs
.get(index
).nextInput
= this;
272 * Add a data column to this line
277 public void addColumn(InputData column
) {
278 if (columns
== null) {
279 columns
= new ArrayList
<>(1);
285 * Get the next input lines.
288 * The map of line "sets".
289 * @return The next list of lines.
291 public List
<InputLine
> getNextInputs(Map
<InputLine
, Integer
> countMap
) {
292 List
<InputLine
> nextInputs
= new ArrayList
<>();
293 InputLine next
= nextInput
;
294 while (next
!= null) {
295 nextInputs
.add(next
);
296 if (next
.cardinality
.min
> 0) {
299 next
= next
.nextInput
;
301 if (parentInput
!= null && parentInput
.level
> 0) {
302 int parentCount
= countMap
.get(parentInput
);
303 if (parentCount
< parentInput
.getMaxCount()) {
304 nextInputs
.add(parentInput
);
306 if (parentCount
< parentInput
.getMinCount()) {
309 nextInputs
.addAll(parentInput
.getNextInputs(countMap
));
315 * Get the minimum possible amount of entries.
317 * @return The minimum
319 public int getMinCount() {
320 return cardinality
.min
;
324 * Get the maximum possible amount of entries.
326 * @return The maximum
328 public int getMaxCount() {
329 return cardinality
.max
;
333 public String
toString() {
334 return regex
+ " " + cardinality
; //$NON-NLS-1$
339 * Data column for input lines.
341 public static class InputData
{
343 /** Name of this column */
350 public String format
;
353 * Default (empty) constructor
355 public InputData() {}
361 * @param action Action
362 * @param format Format
364 public InputData(String name
, int action
, String format
) {
366 this.action
= action
;
367 this.format
= format
;
371 * Constructor with default format
374 * @param action Action
376 public InputData(String name
, int action
) {
378 this.action
= action
;
383 * Input line cardinality
385 public static class Cardinality
{
387 /** Representation of infinity */
388 public final static int INF
= Integer
.MAX_VALUE
;
390 /** Preset for [1, 1] */
391 public final static Cardinality ONE
= new Cardinality(1, 1);
393 /** Preset for [1, inf] */
394 public final static Cardinality ONE_OR_MORE
= new Cardinality(1, INF
);
396 /** Preset for [0, 1] */
397 public final static Cardinality ZERO_OR_ONE
= new Cardinality(0, 1);
399 /** Preset for [0, inf] */
400 public final static Cardinality ZERO_OR_MORE
= new Cardinality(0, INF
);
402 private final int min
;
403 private final int max
;
413 public Cardinality(int min
, int max
) {
419 public String
toString() {
420 return "(" + (min
>= 0 ? min
: "?") + ',' + (max
== INF ?
"\u221E" : (max
>= 0 ? max
: "?")) + ')'; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
424 public int hashCode() {
425 final int prime
= 31;
427 result
= prime
* result
+ max
;
428 result
= prime
* result
+ min
;
433 public boolean equals(Object obj
) {
440 if (!(obj
instanceof Cardinality
)) {
443 Cardinality other
= (Cardinality
) obj
;
444 return (this.min
== other
.min
&& this.max
== other
.max
);
450 save(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME
);
454 public void save(String path
) {
456 DocumentBuilderFactory dbf
= DocumentBuilderFactory
.newInstance();
457 DocumentBuilder db
= dbf
.newDocumentBuilder();
459 // The following allows xml parsing without access to the dtd
460 EntityResolver resolver
= new EntityResolver() {
462 public InputSource
resolveEntity(String publicId
, String systemId
) {
463 String empty
= ""; //$NON-NLS-1$
464 ByteArrayInputStream bais
= new ByteArrayInputStream(empty
.getBytes());
465 return new InputSource(bais
);
468 db
.setEntityResolver(resolver
);
470 // The following catches xml parsing exceptions
471 db
.setErrorHandler(new ErrorHandler() {
473 public void error(SAXParseException saxparseexception
) throws SAXException
{}
476 public void warning(SAXParseException saxparseexception
) throws SAXException
{}
479 public void fatalError(SAXParseException saxparseexception
) throws SAXException
{
480 throw saxparseexception
;
485 File file
= new File(path
);
486 if (file
.canRead()) {
487 doc
= db
.parse(file
);
488 if (!doc
.getDocumentElement().getNodeName().equals(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT
)) {
492 doc
= db
.newDocument();
493 Node node
= doc
.createElement(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT
);
494 doc
.appendChild(node
);
497 Element root
= doc
.getDocumentElement();
499 NodeList nodeList
= root
.getChildNodes();
500 for (int i
= 0; i
< nodeList
.getLength(); i
++) {
501 Node node
= nodeList
.item(i
);
502 if (node
instanceof Element
&&
503 node
.getNodeName().equals(DEFINITION_ELEMENT
) &&
504 definitionName
.equals(((Element
) node
).getAttribute(NAME_ATTRIBUTE
))) {
505 root
.removeChild(node
);
508 Element definitionElement
= doc
.createElement(DEFINITION_ELEMENT
);
509 root
.appendChild(definitionElement
);
510 definitionElement
.setAttribute(NAME_ATTRIBUTE
, definitionName
);
512 Element formatElement
= doc
.createElement(TIME_STAMP_OUTPUT_FORMAT_ELEMENT
);
513 definitionElement
.appendChild(formatElement
);
514 formatElement
.appendChild(doc
.createTextNode(timeStampOutputFormat
));
516 if (inputs
!= null) {
517 for (InputLine inputLine
: inputs
) {
518 definitionElement
.appendChild(createInputLineElement(inputLine
, doc
));
522 if (outputs
!= null) {
523 for (OutputColumn output
: outputs
) {
524 Element outputColumnElement
= doc
.createElement(OUTPUT_COLUMN_ELEMENT
);
525 definitionElement
.appendChild(outputColumnElement
);
526 outputColumnElement
.setAttribute(NAME_ATTRIBUTE
, output
.name
);
530 Transformer transformer
= TransformerFactory
.newInstance().newTransformer();
531 transformer
.setOutputProperty(OutputKeys
.INDENT
, "yes"); //$NON-NLS-1$
533 // initialize StreamResult with File object to save to file
534 StreamResult result
= new StreamResult(new StringWriter());
535 DOMSource source
= new DOMSource(doc
);
536 transformer
.transform(source
, result
);
537 String xmlString
= result
.getWriter().toString();
539 try (FileWriter writer
= new FileWriter(file
);) {
540 writer
.write(xmlString
);
543 TmfTraceType
.addCustomTraceType(TmfTraceType
.CUSTOM_TXT_CATEGORY
, definitionName
);
545 } catch (ParserConfigurationException e
) {
546 Activator
.logError("Error saving CustomTxtTraceDefinition: path=" + path
, e
); //$NON-NLS-1$
547 } catch (TransformerConfigurationException e
) {
548 Activator
.logError("Error saving CustomTxtTraceDefinition: path=" + path
, e
); //$NON-NLS-1$
549 } catch (TransformerFactoryConfigurationError e
) {
550 Activator
.logError("Error saving CustomTxtTraceDefinition: path=" + path
, e
); //$NON-NLS-1$
551 } catch (TransformerException e
) {
552 Activator
.logError("Error saving CustomTxtTraceDefinition: path=" + path
, e
); //$NON-NLS-1$
553 } catch (IOException e
) {
554 Activator
.logError("Error saving CustomTxtTraceDefinition: path=" + path
, e
); //$NON-NLS-1$
555 } catch (SAXException e
) {
556 Activator
.logError("Error saving CustomTxtTraceDefinition: path=" + path
, e
); //$NON-NLS-1$
560 private Element
createInputLineElement(InputLine inputLine
, Document doc
) {
561 Element inputLineElement
= doc
.createElement(INPUT_LINE_ELEMENT
);
563 Element cardinalityElement
= doc
.createElement(CARDINALITY_ELEMENT
);
564 inputLineElement
.appendChild(cardinalityElement
);
565 cardinalityElement
.setAttribute(MIN_ATTRIBUTE
, Integer
.toString(inputLine
.cardinality
.min
));
566 cardinalityElement
.setAttribute(MAX_ATTRIBUTE
, Integer
.toString(inputLine
.cardinality
.max
));
568 Element regexElement
= doc
.createElement(REGEX_ELEMENT
);
569 inputLineElement
.appendChild(regexElement
);
570 regexElement
.appendChild(doc
.createTextNode(inputLine
.regex
));
572 if (inputLine
.columns
!= null) {
573 for (InputData inputData
: inputLine
.columns
) {
574 Element inputDataElement
= doc
.createElement(INPUT_DATA_ELEMENT
);
575 inputLineElement
.appendChild(inputDataElement
);
576 inputDataElement
.setAttribute(NAME_ATTRIBUTE
, inputData
.name
);
577 inputDataElement
.setAttribute(ACTION_ATTRIBUTE
, Integer
.toString(inputData
.action
));
578 if (inputData
.format
!= null) {
579 inputDataElement
.setAttribute(FORMAT_ATTRIBUTE
, inputData
.format
);
584 if (inputLine
.childrenInputs
!= null) {
585 for (InputLine childInputLine
: inputLine
.childrenInputs
) {
586 inputLineElement
.appendChild(createInputLineElement(childInputLine
, doc
));
590 return inputLineElement
;
594 * Load the default text trace definitions file.
596 * @return The loaded trace definitions
598 public static CustomTxtTraceDefinition
[] loadAll() {
599 File defaultFile
= new File(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME
);
600 File legacyFile
= new File(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME_LEGACY
);
603 * If there is no file at the expected location, check the legacy
606 if (!defaultFile
.exists() && legacyFile
.exists()) {
607 CustomTxtTraceDefinition
[] oldDefs
= loadAll(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME_LEGACY
);
608 for (CustomTxtTraceDefinition def
: oldDefs
) {
609 /* Save in the new location */
614 Set
<CustomTxtTraceDefinition
> defs
= new TreeSet
<>(new Comparator
<CustomTxtTraceDefinition
>() {
616 public int compare(CustomTxtTraceDefinition o1
, CustomTxtTraceDefinition o2
) {
617 return o1
.definitionName
.compareTo(o2
.definitionName
);
620 defs
.addAll(Arrays
.asList(loadAll(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME
)));
621 defs
.addAll(Arrays
.asList(loadAll(CUSTOM_TXT_TRACE_DEFINITIONS_DEFAULT_PATH_NAME
)));
622 return defs
.toArray(new CustomTxtTraceDefinition
[0]);
627 * Load a specific text trace definition file.
629 * @param path The path to the file to load
630 * @return The loaded trace definitions
632 public static CustomTxtTraceDefinition
[] loadAll(String path
) {
634 DocumentBuilderFactory dbf
= DocumentBuilderFactory
.newInstance();
635 DocumentBuilder db
= dbf
.newDocumentBuilder();
637 // The following allows xml parsing without access to the dtd
638 EntityResolver resolver
= new EntityResolver() {
640 public InputSource
resolveEntity(String publicId
, String systemId
) {
641 String empty
= ""; //$NON-NLS-1$
642 ByteArrayInputStream bais
= new ByteArrayInputStream(empty
.getBytes());
643 return new InputSource(bais
);
646 db
.setEntityResolver(resolver
);
648 // The following catches xml parsing exceptions
649 db
.setErrorHandler(new ErrorHandler() {
651 public void error(SAXParseException saxparseexception
) throws SAXException
{
655 public void warning(SAXParseException saxparseexception
) throws SAXException
{
659 public void fatalError(SAXParseException saxparseexception
) throws SAXException
{
660 throw saxparseexception
;
664 File file
= new File(path
);
665 if (!file
.canRead()) {
666 return new CustomTxtTraceDefinition
[0];
668 Document doc
= db
.parse(file
);
670 Element root
= doc
.getDocumentElement();
671 if (!root
.getNodeName().equals(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT
)) {
672 return new CustomTxtTraceDefinition
[0];
675 ArrayList
<CustomTxtTraceDefinition
> defList
= new ArrayList
<>();
676 NodeList nodeList
= root
.getChildNodes();
677 for (int i
= 0; i
< nodeList
.getLength(); i
++) {
678 Node node
= nodeList
.item(i
);
679 if (node
instanceof Element
&& node
.getNodeName().equals(DEFINITION_ELEMENT
)) {
680 CustomTxtTraceDefinition def
= extractDefinition((Element
) node
);
686 return defList
.toArray(new CustomTxtTraceDefinition
[0]);
687 } catch (ParserConfigurationException e
) {
688 Activator
.logError("Error loading all in CustomTxtTraceDefinition: path=" + path
, e
); //$NON-NLS-1$
689 } catch (SAXException e
) {
690 Activator
.logError("Error loading all in CustomTxtTraceDefinition: path=" + path
, e
); //$NON-NLS-1$
691 } catch (IOException e
) {
692 Activator
.logError("Error loading all in CustomTxtTraceDefinition: path=" + path
, e
); //$NON-NLS-1$
694 return new CustomTxtTraceDefinition
[0];
698 * Load a single definition.
700 * @param definitionName Name of the definition to load
701 * @return The loaded trace definition
703 public static CustomTxtTraceDefinition
load(String definitionName
) {
705 DocumentBuilderFactory dbf
= DocumentBuilderFactory
.newInstance();
706 DocumentBuilder db
= dbf
.newDocumentBuilder();
708 // The following allows xml parsing without access to the dtd
709 EntityResolver resolver
= new EntityResolver() {
711 public InputSource
resolveEntity(String publicId
, String systemId
) {
712 String empty
= ""; //$NON-NLS-1$
713 ByteArrayInputStream bais
= new ByteArrayInputStream(empty
.getBytes());
714 return new InputSource(bais
);
717 db
.setEntityResolver(resolver
);
719 // The following catches xml parsing exceptions
720 db
.setErrorHandler(new ErrorHandler() {
722 public void error(SAXParseException saxparseexception
) throws SAXException
{
726 public void warning(SAXParseException saxparseexception
) throws SAXException
{
730 public void fatalError(SAXParseException saxparseexception
) throws SAXException
{
731 throw saxparseexception
;
735 CustomTxtTraceDefinition value
= lookupDefinition(definitionName
, db
, CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME
);
737 return lookupDefinition(definitionName
, db
, CUSTOM_TXT_TRACE_DEFINITIONS_DEFAULT_PATH_NAME
);
740 } catch (ParserConfigurationException
| SAXException
| IOException e
) {
741 Activator
.logError("Error loading CustomTxtTraceDefinition: definitionName=" + definitionName
, e
); //$NON-NLS-1$
746 private static CustomTxtTraceDefinition
lookupDefinition(String definitionName
, DocumentBuilder db
, String source
) throws SAXException
, IOException
{
747 File file
= new File(source
);
748 if (!file
.exists()) {
751 Document doc
= db
.parse(file
);
753 Element root
= doc
.getDocumentElement();
754 if (!root
.getNodeName().equals(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT
)) {
758 NodeList nodeList
= root
.getChildNodes();
759 for (int i
= 0; i
< nodeList
.getLength(); i
++) {
760 Node node
= nodeList
.item(i
);
761 if (node
instanceof Element
&&
762 node
.getNodeName().equals(DEFINITION_ELEMENT
) &&
763 definitionName
.equals(((Element
) node
).getAttribute(NAME_ATTRIBUTE
))) {
764 return extractDefinition((Element
) node
);
771 * Get the definition from a definition element.
773 * @param definitionElement The Element to extract from
774 * @return The loaded trace definition
776 public static CustomTxtTraceDefinition
extractDefinition(Element definitionElement
) {
777 CustomTxtTraceDefinition def
= new CustomTxtTraceDefinition();
779 def
.definitionName
= definitionElement
.getAttribute(NAME_ATTRIBUTE
);
780 if (def
.definitionName
== null) {
784 NodeList nodeList
= definitionElement
.getChildNodes();
785 for (int i
= 0; i
< nodeList
.getLength(); i
++) {
786 Node node
= nodeList
.item(i
);
787 String nodeName
= node
.getNodeName();
788 if (nodeName
.equals(TIME_STAMP_OUTPUT_FORMAT_ELEMENT
)) {
789 Element formatElement
= (Element
) node
;
790 def
.timeStampOutputFormat
= formatElement
.getTextContent();
791 } else if (nodeName
.equals(INPUT_LINE_ELEMENT
)) {
792 InputLine inputLine
= extractInputLine((Element
) node
);
793 if (inputLine
!= null) {
794 def
.inputs
.add(inputLine
);
796 } else if (nodeName
.equals(OUTPUT_COLUMN_ELEMENT
)) {
797 Element outputColumnElement
= (Element
) node
;
798 OutputColumn outputColumn
= new OutputColumn();
799 outputColumn
.name
= outputColumnElement
.getAttribute(NAME_ATTRIBUTE
);
800 def
.outputs
.add(outputColumn
);
806 private static InputLine
extractInputLine(Element inputLineElement
) {
807 InputLine inputLine
= new InputLine();
808 NodeList nodeList
= inputLineElement
.getChildNodes();
809 for (int i
= 0; i
< nodeList
.getLength(); i
++) {
810 Node node
= nodeList
.item(i
);
811 String nodeName
= node
.getNodeName();
812 if (nodeName
.equals(CARDINALITY_ELEMENT
)) {
813 Element cardinalityElement
= (Element
) node
;
815 int min
= Integer
.parseInt(cardinalityElement
.getAttribute(MIN_ATTRIBUTE
));
816 int max
= Integer
.parseInt(cardinalityElement
.getAttribute(MAX_ATTRIBUTE
));
817 inputLine
.cardinality
= new Cardinality(min
, max
);
818 } catch (NumberFormatException e
) {
821 } else if (nodeName
.equals(REGEX_ELEMENT
)) {
822 Element regexElement
= (Element
) node
;
823 inputLine
.regex
= regexElement
.getTextContent();
824 } else if (nodeName
.equals(INPUT_DATA_ELEMENT
)) {
825 Element inputDataElement
= (Element
) node
;
826 InputData inputData
= new InputData();
827 inputData
.name
= inputDataElement
.getAttribute(NAME_ATTRIBUTE
);
828 inputData
.action
= Integer
.parseInt(inputDataElement
.getAttribute(ACTION_ATTRIBUTE
));
829 inputData
.format
= inputDataElement
.getAttribute(FORMAT_ATTRIBUTE
);
830 inputLine
.addColumn(inputData
);
831 } else if (nodeName
.equals(INPUT_LINE_ELEMENT
)) {
832 Element childInputLineElement
= (Element
) node
;
833 InputLine childInputLine
= extractInputLine(childInputLineElement
);
834 if (childInputLine
!= null) {
835 inputLine
.addChild(childInputLine
);
843 * Delete a definition from the currently loaded ones.
845 * @param definitionName The name of the definition to delete
847 public static void delete(String definitionName
) {
849 DocumentBuilderFactory dbf
= DocumentBuilderFactory
.newInstance();
850 DocumentBuilder db
= dbf
.newDocumentBuilder();
852 // The following allows xml parsing without access to the dtd
853 EntityResolver resolver
= new EntityResolver() {
855 public InputSource
resolveEntity(String publicId
, String systemId
) {
856 String empty
= ""; //$NON-NLS-1$
857 ByteArrayInputStream bais
= new ByteArrayInputStream(empty
.getBytes());
858 return new InputSource(bais
);
861 db
.setEntityResolver(resolver
);
863 // The following catches xml parsing exceptions
864 db
.setErrorHandler(new ErrorHandler() {
866 public void error(SAXParseException saxparseexception
) throws SAXException
{
870 public void warning(SAXParseException saxparseexception
) throws SAXException
{
874 public void fatalError(SAXParseException saxparseexception
) throws SAXException
{
875 throw saxparseexception
;
879 File file
= new File(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME
);
880 Document doc
= db
.parse(file
);
882 Element root
= doc
.getDocumentElement();
883 if (!root
.getNodeName().equals(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT
)) {
887 NodeList nodeList
= root
.getChildNodes();
888 for (int i
= 0; i
< nodeList
.getLength(); i
++) {
889 Node node
= nodeList
.item(i
);
890 if (node
instanceof Element
&&
891 node
.getNodeName().equals(DEFINITION_ELEMENT
) &&
892 definitionName
.equals(((Element
) node
).getAttribute(NAME_ATTRIBUTE
))) {
893 root
.removeChild(node
);
897 Transformer transformer
= TransformerFactory
.newInstance().newTransformer();
898 transformer
.setOutputProperty(OutputKeys
.INDENT
, "yes"); //$NON-NLS-1$
900 // initialize StreamResult with File object to save to file
901 StreamResult result
= new StreamResult(new StringWriter());
902 DOMSource source
= new DOMSource(doc
);
903 transformer
.transform(source
, result
);
904 String xmlString
= result
.getWriter().toString();
906 try (FileWriter writer
= new FileWriter(file
);) {
907 writer
.write(xmlString
);
910 TmfTraceType
.removeCustomTraceType(TmfTraceType
.CUSTOM_TXT_CATEGORY
, definitionName
);
912 } catch (ParserConfigurationException e
) {
913 Activator
.logError("Error deleting CustomTxtTraceDefinition: definitionName=" + definitionName
, e
); //$NON-NLS-1$
914 } catch (SAXException e
) {
915 Activator
.logError("Error deleting CustomTxtTraceDefinition: definitionName= " + definitionName
, e
); //$NON-NLS-1$
916 } catch (IOException e
) {
917 Activator
.logError("Error deleting CustomTxtTraceDefinition: definitionName= " + definitionName
, e
); //$NON-NLS-1$
918 } catch (TransformerConfigurationException e
) {
919 Activator
.logError("Error deleting CustomTxtTraceDefinition: definitionName= " + definitionName
, e
); //$NON-NLS-1$
920 } catch (TransformerFactoryConfigurationError e
) {
921 Activator
.logError("Error deleting CustomTxtTraceDefinition: definitionName= " + definitionName
, e
); //$NON-NLS-1$
922 } catch (TransformerException e
) {
923 Activator
.logError("Error deleting CustomTxtTraceDefinition: definitionName= " + definitionName
, e
); //$NON-NLS-1$