chrismair | 00dc7bd | 2014-05-11 21:21:28 +0000 | [diff] [blame] | 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 | */
|
| 16 | package org.mockftpserver.stub;
|
| 17 |
|
| 18 | import org.mockftpserver.core.command.CommandHandler;
|
| 19 | import org.mockftpserver.core.command.CommandNames;
|
| 20 | import org.mockftpserver.core.command.ConnectCommandHandler;
|
| 21 | import org.mockftpserver.core.command.ReplyTextBundleUtil;
|
| 22 | import org.mockftpserver.core.command.UnsupportedCommandHandler;
|
| 23 | import org.mockftpserver.core.server.AbstractFtpServer;
|
| 24 | import org.mockftpserver.stub.command.*;
|
| 25 |
|
| 26 | /**
|
| 27 | * <b>StubFtpServer</b> is the top-level class for a "stub" implementation of an FTP Server,
|
| 28 | * suitable for testing FTP client code or standing in for a live FTP server. It supports
|
| 29 | * the main FTP commands by defining handlers for each of the corresponding low-level FTP
|
| 30 | * server commands (e.g. RETR, DELE, LIST). These handlers implement the {@link CommandHandler}
|
| 31 | * interface.
|
| 32 | * <p/>
|
| 33 | * <b>StubFtpServer</b> works out of the box with default command handlers that return
|
| 34 | * success reply codes and empty data (for retrieved files, directory listings, etc.).
|
| 35 | * The command handler for any command can be easily configured to return custom data
|
| 36 | * or reply codes. Or it can be replaced with a custom {@link CommandHandler}
|
| 37 | * implementation. This allows simulation of a complete range of both success and
|
| 38 | * failure scenarios. The command handlers can also be interrogated to verify command
|
| 39 | * invocation data such as command parameters and timestamps.
|
| 40 | * <p/>
|
| 41 | * <b>StubFtpServer</b> can be fully configured programmatically or within the
|
| 42 | * <a href="http://www.springframework.org/">Spring Framework</a> or similar container.
|
| 43 | * <p/>
|
| 44 | * <h4>Starting the StubFtpServer</h4>
|
| 45 | * Here is how to start the <b>StubFtpServer</b> with the default configuration.
|
| 46 | * <pre><code>
|
| 47 | * StubFtpServer stubFtpServer = new StubFtpServer();
|
| 48 | * stubFtpServer.start();
|
| 49 | * </code></pre>
|
| 50 | * <p/>
|
| 51 | * <h4>FTP Server Control Port</h4>
|
| 52 | * By default, <b>StubFtpServer</b> binds to the server control port of 21. You can use a different server control
|
| 53 | * port by setting the <code>serverControlPort</code> property. If you specify a value of <code>0</code>,
|
| 54 | * then a free port number will be chosen automatically; call <code>getServerControlPort()</code> AFTER
|
| 55 | * <code>start()</code> has been called to determine the actual port number being used. Using a non-default
|
| 56 | * port number is usually necessary when running on Unix or some other system where that port number is
|
| 57 | * already in use or cannot be bound from a user process.
|
| 58 | * <p/>
|
| 59 | * <h4>Retrieving Command Handlers</h4>
|
| 60 | * You can retrieve the existing {@link CommandHandler} defined for an FTP server command
|
| 61 | * by calling the {@link #getCommandHandler(String)} method, passing in the FTP server
|
| 62 | * command name. For example:
|
| 63 | * <pre><code>
|
| 64 | * PwdCommandHandler pwdCommandHandler = (PwdCommandHandler) stubFtpServer.getCommandHandler("PWD");
|
| 65 | * </code></pre>
|
| 66 | * <p/>
|
| 67 | * <h4>Replacing Command Handlers</h4>
|
| 68 | * You can replace the existing {@link CommandHandler} defined for an FTP server command
|
| 69 | * by calling the {@link #setCommandHandler(String, CommandHandler)} method, passing
|
| 70 | * in the FTP server command name and {@link CommandHandler} instance. For example:
|
| 71 | * <pre><code>
|
| 72 | * PwdCommandHandler pwdCommandHandler = new PwdCommandHandler();
|
| 73 | * pwdCommandHandler.setDirectory("some/dir");
|
| 74 | * stubFtpServer.setCommandHandler("PWD", pwdCommandHandler);
|
| 75 | * </code></pre>
|
| 76 | * You can also replace multiple command handlers at once by using the {@link #setCommandHandlers(java.util.Map)}
|
| 77 | * method. That is especially useful when configuring the server through the <b>Spring Framework</b>.
|
| 78 | * <h4>FTP Command Reply Text ResourceBundle</h4>
|
| 79 | * <p/>
|
| 80 | * The default text asociated with each FTP command reply code is contained within the
|
| 81 | * "ReplyText.properties" ResourceBundle file. You can customize these messages by providing a
|
| 82 | * locale-specific ResourceBundle file on the CLASSPATH, according to the normal lookup rules of
|
| 83 | * the ResourceBundle class (e.g., "ReplyText_de.properties"). Alternatively, you can
|
| 84 | * completely replace the ResourceBundle file by calling the calling the
|
| 85 | * {@link #setReplyTextBaseName(String)} method.
|
| 86 | *
|
| 87 | * @author Chris Mair
|
| 88 | * @version $Revision$ - $Date$
|
| 89 | */
|
| 90 | public class StubFtpServer extends AbstractFtpServer {
|
| 91 |
|
| 92 | /**
|
| 93 | * Create a new instance. Initialize the default command handlers and
|
| 94 | * reply text ResourceBundle.
|
| 95 | */
|
| 96 | public StubFtpServer() {
|
| 97 | PwdCommandHandler pwdCommandHandler = new PwdCommandHandler();
|
| 98 |
|
| 99 | // Initialize the default CommandHandler mappings
|
| 100 | setCommandHandler(CommandNames.ABOR, new AborCommandHandler());
|
| 101 | setCommandHandler(CommandNames.ACCT, new AcctCommandHandler());
|
| 102 | setCommandHandler(CommandNames.ALLO, new AlloCommandHandler());
|
| 103 | setCommandHandler(CommandNames.APPE, new AppeCommandHandler());
|
| 104 | setCommandHandler(CommandNames.PWD, pwdCommandHandler); // same as XPWD
|
| 105 | setCommandHandler(CommandNames.CONNECT, new ConnectCommandHandler());
|
| 106 | setCommandHandler(CommandNames.CWD, new CwdCommandHandler());
|
| 107 | setCommandHandler(CommandNames.CDUP, new CdupCommandHandler());
|
| 108 | setCommandHandler(CommandNames.DELE, new DeleCommandHandler());
|
| 109 | setCommandHandler(CommandNames.EPRT, new EprtCommandHandler());
|
| 110 | setCommandHandler(CommandNames.EPSV, new EpsvCommandHandler());
|
| 111 | setCommandHandler(CommandNames.HELP, new HelpCommandHandler());
|
| 112 | setCommandHandler(CommandNames.LIST, new ListCommandHandler());
|
| 113 | setCommandHandler(CommandNames.MKD, new MkdCommandHandler());
|
| 114 | setCommandHandler(CommandNames.MODE, new ModeCommandHandler());
|
| 115 | setCommandHandler(CommandNames.NOOP, new NoopCommandHandler());
|
| 116 | setCommandHandler(CommandNames.NLST, new NlstCommandHandler());
|
| 117 | setCommandHandler(CommandNames.PASS, new PassCommandHandler());
|
| 118 | setCommandHandler(CommandNames.PASV, new PasvCommandHandler());
|
| 119 | setCommandHandler(CommandNames.PORT, new PortCommandHandler());
|
| 120 | setCommandHandler(CommandNames.RETR, new RetrCommandHandler());
|
| 121 | setCommandHandler(CommandNames.QUIT, new QuitCommandHandler());
|
| 122 | setCommandHandler(CommandNames.REIN, new ReinCommandHandler());
|
| 123 | setCommandHandler(CommandNames.REST, new RestCommandHandler());
|
| 124 | setCommandHandler(CommandNames.RMD, new RmdCommandHandler());
|
| 125 | setCommandHandler(CommandNames.RNFR, new RnfrCommandHandler());
|
| 126 | setCommandHandler(CommandNames.RNTO, new RntoCommandHandler());
|
| 127 | setCommandHandler(CommandNames.SITE, new SiteCommandHandler());
|
| 128 | setCommandHandler(CommandNames.SMNT, new SmntCommandHandler());
|
| 129 | setCommandHandler(CommandNames.STAT, new StatCommandHandler());
|
| 130 | setCommandHandler(CommandNames.STOR, new StorCommandHandler());
|
| 131 | setCommandHandler(CommandNames.STOU, new StouCommandHandler());
|
| 132 | setCommandHandler(CommandNames.STRU, new StruCommandHandler());
|
| 133 | setCommandHandler(CommandNames.SYST, new SystCommandHandler());
|
| 134 | setCommandHandler(CommandNames.TYPE, new TypeCommandHandler());
|
| 135 | setCommandHandler(CommandNames.USER, new UserCommandHandler());
|
| 136 | setCommandHandler(CommandNames.UNSUPPORTED, new UnsupportedCommandHandler());
|
| 137 | setCommandHandler(CommandNames.XPWD, pwdCommandHandler); // same as PWD
|
| 138 | }
|
| 139 |
|
| 140 | //-------------------------------------------------------------------------
|
| 141 | // Abstract method implementation
|
| 142 | //-------------------------------------------------------------------------
|
| 143 |
|
| 144 | protected void initializeCommandHandler(CommandHandler commandHandler) {
|
| 145 | ReplyTextBundleUtil.setReplyTextBundleIfAppropriate(commandHandler, getReplyTextBundle());
|
| 146 | }
|
| 147 |
|
| 148 | } |