summaryrefslogtreecommitdiffstats
path: root/src/main/java/org/openslx/libvirt/xml/LibvirtXmlNode.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/openslx/libvirt/xml/LibvirtXmlNode.java')
-rw-r--r--src/main/java/org/openslx/libvirt/xml/LibvirtXmlNode.java350
1 files changed, 350 insertions, 0 deletions
diff --git a/src/main/java/org/openslx/libvirt/xml/LibvirtXmlNode.java b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlNode.java
new file mode 100644
index 0000000..a941acb
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlNode.java
@@ -0,0 +1,350 @@
+package org.openslx.libvirt.xml;
+
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * A representation of a XML node as part of a {@link LibvirtXmlDocument}.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class LibvirtXmlNode implements LibvirtXmlCreatable, LibvirtXmlEditable
+{
+ /**
+ * Separation character for internal XPath expressions.
+ */
+ private static final String XPATH_EXPRESSION_SEPARATOR = "/";
+
+ /**
+ * Current XML node selection character for internal XPath expressions.
+ */
+ private static final String XPATH_EXPRESSION_CURRENT_NODE = ".";
+
+ /**
+ * Factory to create XPath objects.
+ */
+ private XPathFactory xPathFactory = null;
+
+ /**
+ * Representation of the XML document, in which this {@link LibvirtXmlNode} is part of.
+ */
+ private Document xmlDocument = null;
+
+ /**
+ * Current XML base node as XML root anchor for relative internal XPath expressions.
+ */
+ private Node xmlBaseNode = null;
+
+ /**
+ * Create and initialize XPath context to define and compile custom XPath expressions.
+ */
+ private void createXPathContext()
+ {
+ this.xPathFactory = XPathFactory.newInstance();
+ }
+
+ /**
+ * Creates empty Libvirt XML node, which does not belong to any XML document and does not specify
+ * any XML base node.
+ *
+ * @implNote Please call {@link LibvirtXmlNode#setXmlDocument(Document)} and
+ * {@link LibvirtXmlNode#setXmlBaseNode(Node)} manually to obtain a functional Libvirt
+ * XML node.
+ */
+ public LibvirtXmlNode()
+ {
+ this( null, null );
+ }
+
+ /**
+ * Creates Libvirt XML node from a existing Libvirt XML node by reference.
+ *
+ * @param xmlNode existing Libvirt XML node.
+ */
+ public LibvirtXmlNode( LibvirtXmlNode xmlNode )
+ {
+ this( xmlNode.getXmlDocument(), xmlNode.getXmlBaseNode() );
+ }
+
+ /**
+ * Creates Libvirt XML node as part of a existing XML document.
+ *
+ * @param xmlDocument existing XML document.
+ *
+ * @implNote Please call {@link LibvirtXmlNode#setXmlBaseNode(Node)} manually to obtain a
+ * functional Libvirt XML node.
+ */
+ public LibvirtXmlNode( Document xmlDocument )
+ {
+ this( xmlDocument, null );
+ }
+
+ /**
+ * Creates Libvirt XML node with a specific XML base node.
+ *
+ * @param xmlBaseNode existing XML base node.
+ *
+ * @implNote Please call {@link LibvirtXmlNode#setXmlDocument(Document)} manually to obtain a
+ * functional Libvirt XML node.
+ */
+ public LibvirtXmlNode( Node xmlBaseNode )
+ {
+ this( null, xmlBaseNode );
+ }
+
+ /**
+ * Creates Libvirt XML node with a specific XML base node as part of a XML document.
+ *
+ * @param xmlDocument existing XML document.
+ * @param xmlBaseNode existing XML base node.
+ */
+ public LibvirtXmlNode( Document xmlDocument, Node xmlBaseNode )
+ {
+ this.createXPathContext();
+
+ this.setXmlDocument( xmlDocument );
+ this.setXmlBaseNode( xmlBaseNode );
+ }
+
+ /**
+ * Returns referenced XML document.
+ *
+ * @return referenced XML document.
+ */
+ public Document getXmlDocument()
+ {
+ return this.xmlDocument;
+ }
+
+ /**
+ * Sets existing XML document for Libvirt XML node.
+ *
+ * @param xmlDocument existing XML document.
+ */
+ public void setXmlDocument( Document xmlDocument )
+ {
+ this.xmlDocument = xmlDocument;
+ }
+
+ /**
+ * Returns current XML base node.
+ *
+ * @return current XML base node as XML root anchor of relative internal XPath expressions.
+ */
+ public Node getXmlBaseNode()
+ {
+ return this.xmlBaseNode;
+ }
+
+ /**
+ * Sets existing XML base node for Libvirt XML node.
+ *
+ * @param xmlBaseNode existing XML base node as XML root anchor for relative internal XPath
+ * expressions.
+ */
+ public void setXmlBaseNode( Node xmlBaseNode )
+ {
+ this.xmlBaseNode = xmlBaseNode;
+ }
+
+ @Override
+ public Node getXmlNode( String expression )
+ {
+ if ( XPATH_EXPRESSION_CURRENT_NODE.equals( expression ) ) {
+ return this.xmlBaseNode;
+ }
+ NodeList nodes = this.getXmlNodes( expression );
+ return nodes.item( 0 );
+ }
+
+ @Override
+ public NodeList getXmlNodes( String expression )
+ {
+ Object nodes = null;
+
+ try {
+ XPath xPath = this.xPathFactory.newXPath();
+ XPathExpression xPathExpr = xPath.compile( expression );
+ nodes = xPathExpr.evaluate( this.xmlBaseNode, XPathConstants.NODESET );
+ } catch ( XPathExpressionException e ) {
+ e.printStackTrace();
+ }
+
+ return NodeList.class.cast( nodes );
+ }
+
+ @Override
+ public Element getXmlElement( String expression )
+ {
+ String completeExpression = null;
+
+ if ( expression == null || expression.isEmpty() ) {
+ completeExpression = XPATH_EXPRESSION_CURRENT_NODE;
+ } else {
+ completeExpression = XPATH_EXPRESSION_CURRENT_NODE + XPATH_EXPRESSION_SEPARATOR + expression;
+ }
+
+ Node node = this.getXmlNode( completeExpression );
+
+ if ( node != null && node.getNodeType() == Node.ELEMENT_NODE ) {
+ return (Element)node;
+ } else {
+ return null;
+ }
+ }
+
+ private Node createXmlElement( String expression )
+ {
+ Node parentNode = this.xmlBaseNode;
+ Node currentNode = parentNode;
+
+ if ( expression != null && !expression.isEmpty() ) {
+ String[] nodeNames = expression.split( XPATH_EXPRESSION_SEPARATOR );
+ String partialExpression = XPATH_EXPRESSION_CURRENT_NODE;
+
+ for ( int i = 0; i < nodeNames.length; i++ ) {
+ partialExpression += XPATH_EXPRESSION_SEPARATOR + nodeNames[i];
+ currentNode = this.getXmlNode( partialExpression );
+
+ if ( currentNode == null ) {
+ currentNode = this.xmlDocument.createElement( nodeNames[i] );
+ parentNode.appendChild( currentNode );
+ }
+
+ parentNode = currentNode;
+ }
+ }
+
+ return currentNode;
+ }
+
+ @Override
+ public void setXmlElement( String expression, Node child )
+ {
+ Node node = this.createXmlElement( expression );
+
+ if ( child != null ) {
+ node.appendChild( child );
+ }
+ }
+
+ @Override
+ public String getXmlElementValue( String expression )
+ {
+ Node node = this.getXmlElement( expression );
+
+ if ( node != null ) {
+ return node.getTextContent();
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public void setXmlElementValue( String expression, String value )
+ {
+ Node node = this.createXmlElement( expression );
+ node.setTextContent( value );
+ }
+
+ @Override
+ public void removeXmlElement( String expression )
+ {
+ Node node = this.getXmlElement( expression );
+
+ if ( node != null ) {
+ node.getParentNode().removeChild( node );
+ }
+ }
+
+ @Override
+ public void removeXmlElementChilds( String expression )
+ {
+ Node node = this.getXmlElement( expression );
+
+ if ( node != null ) {
+ final NodeList childs = node.getChildNodes();
+ while ( childs.getLength() > 0 ) {
+ Node child = childs.item( 0 );
+ node.removeChild( child );
+ }
+ }
+ }
+
+ @Override
+ public String getXmlElementAttributeValue( String expression, String attributeName )
+ {
+ Node node = this.getXmlElement( expression );
+
+ if ( node == null ) {
+ return null;
+ } else {
+ Node attribute = node.getAttributes().getNamedItem( attributeName );
+
+ if ( attribute == null ) {
+ return null;
+ } else {
+ return attribute.getNodeValue();
+ }
+ }
+ }
+
+ @Override
+ public void setXmlElementAttributeValue( String expression, String attributeName, String value )
+ {
+ Node node = this.createXmlElement( expression );
+ Node attribute = node.getAttributes().getNamedItem( attributeName );
+
+ if ( attribute == null ) {
+ Element element = Element.class.cast( node );
+ element.setAttribute( attributeName, value );
+ } else {
+ attribute.setNodeValue( value );
+ }
+ }
+
+ @Override
+ public void removeXmlElementAttribute( String expression, String attributeName )
+ {
+ Node node = this.getXmlElement( expression );
+
+ if ( node != null ) {
+ Node attribute = node.getAttributes().getNamedItem( attributeName );
+ node.getAttributes().removeNamedItem( attribute.getNodeName() );
+ }
+ }
+
+ @Override
+ public void removeXmlElementAttributes( String expression )
+ {
+ Node node = this.getXmlElement( expression );
+
+ if ( node != null ) {
+ for ( int i = 0; i < node.getAttributes().getLength(); i++ ) {
+ Node attribute = node.getAttributes().item( 0 );
+ node.getAttributes().removeNamedItem( attribute.getNodeName() );
+ }
+ }
+ }
+
+ @Override
+ public void fromXmlNode( Node xmlNode )
+ {
+ this.setXmlBaseNode( xmlNode );
+ }
+
+ @Override
+ public Node toXmlNode()
+ {
+ return this.getXmlBaseNode();
+ }
+}