FileEntry.java revision 848932d9e7c6953b3c345c9aa6b0b6c3cfe20d79
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.*; 19 20/** 21 * File system entry representing a file 22 * 23 * @author Chris Mair 24 * @version $Revision$ - $Date$ 25 */ 26public class FileEntry extends AbstractFileSystemEntry { 27 28 private static final byte[] EMPTY = new byte[0]; 29 30 private byte[] bytes = EMPTY; 31 //private Object bytes = EMPTY; 32 private ByteArrayOutputStream out; 33 34 /** 35 * Construct a new instance without setting its path 36 */ 37 public FileEntry() { 38 } 39 40 /** 41 * Construct a new instance with the specified value for its path 42 * 43 * @param path - the value for path 44 */ 45 public FileEntry(String path) { 46 super(path); 47 } 48 49 /** 50 * Construct a new instance with the specified path and file contents 51 * 52 * @param path - the value for path 53 * @param contents - the contents of the file, as a String 54 */ 55 public FileEntry(String path, String contents) { 56 super(path); 57 setContents(contents); 58 } 59 60 /** 61 * Abstract method -- must be implemented within concrete subclasses 62 * 63 * @return true if this file system entry represents a directory 64 */ 65 public boolean isDirectory() { 66 return false; 67 } 68 69 /** 70 * Return the size of this file 71 * 72 * @return the file size in bytes 73 */ 74 public long getSize() { 75 return getCurrentBytes().length; 76 } 77 78 /** 79 * Set the contents of the file represented by this entry 80 * 81 * @param contents - the String whose bytes are used as the contents 82 */ 83 public void setContents(String contents) { 84 byte[] newBytes = (contents != null) ? contents.getBytes() : EMPTY; 85 setContentsInternal(newBytes); 86 } 87 88 /** 89 * Set the contents of the file represented by this entry 90 * 91 * @param contents - the byte[] used as the contents 92 */ 93 public void setContents(byte[] contents) { 94 // Copy the bytes[] to guard against subsequent modification of the source array 95 byte[] newBytes = (contents != null) ? new String(contents).getBytes() : EMPTY; 96 setContentsInternal(newBytes); 97 } 98 99 /** 100 * Create and return an InputStream for reading the contents of the file represented by this entry 101 * 102 * @return an InputStream 103 */ 104 public InputStream createInputStream() { 105 return new ByteArrayInputStream(getCurrentBytes()); 106 } 107 108 /** 109 * Create and return an OutputStream for writing the contents of the file represented by this entry 110 * 111 * @param append - true if the OutputStream should append to any existing contents false if 112 * any existing contents should be overwritten 113 * @return an OutputStream 114 * @throws FileSystemException - if an error occurs creating or initializing the OutputStream 115 */ 116 public OutputStream createOutputStream(boolean append) { 117 // If appending and we already have an OutputStream, then continue to use it 118 if (append && out != null) { 119 return out; 120 } 121 122 out = new ByteArrayOutputStream(); 123 byte[] initialContents = (append) ? bytes : EMPTY; 124 try { 125 out.write(initialContents); 126 } 127 catch (IOException e) { 128 throw new FileSystemException(getPath(), null, e); 129 } 130 return out; 131 } 132 133 /** 134 * Return a new FileSystemEntry that is a clone of this object, except having the specified path 135 * 136 * @param path - the new path value for the cloned file system entry 137 * @return a new FileSystemEntry that has all the same values as this object except for its path 138 */ 139 public FileSystemEntry cloneWithNewPath(String path) { 140 FileEntry clone = new FileEntry(path); 141 clone.setLastModified(getLastModified()); 142 clone.setOwner(getOwner()); 143 clone.setGroup(getGroup()); 144 clone.setPermissions(getPermissions()); 145 clone.setContents(bytes); 146 return clone; 147 } 148 149 //------------------------------------------------------------------------- 150 // Internal Helper Methods 151 //------------------------------------------------------------------------- 152 153 /** 154 * @return the current contents of this file entry as a byte[] 155 */ 156 private byte[] getCurrentBytes() { 157 return (out != null) ? out.toByteArray() : bytes; 158 } 159 160 /** 161 * Set the contents of the file represented by this entry 162 * 163 * @param contents - the byte[] used as the contents 164 */ 165 private void setContentsInternal(byte[] contents) { 166 this.bytes = contents; 167 168 // Get rid of any OutputStream 169 this.out = null; 170 } 171 172 /** 173 * @see java.lang.Object#toString() 174 */ 175 public String toString() { 176 return "File['" + getPath() + "' size=" + getSize() + " lastModified=" + getLastModified() + " owner=" 177 + getOwner() + " group=" + getGroup() + " permissions=" + getPermissions() + "]"; 178 } 179 180} 181