`
dannyhz
  • 浏览: 398095 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

SVNKIT 纯java 操作数据库

阅读更多
引用






文章主题是svnkit的api操作。所以涉及到其它类的,可以忽略。svnkit有两套api,high level和low level 。high level是操作工作拷贝即working copy的。

我这儿用的就是high level。




checkWorkCopy方法里面,先检查当前指定的路径是否是一个working copy。如果是,执行update操作;

如果不是的话,分两种情况:

1.  svn上已经有以此project命名的项目,可能svn上有了,但working copy被删了什么的。就将该project  checkout下来;

2.  svn上没有该project。此时checkout一个空的东西。SVNDepth.EMPTY,只是让我们的路径成为一个working copy,路径下出现一个.svn目录,svn上面的文件不会被checkout下来。因为我们的svn上可能项目很多。如果把整个上级目录checkout下来会很慢也浪费硬盘空间。





用 svnkit 执行commit操作,概况来说,流程如下:

1.  保证本地path是一个working copy。 即checkWorkCopy方法


2.  woking copy可能发生添加,更新,删除等变化操作

3.  检查working copy里面的文件是否under version control。即checkVersiondDirectory方法

4.  执行commit操作












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);
		}
	}

}






分享到:
评论

相关推荐

    svnkit1.8.15

    SVNKit是一个纯Java实现的Subversion客户端库,无需依赖本地SVN客户端或者C语言的SWIG接口。它为开发者提供了API,可以在不离开Java环境的情况下执行所有常见的SVN操作。此外,SVNKit还支持多种数据库后端,如 ...

    SVNKit开发手册

    SVNKit是一种Java库,它提供了对Subversion版本控制系统的完整接口,允许开发者在Java应用程序中集成Subversion功能。SVNKit开发手册为想要学习SVN二次开发的程序员提供了全面的指南,涵盖了SVNKit的主要组件与用法...

    svnkit-tool.rar

    SVNKit通过纯Java实现,无需安装任何本地SVN客户端,因此可以在各种平台如Windows、Linux和Mac OS上运行。该库支持SVN的基本操作,如创建、检查、更新、提交、合并、分支和标签。此外,它还提供了API来处理版本控制...

    jsvnkit安装包

    SVNKit是基于Apache Subversion API的一个纯Java实现,这意味着它无需任何本地SVN客户端即可工作。这使得JSVNKit可以在跨平台的应用程序中无缝运行,无论是Windows、Linux还是Mac OS。 **2. 安装过程** JSVNKit的...

    JAVA编写SVN统计代码数量系统

    Spring Boot可以通过配置自动连接数据库,并提供JPA(Java Persistence API)或MyBatis等ORM(对象关系映射)工具进行数据操作。 4. **SVN接口**:项目需要与SVN服务器进行交互,获取代码提交记录。这通常涉及到SVN...

    site-1.6.15

    3. **svnkit.jar**: SVNKit是一个纯Java实现的Subversion客户端库,允许开发者在Java应用程序中集成Subversion版本控制系统。这个JAR文件是SVNKit的核心库。 4. **sqljet.1.0.3.jar**: SQLJet是一个开源的嵌入式...

    svn java开发

    - `svnkit.jar`:这是一个纯Java实现的svn客户端库,它提供了与svn服务器通信的API,使得开发者可以在Java应用中直接集成svn功能。 - `sqljet.1.0.4.jar`:SqlJet是一个轻量级的嵌入式数据库引擎,可能被svnkit用来...

    eclipseSVN插件

    - SVNKit是Java实现的Subversion客户端库,它允许Java应用程序(如Eclipse插件)与SVN服务器进行通信。此JAR文件包含所有必要的类和方法,用于执行SVN操作。 5. **sqljet.1.0.2.jar**: - SQLJet是一款开源的...

    Eclipse SVN插件(svn-site-1.6.17)

    3. svnkit.jar:这是SVNKit的Java库,它是一个纯Java实现的SVN客户端,允许Eclipse插件在不依赖操作系统特定的SVN库的情况下工作。 4. sqljet.1.0.4.jar:SQLJet是一个开源的嵌入式数据库引擎,用于存储SVN的元数据...

    myeclipse使用的SVN插件

    3. svnkit.jar、svnkit-javahl.jar:这两个文件是SVNKit的组成部分,SVNKit是一个纯Java实现的SVN客户端库,支持JNI(Java Native Interface)与SVN库交互。svnkit.jar是主要的库文件,而svnkit-javahl.jar是用于...

    Eclipse SVN插件site-1.6.10

    SVNKit提供了与Subversion服务器交互的API,支持JavaHL(Java接口到Subversion的本机库)和纯Java实现。 4. sqljet.1.0.1.jar:SQLJet是一个开源的嵌入式数据库引擎,它允许在Java应用程序中直接操作SQLite数据库。...

    myeclipse svn

    3. svnkit.jar:这是 SVNKit 的 JAR 文件,一个纯 Java 实现的 SVN 客户端库,用于在 Java 应用程序中实现 SVN 功能。 4. sqljet.1.0.4.jar:SQLJet 是一个轻量级的嵌入式 SQL 数据库引擎,可能被 SVNKit 使用来存储...

    svn1.6.7 小组开发工具

    它为Java应用提供了一个更接近底层的接口,性能可能会优于纯Java的SVNKit。 JAVAHL-LICENSE:同COPYING,这个文件包含了JavaHL的许可信息,解释了使用JavaHL库的条件和限制。 .options:这可能是Eclipse特定的配置...

    svn插件离线版本

    3. **svnkit.jar**: SVNKit是Java实现的SVN客户端库,它允许开发者在Java应用程序中直接与SVN服务器通信。这个JAR文件是插件的核心部分,提供了SVN操作的API。 4. **sqljet.1.0.2.jar**: SQLJet是一个开源的嵌入式...

    Eclipse SVN离线安装文件

    ANTLR是一个强大的解析器生成器,而JavaHL是SVN的一个纯Java实现,它提供了更高效的性能,尤其是对于那些不支持JNI(Java Native Interface)的环境。 COPYING文件通常包含了开源软件的版权和许可信息,例如GPL...

    site-1.6.13

    3. svnkit.jar 和 svnkit-javahl.jar:这两个文件是 SVNKit 的核心组件,SVNKit 是一个纯 Java 实现的 SVN 客户端库。svnkit.jar 提供了主要的 SVN 功能,而 svnkit-javahl.jar 是一个接口,用于使用 JavaHL(Java ...

    myeclipse8.6svn

    标题 "myeclipse8.6svn" 暗示了这是一个关于如何...同时,它也可能涉及到了一些其他的开发工具或库,如SQLJet用于数据库操作,ANTLR用于解析和生成语法。如果需要更详细的教程或操作指南,可以参考博文链接提供的内容。

    配置好的svn插件(配置好的,看说明,复制即可用)

    3. svnkit.jar:这是SVNKit库的JAR文件,它是一个纯Java实现的SVN客户端API,用于在Java应用中与Subversion服务器交互。 4. sqljet.1.0.4.jar:SqlJet是一个开源的嵌入式数据库引擎,可能被用于存储SVN的元数据或...

    svn Eclipse 插件

    3. **svnkit.jar**:这是SVNKit库的JAR文件,它是一个纯Java实现的Subversion客户端API,允许在Java应用中直接与Subversion服务器通信。 4. **sqljet.1.0.1.jar**:SQLJet是开源的嵌入式数据库引擎,可能在Eclipse ...

Global site tag (gtag.js) - Google Analytics