B/S实现远程配置SVN
 

2008-12-26 作者:dyerac 来源:blogjava.net

 

最近在尝试做一个类似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地址就可以了


火龙果软件/UML软件工程组织致力于提高您的软件工程实践能力,我们不断地吸取业界的宝贵经验,向您提供经过数百家企业验证的有效的工程技术实践经验,同时关注最新的理论进展,帮助您“领跑您所在行业的软件世界”。
资源网站: UML软件工程组织