📄 svnclient.cpp
字号:
/** * @copyright * ==================================================================== * Copyright (c) 2003 CollabNet. All rights reserved. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at http://subversion.tigris.org/license-1.html. * If newer versions of this license are posted there, you may use a * newer version instead, at your option. * * This software consists of voluntary contributions made by many * individuals. For exact contribution history, see the revision * history and logs, available at http://subversion.tigris.org/. * ==================================================================== * @endcopyright */// SVNClient.cpp: implementation of the SVNClient class.////////////////////////////////////////////////////////////////////////#include "SVNClient.h"#include "JNIUtil.h"#include "Notify.h"#include "Notify2.h"#include "Prompter.h"#include "Pool.h"#include "Targets.h"#include "Revision.h"#include "BlameCallback.h"#include "JNIByteArray.h"#include "CommitMessage.h"#include "EnumMapper.h"#include "svn_client.h"#include "svn_sorts.h"#include "svn_time.h"#include "svn_config.h"#include "svn_io.h"#include "svn_path.h"#include "svn_private_config.h"#include "../include/org_tigris_subversion_javahl_Revision.h"#include "../include/org_tigris_subversion_javahl_NodeKind.h"#include "../include/org_tigris_subversion_javahl_StatusKind.h"#include "JNIStringHolder.h"#include <vector>#include <iostream>#include <sstream>//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////struct log_msg_baton{ const char *message; CommitMessage *messageHandler;};SVNClient::SVNClient(){ m_notify = NULL; m_notify2 = NULL; m_prompter = NULL; m_commitMessage = NULL;}SVNClient::~SVNClient(){ delete m_notify; delete m_notify2; delete m_prompter;}SVNClient * SVNClient::getCppObject(jobject jthis){ static jfieldID fid = 0; jlong cppAddr = SVNBase::findCppAddrForJObject(jthis, &fid, JAVA_PACKAGE"/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");}jstring SVNClient::getAdminDirectoryName(){ Pool requestPool; jstring name = JNIUtil::makeJString(svn_wc_get_adm_dir(requestPool.pool())); if (JNIUtil::isJavaExceptionThrown()) { return NULL; } return name;}jboolean SVNClient::isAdminDirectory(const char *name){ Pool requestPool; return svn_wc_is_adm_dir(name, requestPool.pool()) ? JNI_TRUE : JNI_FALSE;}const char * SVNClient::getLastPath(){ return m_lastPath.c_str();}/** * List directory entries of a URL */jobjectArray SVNClient::list(const char *url, Revision &revision, Revision &pegRevision, bool recurse){ Pool requestPool; svn_client_ctx_t *ctx = getContext(NULL); if(ctx == NULL) { return NULL; } if(url == NULL) { JNIUtil::throwNullPointerException("path or url"); return NULL; } Path urlPath(url); svn_error_t *Err = urlPath.error_occured(); if(Err != NULL) { JNIUtil::handleSVNError(Err); return NULL; } apr_hash_t *dirents; Err = svn_client_ls2 (&dirents, urlPath.c_str(), pegRevision.revision(), revision.revision (), recurse, ctx, requestPool.pool()); if (Err == NULL) { apr_array_header_t *array = svn_sort__hash (dirents, svn_sort_compare_items_as_paths, requestPool.pool()); // create the array of DirEntry JNIEnv *env = JNIUtil::getEnv(); jclass clazz = env->FindClass(JAVA_PACKAGE"/DirEntry"); if(JNIUtil::isJavaExceptionThrown()) { return NULL; } jobjectArray ret = env->NewObjectArray(array->nelts, clazz, NULL); if(JNIUtil::isJavaExceptionThrown()) { return NULL; } env->DeleteLocalRef(clazz); if(JNIUtil::isJavaExceptionThrown()) { return NULL; } for (int i = 0; i < array->nelts; i++) { const svn_sort__item_t *item; svn_dirent_t *dirent = NULL; item = &APR_ARRAY_IDX (array, i, const svn_sort__item_t); dirent = (svn_dirent_t *) item->value; jobject obj = createJavaDirEntry((const char *)item->key, dirent); env->SetObjectArrayElement(ret, i, obj); if(JNIUtil::isJavaExceptionThrown()) { return NULL; } env->DeleteLocalRef(obj); if(JNIUtil::isJavaExceptionThrown()) { return NULL; } } return ret; } else { JNIUtil::handleSVNError(Err); return NULL; }}struct status_entry{ const char *path; svn_wc_status2_t *status;};struct status_baton{ std::vector<status_entry> statusVect; apr_pool_t *pool;};/** * callback for svn_client_status (used by status and singleStatus) */void SVNClient::statusReceiver(void *baton, const char *path, svn_wc_status2_t *status){ if(JNIUtil::isJavaExceptionThrown()) return; // Avoid creating Java Status objects here, as there could be // many, and we don't want too many local JNI references. status_baton *statusBaton = (status_baton*)baton; status_entry statusEntry; statusEntry.path = apr_pstrdup(statusBaton->pool,path); statusEntry.status = svn_wc_dup_status2(status,statusBaton->pool); statusBaton->statusVect.push_back(statusEntry);}jobjectArray SVNClient::status(const char *path, bool descend, bool onServer, bool getAll, bool noIgnore, bool ignoreExternals){ status_baton statusBaton; Pool requestPool; svn_revnum_t youngest = SVN_INVALID_REVNUM; svn_opt_revision_t rev; if(path == NULL) { JNIUtil::throwNullPointerException("path"); return NULL; } svn_client_ctx_t *ctx = getContext(NULL); if(ctx == NULL) { return NULL; } Path checkedPath(path); svn_error_t *Err = checkedPath.error_occured(); if(Err != NULL) { JNIUtil::handleSVNError(Err); return NULL; } rev.kind = svn_opt_revision_unspecified; statusBaton.pool = requestPool.pool(); Err = svn_client_status2 ( &youngest, checkedPath.c_str(), &rev, statusReceiver, &statusBaton, descend ? TRUE : FALSE, getAll ? TRUE : FALSE, onServer ? TRUE : FALSE, noIgnore ? TRUE : FALSE, ignoreExternals ? TRUE : FALSE, ctx, requestPool.pool()); if (Err == NULL) { JNIEnv *env = JNIUtil::getEnv(); int size = statusBaton.statusVect.size(); jclass clazz = env->FindClass(JAVA_PACKAGE"/Status"); if(JNIUtil::isJavaExceptionThrown()) { return NULL; } jobjectArray ret = env->NewObjectArray(size, clazz, NULL); if(JNIUtil::isJavaExceptionThrown()) { return NULL; } env->DeleteLocalRef(clazz); if(JNIUtil::isJavaExceptionThrown()) { return NULL; } for(int i = 0; i < size; i++) { status_entry statusEntry = statusBaton.statusVect[i]; jobject jStatus = createJavaStatus(statusEntry.path, statusEntry.status); env->SetObjectArrayElement(ret, i, jStatus); if(JNIUtil::isJavaExceptionThrown()) { return NULL; } env->DeleteLocalRef(jStatus); if(JNIUtil::isJavaExceptionThrown()) { return NULL; } } return ret; } else { JNIUtil::handleSVNError(Err); return NULL; }}jobject SVNClient::singleStatus(const char *path, bool onServer){ status_baton statusBaton; Pool requestPool; svn_revnum_t youngest = SVN_INVALID_REVNUM; svn_opt_revision_t rev; if(path == NULL) { JNIUtil::throwNullPointerException("path"); return NULL; } svn_client_ctx_t *ctx = getContext(NULL); if(ctx == NULL) { return NULL; } rev.kind = svn_opt_revision_unspecified; statusBaton.pool = requestPool.pool(); Path intPath(path); svn_error_t *Err = intPath.error_occured(); if(Err != NULL) { JNIUtil::handleSVNError(Err); return NULL; } Err = svn_client_status2 (&youngest, intPath.c_str(), &rev, statusReceiver, &statusBaton, FALSE, // DESCEND TRUE, // get_All onServer ? TRUE : FALSE, //update FALSE, //no_ignore, FALSE, // ignore externals ctx, requestPool.pool()); if(Err == NULL) { int size = statusBaton.statusVect.size(); if (size == 0) return NULL; // when svn_client_status is used with a directory, the status of the // directory itself and the status of all its direct children are // returned // we just want the status of the directory (ie the status of the // element with the shortest path) int j = 0; for (int i = 0; i < size; i++) { if (strlen(statusBaton.statusVect[i].path) < strlen(statusBaton.statusVect[j].path)) j = i; } jobject jStatus = createJavaStatus(statusBaton.statusVect[j].path, statusBaton.statusVect[j].status); return jStatus; } else { JNIUtil::handleSVNError(Err); return NULL; }}void SVNClient::username(const char *pi_username){ m_userName = (pi_username == NULL ? "" : pi_username);}void SVNClient::password(const char *pi_password){ m_passWord = (pi_password == NULL ? "" : pi_password);}void SVNClient::setPrompt(Prompter *prompter){ delete m_prompter; m_prompter = prompter;}jobjectArray SVNClient::logMessages(const char *path, Revision &revisionStart, Revision &revisionEnd, bool stopOnCopy, bool discoverPaths, long limit){ std::vector<jobject> logs; Pool requestPool; if(path ==NULL) { JNIUtil::throwNullPointerException("path"); return NULL; } svn_client_ctx_t *ctx = getContext(NULL); if(ctx == NULL) { return NULL; } Targets target (path); const apr_array_header_t *targets = target.array(requestPool); svn_error_t *Err = target.error_occured(); if(Err != NULL) { JNIUtil::handleSVNError(Err); return NULL; } Err = svn_client_log2 (targets, revisionStart.revision (), revisionEnd.revision (), limit, discoverPaths, stopOnCopy, messageReceiver, &logs, ctx, requestPool.pool()); if(JNIUtil::isJavaExceptionThrown()) { return NULL; } if(Err == NULL) { int size = logs.size(); JNIEnv *env = JNIUtil::getEnv(); jclass clazz = env->FindClass(JAVA_PACKAGE"/LogMessage"); if(JNIUtil::isJavaExceptionThrown()) { return NULL; } jobjectArray ret = env->NewObjectArray(size, clazz, NULL); if(JNIUtil::isJavaExceptionThrown()) { return NULL; } env->DeleteLocalRef(clazz); if(JNIUtil::isJavaExceptionThrown()) { return NULL; } for(int i = 0; i < size; i++) { jobject log = logs[i]; env->SetObjectArrayElement(ret, i, log); if(JNIUtil::isJavaExceptionThrown()) { return NULL; } env->DeleteLocalRef(log); if(JNIUtil::isJavaExceptionThrown())
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -