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