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