package org.jenkinsci.plugins.svn.upload.step;

import java.io.*;

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.SVNUpdateClient;
import org.tmatesoft.svn.core.wc.SVNWCUtil;

public class SvnUpload {
    private SVNClientManager clientManager;
    private ISVNAuthenticationManager authManager;
    private SVNRepository repository;
    /**
     *
     * @param svnUrl svn地址
     * @param svnUsername svn用户名称
     * @param svnPasswd svn用户密码
     * @throws SVNException 异常信息
     */
    public SvnUpload(String svnUrl, String svnUsername, String svnPasswd)throws SVNException{
        try {
            this.createDefaultAuthenticationManager(svnUsername, svnPasswd);
            this.authSvn(svnUrl);
        } catch (SVNException e) {
            throw new RuntimeException(e.getMessage());
        }
    }
    /**
     * 通过不同的协议初始化版本库
     */  
    private void setupLibrary() {  
        DAVRepositoryFactory.setup();  
        SVNRepositoryFactoryImpl.setup();  
        FSRepositoryFactory.setup();  
    }  
    /**
     *
     * @param username svn用户名称
     * @param password svn用户密码
     * @throws SVNException 异常信息
     */
    private void createDefaultAuthenticationManager(String username, String password)throws SVNException{
        try {  
            // 身份验证  
            authManager = SVNWCUtil.createDefaultAuthenticationManager(username, password);
        } catch (Exception e) {  
            throw new RuntimeException("SVN身份认证失败:" + e.getMessage());
        }  
    }
    /**
     * 验证登录svn
     * @param svnUrl 用户svn的仓库地址
     * @throws SVNException 异常信息
     */
    private void authSvn(String svnUrl) throws SVNException {  
        // 初始化版本库  
        setupLibrary();  
        try {  
            repository = SVNRepositoryFactory.create(SVNURL.parseURIEncoded(svnUrl));  
        } catch (SVNException e) {  
            throw new RuntimeException("SVN创建库连接失败:" + e.getMessage());
        }
        
        // 创建身份验证管理器  
        repository.setAuthenticationManager(authManager);  
        DefaultSVNOptions options = SVNWCUtil.createDefaultOptions(true);  
        try {  
            //创建SVN实例管理器
            clientManager = SVNClientManager.newInstance(options,authManager);  
        } catch (Exception e) {  
            throw new RuntimeException("SVN实例管理器创建失败:" + e.getMessage());
        }
    }
    
    /**
     * 添加文件和目录到版本控制下
     * @param wcPath 工作区路径
     * @throws SVNException 异常信息
     */  
    private void addEntry(File wcPath) throws SVNException{  
        try {  
            clientManager.getWCClient().doAdd(new File[] { wcPath }, true,  
                    false, false, SVNDepth.INFINITY, false, false, true);  
        } catch (SVNException e) {  
            throw new RuntimeException("SVN添加文件到版本控制下失败:" + e.getMessage());
        }  
    }  
     
      
    /**
     * 将工作副本提交到svn
     * @param wcPath  被提交的工作区路径
     * @param keepLocks 是否在SVN仓库中打开或不打开文件
     * @param commitMessage 提交信息
     * @return 返回信息
     * @throws SVNException 异常信息
     */  
    private SVNCommitInfo commit(File wcPath, boolean keepLocks, String commitMessage) throws SVNException {  
        try {  
            return clientManager.getCommitClient().doCommit(  
                    new File[] { wcPath }, keepLocks, commitMessage, null,  
                    null, false, false, SVNDepth.INFINITY);  
        } catch (SVNException e) {  
            throw new RuntimeException("SVN提交失败:" + e.getMessage());
        }  
    }  
      
    /**
     * 确定path是否是一个工作空间
     * @param path 文件路径
     * @return 返回信息
     * @throws SVNException 异常信息
     */  
    private boolean isWorkingCopy(File path) throws SVNException{  
        if(!path.exists()){  
            return false;  
        }  
        try {  
            if(null == SVNWCUtil.getWorkingCopyRoot(path, false)){  
                return false;  
            }  
        } catch (SVNException e) {  
            throw new RuntimeException("确定path是否是一个工作空间 失败:" + e.getMessage());
        }  
        return true;  
    }  
      
    /**
     * 确定一个URL在SVN上是否存在
     * @param url svn访问地址
     * @return 返回信息
     * @throws SVNException 异常信息
     */  
    private boolean isURLExist(SVNURL url) throws SVNException{  
        try {  
            SVNRepository svnRepository = SVNRepositoryFactory.create(url);
            svnRepository.setAuthenticationManager(authManager);  
            SVNNodeKind nodeKind = svnRepository.checkPath("", -1);  
            return nodeKind == SVNNodeKind.NONE ? false : true;   
        } catch (SVNException e) {  
            throw new RuntimeException("确定一个URL在SVN上是否存在失败:" + e.getMessage());
        }    
    }  
    
    /**  
     * 递归检查不在版本控制的文件,并add到svn  
     * @param wc  检查的文件
     * @throws SVNException 异常信息
     */  
    private void checkVersiondDirectory(File wc) throws SVNException{  
        if(!SVNWCUtil.isVersionedDirectory(wc)){  
            this.addEntry(wc);  
        }  
        if(wc.isDirectory()){  
            for(File sub:wc.listFiles()){
                if(sub.isDirectory() && sub.getName().equals(".svn")){
                    continue;  
                }  
                checkVersiondDirectory(sub);  
            }  
        }  
    }
    
    /**
     * 删除目录(文件夹)以及目录下的文件
     * @param   sPath 被删除目录的文件
     * @return  目录删除成功返回true,否则返回false
     */  
    private boolean deleteDirectory(String sPath) {
        //如果sPath不以文件分隔符结尾,自动添加文件分隔符  
        if (!sPath.endsWith(File.separator)) {  
            sPath = sPath + File.separator;  
        }  
        File dirFile = new File(sPath);  
        //如果dir对应的文件不存在,或者不是一个目录,则退出  
        if (!dirFile.exists() || !dirFile.isDirectory()) {  
            return false;  
        }  
        boolean flag = true;  
        //删除文件夹下的所有文件(包括子目录)  
        File[] files = dirFile.listFiles();  
        for (int i = 0; i < files.length; i++) {  
            //删除子文件  
            if (files[i].isFile()) {  
                flag = deleteFile(files[i].getAbsolutePath());  
                if (!flag) break;  
            } //删除子目录  
            else {  
                flag = deleteDirectory(files[i].getAbsolutePath());  
                if (!flag) break;  
            }  
        }  
        if (!flag) return false;  
        //删除当前目录  
        if (dirFile.delete()) {  
            return true;  
        } else {  
            return false;  
        }  
    }
    
    /**
     * 删除单个文件
     * @param   sPath    被删除文件的文件
     * @return 单个文件删除成功返回true,否则返回false
     */  
    private boolean deleteFile(String sPath) {  
        boolean flag = false;
        File file = new File(sPath);  
        // 路径为文件且不为空则进行删除  
        if (file.isFile() && file.exists()) {  
            file.delete();  
            flag = true;  
        }
        return flag;  
    }
    
    /**
     *  根据路径删除指定的目录或文件,无论存在与否
     *@param sPath  要删除的目录或文件
     *@return 删除成功返回 true,否则返回 false。
     */  
    private boolean DeleteFolder(String sPath) {  
        boolean flag = false;
        File file = new File(sPath);  
        // 判断目录或文件是否存在  
        if (!file.exists()) {  // 不存在返回 false  
            return flag;  
        } else {  
            // 判断是否为文件  
            if (file.isFile()) {  // 为文件时调用删除文件方法  
                return deleteFile(file.getAbsolutePath());  
            } else {  // 为目录时调用删除目录方法  
                return deleteDirectory(file.getAbsolutePath());  
            }  
        }  
    }  
    
    /**
     * 更新SVN工作区
     * @param wcPath 工作区路径
     * @param updateToRevision 更新版本
     * @param depth update的深度:目录、子目录、文件
     * @return 返回信息
     * @throws SVNException 异常信息
     */  
    private long update(File wcPath,SVNRevision updateToRevision, SVNDepth depth) throws SVNException{  
        SVNUpdateClient updateClient = clientManager.getUpdateClient();  
        updateClient.setIgnoreExternals(false);  
        try {  
            return updateClient.doUpdate(wcPath, updateToRevision,depth, false, false);  
        } catch (SVNException e) {  
            throw new RuntimeException("更新SVN工作区失败:" + e.getMessage());
        }  
    }  
      
    /**
     * SVN仓库文件检出
     * @param url 文件url
     * @param revision 检出版本
     * @param destPath 目标路径
     * @param depth checkout的深度,目录、子目录、文件
     * @return 返回信息
     * @throws SVNException 异常信息
     */  
    private long checkout(SVNURL url, SVNRevision revision, File destPath, SVNDepth depth) throws SVNException{  
        SVNUpdateClient updateClient = clientManager.getUpdateClient();   
        updateClient.setIgnoreExternals(false);  
        try {  
            return updateClient.doCheckout(url, destPath, revision, revision,depth, false);  
        } catch (SVNException e) {  
            throw new RuntimeException("检出SVN仓库失败:" + e.getMessage());
        }  
    }
    /**
     * @param svnUrl svn地址
     * @param workspace 工作区
     * @param filepath 上传的文件地址
     * @param filename 文件名称
     * @throws SVNException 异常信息
     */
    private void checkWorkCopy(String svnUrl,String workspace,String filepath,String filename)throws SVNException{    
        SVNURL repositoryURL = null;
        try {  
            repositoryURL = SVNURL.parseURIEncoded(svnUrl);  
        } catch (SVNException e) {  
            throw new RuntimeException("解析svnUrl失败:" + e.getMessage());
        }
        String fPath = "";
        if(filepath.indexOf("/") != -1) {
            fPath = filepath.substring(0,filepath.lastIndexOf("/"));
        }
        File wc = new File(workspace+"/"+fPath);
        File wc_project = new File( workspace + "/" + fPath);
          
        SVNURL projectURL = null;
        try {  
            projectURL = repositoryURL.appendPath(filename, false);  
        } catch (SVNException e) {  
            throw new RuntimeException("解析svnUrl文件失败:" + e.getMessage());
        }  
          
        if(!this.isWorkingCopy(wc)){  
            if(!this.isURLExist(projectURL)){
                this.checkout(repositoryURL, SVNRevision.HEAD, wc, SVNDepth.EMPTY);  
            }else{  
                this.checkout(projectURL, SVNRevision.HEAD, wc_project, SVNDepth.INFINITY);  
            }  
        }else{
            this.update(wc, SVNRevision.HEAD, SVNDepth.INFINITY);  
        }  
    }
    /**
     * 循环删除.svn目录
     * @param spath
     */
    private void deletePointSVN(String spath){
        File wc = new File(spath);
        for(File sub:wc.listFiles()){
            if(sub.isDirectory() && sub.getName().equals(".svn")){
                this.deleteDirectory(sub.getAbsolutePath());
                continue;
            }
            if(sub.isDirectory()){
                deletePointSVN(sub.getAbsolutePath());
            }  
        }  
    }
    /**
     *
     * @param svnUrl svn地址
     * @param workspace 工作区
     * @param filepath 上传的文件地址
     * @param filename 上传的文件名称
     * @param isOverwrite 是否覆盖
     * @throws SVNException 异常信息
     */
    public void upload(String svnUrl,String workspace,String filepath,String filename,Boolean isOverwrite)throws SVNException{
        String svnfilePath = svnUrl+"/"+filename;
        //开始前删除以前的.svn文件目录
        deletePointSVN(workspace);
        boolean flag = this.isURLExist(SVNURL.parseURIDecoded(svnfilePath));
        if(flag){
            if(isOverwrite){
                this.uploadFile(svnUrl, workspace, filepath,filename);
            }
        }else{
            this.uploadFile(svnUrl, workspace, filepath,filename);
        }
        //结束后删除当前的.svn文件目录
        deletePointSVN(workspace);
    }
    /**
     *
     * @param svnUrl svn地址
     * @param workspace 工作区
     * @param filepath 上传的文件地址
     * @param filename 文件名称
     * @throws SVNException 异常信息
     */
    private void uploadFile(String svnUrl,String workspace,String filepath,String filename)throws SVNException{
        this.checkWorkCopy(svnUrl, workspace, filepath,filename);
        File file = new File(workspace+"/"+filepath);
        this.checkVersiondDirectory(file);
        this.commit(file, false, "commit file:"+file);
    }

public static void main(String[] args) throws SVNException {
        try {
            String svnUrl = "http://192.168.18.200/svn/repository/hello";
            String username = "admin";
            String passwd = "admin";
            String workspace = "C:\\Users\\kube\\Desktop\\test";
            String upfile = "/q/w/a.txt,b.txt";
            Boolean isOverwrite = true;
            SvnUpload svnUpload = new SvnUpload(svnUrl,username, passwd);
            String [] fileArray = upfile.split(",");
            for(int i=0;i<fileArray.length;i++){
                String filePath = fileArray[i];
                String filename = "";
                if (filePath.indexOf("/") != -1) {
                    filename = filePath.substring(filePath.lastIndexOf("/"));
                } else {
                    filename = filePath;
                }
                svnUpload.upload(svnUrl, workspace, filePath, filename,isOverwrite);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

java调用svnkit工具类上传本地文件到svn服务器的更多相关文章

  1. 用java 代码下载Samba服务器上的文件到本地目录以及上传本地文件到Samba服务器

    引入: 在我们昨天架设好了Samba服务器上并且创建了一个 Samba 账户后,我们就迫不及待的想用JAVA去操作Samba服务器了,我们找到了一个框架叫 jcifs,可以高效的完成我们工作. 实践: ...

  2. 上传本地文件到SVN

    前言:今天按照自己的记忆上传本地文件夹到SVN,出现了点问题,重温了简单操作. https://blog.csdn.net/qq_35150366/article/details/81129847 参 ...

  3. 上传的文件放在SVN服务器的哪个目录下

    SVN服务器版本库有两种格式,一种为FSFS,一种为BDB 把文件上传到SVN版本库后,上传的文件不再以文件原来的格式存储,而是被svn以它自定义的格式压缩成版本库数据,存放在版本库中. 如果是FSF ...

  4. git 上传本地文件到github

    git 上传本地文件到github 1 git config --global user.name "Your Real Name" 2 git config --global u ...

  5. 两种方法上传本地文件到github

    https://www.jianshu.com/p/c70ca3a02087 自从使用github以来,一直都是在github网站在线上传文件到仓库中,但是有时因为网络或者电脑的原因上传失败.最重要的 ...

  6. 两种方法上传本地文件到github(转)

    自从使用github以来,一直都是在github网站在线上传文件到仓库中,但是有时因为网络或者电脑的原因上传失败.最重要的原因是我习惯本地编辑,完成以后再一起上传github.看过了几个教程,总结出最 ...

  7. paramiko模块的安装和使用(含上传本地文件或文件夹到服务器,以及下载服务器文件到本地)

    安装和使用分两步介绍: 介绍一下,本文的运行环境是win7 64位 和python 2.7  . 安装: WIN7_64位 安装python-ssh访问模块(paramiko)的安装教程,本人亲测下面 ...

  8. SSH 远程上传本地文件至服务器

    使用SSH命令行传输文件到远程服务器   以前一直在windows下用SSH Secure Shell连接远程服务器,它自带了一个可视化的文件传输工具,跟ftp差不多 但是它也存在一个缺陷,不支持编码 ...

  9. 如何用一张图片代替 'input:file' 上传本地文件??

    今天去面试,碰到了一道题,也许是因为紧张或者喝水喝多了,一时竟然没有转过弯来,回来之后一细想原来这么简单,哭笑不得,特此记录一下! 原题是这样的:  如何用一张图片代替 'input:file' 上传 ...

随机推荐

  1. swift -pop的简单动画

    //1.新建空文件  命名Podfile //2.写入 pod ‘pop’,’~>1.0’  保存 //3.打开终端,进入项目路径 执行pod install //4.新建桥接头文件 导入#im ...

  2. .NET基础 (08)字符串处理

    字符串处理1 System.String是值类型还是引用类型2 StringBuilder类型有何作用3 如何在String和Byte[]对象之间进行转换4 简述BASE64编码的作用以及C#中对其的 ...

  3. ZOJ3703 Happy Programming Contest 2017-04-06 23:33 61人阅读 评论(0) 收藏

    Happy Programming Contest Time Limit: 2 Seconds      Memory Limit: 65536 KB In Zhejiang University P ...

  4. (zxing.net)一维码UPC A的简介、实现与解码

    一.简介 UPC(Universal Product Code)码是最早大规模应用的条码,其特性是一种长度固定.连续性的条  码,目前主要在美国和加拿大使用,由于其应用范围广泛,故又被称万用条码. U ...

  5. C#读取MP3文件的专辑图片和ID3V2Tag信息(带代码)

    第二次更新,后面的代码有问题,有些专辑图片读取不到.发现是PNG图片的问题.在读取的过程中调试发现,图片帧前10个字节包含了图片的格式,在有些歌曲写着JPEG的格式,数据却是PNG的.先说下思路. j ...

  6. 批判“await使用中的阻塞和并发”——对asyc/await这对基友的误会和更正

    写第一篇<await使用中的阻塞和并发>的时候还自信满满,觉得写的真不错,结果漏洞百出…… 更正第二篇<await使用中的阻塞和并发(二)>的时候觉得这回不会再错了…… 结果我 ...

  7. Robolectric 单元测试中使用 Ressource

    单元测试类中: @RunWith(RobolectricGradleTestRunner.class) @Config(constants=BuildConfig.class, sdk = 21) 获 ...

  8. WORD wFormatTag; /* format type */ //设置波形声音的格式

    0x0000   Microsoft   Unknown   Wave   Format       0x0001   Microsoft   PCM   Format       0x0002    ...

  9. python 杂谈

    python 当前文件导入自定义模块的时候,会默认执行一遍 python使用的变量必须是已经定义或者声明过的.

  10. E - More is better (并查集)

    点击打开链接 Mr Wang wants some boys to help him with a project. Because the project is rather complex, th ...