1b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair/* 2b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * Copyright 2008 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.fake; 17b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 18b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismairimport org.mockftpserver.core.command.CommandHandler; 19b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismairimport org.mockftpserver.core.command.CommandNames; 20b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismairimport org.mockftpserver.core.command.ConnectCommandHandler; 21b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismairimport org.mockftpserver.core.command.ReplyTextBundleUtil; 22b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismairimport org.mockftpserver.core.command.UnsupportedCommandHandler; 23b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismairimport org.mockftpserver.core.server.AbstractFtpServer; 24b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismairimport org.mockftpserver.fake.command.*; 25b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismairimport org.mockftpserver.fake.filesystem.FileSystem; 26b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 27b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismairimport java.util.HashMap; 28b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismairimport java.util.List; 29b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismairimport java.util.Map; 30b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 31b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair/** 32b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <b>FakeFtpServer</b> is the top-level class for a "fake" implementation of an FTP Server, 33b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * suitable for testing FTP client code or standing in for a live FTP server. 34b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <p/> 35b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <b>FakeFtpServer</b> provides a high-level abstraction for an FTP Server and is suitable 36b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * for most testing and simulation scenarios. You define a filesystem (internal, in-memory) containing 37b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * an arbitrary set of files and directories. These files and directories can (optionally) have 38b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * associated access permissions. You also configure a set of one or more user accounts that 39b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * control which users can login to the FTP server, and their home (default) directories. The 40b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * user account is also used when assigning file and directory ownership for new files. 41b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <p> <b>FakeFtpServer</b> processes FTP client requests and responds with reply codes and 42b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * reply messages consistent with its configuration and the contents of its internal filesystem, 43b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * including file and directory permissions, if they have been configured. 44b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <p/> 45b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <b>FakeFtpServer</b> can be fully configured programmatically or within the 46b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <a href="http://www.springframework.org/">Spring Framework</a> or other dependency-injection container. 47b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <p/> 48b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * In general the steps for setting up and starting the <b>FakeFtpServer</b> are: 49b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <ol> 50b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <li>Create a new <b>FakeFtpServer</b> instance, and optionally set the server control port.</li> 51b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <li>Create and configure a <b>FileSystem</b>, and attach to the <b>FakeFtpServer</b> instance.</li> 52b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <li>Create and configure one or more <b>UserAccount</b> objects and attach to the <b>FakeFtpServer</b> instance.</li> 53b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <li>Start the <b>FakeFtpServer</b> instance.</li> 54b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * </ol> 55b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <h4>Example Code</h4> 56b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <pre><code> 57b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * FakeFtpServer fakeFtpServer = new FakeFtpServer(); 58b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 59b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * FileSystem fileSystem = new WindowsFakeFileSystem(); 60b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * fileSystem.add(new DirectoryEntry("c:\\")); 61b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * fileSystem.add(new DirectoryEntry("c:\\data")); 62b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * fileSystem.add(new FileEntry("c:\\data\\file1.txt", "abcdef 1234567890")); 63b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * fileSystem.add(new FileEntry("c:\\data\\run.exe")); 64b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * fakeFtpServer.setFileSystem(fileSystem); 65b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 66b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * // Create UserAccount with username, password, home-directory 67b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * UserAccount userAccount = new UserAccount("joe", "joe123", "c:\\"); 68b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * fakeFtpServer.addUserAccounts(userAccount); 69b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 70b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * fakeFtpServer.start(); 71b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * </code></pre> 72b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 73b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <h4>Example Code with Permissions</h4> 74b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * You can optionally set the permissions and owner/group for each file and directory, as in the following example. 75b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <pre><code> 76b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * FileSystem fileSystem = new UnixFakeFileSystem(); 77b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * DirectoryEntry directoryEntry1 = new DirectoryEntry("/"); 78b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * directoryEntry1.setPermissions(new Permissions("rwxrwx---")); 79b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * directoryEntry1.setOwner("joe"); 80b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * directoryEntry1.setGroup("dev"); 81b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 82b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * DirectoryEntry directoryEntry2 = new DirectoryEntry("/data"); 83b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * directoryEntry2.setPermissions(Permissions.ALL); 84b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * directoryEntry2.setOwner("joe"); 85b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * directoryEntry2.setGroup("dev"); 86b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 87b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * FileEntry fileEntry1 = new FileEntry("/data/file1.txt", "abcdef 1234567890"); 88b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * fileEntry1.setPermissionsFromString("rw-rw-rw-"); 89b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * fileEntry1.setOwner("joe"); 90b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * fileEntry1.setGroup("dev"); 91b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 92b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * FileEntry fileEntry2 = new FileEntry("/data/run.exe"); 93b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * fileEntry2.setPermissionsFromString("rwxrwx---"); 94b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * fileEntry2.setOwner("mary"); 95b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * fileEntry2.setGroup("dev"); 96b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 97b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * fileSystem.add(directoryEntry1); 98b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * fileSystem.add(directoryEntry2); 99b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * fileSystem.add(fileEntry1); 100b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * fileSystem.add(fileEntry2); 101b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 102b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * FakeFtpServer fakeFtpServer = new FakeFtpServer(); 103b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * fakeFtpServer.setFileSystem(fileSystem); 104b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 105b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * // Create UserAccount with username, password, home-directory 106b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * UserAccount userAccount = new UserAccount("joe", "joe123", "/"); 107b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * fakeFtpServer.addUserAccounts(userAccount); 108b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 109b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * fakeFtpServer.start(); 110b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * </code></pre> 111b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 112b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <h4>FTP Server Control Port</h4> 113b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * By default, <b>MockFtpServer</b> binds to the server control port of 21. You can use a different server 114b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * control port by setting the the <code>serverControlPort</code> property. This is usually necessary 115b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * when running on Unix or some other system where that port number is already in use or cannot be bound 116b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * from a user process. 117b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 118b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <h4>Other Configuration</h4> 119b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * The <code>systemName</code> property specifies the value returned by the <code>SYST</code> 120b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * command. Note that this is typically used by an FTP client to determine how to parse 121b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * system-dependent reply text, such as directory listings. This value defaults to <code>"WINDOWS"</code>. 122b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <p/> 123b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * The <code>helpText</code> property specifies a <i>Map</i> of help text replies sent by the 124b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <code>HELP</code> command. The keys in that <i>Map</i> correspond to the command names passed as 125b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * parameters to the <code>HELP</code> command. An entry with the key of an empty string ("") indicates the 126b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * text used as the default help text when no command name parameter is specified for the <code>HELP</code> command. 127b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 128b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <h4>FTP Command Reply Text ResourceBundle</h4> 129b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * The default text asociated with each FTP command reply code is contained within the 130b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * "ReplyText.properties" ResourceBundle file. You can customize these messages by providing a 131b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * locale-specific ResourceBundle file on the CLASSPATH, according to the normal lookup rules of 132b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * the ResourceBundle class (e.g., "ReplyText_de.properties"). Alternatively, you can 133b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * completely replace the ResourceBundle file by calling the calling the 134b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * {@link #setReplyTextBaseName(String)} method. 135b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 136b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @author Chris Mair 137b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @version $Revision$ - $Date$ 138b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair */ 139b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismairpublic class FakeFtpServer extends AbstractFtpServer implements ServerConfiguration { 140b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 141b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair private FileSystem fileSystem; 142b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair private String systemName = "WINDOWS"; 143b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair private String systemStatus = "Connected"; 144b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair private Map helpText = new HashMap(); 145b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair private Map userAccounts = new HashMap(); 146b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 147b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair public FileSystem getFileSystem() { 148b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair return fileSystem; 149b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair } 150b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 151b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair public void setFileSystem(FileSystem fileSystem) { 152b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair this.fileSystem = fileSystem; 153b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair } 154b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 155b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair public String getSystemName() { 156b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair return systemName; 157b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair } 158b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 159b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair public void setSystemName(String systemName) { 160b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair this.systemName = systemName; 161b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair } 162b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 163b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair public Map getHelpText() { 164b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair return helpText; 165b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair } 166b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 167b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair public void setHelpText(Map helpText) { 168b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair this.helpText = helpText; 169b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair } 170b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 171b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair public FakeFtpServer() { 172b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.ACCT, new AcctCommandHandler()); 173b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.ABOR, new AborCommandHandler()); 174b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.ALLO, new AlloCommandHandler()); 175b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.APPE, new AppeCommandHandler()); 176b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.CWD, new CwdCommandHandler()); 177b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.CDUP, new CdupCommandHandler()); 178b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.DELE, new DeleCommandHandler()); 179b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.HELP, new HelpCommandHandler()); 180b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.LIST, new ListCommandHandler()); 181b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.MKD, new MkdCommandHandler()); 182b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.MODE, new ModeCommandHandler()); 183b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.NLST, new NlstCommandHandler()); 184b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.NOOP, new NoopCommandHandler()); 185b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.PASS, new PassCommandHandler()); 186b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.PASV, new PasvCommandHandler()); 187b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.PWD, new PwdCommandHandler()); 188b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.PORT, new PortCommandHandler()); 189b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.QUIT, new QuitCommandHandler()); 190b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.REIN, new ReinCommandHandler()); 191b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.REST, new RestCommandHandler()); 192b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.RETR, new RetrCommandHandler()); 193b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.RMD, new RmdCommandHandler()); 194b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.RNFR, new RnfrCommandHandler()); 195b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.RNTO, new RntoCommandHandler()); 196b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.SITE, new SiteCommandHandler()); 197b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.SMNT, new SmntCommandHandler()); 198b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.STAT, new StatCommandHandler()); 199b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.STOR, new StorCommandHandler()); 200b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.STOU, new StouCommandHandler()); 201b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.STRU, new StruCommandHandler()); 202b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.SYST, new SystCommandHandler()); 203b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.TYPE, new TypeCommandHandler()); 204b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.USER, new UserCommandHandler()); 205b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.XPWD, new PwdCommandHandler()); 206b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 207b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair // "Special" Command Handlers 208b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.CONNECT, new ConnectCommandHandler()); 209b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair setCommandHandler(CommandNames.UNSUPPORTED, new UnsupportedCommandHandler()); 210b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair } 211b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 212b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair /** 213b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * Initialize a CommandHandler that has been registered to this server. 214b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 215b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * If the CommandHandler implements the <code>ServerConfigurationAware</code> interface, then set its 216b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <code>ServerConfiguration</code> property to <code>this</code>. 217b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 218b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * If the CommandHandler implements the <code>ReplyTextBundleAware</code> interface, then set its 219b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * <code>replyTextBundle</code> property using the reply text bundle for this server. 220b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 221b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @param commandHandler - the CommandHandler to initialize 222b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair */ 223b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair protected void initializeCommandHandler(CommandHandler commandHandler) { 224b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair if (commandHandler instanceof ServerConfigurationAware) { 225b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair ServerConfigurationAware sca = (ServerConfigurationAware) commandHandler; 226b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair sca.setServerConfiguration(this); 227b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair } 228b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 229b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair ReplyTextBundleUtil.setReplyTextBundleIfAppropriate(commandHandler, getReplyTextBundle()); 230b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair } 231b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 232b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair /** 233b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @return the {@link UserAccount} configured for this server for the specified user name 234b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair */ 235b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair public UserAccount getUserAccount(String username) { 236b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair return (UserAccount) userAccounts.get(username); 237b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair } 238b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 239b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair /** 240b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * Return the help text for a command or the default help text if no command name is specified 241b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 242b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @param name - the command name; may be empty or null to indicate a request for the default help text 243b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @return the help text for the named command or the default help text if no name is supplied 244b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair */ 245b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair public String getHelpText(String name) { 246b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair String key = name == null ? "" : name; 247b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair return (String) helpText.get(key); 248b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair } 249b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 250b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair /** 251b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * Add a single UserAccount. If an account with the same <code>username</code> already exists, 252b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * it will be replaced. 253b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 254b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @param userAccount - the UserAccount to add 255b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair */ 256b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair public void addUserAccount(UserAccount userAccount) { 257b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair userAccounts.put(userAccount.getUsername(), userAccount); 258b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair } 259b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 260b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair /** 261b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * Add the UserAccount objects in the <code>userAccountList</code> to the set of UserAccounts. 262b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 263b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @param userAccountList - the List of UserAccount objects to add 264b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair */ 265b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair public void setUserAccounts(List userAccountList) { 266b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair for (int i = 0; i < userAccountList.size(); i++) { 267b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair UserAccount userAccount = (UserAccount) userAccountList.get(i); 268b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair userAccounts.put(userAccount.getUsername(), userAccount); 269b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair } 270b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair } 271b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 272b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair /** 273b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * Return the system status description 274b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 275b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @return the system status 276b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair */ 277b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair public String getSystemStatus() { 278b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair return systemStatus; 279b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair } 280b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 281b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair /** 282b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * Set the system status description text, used by the STAT command handler. 283b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * 284b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair * @param systemStatus - the system status description text 285b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair */ 286b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair public void setSystemStatus(String systemStatus) { 287b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair this.systemStatus = systemStatus; 288b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair } 289b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair 290b2f4a2dfc590c250e42b21eb40d9539ac135b495chrismair}