source: java/SVNAccess/src/net/oni2/svnaccess/SVN.java@ 833

Last change on this file since 833 was 764, checked in by alloc, 12 years ago

java lib: SVN Access to check for missing files in WC

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