Make Custom Parser trace type backwards compatible to Linux Tools
[deliverable/tracecompass.git] / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / tmf / core / parsers / custom / CustomXmlTraceDefinition.java
1 /*******************************************************************************
2 * Copyright (c) 2010, 2015 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 * Matthew Khouzam - Add support for default xml parsers
12 *******************************************************************************/
13
14 package org.eclipse.tracecompass.tmf.core.parsers.custom;
15
16 import java.io.ByteArrayInputStream;
17 import java.io.File;
18 import java.io.FileInputStream;
19 import java.io.FileWriter;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.io.StringWriter;
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.Comparator;
26 import java.util.List;
27 import java.util.Set;
28 import java.util.TreeSet;
29
30 import javax.xml.parsers.DocumentBuilder;
31 import javax.xml.parsers.DocumentBuilderFactory;
32 import javax.xml.parsers.ParserConfigurationException;
33 import javax.xml.transform.OutputKeys;
34 import javax.xml.transform.Transformer;
35 import javax.xml.transform.TransformerException;
36 import javax.xml.transform.TransformerFactory;
37 import javax.xml.transform.TransformerFactoryConfigurationError;
38 import javax.xml.transform.dom.DOMSource;
39 import javax.xml.transform.stream.StreamResult;
40
41 import org.eclipse.core.runtime.Platform;
42 import org.eclipse.tracecompass.internal.tmf.core.Activator;
43 import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType;
44 import org.w3c.dom.Document;
45 import org.w3c.dom.Element;
46 import org.w3c.dom.Node;
47 import org.w3c.dom.NodeList;
48 import org.xml.sax.EntityResolver;
49 import org.xml.sax.ErrorHandler;
50 import org.xml.sax.InputSource;
51 import org.xml.sax.SAXException;
52 import org.xml.sax.SAXParseException;
53
54 /**
55 * Trace definition for custom XML traces.
56 *
57 * @author Patrick Tassé
58 * @since 3.0
59 */
60 public class CustomXmlTraceDefinition extends CustomTraceDefinition {
61
62 /** "ignore" tag */
63 public static final String TAG_IGNORE = Messages.CustomXmlTraceDefinition_ignoreTag;
64
65 /**
66 * Custom XML label used internally and therefore should not be externalized
67 */
68 public static final String CUSTOM_XML_CATEGORY = "Custom XML"; //$NON-NLS-1$
69
70
71 /** Name of the default XML definitions file */
72 protected static final String CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_FILE_NAME = "custom_xml_default_parsers.xml"; //$NON-NLS-1$
73
74 /** Name of the XML definitions file */
75 protected static final String CUSTOM_XML_TRACE_DEFINITIONS_FILE_NAME = "custom_xml_parsers.xml"; //$NON-NLS-1$
76
77 /** Path to the XML definitions file */
78 protected static final String CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_PATH_NAME =
79 Platform.getInstallLocation().getURL().getPath() + "templates/org.eclipse.linuxtools.tmf.core/" + //$NON-NLS-1$
80 CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_FILE_NAME;
81
82 /** Path to the XML definitions file */
83 protected static final String CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME =
84 Activator.getDefault().getStateLocation().addTrailingSeparator().append(CUSTOM_XML_TRACE_DEFINITIONS_FILE_NAME).toString();
85
86 /**
87 * Legacy path to the XML definitions file (in the UI plug-in of linux tools) TODO Remove
88 * once we feel the transition phase is over.
89 */
90 private static final String CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME_LEGACY_UI =
91 Activator.getDefault().getStateLocation().removeLastSegments(1).addTrailingSeparator()
92 .append("org.eclipse.linuxtools.tmf.ui") //$NON-NLS-1$
93 .append(CUSTOM_XML_TRACE_DEFINITIONS_FILE_NAME).toString();
94
95 /**
96 * Legacy path to the XML definitions file (in the core plug-in of linux tools) TODO Remove
97 * once we feel the transition phase is over.
98 */
99 private static final String CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME_LEGACY_CORE =
100 Activator.getDefault().getStateLocation().removeLastSegments(1).addTrailingSeparator()
101 .append("org.eclipse.linuxtools.tmf.core") //$NON-NLS-1$
102 .append(CUSTOM_XML_TRACE_DEFINITIONS_FILE_NAME).toString();
103
104 // TODO: These strings should not be externalized
105 private static final String CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT = Messages.CustomXmlTraceDefinition_definitionRootElement;
106 private static final String DEFINITION_ELEMENT = Messages.CustomXmlTraceDefinition_definition;
107 private static final String CATEGORY_ATTRIBUTE = Messages.CustomXmlTraceDefinition_category;
108 private static final String NAME_ATTRIBUTE = Messages.CustomXmlTraceDefinition_name;
109 private static final String LOG_ENTRY_ATTRIBUTE = Messages.CustomXmlTraceDefinition_logEntry;
110 private static final String TIME_STAMP_OUTPUT_FORMAT_ELEMENT = Messages.CustomXmlTraceDefinition_timestampOutputFormat;
111 private static final String INPUT_ELEMENT_ELEMENT = Messages.CustomXmlTraceDefinition_inputElement;
112 private static final String ATTRIBUTE_ELEMENT = Messages.CustomXmlTraceDefinition_attribute;
113 private static final String INPUT_DATA_ELEMENT = Messages.CustomXmlTraceDefinition_inputData;
114 private static final String ACTION_ATTRIBUTE = Messages.CustomXmlTraceDefinition_action;
115 private static final String FORMAT_ATTRIBUTE = Messages.CustomXmlTraceDefinition_format;
116 private static final String OUTPUT_COLUMN_ELEMENT = Messages.CustomXmlTraceDefinition_outputColumn;
117
118 /** Top-level input element */
119 public CustomXmlInputElement rootInputElement;
120
121 /**
122 * Default constructor
123 */
124 public CustomXmlTraceDefinition() {
125 this(CUSTOM_XML_CATEGORY, "", null, new ArrayList<OutputColumn>(), ""); //$NON-NLS-1$ //$NON-NLS-2$
126 }
127
128 /**
129 * Full constructor
130 *
131 * @param traceType
132 * Name of the trace type
133 * @param rootElement
134 * The top-level XML element
135 * @param outputs
136 * The list of output columns
137 * @param timeStampOutputFormat
138 * The timestamp format to use
139 * @deprecated Use
140 * {@link #CustomXmlTraceDefinition(String, String, CustomXmlInputElement, List, String)}
141 */
142 @Deprecated
143 public CustomXmlTraceDefinition(String traceType, CustomXmlInputElement rootElement,
144 List<OutputColumn> outputs, String timeStampOutputFormat) {
145 this.definitionName = traceType;
146 this.rootInputElement = rootElement;
147 this.outputs = outputs;
148 this.timeStampOutputFormat = timeStampOutputFormat;
149 }
150
151 /**
152 * Full constructor
153 *
154 * @param category
155 * Category of the trace type
156 * @param traceType
157 * Name of the trace type
158 * @param rootElement
159 * The top-level XML element
160 * @param outputs
161 * The list of output columns
162 * @param timeStampOutputFormat
163 * The timestamp format to use
164 * @since 3.2
165 */
166 public CustomXmlTraceDefinition(String category, String traceType, CustomXmlInputElement rootElement,
167 List<OutputColumn> outputs, String timeStampOutputFormat) {
168 this.categoryName = category;
169 this.definitionName = traceType;
170 this.rootInputElement = rootElement;
171 this.outputs = outputs;
172 this.timeStampOutputFormat = timeStampOutputFormat;
173 }
174
175 @Override
176 public void save() {
177 save(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME);
178 }
179
180 @Override
181 public void save(String path) {
182 try {
183 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
184 DocumentBuilder db = dbf.newDocumentBuilder();
185
186 // The following allows xml parsing without access to the dtd
187 db.setEntityResolver(createEmptyEntityResolver());
188
189 // The following catches xml parsing exceptions
190 db.setErrorHandler(createErrorHandler());
191
192 Document doc = null;
193 File file = new File(path);
194 if (file.canRead()) {
195 doc = db.parse(file);
196 if (!doc.getDocumentElement().getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT)) {
197 return;
198 }
199 } else {
200 doc = db.newDocument();
201 Node node = doc.createElement(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT);
202 doc.appendChild(node);
203 }
204
205 Element root = doc.getDocumentElement();
206
207 Element oldDefinitionElement = findDefinitionElement(root, categoryName, definitionName);
208 if (oldDefinitionElement != null) {
209 root.removeChild(oldDefinitionElement);
210 }
211 Element definitionElement = doc.createElement(DEFINITION_ELEMENT);
212 root.appendChild(definitionElement);
213 definitionElement.setAttribute(CATEGORY_ATTRIBUTE, categoryName);
214 definitionElement.setAttribute(NAME_ATTRIBUTE, definitionName);
215
216 Element formatElement = doc.createElement(TIME_STAMP_OUTPUT_FORMAT_ELEMENT);
217 definitionElement.appendChild(formatElement);
218 formatElement.appendChild(doc.createTextNode(timeStampOutputFormat));
219
220 if (rootInputElement != null) {
221 definitionElement.appendChild(createInputElementElement(rootInputElement, doc));
222 }
223
224 if (outputs != null) {
225 for (OutputColumn output : outputs) {
226 Element outputColumnElement = doc.createElement(OUTPUT_COLUMN_ELEMENT);
227 definitionElement.appendChild(outputColumnElement);
228 outputColumnElement.setAttribute(NAME_ATTRIBUTE, output.name);
229 }
230 }
231
232 Transformer transformer = TransformerFactory.newInstance().newTransformer();
233 transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
234
235 // initialize StreamResult with File object to save to file
236 StreamResult result = new StreamResult(new StringWriter());
237 DOMSource source = new DOMSource(doc);
238 transformer.transform(source, result);
239 String xmlString = result.getWriter().toString();
240
241 try (FileWriter writer = new FileWriter(file);) {
242 writer.write(xmlString);
243 }
244
245 TmfTraceType.addCustomTraceType(CustomXmlTrace.class, categoryName, definitionName);
246
247 } catch (ParserConfigurationException | TransformerFactoryConfigurationError | TransformerException | IOException | SAXException e) {
248 Activator.logError("Error saving CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$
249 }
250 }
251
252 private Element createInputElementElement(CustomXmlInputElement inputElement, Document doc) {
253 Element inputElementElement = doc.createElement(INPUT_ELEMENT_ELEMENT);
254 inputElementElement.setAttribute(NAME_ATTRIBUTE, inputElement.getElementName());
255
256 if (inputElement.isLogEntry()) {
257 inputElementElement.setAttribute(LOG_ENTRY_ATTRIBUTE, Boolean.toString(inputElement.isLogEntry()));
258 }
259
260 if (inputElement.getParentElement() != null) {
261 Element inputDataElement = doc.createElement(INPUT_DATA_ELEMENT);
262 inputElementElement.appendChild(inputDataElement);
263 inputDataElement.setAttribute(NAME_ATTRIBUTE, inputElement.getInputName());
264 inputDataElement.setAttribute(ACTION_ATTRIBUTE, Integer.toString(inputElement.getInputAction()));
265 if (inputElement.getInputFormat() != null) {
266 inputDataElement.setAttribute(FORMAT_ATTRIBUTE, inputElement.getInputFormat());
267 }
268 }
269
270 if (inputElement.getAttributes() != null) {
271 for (CustomXmlInputAttribute attribute : inputElement.getAttributes()) {
272 Element inputAttributeElement = doc.createElement(ATTRIBUTE_ELEMENT);
273 inputElementElement.appendChild(inputAttributeElement);
274 inputAttributeElement.setAttribute(NAME_ATTRIBUTE, attribute.getAttributeName());
275 Element inputDataElement = doc.createElement(INPUT_DATA_ELEMENT);
276 inputAttributeElement.appendChild(inputDataElement);
277 inputDataElement.setAttribute(NAME_ATTRIBUTE, attribute.getInputName());
278 inputDataElement.setAttribute(ACTION_ATTRIBUTE, Integer.toString(attribute.getInputAction()));
279 if (attribute.getInputFormat() != null) {
280 inputDataElement.setAttribute(FORMAT_ATTRIBUTE, attribute.getInputFormat());
281 }
282 }
283 }
284
285 if (inputElement.getChildElements() != null) {
286 for (CustomXmlInputElement childInputElement : inputElement.getChildElements()) {
287 inputElementElement.appendChild(createInputElementElement(childInputElement, doc));
288 }
289 }
290
291 return inputElementElement;
292 }
293
294 /**
295 * Load all custom XML trace definitions, including the user-defined and
296 * default (built-in) parsers.
297 *
298 * @return The loaded trace definitions
299 */
300 public static CustomXmlTraceDefinition[] loadAll() {
301 return loadAll(true);
302 }
303
304 /**
305 * Load all custom XML trace definitions, including the user-defined and,
306 * optionally, the default (built-in) parsers.
307 *
308 * @param includeDefaults
309 * if true, the default (built-in) parsers are included
310 *
311 * @return The loaded trace definitions
312 * @since 3.2
313 */
314 public static CustomXmlTraceDefinition[] loadAll(boolean includeDefaults) {
315 File defaultFile = new File(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME);
316 File legacyFileUI = new File(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME_LEGACY_UI);
317 File legacyFileCore = new File(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME_LEGACY_CORE);
318
319 /*
320 * If there is no file at the expected location, check the legacy
321 * locations instead.
322 */
323 if (!defaultFile.exists()) {
324 if (legacyFileCore.exists()) {
325 transferDefinitions(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME_LEGACY_CORE);
326 } else if (legacyFileUI.exists()) {
327 transferDefinitions(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME_LEGACY_UI);
328 }
329 }
330
331 Set<CustomXmlTraceDefinition> defs = new TreeSet<>(new Comparator<CustomXmlTraceDefinition>() {
332 @Override
333 public int compare(CustomXmlTraceDefinition o1, CustomXmlTraceDefinition o2) {
334 int result = o1.categoryName.compareTo(o2.categoryName);
335 if (result != 0) {
336 return result;
337 }
338 return o1.definitionName.compareTo(o2.definitionName);
339 }
340 });
341 defs.addAll(Arrays.asList(loadAll(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME)));
342 if (includeDefaults) {
343 defs.addAll(Arrays.asList(loadAll(CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_PATH_NAME)));
344 }
345 return defs.toArray(new CustomXmlTraceDefinition[0]);
346 }
347
348 private static void transferDefinitions(String defFile) {
349 CustomXmlTraceDefinition[] oldDefs = loadAll(defFile);
350 for (CustomXmlTraceDefinition def : oldDefs) {
351 /* Save in the new location */
352 def.save();
353 }
354 }
355
356
357 /**
358 * Load all the XML trace definitions in the given definitions file.
359 *
360 * @param path
361 * Path to the definitions file to load
362 * @return The loaded trace definitions
363 */
364 public static CustomXmlTraceDefinition[] loadAll(String path) {
365 File file = new File(path);
366 if (!file.canRead()) {
367 return new CustomXmlTraceDefinition[0];
368 }
369 try (FileInputStream fis = new FileInputStream(file);) {
370 return loadAll(fis);
371 } catch (IOException e) {
372 Activator.logError("Error loading all in CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$
373 }
374 return new CustomXmlTraceDefinition[0];
375 }
376
377 /**
378 * Load all the XML trace definitions from the given stream
379 *
380 * @param stream
381 * An input stream from which to read the definitions
382 * @return The loaded trace definitions
383 * @since 3.2
384 */
385 public static CustomXmlTraceDefinition[] loadAll(InputStream stream) {
386 try {
387 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
388 DocumentBuilder db = dbf.newDocumentBuilder();
389
390 // The following allows xml parsing without access to the dtd
391 db.setEntityResolver(createEmptyEntityResolver());
392
393 // The following catches xml parsing exceptions
394 db.setErrorHandler(createErrorHandler());
395
396 Document doc = db.parse(stream);
397 Element root = doc.getDocumentElement();
398 if (!root.getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT)) {
399 return new CustomXmlTraceDefinition[0];
400 }
401
402 ArrayList<CustomXmlTraceDefinition> defList = new ArrayList<>();
403 NodeList nodeList = root.getChildNodes();
404 for (int i = 0; i < nodeList.getLength(); i++) {
405 Node node = nodeList.item(i);
406 if (node instanceof Element && node.getNodeName().equals(DEFINITION_ELEMENT)) {
407 CustomXmlTraceDefinition def = extractDefinition((Element) node);
408 if (def != null) {
409 defList.add(def);
410 }
411 }
412 }
413 return defList.toArray(new CustomXmlTraceDefinition[0]);
414 } catch (ParserConfigurationException | SAXException | IOException e) {
415 Activator.logError("Error loading all in CustomXmlTraceDefinition: path=" + stream, e); //$NON-NLS-1$
416 }
417 return new CustomXmlTraceDefinition[0];
418 }
419
420 /**
421 * Load the given trace definition.
422 *
423 * @param definitionName
424 * Name of the XML trace definition to load
425 * @return The loaded trace definition
426 * @deprecated Use {@link #load(String, String)}
427 */
428 @Deprecated
429 public static CustomXmlTraceDefinition load(String definitionName) {
430 return load(CUSTOM_XML_CATEGORY, definitionName);
431 }
432
433 /**
434 * Load the given trace definition.
435 *
436 * @param categoryName
437 * Category of the definition to load
438 * @param definitionName
439 * Name of the XML trace definition to load
440 * @return The loaded trace definition
441 * @since 3.2
442 */
443 public static CustomXmlTraceDefinition load(String categoryName, String definitionName) {
444 try {
445 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
446 DocumentBuilder db = dbf.newDocumentBuilder();
447
448 // The following allows xml parsing without access to the dtd
449 EntityResolver resolver = new EntityResolver() {
450 @Override
451 public InputSource resolveEntity(String publicId, String systemId) {
452 String empty = ""; //$NON-NLS-1$
453 ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes());
454 return new InputSource(bais);
455 }
456 };
457 db.setEntityResolver(resolver);
458
459 // The following catches xml parsing exceptions
460 db.setErrorHandler(new ErrorHandler() {
461 @Override
462 public void error(SAXParseException saxparseexception) throws SAXException {
463 }
464
465 @Override
466 public void warning(SAXParseException saxparseexception) throws SAXException {
467 }
468
469 @Override
470 public void fatalError(SAXParseException saxparseexception) throws SAXException {
471 throw saxparseexception;
472 }
473 });
474
475 CustomXmlTraceDefinition value = lookupXmlDefinition(categoryName, definitionName, db, CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME);
476 if (value == null) {
477 value = lookupXmlDefinition(categoryName, definitionName, db, CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_PATH_NAME);
478 }
479 return value;
480 } catch (ParserConfigurationException | SAXException | IOException e) {
481 Activator.logError("Error loading CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$
482 }
483 return null;
484 }
485
486 private static CustomXmlTraceDefinition lookupXmlDefinition(String categoryName, String definitionName, DocumentBuilder db, String source) throws SAXException, IOException {
487 File file = new File(source);
488 if (!file.exists()) {
489 return null;
490 }
491
492 Document doc = db.parse(file);
493
494 Element root = doc.getDocumentElement();
495 if (!root.getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT)) {
496 return null;
497 }
498
499 Element definitionElement = findDefinitionElement(root, categoryName, definitionName);
500 if (definitionElement != null) {
501 return extractDefinition(definitionElement);
502 }
503 return null;
504 }
505
506 private static Element findDefinitionElement(Element root, String categoryName, String definitionName) {
507 NodeList nodeList = root.getChildNodes();
508 for (int i = 0; i < nodeList.getLength(); i++) {
509 Node node = nodeList.item(i);
510 if (node instanceof Element && node.getNodeName().equals(DEFINITION_ELEMENT)) {
511 Element element = (Element) node;
512 String categoryAttribute = element.getAttribute(CATEGORY_ATTRIBUTE);
513 if (categoryAttribute.isEmpty()) {
514 categoryAttribute = CUSTOM_XML_CATEGORY;
515 }
516 String nameAttribute = element.getAttribute(NAME_ATTRIBUTE);
517 if (categoryName.equals(categoryAttribute) &&
518 definitionName.equals(nameAttribute)) {
519 return element;
520 }
521 }
522 }
523 return null;
524 }
525
526 /**
527 * Extract a trace definition from an XML element.
528 *
529 * @param definitionElement
530 * Definition element
531 * @return The extracted trace definition
532 */
533 public static CustomXmlTraceDefinition extractDefinition(Element definitionElement) {
534 CustomXmlTraceDefinition def = new CustomXmlTraceDefinition();
535
536 def.categoryName = definitionElement.getAttribute(CATEGORY_ATTRIBUTE);
537 if (def.categoryName.isEmpty()) {
538 def.categoryName = CUSTOM_XML_CATEGORY;
539 }
540 def.definitionName = definitionElement.getAttribute(NAME_ATTRIBUTE);
541 if (def.definitionName.isEmpty()) {
542 return null;
543 }
544
545 NodeList nodeList = definitionElement.getChildNodes();
546 for (int i = 0; i < nodeList.getLength(); i++) {
547 Node node = nodeList.item(i);
548 String nodeName = node.getNodeName();
549 if (nodeName.equals(TIME_STAMP_OUTPUT_FORMAT_ELEMENT)) {
550 Element formatElement = (Element) node;
551 def.timeStampOutputFormat = formatElement.getTextContent();
552 } else if (nodeName.equals(INPUT_ELEMENT_ELEMENT)) {
553 CustomXmlInputElement inputElement = extractInputElement((Element) node);
554 if (inputElement != null) {
555 if (def.rootInputElement == null) {
556 def.rootInputElement = inputElement;
557 } else {
558 return null;
559 }
560 }
561 } else if (nodeName.equals(OUTPUT_COLUMN_ELEMENT)) {
562 Element outputColumnElement = (Element) node;
563 OutputColumn outputColumn = new OutputColumn();
564 outputColumn.name = outputColumnElement.getAttribute(NAME_ATTRIBUTE);
565 def.outputs.add(outputColumn);
566 }
567 }
568 return def;
569 }
570
571 private static CustomXmlInputElement extractInputElement(Element inputElementElement) {
572 CustomXmlInputElement inputElement = new CustomXmlInputElement();
573 inputElement.setElementName(inputElementElement.getAttribute(NAME_ATTRIBUTE));
574 inputElement.setLogEntry((Boolean.toString(true).equals(inputElementElement.getAttribute(LOG_ENTRY_ATTRIBUTE))) ? true : false);
575 NodeList nodeList = inputElementElement.getChildNodes();
576 for (int i = 0; i < nodeList.getLength(); i++) {
577 Node node = nodeList.item(i);
578 String nodeName = node.getNodeName();
579 if (nodeName.equals(INPUT_DATA_ELEMENT)) {
580 Element inputDataElement = (Element) node;
581 inputElement.setInputName(inputDataElement.getAttribute(NAME_ATTRIBUTE));
582 inputElement.setInputAction(Integer.parseInt(inputDataElement.getAttribute(ACTION_ATTRIBUTE)));
583 inputElement.setInputFormat(inputDataElement.getAttribute(FORMAT_ATTRIBUTE));
584 } else if (nodeName.equals(ATTRIBUTE_ELEMENT)) {
585 Element attributeElement = (Element) node;
586
587 String attributeName = attributeElement.getAttribute(NAME_ATTRIBUTE);
588 String inputName = null;
589 int inputAction = 0;
590 String inputFormat = null;
591 NodeList attributeNodeList = attributeElement.getChildNodes();
592 for (int j = 0; j < attributeNodeList.getLength(); j++) {
593 Node attributeNode = attributeNodeList.item(j);
594 String attributeNodeName = attributeNode.getNodeName();
595 if (attributeNodeName.equals(INPUT_DATA_ELEMENT)) {
596 Element inputDataElement = (Element) attributeNode;
597 inputName = inputDataElement.getAttribute(NAME_ATTRIBUTE);
598 inputAction = Integer.parseInt(inputDataElement.getAttribute(ACTION_ATTRIBUTE));
599 inputFormat = inputDataElement.getAttribute(FORMAT_ATTRIBUTE);
600 }
601 }
602 inputElement.addAttribute(new CustomXmlInputAttribute(attributeName, inputName, inputAction, inputFormat));
603 } else if (nodeName.equals(INPUT_ELEMENT_ELEMENT)) {
604 Element childInputElementElement = (Element) node;
605 CustomXmlInputElement childInputElement = extractInputElement(childInputElementElement);
606 if (childInputElement != null) {
607 inputElement.addChild(childInputElement);
608 }
609 }
610 }
611 return inputElement;
612 }
613
614 /**
615 * Delete a definition from the currently loaded ones.
616 *
617 * @param definitionName
618 * The name of the definition to delete
619 * @deprecated Use {@link #delete(String, String)}
620 */
621 @Deprecated
622 public static void delete(String definitionName) {
623 delete(CUSTOM_XML_CATEGORY, definitionName);
624 }
625
626 /**
627 * Delete a definition from the currently loaded ones.
628 *
629 * @param categoryName
630 * The category of the definition to delete
631 * @param definitionName
632 * The name of the definition to delete
633 * @since 3.2
634 */
635 public static void delete(String categoryName, String definitionName) {
636 try {
637 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
638 DocumentBuilder db = dbf.newDocumentBuilder();
639
640 // The following allows xml parsing without access to the dtd
641 EntityResolver resolver = new EntityResolver() {
642 @Override
643 public InputSource resolveEntity(String publicId, String systemId) {
644 String empty = ""; //$NON-NLS-1$
645 ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes());
646 return new InputSource(bais);
647 }
648 };
649 db.setEntityResolver(resolver);
650
651 // The following catches xml parsing exceptions
652 db.setErrorHandler(new ErrorHandler() {
653 @Override
654 public void error(SAXParseException saxparseexception) throws SAXException {
655 }
656
657 @Override
658 public void warning(SAXParseException saxparseexception) throws SAXException {
659 }
660
661 @Override
662 public void fatalError(SAXParseException saxparseexception) throws SAXException {
663 throw saxparseexception;
664 }
665 });
666
667 File file = new File(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME);
668 Document doc = db.parse(file);
669
670 Element root = doc.getDocumentElement();
671 if (!root.getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT)) {
672 return;
673 }
674
675 Element definitionElement = findDefinitionElement(root, categoryName, definitionName);
676 if (definitionElement != null) {
677 root.removeChild(definitionElement);
678 }
679
680 Transformer transformer = TransformerFactory.newInstance().newTransformer();
681 transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
682
683 // initialize StreamResult with File object to save to file
684 StreamResult result = new StreamResult(new StringWriter());
685 DOMSource source = new DOMSource(doc);
686 transformer.transform(source, result);
687 String xmlString = result.getWriter().toString();
688
689 try (FileWriter writer = new FileWriter(file);) {
690 writer.write(xmlString);
691 }
692
693 TmfTraceType.removeCustomTraceType(CustomXmlTrace.class, categoryName, definitionName);
694 // Check if default definition needs to be reloaded
695 TmfTraceType.addCustomTraceType(CustomXmlTrace.class, categoryName, definitionName);
696
697 } catch (ParserConfigurationException | SAXException | IOException | TransformerFactoryConfigurationError | TransformerException e) {
698 Activator.logError("Error deleteing CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$
699 }
700 }
701 }
This page took 0.052781 seconds and 5 git commands to generate.