All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.mockftpserver.stub.command.AbstractStubDataCommandHandler Maven / Gradle / Ivy

Go to download

The MockFtpServer project provides mock/dummy FTP server implementations for testing FTP client code. Two FTP Server implementations are provided, each at a different level of abstraction. FakeFtpServer provides a higher-level abstraction. You define a virtual file system, including directories and files, as well as a set of valid user accounts and credentials. The FakeFtpServer then responds with appropriate replies and reply codes based on that configuration. StubFtpServer, on the other hand, is a lower-level "stub" implementation. You configure the individual FTP server commands to return custom data or reply codes, allowing simulation of either success or failure scenarios. You can also verify expected command invocations.

There is a newer version: 3.2.0
Show newest version
/*
 * Copyright 2007 the original author or authors.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.mockftpserver.stub.command;

import org.mockftpserver.core.command.AbstractTrackingCommandHandler;
import org.mockftpserver.core.command.Command;
import org.mockftpserver.core.command.CommandHandler;
import org.mockftpserver.core.command.InvocationRecord;
import org.mockftpserver.core.command.ReplyCodes;
import org.mockftpserver.core.session.Session;
import org.mockftpserver.core.util.AssertFailedException;

/**
 * Abstract superclass for CommandHandlers that read from or write to the data connection.
 *
 * 

Return two replies on the control connection: by default a reply code of 150 before the * data transfer across the data connection and another reply of 226 after the data transfer * is complete. * *

This class implements the Template Method pattern. Subclasses must implement the abstract * processData method to perform read or writes across the data connection. * *

Subclasses can optionally override the {@link #beforeProcessData(Command, Session, InvocationRecord)} * method for logic before the data transfer or the {@link #afterProcessData(Command, Session, InvocationRecord)} * method for logic after the data transfer. * *

Subclasses can optionally override the reply code and/or text for the initial reply (before * the data transfer across the data connection) by calling {@link #setPreliminaryReplyCode(int)}, * {@link #setPreliminaryReplyMessageKey(String)} and/or {@link #setPreliminaryReplyText(String)} * methods. * *

Subclasses can optionally override the reply code and/or text for the final reply (after the * the data transfer is complete) by calling {@link #setFinalReplyCode(int)}, * {@link #setFinalReplyMessageKey(String)} and/or {@link #setFinalReplyText(String)} methods. * * @author Chris Mair */ public abstract class AbstractStubDataCommandHandler extends AbstractTrackingCommandHandler implements CommandHandler { // The completion reply code sent before the data transfer protected int preliminaryReplyCode = 0; // The text for the preliminary reply. If null, use the default message associated with the reply code. // If not null, this value overrides the preliminaryReplyMessageKey - i.e., this text is used instead of // a localized message. protected String preliminaryReplyText = null; // The message key for the preliminary reply text. If null, use the default message associated with // the reply code. protected String preliminaryReplyMessageKey = null; // The completion reply code sent after data transfer protected int finalReplyCode = 0; // The text for the completion reply. If null, use the default message associated with the reply code. // If not null, this value overrides the finalReplyMessageKey - i.e., this text is used instead of // a localized message. protected String finalReplyText = null; // The message key for the completion reply text. If null, use the default message associated with the reply code protected String finalReplyMessageKey = null; /** * Constructor. Initialize the preliminary and final reply code. */ protected AbstractStubDataCommandHandler() { setPreliminaryReplyCode(ReplyCodes.TRANSFER_DATA_INITIAL_OK); setFinalReplyCode(ReplyCodes.TRANSFER_DATA_FINAL_OK); } /** * Handle the command. Perform the following steps: *

    *
  1. Invoke the beforeProcessData() method
  2. *
  3. Open the data connection
  4. *
  5. Send an preliminary reply, default reply code 150
  6. *
  7. Invoke the processData() method
  8. *
  9. Close the data connection
  10. *
  11. Send the final reply, default reply code 226
  12. *
  13. Invoke the afterProcessData() method
  14. *
* * @see org.mockftpserver.core.command.AbstractTrackingCommandHandler#handleCommand(org.mockftpserver.core.command.Command, org.mockftpserver.core.session.Session, org.mockftpserver.core.command.InvocationRecord) */ public final void handleCommand(Command command, Session session, InvocationRecord invocationRecord) throws Exception { beforeProcessData(command, session, invocationRecord); sendPreliminaryReply(session); session.openDataConnection(); processData(command, session, invocationRecord); session.closeDataConnection(); sendFinalReply(session); afterProcessData(command, session, invocationRecord); } /** * Send the final reply. The default implementation sends a reply code of 226 with the * corresponding associated reply text. * * @param session - the Session */ protected void sendFinalReply(Session session) { sendReply(session, finalReplyCode, finalReplyMessageKey, finalReplyText, null); } /** * Perform any necessary logic before transferring data across the data connection. * Do nothing by default. Subclasses should override to validate command parameters and * store information in the InvocationRecord. * * @param command - the Command to be handled * @param session - the session on which the Command was submitted * @param invocationRecord - the InvocationRecord; CommandHandlers are expected to add * handler-specific data to the InvocationRecord, as appropriate * @throws Exception - if an error occurs */ protected void beforeProcessData(Command command, Session session, InvocationRecord invocationRecord) throws Exception { // Do nothing by default } /** * Abstract method placeholder for subclass transfer of data across the data connection. * Subclasses must override. The data connection is opened before this method and is * closed after this method completes. * * @param command - the Command to be handled * @param session - the session on which the Command was submitted * @param invocationRecord - the InvocationRecord; CommandHandlers are expected to add * handler-specific data to the InvocationRecord, as appropriate * @throws Exception - if an error occurs */ protected abstract void processData(Command command, Session session, InvocationRecord invocationRecord) throws Exception; /** * Perform any necessary logic after transferring data across the data connection. * Do nothing by default. * * @param command - the Command to be handled * @param session - the session on which the Command was submitted * @param invocationRecord - the InvocationRecord; CommandHandlers are expected to add * handler-specific data to the InvocationRecord, as appropriate * @throws Exception - if an error occurs */ protected void afterProcessData(Command command, Session session, InvocationRecord invocationRecord) throws Exception { // Do nothing by default } /** * Send the preliminary reply for this command on the control connection. * * @param session - the Session */ private void sendPreliminaryReply(Session session) { sendReply(session, preliminaryReplyCode, preliminaryReplyMessageKey, preliminaryReplyText, null); } /** * Set the completion reply code sent after data transfer * * @param finalReplyCode - the final reply code * @throws AssertFailedException - if the finalReplyCode is invalid */ public void setFinalReplyCode(int finalReplyCode) { assertValidReplyCode(finalReplyCode); this.finalReplyCode = finalReplyCode; } /** * Set the message key for the completion reply text sent after data transfer * * @param finalReplyMessageKey - the final reply message key */ public void setFinalReplyMessageKey(String finalReplyMessageKey) { this.finalReplyMessageKey = finalReplyMessageKey; } /** * Set the text of the completion reply sent after data transfer * * @param finalReplyText - the final reply text */ public void setFinalReplyText(String finalReplyText) { this.finalReplyText = finalReplyText; } /** * Set the completion reply code sent before data transfer * * @param preliminaryReplyCode - the preliminary reply code to set * @throws AssertFailedException - if the preliminaryReplyCode is invalid */ public void setPreliminaryReplyCode(int preliminaryReplyCode) { assertValidReplyCode(preliminaryReplyCode); this.preliminaryReplyCode = preliminaryReplyCode; } /** * Set the message key for the completion reply text sent before data transfer * * @param preliminaryReplyMessageKey - the preliminary reply message key */ public void setPreliminaryReplyMessageKey(String preliminaryReplyMessageKey) { this.preliminaryReplyMessageKey = preliminaryReplyMessageKey; } /** * Set the text of the completion reply sent before data transfer * * @param preliminaryReplyText - the preliminary reply text */ public void setPreliminaryReplyText(String preliminaryReplyText) { this.preliminaryReplyText = preliminaryReplyText; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy