| Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
| StubFtpServer |
|
| 1.0;1 |
| 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: 255 $ - $Date: 2011-06-05 21:23:55 -0400 (Sun, 05 Jun 2011) $ | |
| 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 | 58 | public StubFtpServer() { |
| 97 | 58 | PwdCommandHandler pwdCommandHandler = new PwdCommandHandler(); |
| 98 | ||
| 99 | // Initialize the default CommandHandler mappings | |
| 100 | 58 | setCommandHandler(CommandNames.ABOR, new AborCommandHandler()); |
| 101 | 58 | setCommandHandler(CommandNames.ACCT, new AcctCommandHandler()); |
| 102 | 58 | setCommandHandler(CommandNames.ALLO, new AlloCommandHandler()); |
| 103 | 58 | setCommandHandler(CommandNames.APPE, new AppeCommandHandler()); |
| 104 | 58 | setCommandHandler(CommandNames.PWD, pwdCommandHandler); // same as XPWD |
| 105 | 58 | setCommandHandler(CommandNames.CONNECT, new ConnectCommandHandler()); |
| 106 | 58 | setCommandHandler(CommandNames.CWD, new CwdCommandHandler()); |
| 107 | 58 | setCommandHandler(CommandNames.CDUP, new CdupCommandHandler()); |
| 108 | 58 | setCommandHandler(CommandNames.DELE, new DeleCommandHandler()); |
| 109 | 58 | setCommandHandler(CommandNames.EPRT, new EprtCommandHandler()); |
| 110 | 58 | setCommandHandler(CommandNames.EPSV, new EpsvCommandHandler()); |
| 111 | 58 | setCommandHandler(CommandNames.HELP, new HelpCommandHandler()); |
| 112 | 58 | setCommandHandler(CommandNames.LIST, new ListCommandHandler()); |
| 113 | 58 | setCommandHandler(CommandNames.MKD, new MkdCommandHandler()); |
| 114 | 58 | setCommandHandler(CommandNames.MODE, new ModeCommandHandler()); |
| 115 | 58 | setCommandHandler(CommandNames.NOOP, new NoopCommandHandler()); |
| 116 | 58 | setCommandHandler(CommandNames.NLST, new NlstCommandHandler()); |
| 117 | 58 | setCommandHandler(CommandNames.PASS, new PassCommandHandler()); |
| 118 | 58 | setCommandHandler(CommandNames.PASV, new PasvCommandHandler()); |
| 119 | 58 | setCommandHandler(CommandNames.PORT, new PortCommandHandler()); |
| 120 | 58 | setCommandHandler(CommandNames.RETR, new RetrCommandHandler()); |
| 121 | 58 | setCommandHandler(CommandNames.QUIT, new QuitCommandHandler()); |
| 122 | 58 | setCommandHandler(CommandNames.REIN, new ReinCommandHandler()); |
| 123 | 58 | setCommandHandler(CommandNames.REST, new RestCommandHandler()); |
| 124 | 58 | setCommandHandler(CommandNames.RMD, new RmdCommandHandler()); |
| 125 | 58 | setCommandHandler(CommandNames.RNFR, new RnfrCommandHandler()); |
| 126 | 58 | setCommandHandler(CommandNames.RNTO, new RntoCommandHandler()); |
| 127 | 58 | setCommandHandler(CommandNames.SITE, new SiteCommandHandler()); |
| 128 | 58 | setCommandHandler(CommandNames.SMNT, new SmntCommandHandler()); |
| 129 | 58 | setCommandHandler(CommandNames.STAT, new StatCommandHandler()); |
| 130 | 58 | setCommandHandler(CommandNames.STOR, new StorCommandHandler()); |
| 131 | 58 | setCommandHandler(CommandNames.STOU, new StouCommandHandler()); |
| 132 | 58 | setCommandHandler(CommandNames.STRU, new StruCommandHandler()); |
| 133 | 58 | setCommandHandler(CommandNames.SYST, new SystCommandHandler()); |
| 134 | 58 | setCommandHandler(CommandNames.TYPE, new TypeCommandHandler()); |
| 135 | 58 | setCommandHandler(CommandNames.USER, new UserCommandHandler()); |
| 136 | 58 | setCommandHandler(CommandNames.UNSUPPORTED, new UnsupportedCommandHandler()); |
| 137 | 58 | setCommandHandler(CommandNames.XPWD, pwdCommandHandler); // same as PWD |
| 138 | 58 | } |
| 139 | ||
| 140 | //------------------------------------------------------------------------- | |
| 141 | // Abstract method implementation | |
| 142 | //------------------------------------------------------------------------- | |
| 143 | ||
| 144 | protected void initializeCommandHandler(CommandHandler commandHandler) { | |
| 145 | 2224 | ReplyTextBundleUtil.setReplyTextBundleIfAppropriate(commandHandler, getReplyTextBundle()); |
| 146 | 2224 | } |
| 147 | ||
| 148 | } |