summaryrefslogblamecommitdiffstats
path: root/src/main/java/org/openslx/libvirt/xml/LibvirtXmlNode.java
blob: c4ad2c3d862fe89c1b718b28b93d39cf334d4d72 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14













                                                
                                                                          






                                                                              
                                                               



                                                                     
                                                                               



                                                                        
                                           








                                                                                               
                                                                                            



                                        
                                                                                              



























































































                                                                                                         
                                                                                                   








                                                            

                                                                                                   








                                                      


                                                                           
























                                                                                               
                                                                   



















































































                                                                                                                     


                                                                     







                                                                                            
                                                             


























                                                                                                        
 



































                                                                                                
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 Node 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 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 ) {
					parentNode.appendChild( this.xmlDocument.createElement( nodeNames[i] ) );
					currentNode = parentNode.getLastChild();
				}

				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();
	}
}