/*******************************************************************************
* Copyright (c) 2010, 2014 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
* accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Patrick Tasse - Initial API and implementation
* Matthew Khouzam - Add support for default xml parsers
*******************************************************************************/
package fr.inria.linuxtools.tmf.core.parsers.custom;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.eclipse.core.runtime.Platform;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import fr.inria.linuxtools.internal.tmf.core.Activator;
import fr.inria.linuxtools.tmf.core.project.model.TmfTraceType;
/**
* Trace definition for custom XML traces.
*
* @author Patrick Tassé
* @since 3.0
*/
public class CustomXmlTraceDefinition extends CustomTraceDefinition {
/** "ignore" tag */
public static final String TAG_IGNORE = Messages.CustomXmlTraceDefinition_ignoreTag;
/** Name of the default XML definitions file */
protected static final String CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_FILE_NAME = "custom_xml_default_parsers.xml"; //$NON-NLS-1$
/** Name of the XML definitions file */
protected static final String CUSTOM_XML_TRACE_DEFINITIONS_FILE_NAME = "custom_xml_parsers.xml"; //$NON-NLS-1$
/** Path to the XML definitions file */
protected static final String CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_PATH_NAME =
Platform.getInstallLocation().getURL().getPath() +
"templates/fr.inria.linuxtools.tmf.core/" + //$NON-NLS-1$
CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_FILE_NAME;
/** Path to the XML definitions file */
protected static final String CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME =
Activator.getDefault().getStateLocation().addTrailingSeparator().append(CUSTOM_XML_TRACE_DEFINITIONS_FILE_NAME).toString();
/** Legacy path to the XML definitions file (in the UI plug-in)
* TODO Remove once we feel the transition phase is over. */
private static final String CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME_LEGACY =
Activator.getDefault().getStateLocation().removeLastSegments(1).addTrailingSeparator()
.append("fr.inria.linuxtools.tmf.ui") //$NON-NLS-1$
.append(CUSTOM_XML_TRACE_DEFINITIONS_FILE_NAME).toString();
private static final String CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT = Messages.CustomXmlTraceDefinition_definitionRootElement;
private static final String DEFINITION_ELEMENT = Messages.CustomXmlTraceDefinition_definition;
private static final String NAME_ATTRIBUTE = Messages.CustomXmlTraceDefinition_name;
private static final String LOG_ENTRY_ATTRIBUTE = Messages.CustomXmlTraceDefinition_logEntry;
private static final String TIME_STAMP_OUTPUT_FORMAT_ELEMENT = Messages.CustomXmlTraceDefinition_timestampOutputFormat;
private static final String INPUT_ELEMENT_ELEMENT = Messages.CustomXmlTraceDefinition_inputElement;
private static final String ATTRIBUTE_ELEMENT = Messages.CustomXmlTraceDefinition_attribute;
private static final String INPUT_DATA_ELEMENT = Messages.CustomXmlTraceDefinition_inputData;
private static final String ACTION_ATTRIBUTE = Messages.CustomXmlTraceDefinition_action;
private static final String FORMAT_ATTRIBUTE = Messages.CustomXmlTraceDefinition_format;
private static final String OUTPUT_COLUMN_ELEMENT = Messages.CustomXmlTraceDefinition_outputColumn;
/** Top-level input element */
public InputElement rootInputElement;
/**
* Default constructor
*/
public CustomXmlTraceDefinition() {
this("", null, new ArrayList<OutputColumn>(), ""); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* Full constructor
*
* @param logtype
* Type of trace type
* @param rootElement
* The top-level XML element
* @param outputs
* The list of output columns
* @param timeStampOutputFormat
* The timestamp format to use
*/
public CustomXmlTraceDefinition(String logtype, InputElement rootElement,
List<OutputColumn> outputs, String timeStampOutputFormat) {
this.definitionName = logtype;
this.rootInputElement = rootElement;
this.outputs = outputs;
this.timeStampOutputFormat = timeStampOutputFormat;
}
/**
* Wrapper for input XML elements
*/
public static class InputElement {
/** Name of the element */
public String elementName;
/** Indicates if this is a log entry */
public boolean logEntry;
/** Name of the input element */
public String inputName;
/** Input action */
public int inputAction;
/** Input format */
public String inputFormat;
/** XML attributes of this element */
public List<InputAttribute> attributes;
/** Parent element */
public InputElement parentElement;
/** Following element in the file */
public InputElement nextElement;
/** Child elements */
public List<InputElement> childElements;
/**
* Default (empty) constructor
*/
public InputElement() {
}
/**
* Constructor
*
* @param elementName
* Element name
* @param logEntry
* If this element is a log entry
* @param inputName
* Name of the the input
* @param inputAction
* Input action
* @param inputFormat
* Input format
* @param attributes
* XML attributes of this element
*/
public InputElement(String elementName, boolean logEntry,
String inputName, int inputAction, String inputFormat,
List<InputAttribute> attributes) {
this.elementName = elementName;
this.logEntry = logEntry;
this.inputName = inputName;
this.inputAction = inputAction;
this.inputFormat = inputFormat;
this.attributes = attributes;
}
/**
* Add a XML attribute to the element
*
* @param attribute
* The attribute to add
*/
public void addAttribute(InputAttribute attribute) {
if (attributes == null) {
attributes = new ArrayList<>(1);
}
attributes.add(attribute);
}
/**
* Add a child element to this one.
*
* @param input
* The input element to add as child
*/
public void addChild(InputElement input) {
if (childElements == null) {
childElements = new ArrayList<>(1);
} else if (childElements.size() > 0) {
InputElement last = childElements.get(childElements.size() - 1);
last.nextElement = input;
}
childElements.add(input);
input.parentElement = this;
}
/**
* Set the following input element.
*
* @param input
* The input element to add as next element
*/
public void addNext(InputElement input) {
if (parentElement != null) {
int index = parentElement.childElements.indexOf(this);
parentElement.childElements.add(index + 1, input);
InputElement next = nextElement;
nextElement = input;
input.nextElement = next;
}
input.parentElement = this.parentElement;
}
/**
* Move this element up in its parent's list of children.
*/
public void moveUp() {
if (parentElement != null) {
int index = parentElement.childElements.indexOf(this);
if (index > 0) {
parentElement.childElements.add(index - 1, parentElement.childElements.remove(index));
parentElement.childElements.get(index).nextElement = nextElement;
nextElement = parentElement.childElements.get(index);
}
}
}
/**
* Move this element down in its parent's list of children.
*/
public void moveDown() {
if (parentElement != null) {
int index = parentElement.childElements.indexOf(this);
if (index < parentElement.childElements.size() - 1) {
parentElement.childElements.add(index + 1, parentElement.childElements.remove(index));
nextElement = parentElement.childElements.get(index).nextElement;
parentElement.childElements.get(index).nextElement = this;
}
}
}
}
/**
* Wrapper for XML element attributes
*/
public static class InputAttribute {
/** Name of the XML attribute */
public String attributeName;
/** Input name */
public String inputName;
/** Input action */
public int inputAction;
/** Input format */
public String inputFormat;
/**
* Default (empty) constructor
*/
public InputAttribute() {
}
/**
* Constructor
*
* @param attributeName
* Name of the XML attribute
* @param inputName
* Input name
* @param inputAction
* Input action
* @param inputFormat
* Input format
*/
public InputAttribute(String attributeName, String inputName,
int inputAction, String inputFormat) {
this.attributeName = attributeName;
this.inputName = inputName;
this.inputAction = inputAction;
this.inputFormat = inputFormat;
}
}
@Override
public void save() {
save(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME);
}
@Override
public void save(String path) {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
// The following allows xml parsing without access to the dtd
EntityResolver resolver = new EntityResolver() {
@Override
public InputSource resolveEntity(String publicId, String systemId) {
String empty = ""; //$NON-NLS-1$
ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes());
return new InputSource(bais);
}
};
db.setEntityResolver(resolver);
// The following catches xml parsing exceptions
db.setErrorHandler(new ErrorHandler() {
@Override
public void error(SAXParseException saxparseexception) throws SAXException {
}
@Override
public void warning(SAXParseException saxparseexception) throws SAXException {
}
@Override
public void fatalError(SAXParseException saxparseexception) throws SAXException {
throw saxparseexception;
}
});
Document doc = null;
File file = new File(path);
if (file.canRead()) {
doc = db.parse(file);
if (!doc.getDocumentElement().getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT)) {
return;
}
} else {
doc = db.newDocument();
Node node = doc.createElement(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT);
doc.appendChild(node);
}
Element root = doc.getDocumentElement();
NodeList nodeList = root.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
if (node instanceof Element &&
node.getNodeName().equals(DEFINITION_ELEMENT) &&
definitionName.equals(((Element) node).getAttribute(NAME_ATTRIBUTE))) {
root.removeChild(node);
}
}
Element definitionElement = doc.createElement(DEFINITION_ELEMENT);
root.appendChild(definitionElement);
definitionElement.setAttribute(NAME_ATTRIBUTE, definitionName);
Element formatElement = doc.createElement(TIME_STAMP_OUTPUT_FORMAT_ELEMENT);
definitionElement.appendChild(formatElement);
formatElement.appendChild(doc.createTextNode(timeStampOutputFormat));
if (rootInputElement != null) {
definitionElement.appendChild(createInputElementElement(rootInputElement, doc));
}
if (outputs != null) {
for (OutputColumn output : outputs) {
Element outputColumnElement = doc.createElement(OUTPUT_COLUMN_ELEMENT);
definitionElement.appendChild(outputColumnElement);
outputColumnElement.setAttribute(NAME_ATTRIBUTE, output.name);
}
}
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
// initialize StreamResult with File object to save to file
StreamResult result = new StreamResult(new StringWriter());
DOMSource source = new DOMSource(doc);
transformer.transform(source, result);
String xmlString = result.getWriter().toString();
try (FileWriter writer = new FileWriter(file);) {
writer.write(xmlString);
}
TmfTraceType.addCustomTraceType(TmfTraceType.CUSTOM_XML_CATEGORY, definitionName);
} catch (ParserConfigurationException e) {
Activator.logError("Error saving CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$
} catch (TransformerConfigurationException e) {
Activator.logError("Error saving CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$
} catch (TransformerFactoryConfigurationError e) {
Activator.logError("Error saving CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$
} catch (TransformerException e) {
Activator.logError("Error saving CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$
} catch (IOException e) {
Activator.logError("Error saving CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$
} catch (SAXException e) {
Activator.logError("Error saving CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$
}
}
private Element createInputElementElement(InputElement inputElement, Document doc) {
Element inputElementElement = doc.createElement(INPUT_ELEMENT_ELEMENT);
inputElementElement.setAttribute(NAME_ATTRIBUTE, inputElement.elementName);
if (inputElement.logEntry) {
inputElementElement.setAttribute(LOG_ENTRY_ATTRIBUTE, Boolean.toString(inputElement.logEntry));
}
if (inputElement.parentElement != null) {
Element inputDataElement = doc.createElement(INPUT_DATA_ELEMENT);
inputElementElement.appendChild(inputDataElement);
inputDataElement.setAttribute(NAME_ATTRIBUTE, inputElement.inputName);
inputDataElement.setAttribute(ACTION_ATTRIBUTE, Integer.toString(inputElement.inputAction));
if (inputElement.inputFormat != null) {
inputDataElement.setAttribute(FORMAT_ATTRIBUTE, inputElement.inputFormat);
}
}
if (inputElement.attributes != null) {
for (InputAttribute attribute : inputElement.attributes) {
Element inputAttributeElement = doc.createElement(ATTRIBUTE_ELEMENT);
inputElementElement.appendChild(inputAttributeElement);
inputAttributeElement.setAttribute(NAME_ATTRIBUTE, attribute.attributeName);
Element inputDataElement = doc.createElement(INPUT_DATA_ELEMENT);
inputAttributeElement.appendChild(inputDataElement);
inputDataElement.setAttribute(NAME_ATTRIBUTE, attribute.inputName);
inputDataElement.setAttribute(ACTION_ATTRIBUTE, Integer.toString(attribute.inputAction));
if (attribute.inputFormat != null) {
inputDataElement.setAttribute(FORMAT_ATTRIBUTE, attribute.inputFormat);
}
}
}
if (inputElement.childElements != null) {
for (InputElement childInputElement : inputElement.childElements) {
inputElementElement.appendChild(createInputElementElement(childInputElement, doc));
}
}
return inputElementElement;
}
/**
* Load all the XML trace definitions in the default definitions file.
*
* @return The loaded trace definitions
*/
public static CustomXmlTraceDefinition[] loadAll() {
File defaultFile = new File(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME);
File legacyFile = new File(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME_LEGACY);
/*
* If there is no file at the expected location, check the legacy
* location instead.
*/
if (!defaultFile.exists() && legacyFile.exists()) {
CustomXmlTraceDefinition[] oldDefs = loadAll(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME_LEGACY);
for (CustomXmlTraceDefinition def : oldDefs) {
/* Save in the new location */
def.save();
}
}
Set<CustomXmlTraceDefinition> defs = new TreeSet<>(new Comparator<CustomXmlTraceDefinition>() {
@Override
public int compare(CustomXmlTraceDefinition o1, CustomXmlTraceDefinition o2) {
return o1.definitionName.compareTo(o2.definitionName);
}
});
defs.addAll(Arrays.asList(loadAll(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME)));
defs.addAll(Arrays.asList(loadAll(CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_PATH_NAME)));
return defs.toArray(new CustomXmlTraceDefinition[0]);
}
/**
* Load all the XML trace definitions in the given definitions file.
*
* @param path
* Path to the definitions file to load
* @return The loaded trace definitions
*/
public static CustomXmlTraceDefinition[] loadAll(String path) {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
// The following allows xml parsing without access to the dtd
EntityResolver resolver = new EntityResolver() {
@Override
public InputSource resolveEntity(String publicId, String systemId) {
String empty = ""; //$NON-NLS-1$
ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes());
return new InputSource(bais);
}
};
db.setEntityResolver(resolver);
// The following catches xml parsing exceptions
db.setErrorHandler(new ErrorHandler() {
@Override
public void error(SAXParseException saxparseexception) throws SAXException {
}
@Override
public void warning(SAXParseException saxparseexception) throws SAXException {
}
@Override
public void fatalError(SAXParseException saxparseexception) throws SAXException {
throw saxparseexception;
}
});
File file = new File(path);
if (!file.canRead()) {
return new CustomXmlTraceDefinition[0];
}
Document doc = db.parse(file);
Element root = doc.getDocumentElement();
if (!root.getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT)) {
return new CustomXmlTraceDefinition[0];
}
ArrayList<CustomXmlTraceDefinition> defList = new ArrayList<>();
NodeList nodeList = root.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
if (node instanceof Element && node.getNodeName().equals(DEFINITION_ELEMENT)) {
CustomXmlTraceDefinition def = extractDefinition((Element) node);
if (def != null) {
defList.add(def);
}
}
}
return defList.toArray(new CustomXmlTraceDefinition[0]);
} catch (ParserConfigurationException e) {
Activator.logError("Error loading all in CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$
} catch (SAXException e) {
Activator.logError("Error loading all in CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$
} catch (IOException e) {
Activator.logError("Error loading all in CustomXmlTraceDefinition: path=" + path, e); //$NON-NLS-1$
}
return new CustomXmlTraceDefinition[0];
}
/**
* Load the given trace definition.
*
* @param definitionName
* Name of the XML trace definition to load
* @return The loaded trace definition
*/
public static CustomXmlTraceDefinition load(String definitionName) {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
// The following allows xml parsing without access to the dtd
EntityResolver resolver = new EntityResolver() {
@Override
public InputSource resolveEntity(String publicId, String systemId) {
String empty = ""; //$NON-NLS-1$
ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes());
return new InputSource(bais);
}
};
db.setEntityResolver(resolver);
// The following catches xml parsing exceptions
db.setErrorHandler(new ErrorHandler() {
@Override
public void error(SAXParseException saxparseexception) throws SAXException {
}
@Override
public void warning(SAXParseException saxparseexception) throws SAXException {
}
@Override
public void fatalError(SAXParseException saxparseexception) throws SAXException {
throw saxparseexception;
}
});
CustomXmlTraceDefinition value = lookupXmlDefinition(definitionName, db, CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME);
if (value == null) {
value = lookupXmlDefinition(definitionName, db, CUSTOM_XML_TRACE_DEFINITIONS_DEFAULT_PATH_NAME);
}
return value;
} catch (ParserConfigurationException e) {
Activator.logError("Error loading CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$
} catch (SAXException e) {
Activator.logError("Error loading CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$
} catch (IOException e) {
Activator.logError("Error loading CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$
}
return null;
}
private static CustomXmlTraceDefinition lookupXmlDefinition(String definitionName, DocumentBuilder db, String source) throws SAXException, IOException {
File file = new File(source);
if (!file.exists()) {
return null;
}
Document doc = db.parse(file);
Element root = doc.getDocumentElement();
if (!root.getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT)) {
return null;
}
NodeList nodeList = root.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
if (node instanceof Element &&
node.getNodeName().equals(DEFINITION_ELEMENT) &&
definitionName.equals(((Element) node).getAttribute(NAME_ATTRIBUTE))) {
return extractDefinition((Element) node);
}
}
return null;
}
/**
* Extract a trace definition from an XML element.
*
* @param definitionElement
* Definition element
* @return The extracted trace definition
*/
public static CustomXmlTraceDefinition extractDefinition(Element definitionElement) {
CustomXmlTraceDefinition def = new CustomXmlTraceDefinition();
def.definitionName = definitionElement.getAttribute(NAME_ATTRIBUTE);
if (def.definitionName == null) {
return null;
}
NodeList nodeList = definitionElement.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
String nodeName = node.getNodeName();
if (nodeName.equals(TIME_STAMP_OUTPUT_FORMAT_ELEMENT)) {
Element formatElement = (Element) node;
def.timeStampOutputFormat = formatElement.getTextContent();
} else if (nodeName.equals(INPUT_ELEMENT_ELEMENT)) {
InputElement inputElement = extractInputElement((Element) node);
if (inputElement != null) {
if (def.rootInputElement == null) {
def.rootInputElement = inputElement;
} else {
return null;
}
}
} else if (nodeName.equals(OUTPUT_COLUMN_ELEMENT)) {
Element outputColumnElement = (Element) node;
OutputColumn outputColumn = new OutputColumn();
outputColumn.name = outputColumnElement.getAttribute(NAME_ATTRIBUTE);
def.outputs.add(outputColumn);
}
}
return def;
}
private static InputElement extractInputElement(Element inputElementElement) {
InputElement inputElement = new InputElement();
inputElement.elementName = inputElementElement.getAttribute(NAME_ATTRIBUTE);
inputElement.logEntry = (Boolean.toString(true).equals(inputElementElement.getAttribute(LOG_ENTRY_ATTRIBUTE))) ? true : false;
NodeList nodeList = inputElementElement.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
String nodeName = node.getNodeName();
if (nodeName.equals(INPUT_DATA_ELEMENT)) {
Element inputDataElement = (Element) node;
inputElement.inputName = inputDataElement.getAttribute(NAME_ATTRIBUTE);
inputElement.inputAction = Integer.parseInt(inputDataElement.getAttribute(ACTION_ATTRIBUTE));
inputElement.inputFormat = inputDataElement.getAttribute(FORMAT_ATTRIBUTE);
} else if (nodeName.equals(ATTRIBUTE_ELEMENT)) {
Element attributeElement = (Element) node;
InputAttribute attribute = new InputAttribute();
attribute.attributeName = attributeElement.getAttribute(NAME_ATTRIBUTE);
NodeList attributeNodeList = attributeElement.getChildNodes();
for (int j = 0; j < attributeNodeList.getLength(); j++) {
Node attributeNode = attributeNodeList.item(j);
String attributeNodeName = attributeNode.getNodeName();
if (attributeNodeName.equals(INPUT_DATA_ELEMENT)) {
Element inputDataElement = (Element) attributeNode;
attribute.inputName = inputDataElement.getAttribute(NAME_ATTRIBUTE);
attribute.inputAction = Integer.parseInt(inputDataElement.getAttribute(ACTION_ATTRIBUTE));
attribute.inputFormat = inputDataElement.getAttribute(FORMAT_ATTRIBUTE);
}
}
inputElement.addAttribute(attribute);
} else if (nodeName.equals(INPUT_ELEMENT_ELEMENT)) {
Element childInputElementElement = (Element) node;
InputElement childInputElement = extractInputElement(childInputElementElement);
if (childInputElement != null) {
inputElement.addChild(childInputElement);
}
}
}
return inputElement;
}
/**
* Delete the given trace definition from the list of currently loaded ones.
*
* @param definitionName
* Name of the trace definition to delete
*/
public static void delete(String definitionName) {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
// The following allows xml parsing without access to the dtd
EntityResolver resolver = new EntityResolver() {
@Override
public InputSource resolveEntity(String publicId, String systemId) {
String empty = ""; //$NON-NLS-1$
ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes());
return new InputSource(bais);
}
};
db.setEntityResolver(resolver);
// The following catches xml parsing exceptions
db.setErrorHandler(new ErrorHandler() {
@Override
public void error(SAXParseException saxparseexception) throws SAXException {
}
@Override
public void warning(SAXParseException saxparseexception) throws SAXException {
}
@Override
public void fatalError(SAXParseException saxparseexception) throws SAXException {
throw saxparseexception;
}
});
File file = new File(CUSTOM_XML_TRACE_DEFINITIONS_PATH_NAME);
Document doc = db.parse(file);
Element root = doc.getDocumentElement();
if (!root.getNodeName().equals(CUSTOM_XML_TRACE_DEFINITION_ROOT_ELEMENT)) {
return;
}
NodeList nodeList = root.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
if (node instanceof Element &&
node.getNodeName().equals(DEFINITION_ELEMENT) &&
definitionName.equals(((Element) node).getAttribute(NAME_ATTRIBUTE))) {
root.removeChild(node);
}
}
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
// initialize StreamResult with File object to save to file
StreamResult result = new StreamResult(new StringWriter());
DOMSource source = new DOMSource(doc);
transformer.transform(source, result);
String xmlString = result.getWriter().toString();
try (FileWriter writer = new FileWriter(file);) {
writer.write(xmlString);
}
TmfTraceType.removeCustomTraceType(TmfTraceType.CUSTOM_XML_CATEGORY, definitionName);
// Check if default definition needs to be reloaded
TmfTraceType.addCustomTraceType(TmfTraceType.CUSTOM_XML_CATEGORY, definitionName);
} catch (ParserConfigurationException e) {
Activator.logError("Error deleteing CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$
} catch (SAXException e) {
Activator.logError("Error deleteing CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$
} catch (IOException e) {
Activator.logError("Error deleteing CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$
} catch (TransformerConfigurationException e) {
Activator.logError("Error deleteing CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$
} catch (TransformerFactoryConfigurationError e) {
Activator.logError("Error deleteing CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$
} catch (TransformerException e) {
Activator.logError("Error deleteing CustomXmlTraceDefinition: definitionName=" + definitionName, e); //$NON-NLS-1$
}
}
}