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