]> git.argeo.org Git - gpl/argeo-slc.git/blob - runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/web/ajaxplorer/svn/SvnDriver.java
Remove unused method in SLC Agent interface
[gpl/argeo-slc.git] / runtime / org.argeo.slc.server / src / main / java / org / argeo / slc / web / ajaxplorer / svn / SvnDriver.java
1 package org.argeo.slc.web.ajaxplorer.svn;
2
3 import java.io.File;
4
5 import org.argeo.slc.web.ajaxplorer.AjxpDriverException;
6 import org.argeo.slc.web.ajaxplorer.file.FileDriver;
7 import org.springframework.beans.factory.BeanNameAware;
8 import org.tmatesoft.svn.core.SVNException;
9 import org.tmatesoft.svn.core.SVNURL;
10 import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory;
11 import org.tmatesoft.svn.core.io.SVNRepository;
12 import org.tmatesoft.svn.core.wc.SVNClientManager;
13 import org.tmatesoft.svn.core.wc.SVNInfo;
14 import org.tmatesoft.svn.core.wc.SVNRevision;
15 import org.tmatesoft.svn.core.wc.admin.SVNAdminClient;
16
17 public class SvnDriver extends FileDriver implements BeanNameAware {
18 private final static String DEFAULT_DATA_PATH = System
19 .getProperty("user.home")
20 + File.separator + "AjaXplorerArchiver" + File.separator + "data";
21
22 private final static long WRITE_ACTION_TIMEOUT = 10 * 60 * 1000;
23
24 private SVNURL baseUrl;
25 private SVNClientManager manager;
26
27 private String beanName;
28
29 private boolean isInWriteAction = false;
30
31 public void init() {
32 FSRepositoryFactory.setup();
33 manager = SVNClientManager.newInstance();
34
35 String basePath = getBasePath();
36 if (basePath != null) {
37 File baseDir = new File(basePath);
38 if (baseDir.exists()) {// base dir exists
39 boolean shouldCheckOut = baseDirChecks(baseDir);
40 if (shouldCheckOut) {
41 checkOut(baseDir);
42 }
43 } else {
44 checkOut(baseDir);
45 }
46 } else {
47 String defaultBasePath = DEFAULT_DATA_PATH + File.separator
48 + "svnwc" + File.separator + beanName;
49 log.warn("No base path provided, use " + defaultBasePath);
50 setBasePath(defaultBasePath);
51
52 File baseDir = new File(getBasePath());
53 if (!baseDir.exists()) {
54 baseDir.mkdirs();
55 }
56
57 if (baseDirChecks(baseDir)) {
58 if (getBaseUrl() == null) {
59 String defaultRepoPath = DEFAULT_DATA_PATH + File.separator
60 + "svnrepos" + File.separator + beanName;
61 log.warn("No base URL found, create repository at "
62 + defaultRepoPath);
63 baseUrl = createRepository(new File(defaultRepoPath));
64 }
65 checkOut(new File(getBasePath()));
66 }
67 }
68 log.info("SVN driver initialized with base url " + getBaseUrl()
69 + " and base path " + getBasePath());
70 }
71
72 /** Builds a SVN URL. */
73 public SVNURL getSVNURL(String relativePath) {
74 try {
75 return baseUrl.appendPath(relativePath, false);
76 } catch (SVNException e) {
77 throw new AjxpDriverException(
78 "Cannot build URL from relative path " + relativePath
79 + " and base url " + baseUrl);
80 }
81 }
82
83 public SVNRepository getRepository() {
84 try {
85 return manager.createRepository(baseUrl, true);
86 } catch (SVNException e) {
87 throw new AjxpDriverException("Cannot create repository for "
88 + baseUrl, e);
89 }
90 }
91
92 /**
93 * Verifies that the provided existing base dir is ok and whether one should
94 * check out. Set the base url from the working copy.
95 *
96 * @return whether one should check out.
97 */
98 protected boolean baseDirChecks(File baseDir) {
99 if (!baseDir.isDirectory()) {
100 throw new AjxpDriverException("Base path " + baseDir
101 + " is not a directory.");
102 }
103
104 try {// retrieves SVN infos
105 SVNInfo info = manager.getWCClient().doInfo(baseDir,
106 SVNRevision.WORKING);
107 SVNURL baseUrlTemp = info.getURL();
108 if (baseUrl != null) {
109 if (!baseUrl.equals(baseUrlTemp)) {
110 throw new AjxpDriverException(
111 "SVN URL of the working copy "
112 + baseUrlTemp
113 + " is not compatible with provided baseUrl "
114 + baseUrl);
115 }
116 } else {
117 this.baseUrl = baseUrlTemp;
118 }
119 return false;
120 } catch (SVNException e) {// no info retrieved
121 log
122 .warn("Could not retrieve SVN info from "
123 + baseDir
124 + "("
125 + e.getMessage()
126 + "). Guess that it is and empty dir and try to check out from provided URL.");
127 if (baseDir.listFiles().length != 0) {
128 throw new AjxpDriverException("Base dir " + baseDir
129 + " is not a working copy and not an empty dir.");
130 }
131 return true;
132 }
133 }
134
135 protected void checkOut(File baseDir) {
136 if (getBaseUrl() == null) {
137 throw new AjxpDriverException(
138 "No SVN URL provided, cannot check out.");
139 }
140
141 // Make sure directory exists
142 baseDir.mkdirs();
143
144 try {
145 long revision = manager.getUpdateClient().doCheckout(getBaseUrl(),
146 baseDir, SVNRevision.UNDEFINED, SVNRevision.HEAD, true);
147 log.info("Checked out from " + baseUrl + " to " + baseDir
148 + " at revision " + revision);
149 } catch (SVNException e) {
150 throw new AjxpDriverException("Cannot check out from " + baseUrl
151 + " to " + baseDir, e);
152 }
153 }
154
155 protected SVNURL createRepository(File repoDir) {
156 try {
157 SVNAdminClient adminClient = manager.getAdminClient();
158 return adminClient.doCreateRepository(repoDir, null, true, false);
159 } catch (SVNException e) {
160 throw new AjxpDriverException("Cannot create repository at "
161 + repoDir, e);
162 }
163 }
164
165 private void updateIfRequired(File dir) {
166 try {
167 SVNInfo wcInfo = manager.getWCClient().doInfo(getBaseDir(),
168 SVNRevision.WORKING);
169 SVNRevision wcRev = wcInfo.getRevision();
170 SVNInfo repoInfo = manager.getWCClient().doInfo(getBaseUrl(),
171 null, SVNRevision.HEAD);
172 SVNRevision repoRev = repoInfo.getRevision();
173
174 if (log.isTraceEnabled())
175 log
176 .trace("WC Revision=" + wcRev + ", Repo Revision="
177 + repoRev);
178
179 if (!wcRev.equals(repoRev)) {
180 log.debug("Update working copy from revision " + wcRev
181 + " to revision " + repoRev);
182 manager.getUpdateClient().doUpdate(getBaseDir(),
183 SVNRevision.HEAD, true);
184 }
185 } catch (SVNException e) {
186 throw new AjxpDriverException("Cannot update working copy "
187 + getBaseDir(),e);
188 }
189 }
190
191 public synchronized void beginWriteAction(File dir) {
192 if (isInWriteAction) {
193 try {
194 wait(WRITE_ACTION_TIMEOUT);
195 } catch (InterruptedException e) {
196 // silent
197 }
198 if (isInWriteAction) {
199 throw new AjxpDriverException(
200 "Still in write action after timeout "
201 + WRITE_ACTION_TIMEOUT + " ms.");
202 }
203 }
204
205 isInWriteAction = true;
206 updateIfRequired(dir);
207 }
208
209 public synchronized void completeWriteAction(File dir) {
210 isInWriteAction = false;
211 notifyAll();
212 }
213
214 public synchronized void rollbackWriteAction(File dir) {
215 // TODO: revert?
216 isInWriteAction = false;
217 notifyAll();
218 }
219
220 public void commitAll(String message) throws SVNException{
221 if(log.isTraceEnabled())
222 log.trace("SVN Commit: " + getBaseDir());
223 manager.getCommitClient().doCommit(new File[] { getBaseDir() }, true,
224 message, true, true);
225
226 }
227
228 /** Spring bean name, set at initialization. */
229 public void setBeanName(String beanName) {
230 this.beanName = beanName;
231 }
232
233 public void setBaseUrl(String baseUrl) {
234 try {
235 this.baseUrl = SVNURL.parseURIDecoded(baseUrl);
236 } catch (SVNException e) {
237 throw new AjxpDriverException("Cannot parse SVN URL " + baseUrl, e);
238 }
239 }
240
241 public SVNURL getBaseUrl() {
242 return baseUrl;
243 }
244
245 public SVNClientManager getManager() {
246 return manager;
247 }
248
249 }