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