SVNにJavaからアクセス

先日Perlでリビジョンの推移を計測してみた。
今度は調子のって、誰が何ライン加筆・修正したかを計測しよう考えた。

SVNが持っている情報を最大限に引き出せば、
じゅうぶん求められる指標であることは間違いない。

でみ、SVNコマンドをチマチマと呼び出していたのでは限界がある気がする。

そこで、SVNのバイブル

Subversion実践入門:達人プログラマに学ぶバージョン管理(第2版)

Subversion実践入門:達人プログラマに学ぶバージョン管理(第2版)

で調べてみたらJavaSVNというのがあった。


そこでさっそく昼下がりの眠たい時間でトライしてみた。
それにしても日本語のブログでは、「JavaSVNってのがあるんだぜ」で終わってる記事が多過ぎるかと。
取り合えず簡単なサンプルコードぐらい書けよと声を大にして言いたい。



取り敢えずダウンロードはこちらから
http://svnkit.com/download.php

ダウンロードしたファイルの中から*.jarなファイルをEclipseのBulidPathに追加して。
後は、コードをカキカキしてみる。





Subversion 実践入門をタイプしなおしただけ

package main;

import java.util.*;


import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;

public class JavaSVN {

	/**
	 * 
	 * @param args
	 * @throws SVNException 
	 */
	public static void main(String[] args) throws SVNException {
		// TODO 自動生成されたメソッド・スタブ
		String repoUrl = "http://hostname/apple/";
		SVNURL url = SVNURL.parseURIEncoded(repoUrl);
		
		DAVRepositoryFactory.setup();
		SVNRepository repository = SVNRepositoryFactory.create(url);
		Map<String,String> dirProps = new HashMap<String,String>();
		List<SVNDirEntry> dirEntries = new ArrayList<SVNDirEntry>();
		
		repository.getDir("trunk/", -1,  dirProps, dirEntries);
		
		for (SVNDirEntry dirEntry : dirEntries) {
			printEntry(dirEntry);
		}
		
	}

	private static void printEntry(SVNDirEntry entry) {
		if(entry.getKind() == SVNNodeKind.DIR) {
			System.out.println("Directory = " + entry.getName());
		} else {
			System.out.println("File:" + entry.getName() 
								+ "size:" + entry.getSize()
								+ "last modify by " + entry.getAuthor());
		}
	}
}

と打ち込んでみるとEclipseがエラーを出してる.

repository.getDir("/trunk", -1,  dirProps, dirEntries);


JavaDocを見ると。

abstract long getDir(String path, long revision, SVNProperties properties, int entryFields, ISVNDirEntryHandler handler)
Fetches the contents and/or properties of a directory located at the specified path in a particular revision with the possibility to specify fields of the entry to fetch.
SVNProperties dirProps = new SVNProperties();


なるほどねーってコトで変更すると.今度は

Exception in thread "main" org.tmatesoft.svn.core.SVNAuthenticationException: svn: OPTIONS of '/apple/': 401 Authorization Required (http://hostname)
なるほど認証が通らない。こういう時はサンプルを見れば良いんじゃないかな?ってコトで.
http://svnkit.com/kb/examples/index.php
org.tmatesoft.svn.examples.repositoryのCommit.javaを見てみると、認証っぽい記述があったので真似て挿入してみる

package main;

import java.util.*;

import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.wc.SVNWCUtil;

public class JavaSVN {

	/**
	 * 
	 * @param args
	 * @throws SVNException 
	 */
	public static void main(String[] args) throws SVNException {
		// TODO 自動生成されたメソッド・スタブ
		String repoUrl = "http://hostname/apple/";
		SVNURL url = SVNURL.parseURIEncoded(repoUrl);
		DAVRepositoryFactory.setup();
		SVNRepository repository = SVNRepositoryFactory.create(url);
		
		/* 認証機能を追加 */
		String userName = "jobs";
                String userPassword = "apple";

                ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(userName, userPassword);
                repository.setAuthenticationManager(authManager);
                /* ここまで */

		SVNProperties dirProps = new SVNProperties();//エラーのため修正
		List<SVNDirEntry> dirEntries = new ArrayList<SVNDirEntry>();
		
		repository.getDir("trunk/", -1,  dirProps, dirEntries);
		
		for (SVNDirEntry dirEntry : dirEntries) {
			printEntry(dirEntry);
		}
		
	}

	private static void printEntry(SVNDirEntry entry) {
		if(entry.getKind() == SVNNodeKind.DIR) {
			System.out.println("Directory = " + entry.getName());
		} else {
			System.out.println("File:" + entry.getName() 
								+ "size:" + entry.getSize()
								+ "last modify by " + entry.getAuthor());
		}
	}
}


途中,Exception in thread "main" org.tmatesoft.svn.core.SVNException: svn: '/apple/!svn/bc/885/trunk' path not found: 404 Not Found (http://hostname)
というエラーに出くわして随分と悩んだ....


原因は

repository.getDir("trunk/", -1, dirProps, dirEntries);

repository.getDir("/trunk/", -1, dirProps, dirEntries);

としていたコト
実行結果

Directory = src
Directory = src-shared
Directory = src-client
Directory = conf
Directory = WebContent
Directory = build
File:.projectsize:1416last modify by jobs
Directory = .settings


取り敢えず昼から始めて1時間ぐらいでここまでたどり着いた。