29 |
22 Feb 05 |
nicklas |
1 |
/* |
192 |
17 Mar 05 |
jari |
$Id$ |
29 |
22 Feb 05 |
nicklas |
3 |
|
4889 |
06 Apr 09 |
nicklas |
Copyright (C) 2005, 2006 Jari Häkkinen, Nicklas Nordborg |
3675 |
16 Aug 07 |
jari |
Copyright (C) 2007 Nicklas Nordborg |
29 |
22 Feb 05 |
nicklas |
6 |
|
2304 |
22 May 06 |
jari |
This file is part of BASE - BioArray Software Environment. |
2304 |
22 May 06 |
jari |
Available at http://base.thep.lu.se/ |
29 |
22 Feb 05 |
nicklas |
9 |
|
29 |
22 Feb 05 |
nicklas |
BASE is free software; you can redistribute it and/or |
29 |
22 Feb 05 |
nicklas |
modify it under the terms of the GNU General Public License |
4479 |
05 Sep 08 |
jari |
as published by the Free Software Foundation; either version 3 |
29 |
22 Feb 05 |
nicklas |
of the License, or (at your option) any later version. |
29 |
22 Feb 05 |
nicklas |
14 |
|
29 |
22 Feb 05 |
nicklas |
BASE is distributed in the hope that it will be useful, |
29 |
22 Feb 05 |
nicklas |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
29 |
22 Feb 05 |
nicklas |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
29 |
22 Feb 05 |
nicklas |
GNU General Public License for more details. |
29 |
22 Feb 05 |
nicklas |
19 |
|
29 |
22 Feb 05 |
nicklas |
You should have received a copy of the GNU General Public License |
4515 |
11 Sep 08 |
jari |
along with BASE. If not, see <http://www.gnu.org/licenses/>. |
29 |
22 Feb 05 |
nicklas |
22 |
*/ |
29 |
22 Feb 05 |
nicklas |
23 |
package net.sf.basedb.util; |
29 |
22 Feb 05 |
nicklas |
24 |
|
3719 |
12 Sep 07 |
nicklas |
25 |
import net.sf.basedb.core.AbsoluteProgressReporter; |
3700 |
23 Aug 07 |
martin |
26 |
import net.sf.basedb.core.BaseException; |
647 |
25 May 05 |
nicklas |
27 |
import net.sf.basedb.core.DbControl; |
647 |
25 May 05 |
nicklas |
28 |
import net.sf.basedb.core.Directory; |
3700 |
23 Aug 07 |
martin |
29 |
import net.sf.basedb.core.Include; |
3700 |
23 Aug 07 |
martin |
30 |
import net.sf.basedb.core.InvalidDataException; |
1418 |
07 Oct 05 |
nicklas |
31 |
import net.sf.basedb.core.ItemQuery; |
4794 |
02 Mar 09 |
nicklas |
32 |
import net.sf.basedb.core.ItemResultIterator; |
4794 |
02 Mar 09 |
nicklas |
33 |
import net.sf.basedb.core.PermissionDeniedException; |
5374 |
03 Aug 10 |
nicklas |
34 |
import net.sf.basedb.core.ProgressReporter; |
5374 |
03 Aug 10 |
nicklas |
35 |
import net.sf.basedb.core.SimpleAbsoluteProgressReporter; |
1979 |
14 Feb 06 |
nicklas |
36 |
import net.sf.basedb.core.Type; |
647 |
25 May 05 |
nicklas |
37 |
import net.sf.basedb.core.query.Expressions; |
1418 |
07 Oct 05 |
nicklas |
38 |
import net.sf.basedb.core.query.Hql; |
662 |
27 May 05 |
nicklas |
39 |
import net.sf.basedb.core.query.Orders; |
3700 |
23 Aug 07 |
martin |
40 |
import net.sf.basedb.core.query.Restrictions; |
4120 |
04 Feb 08 |
nicklas |
41 |
import net.sf.basedb.core.signal.ThreadSignalHandler; |
5010 |
23 Jun 09 |
nicklas |
42 |
import net.sf.basedb.util.filter.Filter; |
647 |
25 May 05 |
nicklas |
43 |
|
3700 |
23 Aug 07 |
martin |
44 |
import java.io.BufferedInputStream; |
2038 |
21 Feb 06 |
nicklas |
45 |
import java.io.BufferedOutputStream; |
6880 |
21 Apr 15 |
nicklas |
46 |
import java.io.Closeable; |
2038 |
21 Feb 06 |
nicklas |
47 |
import java.io.File; |
3832 |
15 Oct 07 |
nicklas |
48 |
import java.io.FileFilter; |
3700 |
23 Aug 07 |
martin |
49 |
import java.io.FileInputStream; |
2038 |
21 Feb 06 |
nicklas |
50 |
import java.io.FileOutputStream; |
29 |
22 Feb 05 |
nicklas |
51 |
import java.io.IOException; |
29 |
22 Feb 05 |
nicklas |
52 |
import java.io.InputStream; |
29 |
22 Feb 05 |
nicklas |
53 |
import java.io.OutputStream; |
3510 |
19 Jun 07 |
nicklas |
54 |
import java.io.PushbackInputStream; |
4867 |
31 Mar 09 |
nicklas |
55 |
import java.io.Reader; |
4867 |
31 Mar 09 |
nicklas |
56 |
import java.io.Writer; |
5374 |
03 Aug 10 |
nicklas |
57 |
import java.util.ArrayList; |
3700 |
23 Aug 07 |
martin |
58 |
import java.util.Arrays; |
7310 |
20 Mar 17 |
nicklas |
59 |
import java.util.Collection; |
5374 |
03 Aug 10 |
nicklas |
60 |
import java.util.Collections; |
3700 |
23 Aug 07 |
martin |
61 |
import java.util.HashMap; |
4794 |
02 Mar 09 |
nicklas |
62 |
import java.util.HashSet; |
3700 |
23 Aug 07 |
martin |
63 |
import java.util.LinkedList; |
3700 |
23 Aug 07 |
martin |
64 |
import java.util.List; |
3700 |
23 Aug 07 |
martin |
65 |
import java.util.Map; |
4794 |
02 Mar 09 |
nicklas |
66 |
import java.util.Set; |
29 |
22 Feb 05 |
nicklas |
67 |
|
29 |
22 Feb 05 |
nicklas |
68 |
/** |
29 |
22 Feb 05 |
nicklas |
This class collects some useful methods for file and stream |
29 |
22 Feb 05 |
nicklas |
handling. |
29 |
22 Feb 05 |
nicklas |
71 |
|
29 |
22 Feb 05 |
nicklas |
@author Nicklas |
29 |
22 Feb 05 |
nicklas |
@version 2.0 |
1979 |
14 Feb 06 |
nicklas |
@base.modified $Date$ |
29 |
22 Feb 05 |
nicklas |
75 |
*/ |
29 |
22 Feb 05 |
nicklas |
76 |
public class FileUtil |
29 |
22 Feb 05 |
nicklas |
77 |
{ |
29 |
22 Feb 05 |
nicklas |
78 |
private static final int BUFFER_SIZE = 512; |
29 |
22 Feb 05 |
nicklas |
79 |
|
29 |
22 Feb 05 |
nicklas |
80 |
/** |
29 |
22 Feb 05 |
nicklas |
Copy from the input stream to the output stream |
29 |
22 Feb 05 |
nicklas |
until end of file is reached. |
29 |
22 Feb 05 |
nicklas |
@param in The <code>InputStream</code> to read from |
29 |
22 Feb 05 |
nicklas |
@param out The <code>OutputStream</code> to write to |
29 |
22 Feb 05 |
nicklas |
@return The number of bytes copied |
29 |
22 Feb 05 |
nicklas |
@throws IOException This exception is thrown if there is an error |
29 |
22 Feb 05 |
nicklas |
87 |
*/ |
29 |
22 Feb 05 |
nicklas |
88 |
public static long copy(InputStream in, OutputStream out) |
29 |
22 Feb 05 |
nicklas |
89 |
throws IOException |
29 |
22 Feb 05 |
nicklas |
90 |
{ |
3719 |
12 Sep 07 |
nicklas |
91 |
return copy(in, out, null); |
3719 |
12 Sep 07 |
nicklas |
92 |
} |
3719 |
12 Sep 07 |
nicklas |
93 |
|
3719 |
12 Sep 07 |
nicklas |
94 |
/** |
3719 |
12 Sep 07 |
nicklas |
Copy from the input stream to the output stream |
3719 |
12 Sep 07 |
nicklas |
until end of file is reached. |
3719 |
12 Sep 07 |
nicklas |
@param in The <code>InputStream</code> to read from |
3719 |
12 Sep 07 |
nicklas |
@param out The <code>OutputStream</code> to write to |
3719 |
12 Sep 07 |
nicklas |
@param progress An optional progress reporter |
3719 |
12 Sep 07 |
nicklas |
@return The number of bytes copied |
3719 |
12 Sep 07 |
nicklas |
@throws IOException This exception is thrown if there is an error |
3719 |
12 Sep 07 |
nicklas |
@since 2.5 |
3719 |
12 Sep 07 |
nicklas |
103 |
*/ |
3719 |
12 Sep 07 |
nicklas |
104 |
public static long copy(InputStream in, OutputStream out, AbsoluteProgressReporter progress) |
3719 |
12 Sep 07 |
nicklas |
105 |
throws IOException |
3719 |
12 Sep 07 |
nicklas |
106 |
{ |
29 |
22 Feb 05 |
nicklas |
107 |
int bytes = 0; |
58 |
01 Mar 05 |
nicklas |
108 |
long totalBytes = 0; |
29 |
22 Feb 05 |
nicklas |
109 |
byte[] buffer = new byte[BUFFER_SIZE]; |
3719 |
12 Sep 07 |
nicklas |
110 |
|
29 |
22 Feb 05 |
nicklas |
111 |
while (bytes != -1) // -1 = end of stream |
29 |
22 Feb 05 |
nicklas |
112 |
{ |
4120 |
04 Feb 08 |
nicklas |
113 |
ThreadSignalHandler.checkInterrupted(); |
29 |
22 Feb 05 |
nicklas |
114 |
bytes = in.read(buffer, 0, buffer.length); |
29 |
22 Feb 05 |
nicklas |
115 |
if (bytes > 0) |
29 |
22 Feb 05 |
nicklas |
116 |
{ |
58 |
01 Mar 05 |
nicklas |
117 |
totalBytes += bytes; |
29 |
22 Feb 05 |
nicklas |
118 |
out.write(buffer, 0, bytes); |
3719 |
12 Sep 07 |
nicklas |
119 |
if (progress != null) progress.displayAbsolute(totalBytes, null); |
29 |
22 Feb 05 |
nicklas |
120 |
} |
29 |
22 Feb 05 |
nicklas |
121 |
} |
5384 |
13 Aug 10 |
nicklas |
122 |
out.flush(); |
58 |
01 Mar 05 |
nicklas |
123 |
return totalBytes; |
29 |
22 Feb 05 |
nicklas |
124 |
} |
3719 |
12 Sep 07 |
nicklas |
125 |
|
4867 |
31 Mar 09 |
nicklas |
126 |
/** |
4867 |
31 Mar 09 |
nicklas |
Copy from the reader to the writer until end of file is reached. |
4867 |
31 Mar 09 |
nicklas |
@param in The <code>Reader</code> to read from |
4867 |
31 Mar 09 |
nicklas |
@param out The <code>Writer</code> to write to |
4867 |
31 Mar 09 |
nicklas |
@return The number of characters copied |
4867 |
31 Mar 09 |
nicklas |
@throws IOException This exception is thrown if there is an error |
4867 |
31 Mar 09 |
nicklas |
@since 2.12 |
4867 |
31 Mar 09 |
nicklas |
133 |
*/ |
4867 |
31 Mar 09 |
nicklas |
134 |
public static long copy(Reader in, Writer out) |
4867 |
31 Mar 09 |
nicklas |
135 |
throws IOException |
4867 |
31 Mar 09 |
nicklas |
136 |
{ |
4867 |
31 Mar 09 |
nicklas |
137 |
return copy(in, out, null); |
4867 |
31 Mar 09 |
nicklas |
138 |
} |
3606 |
27 Jul 07 |
nicklas |
139 |
|
3606 |
27 Jul 07 |
nicklas |
140 |
/** |
4867 |
31 Mar 09 |
nicklas |
Copy from the reader to the writer until end of file is reached. |
4867 |
31 Mar 09 |
nicklas |
@param in The <code>Reader</code> to read from |
4867 |
31 Mar 09 |
nicklas |
@param out The <code>Writer</code> to write to |
4867 |
31 Mar 09 |
nicklas |
@param progress An optional progress reporter |
4867 |
31 Mar 09 |
nicklas |
@return The number of characters copied |
4867 |
31 Mar 09 |
nicklas |
@throws IOException This exception is thrown if there is an error |
4867 |
31 Mar 09 |
nicklas |
@since 2.12 |
4867 |
31 Mar 09 |
nicklas |
148 |
*/ |
4867 |
31 Mar 09 |
nicklas |
149 |
public static long copy(Reader in, Writer out, AbsoluteProgressReporter progress) |
4867 |
31 Mar 09 |
nicklas |
150 |
throws IOException |
4867 |
31 Mar 09 |
nicklas |
151 |
{ |
4867 |
31 Mar 09 |
nicklas |
152 |
int numRead = 0; |
4867 |
31 Mar 09 |
nicklas |
153 |
long totalRead = 0; |
4867 |
31 Mar 09 |
nicklas |
154 |
char[] buffer = new char[BUFFER_SIZE]; |
4867 |
31 Mar 09 |
nicklas |
155 |
|
4867 |
31 Mar 09 |
nicklas |
156 |
while (numRead != -1) // -1 = end of stream |
4867 |
31 Mar 09 |
nicklas |
157 |
{ |
4867 |
31 Mar 09 |
nicklas |
158 |
ThreadSignalHandler.checkInterrupted(); |
4867 |
31 Mar 09 |
nicklas |
159 |
numRead = in.read(buffer, 0, buffer.length); |
4867 |
31 Mar 09 |
nicklas |
160 |
if (numRead > 0) |
4867 |
31 Mar 09 |
nicklas |
161 |
{ |
4867 |
31 Mar 09 |
nicklas |
162 |
totalRead += numRead; |
4867 |
31 Mar 09 |
nicklas |
163 |
out.write(buffer, 0, numRead); |
4867 |
31 Mar 09 |
nicklas |
164 |
if (progress != null) progress.displayAbsolute(totalRead, null); |
4867 |
31 Mar 09 |
nicklas |
165 |
} |
4867 |
31 Mar 09 |
nicklas |
166 |
} |
4867 |
31 Mar 09 |
nicklas |
167 |
return totalRead; |
4867 |
31 Mar 09 |
nicklas |
168 |
} |
4867 |
31 Mar 09 |
nicklas |
169 |
|
4867 |
31 Mar 09 |
nicklas |
170 |
/** |
3606 |
27 Jul 07 |
nicklas |
Read from the input stream until the end is reached. |
3606 |
27 Jul 07 |
nicklas |
172 |
|
3606 |
27 Jul 07 |
nicklas |
@param in The <code>InputStream</code> to read from |
3606 |
27 Jul 07 |
nicklas |
@return The number of bytes copied |
3606 |
27 Jul 07 |
nicklas |
@throws IOException This exception is thrown if there is an error |
3606 |
27 Jul 07 |
nicklas |
@since 2.4 |
3606 |
27 Jul 07 |
nicklas |
177 |
*/ |
3606 |
27 Jul 07 |
nicklas |
178 |
public static long read(InputStream in) |
3606 |
27 Jul 07 |
nicklas |
179 |
throws IOException |
3606 |
27 Jul 07 |
nicklas |
180 |
{ |
3606 |
27 Jul 07 |
nicklas |
181 |
int bytes = 0; |
3606 |
27 Jul 07 |
nicklas |
182 |
long totalBytes = 0; |
3606 |
27 Jul 07 |
nicklas |
183 |
byte[] buffer = new byte[BUFFER_SIZE]; |
3606 |
27 Jul 07 |
nicklas |
184 |
|
3606 |
27 Jul 07 |
nicklas |
185 |
while (bytes != -1) // -1 = end of stream |
3606 |
27 Jul 07 |
nicklas |
186 |
{ |
4120 |
04 Feb 08 |
nicklas |
187 |
ThreadSignalHandler.checkInterrupted(); |
3606 |
27 Jul 07 |
nicklas |
188 |
bytes = in.read(buffer, 0, buffer.length); |
3606 |
27 Jul 07 |
nicklas |
189 |
if (bytes > 0) |
3606 |
27 Jul 07 |
nicklas |
190 |
{ |
3606 |
27 Jul 07 |
nicklas |
191 |
totalBytes += bytes; |
3606 |
27 Jul 07 |
nicklas |
192 |
} |
3606 |
27 Jul 07 |
nicklas |
193 |
} |
3606 |
27 Jul 07 |
nicklas |
194 |
return totalBytes; |
3606 |
27 Jul 07 |
nicklas |
195 |
} |
29 |
22 Feb 05 |
nicklas |
196 |
|
29 |
22 Feb 05 |
nicklas |
197 |
/** |
4594 |
21 Oct 08 |
nicklas |
Close an input stream without throwing an exception. |
4594 |
21 Oct 08 |
nicklas |
@param in The input stream to close |
4594 |
21 Oct 08 |
nicklas |
@since 2.9 |
4594 |
21 Oct 08 |
nicklas |
201 |
*/ |
4594 |
21 Oct 08 |
nicklas |
202 |
public static void close(InputStream in) |
4594 |
21 Oct 08 |
nicklas |
203 |
{ |
4594 |
21 Oct 08 |
nicklas |
204 |
if (in == null) return; |
4594 |
21 Oct 08 |
nicklas |
205 |
try |
4594 |
21 Oct 08 |
nicklas |
206 |
{ |
4594 |
21 Oct 08 |
nicklas |
207 |
in.close(); |
4594 |
21 Oct 08 |
nicklas |
208 |
} |
4594 |
21 Oct 08 |
nicklas |
209 |
catch (Throwable t) |
4594 |
21 Oct 08 |
nicklas |
210 |
{} |
4594 |
21 Oct 08 |
nicklas |
211 |
} |
4594 |
21 Oct 08 |
nicklas |
212 |
|
4594 |
21 Oct 08 |
nicklas |
213 |
/** |
4594 |
21 Oct 08 |
nicklas |
Close an output stream without throwing an exception. |
4594 |
21 Oct 08 |
nicklas |
@param out The output stream to close |
4594 |
21 Oct 08 |
nicklas |
@since 2.9 |
4594 |
21 Oct 08 |
nicklas |
217 |
*/ |
4594 |
21 Oct 08 |
nicklas |
218 |
public static void close(OutputStream out) |
4594 |
21 Oct 08 |
nicklas |
219 |
{ |
4594 |
21 Oct 08 |
nicklas |
220 |
if (out == null) return; |
4594 |
21 Oct 08 |
nicklas |
221 |
try |
4594 |
21 Oct 08 |
nicklas |
222 |
{ |
4594 |
21 Oct 08 |
nicklas |
223 |
out.close(); |
4594 |
21 Oct 08 |
nicklas |
224 |
} |
4594 |
21 Oct 08 |
nicklas |
225 |
catch (Throwable t) |
4594 |
21 Oct 08 |
nicklas |
226 |
{} |
4594 |
21 Oct 08 |
nicklas |
227 |
} |
4594 |
21 Oct 08 |
nicklas |
228 |
|
4594 |
21 Oct 08 |
nicklas |
229 |
/** |
6880 |
21 Apr 15 |
nicklas |
Close a {@link Closeable} without throwing an exception. |
6880 |
21 Apr 15 |
nicklas |
@param c The object to close |
6880 |
21 Apr 15 |
nicklas |
@since 3.5 |
6880 |
21 Apr 15 |
nicklas |
233 |
*/ |
6880 |
21 Apr 15 |
nicklas |
234 |
public static void close(Closeable c) |
6880 |
21 Apr 15 |
nicklas |
235 |
{ |
6880 |
21 Apr 15 |
nicklas |
236 |
if (c == null) return; |
6880 |
21 Apr 15 |
nicklas |
237 |
try |
6880 |
21 Apr 15 |
nicklas |
238 |
{ |
6880 |
21 Apr 15 |
nicklas |
239 |
c.close(); |
6880 |
21 Apr 15 |
nicklas |
240 |
} |
6880 |
21 Apr 15 |
nicklas |
241 |
catch (Throwable t) |
6880 |
21 Apr 15 |
nicklas |
242 |
{} |
6880 |
21 Apr 15 |
nicklas |
243 |
} |
6880 |
21 Apr 15 |
nicklas |
244 |
|
7912 |
18 Feb 21 |
nicklas |
245 |
/** |
7912 |
18 Feb 21 |
nicklas |
Close a {@link AutoCloseable} without throwing an exception. |
7912 |
18 Feb 21 |
nicklas |
@param c The object to close |
7912 |
18 Feb 21 |
nicklas |
@since 3.18 |
7912 |
18 Feb 21 |
nicklas |
249 |
*/ |
7912 |
18 Feb 21 |
nicklas |
250 |
public static void close(AutoCloseable c) |
7912 |
18 Feb 21 |
nicklas |
251 |
{ |
7912 |
18 Feb 21 |
nicklas |
252 |
if (c == null) return; |
7912 |
18 Feb 21 |
nicklas |
253 |
try |
7912 |
18 Feb 21 |
nicklas |
254 |
{ |
7912 |
18 Feb 21 |
nicklas |
255 |
c.close(); |
7912 |
18 Feb 21 |
nicklas |
256 |
} |
7912 |
18 Feb 21 |
nicklas |
257 |
catch (Throwable t) |
7912 |
18 Feb 21 |
nicklas |
258 |
{} |
7912 |
18 Feb 21 |
nicklas |
259 |
} |
6880 |
21 Apr 15 |
nicklas |
260 |
|
6880 |
21 Apr 15 |
nicklas |
261 |
/** |
2038 |
21 Feb 06 |
nicklas |
Get a buffered <code>InputStream</code> object reading from |
29 |
22 Feb 05 |
nicklas |
the specified file. |
29 |
22 Feb 05 |
nicklas |
264 |
|
2038 |
21 Feb 06 |
nicklas |
@param file The path to the file to read from |
29 |
22 Feb 05 |
nicklas |
@return A buffered <code>InputStream</code> |
29 |
22 Feb 05 |
nicklas |
@throws IOException If the stream cannot be opened |
29 |
22 Feb 05 |
nicklas |
268 |
*/ |
2038 |
21 Feb 06 |
nicklas |
269 |
public static InputStream getInputStream(File file) |
29 |
22 Feb 05 |
nicklas |
270 |
throws IOException |
29 |
22 Feb 05 |
nicklas |
271 |
{ |
2038 |
21 Feb 06 |
nicklas |
272 |
return new BufferedInputStream(new FileInputStream(file)); |
29 |
22 Feb 05 |
nicklas |
273 |
} |
647 |
25 May 05 |
nicklas |
274 |
|
647 |
25 May 05 |
nicklas |
275 |
/** |
2038 |
21 Feb 06 |
nicklas |
Get a buffered <code>OutputStream</code> object writing to |
2038 |
21 Feb 06 |
nicklas |
the specified file. |
2038 |
21 Feb 06 |
nicklas |
278 |
|
2038 |
21 Feb 06 |
nicklas |
@param file The path to the file to write to |
2038 |
21 Feb 06 |
nicklas |
@return A buffered <code>OutputStream</code> |
2038 |
21 Feb 06 |
nicklas |
@throws IOException If the stream cannot be opened |
2038 |
21 Feb 06 |
nicklas |
282 |
*/ |
2038 |
21 Feb 06 |
nicklas |
283 |
public static OutputStream getOutputStream(File file) |
2038 |
21 Feb 06 |
nicklas |
284 |
throws IOException |
2038 |
21 Feb 06 |
nicklas |
285 |
{ |
2038 |
21 Feb 06 |
nicklas |
286 |
return new BufferedOutputStream(new FileOutputStream(file)); |
2038 |
21 Feb 06 |
nicklas |
287 |
} |
2038 |
21 Feb 06 |
nicklas |
288 |
|
2038 |
21 Feb 06 |
nicklas |
289 |
/** |
3510 |
19 Jun 07 |
nicklas |
Take a peek at an input stream and check if the first few bytes |
3510 |
19 Jun 07 |
nicklas |
matches the bCheck parameter. After the check the bytes are |
3510 |
19 Jun 07 |
nicklas |
pushed back to the stream again. This method is useful to check |
3510 |
19 Jun 07 |
nicklas |
the file format of a file, which can often be done by checing |
3510 |
19 Jun 07 |
nicklas |
the first few bytes at the start of the file. For example |
3510 |
19 Jun 07 |
nicklas |
to check if the file is gzip file: |
3510 |
19 Jun 07 |
nicklas |
<p> |
3510 |
19 Jun 07 |
nicklas |
<code>bCheck = new byte[] { 0x1f, (byte)0x8b };</code> |
3510 |
19 Jun 07 |
nicklas |
298 |
|
3510 |
19 Jun 07 |
nicklas |
@param pin The input stream to read from which must have |
3510 |
19 Jun 07 |
nicklas |
large enough buffer to be able to unread the bytes |
3510 |
19 Jun 07 |
nicklas |
@param bCheck The byte values to use for comparison |
3510 |
19 Jun 07 |
nicklas |
@return TRUE if the file matches the specified bytes, |
3510 |
19 Jun 07 |
nicklas |
FALSE otherwise |
3510 |
19 Jun 07 |
nicklas |
@throws IOException If there is an error reading or unreading |
3510 |
19 Jun 07 |
nicklas |
the bytes |
3510 |
19 Jun 07 |
nicklas |
@throws NullPointerException If pin or bCheck is null |
3510 |
19 Jun 07 |
nicklas |
@throws IllegalArgumentException If bCheck is zero length |
3510 |
19 Jun 07 |
nicklas |
@since 2.4 |
3510 |
19 Jun 07 |
nicklas |
309 |
*/ |
3510 |
19 Jun 07 |
nicklas |
310 |
public static boolean checkMagicNumber(PushbackInputStream pin, byte[] bCheck) |
3510 |
19 Jun 07 |
nicklas |
311 |
throws IOException |
3510 |
19 Jun 07 |
nicklas |
312 |
{ |
3510 |
19 Jun 07 |
nicklas |
313 |
if (pin == null) throw new NullPointerException("pin"); |
3510 |
19 Jun 07 |
nicklas |
314 |
if (bCheck == null) throw new NullPointerException("bCheck"); |
3510 |
19 Jun 07 |
nicklas |
315 |
if (bCheck.length == 0) throw new IllegalArgumentException("bCheck has zero length"); |
3510 |
19 Jun 07 |
nicklas |
316 |
byte[] b = new byte[bCheck.length]; |
5384 |
13 Aug 10 |
nicklas |
317 |
int numRead = pin.read(b); |
5384 |
13 Aug 10 |
nicklas |
318 |
boolean match = numRead == bCheck.length && Arrays.equals(b, bCheck); |
5384 |
13 Aug 10 |
nicklas |
319 |
if (numRead > 0) pin.unread(b, 0, numRead); |
3510 |
19 Jun 07 |
nicklas |
320 |
return match; |
3510 |
19 Jun 07 |
nicklas |
321 |
} |
3510 |
19 Jun 07 |
nicklas |
322 |
|
3510 |
19 Jun 07 |
nicklas |
323 |
/** |
4034 |
05 Dec 07 |
martin |
Get the complete tree of sub-directories from a given directory. |
4794 |
02 Mar 09 |
nicklas |
<p> |
4794 |
02 Mar 09 |
nicklas |
<b>NOTE!!! This method has very bad performance on large directory trees. |
4794 |
02 Mar 09 |
nicklas |
Consider if it is not possible to use the {@link |
4794 |
02 Mar 09 |
nicklas |
#loadMinimalDirectoryTree(DbControl, Directory...)} |
4794 |
02 Mar 09 |
nicklas |
instead together with lazy loading of subdirectories.</b> |
4794 |
02 Mar 09 |
nicklas |
330 |
|
4034 |
05 Dec 07 |
martin |
@param dc DbControl used to access the database. |
647 |
25 May 05 |
nicklas |
@param directory The directory to start with |
647 |
25 May 05 |
nicklas |
@return A <code>Map</code> which maps a directory to a |
4034 |
05 Dec 07 |
martin |
list of it's sub-directories. Directories without sub-directories |
647 |
25 May 05 |
nicklas |
are not included in the map. |
647 |
25 May 05 |
nicklas |
@throws InvalidDataException If the directory is null |
647 |
25 May 05 |
nicklas |
@throws BaseException If there is another error |
647 |
25 May 05 |
nicklas |
338 |
*/ |
647 |
25 May 05 |
nicklas |
339 |
public static Map<Directory, List<Directory>> getDirectoryTree(DbControl dc, Directory directory) |
647 |
25 May 05 |
nicklas |
340 |
throws InvalidDataException, BaseException |
647 |
25 May 05 |
nicklas |
341 |
{ |
1418 |
07 Oct 05 |
nicklas |
342 |
ItemQuery<Directory> query = Directory.getQuery(); |
1418 |
07 Oct 05 |
nicklas |
343 |
query.restrict( |
647 |
25 May 05 |
nicklas |
344 |
Restrictions.in( |
1418 |
07 Oct 05 |
nicklas |
345 |
Hql.property("parent"), |
647 |
25 May 05 |
nicklas |
346 |
Expressions.parameter("parents") |
647 |
25 May 05 |
nicklas |
347 |
) |
647 |
25 May 05 |
nicklas |
348 |
); |
1418 |
07 Oct 05 |
nicklas |
349 |
query.order(Orders.asc(Hql.property("name"))); |
2301 |
22 May 06 |
nicklas |
350 |
query.include(Include.MINE, Include.SHARED, Include.OTHERS, Include.NOT_REMOVED, Include.REMOVED); |
647 |
25 May 05 |
nicklas |
351 |
|
647 |
25 May 05 |
nicklas |
352 |
Map<Directory, List<Directory>> tree = new HashMap<Directory, List<Directory>>(); |
647 |
25 May 05 |
nicklas |
353 |
List<Integer> parents = new LinkedList<Integer>(); |
647 |
25 May 05 |
nicklas |
354 |
parents.add(directory.getId()); |
647 |
25 May 05 |
nicklas |
355 |
while (parents.size() > 0) |
647 |
25 May 05 |
nicklas |
356 |
{ |
1979 |
14 Feb 06 |
nicklas |
357 |
query.setParameter("parents", parents, Type.INT); |
1418 |
07 Oct 05 |
nicklas |
358 |
List<Directory> children = query.list(dc); |
647 |
25 May 05 |
nicklas |
359 |
parents.clear(); |
647 |
25 May 05 |
nicklas |
360 |
for (Directory child : children) |
647 |
25 May 05 |
nicklas |
361 |
{ |
647 |
25 May 05 |
nicklas |
362 |
Directory parent = child.getParent(); |
647 |
25 May 05 |
nicklas |
363 |
if (!tree.containsKey(parent)) |
647 |
25 May 05 |
nicklas |
364 |
{ |
647 |
25 May 05 |
nicklas |
365 |
tree.put(parent, new LinkedList<Directory>()); |
647 |
25 May 05 |
nicklas |
366 |
} |
647 |
25 May 05 |
nicklas |
367 |
tree.get(parent).add(child); |
647 |
25 May 05 |
nicklas |
368 |
parents.add(child.getId()); |
647 |
25 May 05 |
nicklas |
369 |
} |
647 |
25 May 05 |
nicklas |
370 |
} |
647 |
25 May 05 |
nicklas |
371 |
return tree; |
647 |
25 May 05 |
nicklas |
372 |
} |
3698 |
21 Aug 07 |
martin |
373 |
/** |
4794 |
02 Mar 09 |
nicklas |
Load a minimal directory tree that includes at least all the specified directories |
4794 |
02 Mar 09 |
nicklas |
and their parent directories all the way up to the root or as far as the logged in user |
4794 |
02 Mar 09 |
nicklas |
has read permission. |
4794 |
02 Mar 09 |
nicklas |
@param dc A DbControl for accessing the database |
4794 |
02 Mar 09 |
nicklas |
@param directories An array of directories |
4794 |
02 Mar 09 |
nicklas |
@return A <code>Map</code> which maps a directory to a |
4794 |
02 Mar 09 |
nicklas |
list of it's sub-directories. The map is guaranteed to contain an entry for each of |
4794 |
02 Mar 09 |
nicklas |
the given directories, but the list may be empty if there are no subdirectories |
4794 |
02 Mar 09 |
nicklas |
@throws BaseException If there is an error |
4794 |
02 Mar 09 |
nicklas |
@since 2.11 |
4794 |
02 Mar 09 |
nicklas |
384 |
*/ |
4794 |
02 Mar 09 |
nicklas |
385 |
public static Map<Directory, List<Directory>> loadMinimalDirectoryTree(DbControl dc, Directory... directories) |
4794 |
02 Mar 09 |
nicklas |
386 |
throws InvalidDataException, BaseException |
4794 |
02 Mar 09 |
nicklas |
387 |
{ |
7310 |
20 Mar 17 |
nicklas |
388 |
return loadMinimalDirectoryTree(dc, Include.ALL, directories); |
7310 |
20 Mar 17 |
nicklas |
389 |
} |
7310 |
20 Mar 17 |
nicklas |
390 |
|
7310 |
20 Mar 17 |
nicklas |
391 |
/** |
7310 |
20 Mar 17 |
nicklas |
Load a minimal directory tree that includes at least all the specified directories |
7310 |
20 Mar 17 |
nicklas |
and their parent directories all the way up to the root or as far as the logged in user |
7310 |
20 Mar 17 |
nicklas |
has read permission. |
7310 |
20 Mar 17 |
nicklas |
@param dc A DbControl for accessing the database |
7310 |
20 Mar 17 |
nicklas |
@param include Include settings for loading sub directories |
7310 |
20 Mar 17 |
nicklas |
@param directories An array of directories |
7310 |
20 Mar 17 |
nicklas |
@return A <code>Map</code> which maps a directory to a |
7310 |
20 Mar 17 |
nicklas |
list of it's sub-directories. The map is guaranteed to contain an entry for each of |
7310 |
20 Mar 17 |
nicklas |
the given directories, but the list may be empty if there are no subdirectories |
7310 |
20 Mar 17 |
nicklas |
@throws BaseException If there is an error |
7310 |
20 Mar 17 |
nicklas |
@since 3.11 |
7310 |
20 Mar 17 |
nicklas |
403 |
*/ |
7310 |
20 Mar 17 |
nicklas |
404 |
public static Map<Directory, List<Directory>> loadMinimalDirectoryTree(DbControl dc, Collection<Include> include, Directory... directories) |
7310 |
20 Mar 17 |
nicklas |
405 |
throws InvalidDataException, BaseException |
7310 |
20 Mar 17 |
nicklas |
406 |
{ |
4794 |
02 Mar 09 |
nicklas |
407 |
Map<Directory, List<Directory>> tree = new HashMap<Directory, List<Directory>>(); |
4794 |
02 Mar 09 |
nicklas |
408 |
|
4794 |
02 Mar 09 |
nicklas |
// 1. Move up the directory tree as far as possible |
4794 |
02 Mar 09 |
nicklas |
// storing all directories that we pass |
4794 |
02 Mar 09 |
nicklas |
411 |
Set<Integer> all = new HashSet<Integer>(); |
4794 |
02 Mar 09 |
nicklas |
412 |
for (Directory d : directories) |
4794 |
02 Mar 09 |
nicklas |
413 |
{ |
5014 |
25 Jun 09 |
martin |
414 |
if (d == null) |
5014 |
25 Jun 09 |
martin |
415 |
{ |
5014 |
25 Jun 09 |
martin |
/* #### CONTINUE-STATEMENT #### */ |
5014 |
25 Jun 09 |
martin |
417 |
continue; |
5014 |
25 Jun 09 |
martin |
418 |
} |
4794 |
02 Mar 09 |
nicklas |
419 |
tree.put(d, new LinkedList<Directory>()); |
4794 |
02 Mar 09 |
nicklas |
420 |
all.add(d.getId()); |
4794 |
02 Mar 09 |
nicklas |
421 |
try |
4794 |
02 Mar 09 |
nicklas |
422 |
{ |
4794 |
02 Mar 09 |
nicklas |
423 |
Directory parent = d.getParent(); |
4794 |
02 Mar 09 |
nicklas |
424 |
while (parent != null) |
4794 |
02 Mar 09 |
nicklas |
425 |
{ |
4794 |
02 Mar 09 |
nicklas |
426 |
if (all.add(parent.getId())) |
4794 |
02 Mar 09 |
nicklas |
427 |
{ |
4794 |
02 Mar 09 |
nicklas |
428 |
parent = parent.getParent(); |
4794 |
02 Mar 09 |
nicklas |
429 |
} |
4794 |
02 Mar 09 |
nicklas |
430 |
else |
4794 |
02 Mar 09 |
nicklas |
431 |
{ |
4794 |
02 Mar 09 |
nicklas |
// break if the directory has already been added |
4794 |
02 Mar 09 |
nicklas |
433 |
parent = null; |
4794 |
02 Mar 09 |
nicklas |
434 |
} |
4794 |
02 Mar 09 |
nicklas |
435 |
} |
4794 |
02 Mar 09 |
nicklas |
436 |
} |
4794 |
02 Mar 09 |
nicklas |
437 |
catch (PermissionDeniedException ex) |
4794 |
02 Mar 09 |
nicklas |
438 |
{} |
4794 |
02 Mar 09 |
nicklas |
439 |
} |
4794 |
02 Mar 09 |
nicklas |
440 |
|
4794 |
02 Mar 09 |
nicklas |
// 2. Query that loads the subdirectories to all directories that we passed |
4794 |
02 Mar 09 |
nicklas |
442 |
ItemQuery<Directory> query = Directory.getQuery(); |
4794 |
02 Mar 09 |
nicklas |
443 |
query.restrict( |
4794 |
02 Mar 09 |
nicklas |
444 |
Restrictions.in( |
4794 |
02 Mar 09 |
nicklas |
445 |
Hql.property("parent"), |
4794 |
02 Mar 09 |
nicklas |
446 |
Expressions.parameter("parents") |
4794 |
02 Mar 09 |
nicklas |
447 |
) |
4794 |
02 Mar 09 |
nicklas |
448 |
); |
4794 |
02 Mar 09 |
nicklas |
449 |
query.order(Orders.asc(Hql.property("name"))); |
7310 |
20 Mar 17 |
nicklas |
450 |
if (include != null && include.size() > 0) |
7310 |
20 Mar 17 |
nicklas |
451 |
{ |
7310 |
20 Mar 17 |
nicklas |
452 |
query.setIncludes(include); |
7310 |
20 Mar 17 |
nicklas |
453 |
} |
4794 |
02 Mar 09 |
nicklas |
454 |
query.setParameter("parents", all, Type.INT); |
4794 |
02 Mar 09 |
nicklas |
455 |
|
4794 |
02 Mar 09 |
nicklas |
456 |
ItemResultIterator<Directory> it = query.iterate(dc); |
4794 |
02 Mar 09 |
nicklas |
457 |
while (it.hasNext()) |
4794 |
02 Mar 09 |
nicklas |
458 |
{ |
4794 |
02 Mar 09 |
nicklas |
459 |
Directory child = it.next(); |
4794 |
02 Mar 09 |
nicklas |
460 |
Directory parent = child.getParent(); |
4794 |
02 Mar 09 |
nicklas |
461 |
if (!tree.containsKey(parent)) |
4794 |
02 Mar 09 |
nicklas |
462 |
{ |
4794 |
02 Mar 09 |
nicklas |
463 |
tree.put(parent, new LinkedList<Directory>()); |
4794 |
02 Mar 09 |
nicklas |
464 |
} |
4794 |
02 Mar 09 |
nicklas |
465 |
tree.get(parent).add(child); |
4794 |
02 Mar 09 |
nicklas |
466 |
} |
4794 |
02 Mar 09 |
nicklas |
467 |
return tree; |
4794 |
02 Mar 09 |
nicklas |
468 |
} |
4794 |
02 Mar 09 |
nicklas |
469 |
|
4794 |
02 Mar 09 |
nicklas |
470 |
|
4794 |
02 Mar 09 |
nicklas |
471 |
/** |
3832 |
15 Oct 07 |
nicklas |
Find files matching a given filter in a directory. If the filter |
3832 |
15 Oct 07 |
nicklas |
returns sub-directories, this method will check those directories too. |
3832 |
15 Oct 07 |
nicklas |
Use, for example, the {@link RegexpFileFilter} to look for files |
3832 |
15 Oct 07 |
nicklas |
matching a regular expression. |
3832 |
15 Oct 07 |
nicklas |
476 |
|
3832 |
15 Oct 07 |
nicklas |
@param directory The parent directory to search in |
3832 |
15 Oct 07 |
nicklas |
@param filter A filter which specifies which files to find, or null |
3832 |
15 Oct 07 |
nicklas |
to find all files |
3698 |
21 Aug 07 |
martin |
@return A List with the files in directory |
3832 |
15 Oct 07 |
nicklas |
that matches the filter, or null if the specified directory doesn't |
3832 |
15 Oct 07 |
nicklas |
exists or isn't a directory |
3698 |
21 Aug 07 |
martin |
@since 2.5 |
3832 |
15 Oct 07 |
nicklas |
@see RegexpFileFilter |
3698 |
21 Aug 07 |
martin |
485 |
*/ |
3832 |
15 Oct 07 |
nicklas |
486 |
public static List<File> findFiles(File directory, FileFilter filter) |
3698 |
21 Aug 07 |
martin |
487 |
{ |
3832 |
15 Oct 07 |
nicklas |
488 |
if (!directory.exists() || !directory.isDirectory()) |
3700 |
23 Aug 07 |
martin |
489 |
{ |
3832 |
15 Oct 07 |
nicklas |
490 |
return null; |
3700 |
23 Aug 07 |
martin |
491 |
} |
3698 |
21 Aug 07 |
martin |
492 |
|
3832 |
15 Oct 07 |
nicklas |
// To hold the result |
3832 |
15 Oct 07 |
nicklas |
494 |
List<File> searchResult = new LinkedList<File>(); |
3832 |
15 Oct 07 |
nicklas |
495 |
|
3832 |
15 Oct 07 |
nicklas |
// Temporary holds the directories too look in |
3832 |
15 Oct 07 |
nicklas |
497 |
List<File> directories = new LinkedList<File>(); |
3832 |
15 Oct 07 |
nicklas |
498 |
directories.add(directory); |
3832 |
15 Oct 07 |
nicklas |
499 |
|
3832 |
15 Oct 07 |
nicklas |
500 |
while (directories.size() > 0) |
3698 |
21 Aug 07 |
martin |
501 |
{ |
4120 |
04 Feb 08 |
nicklas |
502 |
ThreadSignalHandler.checkInterrupted(); |
3832 |
15 Oct 07 |
nicklas |
503 |
File dir = directories.remove(0); |
3832 |
15 Oct 07 |
nicklas |
504 |
File[] files = dir.listFiles(filter); |
3832 |
15 Oct 07 |
nicklas |
505 |
for (File f : files) |
3698 |
21 Aug 07 |
martin |
506 |
{ |
4120 |
04 Feb 08 |
nicklas |
507 |
ThreadSignalHandler.checkInterrupted(); |
3832 |
15 Oct 07 |
nicklas |
508 |
if (f.isDirectory()) |
3698 |
21 Aug 07 |
martin |
509 |
{ |
3832 |
15 Oct 07 |
nicklas |
510 |
directories.add(f); |
3698 |
21 Aug 07 |
martin |
511 |
} |
3832 |
15 Oct 07 |
nicklas |
512 |
else |
3832 |
15 Oct 07 |
nicklas |
513 |
{ |
3832 |
15 Oct 07 |
nicklas |
514 |
searchResult.add(f); |
3832 |
15 Oct 07 |
nicklas |
515 |
} |
3698 |
21 Aug 07 |
martin |
516 |
} |
3698 |
21 Aug 07 |
martin |
517 |
} |
3698 |
21 Aug 07 |
martin |
518 |
return searchResult; |
3698 |
21 Aug 07 |
martin |
519 |
} |
4977 |
23 Jun 09 |
nicklas |
520 |
|
4977 |
23 Jun 09 |
nicklas |
521 |
/** |
4977 |
23 Jun 09 |
nicklas |
Deletes all empty subdirectories and, optionally, also |
4977 |
23 Jun 09 |
nicklas |
the root directory. |
4977 |
23 Jun 09 |
nicklas |
@param root The root directory to start looking in |
4977 |
23 Jun 09 |
nicklas |
@param deleteRoot TRUE to also delete the root directory |
4977 |
23 Jun 09 |
nicklas |
if it is empty, FALSE to leave it |
4977 |
23 Jun 09 |
nicklas |
@return The number of deleted directories |
4977 |
23 Jun 09 |
nicklas |
@since 2.13 |
4977 |
23 Jun 09 |
nicklas |
529 |
*/ |
4977 |
23 Jun 09 |
nicklas |
530 |
public static int deleteEmptyDirectories(File root, boolean deleteRoot) |
4977 |
23 Jun 09 |
nicklas |
531 |
{ |
4977 |
23 Jun 09 |
nicklas |
// Step 1 - Create a list with all subdirectories |
4977 |
23 Jun 09 |
nicklas |
533 |
List<File> allDirs = new LinkedList<File>(); |
4977 |
23 Jun 09 |
nicklas |
534 |
List<File> unchecked = new LinkedList<File>(); |
4977 |
23 Jun 09 |
nicklas |
535 |
unchecked.add(root); |
4977 |
23 Jun 09 |
nicklas |
536 |
while (unchecked.size() > 0) |
4977 |
23 Jun 09 |
nicklas |
537 |
{ |
4977 |
23 Jun 09 |
nicklas |
538 |
ThreadSignalHandler.checkInterrupted(); |
4977 |
23 Jun 09 |
nicklas |
539 |
File dir = unchecked.remove(0); |
4977 |
23 Jun 09 |
nicklas |
540 |
File[] files = dir.listFiles(); |
4977 |
23 Jun 09 |
nicklas |
541 |
if (files != null) |
4977 |
23 Jun 09 |
nicklas |
542 |
{ |
4977 |
23 Jun 09 |
nicklas |
543 |
for (File f : files) |
4977 |
23 Jun 09 |
nicklas |
544 |
{ |
4977 |
23 Jun 09 |
nicklas |
545 |
if (f.isDirectory()) unchecked.add(f); |
4977 |
23 Jun 09 |
nicklas |
546 |
} |
4977 |
23 Jun 09 |
nicklas |
// Important! Add the directory first in the list! |
4977 |
23 Jun 09 |
nicklas |
548 |
if (deleteRoot || !dir.equals(root)) allDirs.add(0, dir); |
4977 |
23 Jun 09 |
nicklas |
549 |
} |
4977 |
23 Jun 09 |
nicklas |
550 |
} |
4977 |
23 Jun 09 |
nicklas |
551 |
|
4977 |
23 Jun 09 |
nicklas |
// Step 2 - Remove empty directories |
4977 |
23 Jun 09 |
nicklas |
553 |
int numDeleted = 0; |
4977 |
23 Jun 09 |
nicklas |
554 |
for (File subDir : allDirs) |
4977 |
23 Jun 09 |
nicklas |
555 |
{ |
4977 |
23 Jun 09 |
nicklas |
556 |
ThreadSignalHandler.checkInterrupted(); |
4977 |
23 Jun 09 |
nicklas |
557 |
File[] files = subDir.listFiles(); |
4977 |
23 Jun 09 |
nicklas |
558 |
if (files.length == 0) |
4977 |
23 Jun 09 |
nicklas |
559 |
{ |
4977 |
23 Jun 09 |
nicklas |
560 |
if (subDir.delete()) numDeleted++; |
4977 |
23 Jun 09 |
nicklas |
561 |
} |
4977 |
23 Jun 09 |
nicklas |
562 |
} |
4977 |
23 Jun 09 |
nicklas |
563 |
return numDeleted; |
4977 |
23 Jun 09 |
nicklas |
564 |
} |
5010 |
23 Jun 09 |
nicklas |
565 |
|
5010 |
23 Jun 09 |
nicklas |
566 |
/** |
5010 |
23 Jun 09 |
nicklas |
Do something recursively to all files and sub-directories in |
5010 |
23 Jun 09 |
nicklas |
specified root directory. If no directory filter is specified, |
5010 |
23 Jun 09 |
nicklas |
all subdirectories are processed, otherwise only those directories |
5010 |
23 Jun 09 |
nicklas |
were the {@link Filter#evaluate(Object)} method returns TRUE. |
5010 |
23 Jun 09 |
nicklas |
<p> |
5010 |
23 Jun 09 |
nicklas |
Files are only loaded if a file filter is specified. The |
5010 |
23 Jun 09 |
nicklas |
return value of the <code>evaluate</code> method is ignored. |
5010 |
23 Jun 09 |
nicklas |
<p> |
5010 |
23 Jun 09 |
nicklas |
The files and directories may be processed in any order. |
5010 |
23 Jun 09 |
nicklas |
<p> |
5010 |
23 Jun 09 |
nicklas |
NOTE! The intention of this method is that the filter should |
5010 |
23 Jun 09 |
nicklas |
have have a "side-effect" that does some work on the files/ |
5010 |
23 Jun 09 |
nicklas |
sub-directories. |
5010 |
23 Jun 09 |
nicklas |
580 |
|
5010 |
23 Jun 09 |
nicklas |
@param dc A DbControl to use for database access |
5010 |
23 Jun 09 |
nicklas |
@param root The root directory |
5010 |
23 Jun 09 |
nicklas |
@param dirFilter A filter that selects/rejects sub-directories |
5010 |
23 Jun 09 |
nicklas |
@param fileFilter A filter that does something with the file |
5010 |
23 Jun 09 |
nicklas |
@since 2.13 |
5010 |
23 Jun 09 |
nicklas |
586 |
*/ |
5010 |
23 Jun 09 |
nicklas |
587 |
public static void doRecursively(DbControl dc, Directory root, |
5010 |
23 Jun 09 |
nicklas |
588 |
Filter<? super Directory> dirFilter, Filter<? super net.sf.basedb.core.File> fileFilter) |
5010 |
23 Jun 09 |
nicklas |
589 |
{ |
5010 |
23 Jun 09 |
nicklas |
// Create the file/directory queries |
5010 |
23 Jun 09 |
nicklas |
591 |
ItemQuery<Directory> dirQuery = Directory.getQuery(); |
5010 |
23 Jun 09 |
nicklas |
592 |
dirQuery.restrict( |
5010 |
23 Jun 09 |
nicklas |
593 |
Restrictions.eq( |
5010 |
23 Jun 09 |
nicklas |
594 |
Hql.property("parent.id"), |
5010 |
23 Jun 09 |
nicklas |
595 |
Expressions.parameter("parent") |
5010 |
23 Jun 09 |
nicklas |
596 |
) |
5010 |
23 Jun 09 |
nicklas |
597 |
); |
5010 |
23 Jun 09 |
nicklas |
598 |
dirQuery.include(Include.ALL); |
5010 |
23 Jun 09 |
nicklas |
599 |
|
5010 |
23 Jun 09 |
nicklas |
600 |
ItemQuery<net.sf.basedb.core.File> fileQuery = net.sf.basedb.core.File.getQuery(); |
5010 |
23 Jun 09 |
nicklas |
601 |
fileQuery.restrict( |
5010 |
23 Jun 09 |
nicklas |
602 |
Restrictions.eq( |
5010 |
23 Jun 09 |
nicklas |
603 |
Hql.property("directory.id"), |
5010 |
23 Jun 09 |
nicklas |
604 |
Expressions.parameter("directory") |
5010 |
23 Jun 09 |
nicklas |
605 |
) |
5010 |
23 Jun 09 |
nicklas |
606 |
); |
5010 |
23 Jun 09 |
nicklas |
607 |
fileQuery.include(Include.ALL); |
5010 |
23 Jun 09 |
nicklas |
608 |
|
5010 |
23 Jun 09 |
nicklas |
// Load the staring directories |
5010 |
23 Jun 09 |
nicklas |
610 |
List<Directory> directories = new LinkedList<Directory>(); |
5010 |
23 Jun 09 |
nicklas |
611 |
directories.add(root); |
5010 |
23 Jun 09 |
nicklas |
612 |
|
5010 |
23 Jun 09 |
nicklas |
613 |
while (directories.size() > 0) |
5010 |
23 Jun 09 |
nicklas |
614 |
{ |
5010 |
23 Jun 09 |
nicklas |
615 |
ThreadSignalHandler.checkInterrupted(); |
5010 |
23 Jun 09 |
nicklas |
616 |
Directory d = directories.remove(0); |
5010 |
23 Jun 09 |
nicklas |
617 |
if (dirFilter == null || dirFilter.evaluate(d)) |
5010 |
23 Jun 09 |
nicklas |
618 |
{ |
5010 |
23 Jun 09 |
nicklas |
619 |
dirQuery.setParameter("parent", d.getId(), Type.INT); |
5010 |
23 Jun 09 |
nicklas |
620 |
directories.addAll(dirQuery.list(dc)); |
5010 |
23 Jun 09 |
nicklas |
621 |
} |
5010 |
23 Jun 09 |
nicklas |
622 |
if (fileFilter != null) |
5010 |
23 Jun 09 |
nicklas |
623 |
{ |
5010 |
23 Jun 09 |
nicklas |
624 |
fileQuery.setParameter("directory", d.getId(), Type.INT); |
5010 |
23 Jun 09 |
nicklas |
625 |
for (net.sf.basedb.core.File f : fileQuery.list(dc)) |
5010 |
23 Jun 09 |
nicklas |
626 |
{ |
5010 |
23 Jun 09 |
nicklas |
627 |
fileFilter.evaluate(f); |
5010 |
23 Jun 09 |
nicklas |
628 |
} |
5010 |
23 Jun 09 |
nicklas |
629 |
} |
5010 |
23 Jun 09 |
nicklas |
630 |
} |
5010 |
23 Jun 09 |
nicklas |
631 |
} |
5010 |
23 Jun 09 |
nicklas |
632 |
|
5219 |
18 Jan 10 |
nicklas |
633 |
/** |
5219 |
18 Jan 10 |
nicklas |
Creates a temporary directory. This method uses the built-in {@link |
5219 |
18 Jan 10 |
nicklas |
File#createTempFile(String, String, File)} method to first crete a temporary |
5219 |
18 Jan 10 |
nicklas |
file, that is then deleted and made into a directory instead. This should |
5219 |
18 Jan 10 |
nicklas |
ensure that a new empty directory is created each time this method is called. |
5219 |
18 Jan 10 |
nicklas |
The "temporary" nature of this method doesn't involve cleaning up or removing |
5219 |
18 Jan 10 |
nicklas |
the created directory. It is the responsibility of the calling code to remove |
5219 |
18 Jan 10 |
nicklas |
every file and subdirectory as well as the returned directory. This can |
5219 |
18 Jan 10 |
nicklas |
for example be done with the {@link #deleteTempDirectory(File)} method. |
5219 |
18 Jan 10 |
nicklas |
642 |
|
5219 |
18 Jan 10 |
nicklas |
@param prefix A prefix that is used in the directory name |
5219 |
18 Jan 10 |
nicklas |
it must be at least 3 characters long. |
5219 |
18 Jan 10 |
nicklas |
@param suffix An optional suffix for the directory name |
5219 |
18 Jan 10 |
nicklas |
@param directory An optional parent directory in which the temporary |
5219 |
18 Jan 10 |
nicklas |
directory should be created, or null to use the system temporary |
5219 |
18 Jan 10 |
nicklas |
directory |
5219 |
18 Jan 10 |
nicklas |
@return A reference to the created directory |
5219 |
18 Jan 10 |
nicklas |
@throws IOException If there is a problem with the directory creation |
5219 |
18 Jan 10 |
nicklas |
@since 2.15 |
5219 |
18 Jan 10 |
nicklas |
@see File#createTempFile(String, String, File) |
5219 |
18 Jan 10 |
nicklas |
653 |
*/ |
5219 |
18 Jan 10 |
nicklas |
654 |
public static File createTempDirectory(String prefix, String suffix, File directory) |
5219 |
18 Jan 10 |
nicklas |
655 |
throws IOException |
5219 |
18 Jan 10 |
nicklas |
656 |
{ |
5219 |
18 Jan 10 |
nicklas |
657 |
File tmpDir = File.createTempFile(prefix, suffix, directory); |
5219 |
18 Jan 10 |
nicklas |
658 |
if (!tmpDir.delete() || !tmpDir.mkdir()) |
5219 |
18 Jan 10 |
nicklas |
659 |
{ |
5219 |
18 Jan 10 |
nicklas |
660 |
throw new IOException("Could not create directory: " + tmpDir.getAbsolutePath()); |
5219 |
18 Jan 10 |
nicklas |
661 |
} |
5219 |
18 Jan 10 |
nicklas |
662 |
return tmpDir; |
5219 |
18 Jan 10 |
nicklas |
663 |
} |
5219 |
18 Jan 10 |
nicklas |
664 |
|
5219 |
18 Jan 10 |
nicklas |
665 |
/** |
5219 |
18 Jan 10 |
nicklas |
Recursively delete all files and subdirectories within a given |
5219 |
18 Jan 10 |
nicklas |
directory and the also the given directory itself. |
5219 |
18 Jan 10 |
nicklas |
668 |
|
5219 |
18 Jan 10 |
nicklas |
@param root The root directory to start looking in |
5219 |
18 Jan 10 |
nicklas |
@return The number of deleted files and directories |
5219 |
18 Jan 10 |
nicklas |
@since 2.15 |
5219 |
18 Jan 10 |
nicklas |
672 |
*/ |
5219 |
18 Jan 10 |
nicklas |
673 |
public static int deleteTempDirectory(File root) |
5219 |
18 Jan 10 |
nicklas |
674 |
{ |
5219 |
18 Jan 10 |
nicklas |
675 |
int numDeleted = 0; |
5219 |
18 Jan 10 |
nicklas |
676 |
|
5219 |
18 Jan 10 |
nicklas |
// Step 1 - Remove the files and create a list with all subdirectories |
5219 |
18 Jan 10 |
nicklas |
678 |
List<File> allDirs = new LinkedList<File>(); |
5219 |
18 Jan 10 |
nicklas |
679 |
List<File> unchecked = new LinkedList<File>(); |
5219 |
18 Jan 10 |
nicklas |
680 |
unchecked.add(root); |
5219 |
18 Jan 10 |
nicklas |
681 |
while (unchecked.size() > 0) |
5219 |
18 Jan 10 |
nicklas |
682 |
{ |
5219 |
18 Jan 10 |
nicklas |
683 |
ThreadSignalHandler.checkInterrupted(); |
5219 |
18 Jan 10 |
nicklas |
684 |
File dir = unchecked.remove(0); |
5219 |
18 Jan 10 |
nicklas |
685 |
File[] files = dir.listFiles(); |
5219 |
18 Jan 10 |
nicklas |
686 |
if (files != null) |
5219 |
18 Jan 10 |
nicklas |
687 |
{ |
5219 |
18 Jan 10 |
nicklas |
// Important! Add the directory first in the list! |
5219 |
18 Jan 10 |
nicklas |
689 |
allDirs.add(0, dir); |
5219 |
18 Jan 10 |
nicklas |
690 |
for (File f : files) |
5219 |
18 Jan 10 |
nicklas |
691 |
{ |
5219 |
18 Jan 10 |
nicklas |
692 |
if (f.isDirectory()) |
5219 |
18 Jan 10 |
nicklas |
693 |
{ |
5219 |
18 Jan 10 |
nicklas |
694 |
unchecked.add(f); |
5219 |
18 Jan 10 |
nicklas |
695 |
} |
5219 |
18 Jan 10 |
nicklas |
696 |
else |
5219 |
18 Jan 10 |
nicklas |
697 |
{ |
5219 |
18 Jan 10 |
nicklas |
698 |
if (f.delete()) numDeleted++; |
5219 |
18 Jan 10 |
nicklas |
699 |
} |
5219 |
18 Jan 10 |
nicklas |
700 |
} |
5219 |
18 Jan 10 |
nicklas |
701 |
} |
5219 |
18 Jan 10 |
nicklas |
702 |
} |
5219 |
18 Jan 10 |
nicklas |
703 |
|
5219 |
18 Jan 10 |
nicklas |
// Step 2 - Remove the directories |
5219 |
18 Jan 10 |
nicklas |
705 |
for (File subDir : allDirs) |
5219 |
18 Jan 10 |
nicklas |
706 |
{ |
5219 |
18 Jan 10 |
nicklas |
707 |
ThreadSignalHandler.checkInterrupted(); |
5219 |
18 Jan 10 |
nicklas |
708 |
if (subDir.delete()) numDeleted++; |
5219 |
18 Jan 10 |
nicklas |
709 |
} |
5219 |
18 Jan 10 |
nicklas |
710 |
return numDeleted; |
5219 |
18 Jan 10 |
nicklas |
711 |
} |
5219 |
18 Jan 10 |
nicklas |
712 |
|
5374 |
03 Aug 10 |
nicklas |
713 |
/** |
5374 |
03 Aug 10 |
nicklas |
Upload multiple files to BASE. |
5374 |
03 Aug 10 |
nicklas |
@param toDir The directory in the BASE file system that the files should |
5374 |
03 Aug 10 |
nicklas |
be uploaded to |
5374 |
03 Aug 10 |
nicklas |
@param fromDir The directory in the local file system to scan for files |
5374 |
03 Aug 10 |
nicklas |
to upload if the directory doesn't exists or is empty an empty list is |
5374 |
03 Aug 10 |
nicklas |
returned |
5374 |
03 Aug 10 |
nicklas |
@param filter An optional filter that decides which files that should |
5374 |
03 Aug 10 |
nicklas |
be uploaded or not, if null all files, including subdirectories, are |
5374 |
03 Aug 10 |
nicklas |
uploaded |
5374 |
03 Aug 10 |
nicklas |
@param overwrite TRUE if existing files should be overwritten, FALSE to |
5374 |
03 Aug 10 |
nicklas |
only overwrite files that have been marked for removal |
5374 |
03 Aug 10 |
nicklas |
@param progress An optional progress reporter |
5374 |
03 Aug 10 |
nicklas |
@return A list with the new file items that were created |
5374 |
03 Aug 10 |
nicklas |
@since 2.16 |
5374 |
03 Aug 10 |
nicklas |
728 |
*/ |
5374 |
03 Aug 10 |
nicklas |
729 |
public static List<net.sf.basedb.core.File> uploadFiles(DbControl dc, Directory toDir, |
5374 |
03 Aug 10 |
nicklas |
730 |
File fromDir, final FileFilter filter, boolean overwrite, ProgressReporter progress) |
5374 |
03 Aug 10 |
nicklas |
731 |
throws IOException |
5374 |
03 Aug 10 |
nicklas |
732 |
{ |
5374 |
03 Aug 10 |
nicklas |
733 |
if (!fromDir.exists() || !fromDir.isDirectory()) |
5374 |
03 Aug 10 |
nicklas |
734 |
{ |
5374 |
03 Aug 10 |
nicklas |
735 |
return Collections.emptyList(); |
5374 |
03 Aug 10 |
nicklas |
736 |
} |
5374 |
03 Aug 10 |
nicklas |
737 |
|
5374 |
03 Aug 10 |
nicklas |
// All files to upload in BASE and native representation |
5374 |
03 Aug 10 |
nicklas |
739 |
List<net.sf.basedb.core.File> uploaded = new ArrayList<net.sf.basedb.core.File>(); |
5374 |
03 Aug 10 |
nicklas |
740 |
List<File> fileToUpload = new ArrayList<File>(); |
5374 |
03 Aug 10 |
nicklas |
741 |
|
5374 |
03 Aug 10 |
nicklas |
// Temporary holds the directories too look in |
5374 |
03 Aug 10 |
nicklas |
743 |
List<File> directories = new LinkedList<File>(); |
5374 |
03 Aug 10 |
nicklas |
744 |
Map<File, Directory> subdirs = new HashMap<File, Directory>(); |
5374 |
03 Aug 10 |
nicklas |
745 |
directories.add(fromDir); |
5374 |
03 Aug 10 |
nicklas |
746 |
subdirs.put(fromDir, toDir); |
5374 |
03 Aug 10 |
nicklas |
747 |
|
5374 |
03 Aug 10 |
nicklas |
// First step: Scan the directories to find all files to upload |
5374 |
03 Aug 10 |
nicklas |
// This step will create BASE File and Directory items |
5374 |
03 Aug 10 |
nicklas |
750 |
long totalBytes = 0; |
5374 |
03 Aug 10 |
nicklas |
751 |
while (directories.size() > 0) |
5374 |
03 Aug 10 |
nicklas |
752 |
{ |
5374 |
03 Aug 10 |
nicklas |
753 |
ThreadSignalHandler.checkInterrupted(); |
5374 |
03 Aug 10 |
nicklas |
754 |
File dir = directories.remove(0); |
5374 |
03 Aug 10 |
nicklas |
755 |
Directory uploadDir = subdirs.get(dir); |
5374 |
03 Aug 10 |
nicklas |
756 |
|
5374 |
03 Aug 10 |
nicklas |
757 |
File[] files = dir.listFiles(filter); |
5374 |
03 Aug 10 |
nicklas |
758 |
for (File f : files) |
5374 |
03 Aug 10 |
nicklas |
759 |
{ |
5374 |
03 Aug 10 |
nicklas |
760 |
if (f.isDirectory()) |
5374 |
03 Aug 10 |
nicklas |
761 |
{ |
5374 |
03 Aug 10 |
nicklas |
// Create subdirectory |
5374 |
03 Aug 10 |
nicklas |
763 |
directories.add(f); |
5374 |
03 Aug 10 |
nicklas |
764 |
Directory newDirectory = Directory.getNew(dc, uploadDir); |
5374 |
03 Aug 10 |
nicklas |
765 |
newDirectory.setName(f.getName()); |
5374 |
03 Aug 10 |
nicklas |
766 |
dc.saveItem(newDirectory); |
5374 |
03 Aug 10 |
nicklas |
767 |
subdirs.put(f, newDirectory); |
5374 |
03 Aug 10 |
nicklas |
768 |
} |
5374 |
03 Aug 10 |
nicklas |
769 |
else if (f.isFile()) |
5374 |
03 Aug 10 |
nicklas |
770 |
{ |
5374 |
03 Aug 10 |
nicklas |
// Upload the file |
5374 |
03 Aug 10 |
nicklas |
772 |
net.sf.basedb.core.File baseFile = net.sf.basedb.core.File.getFile(dc, uploadDir, f.getName(), true); |
5374 |
03 Aug 10 |
nicklas |
773 |
if (!baseFile.isInDatabase()) |
5374 |
03 Aug 10 |
nicklas |
774 |
{ |
5374 |
03 Aug 10 |
nicklas |
775 |
dc.saveItem(baseFile); |
5374 |
03 Aug 10 |
nicklas |
776 |
} |
5374 |
03 Aug 10 |
nicklas |
777 |
if (overwrite || !baseFile.isInDatabase() || baseFile.isRemoved()) |
5374 |
03 Aug 10 |
nicklas |
778 |
{ |
5374 |
03 Aug 10 |
nicklas |
779 |
uploaded.add(baseFile); |
5374 |
03 Aug 10 |
nicklas |
780 |
fileToUpload.add(f); |
5374 |
03 Aug 10 |
nicklas |
781 |
totalBytes += f.length(); |
5374 |
03 Aug 10 |
nicklas |
782 |
} |
5374 |
03 Aug 10 |
nicklas |
783 |
} |
5374 |
03 Aug 10 |
nicklas |
784 |
} |
5374 |
03 Aug 10 |
nicklas |
785 |
} |
5374 |
03 Aug 10 |
nicklas |
786 |
|
5374 |
03 Aug 10 |
nicklas |
// Second step: Perform the upload |
5374 |
03 Aug 10 |
nicklas |
788 |
SimpleAbsoluteProgressReporter aProgress = null; |
5374 |
03 Aug 10 |
nicklas |
789 |
if (progress != null) aProgress = new SimpleAbsoluteProgressReporter(progress, totalBytes); |
5374 |
03 Aug 10 |
nicklas |
790 |
long numBytes = 0; |
5374 |
03 Aug 10 |
nicklas |
791 |
for (int i = 0; i < fileToUpload.size(); ++i) |
5374 |
03 Aug 10 |
nicklas |
792 |
{ |
5374 |
03 Aug 10 |
nicklas |
793 |
ThreadSignalHandler.checkInterrupted(); |
5374 |
03 Aug 10 |
nicklas |
794 |
File f = fileToUpload.get(i); |
5374 |
03 Aug 10 |
nicklas |
795 |
net.sf.basedb.core.File baseFile = uploaded.get(i); |
5374 |
03 Aug 10 |
nicklas |
796 |
InputStream in = null; |
5374 |
03 Aug 10 |
nicklas |
797 |
OutputStream out = null; |
5374 |
03 Aug 10 |
nicklas |
798 |
try |
5374 |
03 Aug 10 |
nicklas |
799 |
{ |
5374 |
03 Aug 10 |
nicklas |
800 |
if (aProgress != null) |
5374 |
03 Aug 10 |
nicklas |
801 |
{ |
5374 |
03 Aug 10 |
nicklas |
802 |
aProgress.setAbsolute(numBytes, "Uploading: " + f.getName()); |
5374 |
03 Aug 10 |
nicklas |
803 |
} |
5374 |
03 Aug 10 |
nicklas |
804 |
baseFile.setRemoved(false); |
5374 |
03 Aug 10 |
nicklas |
805 |
baseFile.setMimeTypeAuto(null, null); |
5374 |
03 Aug 10 |
nicklas |
806 |
in = FileUtil.getInputStream(f); |
5374 |
03 Aug 10 |
nicklas |
807 |
out = baseFile.getUploadStream(false); |
5374 |
03 Aug 10 |
nicklas |
808 |
numBytes += FileUtil.copy(in, out, aProgress); |
5374 |
03 Aug 10 |
nicklas |
809 |
} |
5374 |
03 Aug 10 |
nicklas |
810 |
finally |
5374 |
03 Aug 10 |
nicklas |
811 |
{ |
5374 |
03 Aug 10 |
nicklas |
812 |
FileUtil.close(in); |
5374 |
03 Aug 10 |
nicklas |
813 |
FileUtil.close(out); |
5374 |
03 Aug 10 |
nicklas |
814 |
} |
5374 |
03 Aug 10 |
nicklas |
815 |
} |
5374 |
03 Aug 10 |
nicklas |
816 |
return uploaded; |
5374 |
03 Aug 10 |
nicklas |
817 |
} |
5374 |
03 Aug 10 |
nicklas |
818 |
|
3698 |
21 Aug 07 |
martin |
819 |
} |