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