Changeset 266
- Timestamp:
- 08/04/08 09:17:20 PM (4 months ago)
- Location:
- trunk/LogicMail/src/org/logicprobe/LogicMail
- Files:
-
- 7 modified
-
mail/AbstractMailConnectionHandler.java (modified) (2 diffs)
-
mail/imap/ImapClient.java (modified) (2 diffs)
-
mail/imap/ImapProtocol.java (modified) (3 diffs)
-
mail/IncomingMailClient.java (modified) (2 diffs)
-
mail/IncomingMailConnectionHandler.java (modified) (2 diffs)
-
mail/pop/PopClient.java (modified) (2 diffs)
-
util/Connection.java (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LogicMail/src/org/logicprobe/LogicMail/mail/AbstractMailConnectionHandler.java
r253 r266 315 315 * a new request arrives, or it is commanded to shutdown. 316 316 * </p> 317 */ 318 protected abstract void handleBeginIdle(); 317 * 318 * @throw IOException on I/O errors 319 * @throw MailException on protocol errors 320 */ 321 protected abstract void handleBeginIdle() throws IOException, MailException; 319 322 320 323 /** … … 373 376 protected Queue getRequestQueue() { 374 377 return this.requestQueue; 378 } 379 380 /** 381 * Gets whether a shutdown is currently in progress. 382 * @return True if shutdown is in progress. 383 */ 384 protected boolean getShutdownInProgress() { 385 return this.shutdownInProgress; 386 } 387 388 /** 389 * Sleep the connection thread. 390 * @param time Time to sleep, in milliseconds. 391 */ 392 protected void sleepConnectionThread(long time) { 393 if(!connectionThread.isShutdown()) { 394 try { 395 ConnectionThread.sleep(time); 396 } catch (InterruptedException e) { } 397 } 375 398 } 376 399 -
trunk/LogicMail/src/org/logicprobe/LogicMail/mail/imap/ImapClient.java
r264 r266 269 269 return true; 270 270 } 271 272 public boolean hasIdle() { 273 return true; 274 } 271 275 272 276 public FolderTreeItem getFolderTree() throws IOException, MailException { … … 575 579 imapProtocol.executeAppend(folder.getPath(), rawMessage, flags); 576 580 } 581 582 public void idleModeBegin() throws IOException, MailException { 583 imapProtocol.executeIdle(); 584 } 585 586 public void idleModeEnd() throws IOException, MailException { 587 imapProtocol.executeIdleDone(); 588 } 589 590 public boolean idleModePoll() throws IOException, MailException { 591 return imapProtocol.executeIdlePoll(); 592 } 577 593 } -
trunk/LogicMail/src/org/logicprobe/LogicMail/mail/imap/ImapProtocol.java
r264 r266 48 48 public class ImapProtocol { 49 49 private Connection connection; 50 private String idleCommandTag; 50 51 51 52 /** … … 889 890 890 891 /** 892 * Execute the "IDLE" command. 893 */ 894 public void executeIdle() throws IOException, MailException { 895 if(EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 896 EventLogger.logEvent( 897 AppInfo.GUID, 898 ("ImapProtocol.executeIdle()").getBytes(), 899 EventLogger.DEBUG_INFO); 900 } 901 idleCommandTag = executeNoReply("IDLE", null); 902 } 903 904 /** 905 * Execute the "DONE" command. 906 */ 907 public void executeIdleDone() throws IOException, MailException { 908 if(EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 909 EventLogger.logEvent( 910 AppInfo.GUID, 911 ("ImapProtocol.executeIdleDone()").getBytes(), 912 EventLogger.DEBUG_INFO); 913 } 914 executeUntagged("DONE", null, idleCommandTag); 915 idleCommandTag = null; 916 } 917 918 /** 919 * Polls the connection during the IDLE state. 920 * For now, this is a simple implementation. It just checks for 921 * the presence of a "+ ?? recent" untagged response, and returns 922 * true if one is found. 923 */ 924 public boolean executeIdlePoll() throws IOException, MailException { 925 String result = receive(); 926 if(result != null && result.startsWith("*") && result.toLowerCase().endsWith("recent")) { 927 return true; 928 } 929 else { 930 return false; 931 } 932 } 933 934 /** 891 935 * Executes an IMAP command several times, with different arguments, 892 936 * and return the replies as an array of strings. … … 1006 1050 return result; 1007 1051 } 1052 1053 /** 1054 * Attempts to read a line of text from the server, without sending 1055 * anything first. 1056 * @return Returned string, or null if nothing is available 1057 */ 1058 protected String receive() 1059 throws IOException, MailException 1060 { 1061 String result; 1062 1063 if(connection.available() > 0) { 1064 System.err.println("-->connection.available() == " + connection.available()); 1065 result = connection.receive(); 1066 System.err.println("-->Read in "+result.length()); 1067 System.err.println("-->connection.available() == " + connection.available()); 1068 } 1069 else { 1070 result = null; 1071 } 1072 return result; 1073 } 1074 1075 /** 1076 * Executes an IMAP command directly and expects no reply. 1077 * @param command IMAP command 1078 * @param arguments Arguments for the command 1079 * @return Tag used to send the command 1080 */ 1081 protected String executeNoReply(String command, String arguments) 1082 throws IOException, MailException 1083 { 1084 String tag = "A" + commandCount++ + " "; 1085 connection.sendCommand(tag + command + (arguments == null ? "" : " " + arguments)); 1086 1087 return tag; 1088 } 1089 1090 /** 1091 * Executes an IMAP command without a tag prefix, 1092 * and returns the reply as an array of strings. 1093 * @param command IMAP command 1094 * @param arguments Arguments for the command 1095 * @param Known tag that indicates the end of the result 1096 * @return List of returned strings 1097 */ 1098 protected String[] executeUntagged(String command, String arguments, String endTag) 1099 throws IOException, MailException 1100 { 1101 String[] result = new String[0]; 1102 1103 connection.sendCommand(command + (arguments == null ? "" : " " + arguments)); 1104 1105 String temp = connection.receive(); 1106 while (!temp.startsWith(endTag)) { 1107 Arrays.add(result, temp); 1108 temp = connection.receive(); 1109 } 1110 1111 temp = temp.substring(endTag.length()); 1112 if (temp.startsWith("BAD ") || temp.startsWith("NO ")) { 1113 throw new MailException(temp); 1114 } 1115 return result; 1116 } 1008 1117 } -
trunk/LogicMail/src/org/logicprobe/LogicMail/mail/IncomingMailClient.java
r264 r266 69 69 70 70 /** 71 * Return whether the underlying protocol supports an idle connection mode. 72 * 73 * @return True if an idle mode is supported, false otherwise 74 */ 75 public abstract boolean hasIdle(); 76 77 /** 71 78 * Get the mail folder tree. 72 79 * This should return null if folders are not supported … … 173 180 */ 174 181 public abstract void undeleteMessage(FolderMessage folderMessage) throws IOException, MailException; 182 183 /** 184 * Begins the idle mode for the underlying protocol. 185 * This should do nothing if the underlying protocol does not support idling. 186 * 187 * @throws IOException on I/O errors 188 * @throws MailException on protocol errors 189 */ 190 public abstract void idleModeBegin() throws IOException, MailException; 191 192 /** 193 * Ends the idle mode for the underlying protocol. 194 * This should do nothing if the underlying protocol does not support idling. 195 * 196 * @throws IOException on I/O errors 197 * @throws MailException on protocol errors 198 */ 199 public abstract void idleModeEnd() throws IOException, MailException; 200 201 /** 202 * Polls the connecting during the idle mode for the underlying protocol. 203 * This should do nothing if the underlying protocol does not support idling. 204 * 205 * @return True if the mailbox has new data, false otherwise. 206 * @throws IOException on I/O errors 207 * @throws MailException on protocol errors 208 */ 209 public abstract boolean idleModePoll() throws IOException, MailException; 175 210 } -
trunk/LogicMail/src/org/logicprobe/LogicMail/mail/IncomingMailConnectionHandler.java
r264 r266 39 39 import org.logicprobe.LogicMail.message.Message; 40 40 import org.logicprobe.LogicMail.message.MessageFlags; 41 import org.logicprobe.LogicMail.util.Queue; 41 42 42 43 public class IncomingMailConnectionHandler extends AbstractMailConnectionHandler { … … 113 114 * Handles the start of the IDLE state. 114 115 */ 115 protected void handleBeginIdle() { 116 protected void handleBeginIdle() throws IOException, MailException { 117 if(incomingClient.hasIdle()) { 118 incomingClient.idleModeBegin(); 119 boolean endIdle = false; 120 while(!endIdle) { 121 sleepConnectionThread(500); 122 if(incomingClient.idleModePoll()) { 123 addRequest( 124 IncomingMailConnectionHandler.REQUEST_FOLDER_MESSAGES_RECENT, 125 new Object[] { incomingClient.getActiveFolder() }); 126 endIdle = true; 127 } 128 else if(getShutdownInProgress()) { 129 endIdle = true; 130 } 131 else 132 { 133 Queue requestQueue = getRequestQueue(); 134 synchronized(requestQueue) { 135 if(requestQueue.element() != null) { 136 endIdle = true; 137 } 138 } 139 } 140 } 141 incomingClient.idleModeEnd(); 142 } 116 143 } 117 144 -
trunk/LogicMail/src/org/logicprobe/LogicMail/mail/pop/PopClient.java
r264 r266 210 210 } 211 211 212 public boolean hasIdle() { 213 return false; 214 } 215 212 216 public FolderTreeItem getFolderTree() throws IOException, MailException { 213 217 return null; … … 336 340 // Undelete is not supported, so we do nothing here. 337 341 } 342 343 public void idleModeBegin() throws IOException, MailException { 344 // Idle mode is not supported, so we do nothing here. 345 } 346 347 public void idleModeEnd() throws IOException, MailException { 348 // Idle mode is not supported, so we do nothing here. 349 } 350 351 public boolean idleModePoll() throws IOException, MailException { 352 // Idle mode is not supported, so we do nothing here. 353 return false; 354 } 338 355 } -
trunk/LogicMail/src/org/logicprobe/LogicMail/util/Connection.java
r209 r266 103 103 protected OutputStream output; 104 104 private boolean useWiFi; 105 private int fakeAvailable = -1; 105 106 106 107 /** … … 114 115 private byte[] buffer = new byte[128]; 115 116 116 /**117 * Holds the actual number of bytes in the buffer.118 */119 private int count;120 121 117 /** 122 118 * Holds a list of open connections … … 150 146 151 147 String protocolStr = (useSSL ? "ssl" : "socket"); 152 // This param , which allows bypassing the MDS proxy, should probably148 // This parameter, which allows bypassing the MDS proxy, should probably 153 149 // be a global user configurable option 154 150 String paramStr = (deviceSide ? ";deviceside=true" : ""); … … 287 283 * Sends a string to the server. This method is used internally for 288 284 * all outgoing communication to the server. The main thing it does 289 * it terminate the line with a CR/LF. If there are occur ences of CR or285 * it terminate the line with a CR/LF. If there are occurrences of CR or 290 286 * LF inside the string, the method ensures that proper CR/LF sequences 291 * are sent for them, since this is what most internet protocols expect.287 * are sent for them, since this is what most Internet protocols expect. 292 288 * 293 289 * @see #receive … … 316 312 317 313 /** 318 * Find next occur ence of a line separator or the end of the314 * Find next occurrence of a line separator or the end of the 319 315 * string. 320 316 */ … … 384 380 } 385 381 382 /** 383 * Returns the number of bytes available for reading. 384 * Used to poll the connection without blocking. 385 * 386 * @see InputStream#available() 387 */ 388 public int available() throws IOException { 389 if(fakeAvailable == -1) { 390 return input.available(); 391 } 392 else { 393 return fakeAvailable; 394 } 395 } 396 386 397 /** 387 398 * Receives a string from the server. This method is used internally for … … 403 414 * characters belonging to a line were read. The result was 404 415 * a high level of heap fragmentation, which made applications 405 * instable on MIDP devices (that don't provide compacting GC,416 * unstable on MIDP devices (that don't provide compacting GC, 406 417 * that is). 407 418 * … … 423 434 StringBuffer resultBuffer = new StringBuffer(); 424 435 boolean stop = false; 436 int actualAvailable = input.available(); 437 int readBytes = 0; 438 int count; 425 439 426 440 /** … … 470 484 */ 471 485 // Note: We really should look for CRLF, and not use this 472 // half-assed approach which screws up on mid-lime LFs. (DK)486 // approach which screws up on mid-line LFs. (DK) 473 487 else { 474 488 byte b = buffer[count]; 489 readBytes++; 475 490 476 491 /** … … 504 519 EventLogger.logEvent(AppInfo.GUID, ("[RECV] " + resultBuffer.toString()).getBytes(), EventLogger.DEBUG_INFO); 505 520 } 521 if(actualAvailable > readBytes) { 522 fakeAvailable = actualAvailable - readBytes; 523 } 524 else { 525 fakeAvailable = -1; 526 } 506 527 507 528 return resultBuffer.toString();
