| 1 | package net.oni2.svnaccess; | 
 
 
 
 
 | 2 |  | 
 
 
 
 
 | 3 | import static java.lang.System.err; | 
 
 
 
 
 | 4 |  | 
 
 
 
 
 | 5 | import java.io.File; | 
 
 
 
 
 | 6 | import java.util.Vector; | 
 
 
 
 
 | 7 |  | 
 
 
 
 
 | 8 | import org.tmatesoft.svn.core.SVNDepth; | 
 
 
 
 
 | 9 | import org.tmatesoft.svn.core.SVNDirEntry; | 
 
 
 
 
 | 10 | import org.tmatesoft.svn.core.SVNException; | 
 
 
 
 
 | 11 | import org.tmatesoft.svn.core.SVNURL; | 
 
 
 
 
 | 12 | import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory; | 
 
 
 
 
 | 13 | import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory; | 
 
 
 
 
 | 14 | import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl; | 
 
 
 
 
 | 15 | import org.tmatesoft.svn.core.wc.SVNClientManager; | 
 
 
 
 
 | 16 | import org.tmatesoft.svn.core.wc.SVNInfo; | 
 
 
 
 
 | 17 | import org.tmatesoft.svn.core.wc.SVNRevision; | 
 
 
 
 
 | 18 | import org.tmatesoft.svn.core.wc.SVNWCUtil; | 
 
 
 
 
 | 19 |  | 
 
 
 
 
 | 20 | /** | 
 
 
 
 
 | 21 | * SVN handling | 
 
 
 
 
 | 22 | * | 
 
 
 
 
 | 23 | * @author Christian Illy | 
 
 
 
 
 | 24 | */ | 
 
 
 
 
 | 25 | public class SVN { | 
 
 
 
 
 | 26 |  | 
 
 
 
 
 | 27 | SVNClientManager svnCManager = null; | 
 
 
 
 
 | 28 |  | 
 
 
 
 
 | 29 | /** | 
 
 
 
 
 | 30 | * Constructor | 
 
 
 
 
 | 31 | */ | 
 
 
 
 
 | 32 | public SVN() { | 
 
 
 
 
 | 33 | // For using over http:// and https:// | 
 
 
 
 
 | 34 | DAVRepositoryFactory.setup(); | 
 
 
 
 
 | 35 | // For using over svn:// and svn+xxx:// | 
 
 
 
 
 | 36 | SVNRepositoryFactoryImpl.setup(); | 
 
 
 
 
 | 37 | // For using over file:/// | 
 
 
 
 
 | 38 | FSRepositoryFactory.setup(); | 
 
 
 
 
 | 39 |  | 
 
 
 
 
 | 40 | svnCManager = SVNClientManager.newInstance(SVNWCUtil | 
 
 
 
 
 | 41 | .createDefaultOptions(true)); | 
 
 
 
 
 | 42 | } | 
 
 
 
 
 | 43 |  | 
 
 
 
 
 | 44 | /** | 
 
 
 
 
 | 45 | * Constructor with init values | 
 
 
 
 
 | 46 | * | 
 
 
 
 
 | 47 | * @param username | 
 
 
 
 
 | 48 | *            Username | 
 
 
 
 
 | 49 | * @param password | 
 
 
 
 
 | 50 | *            Password | 
 
 
 
 
 | 51 | */ | 
 
 
 
 
 | 52 | public SVN(String username, String password) { | 
 
 
 
 
 | 53 | // For using over http:// and https:// | 
 
 
 
 
 | 54 | DAVRepositoryFactory.setup(); | 
 
 
 
 
 | 55 | // For using over svn:// and svn+xxx:// | 
 
 
 
 
 | 56 | SVNRepositoryFactoryImpl.setup(); | 
 
 
 
 
 | 57 | // For using over file:/// | 
 
 
 
 
 | 58 | FSRepositoryFactory.setup(); | 
 
 
 
 
 | 59 |  | 
 
 
 
 
 | 60 | svnCManager = SVNClientManager.newInstance( | 
 
 
 
 
 | 61 | SVNWCUtil.createDefaultOptions(true), username, password); | 
 
 
 
 
 | 62 | } | 
 
 
 
 
 | 63 |  | 
 
 
 
 
 | 64 | /** | 
 
 
 
 
 | 65 | * Checkout/update a repository to a local path | 
 
 
 
 
 | 66 | * | 
 
 
 
 
 | 67 | * @param reposUrl | 
 
 
 
 
 | 68 | *            Repository URL | 
 
 
 
 
 | 69 | * @param wcDir | 
 
 
 
 
 | 70 | *            Local path | 
 
 
 
 
 | 71 | * @param listener | 
 
 
 
 
 | 72 | *            The listener for the status events | 
 
 
 
 
 | 73 | * @return True if successful | 
 
 
 
 
 | 74 | * @throws Exception | 
 
 
 
 
 | 75 | *             if missing parameters or something went wrong | 
 
 
 
 
 | 76 | */ | 
 
 
 
 
 | 77 | public boolean updateWC(String reposUrl, File wcDir, | 
 
 
 
 
 | 78 | SVNUpdateListener listener) throws Exception { | 
 
 
 
 
 | 79 | SVNURL repos = SVNURL.parseURIEncoded(reposUrl); | 
 
 
 
 
 | 80 |  | 
 
 
 
 
 | 81 | if (wcDir.exists()) { | 
 
 
 
 
 | 82 | int rev = pathIsWCof(repos, wcDir); | 
 
 
 
 
 | 83 | if (rev < 0) | 
 
 
 
 
 | 84 | throw new Exception( | 
 
 
 
 
 | 85 | "Destination path exists but is not a Working Copy of the SVN"); | 
 
 
 
 
 | 86 | return update(repos, wcDir, rev, listener); | 
 
 
 
 
 | 87 | } else { | 
 
 
 
 
 | 88 | return checkout(repos, wcDir, listener); | 
 
 
 
 
 | 89 | } | 
 
 
 
 
 | 90 | } | 
 
 
 
 
 | 91 |  | 
 
 
 
 
 | 92 | /** | 
 
 
 
 
 | 93 | * Checks if the SVN contains newer revisions than the local working copy | 
 
 
 
 
 | 94 | * | 
 
 
 
 
 | 95 | * @param reposUrl | 
 
 
 
 
 | 96 | *            URL of repository to check for newer revisions | 
 
 
 
 
 | 97 | * @param wcDir | 
 
 
 
 
 | 98 | *            Local working copy path to compare against | 
 
 
 
 
 | 99 | * @return -1: No local working copy yet<br> | 
 
 
 
 
 | 100 | *         0: Revisions are equal<br> | 
 
 
 
 
 | 101 | *         1: SVN contains newer revisions | 
 
 
 
 
 | 102 | * @throws Exception | 
 
 
 
 
 | 103 | *             If destination is not a WC of the given repository | 
 
 
 
 
 | 104 | */ | 
 
 
 
 
 | 105 | public int checkSVN(String reposUrl, File wcDir) throws Exception { | 
 
 
 
 
 | 106 | SVNURL repos = SVNURL.parseURIEncoded(reposUrl); | 
 
 
 
 
 | 107 |  | 
 
 
 
 
 | 108 | if (wcDir.exists()) { | 
 
 
 
 
 | 109 | int localRev = pathIsWCof(repos, wcDir); | 
 
 
 
 
 | 110 | if (localRev < 0) | 
 
 
 
 
 | 111 | throw new Exception( | 
 
 
 
 
 | 112 | "Destination path exists but is not a Working Copy of the SVN"); | 
 
 
 
 
 | 113 | int remoteRev = getRemoteHeadRevision(repos); | 
 
 
 
 
 | 114 | if (remoteRev > localRev) | 
 
 
 
 
 | 115 | return 1; | 
 
 
 
 
 | 116 | else | 
 
 
 
 
 | 117 | return 0; | 
 
 
 
 
 | 118 | } else { | 
 
 
 
 
 | 119 | return -1; | 
 
 
 
 
 | 120 | } | 
 
 
 
 
 | 121 | } | 
 
 
 
 
 | 122 |  | 
 
 
 
 
 | 123 | private int getRemoteHeadRevision(SVNURL reposUrl) { | 
 
 
 
 
 | 124 | try { | 
 
 
 
 
 | 125 | SVNInfo info = svnCManager.getWCClient().doInfo(reposUrl, | 
 
 
 
 
 | 126 | SVNRevision.HEAD, SVNRevision.HEAD); | 
 
 
 
 
 | 127 | return (int) info.getRevision().getNumber(); | 
 
 
 
 
 | 128 | } catch (SVNException e) { | 
 
 
 
 
 | 129 | e.printStackTrace(); | 
 
 
 
 
 | 130 | } | 
 
 
 
 
 | 131 | return -1; | 
 
 
 
 
 | 132 | } | 
 
 
 
 
 | 133 |  | 
 
 
 
 
 | 134 | private int pathIsWCof(SVNURL reposUrl, File wcDir) { | 
 
 
 
 
 | 135 | if (wcDir.exists()) { | 
 
 
 
 
 | 136 | try { | 
 
 
 
 
 | 137 | SVNInfo info = svnCManager.getWCClient().doInfo(wcDir, | 
 
 
 
 
 | 138 | SVNRevision.WORKING); | 
 
 
 
 
 | 139 |  | 
 
 
 
 
 | 140 | if (info.getURL().equals(reposUrl)) | 
 
 
 
 
 | 141 | return (int) info.getRevision().getNumber(); | 
 
 
 
 
 | 142 | } catch (SVNException e) { | 
 
 
 
 
 | 143 | err.println("Error while getting information of working copy for the location '" | 
 
 
 
 
 | 144 | + reposUrl + "': " + e.getMessage()); | 
 
 
 
 
 | 145 | } | 
 
 
 
 
 | 146 | } | 
 
 
 
 
 | 147 | return -1; | 
 
 
 
 
 | 148 | } | 
 
 
 
 
 | 149 |  | 
 
 
 
 
 | 150 | private Vector<String> getUpdatedFilesInRepository(SVNURL reposUrl, | 
 
 
 
 
 | 151 | int fromRev) { | 
 
 
 
 
 | 152 | Vector<String> list = new Vector<String>(); | 
 
 
 
 
 | 153 | try { | 
 
 
 
 
 | 154 | svnCManager.getLogClient().doLog(reposUrl, | 
 
 
 
 
 | 155 | new String[] { reposUrl.getPath() }, SVNRevision.HEAD, | 
 
 
 
 
 | 156 | SVNRevision.create(fromRev + 1), SVNRevision.HEAD, true, | 
 
 
 
 
 | 157 | true, 0, new LogEntryHandler(list, reposUrl.getPath())); | 
 
 
 
 
 | 158 | } catch (Exception e) { | 
 
 
 
 
 | 159 | if (e.getMessage().startsWith("svn: No such revision ")) | 
 
 
 
 
 | 160 | return null; | 
 
 
 
 
 | 161 | err.println("Error while getting the list of updated files of the location '" | 
 
 
 
 
 | 162 | + reposUrl + "': " + e.getMessage()); | 
 
 
 
 
 | 163 | e.printStackTrace(); | 
 
 
 
 
 | 164 | } | 
 
 
 
 
 | 165 |  | 
 
 
 
 
 | 166 | return list; | 
 
 
 
 
 | 167 | } | 
 
 
 
 
 | 168 |  | 
 
 
 
 
 | 169 | private boolean update(SVNURL reposUrl, File wcDir, int fromRev, | 
 
 
 
 
 | 170 | SVNUpdateListener listener) throws Exception { | 
 
 
 
 
 | 171 | Vector<String> updatedFiles = getUpdatedFilesInRepository(reposUrl, | 
 
 
 
 
 | 172 | fromRev); | 
 
 
 
 
 | 173 |  | 
 
 
 
 
 | 174 | if (updatedFiles == null) | 
 
 
 
 
 | 175 | return true; | 
 
 
 
 
 | 176 |  | 
 
 
 
 
 | 177 | svnCManager.getUpdateClient().setEventHandler( | 
 
 
 
 
 | 178 | new UpdateEventHandler(updatedFiles, listener)); | 
 
 
 
 
 | 179 |  | 
 
 
 
 
 | 180 | try { | 
 
 
 
 
 | 181 | svnCManager.getUpdateClient().doUpdate(wcDir, SVNRevision.HEAD, | 
 
 
 
 
 | 182 | SVNDepth.INFINITY, true, true); | 
 
 
 
 
 | 183 | return true; | 
 
 
 
 
 | 184 | } catch (Exception e) { | 
 
 
 
 
 | 185 | err.println("Error while updating the working copy for the location '" | 
 
 
 
 
 | 186 | + reposUrl + "': " + e.getMessage()); | 
 
 
 
 
 | 187 | } | 
 
 
 
 
 | 188 | return false; | 
 
 
 
 
 | 189 | } | 
 
 
 
 
 | 190 |  | 
 
 
 
 
 | 191 | private Vector<String> getFilesInRepository(SVNURL reposUrl) | 
 
 
 
 
 | 192 | throws Exception { | 
 
 
 
 
 | 193 | Vector<String> list = new Vector<String>(); | 
 
 
 
 
 | 194 | try { | 
 
 
 
 
 | 195 | svnCManager.getLogClient().doList(reposUrl, SVNRevision.HEAD, | 
 
 
 
 
 | 196 | SVNRevision.HEAD, false, SVNDepth.INFINITY, | 
 
 
 
 
 | 197 | SVNDirEntry.DIRENT_ALL, new DirEntryHandler(list)); | 
 
 
 
 
 | 198 | } catch (Exception e) { | 
 
 
 
 
 | 199 | err.println("Error while getting the list of files of the location '" | 
 
 
 
 
 | 200 | + reposUrl + "': " + e.getMessage()); | 
 
 
 
 
 | 201 | } | 
 
 
 
 
 | 202 | return list; | 
 
 
 
 
 | 203 | } | 
 
 
 
 
 | 204 |  | 
 
 
 
 
 | 205 | private boolean checkout(SVNURL reposUrl, File wcDir, | 
 
 
 
 
 | 206 | SVNUpdateListener listener) throws Exception { | 
 
 
 
 
 | 207 | Vector<String> newFiles = getFilesInRepository(reposUrl); | 
 
 
 
 
 | 208 | svnCManager.getUpdateClient().setEventHandler( | 
 
 
 
 
 | 209 | new UpdateEventHandler(newFiles, listener)); | 
 
 
 
 
 | 210 |  | 
 
 
 
 
 | 211 | boolean result = false; | 
 
 
 
 
 | 212 | try { | 
 
 
 
 
 | 213 | wcDir.mkdirs(); | 
 
 
 
 
 | 214 | svnCManager.getUpdateClient() | 
 
 
 
 
 | 215 | .doCheckout(reposUrl, wcDir, SVNRevision.HEAD, | 
 
 
 
 
 | 216 | SVNRevision.HEAD, SVNDepth.INFINITY, true); | 
 
 
 
 
 | 217 | result = true; | 
 
 
 
 
 | 218 | } catch (Exception e) { | 
 
 
 
 
 | 219 | err.println("Error while checking out a working copy for the location '" | 
 
 
 
 
 | 220 | + reposUrl + "': " + e.getMessage()); | 
 
 
 
 
 | 221 | } | 
 
 
 
 
 | 222 | return result; | 
 
 
 
 
 | 223 | } | 
 
 
 
 
 | 224 | } |