package org.wyona.yarep.core.impl.svn;
import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Category;
import org.tmatesoft.svn.core.SVNCommitInfo;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;
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.wc.ISVNOptions;
import org.tmatesoft.svn.core.wc.ISVNPropertyHandler;
import org.tmatesoft.svn.core.wc.SVNClientManager;
import org.tmatesoft.svn.core.wc.SVNInfo;
import org.tmatesoft.svn.core.wc.SVNPropertyData;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc.SVNStatusType;
import org.tmatesoft.svn.core.wc.SVNUpdateClient;
import org.tmatesoft.svn.core.wc.SVNWCUtil;
import org.wyona.yarep.core.Property;
import org.wyona.yarep.core.RepositoryException;
/**
* The SVNClient provides standard svn methods for commit, checkout, update,
* delete, etc. It uses the SVNKit library, see www.svnkit.com
*/
public class SVNClient {
private static Category log = Category.getInstance(SVNClient.class);
protected DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
protected SVNClientManager clientManager;
/**
* Creates a client manager and sets up the repository factories.
*/
public SVNClient(String username, String password) throws SVNException {
ISVNOptions options = SVNWCUtil.createDefaultOptions(true);
clientManager = SVNClientManager.newInstance(options, username, password);
DAVRepositoryFactory.setup(); // http:// and https://
SVNRepositoryFactoryImpl.setup(); // svn:// and svn+xxx://
FSRepositoryFactory.setup(); // file:///
}
/**
* Commit a single file (not recursive).
*
* @param file
* @param commitMessage
* @throws SVNException
*/
public void commit(File file, String commitMessage) throws SVNException {
SVNCommitInfo info = clientManager.getCommitClient().doCommit(new File[] { file }, false,
commitMessage, false, false);
if (info.getErrorMessage() != null) {
throw new SVNException(info.getErrorMessage());
}
}
/**
* Commit a number of paths (not recursive).
*
* @param files
* @param commitMessage
* @throws SVNException
*/
public void commit(File[] files, String commitMessage) throws SVNException {
SVNCommitInfo info = clientManager.getCommitClient().doCommit(files, false, commitMessage,
false, false);
if (info.getErrorMessage() != null) {
throw new SVNException(info.getErrorMessage());
}
}
public long checkout(SVNURL svnRepoUrl, File svnWorkingDir) throws SVNException {
SVNUpdateClient updateClient = clientManager.getUpdateClient();
updateClient.setIgnoreExternals(false);
return updateClient.doCheckout(svnRepoUrl, svnWorkingDir, SVNRevision.HEAD,
SVNRevision.HEAD, true);
}
public void delete(File file) throws SVNException {
clientManager.getWCClient().doDelete(file, false, false);
}
public long update(File file, SVNRevision updateToRevision, boolean isRecursive)
throws SVNException {
SVNUpdateClient updateClient = clientManager.getUpdateClient();
updateClient.setIgnoreExternals(false);
return updateClient.doUpdate(file, updateToRevision, isRecursive);
}
public SVNStatusType getStatus(File file) throws SVNException {
return clientManager.getStatusClient().doStatus(file, false).getContentsStatus();
}
/**
* Recursively checks the status and throws an exception if there are any
* conflicts or if something else is wrong with the local working copy.
*/
public void checkStatus(File file) throws SVNException {
clientManager.getStatusClient().doStatus(file, true, false, false, false,
new ConsistencyStatusHandler());
}
/**
* Adds a file (not recursive).
*
* @param file
* @throws SVNException
*/
public void addFile(File file) throws SVNException {
clientManager.getWCClient().doAdd(file, false, false, false, false);
}
/**
* Adds a directory and creates it (with parents) if it does not exist. Not
* recursive.
*
* @param file
* @throws SVNException
*/
public void addDirectory(File file) throws SVNException {
clientManager.getWCClient().doAdd(file, false, true, false, false);
}
public Date getCommittedDate(File file) throws SVNException {
SVNInfo info = clientManager.getWCClient().doInfo(file, SVNRevision.HEAD);
return info.getCommittedDate();
}
/*public long[] getRevisionNumbers(File file) throws SVNException {
RevisionLogEntryHandler logHandler = new RevisionLogEntryHandler();
clientManager.getLogClient().doLog(new File[] { file }, SVNRevision.HEAD, SVNRevision.BASE,
SVNRevision.create(0), false, false, 100, logHandler);
return logHandler.getRevisions();
}*/
public String[] getRevisionStrings(File file) throws SVNException {
RevisionLogEntryHandler logHandler = new RevisionLogEntryHandler();
clientManager.getLogClient().doLog(new File[] { file }, SVNRevision.HEAD, SVNRevision.BASE,
SVNRevision.create(0), false, false, 100, logHandler);
long[] revisions = logHandler.getRevisions();
//String[] messages = logHandler.getMessages();
Date[] dates = logHandler.getDates();
String[] revStrings = new String[revisions.length];
for (int i=0; i<revisions.length; i++) {
revStrings[i] = String.valueOf(revisions[i]) + "|" + dateFormat.format(dates[i]);
}
return revStrings;
}
//TODO: this is alpha-quality incomplete code, please do not use as is or rely on the exact interface yet.
public Map<String, String> getProperties(File file) throws SVNException {
final Map<String, String> properties = new HashMap<String, String>();
ISVNPropertyHandler handler = new ISVNPropertyHandler() {
public void handleProperty(File arg0, SVNPropertyData data)
throws SVNException {
properties.put(data.getName(), data.getValue());
}
public void handleProperty(SVNURL arg0, SVNPropertyData arg1)
throws SVNException {
throw new RuntimeException("Not implemented!");
}
public void handleProperty(long arg0, SVNPropertyData arg1)
throws SVNException {
throw new RuntimeException("Not implemented!");
}
};
clientManager.getWCClient().doGetProperty(file, null, null, null, false, handler);
return properties;
}
//TODO: this is alpha-quality incomplete code, please do not use as is or rely on the exact interface yet.
public void setProperties(File file, Property[] properties) throws SVNException {
for (Property property : properties) {
try {
clientManager.getWCClient().doSetProperty(file, property.getName(), property.getValueAsString(), true, false, null);
} catch (RepositoryException e) {
log.error(e.getMessage(), e);
}
}
}
}