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