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