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 ? ¬ifyCallback : NULL); + jnotifyCallback != NULL ? ¬ifyCallback : 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();