001package Torello.Java; 002 003import static Torello.Java.C.*; 004 005import java.util.*; 006 007import Torello.JavaDoc.LinkJavaSource; 008 009import java.io.*; 010import java.nio.file.*; 011 012/** 013 * Operating-System independent utilities for moving, copying and deleting files, or an entire 014 * tree of files - using the <CODE>FileNode</CODE> class. 015 * 016 * <EMBED CLASS='external-html' DATA-FILE-ID=FILE_TRANSFER> 017 */ 018@Torello.JavaDoc.StaticFunctional 019public class FileTransfer 020{ 021 private FileTransfer() { } 022 023 /** 024 * <EMBED CLASS='external-html' DATA-FILE-ID=FT_COPY_DESC> 025 * @param directory <EMBED CLASS='external-html' DATA-FILE-ID=FT_COPY_DIRECTORY> 026 * @param filter <EMBED CLASS='external-html' DATA-FILE-ID=FT_COPY_FILTER> 027 * @param targetDirectory <EMBED CLASS='external-html' DATA-FILE-ID=FT_COPY_TARGET_DIR> 028 * 029 * @param a This parameter may be null, but if it is not, then debugging / logging / 030 * informational messages will be sent to this output. 031 * 032 * <EMBED CLASS='external-html' DATA-FILE-ID=APPENDABLE> 033 * 034 * @return The number of files that were copied. 035 * 036 * @throws DirExpectedException If you pass a "file" instance of {@code class FileNode} to 037 * parameter {@code 'directory.'} 038 * 039 * @throws WritableDirectoryException If the target-directory is not available to Java for 040 * copying. 041 * 042 * @throws java.nio.file.NoSuchFileException This will be thrown if the logic which checks to 043 * ensure that the source and target directories are not identical is unable to identify the 044 * <I><B>real path name</B></I> of either the source or target directory. One such possible 045 * situation where this would happen would be if the user applied the UNIX <B>tilda 046 * ({@code '~'})</B> in either the {@code source} or {@code target} directory-name. 047 * 048 * @throws java.nio.file.InvalidPathException This will be thrown if {@code class 049 * java.nio.file.Paths} is unable to instantiate a {@code java.nio.file.Path} for either the 050 * source-directory (parameter {@code directory}), or the {@code targetDirectory}. 051 * 052 * @throws SameSourceAndTargetException This will be thrown if the source and target 053 * directories are found to point to identical locations on the file-system. 054 * 055 * @throws IOException For any IO filesystem errors. 056 * 057 * @see #copyRecursive(FileNode, FileNodeFilter, FileNodeFilter, String, Appendable) 058 * @see FileNode#getDirContentsFiles(RTC) 059 * @see DirExpectedException#check(FileNode) 060 * @see WritableDirectoryException#check(String) 061 * @see SameSourceAndTargetException#check(FileNode, String) 062 */ 063 @LinkJavaSource(handle="CopyFiles") 064 public static int copy( 065 final FileNode directory, 066 final FileNodeFilter filter, 067 final String targetDirectory, 068 final Appendable a 069 ) 070 throws IOException, SameSourceAndTargetException, 071 InvalidPathException, NoSuchFileException 072 { 073 DirExpectedException.check(directory); 074 WritableDirectoryException.check(targetDirectory); 075 SameSourceAndTargetException.check(directory, targetDirectory); 076 077 final String td = targetDirectory.endsWith(File.separator) 078 ? targetDirectory 079 : targetDirectory + File.separator; 080 081 return CopyFiles.COPY(directory, filter, td, a); 082 } 083 084 /** 085 * <EMBED CLASS='external-html' DATA-FILE-ID=FT_CPREC_DESC> 086 * @param directory <EMBED CLASS='external-html' DATA-FILE-ID=FT_CPREC_DIRECTORY> 087 * @param fileFilter <EMBED CLASS='external-html' DATA-FILE-ID=FT_CPREC_FILE_FILT> 088 * @param dirFilter <EMBED CLASS='external-html' DATA-FILE-ID=FT_CPREC_DIR_FILT> 089 * @param targetDirectory <EMBED CLASS='external-html' DATA-FILE-ID=FT_CPREC_TARGET_DIR> 090 * 091 * @param a This parameter may be null, but if it is not, then debugging / logging / 092 * informational messages will be sent to this output. 093 * 094 * @return This method makes calls to the single-level, single-directory-version of the 095 * {@code copy(...)} method in this class for each directory found in the tree. This method 096 * shall sum-up all and count all the files as they are copied. The value returned by this 097 * method is an integer specified how many files were copied in the process. 098 * 099 * @throws DirExpectedException If you pass a "file" instance of {@code class FileNode} to 100 * parameter {@code 'directory.'} 101 * 102 * @throws WritableDirectoryException If the initial target-directory, itself, is not available 103 * to Java for copying, then this exception shall throw. In actuality, all sub-directories 104 * that need to be created will be created by this recursive-copy operation - except for the 105 * highest-level "top directory" (the one indicated by the parameter {@code 'targetDirectory'} 106 * - because if that doesn't exist, then this {@code 'WritableDirectoryException'} will throw). 107 * 108 * @throws java.nio.file.NoSuchFileException This will be thrown if the logic which checks to 109 * ensure that the source and target directories are not identical is unable to identify the 110 * <I><B>real path name</B></I> of either the source or target directory. One such possible 111 * situation where this would happen would be if the user applied the UNIX <B>tilda 112 * ({@code '~'})</B> in either the {@code source} or {@code target} directory-name. 113 * 114 * @throws java.nio.file.InvalidPathException This will be thrown if {@code class 115 * java.nio.file.Paths} is unable to instantiate a {@code java.nio.file.Path} for either the 116 * source-directory (parameter {@code directory}), or the {@code targetDirectory}. 117 * 118 * @throws SameSourceAndTargetException This will be thrown if the source and target 119 * directories are found to point to identical locations on the file-system. 120 * 121 * @throws IOException For any IO filesystem errors. 122 * 123 * @see #copy(FileNode, FileNodeFilter, String, Appendable) 124 * @see FileNode#getDirContentsDirs(RTC) 125 * @see DirExpectedException#check(FileNode) 126 * @see WritableDirectoryException#check(String) 127 * @see SameSourceAndTargetException#check(FileNode, String) 128 */ 129 @LinkJavaSource(handle="CopyFiles") 130 public static int copyRecursive( 131 final FileNode directory, 132 final FileNodeFilter fileFilter, 133 final FileNodeFilter dirFilter, 134 final String targetDirectory, 135 final Appendable a 136 ) 137 throws IOException, SameSourceAndTargetException, 138 InvalidPathException, NoSuchFileException 139 { 140 DirExpectedException.check(directory); 141 WritableDirectoryException.check(targetDirectory); 142 SameSourceAndTargetException.check(directory, targetDirectory); 143 144 final String td = targetDirectory.endsWith(File.separator) 145 ? targetDirectory 146 : targetDirectory + File.separator; 147 148 return CopyFiles.RECURSIVE(directory, fileFilter, dirFilter, td, a); 149 } 150 151 /** 152 * <EMBED CLASS='external-html' DATA-FILE-ID=FT_DEL_DESC> 153 * @param directory <EMBED CLASS='external-html' DATA-FILE-ID=FT_DEL_DIRECTORY> 154 * @param filter <EMBED CLASS='external-html' DATA-FILE-ID=FT_DEL_FILTER> 155 * @param a An output log, for debugging & logging informational messages. 156 * This parameter may be null, and if so, it will be silently ignored. 157 * <EMBED CLASS='external-html' DATA-FILE-ID=APPENDABLE> 158 * @return <EMBED CLASS='external-html' DATA-FILE-ID=FT_DEL_RETURNS> 159 * 160 * @throws DirExpectedException If you pass a "file" instance of {@code class FileNode} to 161 * parameter {@code 'directory'}. 162 * 163 * @throws IOException For any IO file-system errors. 164 * 165 * @see #deleteFilesRecursive(FileNode, FileNodeFilter, FileNodeFilter, Appendable) 166 * @see FileNode#getDirContentsFiles(RTC) 167 * @see FileNode#getJavaIOFile() 168 * @see DirExpectedException#check(FileNode) 169 */ 170 @LinkJavaSource(handle="DeleteFiles") 171 public static int deleteFiles( 172 final FileNode directory, 173 final FileNodeFilter filter, 174 final Appendable a 175 ) 176 throws IOException 177 { 178 DirExpectedException.check(directory); 179 return DeleteFiles.DELETE(directory, filter, a); 180 } 181 182 /** 183 * <EMBED CLASS='external-html' DATA-FILE-ID=FT_DELREC_DESC> 184 * @param directory <EMBED CLASS='external-html' DATA-FILE-ID=FT_DELREC_DIRECTORY> 185 * @param fileFilter <EMBED CLASS='external-html' DATA-FILE-ID=FT_DELREC_FILE_FILT> 186 * @param dirFilter <EMBED CLASS='external-html' DATA-FILE-ID=FT_DELREC_DIR_FILT> 187 * @param a An output log, for debugging & logging informational messages. 188 * This parameter may be null, and if so, it will be silently ignored. 189 * @return <EMBED CLASS='external-html' DATA-FILE-ID=FT_DELREC_RET> 190 * 191 * @throws DirExpectedException If you pass a "file" instance of {@code class FileNode} to 192 * parameter {@code 'directory'} 193 * 194 * @throws IOException For any IO file-system errors. 195 * 196 * @see #deleteFiles(FileNode, FileNodeFilter, Appendable) 197 * @see FileNode#getDirContentsDirs(RTC) 198 * @see FileNode#getJavaIOFile() 199 * @see DirExpectedException#check(FileNode) 200 */ 201 @LinkJavaSource(handle="DeleteFiles") 202 public static int deleteFilesRecursive( 203 FileNode directory, FileNodeFilter fileFilter, FileNodeFilter dirFilter, 204 Appendable a 205 ) 206 throws IOException 207 { 208 DirExpectedException.check(directory); 209 return DeleteFiles.RECURSIVE(directory, fileFilter, dirFilter, a); 210 } 211 212 /** 213 * <EMBED CLASS='external-html' DATA-FILE-ID=FT_MV_DESC> 214 * @param directory <EMBED CLASS='external-html' DATA-FILE-ID=FT_MV_DIRECTORY> 215 * @param targetDirectory <EMBED CLASS='external-html' DATA-FILE-ID=FT_MV_TARGET_DIR> 216 * @param filter <EMBED CLASS='external-html' DATA-FILE-ID=FT_MV_FILTER> 217 * @param a An output log, for debugging & logging informational messages. 218 * This parameter may be null, and if so, it will be silently ignored. 219 * <EMBED CLASS='external-html' DATA-FILE-ID=APPENDABLE> 220 * @return The number of files that were moved. 221 * 222 * @throws DirExpectedException If you pass a "file" instance of {@code class FileNode} to 223 * parameter {@code 'directory.'} 224 * 225 * @throws WritableDirectoryException If the target-directory is not available to Java for 226 * moving. 227 * 228 * @throws java.nio.file.NoSuchFileException 229 * <EMBED CLASS='external-html' DATA-FILE-ID=FT_MV_NO_SUCH_F_EX> 230 * 231 * @throws java.nio.file.InvalidPathException 232 * <EMBED CLASS='external-html' DATA-FILE-ID=FT_MV_INVALID_P_EX> 233 * 234 * @throws SameSourceAndTargetException 235 * <EMBED CLASS='external-html' DATA-FILE-ID=FT_MV_SAME_SRC_T_EX> 236 * 237 * @throws IOException For any IO file-system errors. 238 * 239 * @see #moveRecursive(FileNode, FileNodeFilter, FileNodeFilter, String, Appendable) 240 * @see DirExpectedException#check(FileNode) 241 * @see WritableDirectoryException#check(String) 242 * @see SameSourceAndTargetException#check(FileNode, String) 243 */ 244 @LinkJavaSource(handle="MoveFiles") 245 public static int move( 246 final FileNode directory, 247 final FileNodeFilter filter, 248 final String targetDirectory, 249 final Appendable a 250 ) 251 throws IOException, SameSourceAndTargetException, 252 InvalidPathException, NoSuchFileException 253 { 254 DirExpectedException.check(directory); 255 WritableDirectoryException.check(targetDirectory); 256 SameSourceAndTargetException.check(directory, targetDirectory); 257 258 final String td = targetDirectory.endsWith(File.separator) 259 ? targetDirectory 260 : targetDirectory + File.separator; 261 262 return MoveFiles.MOVE(directory, filter, td, a); 263 } 264 265 /** 266 * <EMBED CLASS='external-html' DATA-FILE-ID=FT_MVREC_DESC> 267 * @param directory <EMBED CLASS='external-html' DATA-FILE-ID=FT_MVREC_DIRECTORY> 268 * @param targetDirectory <EMBED CLASS='external-html' DATA-FILE-ID=FT_MVREC_TARGET_DIR> 269 * @param fileFilter <EMBED CLASS='external-html' DATA-FILE-ID=FT_MVREC_DIR_FILT> 270 * @param dirFilter <EMBED CLASS='external-html' DATA-FILE-ID=FT_MVREC_FILE_FILT> 271 * @param a An output log, for debugging & logging informational messages. 272 * This parameter may be null, and if so, it will be silently ignored. 273 * @return <EMBED CLASS='external-html' DATA-FILE-ID=FT_MVREC_RET> 274 * 275 * @throws DirExpectedException If you pass a "file" instance of {@code class FileNode} to 276 * parameter {@code 'directory.'} 277 * 278 * @throws WritableDirectoryException 279 * <EMBED CLASS='external-html' DATA-FILE-ID=FT_MVREC_W_DIR_EX> 280 * 281 * @throws java.nio.file.NoSuchFileException 282 * <EMBED CLASS='external-html' DATA-FILE-ID=FT_MV_NO_SUCH_F_EX> 283 * 284 * @throws java.nio.file.InvalidPathException 285 * <EMBED CLASS='external-html' DATA-FILE-ID=FT_MV_INVALID_P_EX> 286 * 287 * @throws SameSourceAndTargetException 288 * <EMBED CLASS='external-html' DATA-FILE-ID=FT_MV_SAME_SRC_T_EX> 289 * 290 * @throws IOException For any IO filesystem errors. 291 * 292 * @see #move(FileNode, FileNodeFilter, String, Appendable) 293 * @see FileNode#getDirContentsDirs(RTC) 294 * @see DirExpectedException#check(FileNode) 295 * @see WritableDirectoryException#check(String) 296 * @see SameSourceAndTargetException#check(FileNode, String) 297 */ 298 @LinkJavaSource(handle="MoveFiles") 299 public static int moveRecursive( 300 FileNode directory, FileNodeFilter fileFilter, FileNodeFilter dirFilter, 301 String targetDirectory, Appendable a 302 ) 303 throws IOException, SameSourceAndTargetException, 304 InvalidPathException, NoSuchFileException 305 { 306 DirExpectedException.check(directory); 307 WritableDirectoryException.check(targetDirectory); 308 SameSourceAndTargetException.check(directory, targetDirectory); 309 310 final String td = targetDirectory.endsWith(File.separator) 311 ? targetDirectory 312 : targetDirectory + File.separator; 313 314 return MoveFiles.RECURSIVE(directory, fileFilter, dirFilter, td, a); 315 } 316}