1 /*******************************************************************************
2 * Copyright (c) 2010 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
.ui
.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
.tmf
.ui
.TmfUiPlugin
;
39 import org
.w3c
.dom
.Document
;
40 import org
.w3c
.dom
.Element
;
41 import org
.w3c
.dom
.Node
;
42 import org
.w3c
.dom
.NodeList
;
43 import org
.xml
.sax
.EntityResolver
;
44 import org
.xml
.sax
.ErrorHandler
;
45 import org
.xml
.sax
.InputSource
;
46 import org
.xml
.sax
.SAXException
;
47 import org
.xml
.sax
.SAXParseException
;
49 public class CustomTxtTraceDefinition
extends CustomTraceDefinition
{
51 protected static final String CUSTOM_TXT_TRACE_DEFINITIONS_FILE_NAME
= "custom_txt_parsers.xml";
52 protected static final String CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME
=
53 TmfUiPlugin
.getDefault().getStateLocation().addTrailingSeparator().append(CUSTOM_TXT_TRACE_DEFINITIONS_FILE_NAME
).toString();
55 private static final String CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT
= "CustomTxtTraceDefinitionList";
56 private static final String DEFINITION_ELEMENT
= "Definition";
57 private static final String NAME_ATTRIBUTE
= "name";
58 private static final String TIME_STAMP_OUTPUT_FORMAT_ELEMENT
= "TimeStampOutputFormat";
59 private static final String INPUT_LINE_ELEMENT
= "InputLine";
60 private static final String CARDINALITY_ELEMENT
= "Cardinality";
61 private static final String MIN_ATTRIBUTE
= "min";
62 private static final String MAX_ATTRIBUTE
= "max";
63 private static final String REGEX_ELEMENT
= "RegEx";
64 private static final String INPUT_DATA_ELEMENT
= "InputData";
65 private static final String ACTION_ATTRIBUTE
= "action";
66 private static final String FORMAT_ATTRIBUTE
= "format";
67 private static final String OUTPUT_COLUMN_ELEMENT
= "OutputColumn";
69 public List
<InputLine
> inputs
;
71 public CustomTxtTraceDefinition() {
72 this("", new ArrayList
<InputLine
>(0), new ArrayList
<OutputColumn
>(0), "");
75 public CustomTxtTraceDefinition(String logtype
, List
<InputLine
> inputs
, List
<OutputColumn
> outputs
, String timeStampOutputFormat
) {
76 this.definitionName
= logtype
;
78 this.outputs
= outputs
;
79 this.timeStampOutputFormat
= timeStampOutputFormat
;
82 public static class InputLine
{
83 public List
<InputData
> columns
;
84 public Cardinality cardinality
;
86 private Pattern pattern
;
87 public InputLine parentInput
;
89 public InputLine nextInput
;
90 public List
<InputLine
> childrenInputs
;
92 public InputLine() {};
94 public InputLine(Cardinality cardinality
, String regex
, List
<InputData
> columns
) {
95 this.cardinality
= cardinality
;
97 this.columns
= columns
;
100 public void setRegex(String regex
) {
105 public String
getRegex() {
109 public Pattern
getPattern() throws PatternSyntaxException
{
110 if (pattern
== null) {
111 pattern
= Pattern
.compile(regex
);
116 public void addChild(InputLine input
) {
117 if (childrenInputs
== null) {
118 childrenInputs
= new ArrayList
<InputLine
>(1);
119 } else if (childrenInputs
.size() > 0) {
120 InputLine last
= childrenInputs
.get(childrenInputs
.size() - 1);
121 last
.nextInput
= input
;
123 childrenInputs
.add(input
);
124 input
.parentInput
= this;
125 input
.level
= this.level
+ 1;
128 public void addNext(InputLine input
) {
129 if (parentInput
!= null) {
130 int index
= parentInput
.childrenInputs
.indexOf(this);
131 parentInput
.childrenInputs
.add(index
+ 1, input
);
132 InputLine next
= nextInput
;
134 input
.nextInput
= next
;
136 input
.parentInput
= this.parentInput
;
137 input
.level
= this.level
;
140 public void moveUp() {
141 if (parentInput
!= null) {
142 int index
= parentInput
.childrenInputs
.indexOf(this);
144 parentInput
.childrenInputs
.add(index
- 1 , parentInput
.childrenInputs
.remove(index
));
145 parentInput
.childrenInputs
.get(index
).nextInput
= nextInput
;
146 nextInput
= parentInput
.childrenInputs
.get(index
);
151 public void moveDown() {
152 if (parentInput
!= null) {
153 int index
= parentInput
.childrenInputs
.indexOf(this);
154 if (index
< parentInput
.childrenInputs
.size() - 1) {
155 parentInput
.childrenInputs
.add(index
+ 1 , parentInput
.childrenInputs
.remove(index
));
156 nextInput
= parentInput
.childrenInputs
.get(index
).nextInput
;
157 parentInput
.childrenInputs
.get(index
).nextInput
= this;
162 public void addColumn(InputData column
) {
163 if (columns
== null) {
164 columns
= new ArrayList
<InputData
>(1);
169 public List
<InputLine
> getNextInputs(Map
<InputLine
, Integer
> countMap
) {
170 List
<InputLine
> nextInputs
= new ArrayList
<InputLine
>();
171 InputLine next
= nextInput
;
172 while (next
!= null) {
173 nextInputs
.add(next
);
174 if (next
.cardinality
.min
> 0) {
177 next
= next
.nextInput
;
179 if (parentInput
!= null && parentInput
.level
> 0) {
180 int parentCount
= countMap
.get(parentInput
);
181 if (parentCount
< parentInput
.getMaxCount()) {
182 nextInputs
.add(parentInput
);
184 if (parentCount
< parentInput
.getMinCount()) {
187 nextInputs
.addAll(parentInput
.getNextInputs(countMap
));
192 public int getMinCount() {
193 return cardinality
.min
;
196 public int getMaxCount() {
197 return cardinality
.max
;
201 public String
toString() {
202 return regex
+ " " + cardinality
;
207 public static class InputData
{
210 public String format
;
212 public InputData() {};
214 public InputData(String name
, int action
, String format
) {
216 this.action
= action
;
217 this.format
= format
;
220 public InputData(String name
, int action
) {
222 this.action
= action
;
226 public static class Cardinality
{
227 public final static int INF
= Integer
.MAX_VALUE
;
228 public final static Cardinality ONE
= new Cardinality(1, 1);
229 public final static Cardinality ONE_OR_MORE
= new Cardinality(1, INF
);
230 public final static Cardinality ZERO_OR_ONE
= new Cardinality(0, 1);
231 public final static Cardinality ZERO_OR_MORE
= new Cardinality(0, INF
);
236 public Cardinality(int min
, int max
) {
242 public String
toString() {
243 return "(" + (min
>= 0 ? min
: "?") + "," + (max
== INF ?
"\u221E" : (max
>= 0 ? max
: "?")) + ")";
247 public boolean equals(Object obj
) {
248 if (!(obj
instanceof Cardinality
)) return false;
249 Cardinality other
= (Cardinality
) obj
;
250 return (this.min
== other
.min
&& this.max
== other
.max
);
256 save(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME
);
260 public void save(String path
) {
262 DocumentBuilderFactory dbf
= DocumentBuilderFactory
.newInstance();
263 DocumentBuilder db
= dbf
.newDocumentBuilder();
265 // The following allows xml parsing without access to the dtd
266 EntityResolver resolver
= new EntityResolver () {
268 public InputSource
resolveEntity (String publicId
, String systemId
) {
270 ByteArrayInputStream bais
= new ByteArrayInputStream(empty
.getBytes());
271 return new InputSource(bais
);
274 db
.setEntityResolver(resolver
);
276 // The following catches xml parsing exceptions
277 db
.setErrorHandler(new ErrorHandler(){
279 public void error(SAXParseException saxparseexception
) throws SAXException
{}
281 public void warning(SAXParseException saxparseexception
) throws SAXException
{}
283 public void fatalError(SAXParseException saxparseexception
) throws SAXException
{
284 throw saxparseexception
;
288 File file
= new File(path
);
289 if (file
.canRead()) {
290 doc
= db
.parse(file
);
291 if (! doc
.getDocumentElement().getNodeName().equals(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT
)) {
295 doc
= db
.newDocument();
296 Node node
= doc
.createElement(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT
);
297 doc
.appendChild(node
);
300 Element root
= doc
.getDocumentElement();
302 NodeList nodeList
= root
.getChildNodes();
303 for (int i
= 0; i
< nodeList
.getLength(); i
++) {
304 Node node
= nodeList
.item(i
);
305 if (node
instanceof Element
&&
306 node
.getNodeName().equals(DEFINITION_ELEMENT
) &&
307 definitionName
.equals(((Element
) node
).getAttribute(NAME_ATTRIBUTE
))) {
308 root
.removeChild(node
);
311 Element definitionElement
= doc
.createElement(DEFINITION_ELEMENT
);
312 root
.appendChild(definitionElement
);
313 definitionElement
.setAttribute(NAME_ATTRIBUTE
, definitionName
);
315 Element formatElement
= doc
.createElement(TIME_STAMP_OUTPUT_FORMAT_ELEMENT
);
316 definitionElement
.appendChild(formatElement
);
317 formatElement
.appendChild(doc
.createTextNode(timeStampOutputFormat
));
319 if (inputs
!= null) {
320 for (InputLine inputLine
: inputs
) {
321 definitionElement
.appendChild(createInputLineElement(inputLine
, doc
));
325 if (outputs
!= null) {
326 for (OutputColumn output
: outputs
) {
327 Element outputColumnElement
= doc
.createElement(OUTPUT_COLUMN_ELEMENT
);
328 definitionElement
.appendChild(outputColumnElement
);
329 outputColumnElement
.setAttribute(NAME_ATTRIBUTE
, output
.name
);
333 Transformer transformer
= TransformerFactory
.newInstance().newTransformer();
334 transformer
.setOutputProperty(OutputKeys
.INDENT
, "yes");
336 //initialize StreamResult with File object to save to file
337 StreamResult result
= new StreamResult(new StringWriter());
338 DOMSource source
= new DOMSource(doc
);
339 transformer
.transform(source
, result
);
340 String xmlString
= result
.getWriter().toString();
342 FileWriter writer
= new FileWriter(file
);
343 writer
.write(xmlString
);
345 } catch (ParserConfigurationException e
) {
347 } catch (TransformerConfigurationException e
) {
349 } catch (TransformerFactoryConfigurationError e
) {
351 } catch (TransformerException e
) {
353 } catch (IOException e
) {
355 } catch (SAXException e
) {
360 private Element
createInputLineElement(InputLine inputLine
, Document doc
) {
361 Element inputLineElement
= doc
.createElement(INPUT_LINE_ELEMENT
);
363 Element cardinalityElement
= doc
.createElement(CARDINALITY_ELEMENT
);
364 inputLineElement
.appendChild(cardinalityElement
);
365 cardinalityElement
.setAttribute(MIN_ATTRIBUTE
, Integer
.toString(inputLine
.cardinality
.min
));
366 cardinalityElement
.setAttribute(MAX_ATTRIBUTE
, Integer
.toString(inputLine
.cardinality
.max
));
368 Element regexElement
= doc
.createElement(REGEX_ELEMENT
);
369 inputLineElement
.appendChild(regexElement
);
370 regexElement
.appendChild(doc
.createTextNode(inputLine
.regex
));
372 if (inputLine
.columns
!= null) {
373 for (InputData inputData
: inputLine
.columns
) {
374 Element inputDataElement
= doc
.createElement(INPUT_DATA_ELEMENT
);
375 inputLineElement
.appendChild(inputDataElement
);
376 inputDataElement
.setAttribute(NAME_ATTRIBUTE
, inputData
.name
);
377 inputDataElement
.setAttribute(ACTION_ATTRIBUTE
, Integer
.toString(inputData
.action
));
378 if (inputData
.format
!= null) {
379 inputDataElement
.setAttribute(FORMAT_ATTRIBUTE
, inputData
.format
);
384 if (inputLine
.childrenInputs
!= null) {
385 for (InputLine childInputLine
: inputLine
.childrenInputs
) {
386 inputLineElement
.appendChild(createInputLineElement(childInputLine
, doc
));
390 return inputLineElement
;
393 public static CustomTxtTraceDefinition
[] loadAll() {
394 return loadAll(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME
);
397 public static CustomTxtTraceDefinition
[] loadAll(String path
) {
399 DocumentBuilderFactory dbf
= DocumentBuilderFactory
.newInstance();
400 DocumentBuilder db
= dbf
.newDocumentBuilder();
402 // The following allows xml parsing without access to the dtd
403 EntityResolver resolver
= new EntityResolver () {
405 public InputSource
resolveEntity (String publicId
, String systemId
) {
407 ByteArrayInputStream bais
= new ByteArrayInputStream(empty
.getBytes());
408 return new InputSource(bais
);
411 db
.setEntityResolver(resolver
);
413 // The following catches xml parsing exceptions
414 db
.setErrorHandler(new ErrorHandler(){
416 public void error(SAXParseException saxparseexception
) throws SAXException
{}
418 public void warning(SAXParseException saxparseexception
) throws SAXException
{}
420 public void fatalError(SAXParseException saxparseexception
) throws SAXException
{
421 throw saxparseexception
;
424 File file
= new File(path
);
425 if (!file
.canRead()) {
426 return new CustomTxtTraceDefinition
[0];
428 Document doc
= db
.parse(file
);
430 Element root
= doc
.getDocumentElement();
431 if (! root
.getNodeName().equals(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT
)) {
432 return new CustomTxtTraceDefinition
[0];
435 ArrayList
<CustomTxtTraceDefinition
> defList
= new ArrayList
<CustomTxtTraceDefinition
>();
436 NodeList nodeList
= root
.getChildNodes();
437 for (int i
= 0; i
< nodeList
.getLength(); i
++) {
438 Node node
= nodeList
.item(i
);
439 if (node
instanceof Element
&& node
.getNodeName().equals(DEFINITION_ELEMENT
)) {
440 CustomTxtTraceDefinition def
= extractDefinition((Element
) node
);
446 return defList
.toArray(new CustomTxtTraceDefinition
[0]);
447 } catch (ParserConfigurationException e
) {
449 } catch (SAXException e
) {
451 } catch (IOException e
) {
454 return new CustomTxtTraceDefinition
[0];
457 public static CustomTxtTraceDefinition
load(String definitionName
) {
459 DocumentBuilderFactory dbf
= DocumentBuilderFactory
.newInstance();
460 DocumentBuilder db
= dbf
.newDocumentBuilder();
462 // The following allows xml parsing without access to the dtd
463 EntityResolver resolver
= new EntityResolver () {
465 public InputSource
resolveEntity (String publicId
, String systemId
) {
467 ByteArrayInputStream bais
= new ByteArrayInputStream(empty
.getBytes());
468 return new InputSource(bais
);
471 db
.setEntityResolver(resolver
);
473 // The following catches xml parsing exceptions
474 db
.setErrorHandler(new ErrorHandler(){
476 public void error(SAXParseException saxparseexception
) throws SAXException
{}
478 public void warning(SAXParseException saxparseexception
) throws SAXException
{}
480 public void fatalError(SAXParseException saxparseexception
) throws SAXException
{
481 throw saxparseexception
;
484 File file
= new File(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME
);
485 Document doc
= db
.parse(file
);
487 Element root
= doc
.getDocumentElement();
488 if (! root
.getNodeName().equals(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT
)) {
492 NodeList nodeList
= root
.getChildNodes();
493 for (int i
= 0; i
< nodeList
.getLength(); i
++) {
494 Node node
= nodeList
.item(i
);
495 if (node
instanceof Element
&&
496 node
.getNodeName().equals(DEFINITION_ELEMENT
) &&
497 definitionName
.equals(((Element
) node
).getAttribute(NAME_ATTRIBUTE
))) {
498 return extractDefinition((Element
) node
);
501 } catch (ParserConfigurationException e
) {
503 } catch (SAXException e
) {
505 } catch (IOException e
) {
511 public static CustomTxtTraceDefinition
extractDefinition(Element definitionElement
) {
512 CustomTxtTraceDefinition def
= new CustomTxtTraceDefinition();
514 def
.definitionName
= definitionElement
.getAttribute(NAME_ATTRIBUTE
);
515 if (def
.definitionName
== null) return null;
517 NodeList nodeList
= definitionElement
.getChildNodes();
518 for (int i
= 0; i
< nodeList
.getLength(); i
++) {
519 Node node
= nodeList
.item(i
);
520 String nodeName
= node
.getNodeName();
521 if (nodeName
.equals(TIME_STAMP_OUTPUT_FORMAT_ELEMENT
)) {
522 Element formatElement
= (Element
) node
;
523 def
.timeStampOutputFormat
= formatElement
.getTextContent();
524 } else if (nodeName
.equals(INPUT_LINE_ELEMENT
)) {
525 InputLine inputLine
= extractInputLine((Element
) node
);
526 if (inputLine
!= null) {
527 def
.inputs
.add(inputLine
);
529 } else if (nodeName
.equals(OUTPUT_COLUMN_ELEMENT
)) {
530 Element outputColumnElement
= (Element
) node
;
531 OutputColumn outputColumn
= new OutputColumn();
532 outputColumn
.name
= outputColumnElement
.getAttribute(NAME_ATTRIBUTE
);
533 def
.outputs
.add(outputColumn
);
539 private static InputLine
extractInputLine(Element inputLineElement
) {
540 InputLine inputLine
= new InputLine();
541 NodeList nodeList
= inputLineElement
.getChildNodes();
542 for (int i
= 0; i
< nodeList
.getLength(); i
++) {
543 Node node
= nodeList
.item(i
);
544 String nodeName
= node
.getNodeName();
545 if (nodeName
.equals(CARDINALITY_ELEMENT
)) {
546 Element cardinalityElement
= (Element
) node
;
548 int min
= Integer
.parseInt(cardinalityElement
.getAttribute(MIN_ATTRIBUTE
));
549 int max
= Integer
.parseInt(cardinalityElement
.getAttribute(MAX_ATTRIBUTE
));
550 inputLine
.cardinality
= new Cardinality(min
, max
);
551 } catch (NumberFormatException e
) {
554 } else if (nodeName
.equals(REGEX_ELEMENT
)) {
555 Element regexElement
= (Element
) node
;
556 inputLine
.regex
= regexElement
.getTextContent();
557 } else if (nodeName
.equals(INPUT_DATA_ELEMENT
)) {
558 Element inputDataElement
= (Element
) node
;
559 InputData inputData
= new InputData();
560 inputData
.name
= inputDataElement
.getAttribute(NAME_ATTRIBUTE
);
561 inputData
.action
= Integer
.parseInt(inputDataElement
.getAttribute(ACTION_ATTRIBUTE
));
562 inputData
.format
= inputDataElement
.getAttribute(FORMAT_ATTRIBUTE
);
563 inputLine
.addColumn(inputData
);
564 } else if (nodeName
.equals(INPUT_LINE_ELEMENT
)) {
565 Element childInputLineElement
= (Element
) node
;
566 InputLine childInputLine
= extractInputLine(childInputLineElement
);
567 if (childInputLine
!= null) {
568 inputLine
.addChild(childInputLine
);
575 public static void delete(String definitionName
) {
577 DocumentBuilderFactory dbf
= DocumentBuilderFactory
.newInstance();
578 DocumentBuilder db
= dbf
.newDocumentBuilder();
580 // The following allows xml parsing without access to the dtd
581 EntityResolver resolver
= new EntityResolver () {
583 public InputSource
resolveEntity (String publicId
, String systemId
) {
585 ByteArrayInputStream bais
= new ByteArrayInputStream(empty
.getBytes());
586 return new InputSource(bais
);
589 db
.setEntityResolver(resolver
);
591 // The following catches xml parsing exceptions
592 db
.setErrorHandler(new ErrorHandler(){
594 public void error(SAXParseException saxparseexception
) throws SAXException
{}
596 public void warning(SAXParseException saxparseexception
) throws SAXException
{}
598 public void fatalError(SAXParseException saxparseexception
) throws SAXException
{
599 throw saxparseexception
;
602 File file
= new File(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME
);
603 Document doc
= db
.parse(file
);
605 Element root
= doc
.getDocumentElement();
606 if (! root
.getNodeName().equals(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT
)) {
610 NodeList nodeList
= root
.getChildNodes();
611 for (int i
= 0; i
< nodeList
.getLength(); i
++) {
612 Node node
= nodeList
.item(i
);
613 if (node
instanceof Element
&&
614 node
.getNodeName().equals(DEFINITION_ELEMENT
) &&
615 definitionName
.equals(((Element
) node
).getAttribute(NAME_ATTRIBUTE
))) {
616 root
.removeChild(node
);
620 Transformer transformer
= TransformerFactory
.newInstance().newTransformer();
621 transformer
.setOutputProperty(OutputKeys
.INDENT
, "yes");
623 //initialize StreamResult with File object to save to file
624 StreamResult result
= new StreamResult(new StringWriter());
625 DOMSource source
= new DOMSource(doc
);
626 transformer
.transform(source
, result
);
627 String xmlString
= result
.getWriter().toString();
629 FileWriter writer
= new FileWriter(file
);
630 writer
.write(xmlString
);
632 } catch (ParserConfigurationException e
) {
634 } catch (SAXException e
) {
636 } catch (IOException e
) {
638 } catch (TransformerConfigurationException e
) {
640 } catch (TransformerFactoryConfigurationError e
) {
642 } catch (TransformerException e
) {