tmf: Move TmfTraceType and custom parsers to tmf.core
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / parsers / custom / CustomTxtTraceDefinition.java
1 /*******************************************************************************
2 * Copyright (c) 2010, 2013 Ericsson
3 *
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
8 *
9 * Contributors:
10 * Patrick Tasse - Initial API and implementation
11 *******************************************************************************/
12
13 package org.eclipse.linuxtools.tmf.core.parsers.custom;
14
15 import java.io.ByteArrayInputStream;
16 import java.io.File;
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;
22 import java.util.Map;
23 import java.util.regex.Pattern;
24 import java.util.regex.PatternSyntaxException;
25
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;
37
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;
49
50 /**
51 * Trace definition for custom text traces.
52 *
53 * @author Patrick Tassé
54 * @since 3.0
55 */
56 public class CustomTxtTraceDefinition extends CustomTraceDefinition {
57
58 /** Input lines */
59 public List<InputLine> inputs;
60
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$
63
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();
67
68 private static final String CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT = Messages.CustomTxtTraceDefinition_definitionRootElement;
69 private static final String DEFINITION_ELEMENT = Messages.CustomTxtTraceDefinition_definition;
70 private static final String NAME_ATTRIBUTE = Messages.CustomTxtTraceDefinition_name;
71 private static final String TIME_STAMP_OUTPUT_FORMAT_ELEMENT = Messages.CustomTxtTraceDefinition_timestampOutputFormat;
72 private static final String INPUT_LINE_ELEMENT = Messages.CustomTxtTraceDefinition_inputLine;
73 private static final String CARDINALITY_ELEMENT = Messages.CustomTxtTraceDefinition_cardinality;
74 private static final String MIN_ATTRIBUTE = Messages.CustomTxtTraceDefinition_min;
75 private static final String MAX_ATTRIBUTE = Messages.CustomTxtTraceDefinition_max;
76 private static final String REGEX_ELEMENT = Messages.CustomTxtTraceDefinition_regEx;
77 private static final String INPUT_DATA_ELEMENT = Messages.CustomTxtTraceDefinition_inputData;
78 private static final String ACTION_ATTRIBUTE = Messages.CustomTxtTraceDefinition_action;
79 private static final String FORMAT_ATTRIBUTE = Messages.CustomTxtTraceDefinition_format;
80 private static final String OUTPUT_COLUMN_ELEMENT = Messages.CustomTxtTraceDefinition_outputColumn;
81
82 /**
83 * Default constructor.
84 */
85 public CustomTxtTraceDefinition() {
86 this("", new ArrayList<InputLine>(0), new ArrayList<OutputColumn>(0), ""); //$NON-NLS-1$ //$NON-NLS-2$
87 }
88
89 /**
90 * Full constructor.
91 *
92 * @param logtype
93 * Name of the trace type
94 * @param inputs
95 * List of inputs
96 * @param outputs
97 * List of output columns
98 * @param timeStampOutputFormat
99 * The timestamp format to use
100 */
101 public CustomTxtTraceDefinition(String logtype, List<InputLine> inputs,
102 List<OutputColumn> outputs, String timeStampOutputFormat) {
103 this.definitionName = logtype;
104 this.inputs = inputs;
105 this.outputs = outputs;
106 this.timeStampOutputFormat = timeStampOutputFormat;
107 }
108
109 /**
110 * Wrapper to store a line of the log file
111 */
112 public static class InputLine {
113
114 /** Data columns of this line */
115 public List<InputData> columns;
116
117 /** Cardinality of this line (see {@link Cardinality}) */
118 public Cardinality cardinality;
119
120 /** Parent line */
121 public InputLine parentInput;
122
123 /** Level of this line */
124 public int level;
125
126 /** Next input line in the file */
127 public InputLine nextInput;
128
129 /** Children of this line (if one "event" spans many lines) */
130 public List<InputLine> childrenInputs;
131
132 private String regex;
133 private Pattern pattern;
134
135 /**
136 * Default (empty) constructor.
137 */
138 public InputLine() {}
139
140 /**
141 * Constructor.
142 *
143 * @param cardinality Cardinality of this line.
144 * @param regex Regex
145 * @param columns Columns to use
146 */
147 public InputLine(Cardinality cardinality, String regex, List<InputData> columns) {
148 this.cardinality = cardinality;
149 this.regex = regex;
150 this.columns = columns;
151 }
152
153 /**
154 * Set the regex of this input line
155 *
156 * @param regex
157 * Regex to set
158 */
159 public void setRegex(String regex) {
160 this.regex = regex;
161 this.pattern = null;
162 }
163
164 /**
165 * Get the current regex
166 *
167 * @return The current regex
168 */
169 public String getRegex() {
170 return regex;
171 }
172
173 /**
174 * Get the Pattern object of this line's regex
175 *
176 * @return The Pattern
177 * @throws PatternSyntaxException
178 * If the regex does not parse correctly
179 */
180 public Pattern getPattern() throws PatternSyntaxException {
181 if (pattern == null) {
182 pattern = Pattern.compile(regex);
183 }
184 return pattern;
185 }
186
187 /**
188 * Add a child line to this line.
189 *
190 * @param input
191 * The child input line
192 */
193 public void addChild(InputLine input) {
194 if (childrenInputs == null) {
195 childrenInputs = new ArrayList<>(1);
196 } else if (childrenInputs.size() > 0) {
197 InputLine last = childrenInputs.get(childrenInputs.size() - 1);
198 last.nextInput = input;
199 }
200 childrenInputs.add(input);
201 input.parentInput = this;
202 input.level = this.level + 1;
203 }
204
205 /**
206 * Set the next input line.
207 *
208 * @param input
209 * The next input line
210 */
211 public void addNext(InputLine input) {
212 if (parentInput != null) {
213 int index = parentInput.childrenInputs.indexOf(this);
214 parentInput.childrenInputs.add(index + 1, input);
215 InputLine next = nextInput;
216 nextInput = input;
217 input.nextInput = next;
218 }
219 input.parentInput = this.parentInput;
220 input.level = this.level;
221 }
222
223 /**
224 * Move this line up in its parent's children.
225 */
226 public void moveUp() {
227 if (parentInput != null) {
228 int index = parentInput.childrenInputs.indexOf(this);
229 if (index > 0) {
230 parentInput.childrenInputs.add(index - 1 , parentInput.childrenInputs.remove(index));
231 parentInput.childrenInputs.get(index).nextInput = nextInput;
232 nextInput = parentInput.childrenInputs.get(index);
233 }
234 }
235 }
236
237 /**
238 * Move this line down in its parent's children.
239 */
240 public void moveDown() {
241 if (parentInput != null) {
242 int index = parentInput.childrenInputs.indexOf(this);
243 if (index < parentInput.childrenInputs.size() - 1) {
244 parentInput.childrenInputs.add(index + 1 , parentInput.childrenInputs.remove(index));
245 nextInput = parentInput.childrenInputs.get(index).nextInput;
246 parentInput.childrenInputs.get(index).nextInput = this;
247 }
248 }
249 }
250
251 /**
252 * Add a data column to this line
253 *
254 * @param column
255 * The column to add
256 */
257 public void addColumn(InputData column) {
258 if (columns == null) {
259 columns = new ArrayList<>(1);
260 }
261 columns.add(column);
262 }
263
264 /**
265 * Get the next input lines.
266 *
267 * @param countMap
268 * The map of line "sets".
269 * @return The next list of lines.
270 */
271 public List<InputLine> getNextInputs(Map<InputLine, Integer> countMap) {
272 List<InputLine> nextInputs = new ArrayList<>();
273 InputLine next = nextInput;
274 while (next != null) {
275 nextInputs.add(next);
276 if (next.cardinality.min > 0) {
277 return nextInputs;
278 }
279 next = next.nextInput;
280 }
281 if (parentInput != null && parentInput.level > 0) {
282 int parentCount = countMap.get(parentInput);
283 if (parentCount < parentInput.getMaxCount()) {
284 nextInputs.add(parentInput);
285 }
286 if (parentCount < parentInput.getMinCount()) {
287 return nextInputs;
288 }
289 nextInputs.addAll(parentInput.getNextInputs(countMap));
290 }
291 return nextInputs;
292 }
293
294 /**
295 * Get the minimum possible amount of entries.
296 *
297 * @return The minimum
298 */
299 public int getMinCount() {
300 return cardinality.min;
301 }
302
303 /**
304 * Get the maximum possible amount of entries.
305 *
306 * @return The maximum
307 */
308 public int getMaxCount() {
309 return cardinality.max;
310 }
311
312 @Override
313 public String toString() {
314 return regex + " " + cardinality; //$NON-NLS-1$
315 }
316 }
317
318 /**
319 * Data column for input lines.
320 */
321 public static class InputData {
322
323 /** Name of this column */
324 public String name;
325
326 /** Action id */
327 public int action;
328
329 /** Format */
330 public String format;
331
332 /**
333 * Default (empty) constructor
334 */
335 public InputData() {}
336
337 /**
338 * Full constructor
339 *
340 * @param name Name
341 * @param action Action
342 * @param format Format
343 */
344 public InputData(String name, int action, String format) {
345 this.name = name;
346 this.action = action;
347 this.format = format;
348 }
349
350 /**
351 * Constructor with default format
352 *
353 * @param name Name
354 * @param action Action
355 */
356 public InputData(String name, int action) {
357 this.name = name;
358 this.action = action;
359 }
360 }
361
362 /**
363 * Input line cardinality
364 */
365 public static class Cardinality {
366
367 /** Representation of infinity */
368 public final static int INF = Integer.MAX_VALUE;
369
370 /** Preset for [1, 1] */
371 public final static Cardinality ONE = new Cardinality(1, 1);
372
373 /** Preset for [1, inf] */
374 public final static Cardinality ONE_OR_MORE = new Cardinality(1, INF);
375
376 /** Preset for [0, 1] */
377 public final static Cardinality ZERO_OR_ONE = new Cardinality(0, 1);
378
379 /** Preset for [0, inf] */
380 public final static Cardinality ZERO_OR_MORE = new Cardinality(0, INF);
381
382 private final int min;
383 private final int max;
384
385 /**
386 * Constructor.
387 *
388 * @param min
389 * Minimum
390 * @param max
391 * Maximum
392 */
393 public Cardinality(int min, int max) {
394 this.min = min;
395 this.max = max;
396 }
397
398 @Override
399 public String toString() {
400 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$
401 }
402
403 @Override
404 public int hashCode() {
405 final int prime = 31;
406 int result = 1;
407 result = prime * result + max;
408 result = prime * result + min;
409 return result;
410 }
411
412 @Override
413 public boolean equals(Object obj) {
414 if (this == obj) {
415 return true;
416 }
417 if (obj == null) {
418 return false;
419 }
420 if (!(obj instanceof Cardinality)) {
421 return false;
422 }
423 Cardinality other = (Cardinality) obj;
424 return (this.min == other.min && this.max == other.max);
425 }
426 }
427
428 @Override
429 public void save() {
430 save(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME);
431 }
432
433 @Override
434 public void save(String path) {
435 try {
436 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
437 DocumentBuilder db = dbf.newDocumentBuilder();
438
439 // The following allows xml parsing without access to the dtd
440 EntityResolver resolver = new EntityResolver() {
441 @Override
442 public InputSource resolveEntity(String publicId, String systemId) {
443 String empty = ""; //$NON-NLS-1$
444 ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes());
445 return new InputSource(bais);
446 }
447 };
448 db.setEntityResolver(resolver);
449
450 // The following catches xml parsing exceptions
451 db.setErrorHandler(new ErrorHandler() {
452 @Override
453 public void error(SAXParseException saxparseexception) throws SAXException {}
454
455 @Override
456 public void warning(SAXParseException saxparseexception) throws SAXException {}
457
458 @Override
459 public void fatalError(SAXParseException saxparseexception) throws SAXException {
460 throw saxparseexception;
461 }
462 });
463
464 Document doc = null;
465 File file = new File(path);
466 if (file.canRead()) {
467 doc = db.parse(file);
468 if (! doc.getDocumentElement().getNodeName().equals(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT)) {
469 return;
470 }
471 } else {
472 doc = db.newDocument();
473 Node node = doc.createElement(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT);
474 doc.appendChild(node);
475 }
476
477 Element root = doc.getDocumentElement();
478
479 NodeList nodeList = root.getChildNodes();
480 for (int i = 0; i < nodeList.getLength(); i++) {
481 Node node = nodeList.item(i);
482 if (node instanceof Element &&
483 node.getNodeName().equals(DEFINITION_ELEMENT) &&
484 definitionName.equals(((Element) node).getAttribute(NAME_ATTRIBUTE))) {
485 root.removeChild(node);
486 }
487 }
488 Element definitionElement = doc.createElement(DEFINITION_ELEMENT);
489 root.appendChild(definitionElement);
490 definitionElement.setAttribute(NAME_ATTRIBUTE, definitionName);
491
492 Element formatElement = doc.createElement(TIME_STAMP_OUTPUT_FORMAT_ELEMENT);
493 definitionElement.appendChild(formatElement);
494 formatElement.appendChild(doc.createTextNode(timeStampOutputFormat));
495
496 if (inputs != null) {
497 for (InputLine inputLine : inputs) {
498 definitionElement.appendChild(createInputLineElement(inputLine, doc));
499 }
500 }
501
502 if (outputs != null) {
503 for (OutputColumn output : outputs) {
504 Element outputColumnElement = doc.createElement(OUTPUT_COLUMN_ELEMENT);
505 definitionElement.appendChild(outputColumnElement);
506 outputColumnElement.setAttribute(NAME_ATTRIBUTE, output.name);
507 }
508 }
509
510 Transformer transformer = TransformerFactory.newInstance().newTransformer();
511 transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
512
513 //initialize StreamResult with File object to save to file
514 StreamResult result = new StreamResult(new StringWriter());
515 DOMSource source = new DOMSource(doc);
516 transformer.transform(source, result);
517 String xmlString = result.getWriter().toString();
518
519 try (FileWriter writer = new FileWriter(file);) {
520 writer.write(xmlString);
521 }
522
523 TmfTraceType.getInstance().addCustomTraceType(TmfTraceType.CUSTOM_TXT_CATEGORY, definitionName);
524
525 } catch (ParserConfigurationException e) {
526 Activator.logError("Error saving CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$
527 } catch (TransformerConfigurationException e) {
528 Activator.logError("Error saving CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$
529 } catch (TransformerFactoryConfigurationError e) {
530 Activator.logError("Error saving CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$
531 } catch (TransformerException e) {
532 Activator.logError("Error saving CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$
533 } catch (IOException e) {
534 Activator.logError("Error saving CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$
535 } catch (SAXException e) {
536 Activator.logError("Error saving CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$
537 }
538 }
539
540 private Element createInputLineElement(InputLine inputLine, Document doc) {
541 Element inputLineElement = doc.createElement(INPUT_LINE_ELEMENT);
542
543 Element cardinalityElement = doc.createElement(CARDINALITY_ELEMENT);
544 inputLineElement.appendChild(cardinalityElement);
545 cardinalityElement.setAttribute(MIN_ATTRIBUTE, Integer.toString(inputLine.cardinality.min));
546 cardinalityElement.setAttribute(MAX_ATTRIBUTE, Integer.toString(inputLine.cardinality.max));
547
548 Element regexElement = doc.createElement(REGEX_ELEMENT);
549 inputLineElement.appendChild(regexElement);
550 regexElement.appendChild(doc.createTextNode(inputLine.regex));
551
552 if (inputLine.columns != null) {
553 for (InputData inputData : inputLine.columns) {
554 Element inputDataElement = doc.createElement(INPUT_DATA_ELEMENT);
555 inputLineElement.appendChild(inputDataElement);
556 inputDataElement.setAttribute(NAME_ATTRIBUTE, inputData.name);
557 inputDataElement.setAttribute(ACTION_ATTRIBUTE, Integer.toString(inputData.action));
558 if (inputData.format != null) {
559 inputDataElement.setAttribute(FORMAT_ATTRIBUTE, inputData.format);
560 }
561 }
562 }
563
564 if (inputLine.childrenInputs != null) {
565 for (InputLine childInputLine : inputLine.childrenInputs) {
566 inputLineElement.appendChild(createInputLineElement(childInputLine, doc));
567 }
568 }
569
570 return inputLineElement;
571 }
572
573 /**
574 * Load the default text trace definitions file.
575 *
576 * @return The loaded trace definitions
577 */
578 public static CustomTxtTraceDefinition[] loadAll() {
579 return loadAll(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME);
580 }
581
582 /**
583 * Load a specific text trace definition file.
584 *
585 * @param path
586 * The path to the file to load
587 * @return The loaded trace definitions
588 */
589 public static CustomTxtTraceDefinition[] loadAll(String path) {
590 try {
591 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
592 DocumentBuilder db = dbf.newDocumentBuilder();
593
594 // The following allows xml parsing without access to the dtd
595 EntityResolver resolver = new EntityResolver() {
596 @Override
597 public InputSource resolveEntity(String publicId, String systemId) {
598 String empty = ""; //$NON-NLS-1$
599 ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes());
600 return new InputSource(bais);
601 }
602 };
603 db.setEntityResolver(resolver);
604
605 // The following catches xml parsing exceptions
606 db.setErrorHandler(new ErrorHandler() {
607 @Override
608 public void error(SAXParseException saxparseexception) throws SAXException {}
609
610 @Override
611 public void warning(SAXParseException saxparseexception) throws SAXException {}
612
613 @Override
614 public void fatalError(SAXParseException saxparseexception) throws SAXException {
615 throw saxparseexception;
616 }
617 });
618
619 File file = new File(path);
620 if (!file.canRead()) {
621 return new CustomTxtTraceDefinition[0];
622 }
623 Document doc = db.parse(file);
624
625 Element root = doc.getDocumentElement();
626 if (! root.getNodeName().equals(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT)) {
627 return new CustomTxtTraceDefinition[0];
628 }
629
630 ArrayList<CustomTxtTraceDefinition> defList = new ArrayList<>();
631 NodeList nodeList = root.getChildNodes();
632 for (int i = 0; i < nodeList.getLength(); i++) {
633 Node node = nodeList.item(i);
634 if (node instanceof Element && node.getNodeName().equals(DEFINITION_ELEMENT)) {
635 CustomTxtTraceDefinition def = extractDefinition((Element) node);
636 if (def != null) {
637 defList.add(def);
638 }
639 }
640 }
641 return defList.toArray(new CustomTxtTraceDefinition[0]);
642 } catch (ParserConfigurationException e) {
643 Activator.logError("Error loading all in CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$
644 } catch (SAXException e) {
645 Activator.logError("Error loading all in CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$
646 } catch (IOException e) {
647 Activator.logError("Error loading all in CustomTxtTraceDefinition: path=" + path, e); //$NON-NLS-1$
648 }
649 return new CustomTxtTraceDefinition[0];
650 }
651
652 /**
653 * Load a single definition.
654 *
655 * @param definitionName
656 * Name of the definition to load
657 * @return The loaded trace definition
658 */
659 public static CustomTxtTraceDefinition load(String definitionName) {
660 try {
661 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
662 DocumentBuilder db = dbf.newDocumentBuilder();
663
664 // The following allows xml parsing without access to the dtd
665 EntityResolver resolver = new EntityResolver() {
666 @Override
667 public InputSource resolveEntity(String publicId, String systemId) {
668 String empty = ""; //$NON-NLS-1$
669 ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes());
670 return new InputSource(bais);
671 }
672 };
673 db.setEntityResolver(resolver);
674
675 // The following catches xml parsing exceptions
676 db.setErrorHandler(new ErrorHandler() {
677 @Override
678 public void error(SAXParseException saxparseexception) throws SAXException {}
679
680 @Override
681 public void warning(SAXParseException saxparseexception) throws SAXException {}
682
683 @Override
684 public void fatalError(SAXParseException saxparseexception) throws SAXException {
685 throw saxparseexception;
686 }
687 });
688
689 File file = new File(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME);
690 Document doc = db.parse(file);
691
692 Element root = doc.getDocumentElement();
693 if (! root.getNodeName().equals(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT)) {
694 return null;
695 }
696
697 NodeList nodeList = root.getChildNodes();
698 for (int i = 0; i < nodeList.getLength(); i++) {
699 Node node = nodeList.item(i);
700 if (node instanceof Element &&
701 node.getNodeName().equals(DEFINITION_ELEMENT) &&
702 definitionName.equals(((Element) node).getAttribute(NAME_ATTRIBUTE))) {
703 return extractDefinition((Element) node);
704 }
705 }
706 } catch (ParserConfigurationException e) {
707 Activator.logError("Error loading CustomTxtTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$
708 } catch (SAXException e) {
709 Activator.logError("Error loading CustomTxtTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$
710 } catch (IOException e) {
711 Activator.logError("Error loading CustomTxtTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$
712 }
713 return null;
714 }
715
716 /**
717 * Get the definition from a definition element.
718 *
719 * @param definitionElement
720 * The Element to extract from
721 * @return The loaded trace definition
722 */
723 public static CustomTxtTraceDefinition extractDefinition(Element definitionElement) {
724 CustomTxtTraceDefinition def = new CustomTxtTraceDefinition();
725
726 def.definitionName = definitionElement.getAttribute(NAME_ATTRIBUTE);
727 if (def.definitionName == null) {
728 return null;
729 }
730
731 NodeList nodeList = definitionElement.getChildNodes();
732 for (int i = 0; i < nodeList.getLength(); i++) {
733 Node node = nodeList.item(i);
734 String nodeName = node.getNodeName();
735 if (nodeName.equals(TIME_STAMP_OUTPUT_FORMAT_ELEMENT)) {
736 Element formatElement = (Element) node;
737 def.timeStampOutputFormat = formatElement.getTextContent();
738 } else if (nodeName.equals(INPUT_LINE_ELEMENT)) {
739 InputLine inputLine = extractInputLine((Element) node);
740 if (inputLine != null) {
741 def.inputs.add(inputLine);
742 }
743 } else if (nodeName.equals(OUTPUT_COLUMN_ELEMENT)) {
744 Element outputColumnElement = (Element) node;
745 OutputColumn outputColumn = new OutputColumn();
746 outputColumn.name = outputColumnElement.getAttribute(NAME_ATTRIBUTE);
747 def.outputs.add(outputColumn);
748 }
749 }
750 return def;
751 }
752
753 private static InputLine extractInputLine(Element inputLineElement) {
754 InputLine inputLine = new InputLine();
755 NodeList nodeList = inputLineElement.getChildNodes();
756 for (int i = 0; i < nodeList.getLength(); i++) {
757 Node node = nodeList.item(i);
758 String nodeName = node.getNodeName();
759 if (nodeName.equals(CARDINALITY_ELEMENT)) {
760 Element cardinalityElement = (Element) node;
761 try {
762 int min = Integer.parseInt(cardinalityElement.getAttribute(MIN_ATTRIBUTE));
763 int max = Integer.parseInt(cardinalityElement.getAttribute(MAX_ATTRIBUTE));
764 inputLine.cardinality = new Cardinality(min, max);
765 } catch (NumberFormatException e) {
766 return null;
767 }
768 } else if (nodeName.equals(REGEX_ELEMENT)) {
769 Element regexElement = (Element) node;
770 inputLine.regex = regexElement.getTextContent();
771 } else if (nodeName.equals(INPUT_DATA_ELEMENT)) {
772 Element inputDataElement = (Element) node;
773 InputData inputData = new InputData();
774 inputData.name = inputDataElement.getAttribute(NAME_ATTRIBUTE);
775 inputData.action = Integer.parseInt(inputDataElement.getAttribute(ACTION_ATTRIBUTE));
776 inputData.format = inputDataElement.getAttribute(FORMAT_ATTRIBUTE);
777 inputLine.addColumn(inputData);
778 } else if (nodeName.equals(INPUT_LINE_ELEMENT)) {
779 Element childInputLineElement = (Element) node;
780 InputLine childInputLine = extractInputLine(childInputLineElement);
781 if (childInputLine != null) {
782 inputLine.addChild(childInputLine);
783 }
784 }
785 }
786 return inputLine;
787 }
788
789 /**
790 * Delete a definition from the currently loaded ones.
791 *
792 * @param definitionName
793 * The name of the definition to delete
794 */
795 public static void delete(String definitionName) {
796 try {
797 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
798 DocumentBuilder db = dbf.newDocumentBuilder();
799
800 // The following allows xml parsing without access to the dtd
801 EntityResolver resolver = new EntityResolver() {
802 @Override
803 public InputSource resolveEntity(String publicId, String systemId) {
804 String empty = ""; //$NON-NLS-1$
805 ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes());
806 return new InputSource(bais);
807 }
808 };
809 db.setEntityResolver(resolver);
810
811 // The following catches xml parsing exceptions
812 db.setErrorHandler(new ErrorHandler() {
813 @Override
814 public void error(SAXParseException saxparseexception) throws SAXException {}
815
816 @Override
817 public void warning(SAXParseException saxparseexception) throws SAXException {}
818
819 @Override
820 public void fatalError(SAXParseException saxparseexception) throws SAXException {
821 throw saxparseexception;
822 }
823 });
824
825 File file = new File(CUSTOM_TXT_TRACE_DEFINITIONS_PATH_NAME);
826 Document doc = db.parse(file);
827
828 Element root = doc.getDocumentElement();
829 if (! root.getNodeName().equals(CUSTOM_TXT_TRACE_DEFINITION_ROOT_ELEMENT)) {
830 return;
831 }
832
833 NodeList nodeList = root.getChildNodes();
834 for (int i = 0; i < nodeList.getLength(); i++) {
835 Node node = nodeList.item(i);
836 if (node instanceof Element &&
837 node.getNodeName().equals(DEFINITION_ELEMENT) &&
838 definitionName.equals(((Element) node).getAttribute(NAME_ATTRIBUTE))) {
839 root.removeChild(node);
840 }
841 }
842
843 Transformer transformer = TransformerFactory.newInstance().newTransformer();
844 transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
845
846 //initialize StreamResult with File object to save to file
847 StreamResult result = new StreamResult(new StringWriter());
848 DOMSource source = new DOMSource(doc);
849 transformer.transform(source, result);
850 String xmlString = result.getWriter().toString();
851
852 try (FileWriter writer = new FileWriter(file);) {
853 writer.write(xmlString);
854 }
855
856 TmfTraceType.getInstance().removeCustomTraceType(TmfTraceType.CUSTOM_TXT_CATEGORY, definitionName);
857
858 } catch (ParserConfigurationException e) {
859 Activator.logError("Error deleting CustomTxtTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$
860 } catch (SAXException e) {
861 Activator.logError("Error deleting CustomTxtTraceDefinition: definitionName= " + definitionName, e); //$NON-NLS-1$
862 } catch (IOException e) {
863 Activator.logError("Error deleting CustomTxtTraceDefinition: definitionName= " + definitionName, e); //$NON-NLS-1$
864 } catch (TransformerConfigurationException e) {
865 Activator.logError("Error deleting CustomTxtTraceDefinition: definitionName= " + definitionName, e); //$NON-NLS-1$
866 } catch (TransformerFactoryConfigurationError e) {
867 Activator.logError("Error deleting CustomTxtTraceDefinition: definitionName= " + definitionName, e); //$NON-NLS-1$
868 } catch (TransformerException e) {
869 Activator.logError("Error deleting CustomTxtTraceDefinition: definitionName= " + definitionName, e); //$NON-NLS-1$
870 }
871 }
872 }
This page took 0.053369 seconds and 5 git commands to generate.