tmf: implement hashcode and equals on filter classes
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / parsers / custom / CustomXmlTraceDefinition.java
CommitLineData
be222f56 1/*******************************************************************************
70b7bc9c 2 * Copyright (c) 2010, 2014 Ericsson
be222f56
PT
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
70b7bc9c 11 * Matthew Khouzam - Add support for default xml parsers
be222f56
PT
12 *******************************************************************************/
13
47aafe74 14package org.eclipse.linuxtools.tmf.core.parsers.custom;
be222f56
PT
15
16import java.io.ByteArrayInputStream;
17import java.io.File;
18import java.io.FileWriter;
19import java.io.IOException;
20import java.io.StringWriter;
21import java.util.ArrayList;
70b7bc9c
MK
22import java.util.Arrays;
23import java.util.Comparator;
be222f56 24import java.util.List;
70b7bc9c
MK
25import java.util.Set;
26import java.util.TreeSet;
be222f56
PT
27
28import javax.xml.parsers.DocumentBuilder;
29import javax.xml.parsers.DocumentBuilderFactory;
30import javax.xml.parsers.ParserConfigurationException;
31import javax.xml.transform.OutputKeys;
32import javax.xml.transform.Transformer;
33import javax.xml.transform.TransformerConfigurationException;
34import javax.xml.transform.TransformerException;
35import javax.xml.transform.TransformerFactory;
36import javax.xml.transform.TransformerFactoryConfigurationError;
37import javax.xml.transform.dom.DOMSource;
38import javax.xml.transform.stream.StreamResult;
39
70b7bc9c 40import org.eclipse.core.runtime.Platform;
47aafe74
AM
41import org.eclipse.linuxtools.internal.tmf.core.Activator;
42import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType;
be222f56
PT
43import org.w3c.dom.Document;
44import org.w3c.dom.Element;
45import org.w3c.dom.Node;
46import org.w3c.dom.NodeList;
47import org.xml.sax.EntityResolver;
48import org.xml.sax.ErrorHandler;
49import org.xml.sax.InputSource;
50import org.xml.sax.SAXException;
51import org.xml.sax.SAXParseException;
52
a0a88f65
AM
53/**
54 * Trace definition for custom XML traces.
55 *
56 * @author Patrick Tassé
47aafe74 57 * @since 3.0
a0a88f65 58 */
be222f56
PT
59public class CustomXmlTraceDefinition extends CustomTraceDefinition {
60
a0a88f65
AM
61 /** "ignore" tag */
62 public static final String TAG_IGNORE = Messages.CustomXmlTraceDefinition_ignoreTag;
63
70b7bc9c
MK
64 /** Name of the default XML definitions file */
65 protected static final String CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_FILE_NAME = "custom_xml_default_parsers.xml"; //$NON-NLS-1$
66
a0a88f65 67 /** Name of the XML definitions file */
be222f56 68 protected static final String CUSTOM_XML_TRACE_DEFINITIONS_FILE_NAME = "custom_xml_parsers.xml"; //$NON-NLS-1$
a0a88f65 69
70b7bc9c
MK
70 /** Path to the XML definitions file */
71 protected static final String CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_PATH_NAME =
72 Platform.getInstallLocation().getURL().getPath() +
73 "templates/org.eclipse.linuxtools.tmf.core/" + //$NON-NLS-1$
74 CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_FILE_NAME;
75
a0a88f65 76 /** Path to the XML definitions file */
be222f56 77 protected static final String CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME =
70b7bc9c 78 Activator.getDefault().getStateLocation().addTrailingSeparator().append(CUSTOM_XML_TRACE_DEFINITIONS_FILE_NAME).toString();
be222f56 79
03573754
AM
80 /** Legacy path to the XML definitions file (in the UI plug-in)
81 * TODO Remove once we feel the transition phase is over. */
82 private static final String CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME_LEGACY =
83 Activator.getDefault().getStateLocation().removeLastSegments(1).addTrailingSeparator()
84 .append("org.eclipse.linuxtools.tmf.ui") //$NON-NLS-1$
85 .append(CUSTOM_XML_TRACE_DEFINITIONS_FILE_NAME).toString();
86
be222f56
PT
87 private static final String CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT = Messages.CustomXmlTraceDefinition_definitionRootElement;
88 private static final String DEFINITION_ELEMENT = Messages.CustomXmlTraceDefinition_definition;
89 private static final String NAME_ATTRIBUTE = Messages.CustomXmlTraceDefinition_name;
90 private static final String LOG_ENTRY_ATTRIBUTE = Messages.CustomXmlTraceDefinition_logEntry;
91 private static final String TIME_STAMP_OUTPUT_FORMAT_ELEMENT = Messages.CustomXmlTraceDefinition_timestampOutputFormat;
92 private static final String INPUT_ELEMENT_ELEMENT = Messages.CustomXmlTraceDefinition_inputElement;
93 private static final String ATTRIBUTE_ELEMENT = Messages.CustomXmlTraceDefinition_attribute;
94 private static final String INPUT_DATA_ELEMENT = Messages.CustomXmlTraceDefinition_inputData;
95 private static final String ACTION_ATTRIBUTE = Messages.CustomXmlTraceDefinition_action;
96 private static final String FORMAT_ATTRIBUTE = Messages.CustomXmlTraceDefinition_format;
97 private static final String OUTPUT_COLUMN_ELEMENT = Messages.CustomXmlTraceDefinition_outputColumn;
98
a0a88f65 99 /** Top-level input element */
be222f56
PT
100 public InputElement rootInputElement;
101
a0a88f65
AM
102 /**
103 * Default constructor
104 */
be222f56
PT
105 public CustomXmlTraceDefinition() {
106 this("", null, new ArrayList<OutputColumn>(), ""); //$NON-NLS-1$ //$NON-NLS-2$
107 }
108
a0a88f65
AM
109 /**
110 * Full constructor
111 *
112 * @param logtype
113 * Type of trace type
114 * @param rootElement
115 * The top-level XML element
116 * @param outputs
117 * The list of output columns
118 * @param timeStampOutputFormat
119 * The timestamp format to use
120 */
121 public CustomXmlTraceDefinition(String logtype, InputElement rootElement,
122 List<OutputColumn> outputs, String timeStampOutputFormat) {
be222f56
PT
123 this.definitionName = logtype;
124 this.rootInputElement = rootElement;
125 this.outputs = outputs;
126 this.timeStampOutputFormat = timeStampOutputFormat;
127 }
128
a0a88f65
AM
129 /**
130 * Wrapper for input XML elements
131 */
be222f56 132 public static class InputElement {
a0a88f65
AM
133
134 /** Name of the element */
be222f56 135 public String elementName;
a0a88f65
AM
136
137 /** Indicates if this is a log entry */
be222f56 138 public boolean logEntry;
a0a88f65
AM
139
140 /** Name of the input element */
be222f56 141 public String inputName;
a0a88f65
AM
142
143 /** Input action */
be222f56 144 public int inputAction;
a0a88f65
AM
145
146 /** Input format */
be222f56 147 public String inputFormat;
a0a88f65
AM
148
149 /** XML attributes of this element */
be222f56 150 public List<InputAttribute> attributes;
a0a88f65
AM
151
152 /** Parent element */
be222f56 153 public InputElement parentElement;
a0a88f65
AM
154
155 /** Following element in the file */
be222f56 156 public InputElement nextElement;
a0a88f65
AM
157
158 /** Child elements */
be222f56
PT
159 public List<InputElement> childElements;
160
a0a88f65
AM
161 /**
162 * Default (empty) constructor
163 */
70b7bc9c
MK
164 public InputElement() {
165 }
be222f56 166
a0a88f65
AM
167 /**
168 * Constructor
169 *
170 * @param elementName
171 * Element name
172 * @param logEntry
173 * If this element is a log entry
174 * @param inputName
175 * Name of the the input
176 * @param inputAction
177 * Input action
178 * @param inputFormat
179 * Input format
180 * @param attributes
181 * XML attributes of this element
182 */
183 public InputElement(String elementName, boolean logEntry,
184 String inputName, int inputAction, String inputFormat,
185 List<InputAttribute> attributes) {
be222f56
PT
186 this.elementName = elementName;
187 this.logEntry = logEntry;
188 this.inputName = inputName;
189 this.inputAction = inputAction;
190 this.inputFormat = inputFormat;
191 this.attributes = attributes;
192 }
193
a0a88f65
AM
194 /**
195 * Add a XML attribute to the element
196 *
197 * @param attribute
198 * The attribute to add
199 */
be222f56
PT
200 public void addAttribute(InputAttribute attribute) {
201 if (attributes == null) {
507b1336 202 attributes = new ArrayList<>(1);
be222f56
PT
203 }
204 attributes.add(attribute);
205 }
206
a0a88f65
AM
207 /**
208 * Add a child element to this one.
209 *
210 * @param input
211 * The input element to add as child
212 */
be222f56
PT
213 public void addChild(InputElement input) {
214 if (childElements == null) {
507b1336 215 childElements = new ArrayList<>(1);
be222f56
PT
216 } else if (childElements.size() > 0) {
217 InputElement last = childElements.get(childElements.size() - 1);
218 last.nextElement = input;
219 }
220 childElements.add(input);
221 input.parentElement = this;
222 }
223
a0a88f65
AM
224 /**
225 * Set the following input element.
226 *
227 * @param input
228 * The input element to add as next element
229 */
be222f56
PT
230 public void addNext(InputElement input) {
231 if (parentElement != null) {
232 int index = parentElement.childElements.indexOf(this);
233 parentElement.childElements.add(index + 1, input);
234 InputElement next = nextElement;
235 nextElement = input;
236 input.nextElement = next;
237 }
238 input.parentElement = this.parentElement;
239 }
240
a0a88f65
AM
241 /**
242 * Move this element up in its parent's list of children.
243 */
be222f56
PT
244 public void moveUp() {
245 if (parentElement != null) {
246 int index = parentElement.childElements.indexOf(this);
247 if (index > 0) {
70b7bc9c 248 parentElement.childElements.add(index - 1, parentElement.childElements.remove(index));
be222f56
PT
249 parentElement.childElements.get(index).nextElement = nextElement;
250 nextElement = parentElement.childElements.get(index);
251 }
252 }
253 }
254
a0a88f65
AM
255 /**
256 * Move this element down in its parent's list of children.
257 */
be222f56
PT
258 public void moveDown() {
259 if (parentElement != null) {
260 int index = parentElement.childElements.indexOf(this);
261 if (index < parentElement.childElements.size() - 1) {
70b7bc9c 262 parentElement.childElements.add(index + 1, parentElement.childElements.remove(index));
be222f56
PT
263 nextElement = parentElement.childElements.get(index).nextElement;
264 parentElement.childElements.get(index).nextElement = this;
265 }
266 }
267 }
268
269 }
270
a0a88f65
AM
271 /**
272 * Wrapper for XML element attributes
273 */
be222f56 274 public static class InputAttribute {
a0a88f65
AM
275
276 /** Name of the XML attribute */
be222f56 277 public String attributeName;
a0a88f65
AM
278
279 /** Input name */
be222f56 280 public String inputName;
a0a88f65
AM
281
282 /** Input action */
be222f56 283 public int inputAction;
a0a88f65
AM
284
285 /** Input format */
be222f56
PT
286 public String inputFormat;
287
a0a88f65
AM
288 /**
289 * Default (empty) constructor
290 */
70b7bc9c
MK
291 public InputAttribute() {
292 }
be222f56 293
a0a88f65
AM
294 /**
295 * Constructor
296 *
297 * @param attributeName
298 * Name of the XML attribute
299 * @param inputName
300 * Input name
301 * @param inputAction
302 * Input action
303 * @param inputFormat
304 * Input format
305 */
306 public InputAttribute(String attributeName, String inputName,
307 int inputAction, String inputFormat) {
be222f56
PT
308 this.attributeName = attributeName;
309 this.inputName = inputName;
310 this.inputAction = inputAction;
311 this.inputFormat = inputFormat;
312 }
313 }
314
a0a88f65 315 @Override
be222f56
PT
316 public void save() {
317 save(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME);
318 }
319
70b7bc9c 320 @Override
be222f56
PT
321 public void save(String path) {
322 try {
323 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
324 DocumentBuilder db = dbf.newDocumentBuilder();
325
326 // The following allows xml parsing without access to the dtd
a0a88f65 327 EntityResolver resolver = new EntityResolver() {
be222f56 328 @Override
a0a88f65 329 public InputSource resolveEntity(String publicId, String systemId) {
be222f56
PT
330 String empty = ""; //$NON-NLS-1$
331 ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes());
332 return new InputSource(bais);
333 }
334 };
335 db.setEntityResolver(resolver);
336
337 // The following catches xml parsing exceptions
a0a88f65 338 db.setErrorHandler(new ErrorHandler() {
be222f56 339 @Override
70b7bc9c
MK
340 public void error(SAXParseException saxparseexception) throws SAXException {
341 }
a0a88f65 342
be222f56 343 @Override
70b7bc9c
MK
344 public void warning(SAXParseException saxparseexception) throws SAXException {
345 }
a0a88f65 346
be222f56 347 @Override
a0a88f65 348 public void fatalError(SAXParseException saxparseexception) throws SAXException {
be222f56 349 throw saxparseexception;
a0a88f65
AM
350 }
351 });
be222f56
PT
352
353 Document doc = null;
354 File file = new File(path);
355 if (file.canRead()) {
356 doc = db.parse(file);
70b7bc9c 357 if (!doc.getDocumentElement().getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT)) {
be222f56
PT
358 return;
359 }
360 } else {
361 doc = db.newDocument();
362 Node node = doc.createElement(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT);
363 doc.appendChild(node);
364 }
365
366 Element root = doc.getDocumentElement();
367
368 NodeList nodeList = root.getChildNodes();
369 for (int i = 0; i < nodeList.getLength(); i++) {
370 Node node = nodeList.item(i);
371 if (node instanceof Element &&
372 node.getNodeName().equals(DEFINITION_ELEMENT) &&
373 definitionName.equals(((Element) node).getAttribute(NAME_ATTRIBUTE))) {
374 root.removeChild(node);
375 }
376 }
377 Element definitionElement = doc.createElement(DEFINITION_ELEMENT);
378 root.appendChild(definitionElement);
379 definitionElement.setAttribute(NAME_ATTRIBUTE, definitionName);
380
381 Element formatElement = doc.createElement(TIME_STAMP_OUTPUT_FORMAT_ELEMENT);
382 definitionElement.appendChild(formatElement);
383 formatElement.appendChild(doc.createTextNode(timeStampOutputFormat));
384
385 if (rootInputElement != null) {
386 definitionElement.appendChild(createInputElementElement(rootInputElement, doc));
387 }
388
389 if (outputs != null) {
390 for (OutputColumn output : outputs) {
391 Element outputColumnElement = doc.createElement(OUTPUT_COLUMN_ELEMENT);
392 definitionElement.appendChild(outputColumnElement);
393 outputColumnElement.setAttribute(NAME_ATTRIBUTE, output.name);
394 }
395 }
396
397 Transformer transformer = TransformerFactory.newInstance().newTransformer();
398 transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
399
70b7bc9c 400 // initialize StreamResult with File object to save to file
be222f56
PT
401 StreamResult result = new StreamResult(new StringWriter());
402 DOMSource source = new DOMSource(doc);
403 transformer.transform(source, result);
404 String xmlString = result.getWriter().toString();
405
507b1336
AM
406 try (FileWriter writer = new FileWriter(file);) {
407 writer.write(xmlString);
408 }
52885aeb 409
a4a116c3 410 TmfTraceType.addCustomTraceType(TmfTraceType.CUSTOM_XML_CATEGORY, definitionName);
52885aeb 411
be222f56 412 } catch (ParserConfigurationException e) {
47aafe74 413 Activator.logError("Error saving CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$
be222f56 414 } catch (TransformerConfigurationException e) {
47aafe74 415 Activator.logError("Error saving CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$
be222f56 416 } catch (TransformerFactoryConfigurationError e) {
47aafe74 417 Activator.logError("Error saving CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$
be222f56 418 } catch (TransformerException e) {
47aafe74 419 Activator.logError("Error saving CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$
be222f56 420 } catch (IOException e) {
47aafe74 421 Activator.logError("Error saving CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$
be222f56 422 } catch (SAXException e) {
47aafe74 423 Activator.logError("Error saving CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$
be222f56
PT
424 }
425 }
426
427 private Element createInputElementElement(InputElement inputElement, Document doc) {
428 Element inputElementElement = doc.createElement(INPUT_ELEMENT_ELEMENT);
429 inputElementElement.setAttribute(NAME_ATTRIBUTE, inputElement.elementName);
430
431 if (inputElement.logEntry) {
432 inputElementElement.setAttribute(LOG_ENTRY_ATTRIBUTE, Boolean.toString(inputElement.logEntry));
433 }
434
435 if (inputElement.parentElement != null) {
436 Element inputDataElement = doc.createElement(INPUT_DATA_ELEMENT);
437 inputElementElement.appendChild(inputDataElement);
438 inputDataElement.setAttribute(NAME_ATTRIBUTE, inputElement.inputName);
439 inputDataElement.setAttribute(ACTION_ATTRIBUTE, Integer.toString(inputElement.inputAction));
440 if (inputElement.inputFormat != null) {
441 inputDataElement.setAttribute(FORMAT_ATTRIBUTE, inputElement.inputFormat);
442 }
443 }
444
445 if (inputElement.attributes != null) {
446 for (InputAttribute attribute : inputElement.attributes) {
447 Element inputAttributeElement = doc.createElement(ATTRIBUTE_ELEMENT);
448 inputElementElement.appendChild(inputAttributeElement);
449 inputAttributeElement.setAttribute(NAME_ATTRIBUTE, attribute.attributeName);
450 Element inputDataElement = doc.createElement(INPUT_DATA_ELEMENT);
451 inputAttributeElement.appendChild(inputDataElement);
452 inputDataElement.setAttribute(NAME_ATTRIBUTE, attribute.inputName);
453 inputDataElement.setAttribute(ACTION_ATTRIBUTE, Integer.toString(attribute.inputAction));
454 if (attribute.inputFormat != null) {
455 inputDataElement.setAttribute(FORMAT_ATTRIBUTE, attribute.inputFormat);
456 }
457 }
458 }
459
460 if (inputElement.childElements != null) {
461 for (InputElement childInputElement : inputElement.childElements) {
462 inputElementElement.appendChild(createInputElementElement(childInputElement, doc));
463 }
464 }
465
466 return inputElementElement;
467 }
468
a0a88f65
AM
469 /**
470 * Load all the XML trace definitions in the default definitions file.
471 *
472 * @return The loaded trace definitions
473 */
be222f56 474 public static CustomXmlTraceDefinition[] loadAll() {
03573754
AM
475 File defaultFile = new File(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME);
476 File legacyFile = new File(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME_LEGACY);
477
478 /*
479 * If there is no file at the expected location, check the legacy
480 * location instead.
481 */
482 if (!defaultFile.exists() && legacyFile.exists()) {
483 CustomXmlTraceDefinition[] oldDefs = loadAll(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME_LEGACY);
484 for (CustomXmlTraceDefinition def : oldDefs) {
485 /* Save in the new location */
486 def.save();
487 }
488 }
489
70b7bc9c
MK
490 Set<CustomXmlTraceDefinition> defs = new TreeSet<>(new Comparator<CustomXmlTraceDefinition>() {
491
492 @Override
493 public int compare(CustomXmlTraceDefinition o1, CustomXmlTraceDefinition o2) {
494 return o1.definitionName.compareTo(o2.definitionName);
495 }
496 });
497 defs.addAll(Arrays.asList(loadAll(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME)));
498 defs.addAll(Arrays.asList(loadAll(CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_PATH_NAME)));
499 return defs.toArray(new CustomXmlTraceDefinition[0]);
be222f56
PT
500 }
501
a0a88f65
AM
502 /**
503 * Load all the XML trace definitions in the given definitions file.
504 *
505 * @param path
506 * Path to the definitions file to load
507 * @return The loaded trace definitions
508 */
be222f56
PT
509 public static CustomXmlTraceDefinition[] loadAll(String path) {
510 try {
511 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
512 DocumentBuilder db = dbf.newDocumentBuilder();
513
514 // The following allows xml parsing without access to the dtd
a0a88f65 515 EntityResolver resolver = new EntityResolver() {
be222f56 516 @Override
a0a88f65 517 public InputSource resolveEntity(String publicId, String systemId) {
be222f56
PT
518 String empty = ""; //$NON-NLS-1$
519 ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes());
520 return new InputSource(bais);
521 }
522 };
523 db.setEntityResolver(resolver);
524
525 // The following catches xml parsing exceptions
a0a88f65 526 db.setErrorHandler(new ErrorHandler() {
be222f56 527 @Override
70b7bc9c
MK
528 public void error(SAXParseException saxparseexception) throws SAXException {
529 }
a0a88f65 530
be222f56 531 @Override
70b7bc9c
MK
532 public void warning(SAXParseException saxparseexception) throws SAXException {
533 }
a0a88f65 534
be222f56 535 @Override
a0a88f65 536 public void fatalError(SAXParseException saxparseexception) throws SAXException {
be222f56 537 throw saxparseexception;
a0a88f65
AM
538 }
539 });
be222f56
PT
540
541 File file = new File(path);
542 if (!file.canRead()) {
543 return new CustomXmlTraceDefinition[0];
544 }
545 Document doc = db.parse(file);
546
547 Element root = doc.getDocumentElement();
70b7bc9c 548 if (!root.getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT)) {
be222f56
PT
549 return new CustomXmlTraceDefinition[0];
550 }
551
507b1336 552 ArrayList<CustomXmlTraceDefinition> defList = new ArrayList<>();
be222f56
PT
553 NodeList nodeList = root.getChildNodes();
554 for (int i = 0; i < nodeList.getLength(); i++) {
555 Node node = nodeList.item(i);
556 if (node instanceof Element && node.getNodeName().equals(DEFINITION_ELEMENT)) {
557 CustomXmlTraceDefinition def = extractDefinition((Element) node);
558 if (def != null) {
559 defList.add(def);
560 }
561 }
562 }
563 return defList.toArray(new CustomXmlTraceDefinition[0]);
564 } catch (ParserConfigurationException e) {
47aafe74 565 Activator.logError("Error loading all in CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$
be222f56 566 } catch (SAXException e) {
47aafe74 567 Activator.logError("Error loading all in CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$
be222f56 568 } catch (IOException e) {
47aafe74 569 Activator.logError("Error loading all in CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$
be222f56
PT
570 }
571 return new CustomXmlTraceDefinition[0];
572 }
573
a0a88f65
AM
574 /**
575 * Load the given trace definition.
576 *
577 * @param definitionName
578 * Name of the XML trace definition to load
579 * @return The loaded trace definition
580 */
be222f56
PT
581 public static CustomXmlTraceDefinition load(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
a0a88f65 587 EntityResolver resolver = new EntityResolver() {
be222f56 588 @Override
a0a88f65 589 public InputSource resolveEntity(String publicId, String systemId) {
be222f56
PT
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
a0a88f65 598 db.setErrorHandler(new ErrorHandler() {
be222f56 599 @Override
70b7bc9c
MK
600 public void error(SAXParseException saxparseexception) throws SAXException {
601 }
a0a88f65 602
be222f56 603 @Override
70b7bc9c
MK
604 public void warning(SAXParseException saxparseexception) throws SAXException {
605 }
a0a88f65 606
be222f56 607 @Override
a0a88f65 608 public void fatalError(SAXParseException saxparseexception) throws SAXException {
be222f56 609 throw saxparseexception;
a0a88f65
AM
610 }
611 });
be222f56 612
70b7bc9c
MK
613 CustomXmlTraceDefinition value = lookupXmlDefinition(definitionName, db, CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME);
614 if (value == null) {
615 value = lookupXmlDefinition(definitionName, db, CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_PATH_NAME);
be222f56 616 }
70b7bc9c 617 return value;
be222f56 618 } catch (ParserConfigurationException e) {
47aafe74 619 Activator.logError("Error loading CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$
be222f56 620 } catch (SAXException e) {
47aafe74 621 Activator.logError("Error loading CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$
be222f56 622 } catch (IOException e) {
47aafe74 623 Activator.logError("Error loading CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$
be222f56
PT
624 }
625 return null;
626 }
627
70b7bc9c
MK
628 private static CustomXmlTraceDefinition lookupXmlDefinition(String definitionName, DocumentBuilder db, String source) throws SAXException, IOException {
629 File file = new File(source);
630 if (!file.exists()) {
631 return null;
632 }
633
634 Document doc = db.parse(file);
635
636 Element root = doc.getDocumentElement();
637 if (!root.getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT)) {
638 return null;
639 }
640
641 NodeList nodeList = root.getChildNodes();
642 for (int i = 0; i < nodeList.getLength(); i++) {
643 Node node = nodeList.item(i);
644 if (node instanceof Element &&
645 node.getNodeName().equals(DEFINITION_ELEMENT) &&
646 definitionName.equals(((Element) node).getAttribute(NAME_ATTRIBUTE))) {
647 return extractDefinition((Element) node);
648 }
649 }
650 return null;
651 }
652
a0a88f65
AM
653 /**
654 * Extract a trace definition from an XML element.
655 *
656 * @param definitionElement
657 * Definition element
658 * @return The extracted trace definition
659 */
be222f56
PT
660 public static CustomXmlTraceDefinition extractDefinition(Element definitionElement) {
661 CustomXmlTraceDefinition def = new CustomXmlTraceDefinition();
662
663 def.definitionName = definitionElement.getAttribute(NAME_ATTRIBUTE);
664 if (def.definitionName == null) {
665 return null;
666 }
667
668 NodeList nodeList = definitionElement.getChildNodes();
669 for (int i = 0; i < nodeList.getLength(); i++) {
670 Node node = nodeList.item(i);
671 String nodeName = node.getNodeName();
672 if (nodeName.equals(TIME_STAMP_OUTPUT_FORMAT_ELEMENT)) {
673 Element formatElement = (Element) node;
674 def.timeStampOutputFormat = formatElement.getTextContent();
675 } else if (nodeName.equals(INPUT_ELEMENT_ELEMENT)) {
676 InputElement inputElement = extractInputElement((Element) node);
677 if (inputElement != null) {
678 if (def.rootInputElement == null) {
679 def.rootInputElement = inputElement;
680 } else {
681 return null;
682 }
683 }
684 } else if (nodeName.equals(OUTPUT_COLUMN_ELEMENT)) {
685 Element outputColumnElement = (Element) node;
686 OutputColumn outputColumn = new OutputColumn();
687 outputColumn.name = outputColumnElement.getAttribute(NAME_ATTRIBUTE);
688 def.outputs.add(outputColumn);
689 }
690 }
691 return def;
692 }
693
694 private static InputElement extractInputElement(Element inputElementElement) {
695 InputElement inputElement = new InputElement();
696 inputElement.elementName = inputElementElement.getAttribute(NAME_ATTRIBUTE);
697 inputElement.logEntry = (Boolean.toString(true).equals(inputElementElement.getAttribute(LOG_ENTRY_ATTRIBUTE))) ? true : false;
698 NodeList nodeList = inputElementElement.getChildNodes();
699 for (int i = 0; i < nodeList.getLength(); i++) {
700 Node node = nodeList.item(i);
701 String nodeName = node.getNodeName();
702 if (nodeName.equals(INPUT_DATA_ELEMENT)) {
703 Element inputDataElement = (Element) node;
704 inputElement.inputName = inputDataElement.getAttribute(NAME_ATTRIBUTE);
705 inputElement.inputAction = Integer.parseInt(inputDataElement.getAttribute(ACTION_ATTRIBUTE));
706 inputElement.inputFormat = inputDataElement.getAttribute(FORMAT_ATTRIBUTE);
707 } else if (nodeName.equals(ATTRIBUTE_ELEMENT)) {
708 Element attributeElement = (Element) node;
709 InputAttribute attribute = new InputAttribute();
710 attribute.attributeName = attributeElement.getAttribute(NAME_ATTRIBUTE);
711 NodeList attributeNodeList = attributeElement.getChildNodes();
712 for (int j = 0; j < attributeNodeList.getLength(); j++) {
713 Node attributeNode = attributeNodeList.item(j);
714 String attributeNodeName = attributeNode.getNodeName();
715 if (attributeNodeName.equals(INPUT_DATA_ELEMENT)) {
716 Element inputDataElement = (Element) attributeNode;
717 attribute.inputName = inputDataElement.getAttribute(NAME_ATTRIBUTE);
718 attribute.inputAction = Integer.parseInt(inputDataElement.getAttribute(ACTION_ATTRIBUTE));
719 attribute.inputFormat = inputDataElement.getAttribute(FORMAT_ATTRIBUTE);
720 }
721 }
722 inputElement.addAttribute(attribute);
723 } else if (nodeName.equals(INPUT_ELEMENT_ELEMENT)) {
724 Element childInputElementElement = (Element) node;
725 InputElement childInputElement = extractInputElement(childInputElementElement);
726 if (childInputElement != null) {
727 inputElement.addChild(childInputElement);
728 }
729 }
730 }
731 return inputElement;
732 }
733
a0a88f65
AM
734 /**
735 * Delete the given trace definition from the list of currently loaded ones.
736 *
737 * @param definitionName
738 * Name of the trace definition to delete
739 */
be222f56
PT
740 public static void delete(String definitionName) {
741 try {
742 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
743 DocumentBuilder db = dbf.newDocumentBuilder();
744
745 // The following allows xml parsing without access to the dtd
a0a88f65 746 EntityResolver resolver = new EntityResolver() {
be222f56 747 @Override
a0a88f65 748 public InputSource resolveEntity(String publicId, String systemId) {
be222f56
PT
749 String empty = ""; //$NON-NLS-1$
750 ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes());
751 return new InputSource(bais);
752 }
753 };
754 db.setEntityResolver(resolver);
755
756 // The following catches xml parsing exceptions
a0a88f65 757 db.setErrorHandler(new ErrorHandler() {
be222f56 758 @Override
70b7bc9c
MK
759 public void error(SAXParseException saxparseexception) throws SAXException {
760 }
a0a88f65 761
be222f56 762 @Override
70b7bc9c
MK
763 public void warning(SAXParseException saxparseexception) throws SAXException {
764 }
a0a88f65 765
be222f56 766 @Override
a0a88f65 767 public void fatalError(SAXParseException saxparseexception) throws SAXException {
be222f56 768 throw saxparseexception;
a0a88f65
AM
769 }
770 });
be222f56
PT
771
772 File file = new File(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME);
773 Document doc = db.parse(file);
774
775 Element root = doc.getDocumentElement();
70b7bc9c 776 if (!root.getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT)) {
be222f56
PT
777 return;
778 }
779
780 NodeList nodeList = root.getChildNodes();
781 for (int i = 0; i < nodeList.getLength(); i++) {
782 Node node = nodeList.item(i);
783 if (node instanceof Element &&
784 node.getNodeName().equals(DEFINITION_ELEMENT) &&
785 definitionName.equals(((Element) node).getAttribute(NAME_ATTRIBUTE))) {
786 root.removeChild(node);
787 }
788 }
789
790 Transformer transformer = TransformerFactory.newInstance().newTransformer();
791 transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
792
70b7bc9c 793 // initialize StreamResult with File object to save to file
be222f56
PT
794 StreamResult result = new StreamResult(new StringWriter());
795 DOMSource source = new DOMSource(doc);
796 transformer.transform(source, result);
797 String xmlString = result.getWriter().toString();
798
507b1336
AM
799 try (FileWriter writer = new FileWriter(file);) {
800 writer.write(xmlString);
801 }
52885aeb 802
a4a116c3 803 TmfTraceType.removeCustomTraceType(TmfTraceType.CUSTOM_XML_CATEGORY, definitionName);
0621dbae
PT
804 // Check if default definition needs to be reloaded
805 TmfTraceType.addCustomTraceType(TmfTraceType.CUSTOM_XML_CATEGORY, definitionName);
52885aeb 806
be222f56 807 } catch (ParserConfigurationException e) {
47aafe74 808 Activator.logError("Error deleteing CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$
be222f56 809 } catch (SAXException e) {
47aafe74 810 Activator.logError("Error deleteing CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$
be222f56 811 } catch (IOException e) {
47aafe74 812 Activator.logError("Error deleteing CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$
be222f56 813 } catch (TransformerConfigurationException e) {
47aafe74 814 Activator.logError("Error deleteing CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$
be222f56 815 } catch (TransformerFactoryConfigurationError e) {
47aafe74 816 Activator.logError("Error deleteing CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$
be222f56 817 } catch (TransformerException e) {
47aafe74 818 Activator.logError("Error deleteing CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$
be222f56
PT
819 }
820 }
821}
This page took 0.099759 seconds and 5 git commands to generate.