1b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair/* 2b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * Copyright 2007 the original author or authors. 3b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 4b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * Licensed under the Apache License, Version 2.0 (the "License"); 5b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * you may not use this file except in compliance with the License. 6b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * You may obtain a copy of the License at 7b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 8b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * http://www.apache.org/licenses/LICENSE-2.0 9b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 10b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * Unless required by applicable law or agreed to in writing, software 11b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * distributed under the License is distributed on an "AS IS" BASIS, 12b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * See the License for the specific language governing permissions and 14b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * limitations under the License. 15b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair */ 16b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismairpackage org.mockftpserver.stub.command; 17b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 18b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismairimport org.mockftpserver.core.command.AbstractTrackingCommandHandler; 19b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismairimport org.mockftpserver.core.command.Command; 20b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismairimport org.mockftpserver.core.command.CommandHandler; 21b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismairimport org.mockftpserver.core.command.InvocationRecord; 22b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismairimport org.mockftpserver.core.command.ReplyCodes; 23b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismairimport org.mockftpserver.core.session.Session; 24b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismairimport org.mockftpserver.core.util.AssertFailedException; 25b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 26b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair/** 27b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * Abstract superclass for CommandHandlers that read from or write to the data connection. 28b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <p/> 29b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * Return two replies on the control connection: by default a reply code of 150 before the 30b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * data transfer across the data connection and another reply of 226 after the data transfer 31b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * is complete. 32b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <p/> 33b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * This class implements the <i>Template Method</i> pattern. Subclasses must implement the abstract 34b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <code>processData</code> method to perform read or writes across the data connection. 35b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <p/> 36b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * Subclasses can optionally override the {@link #beforeProcessData(Command, Session, InvocationRecord)} 37b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * method for logic before the data transfer or the {@link #afterProcessData(Command, Session, InvocationRecord)} 38b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * method for logic after the data transfer. 39b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <p/> 40b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * Subclasses can optionally override the reply code and/or text for the initial reply (before 41b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * the data transfer across the data connection) by calling {@link #setPreliminaryReplyCode(int)}, 42b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * {@link #setPreliminaryReplyMessageKey(String)} and/or {@link #setPreliminaryReplyText(String)} 43b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * methods. 44b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <p/> 45b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * Subclasses can optionally override the reply code and/or text for the final reply (after the 46b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * the data transfer is complete) by calling {@link #setFinalReplyCode(int)}, 47b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * {@link #setFinalReplyMessageKey(String)} and/or {@link #setFinalReplyText(String)} methods. 48b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 49b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @author Chris Mair 50b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @version $Revision$ - $Date$ 51b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair */ 52b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismairpublic abstract class AbstractStubDataCommandHandler extends AbstractTrackingCommandHandler implements CommandHandler { 53b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 54b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair // The completion reply code sent before the data transfer 55b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair protected int preliminaryReplyCode = 0; 56b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 57b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair // The text for the preliminary reply. If null, use the default message associated with the reply code. 58b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair // If not null, this value overrides the preliminaryReplyMessageKey - i.e., this text is used instead of 59b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair // a localized message. 60b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair protected String preliminaryReplyText = null; 61b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 62b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair // The message key for the preliminary reply text. If null, use the default message associated with 63b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair // the reply code. 64b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair protected String preliminaryReplyMessageKey = null; 65b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 66b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair // The completion reply code sent after data transfer 67b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair protected int finalReplyCode = 0; 68b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 69b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair // The text for the completion reply. If null, use the default message associated with the reply code. 70b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair // If not null, this value overrides the finalReplyMessageKey - i.e., this text is used instead of 71b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair // a localized message. 72b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair protected String finalReplyText = null; 73b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 74b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair // The message key for the completion reply text. If null, use the default message associated with the reply code 75b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair protected String finalReplyMessageKey = null; 76b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 77b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair /** 78b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * Constructor. Initialize the preliminary and final reply code. 79b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair */ 80b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair protected AbstractStubDataCommandHandler() { 81b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setPreliminaryReplyCode(ReplyCodes.TRANSFER_DATA_INITIAL_OK); 82b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setFinalReplyCode(ReplyCodes.TRANSFER_DATA_FINAL_OK); 83b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair } 84b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 85b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair /** 86b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * Handle the command. Perform the following steps: 87b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <ol> 88b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <li>Invoke the <code>beforeProcessData()</code> method</li> 89b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <li>Open the data connection</li> 90b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <li>Send an preliminary reply, default reply code 150</li> 91b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <li>Invoke the <code>processData()</code> method</li> 92b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <li>Close the data connection</li> 93b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <li>Send the final reply, default reply code 226</li> 94b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <li>Invoke the <code>afterProcessData()</code> method</li> 95b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * </ol> 96b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 97b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @see org.mockftpserver.core.command.AbstractTrackingCommandHandler#handleCommand(org.mockftpserver.core.command.Command, org.mockftpserver.core.session.Session, org.mockftpserver.core.command.InvocationRecord) 98b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair */ 99b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair public final void handleCommand(Command command, Session session, InvocationRecord invocationRecord) throws Exception { 100b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 101b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair beforeProcessData(command, session, invocationRecord); 102b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 103b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair sendPreliminaryReply(session); 104b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair session.openDataConnection(); 105b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair processData(command, session, invocationRecord); 106b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair session.closeDataConnection(); 107b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair sendFinalReply(session); 108b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 109b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair afterProcessData(command, session, invocationRecord); 110b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair } 111b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 112b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair /** 113b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * Send the final reply. The default implementation sends a reply code of 226 with the 114b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * corresponding associated reply text. 115b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 116b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @param session - the Session 117b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair */ 118b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair protected void sendFinalReply(Session session) { 119b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair sendReply(session, finalReplyCode, finalReplyMessageKey, finalReplyText, null); 120b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair } 121b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 122b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair /** 123b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * Perform any necessary logic before transferring data across the data connection. 124b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * Do nothing by default. Subclasses should override to validate command parameters and 125b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * store information in the InvocationRecord. 126b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 127b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @param command - the Command to be handled 128b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @param session - the session on which the Command was submitted 129b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @param invocationRecord - the InvocationRecord; CommandHandlers are expected to add 130b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * handler-specific data to the InvocationRecord, as appropriate 131b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @throws Exception 132b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair */ 133b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair protected void beforeProcessData(Command command, Session session, InvocationRecord invocationRecord) throws Exception { 134b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair // Do nothing by default 135b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair } 136b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 137b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair /** 138b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * Abstract method placeholder for subclass transfer of data across the data connection. 139b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * Subclasses must override. The data connection is opened before this method and is 140b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * closed after this method completes. 141b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 142b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @param command - the Command to be handled 143b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @param session - the session on which the Command was submitted 144b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @param invocationRecord - the InvocationRecord; CommandHandlers are expected to add 145b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * handler-specific data to the InvocationRecord, as appropriate 146b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @throws Exception 147b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair */ 148b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair protected abstract void processData(Command command, Session session, InvocationRecord invocationRecord) throws Exception; 149b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 150b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair /** 151b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * Perform any necessary logic after transferring data across the data connection. 152b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * Do nothing by default. 153b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 154b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @param command - the Command to be handled 155b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @param session - the session on which the Command was submitted 156b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @param invocationRecord - the InvocationRecord; CommandHandlers are expected to add 157b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * handler-specific data to the InvocationRecord, as appropriate 158b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @throws Exception 159b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair */ 160b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair protected void afterProcessData(Command command, Session session, InvocationRecord invocationRecord) throws Exception { 161b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair // Do nothing by default 162b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair } 163b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 164b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair /** 165b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * Send the preliminary reply for this command on the control connection. 166b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 167b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @param session - the Session 168b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair */ 169b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair private void sendPreliminaryReply(Session session) { 170b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair sendReply(session, preliminaryReplyCode, preliminaryReplyMessageKey, preliminaryReplyText, null); 171b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair } 172b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 173b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair /** 174b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * Set the completion reply code sent after data transfer 175b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 176b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @param finalReplyCode - the final reply code 177b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @throws AssertFailedException - if the finalReplyCode is invalid 178b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair */ 179b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair public void setFinalReplyCode(int finalReplyCode) { 180b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair assertValidReplyCode(finalReplyCode); 181b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair this.finalReplyCode = finalReplyCode; 182b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair } 183b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 184b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair /** 185b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * Set the message key for the completion reply text sent after data transfer 186b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 187b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @param finalReplyMessageKey - the final reply message key 188b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair */ 189b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair public void setFinalReplyMessageKey(String finalReplyMessageKey) { 190b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair this.finalReplyMessageKey = finalReplyMessageKey; 191b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair } 192b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 193b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair /** 194b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * Set the text of the completion reply sent after data transfer 195b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 196b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @param finalReplyText - the final reply text 197b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair */ 198b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair public void setFinalReplyText(String finalReplyText) { 199b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair this.finalReplyText = finalReplyText; 200b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair } 201b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 202b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair /** 203b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * Set the completion reply code sent before data transfer 204b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 205b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @param preliminaryReplyCode - the preliminary reply code to set 206b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @throws AssertFailedException - if the preliminaryReplyCode is invalid 207b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair */ 208b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair public void setPreliminaryReplyCode(int preliminaryReplyCode) { 209b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair assertValidReplyCode(preliminaryReplyCode); 210b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair this.preliminaryReplyCode = preliminaryReplyCode; 211b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair } 212b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 213b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair /** 214b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * Set the message key for the completion reply text sent before data transfer 215b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 216b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @param preliminaryReplyMessageKey - the preliminary reply message key 217b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair */ 218b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair public void setPreliminaryReplyMessageKey(String preliminaryReplyMessageKey) { 219b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair this.preliminaryReplyMessageKey = preliminaryReplyMessageKey; 220b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair } 221b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 222b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair /** 223b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * Set the text of the completion reply sent before data transfer 224b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 225b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @param preliminaryReplyText - the preliminary reply text 226b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair */ 227b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair public void setPreliminaryReplyText(String preliminaryReplyText) { 228b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair this.preliminaryReplyText = preliminaryReplyText; 229b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair } 230b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 231b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair} 232