You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

StorageUtil.java 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. package org.apache.archiva.repository.content;
  2. /*
  3. * Licensed to the Apache Software Foundation (ASF) under one
  4. * or more contributor license agreements. See the NOTICE file
  5. * distributed with this work for additional information
  6. * regarding copyright ownership. The ASF licenses this file
  7. * to you under the Apache License, Version 2.0 (the
  8. * "License"); you may not use this file except in compliance
  9. * with the License. You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing,
  14. * software distributed under the License is distributed on an
  15. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  16. * KIND, either express or implied. See the License for the
  17. * specific language governing permissions and limitations
  18. * under the License.
  19. */
  20. import org.apache.archiva.common.filelock.FileLockException;
  21. import org.apache.archiva.common.filelock.FileLockManager;
  22. import org.apache.archiva.common.filelock.FileLockTimeoutException;
  23. import org.apache.archiva.common.filelock.Lock;
  24. import java.io.IOException;
  25. import java.nio.ByteBuffer;
  26. import java.nio.channels.FileChannel;
  27. import java.nio.channels.ReadableByteChannel;
  28. import java.nio.channels.WritableByteChannel;
  29. import java.nio.file.CopyOption;
  30. import java.nio.file.Files;
  31. import java.nio.file.Path;
  32. /**
  33. * @author Martin Stockhammer <martin_s@apache.org>
  34. */
  35. public class StorageUtil
  36. {
  37. private static final int DEFAULT_BUFFER_SIZE = 4096;
  38. /**
  39. * Copies the source asset to the target. The assets may be from different RepositoryStorage instances.
  40. *
  41. * @param source The source asset
  42. * @param target The target asset
  43. * @param locked If true, a readlock is set on the source and a write lock is set on the target.
  44. * @param copyOptions Copy options
  45. * @throws IOException
  46. */
  47. public static final void copyAsset( final StorageAsset source,
  48. final StorageAsset target,
  49. boolean locked,
  50. final CopyOption... copyOptions ) throws IOException
  51. {
  52. if (source.isFileBased() && target.isFileBased()) {
  53. // Short cut for FS operations
  54. final Path sourcePath = source.getFilePath();
  55. final Path targetPath = target.getFilePath( );
  56. if (locked) {
  57. final FileLockManager lmSource = ((FilesystemStorage)source.getStorage()).getFileLockManager();
  58. final FileLockManager lmTarget = ((FilesystemStorage)target.getStorage()).getFileLockManager();
  59. try (Lock lockRead = lmSource.readFileLock( sourcePath ); Lock lockWrite = lmTarget.writeFileLock( targetPath ) )
  60. {
  61. Files.copy( sourcePath, targetPath, copyOptions );
  62. }
  63. catch ( FileLockException e )
  64. {
  65. throw new IOException( e );
  66. }
  67. catch ( FileLockTimeoutException e )
  68. {
  69. throw new IOException( e );
  70. }
  71. } else
  72. {
  73. Files.copy( sourcePath, targetPath, copyOptions );
  74. }
  75. } else {
  76. try {
  77. final RepositoryStorage sourceStorage = source.getStorage();
  78. final RepositoryStorage targetStorage = target.getStorage();
  79. sourceStorage.consumeDataFromChannel( source, is -> wrapWriteFunction( is, targetStorage, target, locked ), locked);
  80. } catch (IOException e) {
  81. throw e;
  82. } catch (Throwable e) {
  83. Throwable cause = e.getCause();
  84. if (cause instanceof IOException) {
  85. throw (IOException)cause;
  86. } else
  87. {
  88. throw new IOException( e );
  89. }
  90. }
  91. }
  92. }
  93. /**
  94. *
  95. * @param source
  96. * @param target
  97. * @param locked
  98. * @param copyOptions
  99. * @throws IOException
  100. */
  101. public static void moveAsset(StorageAsset source, StorageAsset target, boolean locked, CopyOption... copyOptions) throws IOException
  102. {
  103. if (source.isFileBased() && target.isFileBased()) {
  104. // Short cut for FS operations
  105. // Move is atomic operation
  106. Files.move( source.getFilePath(), target.getFilePath(), copyOptions );
  107. } else {
  108. try {
  109. final RepositoryStorage sourceStorage = source.getStorage();
  110. final RepositoryStorage targetStorage = target.getStorage();
  111. sourceStorage.consumeDataFromChannel( source, is -> wrapWriteFunction( is, targetStorage, target, locked ), locked);
  112. sourceStorage.removeAsset( source );
  113. } catch (IOException e) {
  114. throw e;
  115. } catch (Throwable e) {
  116. Throwable cause = e.getCause();
  117. if (cause instanceof IOException) {
  118. throw (IOException)cause;
  119. } else
  120. {
  121. throw new IOException( e );
  122. }
  123. }
  124. }
  125. }
  126. private static void wrapWriteFunction(ReadableByteChannel is, RepositoryStorage targetStorage, StorageAsset target, boolean locked) {
  127. try {
  128. targetStorage.writeDataToChannel( target, os -> copy(is, os), locked );
  129. } catch (Exception e) {
  130. throw new RuntimeException( e );
  131. }
  132. }
  133. private static void copy( final ReadableByteChannel is, final WritableByteChannel os ) {
  134. if (is instanceof FileChannel) {
  135. copy( (FileChannel) is, os );
  136. } else if (os instanceof FileChannel) {
  137. copy(is, (FileChannel)os);
  138. } else
  139. {
  140. try
  141. {
  142. ByteBuffer buffer = ByteBuffer.allocate( DEFAULT_BUFFER_SIZE );
  143. while ( is.read( buffer ) != -1 )
  144. {
  145. buffer.flip( );
  146. while ( buffer.hasRemaining( ) )
  147. {
  148. os.write( buffer );
  149. }
  150. buffer.clear( );
  151. }
  152. }
  153. catch ( IOException e )
  154. {
  155. throw new RuntimeException( e );
  156. }
  157. }
  158. }
  159. private static void copy( final FileChannel is, final WritableByteChannel os ) {
  160. try
  161. {
  162. is.transferTo( 0, is.size( ), os );
  163. }
  164. catch ( IOException e )
  165. {
  166. throw new RuntimeException( e );
  167. }
  168. }
  169. private static void copy( final ReadableByteChannel is, final FileChannel os ) {
  170. try
  171. {
  172. os.transferFrom( is, 0, Long.MAX_VALUE );
  173. }
  174. catch ( IOException e )
  175. {
  176. throw new RuntimeException( e );
  177. }
  178. }
  179. }