Changeset 703 for trunk/LogicMail/src/org/logicprobe
- Timestamp:
- 09/06/10 16:04:52 (21 months ago)
- Location:
- trunk/LogicMail/src/org/logicprobe/LogicMail/model
- Files:
-
- 2 edited
-
MailManager.java (modified) (2 diffs)
-
MailRootNode.java (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LogicMail/src/org/logicprobe/LogicMail/model/MailManager.java
r701 r703 69 69 70 70 // Make sure the initial configuration is loaded 71 mailSettings_MailSettingsSaved(null);71 updateMailModelAccountList(); 72 72 73 73 // Register a listener for configuration changes 74 74 MailSettings.getInstance().addMailSettingsListener(new MailSettingsListener() { 75 75 public void mailSettingsSaved(MailSettingsEvent e) { 76 // This logic is rather crude, and will trigger a full refresh 77 // under a wide variety of circumstances. Its major intent is 78 // to avoid a refresh in a few situations where a minor 79 // configuration change affects future behavior and not 80 // current state. 81 82 boolean refreshAccounts = false; 83 // Trigger a refresh if either the account or outgoing list has changed 84 int listChange = e.getListChange(); 85 if((listChange & MailSettingsEvent.LIST_CHANGED_ACCOUNT) != 0 86 || (listChange & MailSettingsEvent.LIST_CHANGED_OUTGOING) != 0) { 87 refreshAccounts = true; 88 } 89 90 // Trigger a refresh if certain account settings have changed 91 if(!refreshAccounts) { 92 int num = mailSettings.getNumAccounts(); 93 for(int i=0; i<num; i++) { 94 AccountConfig accountConfig = mailSettings.getAccountConfig(i); 95 int accountChange = e.getConfigChange(accountConfig); 96 if((accountChange & AccountConfig.CHANGE_TYPE_NAME) != 0 97 || (accountChange & AccountConfig.CHANGE_TYPE_MAILBOXES) != 0 98 || (accountChange & AccountConfig.CHANGE_TYPE_OUTGOING) != 0) { 99 refreshAccounts = true; 100 break; 101 } 102 OutgoingConfig outgoingConfig = accountConfig.getOutgoingConfig(); 103 if(outgoingConfig != null 104 && (e.getConfigChange(outgoingConfig) & OutgoingConfig.CHANGE_TYPE_CONNECTION) != 0) { 105 refreshAccounts = true; 106 break; 107 } 108 } 109 } 110 111 // Trigger a refresh if appropriate 112 if(refreshAccounts) { 113 mailSettings_MailSettingsSaved(e); 114 refreshMailboxTypes(); 115 } 76 mailSettings_MailSettingsSaved(e); 116 77 } 117 78 }); … … 196 157 } 197 158 198 /** 199 * Called when the account configuration has changed, 200 * to cause the mail model to update its account list. 201 */ 202 private synchronized void mailSettings_MailSettingsSaved(MailSettingsEvent e) { 203 // Build the new account list from the configuration and 204 // the existing account nodes. This works by checking to see 205 // if an account already exists, and only creating new nodes 206 // for new accounts. 207 NetworkAccountNode[] existingAccounts = mailRootNode.getNetworkAccounts(); 208 Vector newAccounts = new Vector(); 209 210 int num = mailSettings.getNumAccounts(); 211 boolean accountExists; 212 for(int i=0; i<num; i++) { 213 AccountConfig accountConfig = mailSettings.getAccountConfig(i); 214 accountExists = false; 215 for(int j=0; j<existingAccounts.length; j++) { 216 if(accountConfig == existingAccounts[j].getAccountConfig()) { 217 accountExists = true; 218 newAccounts.addElement(existingAccounts[j]); 219 break; 220 } 221 } 222 if(!accountExists) { 223 AccountNode newAccountNode = new NetworkAccountNode((NetworkMailStore) MailFactory.createMailStore(accountConfig)); 224 newAccountNode.load(); 225 newAccounts.addElement(newAccountNode); 226 } 227 } 228 229 // Remove and replace all account nodes from the root node. 230 // This approach is taken to preserve any ordering which may 231 // have been changed in the configuration. 232 for(int i=0; i<existingAccounts.length; i++) { 233 mailRootNode.removeAccount(existingAccounts[i]); 234 } 235 num = newAccounts.size(); 236 for(int i=0; i<num; i++) { 237 mailRootNode.addAccount((NetworkAccountNode)newAccounts.elementAt(i)); 238 } 239 240 // Clear deleted accounts from the MailFactory and persistent storage 241 for(int i=0; i<existingAccounts.length; i++) { 242 boolean accountDeleted = true; 243 int size = newAccounts.size(); 244 for(int j=0; j<size; j++) { 245 AccountNode newAccount = (AccountNode)newAccounts.elementAt(j); 246 if(newAccount == existingAccounts[i]) { 247 accountDeleted = false; 248 break; 249 } 250 } 251 if(accountDeleted) { 252 existingAccounts[i].removeSavedData(); 253 MailFactory.clearMailStore(existingAccounts[i].getAccountConfig()); 254 } 255 } 256 257 // Get the newly updated account list, and determine whether 258 // we need to update any mail senders. 259 existingAccounts = mailRootNode.getNetworkAccounts(); 260 for(int i=0; i<existingAccounts.length; i++) { 261 NetworkAccountNode networkAccount = existingAccounts[i]; 262 AbstractMailSender mailSender = networkAccount.getMailSender(); 263 OutgoingConfig outgoingConfig = networkAccount.getAccountConfig().getOutgoingConfig(); 264 if(outgoingConfig == null) { 265 if(mailSender != null) { 266 mailSender.shutdown(false); 267 } 268 networkAccount.setMailSender(null); 269 } 270 else if((mailSender instanceof NetworkMailSender 271 &&((NetworkMailSender)mailSender).getOutgoingConfig() != outgoingConfig)) { 272 mailSender.shutdown(false); 273 networkAccount.setMailSender(MailFactory.createMailSender(networkAccount.getAccountConfig().getOutgoingConfig())); 274 } 275 else if(mailSender == null) { 276 networkAccount.setMailSender(MailFactory.createMailSender(networkAccount.getAccountConfig().getOutgoingConfig())); 277 } 278 } 279 280 //TODO: Clear deleted senders from the MailFactory 281 282 // Notify any listeners 283 fireMailConfigurationChanged(); 284 } 159 private void mailSettings_MailSettingsSaved(MailSettingsEvent e) { 160 // This logic is rather crude, and will trigger a full refresh 161 // under a wide variety of circumstances. Its major intent is 162 // to avoid a refresh in a few situations where a minor 163 // configuration change affects future behavior and not 164 // current state. 165 166 boolean shouldRefreshAccounts = 167 connectionListChanged(e) || accountChangeRequiringRefresh(e); 168 169 // Trigger a refresh if appropriate 170 if(shouldRefreshAccounts) { 171 updateMailModelAccountList(); 172 refreshMailboxTypes(); 173 } 174 } 175 176 private boolean connectionListChanged(MailSettingsEvent e) { 177 int listChange = e.getListChange(); 178 return (listChange & MailSettingsEvent.LIST_CHANGED_ACCOUNT) != 0 179 || (listChange & MailSettingsEvent.LIST_CHANGED_OUTGOING) != 0; 180 } 181 182 private boolean accountChangeRequiringRefresh(MailSettingsEvent e) { 183 boolean refreshRequired = false; 184 int num = mailSettings.getNumAccounts(); 185 for(int i=0; i<num; i++) { 186 AccountConfig accountConfig = mailSettings.getAccountConfig(i); 187 int accountChange = e.getConfigChange(accountConfig); 188 if((accountChange & AccountConfig.CHANGE_TYPE_NAME) != 0 189 || (accountChange & AccountConfig.CHANGE_TYPE_MAILBOXES) != 0 190 || (accountChange & AccountConfig.CHANGE_TYPE_OUTGOING) != 0) { 191 refreshRequired = true; 192 break; 193 } 194 OutgoingConfig outgoingConfig = accountConfig.getOutgoingConfig(); 195 if(outgoingConfig != null 196 && (e.getConfigChange(outgoingConfig) & OutgoingConfig.CHANGE_TYPE_CONNECTION) != 0) { 197 refreshRequired = true; 198 break; 199 } 200 } 201 return refreshRequired; 202 } 203 204 /** 205 * Called when the account configuration has changed, 206 * to cause the mail model to update its account list. 207 */ 208 private synchronized void updateMailModelAccountList() { 209 // Build the new account list from the configuration and 210 // the existing account nodes. This works by checking to see 211 // if an account already exists, and only creating new nodes 212 // for new accounts. 213 NetworkAccountNode[] existingAccounts = mailRootNode.getNetworkAccounts(); 214 NetworkAccountNode[] newAccounts = getNewNetworkAccountNodes(existingAccounts); 215 216 // Remove and replace all account nodes from the root node. 217 // This approach is taken to preserve any ordering which may 218 // have been changed in the configuration. 219 mailRootNode.removeAccounts(existingAccounts); 220 mailRootNode.addAccounts(newAccounts); 221 222 // Clear deleted accounts from the MailFactory and persistent storage 223 clearDeletedAccounts(existingAccounts, newAccounts); 224 225 // Get the newly updated account list, and determine whether 226 // we need to update any mail senders. 227 NetworkAccountNode[] updatedAccounts = mailRootNode.getNetworkAccounts(); 228 updateAccountMailSenders(updatedAccounts); 229 230 //TODO: Clear deleted senders from the MailFactory 231 232 // Notify any listeners 233 fireMailConfigurationChanged(); 234 } 235 236 private NetworkAccountNode[] getNewNetworkAccountNodes(NetworkAccountNode[] existingAccounts) { 237 Vector newAccounts = new Vector(); 238 239 int num = mailSettings.getNumAccounts(); 240 boolean accountExists; 241 for(int i=0; i<num; i++) { 242 AccountConfig accountConfig = mailSettings.getAccountConfig(i); 243 accountExists = false; 244 for(int j=0; j<existingAccounts.length; j++) { 245 if(accountConfig == existingAccounts[j].getAccountConfig()) { 246 accountExists = true; 247 newAccounts.addElement(existingAccounts[j]); 248 break; 249 } 250 } 251 if(!accountExists) { 252 AccountNode newAccountNode = new NetworkAccountNode((NetworkMailStore) MailFactory.createMailStore(accountConfig)); 253 newAccountNode.load(); 254 newAccounts.addElement(newAccountNode); 255 } 256 } 257 NetworkAccountNode[] newAccountsArray = new NetworkAccountNode[newAccounts.size()]; 258 newAccounts.copyInto(newAccountsArray); 259 return newAccountsArray; 260 } 261 262 private void clearDeletedAccounts(NetworkAccountNode[] existingAccounts, NetworkAccountNode[] newAccounts) { 263 for(int i=0; i<existingAccounts.length; i++) { 264 boolean accountDeleted = true; 265 for(int j=0; j<newAccounts.length; j++) { 266 NetworkAccountNode newAccount = newAccounts[j]; 267 if(newAccount == existingAccounts[i]) { 268 accountDeleted = false; 269 break; 270 } 271 } 272 if(accountDeleted) { 273 existingAccounts[i].removeSavedData(); 274 MailFactory.clearMailStore(existingAccounts[i].getAccountConfig()); 275 } 276 } 277 } 278 279 private void updateAccountMailSenders(NetworkAccountNode[] updatedAccounts) { 280 for(int i=0; i<updatedAccounts.length; i++) { 281 NetworkAccountNode networkAccount = updatedAccounts[i]; 282 AbstractMailSender mailSender = networkAccount.getMailSender(); 283 OutgoingConfig outgoingConfig = networkAccount.getAccountConfig().getOutgoingConfig(); 284 if(outgoingConfig == null) { 285 if(mailSender != null) { 286 mailSender.shutdown(false); 287 } 288 networkAccount.setMailSender(null); 289 } 290 else if((mailSender instanceof NetworkMailSender 291 &&((NetworkMailSender)mailSender).getOutgoingConfig() != outgoingConfig)) { 292 mailSender.shutdown(false); 293 networkAccount.setMailSender(MailFactory.createMailSender(networkAccount.getAccountConfig().getOutgoingConfig())); 294 } 295 else if(mailSender == null) { 296 networkAccount.setMailSender(MailFactory.createMailSender(networkAccount.getAccountConfig().getOutgoingConfig())); 297 } 298 } 299 } 285 300 286 301 /** -
trunk/LogicMail/src/org/logicprobe/LogicMail/model/MailRootNode.java
r701 r703 44 44 public class MailRootNode implements Node { 45 45 private LocalAccountNode localAccountNode; 46 private final Vector networkAccounts; 47 private AccountNode[] accountsArray; 48 private NetworkAccountNode[] networkAccountsArray; 49 private final Object accountsLock = new Object(); 50 51 public MailRootNode() { 52 this.networkAccounts = new Vector(); 46 private final Vector networkAccounts; 47 private AccountNode[] accountsArray; 48 private NetworkAccountNode[] networkAccountsArray; 49 private final Object accountsLock = new Object(); 53 50 54 // Add the local mail store account 55 localAccountNode = new LocalAccountNode((LocalMailStore) MailFactory.createLocalMailStore()); 56 localAccountNode.load(); 57 } 58 59 public void accept(NodeVisitor visitor) { 60 visitor.visit(this); 61 } 51 public MailRootNode() { 52 this.networkAccounts = new Vector(); 62 53 63 /** 64 * Get the accounts contained within the mail data model. 65 * This method returns an array that is a shallow copy of the 66 * live accounts list. Since multiple calls to this method 67 * may return the same instance of that array, it should 68 * not be modified by callers. 69 * 70 * @return Account nodes. 71 */ 72 public AccountNode[] getAccounts() { 73 // Since this method is used quite frequently, a reference to the 74 // temporary snapshot array is kept. It is only recreated if the 75 // accounts vector is modified. 76 synchronized(accountsLock) { 77 if(accountsArray == null) { 78 int size = networkAccounts.size(); 79 accountsArray = new AccountNode[size + 1]; 80 accountsArray[0] = localAccountNode; 81 for(int i=0; i<size; i++) { 82 accountsArray[i + 1] = (AccountNode)networkAccounts.elementAt(i); 83 } 84 } 85 } 86 return accountsArray; 87 } 88 54 // Add the local mail store account 55 localAccountNode = new LocalAccountNode((LocalMailStore) MailFactory.createLocalMailStore()); 56 localAccountNode.load(); 57 } 58 59 public void accept(NodeVisitor visitor) { 60 visitor.visit(this); 61 } 62 63 /** 64 * Get the accounts contained within the mail data model. 65 * This method returns an array that is a shallow copy of the 66 * live accounts list. Since multiple calls to this method 67 * may return the same instance of that array, it should 68 * not be modified by callers. 69 * 70 * @return Account nodes. 71 */ 72 public AccountNode[] getAccounts() { 73 // Since this method is used quite frequently, a reference to the 74 // temporary snapshot array is kept. It is only recreated if the 75 // accounts vector is modified. 76 synchronized(accountsLock) { 77 if(accountsArray == null) { 78 int size = networkAccounts.size(); 79 accountsArray = new AccountNode[size + 1]; 80 accountsArray[0] = localAccountNode; 81 for(int i=0; i<size; i++) { 82 accountsArray[i + 1] = (AccountNode)networkAccounts.elementAt(i); 83 } 84 } 85 } 86 return accountsArray; 87 } 88 89 89 /** 90 90 * Get the network accounts contained within the mail data model. … … 96 96 * @return Network account nodes. 97 97 */ 98 public NetworkAccountNode[] getNetworkAccounts() {98 public NetworkAccountNode[] getNetworkAccounts() { 99 99 // Since this method is used quite frequently, a reference to the 100 100 // temporary snapshot array is kept. It is only recreated if the … … 108 108 } 109 109 return networkAccountsArray; 110 } 111 112 /** 113 * Find the account node matching the provided account configuration. 114 * This is a convenience method for a relatively common operation. 115 * 116 * @param accountConfig the account configuration 117 * @return the network account node, or null if none found 118 */ 119 public NetworkAccountNode findAccountForConfig(AccountConfig accountConfig) { 120 NetworkAccountNode[] networkAccounts = getNetworkAccounts(); 121 for(int i=0; i<networkAccounts.length; i++) { 122 if(accountConfig.equals(networkAccounts[i].getAccountConfig())) { 123 return networkAccounts[i]; 124 } 125 } 126 return null; 127 } 128 129 /** 130 * Gets the account node representing the local mail folders. 131 * 132 * @return Local account node. 133 */ 134 public LocalAccountNode getLocalAccount() { 135 return localAccountNode; 136 } 137 138 /** 139 * Adds a network account to the mail data model. 140 * The account is appended to the end of the 141 * live accounts list. 142 * 143 * @param account The account to add. 144 */ 145 void addAccount(NetworkAccountNode account) { 146 synchronized(accountsLock) { 147 if(!networkAccounts.contains(account)) { 148 networkAccounts.addElement(account); 149 accountsArray = null; 150 networkAccountsArray = null; 151 } 152 } 153 } 154 155 /** 156 * Removes a network account from the mail data model. 157 * 158 * @param account The account to remove 159 */ 160 void removeAccount(NetworkAccountNode account) { 161 synchronized(accountsLock) { 162 if(networkAccounts.contains(account)) { 163 networkAccounts.removeElement(account); 164 accountsArray = null; 165 networkAccountsArray = null; 166 } 167 } 168 } 110 } 111 112 /** 113 * Find the account node matching the provided account configuration. 114 * This is a convenience method for a relatively common operation. 115 * 116 * @param accountConfig the account configuration 117 * @return the network account node, or null if none found 118 */ 119 public NetworkAccountNode findAccountForConfig(AccountConfig accountConfig) { 120 NetworkAccountNode[] networkAccounts = getNetworkAccounts(); 121 for(int i=0; i<networkAccounts.length; i++) { 122 if(accountConfig.equals(networkAccounts[i].getAccountConfig())) { 123 return networkAccounts[i]; 124 } 125 } 126 return null; 127 } 128 129 /** 130 * Gets the account node representing the local mail folders. 131 * 132 * @return Local account node. 133 */ 134 public LocalAccountNode getLocalAccount() { 135 return localAccountNode; 136 } 137 138 /** 139 * Adds a network account to the mail data model. 140 * The account is appended to the end of the 141 * live accounts list. 142 * 143 * @param account The account to add. 144 */ 145 void addAccount(NetworkAccountNode account) { 146 synchronized(accountsLock) { 147 if(!networkAccounts.contains(account)) { 148 networkAccounts.addElement(account); 149 accountsArray = null; 150 networkAccountsArray = null; 151 } 152 } 153 } 154 155 /** 156 * Adds a collection of network account to the mail data model. 157 * 158 * @param accounts The accounts to add. 159 */ 160 void addAccounts(NetworkAccountNode[] accounts) { 161 synchronized(accountsLock) { 162 for(int i=0; i<accounts.length; i++) { 163 addAccount(accounts[i]); 164 } 165 } 166 } 167 168 /** 169 * Removes a network account from the mail data model. 170 * 171 * @param account The account to remove. 172 */ 173 void removeAccount(NetworkAccountNode account) { 174 synchronized(accountsLock) { 175 if(networkAccounts.contains(account)) { 176 networkAccounts.removeElement(account); 177 accountsArray = null; 178 networkAccountsArray = null; 179 } 180 } 181 } 182 183 /** 184 * Removes a collection of network accounts from the mail data model. 185 * 186 * @param accounts The accounts to remove. 187 */ 188 void removeAccounts(NetworkAccountNode[] accounts) { 189 synchronized(accountsLock) { 190 for(int i=0; i<accounts.length; i++) { 191 removeAccount(accounts[i]); 192 } 193 } 194 } 169 195 }
Note: See TracChangeset
for help on using the changeset viewer.
