svnclient.cpp
来自「linux subdivision ying gai ke yi le ba」· C++ 代码 · 共 2,291 行 · 第 1/5 页
CPP
2,291 行
/**
* @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 "Prompter.h"
#include "Pool.h"
#include "Targets.h"
#include "Revision.h"
#include "BlameCallback.h"
#include "JNIByteArray.h"
#include "CommitMessage.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_StatusKind.h"
#include "../include/org_tigris_subversion_javahl_Revision.h"
#include "../include/org_tigris_subversion_javahl_NodeKind.h"
#include "../include/org_tigris_subversion_javahl_ScheduleKind.h"
#include "JNIStringHolder.h"
#include <vector>
#include <iostream>
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
struct log_msg_baton
{
const char *message;
CommitMessage *messageHandler;
};
SVNClient::SVNClient()
{
m_notify = NULL;
m_prompter = NULL;
m_commitMessage = NULL;
}
SVNClient::~SVNClient()
{
delete m_notify;
delete m_prompter;
}
jlong SVNClient::getCppAddr()
{
return reinterpret_cast<jlong>(this);
}
SVNClient * SVNClient::getCppObject(jobject jthis)
{
static jfieldID fid = 0;
JNIEnv *env = JNIUtil::getEnv();
if(fid == 0)
{
jclass clazz = env->FindClass(JAVA_PACKAGE"/SVNClient");
if(JNIUtil::isJavaExceptionThrown())
{
return NULL;
}
fid = env->GetFieldID(clazz, "cppAddr", "J");
if(JNIUtil::isJavaExceptionThrown())
{
return NULL;
}
}
jlong cppAddr = env->GetLongField(jthis, fid);
if(JNIUtil::isJavaExceptionThrown())
{
return NULL;
}
return reinterpret_cast<SVNClient*>(cppAddr);
}
void SVNClient::dispose(jobject jthis)
{
delete this;
static jfieldID fid = 0;
JNIEnv *env = JNIUtil::getEnv();
if(fid == 0)
{
jclass clazz = env->FindClass(JAVA_PACKAGE"/SVNClient");
if(JNIUtil::isJavaExceptionThrown())
{
return;
}
fid = env->GetFieldID(clazz, "cppAddr", "J");
if(JNIUtil::isJavaExceptionThrown())
{
return;
}
}
env->SetLongField(jthis, fid, 0);
if(JNIUtil::isJavaExceptionThrown())
{
return;
}
}
void SVNClient::finalize()
{
JNIUtil::putFinalizedClient(this);
}
const char * SVNClient::getLastPath()
{
return m_lastPath.c_str();
}
/**
* List directory entries of a URL
*/
jobjectArray SVNClient::list(const char *url, Revision &revision, 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_ls (&dirents, urlPath.c_str(),
const_cast<svn_opt_revision_t*>(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_status_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_status_t *status)
{
if(JNIUtil::isJavaExceptionThrown())
return;
// we don't create here java Status object as we don't want too many local
// references
status_baton *statusBaton = (status_baton*)baton;
status_entry statusEntry;
statusEntry.path = apr_pstrdup(statusBaton->pool,path);
statusEntry.status = svn_wc_dup_status(status,statusBaton->pool);
statusBaton->statusVect.push_back(statusEntry);
}
jobjectArray SVNClient::status(const char *path, bool descend, bool onServer,
bool getAll, bool noIgnore)
{
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_status (
&youngest, checkedPath.c_str(), &rev, statusReceiver,
&statusBaton, descend ? TRUE : FALSE,
getAll ? TRUE : FALSE,
onServer ? TRUE : FALSE,
noIgnore ? 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_status (&youngest, intPath.c_str(), &rev,
statusReceiver, &statusBaton,
FALSE,
TRUE, // get_All
onServer ? TRUE : FALSE, //update
FALSE, //no_ignore,
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 *username)
{
m_userName = username;
}
void SVNClient::password(const char *password)
{
m_passWord = 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)
{
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_log (targets,
revisionStart.revision (),
revisionEnd.revision (),
discoverPaths,
stopOnCopy,
messageReceiver, &logs, ctx, requestPool.pool());
if(JNIUtil::isJavaExceptionThrown())
{
return NULL;
}
if(Err == NULL)
{
int size = logs.size();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?