1. 程式人生 > >java中對SVN的相關操作

java中對SVN的相關操作




String conflictType = "";
String conflictFile = "";
SVNRepository repository;
SVNClientManager clientManager;
private Logger logger = LoggerFactory.getLogger(SVNUtil.class);

/**
* 通過不同的協議初始化版本庫
*/
public static void setupLibrary() {
DAVRepositoryFactory.setup();
SVNRepositoryFactoryImpl.setup();
FSRepositoryFactory.setup();
}
/**
* SVN登入
* @param svnRoot 程式碼庫路徑
* @param map 登入資訊
* @return 結果
* @throws UnsupportedEncodingException 丟擲異常
*/
public boolean logSVN(String svnRoot,Map<String,String> map) throws UnsupportedEncodingException{
// 正式
//Map<String,String> map = CommonUtil.readFile();
if(map.size() == 0 ){
logger.info("從 配置檔案讀取出現異常");
return false;
}
String svnpass = DESEncryptionUtil.decrypt(map.get("svnpassword"), CMSConstant.readerDesAccountId, CMSConstant.readerDesKey);
try {
loginSVN(svnRoot,map.get("svnusername"),svnpass);
return true;
} catch (Exception e) {
logger.info("登入異常"+e);
return false;
}
}




/**
* SVN登入驗證
* @param svnRoot 程式碼庫路徑
* @param username 使用者名稱
* @param password 密碼
*/
public void loginSVN(String svnRoot, String username,String password) {
// 初始化版本庫
setupLibrary();


// 建立庫連線
repository = null;
try {
repository = SVNRepositoryFactory.create(SVNURL.parseURIEncoded(svnRoot));

// 身份驗證
ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(username, password);

// 建立身份驗證管理器
repository.setAuthenticationManager(authManager);

DefaultSVNOptions options = SVNWCUtil.createDefaultOptions(true);
clientManager = SVNClientManager.newInstance(options,authManager);
} catch (SVNException e) {
logger.info(e.getErrorMessage().toString());
}
}

/**
* Commit work copy's change to svn
* @param clientManager
* @param wcPath 
*working copy paths which changes are to be committed
* @param commitMessage
*commit log message
* @return SVNCommitInfo
*/
public SVNCommitInfo commit(File wcPath,String commitMessage) {
try {
return clientManager.getCommitClient().doCommit(
new File[] { wcPath }, false, commitMessage, null,
null, false, false, SVNDepth.INFINITY);
} catch (SVNException e) {
logger.error(e.getErrorMessage().toString());
}
return null;
}

/**
* 將檔案新增到本地版本庫中
* @param file 要新增的檔案
* @throws SVNException SVNException
*/
public void addFile(File file) throws SVNException{
SVNStatus status=clientManager.getStatusClient().doStatus(file, false);
String fileStatus = status.getContentsStatus().toString();
System.out.println(fileStatus);
if("none".equals(fileStatus)){
clientManager.getWCClient().doAdd(file, false, false, false, SVNDepth.INFINITY,false,false);
}
}

    /**
     * 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 long
     * @throws SVNException
     */
public long update(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().toString());
}
return 0;
}

/**
* recursively checks out a working copy from url into wcDir
* @param url
* a repository location from where a Working Copy will be checked out
* @param destPath
* the local path where the Working Copy will be placed
* @return long
* @throws SVNException
*/
public long checkout(String url, File destPath) {


//判斷資料夾是否存在
if(!destPath.exists()){
destPath.mkdir();
}else{
//判斷destPath是不是資料夾
if(destPath.isFile()&&!destPath.isDirectory()){
destPath.delete();
destPath.mkdir();
}
}
//判斷destPath是不是workcopy,是,則刪除並重新建立資料夾
if(isWorkingCopy(destPath)){
delDir(destPath);
destPath.mkdir();
}

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 {
SVNURL svnUrl = SVNURL.parseURIDecoded(url);
return updateClient.doCheckout(svnUrl, destPath, 
SVNRevision.HEAD, SVNRevision.HEAD, SVNDepth.UNKNOWN, false);
} catch (SVNException e) {
logger.error(e.getErrorMessage().toString());
}
return 0;
}

/**
* 確定path是否是一個工作空間
* @param path 路徑
* @return 結果
*/
public 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);
e.printStackTrace();
}
return true;
}

/**
* 確定一個URL在SVN上是否存在
* @param url 地址
* @param username 使用者名稱
* @param password 密碼
* @return 結果
*/
public 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上建立資料夾
* @param uRLs  repository locations to create
* @param commitMsg  commit log message
* @param makeParents  if true, creates all non-existent parent directories
* @return 結果
* @throws SVNException 丟擲異常
*/
public String mkDir(String[] uRLs,String commitMsg,boolean makeParents) throws SVNException{
SVNCommitInfo info = null;
SVNCommitClient sci = clientManager.getCommitClient();
SVNURL[] urls = new SVNURL[uRLs.length];


for (int i = 0; i < uRLs.length; i++) {
urls[i] = SVNURL.parseURIDecoded(uRLs[i]);
}


info = sci.doMkDir(urls, commitMsg, null, makeParents);
return info.toString();
}

/**
* 刪除SVN上的資料夾
* @param uRLs 
* @param commitMsg 備註
* @return returnMSG 
*/
public String delete(String[] uRLs,String commitMsg){
SVNCommitClient sci = clientManager.getCommitClient();
SVNCommitInfo info = null;
SVNURL[] urls = new SVNURL[uRLs.length];

try {
for(int i=0; i<uRLs.length;i++){
urls[i] = SVNURL.parseURIDecoded(uRLs[i]);
}
info = sci.doDelete(urls, commitMsg);
return info.toString();
} catch (SVNException e1) {
e1.printStackTrace();
return e1.getMessage().toString();
}

}

/**
* 實現svn的Copy to功能, dstURL必須不存在,否則會報錯
* @param srcURL URL for source
* @param dstURL URL for destination
* @return returnMSG 
*/
public String copy(String srcURL, String dstURL){
        SVNCopyClient copyClient = clientManager.getCopyClient();
        
        SVNURL src = null;
        SVNURL dst = null;
try {
src = SVNURL.parseURIDecoded(srcURL);
dst = SVNURL.parseURIDecoded(dstURL);
} catch (SVNException e1) {
e1.printStackTrace();
}
        SVNCopySource copySource = new SVNCopySource(SVNRevision.HEAD, SVNRevision.HEAD, src); 
        
        SVNCommitInfo info = null;
try {
info = copyClient.doCopy(new SVNCopySource[] { copySource }, dst, false, false, true, 
       "copy " + srcURL + " to " + dstURL, null);
return info.toString();
} catch (SVNException e) {
e.printStackTrace();
return e.getMessage().toString();
}
}

/**
* 將srcURL中的檔案進行merge,然後放入dstPath中。
* @param srcURL 
* @param dstPath 
* @throws SVNException 
*/
public void merge(String srcURL,File dstPath) throws SVNException{
SVNDiffClient diffClient = clientManager.getDiffClient();

diffClient.setEventHandler(new ISVNEventHandler(){
public void handleEvent(SVNEvent event,double progress) throws SVNException{
String status = event.getAction() + " " + event.getFile();
System.out.println(status + "--Progress is: "+ event.getContentsStatus().toString());
if(("tree_conflict").equals(event.getAction().toString())){
//if(event.getAction().toString().equals("tree_conflict")){
conflictType = event.getAction().toString();
conflictFile = event.getFile().toString();
}
}
public void checkCancelled() throws SVNCancelException{

}
});

        SVNURL src = null;
try {
src = SVNURL.parseURIDecoded(srcURL);
} catch (SVNException e1) {
e1.printStackTrace();
}

SVNRevisionRange rangeToMerge = new SVNRevisionRange(SVNRevision.create(1), SVNRevision.HEAD);
diffClient.doMerge(src, SVNRevision.HEAD, Collections.singleton(rangeToMerge), 
dstPath, SVNDepth.UNKNOWN, true, false, false, false);
}

/**
* 將srcURL和dstURL中的檔案進行merge,放入dstPath中並提交到svn。
* @param srcURL 
* @param dstURL 
* @param dstPath 
* @param commitMessage 
* @throws SVNException 
*/
public void merge(String srcURL,String dstURL,String dstPath,String commitMessage) throws SVNException{
SVNDiffClient diffClient = clientManager.getDiffClient();

        SVNURL src = null;
        SVNURL dst = null;
try {
src = SVNURL.parseURIDecoded(srcURL);
dst = SVNURL.parseURIDecoded(dstURL);
} catch (SVNException e1) {
e1.printStackTrace();
}
File file = new File(dstPath);
        diffClient.doMerge(src, SVNRevision.HEAD, dst, SVNRevision.HEAD, file, 
        SVNDepth.UNKNOWN, true, false, true, false);
        
        //將merge後的資料夾commit到svn
        commit(file, commitMessage);
}

/**
* 解決合併時出現的衝突
* @param file 
* @param conflictChoice SVNConflictChoice.THEIRS_CONFLICT--伺服器,SVNConflictChoice.MINE_FULL--本地 
* @throws SVNException 
*/
public void resolveConflict(File file,SVNConflictChoice conflictChoice) throws SVNException{
SVNWCClient wc = clientManager.getWCClient();
wc.doResolve(file, SVNDepth.INFINITY, conflictChoice);
}

/**
* 刪除本地資料夾
* @param path 
*/
    public void delDir(File path){
//        File dir=new File(path);
        if(path.exists()){
            File[] tmp=path.listFiles();
            for(int i=0;i<tmp.length;i++){
                if(tmp[i].isDirectory()){
                    delDir(new File(path+"/"+tmp[i].getName()));
                }
                else{
                    tmp[i].delete();
                }
            }
            path.delete();
        }
    }
    

    /**
     * 獲取path下面的資料夾名稱以及對應的revision,並寫入hashmap
     * @param path 相對路徑,例如/trunk,/tags/1-sit
     * @return hashmap 
     * @throws SVNException 
     * 
     */
    public HashMap<String,String> getDir(String path) throws SVNException{
    //System.out.println("獲取版本號的Path = "+path);
    HashMap<String, String> map = new HashMap<String, String>();
    Collection entries = repository.getDir(path, -1, null,(Collection) null);
Iterator iterator = entries.iterator();
while (iterator.hasNext()) {
SVNDirEntry entry = (SVNDirEntry) iterator.next();
if (entry.getKind() == SVNNodeKind.DIR) {
map.put(entry.getName(), entry.getRevision()+"");
//System.out.println(entry.getName() + " (" + "revision: " + entry.getRevision());
}
}
   
return map;
    }
    
    /**
     * 獲取指定svn檔案內容並返回
     * @param file 相對路徑,如/trunk/database/xxx.sql
     * @return ByteArrayOutputStream 或 null
     * @throws SVNException 
     */
    public ByteArrayOutputStream getFileContent(String file) throws SVNException{
    SVNNodeKind nodeKind = repository.checkPath(file, -1);
    SVNProperties fileProperties = new SVNProperties();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        if (nodeKind == SVNNodeKind.NONE) {
        logger.info("未找到檔案!");
//            System.exit(1);
        return null;
        } else if (nodeKind == SVNNodeKind.DIR) {
        logger.info("這是個資料夾,不是檔案!");
//            System.exit(1);
        return null;
        }
        repository.getFile(file, -1, fileProperties, baos);
        String mimeType = fileProperties.getStringValue(SVNProperty.MIME_TYPE);
        boolean isTextType = SVNProperty.isTextMimeType(mimeType);
//        Iterator iterator = fileProperties.nameSet().iterator();
//        while (iterator.hasNext()) {
//            String propertyName = (String) iterator.next();
//            String propertyValue = fileProperties.getStringValue(propertyName);
//            System.out.println("File property: " + propertyName + "=" + propertyValue);
//        }
        if (isTextType) {
//            System.out.println("File contents:");
//            System.out.println();
//            try {
//                baos.writeTo(System.out);
//            } catch (IOException ioe) {
//                ioe.printStackTrace();
//            }
        return baos;
        }else{
        return null;
        }
    }
    
    /**
     * 獲取svn版本號
     * @param uRL svn路徑
     * @return 版本號
     * @throws SVNException 
     */
    public long getRevision(String uRL) throws SVNException{
    SVNURL url = null;
url = SVNURL.parseURIDecoded(uRL);
    SVNWCClient wc = clientManager.getWCClient();
    SVNInfo info = wc.doInfo(url, SVNRevision.HEAD, SVNRevision.HEAD);
    long version = info.getCommittedRevision().getNumber();
    return version;
    }
    
    /**
     * 獲取svn路徑下的檔名,不包含資料夾
     * @param svnPath 
     * @return List 
     * @throws SVNException 
     */
public List<String> getDirContents(String svnPath) throws SVNException {
SVNLogClient log = clientManager.getLogClient();
final List<String> list = new ArrayList<String>();

log.doList(SVNURL.parseURIEncoded(svnPath),
SVNRevision.HEAD, SVNRevision.HEAD, false, false,
new ISVNDirEntryHandler() {
public void handleDirEntry(SVNDirEntry entry)
throws SVNException {
if (entry.getKind() == SVNNodeKind.FILE) {
list.add(entry.getRelativePath().toString());
}
}
});
return list;//返回包含所有檔名的list
}
/** 
     * 將本地檔案提交到svn
     * @param localPath  檔案 地址  
     * @param dstURL svn路徑
     * @param commitMessage  提交資訊
     * @return String  
     */  
    public String importDirectory( File localPath, String dstURL, String commitMessage) {  
        try {  
        SVNURLdstPath=SVNURL.parseURIDecoded(dstURL);
           clientManager.getCommitClient().doImport(localPath, dstPath,  
                    commitMessage, null, true, true,  
                    SVNDepth.fromRecurse(true));
           return CMSConstant.success;
        } catch (SVNException e) {  
        e.printStackTrace();
        }  
        return "";  
    }