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. iphone手机拍照学习笔记

    大纲: 功能 理论 技巧 实战 一.功能 设置-相机可以打开网格. 短按屏幕.画面曝光切换. 长按调节曝光和聚焦,曝光有范围,取决于点选的地方. live photo可以拍出会动的照片,上划编辑,高速 ...

  2. Git版本回退和撤销修改

    版本回退: 在实际工作中,我们会不断对文件进行修改,然后不断提交修改到版本库里,一旦你把文件改乱了,或者误删了文件,还可以从最近的一个commit恢复,然后继续工作,而不是把几个月的工作成果全部丢失. ...

  3. Java_方法的调用②及案例

    语法格式: 方法名称([参数列表]); //注意:只能调用本类的方法 案例: class Method01{ public static void print(){ for(int i = 1; i ...

  4. SQL语句模糊查询年月

    <if test="uploadTime != null" > <![CDATA[ and date_format(w.upload_time, '%Y%m') ...

  5. 如何使一个div能够铺满整个页面? && 模态框的制作 && outerHTML

    说明: 使用 ele.outerHTML = '' 这样的方法可以很容易的清除一个元素. 当然也可以使用parent.removeChild() ,但是相较而言,还是使用 outerHTML = '' ...

  6. Centos 7.0设置/etc/rc.local无效问题解决

    安装centos7以后按照以往习惯修改rc.local添加开机启动命令,但重启后发现无效,再次重启发现依然如故 检查系统rc.local服务运行情况 systemctl | grep "rc ...

  7. 2、编写/修改权限及执行Shell程序的步骤

    学习目标编写Shell程序执行Shell程序 正文Shell程序有很多类似C语言和其他程序设计语言的特征,但是又没有程序语言那样复杂.Shell程序是指放在一个文件中的一系列Linux命令和实用程序. ...

  8. Python对日期进行格式化

    Python对日期进行格式化 把当前时间输出为2017-04-07 19:00:00.进入python交互命令行输入: > import datetime > currtime = dat ...

  9. ElasticSearch深入搜索

    一. 结构化搜索 结构化搜索(Structured search) 是指有关探询那些具有内在结构数据的过程.比如日期.时间和数字都是结构化的:它们有精确的格式,我们可以对这些格式进行逻辑操作.比较常见 ...

  10. MySQL wait_timeout参数设置与网上常见错误小纠

    discard connection com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link fail ...