subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From br...@apache.org
Subject svn commit: r1497315 - in /subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl: ./ native/ src/org/apache/subversion/javahl/ src/org/apache/subversion/javahl/remote/ tests/org/apache/subversion/javahl/
Date Thu, 27 Jun 2013 11:53:50 GMT
Author: brane
Date: Thu Jun 27 11:53:49 2013
New Revision: 1497315

URL: http://svn.apache.org/r1497315
Log:
On the javahl-1.7-extensions branch: Sync JavaHL with trunk up to r1497181.
Note: the remote.CommitEditor is disabled due to its dependence on EV2.

Added:
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/Iterator.cpp
      - copied unchanged from r1497181, subversion/trunk/subversion/bindings/javahl/native/Iterator.cpp
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/Iterator.h
      - copied unchanged from r1497181, subversion/trunk/subversion/bindings/javahl/native/Iterator.h
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/LockTokenTable.cpp
      - copied, changed from r1497181, subversion/trunk/subversion/bindings/javahl/native/LockTokenTable.cpp
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/LockTokenTable.h
      - copied unchanged from r1497181, subversion/trunk/subversion/bindings/javahl/native/LockTokenTable.h
Modified:
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/   (props changed)
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/CommitCallback.cpp
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/CommitCallback.h
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/EnumMapper.cpp
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/EnumMapper.h
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/JNIUtil.cpp
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/JNIUtil.h
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/OperationContext.cpp
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/Path.cpp
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/Path.h
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RemoteSession.cpp
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RemoteSession.h
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RevpropTable.cpp
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RevpropTable.h
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/SVNClient.cpp
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_RemoteSession.cpp
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ClientException.java
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNEditor.java
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRemote.java
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/CommitEditor.java
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/RemoteSession.java
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java

Propchange: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/
------------------------------------------------------------------------------
  Merged /subversion/trunk/subversion/bindings/javahl:r1496335-1497181

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/CommitCallback.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/CommitCallback.cpp?rev=1497315&r1=1497314&r2=1497315&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/CommitCallback.cpp (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/CommitCallback.cpp Thu Jun 27 11:53:49 2013
@@ -37,9 +37,8 @@
  * @param jcallback the Java callback object.
  */
 CommitCallback::CommitCallback(jobject jcallback)
-{
-  m_callback = jcallback;
-}
+  : m_callback(jcallback)
+{}
 
 /**
  * Destroy a CommitCallback object
@@ -102,3 +101,14 @@ CommitCallback::commitInfo(const svn_com
   env->PopLocalFrame(NULL);
   return SVN_NO_ERROR;
 }
+
+
+PersistentCommitCallback::PersistentCommitCallback(jobject jcallback)
+  : CommitCallback(JNIUtil::getEnv()->NewGlobalRef(jcallback))
+{}
+
+PersistentCommitCallback::~PersistentCommitCallback()
+{
+  if (m_callback)
+    JNIUtil::getEnv()->DeleteGlobalRef(m_callback);
+}

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/CommitCallback.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/CommitCallback.h?rev=1497315&r1=1497314&r2=1497315&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/CommitCallback.h (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/CommitCallback.h Thu Jun 27 11:53:49 2013
@@ -47,11 +47,26 @@ class CommitCallback
   svn_error_t *commitInfo(const svn_commit_info_t *commit_info,
                           apr_pool_t *pool);
 
- private:
   /**
    * This a local reference to the Java object.
    */
   jobject m_callback;
 };
 
+/**
+ * Like CommitCallback, but maintains a reference to the Java object
+ * across JNI calls.
+ */
+class PersistentCommitCallback : protected CommitCallback
+{
+ public:
+  PersistentCommitCallback(jobject jcallback);
+  ~PersistentCommitCallback();
+  static svn_error_t *callback(const svn_commit_info_t *commit_info,
+                               void *baton, apr_pool_t *pool)
+    {
+      return CommitCallback::callback(commit_info, baton, pool);
+    }
+};
+
 #endif  // COMMITCALLBACK_H

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/EnumMapper.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/EnumMapper.cpp?rev=1497315&r1=1497314&r2=1497315&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/EnumMapper.cpp (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/EnumMapper.cpp Thu Jun 27 11:53:49 2013
@@ -179,6 +179,18 @@ int EnumMapper::toLogLevel(jobject jLogL
   return getOrdinal(JAVA_PACKAGE"/SVNClient$ClientLogLevel", jLogLevel);
 }
 
+svn_node_kind_t EnumMapper::toNodeKind(jobject jNodeKind)
+{
+  return svn_node_kind_t(
+      getOrdinal(JAVA_PACKAGE"/types/NodeKind", jNodeKind));
+}
+
+svn_checksum_kind_t EnumMapper::toChecksumKind(jobject jChecksumKind)
+{
+  return svn_checksum_kind_t(
+      getOrdinal(JAVA_PACKAGE"/types/Checksum$Kind", jChecksumKind));
+}
+
 svn_depth_t EnumMapper::toDepth(jobject jdepth)
 {
   // The offset for depths is -2

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/EnumMapper.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/EnumMapper.h?rev=1497315&r1=1497314&r2=1497315&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/EnumMapper.h (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/EnumMapper.h Thu Jun 27 11:53:49 2013
@@ -48,6 +48,8 @@ class EnumMapper
   static svn_wc_conflict_choice_t toConflictChoice(jobject jchoice);
   static int toMergeinfoLogKind(jobject jLogKind);
   static int toLogLevel(jobject jLogLevel);
+  static svn_node_kind_t toNodeKind(jobject jNodeKind);
+  static svn_checksum_kind_t toChecksumKind(jobject jChecksumKind);
 
   /* Converting from C enum's */
   static jint mapCommitMessageStateFlags(apr_byte_t flags);

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/JNIUtil.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/JNIUtil.cpp?rev=1497315&r1=1497314&r2=1497315&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/JNIUtil.cpp (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/JNIUtil.cpp Thu Jun 27 11:53:49 2013
@@ -37,9 +37,13 @@
 #include <apr_lib.h>
 
 #include "svn_pools.h"
+#include "svn_fs.h"
+#include "svn_ra.h"
+#include "svn_utf.h"
 #include "svn_wc.h"
 #include "svn_dso.h"
 #include "svn_path.h"
+#include "svn_cache_config.h"
 #include <apr_file_info.h>
 #include "svn_private_config.h"
 #ifdef WIN32
@@ -175,6 +179,19 @@ bool JNIUtil::JNIGlobalInit(JNIEnv *env)
       apr_allocator_max_free_set(allocator, 1);
     }
 
+  svn_utf_initialize(g_pool); /* Optimize character conversions */
+  svn_fs_initialize(g_pool); /* Avoid some theoretical issues */
+  svn_ra_initialize(g_pool);
+
+  /* We shouldn't fill the JVMs memory with FS cache data unless explictly
+     requested. */
+  {
+    svn_cache_config_t settings = *svn_cache_config_get();
+    settings.cache_size = 0;
+    settings.file_handle_count = 0;
+    settings.single_threaded = FALSE;
+    svn_cache_config_set(&settings);
+  }
 
 #ifdef ENABLE_NLS
 #ifdef WIN32
@@ -194,7 +211,7 @@ bool JNIUtil::JNIGlobalInit(JNIEnv *env)
     GetModuleFileNameW(moduleHandle, ucs2_path, inwords);
     inwords = lstrlenW(ucs2_path);
     outbytes = outlength = 3 * (inwords + 1);
-    utf8_path = (char *)apr_palloc(pool, outlength);
+    utf8_path = reinterpret_cast<char *>(apr_palloc(pool, outlength));
     apr_err = apr_conv_ucs2_to_utf8((const apr_wchar_t *) ucs2_path,
                                     &inwords, utf8_path, &outbytes);
     if (!apr_err && (inwords > 0 || outbytes == 0))
@@ -223,7 +240,7 @@ bool JNIUtil::JNIGlobalInit(JNIEnv *env)
   /* See http://svn.apache.org/repos/asf/subversion/trunk/notes/asp-dot-net-hack.txt */
   /* ### This code really only needs to be invoked by consumers of
      ### the libsvn_wc library, which basically means SVNClient. */
-  if (getenv ("SVN_ASP_DOT_NET_HACK"))
+  if (getenv("SVN_ASP_DOT_NET_HACK"))
     {
       err = svn_wc_set_adm_dir("_svn", g_pool);
       if (err)
@@ -240,6 +257,8 @@ bool JNIUtil::JNIGlobalInit(JNIEnv *env)
     }
 #endif
 
+  svn_error_set_malfunction_handler(svn_error_raise_on_malfunction);
+
   // Build all mutexes.
   g_finalizedObjectsMutex = new JNIMutex(g_pool);
   if (isExceptionThrown())
@@ -399,10 +418,66 @@ JNIUtil::putErrorsInTrace(svn_error_t *e
   env->DeleteLocalRef(jfileName);
 }
 
+namespace {
+jobject construct_Jmessage_stack(
+    const JNIUtil::error_message_stack_t& message_stack)
+{
+  JNIEnv *env = JNIUtil::getEnv();
+  env->PushLocalFrame(LOCAL_FRAME_SIZE);
+  if (JNIUtil::isJavaExceptionThrown())
+    return NULL;
+
+  jclass list_clazz = env->FindClass("java/util/ArrayList");
+  if (JNIUtil::isJavaExceptionThrown())
+    POP_AND_RETURN_NULL;
+  jmethodID mid = env->GetMethodID(list_clazz, "<init>", "(I)V");
+  if (JNIUtil::isJavaExceptionThrown())
+    POP_AND_RETURN_NULL;
+  jmethodID add_mid = env->GetMethodID(list_clazz, "add",
+                                       "(Ljava/lang/Object;)Z");
+  if (JNIUtil::isJavaExceptionThrown())
+    POP_AND_RETURN_NULL;
+  jobject jlist = env->NewObject(list_clazz, mid, jint(message_stack.size()));
+  if (JNIUtil::isJavaExceptionThrown())
+    POP_AND_RETURN_NULL;
+
+  jclass clazz = env->FindClass(JAVA_PACKAGE"/ClientException$ErrorMessage");
+  if (JNIUtil::isJavaExceptionThrown())
+    POP_AND_RETURN_NULL;
+  mid = env->GetMethodID(clazz, "<init>",
+                         "(ILjava/lang/String;Z)V");
+  if (JNIUtil::isJavaExceptionThrown())
+    POP_AND_RETURN_NULL;
+
+  for (JNIUtil::error_message_stack_t::const_iterator
+         it = message_stack.begin();
+       it != message_stack.end(); ++it)
+    {
+      jobject jmessage = JNIUtil::makeJString(it->m_message.c_str());
+      if (JNIUtil::isJavaExceptionThrown())
+        POP_AND_RETURN_NULL;
+      jobject jitem = env->NewObject(clazz, mid,
+                                     jint(it->m_code), jmessage,
+                                     jboolean(it->m_generic));
+      if (JNIUtil::isJavaExceptionThrown())
+        POP_AND_RETURN_NULL;
+      env->CallBooleanMethod(jlist, add_mid, jitem);
+      if (JNIUtil::isJavaExceptionThrown())
+        POP_AND_RETURN_NULL;
+
+      env->DeleteLocalRef(jmessage);
+      env->DeleteLocalRef(jitem);
+    }
+  return env->PopLocalFrame(jlist);
+}
+} // anonymous namespace
+
 void JNIUtil::handleSVNError(svn_error_t *err)
 {
   std::string msg;
-  assembleErrorMessage(svn_error_purge_tracing(err), 0, APR_SUCCESS, msg);
+  error_message_stack_t message_stack;
+  assembleErrorMessage(svn_error_purge_tracing(err),
+                       0, APR_SUCCESS, msg, &message_stack);
   const char *source = NULL;
 #ifdef SVN_DEBUG
 #ifndef SVN_ERR__TRACING
@@ -453,12 +528,18 @@ void JNIUtil::handleSVNError(svn_error_t
   if (isJavaExceptionThrown())
     POP_AND_RETURN_NOTHING();
 
+  jobject jmessageStack = construct_Jmessage_stack(message_stack);
+  if (isJavaExceptionThrown())
+    POP_AND_RETURN_NOTHING();
+
   jmethodID mid = env->GetMethodID(clazz, "<init>",
-                                   "(Ljava/lang/String;Ljava/lang/String;I)V");
+                                   "(Ljava/lang/String;"
+                                   "Ljava/lang/String;I"
+                                   "Ljava/util/List;)V");
   if (isJavaExceptionThrown())
     POP_AND_RETURN_NOTHING();
   jobject nativeException = env->NewObject(clazz, mid, jmessage, jsource,
-                                           static_cast<jint>(err->apr_err));
+                                           jint(err->apr_err), jmessageStack);
   if (isJavaExceptionThrown())
     POP_AND_RETURN_NOTHING();
 
@@ -493,8 +574,14 @@ void JNIUtil::handleSVNError(svn_error_t
   if (isJavaExceptionThrown())
     POP_AND_RETURN_NOTHING();
 
-  jobjectArray jStackTrace = env->NewObjectArray(newStackTrace.size(), stClazz,
-                                                 NULL);
+  const jsize stSize = static_cast<jsize>(newStackTrace.size());
+  if (stSize != newStackTrace.size())
+    {
+      env->ThrowNew(env->FindClass("java.lang.ArithmeticException"),
+                    "Overflow converting C size_t to JNI jsize");
+      POP_AND_RETURN_NOTHING();
+    }
+  jobjectArray jStackTrace = env->NewObjectArray(stSize, stClazz, NULL);
   if (isJavaExceptionThrown())
     POP_AND_RETURN_NOTHING();
 
@@ -771,12 +858,37 @@ jobject JNIUtil::createDate(apr_time_t t
   return ret;
 }
 
+apr_time_t
+JNIUtil::getDate(jobject jdate)
+{
+  JNIEnv *env = getEnv();
+  jclass clazz = env->FindClass("java/util/Date");
+  if (isJavaExceptionThrown())
+    return 0;
+
+  static jmethodID mid = 0;
+  if (mid == 0)
+    {
+      mid = env->GetMethodID(clazz, "getTime", "()J");
+      if (isJavaExceptionThrown())
+        return 0;
+    }
+
+  jlong jmillis = env->CallLongMethod(jdate, mid);
+  if (isJavaExceptionThrown())
+    return 0;
+
+  env->DeleteLocalRef(clazz);
+
+  return jmillis * 1000;
+}
+
 /**
  * Create a Java byte array from an array of characters.
  * @param data      the character array
  * @param length    the number of characters in the array
  */
-jbyteArray JNIUtil::makeJByteArray(const signed char *data, int length)
+jbyteArray JNIUtil::makeJByteArray(const void *data, int length)
 {
   if (data == NULL)
     {
@@ -808,6 +920,15 @@ jbyteArray JNIUtil::makeJByteArray(const
 }
 
 /**
+ * Create a Java byte array from an svn_string_t.
+ * @param str       the string
+ */
+jbyteArray JNIUtil::makeJByteArray(const svn_string_t *str)
+{
+  return JNIUtil::makeJByteArray(str->data, static_cast<int>(str->len));
+}
+
+/**
  * Build the error message from the svn error into buffer.  This
  * method calls itselft recursively for all the chained errors
  *
@@ -816,13 +937,15 @@ jbyteArray JNIUtil::makeJByteArray(const
  * @param parent_apr_err    the apr of the previous level, used for formating
  * @param buffer            the buffer where the formated error message will
  *                          be stored
+ * @param message_stack     an array of error codes and messages
  */
 void JNIUtil::assembleErrorMessage(svn_error_t *err, int depth,
                                    apr_status_t parent_apr_err,
-                                   std::string &buffer)
+                                   std::string &buffer,
+                                   error_message_stack_t* message_stack)
 {
   // buffer for a single error message
-  char errbuf[256];
+  char errbuf[1024];
 
   /* Pretty-print the error */
   /* Note: we can also log errors here someday. */
@@ -831,21 +954,43 @@ void JNIUtil::assembleErrorMessage(svn_e
    * the same as before. */
   if (depth == 0 || err->apr_err != parent_apr_err)
     {
+      const char *message;
       /* Is this a Subversion-specific error code? */
       if ((err->apr_err > APR_OS_START_USEERR)
           && (err->apr_err <= APR_OS_START_CANONERR))
-        buffer.append(svn_strerror(err->apr_err, errbuf, sizeof(errbuf)));
+        message = svn_strerror(err->apr_err, errbuf, sizeof(errbuf));
       /* Otherwise, this must be an APR error code. */
       else
-        buffer.append(apr_strerror(err->apr_err, errbuf, sizeof(errbuf)));
+        {
+          /* Messages coming from apr_strerror are in the native
+             encoding, it's a good idea to convert them to UTF-8. */
+          apr_strerror(err->apr_err, errbuf, sizeof(errbuf));
+          svn_error_t* utf8_err =
+            svn_utf_cstring_to_utf8(&message, errbuf, err->pool);
+          if (utf8_err)
+            {
+              /* Use fuzzy transliteration instead. */
+              svn_error_clear(utf8_err);
+              message = svn_utf_cstring_from_utf8_fuzzy(errbuf, err->pool);
+            }
+        }
+
+      if (message_stack)
+        message_stack->push_back(
+            message_stack_item(err->apr_err, message, true));
+      buffer.append(message);
       buffer.append("\n");
     }
   if (err->message)
-    buffer.append(_("svn: ")).append(err->message).append("\n");
+    {
+      if (message_stack)
+        message_stack->push_back(
+            message_stack_item(err->apr_err, err->message));
+      buffer.append(_("svn: ")).append(err->message).append("\n");
+    }
 
   if (err->child)
     assembleErrorMessage(err->child, depth + 1, err->apr_err, buffer);
-
 }
 
 /**

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/JNIUtil.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/JNIUtil.h?rev=1497315&r1=1497314&r2=1497315&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/JNIUtil.h (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/JNIUtil.h Thu Jun 27 11:53:49 2013
@@ -37,6 +37,8 @@ class SVNBase;
 #include <fstream>
 #include <apr_time.h>
 #include <string>
+#include <vector>
+struct svn_string_t;
 struct svn_error_t;
 
 #define JAVA_PACKAGE "org/apache/subversion/javahl"
@@ -62,8 +64,10 @@ class JNIUtil
                                    int aprErr = -1);
 
   static void throwNullPointerException(const char *message);
-  static jbyteArray makeJByteArray(const signed char *data, int length);
+  static jbyteArray makeJByteArray(const void *data, int length);
+  static jbyteArray makeJByteArray(const svn_string_t *str);
   static jobject createDate(apr_time_t time);
+  static apr_time_t getDate(jobject jdate);
   static void logMessage(const char *message);
   static int getLogLevel();
   static char *getFormatBuffer();
@@ -137,10 +141,26 @@ class JNIUtil
   enum { formatBufferSize = 2048 };
   enum { noLog, errorLog, exceptionLog, entryLog } LogLevel;
 
+  struct message_stack_item
+  {
+    apr_status_t m_code;
+    std::string m_message;
+    bool m_generic;
+
+    message_stack_item(apr_status_t code, const char* message,
+                       bool generic = false)
+      : m_code(code),
+        m_message(message),
+        m_generic(generic)
+      {}
+  };
+  typedef std::vector<message_stack_item> error_message_stack_t;
+
  private:
   static void assembleErrorMessage(svn_error_t *err, int depth,
                                    apr_status_t parent_apr_err,
-                                   std::string &buffer);
+                                   std::string &buffer,
+                                   error_message_stack_t* message_stack = NULL);
   static void putErrorsInTrace(svn_error_t *err,
                                std::vector<jobject> &stackTrace);
   /**

Copied: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/LockTokenTable.cpp (from r1497181, subversion/trunk/subversion/bindings/javahl/native/LockTokenTable.cpp)
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/LockTokenTable.cpp?p2=subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/LockTokenTable.cpp&p1=subversion/trunk/subversion/bindings/javahl/native/LockTokenTable.cpp&r1=1497181&r2=1497315&rev=1497315&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/LockTokenTable.cpp (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/LockTokenTable.cpp Thu Jun 27 11:53:49 2013
@@ -29,6 +29,7 @@
 #include "JNIStringHolder.h"
 #include "Array.h"
 #include <apr_hash.h>
+#include <apr_strings.h>
 
 LockTokenTable::~LockTokenTable()
 {

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/OperationContext.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/OperationContext.cpp?rev=1497315&r1=1497314&r2=1497315&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/OperationContext.cpp (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/OperationContext.cpp Thu Jun 27 11:53:49 2013
@@ -215,10 +215,7 @@ OperationContext::getAuthBaton(SVN::Pool
 
 jobject OperationContext::getSelf() const
 {
-  jobject jctx = JNIUtil::getEnv()->NewGlobalRef(m_jctx);
-  if (JNIUtil::isJavaExceptionThrown())
-    return NULL;
-  return jctx;
+  return m_jctx;
 }
 
 void

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/Path.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/Path.cpp?rev=1497315&r1=1497314&r2=1497315&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/Path.cpp (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/Path.cpp Thu Jun 27 11:53:49 2013
@@ -27,18 +27,24 @@
 #include <jni.h>
 #include "Path.h"
 #include "svn_path.h"
+#include "svn_dirent_uri.h"
 #include "JNIUtil.h"
+#include "JNIStringHolder.h"
 #include "Pool.h"
+#include "svn_private_config.h"
 
 /**
  * Constructor
  *
- * @see Path::Path(const std::string &)
+ * @see PathBase::PathBase(const std::string &)
  * @param path Path string
  */
-Path::Path(const char *pi_path, SVN::Pool &in_pool)
+PathBase::PathBase(const char *pi_path,
+                   svn_error_t* initfunc(const char*&, SVN::Pool&),
+                   SVN::Pool &in_pool)
+  : m_error_occurred(NULL)
 {
-  init(pi_path, in_pool);
+  init(pi_path, initfunc, in_pool);
 }
 
 /**
@@ -48,19 +54,26 @@ Path::Path(const char *pi_path, SVN::Poo
  *
  * @param path Path string
  */
-Path::Path(const std::string &pi_path, SVN::Pool &in_pool)
+PathBase::PathBase(const std::string &pi_path,
+                   svn_error_t* initfunc(const char*&, SVN::Pool&),
+                   SVN::Pool &in_pool)
+  : m_error_occurred(NULL)
 {
-  init(pi_path.c_str(), in_pool);
+  init(pi_path.c_str(), initfunc, in_pool);
 }
 
 /**
- * Copy constructor
- *
- * @param path Path to be copied
+ * Constructor from a Java string.
  */
-Path::Path(const Path &pi_path, SVN::Pool &in_pool)
+PathBase::PathBase(jstring jpath,
+                   svn_error_t* initfunc(const char*&, SVN::Pool&),
+                   SVN::Pool &in_pool)
+  : m_error_occurred(NULL)
 {
-  init(pi_path.c_str(), in_pool);
+  JNIStringHolder path(jpath);
+  if (JNIUtil::isJavaExceptionThrown())
+    return;
+  init(path, initfunc, in_pool);
 }
 
 /**
@@ -69,17 +82,13 @@ Path::Path(const Path &pi_path, SVN::Poo
  * @param path Path string
  */
 void
-Path::init(const char *pi_path, SVN::Pool &in_pool)
+PathBase::init(const char *pi_path,
+               svn_error_t* initfunc(const char*&, SVN::Pool&),
+               SVN::Pool &in_pool)
 {
-  if (*pi_path == 0)
-    {
-      m_error_occured = NULL;
-      m_path = "";
-    }
-  else
+  if (pi_path && *pi_path)
     {
-      m_error_occured = JNIUtil::preprocessPath(pi_path, in_pool.getPool());
-
+      m_error_occurred = initfunc(pi_path, in_pool);
       m_path = pi_path;
     }
 }
@@ -88,7 +97,7 @@ Path::init(const char *pi_path, SVN::Poo
  * @return Path string
  */
 const std::string &
-Path::path() const
+PathBase::path() const
 {
   return m_path;
 }
@@ -97,7 +106,7 @@ Path::path() const
  * @return Path string as a C string
  */
 const char *
-Path::c_str() const
+PathBase::c_str() const
 {
   return m_path.c_str();
 }
@@ -105,21 +114,21 @@ Path::c_str() const
 /**
  * Assignment operator
  */
-Path&
-Path::operator=(const Path &pi_path)
+PathBase&
+PathBase::operator=(const PathBase &pi_path)
 {
-  m_error_occured = NULL;
+  m_error_occurred = NULL;
   m_path = pi_path.m_path;
 
   return *this;
 }
 
-  svn_error_t *Path::error_occured() const
+svn_error_t *PathBase::error_occurred() const
 {
-  return m_error_occured;
+  return m_error_occurred;
 }
 
-jboolean Path::isValid(const char *p)
+jboolean PathBase::isValid(const char *p)
 {
   if (p == NULL)
     return JNI_FALSE;
@@ -136,3 +145,25 @@ jboolean Path::isValid(const char *p)
       return JNI_FALSE;
     }
 }
+
+svn_error_t*
+Path::initfunc(const char*& path, SVN::Pool& pool)
+{
+  return JNIUtil::preprocessPath(path, pool.getPool());
+}
+
+svn_error_t*
+URL::initfunc(const char*& path, SVN::Pool& pool)
+{
+  if (svn_path_is_url(path))
+    return JNIUtil::preprocessPath(path, pool.getPool());
+  return svn_error_createf(SVN_ERR_BAD_URL, NULL,
+                           _("Not an URL: %s"), path);
+}
+
+svn_error_t*
+Relpath::initfunc(const char*& path, SVN::Pool& pool)
+{
+  path = svn_relpath__internal_style(path, pool.getPool());
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/Path.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/Path.h?rev=1497315&r1=1497314&r2=1497315&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/Path.h (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/Path.h Thu Jun 27 11:53:49 2013
@@ -24,33 +24,36 @@
  * @brief Interface of the C++ class Path.
  */
 
-#ifndef PATH_H
-#define PATH_H
+#ifndef JAVAHL_PATH_H
+#define JAVAHL_PATH_H
 
 #include <string>
 #include <jni.h>
 #include "Pool.h"
 struct svn_error_t;
 
+
 /**
  * Encapsulation for Subversion Path handling
  */
-class Path
+class PathBase
 {
  private:
   // The path to be stored.
   std::string m_path;
 
-  svn_error_t *m_error_occured;
+  svn_error_t *m_error_occurred;
 
   /**
    * Initialize the class.
    *
    * @param pi_path Path string
    */
-  void init(const char *pi_path, SVN::Pool &in_pool);
+  void init(const char *pi_path,
+            svn_error_t* initfunc(const char*&, SVN::Pool&),
+            SVN::Pool &in_pool);
 
- public:
+ protected:
   /**
    * Constructor that takes a string as parameter.
    * The string is converted to subversion internal
@@ -58,27 +61,31 @@ class Path
    *
    * @param pi_path Path string
    */
-  Path(const std::string &pi_path, SVN::Pool &in_pool);
+  PathBase(const std::string &pi_path,
+           svn_error_t* initfunc(const char*&, SVN::Pool&),
+           SVN::Pool &in_pool);
 
   /**
    * Constructor
    *
-   * @see Path::Path (const std::string &)
+   * @see PathBase::PathBase (const std::string &)
    * @param pi_path Path string
    */
-  Path(const char *pi_path, SVN::Pool &in_pool);
+  PathBase(const char *pi_path,
+           svn_error_t* initfunc(const char*&, SVN::Pool&),
+           SVN::Pool &in_pool);
 
   /**
-   * Copy constructor
-   *
-   * @param pi_path Path to be copied
+   * Constructor from a Java string.
    */
-  Path(const Path &pi_path, SVN::Pool &in_pool);
+  PathBase(jstring jpath,
+           svn_error_t* initfunc(const char*&, SVN::Pool&),
+           SVN::Pool &in_pool);
 
   /**
    * Assignment operator
    */
-  Path &operator=(const Path&);
+  PathBase &operator=(const PathBase&);
 
   /**
    * @return Path string
@@ -90,8 +97,9 @@ class Path
    */
   const char *c_str() const;
 
-  svn_error_t *error_occured() const;
+  svn_error_t *error_occurred() const;
 
+public:
   /**
    * Returns whether @a path is non-NULL and passes the @c
    * svn_path_check_valid() test.
@@ -101,4 +109,117 @@ class Path
   static jboolean isValid(const char *path);
 };
 
-#endif  // PATH_H
+
+/**
+ * Dirent or URI
+ */
+class Path : protected PathBase
+{
+ public:
+  Path(const std::string &pi_path, SVN::Pool &in_pool)
+    : PathBase(pi_path, initfunc, in_pool)
+    {}
+
+  Path(const char *pi_path, SVN::Pool &in_pool)
+    : PathBase(pi_path, initfunc, in_pool)
+    {}
+
+  Path(jstring jpath, SVN::Pool &in_pool)
+    : PathBase(jpath, initfunc, in_pool)
+    {}
+
+  Path& operator=(const Path& that)
+    {
+      PathBase::operator=(that);
+      return *this;
+    }
+
+  const std::string &path() const { return PathBase::path(); }
+  const char *c_str() const { return PathBase::c_str(); }
+
+  svn_error_t *error_occurred() const
+    {
+      return PathBase::error_occurred();
+    }
+  svn_error_t *error_occured() const
+    {
+      return PathBase::error_occurred();
+    }
+
+ private:
+  static svn_error_t* initfunc(const char*&, SVN::Pool&);
+};
+
+/**
+ * URL
+ */
+class URL : protected PathBase
+{
+ public:
+  URL(const std::string &pi_path, SVN::Pool &in_pool)
+    : PathBase(pi_path, initfunc, in_pool)
+    {}
+
+  URL(const char *pi_path, SVN::Pool &in_pool)
+    : PathBase(pi_path, initfunc, in_pool)
+    {}
+
+  URL(jstring jpath, SVN::Pool &in_pool)
+    : PathBase(jpath, initfunc, in_pool)
+    {}
+
+  URL& operator=(const URL& that)
+    {
+      PathBase::operator=(that);
+      return *this;
+    }
+
+  const std::string &path() const { return PathBase::path(); }
+  const char *c_str() const { return PathBase::c_str(); }
+
+  svn_error_t *error_occurred() const
+    {
+      return PathBase::error_occurred();
+    }
+
+ private:
+  static svn_error_t* initfunc(const char*&, SVN::Pool&);
+};
+
+/**
+ * Relative path
+ */
+class Relpath : protected PathBase
+{
+ public:
+  Relpath(const std::string &pi_path, SVN::Pool &in_pool)
+    : PathBase(pi_path, initfunc, in_pool)
+    {}
+
+  Relpath(const char *pi_path, SVN::Pool &in_pool)
+    : PathBase(pi_path, initfunc, in_pool)
+    {}
+
+  Relpath(jstring jpath, SVN::Pool &in_pool)
+    : PathBase(jpath, initfunc, in_pool)
+    {}
+
+  Relpath& operator=(const Relpath& that)
+    {
+      PathBase::operator=(that);
+      return *this;
+    }
+
+  const std::string &path() const { return PathBase::path(); }
+  const char *c_str() const { return PathBase::c_str(); }
+
+  svn_error_t *error_occurred() const
+    {
+      return PathBase::error_occurred();
+    }
+
+ private:
+  static svn_error_t* initfunc(const char*&, SVN::Pool&);
+};
+
+#endif  // JAVAHL_PATH_H

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RemoteSession.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RemoteSession.cpp?rev=1497315&r1=1497314&r2=1497315&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RemoteSession.cpp (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RemoteSession.cpp Thu Jun 27 11:53:49 2013
@@ -30,6 +30,7 @@
 #include "JNIByteArray.h"
 #include "JNIStringHolder.h"
 #include "JNIUtil.h"
+#include "Path.h"
 
 #include "svn_ra.h"
 #include "svn_string.h"
@@ -64,9 +65,11 @@ RemoteSession::open(jint jretryAttempts,
 {
   JNIEnv *env = JNIUtil::getEnv();
 
-  JNIStringHolder url(jurl);
+  SVN::Pool requestPool;
+  URL url(jurl, requestPool);
   if (JNIUtil::isExceptionThrown())
     return NULL;
+  SVN_JNI_ERR(url.error_occurred(), NULL);
   env->DeleteLocalRef(jurl);
 
   JNIStringHolder uuid(juuid);
@@ -98,7 +101,7 @@ RemoteSession::open(jint jretryAttempts,
     }
 
   jobject jremoteSession = open(
-      jretryAttempts, url, uuid, configDirectory,
+      jretryAttempts, url.c_str(), uuid, configDirectory,
       usernameStr, passwordStr, prompter, jprogress);
   if (JNIUtil::isExceptionThrown() || !jremoteSession)
     {
@@ -279,12 +282,13 @@ RemoteSession::dispose(jobject jthis)
 
 void RemoteSession::reparent(jstring jurl)
 {
-  JNIStringHolder url(jurl);
-  if (JNIUtil::isJavaExceptionThrown())
+  SVN::Pool subPool(pool);
+  URL url(jurl, subPool);
+  if (JNIUtil::isExceptionThrown())
     return;
+  SVN_JNI_ERR(url.error_occurred(),);
 
-  SVN::Pool subPool(pool);
-  SVN_JNI_ERR(svn_ra_reparent(m_session, url, subPool.getPool()), );
+  SVN_JNI_ERR(svn_ra_reparent(m_session, url.c_str(), subPool.getPool()), );
 }
 
 jstring
@@ -304,14 +308,15 @@ RemoteSession::getSessionUrl()
 jstring
 RemoteSession::getSessionRelativePath(jstring jurl)
 {
-  JNIStringHolder url(jurl);
-  if (JNIUtil::isJavaExceptionThrown())
+  SVN::Pool subPool(pool);
+  URL url(jurl, subPool);
+  if (JNIUtil::isExceptionThrown())
     return NULL;
+  SVN_JNI_ERR(url.error_occurred(), NULL);
 
-  SVN::Pool subPool(pool);
   const char* rel_path;
   SVN_JNI_ERR(svn_ra_get_path_relative_to_session(
-                  m_session, &rel_path, url, subPool.getPool()),
+                  m_session, &rel_path, url.c_str(), subPool.getPool()),
               NULL);
   jstring jrel_path = JNIUtil::makeJString(rel_path);
   if (JNIUtil::isJavaExceptionThrown())
@@ -323,13 +328,15 @@ RemoteSession::getSessionRelativePath(js
 jstring
 RemoteSession::getReposRelativePath(jstring jurl)
 {
-  JNIStringHolder url(jurl);
-  if (JNIUtil::isJavaExceptionThrown())
+  SVN::Pool subPool(pool);
+  URL url(jurl, subPool);
+  if (JNIUtil::isExceptionThrown())
     return NULL;
+  SVN_JNI_ERR(url.error_occurred(), NULL);
 
-  SVN::Pool subPool(pool);
   const char* rel_path;
-  SVN_JNI_ERR(svn_ra_get_path_relative_to_root(m_session, &rel_path, url,
+  SVN_JNI_ERR(svn_ra_get_path_relative_to_root(m_session, &rel_path,
+                                               url.c_str(),
                                                subPool.getPool()),
               NULL);
 
@@ -471,21 +478,22 @@ jlong
 RemoteSession::getFile(jlong jrevision, jstring jpath,
                        jobject jcontents, jobject jproperties)
 {
-  JNIStringHolder path(jpath);
+  OutputStream contents_proxy(jcontents);
   if (JNIUtil::isExceptionThrown())
     return SVN_INVALID_REVNUM;
 
-  OutputStream contents_proxy(jcontents);
+  SVN::Pool subPool(pool);
+  Relpath path(jpath, subPool);
   if (JNIUtil::isExceptionThrown())
     return SVN_INVALID_REVNUM;
+  SVN_JNI_ERR(path.error_occurred(), SVN_INVALID_REVNUM);
 
-  SVN::Pool subPool(pool);
   apr_hash_t* props = NULL;
   svn_revnum_t fetched_rev = svn_revnum_t(jrevision);
   svn_stream_t* contents = (!jcontents ? NULL
                             : contents_proxy.getStream(subPool));
 
-  SVN_JNI_ERR(svn_ra_get_file(m_session, path, fetched_rev,
+  SVN_JNI_ERR(svn_ra_get_file(m_session, path.c_str(), fetched_rev,
                               contents, &fetched_rev,
                               (jproperties ? &props : NULL),
                               subPool.getPool()),
@@ -579,18 +587,20 @@ RemoteSession::getDirectory(jlong jrevis
                             jint jdirent_fields, jobject jdirents,
                             jobject jproperties)
 {
-  JNIStringHolder path(jpath);
+  SVN::Pool subPool(pool);
+  Relpath path(jpath, subPool);
   if (JNIUtil::isExceptionThrown())
     return SVN_INVALID_REVNUM;
+  SVN_JNI_ERR(path.error_occurred(), SVN_INVALID_REVNUM);
 
-  SVN::Pool subPool(pool);
   apr_hash_t* props = NULL;
   apr_hash_t* dirents = NULL;
   svn_revnum_t fetched_rev = svn_revnum_t(jrevision);
 
   SVN_JNI_ERR(svn_ra_get_dir2(m_session, (jdirents ? &dirents : NULL),
                               &fetched_rev, (jproperties ? &props : NULL),
-                              path, fetched_rev, apr_uint32_t(jdirent_fields),
+                              path.c_str(), fetched_rev,
+                              apr_uint32_t(jdirent_fields),
                               subPool.getPool()),
               SVN_INVALID_REVNUM);
 
@@ -602,7 +612,8 @@ RemoteSession::getDirectory(jlong jrevis
       SVN_JNI_ERR(svn_ra_get_session_url(m_session, &base_url,
                                          subPool.getPool()),
                   SVN_INVALID_REVNUM);
-      fill_dirents(base_url, path, jdirents, dirents, subPool.getPool());
+      fill_dirents(base_url, path.c_str(), jdirents, dirents,
+                   subPool.getPool());
       if (JNIUtil::isExceptionThrown())
         return SVN_INVALID_REVNUM;
     }
@@ -618,30 +629,31 @@ RemoteSession::getDirectory(jlong jrevis
 }
 
 // TODO: getMergeinfo
-// TODO: doUpdate
-// TODO: doSwitch
+// TODO: update
+// TODO: switch
 
 jobject
-RemoteSession::doStatus(jstring jstatus_target,
-                        jlong jrevision, jobject jdepth,
-                        jobject jstatus_editor)
+RemoteSession::status(jstring jstatus_target,
+                      jlong jrevision, jobject jdepth,
+                      jobject jstatus_editor)
 {
   return NULL;
 }
 
-// TODO: doDiff
+// TODO: diff
 // TODO: getLog
 
 jobject
 RemoteSession::checkPath(jstring jpath, jlong jrevision)
 {
-  JNIStringHolder path(jpath);
+  SVN::Pool subPool(pool);
+  Relpath path(jpath, subPool);
   if (JNIUtil::isExceptionThrown())
     return NULL;
+  SVN_JNI_ERR(path.error_occurred(), NULL);
 
-  SVN::Pool subPool(pool);
   svn_node_kind_t kind;
-  SVN_JNI_ERR(svn_ra_check_path(m_session, path,
+  SVN_JNI_ERR(svn_ra_check_path(m_session, path.c_str(),
                                 svn_revnum_t(jrevision),
                                 &kind, subPool.getPool()),
               NULL);
@@ -660,17 +672,18 @@ RemoteSession::checkPath(jstring jpath, 
 jobject
 RemoteSession::getLocks(jstring jpath, jobject jdepth)
 {
-  JNIStringHolder path(jpath);
+  svn_depth_t depth = EnumMapper::toDepth(jdepth);
   if (JNIUtil::isExceptionThrown())
     return NULL;
 
-  svn_depth_t depth = EnumMapper::toDepth(jdepth);
+  SVN::Pool subPool(pool);
+  Relpath path(jpath, subPool);
   if (JNIUtil::isExceptionThrown())
     return NULL;
+  SVN_JNI_ERR(path.error_occurred(), NULL);
 
-  SVN::Pool subPool(pool);
   apr_hash_t *locks;
-  SVN_JNI_ERR(svn_ra_get_locks2(m_session, &locks, path, depth,
+  SVN_JNI_ERR(svn_ra_get_locks2(m_session, &locks, path.c_str(), depth,
                                 subPool.getPool()),
               NULL);
 

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RemoteSession.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RemoteSession.h?rev=1497315&r1=1497314&r2=1497315&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RemoteSession.h (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RemoteSession.h Thu Jun 27 11:53:49 2013
@@ -35,6 +35,8 @@
 #include "RemoteSessionContext.h"
 #include "Prompter.h"
 
+class CommitEditor;
+
 /*
  * This class wraps Ra based operations from svn_ra.h
  */
@@ -76,12 +78,12 @@ class RemoteSession : public SVNBase
     jlong getDirectory(jlong jrevision, jstring jpath, jint jdirent_fields,
                        jobject jdirents, jobject jproperties);
     // TODO: getMergeinfo
-    // TODO: doUpdate
-    // TODO: doSwitch
-    jobject doStatus(jstring jstatus_target,
-                     jlong jrevision, jobject jdepth,
-                     jobject jstatus_editor);
-    // TODO: doDiff
+    // TODO: update
+    // TODO: switch
+    jobject status(jstring jstatus_target,
+                   jlong jrevision, jobject jdepth,
+                   jobject jstatus_editor);
+    // TODO: diff
     // TODO: getLog
     jobject checkPath(jstring jpath, jlong jrevision);
     // TODO: stat
@@ -99,6 +101,7 @@ class RemoteSession : public SVNBase
     jboolean hasCapability(jstring capability);
 
   private:
+    friend class CommitEditor;
     RemoteSession(jobject*, int retryAttempts,
                   const char* url, const char* uuid,
                   const char* configDirectory,

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RevpropTable.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RevpropTable.cpp?rev=1497315&r1=1497314&r2=1497315&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RevpropTable.cpp (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RevpropTable.cpp Thu Jun 27 11:53:49 2013
@@ -42,9 +42,9 @@ RevpropTable::~RevpropTable()
     JNIUtil::getEnv()->DeleteLocalRef(m_revpropTable);
 }
 
-const apr_hash_t *RevpropTable::hash(const SVN::Pool &pool)
+apr_hash_t *RevpropTable::hash(const SVN::Pool &pool, bool nullIfEmpty)
 {
-  if (m_revprops.size() == 0)
+  if (m_revprops.size() == 0 && nullIfEmpty)
     return NULL;
 
   apr_hash_t *revprop_table = apr_hash_make(pool.getPool());
@@ -78,7 +78,7 @@ RevpropTable::RevpropTable(jobject jrevp
 
   if (jrevpropTable != NULL)
     {
-      static jmethodID keySet = 0, toArray = 0, get = 0;
+      static jmethodID keySet = 0, get = 0;
       JNIEnv *env = JNIUtil::getEnv();
 
       jclass mapClazz = env->FindClass("java/util/Map");

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RevpropTable.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RevpropTable.h?rev=1497315&r1=1497314&r2=1497315&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RevpropTable.h (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RevpropTable.h Thu Jun 27 11:53:49 2013
@@ -44,7 +44,7 @@ class RevpropTable
  public:
   RevpropTable(jobject jrevpropTable, bool bytearray_values=false);
   ~RevpropTable();
-  const apr_hash_t *hash(const SVN::Pool &pool);
+  apr_hash_t *hash(const SVN::Pool &pool, bool nullIfEmpty = true);
 };
 
 #endif // REVPROPTABLE_H

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/SVNClient.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/SVNClient.cpp?rev=1497315&r1=1497314&r2=1497315&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/SVNClient.cpp (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/SVNClient.cpp Thu Jun 27 11:53:49 2013
@@ -1548,12 +1548,7 @@ SVNClient::openRemoteSession(const char*
        by creating a copy of the prompter here. */
     Prompter* prompter = new Prompter(context.getPrompter());
     if (!prompter)
-    {
-        /* context.getSelf() created a new global reference. */
-        JNIUtil::getEnv()->DeleteGlobalRef(jctx);
-        JNIUtil::throwNullPointerException("allocating Prompter");
-        return NULL;
-    }
+      return NULL;
 
     jobject jremoteSession = RemoteSession::open(
         retryAttempts, path_info.url.c_str(), path_info.uuid.c_str(),
@@ -1561,12 +1556,7 @@ SVNClient::openRemoteSession(const char*
         context.getUsername(), context.getPassword(),
         prompter, jctx);
     if (JNIUtil::isJavaExceptionThrown())
-    {
-        /* context.getSelf() created a new global reference. */
-        JNIUtil::getEnv()->DeleteGlobalRef(jctx);
-        jremoteSession = NULL;
-        delete prompter;
-    }
+      delete prompter;
 
     return jremoteSession;
 }

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_RemoteSession.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_RemoteSession.cpp?rev=1497315&r1=1497314&r2=1497315&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_RemoteSession.cpp (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_RemoteSession.cpp Thu Jun 27 11:53:49 2013
@@ -49,7 +49,7 @@ JNIEXPORT void JNICALL
 Java_org_apache_subversion_javahl_remote_RemoteSession_nativeDispose(
     JNIEnv *env, jobject jthis)
 {
-  JNIEntry(RemoteSession, dispose);
+  JNIEntry(RemoteSession, nativeDispose);
   RemoteSession *ras = RemoteSession::getCppObject(jthis);
   if (ras != NULL)
     ras->dispose(jthis);
@@ -214,11 +214,11 @@ Java_org_apache_subversion_javahl_remote
 }
 
 // TODO: getMergeinfo
-// TODO: doUpdate
-// TODO: doSwitch
+// TODO: update
+// TODO: switch
 
 JNIEXPORT jobject JNICALL
-Java_org_apache_subversion_javahl_remote_RemoteSession_doStatus(
+Java_org_apache_subversion_javahl_remote_RemoteSession_status(
     JNIEnv *env, jobject jthis, jstring jstatus_target,
     jlong jrevision, jobject jdepth, jobject jstatus_editor)
 {
@@ -226,10 +226,10 @@ Java_org_apache_subversion_javahl_remote
   RemoteSession *ras = RemoteSession::getCppObject(jthis);
   CPPADDR_NULL_PTR(ras, NULL);
 
-  return ras->doStatus(jstatus_target, jrevision, jdepth, jstatus_editor);
+  return ras->status(jstatus_target, jrevision, jdepth, jstatus_editor);
 }
 
-// TODO: doDiff
+// TODO: diff
 // TODO: getLog
 
 JNIEXPORT jobject JNICALL

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ClientException.java
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ClientException.java?rev=1497315&r1=1497314&r2=1497315&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ClientException.java (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ClientException.java Thu Jun 27 11:53:49 2013
@@ -22,6 +22,7 @@
  */
 
 package org.apache.subversion.javahl;
+import java.util.List;
 
 /**
  * This exception is thrown whenever something goes wrong in the
@@ -36,7 +37,54 @@ public class ClientException extends Nat
     // http://java.sun.com/j2se/1.4/pdf/serial-spec.pdf
     // http://java.sun.com/j2se/1.5.0/docs/guide/serialization/spec/version.html#6678
     // http://java.sun.com/javase/6/docs/platform/serialization/spec/version.html#6678
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 2L;
+
+    /**
+     * Describes a single error message in a stack of messages
+     * associated with this exception.
+     * @since 1.9
+     */
+    public static final class ErrorMessage
+    {
+        ErrorMessage(int code, String message, boolean generic)
+        {
+            this.code = code;
+            this.message = message;
+            this.generic = generic;
+        }
+
+        /** @return The APR error code associated with the message. */
+        public final int getCode() { return code; }
+
+        /** @return The error message text. */
+        public final String getMessage() { return message; }
+
+        /** @return A flag indicating whether this is a generic
+            message for the APR error code, or a more specific message
+            generated by the native libraries. */
+        public final boolean isGeneric() { return generic; }
+
+        private final int code;
+        private final String message;
+        private final boolean generic;
+    };
+
+    /**
+     * This constructor is only used by the native library.
+     *
+     * @param message A description of the problem.
+     * @param source The error's source.
+     * @param aprError Any associated APR error code for a wrapped
+     *        <code>svn_error_t</code>.
+     * @param messageStack The whole stack of error messages
+     * @since 1.9
+     */
+    ClientException(String message, String source, int aprError,
+                    List<ErrorMessage> messageStack)
+    {
+        super(message, source, aprError);
+        this.messageStack = messageStack;
+    }
 
     /**
      * This constructor is only used by the native library.
@@ -48,7 +96,12 @@ public class ClientException extends Nat
      */
     ClientException(String message, String source, int aprError)
     {
-        super(message, source, aprError);
+        this(message, source, aprError, null);
+    }
+
+    public List<ErrorMessage> getAllMessages()
+    {
+        return messageStack;
     }
 
     /**
@@ -68,4 +121,6 @@ public class ClientException extends Nat
             return new ClientException(t.getMessage(), null, -1);
         }
     }
+
+    private final List<ErrorMessage> messageStack;
 }

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNEditor.java
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNEditor.java?rev=1497315&r1=1497314&r2=1497315&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNEditor.java (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNEditor.java Thu Jun 27 11:53:49 2013
@@ -27,7 +27,6 @@ import org.apache.subversion.javahl.type
 import org.apache.subversion.javahl.callback.*;
 
 import java.io.InputStream;
-import java.util.List;
 import java.util.Map;
 
 /**
@@ -296,7 +295,7 @@ public interface ISVNEditor
      *
      * @throws ClientException
      */
-    void rotate(List<RotatePair> elements) throws ClientException;
+    void rotate(Iterable<RotatePair> elements) throws ClientException;
 
     public static final class RotatePair
     {

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRemote.java
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRemote.java?rev=1497315&r1=1497314&r2=1497315&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRemote.java (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRemote.java Thu Jun 27 11:53:49 2013
@@ -28,6 +28,7 @@ import org.apache.subversion.javahl.call
 
 import java.util.Date;
 import java.util.Map;
+import java.util.Set;
 import java.io.OutputStream;
 
 /**
@@ -44,7 +45,7 @@ public interface ISVNRemote
     void dispose();
 
     /**
-     * Cancel the active operation.
+     * Cancel the active operation, including any ongoing edits.
      * @throws ClientException
      */
     void cancelOperation() throws ClientException;
@@ -156,10 +157,47 @@ public interface ISVNRemote
             throws ClientException;
 
     /**
-     * Create a commit editor instance, rooted at the current session URL.
-     * @throws ClientException
-     */
-    ISVNEditor getCommitEditor() throws ClientException;
+     * Return an editor for committing changes to the session's
+     * repository, setting the revision properties from
+     * <code>revisionProperties</code>. The revisions being committed
+     * against are passed to the editor functions. The root of the commit
+     * is the session's URL.
+     * <p>
+     * <code>revisionProperties</code> is a hash mapping property names to
+     * property values. The commit log message is expected to be in the
+     * {@link Property#REV_LOG} element.  <code>revisionProperties</code>
+     * can not contain either of {@link Property#REV_DATE} or
+     * {@link Property#REV_AUTHOR}.
+     * <p>
+     * Before {@link ISVNEditor#complete()} returns, but after the commit
+     * has succeeded, it will invoke <code>commitCallback</code> (if not
+     * <code>null</code>) with filled-in {@link CommitInfo}.  If
+     * <code>commitCallback</code> returns an error, that error will be
+     * returned from {@link ISVNEditor#complete()}, otherwise
+     * {@link ISVNEditor#complete()} will return successfully (unless it
+     * encountered an error before invoking <code>commitCallback</code>).
+     * The callback will not be called if the commit was a no-op
+     * (i.e., nothing was committed).
+     * <p>
+     * <code>lockTokens</code>, if not <code>null</code>, is a hash
+     * mapping paths (relative to the session's URL) to lock tokens.  The
+     * server checks that the correct token is provided for each
+     * committed, locked path.  <code>lockTokens</code> must live during
+     * the whole commit operation.
+     * <p>
+     * If <cpde>keepLocks</code> is <cpde>true</code>, then do not release
+     * locks on committed objects.  Else, automatically release such
+     * locks.
+     * <p>
+     * The caller may not perform any remote operations using this session
+     * before finishing the edit.
+     * @throws ClientException
+     */
+    ISVNEditor getCommitEditor(Map<String, byte[]> revisionProperties,
+                               CommitCallback commitCallback,
+                               Set<Lock> lockTokens,
+                               boolean keepLocks)
+            throws ClientException;
 
     /**
      * Fetch the contents and properties of file <code>path</code> at
@@ -242,8 +280,8 @@ public interface ISVNRemote
             throws ClientException;
 
     // TODO: getMergeinfo
-    // TODO: doUpdate
-    // TODO: doSwitch
+    // TODO: update
+    // TODO: switch
 
     /**
      * Ask for a description of the status of a working copy with
@@ -292,12 +330,12 @@ public interface ISVNRemote
      * <code>depth</code>.
      * @throws ClientException
      */
-    ISVNReporter doStatus(String statusTarget,
-                          long revision, Depth depth,
-                          ISVNEditor statusEditor)
+    ISVNReporter status(String statusTarget,
+                        long revision, Depth depth,
+                        ISVNEditor statusEditor)
             throws ClientException;
 
-    // TODO: doDiff
+    // TODO: diff
     // TODO: getLog
 
     /**

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/CommitEditor.java
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/CommitEditor.java?rev=1497315&r1=1497314&r2=1497315&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/CommitEditor.java (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/CommitEditor.java Thu Jun 27 11:53:49 2013
@@ -31,8 +31,8 @@ import org.apache.subversion.javahl.JNIO
 import org.apache.subversion.javahl.ClientException;
 
 import java.io.InputStream;
-import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * Implementation of ISVNEditor that drives commits.
@@ -131,7 +131,7 @@ public class CommitEditor extends JNIObj
         notimplemented("move");
     }
 
-    public void rotate(List<RotatePair> elements) throws ClientException
+    public void rotate(Iterable<RotatePair> elements) throws ClientException
     {
         notimplemented("rotate");
     }
@@ -149,7 +149,11 @@ public class CommitEditor extends JNIObj
     /**
      * This factory method called from RemoteSession.getCommitEditor.
      */
-    static final CommitEditor createInstance(RemoteSession owner)
+    static final CommitEditor createInstance(RemoteSession owner,
+                                             Map<String, byte[]> revisionProperties,
+                                             CommitCallback commitCallback,
+                                             Set<Lock> lockTokens,
+                                             boolean keepLocks)
             throws ClientException
     {
         // FIXME: temporary implementation

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/RemoteSession.java
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/RemoteSession.java?rev=1497315&r1=1497314&r2=1497315&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/RemoteSession.java (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/RemoteSession.java Thu Jun 27 11:53:49 2013
@@ -34,9 +34,9 @@ import org.apache.subversion.javahl.Oper
 import org.apache.subversion.javahl.ClientException;
 
 import java.lang.ref.WeakReference;
-import java.util.HashSet;
 import java.util.Date;
 import java.util.Map;
+import java.util.Set;
 import java.io.OutputStream;
 
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
@@ -46,17 +46,16 @@ public class RemoteSession extends JNIOb
 {
     public void dispose()
     {
-        if (editors != null)
+        if (editorReference != null)
         {
-            // Deactivate all open editors
-            for (WeakReference<ISVNEditor> ref : editors)
+            // Deactivate the open editor
+            ISVNEditor ed = editorReference.get();
+            if (ed != null)
             {
-                ISVNEditor ed = ref.get();
-                if (ed == null)
-                    continue;
                 ed.dispose();
-                ref.clear();
+                editorReference.clear();
             }
+            editorReference = null;
         }
         nativeDispose();
     }
@@ -109,12 +108,22 @@ public class RemoteSession extends JNIOb
     public native byte[] getRevisionProperty(long revision, String propertyName)
             throws ClientException;
 
-    public ISVNEditor getCommitEditor() throws ClientException
+    public ISVNEditor getCommitEditor(Map<String, byte[]> revisionProperties,
+                                      CommitCallback commitCallback,
+                                      Set<Lock> lockTokens,
+                                      boolean keepLocks)
+            throws ClientException
     {
-        ISVNEditor ed = CommitEditor.createInstance(this);
-        if (editors == null)
-            editors = new HashSet<WeakReference<ISVNEditor>>();
-        editors.add(new WeakReference<ISVNEditor>(ed));
+        if (editorReference != null && editorReference.get() != null)
+            throw new IllegalStateException("An editor is already active");
+
+        ISVNEditor ed =
+            CommitEditor.createInstance(this, revisionProperties,
+                                        commitCallback, lockTokens, keepLocks);
+
+        if (editorReference != null)
+            editorReference.clear();
+        editorReference = new WeakReference<ISVNEditor>(ed);
         return ed;
     }
 
@@ -143,15 +152,15 @@ public class RemoteSession extends JNIOb
     }
 
     // TODO: getMergeinfo
-    // TODO: doUpdate
-    // TODO: doSwitch
+    // TODO: update
+    // TODO: switch
 
-    public native ISVNReporter doStatus(String statusTarget,
-                                        long revision, Depth depth,
-                                        ISVNEditor statusEditor)
+    public native ISVNReporter status(String statusTarget,
+                                      long revision, Depth depth,
+                                      ISVNEditor statusEditor)
             throws ClientException;
 
-    // TODO: doDiff
+    // TODO: diff
     // TODO: getLog
 
     public native NodeKind checkPath(String path, long revision)
@@ -219,10 +228,28 @@ public class RemoteSession extends JNIOb
     private class RemoteSessionContext extends OperationContext {}
 
     /*
-     * The set of open editors. We need this in order to dispose/abort
-     * the editors when the session is disposed.
+     * A reference to the current open editor. We need this in order
+     * to dispose/abort the editor when the session is disposed. And
+     * furthermore, there can be only one editor active at any time.
      */
-    private HashSet<WeakReference<ISVNEditor>> editors;
+    private WeakReference<ISVNEditor> editorReference;
+
+    /*
+     * The commit editor callse this when disposed to clear the
+     * reference. Note that this function will be called during our
+     * dispose, so make sure they don't step on each others' toes.
+     */
+    void disposeEditor(CommitEditor editor)
+    {
+        if (editorReference == null)
+            return;
+        ISVNEditor ed = editorReference.get();
+        if (ed == null)
+            return;
+        if (ed != editor)
+            throw new IllegalStateException("Disposing unknown editor");
+        editorReference.clear();
+    }
 
     /*
      * Private helper methods.

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java?rev=1497315&r1=1497314&r2=1497315&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java Thu Jun 27 11:53:49 2013
@@ -24,17 +24,22 @@ package org.apache.subversion.javahl;
 
 import org.apache.subversion.javahl.*;
 import org.apache.subversion.javahl.remote.*;
+import org.apache.subversion.javahl.callback.*;
 import org.apache.subversion.javahl.types.*;
 
 import java.util.Arrays;
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.Set;
 import java.util.Map;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.nio.charset.Charset;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
 
 /**
  * This class is used for testing the SVNReposAccess class
@@ -237,13 +242,13 @@ public class SVNRemoteTests extends SVNT
     public void testGetCommitEditor() throws Exception
     {
         ISVNRemote session = getSession();
-        session.getCommitEditor();
+        session.getCommitEditor(null, null, null, false);
     }
 
     public void testDisposeCommitEditor() throws Exception
     {
         ISVNRemote session = getSession();
-        session.getCommitEditor();
+        session.getCommitEditor(null, null, null, false);
         session.dispose();
     }
 
@@ -300,10 +305,8 @@ public class SVNRemoteTests extends SVNT
         }
         catch (ClientException ex)
         {
-            String msg = ex.getMessage();
-            int index = msg.indexOf('\n');
             assertEquals("Disabled repository feature",
-                         msg.substring(0, index));
+                         ex.getAllMessages().get(0).getMessage());
             return;
         }
 
@@ -370,4 +373,25 @@ public class SVNRemoteTests extends SVNT
         for (Map.Entry<String, byte[]> e : properties.entrySet())
             assertTrue(e.getKey().startsWith("svn:entry:"));
     }
+
+    private final class CommitContext implements CommitCallback
+    {
+        public final ISVNEditor editor;
+        public CommitContext(ISVNRemote session, String logstr)
+            throws ClientException
+        {
+            Charset UTF8 = Charset.forName("UTF-8");
+            byte[] log = (logstr == null
+                          ? new byte[0]
+                          : logstr.getBytes(UTF8));
+            HashMap<String, byte[]> revprops = new HashMap<String, byte[]>();
+            revprops.put("svn:log", log);
+            editor = session.getCommitEditor(revprops, this, null, false);
+        }
+
+        public void commitInfo(CommitInfo info) { this.info = info; }
+        public long getRevision() { return info.getRevision(); }
+
+        private CommitInfo info;
+    }
 }



Mime
View raw message