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/07/02 19:45:51 UTC
svn commit: r1499036 - in /subversion/trunk: ./
subversion/bindings/javahl/native/
subversion/bindings/javahl/src/org/apache/subversion/javahl/
subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/
subversion/bindings/javahl/src/org/apa...
Author: brane
Date: Tue Jul 2 17:45:50 2013
New Revision: 1499036
URL: http://svn.apache.org/r1499036
Log:
Implement RA status using Ev2 shims in JavaHL.
* build.conf (private-built-includes):
Add org_apache_subversion_javahl_remote_StateReporter.h.
[in subversion/bindings/javahl/src/org/apache/subversion/javahl]
* callback/RemoteStatus.java: New callback class; provides simpler interface
to the RA status edit drive.
* ISVNRemote.java (ISVNRemote.status): Replace the statusEditor parameter
with a RemoteStatus receiver reference.
* remote/RemoteSession.java (ISVNRemote.status): Implement non-native part,
delegating the entrails to ...
(RemoteSession.nativeStatus): ... this new private method.
* remote/UpdateReporter.java: Renamed to remote/StateReporter.java.
remote/StateReporter.java: Rename class, and implement it.
* remote/StatusEditor.java: New; This is the private status editor
implementation that drives the RemoteStatus callback.
[in subversion/bindings/javahl/native]
* EditorProxy.h, EditorProxy.cpp: New. Proxy for routing Ev2 operations
to a Java implementation of the Ev2 editor interface (ISVNEditor).
* StateReporter.h, StateReporter.cpp: New. Native implementation of the
StateReporter java class (i.e., an RA reporter interface).
* org_apache_subversion_javahl_remote_StateReporter.cpp: Native wrappers for same.
* RemoteSession.h (RemoteSession::status): Changed prototype.
RemoteSession.cpp (RemoteSession::status): Implement.
(status_unlock_func,
status_fetch_props_func, status_fetch_base_func,
status_start_edit_func, status_target_revision_func) New helpers.
* org_apache_subversion_javahl_remote_RemoteSession.cpp
(Java_org_apache_subversion_javahl_remote_RemoteSession_nativeStatus):
Update because of changed prototype.
Added:
subversion/trunk/subversion/bindings/javahl/native/EditorProxy.cpp
subversion/trunk/subversion/bindings/javahl/native/EditorProxy.h
subversion/trunk/subversion/bindings/javahl/native/StateReporter.cpp
subversion/trunk/subversion/bindings/javahl/native/StateReporter.h
subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_StateReporter.cpp
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/RemoteStatus.java
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/StateReporter.java
- copied, changed from r1499024, subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/UpdateReporter.java
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/StatusEditor.java
Removed:
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/UpdateReporter.java
Modified:
subversion/trunk/build.conf
subversion/trunk/subversion/bindings/javahl/native/RemoteSession.cpp
subversion/trunk/subversion/bindings/javahl/native/RemoteSession.h
subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_RemoteSession.cpp
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRemote.java
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/RemoteSession.java
subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java
Modified: subversion/trunk/build.conf
URL: http://svn.apache.org/viewvc/subversion/trunk/build.conf?rev=1499036&r1=1499035&r2=1499036&view=diff
==============================================================================
--- subversion/trunk/build.conf (original)
+++ subversion/trunk/build.conf Tue Jul 2 17:45:50 2013
@@ -70,6 +70,7 @@ private-built-includes =
subversion/bindings/javahl/include/org_apache_subversion_javahl_remote_RemoteSession.h
subversion/bindings/javahl/include/org_apache_subversion_javahl_remote_RemoteFactory.h
subversion/bindings/javahl/include/org_apache_subversion_javahl_remote_CommitEditor.h
+ subversion/bindings/javahl/include/org_apache_subversion_javahl_remote_StateReporter.h
subversion/bindings/javahl/include/org_apache_subversion_javahl_ConfigImpl_Category.h
test-scripts =
Added: subversion/trunk/subversion/bindings/javahl/native/EditorProxy.cpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/EditorProxy.cpp?rev=1499036&view=auto
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/EditorProxy.cpp (added)
+++ subversion/trunk/subversion/bindings/javahl/native/EditorProxy.cpp Tue Jul 2 17:45:50 2013
@@ -0,0 +1,527 @@
+/**
+ * @copyright
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ * @endcopyright
+ *
+ * @file EditorProxy.h
+ * @brief Interface of all editor proxy classes
+ */
+
+#include "JNIUtil.h"
+#include "JNIStackElement.h"
+#include "EditorProxy.h"
+#include "CreateJ.h"
+#include "EnumMapper.h"
+
+#include <apr_pools.h>
+#include "svn_error.h"
+#include "svn_private_config.h"
+
+
+namespace {
+const struct svn_delta__extra_baton null_extra_baton = {0};
+} // anonymous namespace
+
+EditorProxy::EditorProxy(jobject jeditor, apr_pool_t* edit_pool,
+ const char* repos_root_url, const char* base_relpath,
+ svn_cancel_func_t cancel_func, void* cancel_baton,
+ const EditorProxyCallbacks& callbacks)
+ : m_valid(false),
+ m_jeditor(JNIUtil::getEnv()->NewGlobalRef(jeditor)),
+ m_edit_pool(edit_pool),
+ m_repos_root_url(NULL),
+ m_base_relpath(NULL),
+ m_found_paths(false),
+ m_editor(NULL),
+ m_delta_editor(NULL),
+ m_delta_baton(NULL),
+ m_extra_baton(null_extra_baton)
+{
+ //DEBUG:fprintf(stderr, " (n) EditorProxy::EditorProxy(...)\n");
+
+ static const svn_editor_cb_many_t editor_many_cb = {
+ cb_add_directory, cb_add_file, cb_add_symlink, cb_add_absent,
+ cb_alter_directory, cb_alter_file, cb_alter_symlink,
+ cb_delete, cb_copy, cb_move, cb_rotate,
+ cb_complete, cb_abort
+ };
+
+ SVN::Pool scratchPool(edit_pool);
+ apr_pool_t* scratch_pool = scratchPool.getPool();
+
+ svn_error_t* err = svn_editor_create(&m_editor, this,
+ cancel_func, cancel_baton,
+ edit_pool, scratch_pool);
+ if (!err)
+ err = svn_editor_setcb_many(m_editor, &editor_many_cb, scratch_pool);
+ if (!err)
+ {
+ m_repos_root_url =
+ static_cast<const char*>(apr_pstrdup(edit_pool, repos_root_url));
+ m_base_relpath =
+ static_cast<const char*>(apr_pstrdup(edit_pool, base_relpath));
+ m_extra_baton.start_edit = callbacks.m_start_edit;
+ m_extra_baton.target_revision = callbacks.m_target_revision;
+ m_extra_baton.baton = callbacks.m_callbacks_baton;
+
+ svn_boolean_t found_paths;
+ err = svn_delta__delta_from_editor(&m_delta_editor,
+ &m_delta_baton,
+ m_editor,
+ callbacks.m_unlock_func,
+ callbacks.m_callbacks_baton,
+ &found_paths,
+ repos_root_url, base_relpath,
+ callbacks.m_fetch_props_func,
+ callbacks.m_callbacks_baton,
+ callbacks.m_fetch_base_func,
+ callbacks.m_callbacks_baton,
+ &m_extra_baton,
+ edit_pool);
+ m_found_paths = found_paths;
+ }
+
+ if (err)
+ JNIUtil::handleSVNError(err);
+ else
+ m_valid = true;
+}
+
+EditorProxy::~EditorProxy()
+{
+ //DEBUG:fprintf(stderr, " (n) EditorProxy::~EditorProxy()\n");
+
+ if (m_jeditor)
+ JNIUtil::getEnv()->DeleteGlobalRef(m_jeditor);
+}
+
+namespace {
+inline svn_error_t* invalid_editor()
+{
+ return svn_error_create(SVN_ERR_RA_SVN_EDIT_ABORTED, NULL,
+ _("The editor is not valid"));
+}
+
+svn_error_t*
+get_editor_method(jmethodID& mid, const char* name, const char* sig)
+{
+ if (0 != mid)
+ return SVN_NO_ERROR; // Already known.
+
+ JNIEnv* env = JNIUtil::getEnv();
+ jclass cls = env->FindClass(JAVA_PACKAGE"/ISVNEditor");
+ SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
+ SVN_JNI_CATCH(mid = env->GetMethodID(cls, name, sig),
+ SVN_ERR_RA_SVN_EDIT_ABORTED);
+ return SVN_NO_ERROR;
+}
+} // anonymous namespace
+
+svn_error_t*
+EditorProxy::cb_add_directory(void *baton,
+ const char *relpath,
+ const apr_array_header_t *children,
+ apr_hash_t *props,
+ svn_revnum_t replaces_rev,
+ apr_pool_t *scratch_pool)
+{
+ //DEBUG:fprintf(stderr, " (n) EditorProxy::cb_add_directory('%s')\n", relpath);
+
+ EditorProxy* const ep = static_cast<EditorProxy*>(baton);
+ if (!ep->m_valid)
+ return invalid_editor();
+
+ static jmethodID mid = 0;
+ SVN_ERR(get_editor_method(mid, "addDirectory",
+ "(Ljava/lang/String;"
+ "Ljava/lang/Iterable;"
+ "Ljava/util/Map;J)V"));
+
+ jstring jrelpath = JNIUtil::makeJString(relpath);
+ SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
+ jobject jchildren = (!children ? NULL : CreateJ::StringSet(children));
+ SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
+ jobject jprops = CreateJ::PropertyMap(props);
+ SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
+
+ SVN_JNI_CATCH(
+ JNIUtil::getEnv()->CallVoidMethod(ep->m_jeditor, mid,
+ jrelpath, jchildren, jprops,
+ jlong(replaces_rev)),
+ SVN_ERR_RA_SVN_EDIT_ABORTED);
+ return SVN_NO_ERROR;
+}
+
+svn_error_t*
+EditorProxy::cb_add_file(void *baton,
+ const char *relpath,
+ const svn_checksum_t *checksum,
+ svn_stream_t *contents,
+ apr_hash_t *props,
+ svn_revnum_t replaces_rev,
+ apr_pool_t *scratch_pool)
+{
+ //DEBUG:fprintf(stderr, " (n) EditorProxy::cb_add_file('%s')\n", relpath);
+
+ EditorProxy* const ep = static_cast<EditorProxy*>(baton);
+ if (!ep || !ep->m_valid)
+ return invalid_editor();
+
+ static jmethodID mid = 0;
+ SVN_ERR(get_editor_method(mid, "addFile",
+ "(Ljava/lang/String;"
+ "L"JAVA_PACKAGE"/types/Checksum;"
+ "Ljava/io/InputStream;"
+ "Ljava/util/Map;J)V"));
+
+ jstring jrelpath = JNIUtil::makeJString(relpath);
+ SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
+ jobject jchecksum = CreateJ::Checksum(checksum);
+ SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
+ jobject jcontents = NULL; // FIXME: input stream proxy
+ SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
+ jobject jprops = CreateJ::PropertyMap(props);
+ SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
+
+ SVN_JNI_CATCH(
+ JNIUtil::getEnv()->CallVoidMethod(ep->m_jeditor, mid,
+ jrelpath, jchecksum, jcontents,
+ jprops, jlong(replaces_rev)),
+ SVN_ERR_RA_SVN_EDIT_ABORTED);
+ return SVN_NO_ERROR;
+}
+
+svn_error_t*
+EditorProxy::cb_add_symlink(void *baton,
+ const char *relpath,
+ const char *target,
+ apr_hash_t *props,
+ svn_revnum_t replaces_rev,
+ apr_pool_t *scratch_pool)
+{
+ //DEBUG:fprintf(stderr, " (n) EditorProxy::cb_add_symlink('%s')\n", relpath);
+
+ EditorProxy* const ep = static_cast<EditorProxy*>(baton);
+ if (!ep || !ep->m_valid)
+ return invalid_editor();
+
+ static jmethodID mid = 0;
+ SVN_ERR(get_editor_method(mid, "addSymlink",
+ "(Ljava/lang/String;"
+ "Ljava/lang/String;"
+ "Ljava/util/Map;J)V"));
+
+ jstring jrelpath = JNIUtil::makeJString(relpath);
+ SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
+ jstring jtarget = JNIUtil::makeJString(target);
+ SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
+ jobject jprops = CreateJ::PropertyMap(props);
+ SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
+
+ SVN_JNI_CATCH(
+ JNIUtil::getEnv()->CallVoidMethod(ep->m_jeditor, mid,
+ jrelpath, jtarget, jprops,
+ jlong(replaces_rev)),
+ SVN_ERR_RA_SVN_EDIT_ABORTED);
+ return SVN_NO_ERROR;
+}
+
+svn_error_t*
+EditorProxy::cb_add_absent(void *baton,
+ const char *relpath,
+ svn_node_kind_t kind,
+ svn_revnum_t replaces_rev,
+ apr_pool_t *scratch_pool)
+{
+ //DEBUG:fprintf(stderr, " (n) EditorProxy::cb_add_absent('%s')\n", relpath);
+
+ EditorProxy* const ep = static_cast<EditorProxy*>(baton);
+ if (!ep || !ep->m_valid)
+ return invalid_editor();
+
+ static jmethodID mid = 0;
+ SVN_ERR(get_editor_method(mid, "addAbsent",
+ "(Ljava/lang/String;"
+ "L"JAVA_PACKAGE"/types/NodeKind;"
+ "J)V"));
+
+ jstring jrelpath = JNIUtil::makeJString(relpath);
+ SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
+ jobject jkind = EnumMapper::mapNodeKind(kind);
+ SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
+
+ SVN_JNI_CATCH(
+ JNIUtil::getEnv()->CallVoidMethod(ep->m_jeditor, mid,
+ jrelpath, jkind,
+ jlong(replaces_rev)),
+ SVN_ERR_RA_SVN_EDIT_ABORTED);
+ return SVN_NO_ERROR;
+}
+
+svn_error_t*
+EditorProxy::cb_alter_directory(void *baton,
+ const char *relpath,
+ svn_revnum_t revision,
+ const apr_array_header_t *children,
+ apr_hash_t *props,
+ apr_pool_t *scratch_pool)
+{
+ //DEBUG:fprintf(stderr, " (n) EditorProxy::cb_alter_directory('%s', r%lld)\n",
+ //DEBUG: relpath, static_cast<long long>(revision));
+
+ EditorProxy* const ep = static_cast<EditorProxy*>(baton);
+ if (!ep || !ep->m_valid)
+ return invalid_editor();
+
+ static jmethodID mid = 0;
+ SVN_ERR(get_editor_method(mid, "alterDirectory",
+ "(Ljava/lang/String;J"
+ "Ljava/lang/Iterable;"
+ "Ljava/util/Map;)V"));
+
+ jstring jrelpath = JNIUtil::makeJString(relpath);
+ SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
+ jobject jchildren = (!children ? NULL : CreateJ::StringSet(children));
+ SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
+ jobject jprops = CreateJ::PropertyMap(props);
+ SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
+
+ SVN_JNI_CATCH(
+ JNIUtil::getEnv()->CallVoidMethod(ep->m_jeditor, mid,
+ jrelpath, jlong(revision),
+ jchildren, jprops),
+ SVN_ERR_RA_SVN_EDIT_ABORTED);
+ return SVN_NO_ERROR;
+}
+
+svn_error_t*
+EditorProxy::cb_alter_file(void *baton,
+ const char *relpath,
+ svn_revnum_t revision,
+ const svn_checksum_t *checksum,
+ svn_stream_t *contents,
+ apr_hash_t *props,
+ apr_pool_t *scratch_pool)
+{
+ //DEBUG:fprintf(stderr, " (n) EditorProxy::cb_alter_file('%s', r%lld)\n",
+ //DEBUG: relpath, static_cast<long long>(revision));
+
+ EditorProxy* const ep = static_cast<EditorProxy*>(baton);
+ if (!ep || !ep->m_valid)
+ return invalid_editor();
+
+ static jmethodID mid = 0;
+ SVN_ERR(get_editor_method(mid, "alterFile",
+ "(Ljava/lang/String;J"
+ "L"JAVA_PACKAGE"/types/Checksum;"
+ "Ljava/io/InputStream;"
+ "Ljava/util/Map;)V"));
+
+ jstring jrelpath = JNIUtil::makeJString(relpath);
+ SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
+ jobject jchecksum = CreateJ::Checksum(checksum);
+ SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
+ jobject jcontents = NULL; // FIXME: input stream proxy
+ SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
+ jobject jprops = CreateJ::PropertyMap(props);
+ SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
+
+ SVN_JNI_CATCH(
+ JNIUtil::getEnv()->CallVoidMethod(ep->m_jeditor, mid,
+ jrelpath, jlong(revision),
+ jchecksum, jcontents, jprops),
+ SVN_ERR_RA_SVN_EDIT_ABORTED);
+ return SVN_NO_ERROR;
+}
+
+svn_error_t*
+EditorProxy::cb_alter_symlink(void *baton,
+ const char *relpath,
+ svn_revnum_t revision,
+ const char *target,
+ apr_hash_t *props,
+ apr_pool_t *scratch_pool)
+{
+ //DEBUG:fprintf(stderr, " (n) EditorProxy::cb_alter_symlink('%s', r%lld)\n",
+ //DEBUG: relpath, static_cast<long long>(revision));
+
+ EditorProxy* const ep = static_cast<EditorProxy*>(baton);
+ if (!ep || !ep->m_valid)
+ return invalid_editor();
+
+ static jmethodID mid = 0;
+ SVN_ERR(get_editor_method(mid, "alterSymlink",
+ "(Ljava/lang/String;J"
+ "Ljava/lang/String;"
+ "Ljava/util/Map;)V"));
+
+ jstring jrelpath = JNIUtil::makeJString(relpath);
+ SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
+ jstring jtarget = JNIUtil::makeJString(target);
+ SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
+ jobject jprops = CreateJ::PropertyMap(props);
+ SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
+
+ SVN_JNI_CATCH(
+ JNIUtil::getEnv()->CallVoidMethod(ep->m_jeditor, mid,
+ jrelpath, jlong(revision),
+ jtarget, jprops),
+ SVN_ERR_RA_SVN_EDIT_ABORTED);
+ return SVN_NO_ERROR;
+}
+
+svn_error_t*
+EditorProxy::cb_delete(void *baton,
+ const char *relpath,
+ svn_revnum_t revision,
+ apr_pool_t *scratch_pool)
+{
+ //DEBUG:fprintf(stderr, " (n) EditorProxy::cb_delete('%s', r%lld)\n",
+ //DEBUG: relpath, static_cast<long long>(revision));
+
+ EditorProxy* const ep = static_cast<EditorProxy*>(baton);
+ if (!ep || !ep->m_valid)
+ return invalid_editor();
+
+ static jmethodID mid = 0;
+ SVN_ERR(get_editor_method(mid, "delete",
+ "(Ljava/lang/String;J)V"));
+
+ jstring jrelpath = JNIUtil::makeJString(relpath);
+ SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
+
+ SVN_JNI_CATCH(
+ JNIUtil::getEnv()->CallVoidMethod(ep->m_jeditor, mid, jrelpath),
+ SVN_ERR_RA_SVN_EDIT_ABORTED);
+ return SVN_NO_ERROR;
+}
+
+svn_error_t*
+EditorProxy::cb_copy(void *baton,
+ const char *src_relpath,
+ svn_revnum_t src_revision,
+ const char *dst_relpath,
+ svn_revnum_t replaces_rev,
+ apr_pool_t *scratch_pool)
+{
+ //DEBUG:fprintf(stderr, " (n) EditorProxy::cb_copy('%s', r%lld, '%s')\n",
+ //DEBUG: src_relpath, static_cast<long long>(src_revision), dst_relpath);
+
+ EditorProxy* const ep = static_cast<EditorProxy*>(baton);
+ if (!ep || !ep->m_valid)
+ return invalid_editor();
+
+ static jmethodID mid = 0;
+ SVN_ERR(get_editor_method(mid, "copy",
+ "(Ljava/lang/String;J"
+ "Ljava/lang/String;J)V"));
+
+ jstring jsrc_relpath = JNIUtil::makeJString(src_relpath);
+ SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
+ jstring jdst_relpath = JNIUtil::makeJString(dst_relpath);
+ SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
+
+ SVN_JNI_CATCH(
+ JNIUtil::getEnv()->CallVoidMethod(ep->m_jeditor, mid,
+ jsrc_relpath, jlong(src_revision),
+ jdst_relpath, jlong(replaces_rev)),
+ SVN_ERR_RA_SVN_EDIT_ABORTED);
+ return SVN_NO_ERROR;
+}
+
+svn_error_t*
+EditorProxy::cb_move(void *baton,
+ const char *src_relpath,
+ svn_revnum_t src_revision,
+ const char *dst_relpath,
+ svn_revnum_t replaces_rev,
+ apr_pool_t *scratch_pool)
+{
+ //DEBUG:fprintf(stderr, " (n) EditorProxy::cb_move('%s', r%lld, '%s')\n",
+ //DEBUG: src_relpath, static_cast<long long>(src_revision), dst_relpath);
+
+ EditorProxy* const ep = static_cast<EditorProxy*>(baton);
+ if (!ep || !ep->m_valid)
+ return invalid_editor();
+
+ static jmethodID mid = 0;
+ SVN_ERR(get_editor_method(mid, "move",
+ "(Ljava/lang/String;J"
+ "Ljava/lang/String;J)V"));
+
+ jstring jsrc_relpath = JNIUtil::makeJString(src_relpath);
+ SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
+ jstring jdst_relpath = JNIUtil::makeJString(dst_relpath);
+ SVN_JNI_CATCH(,SVN_ERR_RA_SVN_EDIT_ABORTED);
+
+ SVN_JNI_CATCH(
+ JNIUtil::getEnv()->CallVoidMethod(ep->m_jeditor, mid,
+ jsrc_relpath, jlong(src_revision),
+ jdst_relpath, jlong(replaces_rev)),
+ SVN_ERR_RA_SVN_EDIT_ABORTED);
+ return SVN_NO_ERROR;
+}
+
+svn_error_t*
+EditorProxy::cb_rotate(void*,
+ const apr_array_header_t*,
+ const apr_array_header_t*,
+ apr_pool_t*)
+{
+ return svn_error_create(APR_ENOTIMPL, NULL, "EditorProxy::cb_rotate");
+}
+
+svn_error_t*
+EditorProxy::cb_complete(void *baton, apr_pool_t *scratch_pool)
+{
+ //DEBUG:fprintf(stderr, " (n) EditorProxy::cb_complete()\n");
+
+ EditorProxy* const ep = static_cast<EditorProxy*>(baton);
+ if (!ep || !ep->m_valid)
+ return invalid_editor();
+ ep->m_valid = false;
+
+ static jmethodID mid = 0;
+ SVN_ERR(get_editor_method(mid, "complete", "()V"));
+
+ SVN_JNI_CATCH(
+ JNIUtil::getEnv()->CallVoidMethod(ep->m_jeditor, mid),
+ SVN_ERR_RA_SVN_EDIT_ABORTED);
+ return SVN_NO_ERROR;
+}
+
+svn_error_t*
+EditorProxy::cb_abort(void *baton, apr_pool_t *scratch_pool)
+{
+ //DEBUG:fprintf(stderr, " (n) EditorProxy::cb_abort()\n");
+
+ EditorProxy* const ep = static_cast<EditorProxy*>(baton);
+ if (!ep || !ep->m_valid)
+ return invalid_editor();
+ ep->m_valid = false;
+
+ static jmethodID mid = 0;
+ SVN_ERR(get_editor_method(mid, "abort", "()V"));
+
+ SVN_JNI_CATCH(
+ JNIUtil::getEnv()->CallVoidMethod(ep->m_jeditor, mid),
+ SVN_ERR_RA_SVN_EDIT_ABORTED);
+ return SVN_NO_ERROR;
+}
Added: subversion/trunk/subversion/bindings/javahl/native/EditorProxy.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/EditorProxy.h?rev=1499036&view=auto
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/EditorProxy.h (added)
+++ subversion/trunk/subversion/bindings/javahl/native/EditorProxy.h Tue Jul 2 17:45:50 2013
@@ -0,0 +1,160 @@
+/**
+ * @copyright
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ * @endcopyright
+ *
+ * @file EditorProxy.h
+ * @brief Interface of all editor proxy classes
+ */
+
+#ifndef JAVAHL_EDITOR_PROXY_H
+#define JAVAHL_EDITOR_PROXY_H
+
+#include "svn_delta.h"
+#include "private/svn_editor.h"
+#include "private/svn_delta_private.h"
+
+/**
+ * These callbacks are needed by the delta-to-Ev2 shims.
+ */
+struct EditorProxyCallbacks
+{
+ svn_delta__unlock_func_t m_unlock_func;
+ svn_delta_fetch_props_func_t m_fetch_props_func;
+ svn_delta_fetch_base_func_t m_fetch_base_func;
+ svn_delta__start_edit_func_t m_start_edit;
+ svn_delta__target_revision_func_t m_target_revision;
+ void* m_callbacks_baton;
+};
+
+/**
+ * This is a proxy object that translates Ev2 operations (possibly
+ * implemented through shims) into calls to a Java editor
+ * implementation.
+ */
+class EditorProxy
+{
+public:
+ EditorProxy(jobject jeditor, apr_pool_t* edit_pool,
+ const char* repos_root_url, const char* base_relpath,
+ svn_cancel_func_t cancel_func, void* cancel_baton,
+ const EditorProxyCallbacks& callbacks);
+ ~EditorProxy();
+
+ const svn_delta_editor_t* delta_editor() const
+ {
+ return m_delta_editor;
+ }
+
+ void* delta_baton() const
+ {
+ return m_delta_baton;
+ }
+
+private:
+ EditorProxy(const EditorProxy&); // noncopyable
+
+ static svn_error_t* cb_add_directory(void *baton,
+ const char *relpath,
+ const apr_array_header_t *children,
+ apr_hash_t *props,
+ svn_revnum_t replaces_rev,
+ apr_pool_t *scratch_pool);
+ static svn_error_t* cb_add_file(void *baton,
+ const char *relpath,
+ const svn_checksum_t *checksum,
+ svn_stream_t *contents,
+ apr_hash_t *props,
+ svn_revnum_t replaces_rev,
+ apr_pool_t *scratch_pool);
+ static svn_error_t* cb_add_symlink(void *baton,
+ const char *relpath,
+ const char *target,
+ apr_hash_t *props,
+ svn_revnum_t replaces_rev,
+ apr_pool_t *scratch_pool);
+ static svn_error_t* cb_add_absent(void *baton,
+ const char *relpath,
+ svn_node_kind_t kind,
+ svn_revnum_t replaces_rev,
+ apr_pool_t *scratch_pool);
+ static svn_error_t* cb_alter_directory(void *baton,
+ const char *relpath,
+ svn_revnum_t revision,
+ const apr_array_header_t *children,
+ apr_hash_t *props,
+ apr_pool_t *scratch_pool);
+ static svn_error_t* cb_alter_file(void *baton,
+ const char *relpath,
+ svn_revnum_t revision,
+ const svn_checksum_t *checksum,
+ svn_stream_t *contents,
+ apr_hash_t *props,
+ apr_pool_t *scratch_pool);
+ static svn_error_t* cb_alter_symlink(void *baton,
+ const char *relpath,
+ svn_revnum_t revision,
+ const char *target,
+ apr_hash_t *props,
+ apr_pool_t *scratch_pool);
+ static svn_error_t* cb_delete(void *baton,
+ const char *relpath,
+ svn_revnum_t revision,
+ apr_pool_t *scratch_pool);
+ static svn_error_t* cb_copy(void *baton,
+ const char *src_relpath,
+ svn_revnum_t src_revision,
+ const char *dst_relpath,
+ svn_revnum_t replaces_rev,
+ apr_pool_t *scratch_pool);
+ static svn_error_t* cb_move(void *baton,
+ const char *src_relpath,
+ svn_revnum_t src_revision,
+ const char *dst_relpath,
+ svn_revnum_t replaces_rev,
+ apr_pool_t *scratch_pool);
+ static svn_error_t* cb_rotate(void *baton,
+ const apr_array_header_t *relpaths,
+ const apr_array_header_t *revisions,
+ apr_pool_t *scratch_pool);
+ static svn_error_t* cb_complete(void *baton,
+ apr_pool_t *scratch_pool);
+ static svn_error_t* cb_abort(void *baton,
+ apr_pool_t *scratch_pool);
+
+private:
+ bool m_valid;
+ jobject m_jeditor; ///< Reference to Java editor implementation
+ apr_pool_t* m_edit_pool;
+
+ const char* m_repos_root_url; ///< The root of the repository
+ const char* m_base_relpath; ///< The root of the session within the repo
+ bool m_found_paths; ///< Returned paths are absolute
+
+ svn_editor_t* m_editor;
+ const svn_delta_editor_t* m_delta_editor;
+ void* m_delta_baton;
+
+ // Initialized from the EditorProxyCallbacks struct.
+ struct svn_delta__extra_baton m_extra_baton;
+};
+
+
+#endif // JAVAHL_EDITOR_PROXY_H
Modified: subversion/trunk/subversion/bindings/javahl/native/RemoteSession.cpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/RemoteSession.cpp?rev=1499036&r1=1499035&r2=1499036&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/RemoteSession.cpp (original)
+++ subversion/trunk/subversion/bindings/javahl/native/RemoteSession.cpp Tue Jul 2 17:45:50 2013
@@ -25,6 +25,7 @@
*/
#include <cstring>
+#include <memory>
#include <set>
#include "JNIByteArray.h"
@@ -44,6 +45,8 @@
#include "Prompter.h"
#include "Revision.h"
#include "RemoteSession.h"
+#include "EditorProxy.h"
+#include "StateReporter.h"
#include <apr_strings.h>
#include "svn_private_config.h"
@@ -639,12 +642,109 @@ RemoteSession::getDirectory(jlong jrevis
// TODO: update
// TODO: switch
-jobject
-RemoteSession::status(jstring jstatus_target,
+namespace {
+svn_error_t*
+status_unlock_func(void* baton, const char* path, apr_pool_t* scratch_pool)
+{
+ //DEBUG:fprintf(stderr, " (n) status_unlock_func('%s')\n", path);
+ return SVN_NO_ERROR;
+}
+
+svn_error_t*
+status_fetch_props_func(apr_hash_t **props, void *baton,
+ const char *path, svn_revnum_t base_revision,
+ apr_pool_t *result_pool, apr_pool_t *scratch_pool)
+{
+ //DEBUG:fprintf(stderr, " (n) status_fetch_props_func('%s', r%lld)\n",
+ //DEBUG: path, static_cast<long long>(base_revision));
+ *props = apr_hash_make(scratch_pool);
+ return SVN_NO_ERROR;
+}
+
+svn_error_t*
+status_fetch_base_func(const char **filename, void *baton,
+ const char *path, svn_revnum_t base_revision,
+ apr_pool_t *result_pool, apr_pool_t *scratch_pool)
+{
+ //DEBUG:fprintf(stderr, " (n) status_fetch_base_func('%s', r%lld)\n",
+ //DEBUG: path, static_cast<long long>(base_revision));
+ *filename = NULL;
+ return SVN_NO_ERROR;
+}
+
+svn_error_t*
+status_start_edit_func(void* baton, svn_revnum_t start_revision)
+{
+ //DEBUG:fprintf(stderr, " (n) status_start_edit_func(r%lld)\n",
+ //DEBUG: static_cast<long long>(start_revision));
+ return SVN_NO_ERROR;
+}
+
+svn_error_t*
+status_target_revision_func(void* baton, svn_revnum_t target_revision,
+ apr_pool_t* scratch_pool)
+{
+ //DEBUG:fprintf(stderr, " (n) status_target_revision_func(r%lld)\n",
+ //DEBUG: static_cast<long long>(target_revision));
+ return SVN_NO_ERROR;
+}
+
+const EditorProxyCallbacks status_editor_callbacks = {
+ status_unlock_func,
+ status_fetch_props_func,
+ status_fetch_base_func,
+ status_start_edit_func,
+ status_target_revision_func,
+ NULL
+};
+} // anonymous namespace
+
+void
+RemoteSession::status(jobject jthis, jstring jstatus_target,
jlong jrevision, jobject jdepth,
- jobject jstatus_editor)
+ jobject jstatus_editor, jobject jreporter)
{
- return NULL;
+ StateReporter *rp = StateReporter::getCppObject(jreporter);
+ CPPADDR_NULL_PTR(rp,);
+
+ SVN::Pool scratchPool(rp->get_report_pool());
+ Relpath status_target(jstatus_target, scratchPool);
+ if (JNIUtil::isExceptionThrown())
+ return;
+
+ apr_pool_t* scratch_pool = scratchPool.getPool();
+ const char* repos_root_url;
+ SVN_JNI_ERR(svn_ra_get_repos_root2(m_session, &repos_root_url,
+ scratch_pool),);
+ const char* session_root_url;
+ SVN_JNI_ERR(svn_ra_get_session_url(m_session, &session_root_url,
+ scratch_pool),);
+ const char* base_relpath;
+ SVN_JNI_ERR(svn_ra_get_path_relative_to_root(m_session, &base_relpath,
+ session_root_url,
+ scratch_pool),);
+
+
+ apr_pool_t* report_pool = rp->get_report_pool();
+ std::auto_ptr<EditorProxy> editor(
+ new EditorProxy(jstatus_editor, report_pool,
+ repos_root_url, base_relpath,
+ m_context->checkCancel, m_context,
+ status_editor_callbacks));
+ if (JNIUtil::isExceptionThrown())
+ return;
+
+ const svn_ra_reporter3_t* raw_reporter;
+ void* report_baton;
+ SVN_JNI_ERR(svn_ra_do_status2(m_session,
+ &raw_reporter, &report_baton,
+ status_target.c_str(),
+ svn_revnum_t(jrevision),
+ EnumMapper::toDepth(jdepth),
+ editor->delta_editor(),
+ editor->delta_baton(),
+ report_pool),);
+ rp->set_reporter_data(raw_reporter, report_baton, editor.release());
}
// TODO: diff
Modified: subversion/trunk/subversion/bindings/javahl/native/RemoteSession.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/RemoteSession.h?rev=1499036&r1=1499035&r2=1499036&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/RemoteSession.h (original)
+++ subversion/trunk/subversion/bindings/javahl/native/RemoteSession.h Tue Jul 2 17:45:50 2013
@@ -82,9 +82,9 @@ class RemoteSession : public SVNBase
// TODO: getMergeinfo
// TODO: update
// TODO: switch
- jobject status(jstring jstatus_target,
- jlong jrevision, jobject jdepth,
- jobject jstatus_editor);
+ void status(jobject jthis, jstring jstatus_target,
+ jlong jrevision, jobject jdepth,
+ jobject jstatus_editor, jobject jreporter);
// TODO: diff
void getLog(jobject jpaths, jlong jstartrev, jlong jendrev, jint jlimit,
jboolean jstrict_node_history, jboolean jdiscover_changed_paths,
Added: subversion/trunk/subversion/bindings/javahl/native/StateReporter.cpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/StateReporter.cpp?rev=1499036&view=auto
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/StateReporter.cpp (added)
+++ subversion/trunk/subversion/bindings/javahl/native/StateReporter.cpp Tue Jul 2 17:45:50 2013
@@ -0,0 +1,186 @@
+/**
+ * @copyright
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ * @endcopyright
+ *
+ * @file StateReporter.cpp
+ * @brief Implementation of the class StateReporter
+ */
+
+#include <jni.h>
+
+#include "JNIUtil.h"
+#include "JNIStringHolder.h"
+#include "StateReporter.h"
+#include "EnumMapper.h"
+#include "Path.h"
+
+#include "svn_private_config.h"
+
+StateReporter::StateReporter()
+ : m_valid(false),
+ m_raw_reporter(NULL),
+ m_report_baton(NULL),
+ m_editor(NULL)
+{}
+
+StateReporter::~StateReporter()
+{
+ delete m_editor;
+}
+
+StateReporter*
+StateReporter::getCppObject(jobject jthis)
+{
+ static jfieldID fid = 0;
+ jlong cppAddr = SVNBase::findCppAddrForJObject(jthis, &fid,
+ JAVA_PACKAGE"/remote/StateReporter");
+ return (cppAddr == 0 ? NULL : reinterpret_cast<StateReporter*>(cppAddr));
+}
+
+void
+StateReporter::dispose(jobject jthis)
+{
+ //DEBUG:fprintf(stderr, " (n) StateReporter::dispose()\n");
+
+ if (m_valid)
+ abortReport();
+
+ static jfieldID fid = 0;
+ SVNBase::dispose(jthis, &fid, JAVA_PACKAGE"/remote/StateReporter");
+}
+
+namespace {
+void throw_reporter_inactive()
+{
+ JNIUtil::raiseThrowable("java/lang/IllegalStateException",
+ _("The reporter is not active"));
+}
+} // anonymous namespace
+
+void
+StateReporter::setPath(jstring jpath, jlong jrevision, jobject jdepth,
+ jboolean jstart_empty, jstring jlock_token)
+{
+ //DEBUG:fprintf(stderr, " (n) StateReporter::setPath()\n");
+
+ if (!m_valid) { throw_reporter_inactive(); return; }
+
+ JNIStringHolder lock_token(jlock_token);
+ if (JNIUtil::isJavaExceptionThrown())
+ return;
+
+ SVN::Pool subPool(pool);
+ Relpath path(jpath, subPool);
+ if (JNIUtil::isJavaExceptionThrown())
+ return;
+ svn_depth_t depth = EnumMapper::toDepth(jdepth);
+ if (JNIUtil::isJavaExceptionThrown())
+ return;
+
+ SVN_JNI_ERR(m_raw_reporter->set_path(m_report_baton, path.c_str(),
+ svn_revnum_t(jrevision), depth,
+ bool(jstart_empty), lock_token.c_str(),
+ subPool.getPool()),);
+}
+
+void
+StateReporter::deletePath(jstring jpath)
+{
+ //DEBUG:fprintf(stderr, " (n) StateReporter::deletePath()\n");
+
+ if (!m_valid) { throw_reporter_inactive(); return; }
+
+ SVN::Pool subPool(pool);
+ Relpath path(jpath, subPool);
+ if (JNIUtil::isJavaExceptionThrown())
+ return;
+
+ SVN_JNI_ERR(m_raw_reporter->delete_path(m_report_baton, path.c_str(),
+ subPool.getPool()),);
+}
+
+void
+StateReporter::linkPath(jstring jurl, jstring jpath,
+ jlong jrevision, jobject jdepth,
+ jboolean jstart_empty, jstring jlock_token)
+{
+ //DEBUG:fprintf(stderr, " (n) StateReporter::linkPath()\n");
+
+ if (!m_valid) { throw_reporter_inactive(); return; }
+
+ JNIStringHolder lock_token(jlock_token);
+ if (JNIUtil::isJavaExceptionThrown())
+ return;
+
+ SVN::Pool subPool(pool);
+ Relpath path(jpath, subPool);
+ if (JNIUtil::isJavaExceptionThrown())
+ return;
+ URL url(jurl, subPool);
+ if (JNIUtil::isJavaExceptionThrown())
+ return;
+ svn_depth_t depth = EnumMapper::toDepth(jdepth);
+ if (JNIUtil::isJavaExceptionThrown())
+ return;
+
+ SVN_JNI_ERR(m_raw_reporter->link_path(m_report_baton, path.c_str(),
+ url.c_str(), svn_revnum_t(jrevision),
+ depth, bool(jstart_empty),
+ lock_token.c_str(),
+ subPool.getPool()),);
+}
+
+void
+StateReporter::finishReport()
+{
+ //DEBUG:fprintf(stderr, " (n) StateReporter::finishReport()\n");
+
+ if (!m_valid) { throw_reporter_inactive(); return; }
+
+ SVN::Pool subPool(pool);
+ SVN_JNI_ERR(m_raw_reporter->finish_report(m_report_baton,
+ subPool.getPool()),);
+}
+
+void
+StateReporter::abortReport()
+{
+ //DEBUG:fprintf(stderr, " (n) StateReporter::abortReport()\n");
+
+ if (!m_valid) { throw_reporter_inactive(); return; }
+
+ SVN::Pool subPool(pool);
+ SVN_JNI_ERR(m_raw_reporter->abort_report(m_report_baton,
+ subPool.getPool()),);
+}
+
+void
+StateReporter::set_reporter_data(const svn_ra_reporter3_t* raw_reporter,
+ void* report_baton,
+ EditorProxy* editor)
+{
+ //DEBUG:fprintf(stderr, " (n) StateReporter::set_reporter_data()\n");
+
+ m_editor = editor;
+ m_raw_reporter = raw_reporter;
+ m_report_baton = report_baton;
+ m_valid = true;
+}
Added: subversion/trunk/subversion/bindings/javahl/native/StateReporter.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/StateReporter.h?rev=1499036&view=auto
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/StateReporter.h (added)
+++ subversion/trunk/subversion/bindings/javahl/native/StateReporter.h Tue Jul 2 17:45:50 2013
@@ -0,0 +1,73 @@
+/**
+ * @copyright
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ * @endcopyright
+ *
+ * @file UpdateReporter.h
+ * @brief Interface of the class UpdateReporter
+ */
+
+#ifndef JAVAHL_UPDATE_REPORTER_H
+#define JAVAHL_UPDATE_REPORTER_H
+
+#include <jni.h>
+
+#include "svn_ra.h"
+#include "SVNBase.h"
+#include "EditorProxy.h"
+
+class RemoteSession;
+
+/*
+ * This class wraps the update/status/switch/diff reporter in svn_ra.h
+ */
+class StateReporter : public SVNBase
+{
+public:
+ StateReporter();
+ virtual ~StateReporter();
+
+ static StateReporter* getCppObject(jobject jreporter);
+
+ virtual void dispose(jobject jthis);
+
+ void setPath(jstring jpath, jlong jrevision, jobject jdepth,
+ jboolean jstart_empty, jstring jlock_token);
+ void deletePath(jstring jpath);
+ void linkPath(jstring jurl, jstring jpath, jlong jrevision, jobject jdepth,
+ jboolean jstart_empty, jstring jlock_token);
+ void finishReport();
+ void abortReport();
+
+private:
+
+ bool m_valid;
+ const svn_ra_reporter3_t* m_raw_reporter;
+ void* m_report_baton;
+ EditorProxy* m_editor;
+
+ friend class RemoteSession;
+ apr_pool_t* get_report_pool() const { return pool.getPool(); }
+ void set_reporter_data(const svn_ra_reporter3_t* raw_reporter,
+ void* report_baton,
+ EditorProxy* editor);
+};
+
+#endif // JAVAHL_UPDATE_REPORTER_H
Modified: subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_RemoteSession.cpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_RemoteSession.cpp?rev=1499036&r1=1499035&r2=1499036&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_RemoteSession.cpp (original)
+++ subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_RemoteSession.cpp Tue Jul 2 17:45:50 2013
@@ -217,16 +217,17 @@ Java_org_apache_subversion_javahl_remote
// TODO: update
// TODO: switch
-JNIEXPORT jobject JNICALL
-Java_org_apache_subversion_javahl_remote_RemoteSession_status(
- JNIEnv *env, jobject jthis, jstring jstatus_target,
- jlong jrevision, jobject jdepth, jobject jstatus_editor)
+JNIEXPORT void JNICALL
+Java_org_apache_subversion_javahl_remote_RemoteSession_nativeStatus(
+ JNIEnv *env, jobject jthis, jstring jstatus_target, jlong jrevision,
+ jobject jdepth, jobject jstatus_editor, jobject jreporter)
{
- JNIEntry(SVNReposAccess, doStatus);
+ JNIEntry(SVNReposAccess, nativeStatus);
RemoteSession *ras = RemoteSession::getCppObject(jthis);
- CPPADDR_NULL_PTR(ras, NULL);
+ CPPADDR_NULL_PTR(ras,);
- return ras->status(jstatus_target, jrevision, jdepth, jstatus_editor);
+ ras->status(jthis, jstatus_target, jrevision, jdepth,
+ jstatus_editor, jreporter);
}
// TODO: diff
Added: subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_StateReporter.cpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_StateReporter.cpp?rev=1499036&view=auto
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_StateReporter.cpp (added)
+++ subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_remote_StateReporter.cpp Tue Jul 2 17:45:50 2013
@@ -0,0 +1,117 @@
+/**
+ * @copyright
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ * @endcopyright
+ *
+ * @file org_apache_subversion_javahl_remote_StateReporter.cpp
+ * @brief Implementation of the native methods in the Java class StateReporter
+ */
+
+#include "../include/org_apache_subversion_javahl_remote_StateReporter.h"
+
+#include <jni.h>
+#include "JNIStackElement.h"
+#include "JNIUtil.h"
+#include "StateReporter.h"
+
+#include "svn_private_config.h"
+
+JNIEXPORT void JNICALL
+Java_org_apache_subversion_javahl_remote_StateReporter_finalize(
+ JNIEnv *env, jobject jthis)
+{
+ JNIEntry(StateReporter, finalize);
+ StateReporter *reporter = StateReporter::getCppObject(jthis);
+ if (reporter != NULL)
+ reporter->finalize();
+}
+
+JNIEXPORT void JNICALL
+Java_org_apache_subversion_javahl_remote_StateReporter_nativeDispose(
+ JNIEnv* env, jobject jthis)
+{
+ JNIEntry(StateReporter, nativeCreateInstance);
+ StateReporter* reporter = StateReporter::getCppObject(jthis);
+ CPPADDR_NULL_PTR(reporter,);
+ reporter->dispose(jthis);
+}
+
+JNIEXPORT void JNICALL
+Java_org_apache_subversion_javahl_remote_StateReporter_setPath(
+ JNIEnv* env, jobject jthis,
+ jstring jpath, jlong jrevision, jobject jdepth,
+ jboolean jstart_empty, jstring jlock_token)
+{
+ JNIEntry(StateReporter, setPath);
+ StateReporter* reporter = StateReporter::getCppObject(jthis);
+ CPPADDR_NULL_PTR(reporter,);
+ reporter->setPath(jpath, jrevision, jdepth, jstart_empty, jlock_token);
+}
+
+JNIEXPORT void JNICALL
+Java_org_apache_subversion_javahl_remote_StateReporter_deletePath(
+ JNIEnv* env, jobject jthis, jstring jpath)
+{
+ JNIEntry(StateReporter, deletePath);
+ StateReporter* reporter = StateReporter::getCppObject(jthis);
+ CPPADDR_NULL_PTR(reporter,);
+ reporter->deletePath(jpath);
+}
+
+JNIEXPORT void JNICALL
+Java_org_apache_subversion_javahl_remote_StateReporter_linkPath(
+ JNIEnv* env, jobject jthis,
+ jstring jurl, jstring jpath, jlong jrevision, jobject jdepth,
+ jboolean jstart_empty, jstring jlock_token)
+{
+ JNIEntry(StateReporter, linkPath);
+ StateReporter* reporter = StateReporter::getCppObject(jthis);
+ CPPADDR_NULL_PTR(reporter,);
+ reporter->linkPath(jurl, jpath, jrevision, jdepth, jstart_empty, jlock_token);
+}
+
+JNIEXPORT void JNICALL
+Java_org_apache_subversion_javahl_remote_StateReporter_finishReport(
+ JNIEnv* env, jobject jthis)
+{
+ JNIEntry(StateReporter, finishReport);
+ StateReporter* reporter = StateReporter::getCppObject(jthis);
+ CPPADDR_NULL_PTR(reporter,);
+ reporter->finishReport();
+}
+
+JNIEXPORT void JNICALL
+Java_org_apache_subversion_javahl_remote_StateReporter_abortReport(
+ JNIEnv* env, jobject jthis)
+{
+ JNIEntry(StateReporter, abortReport);
+ StateReporter* reporter = StateReporter::getCppObject(jthis);
+ CPPADDR_NULL_PTR(reporter,);
+ reporter->abortReport();
+}
+
+JNIEXPORT jlong JNICALL
+Java_org_apache_subversion_javahl_remote_StateReporter_nativeCreateInstance(
+ JNIEnv* env, jclass clazz)
+{
+ jobject jthis = NULL;
+ JNIEntry(StateReporter, nativeCreateInstance);
+ return reinterpret_cast<jlong>(new StateReporter);
+}
Modified: subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRemote.java
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRemote.java?rev=1499036&r1=1499035&r2=1499036&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRemote.java (original)
+++ subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNRemote.java Tue Jul 2 17:45:50 2013
@@ -289,8 +289,8 @@ public interface ISVNRemote
* 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 client begins by providing a <code>receiver</code> to
+ * the remote session; this object must contain knowledge of where
* the change will begin in the working copy.
* <p>
* In return, the client receives an {@link ISVNReporter}
@@ -298,14 +298,12 @@ public interface ISVNRemote
* 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.
+ * This results in <code>receiver</code> being called once for
+ * every path in the working copy that is different from the
+ * repository. <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
@@ -317,8 +315,8 @@ public interface ISVNRemote
* <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>.
+ * using this session from within the implementation of
+ * <code>receiver</code>.
* <p>
* <b>Note:</b> The reporter provided by this function does
* <em>not</em> supply copy-from information to the editor
@@ -332,7 +330,7 @@ public interface ISVNRemote
*/
ISVNReporter status(String statusTarget,
long revision, Depth depth,
- ISVNEditor statusEditor)
+ RemoteStatus receiver)
throws ClientException;
// TODO: diff
Added: subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/RemoteStatus.java
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/RemoteStatus.java?rev=1499036&view=auto
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/RemoteStatus.java (added)
+++ subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/callback/RemoteStatus.java Tue Jul 2 17:45:50 2013
@@ -0,0 +1,92 @@
+/**
+ * @copyright
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ * @endcopyright
+ */
+
+package org.apache.subversion.javahl.callback;
+
+import org.apache.subversion.javahl.ISVNRemote;
+
+/**
+ * Called for each affected element in a remote status driave.
+ * <p>
+ * <b>Note:</b> All paths sent to the callback methods are relative to
+ * the {@link ISVNRemtoe} session's URL.
+ * @see ISVNRemote#status
+ * @since 1.9
+ */
+public interface RemoteStatus
+{
+ /**
+ * A directory was added.
+ * @param relativePath The session-relative path of the new directory.
+ */
+ void addedDirectory(String relativePath);
+
+ /**
+ * A file was added.
+ * @param relativePath The session-relative path of the new file.
+ */
+ void addedFile(String relativePath);
+
+ /**
+ * A symbolic link was added.
+ * @param relativePath The session-relative path of the new symbolic link.
+ */
+ void addedSymlink(String relativePath);
+
+ /**
+ * A directory was modified.
+ * @param relativePath The session-relative path of the directory.
+ * @param revision The revision in which it was last modified.
+ * @param childrenModified The directory contents changed.
+ * @param propsModified The directory's properties changed.
+ */
+ void modifiedDirectory(String relativePath, long revision,
+ boolean childrenModified, boolean propsModified);
+
+ /**
+ * A file was modified.
+ * @param relativePath The session-relative path of the directory.
+ * @param revision The revision in which it was last modified.
+ * @param textModified The file contents changed.
+ * @param propsModified The file's properties changed.
+ */
+ void modifiedFile(String relativePath, long revision,
+ boolean textModified, boolean propsModified);
+
+ /**
+ * A symbolic link was modified.
+ * @param relativePath The session-relative path of the symlink.
+ * @param revision The revision in which it was last modified.
+ * @param textModified The link target changed.
+ * @param propsModified The symlink's properties changed.
+ */
+ void modifiedSymlink(String relativePath, long revision,
+ boolean targetModified, boolean propsModified);
+
+ /**
+ * An entry was deleted.
+ * @param relativePath The session-relative path of the entry.
+ * @param revision The revision in which it was deleted.
+ */
+ void deleted(String relativePath, long revision);
+}
Modified: subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/RemoteSession.java
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/RemoteSession.java?rev=1499036&r1=1499035&r2=1499036&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/RemoteSession.java (original)
+++ subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/RemoteSession.java Tue Jul 2 17:45:50 2013
@@ -163,10 +163,24 @@ public class RemoteSession extends JNIOb
// TODO: update
// TODO: switch
- public native ISVNReporter status(String statusTarget,
- long revision, Depth depth,
- ISVNEditor statusEditor)
- throws ClientException;
+ public ISVNReporter status(String statusTarget,
+ long revision, Depth depth,
+ RemoteStatus receiver)
+ throws ClientException
+ {
+ check_inactive(editorReference, reporterReference);
+ StateReporter rp = StateReporter.createInstance(this);
+
+ // At this point, the reporter is not active/valid.
+ StatusEditor editor = new StatusEditor(receiver);
+ nativeStatus(statusTarget, revision, depth, editor, rp);
+ // Now it should be valid.
+
+ if (reporterReference != null)
+ reporterReference.clear();
+ reporterReference = new WeakReference<ISVNReporter>(rp);
+ return rp;
+ }
// TODO: diff
@@ -227,12 +241,16 @@ public class RemoteSession extends JNIOb
OutputStream contents,
Map<String, byte[]> properties)
throws ClientException;
-
private native long nativeGetDirectory(long revision, String path,
int direntFields,
Map<String, DirEntry> dirents,
Map<String, byte[]> properties)
throws ClientException;
+ private native void nativeStatus(String statusTarget,
+ long revision, Depth depth,
+ ISVNEditor statusEditor,
+ ISVNReporter reporter)
+ throws ClientException;
private native boolean nativeHasCapability(String capability)
throws ClientException;
Copied: subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/StateReporter.java (from r1499024, subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/UpdateReporter.java)
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/StateReporter.java?p2=subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/StateReporter.java&p1=subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/UpdateReporter.java&r1=1499024&r2=1499036&rev=1499036&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/UpdateReporter.java (original)
+++ subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/StateReporter.java Tue Jul 2 17:45:50 2013
@@ -34,7 +34,7 @@ import org.apache.subversion.javahl.Clie
* Implementation of ISVNReporter.
* @since 1.9
*/
-public class UpdateReporter extends JNIObject implements ISVNReporter
+public class StateReporter extends JNIObject implements ISVNReporter
{
public void dispose()
{
@@ -42,51 +42,52 @@ public class UpdateReporter extends JNIO
nativeDispose();
}
- public void setPath(String path,
- long revision,
- Depth depth,
- boolean startEmpty,
- String lockToken)
- throws ClientException
- {
- throw new RuntimeException("Not implemented: setPath");
- }
+ public native void setPath(String path,
+ long revision,
+ Depth depth,
+ boolean startEmpty,
+ String lockToken)
+ throws ClientException;
+
+ public native void deletePath(String path) throws ClientException;
+
+ public native void linkPath(String url,
+ String path,
+ long revision,
+ Depth depth,
+ boolean startEmpty,
+ String lockToken)
+ throws ClientException;
- public void deletePath(String path) throws ClientException
- {
- throw new RuntimeException("Not implemented: deletePath");
- }
+ public native void finishReport() throws ClientException;
- public void linkPath(String url,
- String path,
- long revision,
- Depth depth,
- boolean startEmpty,
- String lockToken)
- throws ClientException
- {
- throw new RuntimeException("Not implemented: linkPath");
- }
+ public native void abortReport() throws ClientException;
- public void finishReport() throws ClientException
+ /**
+ * This factory method called from RemoteSession.status and friends.
+ */
+ static final
+ StateReporter createInstance(RemoteSession session)
+ throws ClientException
{
- throw new RuntimeException("Not implemented: finishReport");
+ long cppAddr = nativeCreateInstance();
+ return new StateReporter(cppAddr, session);
}
- public void abortReport() throws ClientException
- {
- throw new RuntimeException("Not implemented: abortReport");
- }
+ @Override
+ public native void finalize() throws Throwable;
/*
* Wrapped private native implementation declarations.
*/
- private /*TODO:native*/ void nativeDispose() {;}
+ private native void nativeDispose();
+ private static final native long nativeCreateInstance()
+ throws ClientException;
/**
- * This constructor is called from the factory to get an instance.
+ * This constructor is called from the factory method.
*/
- protected UpdateReporter(long cppAddr, RemoteSession session)
+ protected StateReporter(long cppAddr, RemoteSession session)
{
super(cppAddr);
this.session = session;
Added: subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/StatusEditor.java
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/StatusEditor.java?rev=1499036&view=auto
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/StatusEditor.java (added)
+++ subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/remote/StatusEditor.java Tue Jul 2 17:45:50 2013
@@ -0,0 +1,189 @@
+/**
+ * @copyright
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ * @endcopyright
+ */
+
+package org.apache.subversion.javahl.remote;
+
+import org.apache.subversion.javahl.types.*;
+import org.apache.subversion.javahl.callback.*;
+
+import org.apache.subversion.javahl.ISVNEditor;
+
+import java.util.Map;
+import java.io.InputStream;
+
+/**
+ * Package-private editor implementation that converts an editor drive
+ * to {@link RemoteStatus} callbacks.
+ * @since 1.9
+ */
+class StatusEditor implements ISVNEditor
+{
+ StatusEditor(RemoteStatus receiver)
+ {
+ this.receiver = receiver;
+ }
+ protected RemoteStatus receiver = null;
+
+ protected void checkState()
+ {
+ if (receiver == null)
+ throw new IllegalStateException("Status editor is not active");
+ }
+
+ public void dispose()
+ {
+ //DEBUG:System.err.println(" [J] StatusEditor.dispose");
+ if (this.receiver != null)
+ abort();
+ }
+
+ public void addDirectory(String relativePath,
+ Iterable<String> children,
+ Map<String, byte[]> properties,
+ long replacesRevision)
+ {
+ //DEBUG:System.err.println(" [J] StatusEditor.addDirectory");
+ checkState();
+ receiver.addedDirectory(relativePath);
+ }
+
+ public void addFile(String relativePath,
+ Checksum checksum,
+ InputStream contents,
+ Map<String, byte[]> properties,
+ long replacesRevision)
+ {
+ //DEBUG:System.err.println(" [J] StatusEditor.addFile");
+ checkState();
+ receiver.addedFile(relativePath);
+ }
+
+ public void addSymlink(String relativePath,
+ String target,
+ Map<String, byte[]> properties,
+ long replacesRevision)
+ {
+ //DEBUG:System.err.println(" [J] StatusEditor.addSymlink");
+ checkState();
+ receiver.addedSymlink(relativePath);
+ }
+
+ public void addAbsent(String relativePath,
+ NodeKind kind,
+ long replacesRevision)
+ {
+ //DEBUG:System.err.println(" [J] StatusEditor.addAbsent");
+ checkState();
+ throw new RuntimeException("Not implemented: StatusEditor.addAbsent");
+ }
+
+ public void alterDirectory(String relativePath,
+ long revision,
+ Iterable<String> children,
+ Map<String, byte[]> properties)
+ {
+ //DEBUG:System.err.println(" [J] StatusEditor.alterDirectory");
+ checkState();
+ receiver.modifiedDirectory(relativePath, revision, (children != null),
+ props_changed(properties));
+ }
+
+ public void alterFile(String relativePath,
+ long revision,
+ Checksum checksum,
+ InputStream contents,
+ Map<String, byte[]> properties)
+ {
+ //DEBUG:System.err.println(" [J] StatusEditor.alterFile");
+ checkState();
+ receiver.modifiedFile(relativePath, revision,
+ (checksum != null && contents != null),
+ props_changed(properties));
+ }
+
+ public void alterSymlink(String relativePath,
+ long revision,
+ String target,
+ Map<String, byte[]> properties)
+ {
+ //DEBUG:System.err.println(" [J] StatusEditor.alterSymlink");
+ checkState();
+ receiver.modifiedSymlink(relativePath, revision, (target != null),
+ props_changed(properties));
+ }
+
+ public void delete(String relativePath, long revision)
+ {
+ //DEBUG:System.err.println(" [J] StatusEditor.delete");
+ checkState();
+ receiver.deleted(relativePath, revision);
+ }
+
+ public void copy(String sourceRelativePath,
+ long sourceRevision,
+ String destinationRelativePath,
+ long replacesRevision)
+ {
+ //DEBUG:System.err.println(" [J] StatusEditor.copy");
+ checkState();
+ throw new RuntimeException("Not implemented: StatusEditor.copy");
+ }
+
+ public void move(String sourceRelativePath,
+ long sourceRevision,
+ String destinationRelativePath,
+ long replacesRevision)
+ {
+ //DEBUG:System.err.println(" [J] StatusEditor.move");
+ checkState();
+ throw new RuntimeException("Not implemented: StatusEditor.move");
+ }
+
+ public void complete()
+ {
+ //DEBUG:System.err.println(" [J] StatusEditor.complete");
+ abort();
+ }
+
+ public void abort()
+ {
+ //DEBUG:System.err.println(" [J] StatusEditor.abort");
+ checkState();
+ receiver = null;
+ }
+
+ /*
+ * Filter entry props from the incoming properties
+ */
+ private static final String wcprop_prefix = "svn:wc:";
+ private static final String entryprop_prefix = "svn:entry:";
+ private static final boolean props_changed(Map<String, byte[]> properties)
+ {
+ if (properties != null)
+ for (String name : properties.keySet())
+ if (!name.startsWith(wcprop_prefix)
+ && !name.startsWith(entryprop_prefix))
+ return true;
+ return false;
+ }
+}
Modified: subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java?rev=1499036&r1=1499035&r2=1499036&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java (original)
+++ subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/SVNRemoteTests.java Tue Jul 2 17:45:50 2013
@@ -659,7 +659,7 @@ public class SVNRemoteTests extends SVNT
try {
exmsg = "";
cc.editor.addSymlink("", "", props, 1);
- } catch (IllegalStateException ex) {
+ } catch (RuntimeException ex) {
exmsg = ex.getMessage();
}
assertEquals("Not implemented: CommitEditor.addSymlink", exmsg);
@@ -667,7 +667,7 @@ public class SVNRemoteTests extends SVNT
try {
exmsg = "";
cc.editor.alterSymlink("", 1, "", null);
- } catch (IllegalStateException ex) {
+ } catch (RuntimeException ex) {
exmsg = ex.getMessage();
}
assertEquals("Not implemented: CommitEditor.alterSymlink", exmsg);
@@ -675,10 +675,10 @@ public class SVNRemoteTests extends SVNT
// try {
// exmsg = "";
// cc.editor.rotate(rotation);
- // } catch (IllegalStateException ex) {
+ // } catch (RuntimeException ex) {
// exmsg = ex.getMessage();
// }
- assertEquals("Not implemented: CommitEditor.rotate", exmsg);
+ // assertEquals("Not implemented: CommitEditor.rotate", exmsg);
} finally {
cc.editor.dispose();
}
@@ -783,4 +783,124 @@ public class SVNRemoteTests extends SVNT
handler);
session.getLatestRevision(); // Make sure the configuration gets loaded
}
+
+ private static class RemoteStatusReceiver implements RemoteStatus
+ {
+ static class StatInfo
+ {
+ public String relpath = null;
+ public char kind = ' '; // F, D, L
+ public boolean textChanged = false;
+ public boolean propsChanged = false;
+ public boolean deleted = false;
+ public long revision = -1;
+
+ StatInfo(String relpath, char kind, boolean added)
+ {
+ this.relpath = relpath;
+ this.kind = kind;
+ this.deleted = !added;
+ }
+
+ StatInfo(String relpath, char kind, long revision,
+ boolean textChanged, boolean propsChanged)
+ {
+ this.relpath = relpath;
+ this.kind = kind;
+ this.textChanged = textChanged;
+ this.propsChanged = propsChanged;
+ this.revision = revision;
+ }
+ }
+
+ public ArrayList<StatInfo> status = new ArrayList<StatInfo>();
+
+ public void addedDirectory(String relativePath)
+ {
+ status.add(new StatInfo(relativePath, 'D', true));
+ }
+
+ public void addedFile(String relativePath)
+ {
+ status.add(new StatInfo(relativePath, 'F', true));
+ }
+
+ public void addedSymlink(String relativePath)
+ {
+ status.add(new StatInfo(relativePath, 'L', true));
+ }
+
+ public void modifiedDirectory(String relativePath, long revision,
+ boolean childrenModified, boolean propsModified)
+ {
+ status.add(new StatInfo(relativePath, 'D', revision,
+ childrenModified, propsModified));
+ }
+
+ public void modifiedFile(String relativePath, long revision,
+ boolean textModified, boolean propsModified)
+ {
+ status.add(new StatInfo(relativePath, 'F', revision,
+ textModified, propsModified));
+ }
+
+ public void modifiedSymlink(String relativePath, long revision,
+ boolean targetModified, boolean propsModified)
+ {
+ status.add(new StatInfo(relativePath, 'L', revision,
+ targetModified, propsModified));
+ }
+
+ public void deleted(String relativePath, long revision)
+ {
+ status.add(new StatInfo(relativePath, ' ', false));
+ }
+ }
+
+ public void testSimpleStatus() throws Exception
+ {
+ ISVNRemote session = getSession();
+
+ RemoteStatusReceiver receiver = new RemoteStatusReceiver();
+ ISVNReporter rp = session.status(null, Revision.SVN_INVALID_REVNUM,
+ Depth.infinity, receiver);
+ try {
+ rp.setPath("", 0, Depth.infinity, true, null);
+ rp.finishReport();
+ } finally {
+ rp.dispose();
+ }
+ assertEquals(21, receiver.status.size());
+ }
+
+ public void testPropchangeStatus() throws Exception
+ {
+ ISVNRemote session = getSession();
+
+ CommitMessageCallback cmcb = new CommitMessageCallback() {
+ public String getLogMessage(Set<CommitItem> x) {
+ return "Property change on A/D/gamma";
+ }
+ };
+ client.propertySetRemote(getTestRepoUrl() + "/A/D/gamma",
+ 1L, "foo", "bar".getBytes(), cmcb,
+ false, null, null);
+
+ RemoteStatusReceiver receiver = new RemoteStatusReceiver();
+ ISVNReporter rp = session.status(null, Revision.SVN_INVALID_REVNUM,
+ Depth.infinity, receiver);
+ try {
+ rp.setPath("", 1, Depth.infinity, false, null);
+ rp.finishReport();
+ } finally {
+ rp.dispose();
+ }
+ assertEquals(4, receiver.status.size());
+ RemoteStatusReceiver.StatInfo mod = receiver.status.get(3);
+ assertEquals("A/D/gamma", mod.relpath);
+ assertEquals('F', mod.kind);
+ assertEquals(false, mod.textChanged);
+ assertEquals(true, mod.propsChanged);
+ assertEquals(1, mod.revision);
+ }
}