[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [libvirt] libvirt-java storage support and refactoring



Here's a new take on the patch (It's against current CVS)

The changes from the previous patch:

- I've changed the generic functions to macros, so now they are as
typesafe as JNI lets them be.

- I've converted all applicable functions to the new macros

- Fixed more GetStringUTF... leaks

- Added SerialVersionUID to make Java happy

- Supressed warning about unused java method

This patch contains all outstanding major work that I had planned to do
short-term.

I think that all 0.4.1 functionality is in, and the Peek functions are
the only ones that remain from 0.4.4. I have plans to implement that as
well, but it may take a while, as they are not that interesting or
usable from java-land.

I've decided not to take the suggested script-generated route, because
at this point it seemed more trouble than it was worth. (The easy
methods are added in 3 minutes each as it is, and it won't help with the
complex ones. Also, the JNI workflow of .java->.class->.h->.c makes
auto-generation too hairy for my tastes.)

I've also re-evaluated the usage of jlong for pointers, but I still
think that it is solid. Realistically, the code will run either 32 or 64
bit architecture. On 64 bit the size is the same, and while there is a
signed-ness difference, the java code does no arithmetic on the values,
so it should be safe. If we run on 32 bits, then the JNI C code will
cast the received 32 bit pointer to 64 bit, which java will store as 64
bit signed, and then the reverse cast will convert it back to a 32 bit
pointer, the upper 32 bits are zeroed out all the way, so again, no data
is lost or corrupted.

Best regards

István


On Mon, 2008-08-04 at 01:56 -0400, Daniel Veillard wrote:
> On Mon, Aug 04, 2008 at 07:46:05AM +0200, Toth Istvan wrote:
> > On Sun, 2008-08-03 at 05:56 -0400, Daniel Veillard wrote: 
> > >   How is it smaller code ?
> > 
> > Actually, that's not the new-style code, It's just the bugfixed one. I
> > have not converted that file yet.
> 
>   heh, okay :-)
> 
> > To see the new style code, look at the *Storage*.c files.
> > 
> > A similar function looks like this there:
> > 
> > JNIEXPORT jlong JNICALL Java_org_libvirt_StoragePool__1storageVolCreateXML
> >   (JNIEnv *env, jobject obj, jlong VSPP, jstring xmlDesc, jint flags){
> > return generic_CreateDefineXML_with_flags(env, obj, VSPP, xmlDesc, flags, (void* (*)(void*, const char *, unsigned int))&virStorageVolCreateXML);
> > }
> > 
> 
>   ah, yes, I see now !
> 
> > > 
> > >  It seems to be that the old code didn't ever tried to free allocated strings
> > > and the new one does, which is the explanation of the code grows. I would side
> > > with Chris on the usage of macros instead of call like this. There is 2 reasons
> > > one is the readability, but also the static type checking.
> > 
> > Actually, the old-style function does static type checking, it's just
> > new style that suffers there.
> > 
> > Using macros is a great idea, that may get rid of all those nasty casts.
> 
>   yes that's probably the best alternative,
> 
>     thanks !
> 
> Daniel
> 
Index: src/org/libvirt/ErrorException.java
===================================================================
RCS file: /data/cvs/libvirt-java/src/org/libvirt/ErrorException.java,v
retrieving revision 1.1
diff -u -r1.1 ErrorException.java
--- src/org/libvirt/ErrorException.java	18 Jul 2008 14:37:21 -0000	1.1
+++ src/org/libvirt/ErrorException.java	4 Aug 2008 21:07:41 -0000
@@ -7,7 +7,7 @@
  *
  */
 public class ErrorException extends Exception {
-
+	private static final long serialVersionUID = -4329050530233404971L;
 	public ErrorException(String message) {
 		super(message);
 	}
Index: src/org/libvirt/Connect.java
===================================================================
RCS file: /data/cvs/libvirt-java/src/org/libvirt/Connect.java,v
retrieving revision 1.1
diff -u -r1.1 Connect.java
--- src/org/libvirt/Connect.java	18 Jul 2008 14:37:21 -0000	1.1
+++ src/org/libvirt/Connect.java	4 Aug 2008 21:07:41 -0000
@@ -1,5 +1,9 @@
 package org.libvirt;
 
+import org.libvirt.LibvirtException;
+import org.libvirt.StoragePool;
+import org.libvirt.StorageVol;
+
 /**
  * The Connect object represents a connection to a local or remote hypervisor/driver.
  *
@@ -91,7 +95,7 @@
 		VCP = 0;
 	}
 
-	private native void _close(long VCP) throws LibvirtException;
+	private native int _close(long VCP) throws LibvirtException;
 
 
 	/**
@@ -541,4 +545,157 @@
 
 	private native int _setDom0Memory(long memory) throws LibvirtException;
 
+	/**
+	 * Provides the number of inactive storage pools
+	 * 
+	 * @return the number of pools found
+	 * @throws LibvirtException
+	 */
+	public int numOfDefinedStoragePools() throws LibvirtException {
+		return _numOfDefinedStoragePools(VCP);
+	}
+
+	private native int _numOfDefinedStoragePools(long VCP) throws LibvirtException;
+
+	/**
+	 * Provides the number of active storage pools
+	 * 
+	 * @return the number of pools found
+	 * @throws LibvirtException
+	 */
+	public int numOfStoragePools() throws LibvirtException {
+		return _numOfStoragePools(VCP);
+	}
+
+	private native int _numOfStoragePools(long VCP) throws LibvirtException;
+
+	/**
+	 * Provides the list of names of inactive storage pools.
+	 *
+	 * @return an Array of Strings that contains the names of the defined storage pools
+	 * @throws LibvirtException
+	 */
+	public String[] listDefinedStoragePools() throws LibvirtException {
+		return _listDefinedStoragePools(VCP);
+	}
+
+	private native String[] _listDefinedStoragePools(long VCP)
+	throws LibvirtException;
+
+	/**
+	 * Provides the list of names of active storage pools.
+	 *
+	 * @return an Array of Strings that contains the names of the defined storage pools
+	 * @throws LibvirtException
+	 */
+	public String[] listStoragePools() throws LibvirtException {
+		return _listStoragePools(VCP);
+	}
+
+	private native String[] _listStoragePools(long VCP)
+	throws LibvirtException;
+	
+	/**
+	 * Create a new storage based on its XML description. 
+	 * The pool is not persistent, so its definition will disappear when it is destroyed, or if the host is restarted
+	 * 
+	 * @param xmlDesc XML description for new pool
+	 * @param flags future flags, use 0 for now
+	 * @return StoragePool object
+	 * @throws LibvirtException
+	 */
+	public StoragePool storagePoolCreateXML(String xmlDesc, int flags)
+	throws LibvirtException {
+		return new StoragePool(this, _virStoragePoolCreateXML(VCP, xmlDesc, flags));
+	}
+
+	private native long _virStoragePoolCreateXML(long VCP, String xmlDesc, int flags)
+	throws LibvirtException;
+	
+	/**
+	 * Define a new inactive storage pool based on its XML description. 
+	 * The pool is persistent, until explicitly undefined.
+	 * 
+	 * @param xmlDesc XML description for new pool
+	 * @param flags flags future flags, use 0 for now
+	 * @return StoragePool object
+	 * @throws LibvirtException
+	 */
+	public StoragePool storagePoolDefineXML(String xml, int flags)
+	throws LibvirtException {
+		return new StoragePool(this, _virStoragePoolDefineXML(VCP, xml, flags));
+	}
+
+	private native long _virStoragePoolDefineXML(long VCP, String xml, int flags)
+	throws LibvirtException;
+
+	/**
+	 * Fetch a storage pool based on its unique name
+	 * 
+	 * @param name name of pool to fetch
+	 * @return StoragePool object
+	 * @throws LibvirtException
+	 */
+	public StoragePool storagePoolLookupByName(String name)
+	throws LibvirtException {
+		return new StoragePool(this, _virStoragePoolLookupByName(VCP, name));
+	}
+
+	private native long _virStoragePoolLookupByName(long VCP, String name)
+	throws LibvirtException;
+
+	/**
+	 * Fetch a storage pool based on its globally unique id
+	 * 
+	 * @param UUID globally unique id of pool to fetch
+	 * @return a new network object
+	 * @throws LibvirtException
+	 */
+	public StoragePool storagePoolLookupByUUID(int[] UUID)
+	throws LibvirtException {
+		return new StoragePool(this, _virStoragePoolLookupByUUID(VCP, UUID));
+	}
+
+	private native long _virStoragePoolLookupByUUID(long VCP, int[] UUID);
+	
+	/**
+	 * Fetch a storage pool based on its globally unique id
+	 * 
+	 * @param UUID globally unique id of pool to fetch
+	 * @return VirStoragePool object
+	 * @throws LibvirtException
+	 */
+	public StoragePool storagePoolLookupByUUIDString(String UUID)
+	throws LibvirtException {
+		return new StoragePool(this, _virStoragePoolLookupByUUIDString(VCP, UUID));
+	}
+
+	private native long _virStoragePoolLookupByUUIDString(long VCP, String UUID)
+	throws LibvirtException;
+	
+	/**
+	 * Fetch a a storage volume based on its globally unique key
+	 * 
+	 * @param key globally unique key
+	 * @return a storage volume
+	 */
+	public StorageVol storageVolLookupByKey(String key){
+		return new StorageVol(this, _virStorageVolLookupByKey(VCP, key));
+	}
+	
+	private native long _virStorageVolLookupByKey(long VCP, String key);
+	
+	/**
+	 * Fetch a storage volume based on its locally (host) unique path
+	 * 
+	 * @param path locally unique path
+	 * @return 	a storage volume
+	 */
+	public StorageVol storageVolLookupByPath(String path){
+		return new StorageVol(this, _virStorageVolLookupByPath(VCP, path));
+	}
+	
+	private native long _virStorageVolLookupByPath(long VCP, String path);
+
+
 }
Index: src/org/libvirt/LibvirtException.java
===================================================================
RCS file: /data/cvs/libvirt-java/src/org/libvirt/LibvirtException.java,v
retrieving revision 1.3
diff -u -r1.3 LibvirtException.java
--- src/org/libvirt/LibvirtException.java	18 Jul 2008 14:37:21 -0000	1.3
+++ src/org/libvirt/LibvirtException.java	4 Aug 2008 21:07:41 -0000
@@ -9,6 +9,8 @@
  */
 public class LibvirtException extends Exception {
 
+	private static final long serialVersionUID = 5566904363426773529L;
+	
 	Error virError;
 
 	LibvirtException(Error virError) {
Index: src/org/libvirt/ConnectAuth.java
===================================================================
RCS file: /data/cvs/libvirt-java/src/org/libvirt/ConnectAuth.java,v
retrieving revision 1.1
diff -u -r1.1 ConnectAuth.java
--- src/org/libvirt/ConnectAuth.java	18 Jul 2008 14:37:21 -0000	1.1
+++ src/org/libvirt/ConnectAuth.java	4 Aug 2008 21:07:41 -0000
@@ -56,6 +56,7 @@
 		 *
 		 * @return The integer equivalent
 		 */
+		@SuppressWarnings("all")
 		private int mapToInt(){
 			switch(this){
 				case VIR_CRED_USERNAME: return 1;
Index: src/jni/org_libvirt_Connect.c
===================================================================
RCS file: /data/cvs/libvirt-java/src/jni/org_libvirt_Connect.c,v
retrieving revision 1.2
diff -u -r1.2 org_libvirt_Connect.c
--- src/jni/org_libvirt_Connect.c	22 Jul 2008 08:27:42 -0000	1.2
+++ src/jni/org_libvirt_Connect.c	4 Aug 2008 21:07:40 -0000
@@ -3,10 +3,11 @@
 #include <stdlib.h>
 #include "ErrorHandler.h"
 #include "ConnectAuthCallbackBridge.h"
-
+#include "generic.h"
 #include <assert.h>
 
-//TODO We are leaking UTFChars all over the place. We need to strcpy, then release every string we get from JAVA, and not use them directly!
+//TODO We are leaking UTFChars all over the place. We need to release every string we get from JAVA with ReleaseStringUTFChars! (Done)
+//TODO The same for *ArrayElements
 
 JNIEXPORT jint JNICALL Java_org_libvirt_Connect__1virInitialize
   (JNIEnv *env, jclass cls){
@@ -18,48 +19,32 @@
 	return result;
 }
 
-JNIEXPORT void JNICALL Java_org_libvirt_Connect__1close
+JNIEXPORT jint JNICALL Java_org_libvirt_Connect__1close
   (JNIEnv *env, jobject obj, jlong VCP){
-	virConnectClose( (virConnectPtr)VCP );
+	GENERIC__VIROBJ__INT(env, obj, (virConnectPtr)VCP, virConnectClose)
 }
 
 JNIEXPORT jstring JNICALL Java_org_libvirt_Connect__1getHostName
   (JNIEnv *env, jobject obj, jlong VCP){
-	//All this gymnastics is so that we can free() the hostname string
-	jstring j_hostname=NULL;
-	char *hostname;
-	if((hostname = virConnectGetHostname((virConnectPtr)VCP))){
-		j_hostname = (*env)->NewStringUTF(env, hostname);
-		free(hostname);
-	}
-	return j_hostname;
+	GENERIC__VIROBJ__STRING(env, obj, (virConnectPtr)VCP, virConnectGetHostname)
 };
 
 JNIEXPORT jstring JNICALL Java_org_libvirt_Connect__1getCapabilities
   (JNIEnv *env, jobject obj, jlong VCP){
-	jstring j_capabilities=NULL;
-	char *capabilities;
-	if((capabilities = virConnectGetCapabilities((virConnectPtr)VCP))){
-		j_capabilities = (*env)->NewStringUTF(env, capabilities);
-		free(capabilities);
-	}
-	return j_capabilities;
+	GENERIC__VIROBJ__STRING(env, obj, (virConnectPtr)VCP, virConnectGetCapabilities)
 }
 
 JNIEXPORT jint JNICALL Java_org_libvirt_Connect__1getMaxVcpus
-  (JNIEnv *env, jobject obj, jlong VCP, jstring type){
-	return virConnectGetMaxVcpus((virConnectPtr)VCP , (*env)->GetStringUTFChars(env, type, NULL));
+  (JNIEnv *env, jobject obj, jlong VCP, jstring j_type){
+	const char *type = (*env)->GetStringUTFChars(env, j_type, NULL);
+	int retval = (jint)virConnectGetMaxVcpus((virConnectPtr)VCP, type);
+	(*env)->ReleaseStringUTFChars(env, j_type, type);
+	return retval;
 };
 
 JNIEXPORT jstring JNICALL Java_org_libvirt_Connect__1getType
   (JNIEnv *env, jobject obj, jlong VCP){
-	const char *type;
-	//Here we get a static string, no need to free()
-	if((type=virConnectGetType((virConnectPtr)VCP))){
-		return (*env)->NewStringUTF(env, type);
-	} else {
-		return NULL;
-	}
+	GENERIC__VIROBJ__CONSTSTRING(env, obj, (virConnectPtr)VCP, virConnectGetType)
 };
 
 JNIEXPORT jstring JNICALL Java_org_libvirt_Connect__1getURI
@@ -76,101 +61,70 @@
 JNIEXPORT jlong JNICALL Java_org_libvirt_Connect__1getVersion
   (JNIEnv *env, jobject obj, jlong VCP){
 	unsigned long hvVer=0;
-	int retval = virConnectGetVersion((virConnectPtr)VCP, &hvVer);
+	virConnectGetVersion((virConnectPtr)VCP, &hvVer);
 	return (jlong)(hvVer);
 };
 
 JNIEXPORT jobjectArray JNICALL Java_org_libvirt_Connect__1listDefinedNetworks
   (JNIEnv *env, jobject obj, jlong VCP){
-	int maxnames;
-	char **names;
-	int c;
-	jobjectArray j_names=NULL;
-	if((maxnames = virConnectNumOfDefinedNetworks((virConnectPtr)VCP))<0)
-		return NULL;
-	names= (char**)calloc(maxnames, sizeof(char*));
-	if(virConnectListDefinedNetworks((virConnectPtr)VCP, names, maxnames)>=0){
-		j_names= (jobjectArray)(*env)->NewObjectArray(env, maxnames,
-			(*env)->FindClass(env,"java/lang/String"),
-			(*env)->NewStringUTF(env,""));
-		for(c=0; c<maxnames; c++){
-			(*env)->SetObjectArrayElement(env, j_names, c, (*env)->NewStringUTF(env, names[c]));
-		}
-	}
-	free(names);
-
-	return j_names;
+	GENERIC_LIST_STRINGARRAY(env, obj, (virConnectPtr)VCP, virConnectListDefinedNetworks, virConnectNumOfDefinedNetworks)
 }
 
 JNIEXPORT jobjectArray JNICALL Java_org_libvirt_Connect__1listNetworks
   (JNIEnv *env, jobject obj, jlong VCP){
-	int maxnames;
-	char **names;
-	int c;
-	jobjectArray j_names=NULL;
-	if((maxnames = virConnectNumOfNetworks((virConnectPtr)VCP))<0)
-		return NULL;
-	names= (char**)calloc(maxnames, sizeof(char*));
-	if(virConnectListNetworks((virConnectPtr)VCP, names, maxnames)>=0){
-		j_names= (jobjectArray)(*env)->NewObjectArray(env, maxnames,
-			(*env)->FindClass(env,"java/lang/String"),
-			(*env)->NewStringUTF(env,""));
-		for(c=0; c<maxnames; c++){
-			(*env)->SetObjectArrayElement(env, j_names, c, (*env)->NewStringUTF(env, names[c]));
-		}
-	}
-	free(names);
-
-	return j_names;
+	GENERIC_LIST_STRINGARRAY(env, obj, (virConnectPtr)VCP, virConnectListNetworks, virConnectNumOfNetworks)
 }
 
 JNIEXPORT jint JNICALL Java_org_libvirt_Connect__1numOfDefinedDomains
   (JNIEnv *env, jobject obj, jlong VCP){
-	return virConnectNumOfDefinedDomains((virConnectPtr)VCP);
+	GENERIC__VIROBJ__INT(env, obj, (virConnectPtr)VCP, virConnectNumOfDefinedDomains)
 };
 
 JNIEXPORT jint JNICALL Java_org_libvirt_Connect__1numOfDefinedNetworks
   (JNIEnv *env, jobject obj, jlong VCP){
-	return virConnectNumOfDefinedNetworks((virConnectPtr)VCP);
+	GENERIC__VIROBJ__INT(env, obj, (virConnectPtr)VCP, virConnectNumOfDefinedNetworks)
 };
 
 JNIEXPORT jint JNICALL Java_org_libvirt_Connect__1numOfDomains
   (JNIEnv *env, jobject obj, jlong VCP){
-	return virConnectNumOfDomains((virConnectPtr)VCP);
+	GENERIC__VIROBJ__INT(env, obj, (virConnectPtr)VCP, virConnectNumOfDomains)
 };
 
 JNIEXPORT jint JNICALL Java_org_libvirt_Connect__1numOfNetworks
   (JNIEnv *env, jobject obj, jlong VCP){
-	return virConnectNumOfNetworks((virConnectPtr)VCP);
+	GENERIC__VIROBJ__INT(env, obj, (virConnectPtr)VCP, virConnectNumOfNetworks)
 };
 
-
 JNIEXPORT jlong JNICALL Java_org_libvirt_Connect__1open
-  (JNIEnv *env, jobject obj, jstring uri){
+  (JNIEnv *env, jobject obj, jstring j_uri){
 
 	virConnectPtr vc;
+	const char *uri=(*env)->GetStringUTFChars(env, j_uri, NULL);
 
 	//Initialize the libvirt VirtConn Object
-	vc=virConnectOpen((*env)->GetStringUTFChars(env, uri, NULL));
+	vc=virConnectOpen(uri);
+	(*env)->ReleaseStringUTFChars(env, j_uri, uri);
 	if(vc==NULL){
 		//We have a pending java exception, let's return
 		assert((*env)->ExceptionOccurred(env));
 		return (jlong)NULL;
 	}
 
-	//Initialized the error handler for this connection
+	//Initialize the error handler for this connection
 	virConnSetErrorFunc(vc, env, virErrorHandler);
 
 	return (jlong)vc;
 };
 
 JNIEXPORT jlong JNICALL Java_org_libvirt_Connect__1openReadOnly
-  (JNIEnv *env, jobject obj, jstring uri){
+  (JNIEnv *env, jobject obj, jstring j_uri){
 
 	virConnectPtr vc;
-
+	const char *uri=(*env)->GetStringUTFChars(env, j_uri, NULL);
+	
 	//Initialize the libvirt VirtConn Object
-	vc=virConnectOpenReadOnly((*env)->GetStringUTFChars(env, uri, NULL));
+	vc=virConnectOpenReadOnly(uri);
+	(*env)->ReleaseStringUTFChars(env, j_uri, uri);
 	if(vc==NULL){
 		//We have a pending java exception, let's return
 		assert((*env)->ExceptionOccurred(env));
@@ -184,10 +138,10 @@
 };
 
 JNIEXPORT jlong JNICALL Java_org_libvirt_Connect__1openAuth
-  (JNIEnv *env, jobject obj, jstring uri, jobject j_auth, jint flags){
+  (JNIEnv *env, jobject obj, jstring j_uri, jobject j_auth, jint flags){
 
 	virConnectPtr vc;
-	virError error;
+	const char *uri=(*env)->GetStringUTFChars(env, j_uri, NULL);
 
 	virConnectAuth *auth = malloc(sizeof(virConnectAuth));
 
@@ -222,8 +176,9 @@
 	cb_wrapper->env = env;
 	cb_wrapper->auth = j_auth;
 	auth->cbdata=cb_wrapper;
-
-	vc=virConnectOpenAuth((*env)->GetStringUTFChars(env, uri, NULL), auth, flags);
+	
+	vc=virConnectOpenAuth(uri, auth, flags);
+	(*env)->ReleaseStringUTFChars(env, j_uri, uri);
 	if (vc==NULL){
 		//We have a pending java exception, let's return
 		assert((*env)->ExceptionOccurred(env));
@@ -237,35 +192,29 @@
 }
 
 JNIEXPORT jlong JNICALL Java_org_libvirt_Connect__1virNetworkCreateXML
-  (JNIEnv *env, jobject obj, jlong VCP, jstring xmlDesc){
-	return (jlong)virNetworkCreateXML((virConnectPtr)VCP, (*env)->GetStringUTFChars(env, xmlDesc, NULL));
+  (JNIEnv *env, jobject obj, jlong VCP, jstring j_xmlDesc){
+	GENERIC_VIROBJ_STRING__VIROBJ(env, obj, (virConnectPtr)VCP, j_xmlDesc, virNetworkCreateXML)
 }
 
 JNIEXPORT jlong JNICALL Java_org_libvirt_Connect__1virNetworkDefineXML
-(JNIEnv *env, jobject obj, jlong VCP, jstring xmlDesc){
-	return (jlong)virNetworkDefineXML((virConnectPtr)VCP, (*env)->GetStringUTFChars(env, xmlDesc, NULL));
+(JNIEnv *env, jobject obj, jlong VCP, jstring j_xmlDesc){
+	GENERIC_VIROBJ_STRING__VIROBJ(env, obj, (virConnectPtr)VCP, j_xmlDesc, virNetworkDefineXML)
 }
 
 JNIEXPORT jlong JNICALL Java_org_libvirt_Connect__1virNetworkLookupByName
-  (JNIEnv *env, jobject obj, jlong VCP, jstring name){
-	return (jlong)virNetworkLookupByName((virConnectPtr)VCP, (*env)->GetStringUTFChars(env, name, NULL));
+  (JNIEnv *env, jobject obj, jlong VCP, jstring j_name){
+	GENERIC_LOOKUPBY_STRING(env, obj, (virConnectPtr)VCP, j_name, virNetworkLookupByName)
 }
 
 JNIEXPORT jlong JNICALL Java_org_libvirt_Connect__1virNetworkLookupByUUID
   (JNIEnv *env, jobject obj, jlong VCP, jintArray j_UUID){
-	unsigned char UUID[VIR_UUID_BUFLEN];
-	int c;
-	int *UUID_int  = (*env)->GetIntArrayElements(env, j_UUID, NULL);
-	//compact to bytes
-	for(c=0; c < VIR_UUID_BUFLEN; c++)
-		UUID[c]=UUID_int[c];
-	return (jlong)virNetworkLookupByUUID((virConnectPtr)VCP, UUID);
+	GENERIC_LOOKUPBY_UUID(env, obj, (virConnectPtr)VCP, j_UUID, virNetworkLookupByUUID)
 }
 
 
 JNIEXPORT jlong JNICALL Java_org_libvirt_Connect__1virNetworkLookupByUUIDString
-  (JNIEnv *env, jobject obj, jlong VCP, jstring UUID){
-	return (jlong)virNetworkLookupByUUIDString((virConnectPtr)VCP, (*env)->GetStringUTFChars(env, UUID, NULL));
+  (JNIEnv *env, jobject obj, jlong VCP, jstring j_UUID){
+	GENERIC_LOOKUPBY_STRING(env, obj, (virConnectPtr)VCP, j_UUID, virNetworkLookupByUUIDString)
 }
 
 JNIEXPORT jobject JNICALL Java_org_libvirt_Connect__1virNodeInfo
@@ -298,24 +247,7 @@
 
 JNIEXPORT jobjectArray JNICALL Java_org_libvirt_Connect__1listDefinedDomains
   (JNIEnv *env, jobject obj, jlong VCP){
-	int maxnames;
-	char **names;
-	int c;
-	jobjectArray j_names=NULL;
-	if((maxnames = virConnectNumOfDefinedDomains((virConnectPtr)VCP))<0)
-		return NULL;
-	names= (char**)calloc(maxnames, sizeof(char*));
-	if(virConnectListDefinedDomains((virConnectPtr)VCP, names, maxnames)>=0){
-		j_names= (jobjectArray)(*env)->NewObjectArray(env, maxnames,
-			(*env)->FindClass(env,"java/lang/String"),
-			(*env)->NewStringUTF(env,""));
-		for(c=0; c<maxnames; c++){
-			(*env)->SetObjectArrayElement(env, j_names, c, (*env)->NewStringUTF(env, names[c]));
-		}
-	}
-	free(names);
-
-	return j_names;
+	GENERIC_LIST_STRINGARRAY(env, obj, (virConnectPtr)VCP, virConnectListDefinedDomains, virConnectNumOfDefinedDomains)
 }
 
 JNIEXPORT jintArray JNICALL Java_org_libvirt_Connect__1listDomains
@@ -342,24 +274,18 @@
 }
 
 JNIEXPORT jlong JNICALL Java_org_libvirt_Connect__1virDomainLookupByName
-  (JNIEnv *env, jobject obj, jlong VCP, jstring name){
-		return (jlong)virDomainLookupByName((virConnectPtr)VCP, (*env)->GetStringUTFChars(env, name, NULL));
+  (JNIEnv *env, jobject obj, jlong VCP, jstring j_name){
+	GENERIC_LOOKUPBY_STRING(env, obj, (virConnectPtr)VCP, j_name, virDomainLookupByName)
 }
 
 JNIEXPORT jlong JNICALL Java_org_libvirt_Connect__1virDomainLookupByUUID
   (JNIEnv *env, jobject obj, jlong VCP, jintArray j_UUID){
-	unsigned char UUID[VIR_UUID_BUFLEN];
-	int c;
-	int *UUID_int  = (*env)->GetIntArrayElements(env, j_UUID, NULL);
-	//compact to bytes
-	for(c=0; c < VIR_UUID_BUFLEN; c++)
-		UUID[c]=UUID_int[c];
-	return (jlong)virDomainLookupByUUID((virConnectPtr)VCP, UUID);
+	GENERIC_LOOKUPBY_UUID(env, obj, (virConnectPtr)VCP, j_UUID, virDomainLookupByUUID)
 }
 
 JNIEXPORT jlong JNICALL Java_org_libvirt_Connect__1virDomainLookupByUUIDString
-  (JNIEnv *env, jobject obj, jlong VCP, jstring UUID){
-	return (jlong)virDomainLookupByUUIDString((virConnectPtr)VCP, (*env)->GetStringUTFChars(env, UUID, NULL));
+  (JNIEnv *env, jobject obj, jlong VCP, jstring j_UUID){
+	GENERIC_LOOKUPBY_STRING(env, obj, (virConnectPtr)VCP, j_UUID, virDomainLookupByUUIDString)
 }
 
 JNIEXPORT jlong JNICALL Java_org_libvirt_Connect__1virGetLibVirVersion
@@ -376,26 +302,63 @@
 	type = (*env)->GetStringUTFChars(env, j_type, NULL);
 
 	virGetVersion(&libVer, type, &typeVer);
+	(*env)->ReleaseStringUTFChars(env, j_type, type);
 
 	return libVer;
 }
 
 JNIEXPORT jlong JNICALL Java_org_libvirt_Connect__1virDomainCreateLinux
-  (JNIEnv *env, jobject obj, jlong VCP, jstring xmlDesc, jint flags){
-	return(jlong)virDomainCreateLinux((virConnectPtr)VCP, (*env)->GetStringUTFChars(env, xmlDesc, NULL), flags);
+  (JNIEnv *env, jobject obj, jlong VCP, jstring j_xmlDesc, jint flags){
+	GENERIC_VIROBJ_STRING_INT__VIROBJ(env, obj, (virConnectPtr)VCP, j_xmlDesc, flags, virDomainCreateLinux)
 }
 
 JNIEXPORT jlong JNICALL Java_org_libvirt_Connect__1virDomainDefineXML
-  (JNIEnv *env, jobject obj, jlong VCP, jstring xmlDesc){
-	return(jlong)virDomainDefineXML((virConnectPtr)VCP, (*env)->GetStringUTFChars(env, xmlDesc, NULL));
+  (JNIEnv *env, jobject obj, jlong VCP, jstring j_xmlDesc){
+	GENERIC_VIROBJ_STRING__VIROBJ(env, obj, (virConnectPtr)VCP, j_xmlDesc, virDomainDefineXML)
 }
 
 JNIEXPORT jint JNICALL Java_org_libvirt_Connect__1virDomainRestore
-  (JNIEnv *env, jobject obj, jlong VCP, jstring from){
-	return virDomainRestore((virConnectPtr)VCP, (char*)(*env)->GetStringUTFChars(env, from, NULL));
+  (JNIEnv *env, jobject obj, jlong VCP, jstring j_from){
+	GENERIC_VIROBJ_STRING__VIROBJ(env, obj, (virConnectPtr)VCP, j_from, virDomainRestore)
 }
 
 JNIEXPORT jint JNICALL Java_org_libvirt_Connect__1setDom0Memory
   (JNIEnv *env, jobject obj, jlong memory){
 	return virDomainSetMemory(NULL, memory);
 }
+
+JNIEXPORT jint JNICALL Java_org_libvirt_Connect__1numOfDefinedStoragePools
+  (JNIEnv *env, jobject obj, jlong VCP){
+	GENERIC__VIROBJ__INT(env, obj, (virConnectPtr)VCP, virConnectNumOfDefinedStoragePools)
+}
+
+JNIEXPORT jint JNICALL Java_org_libvirt_Connect__1numOfStoragePools
+  (JNIEnv *env, jobject obj, jlong VCP){
+	GENERIC__VIROBJ__INT(env, obj, (virConnectPtr)VCP, virConnectNumOfStoragePools)
+}
+
+JNIEXPORT jobjectArray JNICALL Java_org_libvirt_Connect__1listDefinedStoragePools
+(JNIEnv *env, jobject obj, jlong VCP){
+	GENERIC_LIST_STRINGARRAY(env, obj, (virConnectPtr)VCP, virConnectListDefinedStoragePools, virConnectNumOfDefinedStoragePools)
+}
+
+JNIEXPORT jobjectArray JNICALL Java_org_libvirt_Connect__1listStoragePools
+(JNIEnv *env, jobject obj, jlong VCP){
+	GENERIC_LIST_STRINGARRAY(env, obj, (virConnectPtr)VCP, virConnectListStoragePools, virConnectNumOfStoragePools)
+}
+
+JNIEXPORT jlong JNICALL Java_org_libvirt_Connect__1virStoragePoolCreateXML
+(JNIEnv *env, jobject obj, jlong VCP, jstring j_xmlDesc, jint flags){
+	GENERIC_VIROBJ_STRING_INT__VIROBJ(env, obj, (virConnectPtr)VCP, j_xmlDesc, flags, virStoragePoolCreateXML)
+}
+
+JNIEXPORT jlong JNICALL Java_org_libvirt_Connect__1virStoragePoolDefineXML
+(JNIEnv *env, jobject obj, jlong VCP, jstring j_xmlDesc, jint flags){
+	GENERIC_VIROBJ_STRING_INT__VIROBJ(env, obj, (virConnectPtr)VCP, j_xmlDesc, flags, virStoragePoolDefineXML)
+}
+
+JNIEXPORT jlong JNICALL Java_org_libvirt_Connect__1virStoragePoolLookupByName
+(JNIEnv *env, jobject obj, jlong VCP, jstring j_name){
+	GENERIC_LOOKUPBY_STRING(env, obj, (virConnectPtr)VCP, j_name, virStoragePoolLookupByName)
+}
+
Index: src/jni/org_libvirt_Network.c
===================================================================
RCS file: /data/cvs/libvirt-java/src/jni/org_libvirt_Network.c,v
retrieving revision 1.1
diff -u -r1.1 org_libvirt_Network.c
--- src/jni/org_libvirt_Network.c	18 Jul 2008 14:37:21 -0000	1.1
+++ src/jni/org_libvirt_Network.c	4 Aug 2008 21:07:40 -0000
@@ -1,89 +1,59 @@
 #include "org_libvirt_Network.h"
 #include <libvirt/libvirt.h>
+#include "generic.h"
 #include <stdlib.h>
 
 JNIEXPORT jstring JNICALL Java_org_libvirt_Network__1getXMLDesc
-  (JNIEnv *env, jobject obj, jlong VNP, jint flags){
-	jstring j_xmlDesc;
-	char* xmlDesc;
-	if((xmlDesc = virNetworkGetXMLDesc((virNetworkPtr)VNP, flags))){
-		j_xmlDesc = (*env)->NewStringUTF(env, xmlDesc);
-		free(xmlDesc);
-	}
-	return j_xmlDesc;
+  (JNIEnv *env, jobject obj, jlong VNP, jint j_flags){
+	GENERIC_VIROBJ_INT__STRING(env, obj, (virNetworkPtr)VNP, j_flags, virNetworkGetXMLDesc)
 };
 
 JNIEXPORT jint JNICALL Java_org_libvirt_Network__1create
   (JNIEnv *env, jobject obj, jlong VNP){
-	return virNetworkCreate((virNetworkPtr)VNP);
+	GENERIC__VIROBJ__INT(env, obj, (virNetworkPtr)VNP, virNetworkCreate)
 }
 
 JNIEXPORT jint JNICALL Java_org_libvirt_Network__1destroy
 (JNIEnv *env, jobject obj, jlong VNP){
-	return virNetworkDestroy((virNetworkPtr)VNP);
+	GENERIC__VIROBJ__INT(env, obj, (virNetworkPtr)VNP, virNetworkDestroy)
 }
 
 JNIEXPORT jint JNICALL Java_org_libvirt_Network__1free
 (JNIEnv *env, jobject obj, jlong VNP){
-	return virNetworkFree((virNetworkPtr)VNP);
+	GENERIC__VIROBJ__INT(env, obj, (virNetworkPtr)VNP, virNetworkFree)
 }
 
 JNIEXPORT jboolean JNICALL Java_org_libvirt_Network__1getAutostart
   (JNIEnv *env, jobject obj, jlong VNP){
-	int autostart;
-	virNetworkGetAutostart((virNetworkPtr)VNP, &autostart);
-	return (jboolean)autostart;
+	GENERIC_GETAUTOSTART(env, obj, (virNetworkPtr)VNP, virNetworkGetAutostart)
 }
 
 JNIEXPORT jint JNICALL Java_org_libvirt_Network__1setAutostart
-  (JNIEnv *env, jobject obj, jlong VNP, jboolean autostart){
-	return virNetworkSetAutostart((virNetworkPtr)VNP, autostart);
+  (JNIEnv *env, jobject obj, jlong VNP, jboolean j_autostart){
+	GENERIC__VIROBJ_INT__INT(env, obj, (virNetworkPtr)VNP, j_autostart, virNetworkSetAutostart)
 }
 
 JNIEXPORT jstring JNICALL Java_org_libvirt_Network__1getBridgeName
   (JNIEnv *env, jobject obj, jlong VNP){
-	jstring j_bridgeName;
-	char *bridgeName=NULL;
-
-	if((bridgeName = virNetworkGetBridgeName((virNetworkPtr)VNP))){
-		j_bridgeName = (*env)->NewStringUTF(env, bridgeName);
-		free(bridgeName);
-	}
-	return j_bridgeName;
+	GENERIC__VIROBJ__STRING(env, obj, (virNetworkPtr)VNP, virNetworkGetBridgeName)
 }
 
 JNIEXPORT jstring JNICALL Java_org_libvirt_Network__1getName
   (JNIEnv *env, jobject obj, jlong VNP){
-	return (*env)->NewStringUTF(env, virNetworkGetName((virNetworkPtr)VNP));
+	GENERIC__VIROBJ__CONSTSTRING(env, obj, (virNetworkPtr)VNP, virNetworkGetName)
 }
 
 JNIEXPORT jintArray JNICALL Java_org_libvirt_Network__1getUUID
   (JNIEnv *env, jobject obj, jlong VNP){
-	unsigned char uuid[VIR_UUID_BUFLEN];
-	jintArray j_uuid;
-	int c;
-	int uuidbyte[VIR_UUID_BUFLEN];
-
-	if(virNetworkGetUUID((virNetworkPtr)VNP, uuid)<0)
-		return NULL;
-	//unpack UUID
-	j_uuid=(*env)->NewIntArray(env, VIR_UUID_BUFLEN);
-	for(c=0; c<VIR_UUID_BUFLEN; c++){
-			uuidbyte[c]=uuid[c];
-	}
-	(*env)->SetIntArrayRegion(env, j_uuid, 0, VIR_UUID_BUFLEN, uuidbyte);
-
-	return j_uuid;
+	GENERIC_GETUUID(env, obj, (virNetworkPtr)VNP, virNetworkGetUUID)
 }
 
 JNIEXPORT jstring JNICALL Java_org_libvirt_Network__1getUUIDString
 (JNIEnv *env, jobject obj, jlong VNP){
-	char uuidString[VIR_UUID_STRING_BUFLEN];
-	virNetworkGetUUIDString((virNetworkPtr)VNP, uuidString);
-	return (*env)->NewStringUTF(env, uuidString);
+	GENERIC_GETUUIDSTRING(env, obj, (virNetworkPtr)VNP, virNetworkGetUUIDString)
 }
 
 JNIEXPORT jint JNICALL Java_org_libvirt_Network__1undefine
   (JNIEnv *env, jobject obj, jlong VNP){
-	return virNetworkUndefine((virNetworkPtr)VNP);
+	GENERIC__VIROBJ__INT(env, obj, (virNetworkPtr)VNP, virNetworkUndefine)
 }
Index: src/jni/Makefile.am
===================================================================
RCS file: /data/cvs/libvirt-java/src/jni/Makefile.am,v
retrieving revision 1.5
diff -u -r1.5 Makefile.am
--- src/jni/Makefile.am	18 Jul 2008 14:37:21 -0000	1.5
+++ src/jni/Makefile.am	4 Aug 2008 21:07:40 -0000
@@ -4,7 +4,13 @@
   org_libvirt_Domain.h \
   org_libvirt_Domain_CreateFlags.h \
   org_libvirt_Domain_MigrateFlags.h \
-  org_libvirt_Domain_XMLFlags.h
+  org_libvirt_Domain_XMLFlags.h \
+  org_libvirt_StoragePool_BuildFlags.h \
+  org_libvirt_StoragePool_DeleteFlags.h \
+  org_libvirt_StoragePool.h \
+  org_libvirt_StorageVol_Type.h \
+  org_libvirt_StorageVol_DeleteFlags.h \
+  org_libvirt_StorageVol.h
 
 BUILT_SOURCES = $(GENERATED)
 
@@ -18,12 +24,21 @@
 
 org_libvirt_Domain.h org_libvirt_Domain_CreateFlags.h org_libvirt_Domain_MigrateFlags.h org_libvirt_Domain_XMLFlags.h : $(JAVA_CLASS_ROOT)/org/libvirt/Domain.class
 	$(JAVAH) -classpath $(JAVA_CLASS_ROOT) org.libvirt.Domain
+	
+org_libvirt_StoragePool.h org_libvirt_StoragePool_BuildFlags.h org_libvirt_StoragePool_DeleteFlags.h : $(JAVA_CLASS_ROOT)/org/libvirt/StoragePool.class
+	$(JAVAH) -classpath $(JAVA_CLASS_ROOT) org.libvirt.StoragePool
+	
+org_libvirt_StorageVol.h org_libvirt_StorageVol_Type.h org_libvirt_StorageVol_DeleteFlags.h : $(JAVA_CLASS_ROOT)/org/libvirt/StorageVol.class
+	$(JAVAH) -classpath $(JAVA_CLASS_ROOT) org.libvirt.StorageVol
 
 lib_LTLIBRARIES = libvirt_jni.la
 libvirt_jni_la_SOURCES = \
   org_libvirt_Network.c \
   org_libvirt_Connect.c \
   org_libvirt_Domain.c \
+  org_libvirt_StoragePool.c \
+  org_libvirt_StorageVol.c \
+  generic.h \
   ErrorHandler.c \
   ErrorHandler.h \
   ConnectAuthCallbackBridge.c \
Index: src/jni/org_libvirt_Domain.c
===================================================================
RCS file: /data/cvs/libvirt-java/src/jni/org_libvirt_Domain.c,v
retrieving revision 1.1
diff -u -r1.1 org_libvirt_Domain.c
--- src/jni/org_libvirt_Domain.c	18 Jul 2008 14:37:21 -0000	1.1
+++ src/jni/org_libvirt_Domain.c	4 Aug 2008 21:07:40 -0000
@@ -1,35 +1,30 @@
 #include "org_libvirt_Domain.h"
 #include <libvirt/libvirt.h>
-#include <stdlib.h>
+#include "generic.h"
 #include <string.h>
 
+//TODO We still leak UTFstrings in the more complex functions, I just don't have the will to touch them now
+//TODO /* hum jlong and virDomainPtr may not have the same size ... */
+//Actually, that's not a problem as casting will take care of that for us in both directions.
+
 JNIEXPORT jstring JNICALL Java_org_libvirt_Domain__1getXMLDesc
   (JNIEnv *env, jobject obj, jlong VDP, jint flags){
-	jstring j_xmlDesc;
-	char* xmlDesc = NULL;
-	/* hum jlong and virDomainPtr may not have the same size ... */
-	if((xmlDesc = virDomainGetXMLDesc((virDomainPtr)VDP, flags))){
-		j_xmlDesc = (*env)->NewStringUTF(env, xmlDesc);
-		free(xmlDesc);
-	}
-	return j_xmlDesc;
+	GENERIC_VIROBJ_INT__STRING(env, obj, (virDomainPtr)VDP, flags, virDomainGetXMLDesc)
 }
 
 JNIEXPORT jboolean JNICALL Java_org_libvirt_Domain__1getAutostart
   (JNIEnv *env, jobject obj, jlong VDP){
-	int autostart=0;
-	virDomainGetAutostart((virDomainPtr)VDP, &autostart);
-	return (jboolean)autostart;
+	GENERIC_GETAUTOSTART(env, obj, (virDomainPtr)VDP, virDomainGetAutostart)
 }
 
 JNIEXPORT jint JNICALL Java_org_libvirt_Domain__1setAutostart
   (JNIEnv *env, jobject obj, jlong VDP, jboolean autostart){
-	return virDomainSetAutostart((virDomainPtr)VDP, (int)autostart);
+	GENERIC__VIROBJ_INT__INT(env, obj, (virDomainPtr)VDP, autostart, virDomainSetAutostart)
 }
 
 JNIEXPORT jint JNICALL Java_org_libvirt_Domain__1getID
   (JNIEnv *env, jobject obj, jlong VDP){
-	return virDomainGetID((virDomainPtr)VDP);
+	GENERIC__VIROBJ__INT(env, obj, (virDomainPtr)VDP, virDomainGetID)
 }
 
 JNIEXPORT jlong JNICALL Java_org_libvirt_Domain__1getMaxMemory
@@ -44,24 +39,17 @@
 
 JNIEXPORT jint JNICALL Java_org_libvirt_Domain__1getMaxVcpus
   (JNIEnv *env, jobject obj, jlong VDP){
-	return virDomainGetMaxVcpus((virDomainPtr)VDP);
+	GENERIC__VIROBJ__INT(env, obj, (virDomainPtr)VDP, virDomainGetMaxVcpus)
 }
 
 JNIEXPORT jstring JNICALL Java_org_libvirt_Domain__1getName
   (JNIEnv *env, jobject obj, jlong VDP){
-	return (*env)->NewStringUTF(env, virDomainGetName((virDomainPtr)VDP));
+	GENERIC__VIROBJ__CONSTSTRING(env, obj, (virDomainPtr)VDP, virDomainGetName)
 }
 
 JNIEXPORT jstring JNICALL Java_org_libvirt_Domain__1getOSType
   (JNIEnv *env, jobject obj, jlong VDP){
-	jstring j_OSType;
-	char *OSType;
-
-	if((OSType = virDomainGetOSType((virDomainPtr)VDP))){
-		j_OSType = (*env)->NewStringUTF(env, OSType);
-		free(OSType);
-	}
-	return j_OSType;
+	GENERIC__VIROBJ__STRING(env, obj, (virDomainPtr)VDP, virDomainGetOSType)
 }
 
 JNIEXPORT jobjectArray JNICALL Java_org_libvirt_Domain__1getSchedulerType
@@ -116,6 +104,7 @@
 	//Fill it
 	for(c=0; c<nparams; c++){
 		j_field = (*env)->NewStringUTF(env, params[c].field);
+		
 		switch(params[c].type){
 		case    VIR_DOMAIN_SCHED_FIELD_INT:
 			cls = (*env)->FindClass(env,"org/libvirt/SchedIntParameter");
@@ -179,47 +168,60 @@
 
 	for(c=0; c<nparams; c++){
 		j_param= (*env)->GetObjectArrayElement(env, j_params, c);
-
+		const char *field;
+		
 		if((*env)->IsInstanceOf(env, j_param, (*env)->FindClass(env, "org/libvirt/SchedIntParameter")))
 		{
 			field_id= (*env)->GetFieldID(env, (*env)->GetObjectClass(env, j_param), "field", "Ljava/lang/String;");
 			value_id= (*env)->GetFieldID(env, (*env)->GetObjectClass(env, j_param), "value", "I");
-			strcpy(params[c].field,(char*)(*env)->GetStringUTFChars(env, (*env)->GetObjectField(env, j_param, field_id), NULL));
+			field = (*env)->GetStringUTFChars(env, (*env)->GetObjectField(env, j_param, field_id), NULL);
+			strcpy(params[c].field, field);
+			(*env)->ReleaseStringUTFChars(env, (*env)->GetObjectField(env, j_param, field_id), field);
 			params[c].value.i= (*env)->GetIntField(env, j_param, value_id);
 			params[c].type= VIR_DOMAIN_SCHED_FIELD_INT;
 		} else if((*env)->IsInstanceOf(env, j_param, (*env)->FindClass(env, "org/libvirt/SchedUintParameter")))
 		{
 			field_id= (*env)->GetFieldID(env, (*env)->GetObjectClass(env, j_param), "field", "Ljava/lang/String;");
 			value_id= (*env)->GetFieldID(env, (*env)->GetObjectClass(env, j_param), "value", "I");
-			strcpy(params[c].field,(char*)(*env)->GetStringUTFChars(env, (*env)->GetObjectField(env, j_param, field_id), NULL));
+			field = (*env)->GetStringUTFChars(env, (*env)->GetObjectField(env, j_param, field_id), NULL);
+			strcpy(params[c].field, field);
+			(*env)->ReleaseStringUTFChars(env, (*env)->GetObjectField(env, j_param, field_id), field);
 			params[c].value.ui= (*env)->GetIntField(env, j_param, value_id);
 			params[c].type= VIR_DOMAIN_SCHED_FIELD_UINT;
 		} else if((*env)->IsInstanceOf(env, j_param, (*env)->FindClass(env, "org/libvirt/SchedLongParameter")))
 		{
 			field_id= (*env)->GetFieldID(env, (*env)->GetObjectClass(env, j_param), "field", "Ljava/lang/String;");
 			value_id= (*env)->GetFieldID(env, (*env)->GetObjectClass(env, j_param), "value", "J");
-			strcpy(params[c].field,(char*)(*env)->GetStringUTFChars(env, (*env)->GetObjectField(env, j_param, field_id), NULL));
+			field = (*env)->GetStringUTFChars(env, (*env)->GetObjectField(env, j_param, field_id), NULL);
+			strcpy(params[c].field, field);
+			(*env)->ReleaseStringUTFChars(env, (*env)->GetObjectField(env, j_param, field_id), field);
 			params[c].value.l= (*env)->GetLongField(env, j_param, value_id);
 			params[c].type= VIR_DOMAIN_SCHED_FIELD_LLONG;
 		} else if((*env)->IsInstanceOf(env, j_param, (*env)->FindClass(env, "org/libvirt/SchedUlongParameter")))
 		{
 			field_id= (*env)->GetFieldID(env, (*env)->GetObjectClass(env, j_param), "field", "Ljava/lang/String;");
 			value_id= (*env)->GetFieldID(env, (*env)->GetObjectClass(env, j_param), "value", "J");
-			strcpy(params[c].field,(char*)(*env)->GetStringUTFChars(env, (*env)->GetObjectField(env, j_param, field_id), NULL));
+			field = (*env)->GetStringUTFChars(env, (*env)->GetObjectField(env, j_param, field_id), NULL);
+			strcpy(params[c].field, field);
+			(*env)->ReleaseStringUTFChars(env, (*env)->GetObjectField(env, j_param, field_id), field);
 			params[c].value.ul= (*env)->GetLongField(env, j_param, value_id);
 			params[c].type= VIR_DOMAIN_SCHED_FIELD_ULLONG;
 		} else if((*env)->IsInstanceOf(env, j_param, (*env)->FindClass(env, "org/libvirt/SchedDoubleParameter")))
 		{
 			field_id= (*env)->GetFieldID(env, (*env)->GetObjectClass(env, j_param), "field", "Ljava/lang/String;");
 			value_id= (*env)->GetFieldID(env, (*env)->GetObjectClass(env, j_param), "value", "D");
-			strcpy(params[c].field,(char*)(*env)->GetStringUTFChars(env, (*env)->GetObjectField(env, j_param, field_id), NULL));
+			field = (*env)->GetStringUTFChars(env, (*env)->GetObjectField(env, j_param, field_id), NULL);
+			strcpy(params[c].field, field);
+			(*env)->ReleaseStringUTFChars(env, (*env)->GetObjectField(env, j_param, field_id), field);
 			params[c].value.d= (*env)->GetDoubleField(env, j_param, value_id);
 			params[c].type= VIR_DOMAIN_SCHED_FIELD_ULLONG;
 		} else if((*env)->IsInstanceOf(env, j_param, (*env)->FindClass(env, "org/libvirt/SchedBooleanParameter")))
 		{
 			field_id= (*env)->GetFieldID(env, (*env)->GetObjectClass(env, j_param), "field", "Ljava/lang/String;");
 			value_id= (*env)->GetFieldID(env, (*env)->GetObjectClass(env, j_param), "value", "Z");
-			strcpy(params[c].field,(char*)(*env)->GetStringUTFChars(env, (*env)->GetObjectField(env, j_param, field_id), NULL));
+			field = (*env)->GetStringUTFChars(env, (*env)->GetObjectField(env, j_param, field_id), NULL);
+			strcpy(params[c].field, field);
+			(*env)->ReleaseStringUTFChars(env, (*env)->GetObjectField(env, j_param, field_id), field);
 			params[c].value.b= (*env)->GetBooleanField(env, j_param, value_id);
 			params[c].type= VIR_DOMAIN_SCHED_FIELD_BOOLEAN;
 		}
@@ -233,27 +235,12 @@
 
 JNIEXPORT jintArray JNICALL Java_org_libvirt_Domain__1getUUID
   (JNIEnv *env, jobject obj, jlong VDP){
-	unsigned char uuid[VIR_UUID_BUFLEN];
-	jintArray j_uuid;
-	int c;
-	int uuidbyte;
-
-	if(virDomainGetUUID((virDomainPtr)VDP, uuid)<0)
-		return NULL;
-	//unpack UUID
-	j_uuid=(*env)->NewIntArray(env, VIR_UUID_BUFLEN);
-	for(c=0; c<VIR_UUID_BUFLEN; c++){
-			uuidbyte=uuid[c];
-			(*env)->SetIntArrayRegion(env, j_uuid, c, 1, &uuidbyte);
-	}
-	return j_uuid;
+	GENERIC_GETUUID(env, obj, (virDomainPtr)VDP, virDomainGetUUID)
 }
 
 JNIEXPORT jstring JNICALL Java_org_libvirt_Domain__1getUUIDString
   (JNIEnv *env, jobject obj, jlong VDP){
-	char uuidString[VIR_UUID_STRING_BUFLEN];
-	virDomainGetUUIDString((virDomainPtr)VDP, uuidString);
-	return (*env)->NewStringUTF(env, uuidString);
+	GENERIC_GETUUIDSTRING(env, obj, (virDomainPtr)VDP, virDomainGetUUIDString)
 }
 
 JNIEXPORT jobjectArray JNICALL Java_org_libvirt_Domain__1getVcpusInfo
@@ -392,78 +379,33 @@
 
 JNIEXPORT jint JNICALL Java_org_libvirt_Domain__1setVcpus
   (JNIEnv *env, jobject obj, jlong VDP, jint nvcpus){
-	return virDomainSetVcpus((virDomainPtr)VDP, nvcpus);
+	GENERIC__VIROBJ_INT__INT(env, obj, (virDomainPtr)VDP, nvcpus, virDomainSetVcpus)
 }
 
 JNIEXPORT jint JNICALL Java_org_libvirt_Domain__1attachDevice
-  (JNIEnv *env, jobject obj, jlong VDP, jstring xmlDesc){
-	return (jlong)virDomainAttachDevice((virDomainPtr)VDP, (char*)(*env)->GetStringUTFChars(env, xmlDesc, NULL));
+  (JNIEnv *env, jobject obj, jlong VDP, jstring j_xmlDesc){
+	GENERIC_VIROBJ_STRING__INT(env, obj, (virDomainPtr)VDP, j_xmlDesc, virDomainAttachDevice);
 }
 
 JNIEXPORT jint JNICALL Java_org_libvirt_Domain__1detachDevice
-  (JNIEnv *env, jobject obj, jlong VDP, jstring xmlDesc){
-	return (jlong)virDomainDetachDevice((virDomainPtr)VDP, (char*)(*env)->GetStringUTFChars(env, xmlDesc, NULL));
+  (JNIEnv *env, jobject obj, jlong VDP, jstring j_xmlDesc){
+	GENERIC_VIROBJ_STRING__INT(env, obj, (virDomainPtr)VDP, j_xmlDesc, virDomainDetachDevice);
 }
 
-//JNIEXPORT jobject JNICALL Java_org_libvirt_Domain__1blockStats
-//  (JNIEnv *env, jobject obj, jlong VDP, jstring j_path){
-//	struct  _virDomainBlockStats stats;
-//	long value;
-//	jobject j_stats;
-//	jclass stats_cls=(*env)->FindClass(env, "org/libvirt/DomainInterfaceStats");
-//	jclass bigint_cls=(*env)->FindClass(env, "java/math/BigInteger");
-//	jmethodID bigint_constructor=(*env)->GetMethodID(env, bigint_cls, "java.math.BigInteger", "([B)V");
-//	jbyteArray bytes;
-//	jobject bigint;
-//
-//	if(virDomainBlockStats((virDomainPtr)VDP, (*env)->GetStringUTFChars(env, j_path, NULL), &stats, sizeof(struct  _virDomainBlockStats))<0)
-//		return NULL;
-//
-//	//Endianness fun. Should work on Linux.
-//	#if __BYTE_ORDER == __LITTLE_ENDIAN
-//	stats.rd_req= bswap_64(stats.rd_req);
-//	stats.rd_bytes= bswap_64(stats.rd_bytes);
-//	stats.wr_req= bswap_64(stats.wr_req);
-//	stats.wr_bytes= bswap_64(stats.wr_bytes);
-//	stats.errs= bswap_64(stats.errs);
-//	#endif
-//
-//	j_stats = (*env)->AllocObject(env, stats_cls);
-//	bytes=(*env)->NewByteArray(env,8);
-//
-//
-//	(*env)->SetByteArrayRegion(env, bytes, 0, 8, (unsigned char*)&(stats.rd_req));
-//	bigint=(*env)->NewObject(env, bigint_cls, bigint_constructor, bytes);
-//	(*env)->SetObjectField(env, j_stats, (*env)->GetFieldID(env, stats_cls, "rd_req", "Ljava/math/BigInteger;"), bigint);
-//
-//	(*env)->SetByteArrayRegion(env, bytes, 0, 8, (unsigned char*)&(stats.rd_bytes));
-//	bigint=(*env)->NewObject(env, bigint_cls, bigint_constructor, bytes);
-//	(*env)->SetObjectField(env, j_stats, (*env)->GetFieldID(env, stats_cls, "rd_bytes", "Ljava/math/BigInteger;"), bigint);
-//
-//	(*env)->SetByteArrayRegion(env, bytes, 0, 8, (unsigned char*)&(stats.wr_req));
-//	bigint=(*env)->NewObject(env, bigint_cls, bigint_constructor, bytes);
-//	(*env)->SetObjectField(env, j_stats, (*env)->GetFieldID(env, stats_cls, "wr_req", "Ljava/math/BigInteger;"), bigint);
-//
-//	(*env)->SetByteArrayRegion(env, bytes, 0, 8, (unsigned char*)&(stats.wr_bytes));
-//	bigint=(*env)->NewObject(env, bigint_cls, bigint_constructor, bytes);
-//	(*env)->SetObjectField(env, j_stats, (*env)->GetFieldID(env, stats_cls, "wr_bytes", "Ljava/math/BigInteger;"), bigint);
-//
-//	(*env)->SetByteArrayRegion(env, bytes, 0, 8, (unsigned char*)&(stats.errs));
-//	bigint=(*env)->NewObject(env, bigint_cls, bigint_constructor, bytes);
-//	(*env)->SetObjectField(env, j_stats, (*env)->GetFieldID(env, stats_cls, "errs", "Ljava/math/BigInteger;"), bigint);
-//
-//	return j_stats;
-//}
 
 JNIEXPORT jobject JNICALL Java_org_libvirt_Domain__1blockStats
   (JNIEnv *env, jobject obj, jlong VDP, jstring j_path){
 	struct  _virDomainBlockStats stats;
 	jobject j_stats;
 	jclass stats_cls=(*env)->FindClass(env, "org/libvirt/DomainInterfaceStats");
-
-	if(virDomainBlockStats((virDomainPtr)VDP, (*env)->GetStringUTFChars(env, j_path, NULL), &stats, sizeof(struct  _virDomainBlockStats))<0)
-		return NULL;
-
+	const char *path = (*env)->GetStringUTFChars(env, j_path, NULL);
+	
+	if(virDomainBlockStats((virDomainPtr)VDP, path, &stats, sizeof(struct  _virDomainBlockStats))<0){
+		(*env)->ReleaseStringUTFChars(env, j_path, path);
+		return NULL;		
+	}
+	(*env)->ReleaseStringUTFChars(env, j_path, path);
+	
 	j_stats = (*env)->AllocObject(env, stats_cls);
 
 	(*env)->SetLongField(env, j_stats, (*env)->GetFieldID(env, stats_cls, "rd_req", "J"), stats.rd_req);
@@ -476,79 +418,18 @@
 }
 
 
-//JNIEXPORT jobject JNICALL Java_org_libvirt_Domain__1interfaceStats
-//  (JNIEnv *env, jobject obj, jlong VDP, jstring j_path){
-//	struct  _virDomainInterfaceStats stats;
-//	long value;
-//	jobject j_stats;
-//	jclass stats_cls=(*env)->FindClass(env, "org/libvirt/DomainInterfaceStats");
-//	jclass bigint_cls=(*env)->FindClass(env, "java/math/BigInteger");
-//	jmethodID bigint_constructor=(*env)->GetMethodID(env, bigint_cls, "java.math.BigInteger", "([B)V");
-//	jbyteArray bytes;
-//	jobject bigint;
-//
-//	if(virDomainInterfaceStats((virDomainPtr)VDP, (*env)->GetStringUTFChars(env, j_path, NULL), &stats, sizeof(struct  _virDomainInterfaceStats))<0)
-//		return NULL;
-//
-//	//Endianness fun. Should work on Linux.
-//	#if __BYTE_ORDER == __LITTLE_ENDIAN
-//	stats.rx_bytes= bswap_64(stats.rx_bytes);
-//	stats.rx_packets= bswap_64(stats.rx_packets);
-//	stats.rx_errs= bswap_64(stats.rx_errs);
-//	stats.rx_drop= bswap_64(stats.rx_drop);
-//	stats.tx_bytes= bswap_64(stats.tx_bytes);
-//	stats.tx_packets= bswap_64(stats.tx_packets);
-//	stats.tx_errs= bswap_64(stats.tx_errs);
-//	stats.tx_drop= bswap_64(stats.tx_drop);
-//	#endif
-//
-//	j_stats = (*env)->AllocObject(env, stats_cls);
-//	bytes=(*env)->NewByteArray(env,8);
-//
-//
-//	(*env)->SetByteArrayRegion(env, bytes, 0, 8, (unsigned char*)&(stats.rx_bytes));
-//	bigint=(*env)->NewObject(env, bigint_cls, bigint_constructor, bytes);
-//	(*env)->SetObjectField(env, j_stats, (*env)->GetFieldID(env, stats_cls, "rx_bytes", "Ljava/math/BigInteger;"), bigint);
-//
-//	(*env)->SetByteArrayRegion(env, bytes, 0, 8, (unsigned char*)&(stats.rx_packets));
-//	bigint=(*env)->NewObject(env, bigint_cls, bigint_constructor, bytes);
-//	(*env)->SetObjectField(env, j_stats, (*env)->GetFieldID(env, stats_cls, "rx_packets", "Ljava/math/BigInteger;"), bigint);
-//
-//	(*env)->SetByteArrayRegion(env, bytes, 0, 8, (unsigned char*)&(stats.rx_errs));
-//	bigint=(*env)->NewObject(env, bigint_cls, bigint_constructor, bytes);
-//	(*env)->SetObjectField(env, j_stats, (*env)->GetFieldID(env, stats_cls, "rx_errs", "Ljava/math/BigInteger;"), bigint);
-//
-//	(*env)->SetByteArrayRegion(env, bytes, 0, 8, (unsigned char*)&(stats.rx_drop));
-//	bigint=(*env)->NewObject(env, bigint_cls, bigint_constructor, bytes);
-//	(*env)->SetObjectField(env, j_stats, (*env)->GetFieldID(env, stats_cls, "rx_drop", "Ljava/math/BigInteger;"), bigint);
-//
-//	(*env)->SetByteArrayRegion(env, bytes, 0, 8, (unsigned char*)&(stats.tx_bytes));
-//	bigint=(*env)->NewObject(env, bigint_cls, bigint_constructor, bytes);
-//	(*env)->SetObjectField(env, j_stats, (*env)->GetFieldID(env, stats_cls, "tx_bytes", "Ljava/math/BigInteger;"), bigint);
-//
-//	(*env)->SetByteArrayRegion(env, bytes, 0, 8, (unsigned char*)&(stats.tx_packets));
-//	bigint=(*env)->NewObject(env, bigint_cls, bigint_constructor, bytes);
-//	(*env)->SetObjectField(env, j_stats, (*env)->GetFieldID(env, stats_cls, "tx_packets", "Ljava/math/BigInteger;"), bigint);
-//
-//	(*env)->SetByteArrayRegion(env, bytes, 0, 8, (unsigned char*)&(stats.tx_errs));
-//	bigint=(*env)->NewObject(env, bigint_cls, bigint_constructor, bytes);
-//	(*env)->SetObjectField(env, j_stats, (*env)->GetFieldID(env, stats_cls, "tx_errs", "Ljava/math/BigInteger;"), bigint);
-//
-//	(*env)->SetByteArrayRegion(env, bytes, 0, 8, (unsigned char*)&(stats.tx_drop));
-//	bigint=(*env)->NewObject(env, bigint_cls, bigint_constructor, bytes);
-//	(*env)->SetObjectField(env, j_stats, (*env)->GetFieldID(env, stats_cls, "tx_drop", "Ljava/math/BigInteger;"), bigint);
-//
-//	return j_stats;
-//}
-
 JNIEXPORT jobject JNICALL Java_org_libvirt_Domain__1interfaceStats
   (JNIEnv *env, jobject obj, jlong VDP, jstring j_path){
 	struct  _virDomainInterfaceStats stats;
 	jobject j_stats;
 	jclass stats_cls=(*env)->FindClass(env, "org/libvirt/DomainInterfaceStats");
-
-	if(virDomainInterfaceStats((virDomainPtr)VDP, (*env)->GetStringUTFChars(env, j_path, NULL), &stats, sizeof(struct  _virDomainInterfaceStats))<0)
+	const char *path = (*env)->GetStringUTFChars(env, j_path, NULL);
+	
+	if(virDomainInterfaceStats((virDomainPtr)VDP, (*env)->GetStringUTFChars(env, j_path, NULL), &stats, sizeof(struct  _virDomainInterfaceStats))<0){
+		(*env)->ReleaseStringUTFChars(env, j_path, path);
 		return NULL;
+	}
+	(*env)->ReleaseStringUTFChars(env, j_path, path);
 
 	j_stats = (*env)->AllocObject(env, stats_cls);
 
@@ -568,23 +449,25 @@
 
 JNIEXPORT jint JNICALL Java_org_libvirt_Domain__1coreDump
   (JNIEnv *env, jobject obj, jlong VDP, jstring j_to, jint flags){
-	char *to = (char*)(*env)->GetStringUTFChars(env, j_to, NULL);
-	return virDomainCoreDump((virDomainPtr)VDP, to, flags);
+	const char *to = (*env)->GetStringUTFChars(env, j_to, NULL);
+	jint retval = virDomainCoreDump((virDomainPtr)VDP, to, flags);
+	(*env)->ReleaseStringUTFChars(env, j_to, to);
+	return retval;
 }
 
 JNIEXPORT jint JNICALL Java_org_libvirt_Domain__1create
   (JNIEnv *env, jobject obj, jlong VDP){
-	return virDomainCreate((virDomainPtr)VDP);
+	GENERIC__VIROBJ__INT(env, obj, (virDomainPtr)VDP, virDomainCreate)
 }
 
 JNIEXPORT jint JNICALL Java_org_libvirt_Domain__1destroy
   (JNIEnv *env, jobject obj, jlong VDP){
-	return virDomainDestroy((virDomainPtr)VDP);
+	GENERIC__VIROBJ__INT(env, obj, (virDomainPtr)VDP, virDomainDestroy)
 }
 
 JNIEXPORT jint JNICALL Java_org_libvirt_Domain__1free
   (JNIEnv *env, jobject obj, jlong VDP){
-	return virDomainFree((virDomainPtr)VDP);
+	GENERIC__VIROBJ__INT(env, obj, (virDomainPtr)VDP, virDomainFree)
 }
 
 JNIEXPORT jobject JNICALL Java_org_libvirt_Domain__1getInfo
@@ -642,52 +525,55 @@
 
 	virConnectPtr destVCP;
 
-	char *dname=NULL;
-	char *uri=NULL;
+	const char *dname=NULL;
+	const char *uri=NULL;
 
 	//if String="", we pass NULL to the library
 	if((*env)->GetStringLength(env, j_dname)>0)
-		dname=(char*)(*env)->GetStringUTFChars(env, j_dname, NULL);
+		dname=(*env)->GetStringUTFChars(env, j_dname, NULL);
 
 	//if String="", we pass NULL to the library
 	if((*env)->GetStringLength(env, j_uri)>0)
-		uri=(char*)(*env)->GetStringUTFChars(env, j_uri, NULL);
+		uri=(*env)->GetStringUTFChars(env, j_uri, NULL);
 
 	//Extract the destination Conn Ptr
 	destVCP=(virConnectPtr)(*env)->GetLongField(env, dconn,
 			(*env)->GetFieldID(env, (*env)->GetObjectClass(env, dconn), "VCP", "J"));
 
-	return (long)virDomainMigrate((virDomainPtr)VDP, destVCP, flags, dname, uri, bandwidth);
+	jlong retval = (jlong)virDomainMigrate((virDomainPtr)VDP, destVCP, flags, dname, uri, bandwidth);
+	(*env)->ReleaseStringUTFChars(env, j_dname, dname);
+	(*env)->ReleaseStringUTFChars(env, j_uri, uri);
+	return retval;
 }
 
 JNIEXPORT jint JNICALL Java_org_libvirt_Domain__1reboot
   (JNIEnv *env, jobject obj, jlong VDP, jint flags){
-	return virDomainReboot((virDomainPtr)VDP, flags);
+	GENERIC__VIROBJ_INT__INT(env, obj, (virDomainPtr)VDP, flags, virDomainReboot)
 }
 
 JNIEXPORT jint JNICALL Java_org_libvirt_Domain__1suspend
 (JNIEnv *env, jobject obj, jlong VDP){
-	return virDomainSuspend((virDomainPtr)VDP);
+	GENERIC__VIROBJ__INT(env, obj, (virDomainPtr)VDP, virDomainSuspend)
 }
 
 JNIEXPORT jint JNICALL Java_org_libvirt_Domain__1resume
   (JNIEnv *env, jobject obj, jlong VDP){
-	return virDomainResume((virDomainPtr)VDP);
+	GENERIC__VIROBJ__INT(env, obj, (virDomainPtr)VDP, virDomainResume)
 }
 
 JNIEXPORT jint JNICALL Java_org_libvirt_Domain__1save
-  (JNIEnv *env, jobject obj, jlong VDP, jstring to){
-	return virDomainSave((virDomainPtr)VDP, (char*)(*env)->GetStringUTFChars(env, to, NULL));
+  (JNIEnv *env, jobject obj, jlong VDP, jstring j_to){
+	GENERIC_VIROBJ_STRING__INT(env, obj, (virDomainPtr)VDP, j_to, virDomainSave)
 }
 
 JNIEXPORT jint JNICALL Java_org_libvirt_Domain__1shutdown
   (JNIEnv *env, jobject obj, jlong VDP){
-	return virDomainShutdown((virDomainPtr)VDP);
+	GENERIC__VIROBJ__INT(env, obj, (virDomainPtr)VDP, virDomainShutdown)
 }
 
 JNIEXPORT jint JNICALL Java_org_libvirt_Domain__1undefine
 (JNIEnv *env, jobject obj, jlong VDP){
-	return virDomainUndefine((virDomainPtr)VDP);
+	GENERIC__VIROBJ__INT(env, obj, (virDomainPtr)VDP, virDomainUndefine)
 }
 
 JNIEXPORT jint JNICALL Java_org_libvirt_Domain__1setMemory
Index: src/Makefile.am
===================================================================
RCS file: /data/cvs/libvirt-java/src/Makefile.am,v
retrieving revision 1.6
diff -u -r1.6 Makefile.am
--- src/Makefile.am	21 Jul 2008 07:52:54 -0000	1.6
+++ src/Makefile.am	4 Aug 2008 21:07:40 -0000
@@ -21,8 +21,12 @@
   org/libvirt/SchedParameter.java \
   org/libvirt/SchedUintParameter.java \
   org/libvirt/SchedUlongParameter.java \
-  org/libvirt/VcpuInfo.java
-
+  org/libvirt/VcpuInfo.java \
+  org/libvirt/StoragePool.java \
+  org/libvirt/StoragePoolInfo.java \
+  org/libvirt/StorageVol.java \
+  org/libvirt/StorageVolInfo.java
+  
 EXTRA_DIST= \
   test.java \
   $(java_libvirt_source_files)
Index: src/org/libvirt/StorageVolInfo.java
===================================================================
RCS file: src/org/libvirt/StorageVolInfo.java
diff -N src/org/libvirt/StorageVolInfo.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/libvirt/StorageVolInfo.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,53 @@
+package org.libvirt;
+
+public class StorageVolInfo {
+	
+	/**
+	 * The type of the Volume
+	 */
+	public VirStorageVolType type;
+	/**
+	 * Logical size bytes
+	 */
+	public long	capacity;
+	/**
+	 * Current allocation bytes
+	 */
+	public long	allocation;
+	
+	public static enum VirStorageVolType{
+		/**
+		 * Regular file based volumes
+		 */
+		VIR_STORAGE_VOL_FILE, 
+		/**
+		 * Block based volumes
+		 */
+		VIR_STORAGE_VOL_BLOCK, 
+	}
+	
+	/**
+	 * This is meant to be called from the JNI side, as a convenience constructor
+	 * 
+	 * @param type the type, as defined by libvirt
+	 * @param capacity
+	 * @param allocation
+	 */
+	StorageVolInfo(int type, long capacity, long allocation){
+		switch(type){
+			case 0: this.type=VirStorageVolType.VIR_STORAGE_VOL_FILE; break;
+			case 1: this.type=VirStorageVolType.VIR_STORAGE_VOL_BLOCK; break;
+			default: assert(false);
+		}
+		this.capacity = capacity;
+		this.allocation = allocation;
+	}	
+	
+	public String toString(){
+		StringBuffer result = new StringBuffer("");
+		result.append("type:" + type + "\n");
+		result.append("capacity:" + capacity + "\n");
+		result.append("allocation:" + allocation + "\n");
+		return result.toString();
+	}
+}
Index: src/jni/org_libvirt_StoragePool.c
===================================================================
RCS file: src/jni/org_libvirt_StoragePool.c
diff -N src/jni/org_libvirt_StoragePool.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/jni/org_libvirt_StoragePool.c	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,117 @@
+#include <libvirt/libvirt.h>
+#include "org_libvirt_StoragePool.h"
+#include "generic.h"
+
+
+JNIEXPORT jint JNICALL Java_org_libvirt_StoragePool__1build
+  (JNIEnv *env, jobject obj, jlong VSPP, jint flags){
+	GENERIC__VIROBJ_INT__INT(env, obj, (virStoragePoolPtr)VSPP, flags, virStoragePoolBuild)
+}
+
+JNIEXPORT jint JNICALL Java_org_libvirt_StoragePool__1create
+  (JNIEnv *env, jobject obj, jlong VSPP, jint flags){
+	GENERIC__VIROBJ_INT__INT(env, obj, (virStoragePoolPtr)VSPP, flags, virStoragePoolCreate)
+}
+
+JNIEXPORT jint JNICALL Java_org_libvirt_StoragePool__1delete
+  (JNIEnv *env, jobject obj, jlong VSPP, jint flags){
+	GENERIC__VIROBJ_INT__INT(env, obj, (virStoragePoolPtr)VSPP, flags, virStoragePoolDelete)
+}
+
+JNIEXPORT jint JNICALL Java_org_libvirt_StoragePool__1destroy
+  (JNIEnv *env, jobject obj, jlong VSPP){
+	GENERIC__VIROBJ__INT(env, obj, (virStoragePoolPtr)VSPP, virStoragePoolDestroy)
+}
+
+JNIEXPORT jint JNICALL Java_org_libvirt_StoragePool__1free
+  (JNIEnv *env, jobject obj, jlong VSPP){
+	GENERIC__VIROBJ__INT(env, obj, (virStoragePoolPtr)VSPP, virStoragePoolFree)
+}
+
+JNIEXPORT jboolean JNICALL Java_org_libvirt_StoragePool__1getAutostart
+  (JNIEnv *env, jobject obj, jlong VSPP){
+	GENERIC_GETAUTOSTART(env, obj, (virStoragePoolPtr)VSPP, virStoragePoolGetAutostart)
+}
+
+JNIEXPORT jobject JNICALL Java_org_libvirt_StoragePool__1getInfo
+  (JNIEnv *env, jobject obj, jlong VSPP){
+
+	virStoragePoolInfo storagePoolInfo;
+
+	jobject j_info;
+
+	//Get the data
+	if(virStoragePoolGetInfo((virStoragePoolPtr)VSPP, &storagePoolInfo)<0)
+		return NULL;
+
+	//get the field Ids of info
+	jclass j_storagePoolInfo_cls = (*env)->FindClass(env,"org/libvirt/StoragePoolInfo");
+	jmethodID j_storagePoolInfo_constructor = (*env)->GetMethodID(env, j_storagePoolInfo_cls, "<init>", "(IJJJ)V");
+	
+	//Long live encapsulation
+	j_info=(*env)->NewObject(env,
+					j_storagePoolInfo_cls,
+					j_storagePoolInfo_constructor,
+					storagePoolInfo.state,
+					storagePoolInfo.capacity,
+					storagePoolInfo.allocation,
+					storagePoolInfo.available);	
+
+	return j_info;
+}
+
+JNIEXPORT jstring JNICALL Java_org_libvirt_StoragePool__1getName
+  (JNIEnv *env, jobject obj, jlong VSPP){
+	GENERIC__VIROBJ__CONSTSTRING(env, obj, (virStoragePoolPtr)VSPP, virStoragePoolGetName)
+}
+
+JNIEXPORT jintArray JNICALL Java_org_libvirt_StoragePool__1getUUID
+  (JNIEnv *env, jobject obj, jlong VSPP){
+	GENERIC_GETUUID(env, obj, (virStoragePoolPtr)VSPP, virStoragePoolGetUUID)
+}
+
+JNIEXPORT jstring JNICALL Java_org_libvirt_StoragePool__1getUUIDString
+  (JNIEnv *env, jobject obj, jlong VSPP){
+	GENERIC_GETUUIDSTRING(env, obj, (virStoragePoolPtr)VSPP, virStoragePoolGetUUIDString)
+}
+
+JNIEXPORT jstring JNICALL Java_org_libvirt_StoragePool__1getXMLDesc
+  (JNIEnv *env, jobject obj, jlong VSPP, jint flags){
+	GENERIC_VIROBJ_INT__STRING(env, obj, (virStoragePoolPtr)VSPP, flags, virStoragePoolGetXMLDesc)
+}
+
+JNIEXPORT jobjectArray JNICALL Java_org_libvirt_StoragePool__1listVolumes
+  (JNIEnv *env, jobject obj, jlong VSPP){
+	GENERIC_LIST_STRINGARRAY(env, obj, (virStoragePoolPtr)VSPP, virStoragePoolListVolumes, virStoragePoolNumOfVolumes)
+}
+
+JNIEXPORT jint JNICALL Java_org_libvirt_StoragePool__1numOfVolumes
+  (JNIEnv *env, jobject obj, jlong VSPP){
+	GENERIC__VIROBJ__INT(env, obj, (virStoragePoolPtr)VSPP, virStoragePoolNumOfVolumes)
+}
+
+JNIEXPORT jint JNICALL Java_org_libvirt_StoragePool__1refresh
+  (JNIEnv *env, jobject obj, jlong VSPP, jint flags){
+	GENERIC__VIROBJ_INT__INT(env, obj, (virStoragePoolPtr)VSPP, flags, virStoragePoolRefresh)
+}
+
+JNIEXPORT jint JNICALL Java_org_libvirt_StoragePool__1setAutostart
+  (JNIEnv *env, jobject obj, jlong VSPP, jint flags){
+	GENERIC__VIROBJ_INT__INT(env, obj, (virStoragePoolPtr)VSPP, flags, virStoragePoolSetAutostart)
+}
+
+JNIEXPORT jint JNICALL Java_org_libvirt_StoragePool__1undefine
+(JNIEnv *env, jobject obj, jlong VSPP){
+	GENERIC__VIROBJ__INT(env, obj, (virStoragePoolPtr)VSPP, virStoragePoolUndefine)
+}
+
+JNIEXPORT jlong JNICALL Java_org_libvirt_StoragePool__1storageVolLookupByName
+  (JNIEnv *env, jobject obj, jlong VSPP, jstring name){
+	GENERIC_LOOKUPBY_STRING(env, obj, (virStoragePoolPtr)VSPP, name, virStorageVolLookupByName)
+}
+
+JNIEXPORT jlong JNICALL Java_org_libvirt_StoragePool__1storageVolCreateXML
+  (JNIEnv *env, jobject obj, jlong VSPP, jstring j_xmlDesc, jint flags){
+	GENERIC_VIROBJ_STRING_INT__VIROBJ(env, obj, (virStoragePoolPtr)VSPP, j_xmlDesc, flags, virStorageVolCreateXML)
+}
+
Index: src/org/libvirt/StorageVol.java
===================================================================
RCS file: src/org/libvirt/StorageVol.java
diff -N src/org/libvirt/StorageVol.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/libvirt/StorageVol.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,158 @@
+package org.libvirt;
+
+public class StorageVol {
+	
+	static final class DeleteFlags{
+		/**
+		 * Delete metadata only (fast)
+		 */
+		static final int VIR_STORAGE_POOL_DELETE_NORMAL	 = 	0;
+		/**
+		 * Clear all data to zeros (slow)
+		 */
+		static final int VIR_STORAGE_POOL_DELETE_ZEROED	= 	1;
+	}
+	
+	public static enum Type {
+		/**
+		 * Regular file based volumes
+		 */
+		VIR_STORAGE_VOL_FILE,
+		/**
+		 * Block based volumes
+		 */
+		VIR_STORAGE_VOL_BLOCK
+	}
+
+	/**
+	 * the native virStorageVolPtr.
+	 */
+	private long  VSVP;
+	
+	/**
+	 * The VirConnect Object that represents the Hypervisor of this Domain
+	 */
+	private Connect virConnect;
+	
+	
+	/**
+	 * Constructs a VirStorageVol object from a known native virStoragePoolPtr, and a VirConnect object.
+	 * For use when native libvirt returns a virStorageVolPtr, i.e. error handling.
+	 * 
+	 * @param virConnect the Domain's hypervisor
+	 * @param VSVP the native virStorageVolPtr
+	 */
+	StorageVol(Connect virConnect, long VSVP){
+		this.virConnect = virConnect;
+		this.VSVP = VSVP;
+	}
+	
+	/**
+	 * Fetch a storage pool which contains this volume
+	 * 
+	 * @return StoragePool object, 
+	 * @throws LibvirtException
+	 */
+	public StoragePool storagePoolLookupByVolume()
+	throws LibvirtException {
+		return new StoragePool(virConnect, _storagePoolLookupByVolume(VSVP));
+	}
+
+	private native long _storagePoolLookupByVolume(long VSVP)
+	throws LibvirtException;
+
+	/**
+	 * Delete the storage volume from the pool
+	 * 
+	 * @param flags future flags, use 0 for now
+	 * @throws LibvirtException
+	 */
+	public void delete(int flags) throws LibvirtException{
+		_delete(VSVP, flags);
+	}
+	
+	private native int _delete(long VSVP, int flags) throws LibvirtException;
+	
+	/**
+	 * Release the storage volume handle. The underlying storage volume contains to exist
+	 * 
+	 * @throws LibvirtException
+	 */
+	public void free() throws LibvirtException{
+		_free(VSVP);
+	}
+	
+	private native int _free(long VSVP) throws LibvirtException;
+	
+	/**
+	 * Provides the connection object associated with a storage volume. The reference counter on the connection is not increased by this call.
+	 * 
+	 * @return the Connect object
+	 */
+	public Connect getConnect(){
+		return virConnect;
+	}
+	
+	/**
+	 * Fetches volatile information about the storage volume such as its current allocation
+	 * 
+	 * @return StorageVolInfo object
+	 * @throws LibvirtException
+	 */
+	public StorageVolInfo getInfo() throws LibvirtException{
+		return _getInfo(VSVP);
+	}
+
+	private native StorageVolInfo _getInfo(long VSVP) throws LibvirtException;
+
+	/**
+	 * Fetch the storage volume key. This is globally unique, so the same volume will have the same key no matter what host it is accessed from
+	 * 
+	 * @return the key
+	 * @throws LibvirtException
+	 */
+	public String getKey() throws LibvirtException{
+		return _getKey(VSVP);
+	}
+
+	private native String _getKey(long VSVP) throws LibvirtException;
+	
+	/**
+	 * Fetch the storage volume name. This is unique within the scope of a pool
+	 * 
+	 * @return the name
+	 * @throws LibvirtException
+	 */
+	public String getName() throws LibvirtException{
+		return _getName(VSVP);
+	}
+
+	private native String _getName(long VSVP) throws LibvirtException;
+	
+	/**
+	 * Fetch the storage volume path. 
+	 * Depending on the pool configuration this is either persistent across hosts, or dynamically assigned at pool startup. 
+	 * Consult pool documentation for information on getting the persistent naming
+	 * 
+	 * @return 
+	 * @throws LibvirtException
+	 */
+	public String getPath() throws LibvirtException{
+		return _getPath(VSVP);
+	}
+
+	private native String _getPath(long VSVP) throws LibvirtException;
+	
+	/**
+	 * Fetch an XML document describing all aspects of this storage volume
+	 * 
+	 * @param flags flags for XML generation (unused, pass 0)
+	 * @return the XML document
+	 * @throws LibvirtException
+	 */
+	public String getXMLDesc(int flags) throws LibvirtException{
+		return _getXMLDesc(VSVP, flags);
+	}
+	
+	private native String _getXMLDesc(long VSVP, int flags) throws LibvirtException;
+}
Index: src/org/libvirt/StoragePoolInfo.java
===================================================================
RCS file: src/org/libvirt/StoragePoolInfo.java
diff -N src/org/libvirt/StoragePoolInfo.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/libvirt/StoragePoolInfo.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,73 @@
+package org.libvirt;
+
+public class StoragePoolInfo {
+	
+	/**
+	 * the running state
+	 */
+	public StoragePoolState state;
+	
+	/**
+	 * Logical size bytes
+	 */
+	public long capacity;
+	
+	/**
+	 * Current allocation bytes
+	 */
+	public long allocation;
+	
+	/**
+	 * Remaining free space bytes
+	 */
+	public long available;
+	
+	public static enum StoragePoolState {
+		/**
+		 * Not running
+		 */
+		VIR_STORAGE_POOL_INACTIVE, 
+		/**
+		 * Initializing pool, not available
+		 */
+		VIR_STORAGE_POOL_BUILDING, 
+		/**
+		 * Running normally
+		 */
+		VIR_STORAGE_POOL_RUNNING, 
+		/**
+		 * Running degraded
+		 */
+		VIR_STORAGE_POOL_DEGRADED, 
+	}
+	
+	/**
+	 * This is meant to be called from the JNI side, as a convenience constructor
+	 * 
+	 * @param state the state, as defined by libvirt
+	 * @param capacity 
+	 * @param allocation
+	 * @param available
+	 */
+	StoragePoolInfo(int state, long capacity, long allocation, long available){
+		switch(state){
+			case 0: this.state=StoragePoolState.VIR_STORAGE_POOL_INACTIVE; break;
+			case 1: this.state=StoragePoolState.VIR_STORAGE_POOL_BUILDING; break;
+			case 2: this.state=StoragePoolState.VIR_STORAGE_POOL_RUNNING; break;
+			case 3: this.state=StoragePoolState.VIR_STORAGE_POOL_DEGRADED; break;
+			default: assert(false);
+		}
+		this.capacity = capacity;
+		this.allocation = allocation;
+		this.available = available;
+	}
+	
+	public String toString(){
+		StringBuffer result = new StringBuffer("");
+		result.append("state:" + state + "\n");
+		result.append("capacity:" + capacity + "\n");
+		result.append("allocation:" + allocation + "\n");
+		result.append("available:" + available + "\n");
+		return result.toString();
+	}
+}
Index: src/org/libvirt/StoragePool.java
===================================================================
RCS file: src/org/libvirt/StoragePool.java
diff -N src/org/libvirt/StoragePool.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/libvirt/StoragePool.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,286 @@
+package org.libvirt;
+
+public class StoragePool {
+
+	static final class BuildFlags{
+		/**
+		 * Regular build from scratch
+		 */
+		static final int VIR_STORAGE_POOL_BUILD_NEW	 = 	0;
+		/**
+		 * Repair / reinitialize
+		 */
+		static final int VIR_STORAGE_POOL_BUILD_REPAIR	= 	1; 
+		/**
+		 * Extend existing pool
+		 */
+		static final int VIR_STORAGE_POOL_BUILD_RESIZE	= 	2;
+	}
+	
+	static final class DeleteFlags{
+		/**
+		 * Delete metadata only (fast)
+		 */
+		static final int VIR_STORAGE_POOL_DELETE_NORMAL	 = 	0;
+		/**
+		 * Clear all data to zeros (slow)
+		 */
+		static final int VIR_STORAGE_POOL_DELETE_ZEROED	= 	1;
+	}
+	
+	/**
+	 * the native virStoragePoolPtr.
+	 */
+	private long  VSPP;
+	
+	/**
+	 * The VirConnect Object that represents the Hypervisor of this Domain
+	 */
+	private Connect virConnect;
+	
+	
+	/**
+	 * Constructs a VirStoragePool object from a known native virStoragePoolPtr, and a VirConnect object.
+	 * For use when native libvirt returns a virStoragePoolPtr, i.e. error handling.
+	 * 
+	 * @param virConnect the Domain's hypervisor
+	 * @param VSPP the native virStoragePoolPtr
+	 */
+	StoragePool(Connect virConnect, long VSPP){
+		this.virConnect = virConnect;
+		this.VSPP = VSPP;
+	}
+	
+	/**
+	 * Build the underlying storage pool
+	 * 
+	 * @param flags future flags, use 0 for now
+	 */
+	public void build(int flags) throws LibvirtException{
+		_build(VSPP, flags);
+	}
+	
+	private native int _build(long VSPP, int flags) throws LibvirtException;
+	
+	/**
+	 * Starts this inactive storage pool
+	 * 
+	 * @param flags future flags, use 0 for now
+	 */
+	public void create(int flags) throws LibvirtException{
+		_create(VSPP, flags);
+	}
+	
+	private native int _create(long VSPP, int flags) throws LibvirtException;
+	
+	/**
+	 * Delete the underlying pool resources. This is a non-recoverable operation. 
+	 * The virStoragePool object itself is not free'd.
+	 * 
+	 * @param flags flags for obliteration process
+	 */
+	public void delete(int flags) throws LibvirtException{
+		_delete(VSPP, flags);
+	}
+	
+	private native int _delete(long VSPP, int flags) throws LibvirtException;
+	
+	/**
+	 * Destroy an active storage pool. 
+	 * This will deactivate the pool on the host, but keep any persistent config associated with it. 
+	 * If it has a persistent config it can later be restarted with virStoragePoolCreate(). 
+	 * This does not free the associated virStoragePoolPtr object.
+	 */
+	public void destroy() throws LibvirtException{
+		_destroy(VSPP);
+	}
+	
+	private native int _destroy(long VSPP) throws LibvirtException;
+	
+	/**
+	 * Free a storage pool object, releasing all memory associated with it. 
+	 * Does not change the state of the pool on the host.
+	 */
+	public void free() throws LibvirtException{
+		_free(VSPP);
+	}
+	
+	private native int _free(long VSPP) throws LibvirtException;
+	
+	
+	/**
+	 * Fetches the value of the autostart flag, which determines whether the pool is automatically started at boot time
+	 *
+	 * @return the result
+	 * @throws LibvirtException
+	 */
+	public boolean getAutostart() throws LibvirtException{
+		return _getAutostart(VSPP);
+	}
+
+	private native boolean _getAutostart(long VSPP) throws LibvirtException;
+	
+	/**
+	 * Provides the connection pointer associated with a storage pool.
+	 *
+	 * @return the Connect object
+	 */
+	public Connect getConnect(){
+		return virConnect;
+	}
+	/**
+	 * Get volatile information about the storage pool such as free space / usage summary
+	 *
+	 * @return a StoragePoolInfo object describing this storage pool
+	 * @throws LibvirtException
+	 */
+	public StoragePoolInfo getInfo() throws LibvirtException{
+		return _getInfo(VSPP);
+	}
+
+	private native StoragePoolInfo _getInfo(long VSPP) throws LibvirtException;
+
+	/**
+	 * Fetch the locally unique name of the storage pool
+	 *
+	 * @return the name
+	 * @throws LibvirtException
+	 */
+	public String getName() throws LibvirtException{
+		return _getName(VSPP);
+	}
+
+	private native String _getName(long VSPP) throws LibvirtException;
+	
+	/**
+	 * Fetch the globally unique ID of this storage pool
+	 * 
+	 * @return the UUID as an unpacked int array
+	 * @throws LibvirtException
+	 */
+	public int[] getUUID() throws LibvirtException{
+		return _getUUID(VSPP);
+	}
+	
+	private native int[] _getUUID(long VSPP) throws LibvirtException;
+	
+
+	/**
+	 * Fetch the globally unique ID of the storage pool as a string
+	 * 
+	 * @return the UUID in canonical String format
+	 * @throws LibvirtException
+	 */
+	public String getUUIDString() throws LibvirtException{
+		return _getUUIDString(VSPP);
+	}
+
+	private native String _getUUIDString(long VSPP) throws LibvirtException;
+	
+	/**
+	 * Fetch an XML document describing all aspects of the storage pool. 
+	 * This is suitable for later feeding back into the virStoragePoolCreateXML method.
+	 * 
+	 * @param flags flags for XML format options (set of virDomainXMLFlags)
+	 * @return a XML document
+	 *-java @throws LibvirtException
+	 */
+	public String getXMLDesc(int flags) throws LibvirtException{
+		return _getXMLDesc(VSPP, flags);
+	}
+	
+	private native String _getXMLDesc(long VSPP, int flags) throws LibvirtException;
+	
+	/**
+	 * Fetch list of storage volume names
+	 *
+	 * @return an Array of Strings that contains the names of the storage volumes
+	 * @throws LibvirtException
+	 */
+	public String[] listVolumes() throws LibvirtException {
+		return _listVolumes(VSPP);
+	}
+
+	private native String[] _listVolumes(long VSPP)
+	throws LibvirtException;
+
+	/**
+	 * Fetch the number of storage volumes within a pool
+	 *
+	 * @return the number of storage pools
+	 * @throws LibvirtException
+	 */
+	public int numOfVolumes() throws LibvirtException {
+		return _numOfVolumes(VSPP);
+	}
+
+	private native int _numOfVolumes(long VSPP) throws LibvirtException;
+
+	/**
+	 * Request that the pool refresh its list of volumes. 
+	 * This may involve communicating with a remote server, and/or initializing new devices at the OS layer
+	 *
+	 * @param flags flags to control refresh behaviour (currently unused, use 0)
+	 * @throws LibvirtException
+	 */
+	public void refresh(int flags) throws LibvirtException {
+		_refresh(VSPP, flags);
+	}
+
+	private native int _refresh(long VSPP, int flags) throws LibvirtException;
+
+	/**
+	 * Sets the autostart flag
+	 *
+	 * @param autostart	new flag setting
+	 * @throws LibvirtException
+	 */
+	public void setAutostart(int autostart) throws LibvirtException {
+		_setAutostart(VSPP, autostart);
+	}
+
+	private native int _setAutostart(long VSPP, int autostart) throws LibvirtException;
+
+	/**
+	 * Undefine an inactive storage pool
+	 *
+	 * @throws LibvirtException
+	 */
+	public void undefine() throws LibvirtException {
+		_undefine(VSPP);
+	}
+
+	private native int _undefine(long VSPP) throws LibvirtException;
+
+	/**
+	 * Fetch an object representing to a storage volume based on its name within a pool
+	 *
+	 * @param name name of storage volume
+	 * @return The StorageVol object found
+	 * @throws LibvirtException
+	 */
+	public StorageVol storageVolLookupByName(String name)
+	throws LibvirtException {
+		return new StorageVol(virConnect, _storageVolLookupByName(VSPP, name));
+	}
+
+	private native long _storageVolLookupByName(long VSPP, String name)
+	throws LibvirtException;
+
+	/**
+	 * Create a storage volume within a pool based on an XML description. Not all pools support creation of volumes
+	 * 
+	 * @param xmlDesc description of volume to create
+	 * @param flags flags for creation (unused, pass 0)
+	 * @return the storage volume
+	 * @throws LibvirtException
+	 */
+	public StorageVol storageVolCreateXML(String xmlDesc, int flags)
+	throws LibvirtException {
+		return new StorageVol(virConnect, _storageVolCreateXML(VSPP, xmlDesc, flags));
+	}
+
+	private native long _storageVolCreateXML(long VSPP, String xmlDesc, int flags)
+	throws LibvirtException;
+
+}
Index: src/jni/org_libvirt_StorageVol.c
===================================================================
RCS file: src/jni/org_libvirt_StorageVol.c
diff -N src/jni/org_libvirt_StorageVol.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/jni/org_libvirt_StorageVol.c	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,65 @@
+#include "org_libvirt_StorageVol.h"
+#include "generic.h"
+#include <libvirt/libvirt.h>
+
+JNIEXPORT jlong JNICALL Java_org_libvirt_StorageVol__1storagePoolLookupByVolume
+  (JNIEnv *env, jobject obj, jlong VSVP){
+	GENERIC_LOOKUPBY_NONE(env, obj, (virStorageVolPtr)VSVP, virStoragePoolLookupByVolume)
+}
+
+JNIEXPORT jint JNICALL Java_org_libvirt_StorageVol__1delete
+  (JNIEnv *env, jobject obj, jlong VSVP, jint flags){
+	GENERIC__VIROBJ_INT__INT(env, obj, (virStorageVolPtr)VSVP, flags, virStorageVolDelete)
+}
+
+JNIEXPORT jint JNICALL Java_org_libvirt_StorageVol__1free
+  (JNIEnv *env, jobject obj, jlong VSVP){
+	GENERIC__VIROBJ__INT(env, obj, (virStorageVolPtr)VSVP, virStorageVolFree)
+}
+
+JNIEXPORT jobject JNICALL Java_org_libvirt_StorageVol__1getInfo
+(JNIEnv *env, jobject obj, jlong VSVP){
+
+	virStorageVolInfo storageVolInfo;
+
+	jobject j_info;
+
+	//Get the data
+	if(virStorageVolGetInfo((virStorageVolPtr)VSVP, &storageVolInfo)<0)
+		return NULL;
+
+	//get the field Ids of info
+	jclass j_storageVolInfo_cls = (*env)->FindClass(env,"org/libvirt/StorageVolInfo");
+	jmethodID j_storageVolInfo_constructor = (*env)->GetMethodID(env, j_storageVolInfo_cls, "<init>", "(IJJ)V");
+	
+	//Long live encapsulation
+	j_info=(*env)->NewObject(env,
+					j_storageVolInfo_cls,
+					j_storageVolInfo_constructor,
+					storageVolInfo.type,
+					storageVolInfo.capacity,
+					storageVolInfo.allocation);	
+
+	return j_info;
+}
+
+JNIEXPORT jstring JNICALL Java_org_libvirt_StorageVol__1getKey
+  (JNIEnv *env, jobject obj, jlong VSVP){
+	GENERIC__VIROBJ__CONSTSTRING(env, obj, (virStorageVolPtr)VSVP, virStorageVolGetKey)
+}
+
+JNIEXPORT jstring JNICALL Java_org_libvirt_StorageVol__1getName
+  (JNIEnv *env, jobject obj, jlong VSVP){
+	GENERIC__VIROBJ__CONSTSTRING(env, obj, (virStorageVolPtr)VSVP, virStorageVolGetName)
+}
+
+JNIEXPORT jstring JNICALL Java_org_libvirt_StorageVol__1getPath
+  (JNIEnv *env, jobject obj, jlong VSVP){
+	GENERIC__VIROBJ__STRING(env, obj, (virStorageVolPtr)VSVP, virStorageVolGetPath)
+}
+
+JNIEXPORT jstring JNICALL Java_org_libvirt_StorageVol__1getXMLDesc
+  (JNIEnv *env, jobject obj, jlong VSVP, jint flags){
+	GENERIC_VIROBJ_INT__STRING(env, obj, (virStorageVolPtr)VSVP, flags, virStorageVolGetXMLDesc)
+}
+
Index: src/jni/generic.h
===================================================================
RCS file: src/jni/generic.h
diff -N src/jni/generic.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/jni/generic.h	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,179 @@
+#ifndef GENERIC_H_
+#define GENERIC_H_
+#include <jni.h>
+#include <libvirt/libvirt.h>
+#include <stdlib.h>
+
+/* The macros here only make sense if they are the only thing in a function.
+ */
+
+/*
+ * Generic macro with a VIROBJ ARGument returning an int
+ * (for functions like virDomainFree)
+ */
+#define GENERIC__VIROBJ__INT(ENV, OBJ, VIROBJ1, VIRFUNC1) \
+	return (jint)VIRFUNC1(VIROBJ1);
+
+/*
+ * Generic macro with a VIROBJ and an int arguments returning an int
+ * (for functions like virStorageVolDelete)
+ */
+#define GENERIC__VIROBJ_INT__INT(ENV, OBJ, VIROBJ1, ARG1, VIRFUNC1) \
+	return (jint)VIRFUNC1(VIROBJ1, ARG1);
+
+/*
+ * Generic macro with a VIROBJ arguments returning a constant String
+ * (for functions like virNetworkGetBridgeName	)
+ */
+#define GENERIC__VIROBJ__CONSTSTRING(ENV, OBJ, VIROBJ1, VIRFUNC1) \
+	jstring j_retstring=NULL; \
+	const char *retstring; \
+	if((retstring = VIRFUNC1(VIROBJ1))){ \
+		j_retstring = (*ENV)->NewStringUTF(ENV, retstring); \
+	} \
+	return j_retstring;
+
+/*
+ * Generic macro with a VIROBJ arguments returning a String to be freed by the caller
+ * (for functions like virNetworkGetName)
+ */
+#define GENERIC__VIROBJ__STRING(ENV, OBJ, VIROBJ1,VIRFUNC1) \
+	jstring j_retstring=NULL; \
+	char *retstring; \
+	if((retstring = VIRFUNC1(VIROBJ1))){ \
+		j_retstring = (*ENV)->NewStringUTF(ENV, retstring); \
+		free(retstring); \
+	} \
+	return j_retstring;
+
+/*
+ * Generic macro with a VIROBJ and an int argument returning a String to be freed by the caller
+ * (for functions like virStoragePoolGetXMLDesc)
+ */
+#define GENERIC_VIROBJ_INT__STRING(ENV, OBJ, VIROBJ, ARG1, VIRFUNC1) \
+	jstring j_retstring; \
+	char* retstring = NULL; \
+	if((retstring = VIRFUNC1(VIROBJ, ARG1))){ \
+		j_retstring = (*ENV)->NewStringUTF(ENV, retstring); \
+		free(retstring); \
+	} \
+	return j_retstring; 
+
+/*
+ * Generic macro with a VIROBJ and an String arguments returning an int
+ * (for functions like virDomainDetachDevice )
+ */
+#define GENERIC_VIROBJ_STRING__INT(ENV, OBJ, VIROBJ, J_XMLDESC, VIRFUNC1) \
+	const char *xmlDesc=(*ENV)->GetStringUTFChars(ENV, J_XMLDESC, NULL); \
+	jint retval = (jlong)VIRFUNC1(VIROBJ, xmlDesc); \
+	(*ENV)->ReleaseStringUTFChars(ENV, J_XMLDESC, xmlDesc); \
+	return retval; 
+
+/*
+ * Generic macro with a VIROBJ and an String arguments returning a virObject
+ * (for functions like *CreateXML* that take no flags)
+ */
+#define GENERIC_VIROBJ_STRING__VIROBJ(ENV, OBJ, VIROBJ, J_XMLDESC, VIRFUNC1) \
+	const char *xmlDesc=(*ENV)->GetStringUTFChars(ENV, J_XMLDESC, NULL); \
+	jlong retval = (jlong)VIRFUNC1(VIROBJ, xmlDesc); \
+	(*ENV)->ReleaseStringUTFChars(ENV, J_XMLDESC, xmlDesc); \
+	return retval; 
+
+/*
+ * * Generic macro with a VIROBJ and String and int arguments returning a virObject
+ * (for functions like *CreateXML* that take a flags)
+ */
+#define GENERIC_VIROBJ_STRING_INT__VIROBJ(ENV, OBJ, VIROBJ, J_XMLDESC, FLAGS, VIRFUNC1) \
+	const char *xmlDesc=(*ENV)->GetStringUTFChars(ENV, J_XMLDESC, NULL); \
+	jlong retval = (jlong)VIRFUNC1(VIROBJ, xmlDesc, FLAGS); \
+	(*ENV)->ReleaseStringUTFChars(ENV, J_XMLDESC, xmlDesc); \
+	return retval;
+
+
+/*
+ * Generic macro for the *getAutoStart functions
+ */
+#define GENERIC_GETAUTOSTART(ENV, OBJ, VIROBJ, VIRFUNC1) \
+	int autostart=0; \
+	VIRFUNC1(VIROBJ, &autostart); \
+	return (jboolean)autostart;
+
+/*
+ * Generic macro for the *getUUID functions
+ */
+#define GENERIC_GETUUID(ENV, OBJ, VIROBJ1, VIRFUNC1) \
+	unsigned char uuid[VIR_UUID_BUFLEN]; \
+	jintArray j_uuid; \
+	int c; \
+	int uuidbyte; \
+	if(VIRFUNC1((void*)VIROBJ1, uuid)<0) \
+		return NULL; \
+	j_uuid=(*ENV)->NewIntArray(ENV, VIR_UUID_BUFLEN); \
+	for(c=0; c<VIR_UUID_BUFLEN; c++){ \
+			uuidbyte=uuid[c]; \
+			(*ENV)->SetIntArrayRegion(ENV, j_uuid, c, 1, &uuidbyte); \
+	} \
+	return j_uuid;
+
+/*
+ * Generic macro for the *getUUIDString functions
+ */
+#define GENERIC_GETUUIDSTRING(ENV, OBJ, VIROBJ, VIRFUNC1) \
+	char uuidString[VIR_UUID_STRING_BUFLEN]; \
+	VIRFUNC1(VIROBJ, uuidString); \
+	return (*ENV)->NewStringUTF(ENV, uuidString);
+
+
+/*
+ * Generic macro for the *List* functions that return an array of strings
+ * VIRFUNC1 is the *List* function
+ * VIRFUNC2 is the corresponding *NumOf* function
+ */
+#define GENERIC_LIST_STRINGARRAY(ENV, OBJ, VIROBJ,VIRFUNC1, VIRFUNC2) \
+	int maxnames; \
+	char **names; \
+	int c; \
+	jobjectArray j_names=NULL; \
+	if((maxnames = VIRFUNC2(VIROBJ))<0) \
+		return NULL; \
+	names= (char**)calloc(maxnames, sizeof(char*)); \
+	if(VIRFUNC1(VIROBJ, names, maxnames)>=0){ \
+		j_names= (jobjectArray)(*ENV)->NewObjectArray(ENV, maxnames, \
+			(*ENV)->FindClass(ENV,"java/lang/String"), \
+			(*ENV)->NewStringUTF(ENV,"")); \
+		for(c=0; c<maxnames; c++){ \
+			(*ENV)->SetObjectArrayElement(ENV, j_names, c, (*ENV)->NewStringUTF(ENV, names[c])); \
+		} \
+	} \
+	free(names); \
+	return j_names;
+
+/*
+ * Generic macro for the *LookupBy* functions that take a string and return a VirObject
+ */
+#define GENERIC_LOOKUPBY_STRING(ENV, OBJ, VIROBJ, J_STRINGID, VIRFUNC1) \
+	const char *stringid=(*ENV)->GetStringUTFChars(ENV, J_STRINGID, NULL); \
+	jlong retval = (jlong)VIRFUNC1(VIROBJ, stringid); \
+	(*ENV)->ReleaseStringUTFChars(ENV, J_STRINGID, stringid); \
+	return retval;
+
+/*
+ * Generic macro for the *LookupBy* functions that take no argument and return a VirObject
+ */
+#define GENERIC_LOOKUPBY_NONE(ENV, OBJ, VIROBJ, VIRFUNC1) \
+return (jlong)VIRFUNC1(VIROBJ);
+
+/*
+ * Generic macro for the *LookupBy* functions that take a UUID and return a VirObject
+ */
+#define GENERIC_LOOKUPBY_UUID(ENV, OBJ, VIROBJ, J_UUID, VIRFUNC1) \
+	unsigned char uuid[VIR_UUID_BUFLEN]; \
+	int c; \
+	int *uuid_int  = (*ENV)->GetIntArrayElements(ENV, J_UUID, NULL); \
+	for(c=0; c < VIR_UUID_BUFLEN; c++) \
+		uuid[c]=uuid_int[c]; \
+	return (jlong)VIRFUNC1(VIROBJ, uuid); 
+
+
+
+#endif /*GENERIC_H_*/


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]