summaryrefslogblamecommitdiffstats
path: root/src/main/java/org/openslx/libvirt/xml/LibvirtXmlDocument.java
blob: 805376f3b1d8ed5bc38b6236c4ebd3d6c8bc9c7b (plain) (tree)
1
2
3
4
5
6
7





                                
                            




                                                      
                                      

                                                             




                                               














































                                                                                                         
                                                                                                 







                                                                                                 
                                                                                                                     















                                                                                                                                 
                                                                                              
                                                                 
                                                                                                                   







                                                                                               
                                                                                                                              












                                                                                            

                                               
                                                                                            











                                                                                            
           
                                                                      
                                                                                            


                                                   








                                                                                            

                                             
                                                                                            











                                                                                            
           
                                                                    
                                                                                            


                                                   








                                                                                            

                                                    
                                                                                            











                                                                                            
           
                                                                           
                                                                                            


                                                   








                                                                                            

                                                    
                                                                                            











                                                                                            
           
                                                                           
                                                                                            


                                                   














                                                                                 
                                                                           















































                                                                                                                 









                                                                               
                                                   
                                         

                                                                                              

                                                  
                                                 
                         





                           








                                                                               

                                            

                                                                                              

                                                  
                                                 
                         




















                                                                       
package org.openslx.libvirt.xml;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;

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.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * A generic representation of a Libvirt XML file.
 * 
 * @implNote Base class to derive the representation of specific Libvirt XML files.
 * 
 * @author Manuel Bentele
 * @version 1.0
 */
public abstract class LibvirtXmlDocument implements LibvirtXmlSerializable, LibvirtXmlValidatable
{
	/**
	 * Document builder to parse Libvirt XML document from file.
	 */
	private DocumentBuilder domBuilder = null;

	/**
	 * Representation of a Libvirt XML document.
	 */
	private Document xmlDocument = null;

	/**
	 * XML transformer to transform Libvirt XML document to a file.
	 */
	private Transformer xmlTransformer = null;

	/**
	 * XML root node of the Libvirt XML document.
	 */
	private LibvirtXmlNode rootXmlNode = null;

	/**
	 * RNG schema validator to validate the Libvirt XML document content.
	 */
	private LibvirtXmlSchemaValidator rngValidator = null;

	/**
	 * Creates and initializes XML context to create and transform a Libvirt XML file from/to a file.
	 * 
	 * @param rngSchema RNG schema to validate the Libvirt XML document content.
	 * 
	 * @throws LibvirtXmlDocumentException error occured during setup of the XML context to read and
	 *            write from/to a Libvirt XML file.
	 */
	private void createXmlContext( InputStream rngSchema ) throws LibvirtXmlDocumentException
	{
		// used for XML input
		try {
			DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
			domFactory.setIgnoringElementContentWhitespace( true );
			domFactory.setNamespaceAware( true );
			this.domBuilder = domFactory.newDocumentBuilder();
		} catch ( ParserConfigurationException e ) {
			String errorMsg = "Setting up XML context for reading from the Libvirt XML document failed.";
			throw new LibvirtXmlDocumentException( errorMsg );
		}

		// used for XML output
		try {
			// use hack to load specific transformer factory implementation for XSLT
			System.setProperty( TransformerFactory.class.getName(),
					"org.apache.xalan.processor.TransformerFactoryImpl" );

			// create XML transformer factory to create XML transformer with specific indentation
			TransformerFactory transformerFactory = TransformerFactory.newInstance();

			// create XML transformer and apply settings for output XML transformation
			InputStream xslOutputSchemaStream = LibvirtXmlResources.getLibvirtXsl( "xml-output-transformation.xsl" );
			StreamSource xslOutputSchema = new StreamSource( xslOutputSchemaStream );
			this.xmlTransformer = transformerFactory.newTransformer( xslOutputSchema );
			this.xmlTransformer.setOutputProperty( OutputKeys.ENCODING, "UTF-8" );
		} catch ( TransformerConfigurationException e ) {
			String errorMsg = "Setting up XML context for writing to the Libvirt XML document failed.";
			throw new LibvirtXmlDocumentException( errorMsg );
		}

		// used for XML validation with RNG schema files
		if ( rngSchema != null ) {
			try {
				this.rngValidator = new LibvirtXmlSchemaValidator( rngSchema );
			} catch ( SAXException e ) {
				String errorMsg = "Setting up XML context for validating to the Libvirt XML document failed.";
				e.printStackTrace();
				throw new LibvirtXmlDocumentException( errorMsg );
			}
		}
	}

	/**
	 * Creates a Libvirt XML document from a given XML content.
	 * 
	 * @param xml XML content as {@link String}.
	 * 
	 * @throws LibvirtXmlDocumentException creation of XML context failed.
	 * @throws LibvirtXmlSerializationException serialization of the XML content failed.
	 */
	public LibvirtXmlDocument( String xml )
			throws LibvirtXmlDocumentException, LibvirtXmlSerializationException
	{
		this( xml, null );
	}

	/**
	 * Creates a Libvirt XML document from a given XML content.
	 * 
	 * @param xml XML content as {@link String}.
	 * @param rngSchema RNG schema to validate XML content.
	 * 
	 * @throws LibvirtXmlDocumentException creation of XML context failed.
	 * @throws LibvirtXmlSerializationException serialization of the XML content failed.
	 */
	public LibvirtXmlDocument( String xml, InputStream rngSchema )
			throws LibvirtXmlDocumentException, LibvirtXmlSerializationException
	{
		this.createXmlContext( rngSchema );
		this.fromXml( xml );
	}

	/**
	 * Creates a Libvirt XML document from a given XML content.
	 * 
	 * @param xml XML content as {@link File}.
	 * 
	 * @throws LibvirtXmlDocumentException creation of XML context failed.
	 * @throws LibvirtXmlSerializationException serialization of the XML content failed.
	 */
	public LibvirtXmlDocument( File xml )
			throws LibvirtXmlDocumentException, LibvirtXmlSerializationException
	{
		this( xml, null );
	}

	/**
	 * Creates a Libvirt XML document from a given XML content.
	 * 
	 * @param xml XML content as {@link File}.
	 * @param rngSchema RNG schema to validate XML content.
	 * 
	 * @throws LibvirtXmlDocumentException creation of XML context failed.
	 * @throws LibvirtXmlSerializationException serialization of the XML content failed.
	 */
	public LibvirtXmlDocument( File xml, InputStream rngSchema )
			throws LibvirtXmlDocumentException, LibvirtXmlSerializationException
	{
		this.createXmlContext( rngSchema );
		this.fromXml( xml );
	}

	/**
	 * Creates a Libvirt XML document from a given XML content.
	 * 
	 * @param xml XML content as {@link InputStream}.
	 * 
	 * @throws LibvirtXmlDocumentException creation of XML context failed.
	 * @throws LibvirtXmlSerializationException serialization of the XML content failed.
	 */
	public LibvirtXmlDocument( InputStream xml )
			throws LibvirtXmlDocumentException, LibvirtXmlSerializationException
	{
		this( xml, null );
	}

	/**
	 * Creates a Libvirt XML document from a given XML content.
	 * 
	 * @param xml XML content as {@link InputStream}.
	 * @param rngSchema RNG schema to validate XML content.
	 * 
	 * @throws LibvirtXmlDocumentException creation of XML context failed.
	 * @throws LibvirtXmlSerializationException serialization of the XML content failed.
	 */
	public LibvirtXmlDocument( InputStream xml, InputStream rngSchema )
			throws LibvirtXmlDocumentException, LibvirtXmlSerializationException
	{
		this.createXmlContext( rngSchema );
		this.fromXml( xml );
	}

	/**
	 * Creates a Libvirt XML document from a given XML content.
	 * 
	 * @param xml XML content as {@link InputSource}.
	 * 
	 * @throws LibvirtXmlDocumentException creation of XML context failed.
	 * @throws LibvirtXmlSerializationException serialization of the XML content failed.
	 */
	public LibvirtXmlDocument( InputSource xml )
			throws LibvirtXmlDocumentException, LibvirtXmlSerializationException
	{
		this( xml, null );
	}

	/**
	 * Creates a Libvirt XML document from a given XML content.
	 * 
	 * @param xml XML content as {@link InputSource}.
	 * @param rngSchema RNG schema to validate XML content.
	 * 
	 * @throws LibvirtXmlDocumentException creation of XML context failed.
	 * @throws LibvirtXmlSerializationException serialization of the XML content failed.
	 */
	public LibvirtXmlDocument( InputSource xml, InputStream rngSchema )
			throws LibvirtXmlDocumentException, LibvirtXmlSerializationException
	{
		this.createXmlContext( rngSchema );
		this.fromXml( xml );
	}

	/**
	 * Returns the XML root node of the Libvirt XML document.
	 * 
	 * @return root node of the Libvirt XML document.
	 */
	public LibvirtXmlNode getRootXmlNode()
	{
		return this.rootXmlNode;
	}

	@Override
	public void fromXml( String xml ) throws LibvirtXmlSerializationException
	{
		this.fromXml( new InputSource( new StringReader( xml ) ) );
	}

	@Override
	public void fromXml( File xml ) throws LibvirtXmlSerializationException
	{
		try {
			this.xmlDocument = this.domBuilder.parse( xml );
			this.xmlDocument.getDocumentElement().normalize();
		} catch ( SAXException e ) {
			throw new LibvirtXmlSerializationException( e.getLocalizedMessage() );
		} catch ( IOException e ) {
			throw new LibvirtXmlSerializationException( e.getLocalizedMessage() );
		}

		this.rootXmlNode = new LibvirtXmlNode( this.xmlDocument, this.xmlDocument.getDocumentElement() );
	}

	@Override
	public void fromXml( InputStream xml ) throws LibvirtXmlSerializationException
	{
		try {
			this.xmlDocument = this.domBuilder.parse( xml );
			this.xmlDocument.getDocumentElement().normalize();
		} catch ( SAXException e ) {
			throw new LibvirtXmlSerializationException( e.getLocalizedMessage() );
		} catch ( IOException e ) {
			throw new LibvirtXmlSerializationException( e.getLocalizedMessage() );
		}

		this.rootXmlNode = new LibvirtXmlNode( this.xmlDocument, this.xmlDocument.getDocumentElement() );
	}

	@Override
	public void fromXml( InputSource xml ) throws LibvirtXmlSerializationException
	{
		try {
			this.xmlDocument = this.domBuilder.parse( xml );
			this.xmlDocument.getDocumentElement().normalize();
		} catch ( SAXException e ) {
			throw new LibvirtXmlSerializationException( e.getLocalizedMessage() );
		} catch ( IOException e ) {
			throw new LibvirtXmlSerializationException( e.getLocalizedMessage() );
		}

		this.rootXmlNode = new LibvirtXmlNode( this.xmlDocument, this.xmlDocument.getDocumentElement() );
	}

	@Override
	public String toXml() throws LibvirtXmlSerializationException
	{
		StringWriter xmlWriter = null;
		String xml = null;

		try {
			xmlWriter = new StringWriter();
			DOMSource source = new DOMSource( this.xmlDocument );
			StreamResult xmlString = new StreamResult( xmlWriter );
			this.xmlTransformer.transform( source, xmlString );
			xml = xmlWriter.toString();
		} catch ( Exception e ) {
			throw new LibvirtXmlSerializationException( e.getLocalizedMessage() );
		} finally {
			try {
				xmlWriter.close();
			} catch ( Throwable e ) {
			}
		}

		return xml;
	}

	@Override
	public void toXml( File xml ) throws LibvirtXmlSerializationException
	{
		FileWriter xmlWriter = null;

		try {
			xmlWriter = new FileWriter( xml );
			DOMSource source = new DOMSource( this.xmlDocument );
			StreamResult xmlStream = new StreamResult( xmlWriter );
			this.xmlTransformer.transform( source, xmlStream );
		} catch ( Exception e ) {
			e.printStackTrace();
			throw new LibvirtXmlSerializationException( e.getLocalizedMessage() );
		} finally {
			try {
				xmlWriter.close();
			} catch ( Throwable e ) {
			}
		}
	}

	@Override
	public void validateXml() throws LibvirtXmlValidationException
	{
		if ( this.rngValidator != null ) {
			this.rngValidator.validate( this.xmlDocument );
		}
	}

	@Override
	public String toString()
	{
		try {
			return this.toXml();
		} catch ( LibvirtXmlSerializationException e ) {
			return null;
		}
	}
}