You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2010/08/31 16:56:27 UTC

svn commit: r991211 - in /subversion/trunk/subversion/bindings/javahl: native/ src/org/apache/subversion/javahl/

Author: hwright
Date: Tue Aug 31 14:56:27 2010
New Revision: 991211

URL: http://svn.apache.org/viewvc?rev=991211&view=rev
Log:
JavaHL: Move more complexity out of C++ and into Java-land.  (See r990952)

* subversion/bindings/javahl/native/ConflictResolverCallback.cpp:
  Remove.

* subversion/bindings/javahl/native/ConflictResolverCallback.h:
  Remove.

* subversion/bindings/javahl/native/SVNClient.h:
  Remove obsolete forward class declaration.

* subversion/bindings/javahl/native/SVNClient.cpp:
  Remove obsolete header inclusion.

* subversion/bindings/javahl/native/ClientContext.h
  (m_conflictResolver): Remove.
  (setConflictResolver): Remove.
  (resolve, javaResultToC): New.

* subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp
  (Java_org_apache_subversion_javahl_SVNClient_setConflictResolver): Remove.

* subversion/bindings/javahl/native/ClientContext.cpp
  (ClientContext): Don't initialize the member object, but do initialize the
    persistent conflict baton and function.
  (~ClientContext): Don't delete the conflict resolver.
  (getContext): Don't set the conflict function or baton.
  (setConflictResolver): Remove.
  (resolve): New.
  (javaResultToC): New.

* subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java
  (setConflictResolver): Add a Java implementation.
  (ClientContext.resolver): New.
  (ClientContext.resolve): New.

Removed:
    subversion/trunk/subversion/bindings/javahl/native/ConflictResolverCallback.cpp
    subversion/trunk/subversion/bindings/javahl/native/ConflictResolverCallback.h
Modified:
    subversion/trunk/subversion/bindings/javahl/native/ClientContext.cpp
    subversion/trunk/subversion/bindings/javahl/native/ClientContext.h
    subversion/trunk/subversion/bindings/javahl/native/SVNClient.cpp
    subversion/trunk/subversion/bindings/javahl/native/SVNClient.h
    subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp
    subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java

Modified: subversion/trunk/subversion/bindings/javahl/native/ClientContext.cpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/ClientContext.cpp?rev=991211&r1=991210&r2=991211&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/ClientContext.cpp (original)
+++ subversion/trunk/subversion/bindings/javahl/native/ClientContext.cpp Tue Aug 31 14:56:27 2010
@@ -33,8 +33,8 @@
 
 #include "Prompter.h"
 #include "CreateJ.h"
+#include "EnumMapper.h"
 #include "CommitMessage.h"
-#include "ConflictResolverCallback.h"
 
 
 struct log_msg_baton
@@ -45,8 +45,7 @@ struct log_msg_baton
 
 ClientContext::ClientContext(jobject jsvnclient)
     : m_prompter(NULL),
-      m_commitMessage(NULL),
-      m_conflictResolver(NULL)
+      m_commitMessage(NULL)
 {
     JNIEnv *env = JNIUtil::getEnv();
     JNICriticalSection criticalSection(*JNIUtil::getGlobalPoolMutex());
@@ -93,13 +92,14 @@ ClientContext::ClientContext(jobject jsv
     persistentCtx->notify_baton2 = m_jctx;
     persistentCtx->progress_func = progress;
     persistentCtx->progress_baton = m_jctx;
+    persistentCtx->conflict_func = resolve;
+    persistentCtx->conflict_baton = m_jctx;
 }
 
 ClientContext::~ClientContext()
 {
     delete m_prompter;
     delete m_commitMessage;
-    delete m_conflictResolver;
 
     JNIEnv *env = JNIUtil::getEnv();
     env->DeleteGlobalRef(m_jctx);
@@ -214,12 +214,6 @@ ClientContext::getContext(const char *me
     ctx->log_msg_baton3 = getCommitMessageBaton(message);
     m_cancelOperation = false;
 
-    if (m_conflictResolver)
-    {
-        ctx->conflict_func = ConflictResolverCallback::resolveConflict;
-        ctx->conflict_baton = m_conflictResolver;
-    }
-
     return ctx;
 }
 
@@ -289,13 +283,6 @@ ClientContext::setPrompt(Prompter *promp
 }
 
 void
-ClientContext::setConflictResolver(ConflictResolverCallback *conflictResolver)
-{
-    delete m_conflictResolver;
-    m_conflictResolver = conflictResolver;
-}
-
-void
 ClientContext::setConfigDirectory(const char *configDir)
 {
     // A change to the config directory may necessitate creation of
@@ -417,3 +404,118 @@ ClientContext::progress(apr_off_t progre
   
   POP_AND_RETURN_NOTHING();
 }
+
+svn_error_t *
+ClientContext::resolve(svn_wc_conflict_result_t **result,
+                       const svn_wc_conflict_description_t *desc,
+                       void *baton,
+                       apr_pool_t *pool)
+{
+  jobject jctx = (jobject) baton;
+  JNIEnv *env = JNIUtil::getEnv();
+
+  // Create a local frame for our references
+  env->PushLocalFrame(LOCAL_FRAME_SIZE);
+  if (JNIUtil::isJavaExceptionThrown())
+    return SVN_NO_ERROR;
+
+  static jmethodID mid = 0;
+  if (mid == 0)
+    {
+      jclass clazz = env->GetObjectClass(jctx);
+      if (JNIUtil::isJavaExceptionThrown())
+        POP_AND_RETURN(SVN_NO_ERROR);
+
+      mid = env->GetMethodID(clazz, "resolve",
+                             "(L"JAVA_PACKAGE"/ConflictDescriptor;)"
+                             "L"JAVA_PACKAGE"/ConflictResult;");
+      if (JNIUtil::isJavaExceptionThrown() || mid == 0)
+        POP_AND_RETURN(SVN_NO_ERROR);
+    }
+
+  // Create an instance of the conflict descriptor.
+  jobject jdesc = CreateJ::ConflictDescriptor(desc);
+  if (JNIUtil::isJavaExceptionThrown())
+    POP_AND_RETURN(SVN_NO_ERROR);
+
+  // Invoke the Java conflict resolver callback method using the descriptor.
+  jobject jresult = env->CallObjectMethod(jctx, mid, jdesc);
+  if (JNIUtil::isJavaExceptionThrown())
+    {
+      // If an exception is thrown by our conflict resolver, remove it
+      // from the JNI env, and convert it into a Subversion error.
+      const char *msg = JNIUtil::thrownExceptionToCString();
+      svn_error_t *err = svn_error_create(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE,
+                                          NULL, msg);
+      env->PopLocalFrame(NULL);
+      return err;
+    }
+
+  *result = javaResultToC(jresult, pool);
+  if (*result == NULL)
+    {
+      // Unable to convert the result into a C representation.
+      env->PopLocalFrame(NULL);
+      return svn_error_create(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL, NULL);
+    }
+
+  env->PopLocalFrame(NULL);
+  return SVN_NO_ERROR;
+}
+
+svn_wc_conflict_result_t *
+ClientContext::javaResultToC(jobject jresult, apr_pool_t *pool)
+{
+  JNIEnv *env = JNIUtil::getEnv();
+
+  // Create a local frame for our references
+  env->PushLocalFrame(LOCAL_FRAME_SIZE);
+  if (JNIUtil::isJavaExceptionThrown())
+    return SVN_NO_ERROR;
+
+  static jmethodID getChoice = 0;
+  static jmethodID getMergedPath = 0;
+
+  jclass clazz = NULL;
+  if (getChoice == 0 || getMergedPath == 0)
+    {
+      clazz = env->FindClass(JAVA_PACKAGE "/ConflictResult");
+      if (JNIUtil::isJavaExceptionThrown())
+        POP_AND_RETURN_NULL;
+    }
+
+  if (getChoice == 0)
+    {
+      getChoice = env->GetMethodID(clazz, "getChoice",
+                                   "()L"JAVA_PACKAGE"/ConflictResult$Choice;");
+      if (JNIUtil::isJavaExceptionThrown() || getChoice == 0)
+        POP_AND_RETURN_NULL;
+    }
+  if (getMergedPath == 0)
+    {
+      getMergedPath = env->GetMethodID(clazz, "getMergedPath",
+                                       "()Ljava/lang/String;");
+      if (JNIUtil::isJavaExceptionThrown() || getMergedPath == 0)
+        POP_AND_RETURN_NULL;
+    }
+
+  jobject jchoice = env->CallObjectMethod(jresult, getChoice);
+  if (JNIUtil::isJavaExceptionThrown())
+    POP_AND_RETURN_NULL;
+
+  jstring jmergedPath = (jstring) env->CallObjectMethod(jresult, getMergedPath);
+  if (JNIUtil::isJavaExceptionThrown())
+    POP_AND_RETURN_NULL;
+
+  JNIStringHolder mergedPath(jmergedPath);
+  if (JNIUtil::isJavaExceptionThrown())
+    POP_AND_RETURN_NULL;
+
+  svn_wc_conflict_result_t *result =
+         svn_wc_create_conflict_result(EnumMapper::toConflictChoice(jchoice),
+                                       mergedPath.pstrdup(pool),
+                                       pool);
+
+  env->PopLocalFrame(NULL);
+  return result;
+}

Modified: subversion/trunk/subversion/bindings/javahl/native/ClientContext.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/ClientContext.h?rev=991211&r1=991210&r2=991211&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/ClientContext.h (original)
+++ subversion/trunk/subversion/bindings/javahl/native/ClientContext.h Tue Aug 31 14:56:27 2010
@@ -37,7 +37,6 @@
 #include "JNIStringHolder.h"
 
 class Prompter;
-class ConflictResolverCallback;
 class CommitMessage;
 
 /**
@@ -55,7 +54,6 @@ class ClientContext
   std::string m_configDir;
 
   Prompter *m_prompter;
-  ConflictResolverCallback *m_conflictResolver;
   bool m_cancelOperation;
 
   CommitMessage *m_commitMessage;
@@ -84,7 +82,6 @@ class ClientContext
   void username(const char *pi_username);
   void password(const char *pi_password);
   void setPrompt(Prompter *prompter);
-  void setConflictResolver(ConflictResolverCallback *conflictResolver);
   void commitMessageHandler(CommitMessage *commitMessage);
   void cancelOperation();
   const char *getConfigDirectory();
@@ -100,6 +97,12 @@ class ClientContext
                      apr_pool_t *pool);
   static void progress(apr_off_t progressVal, apr_off_t total,
                        void *baton, apr_pool_t *pool);
+  static svn_error_t *resolve(svn_wc_conflict_result_t **result,
+                              const svn_wc_conflict_description_t *desc,
+                              void *baton,
+                              apr_pool_t *pool);
+  static svn_wc_conflict_result_t *javaResultToC(jobject result,
+                                                 apr_pool_t *pool);
 };
 
 #endif // CLIENTCONTEXT_H

Modified: subversion/trunk/subversion/bindings/javahl/native/SVNClient.cpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/SVNClient.cpp?rev=991211&r1=991210&r2=991211&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/SVNClient.cpp (original)
+++ subversion/trunk/subversion/bindings/javahl/native/SVNClient.cpp Tue Aug 31 14:56:27 2010
@@ -28,7 +28,6 @@
 #include "JNIUtil.h"
 #include "CopySources.h"
 #include "DiffSummaryReceiver.h"
-#include "ConflictResolverCallback.h"
 #include "ClientContext.h"
 #include "Prompter.h"
 #include "Pool.h"

Modified: subversion/trunk/subversion/bindings/javahl/native/SVNClient.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/SVNClient.h?rev=991211&r1=991210&r2=991211&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/SVNClient.h (original)
+++ subversion/trunk/subversion/bindings/javahl/native/SVNClient.h Tue Aug 31 14:56:27 2010
@@ -35,7 +35,6 @@
 
 class Revision;
 class RevisionRange;
-class ConflictResolverCallback;
 class Targets;
 class JNIByteArray;
 class Prompter;

Modified: subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp?rev=991211&r1=991210&r2=991211&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp (original)
+++ subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp Tue Aug 31 14:56:27 2010
@@ -33,7 +33,6 @@
 #include "Revision.h"
 #include "RevisionRange.h"
 #include "EnumMapper.h"
-#include "ConflictResolverCallback.h"
 #include "CommitMessage.h"
 #include "Prompter.h"
 #include "Targets.h"
@@ -344,25 +343,6 @@ Java_org_apache_subversion_javahl_SVNCli
 }
 
 JNIEXPORT void JNICALL
-Java_org_apache_subversion_javahl_SVNClient_setConflictResolver
-(JNIEnv *env, jobject jthis, jobject jconflictResolver)
-{
-  JNIEntry(SVNClient, setConflictResolver);
-  SVNClient *cl = SVNClient::getCppObject(jthis);
-  if (cl == NULL)
-    {
-      JNIUtil::throwError(_("bad C++ this"));
-      return;
-    }
-  ConflictResolverCallback *listener =
-    ConflictResolverCallback::makeCConflictResolverCallback(jconflictResolver);
-  if (JNIUtil::isExceptionThrown())
-    return;
-
-  cl->getClientContext().setConflictResolver(listener);
-}
-
-JNIEXPORT void JNICALL
 Java_org_apache_subversion_javahl_SVNClient_commitMessageHandler
 (JNIEnv *env, jobject jthis, jobject jcommitMessage)
 {

Modified: subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java?rev=991211&r1=991210&r2=991211&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java (original)
+++ subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java Tue Aug 31 14:56:27 2010
@@ -184,7 +184,10 @@ public class SVNClient implements ISVNCl
     /**
      * @since 1.5
      */
-    public native void setConflictResolver(ConflictResolverCallback listener);
+    public void setConflictResolver(ConflictResolverCallback listener)
+    {
+        clientContext.resolver = listener;
+    }
 
     /**
      * @since 1.5
@@ -650,10 +653,12 @@ public class SVNClient implements ISVNCl
      * persist in this object, such as notification handlers.
      */
     private class ClientContext
-        implements ClientNotifyCallback, ProgressCallback
+        implements ClientNotifyCallback, ProgressCallback,
+            ConflictResolverCallback
     {
         public ClientNotifyCallback notify = null;
         public ProgressCallback listener = null;
+        public ConflictResolverCallback resolver = null;
 
         public void onNotify(ClientNotifyInformation notifyInfo)
         {
@@ -666,5 +671,15 @@ public class SVNClient implements ISVNCl
             if (listener != null)
                 listener.onProgress(event);
         }
+
+        public ConflictResult resolve(ConflictDescriptor conflict)
+            throws SubversionException
+        {
+            if (resolver != null)
+                return resolver.resolve(conflict);
+            else
+                return new ConflictResult(ConflictResult.Choice.postpone,
+                                          null);
+        }
     }
 }