Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/EditorProxy.h URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/EditorProxy.h?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/EditorProxy.h (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/EditorProxy.h Sun Jun 14 20:58:10 2015 @@ -27,6 +27,8 @@ #ifndef JAVAHL_EDITOR_PROXY_H #define JAVAHL_EDITOR_PROXY_H +#include <memory> + #include "svn_delta.h" #include "private/svn_editor.h" #include "private/svn_delta_private.h" @@ -51,6 +53,8 @@ struct EditorProxyCallbacks class EditorProxy { public: + typedef std::auto_ptr<EditorProxy> UniquePtr; + 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, @@ -142,7 +146,7 @@ private: 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;
Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/EnumMapper.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/EnumMapper.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/EnumMapper.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/EnumMapper.cpp Sun Jun 14 20:58:10 2015 @@ -37,13 +37,13 @@ jobject EnumMapper::mapChangePathAction( switch (action) { case 'A': - return mapEnum(JAVA_PACKAGE"/types/ChangePath$Action", 0); + return mapEnum(JAVAHL_CLASS("/types/ChangePath$Action"), 0); case 'D': - return mapEnum(JAVA_PACKAGE"/types/ChangePath$Action", 1); + return mapEnum(JAVAHL_CLASS("/types/ChangePath$Action"), 1); case 'R': - return mapEnum(JAVA_PACKAGE"/types/ChangePath$Action", 2); + return mapEnum(JAVAHL_CLASS("/types/ChangePath$Action"), 2); case 'M': - return mapEnum(JAVA_PACKAGE"/types/ChangePath$Action", 3); + return mapEnum(JAVAHL_CLASS("/types/ChangePath$Action"), 3); default: return NULL; } @@ -55,7 +55,7 @@ jobject EnumMapper::mapChangePathAction( jobject EnumMapper::mapNotifyState(svn_wc_notify_state_t state) { // We're assuming a valid value for the C enum above - return mapEnum(JAVA_PACKAGE"/ClientNotifyInformation$Status", + return mapEnum(JAVAHL_CLASS("/ClientNotifyInformation$Status"), static_cast<int>(state)); } @@ -65,14 +65,14 @@ jobject EnumMapper::mapNotifyState(svn_w jobject EnumMapper::mapNotifyAction(svn_wc_notify_action_t action) { // We're assuming a valid value for the C enum above - return mapEnum(JAVA_PACKAGE"/ClientNotifyInformation$Action", + return mapEnum(JAVAHL_CLASS("/ClientNotifyInformation$Action"), static_cast<int>(action)); } jobject EnumMapper::mapReposNotifyNodeAction(svn_node_action action) { // We're assuming a valid value for the C enum above - return mapEnum(JAVA_PACKAGE"/ReposNotifyInformation$NodeAction", + return mapEnum(JAVAHL_CLASS("/ReposNotifyInformation$NodeAction"), static_cast<int>(action)); } @@ -82,7 +82,7 @@ jobject EnumMapper::mapReposNotifyNodeAc jobject EnumMapper::mapReposNotifyAction(svn_repos_notify_action_t action) { // We're assuming a valid value for the C enum above - return mapEnum(JAVA_PACKAGE"/ReposNotifyInformation$Action", + return mapEnum(JAVAHL_CLASS("/ReposNotifyInformation$Action"), static_cast<int>(action)); } @@ -92,7 +92,7 @@ jobject EnumMapper::mapReposNotifyAction jobject EnumMapper::mapNodeKind(svn_node_kind_t nodeKind) { // We're assuming a valid value for the C enum above - return mapEnum(JAVA_PACKAGE"/types/NodeKind", + return mapEnum(JAVAHL_CLASS("/types/NodeKind"), static_cast<int>(nodeKind)); } @@ -102,7 +102,7 @@ jobject EnumMapper::mapNodeKind(svn_node jobject EnumMapper::mapNotifyLockState(svn_wc_notify_lock_state_t state) { // We're assuming a valid value for the C enum above - return mapEnum(JAVA_PACKAGE"/ClientNotifyInformation$LockStatus", + return mapEnum(JAVAHL_CLASS("/ClientNotifyInformation$LockStatus"), static_cast<int>(state)); } @@ -112,7 +112,7 @@ jobject EnumMapper::mapNotifyLockState(s jobject EnumMapper::mapScheduleKind(svn_wc_schedule_t schedule) { // We're assuming a valid value for the C enum above - return mapEnum(JAVA_PACKAGE"/types/Info$ScheduleKind", + return mapEnum(JAVAHL_CLASS("/types/Info$ScheduleKind"), static_cast<int>(schedule)); } @@ -123,63 +123,63 @@ jobject EnumMapper::mapStatusKind(svn_wc { // We're assuming a valid value for the C enum above // The offset here is +1 - return mapEnum(JAVA_PACKAGE"/types/Status$Kind", + return mapEnum(JAVAHL_CLASS("/types/Status$Kind"), static_cast<int>(svnKind) - 1); } jobject EnumMapper::mapChecksumKind(svn_checksum_kind_t kind) { // We're assuming a valid value for the C enum above - return mapEnum(JAVA_PACKAGE"/types/Checksum$Kind", + return mapEnum(JAVAHL_CLASS("/types/Checksum$Kind"), static_cast<int>(kind)); } jobject EnumMapper::mapConflictKind(svn_wc_conflict_kind_t kind) { // We're assuming a valid value for the C enum above - return mapEnum(JAVA_PACKAGE"/ConflictDescriptor$Kind", + return mapEnum(JAVAHL_CLASS("/ConflictDescriptor$Kind"), static_cast<int>(kind)); } jobject EnumMapper::mapConflictAction(svn_wc_conflict_action_t action) { // We're assuming a valid value for the C enum above - return mapEnum(JAVA_PACKAGE"/ConflictDescriptor$Action", + return mapEnum(JAVAHL_CLASS("/ConflictDescriptor$Action"), static_cast<int>(action)); } jobject EnumMapper::mapConflictReason(svn_wc_conflict_reason_t reason) { // We're assuming a valid value for the C enum above - return mapEnum(JAVA_PACKAGE"/ConflictDescriptor$Reason", + return mapEnum(JAVAHL_CLASS("/ConflictDescriptor$Reason"), static_cast<int>(reason)); } int EnumMapper::toMergeinfoLogKind(jobject jLogKind) { - return getOrdinal(JAVA_PACKAGE"/types/Mergeinfo$LogKind", jLogKind); + return getOrdinal(JAVAHL_CLASS("/types/Mergeinfo$LogKind"), jLogKind); } int EnumMapper::toLogLevel(jobject jLogLevel) { - return getOrdinal(JAVA_PACKAGE"/SVNClient$ClientLogLevel", jLogLevel); + return getOrdinal(JAVAHL_CLASS("/SVNClient$ClientLogLevel"), jLogLevel); } svn_node_kind_t EnumMapper::toNodeKind(jobject jNodeKind) { return svn_node_kind_t( - getOrdinal(JAVA_PACKAGE"/types/NodeKind", jNodeKind)); + getOrdinal(JAVAHL_CLASS("/types/NodeKind"), jNodeKind)); } svn_checksum_kind_t EnumMapper::toChecksumKind(jobject jChecksumKind) { return svn_checksum_kind_t( - getOrdinal(JAVA_PACKAGE"/types/Checksum$Kind", jChecksumKind)); + getOrdinal(JAVAHL_CLASS("/types/Checksum$Kind"), jChecksumKind)); } svn_tristate_t EnumMapper::toTristate(jobject jTristate) { - switch (getOrdinal(JAVA_PACKAGE"/types/Tristate", jTristate)) + switch (getOrdinal(JAVAHL_CLASS("/types/Tristate"), jTristate)) { case 1: return svn_tristate_false; case 2: return svn_tristate_true; @@ -190,14 +190,14 @@ svn_tristate_t EnumMapper::toTristate(jo svn_depth_t EnumMapper::toDepth(jobject jdepth) { // The offset for depths is -2 - return static_cast<svn_depth_t>(getOrdinal(JAVA_PACKAGE"/types/Depth", jdepth) - 2); + return static_cast<svn_depth_t>(getOrdinal(JAVAHL_CLASS("/types/Depth"), jdepth) - 2); } svn_mergeinfo_inheritance_t EnumMapper::toMergeinfoInheritance(jobject jInheritance) { return static_cast<svn_mergeinfo_inheritance_t>( - getOrdinal(JAVA_PACKAGE"/types/Mergeinfo$Inheritance", jInheritance)); + getOrdinal(JAVAHL_CLASS("/types/Mergeinfo$Inheritance"), jInheritance)); } @@ -205,39 +205,39 @@ jobject EnumMapper::mapDepth(svn_depth_t { // We're assuming a valid value for the C enum above // The offset for depths is -2 - return mapEnum(JAVA_PACKAGE"/types/Depth", static_cast<int>(depth) + 2); + return mapEnum(JAVAHL_CLASS("/types/Depth"), static_cast<int>(depth) + 2); } jobject EnumMapper::mapOperation(svn_wc_operation_t operation) { // We're assuming a valid value for the C enum above - return mapEnum(JAVA_PACKAGE"/ConflictDescriptor$Operation", + return mapEnum(JAVAHL_CLASS("/ConflictDescriptor$Operation"), static_cast<int>(operation)); } jobject EnumMapper::mapTristate(svn_tristate_t tristate) { // We're assuming a valid value for the C enum above - return mapEnum(JAVA_PACKAGE"/types/Tristate", + return mapEnum(JAVAHL_CLASS("/types/Tristate"), static_cast<int>(tristate - svn_tristate_false)); } svn_wc_conflict_choice_t EnumMapper::toConflictChoice(jobject jchoice) { return static_cast<svn_wc_conflict_choice_t> - (getOrdinal(JAVA_PACKAGE"/ConflictResult$Choice", jchoice)); + (getOrdinal(JAVAHL_CLASS("/ConflictResult$Choice"), jchoice)); } svn_opt_revision_kind EnumMapper::toRevisionKind(jobject jkind) { return static_cast<svn_opt_revision_kind> - (getOrdinal(JAVA_PACKAGE"/types/Revision$Kind", jkind)); + (getOrdinal(JAVAHL_CLASS("/types/Revision$Kind"), jkind)); } jobject EnumMapper::mapSummarizeKind(svn_client_diff_summarize_kind_t sKind) { // We're assuming a valid value for the C enum above - return mapEnum(JAVA_PACKAGE"/DiffSummary$DiffKind", + return mapEnum(JAVAHL_CLASS("/DiffSummary$DiffKind"), static_cast<int>(sKind)); } Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/ExternalItem.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/ExternalItem.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/ExternalItem.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/ExternalItem.cpp Sun Jun 14 20:58:10 2015 @@ -29,21 +29,22 @@ namespace JavaHL { const char* const ExternalItem::m_class_name = - JAVA_PACKAGE"/types/ExternalItem"; + JAVAHL_CLASS("/types/ExternalItem"); ExternalItem::ClassImpl::ClassImpl(::Java::Env env, jclass cls) : ::Java::Object::ClassImpl(env, cls), m_mid_ctor( env.GetMethodID(cls, "<init>", "(ZLjava/lang/String;Ljava/lang/String;" - "L"JAVA_PACKAGE"/types/Revision;" - "L"JAVA_PACKAGE"/types/Revision;)V")), + JAVAHL_ARG("/types/Revision;") + JAVAHL_ARG("/types/Revision;") + ")V")), m_fid_target_dir(env.GetFieldID(cls, "targetDir", "Ljava/lang/String;")), m_fid_url(env.GetFieldID(cls, "url", "Ljava/lang/String;")), m_fid_revision(env.GetFieldID(cls, "revision", - "L"JAVA_PACKAGE"/types/Revision;")), + JAVAHL_ARG("/types/Revision;"))), m_fid_peg_revision(env.GetFieldID(cls, "pegRevision", - "L"JAVA_PACKAGE"/types/Revision;")) + JAVAHL_ARG("/types/Revision;"))) {} ExternalItem::ClassImpl::~ClassImpl() {} @@ -131,7 +132,7 @@ inline jobject get_static_revision(::Jav { return env.GetStaticObjectField( cls, env.GetStaticFieldID(cls, field_name, - "L"JAVA_PACKAGE"/types/Revision;")); + JAVAHL_ARG("/types/Revision;"))); } } // anonymous namespace @@ -145,12 +146,12 @@ jobject Revision::makeJRevision(const sv if (rev.kind == svn_opt_revision_date) { const jclass cls = env.FindClass( - JAVA_PACKAGE"/types/Revision$DateSpec"); + JAVAHL_CLASS("/types/Revision$DateSpec")); return env.NewObject(cls, env.GetMethodID(cls, "<init>", "(J)V"), jlong(rev.value.date / 1000)); } - const jclass cls = env.FindClass(JAVA_PACKAGE"/types/Revision"); + const jclass cls = env.FindClass(JAVAHL_CLASS("/types/Revision")); switch (rev.kind) { case svn_opt_revision_committed: Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/ImportFilterCallback.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/ImportFilterCallback.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/ImportFilterCallback.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/ImportFilterCallback.cpp Sun Jun 14 20:58:10 2015 @@ -83,13 +83,14 @@ ImportFilterCallback::doImportFilter(svn static jmethodID mid = 0; if (mid == 0) { - jclass clazz = env->FindClass(JAVA_PACKAGE"/callback/ImportFilterCallback"); + jclass clazz = env->FindClass(JAVAHL_CLASS("/callback/ImportFilterCallback")); if (JNIUtil::isJavaExceptionThrown()) POP_AND_RETURN(SVN_NO_ERROR); mid = env->GetMethodID(clazz, "filter", "(Ljava/lang/String;" - "L"JAVA_PACKAGE"/types/NodeKind;Z)Z"); + JAVAHL_ARG("/types/NodeKind;") + "Z)Z"); if (JNIUtil::isJavaExceptionThrown() || mid == 0) POP_AND_RETURN(SVN_NO_ERROR); } Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/InfoCallback.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/InfoCallback.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/InfoCallback.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/InfoCallback.cpp Sun Jun 14 20:58:10 2015 @@ -80,12 +80,12 @@ InfoCallback::singleInfo(const char *pat static jmethodID mid = 0; if (mid == 0) { - jclass clazz = env->FindClass(JAVA_PACKAGE"/callback/InfoCallback"); + jclass clazz = env->FindClass(JAVAHL_CLASS("/callback/InfoCallback")); if (JNIUtil::isJavaExceptionThrown()) POP_AND_RETURN(SVN_NO_ERROR); mid = env->GetMethodID(clazz, "singleInfo", - "(L"JAVA_PACKAGE"/types/Info;)V"); + "(" JAVAHL_ARG("/types/Info;") ")V"); if (JNIUtil::isJavaExceptionThrown() || mid == 0) POP_AND_RETURN(SVN_NO_ERROR); } @@ -95,8 +95,6 @@ InfoCallback::singleInfo(const char *pat POP_AND_RETURN(SVN_NO_ERROR); env->CallVoidMethod(m_callback, mid, jinfo2); - // Return SVN_NO_ERROR here regardless of an exception or not. - env->PopLocalFrame(NULL); - return SVN_NO_ERROR; + POP_AND_RETURN_EXCEPTION_AS_SVNERROR(); } Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/Iterator.h URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/Iterator.h?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/Iterator.h (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/Iterator.h Sun Jun 14 20:58:10 2015 @@ -20,7 +20,7 @@ * ==================================================================== * @endcopyright * - * @file Iterator.cpp + * @file Iterator.h * @brief Interface of the class Iterator */ Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/JNIUtil.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/JNIUtil.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/JNIUtil.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/JNIUtil.cpp Sun Jun 14 20:58:10 2015 @@ -77,6 +77,11 @@ bool JNIUtil::g_initException; int JNIUtil::g_logLevel = JNIUtil::noLog; std::ofstream JNIUtil::g_logStream; +/* The error code we will use to signal a Java exception */ +static const apr_status_t +SVN_ERR_JAVAHL_WRAPPED = SVN_ERR_MALFUNC_CATEGORY_START + + SVN_ERR_CATEGORY_SIZE - 10; + /** * Return the JNI environment to use * @return the JNI environment @@ -446,7 +451,8 @@ ErrorMessageStack assemble_error_message { /* When we're recursing, don't repeat the top-level message if its * the same as before. */ - if (depth == 0 || err->apr_err != parent_apr_err) + if ((depth == 0 || err->apr_err != parent_apr_err) + && err->apr_err != SVN_ERR_JAVAHL_WRAPPED) { const char *message; /* Is this a Subversion-specific error code? */ @@ -511,7 +517,7 @@ jobject construct_Jmessage_stack(const E if (JNIUtil::isJavaExceptionThrown()) POP_AND_RETURN_NULL; - jclass clazz = env->FindClass(JAVA_PACKAGE"/ClientException$ErrorMessage"); + jclass clazz = env->FindClass(JAVAHL_CLASS("/ClientException$ErrorMessage")); if (JNIUtil::isJavaExceptionThrown()) POP_AND_RETURN_NULL; mid = env->GetMethodID(clazz, "<init>", @@ -586,6 +592,9 @@ void JNIUtil::wrappedHandleSVNError(svn_ #endif #endif + if (!jcause) + jcause = JNIUtil::unwrapJavaException(err); + // Much of the following is stolen from throwNativeException(). As much as // we'd like to call that function, we need to do some manual stack // unrolling, so it isn't feasible. @@ -597,7 +606,7 @@ void JNIUtil::wrappedHandleSVNError(svn_ if (JNIUtil::isJavaExceptionThrown()) return; - jclass clazz = env->FindClass(JAVA_PACKAGE "/ClientException"); + jclass clazz = env->FindClass(JAVAHL_CLASS("/ClientException")); if (isJavaExceptionThrown()) POP_AND_RETURN_NOTHING(); @@ -804,6 +813,25 @@ JNIUtil::checkJavaException(apr_status_t err->message = apr_psprintf(err->pool, _("Java exception: %s"), msg); else err->message = _("Java exception"); + + + /* ### TODO: Use apr_pool_userdata_set() on the pool we just created + for the error chain to keep track of the actual Java + exception while the error is inside Subversion. + + Once the error chain re-enters JavaHL we can check + if there is a true exception that we can add to the chain. + + If the error is cleared in Subversion (which may happen + during composing error chains, etc.) the cleanup handler + handles properly releasing the exception. + + apr_status_t + apr_pool_userdata_set(const void *data, + const char *key, + apr_status_t (*cleanup)(void *), + apr_pool_t *pool) + */ return err; } @@ -1043,3 +1071,91 @@ svn_error_t *JNIUtil::preprocessPath(con return NULL; } + +/* Tag to use on the apr_pool_t to store a WrappedException reference */ +static const char *WrapExceptionTag = "org.apache.subversion.JavaHL.svnerror"; + +class WrappedException +{ + JNIEnv *m_env; + jthrowable m_exception; +#ifdef SVN_DEBUG + bool m_fetched; +#endif +public: + WrappedException(JNIEnv *env) + { + m_env = env; + + // Fetch exception inside local frame + jthrowable exceptionObj = env->ExceptionOccurred(); + + // Now clear exception status + env->ExceptionClear(); + + // As adding a reference in exception state fails + m_exception = static_cast<jthrowable>(env->NewGlobalRef(exceptionObj)); + +#ifdef SVN_DEBUG + m_fetched = false; +#endif + } + + static jthrowable get_exception(apr_pool_t *pool) + { + void *data; + if (! apr_pool_userdata_get(&data, WrapExceptionTag, pool)) + { + WrappedException *we = reinterpret_cast<WrappedException *>(data); + + if (we) + { +#ifdef SVN_DEBUG + we->m_fetched = TRUE; +#endif + // Create reference in local frame, as the pool will be cleared + return static_cast<jthrowable>( + we->m_env->NewLocalRef(we->m_exception)); + } + } + return NULL; + } + +private: + ~WrappedException() + { +#ifdef SVN_DEBUG + if (!m_fetched) + SVN_DBG(("Cleared svn_error_t * before Java exception was fetched")); +#endif + m_env->DeleteGlobalRef(m_exception); + } +public: + static apr_status_t cleanup(void *data) + { + WrappedException *we = reinterpret_cast<WrappedException *>(data); + + delete we; + return APR_SUCCESS; + } +}; + +svn_error_t* JNIUtil::wrapJavaException() +{ + if (!isExceptionThrown()) + return SVN_NO_ERROR; + + svn_error_t *err = svn_error_create(SVN_ERR_JAVAHL_WRAPPED, NULL, + "Wrapped Java Exception"); + apr_pool_userdata_set(new WrappedException(getEnv()), WrapExceptionTag, + WrappedException::cleanup, err->pool); + return err; +} + +jthrowable JNIUtil::unwrapJavaException(const svn_error_t *err) +{ + if (!err) + return NULL; + return + WrappedException::get_exception(err->pool); +} Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/JNIUtil.h URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/JNIUtil.h?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/JNIUtil.h (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/JNIUtil.h Sun Jun 14 20:58:10 2015 @@ -38,13 +38,28 @@ class SVNBase; #include <apr_time.h> #include <string> #include <vector> + struct svn_error_t; +struct svn_string_t; #include "svn_error.h" -#define JAVA_PACKAGE "org/apache/subversion/javahl" -struct svn_string_t; +/** + * The name of the package in which the JavaHL classes are defined. + */ +#define JAVAHL_PACKAGE "org/apache/subversion/javahl" + +/** + * Construct a JavaHL class name for JNIEnv::FindClass. + */ +#define JAVAHL_CLASS(name) JAVAHL_PACKAGE name + +/** + * Construct a JavaHL class parameter name for JNIEnv::GetMethodID & co. + */ +#define JAVAHL_ARG(name) "L" JAVAHL_PACKAGE name + /** * Class to hold a number of JNI related utility methods. No Objects @@ -86,6 +101,9 @@ class JNIUtil return getEnv()->ExceptionCheck(); } + static svn_error_t *wrapJavaException(); + static jthrowable unwrapJavaException(const svn_error_t *err); + static void handleAPRError(int error, const char *op); /** @@ -143,7 +161,7 @@ class JNIUtil */ static void throwError(const char *message) { - raiseThrowable(JAVA_PACKAGE"/JNIError", message); + raiseThrowable(JAVAHL_CLASS("/JNIError"), message); } static apr_pool_t *getPool(); @@ -265,6 +283,16 @@ class JNIUtil } \ while (0) +#define POP_AND_RETURN_EXCEPTION_AS_SVNERROR() \ + do \ + { \ + svn_error_t *svn__err_for_exception = JNIUtil::wrapJavaException(); \ + \ + env->PopLocalFrame(NULL); \ + return svn__err_for_exception; \ + } \ + while (0) + /** * A useful macro. Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/ListCallback.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/ListCallback.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/ListCallback.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/ListCallback.cpp Sun Jun 14 20:58:10 2015 @@ -87,13 +87,13 @@ ListCallback::doList(const char *path, static jmethodID mid = 0; if (mid == 0) { - jclass clazz = env->FindClass(JAVA_PACKAGE"/callback/ListCallback"); + jclass clazz = env->FindClass(JAVAHL_CLASS("/callback/ListCallback")); if (JNIUtil::isJavaExceptionThrown()) POP_AND_RETURN(SVN_NO_ERROR); mid = env->GetMethodID(clazz, "doEntry", - "(L"JAVA_PACKAGE"/types/DirEntry;" - "L"JAVA_PACKAGE"/types/Lock;)V"); + "(" JAVAHL_ARG("/types/DirEntry;") + JAVAHL_ARG("/types/Lock;") ")V"); if (JNIUtil::isJavaExceptionThrown() || mid == 0) POP_AND_RETURN(SVN_NO_ERROR); } @@ -113,10 +113,8 @@ ListCallback::doList(const char *path, // call the Java method env->CallVoidMethod(m_callback, mid, jdirentry, jlock); - // No need to check for exception here, because we'll just return anyway - env->PopLocalFrame(NULL); - return SVN_NO_ERROR; + POP_AND_RETURN_EXCEPTION_AS_SVNERROR(); } /** Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/LockTokenTable.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/LockTokenTable.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/LockTokenTable.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/LockTokenTable.cpp Sun Jun 14 20:58:10 2015 @@ -64,7 +64,7 @@ LockTokenTable::LockTokenTable(jobject j { JNIEnv *env = JNIUtil::getEnv(); - jclass lock_cls = env->FindClass(JAVA_PACKAGE"/types/Lock"); + jclass lock_cls = env->FindClass(JAVAHL_CLASS("/types/Lock")); if (JNIUtil::isExceptionThrown()) return; Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/LogMessageCallback.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/LogMessageCallback.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/LogMessageCallback.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/LogMessageCallback.cpp Sun Jun 14 20:58:10 2015 @@ -81,7 +81,7 @@ LogMessageCallback::singleMessage(svn_lo static jmethodID sm_mid = 0; if (sm_mid == 0) { - jclass clazz = env->FindClass(JAVA_PACKAGE"/callback/LogMessageCallback"); + jclass clazz = env->FindClass(JAVAHL_CLASS("/callback/LogMessageCallback")); if (JNIUtil::isJavaExceptionThrown()) POP_AND_RETURN(SVN_NO_ERROR); @@ -125,8 +125,6 @@ LogMessageCallback::singleMessage(svn_lo (jlong)log_entry->revision, jrevprops, (jboolean)log_entry->has_children); - // No need to check for an exception here, because we return anyway. - env->PopLocalFrame(NULL); - return SVN_NO_ERROR; + POP_AND_RETURN_EXCEPTION_AS_SVNERROR(); } Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/MessageReceiver.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/MessageReceiver.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/MessageReceiver.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/MessageReceiver.cpp Sun Jun 14 20:58:10 2015 @@ -58,7 +58,7 @@ void MessageReceiver::receiveMessage(con static jmethodID mid = 0; if (mid == 0) { - jclass clazz = env->FindClass(JAVA_PACKAGE"/ISVNAdmin$MessageReceiver"); + jclass clazz = env->FindClass(JAVAHL_CLASS("/ISVNAdmin$MessageReceiver")); if (JNIUtil::isJavaExceptionThrown()) return; Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/NativeStream.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/NativeStream.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/NativeStream.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/NativeStream.cpp Sun Jun 14 20:58:10 2015 @@ -33,7 +33,7 @@ namespace JavaHL { // Class JavaHL::NativeInputStream const char* const NativeInputStream::m_class_name = - JAVA_PACKAGE "/types/NativeInputStream"; + JAVAHL_CLASS("/types/NativeInputStream"); NativeInputStream::~NativeInputStream() {} @@ -45,16 +45,23 @@ void NativeInputStream::set_stream(svn_s } NativeInputStream* -NativeInputStream::get_self(::Java::Env env, jobject jthis) +NativeInputStream::get_self_unsafe(::Java::Env env, jobject jthis) { jfieldID fid_cppaddr = NULL; const jlong cppaddr = findCppAddrForJObject(jthis, &fid_cppaddr, m_class_name); - if (!cppaddr) - ::Java::NullPointerException(env).raise(_("this [C++]")); return reinterpret_cast<NativeInputStream*>(cppaddr); } +NativeInputStream* +NativeInputStream::get_self(::Java::Env env, jobject jthis) +{ + NativeInputStream* self = get_self_unsafe(env, jthis); + if (!self) + ::Java::NullPointerException(env).raise(_("this [C++]")); + return self; +} + void NativeInputStream::close(::Java::Env env, jobject jthis) { SVN_JAVAHL_CHECK(env, svn_stream_close(m_stream)); @@ -137,7 +144,7 @@ void NativeInputStream::dispose(jobject // Class JavaHL::NativeOutputStream const char* const NativeOutputStream::m_class_name = - JAVA_PACKAGE "/types/NativeOutputStream"; + JAVAHL_CLASS("/types/NativeOutputStream"); NativeOutputStream::~NativeOutputStream() {} @@ -149,16 +156,23 @@ void NativeOutputStream::set_stream(svn_ } NativeOutputStream* -NativeOutputStream::get_self(::Java::Env env, jobject jthis) +NativeOutputStream::get_self_unsafe(::Java::Env env, jobject jthis) { jfieldID fid_cppaddr = NULL; const jlong cppaddr = findCppAddrForJObject(jthis, &fid_cppaddr, m_class_name); - if (!cppaddr) - ::Java::NullPointerException(env).raise(_("this [C++]")); return reinterpret_cast<NativeOutputStream*>(cppaddr); } +NativeOutputStream* +NativeOutputStream::get_self(::Java::Env env, jobject jthis) +{ + NativeOutputStream* self = get_self_unsafe(env, jthis); + if (!self) + ::Java::NullPointerException(env).raise(_("this [C++]")); + return self; +} + void NativeOutputStream::close(::Java::Env env, jobject jthis) { SVN_JAVAHL_CHECK(env, svn_stream_close(m_stream)); @@ -294,6 +308,20 @@ Java_org_apache_subversion_javahl_types_ return 0; } +JNIEXPORT void JNICALL +Java_org_apache_subversion_javahl_types_NativeInputStream_finalize( + JNIEnv* jenv, jobject jthis) +{ + SVN_JAVAHL_JNI_TRY(NativeInputStream, finalize) + { + JavaHL::NativeInputStream* native = + JavaHL::NativeInputStream::get_self_unsafe(Java::Env(jenv), jthis); + if (native != NULL) + native->finalize(); + } + SVN_JAVAHL_JNI_CATCH; +} + // Class JavaHL::NativeOutputStream native method implementation #include "../include/org_apache_subversion_javahl_types_NativeOutputStream.h" @@ -337,3 +365,17 @@ Java_org_apache_subversion_javahl_types_ } SVN_JAVAHL_JNI_CATCH_TO_EXCEPTION(Java::IOException); } + +JNIEXPORT void JNICALL +Java_org_apache_subversion_javahl_types_NativeOutputStream_finalize( + JNIEnv* jenv, jobject jthis) +{ + SVN_JAVAHL_JNI_TRY(NativeOutputStream, finalize) + { + JavaHL::NativeOutputStream* native = + JavaHL::NativeOutputStream::get_self_unsafe(Java::Env(jenv), jthis); + if (native != NULL) + native->finalize(); + } + SVN_JAVAHL_JNI_CATCH; +} Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/NativeStream.hpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/NativeStream.hpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/NativeStream.hpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/NativeStream.hpp Sun Jun 14 20:58:10 2015 @@ -81,6 +81,8 @@ public: */ static NativeInputStream* get_self(::Java::Env env, jobject jthis); + static NativeInputStream* get_self_unsafe(::Java::Env env, jobject jthis); + public: /** * Implements @c InputStream.close(). @@ -176,6 +178,8 @@ public: */ static NativeOutputStream* get_self(::Java::Env env, jobject jthis); + static NativeOutputStream* get_self_unsafe(::Java::Env env, jobject jthis); + public: /** * Implements @c OutputStream.close(). Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/OperationContext.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/OperationContext.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/OperationContext.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/OperationContext.cpp Sun Jun 14 20:58:10 2015 @@ -358,6 +358,9 @@ OperationContext::checkCancel(void *canc OperationContext *that = static_cast<OperationContext *>(cancelBaton); if (that->isCancelledOperation()) return svn_error_create(SVN_ERR_CANCELLED, NULL, _("Operation cancelled")); + else if (JNIUtil::isJavaExceptionThrown()) + return svn_error_create(SVN_ERR_CANCELLED, JNIUtil::wrapJavaException(), + _("Operation cancelled")); else return SVN_NO_ERROR; } @@ -385,13 +388,13 @@ OperationContext::progress(apr_off_t pro POP_AND_RETURN_NOTHING(); mid = env->GetMethodID(clazz, "onProgress", - "(L"JAVA_PACKAGE"/ProgressEvent;)V"); + "(" JAVAHL_ARG("/ProgressEvent;") ")V"); if (JNIUtil::isJavaExceptionThrown() || mid == 0) POP_AND_RETURN_NOTHING(); } static jmethodID midCT = 0; - jclass clazz = env->FindClass(JAVA_PACKAGE"/ProgressEvent"); + jclass clazz = env->FindClass(JAVAHL_CLASS("/ProgressEvent")); if (JNIUtil::isJavaExceptionThrown()) POP_AND_RETURN_NOTHING(); @@ -440,16 +443,16 @@ OperationContext::notifyConfigLoad() static jmethodID onload_mid = 0; if (0 == onload_mid) { - jclass cls = env->FindClass(JAVA_PACKAGE"/callback/ConfigEvent"); + jclass cls = env->FindClass(JAVAHL_CLASS("/callback/ConfigEvent")); if (JNIUtil::isJavaExceptionThrown()) return; onload_mid = env->GetMethodID(cls, "onLoad", - "(L"JAVA_PACKAGE"/ISVNConfig;)V"); + "(" JAVAHL_ARG("/ISVNConfig;") ")V"); if (JNIUtil::isJavaExceptionThrown()) return; } - jclass cfg_cls = env->FindClass(JAVA_PACKAGE"/util/ConfigImpl"); + jclass cfg_cls = env->FindClass(JAVAHL_CLASS("/util/ConfigImpl")); if (JNIUtil::isJavaExceptionThrown()) return; @@ -525,11 +528,11 @@ jobject create_Channel(const char *class jobject create_RequestChannel(JNIEnv *env, apr_file_t *fd) { - return create_Channel(JAVA_PACKAGE"/util/RequestChannel", env, fd); + return create_Channel(JAVAHL_CLASS("/util/RequestChannel"), env, fd); } jobject create_ResponseChannel(JNIEnv *env, apr_file_t *fd) { - return create_Channel(JAVA_PACKAGE"/util/ResponseChannel", env, fd); + return create_Channel(JAVAHL_CLASS("/util/ResponseChannel"), env, fd); } } // anonymous namespace @@ -545,7 +548,7 @@ OperationContext::checkTunnel(void *tunn static jmethodID mid = 0; if (0 == mid) { - jclass cls = env->FindClass(JAVA_PACKAGE"/callback/TunnelAgent"); + jclass cls = env->FindClass(JAVAHL_CLASS("/callback/TunnelAgent")); if (JNIUtil::isJavaExceptionThrown()) return false; mid = env->GetMethodID(cls, "checkTunnel", @@ -605,7 +608,7 @@ OperationContext::openTunnel(svn_stream_ static jmethodID mid = 0; if (0 == mid) { - jclass cls = env->FindClass(JAVA_PACKAGE"/callback/TunnelAgent"); + jclass cls = env->FindClass(JAVAHL_CLASS("/callback/TunnelAgent")); SVN_JNI_CATCH(, SVN_ERR_BASE); SVN_JNI_CATCH( mid = env->GetMethodID( @@ -615,7 +618,7 @@ OperationContext::openTunnel(svn_stream_ "Ljava/lang/String;" "Ljava/lang/String;" "Ljava/lang/String;I)" - "L"JAVA_PACKAGE"/callback/TunnelAgent$CloseTunnelCallback;"), + JAVAHL_ARG("/callback/TunnelAgent$CloseTunnelCallback;")), SVN_ERR_BASE); } @@ -647,7 +650,7 @@ OperationContext::closeTunnel(void *tunn jclass cls; SVN_JNI_CATCH_VOID( cls= env->FindClass( - JAVA_PACKAGE"/callback/TunnelAgent$CloseTunnelCallback")); + JAVAHL_CLASS("/callback/TunnelAgent$CloseTunnelCallback"))); SVN_JNI_CATCH_VOID(mid = env->GetMethodID(cls, "closeTunnel", "()V")); } SVN_JNI_CATCH_VOID(env->CallVoidMethod(jclosecb, mid)); Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/PatchCallback.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/PatchCallback.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/PatchCallback.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/PatchCallback.cpp Sun Jun 14 20:58:10 2015 @@ -80,7 +80,7 @@ PatchCallback::singlePatch(svn_boolean_t static jmethodID mid = 0; if (mid == 0) { - jclass clazz = env->FindClass(JAVA_PACKAGE"/callback/PatchCallback"); + jclass clazz = env->FindClass(JAVAHL_CLASS("/callback/PatchCallback")); if (JNIUtil::isJavaExceptionThrown()) POP_AND_RETURN(SVN_NO_ERROR); @@ -106,7 +106,7 @@ PatchCallback::singlePatch(svn_boolean_t jboolean jfiltered = env->CallBooleanMethod(m_callback, mid, jcanonPath, jpatchAbsPath, jrejectAbsPath); if (JNIUtil::isJavaExceptionThrown()) - POP_AND_RETURN(SVN_NO_ERROR); + POP_AND_RETURN_EXCEPTION_AS_SVNERROR(); *filtered = (jfiltered ? TRUE : FALSE); Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/PropertyTable.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/PropertyTable.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/PropertyTable.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/PropertyTable.cpp Sun Jun 14 20:58:10 2015 @@ -58,7 +58,7 @@ apr_hash_t *PropertyTable::hash(const SV const char *msg = apr_psprintf(pool.getPool(), "Invalid property name: '%s'", propname); - JNIUtil::throwNativeException(JAVA_PACKAGE "/ClientException", msg, + JNIUtil::throwNativeException(JAVAHL_CLASS("/ClientException"), msg, NULL, SVN_ERR_CLIENT_PROPERTY_NAME); return NULL; } Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/ProplistCallback.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/ProplistCallback.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/ProplistCallback.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/ProplistCallback.cpp Sun Jun 14 20:58:10 2015 @@ -89,7 +89,7 @@ svn_error_t *ProplistCallback::singlePat static volatile jmethodID mid = 0; if (mid == 0) { - jclass clazz = env->FindClass(JAVA_PACKAGE"/callback/ProplistCallback"); + jclass clazz = env->FindClass(JAVAHL_CLASS("/callback/ProplistCallback")); if (JNIUtil::isJavaExceptionThrown()) return SVN_NO_ERROR; @@ -112,9 +112,7 @@ svn_error_t *ProplistCallback::singlePat env->CallVoidMethod(m_callback, mid, jpath, jmap); // We return whether an exception was thrown or not. - env->PopLocalFrame(NULL); - - return SVN_NO_ERROR; + POP_AND_RETURN_EXCEPTION_AS_SVNERROR(); } @@ -144,7 +142,7 @@ svn_error_t *ProplistCallback::singlePat static jmethodID mid = 0; if (mid == 0) { - jclass clazz = env->FindClass(JAVA_PACKAGE"/callback/InheritedProplistCallback"); + jclass clazz = env->FindClass(JAVAHL_CLASS("/callback/InheritedProplistCallback")); if (JNIUtil::isJavaExceptionThrown()) return SVN_NO_ERROR; Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/RemoteSession.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/RemoteSession.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/RemoteSession.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/RemoteSession.cpp Sun Jun 14 20:58:10 2015 @@ -52,7 +52,7 @@ #include <apr_strings.h> #include "svn_private_config.h" -#define JAVA_CLASS_REMOTE_SESSION JAVA_PACKAGE "/remote/RemoteSession" +#define JAVA_CLASS_REMOTE_SESSION JAVAHL_CLASS("/remote/RemoteSession") RemoteSession * RemoteSession::getCppObject(jobject jthis) @@ -214,6 +214,8 @@ RemoteSession::RemoteSession(int retryAt cycle_detected = true; break; } + /* ### Shouldn't url be updated for the next attempt? + ### There is no real cycle if we just do the same thing twice? */ } if (cycle_detected) @@ -226,7 +228,7 @@ RemoteSession::RemoteSession(int retryAt corrected_url)); jclass excls = env->FindClass( - JAVA_PACKAGE "/SubversionException"); + JAVAHL_CLASS("/SubversionException")); if (JNIUtil::isJavaExceptionThrown()) return; @@ -256,7 +258,7 @@ RemoteSession::RemoteSession(int retryAt return; jclass excls = env->FindClass( - JAVA_PACKAGE "/remote/RetryOpenSession"); + JAVAHL_CLASS("/remote/RetryOpenSession")); if (JNIUtil::isJavaExceptionThrown()) return; @@ -542,7 +544,7 @@ void fill_dirents(const char* base_url, static jfieldID path_fid = 0; if (path_fid == 0) { - jclass clazz = env->FindClass(JAVA_PACKAGE "/types/DirEntry"); + jclass clazz = env->FindClass(JAVAHL_CLASS("/types/DirEntry")); if (JNIUtil::isJavaExceptionThrown()) POP_AND_RETURN_NOTHING(); @@ -833,7 +835,7 @@ RemoteSession::status(jobject jthis, jst proxy_callbacks.m_extra_baton.baton = &rp->m_target_revision; apr_pool_t* report_pool = rp->get_report_pool(); - std::auto_ptr<EditorProxy> editor( + EditorProxy::UniquePtr editor( new EditorProxy(jstatus_editor, report_pool, repos_root_url, base_relpath, m_context->checkCancel, m_context, @@ -851,7 +853,7 @@ RemoteSession::status(jobject jthis, jst editor->delta_editor(), editor->delta_baton(), report_pool),); - rp->set_reporter_data(raw_reporter, report_baton, editor.release()); + rp->set_reporter_data(raw_reporter, report_baton, editor); } // TODO: diff @@ -877,8 +879,10 @@ RemoteSession::getLog(jobject jpaths, true, subPool); if (JNIUtil::isJavaExceptionThrown()) return; - const apr_array_header_t* revprops = build_string_array(revpropiter, - false, subPool); + const apr_array_header_t* revprops = (jrevprops != NULL) + ? build_string_array(revpropiter, + false, subPool) + : NULL; if (JNIUtil::isJavaExceptionThrown()) return; @@ -1087,7 +1091,7 @@ public: return; m_call_mid = env->GetMethodID( - cls, "doSegment", "(L"JAVA_PACKAGE"/ISVNRemote$LocationSegment;)V"); + cls, "doSegment", "(" JAVAHL_ARG("/ISVNRemote$LocationSegment;") ")V"); if (JNIUtil::isJavaExceptionThrown()) return; } @@ -1096,7 +1100,7 @@ private: void call(svn_location_segment_t* segment) { JNIEnv* env = JNIUtil::getEnv(); - jclass cls = env->FindClass(JAVA_PACKAGE"/ISVNRemote$LocationSegment"); + jclass cls = env->FindClass(JAVAHL_CLASS("/ISVNRemote$LocationSegment")); if (JNIUtil::isJavaExceptionThrown()) return; @@ -1191,7 +1195,7 @@ public: return; m_call_mid = env->GetMethodID( - cls, "doRevision", "(L"JAVA_PACKAGE"/ISVNRemote$FileRevision;)V"); + cls, "doRevision", "(" JAVAHL_ARG("/ISVNRemote$FileRevision;") ")V"); if (JNIUtil::isJavaExceptionThrown()) return; } @@ -1205,7 +1209,7 @@ private: apr_pool_t* scratch_pool) { JNIEnv* env = JNIUtil::getEnv(); - jclass cls = env->FindClass(JAVA_PACKAGE"/ISVNRemote$FileRevision"); + jclass cls = env->FindClass(JAVAHL_CLASS("/ISVNRemote$FileRevision")); if (JNIUtil::isJavaExceptionThrown()) return; Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/RemoteSession.h URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/RemoteSession.h?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/RemoteSession.h (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/RemoteSession.h Sun Jun 14 20:58:10 2015 @@ -56,7 +56,7 @@ class RemoteSession : public SVNBase const char* username, const char* password, Prompter::UniquePtr prompter, jobject jprogress, jobject jcfgcb, jobject jtunnelcb); - ~RemoteSession(); + virtual ~RemoteSession(); void cancelOperation() const { m_context->cancelOperation(); } @@ -102,7 +102,6 @@ class RemoteSession : public SVNBase jlong jstart_revision, jlong jend_revision, jboolean jinclude_merged_revisions, jobject jcallback); - // TODO: getFileRevisions // TODO: lock // TODO: unlock // TODO: getLock Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/RemoteSessionContext.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/RemoteSessionContext.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/RemoteSessionContext.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/RemoteSessionContext.cpp Sun Jun 14 20:58:10 2015 @@ -90,7 +90,7 @@ void RemoteSessionContext::activate(jobj */ static jfieldID ctxFieldID = 0; attachJavaObject(jremoteSession, - "L"JAVA_PACKAGE"/remote/RemoteSession$RemoteSessionContext;", + JAVAHL_ARG("/remote/RemoteSession$RemoteSessionContext;"), "sessionContext", &ctxFieldID); /* @@ -104,7 +104,7 @@ void RemoteSessionContext::activate(jobj jmethodID mid = env->GetMethodID( clazz, "setProgressCallback", - "(L"JAVA_PACKAGE"/callback/ProgressCallback;)V"); + "(" JAVAHL_ARG("/callback/ProgressCallback;") ")V"); if (JNIUtil::isJavaExceptionThrown() || mid == 0) return; Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/ReposFreezeAction.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/ReposFreezeAction.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/ReposFreezeAction.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/ReposFreezeAction.cpp Sun Jun 14 20:58:10 2015 @@ -20,7 +20,7 @@ * ==================================================================== * @endcopyright * - * @file ReposFreezeAction.h + * @file ReposFreezeAction.cpp * @brief Native mirror of the ReposFreezeAction callback interface */ @@ -39,7 +39,7 @@ svn_error_t* ReposFreezeAction::invoke() static volatile jmethodID mid = 0; if (!mid) { - jclass cls = env->FindClass(JAVA_PACKAGE"/callback/ReposFreezeAction"); + jclass cls = env->FindClass(JAVAHL_CLASS("/callback/ReposFreezeAction")); if (!JNIUtil::isJavaExceptionThrown()) mid = env->GetMethodID(cls, "invoke", "()V"); } Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/ReposNotifyCallback.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/ReposNotifyCallback.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/ReposNotifyCallback.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/ReposNotifyCallback.cpp Sun Jun 14 20:58:10 2015 @@ -69,12 +69,12 @@ ReposNotifyCallback::onNotify(const svn_ static jmethodID mid = 0; if (mid == 0) { - jclass clazz = env->FindClass(JAVA_PACKAGE"/callback/ReposNotifyCallback"); + jclass clazz = env->FindClass(JAVAHL_CLASS("/callback/ReposNotifyCallback")); if (JNIUtil::isJavaExceptionThrown()) return; mid = env->GetMethodID(clazz, "onNotify", - "(L"JAVA_PACKAGE"/ReposNotifyInformation;)V"); + "(" JAVAHL_ARG("/ReposNotifyInformation;") ")V"); if (JNIUtil::isJavaExceptionThrown() || mid == 0) return; Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/Revision.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/Revision.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/Revision.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/Revision.cpp Sun Jun 14 20:58:10 2015 @@ -57,12 +57,12 @@ Revision::Revision(jobject jthis, bool h static jfieldID fid = 0; if (fid == 0) { - jclass clazz = env->FindClass(JAVA_PACKAGE"/types/Revision"); + jclass clazz = env->FindClass(JAVAHL_CLASS("/types/Revision")); if (JNIUtil::isJavaExceptionThrown()) POP_AND_RETURN_NOTHING(); fid = env->GetFieldID(clazz, "revKind", - "L"JAVA_PACKAGE"/types/Revision$Kind;"); + JAVAHL_ARG("/types/Revision$Kind;")); if (JNIUtil::isJavaExceptionThrown()) POP_AND_RETURN_NOTHING(); } @@ -81,7 +81,7 @@ Revision::Revision(jobject jthis, bool h if (fidNum == 0) { jclass clazz = - env->FindClass(JAVA_PACKAGE"/types/Revision$Number"); + env->FindClass(JAVAHL_CLASS("/types/Revision$Number")); if (JNIUtil::isJavaExceptionThrown()) POP_AND_RETURN_NOTHING(); @@ -99,7 +99,7 @@ Revision::Revision(jobject jthis, bool h if (fidDate == 0) { jclass clazz = - env->FindClass(JAVA_PACKAGE"/types/Revision$DateSpec"); + env->FindClass(JAVAHL_CLASS("/types/Revision$DateSpec")); if (JNIUtil::isJavaExceptionThrown()) POP_AND_RETURN_NOTHING(); @@ -158,7 +158,7 @@ jobject Revision::makeJRevision(svn_revnum_t rev) { JNIEnv *env = JNIUtil::getEnv(); - jclass clazz = env->FindClass(JAVA_PACKAGE "/types/Revision"); + jclass clazz = env->FindClass(JAVAHL_CLASS("/types/Revision")); if (JNIUtil::isJavaExceptionThrown()) return NULL; @@ -166,7 +166,7 @@ Revision::makeJRevision(svn_revnum_t rev if (getInstance == 0) { getInstance = env->GetStaticMethodID(clazz, "getInstance", - "(J)L" JAVA_PACKAGE "/types/Revision;"); + "(J)" JAVAHL_ARG("/types/Revision;")); if (JNIUtil::isExceptionThrown()) return NULL; } Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/RevisionRange.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/RevisionRange.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/RevisionRange.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/RevisionRange.cpp Sun Jun 14 20:58:10 2015 @@ -52,7 +52,7 @@ void get_range_info(jobject jrange, { JNIEnv *env = JNIUtil::getEnv(); - jclass clazz = env->FindClass(JAVA_PACKAGE"/types/RevisionRange"); + jclass clazz = env->FindClass(JAVAHL_CLASS("/types/RevisionRange")); if (JNIUtil::isExceptionThrown()) return; @@ -63,7 +63,7 @@ void get_range_info(jobject jrange, if (fmid == 0) { fmid = env->GetMethodID(clazz, "getFromRevision", - "()L"JAVA_PACKAGE"/types/Revision;"); + "()" JAVAHL_ARG("/types/Revision;")); if (JNIUtil::isJavaExceptionThrown()) return; } @@ -87,7 +87,7 @@ void get_range_info(jobject jrange, if (tmid == 0) { tmid = env->GetMethodID(clazz, "getToRevision", - "()L"JAVA_PACKAGE"/types/Revision;"); + "()" JAVAHL_ARG("/types/Revision;")); if (JNIUtil::isJavaExceptionThrown()) return; } @@ -163,7 +163,7 @@ RevisionRange::makeJRevisionRange(svn_me { JNIEnv *env = JNIUtil::getEnv(); - jclass rangeClazz = env->FindClass(JAVA_PACKAGE "/types/RevisionRange"); + jclass rangeClazz = env->FindClass(JAVAHL_CLASS("/types/RevisionRange")); if (JNIUtil::isJavaExceptionThrown()) return NULL; static jmethodID rangeCtor = 0; Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/RevisionRangeList.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/RevisionRangeList.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/RevisionRangeList.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/RevisionRangeList.cpp Sun Jun 14 20:58:10 2015 @@ -60,7 +60,7 @@ RevisionRangeList RevisionRangeList::cre jmethodID mid = 0; if (mid == 0) { - jclass cls = env->FindClass(JAVA_PACKAGE"/types/RevisionRangeList"); + jclass cls = env->FindClass(JAVAHL_CLASS("/types/RevisionRangeList")); if (JNIUtil::isJavaExceptionThrown()) return RevisionRangeList(NULL, pool); Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/SVNClient.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/SVNClient.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/SVNClient.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/SVNClient.cpp Sun Jun 14 20:58:10 2015 @@ -70,11 +70,19 @@ #include "svn_diff.h" #include "svn_config.h" #include "svn_io.h" +#include "svn_hash.h" #include "svn_dirent_uri.h" #include "svn_path.h" #include "svn_utf.h" +#include "private/svn_subr_private.h" #include "svn_private_config.h" +#include "ExternalItem.hpp" +#include "jniwrapper/jni_list.hpp" +#include "jniwrapper/jni_stack.hpp" +#include "jniwrapper/jni_string_map.hpp" + + SVNClient::SVNClient(jobject jthis_in) : m_lastPath("", pool), context(jthis_in, pool) { @@ -88,21 +96,21 @@ SVNClient *SVNClient::getCppObject(jobje { static jfieldID fid = 0; jlong cppAddr = SVNBase::findCppAddrForJObject(jthis, &fid, - JAVA_PACKAGE"/SVNClient"); + JAVAHL_CLASS("/SVNClient")); return (cppAddr == 0 ? NULL : reinterpret_cast<SVNClient *>(cppAddr)); } void SVNClient::dispose(jobject jthis) { static jfieldID fid = 0; - SVNBase::dispose(jthis, &fid, JAVA_PACKAGE"/SVNClient"); + SVNBase::dispose(jthis, &fid, JAVAHL_CLASS("/SVNClient")); } jobject SVNClient::getVersionExtended(bool verbose) { JNIEnv *const env = JNIUtil::getEnv(); - jclass clazz = env->FindClass(JAVA_PACKAGE"/types/VersionExtended"); + jclass clazz = env->FindClass(JAVAHL_CLASS("/types/VersionExtended")); if (JNIUtil::isJavaExceptionThrown()) return NULL; @@ -443,9 +451,76 @@ void SVNClient::commit(Targets &targets, ); } + +namespace { +typedef Java::ImmutableList<JavaHL::ExternalItem> PinList; +typedef Java::ImmutableMap<PinList> PinMap; + +struct PinListFunctor +{ + explicit PinListFunctor(const Java::Env& env, SVN::Pool& pool, int refs_len) + : m_pool(pool), + m_refs(apr_array_make(pool.getPool(), refs_len, + sizeof(svn_wc_external_item2_t*))) + {} + + void operator()(const JavaHL::ExternalItem& item) + { + APR_ARRAY_PUSH(m_refs, svn_wc_external_item2_t*) = + item.get_external_item(m_pool); + } + + SVN::Pool& m_pool; + apr_array_header_t *m_refs; +}; + +struct PinMapFunctor +{ + explicit PinMapFunctor(const Java::Env& env, SVN::Pool& pool) + : m_env(env), + m_pool(pool), + m_pin_set(svn_hash__make(pool.getPool())) + {} + + void operator()(const std::string& path, const PinList& refs) + { + PinListFunctor lf(m_env, m_pool, refs.length()); + refs.for_each(lf); + const char* key = static_cast<const char*>( + apr_pmemdup(m_pool.getPool(), path.c_str(), path.size() + 1)); + svn_hash_sets(m_pin_set, key, lf.m_refs); + } + + const Java::Env& m_env; + SVN::Pool& m_pool; + apr_hash_t *m_pin_set; +}; + +apr_hash_t *get_externals_to_pin(jobject jexternalsToPin, SVN::Pool& pool) +{ + if (!jexternalsToPin) + return NULL; + + const Java::Env env; + JNIEnv *jenv = env.get(); + + try + { + PinMap pin_map(env, jexternalsToPin); + PinMapFunctor mf(env, pool); + pin_map.for_each(mf); + return mf.m_pin_set; + } + SVN_JAVAHL_JNI_CATCH; + return NULL; +} +} // anonymous namespace + void SVNClient::copy(CopySources ©Sources, const char *destPath, CommitMessage *message, bool copyAsChild, bool makeParents, bool ignoreExternals, + bool metadataOnly, + bool pinExternals, jobject jexternalsToPin, PropertyTable &revprops, CommitCallback *callback) { SVN::Pool subPool(pool); @@ -460,10 +535,14 @@ void SVNClient::copy(CopySources ©So if (ctx == NULL) return; - SVN_JNI_ERR(svn_client_copy6(srcs, destinationPath.c_str(), - copyAsChild, makeParents, ignoreExternals, - revprops.hash(subPool), - CommitCallback::callback, callback, + apr_hash_t *pin_set = get_externals_to_pin(jexternalsToPin, subPool); + if (!JNIUtil::isJavaExceptionThrown()) + SVN_JNI_ERR(svn_client_copy7(srcs, destinationPath.c_str(), + copyAsChild, makeParents, ignoreExternals, + metadataOnly, + pinExternals, pin_set, + revprops.hash(subPool), + CommitCallback::callback, callback, ctx, subPool.getPool()), ); } Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/SVNClient.h URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/SVNClient.h?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/SVNClient.h (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/SVNClient.h Sun Jun 14 20:58:10 2015 @@ -149,8 +149,9 @@ class SVNClient :public SVNBase PropertyTable &revprops, CommitCallback *callback); void copy(CopySources ©Sources, const char *destPath, CommitMessage *message, bool copyAsChild, bool makeParents, - bool ignoreExternals, PropertyTable &revprops, - CommitCallback *callback); + bool ignoreExternals, bool metaDataOnly, bool pinExternals, + jobject jexternalsToPin, + PropertyTable &revprops, CommitCallback *callback); void commit(Targets &targets, CommitMessage *message, svn_depth_t depth, bool noUnlock, bool keepChangelist, StringArray &changelists, PropertyTable &revprops, Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/SVNRepos.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/SVNRepos.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/SVNRepos.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/SVNRepos.cpp Sun Jun 14 20:58:10 2015 @@ -50,14 +50,14 @@ SVNRepos *SVNRepos::getCppObject(jobject { static jfieldID fid = 0; jlong cppAddr = SVNBase::findCppAddrForJObject(jthis, &fid, - JAVA_PACKAGE"/SVNRepos"); + JAVAHL_CLASS("/SVNRepos")); return (cppAddr == 0 ? NULL : reinterpret_cast<SVNRepos *>(cppAddr)); } void SVNRepos::dispose(jobject jthis) { static jfieldID fid = 0; - SVNBase::dispose(jthis, &fid, JAVA_PACKAGE"/SVNRepos"); + SVNBase::dispose(jthis, &fid, JAVAHL_CLASS("/SVNRepos")); } void SVNRepos::cancelOperation() @@ -716,7 +716,7 @@ jobject SVNRepos::lslocks(File &path, sv NULL); JNIEnv *env = JNIUtil::getEnv(); - jclass clazz = env->FindClass(JAVA_PACKAGE"/types/Lock"); + jclass clazz = env->FindClass(JAVAHL_CLASS("/types/Lock")); if (JNIUtil::isJavaExceptionThrown()) return NULL; Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/StateReporter.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/StateReporter.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/StateReporter.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/StateReporter.cpp Sun Jun 14 20:58:10 2015 @@ -43,16 +43,14 @@ StateReporter::StateReporter() {} StateReporter::~StateReporter() -{ - delete m_editor; -} +{} StateReporter* StateReporter::getCppObject(jobject jthis) { static jfieldID fid = 0; jlong cppAddr = SVNBase::findCppAddrForJObject(jthis, &fid, - JAVA_PACKAGE"/remote/StateReporter"); + JAVAHL_CLASS("/remote/StateReporter")); return (cppAddr == 0 ? NULL : reinterpret_cast<StateReporter*>(cppAddr)); } @@ -65,7 +63,7 @@ StateReporter::dispose(jobject jthis) abortReport(); static jfieldID fid = 0; - SVNBase::dispose(jthis, &fid, JAVA_PACKAGE"/remote/StateReporter"); + SVNBase::dispose(jthis, &fid, JAVAHL_CLASS("/remote/StateReporter")); } namespace { @@ -83,7 +81,7 @@ StateReporter::setPath(jstring jpath, jl //DEBUG:fprintf(stderr, " (n) StateReporter::setPath()\n"); if (!m_valid) { throw_reporter_inactive(); return; } - + JNIStringHolder lock_token(jlock_token); if (JNIUtil::isJavaExceptionThrown()) return; @@ -179,8 +177,8 @@ StateReporter::abortReport() void StateReporter::set_reporter_data(const svn_ra_reporter3_t* raw_reporter, - void* report_baton, - EditorProxy* editor) + void* report_baton, + EditorProxy::UniquePtr editor) { //DEBUG:fprintf(stderr, " (n) StateReporter::set_reporter_data()\n"); Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/StateReporter.h URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/StateReporter.h?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/StateReporter.h (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/StateReporter.h Sun Jun 14 20:58:10 2015 @@ -20,7 +20,7 @@ * ==================================================================== * @endcopyright * - * @file UpdateReporter.h + * @file StateReporter.h * @brief Interface of the class UpdateReporter */ @@ -61,13 +61,13 @@ private: bool m_valid; const svn_ra_reporter3_t* m_raw_reporter; void* m_report_baton; - EditorProxy* m_editor; + EditorProxy::UniquePtr 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); + EditorProxy::UniquePtr editor); svn_revnum_t m_target_revision; }; Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/StatusCallback.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/StatusCallback.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/StatusCallback.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/StatusCallback.cpp Sun Jun 14 20:58:10 2015 @@ -81,13 +81,13 @@ StatusCallback::doStatus(const char *loc // it can be cached. if (mid == 0) { - jclass clazz = env->FindClass(JAVA_PACKAGE"/callback/StatusCallback"); + jclass clazz = env->FindClass(JAVAHL_CLASS("/callback/StatusCallback")); if (JNIUtil::isJavaExceptionThrown()) POP_AND_RETURN(SVN_NO_ERROR); mid = env->GetMethodID(clazz, "doStatus", "(Ljava/lang/String;" - "L"JAVA_PACKAGE"/types/Status;)V"); + JAVAHL_ARG("/types/Status;") ")V"); if (JNIUtil::isJavaExceptionThrown() || mid == 0) POP_AND_RETURN(SVN_NO_ERROR); } @@ -101,11 +101,8 @@ StatusCallback::doStatus(const char *loc POP_AND_RETURN(SVN_NO_ERROR); env->CallVoidMethod(m_callback, mid, jPath, jStatus); - // We return here regardless of whether an exception is thrown or not, - // so we do not need to explicitly check for one. - env->PopLocalFrame(NULL); - return SVN_NO_ERROR; + POP_AND_RETURN_EXCEPTION_AS_SVNERROR(); } void Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/SubversionException.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/SubversionException.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/SubversionException.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/SubversionException.cpp Sun Jun 14 20:58:10 2015 @@ -27,6 +27,6 @@ namespace JavaHL { const char* const SubversionException::m_class_name = - JAVA_PACKAGE"/SubversionException"; + JAVAHL_CLASS("/SubversionException"); } // namespace JavaHL Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/VersionExtended.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/VersionExtended.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/VersionExtended.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/VersionExtended.cpp Sun Jun 14 20:58:10 2015 @@ -27,7 +27,7 @@ #include "JNIUtil.h" #include "VersionExtended.h" -const VersionExtended * +VersionExtended * VersionExtended::getCppObject(jobject jthis) { if (!jthis) @@ -35,7 +35,7 @@ VersionExtended::getCppObject(jobject jt static jfieldID fid = 0; jlong cppAddr = SVNBase::findCppAddrForJObject( - jthis, &fid, JAVA_PACKAGE"/types/VersionExtended"); + jthis, &fid, JAVAHL_CLASS("/types/VersionExtended")); return (cppAddr == 0 ? NULL : reinterpret_cast<VersionExtended *>(cppAddr)); } @@ -46,7 +46,7 @@ static jobject getWrapperAddress(jobject if (!*fid) { *fid = env->GetFieldID(env->GetObjectClass(jthat), "wrapper", - "L"JAVA_PACKAGE"/types/VersionExtended;"); + JAVAHL_ARG("/types/VersionExtended;")); if (JNIUtil::isJavaExceptionThrown()) { *fid = 0; @@ -94,5 +94,5 @@ VersionExtended::~VersionExtended() {} void VersionExtended::dispose(jobject jthis) { static jfieldID fid = 0; - SVNBase::dispose(jthis, &fid, JAVA_PACKAGE"/types/VersionExtended"); + SVNBase::dispose(jthis, &fid, JAVAHL_CLASS("/types/VersionExtended")); } Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/VersionExtended.h URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/VersionExtended.h?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/VersionExtended.h (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/VersionExtended.h Sun Jun 14 20:58:10 2015 @@ -33,7 +33,7 @@ class VersionExtended : public SVNBase { public: - static const VersionExtended *getCppObject(jobject jthis); + static VersionExtended *getCppObject(jobject jthis); static const VersionExtended *getCppObjectFromLinkedLib(jobject jthat); static const VersionExtended *getCppObjectFromLoadedLib(jobject jthat); static const VersionExtended *getCppObjectFromLinkedLibIterator(jobject jthat); Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/jniwrapper/jni_base.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/jniwrapper/jni_base.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/jniwrapper/jni_base.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/jniwrapper/jni_base.cpp Sun Jun 14 20:58:10 2015 @@ -179,30 +179,6 @@ void Env::throw_java_out_of_memory(const const jint LocalFrame::DEFAULT_CAPACITY = 16; -// class Java::GlobalObject - -GlobalObject& GlobalObject::operator=(jobject that) -{ - this->~GlobalObject(); - return *new(this) GlobalObject(Env(), that); -} - -GlobalObject::~GlobalObject() -{ - if (m_obj) - Env().DeleteGlobalRef(m_obj); -} - - -// class Java::GlobalClass - -GlobalClass& GlobalClass::operator=(jclass that) -{ - this->~GlobalClass(); - return *new(this) GlobalClass(Env(), that); -} - - // Class Java::Object const char* const Object::m_class_name = "java/lang/Object"; @@ -375,7 +351,8 @@ const char* unknown_cxx_exception_messag svn_error_t* caught_java_exception_error(apr_status_t status) throw() { - return svn_error_create(status, NULL, _("Java exception")); + return svn_error_create(status, JNIUtil::wrapJavaException(), + _("Java exception")); } } // namespace Java Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/jniwrapper/jni_globalref.hpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/jniwrapper/jni_globalref.hpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/jniwrapper/jni_globalref.hpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/jniwrapper/jni_globalref.hpp Sun Jun 14 20:58:10 2015 @@ -24,6 +24,8 @@ #ifndef SVN_JAVAHL_JNIWRAPPER_GLOBALREF_HPP #define SVN_JAVAHL_JNIWRAPPER_GLOBALREF_HPP +#include <memory> + #include <jni.h> #include "jni_env.hpp" @@ -43,11 +45,19 @@ public: : m_obj(obj ? env.NewGlobalRef(obj) : NULL) {} - ~GlobalObject(); + ~GlobalObject() throw() + { + if (m_obj) + Env().DeleteGlobalRef(m_obj); + } - GlobalObject& operator=(jobject that); + GlobalObject& operator=(jobject that) + { + this->~GlobalObject(); + return *new(this) GlobalObject(Env(), that); + } - jobject get() const + jobject get() const throw() { return m_obj; } @@ -73,9 +83,13 @@ public: : GlobalObject(env, cls) {} - GlobalClass& operator=(jclass that); + GlobalClass& operator=(jclass that) + { + GlobalObject::operator=(that); + return *this; + } - jclass get() const + jclass get() const throw() { return jclass(GlobalObject::get()); } Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp Sun Jun 14 20:58:10 2015 @@ -559,6 +559,7 @@ JNIEXPORT void JNICALL Java_org_apache_subversion_javahl_SVNClient_copy (JNIEnv *env, jobject jthis, jobject jcopySources, jstring jdestPath, jboolean jcopyAsChild, jboolean jmakeParents, jboolean jignoreExternals, + jboolean jmetadataOnly, jboolean jpinExternals, jobject jexternalsToPin, jobject jrevpropTable, jobject jmessage, jobject jcallback) { JNIEntry(SVNClient, copy); @@ -590,8 +591,10 @@ Java_org_apache_subversion_javahl_SVNCli return; CommitCallback callback(jcallback); - cl->copy(copySources, destPath, &message, jcopyAsChild ? true : false, - jmakeParents ? true : false, jignoreExternals ? true : false, + cl->copy(copySources, destPath, &message, + bool(jcopyAsChild), bool(jmakeParents), + bool(jignoreExternals), bool(jmetadataOnly), + bool(jpinExternals), jexternalsToPin, revprops, jcallback ? &callback : NULL); } Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/org_apache_subversion_javahl_types_VersionExtended.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/org_apache_subversion_javahl_types_VersionExtended.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/org_apache_subversion_javahl_types_VersionExtended.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/org_apache_subversion_javahl_types_VersionExtended.cpp Sun Jun 14 20:58:10 2015 @@ -33,8 +33,24 @@ #include "JNIStackElement.h" #include <string> +#include "svn_private_config.h" + // VersionExtended native methods +JNIEXPORT void JNICALL +Java_org_apache_subversion_javahl_types_VersionExtended_dispose( + JNIEnv *env, jobject jthis) +{ + JNIEntry(VersionExtended, dispose); + VersionExtended *const vx = VersionExtended::getCppObject(jthis); + if (vx == NULL) + { + JNIUtil::throwError(_("bad C++ this")); + return; + } + vx->dispose(jthis); +} + JNIEXPORT jstring JNICALL Java_org_apache_subversion_javahl_types_VersionExtended_getBuildDate( JNIEnv *env, jobject jthis) Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/org_apache_subversion_javahl_util_ConfigImpl_Category.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/org_apache_subversion_javahl_util_ConfigImpl_Category.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/org_apache_subversion_javahl_util_ConfigImpl_Category.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/org_apache_subversion_javahl_util_ConfigImpl_Category.cpp Sun Jun 14 20:58:10 2015 @@ -178,7 +178,7 @@ Java_org_apache_subversion_javahl_util_C ctx.m_config, &value, ctx.m_section.c_str(), ctx.m_option.c_str(), default_value.c_str()), - NULL); + NULL); return JNIUtil::makeJString(value); } @@ -270,12 +270,12 @@ Java_org_apache_subversion_javahl_util_C { enumerator_t* enmr = static_cast<enumerator_t*>(baton); JNIEnv* const e = enmr->m_env; - const jobject jh = enmr->m_jhandler;; + const jobject jh = enmr->m_jhandler; static jmethodID mid = 0; if (0 == mid) { - jclass cls = e->FindClass(JAVA_PACKAGE"/ISVNConfig$Enumerator"); + jclass cls = e->FindClass(JAVAHL_CLASS("/ISVNConfig$Enumerator")); if (JNIUtil::isJavaExceptionThrown()) return false; mid = e->GetMethodID(cls, "option", Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/native/org_apache_subversion_javahl_util_SubstLib.cpp URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/native/org_apache_subversion_javahl_util_SubstLib.cpp?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/native/org_apache_subversion_javahl_util_SubstLib.cpp (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/native/org_apache_subversion_javahl_util_SubstLib.cpp Sun Jun 14 20:58:10 2015 @@ -61,7 +61,7 @@ build_keywords_common(Java::Env env, con svn_string_t* keywords_string = keywords_contents.get_string(pool); const char* revision = (jrevision < 0 ? NULL : apr_psprintf(pool.getPool(), - "%"APR_UINT64_T_FMT, + "%" APR_UINT64_T_FMT, apr_uint64_t(jrevision))); const Java::String::Contents url_contents(url); const Java::String::Contents root_url_contents(repos_root_url); Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java Sun Jun 14 20:58:10 2015 @@ -376,6 +376,21 @@ public interface ISVNClient * @param makeParents Whether to create intermediate parents * @param ignoreExternals Whether or not to process external definitions * as part of this operation. + * @param metadataOnly Copy just the metadata and not the working files/dirs + * @param pinExternals Whether or not to pin external definitions as part + * of this operation. + * @param externalsToPin The set of externals to pin. + * Keys are either local absolute paths (when the source of the + * copy is the working copy) or URLs within the repository + * (when the source is the repository) where an + * <code>svn:externals</code> property is defined. + * Values are lists of parsed {@link ExternalItem} + * objects from each external definitions. + * If <code>pinExternals</code> is <code>true</code>, only + * the externals in this set will be pinned; if this parameter + * is <code>null</code>, all externals will be pinned. + * If <code>pinExternals</code> is <code>false</code>, + * this parameter will be ignored. * @param revpropTable A string-to-string mapping of revision properties * to values which will be set if this operation * results in a commit. @@ -383,6 +398,24 @@ public interface ISVNClient * if <code>destPath</code> is not a URL * @throws ClientException If the copy operation fails. * @throws NullPointerException if the <code>sources</code> list is empty. + * @since 1.9 + */ + void copy(List<CopySource> sources, String destPath, + boolean copyAsChild, boolean makeParents, + boolean ignoreExternals, boolean metadataOnly, + boolean pinExternals, + Map<String, List<ExternalItem>> externalsToPin, + Map<String, String> revpropTable, + CommitMessageCallback handler, CommitCallback callback) + throws ClientException; + + /** + * Copy versioned paths with the history preserved. + * <p> + * Behaves like the 1.9 version with + * <code>pinExternals</code> set to <code>false</code> and + * <code>externalsToPin</code> set to <code>null</code> and + * <code>metadataOnly</code> set to <code>false</code>. */ void copy(List<CopySource> sources, String destPath, boolean copyAsChild, boolean makeParents, @@ -469,9 +502,9 @@ public interface ISVNClient * Recursively cleans up a local directory, finishing any * incomplete operations, removing lockfiles, etc. * <p> - * Behaves like the 1.9 version with <code>breakLocks</code> and - * <code>includeExternals</code> set to <code>false<code>, and the - * other flags to <code>true</code>. + * Behaves like the 1.9 version with <code>includeExternals</code> + * set to <code>false<code>, and the other flags to + * <code>true</code>. * @param path a local directory. * @throws ClientException */ Modified: subversion/branches/fsx-1.10/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNEditor.java URL: http://svn.apache.org/viewvc/subversion/branches/fsx-1.10/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNEditor.java?rev=1685464&r1=1685463&r2=1685464&view=diff ============================================================================== --- subversion/branches/fsx-1.10/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNEditor.java (original) +++ subversion/branches/fsx-1.10/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNEditor.java Sun Jun 14 20:58:10 2015 @@ -30,7 +30,10 @@ import java.io.InputStream; import java.util.Map; /** - * Editor interface (implements the EV2 abstraction). + * Commit/update/status editor interface. + * <p> + * <b>This interface is EXPERIMENTAL. + * It may change or be removed in a future version of JavaHL</b> * @see <a href="http://svn.apache.org/repos/asf/subversion/trunk/subversion/include/private/svn_editor.h">svn_editor.h</a> * for all restrictions on driving an editor. * @since 1.9 @@ -91,7 +94,9 @@ public interface ISVNEditor * <code>replacesRevision</code> set accordingly <em>must</em> be used. * <p> * <b>Note:</b> The <code>contents</code> stream's lifetime must not - * extend beyond the scope of this function. + * extend beyond the scope of this function. An + * implementation <b>must</b> close the stream after + * consuming its contents. * * @throws ClientException */ @@ -190,7 +195,9 @@ public interface ISVNEditor * #addFile(). * <p> * <b>Note:</b> The <code>contents</code> stream's lifetime must not - * extend beyond the scope of this function. + * extend beyond the scope of this function. An + * implementation <b>must</b> close the stream after + * consuming its contents. * * @throws ClientException */
