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