java: Address the TODOs related to permissions

This also makes newVPermissionsFromJava and v23_syncbase_Bytes.extractToJava
more robust.

Change-Id: Ie4d0ca8c8d12fdbf7c032a382809f1ca5e162015
diff --git a/services/syncbase/bridge/cgo/jni.go b/services/syncbase/bridge/cgo/jni.go
index 325f759..a92db92 100644
--- a/services/syncbase/bridge/cgo/jni.go
+++ b/services/syncbase/bridge/cgo/jni.go
@@ -143,10 +143,9 @@
 //export Java_io_v_syncbase_internal_Database_Create
 func Java_io_v_syncbase_internal_Database_Create(env *C.JNIEnv, cls C.jclass, name C.jstring, perms C.jobject) {
 	cName := newVStringFromJava(env, name)
+	cPerms := newVPermissionsFromJava(env, perms)
 	var cErr C.v23_syncbase_VError
-	// TODO(razvanm): construct a proper C.v23_syncbase_Permissions based on
-	// the perms object.
-	v23_syncbase_DbCreate(cName, C.v23_syncbase_Permissions{}, &cErr)
+	v23_syncbase_DbCreate(cName, cPerms, &cErr)
 	maybeThrowException(env, &cErr)
 }
 
@@ -360,10 +359,9 @@
 func Java_io_v_syncbase_internal_Collection_Create(env *C.JNIEnv, cls C.jclass, name C.jstring, handle C.jstring, perms C.jobject) {
 	cName := newVStringFromJava(env, name)
 	cHandle := newVStringFromJava(env, handle)
+	cPerms := newVPermissionsFromJava(env, perms)
 	var cErr C.v23_syncbase_VError
-	// TODO(razvanm): construct a proper C.v23_syncbase_Permissions based on
-	// the perms object.
-	v23_syncbase_CollectionCreate(cName, cHandle, C.v23_syncbase_Permissions{}, &cErr)
+	v23_syncbase_CollectionCreate(cName, cHandle, cPerms, &cErr)
 	maybeThrowException(env, &cErr)
 }
 
@@ -634,7 +632,7 @@
 	obj := C.NewObjectA(env, syncgroupSpecClass.class, syncgroupSpecClass.init, nil)
 	C.SetObjectField(env, obj, syncgroupSpecClass.description, x.description.extractToJava(env))
 	C.SetObjectField(env, obj, syncgroupSpecClass.publishSyncbaseName, x.publishSyncbaseName.extractToJava(env))
-	// TODO(razvanm): Also extract the permissions.
+	C.SetObjectField(env, obj, syncgroupSpecClass.permissions, x.perms.extractToJava(env))
 	C.SetObjectField(env, obj, syncgroupSpecClass.collections, x.collections.extractToJava(env))
 	C.SetObjectField(env, obj, syncgroupSpecClass.mountTables, x.mountTables.extractToJava(env))
 	C.SetBooleanField(env, obj, syncgroupSpecClass.isPrivate, x.isPrivate.extractToJava())
diff --git a/services/syncbase/bridge/cgo/jni_types.go b/services/syncbase/bridge/cgo/jni_types.go
index d44db28..9c48df6 100644
--- a/services/syncbase/bridge/cgo/jni_types.go
+++ b/services/syncbase/bridge/cgo/jni_types.go
@@ -14,7 +14,10 @@
 
 package main
 
-import "unsafe"
+import (
+	"fmt"
+	"unsafe"
+)
 
 // #include <stdlib.h>
 // #include "jni_wrapper.h"
@@ -48,6 +51,12 @@
 }
 
 func (x *C.v23_syncbase_Bytes) extractToJava(env *C.JNIEnv) C.jbyteArray {
+	if x.n < 0 {
+		panic(fmt.Sprintf("bad size in C.v23_syncbase_Bytes: %d", x.n))
+	}
+	if x.n == 0 {
+		return nil
+	}
 	obj := C.NewByteArray(env, C.jsize(x.n))
 	if C.ExceptionOccurred(env) != nil {
 		panic("NewByteArray OutOfMemoryError exception")
@@ -191,26 +200,27 @@
 		panic("newVSyngroupSpecFromJava exception while retrieving SyncgroupSpec.publishSyncbaseName")
 	}
 
-	// TODO(razvanm): construct a proper Permissions object based on the
-	// C.v23_syncbase_Permissions.
+	permissions := C.GetObjectField(env, obj, syncgroupSpecClass.permissions)
+	if C.ExceptionOccurred(env) != nil {
+		panic("newVSyngroupSpecFromJava exception while retrieving SyncgroupSpec.permissions")
+	}
 
 	collections := C.GetObjectField(env, obj, syncgroupSpecClass.collections)
 	if C.ExceptionOccurred(env) != nil {
 		panic("newVSyngroupSpecFromJava exception while retrieving SyncgroupSpec.collections")
 	}
-	collectionsIds := newVIdsFromJava(env, collections)
 
 	mountTables := C.GetObjectField(env, obj, syncgroupSpecClass.mountTables)
 	if C.ExceptionOccurred(env) != nil {
 		panic("newVSyngroupSpecFromJava exception while retrieving SyncgroupSpec.mountTables")
 	}
-	mountTablesStrings := newVStringsFromJava(env, mountTables)
 
 	return C.v23_syncbase_SyncgroupSpec{
 		description:         newVStringFromJava(env, description),
 		publishSyncbaseName: newVStringFromJava(env, publishSyncbaseName),
-		collections:         collectionsIds,
-		mountTables:         mountTablesStrings,
+		perms:               newVPermissionsFromJava(env, permissions),
+		collections:         newVIdsFromJava(env, collections),
+		mountTables:         newVStringsFromJava(env, mountTables),
 	}
 }
 
@@ -231,6 +241,9 @@
 // newVPermissionsFromJava creates a v23_syncbase_Permissions from a Permissions
 // object.
 func newVPermissionsFromJava(env *C.JNIEnv, obj C.jobject) C.v23_syncbase_Permissions {
+	if obj == nil {
+		return C.v23_syncbase_Permissions{}
+	}
 	return C.v23_syncbase_Permissions{
 		json: newVBytesFromJava(env, C.jbyteArray(C.GetObjectField(env, obj, permissionsClass.json))),
 	}