1 22 package org.netbeans.lib.cvsclient.file; 23 24 import java.io.*; 25 import java.util.*; 26 27 import org.netbeans.lib.cvsclient.command.*; 28 import org.netbeans.lib.cvsclient.request.*; 29 import org.netbeans.lib.cvsclient.util.*; 30 31 36 public class DefaultFileHandler 37 implements FileHandler { 38 41 private static final boolean DEBUG = false; 42 43 46 private static final int CHUNK_SIZE = 32768; 47 48 51 private Date modifiedDate; 52 53 private TransmitTextFilePreprocessor transmitTextFilePreprocessor; 54 private WriteTextFilePreprocessor writeTextFilePreprocessor; 55 private WriteTextFilePreprocessor writeRcsDiffFilePreprocessor; 56 57 private GlobalOptions globalOptions; 58 59 62 public DefaultFileHandler() { 63 setTransmitTextFilePreprocessor(new DefaultTransmitTextFilePreprocessor()); 64 setWriteTextFilePreprocessor(new DefaultWriteTextFilePreprocessor()); 65 setWriteRcsDiffFilePreprocessor(new WriteRcsDiffFilePreprocessor()); 66 } 67 68 71 public TransmitTextFilePreprocessor getTransmitTextFilePreprocessor() { 72 return transmitTextFilePreprocessor; 73 } 74 75 79 public void setTransmitTextFilePreprocessor(TransmitTextFilePreprocessor transmitTextFilePreprocessor) { 80 this.transmitTextFilePreprocessor = transmitTextFilePreprocessor; 81 } 82 83 86 public WriteTextFilePreprocessor getWriteTextFilePreprocessor() { 87 return writeTextFilePreprocessor; 88 } 89 90 93 public void setWriteTextFilePreprocessor(WriteTextFilePreprocessor writeTextFilePreprocessor) { 94 this.writeTextFilePreprocessor = writeTextFilePreprocessor; 95 } 96 97 101 public WriteTextFilePreprocessor getWriteRcsDiffFilePreprocessor() { 102 return writeRcsDiffFilePreprocessor; 103 } 104 105 109 public void setWriteRcsDiffFilePreprocessor(WriteTextFilePreprocessor writeRcsDiffFilePreprocessor) { 110 this.writeRcsDiffFilePreprocessor = writeRcsDiffFilePreprocessor; 111 } 112 113 119 protected String getLengthString(long length) { 120 return String.valueOf(length) + "\n"; } 122 123 protected Reader getProcessedReader(File f) 124 throws IOException { 125 return new FileReader(f); 126 } 127 128 protected InputStream getProcessedInputStream(File file) throws IOException { 129 return new FileInputStream(file); 130 } 131 132 138 public Request[] getInitialisationRequests() { 139 return null; 140 } 141 142 149 public void transmitTextFile(File file, LoggedDataOutputStream dos) 150 throws IOException { 151 if (file == null || !file.exists()) { 152 throw new IllegalArgumentException ("File is either null or " + 153 "does not exist. Cannot transmit."); 154 } 155 156 File fileToSend = file; 157 158 final TransmitTextFilePreprocessor transmitTextFilePreprocessor = 159 getTransmitTextFilePreprocessor(); 160 161 if (transmitTextFilePreprocessor != null) { 162 fileToSend = transmitTextFilePreprocessor.getPreprocessedTextFile(file); 163 } 164 165 BufferedInputStream bis = null; 166 try { 167 long length = fileToSend.length(); 169 dos.writeBytes(getLengthString(length), "US-ASCII"); 170 171 bis = new BufferedInputStream(new FileInputStream(fileToSend)); 172 byte[] chunk = new byte[CHUNK_SIZE]; 174 while (length > 0) { 175 int bytesToRead = (length >= CHUNK_SIZE) ? CHUNK_SIZE 176 : (int)length; 177 int count = bis.read(chunk, 0, bytesToRead); 178 if (count == -1) { 179 throw new IOException("Unexpected end of stream from "+fileToSend+"."); 180 } 181 length -= count; 182 dos.write(chunk, 0, count); 183 } 184 dos.flush(); 185 } 186 finally { 187 if (bis != null) { 188 try { 189 bis.close(); 190 } 191 catch (IOException ex) { 192 } 194 } 195 if (transmitTextFilePreprocessor != null) { 196 transmitTextFilePreprocessor.cleanup(fileToSend); 197 } 198 } 199 } 200 201 207 public void transmitBinaryFile(File file, LoggedDataOutputStream dos) 208 throws IOException { 209 if (file == null || !file.exists()) { 210 throw new IllegalArgumentException ("File is either null or " + 211 "does not exist. Cannot transmit."); 212 } 213 214 BufferedInputStream bis = null; 215 216 try { 217 bis = new BufferedInputStream(new FileInputStream(file)); 218 long length = file.length(); 220 221 dos.writeBytes(getLengthString(length), "US-ASCII"); 222 223 byte[] chunk = new byte[CHUNK_SIZE]; 225 while (length > 0) { 226 int bytesToRead = (length >= CHUNK_SIZE) ? CHUNK_SIZE 227 : (int)length; 228 int count = bis.read(chunk, 0, bytesToRead); 229 if (count == -1) { 230 throw new IOException("Unexpected end of stream from "+file+"."); 231 } 232 length -= count; 233 dos.write(chunk, 0, count); 234 } 235 dos.flush(); 236 } 237 finally { 238 if (bis != null) { 239 try { 240 bis.close(); 241 } 242 catch (IOException ex) { 243 ex.printStackTrace(); 244 } 245 } 246 } 247 } 248 249 257 public void writeTextFile(String path, String mode, 258 LoggedDataInputStream dis, int length) 259 throws IOException { 260 writeAndPostProcessTextFile(path, mode, dis, length, 261 getWriteTextFilePreprocessor()); 262 } 263 264 273 public void writeRcsDiffFile(String path, String mode, LoggedDataInputStream dis, 274 int length) throws IOException { 275 writeAndPostProcessTextFile(path, mode, dis, length, 276 getWriteRcsDiffFilePreprocessor()); 277 } 278 279 283 private void writeAndPostProcessTextFile(String path, String mode, LoggedDataInputStream dis, 284 int length, WriteTextFilePreprocessor processor) throws IOException { 285 if (DEBUG) { 286 System.err.println("[writeTextFile] writing: " + path); System.err.println("[writeTextFile] length: " + length); System.err.println("Reader object is: " + dis.hashCode()); } 290 291 File file = new File(path); 292 293 boolean readOnly = resetReadOnly(file); 294 295 createNewFile(file); 296 File tempFile = File.createTempFile("cvsCRLF", "tmp"); 303 try { 304 OutputStream os = null; 305 try { 306 os = new BufferedOutputStream(new FileOutputStream(tempFile)); 307 byte[] chunk = new byte[CHUNK_SIZE]; 308 while (length > 0) { 309 int count = (length >= CHUNK_SIZE) ? CHUNK_SIZE 310 :length; 311 count = dis.read(chunk, 0, count); 312 if (count == -1) { 313 throw new IOException("Unexpected end of stream: " + path + "\nMissing " + length + " bytes. Probably network communication failure.\nPlease try again."); } 315 length -= count; 316 if (DEBUG) { 317 System.err.println("Still got: " + length + " to read"); } 319 os.write(chunk, 0, count); 320 } 321 } 322 finally { 323 if (os != null) { 324 try { 325 os.close(); 326 } 327 catch (IOException ex) { 328 } 330 } 331 } 332 333 InputStream tempInput = getProcessedInputStream(tempFile); 337 338 try { 339 processor.copyTextFileToLocation(tempInput, file, new StreamProvider(file)); 341 } finally { 342 tempInput.close(); 343 } 344 345 if (modifiedDate != null) { 346 file.setLastModified(modifiedDate.getTime()); 347 modifiedDate = null; 348 } 349 } 350 finally { 351 tempFile.delete(); 352 } 353 354 if (readOnly) { 355 FileUtils.setFileReadOnly(file, true); 356 } 357 } 358 359 367 public void writeBinaryFile(String path, String mode, 368 LoggedDataInputStream dis, int length) 369 throws IOException { 370 if (DEBUG) { 371 System.err.println("[writeBinaryFile] writing: " + path); System.err.println("[writeBinaryFile] length: " + length); System.err.println("Reader object is: " + dis.hashCode()); } 375 376 File file = new File(path); 377 378 boolean readOnly = resetReadOnly(file); 379 380 createNewFile(file); 381 File cvsDir = new File(file.getParentFile(), "CVS"); 385 cvsDir.mkdir(); 386 File tempFile = File.createTempFile("cvsPostConversion", "tmp", cvsDir); 388 try { 389 BufferedOutputStream bos = 390 new BufferedOutputStream(new FileOutputStream(tempFile)); 391 392 byte[] chunk = new byte[CHUNK_SIZE]; 393 try { 394 while (length > 0) { 395 int bytesToRead = (length >= CHUNK_SIZE) ? CHUNK_SIZE 396 : (int)length; 397 int count = dis.read(chunk, 0, bytesToRead); 398 if (count == -1) { 399 throw new IOException("Unexpected end of stream: " + path + "\nMissing " + length + " bytes. Probably network communication failure.\nPlease try again."); } 401 if (count < 0) { 402 break; 403 } 404 405 length -= count; 406 if (DEBUG) { 407 System.err.println("Still got: " + length + " to read"); } 409 bos.write(chunk, 0, count); 410 } 411 } finally { 412 bos.close(); 413 } 414 415 BufferedInputStream tempIS = 418 new BufferedInputStream(getProcessedInputStream(tempFile)); 419 bos = new BufferedOutputStream(createOutputStream(file)); 420 421 try { 422 for (int count = tempIS.read(chunk, 0, CHUNK_SIZE); 423 count > 0; 424 count = tempIS.read(chunk, 0, CHUNK_SIZE)) { 425 bos.write(chunk, 0, count); 426 } 427 } finally { 428 bos.close(); 429 tempIS.close(); 430 } 431 432 if (modifiedDate != null) { 434 file.setLastModified(modifiedDate.getTime()); 435 modifiedDate = null; 436 } 437 } 438 finally { 439 tempFile.delete(); 440 } 441 442 if (readOnly) { 443 FileUtils.setFileReadOnly(file, true); 444 } 445 } 446 447 448 protected boolean createNewFile(File file) throws IOException { 449 file.getParentFile().mkdirs(); 450 return file.createNewFile(); 451 } 452 453 457 protected OutputStream createOutputStream(File file) throws IOException { 458 return new FileOutputStream(file); 459 } 460 461 private class StreamProvider implements OutputStreamProvider { 462 private final File file; 463 464 public StreamProvider(File file) { 465 this.file = file; 466 } 467 468 public OutputStream createOutputStream() throws IOException { 469 return DefaultFileHandler.this.createOutputStream(file); 470 } 471 } 472 473 private boolean resetReadOnly(File file) throws java.io.IOException { 474 boolean readOnly = globalOptions != null && globalOptions.isCheckedOutFilesReadOnly(); 475 if (file.exists() && readOnly) { 476 readOnly = !file.canWrite(); 477 if (readOnly) { 478 FileUtils.setFileReadOnly(file, false); 479 } 480 } 481 482 return readOnly; 483 } 484 485 491 public void removeLocalFile(String pathname) 492 throws IOException { 493 File fileToDelete = new File(pathname); 494 if (fileToDelete.exists() && !fileToDelete.delete()) { 495 System.err.println("Could not delete file " + 496 fileToDelete.getAbsolutePath()); 497 } 498 } 499 500 508 public void renameLocalFile(String pathname, String newName) 509 throws IOException { 510 File sourceFile = new File(pathname); 511 File destinationFile = new File(sourceFile.getParentFile(), newName); 512 sourceFile.renameTo(destinationFile); 513 } 514 515 521 public void setNextFileDate(Date modifiedDate) { 522 this.modifiedDate = modifiedDate; 523 } 524 525 529 public void setGlobalOptions(GlobalOptions globalOptions) { 530 BugLog.getInstance().assertNotNull(globalOptions); 531 532 this.globalOptions = globalOptions; 533 transmitTextFilePreprocessor.setTempDir(globalOptions.getTempDir()); 534 } 535 } 536 | Popular Tags |