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