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