Index: java/SVNAccess/.classpath
===================================================================
--- java/SVNAccess/.classpath	(revision 732)
+++ java/SVNAccess/.classpath	(revision 732)
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+	<classpathentry kind="lib" path="/_ThirdPartyLibs/svnkit/antlr-runtime-3.4.jar"/>
+	<classpathentry kind="lib" path="/_ThirdPartyLibs/svnkit/sequence-library-1.0.2.jar"/>
+	<classpathentry kind="lib" path="/_ThirdPartyLibs/svnkit/sqljet-1.1.6.jar"/>
+	<classpathentry kind="lib" path="/_ThirdPartyLibs/svnkit/svnkit-1.7.8.jar" sourcepath="/home/ci/.m2/repository/org/tmatesoft/svnkit/svnkit/1.7.8/svnkit-1.7.8-sources.jar"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
Index: java/SVNAccess/.project
===================================================================
--- java/SVNAccess/.project	(revision 732)
+++ java/SVNAccess/.project	(revision 732)
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>SVNAccess</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: java/SVNAccess/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- java/SVNAccess/.settings/org.eclipse.jdt.core.prefs	(revision 732)
+++ java/SVNAccess/.settings/org.eclipse.jdt.core.prefs	(revision 732)
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
Index: java/SVNAccess/src/net/oni2/svnaccess/DirEntryHandler.java
===================================================================
--- java/SVNAccess/src/net/oni2/svnaccess/DirEntryHandler.java	(revision 732)
+++ java/SVNAccess/src/net/oni2/svnaccess/DirEntryHandler.java	(revision 732)
@@ -0,0 +1,37 @@
+package net.oni2.svnaccess;
+
+import java.util.Vector;
+
+import org.tmatesoft.svn.core.ISVNDirEntryHandler;
+import org.tmatesoft.svn.core.SVNDirEntry;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.SVNNodeKind;
+
+
+/**
+ * Used to get the files in a SVN repository
+ * 
+ * @author Christian Illy
+ */
+public class DirEntryHandler implements ISVNDirEntryHandler {
+
+	Vector<String>	target;
+
+
+	/**
+	 * Create a new DirEntryHandler with a list to store the found files in.
+	 * 
+	 * @param targetList
+	 *            Vector used to store the file names
+	 */
+	public DirEntryHandler(Vector<String> targetList) {
+		this.target = targetList;
+	}
+
+	@Override
+	public void handleDirEntry(SVNDirEntry dirEntry) throws SVNException {
+		if (dirEntry.getKind() == SVNNodeKind.FILE)
+			target.add(dirEntry.getURL().getPath());
+	}
+
+}
Index: java/SVNAccess/src/net/oni2/svnaccess/LogEntryHandler.java
===================================================================
--- java/SVNAccess/src/net/oni2/svnaccess/LogEntryHandler.java	(revision 732)
+++ java/SVNAccess/src/net/oni2/svnaccess/LogEntryHandler.java	(revision 732)
@@ -0,0 +1,48 @@
+package net.oni2.svnaccess;
+
+import java.util.Vector;
+
+import org.tmatesoft.svn.core.ISVNLogEntryHandler;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.SVNLogEntry;
+import org.tmatesoft.svn.core.SVNLogEntryPath;
+
+
+/**
+ * Used to get the updated files from SVN between working copy revision and
+ * HEAD.
+ * 
+ * @author Christian Illy
+ */
+public class LogEntryHandler implements ISVNLogEntryHandler {
+
+	Vector<String>	target;
+	String			base;
+
+
+	/**
+	 * Create a new LogEntryHandler with a list to store the found paths to and
+	 * a base path in the repository (paths outside are ignored)
+	 * 
+	 * @param targetList Vector to store the found paths to
+	 * @param basePath Base path of folder to look at
+	 */
+	public LogEntryHandler(Vector<String> targetList, String basePath) {
+		this.target = targetList;
+		this.base = basePath;
+	}
+
+	@Override
+	public void handleLogEntry(SVNLogEntry logEntry) throws SVNException {
+		for (Object o : logEntry.getChangedPaths().keySet()) {
+			SVNLogEntryPath p = (SVNLogEntryPath) logEntry.getChangedPaths()
+					.get(o);
+			if (p.getPath().startsWith(base)) {
+				if (p.getType() != 'D')
+					if (!target.contains(p.getPath()))
+						target.add(p.getPath());
+			}
+		}
+	}
+
+}
Index: java/SVNAccess/src/net/oni2/svnaccess/SVN.java
===================================================================
--- java/SVNAccess/src/net/oni2/svnaccess/SVN.java	(revision 732)
+++ java/SVNAccess/src/net/oni2/svnaccess/SVN.java	(revision 732)
@@ -0,0 +1,224 @@
+package net.oni2.svnaccess;
+
+import static java.lang.System.err;
+
+import java.io.File;
+import java.util.Vector;
+
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.SVNDirEntry;
+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.SVNClientManager;
+import org.tmatesoft.svn.core.wc.SVNInfo;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc.SVNWCUtil;
+
+/**
+ * SVN handling
+ * 
+ * @author Christian Illy
+ */
+public class SVN {
+
+	SVNClientManager svnCManager = null;
+
+	/**
+	 * Constructor
+	 */
+	public SVN() {
+		// For using over http:// and https://
+		DAVRepositoryFactory.setup();
+		// For using over svn:// and svn+xxx://
+		SVNRepositoryFactoryImpl.setup();
+		// For using over file:///
+		FSRepositoryFactory.setup();
+
+		svnCManager = SVNClientManager.newInstance(SVNWCUtil
+				.createDefaultOptions(true));
+	}
+
+	/**
+	 * Constructor with init values
+	 * 
+	 * @param username
+	 *            Username
+	 * @param password
+	 *            Password
+	 */
+	public SVN(String username, String password) {
+		// For using over http:// and https://
+		DAVRepositoryFactory.setup();
+		// For using over svn:// and svn+xxx://
+		SVNRepositoryFactoryImpl.setup();
+		// For using over file:///
+		FSRepositoryFactory.setup();
+
+		svnCManager = SVNClientManager.newInstance(
+				SVNWCUtil.createDefaultOptions(true), username, password);
+	}
+
+	/**
+	 * Checkout/update a repository to a local path
+	 * 
+	 * @param reposUrl
+	 *            Repository URL
+	 * @param wcDir
+	 *            Local path
+	 * @param listener
+	 *            The listener for the status events
+	 * @return True if successful
+	 * @throws Exception
+	 *             if missing parameters or something went wrong
+	 */
+	public boolean updateWC(String reposUrl, File wcDir,
+			SVNUpdateListener listener) throws Exception {
+		SVNURL repos = SVNURL.parseURIEncoded(reposUrl);
+
+		if (wcDir.exists()) {
+			int rev = pathIsWCof(repos, wcDir);
+			if (rev < 0)
+				throw new Exception(
+						"Destination path exists but is not a Working Copy of the SVN");
+			return update(repos, wcDir, rev, listener);
+		} else {
+			return checkout(repos, wcDir, listener);
+		}
+	}
+
+	/**
+	 * Checks if the SVN contains newer revisions than the local working copy
+	 * 
+	 * @param reposUrl
+	 *            URL of repository to check for newer revisions
+	 * @param wcDir
+	 *            Local working copy path to compare against
+	 * @return -1: No local working copy yet<br>
+	 *         0: Revisions are equal<br>
+	 *         1: SVN contains newer revisions
+	 * @throws Exception
+	 *             If destination is not a WC of the given repository
+	 */
+	public int checkSVN(String reposUrl, File wcDir) throws Exception {
+		SVNURL repos = SVNURL.parseURIEncoded(reposUrl);
+
+		if (wcDir.exists()) {
+			int localRev = pathIsWCof(repos, wcDir);
+			if (localRev < 0)
+				throw new Exception(
+						"Destination path exists but is not a Working Copy of the SVN");
+			int remoteRev = getRemoteHeadRevision(repos);
+			if (remoteRev > localRev)
+				return 1;
+			else
+				return 0;
+		} else {
+			return -1;
+		}
+	}
+
+	private int getRemoteHeadRevision(SVNURL reposUrl) {
+		try {
+			SVNInfo info = svnCManager.getWCClient().doInfo(reposUrl,
+					SVNRevision.HEAD, SVNRevision.HEAD);
+			return (int) info.getRevision().getNumber();
+		} catch (SVNException e) {
+			e.printStackTrace();
+		}
+		return -1;
+	}
+
+	private int pathIsWCof(SVNURL reposUrl, File wcDir) {
+		if (wcDir.exists()) {
+			try {
+				SVNInfo info = svnCManager.getWCClient().doInfo(wcDir,
+						SVNRevision.WORKING);
+
+				if (info.getURL().equals(reposUrl))
+					return (int) info.getRevision().getNumber();
+			} catch (SVNException e) {
+				err.println("Error while getting information of working copy for the location '"
+						+ reposUrl + "': " + e.getMessage());
+			}
+		}
+		return -1;
+	}
+
+	private Vector<String> getUpdatedFilesInRepository(SVNURL reposUrl,
+			int fromRev) {
+		Vector<String> list = new Vector<String>();
+		try {
+			svnCManager.getLogClient().doLog(reposUrl,
+					new String[] { reposUrl.getPath() }, SVNRevision.HEAD,
+					SVNRevision.create(fromRev + 1), SVNRevision.HEAD, true,
+					true, 0, new LogEntryHandler(list, reposUrl.getPath()));
+		} catch (Exception e) {
+			if (e.getMessage().startsWith("svn: No such revision "))
+				return null;
+			err.println("Error while getting the list of updated files of the location '"
+					+ reposUrl + "': " + e.getMessage());
+			e.printStackTrace();
+		}
+
+		return list;
+	}
+
+	private boolean update(SVNURL reposUrl, File wcDir, int fromRev,
+			SVNUpdateListener listener) throws Exception {
+		Vector<String> updatedFiles = getUpdatedFilesInRepository(reposUrl,
+				fromRev);
+
+		if (updatedFiles == null)
+			return true;
+
+		svnCManager.getUpdateClient().setEventHandler(
+				new UpdateEventHandler(updatedFiles, listener));
+
+		try {
+			svnCManager.getUpdateClient().doUpdate(wcDir, SVNRevision.HEAD,
+					SVNDepth.INFINITY, true, true);
+			return true;
+		} catch (Exception e) {
+			err.println("Error while updating the working copy for the location '"
+					+ reposUrl + "': " + e.getMessage());
+		}
+		return false;
+	}
+
+	private Vector<String> getFilesInRepository(SVNURL reposUrl)
+			throws Exception {
+		Vector<String> list = new Vector<String>();
+		try {
+			svnCManager.getLogClient().doList(reposUrl, SVNRevision.HEAD,
+					SVNRevision.HEAD, false, SVNDepth.INFINITY,
+					SVNDirEntry.DIRENT_ALL, new DirEntryHandler(list));
+		} catch (Exception e) {
+			err.println("Error while getting the list of files of the location '"
+					+ reposUrl + "': " + e.getMessage());
+		}
+		return list;
+	}
+
+	private boolean checkout(SVNURL reposUrl, File wcDir,
+			SVNUpdateListener listener) throws Exception {
+		Vector<String> newFiles = getFilesInRepository(reposUrl);
+		svnCManager.getUpdateClient().setEventHandler(
+				new UpdateEventHandler(newFiles, listener));
+
+		boolean result = false;
+		try {
+			wcDir.mkdirs();
+			svnCManager.getUpdateClient()
+					.doCheckout(reposUrl, wcDir, SVNRevision.HEAD,
+							SVNRevision.HEAD, SVNDepth.INFINITY, true);
+			result = true;
+		} catch (Exception e) {
+			err.println("Error while checking out a working copy for the location '"
+					+ reposUrl + "': " + e.getMessage());
+		}
+		return result;
+	}
+}
Index: java/SVNAccess/src/net/oni2/svnaccess/SVNUpdateListener.java
===================================================================
--- java/SVNAccess/src/net/oni2/svnaccess/SVNUpdateListener.java	(revision 732)
+++ java/SVNAccess/src/net/oni2/svnaccess/SVNUpdateListener.java	(revision 732)
@@ -0,0 +1,19 @@
+package net.oni2.svnaccess;
+
+/**
+ * Interface for listeners to status updates during checkout/update from SVN
+ * 
+ * @author Christian Illy
+ */
+public interface SVNUpdateListener {
+
+	/**
+	 * Called after checking out / updating a single file
+	 * 
+	 * @param done
+	 *            Files done
+	 * @param total
+	 *            Total files for the current checkout/update
+	 */
+	public void statusUpdate(int done, int total);
+}
Index: java/SVNAccess/src/net/oni2/svnaccess/UpdateEventHandler.java
===================================================================
--- java/SVNAccess/src/net/oni2/svnaccess/UpdateEventHandler.java	(revision 732)
+++ java/SVNAccess/src/net/oni2/svnaccess/UpdateEventHandler.java	(revision 732)
@@ -0,0 +1,64 @@
+package net.oni2.svnaccess;
+
+import java.util.Vector;
+
+import org.tmatesoft.svn.core.SVNCancelException;
+import org.tmatesoft.svn.core.wc.ISVNEventHandler;
+import org.tmatesoft.svn.core.wc.SVNEvent;
+import org.tmatesoft.svn.core.wc.SVNEventAction;
+
+
+/**
+ * Handler to return checkout/update status
+ * 
+ * @author Christian Illy
+ */
+public class UpdateEventHandler implements ISVNEventHandler {
+
+	Vector<String>		list;
+	int					objects;
+	SVNUpdateListener	listener;
+
+
+	/**
+	 * Create a new UpdateEventHandler with a file name list
+	 * 
+	 * @param infoList
+	 *            List containing the file names of all files which will be
+	 *            checked out / updated
+	 * @param listener
+	 *            Listener to send status events to
+	 */
+	public UpdateEventHandler(Vector<String> infoList,
+			SVNUpdateListener listener) {
+		this.list = infoList;
+		this.listener = listener;
+		if (list != null)
+			objects = list.size();
+		else
+			objects = -1;
+	}
+
+	public void handleEvent(SVNEvent event, double progress) {
+		SVNEventAction action = event.getAction();
+		if ((action == SVNEventAction.UPDATE_ADD)
+				|| (action == SVNEventAction.UPDATE_UPDATE)) {
+			if (list != null) {
+				list.remove(event.getURL().getPath());
+				if (listener != null) {
+					listener.statusUpdate(objects - list.size(), objects);
+				} else {
+					System.out.println((objects - list.size()) + " of "
+							+ objects + " done");
+				}
+			}
+		}
+	}
+
+	/*
+	 * Should be implemented to check if the current operation is cancelled. If
+	 * it is, this method should throw an SVNCancelException.
+	 */
+	public void checkCancelled() throws SVNCancelException {
+	}
+}
