Index: subversion/bindings/javahl/native/ClientContext.h =================================================================== --- subversion/bindings/javahl/native/ClientContext.h (revision 1328758) +++ subversion/bindings/javahl/native/ClientContext.h (working copy) @@ -29,6 +29,8 @@ #include +#include "CommonContext.h" + #include "svn_types.h" #include "svn_client.h" @@ -36,7 +38,6 @@ #include "Pool.h" #include "JNIStringHolder.h" -class Prompter; class CommitMessage; /** @@ -44,25 +45,14 @@ class CommitMessage; * and implements the functions read & close of svn_stream_t. * */ -class ClientContext +class ClientContext : public CommonContext { private: svn_client_ctx_t *m_context; - const SVN::Pool *m_pool; - jobject m_jctx; - std::string m_userName; - std::string m_passWord; - std::string m_configDir; - - Prompter *m_prompter; - bool m_cancelOperation; - protected: static void notify(void *baton, const svn_wc_notify_t *notify, apr_pool_t *pool); - static void progress(apr_off_t progressVal, apr_off_t total, - void *baton, apr_pool_t *pool); static svn_error_t *resolve(svn_wc_conflict_result_t **result, const svn_wc_conflict_description2_t *desc, void *baton, @@ -73,24 +63,9 @@ class CommitMessage; public: ClientContext(jobject jsvnclient, SVN::Pool &pool); - ~ClientContext(); + virtual ~ClientContext(); - static svn_error_t *checkCancel(void *cancelBaton); - svn_client_ctx_t *getContext(CommitMessage *message, SVN::Pool &in_pool); - - void username(const char *pi_username); - void password(const char *pi_password); - void setPrompt(Prompter *prompter); - void cancelOperation(); - const char *getConfigDirectory() const; - - /** - * Set the configuration directory, taking the usual steps to - * ensure that Subversion's config file templates exist in the - * specified location. - */ - void setConfigDirectory(const char *configDir); }; #endif // CLIENTCONTEXT_H Index: subversion/bindings/javahl/native/CommonContext.cpp =================================================================== --- subversion/bindings/javahl/native/CommonContext.cpp (working copy) +++ subversion/bindings/javahl/native/CommonContext.cpp (working copy) @@ -20,15 +20,15 @@ * ==================================================================== * @endcopyright * - * @file ClientContext.cpp - * @brief Implementation of the class ClientContext + * @file CommonContext.cpp + * @brief Implementation of the class CommonContext */ #include "svn_client.h" #include "private/svn_wc_private.h" #include "svn_private_config.h" -#include "ClientContext.h" +#include "CommonContext.h" #include "JNIUtil.h" #include "JNICriticalSection.h" @@ -37,337 +37,247 @@ #include "EnumMapper.h" #include "CommitMessage.h" +CommonContext::CommonContext(SVN::Pool &pool) + :m_prompter(NULL), m_cancelOperation(false), m_pool(&pool), m_config(NULL), m_jctx(NULL) +{ +} -ClientContext::ClientContext(jobject jsvnclient, SVN::Pool &pool) - : m_prompter(NULL), - m_cancelOperation(false) +void +CommonContext::attachJavaObject(jobject contextHolder, const char *contextClassType, + const char *contextFieldName, jfieldID * ctxFieldID) { - JNIEnv *env = JNIUtil::getEnv(); + JNIEnv *env = JNIUtil::getEnv(); - /* Grab a global reference to the Java object embedded in the parent Java - object. */ - static jfieldID ctxFieldID = 0; - if (ctxFieldID == 0) + /* Grab a global reference to the Java object embedded in the parent Java + object. */ + if ((*ctxFieldID) == 0) { - jclass clazz = env->GetObjectClass(jsvnclient); - if (JNIUtil::isJavaExceptionThrown()) - return; - - ctxFieldID = env->GetFieldID(clazz, "clientContext", - "L"JAVA_PACKAGE"/SVNClient$ClientContext;"); - if (JNIUtil::isJavaExceptionThrown() || ctxFieldID == 0) - return; - - env->DeleteLocalRef(clazz); - } - - jobject jctx = env->GetObjectField(jsvnclient, ctxFieldID); - if (JNIUtil::isJavaExceptionThrown()) + jclass clazz = env->GetObjectClass(contextHolder); + if (JNIUtil::isJavaExceptionThrown()) return; - m_jctx = env->NewGlobalRef(jctx); - if (JNIUtil::isJavaExceptionThrown()) + (*ctxFieldID) = env->GetFieldID(clazz, contextFieldName, contextClassType); + if (JNIUtil::isJavaExceptionThrown() || (*ctxFieldID) == 0) return; - env->DeleteLocalRef(jctx); + env->DeleteLocalRef(clazz); + } - SVN_JNI_ERR(svn_client_create_context(&m_context, pool.getPool()), - ); + jobject jctx = env->GetObjectField(contextHolder, (*ctxFieldID)); + if (JNIUtil::isJavaExceptionThrown()) + return; - /* Clear the wc_ctx as we don't want to maintain this unconditionally - for compatibility reasons */ - SVN_JNI_ERR(svn_wc_context_destroy(m_context->wc_ctx), - ); - m_context->wc_ctx = NULL; + m_jctx = env->NewGlobalRef(jctx); + if (JNIUtil::isJavaExceptionThrown()) + return; - /* None of the following members change during the lifetime of - this object. */ - m_context->notify_func = NULL; - m_context->notify_baton = NULL; - m_context->log_msg_func3 = CommitMessage::callback; - m_context->log_msg_baton3 = NULL; - m_context->cancel_func = checkCancel; - m_context->cancel_baton = this; - m_context->notify_func2= notify; - m_context->notify_baton2 = m_jctx; - m_context->progress_func = progress; - m_context->progress_baton = m_jctx; - m_context->conflict_func2 = resolve; - m_context->conflict_baton2 = m_jctx; - - m_context->client_name = "javahl"; - m_pool = &pool; + env->DeleteLocalRef(jctx); } -ClientContext::~ClientContext() +CommonContext::~CommonContext() { - delete m_prompter; + delete m_prompter; - JNIEnv *env = JNIUtil::getEnv(); - env->DeleteGlobalRef(m_jctx); + JNIEnv *env = JNIUtil::getEnv(); + env->DeleteGlobalRef(m_jctx); } - -/* Helper function to make sure that we don't keep dangling pointers in ctx. - Note that this function might be called multiple times if getContext() - is called on the same pool. - - The use of this function assumes a proper subpool behavior by its user, - (read: SVNClient) usually per request. - */ -extern "C" { - -struct clearctx_baton_t +apr_hash_t * +CommonContext::getConfigData() { - svn_client_ctx_t *ctx; - svn_client_ctx_t *backup; -}; + if(m_pool->getPool() == NULL) + { + JNIUtil::throwNullPointerException("pool is null"); + } -static apr_status_t clear_ctx_ptrs(void *ptr) -{ - clearctx_baton_t *bt = (clearctx_baton_t*)ptr; + if (m_config == NULL) + { + const char *configDir = m_configDir.c_str(); + if (m_configDir.empty()) + configDir = NULL; + SVN_JNI_ERR( + svn_config_get_config(&m_config, configDir, m_pool->getPool()), NULL); + } - /* Reset all values to those before overwriting by getContext. */ - *bt->ctx = *bt->backup; - - return APR_SUCCESS; + return m_config; } -}; - -svn_client_ctx_t * -ClientContext::getContext(CommitMessage *message, SVN::Pool &in_pool) +svn_auth_baton_t * +CommonContext::getAuthBaton(SVN::Pool &in_pool) { - apr_pool_t *pool = in_pool.getPool(); - svn_auth_baton_t *ab; - svn_client_ctx_t *ctx = m_context; + svn_auth_baton_t *ab; + apr_pool_t *pool = in_pool.getPool(); - /* Make a temporary copy of ctx to restore at pool cleanup to avoid - leaving references to dangling pointers. + apr_hash_t * configData = getConfigData(); - Note that this allows creating a stack of context changes if - the function is invoked multiple times with different pools. - */ - clearctx_baton_t *bt = (clearctx_baton_t *)apr_pcalloc(pool, sizeof(*bt)); - bt->ctx = ctx; - bt->backup = (svn_client_ctx_t*)apr_pmemdup(pool, ctx, sizeof(*ctx)); - apr_pool_cleanup_register(in_pool.getPool(), bt, clear_ctx_ptrs, - clear_ctx_ptrs); + if (configData == NULL) + { + return NULL; + } + svn_config_t *config = (svn_config_t *) apr_hash_get(configData, + SVN_CONFIG_CATEGORY_CONFIG, APR_HASH_KEY_STRING); - if (!ctx->config) - { - const char *configDir = m_configDir.c_str(); - if (m_configDir.empty()) - configDir = NULL; - SVN_JNI_ERR(svn_config_get_config(&(ctx->config), configDir, - m_pool->getPool()), - NULL); + /* The whole list of registered providers */ + apr_array_header_t *providers; - bt->backup->config = ctx->config; - } - svn_config_t *config = (svn_config_t *) apr_hash_get(ctx->config, - SVN_CONFIG_CATEGORY_CONFIG, - APR_HASH_KEY_STRING); + /* Populate the registered providers with the platform-specific providers */ + SVN_JNI_ERR( + svn_auth_get_platform_specific_client_providers(&providers, config, pool), + NULL); + /* Use the prompter (if available) to prompt for password and cert + * caching. */ + svn_auth_plaintext_prompt_func_t plaintext_prompt_func = NULL; + void *plaintext_prompt_baton = NULL; + svn_auth_plaintext_passphrase_prompt_func_t plaintext_passphrase_prompt_func; + void *plaintext_passphrase_prompt_baton = NULL; - /* The whole list of registered providers */ - apr_array_header_t *providers; - - /* Populate the registered providers with the platform-specific providers */ - SVN_JNI_ERR(svn_auth_get_platform_specific_client_providers(&providers, - config, - pool), - NULL); - - /* Use the prompter (if available) to prompt for password and cert - * caching. */ - svn_auth_plaintext_prompt_func_t plaintext_prompt_func = NULL; - void *plaintext_prompt_baton = NULL; - svn_auth_plaintext_passphrase_prompt_func_t plaintext_passphrase_prompt_func; - void *plaintext_passphrase_prompt_baton = NULL; - - if (m_prompter != NULL) + if (m_prompter != NULL) { - plaintext_prompt_func = Prompter::plaintext_prompt; - plaintext_prompt_baton = m_prompter; - plaintext_passphrase_prompt_func = Prompter::plaintext_passphrase_prompt; - plaintext_passphrase_prompt_baton = m_prompter; + plaintext_prompt_func = Prompter::plaintext_prompt; + plaintext_prompt_baton = m_prompter; + plaintext_passphrase_prompt_func = Prompter::plaintext_passphrase_prompt; + plaintext_passphrase_prompt_baton = m_prompter; } - /* The main disk-caching auth providers, for both - * 'username/password' creds and 'username' creds. */ - svn_auth_provider_object_t *provider; + /* The main disk-caching auth providers, for both + * 'username/password' creds and 'username' creds. */ + svn_auth_provider_object_t *provider; - svn_auth_get_simple_provider2(&provider, plaintext_prompt_func, - plaintext_prompt_baton, pool); - APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; + svn_auth_get_simple_provider2(&provider, plaintext_prompt_func, + plaintext_prompt_baton, pool); + APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; - svn_auth_get_username_provider(&provider, pool); - APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; + svn_auth_get_username_provider(&provider, pool); + APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; - /* The server-cert, client-cert, and client-cert-password providers. */ - SVN_JNI_ERR(svn_auth_get_platform_specific_provider(&provider, - "windows", - "ssl_server_trust", - pool), - NULL); + /* The server-cert, client-cert, and client-cert-password providers. */ + SVN_JNI_ERR( + svn_auth_get_platform_specific_provider(&provider, "windows", "ssl_server_trust", pool), + NULL); - if (provider) - APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; - - svn_auth_get_ssl_server_trust_file_provider(&provider, pool); + if (provider) APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; - svn_auth_get_ssl_client_cert_file_provider(&provider, pool); - APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; - svn_auth_get_ssl_client_cert_pw_file_provider2(&provider, - plaintext_passphrase_prompt_func, - plaintext_passphrase_prompt_baton, pool); - APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; - if (m_prompter != NULL) + svn_auth_get_ssl_server_trust_file_provider(&provider, pool); + APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; + svn_auth_get_ssl_client_cert_file_provider(&provider, pool); + APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; + svn_auth_get_ssl_client_cert_pw_file_provider2(&provider, + plaintext_passphrase_prompt_func, plaintext_passphrase_prompt_baton, + pool); + APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; + + if (m_prompter != NULL) { - /* Two basic prompt providers: username/password, and just username.*/ - provider = m_prompter->getProviderSimple(in_pool); + /* Two basic prompt providers: username/password, and just username.*/ + provider = m_prompter->getProviderSimple(in_pool); - APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; + APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; - provider = m_prompter->getProviderUsername(in_pool); - APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; + provider = m_prompter->getProviderUsername(in_pool); + APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; - /* Three ssl prompt providers, for server-certs, client-certs, - * and client-cert-passphrases. */ - provider = m_prompter->getProviderServerSSLTrust(in_pool); - APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; + /* Three ssl prompt providers, for server-certs, client-certs, + * and client-cert-passphrases. */ + provider = m_prompter->getProviderServerSSLTrust(in_pool); + APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; - provider = m_prompter->getProviderClientSSL(in_pool); - APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; + provider = m_prompter->getProviderClientSSL(in_pool); + APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; - provider = m_prompter->getProviderClientSSLPassword(in_pool); - APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; + provider = m_prompter->getProviderClientSSLPassword(in_pool); + APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; } - /* Build an authentication baton to give to libsvn_client. */ - svn_auth_open(&ab, providers, pool); + /* Build an authentication baton to give to libsvn_client. */ + svn_auth_open(&ab, providers, pool); - /* Place any default --username or --password credentials into the - * auth_baton's run-time parameter hash. ### Same with --no-auth-cache? */ - if (!m_userName.empty()) - svn_auth_set_parameter(ab, SVN_AUTH_PARAM_DEFAULT_USERNAME, - apr_pstrdup(in_pool.getPool(), - m_userName.c_str())); - if (!m_passWord.empty()) - svn_auth_set_parameter(ab, SVN_AUTH_PARAM_DEFAULT_PASSWORD, - apr_pstrdup(in_pool.getPool(), - m_passWord.c_str())); - /* Store where to retrieve authentication data? */ - if (!m_configDir.empty()) - svn_auth_set_parameter(ab, SVN_AUTH_PARAM_CONFIG_DIR, - apr_pstrdup(in_pool.getPool(), - m_configDir.c_str())); - - ctx->auth_baton = ab; - ctx->log_msg_baton3 = message; - m_cancelOperation = false; - - SVN_JNI_ERR(svn_wc_context_create(&ctx->wc_ctx, NULL, - in_pool.getPool(), in_pool.getPool()), - NULL); - - return ctx; + /* Place any default --username or --password credentials into the + * auth_baton's run-time parameter hash. ### Same with --no-auth-cache? */ + if (!m_userName.empty()) + svn_auth_set_parameter(ab, SVN_AUTH_PARAM_DEFAULT_USERNAME, + apr_pstrdup(in_pool.getPool(), m_userName.c_str())); + if (!m_passWord.empty()) + svn_auth_set_parameter(ab, SVN_AUTH_PARAM_DEFAULT_PASSWORD, + apr_pstrdup(in_pool.getPool(), m_passWord.c_str())); + /* Store where to retrieve authentication data? */ + if (!m_configDir.empty()) + svn_auth_set_parameter(ab, SVN_AUTH_PARAM_CONFIG_DIR, + apr_pstrdup(in_pool.getPool(), m_configDir.c_str())); + return ab; } void -ClientContext::username(const char *pi_username) +CommonContext::username(const char *pi_username) { - m_userName = (pi_username == NULL ? "" : pi_username); + m_userName = (pi_username == NULL ? "" : pi_username); } void -ClientContext::password(const char *pi_password) +CommonContext::password(const char *pi_password) { - m_passWord = (pi_password == NULL ? "" : pi_password); + m_passWord = (pi_password == NULL ? "" : pi_password); } void -ClientContext::setPrompt(Prompter *prompter) +CommonContext::setPrompt(Prompter *prompter) { - delete m_prompter; - m_prompter = prompter; + delete m_prompter; + m_prompter = prompter; } void -ClientContext::setConfigDirectory(const char *configDir) +CommonContext::setConfigDirectory(const char *configDir) { - // A change to the config directory may necessitate creation of - // the config templates. - SVN::Pool requestPool; - SVN_JNI_ERR(svn_config_ensure(configDir, requestPool.getPool()), ); + // A change to the config directory may necessitate creation of + // the config templates. + SVN::Pool requestPool; + SVN_JNI_ERR(svn_config_ensure(configDir, requestPool.getPool()), ); - m_configDir = (configDir == NULL ? "" : configDir); - m_context->config = NULL; + m_configDir = (configDir == NULL ? "" : configDir); + + m_config = NULL; } const char * -ClientContext::getConfigDirectory() const +CommonContext::getConfigDirectory() const { - return m_configDir.c_str(); + return m_configDir.c_str(); } void -ClientContext::cancelOperation() +CommonContext::cancelOperation() { - m_cancelOperation = true; + m_cancelOperation = true; } -svn_error_t * -ClientContext::checkCancel(void *cancelBaton) +void +CommonContext::resetOperation() { - ClientContext *that = (ClientContext *)cancelBaton; - if (that->m_cancelOperation) - return svn_error_create(SVN_ERR_CANCELLED, NULL, - _("Operation cancelled")); - else - return SVN_NO_ERROR; + m_cancelOperation = false; } -void -ClientContext::notify(void *baton, - const svn_wc_notify_t *notify, - apr_pool_t *pool) +bool +CommonContext::isCancelledOperation() { - jobject jctx = (jobject) baton; - JNIEnv *env = JNIUtil::getEnv(); + return m_cancelOperation; +} - static jmethodID mid = 0; - if (mid == 0) - { - jclass clazz = env->GetObjectClass(jctx); - if (JNIUtil::isJavaExceptionThrown()) - return; - - mid = env->GetMethodID(clazz, "onNotify", - "(L"JAVA_PACKAGE"/ClientNotifyInformation;)V"); - if (JNIUtil::isJavaExceptionThrown() || mid == 0) - return; - - env->DeleteLocalRef(clazz); - } - - jobject jInfo = CreateJ::ClientNotifyInformation(notify); - if (JNIUtil::isJavaExceptionThrown()) - return; - - env->CallVoidMethod(jctx, mid, jInfo); - if (JNIUtil::isJavaExceptionThrown()) - return; - - env->DeleteLocalRef(jInfo); +svn_error_t * +CommonContext::checkCancel(void *cancelBaton) +{ + CommonContext *that = (CommonContext *) cancelBaton; + if (that->isCancelledOperation()) + return svn_error_create(SVN_ERR_CANCELLED, NULL, _("Operation cancelled")); + else + return SVN_NO_ERROR; } void -ClientContext::progress(apr_off_t progressVal, apr_off_t total, - void *baton, apr_pool_t *pool) +CommonContext::progress(apr_off_t progressVal, apr_off_t total, void *baton, + apr_pool_t *pool) { jobject jctx = (jobject) baton; JNIEnv *env = JNIUtil::getEnv(); @@ -385,7 +295,7 @@ void POP_AND_RETURN_NOTHING(); mid = env->GetMethodID(clazz, "onProgress", - "(L"JAVA_PACKAGE"/ProgressEvent;)V"); + "(L"JAVA_PACKAGE"/ProgressEvent;)V"); if (JNIUtil::isJavaExceptionThrown() || mid == 0) POP_AND_RETURN_NOTHING(); } @@ -403,8 +313,8 @@ void } // Call the Java method. - jobject jevent = env->NewObject(clazz, midCT, - (jlong) progressVal, (jlong) total); + jobject jevent = env->NewObject(clazz, midCT, (jlong) progressVal, + (jlong) total); if (JNIUtil::isJavaExceptionThrown()) POP_AND_RETURN_NOTHING(); @@ -413,119 +323,18 @@ void POP_AND_RETURN_NOTHING(); } -svn_error_t * -ClientContext::resolve(svn_wc_conflict_result_t **result, - const svn_wc_conflict_description2_t *desc, - void *baton, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool) +const char * +CommonContext::getClientName() const { - jobject jctx = (jobject) baton; - JNIEnv *env = JNIUtil::getEnv(); - - // Create a local frame for our references - env->PushLocalFrame(LOCAL_FRAME_SIZE); - if (JNIUtil::isJavaExceptionThrown()) - return SVN_NO_ERROR; - - static jmethodID mid = 0; - if (mid == 0) - { - jclass clazz = env->GetObjectClass(jctx); - if (JNIUtil::isJavaExceptionThrown()) - POP_AND_RETURN(SVN_NO_ERROR); - - mid = env->GetMethodID(clazz, "resolve", - "(L"JAVA_PACKAGE"/ConflictDescriptor;)" - "L"JAVA_PACKAGE"/ConflictResult;"); - if (JNIUtil::isJavaExceptionThrown() || mid == 0) - POP_AND_RETURN(SVN_NO_ERROR); - } - - // Create an instance of the conflict descriptor. - jobject jdesc = CreateJ::ConflictDescriptor(desc); - if (JNIUtil::isJavaExceptionThrown()) - POP_AND_RETURN(SVN_NO_ERROR); - - // Invoke the Java conflict resolver callback method using the descriptor. - jobject jresult = env->CallObjectMethod(jctx, mid, jdesc); - if (JNIUtil::isJavaExceptionThrown()) - { - // If an exception is thrown by our conflict resolver, remove it - // from the JNI env, and convert it into a Subversion error. - SVN::Pool tmpPool(scratch_pool); - const char *msg = JNIUtil::thrownExceptionToCString(tmpPool); - svn_error_t *err = svn_error_create(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, - NULL, msg); - env->PopLocalFrame(NULL); - return err; - } - - *result = javaResultToC(jresult, result_pool); - if (*result == NULL) - { - // Unable to convert the result into a C representation. - env->PopLocalFrame(NULL); - return svn_error_create(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL, NULL); - } - - env->PopLocalFrame(NULL); - return SVN_NO_ERROR; + return "javahl"; } -svn_wc_conflict_result_t * -ClientContext::javaResultToC(jobject jresult, apr_pool_t *pool) +svn_error_t * +CommonContext::clientName(void *baton, const char **name, apr_pool_t *pool) { - JNIEnv *env = JNIUtil::getEnv(); + CommonContext *that = (CommonContext *) baton; - // Create a local frame for our references - env->PushLocalFrame(LOCAL_FRAME_SIZE); - if (JNIUtil::isJavaExceptionThrown()) - return SVN_NO_ERROR; + *name = that->getClientName(); - static jmethodID getChoice = 0; - static jmethodID getMergedPath = 0; - - jclass clazz = NULL; - if (getChoice == 0 || getMergedPath == 0) - { - clazz = env->FindClass(JAVA_PACKAGE "/ConflictResult"); - if (JNIUtil::isJavaExceptionThrown()) - POP_AND_RETURN_NULL; - } - - if (getChoice == 0) - { - getChoice = env->GetMethodID(clazz, "getChoice", - "()L"JAVA_PACKAGE"/ConflictResult$Choice;"); - if (JNIUtil::isJavaExceptionThrown() || getChoice == 0) - POP_AND_RETURN_NULL; - } - if (getMergedPath == 0) - { - getMergedPath = env->GetMethodID(clazz, "getMergedPath", - "()Ljava/lang/String;"); - if (JNIUtil::isJavaExceptionThrown() || getMergedPath == 0) - POP_AND_RETURN_NULL; - } - - jobject jchoice = env->CallObjectMethod(jresult, getChoice); - if (JNIUtil::isJavaExceptionThrown()) - POP_AND_RETURN_NULL; - - jstring jmergedPath = (jstring) env->CallObjectMethod(jresult, getMergedPath); - if (JNIUtil::isJavaExceptionThrown()) - POP_AND_RETURN_NULL; - - JNIStringHolder mergedPath(jmergedPath); - if (JNIUtil::isJavaExceptionThrown()) - POP_AND_RETURN_NULL; - - svn_wc_conflict_result_t *result = - svn_wc_create_conflict_result(EnumMapper::toConflictChoice(jchoice), - mergedPath.pstrdup(pool), - pool); - - env->PopLocalFrame(NULL); - return result; + return SVN_NO_ERROR; } Index: subversion/bindings/javahl/native/ClientContext.cpp =================================================================== --- subversion/bindings/javahl/native/ClientContext.cpp (revision 1328758) +++ subversion/bindings/javahl/native/ClientContext.cpp (working copy) @@ -39,38 +39,11 @@ ClientContext::ClientContext(jobject jsvnclient, SVN::Pool &pool) - : m_prompter(NULL), - m_cancelOperation(false) +: CommonContext(pool) { - JNIEnv *env = JNIUtil::getEnv(); - - /* Grab a global reference to the Java object embedded in the parent Java - object. */ static jfieldID ctxFieldID = 0; - if (ctxFieldID == 0) - { - jclass clazz = env->GetObjectClass(jsvnclient); - if (JNIUtil::isJavaExceptionThrown()) - return; + attachJavaObject(jsvnclient, "L"JAVA_PACKAGE"/SVNClient$ClientContext;", "clientContext", &ctxFieldID); - ctxFieldID = env->GetFieldID(clazz, "clientContext", - "L"JAVA_PACKAGE"/SVNClient$ClientContext;"); - if (JNIUtil::isJavaExceptionThrown() || ctxFieldID == 0) - return; - - env->DeleteLocalRef(clazz); - } - - jobject jctx = env->GetObjectField(jsvnclient, ctxFieldID); - if (JNIUtil::isJavaExceptionThrown()) - return; - - m_jctx = env->NewGlobalRef(jctx); - if (JNIUtil::isJavaExceptionThrown()) - return; - - env->DeleteLocalRef(jctx); - SVN_JNI_ERR(svn_client_create_context(&m_context, pool.getPool()), ); @@ -95,16 +68,11 @@ ClientContext::ClientContext(jobject jsvnclient, S m_context->conflict_func2 = resolve; m_context->conflict_baton2 = m_jctx; - m_context->client_name = "javahl"; - m_pool = &pool; + m_context->client_name = getClientName(); } ClientContext::~ClientContext() { - delete m_prompter; - - JNIEnv *env = JNIUtil::getEnv(); - env->DeleteGlobalRef(m_jctx); } @@ -139,7 +107,6 @@ svn_client_ctx_t * ClientContext::getContext(CommitMessage *message, SVN::Pool &in_pool) { apr_pool_t *pool = in_pool.getPool(); - svn_auth_baton_t *ab; svn_client_ctx_t *ctx = m_context; /* Make a temporary copy of ctx to restore at pool cleanup to avoid @@ -154,121 +121,17 @@ ClientContext::getContext(CommitMessage *message, apr_pool_cleanup_register(in_pool.getPool(), bt, clear_ctx_ptrs, clear_ctx_ptrs); - if (!ctx->config) { - const char *configDir = m_configDir.c_str(); - if (m_configDir.empty()) - configDir = NULL; - SVN_JNI_ERR(svn_config_get_config(&(ctx->config), configDir, - m_pool->getPool()), - NULL); + apr_hash_t * configData = getConfigData(); + ctx->config = configData; bt->backup->config = ctx->config; } - svn_config_t *config = (svn_config_t *) apr_hash_get(ctx->config, - SVN_CONFIG_CATEGORY_CONFIG, - APR_HASH_KEY_STRING); - - /* The whole list of registered providers */ - apr_array_header_t *providers; - - /* Populate the registered providers with the platform-specific providers */ - SVN_JNI_ERR(svn_auth_get_platform_specific_client_providers(&providers, - config, - pool), - NULL); - - /* Use the prompter (if available) to prompt for password and cert - * caching. */ - svn_auth_plaintext_prompt_func_t plaintext_prompt_func = NULL; - void *plaintext_prompt_baton = NULL; - svn_auth_plaintext_passphrase_prompt_func_t plaintext_passphrase_prompt_func; - void *plaintext_passphrase_prompt_baton = NULL; - - if (m_prompter != NULL) - { - plaintext_prompt_func = Prompter::plaintext_prompt; - plaintext_prompt_baton = m_prompter; - plaintext_passphrase_prompt_func = Prompter::plaintext_passphrase_prompt; - plaintext_passphrase_prompt_baton = m_prompter; - } - - /* The main disk-caching auth providers, for both - * 'username/password' creds and 'username' creds. */ - svn_auth_provider_object_t *provider; - - svn_auth_get_simple_provider2(&provider, plaintext_prompt_func, - plaintext_prompt_baton, pool); - APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; - - svn_auth_get_username_provider(&provider, pool); - APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; - - /* The server-cert, client-cert, and client-cert-password providers. */ - SVN_JNI_ERR(svn_auth_get_platform_specific_provider(&provider, - "windows", - "ssl_server_trust", - pool), - NULL); - - if (provider) - APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; - - svn_auth_get_ssl_server_trust_file_provider(&provider, pool); - APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; - svn_auth_get_ssl_client_cert_file_provider(&provider, pool); - APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; - svn_auth_get_ssl_client_cert_pw_file_provider2(&provider, - plaintext_passphrase_prompt_func, - plaintext_passphrase_prompt_baton, pool); - APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; - - if (m_prompter != NULL) - { - /* Two basic prompt providers: username/password, and just username.*/ - provider = m_prompter->getProviderSimple(in_pool); - - APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; - - provider = m_prompter->getProviderUsername(in_pool); - APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; - - /* Three ssl prompt providers, for server-certs, client-certs, - * and client-cert-passphrases. */ - provider = m_prompter->getProviderServerSSLTrust(in_pool); - APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; - - provider = m_prompter->getProviderClientSSL(in_pool); - APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; - - provider = m_prompter->getProviderClientSSLPassword(in_pool); - APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; - } - - /* Build an authentication baton to give to libsvn_client. */ - svn_auth_open(&ab, providers, pool); - - /* Place any default --username or --password credentials into the - * auth_baton's run-time parameter hash. ### Same with --no-auth-cache? */ - if (!m_userName.empty()) - svn_auth_set_parameter(ab, SVN_AUTH_PARAM_DEFAULT_USERNAME, - apr_pstrdup(in_pool.getPool(), - m_userName.c_str())); - if (!m_passWord.empty()) - svn_auth_set_parameter(ab, SVN_AUTH_PARAM_DEFAULT_PASSWORD, - apr_pstrdup(in_pool.getPool(), - m_passWord.c_str())); - /* Store where to retrieve authentication data? */ - if (!m_configDir.empty()) - svn_auth_set_parameter(ab, SVN_AUTH_PARAM_CONFIG_DIR, - apr_pstrdup(in_pool.getPool(), - m_configDir.c_str())); - - ctx->auth_baton = ab; + ctx->auth_baton = getAuthBaton(in_pool); ctx->log_msg_baton3 = message; - m_cancelOperation = false; + resetOperation(); SVN_JNI_ERR(svn_wc_context_create(&ctx->wc_ctx, NULL, in_pool.getPool(), in_pool.getPool()), @@ -278,60 +141,6 @@ ClientContext::getContext(CommitMessage *message, } void -ClientContext::username(const char *pi_username) -{ - m_userName = (pi_username == NULL ? "" : pi_username); -} - -void -ClientContext::password(const char *pi_password) -{ - m_passWord = (pi_password == NULL ? "" : pi_password); -} - -void -ClientContext::setPrompt(Prompter *prompter) -{ - delete m_prompter; - m_prompter = prompter; -} - -void -ClientContext::setConfigDirectory(const char *configDir) -{ - // A change to the config directory may necessitate creation of - // the config templates. - SVN::Pool requestPool; - SVN_JNI_ERR(svn_config_ensure(configDir, requestPool.getPool()), ); - - m_configDir = (configDir == NULL ? "" : configDir); - m_context->config = NULL; -} - -const char * -ClientContext::getConfigDirectory() const -{ - return m_configDir.c_str(); -} - -void -ClientContext::cancelOperation() -{ - m_cancelOperation = true; -} - -svn_error_t * -ClientContext::checkCancel(void *cancelBaton) -{ - ClientContext *that = (ClientContext *)cancelBaton; - if (that->m_cancelOperation) - return svn_error_create(SVN_ERR_CANCELLED, NULL, - _("Operation cancelled")); - else - return SVN_NO_ERROR; -} - -void ClientContext::notify(void *baton, const svn_wc_notify_t *notify, apr_pool_t *pool) @@ -365,54 +174,6 @@ ClientContext::notify(void *baton, env->DeleteLocalRef(jInfo); } -void -ClientContext::progress(apr_off_t progressVal, apr_off_t total, - void *baton, apr_pool_t *pool) -{ - jobject jctx = (jobject) baton; - JNIEnv *env = JNIUtil::getEnv(); - - // Create a local frame for our references - env->PushLocalFrame(LOCAL_FRAME_SIZE); - if (JNIUtil::isJavaExceptionThrown()) - return; - - static jmethodID mid = 0; - if (mid == 0) - { - jclass clazz = env->GetObjectClass(jctx); - if (JNIUtil::isJavaExceptionThrown()) - POP_AND_RETURN_NOTHING(); - - mid = env->GetMethodID(clazz, "onProgress", - "(L"JAVA_PACKAGE"/ProgressEvent;)V"); - if (JNIUtil::isJavaExceptionThrown() || mid == 0) - POP_AND_RETURN_NOTHING(); - } - - static jmethodID midCT = 0; - jclass clazz = env->FindClass(JAVA_PACKAGE"/ProgressEvent"); - if (JNIUtil::isJavaExceptionThrown()) - POP_AND_RETURN_NOTHING(); - - if (midCT == 0) - { - midCT = env->GetMethodID(clazz, "", "(JJ)V"); - if (JNIUtil::isJavaExceptionThrown() || midCT == 0) - POP_AND_RETURN_NOTHING(); - } - - // Call the Java method. - jobject jevent = env->NewObject(clazz, midCT, - (jlong) progressVal, (jlong) total); - if (JNIUtil::isJavaExceptionThrown()) - POP_AND_RETURN_NOTHING(); - - env->CallVoidMethod(jctx, mid, jevent); - - POP_AND_RETURN_NOTHING(); -} - svn_error_t * ClientContext::resolve(svn_wc_conflict_result_t **result, const svn_wc_conflict_description2_t *desc, Index: subversion/bindings/javahl/native/CommonContext.h =================================================================== --- subversion/bindings/javahl/native/CommonContext.h (working copy) +++ subversion/bindings/javahl/native/CommonContext.h (working copy) @@ -20,12 +20,12 @@ * ==================================================================== * @endcopyright * - * @file ClientContext.h - * @brief Interface of the class ClientContext + * @file CommonContext.h + * @brief Interface of the class CommonContext */ -#ifndef CLIENTCONTEXT_H -#define CLIENTCONTEXT_H +#ifndef COMMONCONTEXT_H +#define COMMONCONTEXT_H #include @@ -37,52 +37,43 @@ #include "JNIStringHolder.h" class Prompter; -class CommitMessage; /** - * This class contains a Java objects implementing the interface ClientContext - * and implements the functions read & close of svn_stream_t. - * + * This class contains a Java objects implementing the interface CommonContext */ -class ClientContext +class CommonContext { private: - svn_client_ctx_t *m_context; - const SVN::Pool *m_pool; - jobject m_jctx; - std::string m_userName; std::string m_passWord; std::string m_configDir; + apr_hash_t * m_config; + Prompter *m_prompter; bool m_cancelOperation; protected: - static void notify(void *baton, const svn_wc_notify_t *notify, - apr_pool_t *pool); + SVN::Pool *m_pool; + + jobject m_jctx; static void progress(apr_off_t progressVal, apr_off_t total, void *baton, apr_pool_t *pool); - static svn_error_t *resolve(svn_wc_conflict_result_t **result, - const svn_wc_conflict_description2_t *desc, - void *baton, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool); - static svn_wc_conflict_result_t *javaResultToC(jobject result, - apr_pool_t *pool); - public: - ClientContext(jobject jsvnclient, SVN::Pool &pool); - ~ClientContext(); + CommonContext(SVN::Pool &pool); + void attachJavaObject(jobject contextHolder, const char *contextClassType, const char *contextFieldName, jfieldID * ctxFieldID); + virtual ~CommonContext(); static svn_error_t *checkCancel(void *cancelBaton); - svn_client_ctx_t *getContext(CommitMessage *message, SVN::Pool &in_pool); + virtual void username(const char *pi_username); + virtual void password(const char *pi_password); + virtual void setPrompt(Prompter *prompter); + svn_auth_baton_t *getAuthBaton(SVN::Pool &in_pool); - void username(const char *pi_username); - void password(const char *pi_password); - void setPrompt(Prompter *prompter); void cancelOperation(); + void resetOperation(); + virtual bool isCancelledOperation(); const char *getConfigDirectory() const; /** @@ -91,6 +82,15 @@ class Prompter; * specified location. */ void setConfigDirectory(const char *configDir); + + /** + * Return configuration data for the context. + * Read it from config directory if necessary + */ + apr_hash_t *getConfigData(); + + static svn_error_t * clientName(void *baton, const char **name, apr_pool_t *pool); + virtual const char * getClientName() const; }; -#endif // CLIENTCONTEXT_H +#endif // COMMONCONTEXT_H