FileEntry.java revision bda3441225e0607b5ced8b538123fd7c7a417910
1/* 2 * Copyright 2008 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package org.mockftpserver.fake.filesystem; 17 18import java.io.ByteArrayInputStream; 19import java.io.ByteArrayOutputStream; 20import java.io.IOException; 21import java.io.InputStream; 22import java.io.OutputStream; 23 24/** 25 * File system entry representing a file 26 * 27 * @author Chris Mair 28 * @version $Revision$ - $Date$ 29 */ 30public class FileEntry extends AbstractFileSystemEntry { 31 32 private static final byte[] EMPTY = new byte[0]; 33 34 private byte[] bytes = EMPTY; 35 private ByteArrayOutputStream out; 36 37 /** 38 * Construct a new instance without setting its path 39 */ 40 public FileEntry() { 41 } 42 43 /** 44 * Construct a new instance with the specified value for its path 45 * 46 * @param path - the value for path 47 */ 48 public FileEntry(String path) { 49 super(path); 50 } 51 52 /** 53 * Construct a new instance with the specified path and file contents 54 * 55 * @param path - the value for path 56 * @param contents - the contents of the file, as a String 57 */ 58 public FileEntry(String path, String contents) { 59 super(path); 60 setContents(contents); 61 } 62 63 /** 64 * Return false to indicate that this entry represents a file 65 * 66 * @return false 67 */ 68 public boolean isDirectory() { 69 return false; 70 } 71 72 /** 73 * Return the size of this file 74 * 75 * @return the file size in bytes 76 */ 77 public long getSize() { 78 return getCurrentBytes().length; 79 } 80 81 /** 82 * Set the contents of the file represented by this entry 83 * 84 * @param contents - the String whose bytes are used as the contents 85 */ 86 public void setContents(String contents) { 87 byte[] newBytes = (contents != null) ? contents.getBytes() : EMPTY; 88 setContentsInternal(newBytes); 89 } 90 91 /** 92 * Set the contents of the file represented by this entry 93 * 94 * @param contents - the byte[] used as the contents 95 */ 96 public void setContents(byte[] contents) { 97 // Copy the bytes[] to guard against subsequent modification of the source array 98 byte[] newBytes = EMPTY; 99 if (contents != null) { 100 newBytes = new byte[contents.length]; 101 System.arraycopy(contents, 0, newBytes, 0, contents.length); 102 } 103 setContentsInternal(newBytes); 104 } 105 106 /** 107 * Create and return an InputStream for reading the contents of the file represented by this entry 108 * 109 * @return an InputStream 110 */ 111 public InputStream createInputStream() { 112 return new ByteArrayInputStream(getCurrentBytes()); 113 } 114 115 /** 116 * Create and return an OutputStream for writing the contents of the file represented by this entry 117 * 118 * @param append - true if the OutputStream should append to any existing contents false if 119 * any existing contents should be overwritten 120 * @return an OutputStream 121 * @throws FileSystemException - if an error occurs creating or initializing the OutputStream 122 */ 123 public OutputStream createOutputStream(boolean append) { 124 // If appending and we already have an OutputStream, then continue to use it 125 if (append && out != null) { 126 return out; 127 } 128 129 out = new ByteArrayOutputStream(); 130 byte[] initialContents = (append) ? bytes : EMPTY; 131 try { 132 out.write(initialContents); 133 } 134 catch (IOException e) { 135 throw new FileSystemException(getPath(), null, e); 136 } 137 return out; 138 } 139 140 /** 141 * Return a new FileSystemEntry that is a clone of this object, except having the specified path 142 * 143 * @param path - the new path value for the cloned file system entry 144 * @return a new FileSystemEntry that has all the same values as this object except for its path 145 */ 146 public FileSystemEntry cloneWithNewPath(String path) { 147 FileEntry clone = new FileEntry(path); 148 clone.setLastModified(getLastModified()); 149 clone.setOwner(getOwner()); 150 clone.setGroup(getGroup()); 151 clone.setPermissions(getPermissions()); 152 clone.setContents(getCurrentBytes()); 153 return clone; 154 } 155 156 //------------------------------------------------------------------------- 157 // Internal Helper Methods 158 //------------------------------------------------------------------------- 159 160 /** 161 * @return the current contents of this file entry as a byte[] 162 */ 163 private byte[] getCurrentBytes() { 164 return (out != null) ? out.toByteArray() : bytes; 165 } 166 167 /** 168 * Set the contents of the file represented by this entry 169 * 170 * @param contents - the byte[] used as the contents 171 */ 172 private void setContentsInternal(byte[] contents) { 173 this.bytes = contents; 174 175 // Get rid of any OutputStream 176 this.out = null; 177 } 178 179 /** 180 * @see java.lang.Object#toString() 181 */ 182 public String toString() { 183 return "File['" + getPath() + "' size=" + getSize() + " lastModified=" + getLastModified() + " owner=" 184 + getOwner() + " group=" + getGroup() + " permissions=" + getPermissions() + "]"; 185 } 186 187} 188