We should update the JavaHL bindings for 'dump' accordingly.

Here is a patch that begins that process. It is not finished: as noted in the log message, at least I haven't implemented CreateJ:FSPath and the callback should (probably) be moved into its own file, and I have presumably made some mistake already because even when I stub out the unimplemented part all the tests are failing.

Would someone care to take a look at this and point out what I need to fix or maybe even finish it, as I am running out of steam? (Brane?)

- Julian
Implement JavaHL bindings support for 'svnadmin dump --include/exclude'.

### Unfinished:
# CreateJ::FSRoot is unimplemented
# ReposDumpFilterCallback should be in its own pair of files

A follow-up to r1811992 which added 'svnadmin dump --include/exclude'.

* subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNRepos.cpp
  (Java_org_apache_subversion_javahl_SVNRepos_dump): Extend with a 'filter'
    argument.

* subversion/bindings/javahl/native/ReposVerifyCallback.cpp,
  subversion/bindings/javahl/native/ReposVerifyCallback.h
  (ReposDumpFilterCallback): New.

* subversion/bindings/javahl/native/SVNRepos.cpp,
  subversion/bindings/javahl/native/SVNRepos.h
  (dump): Extend with a 'filter' argument.
--This line, and those below, will be ignored--

Index: subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNRepos.cpp
===================================================================
--- subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNRepos.cpp	(revision 1811982)
+++ subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNRepos.cpp	(working copy)
@@ -131,13 +131,13 @@ Java_org_apache_subversion_javahl_SVNRep
 }
 
 JNIEXPORT void JNICALL
 Java_org_apache_subversion_javahl_SVNRepos_dump
 (JNIEnv *env, jobject jthis, jobject jpath, jobject jdataout,
  jobject jrevisionStart, jobject jrevisionEnd, jboolean jincremental,
- jboolean juseDeltas, jobject jnotifyCallback)
+ jboolean juseDeltas, jobject jnotifyCallback, jobject jfilterCallback)
 {
   JNIEntry(SVNRepos, dump);
   SVNRepos *cl = SVNRepos::getCppObject(jthis);
   if (cl == NULL)
     {
       JNIUtil::throwError(_("bad C++ this"));
@@ -158,16 +158,18 @@ Java_org_apache_subversion_javahl_SVNRep
 
   Revision revisionEnd(jrevisionEnd);
   if (JNIUtil::isExceptionThrown())
     return;
 
   ReposNotifyCallback notifyCallback(jnotifyCallback);
+  ReposDumpFilterCallback filterCallback(jfilterCallback);
 
   cl->dump(path, dataOut, revisionStart, revisionEnd,
            jincremental ? true : false, juseDeltas ? true : false,
-           jnotifyCallback != NULL ? &notifyCallback : NULL);
+           jnotifyCallback != NULL ? &notifyCallback : NULL,
+           jfilterCallback != NULL ? &filterCallback : NULL);
 }
 
 JNIEXPORT void JNICALL
 Java_org_apache_subversion_javahl_SVNRepos_hotcopy
 (JNIEnv *env, jobject jthis, jobject jpath, jobject jtargetPath,
  jboolean jcleanLogs, jboolean jincremental, jobject jnotifyCallback)
Index: subversion/bindings/javahl/native/ReposVerifyCallback.cpp
===================================================================
--- subversion/bindings/javahl/native/ReposVerifyCallback.cpp	(revision 1811982)
+++ subversion/bindings/javahl/native/ReposVerifyCallback.cpp	(working copy)
@@ -83,6 +83,66 @@ ReposVerifyCallback::onVerifyError(svn_r
     return;
 
   env->CallVoidMethod(m_jverify_cb, mid, jlong(revision), jverify_err);
   if (verify_err)
     env->DeleteLocalRef(jverify_err);
 }
+
+ReposDumpFilterCallback::ReposDumpFilterCallback(jobject jfilter_cb)
+  : m_jfilter_cb(jfilter_cb)
+{}
+
+ReposDumpFilterCallback::~ReposDumpFilterCallback()
+{
+  // Don't need to destroy the reference, since it was given us by Java
+}
+
+svn_error_t *
+ReposDumpFilterCallback::callback(svn_boolean_t *include,
+                                  svn_fs_root_t *root,
+                                  const char *path,
+                                  void *baton,
+                                  apr_pool_t *scratch_pool)
+{
+  if (!baton)
+    return SVN_NO_ERROR;
+
+  static_cast<ReposDumpFilterCallback*>(baton)
+    ->onFilter(include, root, path, scratch_pool);
+  if (JNIUtil::isJavaExceptionThrown())
+    return JNIUtil::wrapJavaException();
+  return SVN_NO_ERROR;
+}
+
+void
+ReposDumpFilterCallback::onFilter(svn_boolean_t *include,
+                                  svn_fs_root_t *root,
+                                  const char *path,
+                                  apr_pool_t *scratch_pool)
+{
+  JNIEnv *env = JNIUtil::getEnv();
+
+  // Java method id will not change during the time this library is
+  // loaded, so it can be cached.
+  static jmethodID mid = 0;
+  if (mid == 0)
+    {
+      jclass clazz = env->FindClass(JAVAHL_CLASS("/callback/ReposDumpFilterCallback"));
+      if (JNIUtil::isJavaExceptionThrown())
+        return;
+
+      mid = env->GetMethodID(clazz, "onFilter",
+                             "(J" JAVAHL_ARG("/ClientException;") ")V");
+      if (JNIUtil::isJavaExceptionThrown() || mid == 0)
+        return;
+
+      env->DeleteLocalRef(clazz);
+    }
+
+  jobject jRoot = CreateJ::FSRoot(root);
+  if (JNIUtil::isJavaExceptionThrown())
+    return;
+
+  env->CallVoidMethod(m_jfilter_cb, mid, include, jRoot, path);
+
+  env->DeleteLocalRef(jRoot);
+}
Index: subversion/bindings/javahl/native/ReposVerifyCallback.h
===================================================================
--- subversion/bindings/javahl/native/ReposVerifyCallback.h	(revision 1811982)
+++ subversion/bindings/javahl/native/ReposVerifyCallback.h	(working copy)
@@ -69,7 +69,48 @@ class ReposVerifyCallback
    */
   void onVerifyError(svn_revnum_t revision,
                      svn_error_t *verify_err,
                      apr_pool_t *scratch_pool);
 };
 
+/**
+ * Callback for filtering repository contents during dump.
+ * svn_repos_dump_filter_func_t
+ */
+class ReposDumpFilterCallback
+{
+ private:
+  /**
+   * The local reference to the Java object.
+   */
+  jobject m_jfilter_cb;
+
+ public:
+  ReposDumpFilterCallback(jobject jfilter_cb);
+  ~ReposDumpFilterCallback();
+
+  /**
+   * Implementation of the svn_repos_dump_filter_func_t API.
+   *
+   * @param include the result: whether the dump should include this node
+   * @param root the root of the node
+   * @param path the path within @a root of the node
+   * @param pool An APR pool from which to allocate memory.
+   */
+  static svn_error_t * callback(svn_boolean_t *include,
+                                svn_fs_root_t *root,
+                                const char *path,
+                                void *baton,
+                                apr_pool_t *scratch_pool);
+
+  /**
+   * Handler for Subversion notifications.
+   *
+   * @param pool An APR pool from which to allocate memory.
+   */
+  void onFilter(svn_boolean_t *include,
+                svn_fs_root_t *root,
+                const char *path,
+                apr_pool_t *scratch_pool);
+};
+
 #endif  // SVN_JAVAHL_REPOS_VERIFY_CALLBACK_H
Index: subversion/bindings/javahl/native/SVNRepos.cpp
===================================================================
--- subversion/bindings/javahl/native/SVNRepos.cpp	(revision 1812076)
+++ subversion/bindings/javahl/native/SVNRepos.cpp	(working copy)
@@ -177,13 +177,14 @@ void SVNRepos::deltify(File &path, Revis
   return;
 }
 
 void SVNRepos::dump(File &path, OutputStream &dataOut,
                     Revision &revisionStart, Revision &revisionEnd,
                     bool incremental, bool useDeltas,
-                    ReposNotifyCallback *notifyCallback)
+                    ReposNotifyCallback *notifyCallback,
+                    ReposDumpFilterCallback *filterCallback)
 {
   SVN::Pool requestPool;
   svn_repos_t *repos;
   svn_fs_t *fs;
   svn_revnum_t lower = SVN_INVALID_REVNUM, upper = SVN_INVALID_REVNUM;
   svn_revnum_t youngest;
@@ -244,13 +245,16 @@ void SVNRepos::dump(File &path, OutputSt
                                  lower, upper, incremental, useDeltas,
                                  true, true,
                                  notifyCallback != NULL
                                     ? ReposNotifyCallback::notify
                                     : NULL,
                                  notifyCallback,
-                                 NULL, NULL,
+                                 filterCallback != NULL
+                                    ? ReposDumpFilterCallback::callback
+                                    : NULL,
+                                 filterCallback,
                                  checkCancel, this, requestPool.getPool()), );
 }
 
 void SVNRepos::hotcopy(File &path, File &targetPath,
                        bool cleanLogs, bool incremental,
                        ReposNotifyCallback *notifyCallback)
Index: subversion/bindings/javahl/native/SVNRepos.h
===================================================================
--- subversion/bindings/javahl/native/SVNRepos.h	(revision 1811982)
+++ subversion/bindings/javahl/native/SVNRepos.h	(working copy)
@@ -67,13 +67,14 @@ class SVNRepos : public SVNBase
                         MessageReceiver &messageReceiver);
   void listDBLogs(File &path, MessageReceiver &messageReceiver);
   void hotcopy(File &path, File &targetPath, bool cleanLogs, bool incremental,
                ReposNotifyCallback *notifyCallback);
   void dump(File &path, OutputStream &dataOut, Revision &revsionStart,
             Revision &RevisionEnd, bool incremental, bool useDeltas,
-            ReposNotifyCallback *notifyCallback);
+            ReposNotifyCallback *notifyCallback,
+            ReposDumpFilterCallback *filterCallback);
   void deltify(File &path, Revision &start, Revision &end);
   void create(File &path, bool ignoreUUID, bool forceUUID, File &configPath,
               const char *fstype);
   void upgrade(File &path, ReposNotifyCallback *callback);
   void pack(File &path, ReposNotifyCallback *callback);
   SVNRepos();

Reply via email to