1abd32a990e145862f22d15316feedced5ad246aachrismair/* 2abd32a990e145862f22d15316feedced5ad246aachrismair * Copyright 2008 the original author or authors. 3334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair * 4abd32a990e145862f22d15316feedced5ad246aachrismair * Licensed under the Apache License, Version 2.0 (the "License"); 5abd32a990e145862f22d15316feedced5ad246aachrismair * you may not use this file except in compliance with the License. 6abd32a990e145862f22d15316feedced5ad246aachrismair * You may obtain a copy of the License at 7334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair * 8abd32a990e145862f22d15316feedced5ad246aachrismair * http://www.apache.org/licenses/LICENSE-2.0 9334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair * 10abd32a990e145862f22d15316feedced5ad246aachrismair * Unless required by applicable law or agreed to in writing, software 11abd32a990e145862f22d15316feedced5ad246aachrismair * distributed under the License is distributed on an "AS IS" BASIS, 12abd32a990e145862f22d15316feedced5ad246aachrismair * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13abd32a990e145862f22d15316feedced5ad246aachrismair * See the License for the specific language governing permissions and 14abd32a990e145862f22d15316feedced5ad246aachrismair * limitations under the License. 15abd32a990e145862f22d15316feedced5ad246aachrismair */ 16334c6ebce811c954bf2a79ba4579589a4a3326bfchrismairpackage org.mockftpserver.fake.filesystem; 17334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair 185e9566a04364b1cad5c33001a37d4638bc8a93e6chrismairimport java.io.ByteArrayInputStream; 195e9566a04364b1cad5c33001a37d4638bc8a93e6chrismairimport java.io.ByteArrayOutputStream; 205e9566a04364b1cad5c33001a37d4638bc8a93e6chrismairimport java.io.IOException; 215e9566a04364b1cad5c33001a37d4638bc8a93e6chrismairimport java.io.InputStream; 225e9566a04364b1cad5c33001a37d4638bc8a93e6chrismairimport java.io.OutputStream; 23abd32a990e145862f22d15316feedced5ad246aachrismair 24abd32a990e145862f22d15316feedced5ad246aachrismair/** 25abd32a990e145862f22d15316feedced5ad246aachrismair * File system entry representing a file 2681c5294b43234e26add70ffd5bfb8fbc31db45c9chrismair * 27abd32a990e145862f22d15316feedced5ad246aachrismair * @author Chris Mair 282a0a3f946dba517a01cc26278f905156857c9c91chrismair * @version $Revision$ - $Date$ 29abd32a990e145862f22d15316feedced5ad246aachrismair */ 30abd32a990e145862f22d15316feedced5ad246aachrismairpublic class FileEntry extends AbstractFileSystemEntry { 31abd32a990e145862f22d15316feedced5ad246aachrismair 32334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair private static final byte[] EMPTY = new byte[0]; 3381c5294b43234e26add70ffd5bfb8fbc31db45c9chrismair 34334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair private byte[] bytes = EMPTY; 35334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair private ByteArrayOutputStream out; 3681c5294b43234e26add70ffd5bfb8fbc31db45c9chrismair 37abd32a990e145862f22d15316feedced5ad246aachrismair /** 38334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair * Construct a new instance without setting its path 39abd32a990e145862f22d15316feedced5ad246aachrismair */ 40334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair public FileEntry() { 41abd32a990e145862f22d15316feedced5ad246aachrismair } 42abd32a990e145862f22d15316feedced5ad246aachrismair 43abd32a990e145862f22d15316feedced5ad246aachrismair /** 44334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair * Construct a new instance with the specified value for its path 45334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair * 46abd32a990e145862f22d15316feedced5ad246aachrismair * @param path - the value for path 47abd32a990e145862f22d15316feedced5ad246aachrismair */ 48334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair public FileEntry(String path) { 49334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair super(path); 50abd32a990e145862f22d15316feedced5ad246aachrismair } 51abd32a990e145862f22d15316feedced5ad246aachrismair 52abd32a990e145862f22d15316feedced5ad246aachrismair /** 53334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair * Construct a new instance with the specified path and file contents 54334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair * 55334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair * @param path - the value for path 56abd32a990e145862f22d15316feedced5ad246aachrismair * @param contents - the contents of the file, as a String 57abd32a990e145862f22d15316feedced5ad246aachrismair */ 58334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair public FileEntry(String path, String contents) { 59334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair super(path); 60334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair setContents(contents); 61abd32a990e145862f22d15316feedced5ad246aachrismair } 62abd32a990e145862f22d15316feedced5ad246aachrismair 63abd32a990e145862f22d15316feedced5ad246aachrismair /** 64ef1713518991f8db0e129928853890a6508eade9chrismair * Return false to indicate that this entry represents a file 65334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair * 66ef1713518991f8db0e129928853890a6508eade9chrismair * @return false 67abd32a990e145862f22d15316feedced5ad246aachrismair */ 68334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair public boolean isDirectory() { 69334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair return false; 70abd32a990e145862f22d15316feedced5ad246aachrismair } 7181c5294b43234e26add70ffd5bfb8fbc31db45c9chrismair 72abd32a990e145862f22d15316feedced5ad246aachrismair /** 73abd32a990e145862f22d15316feedced5ad246aachrismair * Return the size of this file 74334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair * 75abd32a990e145862f22d15316feedced5ad246aachrismair * @return the file size in bytes 76abd32a990e145862f22d15316feedced5ad246aachrismair */ 77334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair public long getSize() { 78334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair return getCurrentBytes().length; 79abd32a990e145862f22d15316feedced5ad246aachrismair } 8081c5294b43234e26add70ffd5bfb8fbc31db45c9chrismair 81abd32a990e145862f22d15316feedced5ad246aachrismair /** 82abd32a990e145862f22d15316feedced5ad246aachrismair * Set the contents of the file represented by this entry 83334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair * 84abd32a990e145862f22d15316feedced5ad246aachrismair * @param contents - the String whose bytes are used as the contents 85abd32a990e145862f22d15316feedced5ad246aachrismair */ 86334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair public void setContents(String contents) { 87334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair byte[] newBytes = (contents != null) ? contents.getBytes() : EMPTY; 88334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair setContentsInternal(newBytes); 89abd32a990e145862f22d15316feedced5ad246aachrismair } 9081c5294b43234e26add70ffd5bfb8fbc31db45c9chrismair 91abd32a990e145862f22d15316feedced5ad246aachrismair /** 92abd32a990e145862f22d15316feedced5ad246aachrismair * Set the contents of the file represented by this entry 93334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair * 94abd32a990e145862f22d15316feedced5ad246aachrismair * @param contents - the byte[] used as the contents 95abd32a990e145862f22d15316feedced5ad246aachrismair */ 96334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair public void setContents(byte[] contents) { 97abd32a990e145862f22d15316feedced5ad246aachrismair // Copy the bytes[] to guard against subsequent modification of the source array 983b10a12a6bf22b061eb0861469fbb5fd212de1bcchrismair byte[] newBytes = EMPTY; 993b10a12a6bf22b061eb0861469fbb5fd212de1bcchrismair if (contents != null) { 1003b10a12a6bf22b061eb0861469fbb5fd212de1bcchrismair newBytes = new byte[contents.length]; 1013b10a12a6bf22b061eb0861469fbb5fd212de1bcchrismair System.arraycopy(contents, 0, newBytes, 0, contents.length); 1023b10a12a6bf22b061eb0861469fbb5fd212de1bcchrismair } 103334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair setContentsInternal(newBytes); 104abd32a990e145862f22d15316feedced5ad246aachrismair } 10581c5294b43234e26add70ffd5bfb8fbc31db45c9chrismair 106abd32a990e145862f22d15316feedced5ad246aachrismair /** 107abd32a990e145862f22d15316feedced5ad246aachrismair * Create and return an InputStream for reading the contents of the file represented by this entry 108334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair * 109abd32a990e145862f22d15316feedced5ad246aachrismair * @return an InputStream 110abd32a990e145862f22d15316feedced5ad246aachrismair */ 111334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair public InputStream createInputStream() { 112334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair return new ByteArrayInputStream(getCurrentBytes()); 113abd32a990e145862f22d15316feedced5ad246aachrismair } 114abd32a990e145862f22d15316feedced5ad246aachrismair 115abd32a990e145862f22d15316feedced5ad246aachrismair /** 116abd32a990e145862f22d15316feedced5ad246aachrismair * Create and return an OutputStream for writing the contents of the file represented by this entry 117334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair * 118334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair * @param append - true if the OutputStream should append to any existing contents false if 119334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair * any existing contents should be overwritten 120abd32a990e145862f22d15316feedced5ad246aachrismair * @return an OutputStream 121abd32a990e145862f22d15316feedced5ad246aachrismair * @throws FileSystemException - if an error occurs creating or initializing the OutputStream 122abd32a990e145862f22d15316feedced5ad246aachrismair */ 123334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair public OutputStream createOutputStream(boolean append) { 124abd32a990e145862f22d15316feedced5ad246aachrismair // If appending and we already have an OutputStream, then continue to use it 125abd32a990e145862f22d15316feedced5ad246aachrismair if (append && out != null) { 126334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair return out; 127abd32a990e145862f22d15316feedced5ad246aachrismair } 12881c5294b43234e26add70ffd5bfb8fbc31db45c9chrismair 129334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair out = new ByteArrayOutputStream(); 130334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair byte[] initialContents = (append) ? bytes : EMPTY; 131abd32a990e145862f22d15316feedced5ad246aachrismair try { 132334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair out.write(initialContents); 133abd32a990e145862f22d15316feedced5ad246aachrismair } 134abd32a990e145862f22d15316feedced5ad246aachrismair catch (IOException e) { 135334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair throw new FileSystemException(getPath(), null, e); 136abd32a990e145862f22d15316feedced5ad246aachrismair } 137334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair return out; 138abd32a990e145862f22d15316feedced5ad246aachrismair } 139abd32a990e145862f22d15316feedced5ad246aachrismair 14009415075d96852489d096aea7ae07dd156b58643chrismair /** 14109415075d96852489d096aea7ae07dd156b58643chrismair * Return a new FileSystemEntry that is a clone of this object, except having the specified path 142334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair * 14309415075d96852489d096aea7ae07dd156b58643chrismair * @param path - the new path value for the cloned file system entry 14409415075d96852489d096aea7ae07dd156b58643chrismair * @return a new FileSystemEntry that has all the same values as this object except for its path 14509415075d96852489d096aea7ae07dd156b58643chrismair */ 146334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair public FileSystemEntry cloneWithNewPath(String path) { 147334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair FileEntry clone = new FileEntry(path); 148334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair clone.setLastModified(getLastModified()); 149334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair clone.setOwner(getOwner()); 150334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair clone.setGroup(getGroup()); 151334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair clone.setPermissions(getPermissions()); 152a5c19061b721f203631e1969bf38127301e29414chrismair clone.setContents(getCurrentBytes()); 153334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair return clone; 15409415075d96852489d096aea7ae07dd156b58643chrismair } 15509415075d96852489d096aea7ae07dd156b58643chrismair 156abd32a990e145862f22d15316feedced5ad246aachrismair //------------------------------------------------------------------------- 157abd32a990e145862f22d15316feedced5ad246aachrismair // Internal Helper Methods 158abd32a990e145862f22d15316feedced5ad246aachrismair //------------------------------------------------------------------------- 15981c5294b43234e26add70ffd5bfb8fbc31db45c9chrismair 160abd32a990e145862f22d15316feedced5ad246aachrismair /** 161abd32a990e145862f22d15316feedced5ad246aachrismair * @return the current contents of this file entry as a byte[] 162abd32a990e145862f22d15316feedced5ad246aachrismair */ 163abd32a990e145862f22d15316feedced5ad246aachrismair private byte[] getCurrentBytes() { 164334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair return (out != null) ? out.toByteArray() : bytes; 165abd32a990e145862f22d15316feedced5ad246aachrismair } 16681c5294b43234e26add70ffd5bfb8fbc31db45c9chrismair 167abd32a990e145862f22d15316feedced5ad246aachrismair /** 168abd32a990e145862f22d15316feedced5ad246aachrismair * Set the contents of the file represented by this entry 169334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair * 170abd32a990e145862f22d15316feedced5ad246aachrismair * @param contents - the byte[] used as the contents 171abd32a990e145862f22d15316feedced5ad246aachrismair */ 172abd32a990e145862f22d15316feedced5ad246aachrismair private void setContentsInternal(byte[] contents) { 173334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair this.bytes = contents; 17481c5294b43234e26add70ffd5bfb8fbc31db45c9chrismair 175abd32a990e145862f22d15316feedced5ad246aachrismair // Get rid of any OutputStream 176334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair this.out = null; 177abd32a990e145862f22d15316feedced5ad246aachrismair } 17881c5294b43234e26add70ffd5bfb8fbc31db45c9chrismair 1798c7679f897c9a2e018a225fd3080f1b038ddeeacchrismair /** 1808c7679f897c9a2e018a225fd3080f1b038ddeeacchrismair * @see java.lang.Object#toString() 1818c7679f897c9a2e018a225fd3080f1b038ddeeacchrismair */ 182334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair public String toString() { 183334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair return "File['" + getPath() + "' size=" + getSize() + " lastModified=" + getLastModified() + " owner=" 184334c6ebce811c954bf2a79ba4579589a4a3326bfchrismair + getOwner() + " group=" + getGroup() + " permissions=" + getPermissions() + "]"; 1858c7679f897c9a2e018a225fd3080f1b038ddeeacchrismair } 18681c5294b43234e26add70ffd5bfb8fbc31db45c9chrismair 187abd32a990e145862f22d15316feedced5ad246aachrismair} 188