OSDN Git Service

20a98779838644022260e950cee3af715e1a2c29
[filelock/repo.git] / filelock / src / main / java / jp / gr / java_conf / u6k / filelock / FileLockUtil.java
1 /*\r
2  * Copyright (C) 2007 uguu at users.sourceforge.jp, All Rights Reserved.\r
3  *\r
4  * Redistribution and use in source and binary forms, with or without\r
5  * modification, are permitted provided that the following conditions\r
6  * are met:\r
7  *\r
8  *    1. Redistributions of source code must retain the above copyright\r
9  *       notice, this list of conditions and the following disclaimer.\r
10  *\r
11  *    2. Redistributions in binary form must reproduce the above copyright\r
12  *       notice, this list of conditions and the following disclaimer in the\r
13  *       documentation and/or other materials provided with the distribution.\r
14  *\r
15  *    3. Neither the name of Clarkware Consulting, Inc. nor the names of its\r
16  *       contributors may be used to endorse or promote products derived\r
17  *       from this software without prior written permission. For written\r
18  *       permission, please contact clarkware@clarkware.com.\r
19  *\r
20  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,\r
21  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\r
22  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL\r
23  * CLARKWARE CONSULTING OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
26  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
28  * NEGLIGENCE OR OTHERWISE) ARISING IN  ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
29  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
30  */\r
31 \r
32 package jp.gr.java_conf.u6k.filelock;\r
33 \r
34 import java.io.File;\r
35 import java.io.IOException;\r
36 import java.io.RandomAccessFile;\r
37 import java.nio.channels.FileChannel;\r
38 import java.nio.channels.FileLock;\r
39 import java.util.ArrayList;\r
40 import java.util.List;\r
41 import java.util.Map;\r
42 import java.util.TreeMap;\r
43 \r
44 /**\r
45  * <p>\r
46  * ファイルをロックします。\r
47  * </p>\r
48  * \r
49  * @author $Author$\r
50  * @version $Rev$ $Date$\r
51  */\r
52 public final class FileLockUtil {\r
53 \r
54     /**\r
55      * <p>\r
56      * ロックしたファイルのパスと{@link FileLock}インスタンスのマップ。\r
57      * </p>\r
58      */\r
59     private Map<String, FileLock>    lockMap    = new TreeMap<String, FileLock>();\r
60 \r
61     /**\r
62      * <p>\r
63      * ファイルとチャネルのマップ。\r
64      * </p>\r
65      */\r
66     private Map<String, FileChannel> channelMap = new TreeMap<String, FileChannel>();\r
67 \r
68     /**\r
69      * <p>\r
70      * 指定したファイルをロックし、{@link FileLockUtil}インスタンスを初期化します。ディレクトリを指定した場合、子ファイルを再帰的に検索し、ロックします。ロックに失敗しても例外はスローしません。\r
71      * </p>\r
72      * \r
73      * @param paths\r
74      *            ロックするファイルの配列。\r
75      * @throws IOException\r
76      *             スローされない。\r
77      */\r
78     public FileLockUtil(String[] paths) throws IOException {\r
79         if (paths == null) {\r
80             throw new NullPointerException("paths");\r
81         }\r
82 \r
83         for (String path : paths) {\r
84             File file = new File(path).getCanonicalFile();\r
85             this.lock(file);\r
86         }\r
87     }\r
88 \r
89     private void lock(File file) throws IOException {\r
90         if (file.isFile()) {\r
91             FileChannel fch = new RandomAccessFile(file, "rw").getChannel();\r
92             this.channelMap.put(file.getAbsolutePath(), fch);\r
93 \r
94             FileLock l = fch.tryLock();\r
95             this.lockMap.put(file.getAbsolutePath(), l);\r
96         } else if (file.isDirectory()) {\r
97             for (File child : file.listFiles()) {\r
98                 this.lock(child);\r
99             }\r
100         }\r
101     }\r
102 \r
103     /**\r
104      * <p>\r
105      * ロックに成功したファイルのパスの配列を返します。\r
106      * </p>\r
107      * \r
108      * @return ロックに成功したファイルのパスの配列。\r
109      */\r
110     public String[] lockFiles() {\r
111         List<String> files = new ArrayList<String>();\r
112         for (String path : this.lockMap.keySet()) {\r
113             if (this.lockMap.get(path) != null) {\r
114                 files.add(path);\r
115             }\r
116         }\r
117         return files.toArray(new String[0]);\r
118     }\r
119 \r
120     /**\r
121      * <p>\r
122      * ロックに失敗したファイルのパスの配列を返します。\r
123      * </p>\r
124      * \r
125      * @return ロックに失敗したファイルのパスの配列。\r
126      */\r
127     public String[] lockFailFiles() {\r
128         List<String> files = new ArrayList<String>();\r
129         for (String path : this.lockMap.keySet()) {\r
130             if (this.lockMap.get(path) == null) {\r
131                 files.add(path);\r
132             }\r
133         }\r
134         return files.toArray(new String[0]);\r
135     }\r
136 \r
137     /**\r
138      * <p>\r
139      * 保持している全てのロックを解除します。\r
140      * </p>\r
141      */\r
142     public void release() {\r
143         for (FileChannel fch : this.channelMap.values()) {\r
144             try {\r
145                 fch.close();\r
146             } catch (IOException e) {\r
147                 e.printStackTrace();\r
148             }\r
149         }\r
150     }\r
151 \r
152 }\r