1 package org.eclipse.aether.named.providers;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.IOException;
23 import java.io.UncheckedIOException;
24 import java.nio.channels.FileChannel;
25 import java.nio.file.Files;
26 import java.nio.file.Path;
27 import java.nio.file.Paths;
28 import java.nio.file.StandardOpenOption;
29 import java.util.concurrent.ConcurrentHashMap;
30 import java.util.concurrent.ConcurrentMap;
31
32 import javax.inject.Named;
33 import javax.inject.Singleton;
34
35 import org.eclipse.aether.named.support.FileLockNamedLock;
36 import org.eclipse.aether.named.support.FileSystemFriendly;
37 import org.eclipse.aether.named.support.NamedLockFactorySupport;
38 import org.eclipse.aether.named.support.NamedLockSupport;
39
40
41
42
43
44
45
46 @Singleton
47 @Named( FileLockNamedLockFactory.NAME )
48 public class FileLockNamedLockFactory
49 extends NamedLockFactorySupport
50 implements FileSystemFriendly
51 {
52 public static final String NAME = "file-lock";
53
54 private final ConcurrentMap<String, FileChannel> fileChannels;
55
56 public FileLockNamedLockFactory()
57 {
58 this.fileChannels = new ConcurrentHashMap<>();
59 }
60
61 @Override
62 protected NamedLockSupport createLock( final String name )
63 {
64 Path path = Paths.get( name );
65 FileChannel fileChannel = fileChannels.computeIfAbsent( name, k ->
66 {
67 try
68 {
69 Files.createDirectories( path.getParent() );
70 return FileChannel.open(
71 path,
72 StandardOpenOption.READ, StandardOpenOption.WRITE,
73 StandardOpenOption.CREATE, StandardOpenOption.DELETE_ON_CLOSE
74 );
75 }
76 catch ( IOException e )
77 {
78 throw new UncheckedIOException( "Failed to open file channel for '"
79 + name + "'", e );
80 }
81 } );
82 return new FileLockNamedLock( name, fileChannel, this );
83 }
84
85 @Override
86 protected void destroyLock( final String name )
87 {
88 FileChannel fileChannel = fileChannels.remove( name );
89 if ( fileChannel == null )
90 {
91 throw new IllegalStateException( "File channel expected, but does not exist: " + name );
92 }
93
94 try
95 {
96 fileChannel.close();
97 }
98 catch ( IOException e )
99 {
100 throw new UncheckedIOException( "Failed to close file channel for '"
101 + name + "'", e );
102 }
103 }
104 }