You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2013/06/30 03:03:14 UTC

svn commit: r1498045 [2/8] - in /subversion/branches/fsfs-format7: ./ build/ build/generator/ build/generator/templates/ notes/tree-conflicts/ subversion/bindings/cxxhl/include/ subversion/bindings/cxxhl/include/svncxxhl/ subversion/bindings/cxxhl/src/...

Modified: subversion/branches/fsfs-format7/subversion/bindings/javahl/native/ClientContext.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/bindings/javahl/native/ClientContext.h?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/bindings/javahl/native/ClientContext.h (original)
+++ subversion/branches/fsfs-format7/subversion/bindings/javahl/native/ClientContext.h Sun Jun 30 01:03:10 2013
@@ -29,6 +29,8 @@
 
 #include <string>
 
+#include "OperationContext.h"
+
 #include "svn_types.h"
 #include "svn_client.h"
 
@@ -36,7 +38,6 @@
 #include "Pool.h"
 #include "JNIStringHolder.h"
 
-class Prompter;
 class CommitMessage;
 
 /**
@@ -44,25 +45,14 @@ class CommitMessage;
  * and implements the functions read & close of svn_stream_t.
  *
  */
-class ClientContext
+class ClientContext : public OperationContext
 {
  private:
   svn_client_ctx_t *m_context;
-  const SVN::Pool *m_pool;
-  jobject m_jctx;
-
-  std::string m_userName;
-  std::string m_passWord;
-  std::string m_configDir;
-
-  Prompter *m_prompter;
-  bool m_cancelOperation;
 
  protected:
   static void notify(void *baton, const svn_wc_notify_t *notify,
                      apr_pool_t *pool);
-  static void progress(apr_off_t progressVal, apr_off_t total,
-                       void *baton, apr_pool_t *pool);
   static svn_error_t *resolve(svn_wc_conflict_result_t **result,
                               const svn_wc_conflict_description2_t *desc,
                               void *baton,
@@ -73,24 +63,9 @@ class ClientContext
 
  public:
   ClientContext(jobject jsvnclient, SVN::Pool &pool);
-  ~ClientContext();
-
-  static svn_error_t *checkCancel(void *cancelBaton);
+  virtual ~ClientContext();
 
   svn_client_ctx_t *getContext(CommitMessage *message, SVN::Pool &in_pool);
-
-  void username(const char *pi_username);
-  void password(const char *pi_password);
-  void setPrompt(Prompter *prompter);
-  void cancelOperation();
-  const char *getConfigDirectory() const;
-
-  /**
-   * Set the configuration directory, taking the usual steps to
-   * ensure that Subversion's config file templates exist in the
-   * specified location.
-   */
-  void setConfigDirectory(const char *configDir);
 };
 
 #endif // CLIENTCONTEXT_H

Modified: subversion/branches/fsfs-format7/subversion/bindings/javahl/native/CommitCallback.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/bindings/javahl/native/CommitCallback.cpp?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/bindings/javahl/native/CommitCallback.cpp (original)
+++ subversion/branches/fsfs-format7/subversion/bindings/javahl/native/CommitCallback.cpp Sun Jun 30 01:03:10 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/fsfs-format7/subversion/bindings/javahl/native/CommitCallback.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/bindings/javahl/native/CommitCallback.h?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/bindings/javahl/native/CommitCallback.h (original)
+++ subversion/branches/fsfs-format7/subversion/bindings/javahl/native/CommitCallback.h Sun Jun 30 01:03:10 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/fsfs-format7/subversion/bindings/javahl/native/CreateJ.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/bindings/javahl/native/CreateJ.cpp?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/bindings/javahl/native/CreateJ.cpp (original)
+++ subversion/branches/fsfs-format7/subversion/bindings/javahl/native/CreateJ.cpp Sun Jun 30 01:03:10 2013
@@ -230,6 +230,61 @@ CreateJ::Checksum(const svn_checksum_t *
 }
 
 jobject
+CreateJ::DirEntry(const char *path, const char *absPath,
+                  const svn_dirent_t *dirent)
+{
+  JNIEnv *env = JNIUtil::getEnv();
+
+  // Create a local frame for our references
+  env->PushLocalFrame(LOCAL_FRAME_SIZE);
+  if (JNIUtil::isJavaExceptionThrown())
+    return SVN_NO_ERROR;
+
+  jclass clazz = env->FindClass(JAVA_PACKAGE"/types/DirEntry");
+  if (JNIUtil::isJavaExceptionThrown())
+    POP_AND_RETURN_NULL;
+
+  static jmethodID mid = 0;
+  if (mid == 0)
+    {
+      mid = env->GetMethodID(clazz, "<init>",
+                             "(Ljava/lang/String;Ljava/lang/String;"
+                             "L"JAVA_PACKAGE"/types/NodeKind;"
+                             "JZJJLjava/lang/String;)V");
+      if (JNIUtil::isJavaExceptionThrown())
+        POP_AND_RETURN_NULL;
+    }
+
+  jstring jPath = JNIUtil::makeJString(path);
+  if (JNIUtil::isJavaExceptionThrown())
+    POP_AND_RETURN_NULL;
+
+  jstring jAbsPath = JNIUtil::makeJString(absPath);
+  if (JNIUtil::isJavaExceptionThrown())
+    POP_AND_RETURN_NULL;
+
+  jobject jNodeKind = EnumMapper::mapNodeKind(dirent->kind);
+  if (JNIUtil::isJavaExceptionThrown())
+    POP_AND_RETURN_NULL;
+
+  jlong jSize = dirent->size;
+  jboolean jHasProps = (dirent->has_props? JNI_TRUE : JNI_FALSE);
+  jlong jLastChangedRevision = dirent->created_rev;
+  jlong jLastChanged = dirent->time;
+  jstring jLastAuthor = JNIUtil::makeJString(dirent->last_author);
+  if (JNIUtil::isJavaExceptionThrown())
+    POP_AND_RETURN_NULL;
+
+  jobject ret = env->NewObject(clazz, mid, jPath, jAbsPath, jNodeKind,
+                               jSize, jHasProps, jLastChangedRevision,
+                               jLastChanged, jLastAuthor);
+  if (JNIUtil::isJavaExceptionThrown())
+    POP_AND_RETURN_NULL;
+
+  return env->PopLocalFrame(ret);
+}
+
+jobject
 CreateJ::Info(const char *path, const svn_client_info2_t *info)
 {
   JNIEnv *env = JNIUtil::getEnv();
@@ -423,6 +478,72 @@ CreateJ::Lock(const svn_lock_t *lock)
 }
 
 jobject
+CreateJ::LockMap(const apr_hash_t *locks, apr_pool_t *pool)
+{
+  JNIEnv *env = JNIUtil::getEnv();
+
+  if (locks == NULL)
+    return NULL;
+
+  // Create a local frame for our references
+  env->PushLocalFrame(LOCAL_FRAME_SIZE);
+  if (JNIUtil::isJavaExceptionThrown())
+    return NULL;
+
+  jclass clazz = env->FindClass("java/util/HashMap");
+  if (JNIUtil::isJavaExceptionThrown())
+    POP_AND_RETURN_NULL;
+
+  static jmethodID init_mid = 0;
+  if (init_mid == 0)
+    {
+      init_mid = env->GetMethodID(clazz, "<init>", "()V");
+      if (JNIUtil::isJavaExceptionThrown())
+        POP_AND_RETURN_NULL;
+    }
+
+  static jmethodID put_mid = 0;
+  if (put_mid == 0)
+    {
+      put_mid = env->GetMethodID(clazz, "put",
+                                 "(Ljava/lang/Object;Ljava/lang/Object;)"
+                                 "Ljava/lang/Object;");
+      if (JNIUtil::isJavaExceptionThrown())
+        POP_AND_RETURN_NULL;
+    }
+
+  jobject map = env->NewObject(clazz, init_mid);
+  if (JNIUtil::isJavaExceptionThrown())
+    POP_AND_RETURN_NULL;
+
+  apr_hash_index_t *hi;
+  int i = 0;
+  for (hi = apr_hash_first(pool, (apr_hash_t *) locks); hi;
+        hi = apr_hash_next(hi), ++i)
+    {
+      const char *key = (const char *) svn__apr_hash_index_key(hi);
+      const svn_lock_t *lock = (const svn_lock_t *) svn__apr_hash_index_val(hi);
+
+      jstring jpath = JNIUtil::makeJString(key);
+      if (JNIUtil::isJavaExceptionThrown())
+        POP_AND_RETURN_NULL;
+
+      jobject jlock = Lock(lock);
+      if (JNIUtil::isJavaExceptionThrown())
+        POP_AND_RETURN_NULL;
+
+      env->CallObjectMethod(map, put_mid, jpath, jlock);
+      if (JNIUtil::isJavaExceptionThrown())
+        POP_AND_RETURN_NULL;
+
+      env->DeleteLocalRef(jpath);
+      env->DeleteLocalRef(jlock);
+    }
+
+  return env->PopLocalFrame(map);
+}
+
+jobject
 CreateJ::ChangedPath(const char *path, svn_log_changed_path2_t *log_item)
 {
   JNIEnv *env = JNIUtil::getEnv();
@@ -1058,6 +1179,37 @@ jobject CreateJ::PropertyMap(apr_hash_t 
   if (JNIUtil::isJavaExceptionThrown())
     POP_AND_RETURN_NULL;
 
+  FillPropertyMap(map, prop_hash, put_mid);
+  if (JNIUtil::isJavaExceptionThrown())
+    POP_AND_RETURN_NULL;
+
+  return env->PopLocalFrame(map);
+}
+
+void CreateJ::FillPropertyMap(jobject map, apr_hash_t* prop_hash,
+                              jmethodID put_mid)
+{
+  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();
+    }
+
   apr_hash_index_t *hi;
   for (hi = apr_hash_first(apr_hash_pool_get(prop_hash), prop_hash);
        hi; hi = apr_hash_next(hi))
@@ -1065,28 +1217,28 @@ jobject CreateJ::PropertyMap(apr_hash_t 
       const char *key;
       svn_string_t *val;
 
-      apr_hash_this(hi,
-                    reinterpret_cast<const void **>(&key),
-                    NULL,
-                    reinterpret_cast<void **>(&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_NULL;
+        POP_AND_RETURN_NOTHING();
 
       jbyteArray jpropVal = JNIUtil::makeJByteArray(val);
       if (JNIUtil::isJavaExceptionThrown())
-        POP_AND_RETURN_NULL;
+        POP_AND_RETURN_NOTHING();
 
       env->CallObjectMethod(map, put_mid, jpropName, jpropVal);
       if (JNIUtil::isJavaExceptionThrown())
-        POP_AND_RETURN_NULL;
+        POP_AND_RETURN_NOTHING();
 
       env->DeleteLocalRef(jpropName);
       env->DeleteLocalRef(jpropVal);
     }
-
-  return env->PopLocalFrame(map);
 }
 
 jobject CreateJ::InheritedProps(apr_array_header_t *iprops)

Modified: subversion/branches/fsfs-format7/subversion/bindings/javahl/native/CreateJ.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/bindings/javahl/native/CreateJ.h?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/bindings/javahl/native/CreateJ.h (original)
+++ subversion/branches/fsfs-format7/subversion/bindings/javahl/native/CreateJ.h Sun Jun 30 01:03:10 2013
@@ -49,12 +49,19 @@ class CreateJ
   Checksum(const svn_checksum_t *checksum);
 
   static jobject
+  DirEntry(const char *path, const char *absPath,
+           const svn_dirent_t *dirent);
+
+  static jobject
   Info(const char *path, const svn_client_info2_t *info);
 
   static jobject
   Lock(const svn_lock_t *lock);
 
   static jobject
+  LockMap(const apr_hash_t *locks, apr_pool_t *pool);
+
+  static jobject
   ChangedPath(const char *path, svn_log_changed_path2_t *log_item);
 
   static jobject
@@ -82,6 +89,10 @@ class CreateJ
   static jobject
   PropertyMap(apr_hash_t *prop_hash);
 
+  static void
+  FillPropertyMap(jobject map, apr_hash_t* prop_hash,
+                  jmethodID put_method_id = 0);
+
   static jobject
   InheritedProps(apr_array_header_t *inherited_props);
 

Modified: subversion/branches/fsfs-format7/subversion/bindings/javahl/native/EnumMapper.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/bindings/javahl/native/EnumMapper.cpp?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/bindings/javahl/native/EnumMapper.cpp (original)
+++ subversion/branches/fsfs-format7/subversion/bindings/javahl/native/EnumMapper.cpp Sun Jun 30 01:03:10 2013
@@ -191,6 +191,28 @@ 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_tristate_t EnumMapper::toTristate(jobject jTristate)
+{
+  switch (getOrdinal(JAVA_PACKAGE"/types/Tristate", jTristate))
+    {
+    case 1: return svn_tristate_false;
+    case 2: return svn_tristate_true;
+    default: return svn_tristate_unknown;
+    }
+}
+
 svn_depth_t EnumMapper::toDepth(jobject jdepth)
 {
   // The offset for depths is -2

Modified: subversion/branches/fsfs-format7/subversion/bindings/javahl/native/EnumMapper.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/bindings/javahl/native/EnumMapper.h?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/bindings/javahl/native/EnumMapper.h (original)
+++ subversion/branches/fsfs-format7/subversion/bindings/javahl/native/EnumMapper.h Sun Jun 30 01:03:10 2013
@@ -48,6 +48,9 @@ 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);
+  static svn_tristate_t toTristate(jobject jTristate);
 
   /* Converting from C enum's */
   static jint mapCommitMessageStateFlags(apr_byte_t flags);

Modified: subversion/branches/fsfs-format7/subversion/bindings/javahl/native/JNIStringHolder.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/bindings/javahl/native/JNIStringHolder.h?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/bindings/javahl/native/JNIStringHolder.h (original)
+++ subversion/branches/fsfs-format7/subversion/bindings/javahl/native/JNIStringHolder.h Sun Jun 30 01:03:10 2013
@@ -36,6 +36,7 @@ class JNIStringHolder
   JNIStringHolder(jstring jtext);
   ~JNIStringHolder();
   operator const char *() { return m_str; }
+  const char* c_str() const { return m_str; }
   const char *pstrdup(apr_pool_t *pool);
 
  protected:

Modified: subversion/branches/fsfs-format7/subversion/bindings/javahl/native/JNIUtil.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/bindings/javahl/native/JNIUtil.cpp?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/bindings/javahl/native/JNIUtil.cpp (original)
+++ subversion/branches/fsfs-format7/subversion/bindings/javahl/native/JNIUtil.cpp Sun Jun 30 01:03:10 2013
@@ -418,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
@@ -472,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();
 
@@ -796,6 +858,31 @@ 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
@@ -850,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. */
@@ -865,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/fsfs-format7/subversion/bindings/javahl/native/JNIUtil.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/bindings/javahl/native/JNIUtil.h?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/bindings/javahl/native/JNIUtil.h (original)
+++ subversion/branches/fsfs-format7/subversion/bindings/javahl/native/JNIUtil.h Sun Jun 30 01:03:10 2013
@@ -37,6 +37,7 @@ class SVNBase;
 #include <fstream>
 #include <apr_time.h>
 #include <string>
+#include <vector>
 struct svn_error_t;
 
 #define JAVA_PACKAGE "org/apache/subversion/javahl"
@@ -67,6 +68,7 @@ class JNIUtil
   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();
@@ -140,10 +142,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);
   /**

Modified: subversion/branches/fsfs-format7/subversion/bindings/javahl/native/ListCallback.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/bindings/javahl/native/ListCallback.cpp?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/bindings/javahl/native/ListCallback.cpp (original)
+++ subversion/branches/fsfs-format7/subversion/bindings/javahl/native/ListCallback.cpp Sun Jun 30 01:03:10 2013
@@ -126,53 +126,5 @@ jobject
 ListCallback::createJavaDirEntry(const char *path, const char *absPath,
                                  const svn_dirent_t *dirent)
 {
-  JNIEnv *env = JNIUtil::getEnv();
-
-  // Create a local frame for our references
-  env->PushLocalFrame(LOCAL_FRAME_SIZE);
-  if (JNIUtil::isJavaExceptionThrown())
-    return SVN_NO_ERROR;
-
-  jclass clazz = env->FindClass(JAVA_PACKAGE"/types/DirEntry");
-  if (JNIUtil::isJavaExceptionThrown())
-    POP_AND_RETURN_NULL;
-
-  static jmethodID mid = 0;
-  if (mid == 0)
-    {
-      mid = env->GetMethodID(clazz, "<init>",
-                             "(Ljava/lang/String;Ljava/lang/String;"
-                             "L"JAVA_PACKAGE"/types/NodeKind;"
-                             "JZJJLjava/lang/String;)V");
-      if (JNIUtil::isJavaExceptionThrown())
-        POP_AND_RETURN_NULL;
-    }
-
-  jstring jPath = JNIUtil::makeJString(path);
-  if (JNIUtil::isJavaExceptionThrown())
-    POP_AND_RETURN_NULL;
-
-  jstring jAbsPath = JNIUtil::makeJString(absPath);
-  if (JNIUtil::isJavaExceptionThrown())
-    POP_AND_RETURN_NULL;
-
-  jobject jNodeKind = EnumMapper::mapNodeKind(dirent->kind);
-  if (JNIUtil::isJavaExceptionThrown())
-    POP_AND_RETURN_NULL;
-
-  jlong jSize = dirent->size;
-  jboolean jHasProps = (dirent->has_props? JNI_TRUE : JNI_FALSE);
-  jlong jLastChangedRevision = dirent->created_rev;
-  jlong jLastChanged = dirent->time;
-  jstring jLastAuthor = JNIUtil::makeJString(dirent->last_author);
-  if (JNIUtil::isJavaExceptionThrown())
-    POP_AND_RETURN_NULL;
-
-  jobject ret = env->NewObject(clazz, mid, jPath, jAbsPath, jNodeKind,
-                               jSize, jHasProps, jLastChangedRevision,
-                               jLastChanged, jLastAuthor);
-  if (JNIUtil::isJavaExceptionThrown())
-    POP_AND_RETURN_NULL;
-
-  return env->PopLocalFrame(ret);
+  return CreateJ::DirEntry(path, absPath, dirent);
 }

Modified: subversion/branches/fsfs-format7/subversion/bindings/javahl/native/Path.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/bindings/javahl/native/Path.cpp?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/bindings/javahl/native/Path.cpp (original)
+++ subversion/branches/fsfs-format7/subversion/bindings/javahl/native/Path.cpp Sun Jun 30 01:03:10 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_occurred = NULL;
-      m_path = "";
-    }
-  else
+  if (pi_path && *pi_path)
     {
-      m_error_occurred = 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,8 +114,8 @@ Path::c_str() const
 /**
  * Assignment operator
  */
-Path&
-Path::operator=(const Path &pi_path)
+PathBase&
+PathBase::operator=(const PathBase &pi_path)
 {
   m_error_occurred = NULL;
   m_path = pi_path.m_path;
@@ -114,12 +123,12 @@ Path::operator=(const Path &pi_path)
   return *this;
 }
 
-  svn_error_t *Path::error_occurred() const
+svn_error_t *PathBase::error_occurred() const
 {
   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/fsfs-format7/subversion/bindings/javahl/native/Path.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/bindings/javahl/native/Path.h?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/bindings/javahl/native/Path.h (original)
+++ subversion/branches/fsfs-format7/subversion/bindings/javahl/native/Path.h Sun Jun 30 01:03:10 2013
@@ -24,18 +24,19 @@
  * @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.
@@ -48,9 +49,11 @@ class Path
    *
    * @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
@@ -92,6 +99,7 @@ class Path
 
   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,113 @@ 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();
+    }
+
+ 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/fsfs-format7/subversion/bindings/javahl/native/Prompter.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/bindings/javahl/native/Prompter.cpp?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/bindings/javahl/native/Prompter.cpp (original)
+++ subversion/branches/fsfs-format7/subversion/bindings/javahl/native/Prompter.cpp Sun Jun 30 01:03:10 2013
@@ -40,9 +40,9 @@
  * @param jprompter     a global reference to the Java callback object
  */
 Prompter::Prompter(jobject jprompter)
-{
-  m_prompter = jprompter;
-}
+  : m_prompter(jprompter),
+    m_maySave(false)
+{}
 
 Prompter::~Prompter()
 {

Modified: subversion/branches/fsfs-format7/subversion/bindings/javahl/native/RevpropTable.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/bindings/javahl/native/RevpropTable.cpp?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/bindings/javahl/native/RevpropTable.cpp (original)
+++ subversion/branches/fsfs-format7/subversion/bindings/javahl/native/RevpropTable.cpp Sun Jun 30 01:03:10 2013
@@ -27,6 +27,7 @@
 #include "RevpropTable.h"
 #include "JNIUtil.h"
 #include "JNIStringHolder.h"
+#include "JNIByteArray.h"
 #include "Array.h"
 #include <apr_tables.h>
 #include <apr_strings.h>
@@ -41,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());
@@ -71,7 +72,7 @@ const apr_hash_t *RevpropTable::hash(con
   return revprop_table;
 }
 
-RevpropTable::RevpropTable(jobject jrevpropTable)
+RevpropTable::RevpropTable(jobject jrevpropTable, bool bytearray_values)
 {
   m_revpropTable = jrevpropTable;
 
@@ -116,12 +117,27 @@ RevpropTable::RevpropTable(jobject jrevp
           if (JNIUtil::isExceptionThrown())
             return;
 
-          JNIStringHolder propval((jstring)jpropval);
-          if (JNIUtil::isExceptionThrown())
-            return;
+          std::string pv;
+          if (bytearray_values)
+            {
+              JNIByteArray propval((jbyteArray)jpropval);
+              if (JNIUtil::isExceptionThrown())
+                return;
+              if (!propval.isNull())
+                pv = std::string(
+                    reinterpret_cast<const char*>(propval.getBytes()),
+                    propval.getLength());
+            }
+          else
+            {
+              JNIStringHolder propval((jstring)jpropval);
+              if (JNIUtil::isExceptionThrown())
+                return;
+              if (NULL != static_cast<const char *>(propval))
+                pv = static_cast<const char *>(propval);
+            }
 
-          m_revprops[std::string(static_cast<const char *>(propname))]
-            = std::string(static_cast<const char *>(propval));
+          m_revprops[std::string(static_cast<const char *>(propname))] = pv;
 
           JNIUtil::getEnv()->DeleteLocalRef(jpropval);
         }

Modified: subversion/branches/fsfs-format7/subversion/bindings/javahl/native/RevpropTable.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/bindings/javahl/native/RevpropTable.h?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/bindings/javahl/native/RevpropTable.h (original)
+++ subversion/branches/fsfs-format7/subversion/bindings/javahl/native/RevpropTable.h Sun Jun 30 01:03:10 2013
@@ -42,9 +42,9 @@ class RevpropTable
   std::map<std::string, std::string> m_revprops;
   jobject m_revpropTable;
  public:
-  RevpropTable(jobject jrevpropTable);
+  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/fsfs-format7/subversion/bindings/javahl/native/SVNBase.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/bindings/javahl/native/SVNBase.cpp?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/bindings/javahl/native/SVNBase.cpp (original)
+++ subversion/branches/fsfs-format7/subversion/bindings/javahl/native/SVNBase.cpp Sun Jun 30 01:03:10 2013
@@ -97,3 +97,29 @@ inline void SVNBase::findCppAddrFieldID(
         }
     }
 }
+
+jobject SVNBase::createCppBoundObject(const char *clazzName)
+{
+  JNIEnv *env = JNIUtil::getEnv();
+
+  // Create java session object
+  jclass clazz = env->FindClass(clazzName);
+  if (JNIUtil::isJavaExceptionThrown())
+    return NULL;
+
+  static jmethodID ctor = 0;
+  if (ctor == 0)
+    {
+      ctor = env->GetMethodID(clazz, "<init>", "(J)V");
+      if (JNIUtil::isJavaExceptionThrown())
+        return NULL;
+    }
+
+  jlong cppAddr = this->getCppAddr();
+
+  jobject jself = env->NewObject(clazz, ctor, cppAddr);
+  if (JNIUtil::isJavaExceptionThrown())
+    return NULL;
+
+  return jself;
+}

Modified: subversion/branches/fsfs-format7/subversion/bindings/javahl/native/SVNBase.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/bindings/javahl/native/SVNBase.h?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/bindings/javahl/native/SVNBase.h (original)
+++ subversion/branches/fsfs-format7/subversion/bindings/javahl/native/SVNBase.h Sun Jun 30 01:03:10 2013
@@ -82,6 +82,11 @@ class SVNBase
    */
   void dispose(jobject jthis, jfieldID *fid, const char *className);
 
+  /**
+   * Instantiates java object attached to this base object
+   */
+  jobject createCppBoundObject(const char *clazzName);
+
  private:
   /**
    * If the value pointed to by @a fid is zero, find the @c jfieldID

Modified: subversion/branches/fsfs-format7/subversion/bindings/javahl/native/SVNClient.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/bindings/javahl/native/SVNClient.cpp?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/bindings/javahl/native/SVNClient.cpp (original)
+++ subversion/branches/fsfs-format7/subversion/bindings/javahl/native/SVNClient.cpp Sun Jun 30 01:03:10 2013
@@ -30,6 +30,7 @@
 #include "DiffSummaryReceiver.h"
 #include "ClientContext.h"
 #include "Prompter.h"
+#include "RemoteSession.h"
 #include "Pool.h"
 #include "Targets.h"
 #include "Revision.h"
@@ -70,6 +71,7 @@
 #include <vector>
 #include <iostream>
 #include <sstream>
+#include <string>
 
 
 SVNClient::SVNClient(jobject jthis_in)
@@ -227,23 +229,23 @@ rev_range_vector_to_apr_array(std::vecto
     std::vector<RevisionRange>::const_iterator it;
     for (it = revRanges.begin(); it != revRanges.end(); ++it)
     {
-        if (it->toRange(subPool)->start.kind
-            == svn_opt_revision_unspecified
-            && it->toRange(subPool)->end.kind
-            == svn_opt_revision_unspecified)
+        const svn_opt_revision_range_t *range = it->toRange(subPool);
+
+        if (range->start.kind == svn_opt_revision_unspecified
+            && range->end.kind == svn_opt_revision_unspecified)
         {
-            svn_opt_revision_range_t *range =
+            svn_opt_revision_range_t *full =
                 reinterpret_cast<svn_opt_revision_range_t *>
                     (apr_pcalloc(subPool.getPool(), sizeof(*range)));
-            range->start.kind = svn_opt_revision_number;
-            range->start.value.number = 1;
-            range->end.kind = svn_opt_revision_head;
-            APR_ARRAY_PUSH(ranges, const svn_opt_revision_range_t *) = range;
+            full->start.kind = svn_opt_revision_number;
+            full->start.value.number = 1;
+            full->end.kind = svn_opt_revision_head;
+            full->end.value.number = 0;
+            APR_ARRAY_PUSH(ranges, const svn_opt_revision_range_t *) = full;
         }
         else
         {
-            APR_ARRAY_PUSH(ranges, const svn_opt_revision_range_t *) =
-                it->toRange(subPool);
+            APR_ARRAY_PUSH(ranges, const svn_opt_revision_range_t *) = range;
         }
         if (JNIUtil::isExceptionThrown())
             return NULL;
@@ -545,6 +547,7 @@ void SVNClient::resolve(const char *path
 jlong SVNClient::doExport(const char *srcPath, const char *destPath,
                           Revision &revision, Revision &pegRevision,
                           bool force, bool ignoreExternals,
+                          bool ignoreKeywords,
                           svn_depth_t depth, const char *nativeEOL)
 {
     SVN::Pool subPool(pool);
@@ -563,7 +566,7 @@ jlong SVNClient::doExport(const char *sr
                                    destinationPath.c_str(),
                                    pegRevision.revision(),
                                    revision.revision(), force,
-                                   ignoreExternals, FALSE,
+                                   ignoreExternals, ignoreKeywords,
                                    depth,
                                    nativeEOL, ctx,
                                    subPool.getPool()),
@@ -1525,6 +1528,68 @@ SVNClient::patch(const char *patchPath, 
                                  ctx, subPool.getPool()), );
 }
 
+jobject
+SVNClient::openRemoteSession(const char* path, int retryAttempts)
+{
+    static const svn_opt_revision_t HEAD = { svn_opt_revision_head, {0}};
+    static const svn_opt_revision_t NONE = { svn_opt_revision_unspecified, {0}};
+
+    SVN_JNI_NULL_PTR_EX(path, "path", NULL);
+
+    SVN::Pool subPool(pool);
+    svn_client_ctx_t *ctx = context.getContext(NULL, subPool);
+    if (ctx == NULL)
+        return NULL;
+
+    Path checkedPath(path, subPool);
+    SVN_JNI_ERR(checkedPath.error_occurred(), NULL);
+
+    struct PathInfo
+    {
+        std::string url;
+        std::string uuid;
+        static svn_error_t *callback(void *baton,
+                                     const char *,
+                                     const svn_client_info2_t *info,
+                                     apr_pool_t *)
+          {
+              PathInfo* const pi = static_cast<PathInfo*>(baton);
+              pi->url = info->URL;
+              pi->uuid = info->repos_UUID;
+              return SVN_NO_ERROR;
+          }
+    } path_info;
+
+    SVN_JNI_ERR(svn_client_info3(
+                    checkedPath.c_str(), &NONE,
+                    (svn_path_is_url(checkedPath.c_str()) ? &HEAD : &NONE),
+                    svn_depth_empty, FALSE, TRUE, NULL,
+                    PathInfo::callback, &path_info,
+                    ctx, subPool.getPool()),
+                NULL);
+
+    jobject jctx = context.getSelf();
+    if (JNIUtil::isJavaExceptionThrown())
+        return NULL;
+
+    /* Decouple the RemoteSession's context from SVNClient's context
+       by creating a copy of the prompter here. */
+    Prompter* prompter = new Prompter(context.getPrompter());
+    if (!prompter)
+      return NULL;
+
+    jobject jremoteSession = RemoteSession::open(
+        retryAttempts, path_info.url.c_str(), path_info.uuid.c_str(),
+        context.getConfigDirectory(),
+        context.getConfigCallback(),
+        context.getUsername(), context.getPassword(),
+        prompter, jctx);
+    if (JNIUtil::isJavaExceptionThrown())
+      delete prompter;
+
+    return jremoteSession;
+}
+
 ClientContext &
 SVNClient::getClientContext()
 {

Modified: subversion/branches/fsfs-format7/subversion/bindings/javahl/native/SVNClient.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/bindings/javahl/native/SVNClient.h?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/bindings/javahl/native/SVNClient.h (original)
+++ subversion/branches/fsfs-format7/subversion/bindings/javahl/native/SVNClient.h Sun Jun 30 01:03:10 2013
@@ -62,6 +62,7 @@ class DiffOptions;
 class SVNClient :public SVNBase
 {
  public:
+  jobject openRemoteSession(const char* path, int);
   void patch(const char *patchPath, const char *targetPath, bool dryRun,
              int stripCount, bool reverse, bool ignoreWhitespace,
              bool removeTempfiles, PatchCallback *callback);
@@ -122,8 +123,8 @@ class SVNClient :public SVNBase
                  bool allowUnverObstructions, bool ignoreAncestry);
   jlong doExport(const char *srcPath, const char *destPath,
                  Revision &revision, Revision &pegRevision, bool force,
-                 bool ignoreExternals, svn_depth_t depth,
-                 const char *nativeEOL);
+                 bool ignoreExternals, bool ignoreKeywords,
+                 svn_depth_t depth, const char *nativeEOL);
   void resolve(const char *path, svn_depth_t depth,
                svn_wc_conflict_choice_t choice);
   void cleanup(const char *path);

Modified: subversion/branches/fsfs-format7/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp (original)
+++ subversion/branches/fsfs-format7/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp Sun Jun 30 01:03:10 2013
@@ -660,7 +660,8 @@ JNIEXPORT jlong JNICALL
 Java_org_apache_subversion_javahl_SVNClient_doExport
 (JNIEnv *env, jobject jthis, jstring jsrcPath, jstring jdestPath,
  jobject jrevision, jobject jpegRevision, jboolean jforce,
- jboolean jignoreExternals, jobject jdepth, jstring jnativeEOL)
+ jboolean jignoreExternals, jboolean jignoreKeywords,
+ jobject jdepth, jstring jnativeEOL)
 {
   JNIEntry(SVNClient, doExport);
   SVNClient *cl = SVNClient::getCppObject(jthis);
@@ -690,7 +691,9 @@ Java_org_apache_subversion_javahl_SVNCli
     return -1;
 
   return cl->doExport(srcPath, destPath, revision, pegRevision,
-                      jforce ? true : false, jignoreExternals ? true : false,
+                      jforce ? true : false,
+                      jignoreExternals ? true : false,
+                      jignoreKeywords ? true : false,
                       EnumMapper::toDepth(jdepth), nativeEOL);
 }
 
@@ -1631,6 +1634,21 @@ Java_org_apache_subversion_javahl_SVNCli
   cl->getClientContext().setConfigDirectory(configDir);
 }
 
+JNIEXPORT void JNICALL
+Java_org_apache_subversion_javahl_SVNClient_setConfigEventHandler
+(JNIEnv *env, jobject jthis, jobject jconfigHandler)
+{
+  JNIEntry(SVNClient, setConfigDirectory);
+  SVNClient *cl = SVNClient::getCppObject(jthis);
+  if (cl == NULL)
+    {
+      JNIUtil::throwError(_("bad C++ this"));
+      return;
+    }
+
+  cl->getClientContext().setConfigCallback(jconfigHandler);
+}
+
 JNIEXPORT jstring JNICALL
 Java_org_apache_subversion_javahl_SVNClient_getConfigDirectory
 (JNIEnv *env, jobject jthis)
@@ -1851,3 +1869,22 @@ Java_org_apache_subversion_javahl_SVNCli
             jreverse ? true : false, jignoreWhitespace ? true : false,
             jremoveTempfiles ? true : false, &callback);
 }
+
+JNIEXPORT jobject JNICALL
+Java_org_apache_subversion_javahl_SVNClient_nativeOpenRemoteSession
+(JNIEnv *env, jobject jthis, jstring jpath, jint jretryAttempts)
+{
+  JNIEntry(SVNClient, openRemoteSession);
+  SVNClient *cl = SVNClient::getCppObject(jthis);
+  if (cl == NULL)
+    {
+      JNIUtil::throwError("bad C++ this");
+      return NULL;
+    }
+
+  JNIStringHolder path(jpath);
+  if (JNIUtil::isJavaExceptionThrown())
+    return NULL;
+
+  return cl->openRemoteSession(path, jretryAttempts);
+}

Modified: subversion/branches/fsfs-format7/subversion/bindings/javahl/src/org/apache/subversion/javahl/ClientException.java
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/bindings/javahl/src/org/apache/subversion/javahl/ClientException.java?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/bindings/javahl/src/org/apache/subversion/javahl/ClientException.java (original)
+++ subversion/branches/fsfs-format7/subversion/bindings/javahl/src/org/apache/subversion/javahl/ClientException.java Sun Jun 30 01:03:10 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/fsfs-format7/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java (original)
+++ subversion/branches/fsfs-format7/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java Sun Jun 30 01:03:10 2013
@@ -221,6 +221,10 @@ public interface ISVNClient
 
     /**
      * Adds a file to the repository.
+     * <p>
+     * <b>Note:</b> Behaves like the 1.8 version with
+     * <code>noAutoProps</code> set to <code>false</code>.
+     *
      * @param path      path to be added.
      * @param depth     the depth to recurse into subdirectories
      * @param force     if adding a directory and recurse true and path is a
@@ -229,7 +233,6 @@ public interface ISVNClient
      *                  ignore patterns
      * @param addParents add any intermediate parents to the working copy
      * @throws ClientException
-     * @note this method behaves like the 1.8 version with noAutoProps=false
      */
     void add(String path, Depth depth, boolean force, boolean noIgnores,
              boolean addParents)
@@ -399,6 +402,31 @@ public interface ISVNClient
      * @param depth           how deep to recurse in subdirectories
      * @param nativeEOL       which EOL characters to use during export
      * @throws ClientException
+     * @since 1.9
+     */
+    long doExport(String srcPath, String destPath, Revision revision,
+                  Revision pegRevision, boolean force,
+                  boolean ignoreExternals, boolean ignoreKeywords,
+                  Depth depth, String nativeEOL)
+            throws ClientException;
+
+    /**
+     * Exports the contents of either a subversion repository into a
+     * 'clean' directory (meaning a directory with no administrative
+     * directories).
+     * <p>
+     * <b>Note:</b> Behaves like the 1.9 version with
+     * ignoreKeywords set to false.
+     *
+     * @param srcPath         the url of the repository path to be exported
+     * @param destPath        a destination path that must not already exist.
+     * @param revision        the revsion to be exported
+     * @param pegRevision     the revision to interpret srcPath
+     * @param force           set if it is ok to overwrite local files
+     * @param ignoreExternals ignore external during export
+     * @param depth           how deep to recurse in subdirectories
+     * @param nativeEOL       which EOL characters to use during export
+     * @throws ClientException
      */
     long doExport(String srcPath, String destPath, Revision revision,
                   Revision pegRevision, boolean force, boolean ignoreExternals,
@@ -457,6 +485,10 @@ public interface ISVNClient
     /**
      * Import a file or directory into a repository directory  at
      * head.
+     * <p>
+     * <b>Note:</b> Behaves like the 1.8 version with noAutoProps
+     * set to false and without the filtering option.
+     *
      * @param path      the local path
      * @param url       the target url
      * @param depth     depth to traverse into subdirectories
@@ -469,8 +501,6 @@ public interface ISVNClient
      * @param handler   the commit message callback
      * @param callback  the commit status callback
      * @throws ClientException
-     * @note this method behaves like the 1.8 version with noAutoProps=false
-     *       and without the filtering option.
      */
     void doImport(String path, String url, Depth depth,
                   boolean noIgnore, boolean ignoreUnknownNodeTypes,
@@ -513,6 +543,9 @@ public interface ISVNClient
 
     /**
      * Merge changes from two paths into a new local path.
+     * <p>
+     * <b>Note:</b> Behaves like the 1.8 version where ignoreAncestry
+     * maps to both ignoreMergeinfo and diffIgnoreAncestry
      *
      * @param path1          first path or url
      * @param revision1      first revision
@@ -525,8 +558,6 @@ public interface ISVNClient
      * @param dryRun         do not change anything
      * @param recordOnly     record mergeinfo but do not run merge
      * @throws ClientException
-     * @note Behaves like the 1.8 where ignoreAncestry maps to
-     *       both ignoreMergeinfo and diffIgnoreAncestry
      */
     void merge(String path1, Revision revision1, String path2,
                Revision revision2, String localPath, boolean force, Depth depth,
@@ -557,6 +588,10 @@ public interface ISVNClient
 
     /**
      * Merge set of revisions into a new local path.
+     * <p>
+     * <b>Note:</b> Behaves like the 1.8 version where ignoreAncestry
+     * maps to both ignoreMergeinfo and diffIgnoreAncestry
+     *
      * @param path          path or url
      * @param pegRevision   revision to interpret path
      * @param revisions     revisions to merge;
@@ -569,8 +604,6 @@ public interface ISVNClient
      * @param dryRun        do not change anything
      * @param recordOnly    record mergeinfo but do not run merge
      * @throws ClientException
-     * @note Behaves like the 1.8 where ignoreAncestry maps to
-     *       both ignoreMergeinfo and diffIgnoreAncestry
      */
     void merge(String path, Revision pegRevision, List<RevisionRange> revisions,
                String localPath, boolean force, Depth depth,
@@ -635,6 +668,10 @@ public interface ISVNClient
 
     /**
      * Retrieve either merged or eligible-to-be-merged revisions.
+     * <p>
+     * <b>Note:</b> Behaves like the 1.8 version, with unspecified
+     * revision range.
+     *
      * @param kind                   kind of revisions to receive
      * @param pathOrUrl              target of merge
      * @param pegRevision            peg rev for pathOrUrl
@@ -644,7 +681,6 @@ public interface ISVNClient
      * @param depth                  the depth to recurse to
      * @param revProps               the revprops to retrieve
      * @param callback               the object to receive the log messages
-     * @note Behaves like the 1.8 version, with unspecified revision range.
      */
     void getMergeinfoLog(Mergeinfo.LogKind kind, String pathOrUrl,
                          Revision pegRevision, String mergeSourceUrl,
@@ -1033,6 +1069,12 @@ public interface ISVNClient
     void setConfigDirectory(String configDir) throws ClientException;
 
     /**
+     * Set an event handler that will be called every time the
+     * configuration is loaded.
+     */
+    void setConfigEventHandler(ConfigEvent configHandler);
+
+    /**
      * Get the configuration directory
      * @return  the directory
      * @throws ClientException
@@ -1145,4 +1187,40 @@ public interface ISVNClient
                int stripCount, boolean reverse, boolean ignoreWhitespace,
                boolean removeTempfiles, PatchCallback callback)
             throws ClientException;
+
+    /**
+     * Open a persistent session to a repository.
+     * <p>
+     * <b>Note:</b> The session object inherits the progress callback,
+     * configuration directory and authentication info.
+     *
+     * @param pathOrUrl A path in a working copy from which the
+     *        session URL is derived, or the URL itself.
+     * @throws remote.RetryOpenSession If the session URL was redirected
+     * @throws SubversionException If an URL redirect cycle was detected
+     * @throws ClientException
+     * @since 1.9
+     */
+    ISVNRemote openRemoteSession(String pathOrUrl)
+            throws ClientException, SubversionException;
+
+    /**
+     * Open a persistent session to a repository.
+     * <p>
+     * <b>Note:</b> The session object inherits the progress callback,
+     * configuration directory and authentication info.
+     *
+     * @param pathOrUrl A path in a working copy from which the
+     *        session URL is derived, or the URL itself.
+     * @param retryAttempts The number of times to retry the operation
+     *        if the given URL is redirected.
+     * @throws IllegalArgumentException If <code>retryAttempts</code>
+     *         is not positive
+     * @throws remote.RetryOpenSession If the session URL was redirected
+     * @throws SubversionException If an URL redirect cycle was detected
+     * @throws ClientException
+     * @since 1.9
+     */
+    ISVNRemote openRemoteSession(String pathOrUrl, int retryAttempts)
+            throws ClientException, SubversionException;
 }

Modified: subversion/branches/fsfs-format7/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java (original)
+++ subversion/branches/fsfs-format7/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java Sun Jun 30 01:03:10 2013
@@ -151,14 +151,14 @@ public class SVNClient implements ISVNCl
         clientContext.notify = notify;
     }
 
-    public void setConflictResolver(ConflictResolverCallback listener)
+    public void setConflictResolver(ConflictResolverCallback resolver)
     {
-        clientContext.resolver = listener;
+        clientContext.resolver = resolver;
     }
 
-    public void setProgressCallback(ProgressCallback listener)
+    public void setProgressCallback(ProgressCallback progress)
     {
-        clientContext.listener = listener;
+        clientContext.setProgressCallback(progress);
     }
 
     public native void remove(Set<String> paths, boolean force,
@@ -239,9 +239,20 @@ public class SVNClient implements ISVNCl
     public native long doExport(String srcPath, String destPath,
                                 Revision revision, Revision pegRevision,
                                 boolean force, boolean ignoreExternals,
+                                boolean ignorKeywords,
                                 Depth depth, String nativeEOL)
             throws ClientException;
 
+    public long doExport(String srcPath, String destPath,
+                                Revision revision, Revision pegRevision,
+                                boolean force, boolean ignoreExternals,
+                                Depth depth, String nativeEOL)
+            throws ClientException
+    {
+        return doExport(srcPath, destPath, revision, pegRevision,
+                        force, ignoreExternals, false, depth, nativeEOL);
+    }
+
     public native long doSwitch(String path, String url, Revision revision,
                                 Revision pegRevision, Depth depth,
                                 boolean depthIsSticky, boolean ignoreExternals,
@@ -562,6 +573,8 @@ public class SVNClient implements ISVNCl
     public native void setConfigDirectory(String configDir)
             throws ClientException;
 
+    public native void setConfigEventHandler(ConfigEvent configHandler);
+
     public native String getConfigDirectory()
             throws ClientException;
 
@@ -661,16 +674,33 @@ public class SVNClient implements ISVNCl
                              PatchCallback callback)
             throws ClientException;
 
+    public ISVNRemote openRemoteSession(String pathOrUrl)
+            throws ClientException, SubversionException
+    {
+        return nativeOpenRemoteSession(pathOrUrl, 1);
+    }
+
+    public ISVNRemote openRemoteSession(String pathOrUrl, int retryAttempts)
+            throws ClientException, SubversionException
+    {
+        if (retryAttempts <= 0)
+            throw new IllegalArgumentException(
+                "retryAttempts must be positive");
+        return nativeOpenRemoteSession(pathOrUrl, retryAttempts);
+    }
+
+    private native ISVNRemote nativeOpenRemoteSession(
+        String pathOrUrl, int retryAttempts)
+            throws ClientException, SubversionException;
+
     /**
      * A private class to hold the contextual information required to
      * persist in this object, such as notification handlers.
      */
-    private class ClientContext
-        implements ClientNotifyCallback, ProgressCallback,
-            ConflictResolverCallback
+    private class ClientContext extends OperationContext
+        implements ClientNotifyCallback, ConflictResolverCallback
     {
         public ClientNotifyCallback notify = null;
-        public ProgressCallback listener = null;
         public ConflictResolverCallback resolver = null;
 
         public void onNotify(ClientNotifyInformation notifyInfo)
@@ -679,12 +709,6 @@ public class SVNClient implements ISVNCl
                 notify.onNotify(notifyInfo);
         }
 
-        public void onProgress(ProgressEvent event)
-        {
-            if (listener != null)
-                listener.onProgress(event);
-        }
-
         public ConflictResult resolve(ConflictDescriptor conflict)
             throws SubversionException
         {

Modified: subversion/branches/fsfs-format7/subversion/bindings/javahl/src/org/apache/subversion/javahl/types/VersionExtended.java
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/bindings/javahl/src/org/apache/subversion/javahl/types/VersionExtended.java?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/bindings/javahl/src/org/apache/subversion/javahl/types/VersionExtended.java (original)
+++ subversion/branches/fsfs-format7/subversion/bindings/javahl/src/org/apache/subversion/javahl/types/VersionExtended.java Sun Jun 30 01:03:10 2013
@@ -45,9 +45,9 @@ public class VersionExtended
     /**
      * @return The canonical host triplet (arch-vendor-osname) of the
      * system where libsvn_subr was compiled.
-     *
-     * @note On Unix-like systems (includng Mac OS X), this string is
-     * the same as the output of the config.guess script for the
+     * <p>
+     * <b>Note:</b> On Unix-like systems (includng Mac OS X), this string
+     * is the same as the output of the config.guess script for the
      * underlying Subversion libraries.
      */
     public native String getBuildHost();
@@ -60,8 +60,8 @@ public class VersionExtended
     /**
      * @return The canonical host triplet (arch-vendor-osname) of the
      * system where the current process is running.
-     *
-     * @note This string may not be the same as the output of
+     * <p>
+     * <b>Note:</b> This string may not be the same as the output of
      * config.guess on the same system.
      */
     public native String getRuntimeHost();
@@ -139,8 +139,8 @@ public class VersionExtended
     /**
      * @return Iterator for an immutable internal list of #LoadedLib
      * describing loaded shared libraries.  The the list may be empty.
-     *
-     * @note On Mac OS X, the loaded frameworks, private frameworks
+     * <p>
+     * <b>Note:</b> On Mac OS X, the loaded frameworks, private frameworks
      * and system libraries will not be listed.
      */
     public java.util.Iterator<LoadedLib> getLoadedLibs()
@@ -178,7 +178,8 @@ public class VersionExtended
 
         /**
          * Implementation of java.util.Iterator#remove().
-         * @note Not implemented, all sequences are immutable.
+         * <p>
+         * <b>Note:</b> Not implemented, all sequences are immutable.
          */
         public void remove()
         {
@@ -219,7 +220,8 @@ public class VersionExtended
 
         /**
          * Implementation of java.util.Iterator#remove().
-         * @note Not implemented, all sequences are immutable.
+         * <p>
+         * <b>Note:</b> Not implemented, all sequences are immutable.
          */
         public void remove()
         {

Modified: subversion/branches/fsfs-format7/subversion/bindings/javahl/tests/org/apache/subversion/javahl/RunTests.java
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/bindings/javahl/tests/org/apache/subversion/javahl/RunTests.java?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/bindings/javahl/tests/org/apache/subversion/javahl/RunTests.java (original)
+++ subversion/branches/fsfs-format7/subversion/bindings/javahl/tests/org/apache/subversion/javahl/RunTests.java Sun Jun 30 01:03:10 2013
@@ -92,6 +92,7 @@ public class RunTests
             {
                 // Add default test suites.
                 suite.addTestSuite(SVNReposTests.class);
+                suite.addTestSuite(SVNRemoteTests.class);
                 suite.addTestSuite(BasicTests.class);
             }
             else

Modified: subversion/branches/fsfs-format7/subversion/bindings/swig/perl/native/Client.pm
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/bindings/swig/perl/native/Client.pm?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/bindings/swig/perl/native/Client.pm (original)
+++ subversion/branches/fsfs-format7/subversion/bindings/swig/perl/native/Client.pm Sun Jun 30 01:03:10 2013
@@ -131,16 +131,17 @@ to an array of them.
 
 =item $revision
 
-This specifies a revision in the subversion repository.  You can specify a
+This specifies a revision in the Subversion repository.  You can specify a
 revision in several ways.  The easiest and most obvious is to directly
 provide the revision number.  You may also use the strings (aka revision
 keywords) 'HEAD', 'BASE', 'COMMITTED', and 'PREV' which have the same
 meanings as in the command line client.  When referencing a working copy
 you can use the string 'WORKING" to reference the BASE plus any local
-modifications.  undef may be used to specify an unspecified revision.
-Finally you may pass a date by specifying the date inside curly braces
+modifications.  C<undef> may be used to specify an unspecified revision.
+You may alos pass a date by specifying the date inside curly braces
 '{}'.  The date formats accepted are the same as the command line client
-accepts.
+accepts. Finally a C<_p_svn_opt_revision_t> object is accepted
+(which may have been returned by some Subversion function).
 
 =item $recursive $nonrecursive.
 
@@ -564,48 +565,113 @@ operation, invoking $receiver on each ch
  };
  $client->info( 'foo/bar.c', undef, 'WORKING', $receiver, 0 );
 
-=item $client-E<gt>log($targets, $start, $end, $discover_changed_paths, $strict_node_history, \&log_receiver, $pool);
+=item $client-E<gt>log5($targets, $peg_revision, $revision_ranges, $limit, $discover_changed_paths, $strict_node_history, $include_merged_revisions, $revprops, \&log_entry_receiver, $pool);
 
-Invoke the log_receiver subroutine on each log_message from $start to $end in
-turn, inclusive (but will never invoke receiver on a given log message more
+Invoke C<log_entry_receiver> on each log message from
+each revision range in C<$revision_ranges> in turn,
+inclusive (but never invoke C<log_entry_receiver> on a given log message more
 than once).
 
-$targets is a reference to an array containing all the paths or URLs for
-which the log messages are desired.  The log_receiver is only invoked on
-messages whose revisions involved a change to some path in $targets.
+C<$targets> is a reference to an array of either a URL followed by zero 
+or more relative paths, or 1 working copy path, for which log
+messages are desired. If the array contains only a single element
+you may set C<$targets> to this element instead.
+C<log_entry_receiver> is invoked only on messages whose
+revisions involved a change to some path in C<$targets>.
+
+C<$peg_revision> indicates in which revision C<$targets> are valid. 
+If C<$peg_revision> is C<undef>, it defaults to 'HEAD'
+for URLs or 'WORKING' for WC paths.
+
+C<$revision_ranges> is either a single I<revision range> or a reference
+to an array of them. A I<revision range> may be specified
+as a reference to a two-element array C<[$start, $end]>
+of L<$revision|/$revision>s or a 
+L<SVN::Core::svn_opt_revision_range_t|SVN::Core/svn_opt_revision_range_t> 
+object. Examples:
+
+  $revision_ranges = ['HEAD', 1];
+  $revision_ranges = [[2, 3], [5, 8], [13, 21]];
+
+If C<$limit> is non-zero only invoke C<log_entry_receiver> 
+on the first C<$limit> logs.
+
+If C<$discover_changed_paths> is true, then the I<changed_paths2> field 
+in the C<$log_entry> argument to C<log_entry_receiver> will be
+populated on each invocation.  I<Note:> The I<text_modified> and
+I<props_modified> fields of the I<changed_paths2> structure may have the value
+C<$SVN::Tristate::unknown> if the repository does not report that information.
+
+If C<$strict_node_history> is true, copy history (if any exists) will
+not be traversed while harvesting revision logs for each target.
+
+If C<$include_merged_revisions> is true, log information for revisions
+which have been merged to C<$targets> will also be returned.
+
+If C<$revprops> is C<undef>, retrieve all revision properties.
+Otherwise C<$revpros> should be a reference to an array of
+property names and only these properties will be retrieved
+(i.e. none if the array is empty).
+
+Use C<$pool> for any temporary allocation.
+
+Calls the notify subroutine with a C<$SVN::Wc::Notify::Action::skip> 
+signal on any unversioned C<$targets>.
+
+The C<log_entry_receiver> takes the following arguments:
+C<$log_entry, $pool>.  C<$log_entry> is a 
+L<SVN::Core::svn_log_entry_t|SVN::Core/svn_log_entry_t> object.
+
+=item $client-E<gt>log4($targets, $peg_revision, $start, $end, $limit, $discover_changed_paths, $strict_node_history, $include_merged_revisions, $revprops, \&log_entry_receiver, $pool);
+
+Similar to C<$client-E<gt>log5()>, 
+but takes explicit C<$start> and C<$end> parameters
+instead of C<$revision_ranges>.
+
+Deprecated.
+
+=item $client-E<gt>log3($targets, $peg_revision, $start, $end, $limit, $discover_changed_paths, $strict_node_history, \&log_message_receiver, $pool);
+
+Similar to C<$client-E<gt>log4()>, but using C<log_message_receiver>
+instead of C<log_entry_receiver>.  Also, C<$include_merged_revisions> 
+is false and C<$revprops> is [qw( svn:author svn:date and svn:log )].
+
+The C<log_message_receiver> takes the following arguments:
+C<$changed_paths, $revision, $author, $date, $message, $pool>.
+It is called once for each log C<$message> from the C<$revision>
+on C<$date> by C<$author>.  C<$author>, C<$date> or C<$message> 
+may be C<undef>.
+
+If C<$changed_paths> is defined it references a hash with the keys
+every path committed in C<$revision>; the values are 
+L<SVN::Core::svn_log_changed_path_t|SVN::Core/svn_log_changed_path_t>
+objects.
+
+Deprecated.
+
+=item $client-E<gt>log2($targets, $start, $end, $limit, $discover_changed_paths, $strict_node_history, \&log_message_receiver, $pool);
 
-If $discover_changed_paths is set, then the changed_paths argument to the
-log_receiver routine will be passed on each invocation.
+Similar to C<$client-E<gt>log3()>, but with C<$peg_revision> set to C<undef>.
 
-If $strict_node_history is set, copy history (if any exists) will not be
-traversed while harvesting revision logs for each target.
+Deprecated.
 
-If $start or $end is undef the arp_err code will be set to:
-$SVN::Error::CLIENT_BAD_REVISION.
+=item $client-E<gt>log($targets, $start, $end, $discover_changed_paths, $strict_node_history, \&log_message_receiver, $pool);
 
-Special case for repositories at revision 0:
+Similar to C<$client-E<gt>log2()>, but with C<$limit> set to 0.
 
-If $start is 'HEAD' and $end is 1, then handle an empty (no revisions)
+I<Special case for repositories at revision 0:>
+If C<$start> is 'HEAD' and C<$end> is 1, then handle an empty (no revisions)
 repository specially: instead of erroring because requested revision 1
-when the highest revision is 0, just invoke $log_receiver on revision 0,
-passing undef to changed paths and empty strings for the author and date.
-This is because that particular combination of $start and $end usually indicates
+when the highest revision is 0, just invoke 
+C<log_message_receiver> on revision 0,
+passing C<undef> to C<$changed_paths> and empty strings for the author and date.
+This is because that particular combination of C<$start> 
+and C<$end> usually indicates
 the common case of log invocation; the user wants to see all log messages from
 youngest to oldest, where the oldest commit is revision 1.  That works fine,
 except there are no commits in the repository, hence this special case.
 
-Calls the notify subroutine with a $SVN::Wc::Notify::Action::skip signal on any
-unversioned targets.
-
-The log_receiver takes the following arguments:
-$changed_paths, $revision, $author, $date, $message, $pool
-
-It is called once for each log $message from the $revision
-on $date by $author.  $author, $date or $message may be undef.
-
-If $changed_paths is defined it references a hash with the keys
-every path committed in $revision; the values are svn_log_changed_path_t
-objects.
+Deprecated.
 
 =item $client-E<gt>ls($target, $revision, $recursive, $pool);
 
@@ -1719,14 +1785,6 @@ for more details.
 
 =item $client-E<gt>list2(...)
 
-=item $client-E<gt>log2(...)
-
-=item $client-E<gt>log3(...)
-
-=item $client-E<gt>log4(...)
-
-=item $client-E<gt>log5(...)
-
 =item $client-E<gt>ls2(...)
 
 =item $client-E<gt>ls3(...)

Modified: subversion/branches/fsfs-format7/subversion/bindings/swig/ruby/test/util.rb
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/bindings/swig/ruby/test/util.rb?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/bindings/swig/ruby/test/util.rb (original)
+++ subversion/branches/fsfs-format7/subversion/bindings/swig/ruby/test/util.rb Sun Jun 30 01:03:10 2013
@@ -19,7 +19,41 @@
 
 require "fileutils"
 require "pathname"
-require "./svn/util"
+
+# Tale of a hack...
+#
+# Here we are, %SVN-WC-ROOT%/subversion/bindings/swig/ruby/test/util.rb,
+# trying to require %SVN-WC-ROOT%/subversion/bindings/swig/ruby/svn/util.rb,
+# all the while supporting both Ruby 1.8 and 1.9.  Simply using this,
+#
+#   require "svn/util"
+#
+# works for Ruby 1.8 if the CWD is subversion/bindings/swig/ruby
+# when we are running the tests, e.g.:
+#
+#   %SVN-WC-ROOT%/subversion/bindings/swig/ruby>ruby test\run-test.rb
+#
+# This is because the CWD is included in the load path when Ruby 1.8
+# searches for required files.  But this doesn't work for Ruby 1.9,
+# which doesn't include the CWD this way, so instead we could use this:
+#
+#   require "./svn/util"
+#
+# But that only works if ./svn/util is relative to the CWD (again if the
+# CWD is %SVN-WC-ROOT%/subversion/bindings/swig/ruby).  However, if we run
+# the tests from a different CWD and specify
+# %SVN-WC-ROOT%/subversion/bindings/swig/ruby as an additional $LOAD_PATH
+# using the ruby -I option, then that fails on both 1.8 and 1.9 with a
+# LoadError.
+#
+# The usual solution in a case like this is to use require_relative,
+#
+#  require_relative "../svn/util"
+#
+# But that's only available in Ruby 1.9.  We could require the backports gem
+# but there is a simple workaround, just calculate the full path of util:
+require File.join(File.dirname(__FILE__), '../svn/util')
+
 require "tmpdir"
 
 require "my-assertions"

Modified: subversion/branches/fsfs-format7/subversion/include/private/svn_client_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/include/private/svn_client_private.h?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/include/private/svn_client_private.h (original)
+++ subversion/branches/fsfs-format7/subversion/include/private/svn_client_private.h Sun Jun 30 01:03:10 2013
@@ -200,29 +200,6 @@ svn_client__create_status(svn_client_sta
                           apr_pool_t *result_pool,
                           apr_pool_t *scratch_pool);
 
-/* Set *ANCESTOR_URL and *ANCESTOR_REVISION to the URL and revision,
- * respectively, of the youngest common ancestor of the two locations
- * PATH_OR_URL1@REV1 and PATH_OR_URL2@REV2.  Set *ANCESTOR_RELPATH to
- * NULL and *ANCESTOR_REVISION to SVN_INVALID_REVNUM if they have no
- * common ancestor.  This function assumes that PATH_OR_URL1@REV1 and
- * PATH_OR_URL2@REV2 both refer to the same repository.
- *
- * Use the authentication baton cached in CTX to authenticate against
- * the repository.
- *
- * See also svn_client__get_youngest_common_ancestor().
- */
-svn_error_t *
-svn_client__youngest_common_ancestor(const char **ancestor_url,
-                                     svn_revnum_t *ancestor_rev,
-                                     const char *path_or_url1,
-                                     const svn_opt_revision_t *revision1,
-                                     const char *path_or_url2,
-                                     const svn_opt_revision_t *revision2,
-                                     svn_client_ctx_t *ctx,
-                                     apr_pool_t *result_pool,
-                                     apr_pool_t *scratch_pool);
-
 /* Get the repository location of the base node at LOCAL_ABSPATH.
  *
  * A pathrev_t wrapper around svn_wc__node_get_base().

Modified: subversion/branches/fsfs-format7/subversion/include/private/svn_editor.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/include/private/svn_editor.h?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/include/private/svn_editor.h (original)
+++ subversion/branches/fsfs-format7/subversion/include/private/svn_editor.h Sun Jun 30 01:03:10 2013
@@ -573,9 +573,9 @@ typedef svn_error_t *(*svn_editor_cb_alt
   void *baton,
   const char *relpath,
   svn_revnum_t revision,
-  apr_hash_t *props,
   const svn_checksum_t *checksum,
   svn_stream_t *contents,
+  apr_hash_t *props,
   apr_pool_t *scratch_pool);
 
 /** @see svn_editor_alter_symlink(), svn_editor_t.
@@ -585,8 +585,8 @@ typedef svn_error_t *(*svn_editor_cb_alt
   void *baton,
   const char *relpath,
   svn_revnum_t revision,
-  apr_hash_t *props,
   const char *target,
+  apr_hash_t *props,
   apr_pool_t *scratch_pool);
 
 /** @see svn_editor_delete(), svn_editor_t.
@@ -1020,9 +1020,9 @@ svn_error_t *
 svn_editor_alter_file(svn_editor_t *editor,
                       const char *relpath,
                       svn_revnum_t revision,
-                      apr_hash_t *props,
                       const svn_checksum_t *checksum,
-                      svn_stream_t *contents);
+                      svn_stream_t *contents,
+                      apr_hash_t *props);
 
 /** Drive @a editor's #svn_editor_cb_alter_symlink_t callback.
  *
@@ -1047,8 +1047,8 @@ svn_error_t *
 svn_editor_alter_symlink(svn_editor_t *editor,
                          const char *relpath,
                          svn_revnum_t revision,
-                         apr_hash_t *props,
-                         const char *target);
+                         const char *target,
+                         apr_hash_t *props);
 
 /** Drive @a editor's #svn_editor_cb_delete_t callback.
  *