You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2013/08/19 14:07:58 UTC

svn commit: r1515380 [3/15] - in /subversion/branches/move-tracking-1: ./ build/ac-macros/ build/generator/ build/generator/swig/ build/generator/templates/ contrib/client-side/emacs/ doc/programmer/ notes/http-and-webdav/ subversion/ subversion/bindin...

Modified: subversion/branches/move-tracking-1/subversion/bindings/cxxhl/src/exception.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/bindings/cxxhl/src/exception.cpp?rev=1515380&r1=1515379&r2=1515380&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/bindings/cxxhl/src/exception.cpp (original)
+++ subversion/branches/move-tracking-1/subversion/bindings/cxxhl/src/exception.cpp Mon Aug 19 12:07:51 2013
@@ -28,6 +28,8 @@
 #include <sstream>
 
 #include "svncxxhl/exception.hpp"
+#include "private.hpp"
+#include "aprwrap.hpp"
 
 #include "svn_error.h"
 #include "svn_utf.h"
@@ -46,90 +48,104 @@ namespace detail {
 class ErrorDescription
 {
 public:
-  static ErrorDescription* create(const char* message,
-                                  const char *loc_file, long loc_line,
-                                  bool trace_link)
+  typedef compat::shared_ptr<ErrorDescription> shared_ptr;
+
+  static shared_ptr create(const char* message, int error_code,
+                           const char *loc_file, long loc_line,
+                           bool trace_link)
     {
-      bool empty_message = (message == NULL);
+      const bool empty_message = (message == NULL);
       const std::size_t length = (empty_message ? 0 : std::strlen(message));
-      void *memblock = ::operator new(length + sizeof(ErrorDescription));
+      void* memblock = ::operator new(length + sizeof(ErrorDescription));
 
       ErrorDescription* description = new(memblock) ErrorDescription(
-          loc_file, loc_line, trace_link, empty_message);
+          error_code, loc_file, loc_line, trace_link, empty_message);
       if (length)
         std::memcpy(description->m_message, message, length);
       description->m_message[length] = 0;
-      return description;
+      return shared_ptr(description);
     }
 
-  static ErrorDescription* create(const char* message)
+  static shared_ptr create(const char* message, int error_code)
     {
-      return create(message, NULL, 0, false);
+      return create(message, error_code, NULL, 0, false);
     }
 
-  ErrorDescription* reference() throw()
-    {
-      if (this)
-        svn_atomic_inc(&m_refcount);
-      return this;
-    }
-
-  ErrorDescription* dereference() throw()
-    {
-      if (this && 0 == svn_atomic_dec(&m_refcount))
-        {
-          this->~ErrorDescription();
-          ::operator delete(this, std::nothrow);
-          return NULL;
-        }
-      return this;
-    }
+  ~ErrorDescription() throw() {}
 
   const char* what() const throw() { return (m_empty ? NULL : m_message); }
+  int code() const throw() { return m_errno; }
   const char* file() const throw() { return m_loc_file; }
   long line() const throw() { return m_loc_line; }
   bool trace() const throw() { return m_trace; }
+  shared_ptr& nested() throw() { return m_nested; }
+  const shared_ptr& nested() const throw() { return m_nested; }
 
 private:
-  ErrorDescription(const char *loc_file, long loc_line,
+  ErrorDescription(int error_code,
+                   const char *loc_file, long loc_line,
                    bool trace_link, bool empty_message) throw()
     : m_loc_file(loc_file),
       m_loc_line(loc_line),
       m_trace(trace_link),
       m_empty(empty_message),
-      m_refcount(0)
+      m_errno(error_code)
     {}
 
-  ~ErrorDescription() throw() {}
-
   const char* m_loc_file;
   long m_loc_line;
   bool m_trace;
   bool m_empty;
 
-  volatile svn_atomic_t m_refcount;
-  char m_message[1];
+  shared_ptr m_nested;
+
+  int m_errno;                  ///< The (SVN or APR) error code.
+  char m_message[1];            ///< The error message
 };
 
 } // namespace detail
 
+//
+// Class InternalError
+//
 
-Error::Error(const char* description, int error_code)
-  : m_errno(error_code),
-    m_description(detail::ErrorDescription::create(description)->reference())
+InternalError::InternalError(const char* description)
+  : m_description(detail::ErrorDescription::create(description, 0))
 {}
 
-Error::Error(const char* description, int error_code,
-             Error::shared_ptr nested_error)
-  : m_errno(error_code),
-    m_nested(nested_error),
-    m_description(detail::ErrorDescription::create(description)->reference())
+InternalError::InternalError(const InternalError& that) throw()
+  : m_description(that.m_description)
 {}
 
+InternalError& InternalError::operator=(const InternalError& that) throw()
+{
+  if (this == &that)
+    return *this;
+
+  // This in-place destroy+copy implementation of the assignment
+  // operator is safe because both the destructor and the copy
+  // constructor do not throw exceptions.
+  this->~InternalError();
+  return *new(this) InternalError(that);
+}
+
+InternalError::~InternalError() throw() {}
+
+const char* InternalError::what() const throw()
+{
+  return m_description->what();
+}
+
+InternalError::InternalError(description_ptr description) throw()
+  : m_description(description)
+{}
+
+//
+// Class Error
+//
+
 Error::Error(const Error& that) throw()
-  : m_errno(that.m_errno),
-    m_nested(that.m_nested),
-    m_description(that.m_description->reference())
+  : InternalError(that.m_description)
 {}
 
 Error& Error::operator=(const Error& that) throw()
@@ -144,87 +160,50 @@ Error& Error::operator=(const Error& tha
   return *new(this) Error(that);
 }
 
-Error::~Error() throw()
-{
-  m_description->dereference();
-}
+Error::~Error() throw() {}
 
-const char* Error::what() const throw()
+int Error::code() const throw()
 {
-  return m_description->what();
+  return m_description->code();
 }
 
-Error::Error(int error_code, detail::ErrorDescription* description) throw()
-  : m_errno(error_code),
-    m_description(description)
-{}
-
-void Error::throw_svn_error(svn_error_t* err)
+namespace {
+const char* get_generic_message(apr_status_t error_code,
+                                const APR::Pool& scratch_pool)
 {
-  detail::ErrorDescription* description = NULL;
-  try
-    {
-      // Be very careful when creating the error descriptions, so that
-      // the exception unwinder can free them if an allocation fails.
-      // The private constructor does not increment the refcount
-      // precisely for this reason.
+  char errorbuf[512];
 
-      shared_ptr nested;
-      shared_ptr* current = &nested;
+  // Is this a Subversion-specific error code?
+  if (error_code > APR_OS_START_USEERR && error_code <= APR_OS_START_CANONERR)
+    return svn_strerror(error_code, errorbuf, sizeof(errorbuf));
+  // Otherwise, this must be an APR error code.
+  else
+    {
+      const char* generic;
+      svn_error_t* err = svn_utf_cstring_to_utf8(
+          &generic,
+          apr_strerror(error_code, errorbuf, sizeof(errorbuf)),
+          scratch_pool.get());
+      if (!err)
+        return generic;
 
-      bool cancelled = (err->apr_err == SVN_ERR_CANCELLED);
-      for (svn_error_t* next = err->child; next; next = next->child)
-        {
-          description = detail::ErrorDescription::create(
-              next->message, next->file, next->line,
-              svn_error__is_tracing_link(next));
-          description->reference();
-          current->reset(new Error(next->apr_err, description));
-          description = NULL;
-          current = &(*current)->m_nested;
-          if (next->apr_err == SVN_ERR_CANCELLED)
-            cancelled = true;
-        }
-
-      const int apr_err = err->apr_err;
-      description = detail::ErrorDescription::create(
-          err->message, err->file, err->line,
-          svn_error__is_tracing_link(err));
-      description->reference();
+      // Use fuzzy transliteration instead.
       svn_error_clear(err);
-      if (cancelled)
-        {
-          Cancelled converted = Cancelled(apr_err, description);
-          description = NULL;
-          converted.m_nested = nested;
-          throw converted;
-        }
-      else
-        {
-          Error converted = Error(apr_err, description);
-          description = NULL;
-          converted.m_nested = nested;
-          throw converted;
-        }
-    }
-  catch (...)
-    {
-      description->dereference();
-      throw;
+      return svn_utf_cstring_from_utf8_fuzzy(errorbuf, scratch_pool.get());
     }
 }
 
-
-namespace {
 void handle_one_error(Error::MessageList& ml, bool show_traces,
-                      int error_code, detail::ErrorDescription* descr,
-                      apr_pool_t* pool)
+                      const detail::ErrorDescription* descr,
+                      const APR::Pool& pool)
 {
+  const int error_code = descr->code();
+
   if (show_traces && descr->file())
     {
       const char* file_utf8 = NULL;
       svn_error_t* err =
-        svn_utf_cstring_to_utf8(&file_utf8, descr->file(), pool);
+        svn_utf_cstring_to_utf8(&file_utf8, descr->file(), pool.get());
       if (err)
         {
           svn_error_clear(err);
@@ -240,15 +219,13 @@ void handle_one_error(Error::MessageList
       else
         {
 #ifdef SVN_DEBUG
-          if (const char *const symbolic_name =
-              svn_error_symbolic_name(error_code))
-            //if (symbolic_name)
+          if (const char* symbolic_name = svn_error_symbolic_name(error_code))
             buffer << ": (apr_err=" << symbolic_name << ')';
           else
 #endif
             buffer << ": (apr_err=" << error_code << ')';
         }
-      ml.push_back(Error::Message(0, buffer.str()));
+      ml.push_back(Error::Message(error_code, buffer.str(), true));
     }
 
   if (descr->trace())
@@ -256,28 +233,8 @@ void handle_one_error(Error::MessageList
 
   const char *description = descr->what();
   if (!description)
-    {
-      char errorbuf[512];
-
-      // Is this a Subversion-specific error code?
-      if (error_code > APR_OS_START_USEERR
-          && error_code <= APR_OS_START_CANONERR)
-        description = svn_strerror(error_code, errorbuf, sizeof(errorbuf));
-      // Otherwise, this must be an APR error code.
-      else
-        {
-          svn_error_t* err = svn_utf_cstring_to_utf8(
-              &description,
-              apr_strerror(error_code, errorbuf, sizeof(errorbuf)),
-              pool);
-          if (err)
-            {
-              svn_error_clear(err);
-              description = _("Can't recode error string from APR");
-            }
-        }
-    }
-  ml.push_back(Error::Message(error_code, std::string(description)));
+    description = get_generic_message(error_code, pool);
+  ml.push_back(Error::Message(error_code, std::string(description), false));
 }
 } // anonymous namespace
 
@@ -285,11 +242,12 @@ Error::MessageList Error::compile_messag
 {
   // Determine the maximum size of the returned list
   MessageList::size_type max_length = 0;
-  for (const Error* err = this; err; err = err->m_nested.get())
+  for (const detail::ErrorDescription* description = m_description.get();
+       description; description = description->nested().get())
     {
-      if (show_traces && m_description->file())
+      if (show_traces && description->file())
         ++max_length;                   // We will display an error location
-      if (!m_description->trace())
+      if (!description->trace())
         ++max_length;                   // Traces do not emit a message line
     }
   MessageList ml;
@@ -300,36 +258,74 @@ Error::MessageList Error::compile_messag
   std::vector<int> empties;
   empties.reserve(max_length);
 
-  apr_pool_t* pool = NULL;
-  apr_pool_create(&pool, NULL);
-  try
+  APR::IterationPool iterbase;
+  for (const detail::ErrorDescription* description = m_description.get();
+       description; description = description->nested().get())
     {
-      for (const Error* err = this; err; err = err->m_nested.get())
+      APR::Pool::Iteration iterpool(iterbase);
+
+      if (!description->what())
         {
-          if (!err->m_description->what())
-            {
-              // Non-specific messages are printed only once.
-              std::vector<int>::iterator it = std::find(
-                  empties.begin(), empties.end(), err->m_errno);
-              if (it != empties.end())
-                continue;
-              empties.push_back(err->m_errno);
-            }
-          handle_one_error(ml, show_traces,
-                           err->m_errno, err->m_description,
-                           pool);
+          // Non-specific messages are printed only once.
+          std::vector<int>::iterator it = std::find(
+              empties.begin(), empties.end(), description->code());
+          if (it != empties.end())
+            continue;
+          empties.push_back(description->code());
         }
+      handle_one_error(ml, show_traces, description, iterpool.pool());
     }
-  catch (...)
-    {
-      apr_pool_destroy(pool);
-      throw;
-    }
-
-  apr_pool_destroy(pool);
   return ml;
 }
 
+const char* Error::Message::generic_message() const
+{
+  APR::Pool pool;
+  return get_generic_message(m_errno, pool);
+}
+
+namespace detail {
+void checked_call(svn_error_t* err)
+{
+  if (!err)
+    return;
+
+  struct ErrorBuilder : public Error
+  {
+    explicit ErrorBuilder (ErrorDescription::shared_ptr description)
+      : Error(description)
+      {}
+  };
+
+  struct CancelledBuilder : public Cancelled
+  {
+    explicit CancelledBuilder (ErrorDescription::shared_ptr description)
+      : Cancelled(description)
+      {}
+  };
+
+  ErrorDescription::shared_ptr description;
+  ErrorDescription::shared_ptr* current = &description;
+
+  bool cancelled = false;
+  for (svn_error_t* next = err; next; next = next->child)
+    {
+      *current = ErrorDescription::create(next->message, next->apr_err,
+                                          next->file, next->line,
+                                          svn_error__is_tracing_link(next));
+      current = &(*current)->nested();
+      if (next->apr_err == SVN_ERR_CANCELLED)
+        cancelled = true;
+    }
+  svn_error_clear(err);
+
+  if (cancelled)
+    throw CancelledBuilder(description);
+  else
+    throw ErrorBuilder(description);
+}
+} // namespace detail
+
 } // namespace cxxhl
 } // namespace subversion
 } // namespace apache

Modified: subversion/branches/move-tracking-1/subversion/bindings/cxxhl/tests/test_exception.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/bindings/cxxhl/tests/test_exception.cpp?rev=1515380&r1=1515379&r2=1515380&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/bindings/cxxhl/tests/test_exception.cpp (original)
+++ subversion/branches/move-tracking-1/subversion/bindings/cxxhl/tests/test_exception.cpp Mon Aug 19 12:07:51 2013
@@ -26,52 +26,16 @@
 #include <iostream>
 
 #include "svncxxhl.hpp"
+#include "../src/private.hpp"
 
 #include <apr.h>
 #include "svn_error.h"
+#undef TRUE
+#undef FALSE
 
-namespace {
-void trace(const SVN::Error::Message& msg)
-{
-  std::cout << "    ";
-  if (msg.first)
-    std::cout << "test_exception: E"
-              << std::setw(6) << std::setfill('0') << std::right
-              << msg.first << ':' << ' ';
-  std::cout << msg.second << std::endl;
-}
-
-void traceall(const char *message, const SVN::Error& err)
-{
-  typedef SVN::Error::MessageList MessageList;
-  std::cout << message << std::endl;
-  std::cout << "Traced Messages:" << std::endl;
-  MessageList ml = err.traced_messages();
-  std::for_each(ml.begin(), ml.end(), trace);
-  std::cout << "Just Messages:" << std::endl;
-  ml = err.messages();
-  std::for_each(ml.begin(), ml.end(), trace);
-}
-
-void tracecheck(svn_error_t* err)
-{
-  std::cout << "C-API handler:" << std::endl;
-  svn_handle_error2(err, stdout, false, "    test_exception");
-  svn_error_clear(err);
-}
-
-svn_error_t* make_cancel_test_error()
-{
-  svn_error_t* err;
-  err = svn_error_create(SVN_ERR_CANCELLED, NULL, NULL);
-  err = svn_error_create(SVN_ERR_CANCELLED, err, NULL);
-  err = svn_error_trace(err);
-  err = svn_error_create(SVN_ERR_TEST_FAILED, err, "original message");
-  err = svn_error_create(SVN_ERR_BASE, err, "wrapper message");
-  err = svn_error_trace(err);
-  return err;
-}
+#include <gmock/gmock.h>
 
+namespace {
 svn_error_t* make_error_test_error()
 {
   svn_error_t* err;
@@ -85,67 +49,85 @@ svn_error_t* make_error_test_error()
 }
 } // anonymous namespace
 
-
-bool test_cancel()
+TEST(Exceptions, CatchError)
 {
   try
     {
-      SVN::Error::throw_svn_error(make_cancel_test_error());
-    }
-  catch (const SVN::Cancelled& err)
-    {
-      traceall("Caught: CANCELLED", err);
-      tracecheck(make_cancel_test_error());
-      return true;
+      SVN::detail::checked_call(make_error_test_error());
     }
   catch (const SVN::Error& err)
     {
-      traceall("Caught: ERROR", err);
-      tracecheck(make_cancel_test_error());
-      return false;
-    }
-  catch (...)
-    {
-      return false;
+      SVN::Error::MessageList ml = err.messages();
+      EXPECT_EQ(3, ml.size());
+      EXPECT_EQ(SVN_ERR_UNSUPPORTED_FEATURE, ml[0].code());
+      EXPECT_EQ(SVN_ERR_BASE, ml[1].code());
+      EXPECT_EQ(SVN_ERR_TEST_FAILED, ml[2].code());
+
+      SVN::Error::MessageList tml = err.traced_messages();
+#ifdef SVN_DEBUG
+      EXPECT_EQ(8, tml.size());
+      EXPECT_EQ(SVN_ERR_UNSUPPORTED_FEATURE, tml[0].code());
+      EXPECT_EQ(SVN_ERR_UNSUPPORTED_FEATURE, tml[1].code());
+      EXPECT_EQ(SVN_ERR_UNSUPPORTED_FEATURE, tml[2].code());
+      EXPECT_EQ(SVN_ERR_BASE, tml[3].code());
+      EXPECT_EQ(SVN_ERR_BASE, tml[4].code());
+      EXPECT_EQ(SVN_ERR_BASE, tml[5].code());
+      EXPECT_EQ(SVN_ERR_TEST_FAILED, tml[6].code());
+      EXPECT_EQ(SVN_ERR_TEST_FAILED, tml[7].code());
+#else  // !SVN_DEBUG
+      EXPECT_EQ(3, tml.size());
+      EXPECT_EQ(SVN_ERR_UNSUPPORTED_FEATURE, tml[0].code());
+      EXPECT_EQ(SVN_ERR_BASE, tml[1].code());
+      EXPECT_EQ(SVN_ERR_TEST_FAILED, tml[2].code());
+#endif // SVN_DEBUG
     }
-  return false;
 }
 
-int test_error()
+
+namespace {
+svn_error_t* make_cancel_test_error()
+{
+  svn_error_t* err;
+  err = svn_error_create(SVN_ERR_CANCELLED, NULL, NULL);
+  err = svn_error_create(SVN_ERR_CANCELLED, err, NULL);
+  err = svn_error_trace(err);
+  err = svn_error_create(SVN_ERR_TEST_FAILED, err, "original message");
+  err = svn_error_create(SVN_ERR_BASE, err, "wrapper message");
+  err = svn_error_trace(err);
+  return err;
+}
+} // anonymous namespace
+
+TEST(Exceptions, CatchCancelled)
 {
   try
     {
-      SVN::Error::throw_svn_error(make_error_test_error());
+      SVN::detail::checked_call(make_cancel_test_error());
     }
   catch (const SVN::Cancelled& err)
     {
-      traceall("Caught: CANCELLED", err);
-      tracecheck(make_error_test_error());
-      return false;
-    }
-  catch (const SVN::Error& err)
-    {
-      traceall("Caught: ERROR", err);
-      tracecheck(make_error_test_error());
-      return true;
-    }
-  catch (...)
-    {
-      return false;
+      SVN::Error::MessageList ml = err.messages();
+      EXPECT_EQ(3, ml.size());
+      EXPECT_EQ(SVN_ERR_BASE, ml[0].code());
+      EXPECT_EQ(SVN_ERR_TEST_FAILED, ml[1].code());
+      EXPECT_EQ(SVN_ERR_CANCELLED, ml[2].code());
+
+      SVN::Error::MessageList tml = err.traced_messages();
+#ifdef SVN_DEBUG
+      EXPECT_EQ(8, tml.size());
+      EXPECT_EQ(SVN_ERR_BASE, tml[0].code());
+      EXPECT_EQ(SVN_ERR_BASE, tml[1].code());
+      EXPECT_EQ(SVN_ERR_BASE, tml[2].code());
+      EXPECT_EQ(SVN_ERR_TEST_FAILED, tml[3].code());
+      EXPECT_EQ(SVN_ERR_TEST_FAILED, tml[4].code());
+      EXPECT_EQ(SVN_ERR_CANCELLED, tml[5].code());
+      EXPECT_EQ(SVN_ERR_CANCELLED, tml[6].code());
+      EXPECT_EQ(SVN_ERR_CANCELLED, tml[7].code());
+#else  // !SVN_DEBUG
+      EXPECT_EQ(3, tml.size());
+      EXPECT_EQ(SVN_ERR_BASE, tml[0].code());
+      EXPECT_EQ(SVN_ERR_TEST_FAILED, tml[1].code());
+      EXPECT_EQ(SVN_ERR_CANCELLED, tml[2].code());
+#endif // SVN_DEBUG
     }
-  return false;
-}
-
-int main()
-{
-  apr_initialize();
-
-  const char *stat  = (test_cancel() ? "OK" : "ERROR");
-  std::cerr << "test_cancel .... " << stat << std::endl;
-
-  stat = (test_error() ? "OK" : "ERROR");
-  std::cerr << "test_error ..... " << stat << std::endl;
-
-  apr_terminate();
-  return 0;
 }

Modified: subversion/branches/move-tracking-1/subversion/bindings/javahl/native/CommitEditor.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/bindings/javahl/native/CommitEditor.cpp?rev=1515380&r1=1515379&r2=1515380&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/bindings/javahl/native/CommitEditor.cpp (original)
+++ subversion/branches/move-tracking-1/subversion/bindings/javahl/native/CommitEditor.cpp Mon Aug 19 12:07:51 2013
@@ -30,7 +30,7 @@
 #include "Iterator.h"
 #include "JNIByteArray.h"
 #include "LockTokenTable.h"
-#include "RevpropTable.h"
+#include "PropertyTable.h"
 #include "RemoteSession.h"
 
 #include <apr_tables.h>
@@ -69,7 +69,6 @@ CommitEditor::createInstance(jobject jse
   return editor->getCppAddr();
 }
 
-
 CommitEditor::CommitEditor(RemoteSession* session,
                            jobject jrevprops, jobject jcommit_callback,
                            jobject jlock_tokens, jboolean jkeep_locks)
@@ -90,7 +89,7 @@ CommitEditor::CommitEditor(RemoteSession
                                &m_callback_session_uuid,
                                pool.getPool()),);
 
-  RevpropTable revprops(jrevprops, true);
+  PropertyTable revprops(jrevprops, true);
   if (JNIUtil::isJavaExceptionThrown())
     return;
   LockTokenTable lock_tokens(jlock_tokens);
@@ -105,8 +104,8 @@ CommitEditor::CommitEditor(RemoteSession
                   m_callback.callback, &m_callback,
                   lock_tokens.hash(subPool, true),
                   bool(jkeep_locks),
-                  NULL,               // svn_ra__provide_base_cb_t
-                  NULL,               // svn_ra__provide_props_cb_t
+                  this->provide_base_cb,
+                  this->provide_props_cb,
                   this->get_copysrc_kind_cb, this,
                   pool.getPool(),     // result pool
                   subPool.getPool()), // scratch pool
@@ -265,7 +264,7 @@ void CommitEditor::addDirectory(jstring 
   Iterator children(jchildren);
   if (JNIUtil::isJavaExceptionThrown())
     return;
-  RevpropTable properties(jproperties, true);
+  PropertyTable properties(jproperties, true);
   if (JNIUtil::isJavaExceptionThrown())
     return;
 
@@ -290,7 +289,7 @@ void CommitEditor::addFile(jstring jrelp
   SVN_JNI_ERR(m_session->m_context->checkCancel(m_session->m_context),);
 
   InputStream contents(jcontents);
-  RevpropTable properties(jproperties, true);
+  PropertyTable properties(jproperties, true);
   if (JNIUtil::isJavaExceptionThrown())
     return;
 
@@ -342,7 +341,7 @@ void CommitEditor::alterDirectory(jstrin
   Iterator children(jchildren);
   if (JNIUtil::isJavaExceptionThrown())
     return;
-  RevpropTable properties(jproperties, true);
+  PropertyTable properties(jproperties, true);
   if (JNIUtil::isJavaExceptionThrown())
     return;
 
@@ -366,7 +365,7 @@ void CommitEditor::alterFile(jstring jre
   SVN_JNI_ERR(m_session->m_context->checkCancel(m_session->m_context),);
 
   InputStream contents(jcontents);
-  RevpropTable properties(jproperties, true);
+  PropertyTable properties(jproperties, true);
   if (JNIUtil::isJavaExceptionThrown())
     return;
 
@@ -487,23 +486,20 @@ void CommitEditor::abort()
 }
 
 
-svn_error_t*
-CommitEditor::get_copysrc_kind_cb(svn_node_kind_t* kind, void* baton,
-                                  const char* repos_relpath,
-                                  svn_revnum_t src_revision,
-                                  apr_pool_t *scratch_pool)
+namespace {
+svn_error_t* open_callback_session(svn_ra_session_t*& session,
+                                   const char* url, const char* uuid,
+                                   RemoteSessionContext* context,
+                                   SVN::Pool& sessionPool)
 {
-  CommitEditor* editor = static_cast<CommitEditor*>(baton);
-  if (!editor->m_callback_session)
+  if (!session)
     {
-      const char* corrected_url;
-      SVN_ERR(svn_ra_open4(&editor->m_callback_session, &corrected_url,
-                           editor->m_callback_session_url,
-                           editor->m_callback_session_uuid,
-                           editor->m_session->m_context->getCallbacks(),
-                           editor->m_session->m_context->getCallbackBaton(),
-                           editor->m_session->m_context->getConfigData(),
-                           editor->pool.getPool()));
+      const char* corrected_url = NULL;
+      SVN_ERR(svn_ra_open4(&session, &corrected_url, url, uuid,
+                           context->getCallbacks(),
+                           context->getCallbackBaton(),
+                           context->getConfigData(),
+                           sessionPool.getPool()));
 
       if (corrected_url)
         {
@@ -515,12 +511,79 @@ CommitEditor::get_copysrc_kind_cb(svn_no
               SVN_ERR_RA_ILLEGAL_URL, NULL,
               _("Repository URL changed while session was open.\n"
                 "Expected URL: %s\nApparent URL: %s"),
-              editor->m_callback_session_url, corrected_url);
+              url, corrected_url);
         }
     }
+  return SVN_NO_ERROR;
+}
+} // anonymous namespace
+
+
+svn_error_t*
+CommitEditor::provide_base_cb(svn_stream_t **contents,
+                              svn_revnum_t *revision,
+                              void *baton,
+                              const char *repos_relpath,
+                              apr_pool_t *result_pool,
+                              apr_pool_t *scratch_pool)
+{
+  *contents = NULL;
+  *revision = SVN_INVALID_REVNUM;
+  return SVN_NO_ERROR;
+}
+
+svn_error_t*
+CommitEditor::provide_props_cb(apr_hash_t **props,
+                               svn_revnum_t *revision,
+                               void *baton,
+                               const char *repos_relpath,
+                               apr_pool_t *result_pool,
+                               apr_pool_t *scratch_pool)
+{
+  CommitEditor* editor = static_cast<CommitEditor*>(baton);
+  SVN_ERR(open_callback_session(editor->m_callback_session,
+                                editor->m_callback_session_url,
+                                editor->m_callback_session_uuid,
+                                editor->m_session->m_context,
+                                editor->pool));
+
+  svn_node_kind_t kind = svn_node_unknown;
+  SVN_ERR(svn_ra_check_path(editor->m_callback_session,
+                            repos_relpath, SVN_INVALID_REVNUM, &kind,
+                            scratch_pool));
+
+  // FIXME: Getting properties from the youngest revision is in fact
+  // not such a bright idea, as the path may have been moved or
+  // deleted in the path.
+  if (kind == svn_node_file)
+    return svn_ra_get_file(editor->m_callback_session,
+                           repos_relpath, SVN_INVALID_REVNUM,
+                           NULL, revision, props, scratch_pool);
+  else if (kind == svn_node_dir)
+    return svn_ra_get_dir2(editor->m_callback_session, NULL, revision, props,
+                           repos_relpath, SVN_INVALID_REVNUM, 0, scratch_pool);
+  else
+    return svn_error_createf(SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
+                             _("Expected node kind '%s' or '%s' but got '%s'"),
+                             svn_node_kind_to_word(svn_node_file),
+                             svn_node_kind_to_word(svn_node_dir),
+                             svn_node_kind_to_word(kind));
+}
+
+svn_error_t*
+CommitEditor::get_copysrc_kind_cb(svn_node_kind_t* kind, void* baton,
+                                  const char* repos_relpath,
+                                  svn_revnum_t src_revision,
+                                  apr_pool_t *scratch_pool)
+{
+  CommitEditor* editor = static_cast<CommitEditor*>(baton);
+  SVN_ERR(open_callback_session(editor->m_callback_session,
+                                editor->m_callback_session_url,
+                                editor->m_callback_session_uuid,
+                                editor->m_session->m_context,
+                                editor->pool));
 
-  SVN::Pool subPool(editor->pool);
   return svn_ra_check_path(editor->m_callback_session,
                            repos_relpath, src_revision, kind,
-                           subPool.getPool());
+                           scratch_pool);
 }

Modified: subversion/branches/move-tracking-1/subversion/bindings/javahl/native/CommitEditor.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/bindings/javahl/native/CommitEditor.h?rev=1515380&r1=1515379&r2=1515380&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/bindings/javahl/native/CommitEditor.h (original)
+++ subversion/branches/move-tracking-1/subversion/bindings/javahl/native/CommitEditor.h Mon Aug 19 12:07:51 2013
@@ -90,7 +90,19 @@ private:
                jobject jrevprops, jobject jcommit_callback,
                jobject jlock_tokens, jboolean jkeep_locks);
 
-  // This is our svn_ra__get_copysrc_kind_cb_t for the commit editor.
+  // This is our private callbacks for the commit editor.
+  static svn_error_t* provide_base_cb(svn_stream_t **contents,
+                                      svn_revnum_t *revision,
+                                      void *baton,
+                                      const char *repos_relpath,
+                                      apr_pool_t *result_pool,
+                                      apr_pool_t *scratch_pool);
+  static svn_error_t* provide_props_cb(apr_hash_t **props,
+                                       svn_revnum_t *revision,
+                                       void *baton,
+                                       const char *repos_relpath,
+                                       apr_pool_t *result_pool,
+                                       apr_pool_t *scratch_pool);
   static svn_error_t* get_copysrc_kind_cb(svn_node_kind_t* kind, void* baton,
                                           const char* repos_relpath,
                                           svn_revnum_t src_revision,

Modified: subversion/branches/move-tracking-1/subversion/bindings/javahl/native/CreateJ.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/bindings/javahl/native/CreateJ.cpp?rev=1515380&r1=1515379&r2=1515380&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/bindings/javahl/native/CreateJ.cpp (original)
+++ subversion/branches/move-tracking-1/subversion/bindings/javahl/native/CreateJ.cpp Mon Aug 19 12:07:51 2013
@@ -30,6 +30,7 @@
 #include "JNIStringHolder.h"
 #include "EnumMapper.h"
 #include "RevisionRange.h"
+#include "RevisionRangeList.h"
 #include "CreateJ.h"
 #include "../include/org_apache_subversion_javahl_types_Revision.h"
 #include "../include/org_apache_subversion_javahl_CommitItemStateFlags.h"
@@ -1073,82 +1074,129 @@ CreateJ::CommitInfo(const svn_commit_inf
 }
 
 jobject
-CreateJ::RevisionRangeList(svn_rangelist_t *ranges)
+CreateJ::StringSet(const apr_array_header_t *strings)
 {
-  JNIEnv *env = JNIUtil::getEnv();
-
-  // Create a local frame for our references
-  env->PushLocalFrame(LOCAL_FRAME_SIZE);
-  if (JNIUtil::isJavaExceptionThrown())
-    return NULL;
-
-  jclass clazz = env->FindClass("java/util/ArrayList");
-  if (JNIUtil::isJavaExceptionThrown())
-    POP_AND_RETURN_NULL;
+  std::vector<jobject> jstrs;
 
-  static jmethodID init_mid = 0;
-  if (init_mid == 0)
+  for (int i = 0; i < strings->nelts; ++i)
     {
-      init_mid = env->GetMethodID(clazz, "<init>", "()V");
+      const char *str = APR_ARRAY_IDX(strings, i, const char *);
+      jstring jstr = JNIUtil::makeJString(str);
       if (JNIUtil::isJavaExceptionThrown())
-        POP_AND_RETURN_NULL;
-    }
+        return NULL;
 
-  static jmethodID add_mid = 0;
-  if (add_mid == 0)
-    {
-      add_mid = env->GetMethodID(clazz, "add", "(Ljava/lang/Object;)Z");
-      if (JNIUtil::isJavaExceptionThrown())
-        POP_AND_RETURN_NULL;
+      jstrs.push_back(jstr);
     }
 
-  jobject jranges = env->NewObject(clazz, init_mid);
+  return CreateJ::Set(jstrs);
+}
 
-  for (int i = 0; i < ranges->nelts; ++i)
-    {
-      // Convert svn_merge_range_t *'s to Java RevisionRange objects.
-      svn_merge_range_t *range =
-          APR_ARRAY_IDX(ranges, i, svn_merge_range_t *);
+namespace {
+void fill_property_map(jobject map,
+                       apr_hash_t* prop_hash, apr_array_header_t* prop_diffs,
+                       apr_pool_t* scratch_pool, jmethodID put_mid)
+{
+  SVN_ERR_ASSERT_NO_RETURN(!prop_hash != !prop_diffs
+                           || !prop_hash && !prop_diffs);
 
-      jobject jrange = RevisionRange::makeJRevisionRange(range);
-      if (JNIUtil::isJavaExceptionThrown())
-        POP_AND_RETURN_NULL;
+  if (!map || (prop_hash == NULL && prop_diffs == NULL))
+    return;
 
-      env->CallBooleanMethod(jranges, add_mid, jrange);
-      if (JNIUtil::isJavaExceptionThrown())
-        POP_AND_RETURN_NULL;
+  JNIEnv *env = JNIUtil::getEnv();
 
-      env->DeleteLocalRef(jrange);
+  // Create a local frame for our references
+  env->PushLocalFrame(LOCAL_FRAME_SIZE);
+  if (JNIUtil::isJavaExceptionThrown())
+    return;
+
+  // The caller may not know the concrete class of the map, so
+  // determine the "put" method identifier here.
+  if (put_mid == 0)
+    {
+      put_mid = env->GetMethodID(env->GetObjectClass(map), "put",
+                                 "(Ljava/lang/Object;Ljava/lang/Object;)"
+                                 "Ljava/lang/Object;");
+      if (JNIUtil::isJavaExceptionThrown())
+        POP_AND_RETURN_NOTHING();
     }
 
-  return env->PopLocalFrame(jranges);
-}
+  struct body
+  {
+    void operator()(const char* key, const svn_string_t* val)
+      {
+        jstring jpropName = JNIUtil::makeJString(key);
+        if (JNIUtil::isJavaExceptionThrown())
+          return;
+
+        jbyteArray jpropVal = (!val ? NULL
+                               : JNIUtil::makeJByteArray(val));
+        if (JNIUtil::isJavaExceptionThrown())
+          return;
+
+        m_env->CallObjectMethod(m_map, m_put_mid, jpropName, jpropVal);
+        if (JNIUtil::isJavaExceptionThrown())
+          return;
+
+        m_env->DeleteLocalRef(jpropName);
+        m_env->DeleteLocalRef(jpropVal);
+      }
+
+    JNIEnv*& m_env;
+    jmethodID& m_put_mid;
+    jobject& m_map;
+
+    body(JNIEnv*& xenv, jmethodID& xput_mid, jobject& xmap)
+      : m_env(xenv), m_put_mid(xput_mid), m_map(xmap)
+      {}
+  } loop_body(env, put_mid, map);
+
+  if (prop_hash)
+    {
+      if (!scratch_pool)
+        scratch_pool = apr_hash_pool_get(prop_hash);
+
+      apr_hash_index_t *hi;
+      for (hi = apr_hash_first(scratch_pool, prop_hash);
+           hi; hi = apr_hash_next(hi))
+        {
+          const char* key;
+          svn_string_t* val;
 
-jobject
-CreateJ::StringSet(const apr_array_header_t *strings)
-{
-  std::vector<jobject> jstrs;
+          const void* v_key;
+          void* v_val;
 
-  for (int i = 0; i < strings->nelts; ++i)
-    {
-      const char *str = APR_ARRAY_IDX(strings, i, const char *);
-      jstring jstr = JNIUtil::makeJString(str);
-      if (JNIUtil::isJavaExceptionThrown())
-        return NULL;
+          apr_hash_this(hi, &v_key, NULL, &v_val);
+          key = static_cast<const char*>(v_key);
+          val = static_cast<svn_string_t*>(v_val);
 
-      jstrs.push_back(jstr);
+          loop_body(key, val);
+          if (JNIUtil::isJavaExceptionThrown())
+            POP_AND_RETURN_NOTHING();
+        }
+    }
+  else
+    {
+      for (int i = 0; i < prop_diffs->nelts; ++i)
+        {
+          svn_prop_t* prop = APR_ARRAY_IDX(prop_diffs, i, svn_prop_t*);
+          loop_body(prop->name, prop->value);
+          if (JNIUtil::isJavaExceptionThrown())
+            POP_AND_RETURN_NOTHING();
+        }
     }
-
-  return CreateJ::Set(jstrs);
 }
 
-jobject CreateJ::PropertyMap(apr_hash_t *prop_hash, apr_pool_t* scratch_pool)
+jobject property_map(apr_hash_t *prop_hash, apr_array_header_t* prop_diffs,
+                     apr_pool_t* scratch_pool)
 {
-  JNIEnv *env = JNIUtil::getEnv();
+  SVN_ERR_ASSERT_NO_RETURN(!prop_hash != !prop_diffs
+                           || !prop_hash && !prop_diffs);
 
-  if (prop_hash == NULL)
+  if (prop_hash == NULL && prop_diffs == NULL)
     return NULL;
 
+  JNIEnv *env = JNIUtil::getEnv();
+
   // Create a local frame for our references
   env->PushLocalFrame(LOCAL_FRAME_SIZE);
   if (JNIUtil::isJavaExceptionThrown())
@@ -1180,69 +1228,35 @@ jobject CreateJ::PropertyMap(apr_hash_t 
   if (JNIUtil::isJavaExceptionThrown())
     POP_AND_RETURN_NULL;
 
-  FillPropertyMap(map, prop_hash, scratch_pool, put_mid);
+  fill_property_map(map, prop_hash, prop_diffs, scratch_pool, put_mid);
   if (JNIUtil::isJavaExceptionThrown())
     POP_AND_RETURN_NULL;
 
   return env->PopLocalFrame(map);
 }
+} // anonymous namespace
 
-void CreateJ::FillPropertyMap(jobject map, apr_hash_t* prop_hash,
-                              apr_pool_t* scratch_pool, jmethodID put_mid)
+jobject CreateJ::PropertyMap(apr_hash_t *prop_hash, apr_pool_t* scratch_pool)
 {
-  JNIEnv *env = JNIUtil::getEnv();
-
-  if (!map || !prop_hash)
-    return;
-
-  // Create a local frame for our references
-  env->PushLocalFrame(LOCAL_FRAME_SIZE);
-  if (JNIUtil::isJavaExceptionThrown())
-    return;
-
-  // The caller may not know the concrete class of the map, so
-  // determine the "put" method identifier here.
-  if (put_mid == 0)
-    {
-      put_mid = env->GetMethodID(env->GetObjectClass(map), "put",
-                                 "(Ljava/lang/Object;Ljava/lang/Object;)"
-                                 "Ljava/lang/Object;");
-      if (JNIUtil::isJavaExceptionThrown())
-        POP_AND_RETURN_NOTHING();
-    }
-
-  if (!scratch_pool)
-    scratch_pool = apr_hash_pool_get(prop_hash);
-
-  apr_hash_index_t *hi;
-  for (hi = apr_hash_first(scratch_pool, prop_hash);
-       hi; hi = apr_hash_next(hi))
-    {
-      const char *key;
-      svn_string_t *val;
-
-      const void *v_key;
-      void *v_val;
-
-      apr_hash_this(hi, &v_key, NULL, &v_val);
-      key = static_cast<const char*>(v_key);
-      val = static_cast<svn_string_t*>(v_val);
-
-      jstring jpropName = JNIUtil::makeJString(key);
-      if (JNIUtil::isJavaExceptionThrown())
-        POP_AND_RETURN_NOTHING();
+  return property_map(prop_hash, NULL, scratch_pool);
+}
 
-      jbyteArray jpropVal = JNIUtil::makeJByteArray(val);
-      if (JNIUtil::isJavaExceptionThrown())
-        POP_AND_RETURN_NOTHING();
+jobject CreateJ::PropertyMap(apr_array_header_t* prop_diffs,
+                             apr_pool_t* scratch_pool)
+{
+  return property_map(NULL, prop_diffs, scratch_pool);
+}
 
-      env->CallObjectMethod(map, put_mid, jpropName, jpropVal);
-      if (JNIUtil::isJavaExceptionThrown())
-        POP_AND_RETURN_NOTHING();
+void CreateJ::FillPropertyMap(jobject map, apr_hash_t* prop_hash,
+                              apr_pool_t* scratch_pool, jmethodID put_mid)
+{
+  fill_property_map(map, prop_hash, NULL, scratch_pool, put_mid);
+}
 
-      env->DeleteLocalRef(jpropName);
-      env->DeleteLocalRef(jpropVal);
-    }
+void CreateJ::FillPropertyMap(jobject map, apr_array_header_t* prop_diffs,
+                              apr_pool_t* scratch_pool, jmethodID put_mid)
+{
+  fill_property_map(map, NULL, prop_diffs, scratch_pool, put_mid);
 }
 
 jobject CreateJ::InheritedProps(apr_array_header_t *iprops)
@@ -1370,7 +1384,7 @@ jobject CreateJ::Mergeinfo(svn_mergeinfo
       jstring jpath =
         JNIUtil::makeJString(static_cast<const char*>(path));
       jobject jranges =
-        RevisionRangeList(static_cast<svn_rangelist_t*>(val));
+        RevisionRangeList(static_cast<svn_rangelist_t*>(val)).toList();
 
       env->CallVoidMethod(jmergeinfo, addRevisions, jpath, jranges);
 

Modified: subversion/branches/move-tracking-1/subversion/bindings/javahl/native/CreateJ.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/bindings/javahl/native/CreateJ.h?rev=1515380&r1=1515379&r2=1515380&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/bindings/javahl/native/CreateJ.h (original)
+++ subversion/branches/move-tracking-1/subversion/bindings/javahl/native/CreateJ.h Mon Aug 19 12:07:51 2013
@@ -82,19 +82,24 @@ class CreateJ
   CommitInfo(const svn_commit_info_t *info);
 
   static jobject
-  RevisionRangeList(svn_rangelist_t *ranges);
-
-  static jobject
   StringSet(const apr_array_header_t *strings);
 
   static jobject
   PropertyMap(apr_hash_t *prop_hash, apr_pool_t* scratch_pool = NULL);
 
+  static jobject
+  PropertyMap(apr_array_header_t* prop_diffs, apr_pool_t* scratch_pool = NULL);
+
   static void
   FillPropertyMap(jobject map, apr_hash_t* prop_hash,
                   apr_pool_t* scratch_pool,
                   jmethodID put_method_id = 0);
 
+  static void
+  FillPropertyMap(jobject map, apr_array_header_t* prop_diffs,
+                  apr_pool_t* scratch_pool,
+                  jmethodID put_method_id = 0);
+
   static jobject
   InheritedProps(apr_array_header_t *inherited_props);
 

Modified: subversion/branches/move-tracking-1/subversion/bindings/javahl/native/JNIUtil.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/bindings/javahl/native/JNIUtil.cpp?rev=1515380&r1=1515379&r2=1515380&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/bindings/javahl/native/JNIUtil.cpp (original)
+++ subversion/branches/move-tracking-1/subversion/bindings/javahl/native/JNIUtil.cpp Mon Aug 19 12:07:51 2013
@@ -908,11 +908,9 @@ JNIUtil::getDate(jobject jdate)
  */
 jbyteArray JNIUtil::makeJByteArray(const void *data, int length)
 {
-  if (data == NULL)
-    {
-      // a NULL will create no Java array
-      return NULL;
-    }
+  // a NULL will create no Java array
+  if (!data)
+    return NULL;
 
   JNIEnv *env = getEnv();
 
@@ -943,6 +941,10 @@ jbyteArray JNIUtil::makeJByteArray(const
  */
 jbyteArray JNIUtil::makeJByteArray(const svn_string_t *str)
 {
+  // a NULL will create no Java array
+  if (!str)
+    return NULL;
+
   return JNIUtil::makeJByteArray(str->data, static_cast<int>(str->len));
 }
 

Modified: subversion/branches/move-tracking-1/subversion/bindings/javahl/native/RemoteSession.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/bindings/javahl/native/RemoteSession.cpp?rev=1515380&r1=1515379&r2=1515380&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/bindings/javahl/native/RemoteSession.cpp (original)
+++ subversion/branches/move-tracking-1/subversion/bindings/javahl/native/RemoteSession.cpp Mon Aug 19 12:07:51 2013
@@ -110,8 +110,8 @@ RemoteSession::open(jint jretryAttempts,
 
   jobject jremoteSession = open(
       jretryAttempts, url.c_str(), uuid,
-      configDirectory.c_str(), jconfigHandler,
-      usernameStr, passwordStr, prompter, jprogress);
+      (jconfigDirectory ? configDirectory.c_str() : NULL),
+      jconfigHandler, usernameStr, passwordStr, prompter, jprogress);
   if (JNIUtil::isExceptionThrown() || !jremoteSession)
     {
       delete prompter;
@@ -125,7 +125,7 @@ RemoteSession::open(jint jretryAttempts,
                     const char* url, const char* uuid,
                     const char* configDirectory, jobject jconfigHandler,
                     const char*  usernameStr, const char*  passwordStr,
-                    Prompter* prompter, jobject jprogress)
+                    Prompter*& prompter, jobject jprogress)
 {
   /*
    * Initialize ra layer if we have not done so yet
@@ -168,7 +168,7 @@ RemoteSession::RemoteSession(jobject* jt
                              const char* configDirectory,
                              jobject jconfigHandler,
                              const char*  username, const char*  password,
-                             Prompter* prompter, jobject jprogress)
+                             Prompter*& prompter, jobject jprogress)
   : m_session(NULL), m_context(NULL)
 {
   // Create java session object
@@ -198,6 +198,14 @@ RemoteSession::RemoteSession(jobject* jt
   if (JNIUtil::isJavaExceptionThrown())
     return;
 
+  // Avoid double-free in RemoteSession::open and
+  // SVNClient::openRemoteSession if the svn_ra_open call fails. The
+  // prompter object is now owned by m_context.
+  //
+  // FIXME: Should be using smart pointers, really -- but JavaHL
+  // currently doesn't. Future enhancements FTW.
+  prompter = NULL;
+
   const char* corrected_url = NULL;
   bool cycle_detected = false;
   attempt_set attempted;
@@ -410,14 +418,13 @@ RemoteSession::getRevisionByTimestamp(jl
 }
 
 namespace {
-bool byte_array_to_svn_string(JNIByteArray& ary, svn_string_t& str)
+svn_string_t*
+byte_array_to_svn_string(JNIByteArray& ary, SVN::Pool& scratch_pool)
 {
   if (ary.isNull())
-    return false;
-
-  str.data = reinterpret_cast<const char*>(ary.getBytes());
-  str.len = ary.getLength();
-  return true;
+    return NULL;
+  return svn_string_ncreate(reinterpret_cast<const char*>(ary.getBytes()),
+                            ary.getLength(), scratch_pool.getPool());
 }
 } // anonymous namespace
 
@@ -438,21 +445,17 @@ RemoteSession::changeRevisionProperty(
   if (JNIUtil::isExceptionThrown())
     return;
 
-  svn_string_t str_old_value;
-  svn_string_t* const p_old_value = &str_old_value;
-  svn_string_t* const* pp_old_value = NULL;
-  if (byte_array_to_svn_string(old_value, str_old_value))
-      pp_old_value = &p_old_value;
-
-  svn_string_t str_value;
-  svn_string_t* p_value = NULL;
-  if (byte_array_to_svn_string(value, str_value))
-      p_value = &str_value;
-
   SVN::Pool subPool(pool);
+  svn_string_t* const* p_old_value = NULL;
+  svn_string_t* const str_old_value =
+    byte_array_to_svn_string(old_value, subPool);
+  if (str_old_value)
+    p_old_value = &str_old_value;
+
   SVN_JNI_ERR(svn_ra_change_rev_prop2(m_session,
                                       svn_revnum_t(jrevision),
-                                      name, pp_old_value, p_value,
+                                      name, p_old_value,
+                                      byte_array_to_svn_string(value, subPool),
                                       subPool.getPool()), );
 }
 
@@ -921,10 +924,355 @@ RemoteSession::checkPath(jstring jpath, 
   return EnumMapper::mapNodeKind(kind);
 }
 
-// TODO: stat
-// TODO: getLocations
-// TODO: getLocationSegments
-// TODO: getFileRevisions
+jobject
+RemoteSession::stat(jstring jpath, jlong jrevision)
+{
+  SVN::Pool subPool(pool);
+  Relpath path(jpath, subPool);
+  if (JNIUtil::isExceptionThrown())
+    return NULL;
+  SVN_JNI_ERR(path.error_occurred(), NULL);
+
+  svn_dirent_t* dirent;
+  SVN_JNI_ERR(svn_ra_stat(m_session, path.c_str(),
+                          svn_revnum_t(jrevision),
+                          &dirent, subPool.getPool()),
+              NULL);
+
+  if (dirent)
+    return CreateJ::DirEntry(path.c_str(), path.c_str(), dirent);
+  return NULL;
+}
+
+namespace {
+apr_array_header_t*
+long_iterable_to_revnum_array(jobject jlong_iterable, apr_pool_t* pool)
+{
+
+  JNIEnv* env = JNIUtil::getEnv();
+
+  jclass cls = env->FindClass("java/lang/Long");
+  if (JNIUtil::isExceptionThrown())
+    return NULL;
+
+  static jmethodID mid = 0;
+  if (0 == mid)
+    {
+      mid = env->GetMethodID(cls, "longValue", "()J");
+      if (JNIUtil::isExceptionThrown())
+        return NULL;
+    }
+
+  apr_array_header_t* array = apr_array_make(pool, 0, sizeof(svn_revnum_t));
+  Iterator iter(jlong_iterable);
+  while (iter.hasNext())
+    {
+      const jlong entry = env->CallLongMethod(iter.next(), mid);
+      if (JNIUtil::isExceptionThrown())
+        return NULL;
+      APR_ARRAY_PUSH(array, svn_revnum_t) = svn_revnum_t(entry);
+    }
+  return array;
+}
+
+jobject
+location_hash_to_map(apr_hash_t* locations, apr_pool_t* scratch_pool)
+{
+  JNIEnv* env = JNIUtil::getEnv();
+
+  jclass long_cls = env->FindClass("java/lang/Long");
+  if (JNIUtil::isExceptionThrown())
+    return NULL;
+
+  static jmethodID long_ctor = 0;
+  if (0 == long_ctor)
+    {
+      long_ctor = env->GetMethodID(long_cls, "<init>", "(J)V");
+      if (JNIUtil::isExceptionThrown())
+        return NULL;
+    }
+
+  jclass hash_cls = env->FindClass("java/util/HashMap");
+  if (JNIUtil::isExceptionThrown())
+    return NULL;
+
+  static jmethodID hash_ctor = 0;
+  if (0 == hash_ctor)
+    {
+      hash_ctor = env->GetMethodID(hash_cls, "<init>", "()V");
+      if (JNIUtil::isExceptionThrown())
+        return NULL;
+    }
+
+  static jmethodID hash_put = 0;
+  if (0 == hash_put)
+    {
+      hash_put = env->GetMethodID(hash_cls, "put",
+                                  "(Ljava/lang/Object;Ljava/lang/Object;"
+                                  ")Ljava/lang/Object;");
+      if (JNIUtil::isExceptionThrown())
+        return NULL;
+    }
+
+  jobject result = env->NewObject(hash_cls, hash_ctor);
+  if (JNIUtil::isExceptionThrown())
+    return NULL;
+
+  if (!locations)
+    return result;
+
+  for (apr_hash_index_t* hi = apr_hash_first(scratch_pool, locations);
+       hi; hi = apr_hash_next(hi))
+    {
+      const void* key;
+      void* val;
+
+      apr_hash_this(hi, &key, NULL, &val);
+
+      jobject jkey = env->NewObject(
+          long_cls, long_ctor, jlong(*static_cast<const svn_revnum_t*>(key)));
+      if (JNIUtil::isExceptionThrown())
+        return NULL;
+      jstring jval = JNIUtil::makeJString(static_cast<const char*>(val));
+      if (JNIUtil::isExceptionThrown())
+        return NULL;
+
+      env->CallObjectMethod(result, hash_put, jkey, jval);
+      if (JNIUtil::isExceptionThrown())
+        return NULL;
+
+      env->DeleteLocalRef(jkey);
+      env->DeleteLocalRef(jval);
+    }
+
+  return result;
+}
+} // anonymous namespace
+
+jobject
+RemoteSession::getLocations(jstring jpath, jlong jpeg_revision,
+                            jobject jlocation_revisions)
+{
+  if (!jpath || !jlocation_revisions)
+    return NULL;
+
+  SVN::Pool subPool(pool);
+  Relpath path(jpath, subPool);
+  if (JNIUtil::isExceptionThrown())
+    return NULL;
+  SVN_JNI_ERR(path.error_occurred(), NULL);
+
+  apr_array_header_t* location_revisions =
+    long_iterable_to_revnum_array(jlocation_revisions, subPool.getPool());
+  if (!location_revisions)
+    return NULL;
+
+  apr_hash_t* locations;
+  SVN_JNI_ERR(svn_ra_get_locations(m_session, &locations,
+                                   path.c_str(), svn_revnum_t(jpeg_revision),
+                                   location_revisions, subPool.getPool()),
+              NULL);
+  return location_hash_to_map(locations, subPool.getPool());
+}
+
+namespace {
+class LocationSegmentHandler
+{
+public:
+  static svn_error_t* callback(svn_location_segment_t* segment,
+                               void* baton, apr_pool_t*)
+    {
+      LocationSegmentHandler* const self =
+        static_cast<LocationSegmentHandler*>(baton);
+      SVN_ERR_ASSERT(self->m_jcallback != NULL);
+      self->call(segment);
+      SVN_ERR(JNIUtil::checkJavaException(SVN_ERR_BASE));
+      return SVN_NO_ERROR;
+    }
+
+  LocationSegmentHandler(jobject jcallback)
+    : m_jcallback(jcallback),
+      m_call_mid(0)
+    {
+      JNIEnv* env = JNIUtil::getEnv();
+      jclass cls = env->GetObjectClass(jcallback);
+      if (JNIUtil::isJavaExceptionThrown())
+        return;
+
+      m_call_mid = env->GetMethodID(
+          cls, "doSegment", "(L"JAVA_PACKAGE"/ISVNRemote$LocationSegment;)V");
+      if (JNIUtil::isJavaExceptionThrown())
+        return;
+    }
+
+private:
+  void call(svn_location_segment_t* segment)
+    {
+      JNIEnv* env = JNIUtil::getEnv();
+      jclass cls = env->FindClass(JAVA_PACKAGE"/ISVNRemote$LocationSegment");
+      if (JNIUtil::isJavaExceptionThrown())
+        return;
+
+      static jmethodID mid = 0;
+      if (mid == 0)
+        {
+          mid = env->GetMethodID(cls, "<init>",
+                                 "(Ljava/lang/String;JJ)V");
+          if (JNIUtil::isJavaExceptionThrown())
+            return;
+        }
+
+      jstring jpath = JNIUtil::makeJString(segment->path);
+      if (JNIUtil::isJavaExceptionThrown())
+        return;
+
+      env->CallVoidMethod(m_jcallback, m_call_mid,
+                          env->NewObject(cls, mid, jpath,
+                                         jlong(segment->range_start),
+                                         jlong(segment->range_end)));
+      if (JNIUtil::isJavaExceptionThrown())
+        return;
+      env->DeleteLocalRef(jpath);
+    }
+
+  jobject m_jcallback;
+  jmethodID m_call_mid;
+};
+} // anonymous namespace
+
+void
+RemoteSession::getLocationSegments(jstring jpath, jlong jpeg_revision,
+                                   jlong jstart_revision, jlong jend_revision,
+                                   jobject jcallback)
+{
+  SVN::Pool subPool(pool);
+  Relpath path(jpath, subPool);
+  if (JNIUtil::isExceptionThrown())
+    return;
+  SVN_JNI_ERR(path.error_occurred(), );
+
+  LocationSegmentHandler handler(jcallback);
+  if (JNIUtil::isExceptionThrown())
+    return ;
+
+  SVN_JNI_ERR(svn_ra_get_location_segments(m_session, path.c_str(),
+                                           svn_revnum_t(jpeg_revision),
+                                           svn_revnum_t(jstart_revision),
+                                           svn_revnum_t(jend_revision),
+                                           handler.callback, &handler,
+                                           subPool.getPool()),);
+}
+
+namespace {
+class FileRevisionHandler
+{
+public:
+  static svn_error_t* callback(void* baton,
+                               const char* path, svn_revnum_t revision,
+                               apr_hash_t* revision_props,
+                               // We ignore the deltas as they're not
+                               // exposed in the JavaHL API.
+                               svn_boolean_t result_of_merge,
+                               svn_txdelta_window_handler_t*, void**,
+                               apr_array_header_t* prop_diffs,
+                               apr_pool_t* scratch_pool)
+    {
+      FileRevisionHandler* const self =
+        static_cast<FileRevisionHandler*>(baton);
+      SVN_ERR_ASSERT(self->m_jcallback != NULL);
+      self->call(path, revision, revision_props,
+                result_of_merge, prop_diffs, scratch_pool);
+      SVN_ERR(JNIUtil::checkJavaException(SVN_ERR_BASE));
+      return SVN_NO_ERROR;
+    }
+
+  FileRevisionHandler(jobject jcallback)
+    : m_jcallback(jcallback),
+      m_call_mid(0)
+    {
+      JNIEnv* env = JNIUtil::getEnv();
+      jclass cls = env->GetObjectClass(jcallback);
+      if (JNIUtil::isJavaExceptionThrown())
+        return;
+
+      m_call_mid = env->GetMethodID(
+          cls, "doRevision", "(L"JAVA_PACKAGE"/ISVNRemote$FileRevision;)V");
+      if (JNIUtil::isJavaExceptionThrown())
+        return;
+    }
+
+private:
+  void call(const char* path, svn_revnum_t revision,
+           apr_hash_t* revision_props,
+           svn_boolean_t result_of_merge,
+           apr_array_header_t* prop_diffs,
+           apr_pool_t* scratch_pool)
+    {
+      JNIEnv* env = JNIUtil::getEnv();
+      jclass cls = env->FindClass(JAVA_PACKAGE"/ISVNRemote$FileRevision");
+      if (JNIUtil::isJavaExceptionThrown())
+        return;
+
+      static jmethodID mid = 0;
+      if (mid == 0)
+        {
+          mid = env->GetMethodID(cls, "<init>",
+                                 "(Ljava/lang/String;JZ"
+                                 "Ljava/util/Map;Ljava/util/Map;)V");
+          if (JNIUtil::isJavaExceptionThrown())
+            return;
+        }
+
+      jstring jpath = JNIUtil::makeJString(path);
+      if (JNIUtil::isJavaExceptionThrown())
+        return;
+      jobject jrevprops = CreateJ::PropertyMap(revision_props, scratch_pool);
+      if (JNIUtil::isJavaExceptionThrown())
+        return;
+      jobject jpropdelta = CreateJ::PropertyMap(prop_diffs, scratch_pool);
+      if (JNIUtil::isJavaExceptionThrown())
+        return;
+
+      env->CallVoidMethod(m_jcallback, m_call_mid,
+                          env->NewObject(cls, mid, jpath, jlong(revision),
+                                         jboolean(result_of_merge),
+                                         jrevprops, jpropdelta));
+      if (JNIUtil::isJavaExceptionThrown())
+        return;
+      env->DeleteLocalRef(jpath);
+      env->DeleteLocalRef(jrevprops);
+      env->DeleteLocalRef(jpropdelta);
+    }
+
+  jobject m_jcallback;
+  jmethodID m_call_mid;
+};
+} // anonymous namespace
+
+void
+RemoteSession::getFileRevisions(jstring jpath,
+                                jlong jstart_revision, jlong jend_revision,
+                                jboolean jinclude_merged_revisions,
+                                jobject jcallback)
+{
+  SVN::Pool subPool(pool);
+  Relpath path(jpath, subPool);
+  if (JNIUtil::isExceptionThrown())
+    return;
+  SVN_JNI_ERR(path.error_occurred(), );
+
+  FileRevisionHandler handler(jcallback);
+  if (JNIUtil::isExceptionThrown())
+    return;
+
+  SVN_JNI_ERR(svn_ra_get_file_revs2(m_session, path.c_str(),
+                                    svn_revnum_t(jstart_revision),
+                                    svn_revnum_t(jend_revision),
+                                    bool(jinclude_merged_revisions),
+                                    handler.callback, &handler,
+                                    subPool.getPool()),);
+}
+
 // TODO: lock
 // TODO: unlock
 // TODO: getLock

Modified: subversion/branches/move-tracking-1/subversion/bindings/javahl/native/RemoteSession.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/bindings/javahl/native/RemoteSession.h?rev=1515380&r1=1515379&r2=1515380&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/bindings/javahl/native/RemoteSession.h (original)
+++ subversion/branches/move-tracking-1/subversion/bindings/javahl/native/RemoteSession.h Mon Aug 19 12:07:51 2013
@@ -55,7 +55,7 @@ class RemoteSession : public SVNBase
                         const char* configDirectory,
                         jobject jconfigHandler,
                         const char* username, const char* password,
-                        Prompter* prompter, jobject jprogress);
+                        Prompter*& prompter, jobject jprogress);
     ~RemoteSession();
 
     void cancelOperation() const { m_context->cancelOperation(); }
@@ -92,9 +92,16 @@ class RemoteSession : public SVNBase
                 jboolean jinclude_merged_revisions,
                 jobject jrevprops, jobject jlog_callback);
     jobject checkPath(jstring jpath, jlong jrevision);
-    // TODO: stat
-    // TODO: getLocations
-    // TODO: getLocationSegments
+    jobject stat(jstring jpath, jlong jrevision);
+    jobject getLocations(jstring jpath, jlong jpeg_revision,
+                         jobject jlocation_revisions);
+    void getLocationSegments(jstring jpath, jlong jpeg_revision,
+                             jlong jstart_revision, jlong jend_revision,
+                             jobject jcallback);
+    void getFileRevisions(jstring jpath,
+                          jlong jstart_revision, jlong jend_revision,
+                          jboolean jinclude_merged_revisions,
+                          jobject jcallback);
     // TODO: getFileRevisions
     // TODO: lock
     // TODO: unlock
@@ -113,7 +120,7 @@ class RemoteSession : public SVNBase
                   const char* configDirectory,
                   jobject jconfigHandler,
                   const char* username, const char* password,
-                  Prompter* prompter, jobject jprogress);
+                  Prompter*& prompter, jobject jprogress);
 
     svn_ra_session_t* m_session;
     RemoteSessionContext* m_context;

Modified: subversion/branches/move-tracking-1/subversion/bindings/javahl/native/RevisionRange.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/bindings/javahl/native/RevisionRange.cpp?rev=1515380&r1=1515379&r2=1515380&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/bindings/javahl/native/RevisionRange.cpp (original)
+++ subversion/branches/move-tracking-1/subversion/bindings/javahl/native/RevisionRange.cpp Mon Aug 19 12:07:51 2013
@@ -44,60 +44,117 @@ RevisionRange::~RevisionRange()
     // explicitly destroyed.
 }
 
-const svn_opt_revision_range_t *RevisionRange::toRange(SVN::Pool &pool) const
+namespace {
+void get_range_info(jobject jrange,
+                    svn_opt_revision_t* range_start,
+                    svn_opt_revision_t* range_end,
+                    svn_boolean_t* range_inheritable)
 {
   JNIEnv *env = JNIUtil::getEnv();
 
   jclass clazz = env->FindClass(JAVA_PACKAGE"/types/RevisionRange");
   if (JNIUtil::isExceptionThrown())
-    return NULL;
+    return;
 
-  static jmethodID fmid = 0;
-  if (fmid == 0)
+  if (range_start)
     {
-      fmid = env->GetMethodID(clazz, "getFromRevision",
-                              "()L"JAVA_PACKAGE"/types/Revision;");
-      if (JNIUtil::isJavaExceptionThrown())
-        return NULL;
+
+      static jmethodID fmid = 0;
+      if (fmid == 0)
+        {
+          fmid = env->GetMethodID(clazz, "getFromRevision",
+                                  "()L"JAVA_PACKAGE"/types/Revision;");
+          if (JNIUtil::isJavaExceptionThrown())
+            return;
+        }
+
+      jobject jstartRevision = env->CallObjectMethod(jrange, fmid);
+      if (JNIUtil::isExceptionThrown())
+        return;
+
+      Revision startRevision(jstartRevision);
+      if (JNIUtil::isExceptionThrown())
+        return;
+
+      *range_start = *startRevision.revision();
+      if (JNIUtil::isExceptionThrown())
+        return;
     }
 
-  static jmethodID tmid = 0;
-  if (tmid == 0)
+  if (range_end)
     {
-      tmid = env->GetMethodID(clazz, "getToRevision",
-                              "()L"JAVA_PACKAGE"/types/Revision;");
-      if (JNIUtil::isJavaExceptionThrown())
-        return NULL;
+      static jmethodID tmid = 0;
+      if (tmid == 0)
+        {
+          tmid = env->GetMethodID(clazz, "getToRevision",
+                                  "()L"JAVA_PACKAGE"/types/Revision;");
+          if (JNIUtil::isJavaExceptionThrown())
+            return;
+        }
+
+      jobject jendRevision = env->CallObjectMethod(jrange, tmid);
+      if (JNIUtil::isExceptionThrown())
+        return;
+
+      Revision endRevision(jendRevision);
+      if (JNIUtil::isExceptionThrown())
+        return;
+
+      *range_end = *endRevision.revision();
+      if (JNIUtil::isExceptionThrown())
+        return;
     }
 
-  jobject jstartRevision = env->CallObjectMethod(m_range, fmid);
-  if (JNIUtil::isExceptionThrown())
-    return NULL;
+  if (range_inheritable)
+    {
+      static jmethodID imid = 0;
+      if (imid == 0 && range_inheritable)
+        {
+          imid = env->GetMethodID(clazz, "isInheritable", "()Z");
+          if (JNIUtil::isJavaExceptionThrown())
+            return;
+        }
+
+      jboolean inheritable = env->CallBooleanMethod(jrange, imid);
+      if (JNIUtil::isExceptionThrown())
+        return;
+      *range_inheritable = inheritable;
+    }
+}
+} // anonymous namespace
 
-  Revision startRevision(jstartRevision);
+svn_merge_range_t* RevisionRange::toMergeRange(SVN::Pool &pool) const
+{
+  svn_opt_revision_t range_start, range_end;
+  svn_boolean_t range_inheritable;
+  get_range_info(m_range, &range_start, &range_end, &range_inheritable);
   if (JNIUtil::isExceptionThrown())
     return NULL;
 
-  jobject jendRevision = env->CallObjectMethod(m_range, tmid);
-  if (JNIUtil::isExceptionThrown())
-    return NULL;
+  if (range_start.kind != svn_opt_revision_number
+      || range_end.kind != svn_opt_revision_number)
+    JNIUtil::raiseThrowable("java.lang.InvalidStateException",
+                            "Revsision ranges must contain revision numbers");
 
-  Revision endRevision(jendRevision);
-  if (JNIUtil::isExceptionThrown())
-    return NULL;
+  svn_merge_range_t* range =
+    static_cast<svn_merge_range_t*>
+      (apr_palloc(pool.getPool(), sizeof(*range)));
+
+  range->start = range_start.value.number;
+  range->end = range_end.value.number;
+  range->inheritable = range_inheritable;
+  return range;
+}
 
+svn_opt_revision_range_t *RevisionRange::toRange(SVN::Pool &pool) const
+{
   svn_opt_revision_range_t *range =
-    reinterpret_cast<svn_opt_revision_range_t *>
+    static_cast<svn_opt_revision_range_t *>
       (apr_palloc(pool.getPool(), sizeof(*range)));
 
-  range->start = *startRevision.revision();
-  if (JNIUtil::isExceptionThrown())
-    return NULL;
-
-  range->end = *endRevision.revision();
+  get_range_info(m_range, &range->start, &range->end, NULL);
   if (JNIUtil::isExceptionThrown())
-    return NULL;
-
+    range = NULL;
   return range;
 }
 

Modified: subversion/branches/move-tracking-1/subversion/bindings/javahl/native/RevisionRange.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/bindings/javahl/native/RevisionRange.h?rev=1515380&r1=1515379&r2=1515380&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/bindings/javahl/native/RevisionRange.h (original)
+++ subversion/branches/move-tracking-1/subversion/bindings/javahl/native/RevisionRange.h Mon Aug 19 12:07:51 2013
@@ -29,6 +29,7 @@
 
 #include <jni.h>
 #include "svn_types.h"
+#include "svn_opt.h"
 
 #include "Pool.h"
 
@@ -53,7 +54,12 @@ class RevisionRange
   /**
    * Return an svn_opt_revision_range_t.
    */
-  const svn_opt_revision_range_t *toRange(SVN::Pool &pool) const;
+  svn_opt_revision_range_t *toRange(SVN::Pool &pool) const;
+
+  /**
+   * Return an svn_merge_range_t.
+   */
+  svn_merge_range_t* toMergeRange(SVN::Pool &pool) const;
 
   /**
    * Make a (single) RevisionRange Java object.

Modified: subversion/branches/move-tracking-1/subversion/bindings/javahl/native/SVNClient.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/bindings/javahl/native/SVNClient.cpp?rev=1515380&r1=1515379&r2=1515380&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/bindings/javahl/native/SVNClient.cpp (original)
+++ subversion/branches/move-tracking-1/subversion/bindings/javahl/native/SVNClient.cpp Mon Aug 19 12:07:51 2013
@@ -51,7 +51,7 @@
 #include "CommitMessage.h"
 #include "EnumMapper.h"
 #include "StringArray.h"
-#include "RevpropTable.h"
+#include "PropertyTable.h"
 #include "DiffOptions.h"
 #include "CreateJ.h"
 #include "svn_auth.h"
@@ -319,7 +319,7 @@ jlong SVNClient::checkout(const char *mo
 }
 
 void SVNClient::remove(Targets &targets, CommitMessage *message, bool force,
-                       bool keep_local, RevpropTable &revprops,
+                       bool keep_local, PropertyTable &revprops,
                        CommitCallback *callback)
 {
     SVN::Pool subPool(pool);
@@ -419,7 +419,7 @@ jlongArray SVNClient::update(Targets &ta
 
 void SVNClient::commit(Targets &targets, CommitMessage *message,
                        svn_depth_t depth, bool noUnlock, bool keepChangelist,
-                       StringArray &changelists, RevpropTable &revprops,
+                       StringArray &changelists, PropertyTable &revprops,
                        CommitCallback *callback)
 {
     SVN::Pool subPool(pool);
@@ -444,7 +444,7 @@ void SVNClient::commit(Targets &targets,
 void SVNClient::copy(CopySources &copySources, const char *destPath,
                      CommitMessage *message, bool copyAsChild,
                      bool makeParents, bool ignoreExternals,
-                     RevpropTable &revprops, CommitCallback *callback)
+                     PropertyTable &revprops, CommitCallback *callback)
 {
     SVN::Pool subPool(pool);
 
@@ -473,7 +473,7 @@ void SVNClient::copy(CopySources &copySo
 void SVNClient::move(Targets &srcPaths, const char *destPath,
                      CommitMessage *message, bool force, bool moveAsChild,
                      bool makeParents, bool metadataOnly, bool allowMixRev,
-                     RevpropTable &revprops, CommitCallback *callback)
+                     PropertyTable &revprops, CommitCallback *callback)
 {
     SVN::Pool subPool(pool);
 
@@ -498,7 +498,7 @@ void SVNClient::move(Targets &srcPaths, 
 }
 
 void SVNClient::mkdir(Targets &targets, CommitMessage *message,
-                      bool makeParents, RevpropTable &revprops,
+                      bool makeParents, PropertyTable &revprops,
                       CommitCallback *callback)
 {
     SVN::Pool subPool(pool);
@@ -616,7 +616,7 @@ void SVNClient::doImport(const char *pat
                          CommitMessage *message, svn_depth_t depth,
                          bool noIgnore, bool noAutoProps,
                          bool ignoreUnknownNodeTypes,
-                         RevpropTable &revprops,
+                         PropertyTable &revprops,
                          ImportFilterCallback *ifCallback,
                          CommitCallback *commitCallback)
 {
@@ -905,7 +905,7 @@ void SVNClient::propertySetRemote(const 
                                   const char *name,
                                   CommitMessage *message,
                                   JNIByteArray &value, bool force,
-                                  RevpropTable &revprops,
+                                  PropertyTable &revprops,
                                   CommitCallback *callback)
 {
     SVN::Pool subPool(pool);

Modified: subversion/branches/move-tracking-1/subversion/bindings/javahl/native/SVNClient.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/bindings/javahl/native/SVNClient.h?rev=1515380&r1=1515379&r2=1515380&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/bindings/javahl/native/SVNClient.h (original)
+++ subversion/branches/move-tracking-1/subversion/bindings/javahl/native/SVNClient.h Mon Aug 19 12:07:51 2013
@@ -53,7 +53,7 @@ class PatchCallback;
 class ChangelistCallback;
 class CommitMessage;
 class StringArray;
-class RevpropTable;
+class PropertyTable;
 class DiffOptions;
 #include "svn_types.h"
 #include "svn_client.h"
@@ -87,7 +87,7 @@ class SVNClient :public SVNBase
   void propertySetRemote(const char *path, long base_rev, const char *name,
                          CommitMessage *message,
                          JNIByteArray &value, bool force,
-                         RevpropTable &revprops, CommitCallback *callback);
+                         PropertyTable &revprops, CommitCallback *callback);
   void properties(const char *path, Revision &revision,
                   Revision &pegRevision, svn_depth_t depth,
                   StringArray &changelists, ProplistCallback *callback);
@@ -115,7 +115,7 @@ class SVNClient :public SVNBase
   void doImport(const char *path, const char *url, CommitMessage *message,
                 svn_depth_t depth, bool noIgnore, bool noAutoProps,
                 bool ignoreUnknownNodeTypes,
-                RevpropTable &revprops, ImportFilterCallback *ifCallback,
+                PropertyTable &revprops, ImportFilterCallback *ifCallback,
                 CommitCallback *commitCallback);
   jlong doSwitch(const char *path, const char *url, Revision &revision,
                  Revision &pegRevision, svn_depth_t depth,
@@ -129,18 +129,18 @@ class SVNClient :public SVNBase
                svn_wc_conflict_choice_t choice);
   void cleanup(const char *path);
   void mkdir(Targets &targets, CommitMessage *message, bool makeParents,
-             RevpropTable &revprops, CommitCallback *callback);
+             PropertyTable &revprops, CommitCallback *callback);
   void move(Targets &srcPaths, const char *destPath,
             CommitMessage *message, bool force, bool moveAsChild,
             bool makeParents, bool metadataOnly, bool allowMixRev,
-            RevpropTable &revprops, CommitCallback *callback);
+            PropertyTable &revprops, CommitCallback *callback);
   void copy(CopySources &copySources, const char *destPath,
             CommitMessage *message, bool copyAsChild, bool makeParents,
-            bool ignoreExternals, RevpropTable &revprops,
+            bool ignoreExternals, PropertyTable &revprops,
             CommitCallback *callback);
   void commit(Targets &targets, CommitMessage *message, svn_depth_t depth,
               bool noUnlock, bool keepChangelist,
-              StringArray &changelists, RevpropTable &revprops,
+              StringArray &changelists, PropertyTable &revprops,
               CommitCallback *callback);
   jlongArray update(Targets &targets, Revision &revision, svn_depth_t depth,
                     bool depthIsSticky, bool makeParents, bool ignoreExternals,
@@ -149,7 +149,7 @@ class SVNClient :public SVNBase
            bool no_ignore, bool no_autoprops, bool add_parents);
   void revert(const char *path, svn_depth_t depth, StringArray &changelists);
   void remove(Targets &targets, CommitMessage *message, bool force,
-              bool keep_local, RevpropTable &revprops,
+              bool keep_local, PropertyTable &revprops,
               CommitCallback *callback);
   jlong checkout(const char *moduleName, const char *destPath,
                  Revision &revision, Revision &pegRevsion, svn_depth_t depth,

Modified: subversion/branches/move-tracking-1/subversion/bindings/javahl/native/org_apache_subversion_javahl_ConfigImpl_Category.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/bindings/javahl/native/org_apache_subversion_javahl_ConfigImpl_Category.cpp?rev=1515380&r1=1515379&r2=1515380&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/bindings/javahl/native/org_apache_subversion_javahl_ConfigImpl_Category.cpp (original)
+++ subversion/branches/move-tracking-1/subversion/bindings/javahl/native/org_apache_subversion_javahl_ConfigImpl_Category.cpp Mon Aug 19 12:07:51 2013
@@ -33,9 +33,9 @@
 #include "CreateJ.h"
 #include "EnumMapper.h"
 
+#include "svn_private_config.h"
 #include "svn_config.h"
 #include "svn_hash.h"
-#include "svn_private_config.h"
 
 #include <string>
 #include <vector>

Modified: subversion/branches/move-tracking-1/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp?rev=1515380&r1=1515379&r2=1515380&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp (original)
+++ subversion/branches/move-tracking-1/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp Mon Aug 19 12:07:51 2013
@@ -50,7 +50,7 @@
 #include "ImportFilterCallback.h"
 #include "ChangelistCallback.h"
 #include "StringArray.h"
-#include "RevpropTable.h"
+#include "PropertyTable.h"
 #include "VersionExtended.h"
 #include "DiffOptions.h"
 #include "svn_version.h"
@@ -384,7 +384,7 @@ Java_org_apache_subversion_javahl_SVNCli
   if (JNIUtil::isExceptionThrown())
     return;
 
-  RevpropTable revprops(jrevpropTable);
+  PropertyTable revprops(jrevpropTable);
   if (JNIUtil::isExceptionThrown())
     return;
 
@@ -498,7 +498,7 @@ Java_org_apache_subversion_javahl_SVNCli
   if (JNIUtil::isExceptionThrown())
     return;
 
-  RevpropTable revprops(jrevpropTable);
+  PropertyTable revprops(jrevpropTable);
   if (JNIUtil::isExceptionThrown())
     return;
 
@@ -539,7 +539,7 @@ Java_org_apache_subversion_javahl_SVNCli
   if (JNIUtil::isExceptionThrown())
     return;
 
-  RevpropTable revprops(jrevpropTable);
+  PropertyTable revprops(jrevpropTable);
   if (JNIUtil::isExceptionThrown())
     return;
 
@@ -577,7 +577,7 @@ Java_org_apache_subversion_javahl_SVNCli
   if (JNIUtil::isExceptionThrown())
     return;
 
-  RevpropTable revprops(jrevpropTable);
+  PropertyTable revprops(jrevpropTable);
   if (JNIUtil::isExceptionThrown())
     return;
 
@@ -610,7 +610,7 @@ Java_org_apache_subversion_javahl_SVNCli
   if (JNIUtil::isExceptionThrown())
     return;
 
-  RevpropTable revprops(jrevpropTable);
+  PropertyTable revprops(jrevpropTable);
   if (JNIUtil::isExceptionThrown())
     return;
 
@@ -761,7 +761,7 @@ Java_org_apache_subversion_javahl_SVNCli
   if (JNIUtil::isExceptionThrown())
     return;
 
-  RevpropTable revprops(jrevpropTable);
+  PropertyTable revprops(jrevpropTable);
   if (JNIUtil::isExceptionThrown())
     return;
 
@@ -1012,7 +1012,7 @@ Java_org_apache_subversion_javahl_SVNCli
   if (JNIUtil::isExceptionThrown())
     return;
 
-  RevpropTable revprops(jrevpropTable);
+  PropertyTable revprops(jrevpropTable);
   if (JNIUtil::isExceptionThrown())
     return;
 

Modified: subversion/branches/move-tracking-1/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_RemoteSession.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-1/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_RemoteSession.cpp?rev=1515380&r1=1515379&r2=1515380&view=diff
==============================================================================
--- subversion/branches/move-tracking-1/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_RemoteSession.cpp (original)
+++ subversion/branches/move-tracking-1/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_RemoteSession.cpp Mon Aug 19 12:07:51 2013
@@ -272,10 +272,61 @@ Java_org_apache_subversion_javahl_remote
   return ras->checkPath(jpath, jrevision);
 }
 
-// TODO: stat
-// TODO: getLocations
-// TODO: getLocationSegments
-// TODO: getFileRevisions
+JNIEXPORT jobject JNICALL
+Java_org_apache_subversion_javahl_remote_RemoteSession_stat(
+    JNIEnv *env, jobject jthis, jstring jpath, jlong jrevision)
+{
+  JNIEntry(SVNReposAccess, stat);
+  RemoteSession *ras = RemoteSession::getCppObject(jthis);
+  CPPADDR_NULL_PTR(ras, NULL);
+
+  return ras->stat(jpath, jrevision);
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_apache_subversion_javahl_remote_RemoteSession_getLocations(
+    JNIEnv *env, jobject jthis, jstring jpath, jlong jpeg_revision,
+    jobject jlocation_revisions)
+{
+  JNIEntry(SVNReposAccess, getLocations);
+  RemoteSession *ras = RemoteSession::getCppObject(jthis);
+  CPPADDR_NULL_PTR(ras, NULL);
+
+  return ras->getLocations(jpath, jpeg_revision, jlocation_revisions);
+}
+
+JNIEXPORT void JNICALL
+Java_org_apache_subversion_javahl_remote_RemoteSession_getLocationSegments(
+    JNIEnv *env, jobject jthis, jstring jpath, jlong jpeg_revision,
+    jlong jstart_revision, jlong jend_revision, jobject jcallback)
+{
+  JNIEntry(SVNReposAccess, getLocationSegments);
+  RemoteSession *ras = RemoteSession::getCppObject(jthis);
+  CPPADDR_NULL_PTR(ras, );
+
+  if (jcallback == NULL)
+    JNIUtil::throwNullPointerException("handler");
+  ras->getLocationSegments(jpath, jpeg_revision,
+                           jstart_revision, jend_revision,
+                           jcallback);
+}
+
+JNIEXPORT void JNICALL
+Java_org_apache_subversion_javahl_remote_RemoteSession_getFileRevisions(
+    JNIEnv *env, jobject jthis, jstring jpath,
+    jlong jstart_revision, jlong jend_revision,
+    jboolean jinclude_merged_revisions, jobject jcallback)
+{
+  JNIEntry(SVNReposAccess, getFileRevisions);
+  RemoteSession *ras = RemoteSession::getCppObject(jthis);
+  CPPADDR_NULL_PTR(ras, );
+
+  if (jcallback == NULL)
+    JNIUtil::throwNullPointerException("handler");
+  ras->getFileRevisions(jpath, jstart_revision, jend_revision,
+                        jinclude_merged_revisions, jcallback);
+}
+
 // TODO: lock
 // TODO: unlock
 // TODO: getLock