SVNKIT 纯java 操作数据库

1 篇文章 0 订阅
[quote]


文章主题是svnkit的api操作。所以涉及到其它类的,可以忽略。svnkit有两套api,high level和low level 。high level是操作工作拷贝即working copy的。

我这儿用的就是high level。


checkWorkCopy方法里面,先检查当前指定的路径是否是一个working copy。如果是,执行update操作;

如果不是的话,分两种情况:

1. svn上已经有以此project命名的项目,可能svn上有了,但working copy被删了什么的。就将该project checkout下来;

2. svn上没有该project。此时checkout一个空的东西。SVNDepth.EMPTY,只是让我们的路径成为一个working copy,路径下出现一个.svn目录,svn上面的文件不会被checkout下来。因为我们的svn上可能项目很多。如果把整个上级目录checkout下来会很慢也浪费硬盘空间。


用 svnkit 执行commit操作,概况来说,流程如下:

1. 保证本地path是一个working copy。 即checkWorkCopy方法


2. woking copy可能发生添加,更新,删除等变化操作

3. 检查working copy里面的文件是否under version control。即checkVersiondDirectory方法

4. 执行commit操作


[/quote]





import java.io.File;

import org.apache.log4j.Logger;
import org.tmatesoft.svn.core.SVNCommitInfo;
import org.tmatesoft.svn.core.SVNDepth;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNNodeKind;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
import org.tmatesoft.svn.core.internal.wc.DefaultSVNOptions;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.wc.SVNClientManager;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc.SVNStatus;
import org.tmatesoft.svn.core.wc.SVNUpdateClient;
import org.tmatesoft.svn.core.wc.SVNWCUtil;

/**
* SVNKit Utility
* @author lena yang
*
*/
public class SVNUtil {

private static Logger logger = Logger.getLogger(SVNUtil.class);

/**
* 通过不同的协议初始化版本库
*/
public static void setupLibrary() {
DAVRepositoryFactory.setup();
SVNRepositoryFactoryImpl.setup();
FSRepositoryFactory.setup();
}

/**
* 验证登录svn
*/
public static SVNClientManager authSvn(String svnRoot, String username,
String password) {
// 初始化版本库
setupLibrary();

// 创建库连接
SVNRepository repository = null;
try {
repository = SVNRepositoryFactory.create(SVNURL
.parseURIEncoded(svnRoot));
} catch (SVNException e) {
logger.error(e.getErrorMessage(), e);
return null;
}

// 身份验证
ISVNAuthenticationManager authManager = SVNWCUtil

.createDefaultAuthenticationManager(username, password);

// 创建身份验证管理器
repository.setAuthenticationManager(authManager);

DefaultSVNOptions options = SVNWCUtil.createDefaultOptions(true);
SVNClientManager clientManager = SVNClientManager.newInstance(options,
authManager);
return clientManager;
}

/**
* Make directory in svn repository
* @param clientManager
* @param url
* eg: http://svn.ambow.com/wlpt/bsp/trunk
* @param commitMessage
* @return
* @throws SVNException
*/
public static SVNCommitInfo makeDirectory(SVNClientManager clientManager,
SVNURL url, String commitMessage) {
try {
return clientManager.getCommitClient().doMkDir(
new SVNURL[] { url }, commitMessage);
} catch (SVNException e) {
logger.error(e.getErrorMessage(), e);
}
return null;
}

/**
* Imports an unversioned directory into a repository location denoted by a
* destination URL
* @param clientManager
* @param localPath
* a local unversioned directory or singal file that will be imported into a
* repository;
* @param dstURL
* a repository location where the local unversioned directory/file will be
* imported into
* @param commitMessage
* @param isRecursive 递归
* @return
*/
public static SVNCommitInfo importDirectory(SVNClientManager clientManager,
File localPath, SVNURL dstURL, String commitMessage,
boolean isRecursive) {
try {
return clientManager.getCommitClient().doImport(localPath, dstURL,
commitMessage, null, true, true,
SVNDepth.fromRecurse(isRecursive));
} catch (SVNException e) {
logger.error(e.getErrorMessage(), e);
}
return null;
}

/**
* Puts directories and files under version control
* @param clientManager
* SVNClientManager
* @param wcPath
* work copy path
*/
public static void addEntry(SVNClientManager clientManager, File wcPath) {
try {
clientManager.getWCClient().doAdd(new File[] { wcPath }, true,
false, false, SVNDepth.INFINITY, false, false,
true);
} catch (SVNException e) {
logger.error(e.getErrorMessage(), e);
}
}

/**
* Collects status information on a single Working Copy item
* @param clientManager
* @param wcPath
* local item's path
* @param remote
* true to check up the status of the item in the repository,
* that will tell if the local item is out-of-date (like '-u' option in the SVN client's
* 'svn status' command), otherwise false
* @return
* @throws SVNException
*/
public static SVNStatus showStatus(SVNClientManager clientManager,
File wcPath, boolean remote) {
SVNStatus status = null;
try {
status = clientManager.getStatusClient().doStatus(wcPath, remote);
} catch (SVNException e) {
logger.error(e.getErrorMessage(), e);
}
return status;
}

/**
* Commit work copy's change to svn
* @param clientManager
* @param wcPath
* working copy paths which changes are to be committed
* @param keepLocks
* whether to unlock or not files in the repository
* @param commitMessage
* commit log message
* @return
* @throws SVNException
*/
public static SVNCommitInfo commit(SVNClientManager clientManager,
File wcPath, boolean keepLocks, String commitMessage) {
try {
return clientManager.getCommitClient().doCommit(
new File[] { wcPath }, keepLocks, commitMessage, null,
null, false, false, SVNDepth.INFINITY);
} catch (SVNException e) {
logger.error(e.getErrorMessage(), e);
}
return null;
}

/**
* Updates a working copy (brings changes from the repository into the working copy).
* @param clientManager
* @param wcPath
* working copy path
* @param updateToRevision
* revision to update to
* @param depth
* update的深度:目录、子目录、文件
* @return
* @throws SVNException
*/
public static long update(SVNClientManager clientManager, File wcPath,
SVNRevision updateToRevision, SVNDepth depth) {
SVNUpdateClient updateClient = clientManager.getUpdateClient();

/*
* sets externals not to be ignored during the update
*/
updateClient.setIgnoreExternals(false);

/*
* returns the number of the revision wcPath was updated to
*/
try {
return updateClient.doUpdate(wcPath, updateToRevision,depth, false, false);
} catch (SVNException e) {
logger.error(e.getErrorMessage(), e);
}
return 0;
}

/**
* recursively checks out a working copy from url into wcDir
* @param clientManager
* @param url
* a repository location from where a Working Copy will be checked out
* @param revision
* the desired revision of the Working Copy to be checked out
* @param destPath
* the local path where the Working Copy will be placed
* @param depth
* checkout的深度,目录、子目录、文件
* @return
* @throws SVNException
*/
public static long checkout(SVNClientManager clientManager, SVNURL url,
SVNRevision revision, File destPath, SVNDepth depth) {

SVNUpdateClient updateClient = clientManager.getUpdateClient();
/*
* sets externals not to be ignored during the checkout
*/
updateClient.setIgnoreExternals(false);
/*
* returns the number of the revision at which the working copy is
*/
try {
return updateClient.doCheckout(url, destPath, revision, revision,depth, false);
} catch (SVNException e) {
logger.error(e.getErrorMessage(), e);
}
return 0;
}

/**
* 确定path是否是一个工作空间
* @param path
* @return
*/
public static boolean isWorkingCopy(File path){
if(!path.exists()){
logger.warn("'" + path + "' not exist!");
return false;
}
try {
if(null == SVNWCUtil.getWorkingCopyRoot(path, false)){
return false;
}
} catch (SVNException e) {
logger.error(e.getErrorMessage(), e);
}
return true;
}

/**
* 确定一个URL在SVN上是否存在
* @param url
* @return
*/
public static boolean isURLExist(SVNURL url,String username,String password){
try {
SVNRepository svnRepository = SVNRepositoryFactory.create(url);
ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(username, password);
svnRepository.setAuthenticationManager(authManager);
SVNNodeKind nodeKind = svnRepository.checkPath("", -1);
return nodeKind == SVNNodeKind.NONE ? false : true;
} catch (SVNException e) {
e.printStackTrace();
}
return false;
}

}


/**
* 创建项目框架,SVN提交、更新
* @author lena yang
*
*/
@Service("svnProjectService")
public class SvnProjectService {

private Logger logger = Logger.getLogger(SvnProjectService.class);

// 项目的存放位置
private String workspace = null;

private ResourceBundle rb = ResourceBundle.getBundle("application");

// SVN的用户名、密码
private String username = null;
private String password = null;

private String templete = null;

@Resource(name="xcodeService")
private XcodeService xcodeService;


private void init(){
String webapp = System.getProperty("webapp.root");
if(null!=webapp&&!webapp.endsWith("/") && !webapp.endsWith("\\")){
webapp = webapp + "/";
}
// 发布到web服务器以后,有可能WebContent没了
if(new File(webapp + "WebContent").exists()){
webapp = webapp + "WebContent";
}
username = rb.getString("svn.username");
password = rb.getString("svn.password");
workspace = rb.getString("project.svn.path");
templete = webapp + "templete";
}

public SvnProjectService(){
super();
init();
}

/**
* 创建项目框架
* @param project
* Project
* @return
*/
public boolean createProjectFrame(Project project,List<String> tableNames) {
if(project == null){
return false;
}
File src = new File(templete); // 模板项目的位置
File ws = new File(workspace); // work copy
if(!ws.exists()){
ws.mkdirs();
}
File dest = new File(workspace + "/" + project.getName());
if(!dest.exists()){
dest.mkdirs();
}

checkWorkCopy(project); // 确定工作空间

// 复制模板项目到工作空间
try {
FileUtils.copyDirectory(src, dest);
} catch (IOException e) {
logger.error(e.getMessage(), e);
return false;
}

//修改.project文件中的内容
editProjectFile(project);

// 生成框架代码
xcodeService.createBaseFrameWithDatasource(project,tableNames);

// 提交到SVN
commitProjectToSvn(project);

return true;
}

/**
* 修改项目文件
* @param project
* @throws DocumentException
* @throws IOException
*/
@SuppressWarnings("unchecked")
private void editProjectFile(Project project) {

String pro = workspace + "/" + project.getName() + "/";

String settings = pro + ".settings/";

// 1. 修改.settings/org.eclipse.wst.common.component
Document document = null;
try {
document = XmlReaderUtil.getDocument(new File(settings
+ "org.eclipse.wst.common.component"));
} catch (DocumentException e) {
e.printStackTrace();
}

Element root = document.getRootElement();

root.element("wb-module").attribute("deploy-name")
.setValue(project.getName());

if (root.element("wb-module").element("property").attribute("name")
.getValue().equals("java-output-path")) {

root.element("wb-module").element("property").attribute("value")
.setValue("/" + project.getName() + "/build/classes");
}

Iterator<Element> itr = (Iterator<Element>) XmlReaderUtil.getElements(
document, "//wb-module//property").iterator();

while (itr.hasNext()) {
Element element = itr.next();
if ("context-root".equals(element.attribute("name").getValue())) {
element.attribute("value").setValue("/" + project.getName());
}
}

// 将修改后的值写入
XmlReaderUtil.writerXml(document, settings
+ "org.eclipse.wst.common.component");

// 2. 修改.project
try {
document = XmlReaderUtil.getDocument(new File(pro + ".project"));
XmlReaderUtil.setElementText(document, "//projectDescription",
"name", project.getName());
XmlReaderUtil.writerXml(document, pro + ".project");
} catch (DocumentException e) {
e.printStackTrace();
}
}

/**
* 从SVN更新项目到work copy
* @param project
* Project
* @return
*/
public boolean updateProjectFromSvn(Project project) {
if(null == project || null == rb.getString("svn.url")){
return false;
}
project.setSvnUrl(rb.getString("svn.url"));

SVNClientManager clientManager = SVNUtil.authSvn(project.getSvnUrl(), username, password);
if (null == clientManager) {
logger.error("SVN login error! >>> url:" + project.getSvnUrl()
+ " username:" + username + " password:" + password);
return false;
}

// 注册一个更新事件处理器
clientManager.getCommitClient().setEventHandler(new UpdateEventHandler());

SVNURL repositoryURL = null;
try {
// eg: http://svn.ambow.com/wlpt/bsp
repositoryURL = SVNURL.parseURIEncoded(project.getSvnUrl()).appendPath("trunk/"+project.getName(), false);
} catch (SVNException e) {
logger.error(e.getMessage(),e);
return false;
}

File ws = new File(new File(workspace), project.getName());
if(!SVNWCUtil.isVersionedDirectory(ws)){
SVNUtil.checkout(clientManager, repositoryURL, SVNRevision.HEAD, new File(workspace), SVNDepth.INFINITY);
}else{
SVNUtil.update(clientManager, ws, SVNRevision.HEAD, SVNDepth.INFINITY);
}
return true;
}

/**
* 提交项目到SVN
* @param project
* Project
* @return
*/
public boolean commitProjectToSvn(Project project) {
SVNClientManager clientManager = SVNUtil.authSvn(project.getSvnUrl(), username, password);

clientManager.getCommitClient().setEventHandler(new CommitEventHandler());

File wc_project = new File( workspace + "/" + project.getName());

checkVersiondDirectory(clientManager,wc_project);

SVNUtil.commit(clientManager, wc_project, false, "svnkit");

return true;
}

/**
* 递归检查不在版本控制的文件,并add到svn
* @param clientManager
* @param wc
*/
private void checkVersiondDirectory(SVNClientManager clientManager,File wc){
if(!SVNWCUtil.isVersionedDirectory(wc)){
SVNUtil.addEntry(clientManager, wc);
}
if(wc.isDirectory()){
for(File sub:wc.listFiles()){
if(sub.isDirectory() && sub.getName().equals(".svn")){
continue;
}
checkVersiondDirectory(clientManager,sub);
}
}
}

private void checkWorkCopy(Project project){
project.setSvnUrl(rb.getString("svn.url"));
SVNClientManager clientManager = SVNUtil.authSvn(project.getSvnUrl(), username, password);

SVNURL repositoryURL = null; // trunk
try {
// eg: http://svn.ambow.com/wlpt/bsp
repositoryURL = SVNURL.parseURIEncoded(project.getSvnUrl())
.appendPath("trunk", false);
} catch (SVNException e) {
logger.error(e.getMessage(),e);
}

File wc = new File(workspace);
File wc_project = new File( workspace + "/" + project.getName());

SVNURL projectURL = null; // projectName
try {
projectURL = repositoryURL.appendPath(project.getName(), false);
} catch (SVNException e) {
logger.error(e.getMessage(),e);
}

if(!SVNUtil.isWorkingCopy(wc)){
if(!SVNUtil.isURLExist(projectURL,username,password)){
SVNUtil.checkout(clientManager, repositoryURL, SVNRevision.HEAD, wc, SVNDepth.EMPTY);
}else{
SVNUtil.checkout(clientManager, projectURL, SVNRevision.HEAD, wc_project, SVNDepth.INFINITY);
}
}else{
SVNUtil.update(clientManager, wc, SVNRevision.HEAD, SVNDepth.INFINITY);
}
}

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值