You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2014/01/31 08:50:04 UTC

svn commit: r1563078 - in /subversion/trunk/subversion/bindings/javahl: native/JNIUtil.h native/OperationContext.cpp native/OperationContext.h src/org/apache/subversion/javahl/callback/TunnelAgent.java tests/org/apache/subversion/javahl/BasicTests.java

Author: brane
Date: Fri Jan 31 07:50:03 2014
New Revision: 1563078

URL: http://svn.apache.org/r1563078
Log:
Update JavaHL's tunnel callback API to match changes in the RA API.

[in subversion/bindings/javahl]
* src/org/apache/subversion/javahl/callback/TunnelAgent.java
  (TunnelAgent.CloseTunnelCallback): New nested interface.
  (TunnelAgent.openTunnel): Return an optional close-tunnel object.
  (TunnelAgent.closeTunnel): Removed, obsolete.

* native/JNIUtil.h (SVN_JNI_CATCH_VOID): New macro.
* native/OperationContext.h (inner_closeTunnel): Remove.
* native/OperationContext.cpp (OperationContext::TunnelContext):
   Revert r1562425; remove the tunnel_name, user, host and port members.
   Add jclosecb member, a reference to the close-tunnel interface.
  (OperationContext::openTunnel): Update TunnelContext construction,
   the call to the Java openTunnel implementation, and populate the
   TunnelContext::jclosecb.
  (OperationContext::closeTunnel):
   Merged into OperationContext::inner_closeTunnel.
   Update propagation to Java callback to the new API.

* tests/org/apache/subversion/javahl/BasicTests.java
  (BasicTests.Tunnel): Update to the new TunnelAgent API.

Modified:
    subversion/trunk/subversion/bindings/javahl/native/JNIUtil.h
    subversion/trunk/subversion/bindings/javahl/native/OperationContext.cpp
    subversion/trunk/subversion/bindings/javahl/native/OperationContext.h
    subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/TunnelAgent.java
    subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java

Modified: subversion/trunk/subversion/bindings/javahl/native/JNIUtil.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/JNIUtil.h?rev=1563078&r1=1563077&r2=1563078&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/JNIUtil.h (original)
+++ subversion/trunk/subversion/bindings/javahl/native/JNIUtil.h Fri Jan 31 07:50:03 2014
@@ -285,4 +285,13 @@ class JNIUtil
     SVN_ERR(JNIUtil::checkJavaException((errorcode)));  \
   } while(0)
 
+#define SVN_JNI_CATCH_VOID(statement)                   \
+  do {                                                  \
+    do { statement; } while(0);                         \
+    if (JNIUtil::getEnv()->ExceptionCheck()) {          \
+      JNIUtil::getEnv()->ExceptionClear();              \
+      return;                                           \
+    }                                                   \
+  } while(0)
+
 #endif  // JNIUTIL_H

Modified: subversion/trunk/subversion/bindings/javahl/native/OperationContext.cpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/OperationContext.cpp?rev=1563078&r1=1563077&r2=1563078&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/OperationContext.cpp (original)
+++ subversion/trunk/subversion/bindings/javahl/native/OperationContext.cpp Fri Jan 31 07:50:03 2014
@@ -485,13 +485,12 @@ namespace {
 class TunnelContext
 {
 public:
-  explicit TunnelContext(const char *t_name, const char *t_user,
-                         const char *t_hostname, int t_port,
-                         apr_pool_t *pool)
+  explicit TunnelContext(apr_pool_t *pool)
     : request_in(NULL),
       request_out(NULL),
       response_in(NULL),
-      response_out(NULL)
+      response_out(NULL),
+      jclosecb(NULL)
     {
 #if APR_VERSION_AT_LEAST(1, 3, 0)
       status = apr_file_pipe_create_ex(&request_in, &request_out,
@@ -508,10 +507,6 @@ public:
       if (!status)
         status = apr_file_pipe_create(&response_in, &response_out, pool);
 #endif
-      tunnel_name = apr_pstrdup(pool, t_name);
-      user = apr_pstrdup(pool, t_user);
-      hostname = apr_pstrdup(pool, t_hostname);
-      port = t_port;
     }
 
   ~TunnelContext()
@@ -525,11 +520,7 @@ public:
   apr_file_t *response_in;
   apr_file_t *response_out;
   apr_status_t status;
-
-  const char *tunnel_name;
-  const char *user;
-  const char *hostname;
-  int port;
+  jobject jclosecb;
 };
 
 jobject create_Channel(const char *class_name, JNIEnv *env, apr_file_t *fd)
@@ -591,8 +582,7 @@ OperationContext::openTunnel(svn_stream_
                              const char *hostname, int port,
                              apr_pool_t *pool)
 {
-  TunnelContext *tc = new TunnelContext(tunnel_name, user, hostname, port,
-                                        pool);
+  TunnelContext *tc = new TunnelContext(pool);
   if (tc->status)
     {
       delete tc;
@@ -628,74 +618,47 @@ OperationContext::openTunnel(svn_stream_
       jclass cls = env->FindClass(JAVA_PACKAGE"/callback/TunnelAgent");
       SVN_JNI_CATCH(, SVN_ERR_BASE);
       SVN_JNI_CATCH(
-          mid = env->GetMethodID(cls, "openTunnel",
-                                 "(Ljava/nio/channels/ReadableByteChannel;"
-                                 "Ljava/nio/channels/WritableByteChannel;"
-                                 "Ljava/lang/String;"
-                                 "Ljava/lang/String;"
-                                 "Ljava/lang/String;I)V"),
+          mid = env->GetMethodID(
+              cls, "openTunnel",
+              "(Ljava/nio/channels/ReadableByteChannel;"
+              "Ljava/nio/channels/WritableByteChannel;"
+              "Ljava/lang/String;"
+              "Ljava/lang/String;"
+              "Ljava/lang/String;I)"
+              "L"JAVA_PACKAGE"/callback/TunnelAgent$CloseTunnelCallback;"),
           SVN_ERR_BASE);
     }
 
   jobject jtunnelcb = jobject(tunnel_baton);
   SVN_JNI_CATCH(
-      env->CallVoidMethod(jtunnelcb, mid, jrequest, jresponse,
-                          jtunnel_name, juser, jhostname, jint(port)),
+      tc->jclosecb = env->CallObjectMethod(
+          jtunnelcb, mid, jrequest, jresponse,
+          jtunnel_name, juser, jhostname, jint(port)),
       SVN_ERR_BASE);
 
   return SVN_NO_ERROR;
 }
 
-svn_error_t *
-OperationContext::inner_closeTunnel(void *tunnel_context, void *tunnel_baton)
+void
+OperationContext::closeTunnel(void *tunnel_context, void *)
 {
   TunnelContext* tc = static_cast<TunnelContext*>(tunnel_context);
-
-  /* ### These are allocated in the pool, so it is safe to cache them here */
-  const char *tunnel_name = tc->tunnel_name;
-  const char *user = tc->user;
-  const char *hostname = tc->hostname;
-  int port = tc->port;
-
+  jobject jclosecb = tc->jclosecb;
   delete tc;
 
-  jstring jtunnel_name = JNIUtil::makeJString(tunnel_name);
-  SVN_JNI_CATCH(, SVN_ERR_BASE);
-
-  jstring juser = JNIUtil::makeJString(user);
-  SVN_JNI_CATCH(, SVN_ERR_BASE);
-
-  jstring jhostname = JNIUtil::makeJString(hostname);
-  SVN_JNI_CATCH(, SVN_ERR_BASE);
+  if (!jclosecb)
+    return;
 
   JNIEnv *env = JNIUtil::getEnv();
 
   static jmethodID mid = 0;
   if (0 == mid)
     {
-      jclass cls = env->FindClass(JAVA_PACKAGE"/callback/TunnelAgent");
-      SVN_JNI_CATCH(, SVN_ERR_BASE);
-      SVN_JNI_CATCH(
-          mid = env->GetMethodID(cls, "closeTunnel",
-                                 "(Ljava/lang/String;"
-                                 "Ljava/lang/String;"
-                                 "Ljava/lang/String;I)V"),
-          SVN_ERR_BASE);
+      jclass cls;
+      SVN_JNI_CATCH_VOID(
+          cls= env->FindClass(
+              JAVA_PACKAGE"/callback/TunnelAgent$CloseTunnelCallback"));
+      SVN_JNI_CATCH_VOID(mid = env->GetMethodID(cls, "closeTunnel", "()V"));
     }
-
-  jobject jtunnelcb = jobject(tunnel_baton);
-  SVN_JNI_CATCH(
-      env->CallVoidMethod(jtunnelcb, mid,
-                          jtunnel_name, juser, jhostname, jint(port)),
-      SVN_ERR_BASE);
-
-  return SVN_NO_ERROR;
-}
-
-void
-OperationContext::closeTunnel(void *tunnel_context, void *tunnel_baton)
-{
-  /* ### We now ignore all errors here. We used to ignore them in the
-         Subversion API */
-  svn_error_clear(inner_closeTunnel(tunnel_context, tunnel_baton));
+  SVN_JNI_CATCH_VOID(env->CallVoidMethod(jclosecb, mid));
 }

Modified: subversion/trunk/subversion/bindings/javahl/native/OperationContext.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/OperationContext.h?rev=1563078&r1=1563077&r2=1563078&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/OperationContext.h (original)
+++ subversion/trunk/subversion/bindings/javahl/native/OperationContext.h Fri Jan 31 07:50:03 2014
@@ -76,9 +76,6 @@ class OperationContext
       const char *hostname, int port,
       apr_pool_t *pool);
 
-  static svn_error_t *inner_closeTunnel(
-      void *tunnel_context, void *tunnel_baton);
-
   static void closeTunnel(
       void *tunnel_context, void *tunnel_baton);
 

Modified: subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/TunnelAgent.java
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/TunnelAgent.java?rev=1563078&r1=1563077&r2=1563078&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/TunnelAgent.java (original)
+++ subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/TunnelAgent.java Fri Jan 31 07:50:03 2014
@@ -50,6 +50,22 @@ public interface TunnelAgent
     boolean checkTunnel(String name);
 
     /**
+     * Callback interface returned from {@link #openTunnel()}.
+     */
+    public static interface CloseTunnelCallback
+    {
+        /**
+         * This callback method is called when a tunnel needs to be closed
+         * and the request and response streams detached from it.
+         * <p>
+         * <b>Note:</b> Errors on connection-close are not propagated
+         * to the implementation, therefore this method cannot throw
+         * any exceptions.
+         */
+        void closeTunnel();
+    }
+
+    /**
      * This callback method is called when a tunnel needs to be
      * created and the request and response streams attached to it.
      * @param request The request stream of the tunnel. The tunnel
@@ -63,21 +79,16 @@ public interface TunnelAgent
      * @param user the tunnel username
      * @param hostname the host part of the svn+tunnel:// URL
      * @param port the port part of the svn+tunnel:// URL
+     *
+     * @return an instance od {@link CloseTunnelCallback}, which will
+     *         be invoked when the connection is closed, or
+     *         <code>null</code>.
+     *
      * @throws any exception will abort the connection
      */
-    void openTunnel(ReadableByteChannel request, WritableByteChannel response,
-                    String name, String user, String hostname, int port)
-        throws Throwable;
-
-    /**
-     * This callback method is called when a tunnel needs to be closed
-     * and the request and response streams detached from it.
-     * @param name the name of the tunnel, as in
-     *                  <tt>svn+</tt><em>name</em><tt>://...</tt>
-     * @param user the tunnel username
-     * @param hostname the host part of the svn+tunnel:// URL
-     * @param port the port part of the svn+tunnel:// URL
-     */
-    void closeTunnel(String name, String user, String hostname, int port)
+    CloseTunnelCallback openTunnel(ReadableByteChannel request,
+                                   WritableByteChannel response,
+                                   String name, String user,
+                                   String hostname, int port)
         throws Throwable;
 }

Modified: subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java?rev=1563078&r1=1563077&r2=1563078&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java (original)
+++ subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java Fri Jan 31 07:50:03 2014
@@ -3933,30 +3933,37 @@ public class BasicTests extends SVNTests
         assertEquals(1, result.size());
     }
 
-    private class Tunnel extends Thread implements TunnelAgent
+    private class Tunnel extends Thread
+        implements TunnelAgent, TunnelAgent.CloseTunnelCallback
     {
         public boolean checkTunnel(String name)
         {
             return name.equals("test");
         }
 
-        public void openTunnel(ReadableByteChannel request,
-                               WritableByteChannel response,
-                               String name, String user,
-                               String hostname, int port)
+        public TunnelAgent.CloseTunnelCallback
+            openTunnel(ReadableByteChannel request,
+                       WritableByteChannel response,
+                       String name, String user,
+                       String hostname, int port)
         {
             this.request = request;
             this.response = response;
             start();
+            return this;
         }
 
-        public void closeTunnel(String name, String user,
-                                String hostname, int port)
-            throws Throwable
-        {
-            request.close();
-            join();
-            response.close();
+        public void closeTunnel()
+        {
+            Throwable t = null;
+            try {
+                request.close();
+                join();
+                response.close();
+            } catch (Throwable ex) {
+                t = ex;
+            }
+            assertEquals("No exception thrown", null, t);
         }
 
         private ReadableByteChannel request;