| package org.netbeans.lib.cvsclient.file; |
| |
| import com.intellij.openapi.util.io.FileUtil; |
| import org.jetbrains.annotations.NonNls; |
| import org.netbeans.lib.cvsclient.SmartCvsSrcBundle; |
| import org.netbeans.lib.cvsclient.util.BugLog; |
| |
| import java.io.*; |
| import java.nio.charset.Charset; |
| import java.util.Date; |
| |
| /** |
| * @author Thomas Singer |
| */ |
| public final class LocalFileWriter implements ILocalFileWriter { |
| |
| // Constants ============================================================== |
| |
| private static final int BUFFER_SIZE = 128 * 1024; |
| |
| // Fields ================================================================= |
| |
| private final IReceiveTextFilePreprocessor receiveTextFilePreprocessor; |
| |
| private Date modifiedDate; |
| private String nextFileMode; |
| @NonNls private static final String RECEIVING_TMP_FILE_NAME = "receiving"; |
| |
| // Setup ================================================================== |
| |
| public LocalFileWriter(IReceiveTextFilePreprocessor receiveTextFilePreprocessor) { |
| BugLog.getInstance().assertNotNull(receiveTextFilePreprocessor); |
| |
| this.receiveTextFilePreprocessor = receiveTextFilePreprocessor; |
| } |
| |
| // Implemented ============================================================ |
| |
| public void writeTextFile(FileObject fileObject, |
| int length, |
| InputStream inputStream, |
| boolean readOnly, |
| IReaderFactory readerFactory, |
| IFileReadOnlyHandler fileReadOnlyHandler, |
| IFileSystem fileSystem, |
| final Charset charSet) throws IOException { |
| final File localFile = fileSystem.getFile(fileObject); |
| localFile.getParentFile().mkdirs(); |
| if (localFile.exists()) { |
| deleteFile(localFile, fileReadOnlyHandler); |
| } |
| else { |
| FileUtil.createIfDoesntExist(localFile); |
| } |
| |
| receiveTextFilePreprocessor.copyTextFileToLocation(inputStream, length, localFile, readerFactory, charSet); |
| setModifiedDateAndMode(localFile, fileReadOnlyHandler); |
| fileReadOnlyHandler.setFileReadOnly(localFile, readOnly); |
| } |
| |
| public void writeBinaryFile(FileObject fileObject, |
| int length, |
| InputStream inputStream, |
| boolean readOnly, |
| IFileReadOnlyHandler fileReadOnlyHandler, |
| ICvsFileSystem cvsFileSystem) throws IOException { |
| final File localFile = cvsFileSystem.getLocalFileSystem().getFile(fileObject); |
| localFile.getParentFile().mkdirs(); |
| |
| deleteFile(localFile, fileReadOnlyHandler); |
| |
| writeFile(localFile, length, inputStream); |
| setModifiedDateAndMode(localFile, fileReadOnlyHandler); |
| |
| fileReadOnlyHandler.setFileReadOnly(localFile, readOnly); |
| } |
| |
| public void removeLocalFile(FileObject fileObject, ICvsFileSystem cvsFileSystem, IFileReadOnlyHandler fileReadOnlyHandler) |
| throws IOException { |
| final File file = cvsFileSystem.getLocalFileSystem().getFile(fileObject); |
| deleteFile(file, fileReadOnlyHandler); |
| } |
| |
| public void renameLocalFile(FileObject fileObject, ICvsFileSystem cvsFileSystem, String newFileName) { |
| final File originalFile = cvsFileSystem.getLocalFileSystem().getFile(fileObject); |
| final File targetFile = new File(originalFile.getParentFile(), newFileName); |
| try { |
| FileUtil.rename(originalFile, targetFile); |
| } |
| catch (IOException e) { |
| //ignore |
| } |
| } |
| |
| /** |
| * Set the modified date of the next file to be written. |
| * The next call to writeFile will use this date. |
| * |
| * @param modifiedDate the date the file should be marked as modified |
| */ |
| public void setNextFileDate(Date modifiedDate) { |
| this.modifiedDate = modifiedDate; |
| } |
| |
| public void setNextFileMode(String nextFileMode) { |
| this.nextFileMode = nextFileMode; |
| } |
| |
| // Utils ================================================================== |
| |
| private static void deleteFile(File file, IFileReadOnlyHandler fileReadOnlyHandler) throws IOException { |
| if (!file.exists()) { |
| return; |
| } |
| |
| if (!file.canWrite()) { |
| fileReadOnlyHandler.setFileReadOnly(file, false); |
| } |
| if (!file.delete()) { |
| throw new IOException(SmartCvsSrcBundle.message("could.not.delete.file.error.message", file)); |
| } |
| } |
| |
| private static void writeFile(File file, int length, InputStream inputStream) throws IOException { |
| if (length == 0) { |
| FileUtil.createIfDoesntExist(file); |
| return; |
| } |
| |
| final OutputStream fileOutputStream = new FileOutputStream(file); |
| try { |
| final byte[] chunk = new byte[BUFFER_SIZE]; |
| int size = length; |
| while (size > 0) { |
| final int bytesToRead = Math.min(size, chunk.length); |
| final int bytesRead = inputStream.read(chunk, 0, bytesToRead); |
| if (bytesRead < 0) { |
| break; |
| } |
| |
| size -= bytesRead; |
| fileOutputStream.write(chunk, 0, bytesRead); |
| } |
| } |
| finally { |
| try { |
| fileOutputStream.close(); |
| } |
| catch (IOException ex) { |
| // ignore |
| } |
| } |
| } |
| |
| private void setModifiedDateAndMode(File localFile, IFileReadOnlyHandler readOnlyHandler) throws IOException { |
| if (modifiedDate != null) { |
| localFile.setLastModified(modifiedDate.getTime()); |
| modifiedDate = null; |
| } |
| |
| if (nextFileMode != null) { |
| readOnlyHandler.setFileReadOnly(localFile, FileUtils.isReadOnlyMode(nextFileMode)); |
| nextFileMode = null; |
| } |
| } |
| } |