|
19 | 19 | package org.apache.maven.repository.legacy; |
20 | 20 |
|
21 | 21 | import java.io.File; |
22 | | -import java.io.FileInputStream; |
23 | | -import java.io.IOException; |
24 | | -import java.io.RandomAccessFile; |
25 | | -import java.nio.channels.Channels; |
26 | | -import java.nio.channels.FileChannel; |
27 | | -import java.nio.channels.FileLock; |
28 | 22 | import java.util.Date; |
| 23 | +import java.util.HashMap; |
29 | 24 | import java.util.Properties; |
30 | 25 |
|
31 | 26 | import org.apache.maven.artifact.Artifact; |
|
35 | 30 | import org.apache.maven.artifact.repository.metadata.RepositoryMetadata; |
36 | 31 | import org.apache.maven.repository.Proxy; |
37 | 32 | import org.codehaus.plexus.component.annotations.Component; |
| 33 | +import org.codehaus.plexus.component.annotations.Requirement; |
38 | 34 | import org.codehaus.plexus.logging.AbstractLogEnabled; |
39 | 35 | import org.codehaus.plexus.logging.Logger; |
| 36 | +import org.eclipse.aether.internal.impl.TrackingFileManager; |
40 | 37 |
|
41 | 38 | /** |
42 | 39 | * DefaultUpdateCheckManager |
43 | 40 | */ |
44 | 41 | @Component(role = UpdateCheckManager.class) |
45 | 42 | public class DefaultUpdateCheckManager extends AbstractLogEnabled implements UpdateCheckManager { |
| 43 | + @Requirement |
| 44 | + private TrackingFileManager trackingFileManager; |
46 | 45 |
|
47 | 46 | private static final String ERROR_KEY_SUFFIX = ".error"; |
48 | 47 |
|
49 | | - public DefaultUpdateCheckManager() {} |
| 48 | + public DefaultUpdateCheckManager() { |
| 49 | + // for plexus |
| 50 | + } |
50 | 51 |
|
51 | | - public DefaultUpdateCheckManager(Logger logger) { |
| 52 | + /** |
| 53 | + * For testing purposes. |
| 54 | + */ |
| 55 | + public DefaultUpdateCheckManager(Logger logger, TrackingFileManager trackingFileManager) { |
52 | 56 | enableLogging(logger); |
| 57 | + this.trackingFileManager = trackingFileManager; |
53 | 58 | } |
54 | 59 |
|
55 | 60 | public static final String LAST_UPDATE_TAG = ".lastUpdated"; |
@@ -148,7 +153,7 @@ public void touch(Artifact artifact, ArtifactRepository repository, String error |
148 | 153 | File touchfile = getTouchfile(artifact); |
149 | 154 |
|
150 | 155 | if (file.exists()) { |
151 | | - touchfile.delete(); |
| 156 | + trackingFileManager.delete(touchfile); |
152 | 157 | } else { |
153 | 158 | writeLastUpdated(touchfile, getRepositoryKey(repository), error); |
154 | 159 | } |
@@ -192,70 +197,10 @@ String getRepositoryKey(ArtifactRepository repository) { |
192 | 197 | } |
193 | 198 |
|
194 | 199 | private void writeLastUpdated(File touchfile, String key, String error) { |
195 | | - synchronized (touchfile.getAbsolutePath().intern()) { |
196 | | - if (!touchfile.getParentFile().exists() |
197 | | - && !touchfile.getParentFile().mkdirs()) { |
198 | | - getLogger() |
199 | | - .debug("Failed to create directory: " + touchfile.getParent() |
200 | | - + " for tracking artifact metadata resolution."); |
201 | | - return; |
202 | | - } |
203 | | - |
204 | | - FileChannel channel = null; |
205 | | - FileLock lock = null; |
206 | | - try { |
207 | | - Properties props = new Properties(); |
208 | | - |
209 | | - channel = new RandomAccessFile(touchfile, "rw").getChannel(); |
210 | | - lock = channel.lock(); |
211 | | - |
212 | | - if (touchfile.canRead()) { |
213 | | - getLogger().debug("Reading resolution-state from: " + touchfile); |
214 | | - props.load(Channels.newInputStream(channel)); |
215 | | - } |
216 | | - |
217 | | - props.setProperty(key, Long.toString(System.currentTimeMillis())); |
218 | | - |
219 | | - if (error != null) { |
220 | | - props.setProperty(key + ERROR_KEY_SUFFIX, error); |
221 | | - } else { |
222 | | - props.remove(key + ERROR_KEY_SUFFIX); |
223 | | - } |
224 | | - |
225 | | - getLogger().debug("Writing resolution-state to: " + touchfile); |
226 | | - channel.truncate(0); |
227 | | - props.store(Channels.newOutputStream(channel), "Last modified on: " + new Date()); |
228 | | - |
229 | | - lock.release(); |
230 | | - lock = null; |
231 | | - |
232 | | - channel.close(); |
233 | | - channel = null; |
234 | | - } catch (IOException e) { |
235 | | - getLogger() |
236 | | - .debug( |
237 | | - "Failed to record lastUpdated information for resolution.\nFile: " |
238 | | - + touchfile.toString() + "; key: " + key, |
239 | | - e); |
240 | | - } finally { |
241 | | - if (lock != null) { |
242 | | - try { |
243 | | - lock.release(); |
244 | | - } catch (IOException e) { |
245 | | - getLogger() |
246 | | - .debug("Error releasing exclusive lock for resolution tracking file: " + touchfile, e); |
247 | | - } |
248 | | - } |
249 | | - |
250 | | - if (channel != null) { |
251 | | - try { |
252 | | - channel.close(); |
253 | | - } catch (IOException e) { |
254 | | - getLogger().debug("Error closing FileChannel for resolution tracking file: " + touchfile, e); |
255 | | - } |
256 | | - } |
257 | | - } |
258 | | - } |
| 200 | + HashMap<String, String> update = new HashMap<>(); |
| 201 | + update.put(key, Long.toString(System.currentTimeMillis())); |
| 202 | + update.put(key + ERROR_KEY_SUFFIX, error); // error==null => remove mapping |
| 203 | + trackingFileManager.update(touchfile, update); |
259 | 204 | } |
260 | 205 |
|
261 | 206 | Date readLastUpdated(File touchfile, String key) { |
@@ -284,53 +229,7 @@ private String getError(File touchFile, String key) { |
284 | 229 | } |
285 | 230 |
|
286 | 231 | private Properties read(File touchfile) { |
287 | | - if (!touchfile.canRead()) { |
288 | | - getLogger().debug("Skipped unreadable resolution tracking file " + touchfile); |
289 | | - return null; |
290 | | - } |
291 | | - |
292 | | - synchronized (touchfile.getAbsolutePath().intern()) { |
293 | | - FileInputStream in = null; |
294 | | - FileLock lock = null; |
295 | | - |
296 | | - try { |
297 | | - Properties props = new Properties(); |
298 | | - |
299 | | - in = new FileInputStream(touchfile); |
300 | | - lock = in.getChannel().lock(0, Long.MAX_VALUE, true); |
301 | | - |
302 | | - getLogger().debug("Reading resolution-state from: " + touchfile); |
303 | | - props.load(in); |
304 | | - |
305 | | - lock.release(); |
306 | | - lock = null; |
307 | | - |
308 | | - in.close(); |
309 | | - in = null; |
310 | | - |
311 | | - return props; |
312 | | - } catch (IOException e) { |
313 | | - getLogger().debug("Failed to read resolution tracking file " + touchfile, e); |
314 | | - |
315 | | - return null; |
316 | | - } finally { |
317 | | - if (lock != null) { |
318 | | - try { |
319 | | - lock.release(); |
320 | | - } catch (IOException e) { |
321 | | - getLogger().debug("Error releasing shared lock for resolution tracking file: " + touchfile, e); |
322 | | - } |
323 | | - } |
324 | | - |
325 | | - if (in != null) { |
326 | | - try { |
327 | | - in.close(); |
328 | | - } catch (IOException e) { |
329 | | - getLogger().debug("Error closing FileChannel for resolution tracking file: " + touchfile, e); |
330 | | - } |
331 | | - } |
332 | | - } |
333 | | - } |
| 232 | + return trackingFileManager.read(touchfile); |
334 | 233 | } |
335 | 234 |
|
336 | 235 | File getTouchfile(Artifact artifact) { |
|
0 commit comments