This project has retired. For details please refer to its
Attic page.
StorageUtil xref
1 package org.apache.archiva.repository.storage;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.archiva.common.filelock.FileLockException;
23 import org.apache.archiva.common.filelock.FileLockManager;
24 import org.apache.archiva.common.filelock.FileLockTimeoutException;
25 import org.apache.archiva.common.filelock.Lock;
26 import org.apache.commons.lang3.StringUtils;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 import java.io.IOException;
31 import java.nio.ByteBuffer;
32 import java.nio.channels.FileChannel;
33 import java.nio.channels.ReadableByteChannel;
34 import java.nio.channels.WritableByteChannel;
35 import java.nio.file.*;
36 import java.util.HashSet;
37 import java.util.function.Consumer;
38
39
40
41
42
43
44
45
46 public class StorageUtil
47 {
48 private static final int DEFAULT_BUFFER_SIZE = 4096;
49 private static final Logger log = LoggerFactory.getLogger(StorageUtil.class);
50
51
52
53
54
55
56
57
58
59
60
61
62 public static final void copyAsset( final StorageAsset source,
63 final StorageAsset target,
64 boolean locked,
65 final CopyOption... copyOptions ) throws IOException
66 {
67 if (source.isFileBased() && target.isFileBased()) {
68
69 final Path sourcePath = source.getFilePath();
70 final Path targetPath = target.getFilePath( );
71 if (locked) {
72 final FileLockManager lmSource = ((FilesystemStorage)source.getStorage()).getFileLockManager();
73 final FileLockManager lmTarget = ((FilesystemStorage)target.getStorage()).getFileLockManager();
74 Lock lockRead = null;
75 Lock lockWrite = null;
76 try {
77 lockRead = lmSource.readFileLock(sourcePath);
78 } catch (Exception e) {
79 log.error("Could not create read lock on {}", sourcePath);
80 throw new IOException(e);
81 }
82 try {
83 lockWrite = lmTarget.writeFileLock(targetPath);
84 } catch (Exception e) {
85 log.error("Could not create write lock on {}", targetPath);
86 throw new IOException(e);
87 }
88 try {
89 Files.copy(sourcePath, targetPath, copyOptions);
90 } finally {
91 if (lockRead!=null) {
92 try {
93 lmSource.release(lockRead);
94 } catch (FileLockException e) {
95 log.error("Error during lock release of read lock {}", lockRead.getFile());
96 }
97 }
98 if (lockWrite!=null) {
99 try {
100 lmTarget.release(lockWrite);
101 } catch (FileLockException e) {
102 log.error("Error during lock release of write lock {}", lockWrite.getFile());
103 }
104 }
105 }
106 } else
107 {
108 Files.copy( sourcePath, targetPath, copyOptions );
109 }
110 } else {
111 try {
112 final RepositoryStorage sourceStorage = source.getStorage();
113 final RepositoryStorage targetStorage = target.getStorage();
114 sourceStorage.consumeDataFromChannel( source, is -> wrapWriteFunction( is, targetStorage, target, locked ), locked);
115 } catch (IOException e) {
116 throw e;
117 } catch (Throwable e) {
118 Throwable cause = e.getCause();
119 if (cause instanceof IOException) {
120 throw (IOException)cause;
121 } else
122 {
123 throw new IOException( e );
124 }
125 }
126 }
127 }
128
129
130
131
132
133
134
135
136
137
138
139
140 public static final void moveAsset(StorageAsset./../../../org/apache/archiva/repository/storage/StorageAsset.html#StorageAsset">StorageAsset source, StorageAsset target, boolean locked, CopyOption... copyOptions) throws IOException
141 {
142 if (source.isFileBased() && target.isFileBased()) {
143
144
145 if (!Files.exists(target.getFilePath().getParent())) {
146 Files.createDirectories(target.getFilePath().getParent());
147 }
148 Files.move( source.getFilePath(), target.getFilePath(), copyOptions );
149 } else {
150 try {
151 final RepositoryStorage sourceStorage = source.getStorage();
152 final RepositoryStorage targetStorage = target.getStorage();
153 sourceStorage.consumeDataFromChannel( source, is -> wrapWriteFunction( is, targetStorage, target, locked ), locked);
154 sourceStorage.removeAsset( source );
155 } catch (IOException e) {
156 throw e;
157 } catch (Throwable e) {
158 Throwable cause = e.getCause();
159 if (cause instanceof IOException) {
160 throw (IOException)cause;
161 } else
162 {
163 throw new IOException( e );
164 }
165 }
166 }
167
168 }
169
170 private static final void wrapWriteFunction(ReadableByteChannel is, RepositoryStorage targetStorage, StorageAsset target, boolean locked) {
171 try {
172 targetStorage.writeDataToChannel( target, os -> copy(is, os), locked );
173 } catch (Exception e) {
174 throw new RuntimeException( e );
175 }
176 }
177
178
179 private static final void copy( final ReadableByteChannel is, final WritableByteChannel os ) {
180 if (is instanceof FileChannel) {
181 copy( (FileChannel) is, os );
182 } else if (os instanceof FileChannel) {
183 copy(is, (FileChannel)os);
184 } else
185 {
186 try
187 {
188 ByteBuffer buffer = ByteBuffer.allocate( DEFAULT_BUFFER_SIZE );
189 while ( is.read( buffer ) != -1 )
190 {
191 buffer.flip( );
192 while ( buffer.hasRemaining( ) )
193 {
194 os.write( buffer );
195 }
196 buffer.clear( );
197 }
198 }
199 catch ( IOException e )
200 {
201 throw new RuntimeException( e );
202 }
203 }
204 }
205
206 private static final void copy( final FileChannel is, final WritableByteChannel os ) {
207 try
208 {
209 is.transferTo( 0, is.size( ), os );
210 }
211 catch ( IOException e )
212 {
213 throw new RuntimeException( e );
214 }
215 }
216
217 private static final void copy( final ReadableByteChannel is, final FileChannel os ) {
218 try
219 {
220 os.transferFrom( is, 0, Long.MAX_VALUE );
221 }
222 catch ( IOException e )
223 {
224 throw new RuntimeException( e );
225 }
226 }
227
228
229
230
231
232
233
234
235 public static final void recurse(final StorageAsset baseAsset, final Consumer<StorageAsset> consumer, final boolean depthFirst, final int maxDepth) throws IOException {
236 recurse(baseAsset, consumer, depthFirst, maxDepth, 0);
237 }
238
239
240
241
242
243
244
245
246
247 public static final void recurse(final StorageAsset baseAsset, final Consumer<StorageAsset> consumer, final boolean depthFirst) throws IOException {
248 recurse(baseAsset, consumer, depthFirst, Integer.MAX_VALUE, 0);
249 }
250
251
252
253
254
255
256
257
258 public static final void recurse(final StorageAsset baseAsset, final Consumer<StorageAsset> consumer) throws IOException {
259 recurse(baseAsset, consumer, false, Integer.MAX_VALUE, 0);
260 }
261
262 private static final void recurse(final StorageAsset baseAsset, final Consumer<StorageAsset> consumer, final boolean depthFirst, final int maxDepth, final int currentDepth)
263 throws IOException {
264 if (!depthFirst) {
265 consumer.accept(baseAsset);
266 }
267 if (currentDepth<maxDepth && baseAsset.isContainer()) {
268 for(StorageAsset asset : baseAsset.list() ) {
269 recurse(asset, consumer, depthFirst, maxDepth, currentDepth+1);
270 }
271 }
272 if (depthFirst) {
273 consumer.accept(baseAsset);
274 }
275 }
276
277
278
279
280
281
282 public static final void deleteRecursively(StorageAsset baseDir) throws IOException {
283 recurse(baseDir, a -> {
284 try {
285 a.getStorage().removeAsset(a);
286 } catch (IOException e) {
287 log.error("Could not delete asset {}", a.getPath());
288 }
289 },true);
290 }
291
292
293
294
295
296
297
298
299 public static final String getExtension(StorageAsset asset) {
300 return StringUtils.substringAfterLast(asset.getName(),".");
301 }
302
303 public static final void copyToLocalFile(StorageAsset asset, Path destination, CopyOption... copyOptions) throws IOException {
304 if (asset.isFileBased()) {
305 Files.copy(asset.getFilePath(), destination, copyOptions);
306 } else {
307 try {
308
309 HashSet<OpenOption> openOptions = new HashSet<>();
310 for (CopyOption option : copyOptions) {
311 if (option == StandardCopyOption.REPLACE_EXISTING) {
312 openOptions.add(StandardOpenOption.CREATE);
313 openOptions.add(StandardOpenOption.TRUNCATE_EXISTING);
314 openOptions.add(StandardOpenOption.WRITE);
315 } else {
316 openOptions.add(StandardOpenOption.WRITE);
317 openOptions.add(StandardOpenOption.CREATE_NEW);
318 }
319 }
320 asset.getStorage().consumeDataFromChannel(asset, channel -> {
321 try {
322 FileChannel.open(destination, openOptions).transferFrom(channel, 0, Long.MAX_VALUE);
323 } catch (IOException e) {
324 throw new RuntimeException(e);
325 }
326 }, false);
327 } catch (Throwable e) {
328 if (e.getCause() instanceof IOException) {
329 throw (IOException)e.getCause();
330 } else {
331 throw new IOException(e);
332 }
333 }
334 }
335 }
336
337 public static class PathInformation {
338 final Path path ;
339 final boolean tmpFile;
340
341 PathInformation(Path path, boolean tmpFile) {
342 this.path = path;
343 this.tmpFile = tmpFile;
344 }
345
346 public Path getPath() {
347 return path;
348 }
349
350 public boolean isTmpFile() {
351 return tmpFile;
352 }
353
354 }
355
356 public static final PathInformation getAssetDataAsPath(StorageAsset asset) throws IOException {
357 if (!asset.exists()) {
358 throw new IOException("Asset does not exist");
359 }
360 if (asset.isFileBased()) {
361 return new PathInformation(asset.getFilePath(), false);
362 } else {
363 Path tmpFile = Files.createTempFile(asset.getName(), getExtension(asset));
364 copyToLocalFile(asset, tmpFile, StandardCopyOption.REPLACE_EXISTING);
365 return new PathInformation(tmpFile, true);
366 }
367 }
368
369 }