blob: c4ad2c3d862fe89c1b718b28b93d39cf334d4d72 (
plain) (
tree)
|
|
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();
}
}
|