SVNKit中怎样使用不同的仓库访问协议?

当你下载了最新版的SVNKit二进制文件并且准备使用它时,一个问题出现了,要创建一个库需要做哪些初始化的步骤?直接与Subversion仓库交互已经在低级层API中实现,主要的仓库访问驱动的接口就是SVNRepository抽象类。这个驱动实现了一些协议,一个协议一个实现。每个驱动由一个抽象工厂类-SVNRepositoryFactory 创建,抽象工厂类也有每一种协议的实现。下面的表格将一种协议和工厂类的实现类一一对应:

svn://(svns://)

SVNRepositoryFactoryImpl

http://(https://)

DAVRepositoryFactory

file:///

FSRepositoryFactory

SVNKit初始化的操作

在使用SVNKit库前,你必须为某一特定的协议创建一个合适的SVNRepositryFactory对象。例如,如果你想使用 svn:// 协议来和仓库交互,你必须注册一下SVNRepositoryFactoryImpl工厂:

  1. try {
  2. SVNRepositoryFactoryImpl.setup();
  3. ...
  4. } catch (SVNException e) {
  5. //handle exception
  6. }

这一步之后,由于SVNKit包含了注册的工厂对象,SVNRepositoryFactory知道了怎样给svn:// 协议创建SVNRepository驱动。接下来你就可以为它创建一个驱动了:

  1. try {
  2. ...
  3. SVNURL url = SVNURL.parseURIDecoded( "svn://host/path_to_repository_root/inner_path" );
  4. SVNRepository repository = SVNRepositoryFactory.create( url, null );
  5. ...
  6. } catch ( SVNException e ) {
  7. //handle exception
  8. }

在SVNKit中,所有的仓库url由SVNURL类来表示,如果一个路径字符串不是UTF-8编码的,可以使用SVNURL的parseURIDecoded()方法来创建一个新的url(如果需要编码,它会重新编码)。然后你可以通过这个url来在SVNRepositoryFactory中创建一个新的SVNRepository驱动。这样,你可以绑定驱动到任何一个你想访问的仓库地址。

使用高级层API

当你使用SVNKit管理工作拷贝时,由于高级层API使用低级层API来与仓库交互,你也需要创建合适的工厂类,如果你遗漏了这一初始化步骤,可能会抛出一个SVNKit不能给提供的url创建SVNRepository对象的异常。

当然就想我们使用其他svn客户端或者是svn插件一样。我们对Repository进行操作的时候是需要身份验证的,使用SVNKit也是一样。我们需要提供身份信息:

  1. <span style="white-space:pre">    </span>/*
  2. * 对版本库设置认证信息。
  3. */
  4. ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(name, password);
  5. repository.setAuthenticationManager(authManager);

实现DisplayFile:

  1. <span style="font-size:18px;">import java.io.ByteArrayOutputStream;
  2. import java.io.IOException;
  3. import java.util.ArrayList;
  4. import java.util.Iterator;
  5. import java.util.List;
  6. import org.tmatesoft.svn.core.SVNException;
  7. import org.tmatesoft.svn.core.SVNLogEntry;
  8. import org.tmatesoft.svn.core.SVNNodeKind;
  9. import org.tmatesoft.svn.core.SVNProperties;
  10. import org.tmatesoft.svn.core.SVNProperty;
  11. import org.tmatesoft.svn.core.SVNURL;
  12. import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
  13. import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
  14. import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory;
  15. import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
  16. import org.tmatesoft.svn.core.io.SVNRepository;
  17. import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
  18. import org.tmatesoft.svn.core.wc.SVNWCUtil;
  19. public class DisplayFile {
  20. /**
  21. * @param args
  22. */
  23. public static void main(String[] args) {
  24. //初始化库。 必须先执行此操作。具体操作封装在setupLibrary方法中。
  25. setupLibrary();
  26. /*
  27. * 相关变量赋值
  28. */
  29. String url = "https://hy/svn/svnkittest/branches";
  30. String name = "hanyi";
  31. String password = "hanyi";
  32. String filePath = "doImport.txt";
  33. //定义svn版本库的URL。
  34. SVNURL repositoryURL = null;
  35. //定义版本库。
  36. SVNRepository repository = null;
  37. try {
  38. //获取SVN的URL。
  39. repositoryURL=SVNURL.parseURIEncoded(url);
  40. //根据URL实例化SVN版本库。
  41. repository = SVNRepositoryFactory.create(repositoryURL);
  42. } catch (SVNException svne) {
  43. /*
  44. * 打印版本库实例创建失败的异常。
  45. */
  46. System.err
  47. .println("创建版本库实例时失败,版本库的URL是 '"
  48. + url + "': " + svne.getMessage());
  49. System.exit(1);
  50. }
  51. /*
  52. * 对版本库设置认证信息。
  53. */
  54. ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(name, password);
  55. repository.setAuthenticationManager(authManager);
  56. //此变量用来存放要查看的文件的属性名/属性值列表。
  57. SVNProperties fileProperties = new SVNProperties();
  58. //此输出流用来存放要查看的文件的内容。
  59. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  60. try {
  61. //获得版本库中文件的类型状态(是否存在、是目录还是文件),参数-1表示是版本库中的最新版本。
  62. SVNNodeKind nodeKind = repository.checkPath(filePath, -1);
  63. if (nodeKind == SVNNodeKind.NONE) {
  64. System.err.println("要查看的文件在 '" + url + "'中不存在.");
  65. System.exit(1);
  66. } else if (nodeKind == SVNNodeKind.DIR) {
  67. System.err.println("要查看对应版本的条目在 '" + url
  68. + "'中是一个目录.");
  69. System.exit(1);
  70. }
  71. //获取要查看文件的内容和属性,结果保存在baos和fileProperties变量中。
  72. repository.getFile(filePath, -1, fileProperties, baos);
  73. } catch (SVNException svne) {
  74. System.err.println("在获取文件内容和属性时发生错误: " + svne.getMessage());
  75. System.exit(1);
  76. }
  77. //获取文件的mime-type
  78. String mimeType = fileProperties.getStringValue(SVNProperty.MIME_TYPE);
  79. //判断此文件是否是文本文件
  80. boolean isTextType = SVNProperty.isTextMimeType(mimeType);
  81. /*
  82. * 显示文件的所有属性
  83. */
  84. Iterator iterator = fileProperties.nameSet().iterator();
  85. while (iterator.hasNext()) {
  86. String propertyName = (String) iterator.next();
  87. String propertyValue = fileProperties.getStringValue(propertyName);
  88. System.out.println("文件的属性: " + propertyName + "="
  89. + propertyValue);
  90. }
  91. /*
  92. * 如果文件是文本类型,则把文件的内容显示到控制台。
  93. */
  94. if (isTextType) {
  95. System.out.println("File contents:");
  96. System.out.println();
  97. try {
  98. baos.writeTo(System.out);
  99. } catch (IOException ioe) {
  100. ioe.printStackTrace();
  101. }
  102. } else {
  103. System.out
  104. .println("因为文件不是文本文件,无法显示!");
  105. }
  106. System.out.println("");
  107. /*
  108. * 获得版本库的最新版本号。
  109. */
  110. long latestRevision = -1;
  111. try {
  112. latestRevision = repository.getLatestRevision();
  113. List<SVNLogEntry> entries = new ArrayList<SVNLogEntry>();
  114. try
  115. {
  116. repository.log(new String[]{""},//为过滤的文件路径前缀,为空表示不进行过滤
  117. entries,
  118. -1,//-1代表最新的版本号,初始版本号为0
  119. -1,
  120. true,
  121. true);
  122. }
  123. catch (SVNException e)
  124. {
  125. e.printStackTrace();
  126. }
  127. System.out.println("当前log信息数量:"+entries.size());
  128. String message=entries.get(0).getMessage().toString();
  129. System.out.println("提交的message信息:"+message);
  130. } catch (SVNException svne) {
  131. System.err.println("获取最新版本号时出错: " + svne.getMessage());
  132. System.exit(1);
  133. }
  134. System.out.println("");
  135. System.out.println("---------------------------------------------");
  136. System.out.println("版本库的最新版本号: " + latestRevision);
  137. System.exit(0);
  138. }
  139. /*
  140. * 初始化库
  141. */
  142. private static void setupLibrary() {
  143. /*
  144. * For using over http:// and https://
  145. */
  146. DAVRepositoryFactory.setup();
  147. /*
  148. * For using over svn:// and svn+xxx://
  149. */
  150. SVNRepositoryFactoryImpl.setup();
  151. /*
  152. * For using over file:///
  153. */
  154. FSRepositoryFactory.setup();
  155. }
  156. }</span><span style="font-weight: bold; font-size: 16pt;">
  157. </span>

打印的结果:

文件的属性: svn:entry:uuid=bf3500c6-b8a2-f84e-86b3-86d6154c1411
文件的属性: svn:entry:revision=2
文件的属性: svn:entry:committed-date=2015-04-29T15:53:24.910060Z
文件的属性: svn:wc:ra_dav:version-url=/svn/svnkittest/!svn/ver/2/branches/doImport.txt
文件的属性: svn:entry:checksum=1a3f6dc35be7edaba541a5a5053a2e03
文件的属性: svn:entry:committed-rev=2
文件的属性: svn:entry:last-author=hanyi
File contents:

hello the first svnkit demo
当前log信息数量:1
提交的message信息:韩义:svnkit demo test
---------------------------------------------
版本库的最新版本号: 2

实现DisplayRepositoryTree:

  1. import java.util.Collection;
  2. import java.util.Iterator;
  3. import org.tmatesoft.svn.core.SVNDirEntry;
  4. import org.tmatesoft.svn.core.SVNException;
  5. import org.tmatesoft.svn.core.SVNNodeKind;
  6. import org.tmatesoft.svn.core.SVNURL;
  7. import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
  8. import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
  9. import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
  10. import org.tmatesoft.svn.core.io.SVNRepository;
  11. import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
  12. import org.tmatesoft.svn.core.wc.SVNWCUtil;
  13. public class DisplayRepositoryTree {
  14. /**
  15. * @param args
  16. */
  17. public static void main(String[] args) {
  18. /*
  19. * For using over http:// and https://
  20. */
  21. DAVRepositoryFactory.setup();
  22. /*
  23. * 相关变量赋值
  24. */
  25. String url = "https://hy/svn/svnkittest";
  26. String name = "hanyi";
  27. String password = "hanyi";
  28. //定义svn版本库的URL。
  29. SVNURL repositoryURL = null;
  30. //定义版本库。
  31. SVNRepository repository = null;
  32. /*
  33. * 实例化版本库类
  34. * */
  35. try {
  36. //获取SVN的URL。
  37. repositoryURL=SVNURL.parseURIEncoded(url);
  38. //根据URL实例化SVN版本库。
  39. repository = SVNRepositoryFactory.create(repositoryURL);
  40. } catch (SVNException svne) {
  41. /*
  42. * 打印版本库实例创建失败的异常。
  43. */
  44. System.err
  45. .println("创建版本库实例时失败,版本库的URL是 '"
  46. + url + "': " + svne.getMessage());
  47. System.exit(1);
  48. }
  49. /*
  50. * 对版本库设置认证信息。
  51. */
  52. ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(name, password);
  53. repository.setAuthenticationManager(authManager);
  54. /*
  55. * 上面的代码基本上是固定的操作。
  56. * 下面的部分根据任务不同,执行不同的操作。
  57. * */
  58. try {
  59. //打印版本库的根
  60. System.out.println("Repository Root: " + repository.getRepositoryRoot(true));
  61. //打印出版本库的UUID
  62. System.out.println("Repository UUID: " + repository.getRepositoryUUID(true));
  63. System.out.println("");
  64. //打印版本库的目录树结构
  65. listEntries(repository, "");
  66. } catch (SVNException svne) {
  67. System.err.println("打印版本树时发生错误: "
  68. + svne.getMessage());
  69. System.exit(1);
  70. }
  71. /*
  72. * 获得版本库的最新版本树
  73. */
  74. long latestRevision = -1;
  75. try {
  76. latestRevision = repository.getLatestRevision();
  77. } catch (SVNException svne) {
  78. System.err
  79. .println("获取最新版本号时出错: "
  80. + svne.getMessage());
  81. System.exit(1);
  82. }
  83. System.out.println("");
  84. System.out.println("---------------------------------------------");
  85. System.out.println("版本库的最新版本是: " + latestRevision);
  86. System.exit(0);
  87. }
  88. /*
  89. * 此函数递归的获取版本库中某一目录下的所有条目。
  90. */
  91. public static void listEntries(SVNRepository repository, String path)
  92. throws SVNException {
  93. //获取版本库的path目录下的所有条目。参数-1表示是最新版本。
  94. Collection entries = repository.getDir(path, -1, null,
  95. (Collection) null);
  96. Iterator iterator = entries.iterator();
  97. while (iterator.hasNext()) {
  98. SVNDirEntry entry = (SVNDirEntry) iterator.next();
  99. System.out.println("/" + (path.equals("") ? "" : path + "/")
  100. + entry.getName() + " (author: '" + entry.getAuthor()
  101. + "'; revision: " + entry.getRevision() + "; date: " + entry.getDate() + ")");
  102. /*
  103. * 检查此条目是否为目录,如果为目录递归执行
  104. */
  105. if (entry.getKind() == SVNNodeKind.DIR) {
  106. listEntries(repository, (path.equals("")) ? entry.getName()
  107. : path + "/" + entry.getName());
  108. }
  109. }
  110. }
  111. }

打印的结果:

Repository Root: https://hy/svn/svnkittest
Repository UUID: bf3500c6-b8a2-f84e-86b3-86d6154c1411
/branches (author: 'hanyi'; revision: 2; date: Wed Apr 29 23:53:24 CST 2015)
/branches/doImport.txt (author: 'hanyi'; revision: 2; date: Wed Apr 29 23:53:24 CST 2015)
/tags (author: 'VisualSVN Server'; revision: 1; date: Wed Apr 29 14:14:01 CST 2015)
/trunk (author: 'VisualSVN Server'; revision: 1; date: Wed Apr 29 14:14:01 CST 2015)
---------------------------------------------
版本库的最新版本是: 2

其他的操作包括CheckOut,DoCommit,DoDiff,DoImport,DoUpdate我就不一一的写出了。上传一个包含所有操作的小例子,方便大家在以后的工作中学习使用:SVNKitTest(猛戳这里)

总结:

在学习SVNKit的过程中让我想起了我使用过的一些成型的产品,包括fisheye,Jenkins他们的底层与svn的集成或许就是通过SVNKit来实现的。或者是类似的产品实现的。对于我们更好的理解这些工具的使用提供了很大的帮助。

java操作svn【svnkit】实操的更多相关文章

  1. 利用 Java 操作 Jenkins API 实现对 Jenkins 的控制详解

    本文转载自利用 Java 操作 Jenkins API 实现对 Jenkins 的控制详解 导语 由于最近工作需要利用 Jenkins 远程 API 操作 Jenkins 来完成一些列操作,就抽空研究 ...

  2. svnkit 用java 操作 svn

    官网 https://svnkit.com/ https://blog.csdn.net/Hui_hai/article/details/80318518 https://blog.csdn.net/ ...

  3. java操作svn工具类SvnUtil

    直接上代码,工作中使用的版本,记录下. public class SvnUtil { private static Logger logger = Logger.getLogger(SvnUtil.c ...

  4. .net基础学java系列(四)Console实操

    上一篇文章 .net基础学java系列(三)徘徊反思 本章节没啥营养,请绕路! 看视频,不实操,对于上了年龄的人来说,是记不住的!我已经看了几遍IDEA的教学视频: https://edu.51cto ...

  5. Java初学者作业——编写JAVA程序,要求输入技术部门5位员工的理论成绩和实操成绩,计算并输出各位员工的最终评测成绩。

    返回本章节 返回作业目录 需求说明: 某软件公司要求对技术部门的所有员工进行技能评测,技术评测分为两个部分:理论部分以及实操部分,最终评测成绩=理论成绩×0.4+实操成绩×0.6,要求输入技术部门5位 ...

  6. SBT实操指南

    参考资料:1.英文官方文档2.中文官方文档,内容翻译的不全 SBT是类似maven和gradle的自动构建和包依赖管理工具,SBT是Scala技术体系下的包管理工具,都是Lightbend公司开发的, ...

  7. 第十章 Fisco Bcos 权限控制下的数据上链实操演练

    一.目的 前面已经完成fisco bcos 相关底层搭建.sdk使用.控制台.webase中间件平台等系列实战开发, 本次进行最后一个部分,体系化管理区块链底层,建立有序的底层控管制度,实现权限化管理 ...

  8. kettle安装部署基本操作及实操文档

    一.kettle是什么? Kettle,简称ETL(Extract-Transform-Load的缩写,即数据抽取.转换.装载的过程),是一款国外开源的ETL工具,纯Java编写,可以在Window. ...

  9. 性能测试工具 jmeter 分布式压力测试实操

    性能测试工具 jmeter 分布式压力测试实操 本文在Non-GUI Mode下进行,准备好三台有jdk环境,linux操作系统,同一局域网测试机器,运行两台slave,一台master机器,进行分布 ...

随机推荐

  1. Intel GPA 抓取3d模型

    原文链接在这里 http://dev.cra0kalo.com/?p=213 背景信息 Intel的GPA本身是一款图形分析软件,并没有设计从3D程序里抓取模型资源的功能,但这里作者是通过hook G ...

  2. Python机器学习库sklearn的安装

    Python机器学习库sklearn的安装 scikit-learn是Python的一个开源机器学习模块,它建立在NumPy,SciPy和matplotlib模块之上能够为用户提供各种机器学习算法接口 ...

  3. 一站式机器学习平台TI-ONE是什么?——云+未来峰会开发者专场回顾

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 背景:5月23-24日,以“焕启”为主题的腾讯“云+未来”峰会在广州召开,广东省各级政府机构领导.海内外业内学术专家.行业大咖及技术大牛等在 ...

  4. mongodb配置文件与启动

    数据库配置文件 mongo.cnf #日志文件位置 logpath=/data/db/journal/mongodb.log (这些都是可以自定义修改的) # 以追加方式写入日志 logappend= ...

  5. bzoj 4709: [Jsoi2011]柠檬

    Description Flute 很喜欢柠檬.它准备了一串用树枝串起来的贝壳,打算用一种魔法把贝壳变成柠檬.贝壳一共有 N (1 ≤ N ≤ 100,000) 只,按顺序串在树枝上.为了方便,我们从 ...

  6. 虚拟机centos笔记整理,持续更新~~

    远程拷贝文件:scp -r 文件名 主机名:完整路径名(冒号不能少)拷贝当前windows系统的文件到当前目录:rz -y 查找文件:updatedb 修改数据库locate 文件名 即可查找文件

  7. 项目管理系列--从零开始Code Review[转]

    从零开始Code Review 这篇帖子不是通篇介绍Code Review的方法论, 而是前大段记录了我们团队怎么从没有这个习惯到每天都进行review的过程, 后小段给出了我的一些建议. 希望能对诸 ...

  8. Iterator和for...of循环

    Iterator和for...of循环 Iterator(遍历器)的概念 数据结构的默认Iterator接口 调用Iterator接口的场合 字符串的Iterator接口 Iterator接口与Gen ...

  9. PostgreSQL Entity Framework 自动迁移

    1.依次添加NuGet包 EntityFramework.Npgsql.EntityFramework6.Npgsql,会自动生成一些配置文件,不过缺少数据库驱动的配置节点: <system.d ...

  10. 第四章使用java实现面向对象-接口

    一.接口 1.接口可以看作是一种特殊的“抽象类”. 2.接口有比抽象类更好的特性 3.可以被多继承 4.设计和实现完全分离 5.更自然的使用多态 二.接口约定 1.接口表示一种约定:体现在接口名称和注 ...