1ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair/* 2ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Copyright 2008 the original author or authors. 3ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * 4ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Licensed under the Apache License, Version 2.0 (the "License"); 5ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * you may not use this file except in compliance with the License. 6ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * You may obtain a copy of the License at 7ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * 8ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * http://www.apache.org/licenses/LICENSE-2.0 9ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * 10ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Unless required by applicable law or agreed to in writing, software 11ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * distributed under the License is distributed on an "AS IS" BASIS, 12ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * See the License for the specific language governing permissions and 14ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * limitations under the License. 15ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 16ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairpackage org.mockftpserver.fake; 17ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 18ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.core.command.CommandHandler; 19ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.core.command.CommandNames; 20ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.core.server.AbstractFtpServer; 21ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.fake.command.*; 22ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport org.mockftpserver.fake.filesystem.FileSystem; 23ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 24ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport java.util.HashMap; 25ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport java.util.List; 26ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairimport java.util.Map; 27ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 28ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair/** 29ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * <b>FakeFtpServer</b> is the top-level class for a "fake" implementation of an FTP Server, 30ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * suitable for testing FTP client code or standing in for a live FTP server. 31ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * <p/> 32ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * <b>FakeFtpServer</b> provides a high-level abstraction for an FTP Server and is suitable 33ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * for most testing and simulation scenarios. You define a filesystem (internal, in-memory) containing 34ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * an arbitrary set of files and directories. These files and directories can (optionally) have 35ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * associated access permissions. You also configure a set of one or more user accounts that 36ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * control which users can login to the FTP server, and their home (default) directories. The 37ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * user account is also used when assigning file and directory ownership for new files. 38ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * <p> <b>FakeFtpServer</b> processes FTP client requests and responds with reply codes and 39ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * reply messages consistent with its configuration and the contents of its internal filesystem, 40ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * including file and directory permissions, if they have been configured. 41ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * <p/> 42ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * <b>FakeFtpServer</b> can be fully configured programmatically or within the 43ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * <b>Spring Framework</b> or other dependency-injection container. 44ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * <p/> 45ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * In general the steps for setting up and starting the <b>FakeFtpServer</b> are: 46ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * <ol> 47ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * <li>Create a new <b>FakeFtpServer</b> instance, and optionally set the server control port.</li> 48ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * <li>Create and configure a <b>FileSystem</b>, and attach to the <b>FakeFtpServer</b> instance.</li> 49ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * <li>Create and configure one or more <b>UserAccount</b> objects and attach to the <b>FakeFtpServer</b> instance.</li> 50ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * </ol> 51ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * <h4>Example Code</h4> 52ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * <pre><code> 53ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * FileSystem fileSystem = new WindowsFakeFileSystem(); 54ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * DirectoryEntry directoryEntry1 = new DirectoryEntry("c:\\"); 55ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * directoryEntry1.setPermissions(new Permissions("rwxrwx---")); 56ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * directoryEntry1.setOwner("joe"); 57ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * directoryEntry1.setGroup("dev"); 58ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * <p/> 59ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * DirectoryEntry directoryEntry2 = new DirectoryEntry("c:\\data"); 60ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * directoryEntry2.setPermissions(Permissions.ALL); 61ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * directoryEntry2.setOwner("joe"); 62ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * directoryEntry2.setGroup("dev"); 63ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * <p/> 64ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * FileEntry fileEntry1 = new FileEntry("c:\\data\\file1.txt", "abcdef 1234567890"); 65ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * fileEntry1.setPermissionsFromString("rw-rw-rw-"); 66ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * fileEntry1.setOwner("joe"); 67ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * fileEntry1.setGroup("dev"); 68ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * <p/> 69ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * FileEntry fileEntry2 = new FileEntry("c:\\data\\run.exe"); 70ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * fileEntry2.setPermissionsFromString("rwxrwx---"); 71ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * fileEntry2.setOwner("mary"); 72ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * fileEntry2.setGroup("dev"); 73ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * <p/> 74ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * fileSystem.add(directoryEntry1); 75ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * fileSystem.add(directoryEntry2); 76ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * fileSystem.add(fileEntry1); 77ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * fileSystem.add(fileEntry2); 78ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * <p/> 79ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * FakeFtpServer fakeFtpServer = new FakeFtpServer(); 80ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * fakeFtpServer.setFileSystem(fileSystem); 81ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * <p/> 82ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * UserAccount userAccount = new UserAccount(); 83ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * userAccount.setUsername("joe"); 84ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * userAccount.setPassword("joe123"); 85ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * userAccount.setHomeDirectory("c:\\"); 86ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * List userAccounts = Collections.singletonList(userAccount); 87ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * fakeFtpServer.setUserAccounts(userAccounts); 88ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * <p/> 89ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * fakeFtpServer.start(); 90ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * </code></pre> 91ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * <p/> 92ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * <h4>FTP Command Reply Text ResourceBundle</h4> 93ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * <p/> 94ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * The default text asociated with each FTP command reply code is contained within the 95ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * "ReplyText.properties" ResourceBundle file. You can customize these messages by providing a 96ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * locale-specific ResourceBundle file on the CLASSPATH, according to the normal lookup rules of 97ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * the ResourceBundle class (e.g., "ReplyText_de.properties"). Alternatively, you can 98ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * completely replace the ResourceBundle file by calling the calling the 99ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * {@link #setReplyTextBaseName(String)} method. 100ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * 101ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @author Chris Mair 102ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @version $Revision: 143 $ - $Date: 2008-10-31 21:07:23 -0400 (Fri, 31 Oct 2008) $ 103ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 104ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismairpublic class FakeFtpServer extends AbstractFtpServer implements ServerConfiguration { 105ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 106ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair private FileSystem fileSystem; 107ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair private String systemName = "WINDOWS"; 108ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair private Map helpText = new HashMap(); 109ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair private Map userAccounts = new HashMap(); 110ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 111ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair public FileSystem getFileSystem() { 112ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair return fileSystem; 113ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 114ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 115ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair public void setFileSystem(FileSystem fileSystem) { 116ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair this.fileSystem = fileSystem; 117ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 118ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 119ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair public String getSystemName() { 120ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair return systemName; 121ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 122ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 123ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair public void setSystemName(String systemName) { 124ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair this.systemName = systemName; 125ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 126ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 127ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair public Map getHelpText() { 128ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair return helpText; 129ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 130ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 131ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair public void setHelpText(Map helpText) { 132ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair this.helpText = helpText; 133ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 134ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 135ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair public FakeFtpServer() { 136ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.ACCT, new AcctCommandHandler()); 137ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.ABOR, new AborCommandHandler()); 138ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.ALLO, new AlloCommandHandler()); 139ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.APPE, new AppeCommandHandler()); 140ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.CONNECT, new ConnectCommandHandler()); 141ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.CWD, new CwdCommandHandler()); 142ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.CDUP, new CdupCommandHandler()); 143ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.DELE, new DeleCommandHandler()); 144ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.HELP, new HelpCommandHandler()); 145ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.LIST, new ListCommandHandler()); 146ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.MKD, new MkdCommandHandler()); 147ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.MODE, new ModeCommandHandler()); 148ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.NLST, new NlstCommandHandler()); 149ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.NOOP, new NoopCommandHandler()); 150ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.PASS, new PassCommandHandler()); 151ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.PASV, new PasvCommandHandler()); 152ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.PWD, new PwdCommandHandler()); 153ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.PORT, new PortCommandHandler()); 154ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.QUIT, new QuitCommandHandler()); 155ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.REIN, new ReinCommandHandler()); 156ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.REST, new RestCommandHandler()); 157ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.RETR, new RetrCommandHandler()); 158ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.RMD, new RmdCommandHandler()); 159ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.RNFR, new RnfrCommandHandler()); 160ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.RNTO, new RntoCommandHandler()); 161ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.SITE, new SiteCommandHandler()); 162ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.STOR, new StorCommandHandler()); 163ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.STOU, new StouCommandHandler()); 164ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.STRU, new StruCommandHandler()); 165ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.SYST, new SystCommandHandler()); 166ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.TYPE, new TypeCommandHandler()); 167ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.USER, new UserCommandHandler()); 168ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair setCommandHandler(CommandNames.XPWD, new PwdCommandHandler()); 169ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 170ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 171ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 172ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Initialize a CommandHandler that has been registered to this server. If the CommandHandler implements 173ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * the <code>ServerConfigurationAware</code> interface, then set its <code>ServerConfiguration</code> 174ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * property to <code>this</code>. 175ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * 176ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param commandHandler - the CommandHandler to initialize 177ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 178ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair protected void initializeCommandHandler(CommandHandler commandHandler) { 179ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair if (commandHandler instanceof ServerConfigurationAware) { 180ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair ServerConfigurationAware sca = (ServerConfigurationAware) commandHandler; 181ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair sca.setServerConfiguration(this); 182ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 183ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 184ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 185ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 186ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @return the {@link UserAccount} configured for this server for the specified user name 187ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 188ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair public UserAccount getUserAccount(String username) { 189ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair return (UserAccount) userAccounts.get(username); 190ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 191ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 192ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 193ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Return the help text for a command or the default help text if no command name is specified 194ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * 195ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param name - the command name; may be empty or null to indicate a request for the default help text 196ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @return the help text for the named command or the default help text if no name is supplied 197ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 198ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair public String getHelpText(String name) { 199ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair String key = name == null ? "" : name; 200ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair return (String) helpText.get(key); 201ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 202ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 203ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 204ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Add a single UserAccount. If an account with the same <code>username</code> already exists, 205ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * it will be replaced. 206ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * 207ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param userAccount - the UserAccount to add 208ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 209ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair public void addUserAccount(UserAccount userAccount) { 210ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair userAccounts.put(userAccount.getUsername(), userAccount); 211ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 212ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 213ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair /** 214ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * Add the UserAccount objects in the <code>userAccountList</code> to the set of UserAccounts. 215ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * 216ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair * @param userAccountList - the List of UserAccount objects to add 217ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair */ 218ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair public void setUserAccounts(List userAccountList) { 219ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair for (int i = 0; i < userAccountList.size(); i++) { 220ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair UserAccount userAccount = (UserAccount) userAccountList.get(i); 221ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair userAccounts.put(userAccount.getUsername(), userAccount); 222ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 223ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair } 224ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair 225ad39334d4c363c6ada5863d0bb3184f5f4699d69chrismair}