summaryrefslogtreecommitdiffstats
path: root/src/main/java/org/openslx/libvirt
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/openslx/libvirt')
-rw-r--r--src/main/java/org/openslx/libvirt/capabilities/Capabilities.java155
-rw-r--r--src/main/java/org/openslx/libvirt/capabilities/cpu/Cpu.java165
-rw-r--r--src/main/java/org/openslx/libvirt/capabilities/cpu/Feature.java51
-rw-r--r--src/main/java/org/openslx/libvirt/capabilities/cpu/Pages.java60
-rw-r--r--src/main/java/org/openslx/libvirt/capabilities/guest/Domain.java53
-rw-r--r--src/main/java/org/openslx/libvirt/capabilities/guest/Guest.java127
-rw-r--r--src/main/java/org/openslx/libvirt/capabilities/guest/Machine.java72
-rw-r--r--src/main/java/org/openslx/libvirt/domain/Domain.java1743
-rw-r--r--src/main/java/org/openslx/libvirt/domain/DomainUtils.java118
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/Controller.java181
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/ControllerFloppy.java54
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/ControllerIde.java128
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/ControllerPci.java145
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/ControllerSata.java54
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/ControllerScsi.java138
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/ControllerUsb.java139
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/Device.java290
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/Disk.java427
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/DiskCdrom.java55
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/DiskFloppy.java52
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/DiskStorage.java54
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/FileSystem.java292
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/Graphics.java269
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/GraphicsSpice.java261
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/GraphicsVnc.java54
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/Hostdev.java175
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/HostdevAddressableSource.java26
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/HostdevAddressableTarget.java26
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/HostdevMdev.java182
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/HostdevMdevDeviceAddress.java99
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/HostdevPci.java74
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/HostdevPciDeviceAddress.java295
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/HostdevPciDeviceDescription.java186
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/HostdevUsb.java88
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/HostdevUsbDeviceAddress.java141
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/HostdevUsbDeviceDescription.java190
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/HostdevUtils.java32
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/Interface.java344
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/InterfaceBridge.java54
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/InterfaceNetwork.java54
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/Parallel.java158
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/Serial.java156
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/Shmem.java178
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/Sound.java128
-rw-r--r--src/main/java/org/openslx/libvirt/domain/device/Video.java197
-rw-r--r--src/main/java/org/openslx/libvirt/libosinfo/LibOsInfo.java158
-rw-r--r--src/main/java/org/openslx/libvirt/libosinfo/os/Os.java93
-rw-r--r--src/main/java/org/openslx/libvirt/xml/LibvirtXmlCreatable.java26
-rw-r--r--src/main/java/org/openslx/libvirt/xml/LibvirtXmlDocument.java355
-rw-r--r--src/main/java/org/openslx/libvirt/xml/LibvirtXmlDocumentException.java25
-rw-r--r--src/main/java/org/openslx/libvirt/xml/LibvirtXmlEditable.java285
-rw-r--r--src/main/java/org/openslx/libvirt/xml/LibvirtXmlNode.java350
-rw-r--r--src/main/java/org/openslx/libvirt/xml/LibvirtXmlResources.java105
-rw-r--r--src/main/java/org/openslx/libvirt/xml/LibvirtXmlSchemaValidator.java284
-rw-r--r--src/main/java/org/openslx/libvirt/xml/LibvirtXmlSerializable.java69
-rw-r--r--src/main/java/org/openslx/libvirt/xml/LibvirtXmlSerializationException.java25
-rw-r--r--src/main/java/org/openslx/libvirt/xml/LibvirtXmlValidatable.java18
-rw-r--r--src/main/java/org/openslx/libvirt/xml/LibvirtXmlValidationException.java25
58 files changed, 9738 insertions, 0 deletions
diff --git a/src/main/java/org/openslx/libvirt/capabilities/Capabilities.java b/src/main/java/org/openslx/libvirt/capabilities/Capabilities.java
new file mode 100644
index 0000000..7987371
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/capabilities/Capabilities.java
@@ -0,0 +1,155 @@
+package org.openslx.libvirt.capabilities;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openslx.libvirt.capabilities.cpu.Cpu;
+import org.openslx.libvirt.capabilities.guest.Guest;
+import org.openslx.libvirt.xml.LibvirtXmlDocument;
+import org.openslx.libvirt.xml.LibvirtXmlDocumentException;
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+import org.openslx.libvirt.xml.LibvirtXmlResources;
+import org.openslx.libvirt.xml.LibvirtXmlSerializationException;
+import org.openslx.libvirt.xml.LibvirtXmlValidationException;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+
+/**
+ * Implementation of the Libvirt capabilities XML document.
+ *
+ * The Libvirt capabilities XML document is used to describe the configuration and capabilities of
+ * the hypervisor's host.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class Capabilities extends LibvirtXmlDocument
+{
+ /**
+ * Creates Libvirt capabilities XML document from {@link String} providing Libvirt capabilities
+ * XML content.
+ *
+ * @param xml {@link String} with Libvirt capabilities XML content.
+ *
+ * @throws LibvirtXmlDocumentException creation of XML context failed.
+ * @throws LibvirtXmlSerializationException serialization of the capabilities XML content failed.
+ * @throws LibvirtXmlValidationException XML content is not a valid capabilities XML document.
+ */
+ public Capabilities( String xml )
+ throws LibvirtXmlDocumentException, LibvirtXmlSerializationException, LibvirtXmlValidationException
+ {
+ super( xml, LibvirtXmlResources.getLibvirtRng( "capabilities.rng" ) );
+ }
+
+ /**
+ * Creates Libvirt capabilities XML document from {@link File} containing Libvirt capabilities
+ * XML content.
+ *
+ * @param xml existing {@link File} containing Libvirt capabilities XML content.
+ *
+ * @throws LibvirtXmlDocumentException creation of XML context failed.
+ * @throws LibvirtXmlSerializationException serialization of the capabilities XML content failed.
+ * @throws LibvirtXmlValidationException XML content is not a valid capabilities XML document.
+ */
+ public Capabilities( File xml )
+ throws LibvirtXmlDocumentException, LibvirtXmlSerializationException, LibvirtXmlValidationException
+ {
+ super( xml, LibvirtXmlResources.getLibvirtRng( "capabilities.rng" ) );
+ }
+
+ /**
+ * Creates Libvirt capabilities XML document from {@link InputStream} providing Libvirt
+ * capabilities XML content.
+ *
+ * @param xml {@link InputStream} providing Libvirt capabilities XML content.
+ *
+ * @throws LibvirtXmlDocumentException creation of XML context failed.
+ * @throws LibvirtXmlSerializationException serialization of the capabilities XML content failed.
+ * @throws LibvirtXmlValidationException XML content is not a valid capabilities XML document.
+ */
+ public Capabilities( InputStream xml )
+ throws LibvirtXmlDocumentException, LibvirtXmlSerializationException, LibvirtXmlValidationException
+ {
+ super( xml, LibvirtXmlResources.getLibvirtRng( "capabilities.rng" ) );
+ }
+
+ /**
+ * Creates Libvirt capabilities XML document from {@link InputSource} providing Libvirt
+ * capabilities XML content.
+ *
+ * @param xml {@link InputSource} providing Libvirt capabilities XML content.
+ *
+ * @throws LibvirtXmlDocumentException creation of XML context failed.
+ * @throws LibvirtXmlSerializationException serialization of the capabilities XML content failed.
+ * @throws LibvirtXmlValidationException XML content is not a valid capabilities XML document.
+ */
+ public Capabilities( InputSource xml )
+ throws LibvirtXmlDocumentException, LibvirtXmlSerializationException, LibvirtXmlValidationException
+ {
+ super( xml, LibvirtXmlResources.getLibvirtRng( "capabilities.rng" ) );
+ }
+
+ /**
+ * Returns UUID of the Libvirt host machine.
+ *
+ * @return UUID of the host machine.
+ */
+ public String getHostUuid()
+ {
+ return this.getRootXmlNode().getXmlElementValue( "host/uuid" );
+ }
+
+ /**
+ * Returns CPU capabilities of the host machine.
+ *
+ * @return CPU capabilities of the host machine.
+ */
+ public Cpu getHostCpu()
+ {
+ final Node hostCpuNode = this.getRootXmlNode().getXmlElement( "host/cpu" );
+
+ if ( hostCpuNode == null ) {
+ return null;
+ } else {
+ final LibvirtXmlNode hostCpuXmlNode = new LibvirtXmlNode( this.getRootXmlNode().getXmlDocument(),
+ hostCpuNode );
+ return Cpu.newInstance( hostCpuXmlNode );
+ }
+ }
+
+ /**
+ * Checks whether the Libvirt host machine has IOMMU support.
+ *
+ * @return State of the IOMMU support.
+ */
+ public boolean hasHostIommuSupport()
+ {
+ return this.getRootXmlNode().getXmlElementAttributeValueAsBool( "host/iommu", "support" );
+ }
+
+ /**
+ * Returns capabilities of all possible guest machines.
+ *
+ * @return capabilities of all possible guest machines.
+ */
+ public List<Guest> getGuests()
+ {
+ final List<Guest> guestList = new ArrayList<Guest>();
+ final NodeList guestNodes = this.getRootXmlNode().getXmlNodes( "guest" );
+
+ for ( int i = 0; i < guestNodes.getLength(); i++ ) {
+ final LibvirtXmlNode guestNode = new LibvirtXmlNode( this.getRootXmlNode().getXmlDocument(),
+ guestNodes.item( i ) );
+ final Guest guest = Guest.newInstance( guestNode );
+
+ if ( guest != null ) {
+ guestList.add( guest );
+ }
+ }
+
+ return guestList;
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/capabilities/cpu/Cpu.java b/src/main/java/org/openslx/libvirt/capabilities/cpu/Cpu.java
new file mode 100644
index 0000000..dc5fbd0
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/capabilities/cpu/Cpu.java
@@ -0,0 +1,165 @@
+package org.openslx.libvirt.capabilities.cpu;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+import org.w3c.dom.NodeList;
+
+/**
+ * Implementation of the host CPU capabilities as part of the Libvirt capabilities XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class Cpu extends LibvirtXmlNode
+{
+ /**
+ * Creates an empty host CPU capabilities instance.
+ */
+ public Cpu()
+ {
+ super();
+ }
+
+ /**
+ * Creates a host CPU capabilities instance representing an existing Libvirt XML host CPU
+ * capabilities element.
+ *
+ * @param xmlNode existing Libvirt XML host CPU capabilities element.
+ */
+ public Cpu( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Returns the architecture name of the host CPU.
+ *
+ * @return architecture name of the host CPU.
+ */
+ public String getArch()
+ {
+ return this.getXmlElementValue( "arch" );
+ }
+
+ /**
+ * Returns the model name of the host CPU.
+ *
+ * @return model name of the host CPU.
+ */
+ public String getModel()
+ {
+ return this.getXmlElementValue( "model" );
+ }
+
+ /**
+ * Returns the vendor name of the host CPU.
+ *
+ * @return vendor name of the host CPU.
+ */
+ public String getVendor()
+ {
+ return this.getXmlElementValue( "vendor" );
+ }
+
+ /**
+ * Returns the number of sockets of the host CPU.
+ *
+ * @return number of sockets of the host CPU.
+ */
+ public int getTopologySockets()
+ {
+ final String numSockets = this.getXmlElementAttributeValue( "topology", "sockets" );
+ return Integer.parseInt( numSockets );
+ }
+
+ /**
+ * Returns the number of dies of the host CPU.
+ *
+ * @return number of dies of the host CPU.
+ */
+ public int getTopologyDies()
+ {
+ final String numDies = this.getXmlElementAttributeValue( "topology", "dies" );
+ return Integer.parseInt( numDies );
+ }
+
+ /**
+ * Returns the number of cores of the host CPU.
+ *
+ * @return number of cores of the host CPU.
+ */
+ public int getTopologyCores()
+ {
+ final String numCores = this.getXmlElementAttributeValue( "topology", "cores" );
+ return Integer.parseInt( numCores );
+ }
+
+ /**
+ * Returns the number of threads of the host CPU.
+ *
+ * @return number of threads of the host CPU.
+ */
+ public int getTopologyThreads()
+ {
+ final String numThreads = this.getXmlElementAttributeValue( "topology", "threads" );
+ return Integer.parseInt( numThreads );
+ }
+
+ /**
+ * Returns the supported features of the host CPU.
+ *
+ * @return supported features of the host CPU.
+ */
+ public List<Feature> getFeatures()
+ {
+ final List<Feature> featureList = new ArrayList<Feature>();
+ final NodeList featureNodes = this.getXmlNodes( "feature" );
+
+ for ( int i = 0; i < featureNodes.getLength(); i++ ) {
+ final LibvirtXmlNode featureNode = new LibvirtXmlNode( this.getXmlDocument(), featureNodes.item( i ) );
+ final Feature feature = Feature.newInstance( featureNode );
+
+ if ( feature != null ) {
+ featureList.add( feature );
+ }
+ }
+
+ return featureList;
+ }
+
+ /**
+ * Returns the supported memory pages of the host CPU.
+ *
+ * @return supported memory pages of the host CPU.
+ */
+ public List<Pages> getPages()
+ {
+ final List<Pages> pagesList = new ArrayList<Pages>();
+ final NodeList pagesNodes = this.getXmlNodes( "pages" );
+
+ for ( int i = 0; i < pagesNodes.getLength(); i++ ) {
+ final LibvirtXmlNode pagesNode = new LibvirtXmlNode( this.getXmlDocument(), pagesNodes.item( i ) );
+ final Pages pages = Pages.newInstance( pagesNode );
+
+ if ( pages != null ) {
+ pagesList.add( pages );
+ }
+ }
+
+ return pagesList;
+ }
+
+ /**
+ * Creates a host CPU capabilities instance representing an existing Libvirt XML host CPU
+ * capabilities element.
+ *
+ * @param xmlNode existing Libvirt XML host CPU capabilities element.
+ * @return host CPU capabilities instance.
+ */
+ public static Cpu newInstance( LibvirtXmlNode xmlNode )
+ {
+ return new Cpu( xmlNode );
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/capabilities/cpu/Feature.java b/src/main/java/org/openslx/libvirt/capabilities/cpu/Feature.java
new file mode 100644
index 0000000..96c77d5
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/capabilities/cpu/Feature.java
@@ -0,0 +1,51 @@
+package org.openslx.libvirt.capabilities.cpu;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+
+/**
+ * Implementation of a host CPU feature as part of the Libvirt capabilities XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class Feature extends LibvirtXmlNode
+{
+ /**
+ * Creates an empty host CPU feature instance.
+ */
+ public Feature()
+ {
+ super();
+ }
+
+ /**
+ * Creates an host CPU feature representing an existing Libvirt XML host CPU feature element.
+ *
+ * @param xmlNode existing Libvirt XML host CPU feature element.
+ */
+ public Feature( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Returns the name of the host CPU feature.
+ *
+ * @return name of the host CPU feature.
+ */
+ public String getName()
+ {
+ return this.getXmlElementAttributeValue( "name" );
+ }
+
+ /**
+ * Creates an host CPU feature representing an existing Libvirt XML host CPU feature element.
+ *
+ * @param xmlNode existing Libvirt XML host CPU feature element.
+ * @return host CPU feature instance.
+ */
+ public static Feature newInstance( LibvirtXmlNode xmlNode )
+ {
+ return new Feature( xmlNode );
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/capabilities/cpu/Pages.java b/src/main/java/org/openslx/libvirt/capabilities/cpu/Pages.java
new file mode 100644
index 0000000..eea5a36
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/capabilities/cpu/Pages.java
@@ -0,0 +1,60 @@
+package org.openslx.libvirt.capabilities.cpu;
+
+import java.math.BigInteger;
+
+import org.openslx.libvirt.domain.DomainUtils;
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+
+/**
+ * Implementation of a host CPU memory pages instance as part of the Libvirt capabilities XML
+ * document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class Pages extends LibvirtXmlNode
+{
+ /**
+ * Creates an empty host CPU memory pages instance.
+ */
+ public Pages()
+ {
+ super();
+ }
+
+ /**
+ * Creates a host CPU memory pages instance representing an existing Libvirt XML host CPU pages
+ * element.
+ *
+ * @param xmlNode existing Libvirt XML host CPU pages element.
+ */
+ public Pages( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Returns size of the memory pages instance.
+ *
+ * @return size of the memory pages instance.
+ */
+ public BigInteger getSize()
+ {
+ final String pagesValue = this.getXmlElementAttributeValue( "size" );
+ final String pagesUnit = this.getXmlElementAttributeValue( "unit" );
+
+ return DomainUtils.decodeMemory( pagesValue, pagesUnit );
+ }
+
+ /**
+ * Creates a host CPU memory pages instance representing an existing Libvirt XML host CPU pages
+ * element.
+ *
+ * @param xmlNode existing Libvirt XML host CPU pages element.
+ * @return host CPU memory pages instance.
+ */
+ public static Pages newInstance( LibvirtXmlNode xmlNode )
+ {
+ return new Pages( xmlNode );
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/capabilities/guest/Domain.java b/src/main/java/org/openslx/libvirt/capabilities/guest/Domain.java
new file mode 100644
index 0000000..8716064
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/capabilities/guest/Domain.java
@@ -0,0 +1,53 @@
+package org.openslx.libvirt.capabilities.guest;
+
+import org.openslx.libvirt.domain.Domain.Type;
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+
+/**
+ * Implementation of a guest domain as part of the Libvirt capabilities XML capabilities document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class Domain extends LibvirtXmlNode
+{
+ /**
+ * Creates an empty guest domain instance.
+ */
+ public Domain()
+ {
+ super();
+ }
+
+ /**
+ * Creates a guest domain representing an existing Libvirt XML guest domain element.
+ *
+ * @param xmlNode existing Libvirt XML guest domain element.
+ */
+ public Domain( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Returns the domain type of the guest domain.
+ *
+ * @return type of the guest domain.
+ */
+ public Type getType()
+ {
+ final String type = this.getXmlElementAttributeValue( "type" );
+ return Type.fromString( type );
+ }
+
+ /**
+ * Creates a guest domain representing an existing Libvirt XML guest domain element.
+ *
+ * @param xmlNode existing Libvirt XML guest domain element.
+ * @return guest domain instance.
+ */
+ public static Domain newInstance( LibvirtXmlNode xmlNode )
+ {
+ return new Domain( xmlNode );
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/capabilities/guest/Guest.java b/src/main/java/org/openslx/libvirt/capabilities/guest/Guest.java
new file mode 100644
index 0000000..2471180
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/capabilities/guest/Guest.java
@@ -0,0 +1,127 @@
+package org.openslx.libvirt.capabilities.guest;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openslx.libvirt.domain.Domain.OsType;
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+import org.w3c.dom.NodeList;
+
+/**
+ * Implementation of the guest capabilities as part of the Libvirt capabilities XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class Guest extends LibvirtXmlNode
+{
+ /**
+ * Creates an empty guest instance.
+ */
+ public Guest()
+ {
+ super();
+ }
+
+ /**
+ * Creates a guest representing an existing Libvirt XML guest capabilities element.
+ *
+ * @param xmlNode existing Libvirt XML guest capabilities element.
+ */
+ public Guest( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Return OS type of the guest.
+ *
+ * @return OS type of the guest.
+ */
+ public OsType getOsType()
+ {
+ final String osType = this.getXmlElementValue( "os_type" );
+ return OsType.fromString( osType );
+ }
+
+ /**
+ * Returns the architecture name of the guest.
+ *
+ * @return architecture name of the guest.
+ */
+ public String getArchName()
+ {
+ return this.getXmlElementAttributeValue( "arch", "name" );
+ }
+
+ /**
+ * Return word size of the guest's architecture.
+ *
+ * @return word size of the guest's architecture.
+ */
+ public int getArchWordSize()
+ {
+ final String archWordSize = this.getXmlElementValue( "arch/wordsize" );
+ return Integer.parseInt( archWordSize );
+ }
+
+ public String getArchEmulator()
+ {
+ return this.getXmlElementValue( "arch/emulator" );
+ }
+
+ /**
+ * Returns the available machines of the guest's architecture.
+ *
+ * @return available machines of the guest's architecture.
+ */
+ public List<Machine> getArchMachines()
+ {
+ final List<Machine> machinesList = new ArrayList<Machine>();
+ final NodeList machineNodes = this.getXmlNodes( "arch/machine" );
+
+ for ( int i = 0; i < machineNodes.getLength(); i++ ) {
+ final LibvirtXmlNode machineNode = new LibvirtXmlNode( this.getXmlDocument(), machineNodes.item( i ) );
+ final Machine machine = Machine.newInstance( machineNode );
+
+ if ( machine != null ) {
+ machinesList.add( machine );
+ }
+ }
+
+ return machinesList;
+ }
+
+ /**
+ * Returns the supported domains of the guest.
+ *
+ * @return supported domains of the guest.
+ */
+ public List<Domain> getArchDomains()
+ {
+ final List<Domain> domainList = new ArrayList<Domain>();
+ final NodeList domainNodes = this.getXmlNodes( "arch/domain" );
+
+ for ( int i = 0; i < domainNodes.getLength(); i++ ) {
+ final LibvirtXmlNode domainNode = new LibvirtXmlNode( this.getXmlDocument(), domainNodes.item( i ) );
+ final Domain domain = Domain.newInstance( domainNode );
+
+ if ( domain != null ) {
+ domainList.add( domain );
+ }
+ }
+
+ return domainList;
+ }
+
+ /**
+ * Creates a guest representing an existing Libvirt XML guest capabilities element.
+ *
+ * @param xmlNode existing Libvirt XML guest capabilities element.
+ * @return guest capabilities instance.
+ */
+ public static Guest newInstance( LibvirtXmlNode xmlNode )
+ {
+ return new Guest( xmlNode );
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/capabilities/guest/Machine.java b/src/main/java/org/openslx/libvirt/capabilities/guest/Machine.java
new file mode 100644
index 0000000..dfe6362
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/capabilities/guest/Machine.java
@@ -0,0 +1,72 @@
+package org.openslx.libvirt.capabilities.guest;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+
+/**
+ * Implementation of a guest machine as part of the Libvirt XML capabilities document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class Machine extends LibvirtXmlNode
+{
+ /**
+ * Creates an empty guest machine instance.
+ */
+ public Machine()
+ {
+ super();
+ }
+
+ /**
+ * Creates an guest machine representing an existing Libvirt XML guest machine element.
+ *
+ * @param xmlNode existing Libvirt XML guest machine element.
+ */
+ public Machine( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Returns the canonical machine name.
+ *
+ * @return canonical machine name.
+ */
+ public String getCanonicalMachine()
+ {
+ return this.getXmlElementAttributeValue( "canonical" );
+ }
+
+ /**
+ * Returns the maximum number of CPUs supported by the guest machine.
+ *
+ * @return maximum number of CPUs supported by the guest machine.
+ */
+ public int getMaxCpus()
+ {
+ final String numMaxCpus = this.getXmlElementAttributeValue( "maxCpus" );
+ return Integer.parseUnsignedInt( numMaxCpus );
+ }
+
+ /**
+ * Returns the name of the guest machine.
+ *
+ * @return name of the guest machine.
+ */
+ public String getName()
+ {
+ return this.getXmlElementValue( null );
+ }
+
+ /**
+ * Creates an guest machine representing an existing Libvirt XML guest machine element.
+ *
+ * @param xmlNode existing Libvirt XML guest machine element.
+ * @return guest machine instance.
+ */
+ public static Machine newInstance( LibvirtXmlNode xmlNode )
+ {
+ return new Machine( xmlNode );
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/Domain.java b/src/main/java/org/openslx/libvirt/domain/Domain.java
new file mode 100644
index 0000000..c19b2a3
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/Domain.java
@@ -0,0 +1,1743 @@
+package org.openslx.libvirt.domain;
+
+import java.io.File;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import javax.xml.XMLConstants;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+
+import org.openslx.libvirt.domain.device.Controller;
+import org.openslx.libvirt.domain.device.ControllerFloppy;
+import org.openslx.libvirt.domain.device.ControllerIde;
+import org.openslx.libvirt.domain.device.ControllerPci;
+import org.openslx.libvirt.domain.device.ControllerSata;
+import org.openslx.libvirt.domain.device.ControllerScsi;
+import org.openslx.libvirt.domain.device.ControllerUsb;
+import org.openslx.libvirt.domain.device.Device;
+import org.openslx.libvirt.domain.device.Disk;
+import org.openslx.libvirt.domain.device.DiskCdrom;
+import org.openslx.libvirt.domain.device.DiskFloppy;
+import org.openslx.libvirt.domain.device.DiskStorage;
+import org.openslx.libvirt.domain.device.FileSystem;
+import org.openslx.libvirt.domain.device.Graphics;
+import org.openslx.libvirt.domain.device.GraphicsSpice;
+import org.openslx.libvirt.domain.device.GraphicsVnc;
+import org.openslx.libvirt.domain.device.Hostdev;
+import org.openslx.libvirt.domain.device.HostdevMdev;
+import org.openslx.libvirt.domain.device.HostdevPci;
+import org.openslx.libvirt.domain.device.HostdevUsb;
+import org.openslx.libvirt.domain.device.Interface;
+import org.openslx.libvirt.domain.device.InterfaceBridge;
+import org.openslx.libvirt.domain.device.InterfaceNetwork;
+import org.openslx.libvirt.domain.device.Parallel;
+import org.openslx.libvirt.domain.device.Serial;
+import org.openslx.libvirt.domain.device.Shmem;
+import org.openslx.libvirt.domain.device.Sound;
+import org.openslx.libvirt.domain.device.Video;
+import org.openslx.libvirt.xml.LibvirtXmlDocument;
+import org.openslx.libvirt.xml.LibvirtXmlDocumentException;
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+import org.openslx.libvirt.xml.LibvirtXmlResources;
+import org.openslx.libvirt.xml.LibvirtXmlSerializationException;
+import org.openslx.libvirt.xml.LibvirtXmlValidationException;
+import org.openslx.util.XmlHelper;
+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;
+
+/**
+ * Implementation of the Libvirt domain XML document.
+ *
+ * The Libvirt domain XML document is used to describe virtual machines and their configurations.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class Domain extends LibvirtXmlDocument
+{
+ /**
+ * XML namespace URI for QEMU command line elements in the Libvirt domain XML document.
+ */
+ private static final String XMLNS_QEMU_NS_URI = "http://libvirt.org/schemas/domain/qemu/1.0";
+
+ /**
+ * XML namespace prefix for QEMU command line elements in the Libvirt domain XML document.
+ */
+ private static final String XMLNS_QEMU_NS_PREFIX = "qemu";
+
+ /**
+ * Creates Libvirt domain XML document from {@link String} providing Libvirt domain XML content.
+ *
+ * @param xml {@link String} with Libvirt domain XML content.
+ *
+ * @throws LibvirtXmlDocumentException creation of XML context failed.
+ * @throws LibvirtXmlSerializationException serialization of the domain XML content failed.
+ * @throws LibvirtXmlValidationException XML content is not a valid domain XML document.
+ */
+ public Domain( String xml )
+ throws LibvirtXmlDocumentException, LibvirtXmlSerializationException, LibvirtXmlValidationException
+ {
+ super( xml, LibvirtXmlResources.getLibvirtRng( "domain.rng" ) );
+ this.assertDomainType();
+ }
+
+ /**
+ * Creates Libvirt domain XML document from {@link File} containing Libvirt domain XML content.
+ *
+ * @param xml existing {@link File} containing Libvirt domain XML content.
+ *
+ * @throws LibvirtXmlDocumentException creation of XML context failed.
+ * @throws LibvirtXmlSerializationException serialization of the domain XML content failed.
+ * @throws LibvirtXmlValidationException XML content is not a valid domain XML document.
+ */
+ public Domain( File xml )
+ throws LibvirtXmlDocumentException, LibvirtXmlSerializationException, LibvirtXmlValidationException
+ {
+ super( xml, LibvirtXmlResources.getLibvirtRng( "domain.rng" ) );
+ this.assertDomainType();
+ }
+
+ /**
+ * Creates Libvirt domain XML document from {@link InputStream} providing Libvirt domain XML
+ * content.
+ *
+ * @param xml {@link InputStream} providing Libvirt domain XML content.
+ *
+ * @throws LibvirtXmlDocumentException creation of XML context failed.
+ * @throws LibvirtXmlSerializationException serialization of the domain XML content failed.
+ * @throws LibvirtXmlValidationException XML content is not a valid domain XML document.
+ */
+ public Domain( InputStream xml )
+ throws LibvirtXmlDocumentException, LibvirtXmlSerializationException, LibvirtXmlValidationException
+ {
+ super( xml, LibvirtXmlResources.getLibvirtRng( "domain.rng" ) );
+ this.assertDomainType();
+ }
+
+ /**
+ * Creates Libvirt domain XML document from {@link InputSource} providing Libvirt domain XML
+ * content.
+ *
+ * @param xml {@link InputSource} providing Libvirt domain XML content.
+ *
+ * @throws LibvirtXmlDocumentException creation of XML context failed.
+ * @throws LibvirtXmlSerializationException serialization of the domain XML content failed.
+ * @throws LibvirtXmlValidationException XML content is not a valid domain XML document.
+ */
+ public Domain( InputSource xml )
+ throws LibvirtXmlDocumentException, LibvirtXmlSerializationException, LibvirtXmlValidationException
+ {
+ super( xml, LibvirtXmlResources.getLibvirtRng( "domain.rng" ) );
+ this.assertDomainType();
+ }
+
+ /**
+ * Quick sanity check whether this could be a libvirt domain file at all.
+ * We just check if the root node is called domain and has the attribute type.
+ *
+ * @throws LibvirtXmlValidationException If this is not met.
+ */
+ private void assertDomainType() throws LibvirtXmlValidationException
+ {
+ try {
+ XPathExpression expr = XmlHelper.compileXPath( "/domain[@type]" );
+ Object nodesObject = expr.evaluate( this.getRootXmlNode().getXmlDocument(), XPathConstants.NODESET );
+ NodeList nodes = (NodeList)nodesObject;
+ if ( nodes.getLength() == 0 )
+ throw new LibvirtXmlValidationException( "Root element isn't <domain type=...>" );
+ } catch ( XPathExpressionException e ) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Types of hypervisors specifiable for a virtual machine in the Libvirt domain XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+ public enum Type
+ {
+ // @formatter:off
+ QEMU ( "qemu" ),
+ KQEMU ( "kqemu" ),
+ KVM ( "kvm" ),
+ XEN ( "xen" ),
+ LXC ( "lxc" ),
+ UML ( "uml" ),
+ OPENVZ( "openvz" ),
+ TEST ( "test" ),
+ VMWARE( "vmware" ),
+ HYPERV( "hyperv" ),
+ VBOX ( "vbox" ),
+ PHYP ( "phyp" ),
+ VZ ( "vz" ),
+ BHYVE ( "bhyve" );
+ // @formatter:on
+
+ /**
+ * Name of the hypervisor in a Libvirt domain XML document.
+ */
+ private String type;
+
+ /**
+ * Creates a hypervisor type.
+ *
+ * @param type valid name of the hypervisor in a Libvirt domain XML document.
+ */
+ Type( String type )
+ {
+ this.type = type;
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.type;
+ }
+
+ /**
+ * Creates a hypervisor type from its name with error check.
+ *
+ * @param type name of the hypervisor in the Libvirt domain XML document.
+ * @return valid hypervisor type.
+ */
+ public static Type fromString( String type )
+ {
+ for ( Type t : Type.values() ) {
+ if ( t.type.equalsIgnoreCase( type ) ) {
+ return t;
+ }
+ }
+
+ return null;
+ }
+ }
+
+ /**
+ * Returns hypervisor type defined in the Libvirt domain XML document.
+ *
+ * @return hypervisor type.
+ */
+ public Type getType()
+ {
+ String typeValue = this.getRootXmlNode().getXmlElementAttributeValue( null, "type" );
+ return Type.fromString( typeValue );
+ }
+
+ /**
+ * Sets hypervisor type in Libvirt domain XML document.
+ *
+ * @param type hypervisor type for Libvirt domain XML document.
+ */
+ public void setType( Type type )
+ {
+ this.getRootXmlNode().setXmlElementAttributeValue( null, "type", type.toString() );
+ }
+
+ /**
+ * Returns virtual machine name defined in the Libvirt domain XML document.
+ *
+ * @return name of the virtual machine.
+ */
+ public String getName()
+ {
+ return this.getRootXmlNode().getXmlElementValue( "name" );
+ }
+
+ /**
+ * Sets virtual machine name in the Libvirt domain XML document.
+ *
+ * @param name virtual machine name for Libvirt domain XML document.
+ */
+ public void setName( String name )
+ {
+ this.getRootXmlNode().setXmlElementValue( "name", name );
+ }
+
+ /**
+ * Returns virtual machine title defined in the Libvirt domain XML document.
+ *
+ * @return title of the virtual machine.
+ */
+ public String getTitle()
+ {
+ return this.getRootXmlNode().getXmlElementValue( "title" );
+ }
+
+ /**
+ * Sets virtual machine title in the Libvirt domain XML document.
+ *
+ * @param title virtual machine title for Libvirt domain XML document.
+ */
+ public void setTitle( String title )
+ {
+ this.getRootXmlNode().setXmlElementValue( "title", title );
+ }
+
+ /**
+ * Returns virtual machine description defined in the Libvirt domain XML document.
+ *
+ * @return description of virtual machine.
+ */
+ public String getDescription()
+ {
+ return this.getRootXmlNode().getXmlElementValue( "description" );
+ }
+
+ /**
+ * Sets virtual machine description in the Libvirt domain XML document.
+ *
+ * @param description virtual machine description for Libvirt domain XML document.
+ */
+ public void setDescription( String description )
+ {
+ this.getRootXmlNode().setXmlElementValue( "description", description );
+ }
+
+ /**
+ * Returns the libosinfo operating system identifier.
+ *
+ * @return libosinfo operating system identifier.
+ */
+ public String getLibOsInfoOsId()
+ {
+ return this.getRootXmlNode()
+ .getXmlElementAttributeValue( "metadata/*[local-name()='libosinfo']/*[local-name()='os']", "id" );
+ }
+
+ /**
+ * Returns the state of the Hyper-V vendor identifier feature.
+ *
+ * @return state of the Hyper-V vendor identifier feature.
+ */
+ public boolean isFeatureHypervVendorIdStateOn()
+ {
+ return this.getRootXmlNode().getXmlElementAttributeValueAsBool( "features/hyperv/vendor_id", "state" );
+ }
+
+ /**
+ * Sets the state of the Hyper-V vendor identifier feature.
+ *
+ * @param on state for the Hyper-V vendor identifier feature.
+ */
+ public void setFeatureHypervVendorIdState( boolean on )
+ {
+ this.getRootXmlNode().setXmlElementAttributeValueOnOff( "features/hyperv/vendor_id", "state", on );
+ }
+
+ /**
+ * Returns the value of the Hyper-V vendor identifier feature.
+ *
+ * @return value of the Hyper-V vendor identifier feature.
+ */
+ public String getFeatureHypervVendorIdValue()
+ {
+ return this.getRootXmlNode().getXmlElementAttributeValue( "features/hyperv/vendor_id", "value" );
+ }
+
+ /**
+ * Sets the value of the Hyper-V vendor identifier feature.
+ *
+ * @param value value for the Hyper-V vendor identifier feature.
+ */
+ public void setFeatureHypervVendorIdValue( String value )
+ {
+ this.getRootXmlNode().setXmlElementAttributeValue( "features/hyperv/vendor_id", "value", value );
+ }
+
+ /**
+ * Returns the state of the KVM hidden feature.
+ *
+ * @return state of the KVM hidden feature.
+ */
+ public boolean isFeatureKvmHiddenStateOn()
+ {
+ return this.getRootXmlNode().getXmlElementAttributeValueAsBool( "features/kvm/hidden", "state" );
+ }
+
+ /**
+ * Sets the state of the KVM hidden feature.
+ *
+ * @param on state for the KVM hidden feature.
+ */
+ public void setFeatureKvmHiddenState( boolean on )
+ {
+ this.getRootXmlNode().setXmlElementAttributeValueOnOff( "features/kvm/hidden", "state", on );
+ this.getRootXmlNode().setXmlElement( "cpu" );
+ if ( on ) {
+ Element cpu = this.getRootXmlNode().getXmlElement( "cpu" );
+ XmlHelper.getOrCreateElement( this.getRootXmlNode().getXmlDocument(), cpu,
+ null, null,
+ "feature", "name", "hypervisor" );
+ this.getRootXmlNode().setXmlElementAttributeValue( "cpu/feature", "policy", "disable" );
+ } else {
+ this.getRootXmlNode().removeXmlElement( "cpu/feature[@name='hypervisor']" );
+ }
+ }
+
+ /**
+ * Returns virtual machine UUID defined in the Libvirt domain XML document.
+ *
+ * @return UUID of virtual machine.
+ */
+ public String getUuid()
+ {
+ return this.getRootXmlNode().getXmlElementValue( "uuid" );
+ }
+
+ /**
+ * Sets virtual machine UUID in the Libvirt domain XML document.
+ *
+ * @param uuid virtual machine UUID for Libvirt domain XML document.
+ */
+ public void setUuid( String uuid )
+ {
+ this.getRootXmlNode().setXmlElementValue( "uuid", uuid );
+ }
+
+ /**
+ * Removes virtual machine UUID in the Libvirt domain XML document.
+ */
+ public void removeUuid()
+ {
+ this.getRootXmlNode().removeXmlElement( "uuid" );
+ }
+
+ /**
+ * Returns virtual machine memory defined in the Libvirt domain XML document.
+ *
+ * @return memory of virtual machine.
+ */
+ public BigInteger getMemory()
+ {
+ String memValue = this.getRootXmlNode().getXmlElementValue( "memory" );
+ String memUnit = this.getRootXmlNode().getXmlElementAttributeValue( "memory", "unit" );
+ return DomainUtils.decodeMemory( memValue, memUnit );
+ }
+
+ /**
+ * Sets virtual machine memory in the Libvirt domain XML document.
+ *
+ * @param memory virtual machine memory in the Libvirt domain XML document.
+ */
+ public void setMemory( BigInteger memory )
+ {
+ this.getRootXmlNode().setXmlElementAttributeValue( "memory", "unit", "KiB" );
+ this.getRootXmlNode().setXmlElementValue( "memory", DomainUtils.encodeMemory( memory, "KiB" ) );
+ }
+
+ /**
+ * Returns current virtual machine memory defined in the Libvirt domain XML document.
+ *
+ * @return current memory of virtual machine.
+ */
+ public BigInteger getCurrentMemory()
+ {
+ String memValue = this.getRootXmlNode().getXmlElementValue( "currentMemory" );
+ String memUnit = this.getRootXmlNode().getXmlElementAttributeValue( "currentMemory", "unit" );
+ return DomainUtils.decodeMemory( memValue, memUnit );
+ }
+
+ /**
+ * Set current virtual machine memory in the Libvirt domain XML document.
+ *
+ * @param currentMemory current virtual machine memory in the Libvirt domain XML document.
+ */
+ public void setCurrentMemory( BigInteger currentMemory )
+ {
+ this.getRootXmlNode().setXmlElementAttributeValue( "currentMemory", "unit", "KiB" );
+ this.getRootXmlNode().setXmlElementValue( "currentMemory", DomainUtils.encodeMemory( currentMemory, "KiB" ) );
+ }
+
+ /**
+ * Returns number of virtual machine CPUs defined in the Libvirt domain XML document.
+ *
+ * @return number of CPUs of the virtual machine.
+ */
+ public int getVCpu()
+ {
+ String number = this.getRootXmlNode().getXmlElementValue( "vcpu" );
+ return Integer.parseUnsignedInt( number );
+ }
+
+ /**
+ * Set number of virtual machine CPUs in the Libvirt domain XML document.
+ *
+ * @param number virtual machine CPUs.
+ */
+ public void setVCpu( int number )
+ {
+ this.getRootXmlNode().setXmlElementValue( "vcpu", Integer.toString( number ) );
+ }
+
+ /**
+ * Returns OS type defined in the Libvirt domain XML document.
+ *
+ * @return OS type of the virtual machine.
+ */
+ public OsType getOsType()
+ {
+ final String osType = this.getRootXmlNode().getXmlElementValue( "os/type" );
+ return OsType.fromString( osType );
+ }
+
+ /**
+ * Set OS type in the Libvirt domain XML document.
+ *
+ * @param type OS type for the virtual machine.
+ */
+ public void setOsType( OsType type )
+ {
+ this.getRootXmlNode().setXmlElementValue( "os/type", type.toString() );
+ }
+
+ /**
+ * Returns OS architecture defined in the Libvirt domain XML document.
+ *
+ * @return OS architecture of the virtual machine.
+ */
+ public String getOsArch()
+ {
+ return this.getRootXmlNode().getXmlElementAttributeValue( "os/type", "arch" );
+ }
+
+ /**
+ * Set OS architecture in the Libvirt domain XML document.
+ *
+ * @param arch OS architecture for the virtual machine.
+ */
+ public void setOsArch( String arch )
+ {
+ this.getRootXmlNode().setXmlElementAttributeValue( "os/type", "arch", arch );
+ }
+
+ /**
+ * Returns OS machine defined in the Libvirt domain XML document.
+ *
+ * @return OS machine of the virtual machine.
+ */
+ public String getOsMachine()
+ {
+ return this.getRootXmlNode().getXmlElementAttributeValue( "os/type", "machine" );
+ }
+
+ /**
+ * Set OS machine in the Libvirt domain XML document.
+ *
+ * @param machine OS machine for the virtual machine.
+ */
+ public void setOsMachine( String machine )
+ {
+ this.getRootXmlNode().setXmlElementAttributeValue( "os/type", "machine", machine );
+ }
+
+ /**
+ * Returns OS loader defined in the Libvirt domain XML document.
+ *
+ * @return OS loader of the virtual machine.
+ */
+ public String getOsLoader()
+ {
+ return this.getRootXmlNode().getXmlElementValue( "os/loader" );
+ }
+
+ /**
+ * Set OS loader in the Libvirt domain XML document.
+ *
+ * @param loader OS loader for the virtual machine.
+ */
+ public void setOsLoader( String loader )
+ {
+ this.getRootXmlNode().setXmlElementValue( "os/loader", loader );
+ }
+
+ /**
+ * Returns OS Nvram defined in the Libvirt domain XML document.
+ *
+ * @return OS Nvram of the virtual machine.
+ */
+ public String getOsNvram()
+ {
+ return this.getRootXmlNode().getXmlElementValue( "os/nvram" );
+ }
+
+ /**
+ * Set OS Nvram in the Libvirt domain XML document.
+ *
+ * @param nvram OS Nvram for the virtual machine.
+ */
+ public void setOsNvram( String nvram )
+ {
+ this.getRootXmlNode().setXmlElementValue( "os/nvram", nvram );
+ }
+
+ /**
+ * Operating system types specifiable for a virtual machine in the Libvirt domain XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+ public enum OsType
+ {
+ // @formatter:off
+ XEN ( "xen" ),
+ LINUX( "linux" ),
+ HVM ( "hvm" ),
+ EXE ( "exe" ),
+ UML ( "uml" );
+ // @formatter:on
+
+ /**
+ * Name of the OS type in a Libvirt domain XML document.
+ */
+ private final String osType;
+
+ /**
+ * Creates an OS type.
+ *
+ * @param osType valid name of the OS type in the Libvirt domain XML document.
+ */
+ OsType( String osType )
+ {
+ this.osType = osType;
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.osType;
+ }
+
+ /**
+ * Creates an OS type from its name with error check.
+ *
+ * @param osType name of the OS type in the Libvirt domain XML document.
+ * @return valid OS type.
+ */
+ public static OsType fromString( String osType )
+ {
+ for ( OsType t : OsType.values() ) {
+ if ( t.osType.equalsIgnoreCase( osType ) ) {
+ return t;
+ }
+ }
+
+ return null;
+ }
+ }
+
+ /**
+ * Returns virtual machine CPU model defined in the Libvirt domain XML document.
+ *
+ * @return CPU model of virtual machine.
+ */
+ public String getCpuModel()
+ {
+ return this.getRootXmlNode().getXmlElementValue( "cpu/model" );
+ }
+
+ /**
+ * Sets virtual machine CPU model in the Libvirt domain XML document.
+ *
+ * @param model virtual machine CPU model.
+ */
+ public void setCpuModel( String model )
+ {
+ this.getRootXmlNode().setXmlElementValue( "cpu/model", model );
+ }
+
+ /**
+ * CPU modes specifiable for a virtual machine in the Libvirt domain XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+ public enum CpuMode
+ {
+ // @formatter:off
+ CUSTOM ( "custom" ),
+ HOST_MODEL ( "host-model" ),
+ HOST_PASSTHROUGH( "host-passthrough" );
+ // @formatter:on
+
+ /**
+ * Name of the CPU mode in a Libvirt domain XML document.
+ */
+ private String cpuMode;
+
+ /**
+ * Creates a CPU mode.
+ *
+ * @param mode valid name of the CPU mode in the Libvirt domain XML document.
+ */
+ CpuMode( String mode )
+ {
+ this.cpuMode = mode;
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.cpuMode;
+ }
+
+ /**
+ * Creates a CPU mode from its name with error check.
+ *
+ * @param mode name of the CPU mode in the Libvirt domain XML document.
+ * @return valid CPU mode.
+ */
+ public static CpuMode fromString( String mode )
+ {
+ for ( CpuMode t : CpuMode.values() ) {
+ if ( t.cpuMode.equalsIgnoreCase( mode ) ) {
+ return t;
+ }
+ }
+
+ return null;
+ }
+ }
+
+ /**
+ * Returns virtual machine CPU mode defined in the Libvirt domain XML document.
+ *
+ * @return CPU mode of the virtual machine.
+ */
+ public CpuMode getCpuMode()
+ {
+ String cpuMode = this.getRootXmlNode().getXmlElementAttributeValue( "cpu", "mode" );
+ return CpuMode.fromString( cpuMode );
+ }
+
+ /**
+ * Sets virtual machine CPU mode in the Libvirt domain XML document.
+ *
+ * @param mode virtual machine CPU mode.
+ */
+ public void setCpuMode( CpuMode mode )
+ {
+ this.getRootXmlNode().setXmlElementAttributeValue( "cpu", "mode", mode.toString() );
+ // Pass through cache information as well, because for some reason this is no the default
+ // when we do CPU host passthrough....
+ if ( mode == CpuMode.HOST_PASSTHROUGH ) {
+ this.getRootXmlNode().setXmlElementAttributeValue( "cpu/cache", "mode", "passthrough" );
+ } else if ( "passthrough".equals( this.getRootXmlNode().getXmlElementAttributeValue( "cpu/cache", "mode" ) ) ) {
+ this.getRootXmlNode().removeXmlElement( "cpu/cache" );
+ }
+ }
+
+ /**
+ * Returns if the CPU migratable flag is set in the Libvirt domain XML document.
+ */
+ public boolean getCpuMigratable()
+ {
+ return this.getRootXmlNode().getXmlElementAttributeValueAsBool( "cpu", "migratable" );
+ }
+
+ /**
+ * Sets if vCPU is migratable in the Libvirt domain XML document.
+ */
+ public void setCpuMigratable( boolean migratable )
+ {
+ this.getRootXmlNode().setXmlElementAttributeValueOnOff( "cpu", "migratable", migratable );
+ }
+
+ /**
+ * CPU checks specifiable for a virtual machine in the Libvirt domain XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+ public enum CpuCheck
+ {
+ // @formatter:off
+ NONE ( "none" ),
+ PARTIAL( "partial" ),
+ FULL ( "full" );
+ // @formatter:on
+
+ /**
+ * Name of the CPU check in the Libvirt domain XML document.
+ */
+ private String cpuCheck;
+
+ /**
+ * Creates a CPU check.
+ *
+ * @param check valid name of the CPU check in the Libvirt domain XML document.
+ */
+ CpuCheck( String check )
+ {
+ this.cpuCheck = check;
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.cpuCheck;
+ }
+
+ /**
+ * Creates a CPU check from its name with error check.
+ *
+ * @param check name of the CPU check in the Libvirt domain XML document.
+ * @return valid CPU check.
+ */
+ public static CpuCheck fromString( String check )
+ {
+ for ( CpuCheck t : CpuCheck.values() ) {
+ if ( t.cpuCheck.equalsIgnoreCase( check ) ) {
+ return t;
+ }
+ }
+
+ return null;
+ }
+ }
+
+ /**
+ * Returns virtual machine CPU check defined in the Libvirt domain XML document.
+ *
+ * @return CPU check of the virtual machine.
+ */
+ public CpuCheck getCpuCheck()
+ {
+ String cpuCheck = this.getRootXmlNode().getXmlElementAttributeValue( "cpu", "check" );
+ return CpuCheck.fromString( cpuCheck );
+ }
+
+ /**
+ * Sets virtual machine CPU check in the Libvirt domain XML document.
+ *
+ * @param check virtual machine CPU check.
+ */
+ public void setCpuCheck( CpuCheck check )
+ {
+ this.getRootXmlNode().setXmlElementAttributeValue( "cpu", "check", check.toString() );
+ }
+
+ /**
+ * Returns the number of virtual machine CPU dies defined in the Libvirt domain XML document.
+ *
+ * @return number of virtual machine CPU dies.
+ */
+ public int getCpuDies()
+ {
+ final String numDies = this.getRootXmlNode().getXmlElementAttributeValue( "cpu/topology", "dies" );
+ return Integer.valueOf( numDies );
+ }
+
+ /**
+ * Set number of virtual machine CPU dies in the Libvirt domain XML document.
+ *
+ * @param number virtual machine CPU dies.
+ */
+ public void setCpuDies( int number )
+ {
+ this.getRootXmlNode().setXmlElementAttributeValue( "cpu/topology", "dies", Integer.toString( number ) );
+ }
+
+ /**
+ * Returns the number of virtual machine CPU sockets defined in the Libvirt domain XML document.
+ *
+ * @return number of virtual machine CPU sockets.
+ */
+ public int getCpuSockets()
+ {
+ final String numSockets = this.getRootXmlNode().getXmlElementAttributeValue( "cpu/topology", "sockets" );
+ return Integer.valueOf( numSockets );
+ }
+
+ /**
+ * Set number of virtual machine CPU dies in the Libvirt domain XML document.
+ *
+ * @param number virtual machine CPU dies.
+ */
+ public void setCpuSockets( int number )
+ {
+ this.getRootXmlNode().setXmlElementAttributeValue( "cpu/topology", "sockets", Integer.toString( number ) );
+ }
+
+ /**
+ * Returns the number of virtual machine CPU cores defined in the Libvirt domain XML document.
+ *
+ * @return number of virtual machine CPU cores.
+ */
+ public int getCpuCores()
+ {
+ final String numCores = this.getRootXmlNode().getXmlElementAttributeValue( "cpu/topology", "cores" );
+ return Integer.valueOf( numCores );
+ }
+
+ /**
+ * Set number of virtual machine CPU cores in the Libvirt domain XML document.
+ *
+ * @param number virtual machine CPU cores.
+ */
+ public void setCpuCores( int number )
+ {
+ this.getRootXmlNode().setXmlElementAttributeValue( "cpu/topology", "cores", Integer.toString( number ) );
+ }
+
+ /**
+ * Returns the number of virtual machine CPU threads defined in the Libvirt domain XML document.
+ *
+ * @return number of virtual machine CPU threads.
+ */
+ public int getCpuThreads()
+ {
+ final String numThreads = this.getRootXmlNode().getXmlElementAttributeValue( "cpu/topology", "threads" );
+ return Integer.valueOf( numThreads );
+ }
+
+ /**
+ * Set number of virtual machine CPU threads in the Libvirt domain XML document.
+ *
+ * @param number virtual machine CPU threads.
+ */
+ public void setCpuThreads( int number )
+ {
+ this.getRootXmlNode().setXmlElementAttributeValue( "cpu/topology", "threads", Integer.toString( number ) );
+ }
+
+ /**
+ * Returns the file name of the emulator binary defined in the Libvirt domain XML document.
+ *
+ * @return file name of the emulator binary.
+ */
+ public String getDevicesEmulator()
+ {
+ return this.getRootXmlNode().getXmlElementValue( "devices/emulator" );
+ }
+
+ /**
+ * Sets the file name of the emulator binary in the Libvirt domain XML document.
+ *
+ * @param emulator file name of the emulator binary.
+ */
+ public void setDevicesEmulator( String emulator )
+ {
+ this.getRootXmlNode().setXmlElementValue( "devices/emulator", emulator );
+ }
+
+ /**
+ * Returns virtual machine devices defined in the Libvirt domain XML document.
+ *
+ * @return devices of the virtual machine.
+ */
+ public ArrayList<Device> getDevices()
+ {
+ ArrayList<Device> devices = new ArrayList<Device>();
+ Node devicesNode = this.getRootXmlNode().getXmlElement( "devices" );
+
+ if ( devicesNode != null ) {
+
+ NodeList devicesElements = devicesNode.getChildNodes();
+
+ for ( int i = 0; i < devicesElements.getLength(); i++ ) {
+ final Node childNode = devicesElements.item( i );
+ if ( childNode.getNodeType() == Node.ELEMENT_NODE ) {
+ LibvirtXmlNode deviceNode = new LibvirtXmlNode( this.getRootXmlNode().getXmlDocument(), childNode );
+ Device device = Device.newInstance( deviceNode );
+
+ if ( device != null ) {
+ devices.add( device );
+ }
+ }
+ }
+ }
+
+ return devices;
+ }
+
+ /**
+ * Filter list of virtual machine devices of type {@link Device} and cast filtered instances to
+ * more specific device type <code>R</code>.
+ *
+ * @param <R> specific device type for filtering and casting.
+ * @param cls specific device type's class.
+ * @param devices list of virtual machines devices.
+ * @return filtered list of virtual machines devices of type <code>R</code>.
+ */
+ private static <R> ArrayList<R> filterDevices( Class<R> cls, ArrayList<Device> devices )
+ {
+ Predicate<Device> byFilter = device -> cls.isInstance( device );
+ Function<Device, R> castFunction = device -> cls.cast( device );
+
+ return devices.stream().filter( byFilter ).map( castFunction )
+ .collect( Collectors.toCollection( ArrayList::new ) );
+ }
+
+ /**
+ * Returns list of virtual machine controller devices specified in the Libvirt domain XML
+ * document.
+ *
+ * @return list of virtual machine controller devices.
+ */
+ public ArrayList<Controller> getControllerDevices()
+ {
+ return Domain.filterDevices( Controller.class, this.getDevices() );
+ }
+
+ /**
+ * Returns list of virtual machine floppy controller devices specified in the Libvirt domain XML
+ * document.
+ *
+ * @return list of virtual machine floppy controller devices.
+ */
+ public ArrayList<ControllerFloppy> getFloppyControllerDevices()
+ {
+ return Domain.filterDevices( ControllerFloppy.class, this.getDevices() );
+ }
+
+ /**
+ * Returns list of virtual machine IDE controller devices specified in the Libvirt domain XML
+ * document.
+ *
+ * @return list of virtual machine IDE controller devices.
+ */
+ public ArrayList<ControllerIde> getIdeControllerDevices()
+ {
+ return Domain.filterDevices( ControllerIde.class, this.getDevices() );
+ }
+
+ /**
+ * Returns list of virtual machine floppy controller devices specified in the Libvirt domain XML
+ * document.
+ *
+ * @return list of virtual machine floppy controller devices.
+ */
+ public ArrayList<ControllerPci> getPciControllerDevices()
+ {
+ return Domain.filterDevices( ControllerPci.class, this.getDevices() );
+ }
+
+ /**
+ * Returns list of virtual machine SATA controller devices specified in the Libvirt domain XML
+ * document.
+ *
+ * @return list of virtual machine SATA controller devices.
+ */
+ public ArrayList<ControllerSata> getSataControllerDevices()
+ {
+ return Domain.filterDevices( ControllerSata.class, this.getDevices() );
+ }
+
+ /**
+ * Returns list of virtual machine SCSI controller devices specified in the Libvirt domain XML
+ * document.
+ *
+ * @return list of virtual machine SCSI controller devices.
+ */
+ public ArrayList<ControllerScsi> getScsiControllerDevices()
+ {
+ return Domain.filterDevices( ControllerScsi.class, this.getDevices() );
+ }
+
+ /**
+ * Returns list of virtual machine USB controller devices specified in the Libvirt domain XML
+ * document.
+ *
+ * @return list of virtual machine USB controller devices.
+ */
+ public ArrayList<ControllerUsb> getUsbControllerDevices()
+ {
+ return Domain.filterDevices( ControllerUsb.class, this.getDevices() );
+ }
+
+ /**
+ * Returns list of virtual machine disk devices specified in the Libvirt domain XML document.
+ *
+ * @return list of virtual machine disk devices.
+ */
+ public ArrayList<Disk> getDiskDevices()
+ {
+ return Domain.filterDevices( Disk.class, this.getDevices() );
+ }
+
+ /**
+ * Returns list of virtual machine disk CDROM devices specified in the Libvirt domain XML
+ * document.
+ *
+ * @return list of virtual machine disk CDROM devices.
+ */
+ public ArrayList<DiskCdrom> getDiskCdromDevices()
+ {
+ return Domain.filterDevices( DiskCdrom.class, this.getDevices() );
+ }
+
+ /**
+ * Returns list of virtual machine disk floppy devices specified in the Libvirt domain XML
+ * document.
+ *
+ * @return list of virtual machine disk floppy devices.
+ */
+ public ArrayList<DiskFloppy> getDiskFloppyDevices()
+ {
+ return Domain.filterDevices( DiskFloppy.class, this.getDevices() );
+ }
+
+ /**
+ * Returns list of virtual machine disk storage devices specified in the Libvirt domain XML
+ * document.
+ *
+ * @return list of virtual machine disk storage devices.
+ */
+ public ArrayList<DiskStorage> getDiskStorageDevices()
+ {
+ return Domain.filterDevices( DiskStorage.class, this.getDevices() );
+ }
+
+ /**
+ * Returns list of virtual machine file system devices specified in the Libvirt domain XML
+ * document.
+ *
+ * @return list of virtual machine file system devices.
+ */
+ public ArrayList<FileSystem> getFileSystemDevices()
+ {
+ return Domain.filterDevices( FileSystem.class, this.getDevices() );
+ }
+
+ /**
+ * Returns list of virtual machine hostdev devices specified in the Libvirt domain XML document.
+ *
+ * @return list of virtual machine hostdev devices.
+ */
+ public ArrayList<Hostdev> getHostdevDevices()
+ {
+ return Domain.filterDevices( Hostdev.class, this.getDevices() );
+ }
+
+ /**
+ * Returns list of virtual machine mediated hostdev devices specified in the Libvirt domain XML
+ * document.
+ *
+ * @return list of virtual machine mediated hostdev devices.
+ */
+ public ArrayList<HostdevMdev> getHostdevMdevDevices()
+ {
+ return Domain.filterDevices( HostdevMdev.class, this.getDevices() );
+ }
+
+ /**
+ * Returns list of virtual machine PCI hostdev devices specified in the Libvirt domain XML
+ * document.
+ *
+ * @return list of virtual machine PCI hostdev devices.
+ */
+ public ArrayList<HostdevPci> getHostdevPciDevices()
+ {
+ return Domain.filterDevices( HostdevPci.class, this.getDevices() );
+ }
+
+ /**
+ * Returns list of virtual machine USB hostdev devices specified in the Libvirt domain XML
+ * document.
+ *
+ * @return list of virtual machine USB hostdev devices.
+ */
+ public ArrayList<HostdevUsb> getHostdevUsbDevices()
+ {
+ return Domain.filterDevices( HostdevUsb.class, this.getDevices() );
+ }
+
+ /**
+ * Returns list of virtual machine network interface devices specified in the Libvirt domain XML
+ * document.
+ *
+ * @return list of virtual machine network interface devices.
+ */
+ public ArrayList<Interface> getInterfaceDevices()
+ {
+ return Domain.filterDevices( Interface.class, this.getDevices() );
+ }
+
+ /**
+ * Returns list of virtual machine graphic devices specified in the Libvirt domain XML document.
+ *
+ * @return list of virtual machine graphic devices.
+ */
+ public ArrayList<Graphics> getGraphicDevices()
+ {
+ return Domain.filterDevices( Graphics.class, this.getDevices() );
+ }
+
+ /**
+ * Returns list of virtual machine SPICE graphic devices specified in the Libvirt domain XML
+ * document.
+ *
+ * @return list of virtual machine SPICE graphic devices.
+ */
+ public ArrayList<GraphicsSpice> getGraphicSpiceDevices()
+ {
+ return Domain.filterDevices( GraphicsSpice.class, this.getDevices() );
+ }
+
+ /**
+ * Returns list of virtual machine VNC graphic devices specified in the Libvirt domain XML
+ * document.
+ *
+ * @return list of virtual machine VNC graphic devices.
+ */
+ public ArrayList<GraphicsVnc> getGraphicVncDevices()
+ {
+ return Domain.filterDevices( GraphicsVnc.class, this.getDevices() );
+ }
+
+ /**
+ * Returns list of virtual machine parallel port devices specified in the Libvirt domain XML
+ * document.
+ *
+ * @return list of virtual machine parallel port devices.
+ */
+ public ArrayList<Parallel> getParallelDevices()
+ {
+ return Domain.filterDevices( Parallel.class, this.getDevices() );
+ }
+
+ /**
+ * Returns list of virtual machine serial port devices specified in the Libvirt domain XML
+ * document.
+ *
+ * @return list of virtual machine serial port devices.
+ */
+ public ArrayList<Serial> getSerialDevices()
+ {
+ return Domain.filterDevices( Serial.class, this.getDevices() );
+ }
+
+ /**
+ * Returns list of virtual machine shared memory devices specified in the Libvirt domain XML
+ * document.
+ *
+ * @return list of virtual machine shared memory devices.
+ */
+ public ArrayList<Shmem> getShmemDevices()
+ {
+ return Domain.filterDevices( Shmem.class, this.getDevices() );
+ }
+
+ /**
+ * Returns list of virtual machine sound devices specified in the Libvirt domain XML document.
+ *
+ * @return list of virtual machine sound devices.
+ */
+ public ArrayList<Sound> getSoundDevices()
+ {
+ return Domain.filterDevices( Sound.class, this.getDevices() );
+ }
+
+ /**
+ * Returns list of virtual machine video devices specified in the Libvirt domain XML document.
+ *
+ * @return list of virtual machine video devices.
+ */
+ public ArrayList<Video> getVideoDevices()
+ {
+ return Domain.filterDevices( Video.class, this.getDevices() );
+ }
+
+ /**
+ * Returns the values of QEMU command line arguments from the Libvirt domain XML document.
+ *
+ * @return values of QEMU command line arguments from the Libvirt domain XML document.
+ */
+ public ArrayList<String> getQemuCmdlnArguments()
+ {
+ final Document xmlDocument = this.getRootXmlNode().getXmlDocument();
+ final ArrayList<String> qemuCmdlnArgs = new ArrayList<String>();
+
+ final NodeList qemuCmdlnNodes = xmlDocument.getElementsByTagNameNS( XMLNS_QEMU_NS_URI, "commandline" );
+ if ( qemuCmdlnNodes.getLength() > 0 ) {
+ final Node qemuCmdlnNode = qemuCmdlnNodes.item( 0 );
+ final NodeList qemuCmdlnArgNodes = qemuCmdlnNode.getChildNodes();
+ for ( int i = 0; i < qemuCmdlnArgNodes.getLength(); i++ ) {
+ final Node qemuCmdlnArgNode = qemuCmdlnArgNodes.item( i );
+ if ( qemuCmdlnArgNode.getNodeType() == Node.ELEMENT_NODE ) {
+ final Element qemuCmdlnArgElement = Element.class.cast( qemuCmdlnArgNode );
+ final String value = qemuCmdlnArgElement.getAttribute( "value" );
+ if ( value != null && !value.isEmpty() ) {
+ qemuCmdlnArgs.add( value );
+ }
+ }
+ }
+ }
+
+ return qemuCmdlnArgs;
+ }
+
+ /**
+ * Adds a virtual machine device to the Libvirt domain XML document.
+ *
+ * @param device virtual machine device that is added to the Libvirt domain XML document.
+ * @return reference to the added device for configuration purposes if creation was successful.
+ */
+ public Device addDevice( Device device )
+ {
+ Device addedDevice = null;
+
+ if ( device != null ) {
+ Node devicesNode = this.getRootXmlNode().getXmlElement( "devices" );
+
+ if ( devicesNode != null ) {
+ LibvirtXmlNode parentDevicesNode = null;
+ parentDevicesNode = new LibvirtXmlNode( this.getRootXmlNode().getXmlDocument(), devicesNode );
+ addedDevice = Device.createInstance( device, parentDevicesNode );
+ }
+ }
+
+ return addedDevice;
+ }
+
+ /**
+ * Adds a virtual machine controller device to the Libvirt domain XML document.
+ *
+ * @return reference to the added controller device if creation was successful.
+ */
+ public Controller addControllerDevice()
+ {
+ return Controller.class.cast( this.addDevice( new Controller() ) );
+ }
+
+ /**
+ * Adds a virtual machine floppy controller device to the Libvirt domain XML document.
+ *
+ * @return reference to the added floppy controller device if creation was successful.
+ */
+ public ControllerFloppy addControllerFloppyDevice()
+ {
+ return ControllerFloppy.class.cast( this.addDevice( new ControllerFloppy() ) );
+ }
+
+ /**
+ * Adds a virtual machine IDE controller device to the Libvirt domain XML document.
+ *
+ * @return reference to the added IDE controller device if creation was successful.
+ */
+ public ControllerIde addControllerIdeDevice()
+ {
+ return ControllerIde.class.cast( this.addDevice( new ControllerIde() ) );
+ }
+
+ /**
+ * Adds a virtual machine PCI controller device to the Libvirt domain XML document.
+ *
+ * @return reference to the added PCI controller device if creation was successful.
+ */
+ public ControllerPci addControllerPciDevice()
+ {
+ return ControllerPci.class.cast( this.addDevice( new ControllerPci() ) );
+ }
+
+ /**
+ * Adds a virtual machine SATA controller device to the Libvirt domain XML document.
+ *
+ * @return reference to the added SATA controller device if creation was successful.
+ */
+ public ControllerSata addControllerSataDevice()
+ {
+ return ControllerSata.class.cast( this.addDevice( new ControllerSata() ) );
+ }
+
+ /**
+ * Adds a virtual machine SCSI controller device to the Libvirt domain XML document.
+ *
+ * @return reference to the added SCSI controller device if creation was successful.
+ */
+ public ControllerScsi addControllerScsiDevice()
+ {
+ return ControllerScsi.class.cast( this.addDevice( new ControllerScsi() ) );
+ }
+
+ /**
+ * Adds a virtual machine USB controller device to the Libvirt domain XML document.
+ *
+ * @return reference to the added USB controller device if creation was successful.
+ */
+ public ControllerUsb addControllerUsbDevice()
+ {
+ return ControllerUsb.class.cast( this.addDevice( new ControllerUsb() ) );
+ }
+
+ /**
+ * Adds a virtual machine disk device to the Libvirt domain XML document.
+ *
+ * @return reference to the added disk device if creation was successful.
+ */
+ public Disk addDiskDevice()
+ {
+ return Disk.class.cast( this.addDevice( new Disk() ) );
+ }
+
+ /**
+ * Adds a virtual machine CDROM disk device to the Libvirt domain XML document.
+ *
+ * @return reference to the added CDROM disk device if creation was successful.
+ */
+ public DiskCdrom addDiskCdromDevice()
+ {
+ return DiskCdrom.class.cast( this.addDevice( new DiskCdrom() ) );
+ }
+
+ /**
+ * Adds a virtual machine floppy disk device to the Libvirt domain XML document.
+ *
+ * @return reference to the added floppy disk device if creation was successful.
+ */
+ public DiskFloppy addDiskFloppyDevice()
+ {
+ return DiskFloppy.class.cast( this.addDevice( new DiskFloppy() ) );
+ }
+
+ /**
+ * Adds a virtual machine storage disk device to the Libvirt domain XML document.
+ *
+ * @return reference to the added storage disk device if creation was successful.
+ */
+ public DiskStorage addDiskStorageDevice()
+ {
+ return DiskStorage.class.cast( this.addDevice( new DiskStorage() ) );
+ }
+
+ /**
+ * Adds a virtual machine file system device to the Libvirt domain XML document.
+ *
+ * @return reference to the added file system device if creation was successful.
+ */
+ public FileSystem addFileSystemDevice()
+ {
+ return FileSystem.class.cast( this.addDevice( new FileSystem() ) );
+ }
+
+ /**
+ * Adds a virtual machine hostdev device to the Libvirt domain XML document.
+ *
+ * @return reference to the added hostdev device if creation was successful.
+ */
+ public Hostdev addHostdevDevice()
+ {
+ return Hostdev.class.cast( this.addDevice( new Hostdev() ) );
+ }
+
+ /**
+ * Adds a virtual machine mediated hostdev device to the Libvirt domain XML document.
+ *
+ * @return reference to the added mediated hostdev device if creation was successful.
+ */
+ public HostdevMdev addHostdevMdevDevice()
+ {
+ return HostdevMdev.class.cast( this.addDevice( new HostdevMdev() ) );
+ }
+
+ /**
+ * Adds a virtual machine PCI hostdev device to the Libvirt domain XML document.
+ *
+ * @return reference to the added PCI hostdev device if creation was successful.
+ */
+ public HostdevPci addHostdevPciDevice()
+ {
+ return HostdevPci.class.cast( this.addDevice( new HostdevPci() ) );
+ }
+
+ /**
+ * Adds a virtual machine USB hostdev device to the Libvirt domain XML document.
+ *
+ * @return reference to the added USB hostdev device if creation was successful.
+ */
+ public HostdevUsb addHostdevUsbDevice()
+ {
+ return HostdevUsb.class.cast( this.addDevice( new HostdevUsb() ) );
+ }
+
+ /**
+ * Adds a virtual machine network device to the Libvirt domain XML document.
+ *
+ * @return reference to the added network device if creation was successful.
+ */
+ public Interface addInterfaceDevice()
+ {
+ return Interface.class.cast( this.addDevice( new Interface() ) );
+ }
+
+ /**
+ * Adds a virtual machine network bridge interface device to the Libvirt domain XML document.
+ *
+ * @return reference to the added network interface device if creation was successful.
+ */
+ public InterfaceBridge addInterfaceBridgeDevice()
+ {
+ return InterfaceBridge.class.cast( this.addDevice( new InterfaceBridge() ) );
+ }
+
+ /**
+ * Adds a virtual machine network interface device to the Libvirt domain XML document.
+ *
+ * @return reference to the added network interface device if creation was successful.
+ */
+ public InterfaceNetwork addInterfaceNetworkDevice()
+ {
+ return InterfaceNetwork.class.cast( this.addDevice( new InterfaceNetwork() ) );
+ }
+
+ /**
+ * Adds a virtual machine graphics device to the Libvirt domain XML document.
+ *
+ * @return reference to the added graphics device if creation was successful.
+ */
+ public Graphics addGraphicsDevice()
+ {
+ return Graphics.class.cast( this.addDevice( new Graphics() ) );
+ }
+
+ /**
+ * Adds a virtual machine SPICE graphics device to the Libvirt domain XML document.
+ *
+ * @return reference to the added SPICE graphics device if creation was successful.
+ */
+ public GraphicsSpice addGraphicsSpiceDevice()
+ {
+ return GraphicsSpice.class.cast( this.addDevice( new GraphicsSpice() ) );
+ }
+
+ /**
+ * Adds a virtual machine VNC graphics device to the Libvirt domain XML document.
+ *
+ * @return reference to the added VNC graphics device if creation was successful.
+ */
+ public GraphicsVnc addGraphicsVncDevice()
+ {
+ return GraphicsVnc.class.cast( this.addDevice( new GraphicsVnc() ) );
+ }
+
+ /**
+ * Adds a virtual machine parallel port device to the Libvirt domain XML document.
+ *
+ * @return reference to the added parallel port device if creation was successful.
+ */
+ public Parallel addParallelDevice()
+ {
+ return Parallel.class.cast( this.addDevice( new Parallel() ) );
+ }
+
+ /**
+ * Adds a virtual machine serial port device to the Libvirt domain XML document.
+ *
+ * @return reference to the added serial port device if creation was successful.
+ */
+ public Serial addSerialDevice()
+ {
+ return Serial.class.cast( this.addDevice( new Serial() ) );
+ }
+
+ /**
+ * Adds a virtual machine shared memory device to the Libvirt domain XML document.
+ *
+ * @return reference to the added shared memory device if creation was successful.
+ */
+ public Shmem addShmemDevice()
+ {
+ return Shmem.class.cast( this.addDevice( new Shmem() ) );
+ }
+
+ /**
+ * Adds a virtual machine sound device to the Libvirt domain XML document.
+ *
+ * @return reference to the added sound device if creation was successful.
+ */
+ public Sound addSoundDevice()
+ {
+ return Sound.class.cast( this.addDevice( new Sound() ) );
+ }
+
+ /**
+ * Adds a virtual machine video device to the Libvirt domain XML document.
+ *
+ * @return reference to the added video device if creation was successful.
+ */
+ public Video addVideoDevice()
+ {
+ return Video.class.cast( this.addDevice( new Video() ) );
+ }
+
+ /**
+ * Adds an given value as QEMU command line argument to the Libvirt domain XML document.
+ *
+ * @param value QEMU command line argument value.
+ */
+ public void addQemuCmdlnArgument( final String value )
+ {
+ final Element rootElement = Element.class.cast( this.getRootXmlNode().getXmlBaseNode() );
+ final Document xmlDocument = this.getRootXmlNode().getXmlDocument();
+ final Element qemuCmdlnElement;
+
+ final NodeList qemuCmdlnNodes = rootElement.getElementsByTagNameNS( XMLNS_QEMU_NS_URI, "commandline" );
+ if ( qemuCmdlnNodes.getLength() < 1 ) {
+ // add missing <domain xmlns:qemu="..."> namespace attribute
+ rootElement.setAttributeNS( XMLConstants.XMLNS_ATTRIBUTE_NS_URI,
+ XMLConstants.XMLNS_ATTRIBUTE + ":" + XMLNS_QEMU_NS_PREFIX, XMLNS_QEMU_NS_URI );
+ // add missing <qemu:commandline> element
+ qemuCmdlnElement = xmlDocument.createElementNS( XMLNS_QEMU_NS_URI, "commandline" );
+ qemuCmdlnElement.setPrefix( XMLNS_QEMU_NS_PREFIX );
+ rootElement.appendChild( qemuCmdlnElement );
+ } else {
+ // use available <qemu:commandline> element
+ final Node qemuCmdlnNode = qemuCmdlnNodes.item( 0 );
+ assert ( qemuCmdlnNode.getNodeType() == Node.ELEMENT_NODE );
+ qemuCmdlnElement = Element.class.cast( qemuCmdlnNode );
+ }
+
+ // append <qemu:arg value='...'> element with attribute
+ final Element qemuCmdlnArgElement = xmlDocument.createElementNS( XMLNS_QEMU_NS_URI, "arg" );
+ qemuCmdlnArgElement.setAttribute( "value", value );
+ qemuCmdlnElement.appendChild( qemuCmdlnArgElement );
+ }
+
+ public void addGvtg( String optionalRomfile )
+ {
+ final Element rootElement = Element.class.cast( this.getRootXmlNode().getXmlBaseNode() );
+ final Document xmlDocument = this.getRootXmlNode().getXmlDocument();
+ final Element qemuOverrideElement;
+
+ final NodeList qemuCmdlnNodes = rootElement.getElementsByTagNameNS( XMLNS_QEMU_NS_URI, "override" );
+ if ( qemuCmdlnNodes.getLength() < 1 ) {
+ // add missing <domain xmlns:qemu="..."> namespace attribute
+ rootElement.setAttributeNS( XMLConstants.XMLNS_ATTRIBUTE_NS_URI,
+ XMLConstants.XMLNS_ATTRIBUTE + ":" + XMLNS_QEMU_NS_PREFIX, XMLNS_QEMU_NS_URI );
+ // add missing <qemu:override> element
+ qemuOverrideElement = xmlDocument.createElementNS( XMLNS_QEMU_NS_URI, "override" );
+ qemuOverrideElement.setPrefix( XMLNS_QEMU_NS_PREFIX );
+ rootElement.appendChild( qemuOverrideElement );
+ } else {
+ // use available <qemu:override> element
+ final Node qemuOverrideNode = qemuCmdlnNodes.item( 0 );
+ assert ( qemuOverrideNode.getNodeType() == Node.ELEMENT_NODE );
+ qemuOverrideElement = Element.class.cast( qemuOverrideNode );
+ }
+
+ // Get device subnode
+ Element qemuDeviceElement = XmlHelper.getOrCreateElement( xmlDocument, qemuOverrideElement,
+ XMLNS_QEMU_NS_URI, XMLNS_QEMU_NS_PREFIX, "device", "alias", "hostdev0" );
+ //
+ Element qemuFrontendElement = XmlHelper.getOrCreateElement( xmlDocument, qemuDeviceElement,
+ XMLNS_QEMU_NS_URI, XMLNS_QEMU_NS_PREFIX, "frontend", null, null );
+ // Properties
+ Element prop;
+ prop = XmlHelper.getOrCreateElement( xmlDocument, qemuFrontendElement,
+ XMLNS_QEMU_NS_URI, XMLNS_QEMU_NS_PREFIX, "property", "name", "x-igd-opregion" );
+ prop.setAttribute( "type", "bool" );
+ prop.setAttribute( "value", "true" );
+ prop = XmlHelper.getOrCreateElement( xmlDocument, qemuFrontendElement,
+ XMLNS_QEMU_NS_URI, XMLNS_QEMU_NS_PREFIX, "property", "name", "driver" );
+ prop.setAttribute( "type", "string" );
+ prop.setAttribute( "value", "vfio-pci-nohotplug" );
+ prop = XmlHelper.getOrCreateElement( xmlDocument, qemuFrontendElement,
+ XMLNS_QEMU_NS_URI, XMLNS_QEMU_NS_PREFIX, "property", "name", "ramfb" );
+ prop.setAttribute( "type", "bool" );
+ prop.setAttribute( "value", "true" );
+ if ( optionalRomfile != null ) {
+ prop = XmlHelper.getOrCreateElement( xmlDocument, qemuFrontendElement,
+ XMLNS_QEMU_NS_URI, XMLNS_QEMU_NS_PREFIX, "property", "name", "romfile" );
+ prop.setAttribute( "type", "string" );
+ prop.setAttribute( "value", optionalRomfile );
+ }
+ }
+
+ /**
+ * Removes boot oder entries in the Libvirt domain XML document.
+ */
+ public void removeBootOrder()
+ {
+ // remove boot order entries of all disk devices
+ for ( Disk diskDevice : this.getDiskDevices() ) {
+ diskDevice.removeBootOrder();
+ }
+
+ // remove boot order entries of all network interface devices
+ for ( Interface interfaceDevice : this.getInterfaceDevices() ) {
+ interfaceDevice.removeBootOrder();
+ }
+
+ // remove boot order entries of all hostdev devices
+ for ( Hostdev hostdevDevice : this.getHostdevDevices() ) {
+ hostdevDevice.removeBootOrder();
+ }
+
+ // remove boot oder entries under the 'os' element
+ this.getRootXmlNode().removeXmlElement( "os/boot" );
+ }
+
+ /**
+ * Removes underlying source for all disk devices in the Libvirt domain XML document.
+ *
+ * @implNote Calling this method will result in an invalid Libvirt domain XML document.
+ */
+ public void removeDiskDevicesStorage()
+ {
+ for ( Disk diskDevice : this.getDiskDevices() ) {
+ diskDevice.removeStorage();
+ }
+ }
+
+ /**
+ * Removes specified Nvram file in the Libvirt domain XML document.
+ */
+ public void removeOsNvram()
+ {
+ final Node nvramElement = this.getRootXmlNode().getXmlElement( "os/nvram" );
+
+ if ( nvramElement != null ) {
+ nvramElement.getParentNode().removeChild( nvramElement );
+ }
+ }
+
+ /**
+ * Removes network source for all interface devices in the Libvirt domain XML document.
+ */
+ public void removeInterfaceDevicesSource()
+ {
+ for ( Interface interfaceDevice : this.getInterfaceDevices() ) {
+ // set empty source to preserve the XML attribute (to prevent XML validation errors)
+ interfaceDevice.setSource( "" );
+ }
+ }
+
+ /**
+ * Remove any existing CPU pinning and numa config
+ */
+ public void resetCpuPin()
+ {
+ this.getRootXmlNode().removeXmlElement( "cputune" );
+ this.getRootXmlNode().removeXmlElement( "numatune" );
+ }
+
+ public void addCpuPin( int virtualCore, int hostCore )
+ {
+ final Element rootElement = Element.class.cast( this.getRootXmlNode().getXmlBaseNode() );
+ final Document xmlDocument = this.getRootXmlNode().getXmlDocument();
+ Node cpuTune = this.getRootXmlNode().getXmlElement( "cputune" );
+ if ( cpuTune == null ) {
+ cpuTune = xmlDocument.createElement( "cputune" );
+ rootElement.appendChild( cpuTune );
+ }
+ Element pin = xmlDocument.createElement( "vcpupin" );
+ pin.setAttribute( "vcpu", Integer.toString( virtualCore ) );
+ pin.setAttribute( "cpuset", Integer.toString( hostCore ) );
+ cpuTune.appendChild( pin );
+ Node vcpuNode = this.getRootXmlNode().getXmlElement( "vcpu" );
+ if ( vcpuNode instanceof Element ) {
+ ( (Element)vcpuNode ).setAttribute( "placement", "static" );
+ }
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/DomainUtils.java b/src/main/java/org/openslx/libvirt/domain/DomainUtils.java
new file mode 100644
index 0000000..2462371
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/DomainUtils.java
@@ -0,0 +1,118 @@
+package org.openslx.libvirt.domain;
+
+import java.math.BigInteger;
+
+/**
+ * Collection of helper functions to maintain a Libvirt domain XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public final class DomainUtils
+{
+
+ /**
+ * Converts memory value with specified SI unit to absolute value in bytes.
+ *
+ * @param value amount of memory in specified SI unit.
+ * @param unit SI unit name, one of: bytes, KB, k, KiB, MB, M, MiB, GB, G, GiB, TB, T, TiB, for
+ * <code>value</code>.
+ * @return absolute amount of memory in bytes.
+ */
+ public static BigInteger decodeMemory( String value, String unit )
+ {
+ BigInteger factor = null;
+ BigInteger result = new BigInteger( value );
+
+ switch ( unit ) {
+ case "b":
+ case "bytes":
+ factor = new BigInteger( "1" );
+ break;
+ case "KB":
+ factor = new BigInteger( "1000" );
+ break;
+ case "k":
+ case "KiB":
+ factor = new BigInteger( "1024" );
+ break;
+ case "MB":
+ factor = new BigInteger( "1000000" );
+ break;
+ case "M":
+ case "MiB":
+ factor = new BigInteger( "1048576" );
+ break;
+ case "GB":
+ factor = new BigInteger( "1000000000" );
+ break;
+ case "G":
+ case "GiB":
+ factor = new BigInteger( "1073741824" );
+ break;
+ case "TB":
+ factor = new BigInteger( "1000000000000" );
+ break;
+ case "T":
+ case "TiB":
+ factor = new BigInteger( "1099511627776" );
+ break;
+ default:
+ return null;
+ }
+
+ return result.multiply( factor );
+ }
+
+ /**
+ * Convert memory from absolute value in bytes to value in specified SI unit.
+ *
+ * @param value absolute amount of memory in bytes.
+ * @param unit SI unit name, one of: bytes, KB, k, KiB, MB, M, MiB, GB, G, GiB, TB, T, TiB for
+ * returned memory value.
+ * @return amount of memory in specified SI unit.
+ */
+ public static String encodeMemory( BigInteger value, String unit )
+ {
+ BigInteger dividend = null;
+
+ switch ( unit ) {
+ case "b":
+ case "bytes":
+ dividend = new BigInteger( "1" );
+ break;
+ case "KB":
+ dividend = new BigInteger( "1000" );
+ break;
+ case "k":
+ case "KiB":
+ dividend = new BigInteger( "1024" );
+ break;
+ case "MB":
+ dividend = new BigInteger( "1000000" );
+ break;
+ case "M":
+ case "MiB":
+ dividend = new BigInteger( "1048576" );
+ break;
+ case "GB":
+ dividend = new BigInteger( "1000000000" );
+ break;
+ case "G":
+ case "GiB":
+ dividend = new BigInteger( "1073741824" );
+ break;
+ case "TB":
+ dividend = new BigInteger( "1000000000000" );
+ break;
+ case "T":
+ case "TiB":
+ dividend = new BigInteger( "1099511627776" );
+ break;
+ default:
+ return null;
+ }
+
+ return value.divide( dividend ).toString();
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/Controller.java b/src/main/java/org/openslx/libvirt/domain/device/Controller.java
new file mode 100644
index 0000000..626462b
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/Controller.java
@@ -0,0 +1,181 @@
+package org.openslx.libvirt.domain.device;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+
+/**
+ * A controller (PCI, USB, ...) device node in a Libvirt domain XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class Controller extends Device
+{
+ /**
+ * Creates an empty controller device.
+ */
+ public Controller()
+ {
+ super();
+ }
+
+ /**
+ * Creates a controller device representing an existing Libvirt XML controller device element.
+ *
+ * @param xmlNode existing Libvirt XML controller device element.
+ */
+ public Controller( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Returns index of the controller.
+ *
+ * @return index of the controller.
+ */
+ public int getIndex()
+ {
+ String index = this.getXmlElementAttributeValue( "index" );
+ return Integer.parseInt( index );
+ }
+
+ /**
+ * Sets index for the controller.
+ *
+ * @param index index for the controller.
+ */
+ public void setIndex( int index )
+ {
+ this.setXmlElementAttributeValue( "index", Integer.toString( index ) );
+ }
+
+ /**
+ * Creates a non-existent controller device as Libvirt XML device element.
+ *
+ * @param controller controller device that is created.
+ * @param xmlNode Libvirt XML node of the Libvirt XML device that is created.
+ * @return created controller device instance.
+ */
+ public static Controller createInstance( Controller controller, LibvirtXmlNode xmlNode )
+ {
+ Controller addedController = null;
+
+ if ( controller instanceof ControllerFloppy ) {
+ xmlNode.setXmlElementAttributeValue( "type", Type.FLOPPY.toString() );
+ addedController = ControllerFloppy.createInstance( xmlNode );
+ } else if ( controller instanceof ControllerIde ) {
+ xmlNode.setXmlElementAttributeValue( "type", Type.IDE.toString() );
+ addedController = ControllerIde.createInstance( xmlNode );
+ } else if ( controller instanceof ControllerPci ) {
+ xmlNode.setXmlElementAttributeValue( "type", Type.PCI.toString() );
+ addedController = ControllerPci.createInstance( xmlNode );
+ } else if ( controller instanceof ControllerSata ) {
+ xmlNode.setXmlElementAttributeValue( "type", Type.SATA.toString() );
+ addedController = ControllerSata.createInstance( xmlNode );
+ } else if ( controller instanceof ControllerScsi ) {
+ xmlNode.setXmlElementAttributeValue( "type", Type.SCSI.toString() );
+ addedController = ControllerScsi.createInstance( xmlNode );
+ } else if ( controller instanceof ControllerUsb ) {
+ xmlNode.setXmlElementAttributeValue( "type", Type.USB.toString() );
+ addedController = ControllerUsb.createInstance( xmlNode );
+ }
+
+ return addedController;
+ }
+
+ /**
+ * Creates a controller device representing an existing Libvirt XML controller device element.
+ *
+ * @param xmlNode existing Libvirt XML controller device element.
+ * @return controller device instance.
+ */
+ public static Controller newInstance( LibvirtXmlNode xmlNode )
+ {
+
+ Controller deviceController = null;
+ Type type = Type.fromString( xmlNode.getXmlElementAttributeValue( "type" ) );
+
+ if ( type == null ) {
+ return null;
+ }
+
+ switch ( type ) {
+ case FLOPPY:
+ deviceController = ControllerFloppy.newInstance( xmlNode );
+ break;
+ case IDE:
+ deviceController = ControllerIde.newInstance( xmlNode );
+ break;
+ case PCI:
+ deviceController = ControllerPci.newInstance( xmlNode );
+ break;
+ case SATA:
+ deviceController = ControllerSata.newInstance( xmlNode );
+ break;
+ case SCSI:
+ deviceController = ControllerScsi.newInstance( xmlNode );
+ break;
+ case USB:
+ deviceController = ControllerUsb.newInstance( xmlNode );
+ break;
+ }
+
+ return deviceController;
+ }
+
+ /**
+ * Type of controller device.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+ enum Type
+ {
+ // @formatter:off
+ FLOPPY( "fdc" ),
+ IDE ( "ide" ),
+ PCI ( "pci" ),
+ SATA ( "sata" ),
+ SCSI ( "scsi" ),
+ USB ( "usb" );
+ // @formatter:on
+
+ /**
+ * Name of the controller device type.
+ */
+ private String type = null;
+
+ /**
+ * Creates controller device type.
+ *
+ * @param type valid name of the controller device type in a Libvirt domain XML document.
+ */
+ Type( String type )
+ {
+ this.type = type;
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.type;
+ }
+
+ /**
+ * Creates controller device type from its name with error check.
+ *
+ * @param type name of the controller device type in a Libvirt domain XML document.
+ * @return valid controller device type.
+ */
+ public static Type fromString( String type )
+ {
+ for ( Type t : Type.values() ) {
+ if ( t.type.equalsIgnoreCase( type ) ) {
+ return t;
+ }
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/ControllerFloppy.java b/src/main/java/org/openslx/libvirt/domain/device/ControllerFloppy.java
new file mode 100644
index 0000000..5e580bd
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/ControllerFloppy.java
@@ -0,0 +1,54 @@
+package org.openslx.libvirt.domain.device;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+
+/**
+ * A floppy controller device in a Libvirt domain XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class ControllerFloppy extends Controller
+{
+ /**
+ * Creates an empty floppy controller device.
+ */
+ public ControllerFloppy()
+ {
+ super();
+ }
+
+ /**
+ * Creates a floppy controller device representing an existing Libvirt XML floppy controller
+ * device element.
+ *
+ * @param xmlNode existing Libvirt XML controller device element.
+ */
+ public ControllerFloppy( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Creates a non-existent floppy controller device as Libvirt XML device element.
+ *
+ * @param xmlNode Libvirt XML node of the Libvirt XML device that is created.
+ * @return created floppy controller device instance.
+ */
+ public static ControllerFloppy createInstance( LibvirtXmlNode xmlNode )
+ {
+ return ControllerFloppy.newInstance( xmlNode );
+ }
+
+ /**
+ * Creates a floppy controller device representing an existing Libvirt XML floppy controller
+ * device element.
+ *
+ * @param xmlNode existing Libvirt XML controller device element.
+ * @return floppy controller device instance.
+ */
+ public static ControllerFloppy newInstance( LibvirtXmlNode xmlNode )
+ {
+ return new ControllerFloppy( xmlNode );
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/ControllerIde.java b/src/main/java/org/openslx/libvirt/domain/device/ControllerIde.java
new file mode 100644
index 0000000..062b67d
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/ControllerIde.java
@@ -0,0 +1,128 @@
+package org.openslx.libvirt.domain.device;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+
+/**
+ * An IDE controller device node in a Libvirt domain XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class ControllerIde extends Controller
+{
+ /**
+ * Creates an empty IDE controller device.
+ */
+ public ControllerIde()
+ {
+ super();
+ }
+
+ /**
+ * Creates an IDE controller device representing an existing Libvirt XML IDE controller device
+ * element.
+ *
+ * @param xmlNode existing Libvirt XML IDE controller device element.
+ */
+ public ControllerIde( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Returns emulated hardware model of the IDE controller.
+ *
+ * @return hardware model of the IDE controller.
+ */
+ public Model getModel()
+ {
+ String model = this.getXmlElementAttributeValue( "model" );
+ return Model.fromString( model );
+ }
+
+ /**
+ * Sets hardware model for the IDE controller.
+ *
+ * @param model hardware model for the IDE controller.
+ */
+ public void setModel( Model model )
+ {
+ this.setXmlElementAttributeValue( "model", model.toString() );
+ }
+
+ /**
+ * Creates a non-existent IDE controller device as Libvirt XML device element.
+ *
+ * @param xmlNode Libvirt XML node of the Libvirt XML device that is created.
+ * @return created IDE controller device instance.
+ */
+ public static ControllerIde createInstance( LibvirtXmlNode xmlNode )
+ {
+ return ControllerIde.newInstance( xmlNode );
+ }
+
+ /**
+ * Creates an IDE controller device representing an existing Libvirt XML IDE controller device
+ * element.
+ *
+ * @param xmlNode existing Libvirt XML IDE controller device element.
+ * @return IDE controller device instance.
+ */
+ public static ControllerIde newInstance( LibvirtXmlNode xmlNode )
+ {
+ return new ControllerIde( xmlNode );
+ }
+
+ /**
+ * Model of IDE controller device.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+ enum Model
+ {
+ // @formatter:off
+ PIIX3( "piix3" ),
+ PIIX4( "pixx4" ),
+ ICH6 ( "ich6" );
+ // @formatter:on
+
+ /**
+ * Name of the IDE controller device model.
+ */
+ private String model = null;
+
+ /**
+ * Creates IDE controller device model.
+ *
+ * @param type valid name of the IDE controller device model in a Libvirt domain XML document.
+ */
+ Model( String model )
+ {
+ this.model = model;
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.model;
+ }
+
+ /**
+ * Creates IDE controller device model from its name with error check.
+ *
+ * @param type name of the IDE controller device model in a Libvirt domain XML document.
+ * @return valid IDE controller device model.
+ */
+ public static Model fromString( String model )
+ {
+ for ( Model t : Model.values() ) {
+ if ( t.model.equalsIgnoreCase( model ) ) {
+ return t;
+ }
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/ControllerPci.java b/src/main/java/org/openslx/libvirt/domain/device/ControllerPci.java
new file mode 100644
index 0000000..feb8b1a
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/ControllerPci.java
@@ -0,0 +1,145 @@
+package org.openslx.libvirt.domain.device;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+
+/**
+ * A PCI controller device node in a Libvirt domain XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class ControllerPci extends Controller
+{
+ /**
+ * Creates an empty PCI controller device.
+ */
+ public ControllerPci()
+ {
+ super();
+ }
+
+ /**
+ * Creates a PCI controller device representing an existing Libvirt XML PCI controller device
+ * element.
+ *
+ * @param xmlNode existing Libvirt XML PCI controller device element.
+ */
+ public ControllerPci( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Returns model of the PCI controller.
+ *
+ * @return model of the PCI controller.
+ */
+ public Model getModel()
+ {
+ String model = this.getXmlElementAttributeValue( "model" );
+ return Model.fromString( model );
+ }
+
+ /**
+ * Sets model for the PCI controller.
+ *
+ * @param model model for the PCI controller.
+ */
+ public void setModel( Model model )
+ {
+ this.setXmlElementAttributeValue( "model", model.toString() );
+ }
+
+ /**
+ * Returns emulated hardware model of the PCI controller.
+ *
+ * @return emulated hardware model of the PCI controller.
+ */
+ public String getModelEmulated()
+ {
+ return this.getXmlElementAttributeValue( "model", "name" );
+ }
+
+ /**
+ * Creates a non-existent PCI controller device as Libvirt XML device element.
+ *
+ * @param xmlNode Libvirt XML node of the Libvirt XML device that is created.
+ * @return created PCI controller device instance.
+ */
+ public static ControllerPci createInstance( LibvirtXmlNode xmlNode )
+ {
+ return ControllerPci.newInstance( xmlNode );
+ }
+
+ /**
+ * Creates a PCI controller device representing an existing Libvirt XML PCI controller device
+ * element.
+ *
+ * @param xmlNode existing Libvirt XML PCI controller device element.
+ * @return PCI controller device instance.
+ */
+ public static ControllerPci newInstance( LibvirtXmlNode xmlNode )
+ {
+ return new ControllerPci( xmlNode );
+ }
+
+ /**
+ * Model of PCI controller device.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+ enum Model
+ {
+ // @formatter:off
+ PCI_ROOT ( "pci-root" ),
+ PCI_BRDIGE ( "pci-bridge" ),
+ PCIE_ROOT ( "pcie-root" ),
+ PCI_DMI2BRIDGE ( "dmi-to-pci-bridge" ),
+ PCIE_ROOT_PORT ( "pcie-root-port" ),
+ PCIE_SWITCH_UPSTREAM_PORT ( "pcie-switch-upstream-port" ),
+ PCIE_SWITCH_DOWNSTREAM_PORT( "pcie-switch-downstream-port" ),
+ PCI_EXPANDER_BUS ( "pci-expander-bus" ),
+ PCIE_EXPANDER_BUS ( "pcie-expander-bus" ),
+ PCIE2PCI_BRIDGE ( "pcie-to-pci-bridge" );
+ // @formatter:on
+
+ /**
+ * Name of the PCI controller device model.
+ */
+ private String model = null;
+
+ /**
+ * Creates PCI controller device model.
+ *
+ * @param type valid name of the PCI controller device model in a Libvirt domain XML document.
+ */
+ Model( String model )
+ {
+ this.model = model;
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.model;
+ }
+
+ /**
+ * Creates PCI controller device model from its name with error check.
+ *
+ * @param type name of the PCI controller device model in a Libvirt domain XML document.
+ * @return valid PCI controller device model.
+ */
+ public static Model fromString( String model )
+ {
+ for ( Model t : Model.values() ) {
+ if ( t.model.equalsIgnoreCase( model ) ) {
+ return t;
+ }
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/ControllerSata.java b/src/main/java/org/openslx/libvirt/domain/device/ControllerSata.java
new file mode 100644
index 0000000..b784ae0
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/ControllerSata.java
@@ -0,0 +1,54 @@
+package org.openslx.libvirt.domain.device;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+
+/**
+ * A SATA controller device node in a Libvirt domain XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class ControllerSata extends Controller
+{
+ /**
+ * Creates an empty SATA controller device.
+ */
+ public ControllerSata()
+ {
+ super();
+ }
+
+ /**
+ * Creates a SATA controller device representing an existing Libvirt XML SATA controller device
+ * element.
+ *
+ * @param xmlNode existing Libvirt XML SATA controller device element.
+ */
+ public ControllerSata( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Creates a non-existent SATA controller device as Libvirt XML device element.
+ *
+ * @param xmlNode Libvirt XML node of the Libvirt XML device that is created.
+ * @return created SATA controller device instance.
+ */
+ public static ControllerSata createInstance( LibvirtXmlNode xmlNode )
+ {
+ return ControllerSata.newInstance( xmlNode );
+ }
+
+ /**
+ * Creates a SATA controller device representing an existing Libvirt XML SATA controller device
+ * element.
+ *
+ * @param xmlNode existing Libvirt XML SATA controller device element.
+ * @return SATA controller device instance.
+ */
+ public static ControllerSata newInstance( LibvirtXmlNode xmlNode )
+ {
+ return new ControllerSata( xmlNode );
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/ControllerScsi.java b/src/main/java/org/openslx/libvirt/domain/device/ControllerScsi.java
new file mode 100644
index 0000000..16c3a0f
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/ControllerScsi.java
@@ -0,0 +1,138 @@
+package org.openslx.libvirt.domain.device;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+
+/**
+ * A SCSI controller device node in a Libvirt domain XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class ControllerScsi extends Controller
+{
+ /**
+ * Creates an empty SCSI controller device.
+ */
+ public ControllerScsi()
+ {
+ super();
+ }
+
+ /**
+ * Creates a SCSI controller device representing an existing Libvirt XML SCSI controller device
+ * element.
+ *
+ * @param xmlNode existing Libvirt XML SCSI controller device element.
+ */
+ public ControllerScsi( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Returns hardware model of the PCI controller.
+ *
+ * @return hardware model of the PCI controller.
+ */
+ public Model getModel()
+ {
+ String model = this.getXmlElementAttributeValue( "model" );
+ return Model.fromString( model );
+ }
+
+ /**
+ * Sets hardware model for the PCI controller.
+ *
+ * @param model hardware model for the PCI controller.
+ */
+ public void setModel( Model model )
+ {
+ this.setXmlElementAttributeValue( "model", model.toString() );
+ }
+
+ /**
+ * Creates a non-existent SCSI controller device as Libvirt XML device element.
+ *
+ * @param xmlNode Libvirt XML node of the Libvirt XML device that is created.
+ * @return created SCSI controller device instance.
+ */
+ public static ControllerScsi createInstance( LibvirtXmlNode xmlNode )
+ {
+ return ControllerScsi.newInstance( xmlNode );
+ }
+
+ /**
+ * Creates a SCSI controller device representing an existing Libvirt XML SCSI controller device
+ * element.
+ *
+ * @param xmlNode existing Libvirt XML SCSI controller device element.
+ * @return SCSI controller device instance.
+ */
+ public static ControllerScsi newInstance( LibvirtXmlNode xmlNode )
+ {
+ return new ControllerScsi( xmlNode );
+ }
+
+ /**
+ * Model of SCSI controller device.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+ enum Model
+ {
+ // @formatter:off
+ AUTO ( "auto" ),
+ BUSLOGIC ( "buslogic" ),
+ IBMVSCSI ( "ibmvscsi" ),
+ LSISAS1068 ( "lsisas1068" ),
+ LSISAS1078 ( "lsisas1078" ),
+ VIRTIO_SCSI ( "virtio-scsi" ),
+ VMPVSCSI ( "vmpvscsi" ),
+ VIRTIO_TRANSITIONAL ( "virtio-transitional" ),
+ VIRTIO_NON_TRANSITIONAL( "virtio-non-transitional" ),
+ NCR53C90 ( "ncr53c90" ),
+ AM53C974 ( "am53c974" ),
+ DC390 ( "dc390" );
+ // @formatter:on
+
+ /**
+ * Name of the SCSI controller device model.
+ */
+ private String model = null;
+
+ /**
+ * Creates SCSI controller device model.
+ *
+ * @param type valid name of the SCSI controller device model in a Libvirt domain XML
+ * document.
+ */
+ Model( String model )
+ {
+ this.model = model;
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.model;
+ }
+
+ /**
+ * Creates SCSI controller device model from its name with error check.
+ *
+ * @param type name of the SCSI controller device model in a Libvirt domain XML document.
+ * @return valid SCSI controller device model.
+ */
+ public static Model fromString( String model )
+ {
+ for ( Model t : Model.values() ) {
+ if ( t.model.equalsIgnoreCase( model ) ) {
+ return t;
+ }
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/ControllerUsb.java b/src/main/java/org/openslx/libvirt/domain/device/ControllerUsb.java
new file mode 100644
index 0000000..1798027
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/ControllerUsb.java
@@ -0,0 +1,139 @@
+package org.openslx.libvirt.domain.device;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+
+/**
+ * A USB controller device node in a Libvirt domain XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class ControllerUsb extends Controller
+{
+ /**
+ * Creates an empty USB controller device.
+ */
+ public ControllerUsb()
+ {
+ super();
+ }
+
+ /**
+ * Creates an USB controller device representing an existing Libvirt XML USB controller device
+ * element.
+ *
+ * @param xmlNode existing Libvirt XML USB controller device element.
+ */
+ public ControllerUsb( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Returns hardware model of the PCI controller.
+ *
+ * @return hardware model of the PCI controller.
+ */
+ public Model getModel()
+ {
+ String model = this.getXmlElementAttributeValue( "model" );
+ return Model.fromString( model );
+ }
+
+ /**
+ * Sets hardware model for the PCI controller.
+ *
+ * @param model hardware model for the PCI controller.
+ */
+ public void setModel( Model model )
+ {
+ this.setXmlElementAttributeValue( "model", model.toString() );
+ }
+
+ /**
+ * Creates a non-existent USB controller device as Libvirt XML device element.
+ *
+ * @param xmlNode Libvirt XML node of the Libvirt XML device that is created.
+ * @return created USB controller device instance.
+ */
+ public static ControllerUsb createInstance( LibvirtXmlNode xmlNode )
+ {
+ return ControllerUsb.newInstance( xmlNode );
+ }
+
+ /**
+ * Creates an USB controller device representing an existing Libvirt XML USB controller device
+ * element.
+ *
+ * @param xmlNode existing Libvirt XML USB controller device element.
+ * @return USB controller device instance.
+ */
+ public static ControllerUsb newInstance( LibvirtXmlNode xmlNode )
+ {
+ return new ControllerUsb( xmlNode );
+ }
+
+ /**
+ * Model of PCI controller device.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+ public enum Model
+ {
+ // @formatter:off
+ NONE ( "none" ),
+ PIIX3_UHCI ( "piix3-uhci" ),
+ PIIX4_UHCI ( "piix4-uhci" ),
+ EHCI ( "ehci" ),
+ ICH9_EHCI1 ( "ich9-ehci1" ),
+ ICH9_UHCI1 ( "ich9-uhci1" ),
+ ICH9_UHCI2 ( "ich9-uhci2" ),
+ ICH9_UHCI3 ( "ich9-uhci3" ),
+ VT82C686B_UHCI( "vt82c686b-uhci" ),
+ PCI_OHCI ( "pci-ohci" ),
+ NEC_XHCI ( "nec-xhci" ),
+ QUSB1 ( "qusb1" ),
+ QUSB2 ( "qusb2" ),
+ QEMU_XHCI ( "qemu-xhci" );
+ // @formatter:on
+
+ /**
+ * Name of the USB controller device model.
+ */
+ private String model = null;
+
+ /**
+ * Creates USB controller device model.
+ *
+ * @param type valid name of the USB controller device model in a Libvirt domain XML document.
+ */
+ Model( String model )
+ {
+ this.model = model;
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.model;
+ }
+
+ /**
+ * Creates USB controller device model from its name with error check.
+ *
+ * @param model name of the USB controller device model in a Libvirt domain XML document.
+ * @return valid USB controller device model.
+ */
+ public static Model fromString( String model )
+ {
+ for ( Model t : Model.values() ) {
+ if ( t.model.equalsIgnoreCase( model ) ) {
+ return t;
+ }
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/Device.java b/src/main/java/org/openslx/libvirt/domain/device/Device.java
new file mode 100644
index 0000000..31a54ca
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/Device.java
@@ -0,0 +1,290 @@
+package org.openslx.libvirt.domain.device;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * A virtual machines device node in a Libvirt domain XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class Device extends LibvirtXmlNode implements HostdevAddressableTarget<HostdevPciDeviceAddress>
+{
+ /**
+ * Creates an empty virtual machine device.
+ */
+ public Device()
+ {
+ super();
+ }
+
+ /**
+ * Creates a virtual machine device representing an existing Libvirt XML device element.
+ *
+ * @param xmlNode existing Libvirt XML device element.
+ */
+ public Device( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Removes device from Libvirt domain XML document.
+ */
+ public void remove()
+ {
+ Node node = this.getXmlElement();
+ node.getParentNode().removeChild( node );
+ }
+
+ /**
+ * Creates a Libvirt XML device element as child of a given Libvirt XML parent node.
+ *
+ * @param xmlParentNode parent Libvirt XML node of the Libvirt XML device element that is
+ * created.
+ * @param deviceType type of the Libvirt XML device element.
+ * @return created Libvirt XML device node.
+ */
+ private static LibvirtXmlNode createDeviceElement( LibvirtXmlNode xmlParentNode, Type deviceType )
+ {
+ // create XML element as part of the Libvirt XML document
+ Document xmlDocument = xmlParentNode.getXmlDocument();
+ Element deviceNode = xmlDocument.createElement( deviceType.toString() );
+
+ // append the created XML element to the Libvirt XML document
+ xmlParentNode.getXmlBaseNode().appendChild( deviceNode );
+
+ return new LibvirtXmlNode( xmlParentNode.getXmlDocument(), deviceNode );
+ }
+
+ /**
+ * Creates a non-existent virtual machine device as Libvirt XML device element.
+ *
+ * @param device virtual machine device that is created.
+ * @param xmlParentNode parent Libvirt XML node of the Libvirt XML device that is created.
+ * @return created virtual machine device instance.
+ */
+ public static Device createInstance( Device device, LibvirtXmlNode xmlParentNode )
+ {
+ Device createdDevice = null;
+
+ if ( device instanceof Controller ) {
+ LibvirtXmlNode xmlNode = Device.createDeviceElement( xmlParentNode, Type.CONTROLLER );
+ createdDevice = Controller.createInstance( Controller.class.cast( device ), xmlNode );
+ } else if ( device instanceof Disk ) {
+ LibvirtXmlNode xmlNode = Device.createDeviceElement( xmlParentNode, Type.DISK );
+ createdDevice = Disk.createInstance( Disk.class.cast( device ), xmlNode );
+ } else if ( device instanceof FileSystem ) {
+ LibvirtXmlNode xmlNode = Device.createDeviceElement( xmlParentNode, Type.FILESYSTEM );
+ createdDevice = FileSystem.createInstance( xmlNode );
+ } else if ( device instanceof Hostdev ) {
+ LibvirtXmlNode xmlNode = Device.createDeviceElement( xmlParentNode, Type.HOSTDEV );
+ createdDevice = Hostdev.createInstance( Hostdev.class.cast( device ), xmlNode );
+ } else if ( device instanceof Interface ) {
+ LibvirtXmlNode xmlNode = Device.createDeviceElement( xmlParentNode, Type.INTERFACE );
+ createdDevice = Interface.createInstance( Interface.class.cast( device ), xmlNode );
+ } else if ( device instanceof Graphics ) {
+ LibvirtXmlNode xmlNode = Device.createDeviceElement( xmlParentNode, Type.GRAPHICS );
+ createdDevice = Graphics.createInstance( Graphics.class.cast( device ), xmlNode );
+ } else if ( device instanceof Parallel ) {
+ LibvirtXmlNode xmlNode = Device.createDeviceElement( xmlParentNode, Type.PARALLEL );
+ createdDevice = Parallel.createInstance( xmlNode );
+ } else if ( device instanceof Serial ) {
+ LibvirtXmlNode xmlNode = Device.createDeviceElement( xmlParentNode, Type.SERIAL );
+ createdDevice = Serial.createInstance( xmlNode );
+ } else if ( device instanceof Shmem ) {
+ LibvirtXmlNode xmlNode = Device.createDeviceElement( xmlParentNode, Type.SHMEM );
+ createdDevice = Shmem.createInstance( xmlNode );
+ } else if ( device instanceof Sound ) {
+ LibvirtXmlNode xmlNode = Device.createDeviceElement( xmlParentNode, Type.SOUND );
+ createdDevice = Sound.createInstance( xmlNode );
+ } else if ( device instanceof Video ) {
+ LibvirtXmlNode xmlNode = Device.createDeviceElement( xmlParentNode, Type.VIDEO );
+ createdDevice = Video.createInstance( xmlNode );
+ }
+
+ return createdDevice;
+ }
+
+ /**
+ * Creates a virtual machine device representing an existing Libvirt XML device element.
+ *
+ * @param xmlNode existing Libvirt XML device element.
+ * @return virtual machine device instance.
+ */
+ public static Device newInstance( LibvirtXmlNode xmlNode )
+ {
+
+ Node element = xmlNode.getXmlElement();
+
+ if ( element == null ) {
+ return null;
+ } else {
+ Device device = null;
+ Type type = Type.fromString( element.getNodeName() );
+
+ if ( type == null ) {
+ return null;
+ }
+
+ switch ( type ) {
+ case CONTROLLER:
+ device = Controller.newInstance( xmlNode );
+ break;
+ case DISK:
+ device = Disk.newInstance( xmlNode );
+ break;
+ case FILESYSTEM:
+ device = FileSystem.newInstance( xmlNode );
+ break;
+ case HOSTDEV:
+ device = Hostdev.newInstance( xmlNode );
+ break;
+ case INTERFACE:
+ device = Interface.newInstance( xmlNode );
+ break;
+ case GRAPHICS:
+ device = Graphics.newInstance( xmlNode );
+ break;
+ case PARALLEL:
+ device = Parallel.newInstance( xmlNode );
+ break;
+ case SERIAL:
+ device = Serial.newInstance( xmlNode );
+ break;
+ case SHMEM:
+ device = Shmem.newInstance( xmlNode );
+ break;
+ case SOUND:
+ device = Sound.newInstance( xmlNode );
+ break;
+ case VIDEO:
+ device = Video.newInstance( xmlNode );
+ break;
+ }
+
+ return device;
+ }
+ }
+
+ /**
+ * Sets the PCI device address for an XML address element selected by a XPath expression.
+ *
+ * @param expression XPath expression to select the XML address element.
+ * @param address PCI device address for the selected XML address element.
+ */
+ protected void setPciAddress( final String expression, final HostdevPciDeviceAddress address )
+ {
+ final String pciDomain = HostdevUtils.appendHexPrefix( address.getPciDomainAsString() );
+ final String pciBus = HostdevUtils.appendHexPrefix( address.getPciBusAsString() );
+ final String pciDevice = HostdevUtils.appendHexPrefix( address.getPciDeviceAsString() );
+ final String pciFunction = HostdevUtils.appendHexPrefix( address.getPciFunctionAsString() );
+
+ this.setXmlElementAttributeValue( expression, "domain", pciDomain );
+ this.setXmlElementAttributeValue( expression, "bus", pciBus );
+ this.setXmlElementAttributeValue( expression, "slot", pciDevice );
+ this.setXmlElementAttributeValue( expression, "function", pciFunction );
+ }
+
+ /**
+ * Returns the PCI device address from an address XML element selected by a XPath expression.
+ *
+ * @param expression XPath expression to select the XML address element.
+ * @return PCI device address from the selected XML address element.
+ */
+ protected HostdevPciDeviceAddress getPciAddress( final String expression )
+ {
+ String pciDomain = this.getXmlElementAttributeValue( expression, "domain" );
+ String pciBus = this.getXmlElementAttributeValue( expression, "bus" );
+ String pciDevice = this.getXmlElementAttributeValue( expression, "slot" );
+ String pciFunction = this.getXmlElementAttributeValue( expression, "function" );
+
+ pciDomain = HostdevUtils.removeHexPrefix( pciDomain );
+ pciBus = HostdevUtils.removeHexPrefix( pciBus );
+ pciDevice = HostdevUtils.removeHexPrefix( pciDevice );
+ pciFunction = HostdevUtils.removeHexPrefix( pciFunction );
+
+ return HostdevPciDeviceAddress.valueOf( pciDomain + ":" + pciBus + ":" + pciDevice + "." + pciFunction );
+ }
+
+ /**
+ * Returns this devices PCI bus address, or null if it doesn't have an explicit one
+ * set, or if the address type isn't PCI.
+ */
+ public HostdevPciDeviceAddress getPciTarget()
+ {
+ if ( !"pci".equals( this.getXmlElementAttributeValue( "address", "type" ) ) )
+ return null;
+ return this.getPciAddress( "address" );
+ }
+
+ public void setPciTarget( HostdevPciDeviceAddress address )
+ {
+ this.setPciAddress( "address", address );
+ this.setXmlElementAttributeValue( "address", "type", "pci" );
+ }
+
+ /**
+ * Type of virtual machine devices.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+ enum Type
+ {
+ // @formatter:off
+ CONTROLLER( "controller" ),
+ DISK ( "disk" ),
+ FILESYSTEM( "filesystem" ),
+ HOSTDEV ( "hostdev" ),
+ INTERFACE ( "interface" ),
+ GRAPHICS ( "graphics" ),
+ PARALLEL ( "parallel" ),
+ SERIAL ( "serial" ),
+ SHMEM ( "shmem" ),
+ SOUND ( "sound" ),
+ VIDEO ( "video" );
+ // @formatter:on
+
+ /**
+ * Name of the virtual machine device type.
+ */
+ private String type = null;
+
+ /**
+ * Creates virtual machine device type.
+ *
+ * @param type valid name of the virtual machine device type in a Libvirt domain XML document.
+ */
+ Type( String type )
+ {
+ this.type = type;
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.type;
+ }
+
+ /**
+ * Creates virtual machine device type from its name with error check.
+ *
+ * @param type name of the virtual machine device type in a Libvirt domain XML document.
+ * @return valid virtual machine device type.
+ */
+ public static Type fromString( String type )
+ {
+ for ( Type t : Type.values() ) {
+ if ( t.type.equalsIgnoreCase( type ) ) {
+ return t;
+ }
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/Disk.java b/src/main/java/org/openslx/libvirt/domain/device/Disk.java
new file mode 100644
index 0000000..7694538
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/Disk.java
@@ -0,0 +1,427 @@
+package org.openslx.libvirt.domain.device;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+import org.w3c.dom.Node;
+
+/**
+ * A disk (floppy, CDROM, ...) device node in a Libvirt domain XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class Disk extends Device
+{
+ /**
+ * Creates an empty disk device.
+ */
+ public Disk()
+ {
+ super();
+ }
+
+ /**
+ * Creates a disk device representing an existing Libvirt XML disk device element.
+ *
+ * @param xmlNode existing Libvirt XML disk device element.
+ */
+ public Disk( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Returns storage type of the disk device.
+ *
+ * @return storage type of underlying source for the disk device.
+ */
+ public StorageType getStorageType()
+ {
+ String storageType = this.getXmlElementAttributeValue( "type" );
+ return StorageType.fromString( storageType );
+ }
+
+ /**
+ * Sets storage type for the disk device.
+ *
+ * @param storageType storage type of underlying source for the disk device.
+ *
+ * @implNote Please call {@link #setStorageSource(String)} after calling this method, otherwise
+ * the underlying source for the disk device may be invalid.
+ */
+ protected void setStorageType( StorageType storageType )
+ {
+ this.setXmlElementAttributeValue( "type", storageType.toString() );
+ }
+
+ /**
+ * Returns underlying source of disk device.
+ *
+ * @return file path to underlying source of disk device.
+ */
+ public String getStorageSource()
+ {
+ StorageType storageType = this.getStorageType();
+ String storageSource = null;
+
+ switch ( storageType ) {
+ case FILE:
+ storageSource = this.getXmlElementAttributeValue( "source", "file" );
+ break;
+ case BLOCK:
+ storageSource = this.getXmlElementAttributeValue( "source", "dev" );
+ break;
+ }
+
+ return storageSource;
+ }
+
+ /**
+ * Sets underlying source for disk device.
+ *
+ * @param source file path to underlying source for disk device.
+ *
+ * @implNote Please call {@link #setStorageType(StorageType)} before calling this method,
+ * otherwise the underlying source for the disk device is not set.
+ */
+ protected void setStorageSource( String source )
+ {
+ StorageType storageType = this.getStorageType();
+
+ // remove all attributes from sub-element 'source'
+ this.removeXmlElementAttributes( "source" );
+
+ // rewrite specific attribute depending on the storage type
+ switch ( storageType ) {
+ case FILE:
+ this.setXmlElementAttributeValue( "source", "file", source );
+ break;
+ case BLOCK:
+ this.setXmlElementAttributeValue( "source", "dev", source );
+ break;
+ }
+ }
+
+ /**
+ * Sets storage type and underlying source for disk device.
+ *
+ * @param storageType storage type of underlying source for the disk device.
+ * @param source file path to underlying source for disk device.
+ */
+ public void setStorage( StorageType storageType, String source )
+ {
+ this.setStorageType( storageType );
+ this.setStorageSource( source );
+ }
+
+ /**
+ * Removes underlying source of the disk device.
+ *
+ * @implNote Calling this method will result in an invalid Libvirt domain XML content.
+ */
+ public void removeStorage()
+ {
+ this.removeXmlElement( "source" );
+ }
+
+ /**
+ * Removes boot oder entry of the disk device.
+ */
+ public void removeBootOrder()
+ {
+ this.removeXmlElement( "boot" );
+ }
+
+ /**
+ * Returns read only state of disk device.
+ *
+ * @return read only state of disk device.
+ */
+ public boolean isReadOnly()
+ {
+ Node readOnly = this.getXmlElement( "readonly" );
+
+ if ( readOnly == null ) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * Sets read only state for disk device.
+ *
+ * @param readOnly state for disk device and its read only functionality.
+ */
+ public void setReadOnly( boolean readOnly )
+ {
+ if ( readOnly ) {
+ this.setXmlElement( "readonly" );
+ } else {
+ this.removeXmlElement( "readonly" );
+ }
+ }
+
+ /**
+ * Returns bus type of the disk device.
+ *
+ * @return bus type of the disk device.
+ */
+ public BusType getBusType()
+ {
+ String busType = this.getXmlElementAttributeValue( "target", "bus" );
+ return BusType.fromString( busType );
+ }
+
+ /**
+ * Sets bus type for the disk device.
+ *
+ * @param busType bus type for the disk device.
+ */
+ public void setBusType( BusType busType )
+ {
+ this.setXmlElementAttributeValue( "target", "bus", busType.toString() );
+ }
+
+ /**
+ * Returns target device of the disk device.
+ *
+ * @return target device of the disk device.
+ */
+ public String getTargetDevice()
+ {
+ return this.getXmlElementAttributeValue( "target", "dev" );
+ }
+
+ /**
+ * Sets target device for the disk device.
+ *
+ * @param targetDevice target device for the disk device.
+ */
+ public void setTargetDevice( String targetDevice )
+ {
+ this.setXmlElementAttributeValue( "target", "dev", targetDevice );
+ }
+
+ /**
+ * Creates a non-existent disk device as Libvirt XML device element.
+ *
+ * @param disk disk device that is created.
+ * @param xmlNode Libvirt XML node of the Libvirt XML device that is created.
+ * @return created disk device instance.
+ */
+ public static Disk createInstance( Disk disk, LibvirtXmlNode xmlNode )
+ {
+ Disk addedDisk = null;
+
+ if ( disk instanceof DiskCdrom ) {
+ xmlNode.setXmlElementAttributeValue( "device", Type.CDROM.toString() );
+ addedDisk = DiskCdrom.createInstance( xmlNode );
+ } else if ( disk instanceof DiskFloppy ) {
+ xmlNode.setXmlElementAttributeValue( "device", Type.FLOPPY.toString() );
+ addedDisk = DiskFloppy.createInstance( xmlNode );
+ } else if ( disk instanceof DiskStorage ) {
+ xmlNode.setXmlElementAttributeValue( "device", Type.STORAGE.toString() );
+ addedDisk = DiskStorage.createInstance( xmlNode );
+ }
+
+ return addedDisk;
+ }
+
+ /**
+ * Creates a disk device representing an existing Libvirt XML disk device element.
+ *
+ * @param xmlNode existing Libvirt XML disk device element.
+ * @return disk device instance.
+ */
+ public static Disk newInstance( LibvirtXmlNode xmlNode )
+ {
+ Disk deviceDisk = null;
+ Type type = Type.fromString( xmlNode.getXmlElementAttributeValue( "device" ) );
+
+ if ( type == null ) {
+ return null;
+ }
+
+ switch ( type ) {
+ case CDROM:
+ deviceDisk = DiskCdrom.newInstance( xmlNode );
+ break;
+ case FLOPPY:
+ deviceDisk = DiskFloppy.newInstance( xmlNode );
+ break;
+ case STORAGE:
+ deviceDisk = DiskStorage.newInstance( xmlNode );
+ break;
+ }
+
+ return deviceDisk;
+ }
+
+ /**
+ * Type of disk device.
+ *
+ * Indicates how a disk is to be exposed to the guest OS.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+ enum Type
+ {
+ // @formatter:off
+ CDROM ( "cdrom" ),
+ FLOPPY ( "floppy" ),
+ STORAGE( "disk" );
+ // @formatter:on
+
+ /**
+ * Name of the disk device type.
+ */
+ private String type = null;
+
+ /**
+ * Creates disk device type.
+ *
+ * @param type valid name of the disk device type in a Libvirt domain XML document.
+ */
+ Type( String type )
+ {
+ this.type = type;
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.type;
+ }
+
+ /**
+ * Creates disk device type from its name with error check.
+ *
+ * @param type name of the disk device type in a Libvirt domain XML document.
+ * @return valid disk device type.
+ */
+ public static Type fromString( String type )
+ {
+ for ( Type t : Type.values() ) {
+ if ( t.type.equalsIgnoreCase( type ) ) {
+ return t;
+ }
+ }
+
+ return null;
+ }
+ }
+
+ /**
+ * Storage type of a disk device.
+ *
+ * The storage type refers to the underlying source for the disk.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+ public enum StorageType
+ {
+ // @formatter:off
+ FILE ( "file" ),
+ BLOCK ( "block" );
+ // @formatter:on
+
+ /**
+ * Name of the disk device type.
+ */
+ private String storageType = null;
+
+ /**
+ * Creates disk device storage type.
+ *
+ * @param storageType valid name of the disk device storage type in a Libvirt domain XML
+ * document.
+ */
+ StorageType( String storageType )
+ {
+ this.storageType = storageType;
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.storageType;
+ }
+
+ /**
+ * Creates disk device storage type from its name with error check.
+ *
+ * @param storageType name of the disk device storage type in a Libvirt domain XML document.
+ * @return valid disk device storage type.
+ */
+ public static StorageType fromString( String storageType )
+ {
+ for ( StorageType t : StorageType.values() ) {
+ if ( t.storageType.equalsIgnoreCase( storageType ) ) {
+ return t;
+ }
+ }
+
+ return null;
+ }
+ }
+
+ /**
+ * Bus type (IDE, SATA, ...) of a disk device.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+ public enum BusType
+ {
+ // @formatter:off
+ IDE ( "ide" ),
+ FDC ( "fdc" ),
+ SATA ( "sata" ),
+ SCSI ( "scsi" ),
+ SD ( "sd" ),
+ USB ( "usb" ),
+ VIRTIO( "virtio" ),
+ XEN ( "xen" );
+ // @formatter:on
+
+ /**
+ * Name of the disk device bus type.
+ */
+ private String busType = null;
+
+ /**
+ * Creates disk device bus type.
+ *
+ * @param busType valid name of the disk device bus type in a Libvirt domain XML document.
+ */
+ BusType( String busType )
+ {
+ this.busType = busType;
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.busType;
+ }
+
+ /**
+ * Creates disk device bus type from its name with error check.
+ *
+ * @param busType name of the disk device bus type in a Libvirt domain XML document.
+ * @return valid disk device bus type.
+ */
+ public static BusType fromString( String busType )
+ {
+ for ( BusType t : BusType.values() ) {
+ if ( t.busType.equalsIgnoreCase( busType ) ) {
+ return t;
+ }
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/DiskCdrom.java b/src/main/java/org/openslx/libvirt/domain/device/DiskCdrom.java
new file mode 100644
index 0000000..2ae08e1
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/DiskCdrom.java
@@ -0,0 +1,55 @@
+package org.openslx.libvirt.domain.device;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+
+/**
+ * A CDROM disk device node in a Libvirt domain XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class DiskCdrom extends Disk
+{
+ /**
+ * Creates an empty CDROM disk device.
+ */
+ public DiskCdrom()
+ {
+ super();
+ }
+
+ /**
+ * Creates a CDROM disk device representing an existing Libvirt XML CDROM disk device element.
+ *
+ * @param xmlNode existing Libvirt XML CDROM disk device element.
+ */
+ public DiskCdrom( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+
+ // restrict CDROM disk device default read/write access always to readonly
+ this.setReadOnly( true );
+ }
+
+ /**
+ * Creates a non-existent CDROM disk device as Libvirt XML device element.
+ *
+ * @param xmlNode Libvirt XML node of the Libvirt XML device that is created.
+ * @return created CDROM disk device instance.
+ */
+ public static DiskCdrom createInstance( LibvirtXmlNode xmlNode )
+ {
+ return DiskCdrom.newInstance( xmlNode );
+ }
+
+ /**
+ * Creates a CDROM disk device representing an existing Libvirt XML CDROM disk device element.
+ *
+ * @param xmlNode existing Libvirt XML CDROM disk device element.
+ * @return CDROM disk device instance.
+ */
+ public static DiskCdrom newInstance( LibvirtXmlNode xmlNode )
+ {
+ return new DiskCdrom( xmlNode );
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/DiskFloppy.java b/src/main/java/org/openslx/libvirt/domain/device/DiskFloppy.java
new file mode 100644
index 0000000..ce9733b
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/DiskFloppy.java
@@ -0,0 +1,52 @@
+package org.openslx.libvirt.domain.device;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+
+/**
+ * A floppy disk device node in a Libvirt domain XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class DiskFloppy extends Disk
+{
+ /**
+ * Creates an empty floppy disk device.
+ */
+ public DiskFloppy()
+ {
+ super();
+ }
+
+ /**
+ * Creates a floppy disk device representing an existing Libvirt XML floppy disk device element.
+ *
+ * @param xmlNode existing Libvirt XML floppy disk device element.
+ */
+ public DiskFloppy( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Creates a non-existent floppy disk device as Libvirt XML device element.
+ *
+ * @param xmlNode Libvirt XML node of the Libvirt XML device that is created.
+ * @return created floppy disk device instance.
+ */
+ public static DiskFloppy createInstance( LibvirtXmlNode xmlNode )
+ {
+ return DiskFloppy.newInstance( xmlNode );
+ }
+
+ /**
+ * Creates a floppy disk device representing an existing Libvirt XML floppy disk device element.
+ *
+ * @param xmlNode existing Libvirt XML floppy disk device element.
+ * @return floppy disk device instance.
+ */
+ public static DiskFloppy newInstance( LibvirtXmlNode xmlNode )
+ {
+ return new DiskFloppy( xmlNode );
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/DiskStorage.java b/src/main/java/org/openslx/libvirt/domain/device/DiskStorage.java
new file mode 100644
index 0000000..7fca789
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/DiskStorage.java
@@ -0,0 +1,54 @@
+package org.openslx.libvirt.domain.device;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+
+/**
+ * A storage (HDD, SSD, ...) disk device node in a Libvirt domain XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class DiskStorage extends Disk
+{
+ /**
+ * Creates an empty storage disk device.
+ */
+ public DiskStorage()
+ {
+ super();
+ }
+
+ /**
+ * Creates a storage disk device representing an existing Libvirt XML storage disk device
+ * element.
+ *
+ * @param xmlNode existing Libvirt XML storage disk device element.
+ */
+ public DiskStorage( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Creates a non-existent storage disk device as Libvirt XML device element.
+ *
+ * @param xmlNode Libvirt XML node of the Libvirt XML device that is created.
+ * @return created storage disk device instance.
+ */
+ public static DiskStorage createInstance( LibvirtXmlNode xmlNode )
+ {
+ return DiskStorage.newInstance( xmlNode );
+ }
+
+ /**
+ * Creates a storage disk device representing an existing Libvirt XML storage disk device
+ * element.
+ *
+ * @param xmlNode existing Libvirt XML storage disk device element.
+ * @return storage disk device instance.
+ */
+ public static DiskStorage newInstance( LibvirtXmlNode xmlNode )
+ {
+ return new DiskStorage( xmlNode );
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/FileSystem.java b/src/main/java/org/openslx/libvirt/domain/device/FileSystem.java
new file mode 100644
index 0000000..9ec8caf
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/FileSystem.java
@@ -0,0 +1,292 @@
+package org.openslx.libvirt.domain.device;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+
+/**
+ * A file system device node in a Libvirt domain XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class FileSystem extends Device
+{
+ /**
+ * Creates an empty file system device.
+ */
+ public FileSystem()
+ {
+ super();
+ }
+
+ /**
+ * Creates a file system device representing an existing Libvirt XML file system device element.
+ *
+ * @param xmlNode existing Libvirt XML file system device element.
+ */
+ public FileSystem( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Returns access mode of the file system device.
+ *
+ * @return access mode of the file system device.
+ */
+ public AccessMode getAccessMode()
+ {
+ final String mode = this.getXmlElementAttributeValue( "accessmode" );
+ return AccessMode.fromString( mode );
+ }
+
+ /**
+ * Sets access mode for the file system device.
+ *
+ * @param mode access mode for the file system device.
+ */
+ public void setAccessMode( AccessMode mode )
+ {
+ this.setXmlElementAttributeValue( "accessmode", mode.toString() );
+ }
+
+ /**
+ * Returns type of the file system device.
+ *
+ * @return type of the file system device.
+ */
+ public Type getType()
+ {
+ final String type = this.getXmlElementAttributeValue( "type" );
+ return Type.fromString( type );
+ }
+
+ /**
+ * Sets type for the file system device.
+ *
+ * @param type type for the file system device.
+ */
+ public void setType( Type type )
+ {
+ this.setXmlElementAttributeValue( "type", type.toString() );
+ }
+
+ /**
+ * Returns source of the file system device.
+ *
+ * @return source of the file system device.
+ */
+ public String getSource()
+ {
+ final Type type = this.getType();
+ String source = null;
+
+ switch ( type ) {
+ case BIND:
+ source = this.getXmlElementAttributeValue( "source", "dir" );
+ break;
+ case BLOCK:
+ source = this.getXmlElementAttributeValue( "source", "dev" );
+ break;
+ case FILE:
+ source = this.getXmlElementAttributeValue( "source", "file" );
+ break;
+ case MOUNT:
+ source = this.getXmlElementAttributeValue( "source", "dir" );
+ break;
+ case RAM:
+ source = this.getXmlElementAttributeValue( "source", "usage" );
+ break;
+ case TEMPLATE:
+ source = this.getXmlElementAttributeValue( "source", "name" );
+ break;
+ }
+
+ return source;
+ }
+
+ /**
+ * Sets source for the file system device.
+ *
+ * @param source source for the file system device.
+ */
+ public void setSource( String source )
+ {
+ Type type = this.getType();
+
+ // remove all attributes from sub-element 'source'
+ this.removeXmlElementAttributes( "source" );
+
+ switch ( type ) {
+ case BIND:
+ this.setXmlElementAttributeValue( "source", "dir", source );
+ break;
+ case BLOCK:
+ this.setXmlElementAttributeValue( "source", "dev", source );
+ break;
+ case FILE:
+ this.setXmlElementAttributeValue( "source", "file", source );
+ break;
+ case MOUNT:
+ this.setXmlElementAttributeValue( "source", "dir", source );
+ break;
+ case RAM:
+ this.setXmlElementAttributeValue( "source", "usage", source );
+ break;
+ case TEMPLATE:
+ this.setXmlElementAttributeValue( "source", "name", source );
+ break;
+ }
+ }
+
+ /**
+ * Returns target of the file system device.
+ *
+ * @return target of the file system device.
+ */
+ public String getTarget()
+ {
+ return this.getXmlElementAttributeValue( "target", "dir" );
+ }
+
+ /**
+ * Sets target for the file system device.
+ *
+ * @param target target for the file system device.
+ */
+ public void setTarget( String target )
+ {
+ this.setXmlElementAttributeValue( "target", "dir", target );
+ }
+
+ /**
+ * Creates a non-existent file system device as Libvirt XML device element.
+ *
+ * @param xmlNode Libvirt XML node of the Libvirt XML device that is created.
+ * @return created file system device instance.
+ */
+ public static FileSystem createInstance( LibvirtXmlNode xmlNode )
+ {
+ return FileSystem.newInstance( xmlNode );
+ }
+
+ /**
+ * Creates a file system device representing an existing Libvirt XML file system device element.
+ *
+ * @param xmlNode existing Libvirt XML file system device element.
+ * @return file system device instance.
+ */
+ public static FileSystem newInstance( LibvirtXmlNode xmlNode )
+ {
+ return new FileSystem( xmlNode );
+ }
+
+ /**
+ * Access mode for the file system device.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+ public enum AccessMode
+ {
+ // @formatter:off
+ PASSTHROUGH( "passthrough" ),
+ MAPPED ( "mapped" ),
+ SQUASH ( "squash" );
+ // @formatter:on
+
+ /**
+ * Name of the file system device access mode.
+ */
+ private String mode;
+
+ /**
+ * Creates file system device access mode.
+ *
+ * @param mode valid name of the file system device access mode in a Libvirt domain XML
+ * document.
+ */
+ AccessMode( String mode )
+ {
+ this.mode = mode;
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.mode;
+ }
+
+ /**
+ * Creates file system device access mode from its name with error check.
+ *
+ * @param mode name of the file system device access mode in a Libvirt domain XML document.
+ * @return valid file system device access mode.
+ */
+ public static AccessMode fromString( String mode )
+ {
+ for ( AccessMode a : AccessMode.values() ) {
+ if ( a.mode.equalsIgnoreCase( mode ) ) {
+ return a;
+ }
+ }
+
+ return null;
+ }
+ }
+
+ /**
+ * Type of file system device.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+ public enum Type
+ {
+ // @formatter:off
+ MOUNT ( "mount" ),
+ TEMPLATE( "template" ),
+ FILE ( "file" ),
+ BLOCK ( "block" ),
+ RAM ( "ram" ),
+ BIND ( "bind" );
+ // @formatter:on
+
+ /**
+ * Name of the file system device type.
+ */
+ private String type;
+
+ /**
+ * Creates file system device type.
+ *
+ * @param type valid name of the file system device type in a Libvirt domain XML document.
+ */
+ Type( String type )
+ {
+ this.type = type;
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.type;
+ }
+
+ /**
+ * Creates file system device type from its name with error check.
+ *
+ * @param type name of the file system device type in a Libvirt domain XML document.
+ * @return valid file system device type.
+ */
+ public static Type fromString( String type )
+ {
+ for ( Type t : Type.values() ) {
+ if ( t.type.equalsIgnoreCase( type ) ) {
+ return t;
+ }
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/Graphics.java b/src/main/java/org/openslx/libvirt/domain/device/Graphics.java
new file mode 100644
index 0000000..3fd2f81
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/Graphics.java
@@ -0,0 +1,269 @@
+package org.openslx.libvirt.domain.device;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+
+/**
+ * A graphics (display) device node in a Libvirt domain XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class Graphics extends Device
+{
+ /**
+ * Creates an empty graphics device.
+ */
+ public Graphics()
+ {
+ super();
+ }
+
+ /**
+ * Creates a graphics device representing an existing Libvirt XML graphics device element.
+ *
+ * @param xmlNode existing Libvirt XML graphics device element.
+ */
+ public Graphics( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Returns the listen type of the graphics device.
+ *
+ * @return listen type of the graphics device.
+ */
+ public ListenType getListenType()
+ {
+ final String listenType = this.getXmlElementAttributeValue( "listen", "type" );
+ return ListenType.fromString( listenType );
+ }
+
+ /**
+ * Sets the listen type for the graphics device.
+ *
+ * @param type listen type for the graphics device.
+ */
+ public void setListenType( ListenType type )
+ {
+ this.setXmlElementAttributeValue( "listen", "type", type.toString() );
+ }
+
+ /**
+ * Returns the listen address of the graphics device.
+ *
+ * @return listen address of the graphics device.
+ */
+ public InetAddress getListenAddress()
+ {
+ InetAddress parsedListenAddress = null;
+
+ if ( this.getListenType() == ListenType.ADDRESS ) {
+ // only read listen address, if address listen type is set
+ final String rawListenAddress = this.getXmlElementAttributeValue( "listen", "address" );
+
+ try {
+ parsedListenAddress = InetAddress.getByName( rawListenAddress );
+ } catch ( UnknownHostException e ) {
+ parsedListenAddress = null;
+ }
+ }
+
+ return parsedListenAddress;
+ }
+
+ /**
+ * Sets the listen address for the graphics device.
+ *
+ * @param listenAddress listen address for the graphics device.
+ */
+ public void setListenAddress( InetAddress listenAddress )
+ {
+ if ( this.getListenType() == ListenType.ADDRESS && listenAddress != null ) {
+ // only set listen address, if address listen type is set
+ this.setXmlElementAttributeValue( "listen", "address", listenAddress.getHostAddress() );
+ }
+ }
+
+ /**
+ * Returns the listen port of the graphics device.
+ *
+ * @return listen port of the graphics device.
+ */
+ public int getListenPort()
+ {
+ final String listenPort = this.getXmlElementAttributeValue( "port" );
+ return Integer.valueOf( listenPort );
+ }
+
+ /**
+ * Sets the listen port for the graphics device.
+ *
+ * @param listenPort listen port for the graphics device.
+ */
+ public void setListenPort( int listenPort )
+ {
+ if ( this.getListenType() == ListenType.ADDRESS ) {
+ // only set listen port, if address listen type is set
+ this.setXmlElementAttributeValue( "port", Integer.toString( listenPort ) );
+ }
+ }
+
+ /**
+ * Creates a non-existent graphics device as Libvirt XML device element.
+ *
+ * @param graphics graphics device that is created.
+ * @param xmlNode Libvirt XML node of the Libvirt XML device that is created.
+ * @return created graphics device instance.
+ */
+ public static Graphics createInstance( Graphics graphics, LibvirtXmlNode xmlNode )
+ {
+ Graphics addedGraphics = null;
+
+ if ( graphics instanceof GraphicsSpice ) {
+ xmlNode.setXmlElementAttributeValue( "type", Type.SPICE.toString() );
+ addedGraphics = GraphicsSpice.createInstance( xmlNode );
+ } else if ( graphics instanceof GraphicsVnc ) {
+ xmlNode.setXmlElementAttributeValue( "type", Type.VNC.toString() );
+ addedGraphics = GraphicsVnc.createInstance( xmlNode );
+ }
+
+ return addedGraphics;
+ }
+
+ /**
+ * Creates a graphics device representing an existing Libvirt XML graphics device element.
+ *
+ * @param xmlNode existing Libvirt XML graphics device element.
+ * @return graphics device instance.
+ */
+ public static Graphics newInstance( LibvirtXmlNode xmlNode )
+ {
+ Graphics deviceGraphics = null;
+ Type type = Type.fromString( xmlNode.getXmlElementAttributeValue( "type" ) );
+
+ if ( type == null ) {
+ return null;
+ }
+
+ switch ( type ) {
+ case SPICE:
+ deviceGraphics = GraphicsSpice.newInstance( xmlNode );
+ break;
+ case VNC:
+ deviceGraphics = GraphicsVnc.newInstance( xmlNode );
+ break;
+ }
+
+ return deviceGraphics;
+ }
+
+ /**
+ * Listen type of graphics device.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+ public enum ListenType
+ {
+ // @formatter:off
+ NONE ( "none" ),
+ ADDRESS( "address" ),
+ NETWORK( "network" ),
+ SOCKET ( "socket" );
+ // @formatter:on
+
+ /**
+ * Name of graphics device listen type.
+ */
+ private String type = null;
+
+ /**
+ * Creates graphics device listen type.
+ *
+ * @param type valid name of the graphics device listen type in a Libvirt domain XML document.
+ */
+ ListenType( String type )
+ {
+ this.type = type;
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.type;
+ }
+
+ /**
+ * Creates graphics device listen type from its name with error check.
+ *
+ * @param type name of the graphics device listen type in a Libvirt domain XML document.
+ * @return valid graphics device listen type.
+ */
+ public static ListenType fromString( String type )
+ {
+ for ( ListenType t : ListenType.values() ) {
+ if ( t.type.equalsIgnoreCase( type ) ) {
+ return t;
+ }
+ }
+
+ return null;
+ }
+ }
+
+ /**
+ * Type of graphics device.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+ enum Type
+ {
+ // @formatter:off
+ SPICE( "spice" ),
+ VNC ( "vnc" );
+ // @formatter:on
+
+ /**
+ * Name of graphics device type.
+ */
+ private String type = null;
+
+ /**
+ * Creates graphics device type.
+ *
+ * @param type valid name of the graphics device type in a Libvirt domain XML document.
+ */
+ Type( String type )
+ {
+ this.type = type;
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.type;
+ }
+
+ /**
+ * Creates graphics device type from its name with error check.
+ *
+ * @param type name of the graphics device type in a Libvirt domain XML document.
+ * @return valid graphics device type.
+ */
+ public static Type fromString( String type )
+ {
+ for ( Type t : Type.values() ) {
+ if ( t.type.equalsIgnoreCase( type ) ) {
+ return t;
+ }
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/GraphicsSpice.java b/src/main/java/org/openslx/libvirt/domain/device/GraphicsSpice.java
new file mode 100644
index 0000000..be67200
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/GraphicsSpice.java
@@ -0,0 +1,261 @@
+package org.openslx.libvirt.domain.device;
+
+import java.net.InetAddress;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+
+/**
+ * A graphics SPICE device node in a Libvirt domain XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class GraphicsSpice extends Graphics
+{
+ /**
+ * Default address of a SPICE graphics listener.
+ */
+ public static final InetAddress DEFAULT_ADDRESS = InetAddress.getLoopbackAddress();
+
+ /**
+ * Default port of a SPICE graphics listener.
+ */
+ public static final int DEFAULT_PORT = 59000;
+
+ /**
+ * Creates an empty graphics SPICE device.
+ */
+ public GraphicsSpice()
+ {
+ super();
+ }
+
+ /**
+ * Creates a graphics SPICE device representing an existing Libvirt XML graphics SPICE device
+ * element.
+ *
+ * @param xmlNode existing Libvirt XML graphics SPCIE device element.
+ */
+ public GraphicsSpice( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Returns the state whether OpenGL hardware acceleration is enabled or not.
+ *
+ * @return state whether OpenGL hardware acceleration is enabled or not.
+ */
+ public boolean isOpenGlEnabled()
+ {
+ return this.getXmlElementAttributeValueAsBool( "gl", "enable" );
+ }
+
+ /**
+ * Sets the state whether OpenGL hardware acceleration is enabled or not.
+ *
+ * @param enabled state whether OpenGL hardware acceleration is enabled or not.
+ */
+ public void setOpenGl( boolean enabled )
+ {
+ this.setXmlElementAttributeValueYesNo( "gl", "enable", enabled );
+ }
+
+ /**
+ * Returns the image compression type.
+ *
+ * @return image compression type.
+ */
+ public ImageCompression getImageCompression()
+ {
+ final String imageCompression = this.getXmlElementAttributeValue( "image", "compression" );
+ return ImageCompression.fromString( imageCompression );
+ }
+
+ /**
+ * Sets the image compression type.
+ *
+ * @param type image compression type.
+ */
+ public void setImageCompression( ImageCompression type )
+ {
+ this.setXmlElementAttributeValue( "image", "compression", type.toString() );
+ }
+
+ /**
+ * Checks if audio playback compression is enabled or not.
+ *
+ * @return state whether audio playback compression is enabled or not.
+ */
+ public boolean isPlaybackCompressionOn()
+ {
+ return this.getXmlElementAttributeValueAsBool( "playback", "compression" );
+ }
+
+ /**
+ * Sets the state whether audio playback compression is enabled or not.
+ *
+ * @param enabled state whether audio playback compression is enabled or not.
+ */
+ public void setPlaybackCompression( boolean enabled )
+ {
+ this.setXmlElementAttributeValueOnOff( "playback", "compression", enabled );
+ }
+
+ /**
+ * Returns the streaming mode.
+ *
+ * @return streaming mode type.
+ */
+ public StreamingMode getStreamingMode()
+ {
+ final String streamingMode = this.getXmlElementAttributeValue( "streaming", "mode" );
+ return StreamingMode.fromString( streamingMode );
+ }
+
+ /**
+ * Sets the streaming mode.
+ *
+ * @param type streaming mode type.
+ */
+ public void setStreamingMode( StreamingMode type )
+ {
+ this.setXmlElementAttributeValue( "streaming", "mode", type.toString() );
+ }
+
+ /**
+ * Creates a non-existent graphics SPICE device as Libvirt XML device element.
+ *
+ * @param xmlNode Libvirt XML node of the Libvirt XML device that is created.
+ * @return created graphics SPICE device instance.
+ */
+ public static GraphicsSpice createInstance( LibvirtXmlNode xmlNode )
+ {
+ return GraphicsSpice.newInstance( xmlNode );
+ }
+
+ /**
+ * Creates a graphics SPICE device representing an existing Libvirt XML graphics SPICE device
+ * element.
+ *
+ * @param xmlNode existing Libvirt XML graphics SPICE device element.
+ * @return graphics SPICE device instance.
+ */
+ public static GraphicsSpice newInstance( LibvirtXmlNode xmlNode )
+ {
+ return new GraphicsSpice( xmlNode );
+ }
+
+ /**
+ * Image compression type of graphics device.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+ public enum ImageCompression
+ {
+ // @formatter:off
+ AUTO_GLZ( "auto_glz" ),
+ AUTO_LZ ( "auto_lz" ),
+ QUIC ( "quic" ),
+ GLZ ( "glz" ),
+ LZ ( "lz" ),
+ OFF ( "off" );
+ // @formatter:on
+
+ /**
+ * Name of graphics device image compression type.
+ */
+ private String type = null;
+
+ /**
+ * Creates graphics device image compression type.
+ *
+ * @param type valid name of the graphics device image compression type in a Libvirt domain
+ * XML document.
+ */
+ ImageCompression( String type )
+ {
+ this.type = type;
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.type;
+ }
+
+ /**
+ * Creates graphics device image compression type from its name with error check.
+ *
+ * @param type name of the graphics device image compression type in a Libvirt domain XML
+ * document.
+ * @return valid graphics device image compression type.
+ */
+ public static ImageCompression fromString( String type )
+ {
+ for ( ImageCompression t : ImageCompression.values() ) {
+ if ( t.type.equalsIgnoreCase( type ) ) {
+ return t;
+ }
+ }
+
+ return null;
+ }
+ }
+
+ /**
+ * Streaming mode type of graphics device.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+ public enum StreamingMode
+ {
+ // @formatter:off
+ ALL ( "all" ),
+ FILTER( "filter" ),
+ OFF ( "off" );
+ // @formatter:on
+
+ /**
+ * Name of graphics device image compression type.
+ */
+ private String type = null;
+
+ /**
+ * Creates graphics device streaming mode type.
+ *
+ * @param type valid name of the graphics device streaming mode type in a Libvirt domain XML
+ * document.
+ */
+ StreamingMode( String type )
+ {
+ this.type = type;
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.type;
+ }
+
+ /**
+ * Creates graphics device streaming mode type from its name with error check.
+ *
+ * @param type name of the graphics device streaming mode type in a Libvirt domain XML
+ * document.
+ * @return valid graphics device streaming mode type.
+ */
+ public static StreamingMode fromString( String type )
+ {
+ for ( StreamingMode t : StreamingMode.values() ) {
+ if ( t.type.equalsIgnoreCase( type ) ) {
+ return t;
+ }
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/GraphicsVnc.java b/src/main/java/org/openslx/libvirt/domain/device/GraphicsVnc.java
new file mode 100644
index 0000000..f595699
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/GraphicsVnc.java
@@ -0,0 +1,54 @@
+package org.openslx.libvirt.domain.device;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+
+/**
+ * A graphics VNC device node in a Libvirt domain XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class GraphicsVnc extends Graphics
+{
+ /**
+ * Creates an empty graphics VNC device.
+ */
+ public GraphicsVnc()
+ {
+ super();
+ }
+
+ /**
+ * Creates a graphics VNC device representing an existing Libvirt XML graphics VNC device
+ * element.
+ *
+ * @param xmlNode existing Libvirt XML graphics VNC device element.
+ */
+ public GraphicsVnc( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Creates a non-existent graphics VNC device as Libvirt XML device element.
+ *
+ * @param xmlNode Libvirt XML node of the Libvirt XML device that is created.
+ * @return created graphics VNC device instance.
+ */
+ public static GraphicsVnc createInstance( LibvirtXmlNode xmlNode )
+ {
+ return GraphicsVnc.newInstance( xmlNode );
+ }
+
+ /**
+ * Creates a graphics VNC device representing an existing Libvirt XML graphics VNC device
+ * element.
+ *
+ * @param xmlNode existing Libvirt XML graphics VNC device element.
+ * @return graphics VNC device instance.
+ */
+ public static GraphicsVnc newInstance( LibvirtXmlNode xmlNode )
+ {
+ return new GraphicsVnc( xmlNode );
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/Hostdev.java b/src/main/java/org/openslx/libvirt/domain/device/Hostdev.java
new file mode 100644
index 0000000..dc9cf5e
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/Hostdev.java
@@ -0,0 +1,175 @@
+package org.openslx.libvirt.domain.device;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+
+/**
+ * A hostdev device node in a Libvirt domain XML document for PCI, USB, ... passthrough.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class Hostdev extends Device
+{
+ /**
+ * Creates an empty hostdev device.
+ */
+ public Hostdev()
+ {
+ super();
+ }
+
+ /**
+ * Creates a hostdev device representing an existing Libvirt XML hostdev device element.
+ *
+ * @param xmlNode existing Libvirt XML hostdev device element.
+ */
+ public Hostdev( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Checks if hostdev device is managed.
+ *
+ * If {@link #isManaged()} returns <code>true</code> the hostdev device is detached from the
+ * host before being passed on to the guest and reattached to the host after the guest exits.
+ *
+ * @return state whether hostdev device is managed.
+ */
+ public boolean isManaged()
+ {
+ return this.getXmlElementAttributeValueAsBool( "managed" );
+ }
+
+ /**
+ * Sets state whether hostdev device is managed.
+ *
+ * If the <code>managed</code> parameter is set to <code>true</code> the hostdev device is
+ * detached from the host before being passed on to the guest and reattached to the host after
+ * the guest exits.
+ *
+ * @param managed state whether hostdev device is managed or not.
+ */
+ public void setManaged( boolean managed )
+ {
+ this.setXmlElementAttributeValueYesNo( "managed", managed );
+ }
+
+ /**
+ * Removes boot oder entry of the hostdev device.
+ */
+ public void removeBootOrder()
+ {
+ this.removeXmlElement( "boot" );
+ }
+
+ /**
+ * Creates a non-existent hostdev device as Libvirt XML device element.
+ *
+ * @param hostdev hostdev device that is created.
+ * @param xmlNode Libvirt XML node of the Libvirt XML device that is created.
+ * @return created hostdev device instance.
+ */
+ public static Hostdev createInstance( Hostdev hostdev, LibvirtXmlNode xmlNode )
+ {
+ Hostdev addedHostdev = null;
+
+ xmlNode.setXmlElementAttributeValue( "mode", "subsystem" );
+
+ if ( hostdev instanceof HostdevMdev ) {
+ xmlNode.setXmlElementAttributeValue( "type", Type.MDEV.toString() );
+ addedHostdev = HostdevMdev.createInstance( xmlNode );
+ } else if ( hostdev instanceof HostdevPci ) {
+ xmlNode.setXmlElementAttributeValue( "type", Type.PCI.toString() );
+ addedHostdev = HostdevPci.createInstance( xmlNode );
+ } else if ( hostdev instanceof HostdevUsb ) {
+ xmlNode.setXmlElementAttributeValue( "type", Type.USB.toString() );
+ addedHostdev = HostdevUsb.createInstance( xmlNode );
+ }
+
+ return addedHostdev;
+ }
+
+ /**
+ * Creates a hostdev device representing an existing Libvirt XML hostdev device element.
+ *
+ * @param xmlNode existing Libvirt XML hostdev device element.
+ * @return hostdev device instance.
+ */
+ public static Hostdev newInstance( LibvirtXmlNode xmlNode )
+ {
+ Hostdev deviceHostdev = null;
+ Type type = Type.fromString( xmlNode.getXmlElementAttributeValue( "type" ) );
+
+ if ( type == null ) {
+ return null;
+ }
+
+ switch ( type ) {
+ case MDEV:
+ deviceHostdev = HostdevMdev.newInstance( xmlNode );
+ break;
+ case PCI:
+ deviceHostdev = HostdevPci.newInstance( xmlNode );
+ break;
+ case USB:
+ deviceHostdev = HostdevUsb.newInstance( xmlNode );
+ break;
+ }
+
+ return deviceHostdev;
+ }
+
+ /**
+ * Type of hostdev device subsystem passthrough.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+ enum Type
+ {
+ // @formatter:off
+ MDEV( "mdev" ),
+ PCI ( "pci" ),
+ USB ( "usb" );
+ // @formatter:on
+
+ /**
+ * Name of the hostdev device type.
+ */
+ private String type = null;
+
+ /**
+ * Creates hostdev device type.
+ *
+ * @param type valid name of the hostdev device type in a Libvirt domain XML document.
+ */
+ Type( String type )
+ {
+ this.type = type;
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.type;
+ }
+
+ /**
+ * Creates hostdev device type from its name with error check.
+ *
+ * @param type name of the hostdev device storage in a Libvirt domain XML document.
+ * @return valid hostdev device type.
+ */
+ public static Type fromString( String type )
+ {
+ for ( Type t : Type.values() ) {
+ if ( t.type.equalsIgnoreCase( type ) ) {
+ return t;
+ }
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/HostdevAddressableSource.java b/src/main/java/org/openslx/libvirt/domain/device/HostdevAddressableSource.java
new file mode 100644
index 0000000..9377421
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/HostdevAddressableSource.java
@@ -0,0 +1,26 @@
+package org.openslx.libvirt.domain.device;
+
+/**
+ * Addressable source operations for a hostdev device.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ *
+ * @param <T> type of the source.
+ */
+public abstract interface HostdevAddressableSource<T>
+{
+ /**
+ * Returns the source of the source device (on the Libvirt host).
+ *
+ * @return source of the source device (on the Libvirt host).
+ */
+ public T getSource();
+
+ /**
+ * Sets the source for the source device (on the Libvirt host).
+ *
+ * @param source source for the source device (on the Libvirt host).
+ */
+ public void setSource( T source );
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/HostdevAddressableTarget.java b/src/main/java/org/openslx/libvirt/domain/device/HostdevAddressableTarget.java
new file mode 100644
index 0000000..ca06065
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/HostdevAddressableTarget.java
@@ -0,0 +1,26 @@
+package org.openslx.libvirt.domain.device;
+
+/**
+ * Addressable target operations for a hostdev device.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ *
+ * @param <T> type of the target.
+ */
+public abstract interface HostdevAddressableTarget<T>
+{
+ /**
+ * Returns the target of the target device (in the virtual machine).
+ *
+ * @return target of the target device (in the virtual machine).
+ */
+ public T getPciTarget();
+
+ /**
+ * Sets the target for the target device (in the virtual machine).
+ *
+ * @param target target for the target device (in the virtual machine).
+ */
+ public void setPciTarget( T target );
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/HostdevMdev.java b/src/main/java/org/openslx/libvirt/domain/device/HostdevMdev.java
new file mode 100644
index 0000000..082ea5b
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/HostdevMdev.java
@@ -0,0 +1,182 @@
+package org.openslx.libvirt.domain.device;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+
+/**
+ * A hostdev mediated device node in a Libvirt domain XML document for mediated device passthrough.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class HostdevMdev extends Hostdev implements HostdevAddressableSource<HostdevMdevDeviceAddress>
+{
+ /**
+ * Creates an empty hostdev mediated device.
+ */
+ public HostdevMdev()
+ {
+ super();
+ }
+
+ /**
+ * Creates a hostdev mediated device representing an existing Libvirt XML hostdev mediated device
+ * element.
+ *
+ * @param xmlNode existing Libvirt XML hostdev mediated device element.
+ */
+ public HostdevMdev( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Checks whether the hostdev mediated device display is on or off.
+ *
+ * @return state whether the hostdev mediated device display is on or off.
+ */
+ public boolean isDisplayOn()
+ {
+ return this.getXmlElementAttributeValueAsBool( "display" );
+ }
+
+ /**
+ * Sets the state of the hostdev mediated device display.
+ *
+ * @param on state whether the hostdev mediated device display is on or off.
+ */
+ public void setDisplayOn( boolean on )
+ {
+ this.setXmlElementAttributeValueOnOff( "display", on );
+ }
+
+ /**
+ * Checks whether the hostdev mediated device memory framebuffer is on or off.
+ *
+ * @return state whether the hostdev mediated device memory framebuffer is on or off.
+ */
+ public boolean isMemoryFramebufferOn()
+ {
+ return this.getXmlElementAttributeValueAsBool( "ramfb" );
+ }
+
+ /**
+ * Sets the state of the hostdev mediated device memory framebuffer.
+ *
+ * @param on state whether the hostdev mediated device memory framebuffer is on or off.
+ */
+ public void setMemoryFramebufferOn( boolean on )
+ {
+ this.setXmlElementAttributeValueOnOff( "ramfb", on );
+ }
+
+ /**
+ * Returns the hostdev mediated device model.
+ *
+ * @return hostdev mediated device model.
+ */
+ public Model getModel()
+ {
+ final String model = this.getXmlElementAttributeValue( "model" );
+ return Model.fromString( model );
+ }
+
+ /**
+ * Sets the hostdev mediated device model.
+ *
+ * @param model hostdev mediated device model that is set.
+ */
+ public void setModel( Model model )
+ {
+ this.setXmlElementAttributeValue( "model", model.toString() );
+ }
+
+ @Override
+ public HostdevMdevDeviceAddress getSource()
+ {
+ final String mdevDeviceAddress = this.getXmlElementAttributeValue( "source/address", "uuid" );
+ return HostdevMdevDeviceAddress.valueOf( mdevDeviceAddress );
+ }
+
+ @Override
+ public void setSource( HostdevMdevDeviceAddress source )
+ {
+ this.setXmlElementAttributeValue( "source/address", "uuid", source.getDeviceAddressAsString() );
+ }
+
+ /**
+ * Creates a non-existent hostdev mediated device as Libvirt XML device element.
+ *
+ * @param xmlNode Libvirt XML node of the Libvirt XML device that is created.
+ * @return created hostdev mediated device instance.
+ */
+ public static HostdevMdev createInstance( LibvirtXmlNode xmlNode )
+ {
+ return HostdevMdev.newInstance( xmlNode );
+ }
+
+ /**
+ * Creates a hostdev mediated device representing an existing Libvirt XML hostdev mediated device
+ * element.
+ *
+ * @param xmlNode existing Libvirt XML hostdev mediated device element.
+ * @return hostdev mediated device instance.
+ */
+ public static HostdevMdev newInstance( LibvirtXmlNode xmlNode )
+ {
+ return new HostdevMdev( xmlNode );
+ }
+
+ /**
+ * Model for hostdev mediated device passthrough.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+ public enum Model
+ {
+ // @formatter:off
+ VFIO_PCI( "vfio-pci" ),
+ VFIO_CCW( "vfio-ccw" ),
+ VFIO_AP ( "vfio-ap" );
+ // @formatter:on
+
+ /**
+ * Name of the hostdev mediated device model.
+ */
+ private String model = null;
+
+ /**
+ * Creates hostdev mediated device model.
+ *
+ * @param type valid name of the hostdev mediated device model in a Libvirt domain XML
+ * document.
+ */
+ Model( String model )
+ {
+ this.model = model;
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.model;
+ }
+
+ /**
+ * Creates hostdev mediated device model from its name with error check.
+ *
+ * @param model name of the hostdev mediated device model in a Libvirt domain XML document.
+ * @return valid hostdev mediated device model.
+ */
+ public static Model fromString( String model )
+ {
+ for ( Model m : Model.values() ) {
+ if ( m.model.equalsIgnoreCase( model ) ) {
+ return m;
+ }
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/HostdevMdevDeviceAddress.java b/src/main/java/org/openslx/libvirt/domain/device/HostdevMdevDeviceAddress.java
new file mode 100644
index 0000000..337791d
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/HostdevMdevDeviceAddress.java
@@ -0,0 +1,99 @@
+package org.openslx.libvirt.domain.device;
+
+import java.util.UUID;
+
+/**
+ * Representation of an address from a mediated device.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class HostdevMdevDeviceAddress
+{
+ /**
+ * Address of the hostdev mediated device.
+ */
+ private final UUID deviceAddress;
+
+ /**
+ * Creates a new mediated device address and sets the address information to the default address
+ * {@code 00000000-0000-0000-0000-000000000000}.
+ */
+ public HostdevMdevDeviceAddress()
+ {
+ this( new UUID( 0, 0 ) );
+ }
+
+ /**
+ * Creates a new mediated device address consisting of a specified mediated device address.
+ *
+ * @param mdevDeviceAddress mediated device address.
+ */
+ public HostdevMdevDeviceAddress( UUID mdevDeviceAddress )
+ {
+ this.deviceAddress = mdevDeviceAddress;
+ }
+
+ /**
+ * Returns the address of the mediated device.
+ *
+ * @return address of the mediated device.
+ */
+ public UUID getDeviceAddress()
+ {
+ return this.deviceAddress;
+ }
+
+ /**
+ * Returns the address of the mediated device as {@code String}.
+ *
+ * @return address of the mediated device as {@code String}.
+ */
+ public String getDeviceAddressAsString()
+ {
+ return this.getDeviceAddress().toString();
+ }
+
+ /**
+ * Creates a new mediated device address parsed from a {@link String}.
+ *
+ * @param mdevDeviceAddress textual information containing a mediated device address as
+ * {@link String}. The textual mediated device address should be well-formed according
+ * to the string representation as described in {@link UUID#toString}.
+ *
+ * @return mediated device address instance.
+ */
+ public static HostdevMdevDeviceAddress valueOf( String mdevDeviceAddress )
+ {
+ HostdevMdevDeviceAddress parsedMdevDeviceAddress = null;
+
+ try {
+ final UUID deviceAddress = UUID.fromString( mdevDeviceAddress );
+ parsedMdevDeviceAddress = new HostdevMdevDeviceAddress( deviceAddress );
+ } catch ( IllegalArgumentException e ) {
+ parsedMdevDeviceAddress = null;
+ }
+
+ return parsedMdevDeviceAddress;
+ }
+
+ @Override
+ public boolean equals( Object obj )
+ {
+ if ( obj == null ) {
+ return false;
+ } else if ( this.getClass() != obj.getClass() ) {
+ return false;
+ } else {
+ // check if MDEV device addresses are equal
+ final HostdevMdevDeviceAddress other = HostdevMdevDeviceAddress.class.cast( obj );
+ return other.getDeviceAddress().equals( this.getDeviceAddress() );
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.getDeviceAddressAsString();
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/HostdevPci.java b/src/main/java/org/openslx/libvirt/domain/device/HostdevPci.java
new file mode 100644
index 0000000..1351f26
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/HostdevPci.java
@@ -0,0 +1,74 @@
+package org.openslx.libvirt.domain.device;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+
+/**
+ * A hostdev PCI device node in a Libvirt domain XML document for PCI passthrough.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class HostdevPci extends Hostdev implements HostdevAddressableSource<HostdevPciDeviceAddress>
+{
+ /**
+ * Creates an empty hostdev PCI device.
+ */
+ public HostdevPci()
+ {
+ super();
+ }
+
+ /**
+ * Creates a hostdev PCI device representing an existing Libvirt XML hostdev PCI device element.
+ *
+ * @param xmlNode existing Libvirt XML hostdev PCI device element.
+ */
+ public HostdevPci( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ @Override
+ public HostdevPciDeviceAddress getSource()
+ {
+ return this.getPciAddress( "source/address" );
+ }
+
+ @Override
+ public void setSource( HostdevPciDeviceAddress address )
+ {
+ this.setPciAddress( "source/address", address );
+ }
+
+ /**
+ * Set multifunction mode.
+ *
+ * If enabled, the device is said to have multiple functions.
+ */
+ public void setMultifunction( boolean on )
+ {
+ this.setXmlElementAttributeValueOnOff( "address", "multifunction", on );
+ }
+
+ /**
+ * Creates a non-existent hostdev PCI device as Libvirt XML device element.
+ *
+ * @param xmlNode Libvirt XML node of the Libvirt XML device that is created.
+ * @return created hostdev PCI device instance.
+ */
+ public static HostdevPci createInstance( LibvirtXmlNode xmlNode )
+ {
+ return HostdevPci.newInstance( xmlNode );
+ }
+
+ /**
+ * Creates a hostdev PCI device representing an existing Libvirt XML hostdev PCI device element.
+ *
+ * @param xmlNode existing Libvirt XML hostdev PCI device element.
+ * @return hostdev PCI device instance.
+ */
+ public static HostdevPci newInstance( LibvirtXmlNode xmlNode )
+ {
+ return new HostdevPci( xmlNode );
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/HostdevPciDeviceAddress.java b/src/main/java/org/openslx/libvirt/domain/device/HostdevPciDeviceAddress.java
new file mode 100644
index 0000000..9281500
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/HostdevPciDeviceAddress.java
@@ -0,0 +1,295 @@
+package org.openslx.libvirt.domain.device;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Representation of a slot address from a PCI device.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class HostdevPciDeviceAddress
+{
+ /**
+ * Regular expression to parse a PCI device address from a {@link String}.
+ * <p>
+ * The regular expression matches a PCI device address if its textual PCI device address is
+ * well-formed according to the following examples:
+ *
+ * <pre>
+ * 0000:00:02.3
+ * 0000:01:00.0
+ * 0000:00:1f.3
+ * </pre>
+ */
+ private static final String DEVICE_ADDRESS_REGEX = "^([a-f0-9]{4}):([a-f0-9]{2}):([a-f0-9]{2})\\.([0-7]{1})$";
+
+ /**
+ * Minimum value for a valid PCI device address component number.
+ */
+ private static final int DEVICE_ADDRESS_MIN_VALUE = 0;
+
+ /**
+ * Maximum value for a valid PCI device domain number.
+ */
+ private static final int DEVICE_ADDRESS_DOMAIN_MAX_VALUE = 0xffff;
+
+ /**
+ * Maximum value for a valid PCI device bus number.
+ */
+ private static final int DEVICE_ADDRESS_BUS_MAX_VALUE = 0xff;
+
+ /**
+ * Maximum value for a valid PCI device device number.
+ */
+ private static final int DEVICE_ADDRESS_DEVICE_MAX_VALUE = 0x1f;
+
+ /**
+ * Maximum value for a valid PCI device function number.
+ */
+ private static final int DEVICE_ADDRESS_FUNCTION_MAX_VALUE = 0x7;
+
+ /**
+ * Domain number of the PCI device address.
+ */
+ final int pciDomain;
+
+ /**
+ * Bus number of the PCI device address.
+ */
+ final int pciBus;
+
+ /**
+ * Device number of the PCI device address.
+ */
+ final int pciDevice;
+
+ /**
+ * Function number of the PCI device address.
+ */
+ final int pciFunction;
+
+ /**
+ * Creates a new PCI device address and sets the address information to the default
+ * address {@code 0000:00:00.0}.
+ */
+ public HostdevPciDeviceAddress()
+ {
+ this( 0, 0, 0, 0 );
+ }
+
+ /**
+ * Creates a new PCI device address consisting of a specified PCI bus, device, and function.
+ * <p>
+ * The domain of the PCI device address is set to the default number {@code 0000}.
+ *
+ * @param pciBus number of the PCI bus.
+ * @param pciDevice number of the PCI device.
+ * @param pciFunction number of the PCI function.
+ *
+ * @throws IllegalArgumentException failed to validate the PCI bus, device and function.
+ */
+ public HostdevPciDeviceAddress( int pciBus, int pciDevice, int pciFunction ) throws IllegalArgumentException
+ {
+ this( 0, pciBus, pciDevice, pciFunction );
+ }
+
+ /**
+ * Creates a new PCI device address consisting of a specified PCI domain, bus, device, and
+ * function.
+ *
+ * @param pciDomain number of the PCI domain.
+ * @param pciBus number of the PCI bus.
+ * @param pciDevice number of the PCI device.
+ * @param pciFunction number of the PCI function.
+ *
+ * @throws IllegalArgumentException failed to validate the PCI domain, bus, device and function.
+ */
+ public HostdevPciDeviceAddress( int pciDomain, int pciBus, int pciDevice, int pciFunction )
+ throws IllegalArgumentException
+ {
+ HostdevPciDeviceAddress.validatePciDeviceAddress( pciDomain, "PCI domain",
+ HostdevPciDeviceAddress.DEVICE_ADDRESS_DOMAIN_MAX_VALUE );
+ HostdevPciDeviceAddress.validatePciDeviceAddress( pciBus, "PCI bus",
+ HostdevPciDeviceAddress.DEVICE_ADDRESS_BUS_MAX_VALUE );
+ HostdevPciDeviceAddress.validatePciDeviceAddress( pciDevice, "PCI device",
+ HostdevPciDeviceAddress.DEVICE_ADDRESS_DEVICE_MAX_VALUE );
+ HostdevPciDeviceAddress.validatePciDeviceAddress( pciFunction, "PCI function",
+ HostdevPciDeviceAddress.DEVICE_ADDRESS_FUNCTION_MAX_VALUE );
+
+ this.pciDomain = pciDomain;
+ this.pciBus = pciBus;
+ this.pciDevice = pciDevice;
+ this.pciFunction = pciFunction;
+ }
+
+ /**
+ * Validates a specified PCI address component (PCI domain, bus, device or function).
+ *
+ * @param address value of the PCI address component.
+ * @param addressName name of the PCI address component.
+ * @param upperLimit maximum value for the PCI address component
+ *
+ * @throws IllegalArgumentException
+ */
+ private static void validatePciDeviceAddress( final int address, final String addressName, final int upperLimit )
+ throws IllegalArgumentException
+ {
+ if ( address < HostdevPciDeviceAddress.DEVICE_ADDRESS_MIN_VALUE ) {
+ throw new IllegalArgumentException(
+ "The " + addressName + " address must be larger or equal than "
+ + HostdevPciDeviceAddress.DEVICE_ADDRESS_MIN_VALUE );
+ } else if ( address > upperLimit ) {
+ throw new IllegalArgumentException(
+ "The " + addressName + " address must be smaller or equal than " + upperLimit );
+ }
+ }
+
+ /**
+ * Returns the PCI domain.
+ *
+ * @return PCI domain.
+ */
+ public int getPciDomain()
+ {
+ return this.pciDomain;
+ }
+
+ /**
+ * Returns the PCI domain as {@link String}.
+ *
+ * @return PCI domain as {@link String}.
+ */
+ public String getPciDomainAsString()
+ {
+ return String.format( "%04x", HostdevPciDeviceAddress.DEVICE_ADDRESS_DOMAIN_MAX_VALUE & this.getPciDomain() );
+ }
+
+ /**
+ * Returns the PCI bus.
+ *
+ * @return PCI bus.
+ */
+ public int getPciBus()
+ {
+ return this.pciBus;
+ }
+
+ /**
+ * Returns the PCI bus as {@link String}.
+ *
+ * @return PCI bus as {@link String}.
+ */
+ public String getPciBusAsString()
+ {
+ return String.format( "%02x", HostdevPciDeviceAddress.DEVICE_ADDRESS_BUS_MAX_VALUE & this.getPciBus() );
+ }
+
+ /**
+ * Returns the PCI device.
+ *
+ * @return PCI device.
+ */
+ public int getPciDevice()
+ {
+ return this.pciDevice;
+ }
+
+ /**
+ * Returns the PCI device as {@link String}.
+ *
+ * @return PCI device as {@link String}.
+ */
+ public String getPciDeviceAsString()
+ {
+ return String.format( "%02x", HostdevPciDeviceAddress.DEVICE_ADDRESS_DEVICE_MAX_VALUE & this.getPciDevice() );
+ }
+
+ /**
+ * Returns the PCI function.
+ *
+ * @return PCI function.
+ */
+ public int getPciFunction()
+ {
+ return this.pciFunction;
+ }
+
+ /**
+ * Returns the PCI function as {@link String}.
+ *
+ * @return PCI function as {@link String}.
+ */
+ public String getPciFunctionAsString()
+ {
+ return String.format( "%01x", HostdevPciDeviceAddress.DEVICE_ADDRESS_FUNCTION_MAX_VALUE & this.getPciFunction() );
+ }
+
+ /**
+ * Creates a new PCI device address parsed from a {@link String}.
+ * <p>
+ * The PCI device address consists of a PCI domain, bus, device and function parsed from the
+ * specified {@link String}.
+ *
+ * @param pciDeviceAddress textual information containing a PCI device address as {@link String}.
+ * The textual PCI device address should be well-formed according to the defined
+ * regular expression {@link #DEVICE_ADDRESS_REGEX}.
+ *
+ * @return PCI device address instance.
+ */
+ public static HostdevPciDeviceAddress valueOf( String pciDeviceAddress )
+ {
+ HostdevPciDeviceAddress parsedPciDeviceAddress;
+
+ if ( pciDeviceAddress == null || pciDeviceAddress.isEmpty() ) {
+ parsedPciDeviceAddress = null;
+ } else {
+ final Pattern pciDeviceAddressPattern = Pattern.compile( HostdevPciDeviceAddress.DEVICE_ADDRESS_REGEX );
+ final Matcher pciDeviceAddressMatcher = pciDeviceAddressPattern.matcher( pciDeviceAddress.toLowerCase() );
+
+ if ( pciDeviceAddressMatcher.find() ) {
+ final int pciDomain = Integer.valueOf( pciDeviceAddressMatcher.group( 1 ), 16 );
+ final int pciBus = Integer.valueOf( pciDeviceAddressMatcher.group( 2 ), 16 );
+ final int pciDevice = Integer.valueOf( pciDeviceAddressMatcher.group( 3 ), 16 );
+ final int pciFunction = Integer.valueOf( pciDeviceAddressMatcher.group( 4 ), 16 );
+
+ try {
+ parsedPciDeviceAddress = new HostdevPciDeviceAddress( pciDomain, pciBus, pciDevice, pciFunction );
+ } catch ( IllegalArgumentException e ) {
+ parsedPciDeviceAddress = null;
+ }
+ } else {
+ parsedPciDeviceAddress = null;
+ }
+ }
+
+ return parsedPciDeviceAddress;
+ }
+
+ @Override
+ public boolean equals( Object obj )
+ {
+ if ( obj == null ) {
+ return false;
+ } else if ( this.getClass() != obj.getClass() ) {
+ return false;
+ } else {
+ // check if PCI domain, bus, device and function are equal
+ final HostdevPciDeviceAddress other = HostdevPciDeviceAddress.class.cast( obj );
+ if ( this.getPciDomain() == other.getPciDomain() && this.getPciBus() == other.getPciBus()
+ && this.getPciDevice() == other.getPciDevice() && this.getPciFunction() == other.getPciFunction() ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.getPciDomainAsString() + ":" + this.getPciBusAsString() + ":" + this.getPciDeviceAsString() + "."
+ + this.getPciFunctionAsString();
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/HostdevPciDeviceDescription.java b/src/main/java/org/openslx/libvirt/domain/device/HostdevPciDeviceDescription.java
new file mode 100644
index 0000000..25c29f2
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/HostdevPciDeviceDescription.java
@@ -0,0 +1,186 @@
+package org.openslx.libvirt.domain.device;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Representation of a PCI device description.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class HostdevPciDeviceDescription extends Hostdev
+{
+ /**
+ * Regular expression to parse a PCI vendor and device identifier from a {@link String}.
+ * <p>
+ * The regular expression matches a PCI device description if its textual PCI device description
+ * is well-formed according to the following examples:
+ *
+ * <pre>
+ * 8086:a170
+ * 10ec:8168
+ * 8086:15b7
+ * </pre>
+ */
+ private static final String DEVICE_DESCRIPTION_REGEX = "^([a-f0-9]{4}):([a-f0-9]{4})$";
+
+ /**
+ * Minimum value of a valid identifier from a PCI device description.
+ */
+ private static final int DEVICE_DESCRIPTION_ID_MIN_VALUE = 0x0000;
+
+ /**
+ * Maximum value of a valid identifier from a PCI device description.
+ */
+ private static final int DEVICE_DESCRIPTION_ID_MAX_VALUE = 0xffff;
+
+ /**
+ * Vendor identifier of the PCI device.
+ */
+ final int vendorId;
+
+ /**
+ * Device identifier of the PCI device.
+ */
+ final int deviceId;
+
+ /**
+ * Creates a new PCI device description consisting of a PCI vendor and device identifier.
+ *
+ * @param vendorId vendor identifier of the PCI device.
+ * @param deviceId device identifier of the PCI device.
+ *
+ * @throws throws IllegalArgumentException failed to validate the PCI device description
+ * identifiers.
+ */
+ public HostdevPciDeviceDescription( int vendorId, int deviceId ) throws IllegalArgumentException
+ {
+ HostdevPciDeviceDescription.validatePciDeviceDescriptionId( "PCI vendor ID", vendorId );
+ HostdevPciDeviceDescription.validatePciDeviceDescriptionId( "PCI device ID", deviceId );
+
+ this.vendorId = vendorId;
+ this.deviceId = deviceId;
+ }
+
+ /**
+ * Validates a PCI device description ID (a PCI vendor or device ID).
+ *
+ * @param idName name of the PCI device description identifier.
+ * @param id value of the PCI device description identifier that should be validated.
+ *
+ * @throws IllegalArgumentException failed to validate the PCI device description identifier.
+ */
+ private static void validatePciDeviceDescriptionId( final String idName, final int id )
+ throws IllegalArgumentException
+ {
+ if ( id < HostdevPciDeviceDescription.DEVICE_DESCRIPTION_ID_MIN_VALUE ) {
+ throw new IllegalArgumentException(
+ "The " + idName + "must be larger or equal than "
+ + HostdevPciDeviceDescription.DEVICE_DESCRIPTION_ID_MIN_VALUE );
+ } else if ( id > HostdevPciDeviceDescription.DEVICE_DESCRIPTION_ID_MAX_VALUE ) {
+ throw new IllegalArgumentException(
+ "The " + idName + "must be smaller or equal than "
+ + HostdevPciDeviceDescription.DEVICE_DESCRIPTION_ID_MAX_VALUE );
+ }
+ }
+
+ /**
+ * Returns the PCI vendor identifier.
+ *
+ * @return PCI vendor identifier.
+ */
+ public int getVendorId()
+ {
+ return this.vendorId;
+ }
+
+ /**
+ * Returns the PCI vendor identifier as {@link String}.
+ *
+ * @return PCI vendor identifier as {@link String}.
+ */
+ public String getVendorIdAsString()
+ {
+ return String.format( "%04x", HostdevPciDeviceDescription.DEVICE_DESCRIPTION_ID_MAX_VALUE & this.getVendorId() );
+ }
+
+ /**
+ * Returns the PCI device identifier.
+ *
+ * @return PCI device identifier.
+ */
+ public int getDeviceId()
+ {
+ return this.deviceId;
+ }
+
+ /**
+ * Returns the PCI device identifier as {@link String}.
+ *
+ * @return PCI device identifier as {@link String}.
+ */
+ public String getDeviceIdAsString()
+ {
+ return String.format( "%04x", HostdevPciDeviceDescription.DEVICE_DESCRIPTION_ID_MAX_VALUE & this.getDeviceId() );
+ }
+
+ /**
+ * Creates a new PCI device description parsed from a {@link String}.
+ * <p>
+ * The PCI device description consists of a PCI vendor and device identifier parsed from the
+ * specified {@link String}.
+ *
+ * @param vendorDeviceId textual information containing a PCI device description as
+ * {@link String}. The textual PCI device description should be well-formed according
+ * to the defined regular expression {@link #DEVICE_DESCRIPTION_REGEX}.
+ *
+ * @return PCI device description instance.
+ */
+ public static HostdevPciDeviceDescription valueOf( String vendorDeviceId )
+ {
+ final HostdevPciDeviceDescription pciDeviceDescription;
+
+ if ( vendorDeviceId == null || vendorDeviceId.isEmpty() ) {
+ pciDeviceDescription = null;
+ } else {
+ final Pattern pciDeviceDescPattern = Pattern.compile( HostdevPciDeviceDescription.DEVICE_DESCRIPTION_REGEX );
+ final Matcher pciDeviceDescMatcher = pciDeviceDescPattern.matcher( vendorDeviceId.toLowerCase() );
+
+ if ( pciDeviceDescMatcher.find() ) {
+ final int vendorId = Integer.valueOf( pciDeviceDescMatcher.group( 1 ), 16 );
+ final int deviceId = Integer.valueOf( pciDeviceDescMatcher.group( 2 ), 16 );
+
+ pciDeviceDescription = new HostdevPciDeviceDescription( vendorId, deviceId );
+ } else {
+ pciDeviceDescription = null;
+ }
+ }
+
+ return pciDeviceDescription;
+ }
+
+ @Override
+ public boolean equals( Object obj )
+ {
+ if ( obj == null ) {
+ return false;
+ } else if ( this.getClass() != obj.getClass() ) {
+ return false;
+ } else {
+ // check if vendor and device ID are equal
+ final HostdevPciDeviceDescription other = HostdevPciDeviceDescription.class.cast( obj );
+ if ( this.getVendorId() == other.getVendorId() && this.getDeviceId() == other.getDeviceId() ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.getVendorIdAsString() + ":" + this.getDeviceIdAsString();
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/HostdevUsb.java b/src/main/java/org/openslx/libvirt/domain/device/HostdevUsb.java
new file mode 100644
index 0000000..7bf13f4
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/HostdevUsb.java
@@ -0,0 +1,88 @@
+package org.openslx.libvirt.domain.device;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+
+/**
+ * A hostdev USB device node in a Libvirt domain XML document for USB passthrough.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class HostdevUsb extends Hostdev implements HostdevAddressableSource<HostdevUsbDeviceDescription>
+{
+ /**
+ * Creates an empty hostdev USB device.
+ */
+ public HostdevUsb()
+ {
+ super();
+ }
+
+ /**
+ * Creates a hostdev USB device representing an existing Libvirt XML hostdev USB device element.
+ *
+ * @param xmlNode existing Libvirt XML hostdev USB device element.
+ */
+ public HostdevUsb( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ @Override
+ public HostdevUsbDeviceDescription getSource()
+ {
+ String vendorId = this.getXmlElementAttributeValue( "source/address/vendor", "id" );
+ String productId = this.getXmlElementAttributeValue( "source/address/product", "id" );
+
+ vendorId = HostdevUtils.removeHexPrefix( vendorId );
+ productId = HostdevUtils.removeHexPrefix( productId );
+
+ return HostdevUsbDeviceDescription.valueOf( vendorId + ":" + productId );
+ }
+
+ @Override
+ public void setSource( HostdevUsbDeviceDescription description )
+ {
+ final String vendorId = HostdevUtils.appendHexPrefix( description.getVendorIdAsString() );
+ final String productId = HostdevUtils.appendHexPrefix( description.getProductIdAsString() );
+
+ this.setXmlElementAttributeValue( "source/address/vendor", "id", vendorId );
+ this.setXmlElementAttributeValue( "source/address/product", "id", productId );
+ }
+
+ public HostdevUsbDeviceAddress getUsbTarget()
+ {
+ final String usbBus = this.getXmlElementAttributeValue( "address", "bus" );
+ final String usbPort = this.getXmlElementAttributeValue( "address", "port" );
+
+ return HostdevUsbDeviceAddress.valueOf( usbBus, usbPort );
+ }
+
+ public void setUsbTarget( HostdevUsbDeviceAddress address )
+ {
+ this.setXmlElementAttributeValue( "address", "bus", Integer.toString( address.getUsbBus() ) );
+ this.setXmlElementAttributeValue( "address", "port", Integer.toString( address.getUsbPort() ) );
+ }
+
+ /**
+ * Creates a non-existent hostdev USB device as Libvirt XML device element.
+ *
+ * @param xmlNode Libvirt XML node of the Libvirt XML device that is created.
+ * @return created hostdev USB device instance.
+ */
+ public static HostdevUsb createInstance( LibvirtXmlNode xmlNode )
+ {
+ return HostdevUsb.newInstance( xmlNode );
+ }
+
+ /**
+ * Creates a hostdev USB device representing an existing Libvirt XML hostdev USB device element.
+ *
+ * @param xmlNode existing Libvirt XML hostdev USB device element.
+ * @return hostdev USB device instance.
+ */
+ public static HostdevUsb newInstance( LibvirtXmlNode xmlNode )
+ {
+ return new HostdevUsb( xmlNode );
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/HostdevUsbDeviceAddress.java b/src/main/java/org/openslx/libvirt/domain/device/HostdevUsbDeviceAddress.java
new file mode 100644
index 0000000..02961a1
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/HostdevUsbDeviceAddress.java
@@ -0,0 +1,141 @@
+package org.openslx.libvirt.domain.device;
+
+/**
+ * Representation of an address from an USB device.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class HostdevUsbDeviceAddress
+{
+ /**
+ * Minimum value for a valid USB device address component number.
+ */
+ private static final int DEVICE_ADDRESS_MIN_VALUE = 0;
+
+ /**
+ * Maximum value for a valid USB device bus number.
+ */
+ static final int DEVICE_BUS_MAX_VALUE = 127;
+
+ /**
+ * Maximum value for a valid USB device port number.
+ */
+ static final int DEVICE_PORT_MAX_VALUE = 127;
+
+ /**
+ * USB bus of the USB device.
+ */
+ final int usbBus;
+
+ /**
+ * USB port of the USB device.
+ */
+ final int usbPort;
+
+ public HostdevUsbDeviceAddress( int usbBus, int usbPort ) throws IllegalArgumentException
+ {
+ HostdevUsbDeviceAddress.validateUsbDeviceAddress( usbBus, "USB bus",
+ HostdevUsbDeviceAddress.DEVICE_BUS_MAX_VALUE );
+ HostdevUsbDeviceAddress.validateUsbDeviceAddress( usbPort, "USB port",
+ HostdevUsbDeviceAddress.DEVICE_PORT_MAX_VALUE );
+
+ this.usbBus = usbBus;
+ this.usbPort = usbPort;
+ }
+
+ /**
+ * Validates a specified USB device address component (USB bus or port).
+ *
+ * @param address value of the USB address component.
+ * @param addressName name of the USB address component.
+ * @param upperLimit maximum value for the USB address component
+ *
+ * @throws IllegalArgumentException
+ */
+ private static void validateUsbDeviceAddress( final int address, final String addressName, final int upperLimit )
+ throws IllegalArgumentException
+ {
+ if ( address < HostdevUsbDeviceAddress.DEVICE_ADDRESS_MIN_VALUE ) {
+ throw new IllegalArgumentException(
+ "The " + addressName + " must be larger or equal than "
+ + HostdevUsbDeviceAddress.DEVICE_ADDRESS_MIN_VALUE );
+ } else if ( address > upperLimit ) {
+ throw new IllegalArgumentException(
+ "The " + addressName + " must be smaller or equal than " + upperLimit );
+ }
+ }
+
+ /**
+ * Returns the USB bus number.
+ *
+ * @return USB bus number.
+ */
+ public int getUsbBus()
+ {
+ return this.usbBus;
+ }
+
+ /**
+ * Returns the USB port number.
+ *
+ * @return USB port number.
+ */
+ public int getUsbPort()
+ {
+ return this.usbPort;
+ }
+
+ /**
+ * Creates a new USB device address parsed from {@link String}s.
+ *
+ * @param usbBus textual information containing a decimal USB device bus number as
+ * {@link String}.
+ * @param usbPort textual information containing a decimal USB device port number as
+ * {@link String}.
+ * @return USB device address instance.
+ */
+ public static HostdevUsbDeviceAddress valueOf( String usbBus, String usbPort )
+ {
+ HostdevUsbDeviceAddress usbDeviceAddress;
+
+ if ( usbBus == null || usbBus.isEmpty() || usbPort == null || usbPort.isEmpty() ) {
+ usbDeviceAddress = null;
+ } else {
+ try {
+ final int parsedUsbBus = Integer.valueOf( usbBus );
+ final int parsedUsbPort = Integer.valueOf( usbPort );
+ usbDeviceAddress = new HostdevUsbDeviceAddress( parsedUsbBus, parsedUsbPort );
+ } catch ( IllegalArgumentException e ) {
+ usbDeviceAddress = null;
+ }
+ }
+
+ return usbDeviceAddress;
+
+ }
+
+ @Override
+ public boolean equals( Object obj )
+ {
+ if ( obj == null ) {
+ return false;
+ } else if ( this.getClass() != obj.getClass() ) {
+ return false;
+ } else {
+ // check if USB bus and port are equal
+ final HostdevUsbDeviceAddress other = HostdevUsbDeviceAddress.class.cast( obj );
+ if ( this.getUsbBus() == other.getUsbBus() && this.getUsbPort() == other.getUsbPort() ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.getUsbBus() + ":" + this.getUsbPort();
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/HostdevUsbDeviceDescription.java b/src/main/java/org/openslx/libvirt/domain/device/HostdevUsbDeviceDescription.java
new file mode 100644
index 0000000..d1c546f
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/HostdevUsbDeviceDescription.java
@@ -0,0 +1,190 @@
+package org.openslx.libvirt.domain.device;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Representation of an USB device description.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class HostdevUsbDeviceDescription
+{
+ /**
+ * Regular expression to parse an USB device vendor and product identifier from a {@link String}.
+ * <p>
+ * The regular expression matches an USB device description if its textual USB device description
+ * is well-formed according to the following examples:
+ *
+ * <pre>
+ * 1d6b:0002
+ * 0461:4d22
+ * 046d:c312
+ * </pre>
+ */
+ private static final String DEVICE_DESCRIPTION_REGEX = "^([a-f0-9]{4}):([a-f0-9]{4})$";
+
+ /**
+ * Minimum value of a valid identifier from an USB device description.
+ */
+ private static final int DEVICE_DESCRIPTION_ID_MIN_VALUE = 0x0000;
+
+ /**
+ * Maximum value of a valid identifier from an USB device description.
+ */
+ private static final int DEVICE_DESCRIPTION_ID_MAX_VALUE = 0xffff;
+
+ /**
+ * Vendor identifier of the USB device.
+ */
+ final int vendorId;
+
+ /**
+ * Product identifier of the USB device.
+ */
+ final int productId;
+
+ /**
+ * Creates a new USB device description consisting of a USB vendor and product identifier.
+ *
+ * @param vendorId vendor identifier of the USB device.
+ * @param productId product identifier of the USB device.
+ *
+ * @throws throws IllegalArgumentException failed to validate the USB device description
+ * identifiers.
+ */
+ public HostdevUsbDeviceDescription( int vendorId, int productId ) throws IllegalArgumentException
+ {
+ HostdevUsbDeviceDescription.validateUsbDeviceDescriptionId( "PCI vendor ID", vendorId );
+ HostdevUsbDeviceDescription.validateUsbDeviceDescriptionId( "PCI device ID", productId );
+
+ this.vendorId = vendorId;
+ this.productId = productId;
+ }
+
+ /**
+ * Validates an USB device description ID (an USB vendor or product ID).
+ *
+ * @param idName name of the USB device description identifier.
+ * @param id value of the USB device description identifier that should be validated.
+ *
+ * @throws IllegalArgumentException failed to validate the USB device description identifier.
+ */
+ private static void validateUsbDeviceDescriptionId( final String idName, final int id )
+ throws IllegalArgumentException
+ {
+ if ( id < HostdevUsbDeviceDescription.DEVICE_DESCRIPTION_ID_MIN_VALUE ) {
+ throw new IllegalArgumentException(
+ "The " + idName + "must be larger or equal than "
+ + HostdevUsbDeviceDescription.DEVICE_DESCRIPTION_ID_MIN_VALUE );
+ } else if ( id > HostdevUsbDeviceDescription.DEVICE_DESCRIPTION_ID_MAX_VALUE ) {
+ throw new IllegalArgumentException(
+ "The " + idName + "must be smaller or equal than "
+ + HostdevUsbDeviceDescription.DEVICE_DESCRIPTION_ID_MAX_VALUE );
+ }
+ }
+
+ /**
+ * Returns the USB device vendor identifier.
+ *
+ * @return USB device vendor identifier.
+ */
+ public int getVendorId()
+ {
+ return this.vendorId;
+ }
+
+ /**
+ * Returns the USB vendor identifier as {@link String}.
+ *
+ * @return USB vendor identifier as {@link String}.
+ */
+ public String getVendorIdAsString()
+ {
+ return String.format( "%04x", HostdevUsbDeviceDescription.DEVICE_DESCRIPTION_ID_MAX_VALUE & this.getVendorId() );
+ }
+
+ /**
+ * Returns the USB device product identifier.
+ *
+ * @return USB device product identifier.
+ */
+ public int getProductId()
+ {
+ return this.productId;
+ }
+
+ /**
+ * Returns the USB device product identifier as {@link String}.
+ *
+ * @return USB device product identifier as {@link String}.
+ */
+ public String getProductIdAsString()
+ {
+ return String.format( "%04x", HostdevUsbDeviceDescription.DEVICE_DESCRIPTION_ID_MAX_VALUE & this.getProductId() );
+ }
+
+ /**
+ * Creates a new USB device description parsed from a {@link String}.
+ * <p>
+ * The USB device description consists of an USB vendor and product identifier parsed from the
+ * specified {@link String}.
+ *
+ * @param vendorProductId textual information containing an USB device description as
+ * {@link String}. The textual USB device description should be well-formed according
+ * to the defined regular expression {@link #DEVICE_DESCRIPTION_REGEX}.
+ *
+ * @return USB device description instance.
+ */
+ public static HostdevUsbDeviceDescription valueOf( String vendorProductId )
+ {
+ HostdevUsbDeviceDescription usbDeviceDescription;
+
+ if ( vendorProductId == null || vendorProductId.isEmpty() ) {
+ usbDeviceDescription = null;
+ } else {
+ final Pattern usbDeviceDescPattern = Pattern.compile( HostdevUsbDeviceDescription.DEVICE_DESCRIPTION_REGEX );
+ final Matcher usbDeviceDescMatcher = usbDeviceDescPattern.matcher( vendorProductId.toLowerCase() );
+
+ if ( usbDeviceDescMatcher.find() ) {
+ final int vendorId = Integer.valueOf( usbDeviceDescMatcher.group( 1 ), 16 );
+ final int productId = Integer.valueOf( usbDeviceDescMatcher.group( 2 ), 16 );
+
+ try {
+ usbDeviceDescription = new HostdevUsbDeviceDescription( vendorId, productId );
+ } catch ( IllegalArgumentException e ) {
+ usbDeviceDescription = null;
+ }
+ } else {
+ usbDeviceDescription = null;
+ }
+ }
+
+ return usbDeviceDescription;
+ }
+
+ @Override
+ public boolean equals( Object obj )
+ {
+ if ( obj == null ) {
+ return false;
+ } else if ( this.getClass() != obj.getClass() ) {
+ return false;
+ } else {
+ // check if vendor and product ID are equal
+ final HostdevUsbDeviceDescription other = HostdevUsbDeviceDescription.class.cast( obj );
+ if ( this.getVendorId() == other.getVendorId() && this.getProductId() == other.getProductId() ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.getVendorIdAsString() + ":" + this.getProductIdAsString();
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/HostdevUtils.java b/src/main/java/org/openslx/libvirt/domain/device/HostdevUtils.java
new file mode 100644
index 0000000..204bea9
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/HostdevUtils.java
@@ -0,0 +1,32 @@
+package org.openslx.libvirt.domain.device;
+
+/**
+ * Collection of helper methods to maintain a Libvirt related hostdev XML element.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class HostdevUtils
+{
+ /**
+ * Appends the HEX prefix to a specified hostdev address component without any HEX prefix.
+ *
+ * @param component address component without any HEX prefix.
+ * @return address component with the HEX prefix.
+ */
+ public static String appendHexPrefix( String component )
+ {
+ return "0x" + component;
+ }
+
+ /**
+ * Removes a possible HEX prefix of a specified hostdev address component.
+ *
+ * @param component address component with possible HEX prefix.
+ * @return address component without any HEX prefix.
+ */
+ public static String removeHexPrefix( String component )
+ {
+ return component.replaceFirst( "0x", "" );
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/Interface.java b/src/main/java/org/openslx/libvirt/domain/device/Interface.java
new file mode 100644
index 0000000..44b8e4c
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/Interface.java
@@ -0,0 +1,344 @@
+package org.openslx.libvirt.domain.device;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+
+/**
+ * A network interface device node in a Libvirt domain XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class Interface extends Device
+{
+ /**
+ * Creates an empty network device.
+ */
+ public Interface()
+ {
+ super();
+ }
+
+ /**
+ * Creates a network device representing an existing Libvirt XML network interface device
+ * element.
+ *
+ * @param xmlNode existing Libvirt XML network interface device element.
+ */
+ public Interface( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Returns hardware model of the network device.
+ *
+ * @return hardware model of the network device.
+ */
+ public Model getModel()
+ {
+ String model = this.getXmlElementAttributeValue( "model", "type" );
+ return Model.fromString( model );
+ }
+
+ /**
+ * Sets hardware model for the network device.
+ *
+ * @param model hardware model for the network device.
+ */
+ public void setModel( Model model )
+ {
+ this.setXmlElementAttributeValue( "model", "type", model.toString() );
+ }
+
+ /**
+ * Returns type of the network device.
+ *
+ * @return type of the network device.
+ */
+ public Type getType()
+ {
+ return Type.fromString( this.getXmlElementAttributeValue( "type" ) );
+ }
+
+ /**
+ * Sets type of the network device.
+ *
+ * @param type network device type.
+ */
+ public void setType( Type type )
+ {
+ String source = this.getSource();
+
+ // change type and set source again
+ this.setXmlElementAttributeValue( "type", type.toString() );
+ this.setSource( source );
+ }
+
+ /**
+ * Returns the source of the network device.
+ *
+ * @return source of the network device.
+ */
+ public String getSource()
+ {
+ Type type = this.getType();
+ String source = null;
+
+ switch ( type ) {
+ case BRIDGE:
+ source = this.getXmlElementAttributeValue( "source", "bridge" );
+ break;
+ case NETWORK:
+ source = this.getXmlElementAttributeValue( "source", "network" );
+ break;
+ }
+
+ return source;
+ }
+
+ /**
+ * Sets the source for the network device.
+ *
+ * @param source for the network device.
+ */
+ public void setSource( String source )
+ {
+ Type type = this.getType();
+
+ // remove all attributes from sub-element 'source'
+ this.removeXmlElementAttributes( "source" );
+
+ switch ( type ) {
+ case BRIDGE:
+ this.setXmlElementAttributeValue( "source", "bridge", source );
+ break;
+ case NETWORK:
+ this.setXmlElementAttributeValue( "source", "network", source );
+ break;
+ }
+ }
+
+ /**
+ * Returns MAC address of the network device.
+ *
+ * @return MAC address of the network device.
+ */
+ public String getMacAddress()
+ {
+ return this.getXmlElementAttributeValue( "mac", "address" );
+ }
+
+ /**
+ * Sets MAC address of the network device.
+ *
+ * @param macAddress MAC address for the network device.
+ */
+ public void setMacAddress( String macAddress )
+ {
+ this.setXmlElementAttributeValue( "mac", "address", macAddress );
+ }
+
+ /**
+ * Removes boot oder entry of the network interface device.
+ */
+ public void removeBootOrder()
+ {
+ this.removeXmlElement( "boot" );
+ }
+
+ /**
+ * Removes network source of the network interface device.
+ */
+ public void removeSource()
+ {
+ this.removeXmlElement( "source" );
+ }
+
+ /**
+ * Removes MAC address of the network interface device.
+ */
+ public void removeMacAddress()
+ {
+ this.removeXmlElement( "mac" );
+ }
+
+ /**
+ * Creates a non-existent network interface device as Libvirt XML device element.
+ *
+ * @param iface network device that is created.
+ * @param xmlNode Libvirt XML node of the Libvirt XML device that is created.
+ * @return created network device instance.
+ */
+ public static Interface createInstance( Interface iface, LibvirtXmlNode xmlNode )
+ {
+ Interface addedInterface = null;
+
+ if ( iface instanceof InterfaceBridge ) {
+ xmlNode.setXmlElementAttributeValue( "type", Type.BRIDGE.toString() );
+ addedInterface = InterfaceBridge.createInstance( xmlNode );
+ } else if ( iface instanceof InterfaceNetwork ) {
+ xmlNode.setXmlElementAttributeValue( "type", Type.NETWORK.toString() );
+ addedInterface = InterfaceNetwork.createInstance( xmlNode );
+ }
+
+ return addedInterface;
+ }
+
+ /**
+ * Creates a network interface device representing an existing Libvirt XML network interface
+ * device element.
+ *
+ * @param xmlNode existing Libvirt XML network interface device element.
+ * @return network interface device instance.
+ */
+ public static Interface newInstance( LibvirtXmlNode xmlNode )
+ {
+ Interface deviceInterface = null;
+ Type type = Type.fromString( xmlNode.getXmlElementAttributeValue( "type" ) );
+
+ if ( type == null ) {
+ return null;
+ }
+
+ switch ( type ) {
+ case BRIDGE:
+ deviceInterface = InterfaceBridge.newInstance( xmlNode );
+ break;
+ case NETWORK:
+ deviceInterface = InterfaceNetwork.newInstance( xmlNode );
+ break;
+ }
+
+ return deviceInterface;
+ }
+
+ /**
+ * Type of network interface device.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+ public enum Type
+ {
+ // @formatter:off
+ BRIDGE ( "bridge" ),
+ NETWORK( "network" );
+ // @formatter:on
+
+ /**
+ * Name of the network interface device type.
+ */
+ private String type = null;
+
+ /**
+ * Creates network interface device type.
+ *
+ * @param type valid name of the network interface device type in a Libvirt domain XML
+ * document.
+ */
+ Type( String type )
+ {
+ this.type = type;
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.type;
+ }
+
+ /**
+ * Creates network interface device type from its name with error check.
+ *
+ * @param type name of the network interface device type in a Libvirt domain XML document.
+ * @return valid network interface device type.
+ */
+ public static Type fromString( String type )
+ {
+ for ( Type t : Type.values() ) {
+ if ( t.type.equalsIgnoreCase( type ) ) {
+ return t;
+ }
+ }
+
+ return null;
+ }
+ }
+
+ /**
+ * Model of network interface device.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+ public enum Model
+ {
+ // @formatter:off
+ E1000 ( "e1000" ),
+ E1000_82544GC ( "e1000-82544gc" ),
+ E1000_82545EM ( "e1000-82545em" ),
+ E1000E ( "e1000e" ),
+ I82550 ( "i82550" ),
+ I82551 ( "i82551" ),
+ I82557A ( "i82557a" ),
+ I82557B ( "i82557b" ),
+ I82557C ( "i82557c" ),
+ I82558A ( "i82558a" ),
+ I82558B ( "i82558b" ),
+ I82559A ( "i82559a" ),
+ I82559B ( "i82559b" ),
+ I82559C ( "i82559c" ),
+ I82559ER ( "i82559er" ),
+ I82562 ( "i82562" ),
+ I82801 ( "i82801" ),
+ NE2K_PCI ( "ne2k_pci" ),
+ PCNET ( "pcnet" ),
+ RTL8139 ( "rtl8139" ),
+ TULIP ( "tulip" ),
+ VIRTIO ( "virtio" ),
+ VIRTIO_NET_PCI ( "virtio-net-pci" ),
+ VIRTIO_NET_PCI_NON_TRANSITIONAL( "virtio-net-pci-non-transitional" ),
+ VIRTIO_NET_PCI_TRANSITIONAL ( "virtio-net-pci-transitional" ),
+ VMXNET3 ( "vmxnet3" );
+ // @formatter:on
+
+ /**
+ * Name of the network interface device model.
+ */
+ private String model = null;
+
+ /**
+ * Creates network interface device model.
+ *
+ * @param type valid name of the network interface device model in a Libvirt domain XML
+ * document.
+ */
+ Model( String model )
+ {
+ this.model = model;
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.model;
+ }
+
+ /**
+ * Creates network interface device model from its name with error check.
+ *
+ * @param model name of the network interface device model in a Libvirt domain XML document.
+ * @return valid network interface device model.
+ */
+ public static Model fromString( String model )
+ {
+ for ( Model m : Model.values() ) {
+ if ( m.model.equalsIgnoreCase( model ) ) {
+ return m;
+ }
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/InterfaceBridge.java b/src/main/java/org/openslx/libvirt/domain/device/InterfaceBridge.java
new file mode 100644
index 0000000..02eabb0
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/InterfaceBridge.java
@@ -0,0 +1,54 @@
+package org.openslx.libvirt.domain.device;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+
+/**
+ * A network bridge interface device node in a Libvirt domain XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class InterfaceBridge extends Interface
+{
+ /**
+ * Creates an empty network bridge interface device.
+ */
+ public InterfaceBridge()
+ {
+ super();
+ }
+
+ /**
+ * Creates a network bridge interface device representing an existing Libvirt XML network bridge
+ * interface device element.
+ *
+ * @param xmlNode existing Libvirt XML network bridge interface device element.
+ */
+ public InterfaceBridge( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Creates a non-existent network bridge interface device as Libvirt XML device element.
+ *
+ * @param xmlNode Libvirt XML node of the Libvirt XML device that is created.
+ * @return created network bridge interface device instance.
+ */
+ public static InterfaceBridge createInstance( LibvirtXmlNode xmlNode )
+ {
+ return InterfaceBridge.newInstance( xmlNode );
+ }
+
+ /**
+ * Creates a network bridge interface device representing an existing Libvirt XML network bridge
+ * interface device element.
+ *
+ * @param xmlNode existing Libvirt XML network bridge interface device element.
+ * @return network bridge interface device instance.
+ */
+ public static InterfaceBridge newInstance( LibvirtXmlNode xmlNode )
+ {
+ return new InterfaceBridge( xmlNode );
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/InterfaceNetwork.java b/src/main/java/org/openslx/libvirt/domain/device/InterfaceNetwork.java
new file mode 100644
index 0000000..ae1fd40
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/InterfaceNetwork.java
@@ -0,0 +1,54 @@
+package org.openslx.libvirt.domain.device;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+
+/**
+ * A network interface device node in a Libvirt domain XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class InterfaceNetwork extends Interface
+{
+ /**
+ * Creates an empty network interface device.
+ */
+ public InterfaceNetwork()
+ {
+ super();
+ }
+
+ /**
+ * Creates a network interface device representing an existing Libvirt XML network interface
+ * device element.
+ *
+ * @param xmlNode existing Libvirt XML network interface device element.
+ */
+ public InterfaceNetwork( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Creates a non-existent network interface device as Libvirt XML device element.
+ *
+ * @param xmlNode Libvirt XML node of the Libvirt XML device that is created.
+ * @return created network interface device device instance.
+ */
+ public static InterfaceNetwork createInstance( LibvirtXmlNode xmlNode )
+ {
+ return InterfaceNetwork.newInstance( xmlNode );
+ }
+
+ /**
+ * Creates a network interface device representing an existing Libvirt XML network interface
+ * device element.
+ *
+ * @param xmlNode existing Libvirt XML network interface device element.
+ * @return network interface device instance.
+ */
+ public static InterfaceNetwork newInstance( LibvirtXmlNode xmlNode )
+ {
+ return new InterfaceNetwork( xmlNode );
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/Parallel.java b/src/main/java/org/openslx/libvirt/domain/device/Parallel.java
new file mode 100644
index 0000000..7db60ca
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/Parallel.java
@@ -0,0 +1,158 @@
+package org.openslx.libvirt.domain.device;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+
+/**
+ * A parallel port device node in a Libvirt domain XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class Parallel extends Device
+{
+ /**
+ * Creates an empty parallel port device.
+ */
+ public Parallel()
+ {
+ super();
+ }
+
+ /**
+ * Creates a parallel port device representing an existing Libvirt XML parallel port device
+ * element.
+ *
+ * @param xmlNode existing Libvirt XML parallel port device element.
+ */
+ public Parallel( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Returns the type of the parallel port device.
+ *
+ * @return type of the parallel port device.
+ */
+ public Type getType()
+ {
+ final String type = this.getXmlElementAttributeValue( "type" );
+ return Type.fromString( type );
+ }
+
+ /**
+ * Sets the type for the parallel port device.
+ *
+ * @param type type for the parallel port device.
+ */
+ public void setType( Type type )
+ {
+ this.setXmlElementAttributeValue( "type", type.toString() );
+ }
+
+ /**
+ * Returns the source of the parallel port device.
+ *
+ * @return source of the parallel port device.
+ */
+ public String getSource()
+ {
+ return this.getXmlElementAttributeValue( "source", "path" );
+ }
+
+ /**
+ * Sets the source for the parallel port device.
+ *
+ * @param source source for the parallel port device.
+ */
+ public void setSource( String source )
+ {
+ this.setXmlElementAttributeValue( "source", "path", source );
+ }
+
+ /**
+ * Creates a non-existent parallel port device as Libvirt XML parallel port device element.
+ *
+ * @param xmlNode Libvirt XML node of the Libvirt XML parallel port device that is created.
+ * @return created parallel port device instance.
+ */
+ public static Parallel createInstance( LibvirtXmlNode xmlNode )
+ {
+ return Parallel.newInstance( xmlNode );
+ }
+
+ /**
+ * Creates a parallel port device representing an existing Libvirt XML parallel port device
+ * element.
+ *
+ * @param xmlNode existing Libvirt XML parallel port device element.
+ * @return parallel port device instance.
+ */
+ public static Parallel newInstance( LibvirtXmlNode xmlNode )
+ {
+ return new Parallel( xmlNode );
+ }
+
+ /**
+ * Type of parallel port device.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+ public enum Type
+ {
+ // @formatter:off
+ DEV ( "dev" ),
+ FILE ( "file" ),
+ PIPE ( "pipe" ),
+ UNIX ( "unix" ),
+ TCP ( "tcp" ),
+ UDP ( "udp" ),
+ NULL ( "null" ),
+ STDIO ( "stdio" ),
+ VC ( "vc" ),
+ PTY ( "pty" ),
+ SPICEVMC ( "spicevmc" ),
+ SPICEPORT( "spiceport" ),
+ NMDM ( "nmdm" );
+ // @formatter:on
+
+ /**
+ * Name of the parallel port device type.
+ */
+ private String type;
+
+ /**
+ * Creates parallel port device type.
+ *
+ * @param type valid name of the parallel port device type in a Libvirt domain XML document.
+ */
+ Type( String type )
+ {
+ this.type = type;
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.type;
+ }
+
+ /**
+ * Creates parallel port device type from its name with error check.
+ *
+ * @param type name of the parallel port device type in a Libvirt domain XML document.
+ * @return valid parallel port device type.
+ */
+ public static Type fromString( String type )
+ {
+ for ( Type t : Type.values() ) {
+ if ( t.type.equalsIgnoreCase( type ) ) {
+ return t;
+ }
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/Serial.java b/src/main/java/org/openslx/libvirt/domain/device/Serial.java
new file mode 100644
index 0000000..54be26e
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/Serial.java
@@ -0,0 +1,156 @@
+package org.openslx.libvirt.domain.device;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+
+/**
+ * A serial port device node in a Libvirt domain XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class Serial extends Device
+{
+ /**
+ * Creates an empty serial port device.
+ */
+ public Serial()
+ {
+ super();
+ }
+
+ /**
+ * Creates a serial port device representing an existing Libvirt XML serial port device element.
+ *
+ * @param xmlNode existing Libvirt XML serial port device element.
+ */
+ public Serial( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Returns the type of the serial port device.
+ *
+ * @return type of the serial port device.
+ */
+ public Type getType()
+ {
+ final String type = this.getXmlElementAttributeValue( "type" );
+ return Type.fromString( type );
+ }
+
+ /**
+ * Sets the type for the serial port device.
+ *
+ * @param type type for the serial port device.
+ */
+ public void setType( Type type )
+ {
+ this.setXmlElementAttributeValue( "type", type.toString() );
+ }
+
+ /**
+ * Returns the source of the serial port device.
+ *
+ * @return source of the serial port device.
+ */
+ public String getSource()
+ {
+ return this.getXmlElementAttributeValue( "source", "path" );
+ }
+
+ /**
+ * Sets the source for the serial port device.
+ *
+ * @param source source for the serial port device.
+ */
+ public void setSource( String source )
+ {
+ this.setXmlElementAttributeValue( "source", "path", source );
+ }
+
+ /**
+ * Creates a non-existent serial port device as Libvirt XML serial port device element.
+ *
+ * @param xmlNode Libvirt XML node of the Libvirt XML serial port device that is created.
+ * @return created serial port device instance.
+ */
+ public static Serial createInstance( LibvirtXmlNode xmlNode )
+ {
+ return Serial.newInstance( xmlNode );
+ }
+
+ /**
+ * Creates a serial port device representing an existing Libvirt XML serial port device element.
+ *
+ * @param xmlNode existing Libvirt XML serial port device element.
+ * @return serial port device instance.
+ */
+ public static Serial newInstance( LibvirtXmlNode xmlNode )
+ {
+ return new Serial( xmlNode );
+ }
+
+ /**
+ * Type of serial port device.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+ public enum Type
+ {
+ // @formatter:off
+ DEV ( "dev" ),
+ FILE ( "file" ),
+ PIPE ( "pipe" ),
+ UNIX ( "unix" ),
+ TCP ( "tcp" ),
+ UDP ( "udp" ),
+ NULL ( "null" ),
+ STDIO ( "stdio" ),
+ VC ( "vc" ),
+ PTY ( "pty" ),
+ SPICEVMC ( "spicevmc" ),
+ SPICEPORT( "spiceport" ),
+ NMDM ( "nmdm" );
+ // @formatter:on
+
+ /**
+ * Name of the serial port device type.
+ */
+ private String type;
+
+ /**
+ * Creates serial port device type.
+ *
+ * @param type valid name of the serial port device type in a Libvirt domain XML document.
+ */
+ Type( String type )
+ {
+ this.type = type;
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.type;
+ }
+
+ /**
+ * Creates serial port device type from its name with error check.
+ *
+ * @param type name of the serial port device type in a Libvirt domain XML document.
+ * @return valid serial port device type.
+ */
+ public static Type fromString( String type )
+ {
+ for ( Type t : Type.values() ) {
+ if ( t.type.equalsIgnoreCase( type ) ) {
+ return t;
+ }
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/Shmem.java b/src/main/java/org/openslx/libvirt/domain/device/Shmem.java
new file mode 100644
index 0000000..3c48c95
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/Shmem.java
@@ -0,0 +1,178 @@
+package org.openslx.libvirt.domain.device;
+
+import java.math.BigInteger;
+
+import org.openslx.libvirt.domain.DomainUtils;
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+
+/**
+ * A shared memory device node in a Libvirt domain XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class Shmem extends Device
+{
+ /**
+ * Creates an empty sound device.
+ */
+ public Shmem()
+ {
+ super();
+ }
+
+ /**
+ * Creates a shared memory device representing an existing Libvirt XML shared memory device
+ * element.
+ *
+ * @param xmlNode existing Libvirt XML shared memory device element.
+ */
+ public Shmem( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Returns the model of the shared memory device.
+ *
+ * @return model of the shared memory device.
+ */
+ public Model getModel()
+ {
+ String model = this.getXmlElementAttributeValue( "model", "type" );
+ return Model.fromString( model );
+ }
+
+ /**
+ * Sets the model for the shared memory device.
+ *
+ * @param model model for the shared memory device.
+ */
+ public void setModel( Model model )
+ {
+ this.setXmlElementAttributeValue( "model", "type", model.toString() );
+ }
+
+ /**
+ * Returns the name of the shared memory device.
+ *
+ * @return name of the shared memory device.
+ */
+ public String getName()
+ {
+ return this.getXmlElementAttributeValue( "name" );
+ }
+
+ /**
+ * Sets the name for the shared memory device.
+ *
+ * @param name name for the shared memory device.
+ */
+ public void setName( String name )
+ {
+ this.setXmlElementAttributeValue( "name", name );
+ }
+
+ /**
+ * Returns the memory size of the shared memory device.
+ *
+ * @return memory size of the shared memory device in bytes.
+ */
+ public BigInteger getSize()
+ {
+ final String unit = this.getXmlElementAttributeValue( "size", "unit" );
+ final String size = this.getXmlElementValue( "size" );
+
+ return DomainUtils.decodeMemory( size, unit );
+ }
+
+ /**
+ * Sets the memory size for the shared memory device.
+ *
+ * @param size memory size for the shared memory device in bytes.
+ */
+ public void setSize( BigInteger memory )
+ {
+ final String unit = "M";
+ final String size = DomainUtils.encodeMemory( memory, unit );
+
+ this.setXmlElementAttributeValue( "size", "unit", unit );
+ this.setXmlElementValue( "size", size );
+ }
+
+ /**
+ * Creates a non-existent shared memory device as Libvirt XML device element.
+ *
+ * @param xmlNode Libvirt XML node of the Libvirt XML device that is created.
+ * @return created shared memory device instance.
+ */
+ public static Shmem createInstance( LibvirtXmlNode xmlNode )
+ {
+ return Shmem.newInstance( xmlNode );
+ }
+
+ /**
+ * Creates a shared memory device representing an existing Libvirt XML shared memory device
+ * element.
+ *
+ * @param xmlNode existing Libvirt XML shared memory device element.
+ * @return shared memory device instance.
+ */
+ public static Shmem newInstance( LibvirtXmlNode xmlNode )
+ {
+ return new Shmem( xmlNode );
+ }
+
+ /**
+ * Model of shared memory device.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+ public enum Model
+ {
+ // @formatter:off
+ IVSHMEM ( "ivshmem" ),
+ IVSHMEM_PLAIN ( "ivshmem-plain" ),
+ IVSHMEM_DOORBELL( "ivshmem-doorbell" );
+ // @formatter:on
+
+ /**
+ * Name of the shared memory device model.
+ */
+ private String model;
+
+ /**
+ * Creates shared memory device model.
+ *
+ * @param type valid name of the shared memory device model in a Libvirt domain XML document.
+ */
+ Model( String model )
+ {
+ this.model = model;
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.model;
+ }
+
+ /**
+ * Creates shared memory device model from its name with error check.
+ *
+ * @param model name of the shared memory device model in a Libvirt domain XML document.
+ * @return valid shared memory device model.
+ */
+ public static Model fromString( String model )
+ {
+ for ( Model m : Model.values() ) {
+ if ( m.model.equalsIgnoreCase( model ) ) {
+ return m;
+ }
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/Sound.java b/src/main/java/org/openslx/libvirt/domain/device/Sound.java
new file mode 100644
index 0000000..dfeeffd
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/Sound.java
@@ -0,0 +1,128 @@
+package org.openslx.libvirt.domain.device;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+
+/**
+ * A sound device node in a Libvirt domain XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class Sound extends Device
+{
+ /**
+ * Creates an empty sound device.
+ */
+ public Sound()
+ {
+ super();
+ }
+
+ /**
+ * Creates a sound device representing an existing Libvirt XML sound device element.
+ *
+ * @param xmlNode existing Libvirt XML sound device element.
+ */
+ public Sound( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Returns hardware model of the sound device.
+ *
+ * @return hardware model of the sound device.
+ */
+ public Model getModel()
+ {
+ String model = this.getXmlElementAttributeValue( "model" );
+ return Model.fromString( model );
+ }
+
+ /**
+ * Sets hardware model for the sound device.
+ *
+ * @param model hardware model for the sound device.
+ */
+ public void setModel( Model model )
+ {
+ this.setXmlElementAttributeValue( "model", model.toString() );
+ }
+
+ /**
+ * Creates a non-existent sound device as Libvirt XML device element.
+ *
+ * @param xmlNode Libvirt XML node of the Libvirt XML device that is created.
+ * @return created sound device instance.
+ */
+ public static Sound createInstance( LibvirtXmlNode xmlNode )
+ {
+ return Sound.newInstance( xmlNode );
+ }
+
+ /**
+ * Creates a sound device representing an existing Libvirt XML sound device element.
+ *
+ * @param xmlNode existing Libvirt XML sound device element.
+ * @return sound device instance.
+ */
+ public static Sound newInstance( LibvirtXmlNode xmlNode )
+ {
+ return new Sound( xmlNode );
+ }
+
+ /**
+ * Model of sound device.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+ public enum Model
+ {
+ // @formatter:off
+ AC97 ( "ac97" ),
+ ES1370( "es1370" ),
+ ICH6 ( "ich6" ),
+ ICH9 ( "ich9" ),
+ SB16 ( "sb16" );
+ // @formatter:on
+
+ /**
+ * Name of the sound device model.
+ */
+ private String model;
+
+ /**
+ * Creates sound device model.
+ *
+ * @param type valid name of the sound device model in a Libvirt domain XML document.
+ */
+ Model( String model )
+ {
+ this.model = model;
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.model;
+ }
+
+ /**
+ * Creates sound device model from its name with error check.
+ *
+ * @param model name of the sound device model in a Libvirt domain XML document.
+ * @return valid sound device model.
+ */
+ public static Model fromString( String model )
+ {
+ for ( Model m : Model.values() ) {
+ if ( m.model.equalsIgnoreCase( model ) ) {
+ return m;
+ }
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/domain/device/Video.java b/src/main/java/org/openslx/libvirt/domain/device/Video.java
new file mode 100644
index 0000000..a674715
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/domain/device/Video.java
@@ -0,0 +1,197 @@
+package org.openslx.libvirt.domain.device;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+
+/**
+ * A video (GPU) device node in a Libvirt domain XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class Video extends Device
+{
+ /**
+ * Creates an empty video device.
+ */
+ public Video()
+ {
+ super();
+ }
+
+ /**
+ * Creates a video device representing an existing Libvirt XML video device element.
+ *
+ * @param xmlNode existing Libvirt XML video device element.
+ */
+ public Video( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Returns hardware model of the video device.
+ *
+ * @return hardware model of the video device.
+ */
+ public Model getModel()
+ {
+ String model = this.getXmlElementAttributeValue( "model", "type" );
+ return Model.fromString( model );
+ }
+
+ /**
+ * Sets hardware model for the video device.
+ *
+ * @param model hardware model for the video device.
+ */
+ public void setModel( Model model )
+ {
+ this.setXmlElementAttributeValue( "model", "type", model.toString() );
+ }
+
+ /**
+ * Checks whether 2D hardware video acceleration is turned on or off.
+ *
+ * @return state of 2D hardware video acceleration.
+ */
+ public boolean get2DAcceleration()
+ {
+ return this.getXmlElementAttributeValueAsBool( "model/acceleration", "accel2d" );
+ }
+
+ /**
+ * Turns 2D hardware video acceleration on or off.
+ *
+ * @param acceleration state of 2D hardware video acceleration.
+ */
+ public void set2DAcceleration( boolean acceleration )
+ {
+ Model model = this.getModel();
+
+ if ( model != null ) {
+ if ( model == Model.VIRTIO ) {
+ // only set acceleration on supported Virtio GPUs
+ this.setXmlElementAttributeValueYesNo( "model/acceleration", "accel2d", acceleration );
+ } else {
+ String errorMsg =
+ "Video card model '" + model.toString() + "' does not support enabled 2D hardware acceleration.";
+ throw new IllegalArgumentException( errorMsg );
+ }
+ }
+ }
+
+ /**
+ * Checks whether 3D hardware video acceleration is turned on or off.
+ *
+ * @return state of 3D hardware video acceleration.
+ */
+ public boolean get3DAcceleration()
+ {
+ return this.getXmlElementAttributeValueAsBool( "model/acceleration", "accel3d" );
+ }
+
+ /**
+ * Turns 3D hardware video acceleration on or off.
+ *
+ * @param acceleration state of 3D hardware video acceleration.
+ */
+ public void set3DAcceleration( boolean acceleration )
+ {
+ Model model = this.getModel();
+
+ if ( model == Model.VIRTIO ) {
+ // only set acceleration on supported Virtio GPUs
+ this.setXmlElementAttributeValueYesNo( "model/acceleration", "accel3d", acceleration );
+ } else {
+ String errorMsg =
+ "Video card model '" + model.toString() + "' does not support enabled 3D hardware acceleration.";
+ throw new IllegalArgumentException( errorMsg );
+ }
+ }
+
+ /**
+ * Disables the video device by setting the model to {@link Model#NONE}.
+ */
+ public void disable()
+ {
+ this.removeXmlElementChilds();
+ this.setModel( Model.NONE );
+ }
+
+ /**
+ * Creates a non-existent video device as Libvirt XML device element.
+ *
+ * @param xmlNode Libvirt XML node of the Libvirt XML device that is created.
+ * @return created video device instance.
+ */
+ public static Video createInstance( LibvirtXmlNode xmlNode )
+ {
+ return Video.newInstance( xmlNode );
+ }
+
+ /**
+ * Creates a video device representing an existing Libvirt XML video device element.
+ *
+ * @param xmlNode existing Libvirt XML video device element.
+ * @return video device instance.
+ */
+ public static Video newInstance( LibvirtXmlNode xmlNode )
+ {
+ return new Video( xmlNode );
+ }
+
+ /**
+ * Model of video device.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+ public enum Model
+ {
+ // @formatter:off
+ NONE ( "none" ),
+ QXL ( "qxl" ),
+ VGA ( "vga" ),
+ VMVGA ( "vmvga" ),
+ VIRTIO( "virtio" );
+ // @formatter:on
+
+ /**
+ * Name of the video device model.
+ */
+ private String model = null;
+
+ /**
+ * Creates video device model.
+ *
+ * @param type valid name of the video device model in a Libvirt domain XML document.
+ */
+ Model( String model )
+ {
+ this.model = model;
+ }
+
+ @Override
+ public String toString()
+ {
+ return this.model;
+ }
+
+ /**
+ * Creates video device model from its name with error check.
+ *
+ * @param model name of the video device model in a Libvirt domain XML document.
+ * @return valid video device model.
+ */
+ public static Model fromString( String model )
+ {
+ for ( Model m : Model.values() ) {
+ if ( m.model.equalsIgnoreCase( model ) ) {
+ return m;
+ }
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/libosinfo/LibOsInfo.java b/src/main/java/org/openslx/libvirt/libosinfo/LibOsInfo.java
new file mode 100644
index 0000000..f506d74
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/libosinfo/LibOsInfo.java
@@ -0,0 +1,158 @@
+package org.openslx.libvirt.libosinfo;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.function.Predicate;
+
+import org.openslx.libvirt.libosinfo.os.Os;
+import org.openslx.libvirt.xml.LibvirtXmlDocument;
+import org.openslx.libvirt.xml.LibvirtXmlDocumentException;
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+import org.openslx.libvirt.xml.LibvirtXmlResources;
+import org.openslx.libvirt.xml.LibvirtXmlSerializationException;
+import org.openslx.libvirt.xml.LibvirtXmlValidationException;
+import org.openslx.virtualization.Version;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+
+/**
+ * Implementation of a libosinfo XML document.
+ *
+ * The libosinfo XML document is used to describe existing operating systems, devices and their
+ * configuration possibilities.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class LibOsInfo extends LibvirtXmlDocument
+{
+ /**
+ * Creates a libosinfo XML document from a {@link String} providing libosinfo XML content.
+ *
+ * @param xml {@link String} with libosinfo XML content.
+ *
+ * @throws LibvirtXmlDocumentException creation of XML context failed.
+ * @throws LibvirtXmlSerializationException serialization of the libosinfo XML content failed.
+ * @throws LibvirtXmlValidationException XML content is not a valid libosinfo XML document.
+ */
+ public LibOsInfo( String xml )
+ throws LibvirtXmlDocumentException, LibvirtXmlSerializationException, LibvirtXmlValidationException
+ {
+ super( xml, LibvirtXmlResources.getLibOsInfoRng( "osinfo.rng" ) );
+ }
+
+ /**
+ * Creates a libosinfo XML document from a {@link File} containing libosinfo XML content.
+ *
+ * @param xml existing {@link File} containing libosinfo XML content.
+ *
+ * @throws LibvirtXmlDocumentException creation of XML context failed.
+ * @throws LibvirtXmlSerializationException serialization of the libosinfo XML content failed.
+ * @throws LibvirtXmlValidationException XML content is not a valid libosinfo XML document.
+ */
+ public LibOsInfo( File xml )
+ throws LibvirtXmlDocumentException, LibvirtXmlSerializationException, LibvirtXmlValidationException
+ {
+ super( xml, LibvirtXmlResources.getLibOsInfoRng( "osinfo.rng" ) );
+ }
+
+ /**
+ * Creates a libosinfo XML document from an {@link InputStream} providing libosinfo XML content.
+ *
+ * @param xml {@link InputStream} providing libosinfo XML content.
+ *
+ * @throws LibvirtXmlDocumentException creation of XML context failed.
+ * @throws LibvirtXmlSerializationException serialization of the libosinfo XML content failed.
+ * @throws LibvirtXmlValidationException XML content is not a valid libosinfo XML document.
+ */
+ public LibOsInfo( InputStream xml )
+ throws LibvirtXmlDocumentException, LibvirtXmlSerializationException, LibvirtXmlValidationException
+ {
+ super( xml, LibvirtXmlResources.getLibOsInfoRng( "osinfo.rng" ) );
+ }
+
+ /**
+ * Creates libosinfo XML document from {@link InputSource} providing libosinfo XML content.
+ *
+ * @param xml {@link InputSource} providing libosinfo XML content.
+ *
+ * @throws LibvirtXmlDocumentException creation of XML context failed.
+ * @throws LibvirtXmlSerializationException serialization of the libosinfo XML content failed.
+ * @throws LibvirtXmlValidationException XML content is not a valid libosinfo XML document.
+ */
+ public LibOsInfo( InputSource xml )
+ throws LibvirtXmlDocumentException, LibvirtXmlSerializationException, LibvirtXmlValidationException
+ {
+ super( xml, LibvirtXmlResources.getLibOsInfoRng( "osinfo.rng" ) );
+ }
+
+ /**
+ * Returns the version of the libosinfo database.
+ *
+ * @return version of the libosinfo database.
+ */
+ public Version getVersion()
+ {
+ final String version = this.getRootXmlNode().getXmlElementAttributeValue( "version" );
+ return Version.valueOf( version );
+ }
+
+ /**
+ * Returns a list of all defined operating systems.
+ *
+ * @return list of all defined operating systems.
+ */
+ public ArrayList<Os> getOses()
+ {
+ final ArrayList<Os> oses = new ArrayList<Os>();
+ final NodeList osNodes = this.getRootXmlNode().getXmlNodes( "os" );
+
+ if ( osNodes != null ) {
+ for ( int i = 0; i < osNodes.getLength(); i++ ) {
+ final Node childNode = osNodes.item( i );
+ if ( childNode.getNodeType() == Node.ELEMENT_NODE ) {
+ final LibvirtXmlNode osNode = new LibvirtXmlNode( this.getRootXmlNode().getXmlDocument(), childNode );
+ final Os os = Os.newInstance( osNode );
+
+ if ( os != null ) {
+ oses.add( os );
+ }
+ }
+ }
+ }
+
+ return oses;
+ }
+
+ /**
+ * Lookups an operating system in the libosinfo database specified by the operating system
+ * identifier.
+ *
+ * @param osId identifier of the operating system to lookup in the libosinfo database.
+ * @return found operating system from the libosinfo database.
+ */
+ public static Os lookupOs( String osId )
+ {
+ Os os = null;
+
+ if ( osId != null && !osId.isEmpty() ) {
+ ArrayList<Os> oses = null;
+
+ try {
+ final LibOsInfo osInfo = new LibOsInfo( LibvirtXmlResources.getLibOsInfoXml( "osinfo.xml" ) );
+ oses = osInfo.getOses();
+ } catch ( LibvirtXmlDocumentException | LibvirtXmlSerializationException | LibvirtXmlValidationException e ) {
+ oses = null;
+ }
+
+ if ( oses != null ) {
+ final Predicate<Os> byOsId = osCandidate -> osId.equals( osCandidate.getId() );
+ os = oses.stream().filter( byOsId ).findFirst().orElse( null );
+ }
+ }
+
+ return os;
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/libosinfo/os/Os.java b/src/main/java/org/openslx/libvirt/libosinfo/os/Os.java
new file mode 100644
index 0000000..37a0a2e
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/libosinfo/os/Os.java
@@ -0,0 +1,93 @@
+package org.openslx.libvirt.libosinfo.os;
+
+import org.openslx.libvirt.xml.LibvirtXmlNode;
+import org.openslx.virtualization.Version;
+
+/**
+ * A operating system node in a libosinfo XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class Os extends LibvirtXmlNode
+{
+ /**
+ * Creates an empty operating system.
+ */
+ public Os()
+ {
+ super();
+ }
+
+ /**
+ * Creates a operating system representing an existing libosinfo XML operating system element.
+ *
+ * @param xmlNode existing libosinfo XML operating system element.
+ */
+ public Os( LibvirtXmlNode xmlNode )
+ {
+ super( xmlNode );
+ }
+
+ /**
+ * Returns the identifier of the operating system.
+ *
+ * @return identifier of the operating system.
+ */
+ public String getId()
+ {
+ return this.getXmlElementAttributeValue( "id" );
+ }
+
+ /**
+ * Returns the name of the operating system.
+ *
+ * @return name of the operating system.
+ */
+ public String getName()
+ {
+ return this.getXmlElementValue( "name" );
+ }
+
+ /**
+ * Returns the version of the operating system.
+ *
+ * @return version of the operating system.
+ */
+ public Version getVersion()
+ {
+ final String version = this.getXmlElementValue( "version" );
+ return Version.valueOf( version );
+ }
+
+ /**
+ * Returns the system family of the operating system.
+ *
+ * @return system family of the operating system.
+ */
+ public String getFamily()
+ {
+ return this.getXmlElementValue( "family" );
+ }
+
+ /**
+ * Returns the distribution name of the operating system.
+ *
+ * @return distribution name of the operating system.
+ */
+ public String getDistro()
+ {
+ return this.getXmlElementValue( "distro" );
+ }
+
+ /**
+ * Creates a operating system representing an existing libosinfo XML operating system element.
+ *
+ * @param xmlNode existing libosinfo XML operating system element.
+ * @return libosinfo XML operating system instance.
+ */
+ public static Os newInstance( LibvirtXmlNode node )
+ {
+ return new Os( node );
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/xml/LibvirtXmlCreatable.java b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlCreatable.java
new file mode 100644
index 0000000..e799ace
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlCreatable.java
@@ -0,0 +1,26 @@
+package org.openslx.libvirt.xml;
+
+import org.w3c.dom.Node;
+
+/**
+ * Serializability of a Libvirt XML object from/to its XML representation.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public interface LibvirtXmlCreatable
+{
+ /**
+ * Serializing an object from its XML representation.
+ *
+ * @param xmlNode The object's XML representation.
+ */
+ void fromXmlNode( Node xmlNode );
+
+ /**
+ * Serializing the object to its XML representation.
+ *
+ * @return XML representation of the object.
+ */
+ Node toXmlNode();
+}
diff --git a/src/main/java/org/openslx/libvirt/xml/LibvirtXmlDocument.java b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlDocument.java
new file mode 100644
index 0000000..805376f
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlDocument.java
@@ -0,0 +1,355 @@
+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;
+ }
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/xml/LibvirtXmlDocumentException.java b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlDocumentException.java
new file mode 100644
index 0000000..f8605ed
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlDocumentException.java
@@ -0,0 +1,25 @@
+package org.openslx.libvirt.xml;
+
+/**
+ * An exception of a Libvirt XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class LibvirtXmlDocumentException extends Exception
+{
+ /**
+ * Version number for serialization.
+ */
+ private static final long serialVersionUID = -7423926322035713576L;
+
+ /**
+ * Creates an document exception including an error message.
+ *
+ * @param errorMsg message to describe a specific document error.
+ */
+ public LibvirtXmlDocumentException( String errorMsg )
+ {
+ super( errorMsg );
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/xml/LibvirtXmlEditable.java b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlEditable.java
new file mode 100644
index 0000000..0143e46
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlEditable.java
@@ -0,0 +1,285 @@
+package org.openslx.libvirt.xml;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * Editability of XML nodes based on XPath expressions.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public interface LibvirtXmlEditable
+{
+ /**
+ * Returns XML node selected by a XPath expression
+ *
+ * @param expression XPath expression to select XML node.
+ * @return selected XML node.
+ */
+ public Node getXmlNode( String expression );
+
+ /**
+ * Returns XML nodes selected by a XPath expression
+ *
+ * @param expression XPath expression to select XML nodes.
+ * @return selected XML nodes.
+ */
+ public NodeList getXmlNodes( String expression );
+
+ /**
+ * Return current XML root element.
+ *
+ * @return current XML root element.
+ */
+ public default Node getXmlElement()
+ {
+ return this.getXmlElement( null );
+ }
+
+ /**
+ * Returns XML element from selection by a XPath expression.
+ *
+ * @param expression XPath expression to select XML element.
+ * @return selected XML element.
+ */
+ public Node getXmlElement( String expression );
+
+ /**
+ * Sets an XML element selected by a XPath expression.
+ *
+ * If the XML element selected by the given XPath expression does not exists, the XML
+ * element will be created.
+ *
+ * @param expression XPath expression to select XML element.
+ */
+ public default void setXmlElement( String expression )
+ {
+ this.setXmlElement( expression, null );
+ }
+
+ /**
+ * Sets a XML element selected by a XPath expression and appends child XML node.
+ *
+ * If the XML element selected by the given XPath expression does not exists, the XML
+ * element will be created and the given XML child node is appended.
+ *
+ * @param expression XPath expression to select XML element.
+ * @param child XML node that will be appended to the selected XML element.
+ */
+ public void setXmlElement( String expression, Node child );
+
+ /**
+ * Returns the text value of a XML element selected by a XPath expression.
+ *
+ * @param expression XPath expression to select XML element.
+ * @return Text value of the selected XML element.
+ */
+ public String getXmlElementValue( String expression );
+
+ /**
+ * Sets the text value of a XML element selected by a XPath expression.
+ *
+ * @param expression XPath expression to select XML element.
+ * @param value text value to set selected XML element's text.
+ */
+ public void setXmlElementValue( String expression, String value );
+
+ /**
+ * Removes a XML element and all its childs selected by a XPath expression.
+ *
+ * @param expression XPath expression to select XML element.
+ */
+ public void removeXmlElement( String expression );
+
+ /**
+ * Removes all child elements of the current XML root element.
+ */
+ public default void removeXmlElementChilds()
+ {
+ this.removeXmlElementChilds( null );
+ }
+
+ /**
+ * Removes all child elements of a XML element selected by a XPath expression.
+ *
+ * @param expression XPath expression to select XML element.
+ */
+ public void removeXmlElementChilds( String expression );
+
+ /**
+ * Returns the text value of a XML attribute from the current XML root element.
+ *
+ * @param attributeName name to select XML attribute of the current XML root element.
+ * @return attribute text of the XML attribute from the current XML root element as
+ * {@link String}.
+ */
+ public default String getXmlElementAttributeValue( String attributeName )
+ {
+ return this.getXmlElementAttributeValue( null, attributeName );
+ }
+
+ /**
+ * Returns the binary choice of a XML attribute from the current XML root element.
+ *
+ * If the text value of the XML attribute equals to <i>yes</i> or <i>on</i>, the returned
+ * {@link boolean} value is set to <i>true</i>. Otherwise, if the text value of the XML attribute
+ * equals to <i>no</i> or <i>off</i>, the returned {@link boolean} value is set to <i>false</i>.
+ *
+ * @param attributeName name to select XML attribute of the current XML root element.
+ * @return attribute value of the XML attribute from the current XML root element as
+ * {@link boolean}.
+ */
+ public default boolean getXmlElementAttributeValueAsBool( String attributeName )
+ {
+ final String attributeValue = this.getXmlElementAttributeValue( attributeName );
+ return "yes".equals( attributeValue ) || "on".equals( attributeValue ) || "true".equals( attributeValue );
+ }
+
+ /**
+ * Returns the binary choice of a XML attribute from a XML element selected by a XPath
+ * expression.
+ *
+ * If the text value of the XML attribute equals to <i>yes</i> or <i>on</i>, the returned
+ * {@link boolean} value is set to <i>true</i>. Otherwise, if the text value of the XML attribute
+ * equals to <i>no</i> or <i>off</i>, the returned {@link boolean} value is set to <i>false</i>.
+ *
+ * @param expression XPath expression to select XML element.
+ * @param attributeName name to select XML attribute of the current XML root element.
+ * @return attribute value of the XML attribute from the current XML root element as
+ * {@link boolean}.
+ */
+ public default boolean getXmlElementAttributeValueAsBool( String expression, String attributeName )
+ {
+ final String attributeValue = this.getXmlElementAttributeValue( expression, attributeName );
+ return "yes".equals( attributeValue ) || "on".equals( attributeValue );
+ }
+
+ /**
+ * Returns the text value of a XML attribute from a XML element selected by a XPath expression.
+ *
+ * @param expression XPath expression to select XML element.
+ * @param attributeName name to select XML attribute of the selected XML element.
+ * @return attribute text of the XML attribute from the selected XML element.
+ */
+ public String getXmlElementAttributeValue( String expression, String attributeName );
+
+ /**
+ * Sets the text value of a XML attribute from the current XML root element.
+ *
+ * @param attributeName name to select XML attribute of the current XML root element.
+ * @param value XML attribute value for the selected XML attribute from the current XML root
+ * element.
+ */
+ public default void setXmlElementAttributeValue( String attributeName, String value )
+ {
+ this.setXmlElementAttributeValue( null, attributeName, value );
+ }
+
+ /**
+ * Sets the binary choice value of a XML attribute from the current XML root element.
+ *
+ * If the binary choice value for the XML attribute equals to <i>true</i>, the text value of the
+ * selected XML attribute is set to <i>yes</i>. Otherwise, if the binary choice value for the
+ * selected XML attribute equals to <i>false</i>, the text value of the selected XML attribute is
+ * set to <i>no</i>.
+ *
+ * @param attributeName name to select XML attribute of the selected XML element.
+ * @param value binary choice value for the selected XML attribute from the selected XML element.
+ */
+ public default void setXmlElementAttributeValueYesNo( String attributeName, boolean value )
+ {
+ final String valueYesNo = value ? "yes" : "no";
+ this.setXmlElementAttributeValue( attributeName, valueYesNo );
+ }
+
+ /**
+ * Sets the binary choice value of a XML attribute from a XML element selected by a XPath
+ * expression.
+ *
+ * If the binary choice value for the XML attribute equals to <i>true</i>, the text value of the
+ * selected XML attribute is set to <i>yes</i>. Otherwise, if the binary choice value for the
+ * selected XML attribute equals to <i>false</i>, the text value of the selected XML attribute is
+ * set to <i>no</i>.
+ *
+ * @param expression XPath expression to select XML element.
+ * @param attributeName name to select XML attribute of the selected XML element.
+ * @param value binary choice value for the selected XML attribute from the selected XML element.
+ */
+ public default void setXmlElementAttributeValueYesNo( String expression, String attributeName, boolean value )
+ {
+ final String valueYesNo = value ? "yes" : "no";
+ this.setXmlElementAttributeValue( expression, attributeName, valueYesNo );
+ }
+
+ /**
+ * Sets the binary choice value of a XML attribute from the current XML root element.
+ *
+ * If the binary choice value for the XML attribute equals to <i>true</i>, the text value of the
+ * selected XML attribute is set to <i>on</i>. Otherwise, if the binary choice value for the
+ * selected XML attribute equals to <i>false</i>, the text value of the selected XML attribute is
+ * set to <i>off</i>.
+ *
+ * @param attributeName name to select XML attribute of the selected XML element.
+ * @param value binary choice value for the selected XML attribute from the selected XML element.
+ */
+ public default void setXmlElementAttributeValueOnOff( String attributeName, boolean value )
+ {
+ final String valueOnOff = value ? "on" : "off";
+ this.setXmlElementAttributeValue( attributeName, valueOnOff );
+ }
+
+ /**
+ * Sets the binary choice value of a XML attribute from a XML element selected by a XPath
+ * expression.
+ *
+ * If the binary choice value for the XML attribute equals to <i>true</i>, the text value of the
+ * selected XML attribute is set to <i>on</i>. Otherwise, if the binary choice value for the
+ * selected XML attribute equals to <i>false</i>, the text value of the selected XML attribute is
+ * set to <i>off</i>.
+ *
+ * @param expression XPath expression to select XML element.
+ * @param attributeName name to select XML attribute of the selected XML element.
+ * @param value binary choice value for the selected XML attribute from the selected XML element.
+ */
+ public default void setXmlElementAttributeValueOnOff( String expression, String attributeName, boolean value )
+ {
+ final String valueOnOff = value ? "on" : "off";
+ this.setXmlElementAttributeValue( expression, attributeName, valueOnOff );
+ }
+
+ /**
+ * Sets the text value of a XML attribute from a XML element selected by a XPath expression.
+ *
+ * @param expression XPath expression to select XML element.
+ * @param attributeName name to select XML attribute of the selected XML element.
+ * @param value XML attribute value for the selected XML attribute from the selected XML element.
+ */
+ public void setXmlElementAttributeValue( String expression, String attributeName, String value );
+
+ /**
+ * Removes an XML attribute from the current XML root element.
+ *
+ * @param attributeName name of the attribute which should be deleted.
+ */
+ public default void removeXmlElementAttribute( String attributeName )
+ {
+ this.removeXmlElementAttribute( null, attributeName );
+ }
+
+ /**
+ * Removes an XML attribute from a XML element selected by a XPath expression.
+ *
+ * @param expression XPath expression to select XML element.
+ * @param attributeName name of the attribute which should be deleted.
+ */
+ public void removeXmlElementAttribute( String expression, String attributeName );
+
+ /**
+ * Removes all XML attributes from a XML element selected by a XPath expression.
+ *
+ * @param expression XPath expression to select XML element.
+ */
+ public void removeXmlElementAttributes( String expression );
+
+}
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();
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/xml/LibvirtXmlResources.java b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlResources.java
new file mode 100644
index 0000000..5aa3a5b
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlResources.java
@@ -0,0 +1,105 @@
+package org.openslx.libvirt.xml;
+
+import java.io.InputStream;
+
+import org.openslx.util.Resources;
+
+/**
+ * Collection of resource utils for a Libvirt XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public final class LibvirtXmlResources
+{
+ /**
+ * File path prefix of the absolute path to the libvirt resource folder in a *.jar file.
+ */
+ private static final String LIBVIRT_PREFIX_PATH = Resources.PATH_SEPARATOR + "libvirt";
+
+ /**
+ * File path prefix of the absolute path to the libosinfo resource folder in a *.jar file.
+ */
+ private static final String LIBOSINFO_PREFIX_PATH = Resources.PATH_SEPARATOR + "libvirt" + Resources.PATH_SEPARATOR
+ + "libosinfo";
+
+ /**
+ * File path prefix of the absolute path to the libvirt XSL resource folder in a *.jar file.
+ */
+ private static final String LIBVIRT_PREFIX_PATH_XSL = LIBVIRT_PREFIX_PATH + Resources.PATH_SEPARATOR + "xsl";
+
+ /**
+ * File path prefix of the absolute path to the libvirt RNG resource folder in a *.jar file.
+ */
+ private static final String LIBVIRT_PREFIX_PATH_RNG = LIBVIRT_PREFIX_PATH + Resources.PATH_SEPARATOR + "rng";
+
+ /**
+ * File path prefix of the absolute path to the libosinfo RNG resource folder in a *.jar file.
+ */
+ private static final String LIBOSINFO_PREFIX_PATH_RNG = LIBOSINFO_PREFIX_PATH + Resources.PATH_SEPARATOR + "rng";
+
+ /**
+ * File path prefix of the absolute path to the libosinfo XML resource folder in a *.jar file.
+ */
+ private static final String LIBOSINFO_PREFIX_PATH_XML = LIBOSINFO_PREFIX_PATH + Resources.PATH_SEPARATOR + "xml";
+
+ /**
+ * Returns a Libvirt resource as stream.
+ *
+ * @param prefix file path of the Libvirt resource in the resources *.jar folder.
+ * @param fileName file name of the Libvirt resource in the resources *.jar folder.
+ * @return Libvirt resource as stream.
+ */
+ private static InputStream getLibvirtResource( String prefix, String fileName )
+ {
+ final String path = prefix + Resources.PATH_SEPARATOR + fileName;
+ return LibvirtXmlResources.class.getResourceAsStream( path );
+ }
+
+ /**
+ * Returns a Libvirt XSL resource as stream.
+ *
+ * @param libvirtXslFileName file name of the XSL resource in the resources *.jar folder.
+ * @return Libvirt XSL resource as stream.
+ */
+ public static InputStream getLibvirtXsl( String libvirtXslFileName )
+ {
+ return LibvirtXmlResources.getLibvirtResource( LibvirtXmlResources.LIBVIRT_PREFIX_PATH_XSL, libvirtXslFileName );
+ }
+
+ /**
+ * Returns a Libvirt RNG schema resource as stream.
+ *
+ * @param libvirtRngFileName file name of the RNG schema resource in the resources *.jar folder.
+ * @return Libvirt RNG schema resource as stream.
+ */
+ public static InputStream getLibvirtRng( String libvirtRngFileName )
+ {
+ return LibvirtXmlResources.getLibvirtResource( LibvirtXmlResources.LIBVIRT_PREFIX_PATH_RNG, libvirtRngFileName );
+ }
+
+ /**
+ * Returns a libosinfo RNG schema resource as stream.
+ *
+ * @param libosInfoRngFileName file name of the RNG schema resource in the resources *.jar
+ * folder.
+ * @return libosinfo RNG schema resource as stream.
+ */
+ public static InputStream getLibOsInfoRng( String libosInfoRngFileName )
+ {
+ return LibvirtXmlResources.getLibvirtResource( LibvirtXmlResources.LIBOSINFO_PREFIX_PATH_RNG,
+ libosInfoRngFileName );
+ }
+
+ /**
+ * Returns a libosinfo XML resource as stream.
+ *
+ * @param libosInfoXmlFileName file name of the XML resource in the resources *.jar folder.
+ * @return libosinfo XML resource as stream.
+ */
+ public static InputStream getLibOsInfoXml( String libosInfoXmlFileName )
+ {
+ return LibvirtXmlResources.getLibvirtResource( LibvirtXmlResources.LIBOSINFO_PREFIX_PATH_XML,
+ libosInfoXmlFileName );
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/xml/LibvirtXmlSchemaValidator.java b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlSchemaValidator.java
new file mode 100644
index 0000000..d589d41
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlSchemaValidator.java
@@ -0,0 +1,284 @@
+package org.openslx.libvirt.xml;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.nio.charset.StandardCharsets;
+
+import javax.xml.XMLConstants;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.Validator;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.ls.LSInput;
+import org.w3c.dom.ls.LSResourceResolver;
+import org.xml.sax.SAXException;
+
+/**
+ * Resource resolver input for RelaxNG schemas.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+class LibvirtXmlSchemaResourceInput implements LSInput
+{
+ /**
+ * Stores the public identification of the schema resource.
+ */
+ private String publicId;
+
+ /**
+ * Stores the system identification of the schema resource.
+ */
+ private String systemId;
+
+ /**
+ * Stream to process and read the schema resource.
+ */
+ private BufferedInputStream inputStream;
+
+ /**
+ * Creates a resource resolver input for a RelaxNG schema.
+ *
+ * @param publicId public identification of the schema resource.
+ * @param sysId system identification of the schema resource.
+ * @param input stream of the schema resource.
+ */
+ public LibvirtXmlSchemaResourceInput( String publicId, String sysId, InputStream input )
+ {
+ this.publicId = publicId;
+ this.systemId = sysId;
+ this.inputStream = new BufferedInputStream( input );
+ }
+
+ @Override
+ public String getBaseURI()
+ {
+ return null;
+ }
+
+ @Override
+ public InputStream getByteStream()
+ {
+ return null;
+ }
+
+ @Override
+ public boolean getCertifiedText()
+ {
+ return false;
+ }
+
+ @Override
+ public Reader getCharacterStream()
+ {
+ return null;
+ }
+
+ @Override
+ public String getEncoding()
+ {
+ return null;
+ }
+
+ @Override
+ public String getPublicId()
+ {
+ return this.publicId;
+ }
+
+ @Override
+ public String getStringData()
+ {
+ String data = null;
+
+ synchronized ( this.inputStream ) {
+ try {
+ int inputLength = this.inputStream.available();
+ byte[] input = new byte[ inputLength ];
+ this.inputStream.read( input );
+ data = new String( input, StandardCharsets.UTF_8 );
+ } catch ( IOException e ) {
+ e.printStackTrace();
+ }
+ }
+
+ return data;
+ }
+
+ @Override
+ public String getSystemId()
+ {
+ return this.systemId;
+ }
+
+ @Override
+ public void setBaseURI( String arg0 )
+ {
+ }
+
+ @Override
+ public void setByteStream( InputStream arg0 )
+ {
+ }
+
+ @Override
+ public void setCertifiedText( boolean arg0 )
+ {
+ }
+
+ @Override
+ public void setCharacterStream( Reader arg0 )
+ {
+ }
+
+ @Override
+ public void setEncoding( String arg0 )
+ {
+ }
+
+ @Override
+ public void setPublicId( String arg0 )
+ {
+ this.publicId = arg0;
+ }
+
+ @Override
+ public void setStringData( String arg0 )
+ {
+ }
+
+ @Override
+ public void setSystemId( String arg0 )
+ {
+ this.systemId = arg0;
+ }
+}
+
+/**
+ * Resource resolver for RelaxNG schemas.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+class LibvirtXmlSchemaResourceResolver implements LSResourceResolver
+{
+ @Override
+ public LSInput resolveResource( String type, String namespaceURI, String publicId, String systemId, String baseURI )
+ {
+ InputStream rngResourceStream = LibvirtXmlResources.getLibvirtRng( systemId );
+ return new LibvirtXmlSchemaResourceInput( publicId, systemId, rngResourceStream );
+ }
+}
+
+/**
+ * Validator for validation of Libvirt XML documents with RelaxNG schemas.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class LibvirtXmlSchemaValidator
+{
+ /**
+ * RelaxNG based validator for validation of Libvirt XML documents.
+ */
+ private Validator rngSchemaValidator;
+
+ /**
+ * Creates a validator for validation of Libvirt XML documents with RelaxNG schemas.
+ *
+ * @param rngSchema RelaxNG schema used for validation with {@link #validate(Document)}.
+ *
+ * @throws SAXException creation of a Libvirt XML validator failed.
+ */
+ public LibvirtXmlSchemaValidator( InputStream rngSchema ) throws SAXException
+ {
+ this.createValidationContext( rngSchema );
+ }
+
+ /**
+ * Creates context for validation of Libvirt XML documents with a RelaxNG schema.
+ *
+ * @param rngSchema RelaxNG schema used for validation with {@link #validate(Document)}.
+ *
+ * @throws SAXException Loading, creation and processing of <code>rngSchema</code> has failed.
+ */
+ private void createValidationContext( InputStream rngSchema ) throws SAXException
+ {
+ // use hack to load specific schema factory implementation for RelaxNG schemas
+ System.setProperty( SchemaFactory.class.getName() + ":" + XMLConstants.RELAXNG_NS_URI,
+ "com.thaiopensource.relaxng.jaxp.XMLSyntaxSchemaFactory" );
+
+ // create schema resource resolver to resolve schema resources during parsing and validation
+ LibvirtXmlSchemaResourceResolver schemaResolver = new LibvirtXmlSchemaResourceResolver();
+
+ // create schema factory to be able to create a RelaxNG schema validator
+ SchemaFactory factory = SchemaFactory.newInstance( XMLConstants.RELAXNG_NS_URI );
+ factory.setResourceResolver( schemaResolver );
+ Schema schema = factory.newSchema( new StreamSource( rngSchema ) );
+
+ // create the RelaxNG schema validator
+ this.rngSchemaValidator = schema.newValidator();
+ this.rngSchemaValidator.setResourceResolver( schemaResolver );
+ }
+
+ /**
+ * Transforms a DOM source to a Stream source.
+ *
+ * @param domSource DOM source of a Libvirt XML document.
+ * @return Stream source of a Libvirt XML document.
+ *
+ * @throws TransformerException Transformation of DOM source to a Stream source has failed.
+ *
+ * @implNote This utility method is necessary in {@link #validate(Document)} to be able to
+ * validate a DOM Libvirt XML document with the schema and validator implementation for
+ * RelaxNG schema files from
+ * <code>com.thaiopensource.relaxng.jaxp.XMLSyntaxSchemaFactory</code>.
+ */
+ private static StreamSource toStreamSource( DOMSource domSource ) throws TransformerException
+ {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ StreamResult result = new StreamResult( outputStream );
+
+ // create identity transformer
+ Transformer transformer = TransformerFactory.newInstance().newTransformer();
+ transformer.transform( domSource, result );
+
+ ByteArrayInputStream inputStream = new ByteArrayInputStream( outputStream.toByteArray() );
+ return new StreamSource( inputStream );
+ }
+
+ /**
+ * Validates a given (and parsed) DOM Libvirt XML document.
+ *
+ * Validation takes place if the specified <code>xmlDocument</code> is non-null, otherwise the
+ * validation succeeds immediately. If the validation of the <code>xmlDocument</code> fails, a
+ * validation exception is thrown.
+ *
+ * @param xmlDocument Libvirt XML document.
+ *
+ * @throws LibvirtXmlValidationException Validation of Libvirt XML document failed.
+ */
+ public void validate( Document xmlDocument ) throws LibvirtXmlValidationException
+ {
+ if ( xmlDocument != null ) {
+ try {
+ DOMSource domSource = new DOMSource( xmlDocument );
+ StreamSource source = LibvirtXmlSchemaValidator.toStreamSource( domSource );
+ this.rngSchemaValidator.validate( source );
+ } catch ( SAXException | TransformerException | IOException e ) {
+ throw new LibvirtXmlValidationException( e.getLocalizedMessage() );
+ }
+ }
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/xml/LibvirtXmlSerializable.java b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlSerializable.java
new file mode 100644
index 0000000..4cd0a32
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlSerializable.java
@@ -0,0 +1,69 @@
+package org.openslx.libvirt.xml;
+
+import java.io.File;
+import java.io.InputStream;
+
+import org.xml.sax.InputSource;
+
+/**
+ * Serializability of a Libvirt XML document from/to a XML file.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public abstract interface LibvirtXmlSerializable
+{
+ /**
+ * Serialize Libvirt XML document from {@link String}.
+ *
+ * @param xml {@link String} containing XML content.
+ *
+ * @throws LibvirtXmlSerializationException serialization of Libvirt XML document failed.
+ */
+ public void fromXml( String xml ) throws LibvirtXmlSerializationException;
+
+ /**
+ * Serialize Libvirt XML document from {@link File}.
+ *
+ * @param xml {@link File} containing XML content.
+ *
+ * @throws LibvirtXmlSerializationException serialization of Libvirt XML document failed.
+ */
+ public void fromXml( File xml ) throws LibvirtXmlSerializationException;
+
+ /**
+ * Serialize Libvirt XML document from {@link InputStream}.
+ *
+ * @param xml {@link InputStream} providing XML content.
+ *
+ * @throws LibvirtXmlSerializationException serialization of Libvirt XML document failed.
+ */
+ void fromXml( InputStream xml ) throws LibvirtXmlSerializationException;
+
+ /**
+ * Serialize Libvirt XML document from {@link InputSource}.
+ *
+ * @param xml {@link InputSource} providing XML content.
+ *
+ * @throws LibvirtXmlSerializationException serialization of Libvirt XML document failed.
+ */
+ public void fromXml( InputSource xml ) throws LibvirtXmlSerializationException;
+
+ /**
+ * Serialize Libvirt XML document to {@link String}.
+ *
+ * @return XML {@link String} containing Libvirt XML document content.
+ *
+ * @throws LibvirtXmlSerializationException serialization of Libvirt XML document failed.
+ */
+ public String toXml() throws LibvirtXmlSerializationException;
+
+ /**
+ * Serialize Libvirt XML document to {@link File}.
+ *
+ * @param xml XML {@link File} containing Libvirt XML document content.
+ *
+ * @throws LibvirtXmlSerializationException serialization of Libvirt XML document failed.
+ */
+ public void toXml( File xml ) throws LibvirtXmlSerializationException;
+}
diff --git a/src/main/java/org/openslx/libvirt/xml/LibvirtXmlSerializationException.java b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlSerializationException.java
new file mode 100644
index 0000000..d522107
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlSerializationException.java
@@ -0,0 +1,25 @@
+package org.openslx.libvirt.xml;
+
+/**
+ * An exception of an serialization error during Libvirt XML serialization.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class LibvirtXmlSerializationException extends Exception
+{
+ /**
+ * Version number for serialization.
+ */
+ private static final long serialVersionUID = 7995955592221349949L;
+
+ /**
+ * Creates a XML serialization exception including an error message.
+ *
+ * @param errorMsg message to describe a specific XML serialization error.
+ */
+ public LibvirtXmlSerializationException( String errorMsg )
+ {
+ super( errorMsg );
+ }
+}
diff --git a/src/main/java/org/openslx/libvirt/xml/LibvirtXmlValidatable.java b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlValidatable.java
new file mode 100644
index 0000000..8574cc4
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlValidatable.java
@@ -0,0 +1,18 @@
+package org.openslx.libvirt.xml;
+
+/**
+ * Validatability of Libvirt XML document.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public abstract interface LibvirtXmlValidatable
+{
+ /**
+ * Validates the XML document's content and report error if document is not a valid Libvirt XML
+ * document.
+ *
+ * @throws LibvirtXmlValidationException XML content is not a valid Libvirt XML.
+ */
+ public void validateXml() throws LibvirtXmlValidationException;
+}
diff --git a/src/main/java/org/openslx/libvirt/xml/LibvirtXmlValidationException.java b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlValidationException.java
new file mode 100644
index 0000000..24e9db7
--- /dev/null
+++ b/src/main/java/org/openslx/libvirt/xml/LibvirtXmlValidationException.java
@@ -0,0 +1,25 @@
+package org.openslx.libvirt.xml;
+
+/**
+ * An exception of an unsuccessful Libvirt XML validation.
+ *
+ * @author Manuel Bentele
+ * @version 1.0
+ */
+public class LibvirtXmlValidationException extends Exception
+{
+ /**
+ * Version number for serialization.
+ */
+ private static final long serialVersionUID = 2299967599483742777L;
+
+ /**
+ * Creates a validation exception including an error message.
+ *
+ * @param errorMsg message to describe a specific Libvirt XML error.
+ */
+ public LibvirtXmlValidationException( String errorMsg )
+ {
+ super( errorMsg );
+ }
+}