summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Bauer2018-04-25 18:35:04 +0200
committerJonathan Bauer2018-04-25 18:35:04 +0200
commit7439bd659e4befa5786b3455cf6ceb34825736e7 (patch)
treea4bbe267e2e925d271094b5a8cc517009a972417
parent[vbox] more refactoring (diff)
downloadmaster-sync-shared-7439bd659e4befa5786b3455cf6ceb34825736e7.tar.gz
master-sync-shared-7439bd659e4befa5786b3455cf6ceb34825736e7.tar.xz
master-sync-shared-7439bd659e4befa5786b3455cf6ceb34825736e7.zip
[vbox] new XmlHelper class + usage thereof
-rw-r--r--src/main/java/org/openslx/util/XmlHelper.java108
-rw-r--r--src/main/java/org/openslx/util/vm/VboxConfig.java88
-rw-r--r--src/main/java/org/openslx/util/vm/VboxMetaData.java2
-rw-r--r--src/main/java/org/openslx/util/vm/VmMetaData.java5
4 files changed, 135 insertions, 68 deletions
diff --git a/src/main/java/org/openslx/util/XmlHelper.java b/src/main/java/org/openslx/util/XmlHelper.java
new file mode 100644
index 0000000..70c5be8
--- /dev/null
+++ b/src/main/java/org/openslx/util/XmlHelper.java
@@ -0,0 +1,108 @@
+package org.openslx.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+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.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+public class XmlHelper
+{
+ private final static Logger LOGGER = Logger.getLogger( XmlHelper.class );
+
+ // TODO check thread-safety
+ public static final XPath XPath = XPathFactory.newInstance().newXPath();
+ private static DocumentBuilder dBuilder;
+ static {
+ DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
+ dbFactory.setIgnoringComments( true );
+ try {
+ dBuilder = dbFactory.newDocumentBuilder();
+ } catch ( ParserConfigurationException e ) {
+ LOGGER.error( "Failed to initalize DOM parser with default configurations." );
+ }
+ }
+
+ public static Document parseDocumentFromStream( InputStream is )
+ {
+ Document doc = null;
+ try {
+ doc = dBuilder.parse( is );
+ } catch ( SAXException | IOException e ) {
+ LOGGER.error( "Failed to parse input stream to document." );
+ }
+ if ( doc == null )
+ return null;
+ doc.getDocumentElement().normalize();
+ return doc;
+ }
+
+ public static Document removeFormattingNodes( Document doc )
+ {
+ NodeList empty;
+ try {
+ empty = (NodeList)XPath.evaluate( "//text()[normalize-space(.) = '']",
+ doc, XPathConstants.NODESET );
+ } catch ( XPathExpressionException e ) {
+ LOGGER.error( "Bad XPath expression to find all empty text nodes." );
+ return null;
+ }
+
+ for ( int i = 0; i < empty.getLength(); i++ ) {
+ Node node = empty.item( i );
+ node.getParentNode().removeChild( node );
+ }
+ return doc;
+ }
+
+ public static String getUnformattedXml( InputStream is )
+ {
+ // prune empty text nodes, essentially removing all formatting
+ Document doc = parseDocumentFromStream( is );
+ return getXmlFromDocument( removeFormattingNodes( doc ), false );
+ }
+
+ public static String getFormattedXml( InputStream is )
+ {
+ Document doc = parseDocumentFromStream( is );
+ return getXmlFromDocument( doc, true );
+ }
+
+ public static String getXmlFromDocument( Document doc, boolean humanReadable )
+ {
+ try {
+ StringWriter writer = new StringWriter();
+ TransformerFactory tf = TransformerFactory.newInstance();
+ Transformer transformer = tf.newTransformer();
+ transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "no" );
+ transformer.setOutputProperty( OutputKeys.ENCODING, "UTF-8" );
+ transformer.setOutputProperty( OutputKeys.METHOD, "xml" );
+ if ( humanReadable ) {
+ transformer.setOutputProperty( OutputKeys.INDENT, "yes" );
+ transformer.setOutputProperty( "{http://xml.apache.org/xslt}indent-amount", "2" );
+ }
+ transformer.transform( new DOMSource( doc ), new StreamResult( writer ) );
+ return writer.toString();
+ } catch ( Exception ex ) {
+ LOGGER.error( "Failed to transform XML to String: ", ex );
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/org/openslx/util/vm/VboxConfig.java b/src/main/java/org/openslx/util/vm/VboxConfig.java
index 1e3ba10..c558864 100644
--- a/src/main/java/org/openslx/util/vm/VboxConfig.java
+++ b/src/main/java/org/openslx/util/vm/VboxConfig.java
@@ -1,26 +1,17 @@
package org.openslx.util.vm;
+import java.io.ByteArrayInputStream;
import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
-import java.io.StringReader;
-import java.io.StringWriter;
import java.util.ArrayList;
-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.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-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.apache.log4j.Logger;
+import org.openslx.util.XmlHelper;
import org.openslx.util.vm.VmMetaData.DriveBusType;
import org.openslx.util.vm.VmMetaData.HardDisk;
import org.w3c.dom.DOMException;
@@ -28,8 +19,6 @@ import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
/**
* Class handling the parsing of a .vbox machine description file
@@ -44,18 +33,7 @@ public class VboxConfig
private ArrayList<HardDisk> hddsArray = new ArrayList<HardDisk>();
// XPath and DOM parsing related members
- private static final XPath xPath = XPathFactory.newInstance().newXPath();
private Document doc = null;
- private static DocumentBuilder dBuilder;
- static {
- DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
- dbFactory.setIgnoringComments( true );
- try {
- dBuilder = dbFactory.newDocumentBuilder();
- } catch ( ParserConfigurationException e ) {
- LOGGER.error( "Failed to initalize DOM parser with default configurations." );
- }
- }
// list of nodes to automatically remove when reading the vbox file
private static String[] blacklist = {
@@ -102,26 +80,20 @@ public class VboxConfig
public VboxConfig( File file ) throws IOException, UnsupportedVirtualizerFormatException
{
try {
- doc = dBuilder.parse( file );
- doc.getDocumentElement().normalize();
- // prune empty text nodes, essentially removing all formatting
- NodeList empty = (NodeList)xPath.evaluate( "//text()[normalize-space(.) = '']",
- doc, XPathConstants.NODESET );
-
- for ( int i = 0; i < empty.getLength(); i++ ) {
- Node node = empty.item( i );
- node.getParentNode().removeChild( node );
- }
+ doc = XmlHelper.parseDocumentFromStream( new FileInputStream( file ) );
+ doc = XmlHelper.removeFormattingNodes( doc );
+
// TODO - validate against XML schema:
// https://www.virtualbox.org/svn/vbox/trunk/src/VBox/Main/xml/VirtualBox-settings.xsd
if ( !doc.getDocumentElement().getNodeName().equals( "VirtualBox" ) ) {
throw new UnsupportedVirtualizerFormatException( "No <VirtualBox> root node." );
}
- } catch ( SAXException | IOException | XPathExpressionException e ) {
+ } catch ( IOException e ) {
LOGGER.warn( "Could not parse .vbox", e );
- throw new UnsupportedVirtualizerFormatException( "Could not create VBoxConfig!" );
}
+ if ( doc == null )
+ throw new UnsupportedVirtualizerFormatException( "Could not create VBoxConfig!" );
}
/**
@@ -132,13 +104,13 @@ public class VboxConfig
* @param length of the machine description byte array.
* @throws IOException if an
*/
- public VboxConfig( byte[] machineDescription, int length )
+ public VboxConfig( byte[] machineDescription, int length ) throws UnsupportedVirtualizerFormatException
{
- try {
- InputSource is = new InputSource( new StringReader( new String( machineDescription ) ) );
- doc = dBuilder.parse( is );
- } catch ( SAXException | IOException e ) {
- LOGGER.error( "Failed to create a DOM from give machine description: ", e );
+ ByteArrayInputStream is = new ByteArrayInputStream( machineDescription );
+ doc = XmlHelper.parseDocumentFromStream( is );
+ if ( doc == null ) {
+ LOGGER.error( "Failed to create a DOM from given machine description." );
+ throw new UnsupportedVirtualizerFormatException( "Could not create VBoxConfig from byte array." );
}
}
@@ -172,7 +144,7 @@ public class VboxConfig
private void ensureHardwareUuid() throws XPathExpressionException
{
// we will need the machine uuid, so get it
- String machineUuid = xPath.compile( "/VirtualBox/Machine/@uuid" ).evaluate( this.doc );
+ String machineUuid = XmlHelper.XPath.compile( "/VirtualBox/Machine/@uuid" ).evaluate( this.doc );
if ( machineUuid.isEmpty() ) {
LOGGER.error( "Machine UUID empty, should never happen!" );
return;
@@ -269,12 +241,11 @@ public class VboxConfig
{
// iterate over the blackList
for ( String blackedTag : blacklist ) {
- XPathExpression blackedExpr = xPath.compile( blackedTag );
+ XPathExpression blackedExpr = XmlHelper.XPath.compile( blackedTag );
NodeList blackedNodes = (NodeList)blackedExpr.evaluate( this.doc, XPathConstants.NODESET );
for ( int i = 0; i < blackedNodes.getLength(); i++ ) {
// go through the child nodes of the blacklisted ones -> why?
Element child = (Element)blackedNodes.item( i );
- LOGGER.debug( "REMOVING: " + child.getNodeName() + " -> " + child.getNodeValue() );
removeNode( child );
}
}
@@ -288,7 +259,7 @@ public class VboxConfig
*/
public void setMachineName() throws XPathExpressionException
{
- String name = xPath.compile( "/VirtualBox/Machine/@name" ).evaluate( this.doc );
+ String name = XmlHelper.XPath.compile( "/VirtualBox/Machine/@name" ).evaluate( this.doc );
if ( name != null && !name.isEmpty() ) {
displayName = name;
}
@@ -311,7 +282,7 @@ public class VboxConfig
*/
public void setOsType() throws XPathExpressionException
{
- String os = xPath.compile( "/VirtualBox/Machine/@OSType" ).evaluate( this.doc );
+ String os = XmlHelper.XPath.compile( "/VirtualBox/Machine/@OSType" ).evaluate( this.doc );
if ( os != null && !os.isEmpty() ) {
osName = os;
}
@@ -334,7 +305,7 @@ public class VboxConfig
*/
public void setHdds() throws XPathExpressionException
{
- XPathExpression hddsExpr = xPath.compile( "/VirtualBox/Machine/MediaRegistry/HardDisks/*" );
+ XPathExpression hddsExpr = XmlHelper.XPath.compile( "/VirtualBox/Machine/MediaRegistry/HardDisks/*" );
NodeList nodes = (NodeList)hddsExpr.evaluate( this.doc, XPathConstants.NODESET );
for ( int i = 0; i < nodes.getLength(); i++ ) {
Element hddElement = (Element)nodes.item( i );
@@ -434,7 +405,7 @@ public class VboxConfig
{
NodeList nodes = null;
try {
- XPathExpression expr = xPath.compile( xpath );
+ XPathExpression expr = XmlHelper.XPath.compile( xpath );
Object nodesObject = expr.evaluate( this.doc, XPathConstants.NODESET );
nodes = (NodeList)nodesObject;
} catch ( XPathExpressionException e ) {
@@ -549,21 +520,6 @@ public class VboxConfig
*/
public String toString( boolean prettyPrint )
{
- try {
- StringWriter writer = new StringWriter();
- TransformerFactory tf = TransformerFactory.newInstance();
- Transformer transformer = tf.newTransformer();
- transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "no" );
- transformer.setOutputProperty( OutputKeys.ENCODING, "UTF-8" );
- transformer.setOutputProperty( OutputKeys.METHOD, "xml" );
- if ( prettyPrint ) {
- transformer.setOutputProperty( OutputKeys.INDENT, "yes" );
- transformer.setOutputProperty( "{http://xml.apache.org/xslt}indent-amount", "2" );
- }
- transformer.transform( new DOMSource( doc ), new StreamResult( writer ) );
- return writer.toString();
- } catch ( Exception ex ) {
- throw new RuntimeException( "Error converting to String", ex );
- }
+ return XmlHelper.getXmlFromDocument( doc, prettyPrint );
}
}
diff --git a/src/main/java/org/openslx/util/vm/VboxMetaData.java b/src/main/java/org/openslx/util/vm/VboxMetaData.java
index c3f0a43..dffa2d7 100644
--- a/src/main/java/org/openslx/util/vm/VboxMetaData.java
+++ b/src/main/java/org/openslx/util/vm/VboxMetaData.java
@@ -134,7 +134,7 @@ public class VboxMetaData extends VmMetaData<VBoxSoundCardMeta, VBoxDDAccelMeta,
@Override
public byte[] getDefinitionArray()
{
- return config.toString( true ).getBytes( StandardCharsets.UTF_8 );
+ return config.toString( false ).getBytes( StandardCharsets.UTF_8 );
}
@Override
diff --git a/src/main/java/org/openslx/util/vm/VmMetaData.java b/src/main/java/org/openslx/util/vm/VmMetaData.java
index fe74897..d98deee 100644
--- a/src/main/java/org/openslx/util/vm/VmMetaData.java
+++ b/src/main/java/org/openslx/util/vm/VmMetaData.java
@@ -131,6 +131,7 @@ public abstract class VmMetaData<T, U, V, W>
protected String displayName = null;
protected boolean isMachineSnapshot;
+
/*
* Getters for virtual hardware
*/
@@ -189,9 +190,11 @@ public abstract class VmMetaData<T, U, V, W>
/*
* Getter for isMachineSnapshot
*/
- public boolean isMachineSnapshot() {
+ public boolean isMachineSnapshot()
+ {
return isMachineSnapshot;
}
+
/**
* This method should return a minimal representation of the input meta data.
* The representation is platform dependent, and should be stripped of all