TBR implement Java discharge caching support (JNI changes)
Change-Id: If2384c0b1e05b7c5374aaae00571513e8e30da60
diff --git a/util/sign.go b/util/sign.go
index 9020c0c..c20d070 100644
--- a/util/sign.go
+++ b/util/sign.go
@@ -33,6 +33,8 @@
)
var (
+ // CollectionSign denotes a signature of a Java Collection type.
+ CollectionSign = ClassSign("java.util.Collection")
// StringSign denotes a signature of a Java String type.
StringSign = ClassSign("java.lang.String")
// ObjectSign denotes a signature of a Java Object type.
diff --git a/util/util.go b/util/util.go
index 5c6052d..717116e 100644
--- a/util/util.go
+++ b/util/util.go
@@ -45,6 +45,8 @@
jDateTimeClass C.jclass
// Global reference for org.joda.time.Duration class.
jDurationClass C.jclass
+ // Global reference for java.util.Arrays class
+ jArraysClass C.jclass
// Global reference for java.util.ArrayList class.
jArrayListClass C.jclass
// Global reference for java.lang.Throwable class.
@@ -117,6 +119,11 @@
return err
}
jDurationClass = C.jclass(class)
+ class, err = JFindClass(env, "java/util/Arrays")
+ if err != nil {
+ return err
+ }
+ jArraysClass = C.jclass(class)
class, err = JFindClass(env, "java/util/ArrayList")
if err != nil {
return err
@@ -507,6 +514,26 @@
return unsafe.Pointer(ret)
}
+// JObjectArrayList converts the provided slice of C.jobject pointers into a
+// Java ArrayList of the provided element type. The implementation is based on
+// http://stackoverflow.com/questions/157944.
+// NOTE: Because CGO creates package-local types and because this method may be
+// invoked from a different package, Java types are passed in an empty interface
+// and then cast into their package local types.
+func JObjectArrayList(jEnv interface{}, arr []interface{}, jElemClass interface{}) (unsafe.Pointer, error) {
+ jArr := JObjectArray(jEnv, arr, jElemClass)
+ env := getEnv(jEnv)
+ jArrAsList, err := CallStaticObjectMethod(env, jArraysClass, "asList", []Sign{ArraySign(ObjectSign)}, ListSign, jArr)
+ if err != nil {
+ return nil, err
+ }
+ jArrayList, err := NewObject(env, jArrayListClass, []Sign{CollectionSign}, C.jobject(jArrAsList))
+ if err != nil {
+ return nil, err
+ }
+ return jArrayList, nil
+}
+
// GoObjectArray converts a Java Object array to a Go slice of C.jobject
// pointers.
// NOTE: Because CGO creates package-local types and because this method may be
diff --git a/v23/security/jni.go b/v23/security/jni.go
index 4bae71e..5dce22b 100644
--- a/v23/security/jni.go
+++ b/v23/security/jni.go
@@ -19,19 +19,21 @@
import "C"
var (
- principalSign = jutil.ClassSign("io.v.v23.security.VPrincipal")
- blessingsSign = jutil.ClassSign("io.v.v23.security.Blessings")
- wireBlessingsSign = jutil.ClassSign("io.v.v23.security.WireBlessings")
- wireDischargeSign = jutil.ClassSign("io.v.v23.security.WireDischarge")
- blessingStoreSign = jutil.ClassSign("io.v.v23.security.BlessingStore")
- blessingRootsSign = jutil.ClassSign("io.v.v23.security.BlessingRoots")
- blessingPatternSign = jutil.ClassSign("io.v.v23.security.BlessingPattern")
- signerSign = jutil.ClassSign("io.v.v23.security.VSigner")
- caveatSign = jutil.ClassSign("io.v.v23.security.Caveat")
- contextSign = jutil.ClassSign("io.v.v23.context.VContext")
- callSign = jutil.ClassSign("io.v.v23.security.Call")
- signatureSign = jutil.ClassSign("io.v.v23.security.VSignature")
- publicKeySign = jutil.ClassSign("java.security.interfaces.ECPublicKey")
+ dischargeSign = jutil.ClassSign("io.v.v23.security.Discharge")
+ dischargeImpetusSign = jutil.ClassSign("io.v.v23.security.DischargeImpetus")
+ principalSign = jutil.ClassSign("io.v.v23.security.VPrincipal")
+ blessingsSign = jutil.ClassSign("io.v.v23.security.Blessings")
+ wireBlessingsSign = jutil.ClassSign("io.v.v23.security.WireBlessings")
+ wireDischargeSign = jutil.ClassSign("io.v.v23.security.WireDischarge")
+ blessingStoreSign = jutil.ClassSign("io.v.v23.security.BlessingStore")
+ blessingRootsSign = jutil.ClassSign("io.v.v23.security.BlessingRoots")
+ blessingPatternSign = jutil.ClassSign("io.v.v23.security.BlessingPattern")
+ signerSign = jutil.ClassSign("io.v.v23.security.VSigner")
+ caveatSign = jutil.ClassSign("io.v.v23.security.Caveat")
+ contextSign = jutil.ClassSign("io.v.v23.context.VContext")
+ callSign = jutil.ClassSign("io.v.v23.security.Call")
+ signatureSign = jutil.ClassSign("io.v.v23.security.VSignature")
+ publicKeySign = jutil.ClassSign("java.security.interfaces.ECPublicKey")
// Global reference for io.v.v23.security.Blessings class.
jBlessingsClass C.jclass
@@ -59,6 +61,8 @@
jVSecurityClass C.jclass
// Global reference for io.v.v23.security.Discharge class.
jDischargeClass C.jclass
+ // Global reference for io.v.v23.security.DischargeImpetus class.
+ jDischargeImpetusClass C.jclass
)
// Init initializes the JNI code with the given Java evironment. This method
@@ -137,6 +141,11 @@
return err
}
jDischargeClass = C.jclass(class)
+ class, err = jutil.JFindClass(jEnv, "io/v/v23/security/DischargeImpetus")
+ if err != nil {
+ return err
+ }
+ jDischargeImpetusClass = C.jclass(class)
return nil
}
@@ -747,6 +756,66 @@
return C.jobject(jBlessingsMap)
}
+//export Java_io_v_v23_security_BlessingStoreImpl_nativeCacheDischarge
+func Java_io_v_v23_security_BlessingStoreImpl_nativeCacheDischarge(env *C.JNIEnv, jBlessingStoreImpl C.jobject, goPtr C.jlong, jDischarge C.jobject, jCaveat C.jobject, jImpetus C.jobject) {
+ blessingStore := *(*security.BlessingStore)(jutil.Ptr(goPtr))
+ discharge, err := GoDischarge(env, jDischarge)
+ if err != nil {
+ jutil.JThrowV(env, err)
+ return
+ }
+ caveat, err := GoCaveat(env, jCaveat)
+ if err != nil {
+ jutil.JThrowV(env, err)
+ return
+ }
+ var impetus security.DischargeImpetus
+ err = jutil.GoVomCopy(env, jImpetus, jDischargeImpetusClass, &impetus)
+ if err != nil {
+ jutil.JThrowV(env, err)
+ return
+ }
+ blessingStore.CacheDischarge(discharge, caveat, impetus)
+}
+
+//export Java_io_v_v23_security_BlessingStoreImpl_nativeClearDischarges
+func Java_io_v_v23_security_BlessingStoreImpl_nativeClearDischarges(env *C.JNIEnv, jBlessingStoreImpl C.jobject, goPtr C.jlong, jDischarges C.jobject) {
+ blessingStore := *(*security.BlessingStore)(jutil.Ptr(goPtr))
+ var discharges []security.Discharge
+ for _, jDischarge := range jutil.GoObjectArray(env, jDischarges) {
+ discharge, err := GoDischarge(env, jDischarge)
+ if err != nil {
+ jutil.JThrowV(env, err)
+ return
+ }
+ discharges = append(discharges, discharge)
+ }
+ blessingStore.ClearDischarges(discharges...)
+}
+
+//export Java_io_v_v23_security_BlessingStoreImpl_nativeDischarge
+func Java_io_v_v23_security_BlessingStoreImpl_nativeDischarge(env *C.JNIEnv, jBlessingStoreImpl C.jobject, goPtr C.jlong, jCaveat C.jobject, jImpetus C.jobject) C.jobject {
+ blessingStore := *(*security.BlessingStore)(jutil.Ptr(goPtr))
+ caveat, err := GoCaveat(env, jCaveat)
+ if err != nil {
+ jutil.JThrowV(env, err)
+ return nil
+ }
+ var impetus security.DischargeImpetus
+ err = jutil.GoVomCopy(env, jImpetus, jDischargeImpetusClass, &impetus)
+ if err != nil {
+ jutil.JThrowV(env, err)
+ return nil
+ }
+ discharge := blessingStore.Discharge(caveat, impetus)
+ jDischarge, err := JavaDischarge(env, discharge)
+ if err != nil {
+ jutil.JThrowV(env, err)
+ return nil
+ }
+ return jDischarge
+}
+
//export Java_io_v_v23_security_BlessingStoreImpl_nativeDebugString
func Java_io_v_v23_security_BlessingStoreImpl_nativeDebugString(env *C.JNIEnv, jBlessingStoreImpl C.jobject, goPtr C.jlong) C.jstring {
debug := (*(*security.BlessingStore)(jutil.Ptr(goPtr))).DebugString()
diff --git a/v23/security/store.go b/v23/security/store.go
index b93c324..d2c2693 100644
--- a/v23/security/store.go
+++ b/v23/security/store.go
@@ -168,15 +168,76 @@
}
func (s *blessingStore) CacheDischarge(discharge security.Discharge, caveat security.Caveat, impetus security.DischargeImpetus) {
- panic("BlessingStore.CacheDischarge() unimplemented in Java")
+ env, freeFunc := jutil.GetEnv()
+ defer freeFunc()
+ jDischarge, err := JavaDischarge(env, discharge)
+ if err != nil {
+ log.Printf("Couldn't get Java discharge: %v", err)
+ return
+ }
+ jCaveat, err := JavaCaveat(env, caveat)
+ if err != nil {
+ log.Printf("Couldn't get Java caveat: %v", err)
+ return
+ }
+ jImpetus, err := jutil.JVomCopy(env, impetus, jDischargeImpetusClass)
+ if err != nil {
+ log.Printf("Couldn't get Java DischargeImpetus: %v", err)
+ return
+ }
+ err = jutil.CallVoidMethod(env, s.jBlessingStore, "cacheDischarge", []jutil.Sign{dischargeSign, caveatSign, dischargeImpetusSign}, jDischarge, jCaveat, jImpetus)
+ if err != nil {
+ log.Printf("Couldn't call cacheDischarge: %v", err)
+ }
}
func (s *blessingStore) ClearDischarges(discharges ...security.Discharge) {
- panic("BlessingStore.ClearDischarges() unimplemented in Java")
+ env, freeFunc := jutil.GetEnv()
+ defer freeFunc()
+ jDischarges := make([]interface{}, len(discharges))
+ for i := 0; i < len(discharges); i++ {
+ jDischarge, err := JavaDischarge(env, discharges[i])
+ if err != nil {
+ log.Printf("Couldn't get Java discharge: %v", err)
+ return
+ }
+ jDischarges[i] = jDischarge
+ }
+ jDischargeList, err := jutil.JObjectArrayList(env, jDischarges, jDischargeClass)
+ if err != nil {
+ log.Printf("Couldn't get Java discharge list: %v", err)
+ return
+ }
+ err = jutil.CallVoidMethod(env, s.jBlessingStore, "clearDischarges", []jutil.Sign{jutil.ListSign}, jDischargeList)
+ if err != nil {
+ log.Printf("Couldn't call Java clearDischarges method: %v", err)
+ }
}
func (s *blessingStore) Discharge(caveat security.Caveat, impetus security.DischargeImpetus) security.Discharge {
- panic("BlessingStore.Discharge() unimplemented in Java")
+ env, freeFunc := jutil.GetEnv()
+ defer freeFunc()
+ jCaveat, err := JavaCaveat(env, caveat)
+ if err != nil {
+ log.Printf("Couldn't get Java caveat: %v", err)
+ return security.Discharge{}
+ }
+ jImpetus, err := jutil.JVomCopy(env, impetus, jDischargeImpetusClass)
+ if err != nil {
+ log.Printf("Couldn't get Java DischargeImpetus: %v", err)
+ return security.Discharge{}
+ }
+ jDischarge, err := jutil.CallObjectMethod(env, s.jBlessingStore, "discharge", []jutil.Sign{caveatSign, dischargeImpetusSign}, dischargeSign, jCaveat, jImpetus)
+ if err != nil {
+ log.Printf("Couldn't call Java discharge method: %v", err)
+ return security.Discharge{}
+ }
+ discharge, err := GoDischarge(env, jDischarge)
+ if err != nil {
+ log.Printf("Couldn't convert Java discharge to Go: %v", err)
+ return security.Discharge{}
+ }
+ return discharge
}
func (r *blessingStore) DebugString() string {