Javaのsubversionライブラリ SVNKitを試す その2
主なパッケージ
- org.tmatesoft.svn.core.io
- 低レベルなAPIはこちら
- org.tmatesoft.svn.core.wc
- コマンドラインのsvn相当のことをしたければこれ
- org.tmatesoft.svn.core.javahl
- javaHL(nativeのSVNライブラリ)のpure java実装
今回はアプリケーションのデータストアとしてsubversionを使いたいので低レベルAPIに挑戦する。
新しいディレクトリとファイルをコミット
基本的に新規ファイルであっても差分を送信するという思想のようだ。また、ISVNEditorはカレントディレクトリを持っていて、ディレクトリツリーを辿っていくイメージだ。
DAVRepositoryFactory.setup(); SVNRepositoryFactoryImpl.setup(); FSRepositoryFactory.setup(); SVNRepository repository = SVNRepositoryFactory.create(SVNURL.parseURIEncoded("svn+ssh://example.com/path/to/repository")); ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager("hoge", "hogepass"); repository.setAuthenticationManager(authManager); ISVNEditor editor = repository.getCommitEditor("test", new NullWorkspace()); // NullWorkspaceはISVNWorkspaceMediatorの実装。今回は実装は空っぽ。 editor.openRoot(-1); editor.addDir("dirA", null, -1); editor.addFile("dirA/sample.txt", null, -1); editor.applyTextDelta("dirA/sample.txt", null); // ファイルの内容は差分で送信する。 SVNDeltaGenerator deltaGenerator = new SVNDeltaGenerator(); // 空のファイルから差分を作る String checksum = deltaGenerator.sendDelta("dirA/sample.txt", new ByteArrayInputStream("sampleData".getBytes()), editor, true); editor.closeFile("dirA/sample.txt", checksum); editor.closeDir(); // 今のディレクトリをクローズし親ディレクトリへ移動する。 editor.closeDir(); // rootがcloseされる。 editor.closeEdit();
SVNWCUtil.createDefaultAuthenticationManagerだが、createDefaultAuthenticationManager(File configDir)というディレクトリを指定できるものがある。これは、通常ユーザーディレクトリにあるSubversion/auth/の事を指すようで、中身は認証情報のキャッシュである。(参照:クライアント証明のキャッシュ)
アップデート => 編集 => コミット
repositoryからこれから編集しようとしているファイルの古いコンテンツを取ってきて、編集後に差分を作成して送信すればOK。
未解決:この間に誰かが更新=>コミットを行ってコリジョンが発生したらどうなる?
DAVRepositoryFactory.setup(); SVNRepositoryFactoryImpl.setup(); FSRepositoryFactory.setup(); SVNRepository repository = SVNRepositoryFactory.create(SVNURL.parseURIEncoded("svn+ssh://example.com/path/to/repository")); ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager("hoge", "hogepass"); repository.setAuthenticationManager(authManager); ByteArrayOutputStream bufOut = new ByteArrayOutputStream(); repository.getFile("dirA/sample.txt", -1, new HashMap(), bufOut); // 古いコンテンツをupdate byte [] oldData = bufOut.toByteArray(); ISVNEditor editor = repository.getCommitEditor("test", new NullWorkspace()); editor.openRoot(-1); editor.openDir("dirA", -1); editor.openFile("dirA/sample.txt", -1); editor.applyTextDelta("dirA/sample.txt", null); // ファイルの内容は差分で送信する。 SVNDeltaGenerator deltaGenerator = new SVNDeltaGenerator(); // 取ってきたコンテンツから差分を作る String checksum = deltaGenerator.sendDelta("dirA/sample.txt", new ByteArrayInputStream(oldData), 0, new ByteArrayInputStream("changedData".getBytes()), editor, true); ditor.closeFile("dirA/sample.txt", checksum); ditor.closeDir(); // 今のディレクトリをクローズし親ディレクトリへ移動する。 editor.closeDir(); // rootがcloseされる。 editor.closeEdit();