Merge pull request #409 from Alkarex/patch-1
[mono.git] / mcs / tools / monkeydoc / Lucene.Net / Lucene.Net / Store / SimpleFSLockFactory.cs
1 /* 
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  * 
9  * http://www.apache.org/licenses/LICENSE-2.0
10  * 
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 using System;
19
20 namespace Mono.Lucene.Net.Store
21 {
22         
23         /// <summary> <p/>Implements {@link LockFactory} using {@link
24         /// File#createNewFile()}.<p/>
25         /// 
26         /// <p/><b>NOTE:</b> the <a target="_top"
27         /// href="http://java.sun.com/j2se/1.4.2/docs/api/java/io/File.html#createNewFile()">javadocs
28         /// for <code>File.createNewFile</code></a> contain a vague
29         /// yet spooky warning about not using the API for file
30         /// locking.  This warning was added due to <a target="_top"
31         /// href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4676183">this
32         /// bug</a>, and in fact the only known problem with using
33         /// this API for locking is that the Lucene write lock may
34         /// not be released when the JVM exits abnormally.<p/>
35         /// <p/>When this happens, a {@link LockObtainFailedException}
36         /// is hit when trying to create a writer, in which case you
37         /// need to explicitly clear the lock file first.  You can
38         /// either manually remove the file, or use the {@link
39         /// org.apache.lucene.index.IndexReader#unlock(Directory)}
40         /// API.  But, first be certain that no writer is in fact
41         /// writing to the index otherwise you can easily corrupt
42         /// your index.<p/>
43         /// 
44         /// <p/>If you suspect that this or any other LockFactory is
45         /// not working properly in your environment, you can easily
46         /// test it by using {@link VerifyingLockFactory}, {@link
47         /// LockVerifyServer} and {@link LockStressTest}.<p/>
48         /// 
49         /// </summary>
50         /// <seealso cref="LockFactory">
51         /// </seealso>
52         
53         public class SimpleFSLockFactory:FSLockFactory
54         {
55                 
56                 /// <summary> Create a SimpleFSLockFactory instance, with null (unset)
57                 /// lock directory. When you pass this factory to a {@link FSDirectory}
58                 /// subclass, the lock directory is automatically set to the
59                 /// directory itsself. Be sure to create one instance for each directory
60                 /// your create!
61                 /// </summary>
62                 public SimpleFSLockFactory():this((System.IO.DirectoryInfo) null)
63                 {
64                 }
65                 
66                 /// <summary> Instantiate using the provided directory (as a File instance).</summary>
67                 /// <param name="lockDir">where lock files should be created.
68                 /// </param>
69                 [System.Obsolete("Use the constructor that takes a DirectoryInfo, this will be removed in the 3.0 release")]
70                 public SimpleFSLockFactory(System.IO.FileInfo lockDir)
71                 {
72                         SetLockDir(new System.IO.DirectoryInfo(lockDir.FullName));
73                 }
74
75         /// <summary> Instantiate using the provided directory (as a File instance).</summary>
76         /// <param name="lockDir">where lock files should be created.
77         /// </param>
78         public SimpleFSLockFactory(System.IO.DirectoryInfo lockDir)
79         {
80             SetLockDir(lockDir);
81         }
82                 
83                 /// <summary> Instantiate using the provided directory name (String).</summary>
84                 /// <param name="lockDirName">where lock files should be created.
85                 /// </param>
86                 public SimpleFSLockFactory(System.String lockDirName)
87                 {
88                         lockDir = new System.IO.DirectoryInfo(lockDirName);
89                         SetLockDir(lockDir);
90                 }
91                 
92                 public override Lock MakeLock(System.String lockName)
93                 {
94                         if (lockPrefix != null)
95                         {
96                                 lockName = lockPrefix + "-" + lockName;
97                         }
98                         return new SimpleFSLock(lockDir, lockName);
99                 }
100                 
101                 public override void  ClearLock(System.String lockName)
102                 {
103                         bool tmpBool;
104                         if (System.IO.File.Exists(lockDir.FullName))
105                                 tmpBool = true;
106                         else
107                                 tmpBool = System.IO.Directory.Exists(lockDir.FullName);
108                         if (tmpBool)
109                         {
110                                 if (lockPrefix != null)
111                                 {
112                                         lockName = lockPrefix + "-" + lockName;
113                                 }
114                                 System.IO.FileInfo lockFile = new System.IO.FileInfo(System.IO.Path.Combine(lockDir.FullName, lockName));
115                                 bool tmpBool2;
116                                 if (System.IO.File.Exists(lockFile.FullName))
117                                         tmpBool2 = true;
118                                 else
119                                         tmpBool2 = System.IO.Directory.Exists(lockFile.FullName);
120                                 bool tmpBool3;
121                                 if (System.IO.File.Exists(lockFile.FullName))
122                                 {
123                                         System.IO.File.Delete(lockFile.FullName);
124                                         tmpBool3 = true;
125                                 }
126                                 else if (System.IO.Directory.Exists(lockFile.FullName))
127                                 {
128                                         System.IO.Directory.Delete(lockFile.FullName);
129                                         tmpBool3 = true;
130                                 }
131                                 else
132                                         tmpBool3 = false;
133                                 if (tmpBool2 && !tmpBool3)
134                                 {
135                                         throw new System.IO.IOException("Cannot delete " + lockFile);
136                                 }
137                         }
138                 }
139         }
140         
141         
142         class SimpleFSLock:Lock
143         {
144                 
145                 internal System.IO.FileInfo lockFile;
146                 internal System.IO.DirectoryInfo lockDir;
147
148                 [System.Obsolete("Use the constructor that takes a DirectoryInfo, this will be removed in the 3.0 release")]
149                 public SimpleFSLock(System.IO.FileInfo lockDir, System.String lockFileName) : this(new System.IO.DirectoryInfo(lockDir.FullName), lockFileName)
150                 {
151                 }
152
153         public SimpleFSLock(System.IO.DirectoryInfo lockDir, System.String lockFileName)
154         {
155             this.lockDir = new System.IO.DirectoryInfo(lockDir.FullName);
156             lockFile = new System.IO.FileInfo(System.IO.Path.Combine(lockDir.FullName, lockFileName));
157         }
158                 
159                 public override bool Obtain()
160                 {
161                         
162                         // Ensure that lockDir exists and is a directory:
163                         bool tmpBool;
164                         if (System.IO.File.Exists(lockDir.FullName))
165                                 tmpBool = true;
166                         else
167                                 tmpBool = System.IO.Directory.Exists(lockDir.FullName);
168                         if (!tmpBool)
169                         {
170                                 try
171                 {
172                     System.IO.Directory.CreateDirectory(lockDir.FullName);
173                 }
174                 catch
175                 {
176                                         throw new System.IO.IOException("Cannot create directory: " + lockDir.FullName);
177                 }
178                         }
179                         else
180                         {
181                 try
182                 {
183                      System.IO.Directory.Exists(lockDir.FullName);
184                 }
185                 catch
186                 {
187                                 throw new System.IO.IOException("Found regular file where directory expected: " + lockDir.FullName);
188                 }
189                         }
190
191                         if (lockFile.Exists)
192                         {
193                                 return false;
194                         }
195                         else
196                         {
197                                 System.IO.FileStream createdFile = lockFile.Create();
198                                 createdFile.Close();
199                                 return true;
200                         }
201                 }
202                 
203                 public override void  Release()
204                 {
205                         bool tmpBool;
206                         if (System.IO.File.Exists(lockFile.FullName))
207                                 tmpBool = true;
208                         else
209                                 tmpBool = System.IO.Directory.Exists(lockFile.FullName);
210                         bool tmpBool2;
211                         if (System.IO.File.Exists(lockFile.FullName))
212                         {
213                                 System.IO.File.Delete(lockFile.FullName);
214                                 tmpBool2 = true;
215                         }
216                         else if (System.IO.Directory.Exists(lockFile.FullName))
217                         {
218                                 System.IO.Directory.Delete(lockFile.FullName);
219                                 tmpBool2 = true;
220                         }
221                         else
222                                 tmpBool2 = false;
223                         if (tmpBool && !tmpBool2)
224                                 throw new LockReleaseFailedException("failed to delete " + lockFile);
225                 }
226                 
227                 public override bool IsLocked()
228                 {
229                         bool tmpBool;
230                         if (System.IO.File.Exists(lockFile.FullName))
231                                 tmpBool = true;
232                         else
233                                 tmpBool = System.IO.Directory.Exists(lockFile.FullName);
234                         return tmpBool;
235                 }
236                 
237                 public override System.String ToString()
238                 {
239                         return "SimpleFSLock@" + lockFile;
240                 }
241         }
242 }