001 package org.hackystat.sensorshell.usermap; 002 003 import java.io.File; 004 import java.util.HashMap; 005 import java.util.Map; 006 import java.util.Properties; 007 import java.util.Set; 008 009 import org.hackystat.sensorshell.SensorShell; 010 import org.hackystat.sensorshell.SensorShellProperties; 011 import org.hackystat.sensorshell.usermap.UserMap.UserMapKey; 012 013 /** 014 * Allows for lazy instantiation of SensorShells for user tool accounts. This class abstracts the 015 * use of the UserMap class so that sensors for applicable tool sensors won't have to manage it. 016 * <p> 017 * The <code>SensorShellMap</code> is meant to only derive SensorShells for a specific tool. 018 * Queries for SensorShells are done by giving an account name to the <code>getUserShell</code> 019 * method. This account name must be specific to the tool of the <code>SensorShellMap</code> 020 * instance. 021 * <p> 022 * Note that the "tool" name is used in a case-insensitive fashion. 023 * 024 * @author Burt Leung, Julie Ann Sakuda (v8 port) 025 */ 026 public class SensorShellMap { 027 028 /** The tool that this SensorShellMap will return SensorShells for. */ 029 private String tool; 030 031 /** Mapping of Tool specific user accounts to their Hackystat information. */ 032 private UserMap userMap; 033 034 /** Map of Tool specific tool accounts to their SensorShells. */ 035 private Map<String, SensorShell> toolAccountsToShells = new HashMap<String, SensorShell>(); 036 037 /** 038 * Instantiate this class which initializes the UserMap used to get SensorShells for users and 039 * also sets the Hackystat host for the SensorShells. 040 * 041 * @param tool The specific tool that this SensorShellMap will provide SensorShells for. 042 * @throws SensorShellMapException Indicates that the usermaps.xml file is not found. 043 */ 044 public SensorShellMap(String tool) throws SensorShellMapException { 045 // Ensure valid argument 046 if (tool == null || tool.length() == 0) { 047 throw new SensorShellMapException("Error: tool is null or empty string."); 048 } 049 this.tool = tool.trim(); 050 this.userMap = new UserMap(); 051 } 052 053 /** 054 * A package private constructor meant to be used only by Junit test cases. 055 * 056 * @param tool The specific tool that this SensorShellMap will provide SensorShells for. 057 * @param userMapFile The UserMap.xml file. 058 * @throws SensorShellMapException Indicates that the UserMap.xml file is not found. 059 */ 060 public SensorShellMap(String tool, File userMapFile) 061 throws SensorShellMapException { 062 this.tool = tool; 063 this.userMap = new UserMap(userMapFile); 064 } 065 066 /** 067 * Returns true if toolAccount is known so that a corresponding SensorShell can be retrieved. 068 * 069 * @param toolAccount The toolAccount for the tool in this instance, such as "johnson". 070 * @return True if toolAccount is known, otherwise false. 071 */ 072 public boolean hasUserShell(String toolAccount) { 073 if (toolAccount == null || toolAccount.length() == 0) { 074 return false; 075 } 076 else { 077 return this.userMap.hasUser(this.tool, toolAccount.trim()); 078 } 079 } 080 081 /** 082 * Returns the set of tool account names associated with this tool in the usermaps file. 083 * @param tool The tool of interest. 084 * @return The known tool account names for this tool. 085 */ 086 public Set<String> getToolAccounts(String tool) { 087 return this.userMap.getToolAccounts(tool); 088 } 089 090 /** 091 * Returns the UserMap file name associated with this SensorShellMap. 092 * This file may or may not exist. 093 * @return The usermap file name associated with this SensorShellMap. 094 */ 095 public String getUserMapFile() { 096 return this.userMap.getUserMapFile(); 097 } 098 099 /** 100 * Validates the hackystat user, password, and sensorbase associated with tool. 101 * Throws an exception if the sensorbase cannot be contacted and/or if the user/password 102 * combination is not valid for the associated sensorbase. 103 * @param tool The tool of interest. 104 * @throws SensorShellMapException Thrown if user map info cannot be validated. 105 */ 106 public void validateHackystatInfo(String tool) throws SensorShellMapException { 107 this.userMap.validateHackystatUsers(tool); 108 } 109 110 /** 111 * Gets the SensorShell instance for a Hackystat user with an account for the given tool. Assumes 112 * that toolAccount is known and will map to a userKey; use hasUserShell() to check whether this 113 * is true before calling this method. Instantiates the SensorShell instance if it is not yet 114 * available. 115 * 116 * @param toolAccount The name of the account for the given tool. This is not the same as the 117 * Hackystat account name although it may be the same. 118 * @return The SensorShell instance for the specific Hackystat user. 119 * @throws SensorShellMapException When the user account and/or tool is undefined. 120 */ 121 public SensorShell getUserShell(String toolAccount) throws SensorShellMapException { 122 return getUserShell(toolAccount, null); 123 } 124 125 /** 126 * Gets the SensorShell instance for a Hackystat user with an account for the given tool. Assumes 127 * that toolAccount is known and will map to a userKey; use hasUserShell() to check whether this 128 * is true before calling this method. Instantiates the SensorShell instance if it is not yet 129 * available. 130 * 131 * @param toolAccount The name of the account for the given tool. This is not the same as the 132 * Hackystat account name although it may be the same. 133 * @param properties A properties instance holding SensorShell properties to be used to 134 * initialize the underlying SensorShell if it requires instantiation. If null, then no 135 * additional properties are required. 136 * @return The SensorShell instance for the specific Hackystat user. 137 * @throws SensorShellMapException When the user account and/or tool is undefined. 138 */ 139 public SensorShell getUserShell(String toolAccount, Properties properties) 140 throws SensorShellMapException { 141 // Check argument that it is valid 142 if (toolAccount == null || toolAccount.length() == 0) { 143 throw new SensorShellMapException("Error: toolAccount is null or the empty string."); 144 } 145 String trimmedToolAccount = toolAccount.trim(); 146 try { 147 String user = this.userMap.get(this.tool, trimmedToolAccount, UserMapKey.USER); 148 String password = this.userMap.get(this.tool, trimmedToolAccount, UserMapKey.PASSWORD); 149 String host = this.userMap.get(this.tool, trimmedToolAccount, UserMapKey.SENSORBASE); 150 // If we haven't instantiated this shell yet, then do it now. 151 if (this.toolAccountsToShells.get(toolAccount) == null) { 152 // First, build the SensorShellProperties instance. 153 // If properties is null, then call the three arg constructor. otherwise pass them in. 154 // Note: properties do not override user preferences as set in sensorshell.properties. 155 SensorShellProperties sensorProps = (properties == null) ? 156 new SensorShellProperties(host, user, password) : 157 new SensorShellProperties(host, user, password, properties, false) ; 158 // Now, instantiate the non-interactive SensorShell. 159 SensorShell userShell = new SensorShell(sensorProps, false, this.tool + "-" + user); 160 this.toolAccountsToShells.put(trimmedToolAccount, userShell); 161 } 162 // Now return the SensorShell. 163 return this.toolAccountsToShells.get(trimmedToolAccount); 164 } 165 catch (Exception e) { 166 throw new SensorShellMapException("Error getting SensorShell for " + toolAccount, e); 167 } 168 } 169 }