svnkitアプリを使って、純java操作svn、svn提出、更新などの操作を実現します。
23173 ワード
http://blog.csdn.net/hardwin/article/details/7963318
文章のテーマはsvnkitのアプリ操作です。だから他のクラスに関連しています。無視できます。svnkitには二つのアプリがあります。higlevelとlow level。ハイレベは操作作業のコピーであるworking copyです。
ここで使っているのはハイレベルです。
checkWorkCopyメソッドでは、現在指定されているパスがwork copyかどうかを確認します。もしそうならば、udate操作を実行します。
もしそうでないなら、二つの状況に分けられます。
1. svnにはすでにこのプロジェクトの名前が付いています。svnにあるかもしれませんが、working copyは削除されました。このプロジェクトについて チェックアウトします
2. svnにはこのプロジェクトがありません。この時チェックアウトは空いているものです。SVNDepth.EMPTYは、私たちのパスをワードcopyにするだけで、パスの下に一つの.svnディレクトリが現れます。svn上のファイルはcheckoutに下りられません。私たちのsvnはプロジェクトが多いかもしれないからです。上位ディレクトリ全体をチェックアウトすると遅くハードディスクの空間も無駄になります。
svnkitでcomit操作を行います。概況は次の通りです。
1. ローカルパスはworking copyであることを保証します。つまり、check WorkCopy方法です。
2. woking copyは追加、更新、削除などの操作が発生する可能性があります。
3. working copyの中のファイルがunder version controlかどうかをチェックします。つまり、check Version dDirectory方法です。
4. commt操作を実行する
import java.io.File;
import org.apache.log4j.Logger;
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.SVNStatus;
import org.tmatesoft.svn.core.wc.SVNUpdateClient;
import org.tmatesoft.svn.core.wc.SVNWCUtil;
/**
* SVNKit Utility
* @author lena yang
*
*/
public class SVNUtil {
private static Logger logger = Logger.getLogger(SVNUtil.class);
/**
*
*/
public static void setupLibrary() {
DAVRepositoryFactory.setup();
SVNRepositoryFactoryImpl.setup();
FSRepositoryFactory.setup();
}
/**
* svn
*/
public static SVNClientManager authSvn(String svnRoot, String username,
String password) {
//
setupLibrary();
//
SVNRepository repository = null;
try {
repository = SVNRepositoryFactory.create(SVNURL
.parseURIEncoded(svnRoot));
} catch (SVNException e) {
logger.error(e.getErrorMessage(), e);
return null;
}
//
ISVNAuthenticationManager authManager = SVNWCUtil
.createDefaultAuthenticationManager(username, password);
//
repository.setAuthenticationManager(authManager);
DefaultSVNOptions options = SVNWCUtil.createDefaultOptions(true);
SVNClientManager clientManager = SVNClientManager.newInstance(options,
authManager);
return clientManager;
}
/**
* Make directory in svn repository
* @param clientManager
* @param url
* eg: http://svn.ambow.com/wlpt/bsp/trunk
* @param commitMessage
* @return
* @throws SVNException
*/
public static SVNCommitInfo makeDirectory(SVNClientManager clientManager,
SVNURL url, String commitMessage) {
try {
return clientManager.getCommitClient().doMkDir(
new SVNURL[] { url }, commitMessage);
} catch (SVNException e) {
logger.error(e.getErrorMessage(), e);
}
return null;
}
/**
* Imports an unversioned directory into a repository location denoted by a
* destination URL
* @param clientManager
* @param localPath
* a local unversioned directory or singal file that will be imported into a
* repository;
* @param dstURL
* a repository location where the local unversioned directory/file will be
* imported into
* @param commitMessage
* @param isRecursive
* @return
*/
public static SVNCommitInfo importDirectory(SVNClientManager clientManager,
File localPath, SVNURL dstURL, String commitMessage,
boolean isRecursive) {
try {
return clientManager.getCommitClient().doImport(localPath, dstURL,
commitMessage, null, true, true,
SVNDepth.fromRecurse(isRecursive));
} catch (SVNException e) {
logger.error(e.getErrorMessage(), e);
}
return null;
}
/**
* Puts directories and files under version control
* @param clientManager
* SVNClientManager
* @param wcPath
* work copy path
*/
public static void addEntry(SVNClientManager clientManager, File wcPath) {
try {
clientManager.getWCClient().doAdd(new File[] { wcPath }, true,
false, false, SVNDepth.INFINITY, false, false,
true);
} catch (SVNException e) {
logger.error(e.getErrorMessage(), e);
}
}
/**
* Collects status information on a single Working Copy item
* @param clientManager
* @param wcPath
* local item's path
* @param remote
* true to check up the status of the item in the repository,
* that will tell if the local item is out-of-date (like '-u' option in the SVN client's
* 'svn status' command), otherwise false
* @return
* @throws SVNException
*/
public static SVNStatus showStatus(SVNClientManager clientManager,
File wcPath, boolean remote) {
SVNStatus status = null;
try {
status = clientManager.getStatusClient().doStatus(wcPath, remote);
} catch (SVNException e) {
logger.error(e.getErrorMessage(), e);
}
return status;
}
/**
* Commit work copy's change to svn
* @param clientManager
* @param wcPath
* working copy paths which changes are to be committed
* @param keepLocks
* whether to unlock or not files in the repository
* @param commitMessage
* commit log message
* @return
* @throws SVNException
*/
public static SVNCommitInfo commit(SVNClientManager clientManager,
File wcPath, boolean keepLocks, String commitMessage) {
try {
return clientManager.getCommitClient().doCommit(
new File[] { wcPath }, keepLocks, commitMessage, null,
null, false, false, SVNDepth.INFINITY);
} catch (SVNException e) {
logger.error(e.getErrorMessage(), e);
}
return null;
}
/**
* 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
* @throws SVNException
*/
public static long update(SVNClientManager clientManager, 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(), e);
}
return 0;
}
/**
* recursively checks out a working copy from url into wcDir
* @param clientManager
* @param url
* a repository location from where a Working Copy will be checked out
* @param revision
* the desired revision of the Working Copy to be checked out
* @param destPath
* the local path where the Working Copy will be placed
* @param depth
* checkout , 、 、
* @return
* @throws SVNException
*/
public static long checkout(SVNClientManager clientManager, SVNURL url,
SVNRevision revision, File destPath, SVNDepth depth) {
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 {
return updateClient.doCheckout(url, destPath, revision, revision,depth, false);
} catch (SVNException e) {
logger.error(e.getErrorMessage(), e);
}
return 0;
}
/**
* path
* @param path
* @return
*/
public static 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);
}
return true;
}
/**
* URL SVN
* @param url
* @return
*/
public static 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 、
* @author lena yang
*
*/
@Service("svnProjectService")
public class SvnProjectService {
private Logger logger = Logger.getLogger(SvnProjectService.class);
//
private String workspace = null;
private ResourceBundle rb = ResourceBundle.getBundle("application");
// SVN 、
private String username = null;
private String password = null;
private String templete = null;
@Resource(name="xcodeService")
private XcodeService xcodeService;
private void init(){
String webapp = System.getProperty("webapp.root");
if(null!=webapp&&!webapp.endsWith("/") && !webapp.endsWith("\\")){
webapp = webapp + "/";
}
// web , WebContent
if(new File(webapp + "WebContent").exists()){
webapp = webapp + "WebContent";
}
username = rb.getString("svn.username");
password = rb.getString("svn.password");
workspace = rb.getString("project.svn.path");
templete = webapp + "templete";
}
public SvnProjectService(){
super();
init();
}
/**
*
* @param project
* Project
* @return
*/
public boolean createProjectFrame(Project project,List<String> tableNames) {
if(project == null){
return false;
}
File src = new File(templete); //
File ws = new File(workspace); // work copy
if(!ws.exists()){
ws.mkdirs();
}
File dest = new File(workspace + "/" + project.getName());
if(!dest.exists()){
dest.mkdirs();
}
checkWorkCopy(project); //
//
try {
FileUtils.copyDirectory(src, dest);
} catch (IOException e) {
logger.error(e.getMessage(), e);
return false;
}
// .project
editProjectFile(project);
//
xcodeService.createBaseFrameWithDatasource(project,tableNames);
// SVN
commitProjectToSvn(project);
return true;
}
/**
*
* @param project
* @throws DocumentException
* @throws IOException
*/
@SuppressWarnings("unchecked")
private void editProjectFile(Project project) {
String pro = workspace + "/" + project.getName() + "/";
String settings = pro + ".settings/";
// 1. .settings/org.eclipse.wst.common.component
Document document = null;
try {
document = XmlReaderUtil.getDocument(new File(settings
+ "org.eclipse.wst.common.component"));
} catch (DocumentException e) {
e.printStackTrace();
}
Element root = document.getRootElement();
root.element("wb-module").attribute("deploy-name")
.setValue(project.getName());
if (root.element("wb-module").element("property").attribute("name")
.getValue().equals("java-output-path")) {
root.element("wb-module").element("property").attribute("value")
.setValue("/" + project.getName() + "/build/classes");
}
Iterator<Element> itr = (Iterator<Element>) XmlReaderUtil.getElements(
document, "//wb-module//property").iterator();
while (itr.hasNext()) {
Element element = itr.next();
if ("context-root".equals(element.attribute("name").getValue())) {
element.attribute("value").setValue("/" + project.getName());
}
}
//
XmlReaderUtil.writerXml(document, settings
+ "org.eclipse.wst.common.component");
// 2. .project
try {
document = XmlReaderUtil.getDocument(new File(pro + ".project"));
XmlReaderUtil.setElementText(document, "//projectDescription",
"name", project.getName());
XmlReaderUtil.writerXml(document, pro + ".project");
} catch (DocumentException e) {
e.printStackTrace();
}
}
/**
* SVN work copy
* @param project
* Project
* @return
*/
public boolean updateProjectFromSvn(Project project) {
if(null == project || null == rb.getString("svn.url")){
return false;
}
project.setSvnUrl(rb.getString("svn.url"));
SVNClientManager clientManager = SVNUtil.authSvn(project.getSvnUrl(), username, password);
if (null == clientManager) {
logger.error("SVN login error! >>> url:" + project.getSvnUrl()
+ " username:" + username + " password:" + password);
return false;
}
//
clientManager.getCommitClient().setEventHandler(new UpdateEventHandler());
SVNURL repositoryURL = null;
try {
// eg: http://svn.ambow.com/wlpt/bsp
repositoryURL = SVNURL.parseURIEncoded(project.getSvnUrl()).appendPath("trunk/"+project.getName(), false);
} catch (SVNException e) {
logger.error(e.getMessage(),e);
return false;
}
File ws = new File(new File(workspace), project.getName());
if(!SVNWCUtil.isVersionedDirectory(ws)){
SVNUtil.checkout(clientManager, repositoryURL, SVNRevision.HEAD, new File(workspace), SVNDepth.INFINITY);
}else{
SVNUtil.update(clientManager, ws, SVNRevision.HEAD, SVNDepth.INFINITY);
}
return true;
}
/**
* SVN
* @param project
* Project
* @return
*/
public boolean commitProjectToSvn(Project project) {
SVNClientManager clientManager = SVNUtil.authSvn(project.getSvnUrl(), username, password);
clientManager.getCommitClient().setEventHandler(new CommitEventHandler());
File wc_project = new File( workspace + "/" + project.getName());
checkVersiondDirectory(clientManager,wc_project);
SVNUtil.commit(clientManager, wc_project, false, "svnkit");
return true;
}
/**
* , add svn
* @param clientManager
* @param wc
*/
private void checkVersiondDirectory(SVNClientManager clientManager,File wc){
if(!SVNWCUtil.isVersionedDirectory(wc)){
SVNUtil.addEntry(clientManager, wc);
}
if(wc.isDirectory()){
for(File sub:wc.listFiles()){
if(sub.isDirectory() && sub.getName().equals(".svn")){
continue;
}
checkVersiondDirectory(clientManager,sub);
}
}
}
private void checkWorkCopy(Project project){
project.setSvnUrl(rb.getString("svn.url"));
SVNClientManager clientManager = SVNUtil.authSvn(project.getSvnUrl(), username, password);
SVNURL repositoryURL = null; // trunk
try {
// eg: http://svn.ambow.com/wlpt/bsp
repositoryURL = SVNURL.parseURIEncoded(project.getSvnUrl())
.appendPath("trunk", false);
} catch (SVNException e) {
logger.error(e.getMessage(),e);
}
File wc = new File(workspace);
File wc_project = new File( workspace + "/" + project.getName());
SVNURL projectURL = null; // projectName
try {
projectURL = repositoryURL.appendPath(project.getName(), false);
} catch (SVNException e) {
logger.error(e.getMessage(),e);
}
if(!SVNUtil.isWorkingCopy(wc)){
if(!SVNUtil.isURLExist(projectURL,username,password)){
SVNUtil.checkout(clientManager, repositoryURL, SVNRevision.HEAD, wc, SVNDepth.EMPTY);
}else{
SVNUtil.checkout(clientManager, projectURL, SVNRevision.HEAD, wc_project, SVNDepth.INFINITY);
}
}else{
SVNUtil.update(clientManager, wc, SVNRevision.HEAD, SVNDepth.INFINITY);
}
}
}
文章のテーマはsvnkitのアプリ操作です。だから他のクラスに関連しています。無視できます。svnkitには二つのアプリがあります。higlevelとlow level。ハイレベは操作作業のコピーであるworking copyです。
ここで使っているのはハイレベルです。
checkWorkCopyメソッドでは、現在指定されているパスがwork copyかどうかを確認します。もしそうならば、udate操作を実行します。
もしそうでないなら、二つの状況に分けられます。
1. svnにはすでにこのプロジェクトの名前が付いています。svnにあるかもしれませんが、working copyは削除されました。このプロジェクトについて チェックアウトします
2. svnにはこのプロジェクトがありません。この時チェックアウトは空いているものです。SVNDepth.EMPTYは、私たちのパスをワードcopyにするだけで、パスの下に一つの.svnディレクトリが現れます。svn上のファイルはcheckoutに下りられません。私たちのsvnはプロジェクトが多いかもしれないからです。上位ディレクトリ全体をチェックアウトすると遅くハードディスクの空間も無駄になります。
svnkitでcomit操作を行います。概況は次の通りです。
1. ローカルパスはworking copyであることを保証します。つまり、check WorkCopy方法です。
2. woking copyは追加、更新、削除などの操作が発生する可能性があります。
3. working copyの中のファイルがunder version controlかどうかをチェックします。つまり、check Version dDirectory方法です。
4. commt操作を実行する