You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2013/06/25 04:02:49 UTC

svn commit: r1496334 - in /subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl: ./ native/ src/org/apache/subversion/javahl/ src/org/apache/subversion/javahl/remote/ tests/org/apache/subversion/javahl/

Author: brane
Date: Tue Jun 25 02:02:47 2013
New Revision: 1496334

URL: http://svn.apache.org/r1496334
Log:
On the javahl-1.7-extensions branch: Sync JavaHL bindings with trunk up r1496333.

Added:
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNReporter.java
      - copied unchanged from r1496333, subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNReporter.java
Modified:
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/   (props changed)
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/CreateJ.cpp
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/CreateJ.h
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/JNIUtil.cpp
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/ListCallback.cpp
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/OperationContext.cpp
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/OperationContext.h
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RemoteSession.cpp
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RemoteSession.h
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RevpropTable.cpp
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RevpropTable.h
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/SVNClient.cpp
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/SVNClient.h
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_RemoteSession.cpp
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNEditor.java
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRemote.java
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/RemoteFactory.java
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/RemoteSession.java
    subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java

Propchange: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/
------------------------------------------------------------------------------
  Merged /subversion/trunk/subversion/bindings/javahl:r1494651-1496333

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/CreateJ.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/CreateJ.cpp?rev=1496334&r1=1496333&r2=1496334&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/CreateJ.cpp (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/CreateJ.cpp Tue Jun 25 02:02:47 2013
@@ -226,6 +226,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();
@@ -1085,6 +1140,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;
   int i = 0;
   for (hi = apr_hash_first(apr_hash_pool_get(prop_hash), prop_hash);
@@ -1093,26 +1179,29 @@ jobject CreateJ::PropertyMap(apr_hash_t 
       const char *key;
       svn_string_t *val;
 
-      apr_hash_this(hi, (const void **)&key, NULL, (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(
                                     (const signed char *)val->data, val->len);
       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::Set(std::vector<jobject> &objects)

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/CreateJ.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/CreateJ.h?rev=1496334&r1=1496333&r2=1496334&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/CreateJ.h (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/CreateJ.h Tue Jun 25 02:02:47 2013
@@ -49,6 +49,10 @@ 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
@@ -85,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);
+
   /* This creates a set of Objects.  It derefs the members of the vector
    * after putting them in the set, so they caller doesn't need to. */
   static jobject

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/JNIUtil.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/JNIUtil.cpp?rev=1496334&r1=1496333&r2=1496334&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/JNIUtil.cpp (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/JNIUtil.cpp Tue Jun 25 02:02:47 2013
@@ -377,7 +377,7 @@ JNIUtil::putErrorsInTrace(svn_error_t *e
 
   char *tmp_path;
   char *path = svn_dirent_dirname(err->file, err->pool);
-  while (tmp_path = strchr(path, '/'))
+  while ((tmp_path = strchr(path, '/')))
     *tmp_path = '.';
 
   jstring jmethodName = makeJString(path);

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/ListCallback.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/ListCallback.cpp?rev=1496334&r1=1496333&r2=1496334&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/ListCallback.cpp (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/ListCallback.cpp Tue Jun 25 02:02:47 2013
@@ -124,53 +124,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/javahl-1.7-extensions/subversion/bindings/javahl/native/OperationContext.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/OperationContext.cpp?rev=1496334&r1=1496333&r2=1496334&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/OperationContext.cpp (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/OperationContext.cpp Tue Jun 25 02:02:47 2013
@@ -40,7 +40,7 @@
 OperationContext::OperationContext(SVN::Pool &pool)
   : m_config(NULL),
     m_prompter(NULL),
-    m_cancelOperation(false),
+    m_cancelOperation(0),
     m_pool(&pool),
     m_jctx(NULL)
 {}
@@ -279,19 +279,19 @@ const Prompter& OperationContext::getPro
 void
 OperationContext::cancelOperation()
 {
-  m_cancelOperation = true;
+  svn_atomic_set(&m_cancelOperation, 1);
 }
 
 void
 OperationContext::resetCancelRequest()
 {
-  m_cancelOperation = false;
+  svn_atomic_set(&m_cancelOperation, 0);
 }
 
 bool
 OperationContext::isCancelledOperation()
 {
-  return m_cancelOperation;
+  return bool(svn_atomic_read(&m_cancelOperation));
 }
 
 svn_error_t *

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/OperationContext.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/OperationContext.h?rev=1496334&r1=1496333&r2=1496334&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/OperationContext.h (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/OperationContext.h Tue Jun 25 02:02:47 2013
@@ -31,6 +31,7 @@
 
 #include "svn_types.h"
 #include "svn_client.h"
+#include "private/svn_atomic.h"
 
 #include <jni.h>
 #include "Pool.h"
@@ -51,7 +52,7 @@ class OperationContext
   apr_hash_t * m_config;
 
   Prompter *m_prompter;
-  bool m_cancelOperation;
+  svn_atomic_t m_cancelOperation;
 
  protected:
   SVN::Pool *m_pool;

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RemoteSession.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RemoteSession.cpp?rev=1496334&r1=1496333&r2=1496334&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RemoteSession.cpp (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RemoteSession.cpp Tue Jun 25 02:02:47 2013
@@ -27,13 +27,17 @@
 #include <cstring>
 #include <set>
 
+#include "JNIByteArray.h"
 #include "JNIStringHolder.h"
 #include "JNIUtil.h"
 
 #include "svn_ra.h"
+#include "svn_string.h"
+#include "svn_dirent_uri.h"
 
 #include "CreateJ.h"
 #include "EnumMapper.h"
+#include "OutputStream.h"
 #include "Prompter.h"
 #include "Revision.h"
 #include "RemoteSession.h"
@@ -387,26 +391,247 @@ RemoteSession::getRevisionByTimestamp(jl
   return rev;
 }
 
-jobject
-RemoteSession::getLocks(jstring jpath, jobject jdepth)
+namespace {
+bool byte_array_to_svn_string(JNIByteArray& ary, svn_string_t& str)
 {
-  JNIStringHolder path(jpath);
+  if (ary.isNull())
+    return false;
+
+  str.data = reinterpret_cast<const char*>(ary.getBytes());
+  str.len = ary.getLength();
+  return true;
+}
+} // anonymous namespace
+
+void
+RemoteSession::changeRevisionProperty(
+    jlong jrevision, jstring jname,
+    jbyteArray jold_value, jbyteArray jvalue)
+{
+  JNIStringHolder name(jname);
   if (JNIUtil::isExceptionThrown())
-    return NULL;
+    return;
 
-  svn_depth_t depth = EnumMapper::toDepth(jdepth);
+  JNIByteArray old_value(jold_value);
+  if (JNIUtil::isExceptionThrown())
+    return;
+
+  JNIByteArray value(jvalue);
+  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_JNI_ERR(svn_ra_change_rev_prop2(m_session,
+                                      svn_revnum_t(jrevision),
+                                      name, pp_old_value, p_value,
+                                      subPool.getPool()), );
+}
+
+jobject
+RemoteSession::getRevisionProperties(jlong jrevision)
+{
+  SVN::Pool subPool(pool);
+  apr_hash_t *props;
+  SVN_JNI_ERR(svn_ra_rev_proplist(m_session, svn_revnum_t(jrevision),
+                                  &props, subPool.getPool()),
+              NULL);
+
+  return CreateJ::PropertyMap(props);
+}
+
+jbyteArray
+RemoteSession::getRevisionProperty(jlong jrevision, jstring jname)
+{
+  JNIStringHolder name(jname);
   if (JNIUtil::isExceptionThrown())
     return NULL;
 
   SVN::Pool subPool(pool);
-  apr_hash_t *locks;
-  SVN_JNI_ERR(svn_ra_get_locks2(m_session, &locks, path, depth,
-                                subPool.getPool()),
+  svn_string_t *propval;
+  SVN_JNI_ERR(svn_ra_rev_prop(m_session, svn_revnum_t(jrevision),
+                              name, &propval, subPool.getPool()),
               NULL);
 
-  return CreateJ::LockMap(locks, subPool.getPool());
+  return JNIUtil::makeJByteArray((const signed char*)propval->data,
+                                 int(propval->len));
+}
+
+jlong
+RemoteSession::getFile(jlong jrevision, jstring jpath,
+                       jobject jcontents, jobject jproperties)
+{
+  JNIStringHolder path(jpath);
+  if (JNIUtil::isExceptionThrown())
+    return SVN_INVALID_REVNUM;
+
+  OutputStream contents_proxy(jcontents);
+  if (JNIUtil::isExceptionThrown())
+    return SVN_INVALID_REVNUM;
+
+  SVN::Pool subPool(pool);
+  apr_hash_t* props = NULL;
+  svn_revnum_t fetched_rev = svn_revnum_t(jrevision);
+  svn_stream_t* contents = (!jcontents ? NULL
+                            : contents_proxy.getStream(subPool));
+
+  SVN_JNI_ERR(svn_ra_get_file(m_session, path, fetched_rev,
+                              contents, &fetched_rev,
+                              (jproperties ? &props : NULL),
+                              subPool.getPool()),
+              SVN_INVALID_REVNUM);
+
+  if (jproperties)
+    {
+      CreateJ::FillPropertyMap(jproperties, props);
+      if (JNIUtil::isExceptionThrown())
+        return SVN_INVALID_REVNUM;
+    }
+
+  return fetched_rev;
+}
+
+namespace {
+void fill_dirents(const char* base_url, const char* base_relpath,
+                  jobject jdirents, apr_hash_t* dirents,
+                  apr_pool_t* scratch_pool)
+{
+  base_url = apr_pstrcat(scratch_pool, base_url, "/", base_relpath, NULL);
+  base_url = svn_uri_canonicalize(base_url, scratch_pool);
+  svn_stringbuf_t* abs_path = svn_stringbuf_create(base_url, scratch_pool);
+  svn_stringbuf_appendbyte(abs_path, '/');
+  const apr_size_t base_len = abs_path->len;
+
+  JNIEnv *env = JNIUtil::getEnv();
+
+  // Create a local frame for our references
+  env->PushLocalFrame(LOCAL_FRAME_SIZE);
+  if (JNIUtil::isJavaExceptionThrown())
+    return;
+
+  // We have no way of knowing the exact type of `dirents' in advance
+  // so we cannot remember the "put" method ID across calls.
+  jmethodID put_mid =
+    env->GetMethodID(env->GetObjectClass(jdirents), "put",
+                     "(Ljava/lang/Object;Ljava/lang/Object;)"
+                     "Ljava/lang/Object;");
+  if (JNIUtil::isJavaExceptionThrown())
+    POP_AND_RETURN_NOTHING();
+
+  static jfieldID path_fid = 0;
+  if (path_fid == 0)
+    {
+      jclass clazz = env->FindClass(JAVA_PACKAGE "/types/DirEntry");
+      if (JNIUtil::isJavaExceptionThrown())
+        POP_AND_RETURN_NOTHING();
+
+      path_fid = env->GetFieldID(clazz, "path", "Ljava/lang/String;");
+      if (JNIUtil::isJavaExceptionThrown())
+        POP_AND_RETURN_NOTHING();
+    }
+
+  for (apr_hash_index_t* hi = apr_hash_first(scratch_pool, dirents);
+       hi; hi = apr_hash_next(hi))
+    {
+      const char* path;
+      svn_dirent_t* dirent;
+
+      const void *v_key;
+      void *v_val;
+
+      apr_hash_this(hi, &v_key, NULL, &v_val);
+      path = static_cast<const char*>(v_key);
+      dirent = static_cast<svn_dirent_t*>(v_val);
+      abs_path->len = base_len;
+      svn_stringbuf_appendcstr(abs_path, path);
+
+      jobject jdirent = CreateJ::DirEntry(path, abs_path->data, dirent);
+      if (JNIUtil::isJavaExceptionThrown())
+        POP_AND_RETURN_NOTHING();
+
+      // Use the existing DirEntry.path field as the key
+      jstring jpath = jstring(env->GetObjectField(jdirent, path_fid));
+      if (JNIUtil::isJavaExceptionThrown())
+        POP_AND_RETURN_NOTHING();
+
+      env->CallObjectMethod(jdirents, put_mid, jpath, jdirent);
+      if (JNIUtil::isJavaExceptionThrown())
+        POP_AND_RETURN_NOTHING();
+      env->DeleteLocalRef(jdirent);
+    }
+
+  POP_AND_RETURN_NOTHING();
+}
+} // anonymous namespace
+
+jlong
+RemoteSession::getDirectory(jlong jrevision, jstring jpath,
+                            jint jdirent_fields, jobject jdirents,
+                            jobject jproperties)
+{
+  JNIStringHolder path(jpath);
+  if (JNIUtil::isExceptionThrown())
+    return SVN_INVALID_REVNUM;
+
+  SVN::Pool subPool(pool);
+  apr_hash_t* props = NULL;
+  apr_hash_t* dirents = NULL;
+  svn_revnum_t fetched_rev = svn_revnum_t(jrevision);
+
+  SVN_JNI_ERR(svn_ra_get_dir2(m_session, (jdirents ? &dirents : NULL),
+                              &fetched_rev, (jproperties ? &props : NULL),
+                              path, fetched_rev, apr_uint32_t(jdirent_fields),
+                              subPool.getPool()),
+              SVN_INVALID_REVNUM);
+
+  if (jdirents)
+    {
+      // We will construct the absolute path in the DirEntry objects
+      // from the session URL and directory relpath.
+      const char* base_url;
+      SVN_JNI_ERR(svn_ra_get_session_url(m_session, &base_url,
+                                         subPool.getPool()),
+                  SVN_INVALID_REVNUM);
+      fill_dirents(base_url, path, jdirents, dirents, subPool.getPool());
+      if (JNIUtil::isExceptionThrown())
+        return SVN_INVALID_REVNUM;
+    }
+
+  if (jproperties)
+    {
+      CreateJ::FillPropertyMap(jproperties, props);
+      if (JNIUtil::isExceptionThrown())
+        return SVN_INVALID_REVNUM;
+    }
+
+  return fetched_rev;
+}
+
+// TODO: getMergeinfo
+// TODO: doUpdate
+// TODO: doSwitch
+
+jobject
+RemoteSession::doStatus(jstring jstatus_target,
+                        jlong jrevision, jobject jdepth,
+                        jobject jstatus_editor)
+{
+  return NULL;
 }
 
+// TODO: doDiff
+// TODO: getLog
+
 jobject
 RemoteSession::checkPath(jstring jpath, jlong jrevision)
 {
@@ -424,6 +649,39 @@ RemoteSession::checkPath(jstring jpath, 
   return EnumMapper::mapNodeKind(kind);
 }
 
+// TODO: stat
+// TODO: getLocations
+// TODO: getLocationSegments
+// TODO: getFileRevisions
+// TODO: lock
+// TODO: unlock
+// TODO: getLock
+
+jobject
+RemoteSession::getLocks(jstring jpath, jobject jdepth)
+{
+  JNIStringHolder path(jpath);
+  if (JNIUtil::isExceptionThrown())
+    return NULL;
+
+  svn_depth_t depth = EnumMapper::toDepth(jdepth);
+  if (JNIUtil::isExceptionThrown())
+    return NULL;
+
+  SVN::Pool subPool(pool);
+  apr_hash_t *locks;
+  SVN_JNI_ERR(svn_ra_get_locks2(m_session, &locks, path, depth,
+                                subPool.getPool()),
+              NULL);
+
+  return CreateJ::LockMap(locks, subPool.getPool());
+}
+
+// TODO: replayRange
+// TODO: replay
+// TODO: getDeletedRevision
+// TODO: getInheritedProperties
+
 jboolean
 RemoteSession::hasCapability(jstring jcapability)
 {

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RemoteSession.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RemoteSession.h?rev=1496334&r1=1496333&r2=1496334&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RemoteSession.h (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RemoteSession.h Tue Jun 25 02:02:47 2013
@@ -65,10 +65,37 @@ class RemoteSession : public SVNBase
     jstring getReposUUID();
     jstring getReposRootUrl();
     jlong getLatestRevision();
-
-    jlong getRevisionByTimestamp(jlong timestamp);
-    jobject getLocks(jstring jpath, jobject jdepth);
+    jlong getRevisionByTimestamp(jlong jtimestamp);
+    void changeRevisionProperty(jlong jrevision, jstring jname,
+                                jbyteArray jold_value,
+                                jbyteArray jvalue);
+    jobject getRevisionProperties(jlong jrevision);
+    jbyteArray getRevisionProperty(jlong jrevision, jstring jname);
+    jlong getFile(jlong jrevision, jstring jpath,
+                  jobject jcontents, jobject jproperties);
+    jlong getDirectory(jlong jrevision, jstring jpath, jint jdirent_fields,
+                       jobject jdirents, jobject jproperties);
+    // TODO: getMergeinfo
+    // TODO: doUpdate
+    // TODO: doSwitch
+    jobject doStatus(jstring jstatus_target,
+                     jlong jrevision, jobject jdepth,
+                     jobject jstatus_editor);
+    // TODO: doDiff
+    // TODO: getLog
     jobject checkPath(jstring jpath, jlong jrevision);
+    // TODO: stat
+    // TODO: getLocations
+    // TODO: getLocationSegments
+    // TODO: getFileRevisions
+    // TODO: lock
+    // TODO: unlock
+    // TODO: getLock
+    jobject getLocks(jstring jpath, jobject jdepth);
+    // TODO: replayRange
+    // TODO: replay
+    // TODO: getDeletedRevision
+    // TODO: getInheritedProperties
     jboolean hasCapability(jstring capability);
 
   private:

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RevpropTable.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RevpropTable.cpp?rev=1496334&r1=1496333&r2=1496334&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RevpropTable.cpp (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RevpropTable.cpp Tue Jun 25 02:02:47 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>
@@ -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((const char *)propname)]
-            = std::string((const char *)propval);
+          m_revprops[std::string(static_cast<const char *>(propname))] = pv;
 
           JNIUtil::getEnv()->DeleteLocalRef(jpropval);
         }

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RevpropTable.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RevpropTable.h?rev=1496334&r1=1496333&r2=1496334&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RevpropTable.h (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/RevpropTable.h Tue Jun 25 02:02:47 2013
@@ -42,7 +42,7 @@ 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);
 };

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/SVNClient.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/SVNClient.cpp?rev=1496334&r1=1496333&r2=1496334&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/SVNClient.cpp (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/SVNClient.cpp Tue Jun 25 02:02:47 2013
@@ -202,23 +202,23 @@ void SVNClient::logMessages(const char *
     std::vector<RevisionRange>::const_iterator it;
     for (it = logRanges.begin(); it != logRanges.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 =
                 (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;
@@ -488,6 +488,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);
@@ -506,7 +507,7 @@ jlong SVNClient::doExport(const char *sr
                                    destinationPath.c_str(),
                                    pegRevision.revision(),
                                    revision.revision(), force,
-                                   ignoreExternals, FALSE,
+                                   ignoreExternals, ignoreKeywords,
                                    depth,
                                    nativeEOL, ctx,
                                    subPool.getPool()),

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/SVNClient.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/SVNClient.h?rev=1496334&r1=1496333&r2=1496334&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/SVNClient.h (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/SVNClient.h Tue Jun 25 02:02:47 2013
@@ -115,8 +115,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/javahl-1.7-extensions/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp?rev=1496334&r1=1496333&r2=1496334&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp Tue Jun 25 02:02:47 2013
@@ -636,7 +636,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);
@@ -666,7 +667,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);
 }
 

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_RemoteSession.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_RemoteSession.cpp?rev=1496334&r1=1496333&r2=1496334&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_RemoteSession.cpp (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_RemoteSession.cpp Tue Jun 25 02:02:47 2013
@@ -154,6 +154,84 @@ Java_org_apache_subversion_javahl_remote
   return ras->getRevisionByTimestamp(timestamp);
 }
 
+JNIEXPORT void JNICALL
+Java_org_apache_subversion_javahl_remote_RemoteSession_nativeChangeRevisionProperty(
+    JNIEnv *env, jobject jthis, jlong jrevision, jstring jname,
+    jbyteArray jold_value, jbyteArray jvalue)
+{
+  JNIEntry(RemoteSession, nativeChangeRevisionProperty);
+  RemoteSession *ras = RemoteSession::getCppObject(jthis);
+  CPPADDR_NULL_PTR(ras, );
+
+  return ras->changeRevisionProperty(jrevision, jname, jold_value, jvalue);
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_apache_subversion_javahl_remote_RemoteSession_getRevisionProperties(
+    JNIEnv *env, jobject jthis, jlong jrevision)
+{
+  JNIEntry(SVNReposAccess, getRevisionProperties);
+  RemoteSession *ras = RemoteSession::getCppObject(jthis);
+  CPPADDR_NULL_PTR(ras, NULL);
+
+  return ras->getRevisionProperties(jrevision);
+}
+
+JNIEXPORT jbyteArray JNICALL
+Java_org_apache_subversion_javahl_remote_RemoteSession_getRevisionProperty(
+    JNIEnv *env, jobject jthis, jlong jrevision, jstring jname)
+{
+  JNIEntry(SVNReposAccess, getRevisionProperty);
+  RemoteSession *ras = RemoteSession::getCppObject(jthis);
+  CPPADDR_NULL_PTR(ras, NULL);
+
+  return ras->getRevisionProperty(jrevision, jname);
+}
+
+JNIEXPORT jlong JNICALL
+Java_org_apache_subversion_javahl_remote_RemoteSession_nativeGetFile(
+    JNIEnv *env, jobject jthis, jlong jrevision, jstring jpath,
+    jobject jcontents, jobject jproperties)
+{
+  JNIEntry(SVNReposAccess, nativeGetFile);
+  RemoteSession *ras = RemoteSession::getCppObject(jthis);
+  CPPADDR_NULL_PTR(ras, SVN_INVALID_REVNUM);
+
+  return ras->getFile(jrevision, jpath, jcontents, jproperties);
+}
+
+JNIEXPORT jlong JNICALL
+Java_org_apache_subversion_javahl_remote_RemoteSession_nativeGetDirectory(
+    JNIEnv *env, jobject jthis, jlong jrevision, jstring jpath,
+    jint jdirent_fields, jobject jdirents, jobject jproperties)
+{
+  JNIEntry(SVNReposAccess, nativeGetDirectory);
+  RemoteSession *ras = RemoteSession::getCppObject(jthis);
+  CPPADDR_NULL_PTR(ras, SVN_INVALID_REVNUM);
+
+  return ras->getDirectory(jrevision, jpath,
+                           jdirent_fields, jdirents, jproperties);
+}
+
+// TODO: getMergeinfo
+// TODO: doUpdate
+// TODO: doSwitch
+
+JNIEXPORT jobject JNICALL
+Java_org_apache_subversion_javahl_remote_RemoteSession_doStatus(
+    JNIEnv *env, jobject jthis, jstring jstatus_target,
+    jlong jrevision, jobject jdepth, jobject jstatus_editor)
+{
+  JNIEntry(SVNReposAccess, doStatus);
+  RemoteSession *ras = RemoteSession::getCppObject(jthis);
+  CPPADDR_NULL_PTR(ras, NULL);
+
+  return ras->doStatus(jstatus_target, jrevision, jdepth, jstatus_editor);
+}
+
+// TODO: doDiff
+// TODO: getLog
+
 JNIEXPORT jobject JNICALL
 Java_org_apache_subversion_javahl_remote_RemoteSession_checkPath(
     JNIEnv *env, jobject jthis, jstring jpath, jlong jrevision)
@@ -165,6 +243,14 @@ Java_org_apache_subversion_javahl_remote
   return ras->checkPath(jpath, jrevision);
 }
 
+// TODO: stat
+// TODO: getLocations
+// TODO: getLocationSegments
+// TODO: getFileRevisions
+// TODO: lock
+// TODO: unlock
+// TODO: getLock
+
 JNIEXPORT jobject JNICALL
 Java_org_apache_subversion_javahl_remote_RemoteSession_getLocks(
     JNIEnv *env, jobject jthis, jstring jpath, jobject jdepth)
@@ -176,6 +262,11 @@ Java_org_apache_subversion_javahl_remote
   return ras->getLocks(jpath, jdepth);
 }
 
+// TODO: replayRange
+// TODO: replay
+// TODO: getDeletedRevision
+// TODO: getInheritedProperties
+
 JNIEXPORT jboolean JNICALL
 Java_org_apache_subversion_javahl_remote_RemoteSession_nativeHasCapability(
     JNIEnv *env, jobject jthis, jstring jcapability)

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java?rev=1496334&r1=1496333&r2=1496334&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java Tue Jun 25 02:02:47 2013
@@ -215,6 +215,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
@@ -360,6 +364,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,
@@ -401,7 +430,6 @@ public interface ISVNClient
      *                     results in a commit.
      * @param handler   the commit message callback
      * @throws ClientException
-     *
      */
     void doImport(String path, String url, Depth depth,
                   boolean noIgnore, boolean ignoreUnknownNodeTypes,
@@ -890,22 +918,28 @@ public interface ISVNClient
 
     /**
      * Open a persistent session to a repository.
-     * @param path A path in a working copy from which the
-     *        session URL is derived.
+     * <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
-     * @note The session object inherits the progress callback,
-     *       configuration directory and authentication info.
      * @since 1.9
      */
-    ISVNRemote openRemoteSession(String path)
+    ISVNRemote openRemoteSession(String pathOrUrl)
             throws ClientException, SubversionException;
 
     /**
      * Open a persistent session to a repository.
-     * @param path A path in a working copy from which the
-     *        session URL is derived.
+     * <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>
@@ -913,10 +947,8 @@ public interface ISVNClient
      * @throws remote.RetryOpenSession If the session URL was redirected
      * @throws SubversionException If an URL redirect cycle was detected
      * @throws ClientException
-     * @note The session object inherits the progress callback,
-     *       configuration directory and authentication info.
      * @since 1.9
      */
-    ISVNRemote openRemoteSession(String path, int retryAttempts)
+    ISVNRemote openRemoteSession(String pathOrUrl, int retryAttempts)
             throws ClientException, SubversionException;
 }

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNEditor.java
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNEditor.java?rev=1496334&r1=1496333&r2=1496334&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNEditor.java (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNEditor.java Tue Jun 25 02:02:47 2013
@@ -47,10 +47,10 @@ public interface ISVNEditor
     /**
      * Create a new directory at <code>relativePath</code>.
      * The immediate parent of <code>relativePath</code> is expected to exist.
-     *
+     * <p>
      * For descriptions of <code>properties</code> and
      * <code>replacesRevision</code>, see #addFile().
-     *
+     * <p>
      * A complete listing of the immediate children of
      * <code>relativePath</code> that will be added subsequently is
      * given in <code>children</code>. <code>children</code> is a
@@ -70,26 +70,26 @@ public interface ISVNEditor
     /**
      * Create a new file at <code>relativePath</code>.
      * The immediate parent of <code>relativePath</code> is expected to exist.
-     *
+     * <p>
      * The file's contents are specified in <code>contents</code>
      * which has a checksum matching <code>checksum</code>. Both
      * values must be non-<code>null</code>.
-     *
+     * <p>
      * Set the properties of the new file to
      * <code>properties</code>. If no properties are being set on the
      * new file, <code>properties</code> must be empty. It is an error
      * to pass <code>null</code> for <code>properties</code>.
-     *
+     * <p>
      * If this add is expected to replace a previously existing file,
      * symlink or directory at <code>relativePath</code>, the revision
      * number of the node to be replaced must be given in
      * <code>replacesRevision</code>. Otherwise,
      * <code>replacesRevision</code> must be
      * Revision.SVN_INVALID_REVNUM.
-     *
-     * @note It is not allowed to call a "delete" followed by an "add" on the
-     *       same path. Instead, an "add" with <code>replacesRevision</code>
-     *       set accordingly MUST be used.
+     * <p>
+     * <b>Note:</b> It is not allowed to call a "delete" followed by
+     * an "add" on the same path. Instead, an "add" with
+     * <code>replacesRevision</code> set accordingly <em>must</em> be used.
      *
      * @throws ClientException
      */
@@ -132,7 +132,7 @@ public interface ISVNEditor
 
     /**
      * Alter the properties of the directory at <code>relativePath</code>.
-     *
+     * <p>
      * <code>revision</code> specifies the revision at which the
      * receiver should expect to find this node. That is,
      * <code>relativePath</code> at the start of the whole edit and
@@ -143,13 +143,13 @@ public interface ISVNEditor
      * corresponding revision in the repository (e.g. it has not yet
      * been committed), then <code>revision</code> should be
      * Revision.SVN_INVALID_REVNUM.
-     *
+     * <p>
      * If any changes to the set of children will be made in the
      * future of the edit drive, then <code>children</code>
      * <em>must</em> specify the resulting set of children. See
      * #addDirectory() for the format of <code>children</code>.  If
      * not changes will be made, then NULL may be specified.
-     *
+     * <p>
      * For a description of <code>properties</code>, see
      * #addFile(). If no changes to the properties will be made
      * (ie. only future changes to the set of children), then
@@ -168,7 +168,7 @@ public interface ISVNEditor
      * <code>relativePath</code> with <code>revision</code> as its
      * expected revision. See #alterDirectory() for more information
      * about <code>revision</code>.
-     *
+     * <p>
      * If <code>contents</code> is non-<code>null</code>, then the
      * stream will be copied to the file, and its checksum must match
      * <code>checksum</code> (which must also be
@@ -176,13 +176,13 @@ public interface ISVNEditor
      * <code>null</code>, then <code>checksum</code> must also be
      * <code>null</code>, and no change will be applied to the file's
      * contents.
-     *
+     * <p>
      * If <code>properties</code> is non-<code>null</code>, then the
      * properties will be applied.
-     *
+     * <p>
      * For a description of <code>checksum</code> and
      * <code>contents</code>, see #addFile().
-     *
+     * <p>
      * This function allows <code>properties</code> to be
      * <code>null</code>, but the parameter is otherwise described by
      * #addFile().
@@ -201,17 +201,17 @@ public interface ISVNEditor
      * <code>relativePath</code> with <code>revision</code> as its
      * expected revision. See #alterDirectory() for more information
      * about <code>revision</code>.
-     *
+     * <p>
      * If <code>target</code> is non-<code>null</code>, then the
      * symlink's target will be updated.
-     *
+     * <p>
      * If <code>properties</code> is non-<code>null</code>, then the
      * properties will be applied.
-     *
+     * <p>
      * The target and/or the properties must be changed. It is an
      * error to pass <code>null</code> for both <code>target</code>
      * and <code>properties</code>.
-     *
+     * <p>
      * This function allows <code>properties</code> to be
      * <code>null</code>, but the parameter is otherwise described by
      * #addFile().
@@ -237,11 +237,11 @@ public interface ISVNEditor
     /**
      * Move the node at <code>sourceRelativePath</code> to
      * <code>destinationRelativePath</code>.
-     *
+     * <p>
      * For a description of <code>replacesRevision</code>, see #addFile().
-     *
-     * @note See the general instructions on paths for this API. Since
-     * the <code>sourceRelativePath</code> argument must generally be
+     * <p>
+     * <b>Note:</b> See the general instructions on paths for this API.
+     * Sice the <code>sourceRelativePath</code> argument must generally be
      * able to reference any node in the repository, the implication
      * is that the editor's root must be the repository root.
      *
@@ -256,7 +256,7 @@ public interface ISVNEditor
     /**
      * Move the node at <code>sourceRelativePath</code> to
      * <code>destinationRelativePath</code>.
-     *
+     * <p>
      * <code>sourceRevision</code> specifies the revision at which the
      * receiver should expect to find this node.  That is,
      * <code>sourceRelativePath</code> at the start of the whole edit
@@ -264,7 +264,7 @@ public interface ISVNEditor
      * <code>sourceRevision</code> must lie within the same node-rev
      * (aka history-segment).  This is just like the #delete() and
      * #rotate().
-     *
+     * <p>
      * For a description of <code>replacesRevision</code>, see #addFile().
      *
      * @throws ClientException
@@ -276,7 +276,7 @@ public interface ISVNEditor
             throws ClientException;
     /**
      * Perform a rotation among multiple nodes in the target tree.
-     *
+     * <p>
      * The <code>elements</code> list specifies the nodes in the tree
      * which are located at a path and expected to be at a specific
      * revision. These nodes are simultaneously moved in a rotation
@@ -285,7 +285,7 @@ public interface ISVNEditor
      * specified at index 1 of <code>elements</code>. The node at
      * index 1 will be moved to the location at index 2. The node at
      * index N-1 will be moved to the relative path specified at index 0.
-     *
+     * <p>
      * The simplest form of this operation is to swap nodes A and
      * B. One may think to move A to a temporary location T, then move
      * B to A, then move T to B. However, this last move violations

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRemote.java
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRemote.java?rev=1496334&r1=1496333&r2=1496334&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRemote.java (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRemote.java Tue Jun 25 02:02:47 2013
@@ -28,6 +28,7 @@ import org.apache.subversion.javahl.call
 
 import java.util.Date;
 import java.util.Map;
+import java.io.OutputStream;
 
 /**
  * Encapsulates an RA session object and related operations.
@@ -111,6 +112,195 @@ public interface ISVNRemote
     long getRevisionByTimestamp(long timestamp) throws ClientException;
 
     /**
+     * Change the value of an unversioned property.
+     * @param revision The revision to which the propery is attached
+     * @param propertyName The name of the propery
+     * @param oldValue The previous value of the property (see note below)
+     * @param newValue The new value of the property. If <code>newValue</code>
+     *        is <code>null</code>, the property will be deleted.
+     *
+     * @node If the server has Capability.atomic_revprops and
+     *       <code>oldValue</code> is not <code>null</code>, and the
+     *       present value of the propery is not <code>oldValue</code>
+     *       (e.g., if another client changed the property), then
+     *       the operation will fail.
+     * @note If the server does not adveritse Capability.atomic_revprops,
+     *       then <code>oldValue</code> <em>must</em> be <code>null</code>.
+     *
+     * @throws IllegalArgumentException if <code>oldValue</code> is not
+     *         <code>null</code> and the server does not advertise the
+     *         atomic_revprops capability.
+     * @throws ClientException
+     */
+    void changeRevisionProperty(long revision,
+                                String propertyName,
+                                byte[] oldValue,
+                                byte[] newValue)
+            throws ClientException;
+
+    /**
+     * Return the set of unversioned properties set on <code>revision</code>
+     * in the session's repository.
+     * @throws ClientException
+     */
+    Map<String, byte[]> getRevisionProperties(long revision)
+            throws ClientException;
+
+    /**
+     * Return the value of unversioned property <code>propertyName</code>
+     * in <code>revision</code> in the session's repository.
+     * Returns <code>null</code> if the property does not exist.
+     * @throws ClientException
+     */
+    byte[] getRevisionProperty(long revision, String propertyName)
+            throws ClientException;
+
+    /**
+     * Create a commit editor instance, rooted at the current session URL.
+     * @throws ClientException
+     */
+    ISVNEditor getCommitEditor() throws ClientException;
+
+    /**
+     * Fetch the contents and properties of file <code>path</code> at
+     * <code>revision</code>.  <code>revision</code> may be
+     * {@link org.apache.subversion.javahl.types.Revision#SVN_INVALID_REVNUM}
+     * indicating that the HEAD revision should be
+     * used. <code>path</code> is interpreted relative to the
+     * session's URL.
+     * <p>
+
+     * If <code>revision</code> is
+     * {@link org.apache.subversion.javahl.types.Revision#SVN_INVALID_REVNUM}.
+     * returns the actual revision that was retrieved; otherwise
+     * returns <code>revision</code>.
+     * <p>
+     * If <code>contents</code> is not <code>null</code>, push the
+     * contents of the file into the stream.
+     * <p>
+     * If <code>properties</code> is not <code>null</code>, set
+     * <code>properties</code> to contain the properties of the file. This
+     * means <em>all</em> properties: not just ones controlled by the
+     * user and stored in the repository, but immutable ones generated
+     * by the SCM system itself (e.g. 'wcprops', 'entryprops',
+     * etc.). Any existing contents of the <code>properties</code> map
+     * will be discarded by calling {@link java.util.Map#clear()}, if the
+     * map implementation supports that operation.
+     * <p>
+     * The implementations of <code>contents</code> and
+     * <code>properties</code> may not perform any ISVNRemote
+     * operations using this session.
+     * @return The revision of the file that was retreived.
+     * @throws ClientException
+     */
+    long getFile(long revision, String path,
+                 OutputStream contents,
+                 Map<String, byte[]> properties)
+            throws ClientException;
+
+    /**
+     * Fetch the contents and properties of directory <code>path</code>
+     * at <code>revision</code>.  <code>revision</code> may be
+     * {@link org.apache.subversion.javahl.types.Revision#SVN_INVALID_REVNUM},
+     * indicating that the HEAD revision should be
+     * used. <code>path</code> is interpreted relative to the
+     * session's URL.
+     * <p>
+     * If <code>dirents</code> is not <code>null</code>, it will
+     * contain all the entries of the directory; the keys will be the
+     * entry basenames.  Any existing contente of the
+     * <code>dirents</code> collection will be discarded by calling
+     * {@link java.util.Map#clear()}, if the collection implementation
+     * supports that operation.
+     * <p>
+     * <code>direntFields</code> controls which portions of the DirEntry
+     * objects are filled in. To have them completely filled in, just pass
+     * DirEntry.Fields.all, othewise pass a bitwise OR of any of the
+     * DirEntry.Fields flags you would like to have.
+     * <p>
+     * If <code>properties</code> is not <code>null</code>, set
+     * <code>properties</code> to contain the properties of the directory.
+     * This means <em>all</em> properties: not just ones controlled by the
+     * user and stored in the repository, but immutable ones generated
+     * by the SCM system itself (e.g. 'wcprops', 'entryprops',
+     * etc.). Any existing contents of the <code>properties</code> map
+     * will be discarded by calling {@link java.util.Map#clear()}, if the
+     * map implementation supports that operation.
+     * <p>
+     * The implementations of <code>dirents</code> and
+     * <code>properties</code> may not perform any ISVNRemote
+     * operations using this session.
+     * @return The revision of the directory that was retreived.
+     * @throws IllegalArgumentException if <code>direntFields</code>
+     *         is less than or equal to 0.
+     * @throws ClientException
+     */
+    long getDirectory(long revision, String path,
+                      int direntFields,
+                      Map<String, DirEntry> dirents,
+                      Map<String, byte[]> properties)
+            throws ClientException;
+
+    // TODO: getMergeinfo
+    // TODO: doUpdate
+    // TODO: doSwitch
+
+    /**
+     * Ask for a description of the status of a working copy with
+     * respect to <code>revision</code> of the session's repository,
+     * or the HEAD revision if <code>revision</code> is
+     * {@link org.apache.subversion.javahl.types.Revision#SVN_INVALID_REVNUM}.
+     * <p>
+     * The client begins by providing a <code>statusEditor</code> to
+     * the remote session; this editor must contain knowledge of where
+     * the change will begin in the working copy.
+     * <p>
+     * In return, the client receives an {@link ISVNReporter}
+     * instance, which it uses to describe its working copy by making
+     * calls to its methods.
+     * <p>
+     * When finished, the client calls {@link ISVNReporter#finishReport}.
+     * This results in a complete drive of <code>statusEditor</code>,
+     * ending with {@link ISVNEditor#complete()}, to report,
+     * essentially, what would be modified in the working copy were
+     * the client to perform an update.  <code>statusTarget</code> is
+     * an optional single path component that restricts the scope of
+     * the status report to an entry in the directory represented by
+     * the session's URL, or empty if the entire directory is meant to
+     * be examined.
+     * <p>
+     * Get status as deeply as <code>depth</code> indicates.  If
+     * <code>depth</code> is
+     * {@link org.apache.subversion.javahl.types.Depth#unknown},
+     * get the status down to the ambient depth of the working
+     * copy. If <code>depth</code> is deeper than the working copy,
+     * include changes that would be needed to populate the working
+     * copy to that depth.
+     * <p>
+     * The caller may not perform any operations using this session
+     * before finishing the report, and may not perform any operations
+     * using this session from within the editing operations of
+     * <code>statusEditor</code>.
+     * <p>
+     * <b>Note:</b> The reporter provided by this function does
+     * <em>not</em> supply copy-from information to the editor
+     * methods.
+     * <p>
+     * <b>Note:</b> In order to prevent pre-1.5 servers from doing
+     * more work than needed, and sending too much data back, a
+     * pre-1.5 'recurse' directive may be sent to the server, based on
+     * <code>depth</code>.
+     * @throws ClientException
+     */
+    ISVNReporter doStatus(String statusTarget,
+                          long revision, Depth depth,
+                          ISVNEditor statusEditor)
+            throws ClientException;
+
+    // TODO: doDiff
+    // TODO: getLog
+
+    /**
      * Return the kind of the node in path at revision.
      * @param path A path relative to the sessionn URL
      * @throws ClientException
@@ -118,6 +308,14 @@ public interface ISVNRemote
     NodeKind checkPath(String path, long revision)
             throws ClientException;
 
+    // TODO: stat
+    // TODO: getLocations
+    // TODO: getLocationSegments
+    // TODO: getFileRevisions
+    // TODO: lock
+    // TODO: unlock
+    // TODO: getLock
+
     /**
      * Return a dictionary containing all locks on or below the given path.
      * @param path A path relative to the sessionn URL
@@ -130,11 +328,17 @@ public interface ISVNRemote
     Map<String, Lock> getLocks(String path, Depth depth)
             throws ClientException;
 
+    // TODO: replayRange
+    // TODO: replay
+    // TODO: getDeletedRevision
+    // TODO: getInheritedProperties
+
     /**
-     * Create a commit editor instance, rooted at the current session URL.
+     * Check if the server associated with this session has
+     * the given <code>capability</code>.
      * @throws ClientException
      */
-    ISVNEditor getCommitEditor() throws ClientException;
+    boolean hasCapability(Capability capability) throws ClientException;
 
     /**
      * Enumeration of known capabilities of the repository and server.
@@ -212,11 +416,4 @@ public interface ISVNRemote
 
         private String token;
     }
-
-    /**
-     * Check if the server associated with this session has
-     * the given <code>capability</code>.
-     * @throws ClientException
-     */
-    boolean hasCapability(Capability capability) throws ClientException;
 }

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java?rev=1496334&r1=1496333&r2=1496334&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java Tue Jun 25 02:02:47 2013
@@ -214,9 +214,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,
@@ -458,23 +469,23 @@ public class SVNClient implements ISVNCl
                              PatchCallback callback)
             throws ClientException;
 
-    public ISVNRemote openRemoteSession(String path)
+    public ISVNRemote openRemoteSession(String pathOrUrl)
             throws ClientException, SubversionException
     {
-        return nativeOpenRemoteSession(path, 1);
+        return nativeOpenRemoteSession(pathOrUrl, 1);
     }
 
-    public ISVNRemote openRemoteSession(String path, int retryAttempts)
+    public ISVNRemote openRemoteSession(String pathOrUrl, int retryAttempts)
             throws ClientException, SubversionException
     {
         if (retryAttempts <= 0)
             throw new IllegalArgumentException(
                 "retryAttempts must be positive");
-        return nativeOpenRemoteSession(path, retryAttempts);
+        return nativeOpenRemoteSession(pathOrUrl, retryAttempts);
     }
 
     private native ISVNRemote nativeOpenRemoteSession(
-        String path, int retryAttempts)
+        String pathOrUrl, int retryAttempts)
             throws ClientException, SubversionException;
 
     /**

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/RemoteFactory.java
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/RemoteFactory.java?rev=1496334&r1=1496333&r2=1496334&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/RemoteFactory.java (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/RemoteFactory.java Tue Jun 25 02:02:47 2013
@@ -119,13 +119,16 @@ public class RemoteFactory
 
     /**
      * Open a persistent session to a repository.
+     * <p>
+     * <b>Note:</b> The URL can point to a subtree of the repository.
+     * <p>
+     * <b>Note:</b> The session object inherits the progress callback,
+     * configuration directory and authentication info.
+     *
      * @param url The initial session root URL.
      * @throws RetryOpenSession If the session URL was redirected
      * @throws SubversionException If an URL redirect cycle was detected
      * @throws ClientException
-     * @note The URL can point to a subtree of the repository.
-     * @note The session object inherits the progress callback,
-     *       configuration directory and authentication info.
      */
     public ISVNRemote openRemoteSession(String url)
             throws ClientException, SubversionException
@@ -136,6 +139,12 @@ public class RemoteFactory
 
     /**
      * Open a persistent session to a repository.
+     * <p>
+     * <b>Note:</b> The URL can point to a subtree of the repository.
+     * <p>
+     * <b>Note:</b> The session object inherits the progress callback,
+     * configuration directory and authentication info.
+     *
      * @param url The initial session root URL.
      * @param retryAttempts The number of times to retry the operation
      *        if the given URL is redirected.
@@ -144,9 +153,6 @@ public class RemoteFactory
      * @throws RetryOpenSession If the session URL was redirected
      * @throws SubversionException If an URL redirect cycle was detected
      * @throws ClientException
-     * @note The URL can point to a subtree of the repository.
-     * @note The session object inherits the progress callback,
-     *       configuration directory and authentication info.
      */
     public ISVNRemote openRemoteSession(String url, int retryAttempts)
             throws ClientException, SubversionException
@@ -160,16 +166,21 @@ public class RemoteFactory
 
     /**
      * Open a persistent session to a repository.
+     * <p>
+     * <b>Note:</b> The URL can point to a subtree of the repository.
+     * <p>
+     * <b>Note:</b> If the UUID does not match the repository,
+     * this function fails.
+     * <p>
+     * <b>Note:</b> The session object inherits the progress callback,
+     * configuration directory and authentication info.
+     *
      * @param url The initial session root URL.
      * @param reposUUID The expected repository UUID; may not be null..
      * @throws IllegalArgumentException If <code>reposUUID</code> is null.
      * @throws RetryOpenSession If the session URL was redirected
      * @throws SubversionException If an URL redirect cycle was detected
      * @throws ClientException
-     * @note The URL can point to a subtree of the repository.
-     * @note If the UUID does not match the repository, this function fails.
-     * @note The session object inherits the progress callback,
-     *       configuration directory and authentication info.
      */
     public ISVNRemote openRemoteSession(String url, String reposUUID)
             throws ClientException, SubversionException
@@ -182,6 +193,15 @@ public class RemoteFactory
 
     /**
      * Open a persistent session to a repository.
+     * <p>
+     * <b>Note:</b> The URL can point to a subtree of the repository.
+     * <p>
+     * <b>Note:</b> If the UUID does not match the repository,
+     * this function fails.
+     * <p>
+     * <b>Note:</b> The session object inherits the progress callback,
+     * configuration directory and authentication info.
+     *
      * @param url The initial session root URL.
      * @param reposUUID The expected repository UUID; may not be null..
      * @param retryAttempts The number of times to retry the operation
@@ -191,10 +211,6 @@ public class RemoteFactory
      * @throws RetryOpenSession If the session URL was redirected
      * @throws SubversionException If an URL redirect cycle was detected
      * @throws ClientException
-     * @note The URL can point to a subtree of the repository.
-     * @note If the UUID does not match the repository, this function fails.
-     * @note The session object inherits the progress callback,
-     *       configuration directory and authentication info.
      */
     public ISVNRemote openRemoteSession(String url, String reposUUID,
                                         int retryAttempts)

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/RemoteSession.java
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/RemoteSession.java?rev=1496334&r1=1496333&r2=1496334&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/RemoteSession.java (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/RemoteSession.java Tue Jun 25 02:02:47 2013
@@ -28,6 +28,7 @@ import org.apache.subversion.javahl.call
 
 import org.apache.subversion.javahl.ISVNRemote;
 import org.apache.subversion.javahl.ISVNEditor;
+import org.apache.subversion.javahl.ISVNReporter;
 import org.apache.subversion.javahl.JNIObject;
 import org.apache.subversion.javahl.OperationContext;
 import org.apache.subversion.javahl.ClientException;
@@ -36,6 +37,7 @@ import java.lang.ref.WeakReference;
 import java.util.HashSet;
 import java.util.Date;
 import java.util.Map;
+import java.io.OutputStream;
 
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import static java.util.concurrent.TimeUnit.NANOSECONDS;
@@ -86,10 +88,25 @@ public class RemoteSession extends JNIOb
     public native long getRevisionByTimestamp(long timestamp)
             throws ClientException;
 
-    public native NodeKind checkPath(String path, long revision)
+    public void changeRevisionProperty(long revision,
+                                       String propertyName,
+                                       byte[] oldValue,
+                                       byte[] newValue)
+            throws ClientException
+    {
+        if (oldValue != null && !hasCapability(Capability.atomic_revprops))
+            throw new IllegalArgumentException(
+                "oldValue must be null;\n" +
+                "The server does not support" +
+                " atomic revision property changes");
+        nativeChangeRevisionProperty(revision, propertyName,
+                                     oldValue, newValue);
+    }
+
+    public native Map<String, byte[]> getRevisionProperties(long revision)
             throws ClientException;
 
-    public native Map<String, Lock> getLocks(String path, Depth depth)
+    public native byte[] getRevisionProperty(long revision, String propertyName)
             throws ClientException;
 
     public ISVNEditor getCommitEditor() throws ClientException
@@ -101,6 +118,61 @@ public class RemoteSession extends JNIOb
         return ed;
     }
 
+    public long getFile(long revision, String path,
+                        OutputStream contents,
+                        Map<String, byte[]> properties)
+            throws ClientException
+    {
+        maybe_clear(properties);
+        return nativeGetFile(revision, path, contents, properties);
+    }
+
+    public long getDirectory(long revision, String path,
+                             int direntFields,
+                             Map<String, DirEntry> dirents,
+                             Map<String, byte[]> properties)
+            throws ClientException
+    {
+        if (direntFields <= 0 && direntFields != DirEntry.Fields.all)
+            throw new IllegalArgumentException(
+                "direntFields must be positive or DirEntry.Fields.all");
+        maybe_clear(dirents);
+        maybe_clear(properties);
+        return nativeGetDirectory(revision, path,
+                                  direntFields, dirents, properties);
+    }
+
+    // TODO: getMergeinfo
+    // TODO: doUpdate
+    // TODO: doSwitch
+
+    public native ISVNReporter doStatus(String statusTarget,
+                                        long revision, Depth depth,
+                                        ISVNEditor statusEditor)
+            throws ClientException;
+
+    // TODO: doDiff
+    // TODO: getLog
+
+    public native NodeKind checkPath(String path, long revision)
+            throws ClientException;
+
+    // TODO: stat
+    // TODO: getLocations
+    // TODO: getLocationSegments
+    // TODO: getFileRevisions
+    // TODO: lock
+    // TODO: unlock
+    // TODO: getLock
+
+    public native Map<String, Lock> getLocks(String path, Depth depth)
+            throws ClientException;
+
+    // TODO: replayRange
+    // TODO: replay
+    // TODO: getDeletedRevision
+    // TODO: getInheritedProperties
+
     public boolean hasCapability(Capability capability)
             throws ClientException
     {
@@ -118,9 +190,27 @@ public class RemoteSession extends JNIOb
         super(cppAddr);
     }
 
+    /*
+     * Wrapped private native implementation declarations.
+     */
     private native void nativeDispose();
+    private native void nativeChangeRevisionProperty(long revision,
+                                                     String propertyName,
+                                                     byte[] oldValue,
+                                                     byte[] newValue)
+            throws ClientException;
+    private native long nativeGetFile(long revision, String path,
+                                      OutputStream contents,
+                                      Map<String, byte[]> properties)
+            throws ClientException;
 
-    private native boolean nativeHasCapability(String capability);
+    private native long nativeGetDirectory(long revision, String path,
+                                           int direntFields,
+                                           Map<String, DirEntry> dirents,
+                                           Map<String, byte[]> properties)
+            throws ClientException;
+    private native boolean nativeHasCapability(String capability)
+            throws ClientException;
 
     /*
      * NOTE: This field is accessed from native code for callbacks.
@@ -133,4 +223,17 @@ public class RemoteSession extends JNIOb
      * the editors when the session is disposed.
      */
     private HashSet<WeakReference<ISVNEditor>> editors;
+
+    /*
+     * Private helper methods.
+     */
+    private final static void maybe_clear(Map clearable)
+    {
+        if (clearable != null && !clearable.isEmpty())
+            try {
+                clearable.clear();
+            } catch (UnsupportedOperationException ex) {
+                // ignored
+            }
+    }
 }

Modified: subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java?rev=1496334&r1=1496333&r2=1496334&view=diff
==============================================================================
--- subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java (original)
+++ subversion/branches/javahl-1.7-extensions/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java Tue Jun 25 02:02:47 2013
@@ -26,11 +26,15 @@ import org.apache.subversion.javahl.*;
 import org.apache.subversion.javahl.remote.*;
 import org.apache.subversion.javahl.types.*;
 
+import java.util.Arrays;
 import java.util.Date;
 import java.util.Set;
 import java.util.Map;
+import java.util.HashMap;
 import java.util.HashSet;
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.nio.charset.Charset;
 
 /**
  * This class is used for testing the SVNReposAccess class
@@ -248,4 +252,122 @@ public class SVNRemoteTests extends SVNT
         ISVNRemote session = getSession();
         assert(session.hasCapability(ISVNRemote.Capability.depth));
     }
+
+    public void testChangeRevpropNoAtomic() throws Exception
+    {
+        Charset UTF8 = Charset.forName("UTF-8");
+        ISVNRemote session = getSession();
+
+        boolean atomic =
+            session.hasCapability(ISVNRemote.Capability.atomic_revprops);
+
+        if (atomic)
+            return;
+
+        boolean exceptioned = false;
+        try
+        {
+            byte[] oldValue = "bumble".getBytes(UTF8);
+            byte[] newValue = "bee".getBytes(UTF8);
+            session.changeRevisionProperty(1, "svn:author",
+                                           oldValue, newValue);
+        }
+        catch (IllegalArgumentException ex)
+        {
+            exceptioned = true;
+        }
+        assert(exceptioned);
+    }
+
+    public void testChangeRevpropAtomic() throws Exception
+    {
+        Charset UTF8 = Charset.forName("UTF-8");
+        ISVNRemote session = getSession();
+
+        boolean atomic =
+            session.hasCapability(ISVNRemote.Capability.atomic_revprops);
+
+        if (!atomic)
+            return;
+
+        byte[] oldValue = client.revProperty(getTestRepoUrl(), "svn:author",
+                                             Revision.getInstance(1));
+        byte[] newValue = "rayjandom".getBytes(UTF8);
+        try
+        {
+            session.changeRevisionProperty(1, "svn:author",
+                                           oldValue, newValue);
+        }
+        catch (ClientException ex)
+        {
+            String msg = ex.getMessage();
+            int index = msg.indexOf('\n');
+            assertEquals("Disabled repository feature",
+                         msg.substring(0, index));
+            return;
+        }
+
+        byte[] check = client.revProperty(getTestRepoUrl(), "svn:author",
+                                          Revision.getInstance(1));
+        assertTrue(Arrays.equals(check, newValue));
+    }
+
+    public void testGetRevpropList() throws Exception
+    {
+        Charset UTF8 = Charset.forName("UTF-8");
+        ISVNRemote session = getSession();
+
+        Map<String, byte[]> proplist = session.getRevisionProperties(1);
+        assertTrue(Arrays.equals(proplist.get("svn:author"),
+                                 USERNAME.getBytes(UTF8)));
+    }
+
+    public void testGetRevprop() throws Exception
+    {
+        Charset UTF8 = Charset.forName("UTF-8");
+        ISVNRemote session = getSession();
+
+        byte[] propval = session.getRevisionProperty(1, "svn:author");
+        assertTrue(Arrays.equals(propval, USERNAME.getBytes(UTF8)));
+    }
+
+    public void testGetFile() throws Exception
+    {
+        Charset UTF8 = Charset.forName("UTF-8");
+        ISVNRemote session = getSession();
+
+        ByteArrayOutputStream contents = new ByteArrayOutputStream();
+        HashMap<String, byte[]> properties = new HashMap<String, byte[]>();
+        properties.put("fakename", "fakecontents".getBytes(UTF8));
+        long fetched_rev =
+            session.getFile(Revision.SVN_INVALID_REVNUM, "A/B/lambda",
+                            contents, properties);
+        assertEquals(fetched_rev, 1);
+        assertEquals(contents.toString("UTF-8"),
+                     "This is the file 'lambda'.");
+        for (Map.Entry<String, byte[]> e : properties.entrySet())
+            assertTrue(e.getKey().startsWith("svn:entry:"));
+    }
+
+    public void testGetDirectory() throws Exception
+    {
+        Charset UTF8 = Charset.forName("UTF-8");
+        ISVNRemote session = getSession();
+
+        HashMap<String, DirEntry> dirents = new HashMap<String, DirEntry>();
+        dirents.put("E", null);
+        dirents.put("F", null);
+        dirents.put("lambda", null);
+        HashMap<String, byte[]> properties = new HashMap<String, byte[]>();
+        properties.put("fakename", "fakecontents".getBytes(UTF8));
+        long fetched_rev =
+            session.getDirectory(Revision.SVN_INVALID_REVNUM, "A/B",
+                                 DirEntry.Fields.all, dirents, properties);
+        assertEquals(fetched_rev, 1);
+        assertEquals(dirents.get("E").getPath(), "E");
+        assertEquals(dirents.get("F").getPath(), "F");
+        assertEquals(dirents.get("lambda").getPath(), "lambda");
+        for (Map.Entry<String, byte[]> e : properties.entrySet())
+            assertTrue(e.getKey().startsWith("svn:entry:"));
+    }
 }