1/* 2 * Copyright 2007 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.stub.command; 17 18import java.io.IOException; 19import java.io.InputStream; 20 21 22import org.apache.log4j.Logger; 23import org.mockftpserver.core.MockFtpServerException; 24import org.mockftpserver.core.command.Command; 25import org.mockftpserver.core.command.CommandHandler; 26import org.mockftpserver.core.command.InvocationRecord; 27import org.mockftpserver.core.session.Session; 28import org.mockftpserver.core.util.Assert; 29import org.mockftpserver.core.util.AssertFailedException; 30 31/** 32 * CommandHandler for the RETR command. Returns the contents of the specified file on the 33 * data connection, along with two replies on the control connection: a reply code of 150 and 34 * another of 226. 35 * <p> 36 * The <code>file</code> property specifies the pathname for the file whose contents should 37 * be returned from this command. The file path is relative to the CLASSPATH (using the 38 * ClassLoader for this class). 39 * <p> 40 * An exception is thrown if the <code>file</code> property has not been set or if the specified 41 * file does not exist or cannot be read. 42 * <p> 43 * Each invocation record stored by this CommandHandler includes the following data element key/values: 44 * <ul> 45 * <li>{@link #PATHNAME_KEY} ("pathname") - the pathname of the file submitted on the invocation (the first command parameter) 46 * </ul> 47 * 48 * @version $Revision$ - $Date$ 49 * 50 * @author Chris Mair 51 */ 52public final class FileRetrCommandHandler extends AbstractStubDataCommandHandler implements CommandHandler { 53 54 public static final String PATHNAME_KEY = "pathname"; 55 static final int BUFFER_SIZE = 512; // package-private for testing 56 private static final Logger LOG = Logger.getLogger(FileRetrCommandHandler.class); 57 58 private String file; 59 60 /** 61 * Create new uninitialized instance 62 */ 63 public FileRetrCommandHandler() { 64 } 65 66 /** 67 * Create new instance using the specified file pathname 68 * @param file - the path to the file 69 * @throws AssertFailedException - if the file is null 70 */ 71 public FileRetrCommandHandler(String file) { 72 setFile(file); 73 } 74 75 /** 76 * @see org.mockftpserver.stub.command.AbstractStubDataCommandHandler#beforeProcessData(org.mockftpserver.core.command.Command, org.mockftpserver.core.session.Session, org.mockftpserver.core.command.InvocationRecord) 77 */ 78 protected void beforeProcessData(Command command, Session session, InvocationRecord invocationRecord) throws Exception { 79 Assert.notNull(file, "file"); 80 invocationRecord.set(PATHNAME_KEY, command.getRequiredString(0)); 81 } 82 83 /** 84 * @see org.mockftpserver.stub.command.AbstractStubDataCommandHandler#processData(org.mockftpserver.core.command.Command, org.mockftpserver.core.session.Session, org.mockftpserver.core.command.InvocationRecord) 85 */ 86 protected void processData(Command command, Session session, InvocationRecord invocationRecord) { 87 InputStream inputStream = getClass().getClassLoader().getResourceAsStream(file); 88 Assert.notNull(inputStream, "InputStream for [" + file + "]"); 89 byte[] buffer = new byte[BUFFER_SIZE]; 90 try { 91 int numBytes = 0; 92 while ((numBytes = inputStream.read(buffer)) != -1) { 93 LOG.trace("Sending " + numBytes + " bytes..."); 94 session.sendData(buffer, numBytes); 95 } 96 } 97 catch(IOException e) { 98 throw new MockFtpServerException(e); 99 } 100 } 101 102 /** 103 * Set the path of the file whose contents should be returned when this command is 104 * invoked. The path is relative to the CLASSPATH. 105 * @param file - the path to the file 106 * @throws AssertFailedException - if the file is null 107 */ 108 public void setFile(String file) { 109 Assert.notNull(file, "file"); 110 this.file = file; 111 } 112 113} 114