1 package org.oddjob.io; 2 3 import java.io.File ; 4 import java.io.FileInputStream ; 5 import java.io.FileOutputStream ; 6 import java.io.IOException ; 7 import java.io.InputStream ; 8 import java.io.OutputStream ; 9 import java.io.Serializable ; 10 11 import org.apache.commons.io.FileUtils; 12 import org.apache.commons.io.IOUtils; 13 import org.apache.log4j.Logger; 14 import org.oddjob.util.OddjobConfigException; 15 16 17 32 public class CopyJob implements Runnable , Serializable { 33 private static final long serialVersionUID = 20050806; 34 35 private static final Logger logger = Logger.getLogger(CopyJob.class); 36 37 42 private String name; 43 44 49 private File [] from; 50 51 56 private File to; 57 58 63 private transient InputStream input; 64 65 70 private transient OutputStream output; 71 72 77 public String getName() { 78 return name; 79 } 80 81 86 public void setName(String name) { 87 this.name = name; 88 } 89 90 95 synchronized public File [] getFrom() { 96 return from; 97 } 98 99 104 synchronized public void setFrom(File [] file) { 105 this.from = file; 106 } 107 108 113 synchronized public File getTo() { 114 return to; 115 } 116 117 122 synchronized public void setTo(File file) { 123 this.to = file; 124 } 125 126 131 synchronized public void setInput(InputStream in) { 132 this.input = in; 133 } 134 135 140 synchronized public void setOutput(OutputStream out) { 141 this.output = out; 142 } 143 144 public void run() { 145 try { 146 CopyCommand command = command(); 147 if (command == null) { 148 return; 149 } 150 CopyStats stats = new CopyStats(); 151 command.copy(stats); 152 logger.info("Copied " + stats.files + " files, " 153 + stats.directories + " directories."); 154 } catch (IOException e) { 155 throw new RuntimeException (e); 156 } 157 } 158 159 private CopyCommand command() throws IOException { 160 161 if (input != null) { 162 if (output != null) { 163 return new StreamCopy(input, output); 164 } 165 else { 166 return new StreamCopy(input, to); 167 } 168 } 169 170 if (from == null) { 171 throw new RuntimeException ("Nothing to copy from!"); 172 } 173 174 File [] possiblyMany = Files.expand(from); 175 Files.verifyReadable(possiblyMany); 176 File singleFrom = null; 177 178 if (possiblyMany.length == 0) { 179 throw new RuntimeException ("From does not specify any files."); 180 } 181 182 if (possiblyMany.length == 1) { 183 singleFrom = possiblyMany[0]; 184 } 185 186 if (singleFrom != null) { 187 if (output != null) { 188 return new StreamCopy(singleFrom, output); 189 } 190 else if (singleFrom.isDirectory()) { 191 return new DirectoryCopy(singleFrom, to); 192 } else { 193 return new FileCopy(singleFrom, to); 194 } 195 } 196 197 return new MultiFileCopy(possiblyMany, to); 198 } 199 200 203 public InputStream getInput() { 204 return input; 205 } 206 209 public OutputStream getOutput() { 210 return output; 211 } 212 213 public String toString() { 214 if (name == null) { 215 return "Copy Files or Directories"; 216 } 217 return name; 218 } 219 220 221 225 interface CopyCommand { 226 227 public void copy(CopyStats stats) throws IOException ; 228 } 229 230 static class StreamCopy implements CopyCommand { 231 InputStream in; 232 OutputStream out; 233 234 StreamCopy(InputStream in, OutputStream out) { 235 this.in = in; 236 this.out = out; 237 } 238 239 StreamCopy(InputStream in, File to) throws IOException { 240 this.in = in; 241 if (to == null) { 242 throw new RuntimeException ("To file is not specified."); 243 } 244 if (to.isDirectory()) { 245 throw new OddjobConfigException("Can copy stream to a directory."); 246 } 247 this.out = new FileOutputStream (to); 248 } 249 250 StreamCopy(File from, OutputStream out) throws IOException { 251 this.in = new FileInputStream (from); 252 this.out = out; 253 } 254 255 public void copy(CopyStats stats) throws IOException { 256 IOUtils.copy(in, out); 257 stats.files++; 258 } 259 } 260 261 static class FileCopy implements CopyCommand { 262 File from; 263 File to; 264 265 FileCopy(File from, File to) { 266 this.from = from; 267 this.to = to; 268 } 269 270 public void copy(CopyStats stats) throws IOException { 271 if (to.isDirectory()) { 272 FileUtils.copyFileToDirectory(from, to); 273 } 274 else { 275 FileUtils.copyFile(from, to); 276 } 277 stats.files++; 278 } 279 } 280 281 282 static class DirectoryCopy implements CopyCommand { 283 File fromDir; 284 File toDir; 285 286 DirectoryCopy(File from, File to) { 287 this.fromDir = from; 288 if (to == null) { 289 throw new RuntimeException ("To dir not specified."); 290 } 291 if (to.exists()) { 292 if (!to.isDirectory()) { 293 throw new OddjobConfigException("To must be a directory."); 294 } 295 this.toDir = new File (to, from.getName()); 296 } else { 297 this.toDir = to; 298 } 299 } 300 301 public void copy(CopyStats stats) throws IOException { 302 FileUtils.copyDirectory(fromDir, toDir); 303 stats.directories++; 304 } 305 } 306 307 static class MultiFileCopy implements CopyCommand { 308 File [] files; 309 File toDir; 310 311 MultiFileCopy(File [] files, File toDir) { 312 this.files = files; 313 if (toDir == null) { 314 throw new RuntimeException ("To dir is not specified."); 315 } 316 if (!toDir.isDirectory()) { 317 throw new RuntimeException ("To must be a directory."); 318 } 319 this.toDir = toDir; 320 } 321 322 public void copy(CopyStats stats) throws IOException { 323 for (int i = 0; i < files.length; ++i) { 324 CopyCommand command; 325 if (files[i].isDirectory()) { 326 command = new DirectoryCopy(files[i], toDir); 327 } else { 328 command = new FileCopy(files[i], toDir); 329 } 330 command.copy(stats); 331 } 332 } 333 } 334 335 class CopyStats { 336 int files; 337 int directories; 338 } 339 } 340 | Popular Tags |