]> source.dussan.org Git - archiva.git/blob
4adf69b4f86cb896eb7d254fe63d16c363b7e7e0
[archiva.git] /
1 package org.apache.archiva.common.filelock;
2
3 /*
4  * Licensed to the Apache Software Foundation (ASF) under one
5  * or more contributor license agreements.  See the NOTICE file
6  * distributed with this work for additional information
7  * regarding copyright ownership.  The ASF licenses this file
8  * to you under the Apache License, Version 2.0 (the
9  * "License"); you may not use this file except in compliance
10  * with the License.  You may obtain a copy of the License at
11  *
12  *  http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17  * KIND, either express or implied.  See the License for the
18  * specific language governing permissions and limitations
19  * under the License.
20  */
21
22 import org.apache.commons.lang.time.StopWatch;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25 import org.springframework.stereotype.Service;
26
27 import java.io.File;
28 import java.io.FileNotFoundException;
29 import java.io.IOException;
30 import java.util.concurrent.ConcurrentHashMap;
31 import java.util.concurrent.ConcurrentMap;
32
33 /**
34  * @author Olivier Lamy
35  */
36 @Service( "fileLockManager#default" )
37 public class DefaultFileLockManager
38     implements FileLockManager
39 {
40     private static final ConcurrentMap<File, Lock> lockFiles = new ConcurrentHashMap<File, Lock>( 64 );
41
42     private boolean skipLocking = false;
43
44     private Logger log = LoggerFactory.getLogger( getClass() );
45
46     private int timeout = 0;
47
48
49     @Override
50     public Lock readFileLock( File file )
51         throws FileLockException, FileLockTimeoutException
52     {
53         if ( skipLocking )
54         {
55             return new Lock( file );
56
57         }
58         StopWatch stopWatch = new StopWatch();
59         boolean acquired = false;
60         mkdirs( file.getParentFile() );
61         try
62         {
63             Lock lock = new Lock( file, false );
64
65             stopWatch.start();
66
67             while ( !acquired )
68             {
69                 if ( timeout > 0 )
70                 {
71                     long delta = stopWatch.getTime();
72                     log.debug( "delta {}, timeout {}", delta, timeout );
73                     if ( delta > timeout )
74                     {
75                         log.warn( "Cannot acquire read lock within {} millis. Will skip the file: {}", timeout, file );
76                         // we could not get the lock within the timeout period, so  throw  FileLockTimeoutException
77                         throw new FileLockTimeoutException();
78                     }
79                 }
80                 try
81                 {
82                     lock.openLock( false, timeout > 0 );
83                     acquired = true;
84                 }
85                 catch ( IOException e )
86                 {
87                     throw new FileLockException( e.getMessage(), e );
88                 }
89                 catch ( IllegalStateException e )
90                 {
91                     log.debug( "openLock {}:{}", e.getClass(), e.getMessage() );
92                 }
93             }
94             return lock;
95         }
96         catch ( FileNotFoundException e )
97         {
98             throw new FileLockException( e.getMessage(), e );
99         }
100     }
101
102
103     @Override
104     public Lock writeFileLock( File file )
105         throws FileLockException, FileLockTimeoutException
106     {
107         if ( skipLocking )
108         {
109             return new Lock( file );
110         }
111
112         mkdirs( file.getParentFile() );
113
114         StopWatch stopWatch = new StopWatch();
115         boolean acquired = false;
116
117         try
118         {
119             Lock lock = new Lock( file, true );
120
121             stopWatch.start();
122
123             while ( !acquired )
124             {
125                 if ( timeout > 0 )
126                 {
127                     long delta = stopWatch.getTime();
128                     log.debug( "delta {}, timeout {}", delta, timeout );
129                     if ( delta > timeout )
130                     {
131                         log.warn( "Cannot acquire read lock within {} millis. Will skip the file: {}", timeout, file );
132                         // we could not get the lock within the timeout period, so throw FileLockTimeoutException
133                         throw new FileLockTimeoutException();
134                     }
135                 }
136                 try
137                 {
138                     lock.openLock( true, timeout > 0 );
139                     acquired = true;
140                 }
141                 catch ( IOException e )
142                 {
143                     throw new FileLockException( e.getMessage(), e );
144                 }
145                 catch ( IllegalStateException e )
146                 {
147                     log.debug( "openLock {}:{}", e.getClass(), e.getMessage() );
148                 }
149             }
150             return lock;
151         }
152         catch ( FileNotFoundException e )
153         {
154             throw new FileLockException( e.getMessage(), e );
155         }
156
157     }
158
159     @Override
160     public void release( Lock lock )
161         throws FileLockException
162     {
163         if ( lock == null )
164         {
165             log.debug( "skip releasing null" );
166             return;
167         }
168         if ( skipLocking )
169         {
170             return;
171         }
172         try
173         {
174             lock.close();
175         }
176         catch ( IOException e )
177         {
178             throw new FileLockException( e.getMessage(), e );
179         }
180     }
181
182     private boolean mkdirs( File directory )
183     {
184         if ( directory == null )
185         {
186             return false;
187         }
188
189         if ( directory.exists() )
190         {
191             return false;
192         }
193         if ( directory.mkdir() )
194         {
195             return true;
196         }
197
198         File canonDir = null;
199         try
200         {
201             canonDir = directory.getCanonicalFile();
202         }
203         catch ( IOException e )
204         {
205             return false;
206         }
207
208         File parentDir = canonDir.getParentFile();
209         return ( parentDir != null && ( mkdirs( parentDir ) || parentDir.exists() ) && canonDir.mkdir() );
210     }
211
212     public int getTimeout()
213     {
214         return timeout;
215     }
216
217     public void setTimeout( int timeout )
218     {
219         this.timeout = timeout;
220     }
221
222     public boolean isSkipLocking()
223     {
224         return skipLocking;
225     }
226
227     public void setSkipLocking( boolean skipLocking )
228     {
229         this.skipLocking = skipLocking;
230     }
231 }