?? 最近在嘗試做一個類似sourceforge的開源社區,因此需要為項目申請者提供遠程SVN的配置。這里列出自己的代碼和心得,一是為了與大家相互交流,更重要的是為了讓各位提提意見,看看還需要什么內容。
現在提供的功能有:
?? 為項目創建svn倉庫,修改svn賬戶密碼,修改svn權限配置等。
?? 大家覺得還需要什么呢?
代碼如下:
? 首先定義一個異常:
package?commandLineTest;


class?SvnException?extends?Exception?
{

????public?SvnException(String?s)?
{
????????super(s);
????}
}

下面是對svn的操作:
package?commandLineTest;

import?java.io.BufferedReader;
import?java.io.BufferedWriter;
import?java.io.File;
import?java.io.FileNotFoundException;
import?java.io.FileReader;
import?java.io.FileWriter;
import?java.io.IOException;
import?java.io.InputStreamReader;


public?class?SvnCommander?
{

????private?String?svn_home?=?"K:/subversion-repository/";


????/**?*//**
?????*?為指定項目在服務器創建svn倉庫,當用戶選擇開通svn服務時,這個方法將被調用為用戶的項目創建svn倉庫
?????*?
?????*?@param?project
?????*????????????需要創建svn倉庫的項目的名稱
?????*?@throws?SvnException
?????*?????????????當創建失敗時將拋出錯誤
?????*/

????public?void?createRepository(String?project)?throws?SvnException?
{

????????try?
{
????????????Process?p?=?new?ProcessBuilder("svnadmin",?"create",?svn_home
????????????????????+?project).start();
????????????StringBuffer?buffer?=?new?StringBuffer();
????????????String?tmp;
????????????//?BufferedReader?reader=new?BufferedReader(new
????????????//?InputStreamReader(p.getInputStream()));
????????????//?while((tmp=reader.readLine())!=null)
????????????//?buffer.append(tmp);
????????????//?System.out.println(buffer.toString());
????????????//?buffer=new?StringBuffer();
????????????BufferedReader?reader?=?new?BufferedReader(new?InputStreamReader(p
????????????????????.getErrorStream()));
????????????while?((tmp?=?reader.readLine())?!=?null)
????????????????buffer.append(tmp);
????????????//?System.err.println(buffer.toString());
????????????if?(buffer.length()?>?0)
????????????????throw?new?SvnException(buffer.toString());
????????????initSvnServer(project);
????????????initAuthz(project);

????????}?catch?(IOException?e)?
{
????????????//?TODO?Auto-generated?catch?block
????????????e.printStackTrace();
????????}

????}


????/**?*//**
?????*?用于修改svn倉庫的svnserve.conf配置文件,這個方法將在@link?createRepository(String?name)
?????*?中被自動調用,不建議被其他類調用
?????*?
?????*?@param?project
?????*????????????svn倉庫對應的項目名稱
?????*?@throws?SvnException
?????*?????????????當用戶所在的項目并沒有開通svn服務,或者修改svnserve.conf文件出現io錯誤時將拋出SvnException
?????*/

????public?void?initSvnServer(String?project)?throws?SvnException?
{
????????File?svnserve?=?new?File(svn_home?+?project?+?"/conf/svnserve.conf");

????????try?
{
????????????BufferedReader?reader?=?new?BufferedReader(new?FileReader(svnserve));
????????????StringBuffer?buffer?=?new?StringBuffer();
????????????String?tmp;
????????????while?((tmp?=?reader.readLine())?!=?null)
????????????????buffer.append(tmp?+?"\n");
????????????reader.close();
????????????int?index?=?buffer.indexOf("#?anon");
????????????buffer.delete(index,?index?+?2);
????????????index?=?buffer.indexOf("#?auth");
????????????buffer.delete(index,?index?+?2);
????????????index?=?buffer.indexOf("#?pass");
????????????buffer.delete(index,?index?+?2);
????????????index?=?buffer.indexOf("#?auth");
????????????buffer.delete(index,?index?+?2);
????????????BufferedWriter?writer?=?new?BufferedWriter(new?FileWriter(svnserve));
????????????writer.write(buffer.toString());
????????????writer.close();

????????}?catch?(FileNotFoundException?e)?
{
????????????//?TODO?Auto-generated?catch?block
????????????throw?new?SvnException("SvnException:?配置文件svnserve.conf未找到:?"
????????????????????+?e.toString());

????????}?catch?(IOException?e)?
{
????????????//?TODO?Auto-generated?catch?block
????????????throw?new?SvnException("SvnException:?配置文件svnserve.conf的io操作出現問題:?"
????????????????????+?e.toString());
????????}
????}


????/**?*//**
?????*?為用戶設置svn帳戶的密碼,
?????*?該方法將修改項目倉庫的passwd文件,如果該用戶帳戶已存在于passwd文件中,將修改其密碼信息;如果不存在,則會在passwd添加新的記錄
?????*?
?????*?@param?project
?????*????????????用戶所在的項目名稱
?????*?@param?name
?????*????????????用戶帳戶名稱
?????*?@param?key
?????*????????????用戶密碼
?????*?@throws?SvnException
?????*?????????????當用戶所在的項目并沒有開通svn服務,或者修改passwd文件出現io錯誤時將拋出SvnException
?????*/
????public?void?setPassword(String?project,?String?name,?String?key)

????????????throws?SvnException?
{
????????File?file?=?new?File(svn_home?+?project);
????????if?(!file.exists())
????????????throw?new?SvnException("SvnException:?該項目還未開通svn服務");
????????File?passwd?=?new?File(svn_home?+?project?+?"/conf/passwd");

????????try?
{
????????????BufferedReader?reader?=?new?BufferedReader(new?FileReader(passwd));
????????????StringBuffer?buffer?=?new?StringBuffer();
????????????String?tmp;
????????????while?((tmp?=?reader.readLine())?!=?null)
????????????????buffer.append(tmp?+?"\n");
????????????reader.close();
????????????int?index?=?buffer.indexOf(name?+?"?=?");

????????????if?(index?!=?-1)?
{
????????????????int?line_end?=?buffer.indexOf("\n",?index);
????????????????if?(line_end?==?-1)
????????????????????line_end?=?buffer.length();
????????????????buffer.replace(index?+?name.length()?+?3,?line_end,?key);

????????????}?else?
{
????????????????buffer.append(name?+?"?=?"?+?key);
????????????}
????????????BufferedWriter?writer?=?new?BufferedWriter(new?FileWriter(passwd));
????????????writer.write(buffer.toString());
????????????writer.close();

????????}?catch?(FileNotFoundException?e)?
{
????????????//?TODO?Auto-generated?catch?block
????????????throw?new?SvnException("SvnException:?配置文件passwd未找到:?"
????????????????????+?e.toString());

????????}?catch?(IOException?e)?
{
????????????//?TODO?Auto-generated?catch?block
????????????throw?new?SvnException("SvnException:?配置文件passwd的io操作出現問題:?"
????????????????????+?e.toString());
????????}
????}


????private?void?initAuthz(String?project)?throws?SvnException?
{
????????File?template?=?new?File("authz_template.txt");
????????File?authz?=?new?File(svn_home?+?project?+?"/conf/authz");

????????try?
{
????????????BufferedReader?reader?=?new?BufferedReader(new?FileReader(template));
????????????BufferedWriter?writer?=?new?BufferedWriter(new?FileWriter(authz));
????????????String?tmp;
????????????while?((tmp?=?reader.readLine())?!=?null)
????????????????writer.write(tmp);
????????????reader.close();
????????????writer.close();

????????}?catch?(FileNotFoundException?e)?
{
????????????//?TODO?Auto-generated?catch?block
????????????throw?new?SvnException("SvnException:?配置文件passwd未找到:?"
????????????????????+?e.toString());

????????}?catch?(IOException?e)?
{
????????????//?TODO?Auto-generated?catch?block
????????????throw?new?SvnException("SvnException:?配置文件passwd的io操作出現問題:?"
????????????????????+?e.toString());
????????}
????}


????/**?*//**
?????*?用于設置各個用戶對svn的使用權限
?????*?
?????*?@param?project
?????*????????????對應的項目名稱
?????*?@param?path
?????*????????????權限對應的文件夾,該參數應該采取"/foo/bar"的形式,不然設置結果將不起作用
?????*?@param?name
?????*????????????用戶名稱,全部用戶應該使用"*"來表示
?????*?@param?right
?????*????????????權限,為"r"或者"rw"兩種形式
?????*/
????public?void?setAuthz(String?project,?String?path,?String?name,?String?right)

????????????throws?SvnException?
{
????????File?passwd?=?new?File(svn_home?+?project?+?"/conf/authz");

????????try?
{
????????????BufferedReader?reader?=?new?BufferedReader(new?FileReader(passwd));
????????????StringBuffer?buffer?=?new?StringBuffer();
????????????String?tmp;
????????????while?((tmp?=?reader.readLine())?!=?null)
????????????????buffer.append(tmp?+?"\n");
????????????reader.close();
????????????int?begin?=?buffer.indexOf("["?+?project?+?":"?+?path?+?"]");
????????????System.err.println(begin);

????????????if?(begin?!=?-1)?
{
????????????????int?end?=?buffer.indexOf("["?+?project,?begin+1);
????????????????System.err.println(end);
????????????????if?(end?==?-1)
????????????????????end?=?buffer.length();
????????????????int?index?=?buffer.indexOf(name,?begin);
????????????????System.err.println(index);

????????????????if?(index?<?end?&&?index?!=?-1)?
{
????????????????????int?line_end?=?buffer.indexOf("\n",?index);
????????????????????if?(line_end?==?-1)
????????????????????????line_end?=?buffer.length();
????????????????????buffer.replace(index?+?name.length()?+?3,?line_end,?right);

????????????????}?else?
{
????????????????????int?line_end?=?buffer.indexOf("\n",?begin);
????????????????????if?(line_end?==?-1)
????????????????????????line_end?=?buffer.length();
????????????????????buffer.insert(line_end?+?1,?name?+?"?=?"?+?right?+?"\n");
????????????????}

????????????}?else?
{
??????????????buffer.append("["?+?project?+?":"?+?path?+?"]\n");
??????????????buffer.append(name?+?"?=?"?+?right?+?"\n");
????????????}
????????????BufferedWriter?writer?=?new?BufferedWriter(new?FileWriter(passwd));
????????????writer.write(buffer.toString());
????????????writer.close();

????????}?catch?(FileNotFoundException?e)?
{
????????????//?TODO?Auto-generated?catch?block
????????????throw?new?SvnException("SvnException:?配置文件authz未找到:?"
????????????????????+?e.toString());

????????}?catch?(IOException?e)?
{
????????????//?TODO?Auto-generated?catch?block
????????????throw?new?SvnException("SvnException:?配置文件authz的io操作出現問題:?"
????????????????????+?e.toString());
????????}
????}


????/**?*//**
?????*?@param?args
?????*/

????public?static?void?main(String[]?args)?
{
????????//?TODO?Auto-generated?method?stub
????????SvnCommander?s?=?new?SvnCommander();
//????????try?{
//????????????s.createRepository("lala");
//????????}?catch?(SvnException?e)?{
//????????????//?TODO?Auto-generated?catch?block
//????????????System.err.print(e.toString());
//????????}
//?????????try?{
//?????????s.setPassword("lala",?"td",?"12344321");
//?????????}?catch?(SvnException?e)?{
//?????????//?TODO?Auto-generated?catch?block
//?????????System.err.print(e.toString());
//?????????}

????????try?
{
????????????s.setAuthz("lala","/","haha","rw");

????????}?catch?(SvnException?e)?
{
????????????//?TODO?Auto-generated?catch?block
????????????System.err.print(e.toString());
????????}
????}
}

創建svn倉庫是通過調用
Process p = new ProcessBuilder("svnadmin", "create", svn_home
?????+ project).start();
進行的。同時捕捉系統的返回查看是否有異常
BufferedReader reader = new BufferedReader(new InputStreamReader(p
?????.getErrorStream()));
???while ((tmp = reader.readLine()) != null)
????buffer.append(tmp);
???// System.err.println(buffer.toString());
???if (buffer.length() > 0)
????throw new SvnException(buffer.toString());
而對密碼和權限的修改是通過對svn默認的passwd以及authz文件進行文本操作。
另外既然是b/s模式當然有顯示的頁面,礙于篇幅就不詳述咯
最后,有兩個問題還想請問各位:
1.對文本的操作難道只能讀入內存修改后重新寫入嗎?有沒有比較高效的方法呢?
2.還需要什么額外的功能?因為svn的一些基本操作(如導入導出)其實通過svn客戶端訪問svn地址就可以了