- Timestamp:
- 08/19/08 08:34:23 PM (5 months ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
trunk/LogicMail/src/org/logicprobe/LogicMail/mail/imap/ImapParser.java
r262 r275 8 8 * 9 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer. 11 11 * 2. Redistributions in binary form must reproduce the above copyright 12 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution. 14 14 * 3. Neither the name of the project nor the names of its 15 15 * contributors may be used to endorse or promote products derived … … 29 29 * OF THE POSSIBILITY OF SUCH DAMAGE. 30 30 */ 31 32 31 package org.logicprobe.LogicMail.mail.imap; 33 32 34 import java.io.UnsupportedEncodingException;35 import java.util.Calendar;36 import java.util.Vector;37 33 import net.rim.device.api.system.EventLogger; 34 38 35 import org.logicprobe.LogicMail.AppInfo; 39 36 import org.logicprobe.LogicMail.message.MessageEnvelope; 40 37 import org.logicprobe.LogicMail.util.StringParser; 38 39 import java.io.UnsupportedEncodingException; 40 41 import java.util.Calendar; 42 import java.util.Vector; 43 41 44 42 45 /** … … 45 48 */ 46 49 class ImapParser { 47 /**48 * Simple container for a parsed message structure tree49 */50 public static class MessageSection {51 public String address;52 public String type;53 public String subtype;54 public String encoding;55 public String charset;56 public int size;57 public MessageSection[] subsections;58 }59 60 private ImapParser() { }61 62 50 private static String strNIL = "NIL"; 63 51 private static final String MODIFIED_BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,"; 52 53 private ImapParser() { 54 } 55 64 56 static ImapProtocol.MessageFlags parseMessageFlags(Vector flagsVec) { 65 57 ImapProtocol.MessageFlags flags = new ImapProtocol.MessageFlags(); 66 58 67 59 String text; 68 60 int size = flagsVec.size(); 69 for(int i = 0; i < size; i++) { 70 if(flagsVec.elementAt(i) instanceof String) { 71 text = (String)flagsVec.elementAt(i); 72 if(text.equalsIgnoreCase("\\Seen")) { 61 62 for (int i = 0; i < size; i++) { 63 if (flagsVec.elementAt(i) instanceof String) { 64 text = (String) flagsVec.elementAt(i); 65 66 if (text.equalsIgnoreCase("\\Seen")) { 73 67 flags.seen = true; 74 } 75 else if(text.equalsIgnoreCase("\\Answered")) { 68 } else if (text.equalsIgnoreCase("\\Answered")) { 76 69 flags.answered = true; 77 } 78 else if(text.equalsIgnoreCase("\\Flagged")) { 70 } else if (text.equalsIgnoreCase("\\Flagged")) { 79 71 flags.flagged = true; 80 } 81 else if(text.equalsIgnoreCase("\\Deleted")) { 72 } else if (text.equalsIgnoreCase("\\Deleted")) { 82 73 flags.deleted = true; 83 } 84 else if(text.equalsIgnoreCase("\\Draft")) { 74 } else if (text.equalsIgnoreCase("\\Draft")) { 85 75 flags.draft = true; 86 } 87 else if(text.equalsIgnoreCase("\\Recent")) { 76 } else if (text.equalsIgnoreCase("\\Recent")) { 88 77 flags.recent = true; 89 } 90 else if(text.equalsIgnoreCase("Junk") ||text.equalsIgnoreCase("$Junk")) {78 } else if (text.equalsIgnoreCase("Junk") || 79 text.equalsIgnoreCase("$Junk")) { 91 80 flags.junk = true; 92 81 } 93 82 } 94 83 } 84 95 85 return flags; 96 86 } … … 98 88 static String createMessageFlagsString(ImapProtocol.MessageFlags flags) { 99 89 StringBuffer buf = new StringBuffer(); 100 if(flags.seen) { 90 91 if (flags.seen) { 101 92 buf.append("\\Seen"); 102 93 } 103 if(flags.answered) { 104 if(buf.length() > 0) { buf.append(' '); } 94 95 if (flags.answered) { 96 if (buf.length() > 0) { 97 buf.append(' '); 98 } 99 105 100 buf.append("\\Answered"); 106 101 } 107 if(flags.flagged) { 108 if(buf.length() > 0) { buf.append(' '); } 102 103 if (flags.flagged) { 104 if (buf.length() > 0) { 105 buf.append(' '); 106 } 107 109 108 buf.append("\\Flagged"); 110 109 } 111 if(flags.deleted) { 112 if(buf.length() > 0) { buf.append(' '); } 110 111 if (flags.deleted) { 112 if (buf.length() > 0) { 113 buf.append(' '); 114 } 115 113 116 buf.append("\\Deleted"); 114 117 } 115 if(flags.draft) { 116 if(buf.length() > 0) { buf.append(' '); } 118 119 if (flags.draft) { 120 if (buf.length() > 0) { 121 buf.append(' '); 122 } 123 117 124 buf.append("\\Draft"); 118 125 } 119 if(flags.recent) { 120 if(buf.length() > 0) { buf.append(' '); } 126 127 if (flags.recent) { 128 if (buf.length() > 0) { 129 buf.append(' '); 130 } 131 121 132 buf.append("\\Recent"); 122 133 } 134 123 135 return buf.toString(); 124 136 } 125 137 126 138 static MessageEnvelope parseMessageEnvelope(Vector parsedEnv) { 127 139 // Sanity checking 128 if (parsedEnv.size() < 10) {129 EventLogger.logEvent(130 AppInfo.GUID,131 "ImapParser.parseMessageEnvelope: Sanity check failed".getBytes(),132 EventLogger.WARNING); 133 return generateDummyEnvelope();134 } 135 140 if (parsedEnv.size() < 10) { 141 EventLogger.logEvent(AppInfo.GUID, 142 "ImapParser.parseMessageEnvelope: Sanity check failed".getBytes(), 143 EventLogger.WARNING); 144 145 return generateDummyEnvelope(); 146 } 147 136 148 MessageEnvelope env = new MessageEnvelope(); 137 149 138 if (parsedEnv.elementAt(0) instanceof String) {150 if (parsedEnv.elementAt(0) instanceof String) { 139 151 try { 140 env.date = StringParser.parseDateString((String)parsedEnv.elementAt(0)); 152 env.date = StringParser.parseDateString((String) parsedEnv.elementAt( 153 0)); 141 154 } catch (Exception e) { 142 155 env.date = Calendar.getInstance().getTime(); 143 156 } 144 157 } 145 146 if(parsedEnv.elementAt(1) instanceof String) { 147 env.subject = StringParser.parseEncodedHeader((String)parsedEnv.elementAt(1)); 148 } 149 150 if(parsedEnv.elementAt(2) instanceof Vector) { 151 env.from = parseAddressList((Vector)parsedEnv.elementAt(2)); 152 } 153 154 if(parsedEnv.elementAt(3) instanceof Vector) { 155 env.sender = parseAddressList((Vector)parsedEnv.elementAt(3)); 156 } 157 158 if(parsedEnv.elementAt(4) instanceof Vector) { 159 env.replyTo = parseAddressList((Vector)parsedEnv.elementAt(4)); 160 } 161 162 if(parsedEnv.elementAt(5) instanceof Vector) { 163 env.to = parseAddressList((Vector)parsedEnv.elementAt(5)); 164 } 165 166 if(parsedEnv.elementAt(6) instanceof Vector) { 167 env.cc = parseAddressList((Vector)parsedEnv.elementAt(6)); 168 } 169 170 if(parsedEnv.elementAt(7) instanceof Vector) { 171 env.bcc = parseAddressList((Vector)parsedEnv.elementAt(7)); 172 } 173 174 if(parsedEnv.elementAt(8) instanceof String) { 175 env.inReplyTo = (String)parsedEnv.elementAt(8); 176 if(env.inReplyTo.equals(strNIL)) { 158 159 if (parsedEnv.elementAt(1) instanceof String) { 160 env.subject = StringParser.parseEncodedHeader((String) parsedEnv.elementAt( 161 1)); 162 } 163 164 if (parsedEnv.elementAt(2) instanceof Vector) { 165 env.from = parseAddressList((Vector) parsedEnv.elementAt(2)); 166 } 167 168 if (parsedEnv.elementAt(3) instanceof Vector) { 169 env.sender = parseAddressList((Vector) parsedEnv.elementAt(3)); 170 } 171 172 if (parsedEnv.elementAt(4) instanceof Vector) { 173 env.replyTo = parseAddressList((Vector) parsedEnv.elementAt(4)); 174 } 175 176 if (parsedEnv.elementAt(5) instanceof Vector) { 177 env.to = parseAddressList((Vector) parsedEnv.elementAt(5)); 178 } 179 180 if (parsedEnv.elementAt(6) instanceof Vector) { 181 env.cc = parseAddressList((Vector) parsedEnv.elementAt(6)); 182 } 183 184 if (parsedEnv.elementAt(7) instanceof Vector) { 185 env.bcc = parseAddressList((Vector) parsedEnv.elementAt(7)); 186 } 187 188 if (parsedEnv.elementAt(8) instanceof String) { 189 env.inReplyTo = (String) parsedEnv.elementAt(8); 190 191 if (env.inReplyTo.equals(strNIL)) { 177 192 env.inReplyTo = ""; 178 193 } 179 194 } 180 195 181 if(parsedEnv.elementAt(9) instanceof String) { 182 env.messageId = (String)parsedEnv.elementAt(9); 183 if(env.messageId.equals(strNIL)) { 196 if (parsedEnv.elementAt(9) instanceof String) { 197 env.messageId = (String) parsedEnv.elementAt(9); 198 199 if (env.messageId.equals(strNIL)) { 184 200 env.messageId = ""; 185 201 } 186 202 } 203 187 204 return env; 188 205 } … … 192 209 String[] addrList = new String[addrVec.size()]; 193 210 int index = 0; 194 195 for(int i=0;i<addrVec.size();i++) { 196 if((addrVec.elementAt(i) instanceof Vector) && 197 ((Vector)addrVec.elementAt(i)).size() >= 4) { 198 199 Vector entry = (Vector)addrVec.elementAt(i); 211 212 for (int i = 0; i < addrVec.size(); i++) { 213 if ((addrVec.elementAt(i) instanceof Vector) && 214 (((Vector) addrVec.elementAt(i)).size() >= 4)) { 215 Vector entry = (Vector) addrVec.elementAt(i); 200 216 201 217 String realName = strNIL; 202 if(entry.elementAt(0) instanceof String) { 203 realName = StringParser.parseEncodedHeader((String)entry.elementAt(0)); 218 219 if (entry.elementAt(0) instanceof String) { 220 realName = StringParser.parseEncodedHeader((String) entry.elementAt( 221 0)); 204 222 } 205 223 206 224 String mbName = strNIL; 207 if(entry.elementAt(2) instanceof String) { 208 mbName = (String)entry.elementAt(2); 225 226 if (entry.elementAt(2) instanceof String) { 227 mbName = (String) entry.elementAt(2); 209 228 } 210 229 211 230 String hostName = strNIL; 212 if(entry.elementAt(3) instanceof String) { 213 hostName = (String)entry.elementAt(3); 214 } 231 232 if (entry.elementAt(3) instanceof String) { 233 hostName = (String) entry.elementAt(3); 234 } 235 236 String addrStr = (mbName.equals(strNIL) ? "" : mbName) + 237 (hostName.equals(strNIL) ? "" : ('@' + hostName)); 238 215 239 // Now assemble these into a single address entry 216 240 // (possibly eventually storing them separately) 217 if (realName.length() > 0&& !realName.equals(strNIL)) {218 addrList[index] = realName + " <" + mbName + "@" + hostName+ ">";219 } 220 else {221 addrList[index] = mbName + "@" + hostName;222 } 241 if ((realName.length() > 0) && !realName.equals(strNIL)) { 242 addrList[index] = realName + " <" + addrStr + ">"; 243 } else { 244 addrList[index] = addrStr; 245 } 246 223 247 index++; 224 248 } 225 249 } 250 226 251 return addrList; 227 252 } 228 253 229 254 static MessageEnvelope generateDummyEnvelope() { 230 255 MessageEnvelope env = new MessageEnvelope(); … … 233 258 env.from[0] = "<sender>"; 234 259 env.subject = "<subject>"; 260 235 261 return env; 236 262 } … … 244 270 static MessageSection parseMessageStructure(String rawText) { 245 271 Vector parsedText = null; 272 246 273 try { 247 parsedText = StringParser.nestedParenStringLexer(rawText.substring(rawText.indexOf('('))); 274 parsedText = StringParser.nestedParenStringLexer(rawText.substring( 275 rawText.indexOf('('))); 248 276 } catch (Exception exp) { 249 EventLogger.logEvent( 250 AppInfo.GUID, 277 EventLogger.logEvent(AppInfo.GUID, 251 278 ("ImapParser.parseMessageStructure: " + 252 "Caught exception when parsing input:\r\n"+ 253 exp.toString()).getBytes(), 279 "Caught exception when parsing input:\r\n" + exp.toString()).getBytes(), 254 280 EventLogger.WARNING); 281 255 282 return null; 256 283 } 257 284 258 285 // Sanity checking 259 if(parsedText.size() < 4 || 260 !(parsedText.elementAt(3) instanceof Vector)) { 261 EventLogger.logEvent( 262 AppInfo.GUID, 263 "ImapParser.parseMessageStructure: Sanity check failed".getBytes(), 264 EventLogger.WARNING); 265 return null; 266 } 267 268 Vector parsedStruct = (Vector)parsedText.elementAt(3); 269 MessageSection msgStructure = parseMessageStructureHelper(null, 1, parsedStruct); 286 if ((parsedText.size() < 2) || 287 !(parsedText.elementAt(1) instanceof Vector)) { 288 EventLogger.logEvent(AppInfo.GUID, 289 "ImapParser.parseMessageStructure: Sanity check failed".getBytes(), 290 EventLogger.WARNING); 291 292 return null; 293 } 294 295 Vector parsedStruct = (Vector) parsedText.elementAt(1); 296 MessageSection msgStructure = parseMessageStructureHelper(null, 1, 297 parsedStruct); 270 298 fixMessageStructure(msgStructure); 299 271 300 return msgStructure; 272 301 } … … 276 305 */ 277 306 private static void fixMessageStructure(MessageSection msgStructure) { 278 if (msgStructure == null) {307 if (msgStructure == null) { 279 308 return; 280 309 } 310 281 311 int p = msgStructure.address.indexOf('.'); 282 if(p != -1 && p+1 < msgStructure.address.length()) { 283 msgStructure.address = msgStructure.address.substring(p+1); 284 } 285 286 if(msgStructure.subsections != null && msgStructure.subsections.length > 0) { 287 for(int i=0;i<msgStructure.subsections.length;i++) { 312 313 if ((p != -1) && ((p + 1) < msgStructure.address.length())) { 314 msgStructure.address = msgStructure.address.substring(p + 1); 315 } 316 317 if ((msgStructure.subsections != null) && 318 (msgStructure.subsections.length > 0)) { 319 for (int i = 0; i < msgStructure.subsections.length; i++) { 288 320 fixMessageStructure(msgStructure.subsections[i]); 289 321 } 290 322 } 291 323 } 292 293 private static MessageSection parseMessageStructureHelper(String parentAddress, 294 int index, 295 Vector parsedStruct) { 324 325 private static MessageSection parseMessageStructureHelper( 326 String parentAddress, int index, Vector parsedStruct) { 296 327 // Determine the address of this body part 297 328 String address; 298 if(parentAddress == null) { 329 330 if (parentAddress == null) { 299 331 address = Integer.toString(index); 300 } 301 else { 332 } else { 302 333 address = parentAddress + "." + Integer.toString(index); 303 334 } 335 304 336 // Determine the number of body parts and parse 305 if (parsedStruct.elementAt(0) instanceof String) {337 if (parsedStruct.elementAt(0) instanceof String) { 306 338 // The first element is a string, so we hit a simple message part 307 339 MessageSection section = parseMessageStructureSection(parsedStruct); 308 340 section.address = address; 341 309 342 return section; 310 } 311 else if(parsedStruct.elementAt(0) instanceof Vector) { 343 } else if (parsedStruct.elementAt(0) instanceof Vector) { 312 344 // The first element is a vector, so we hit a multipart message part 313 345 int size = parsedStruct.size(); 314 MessageSection[] subSections = new MessageSection[size-4]; 315 for(int i=0;i<size;++i) { 346 MessageSection[] subSections = new MessageSection[size - 4]; 347 348 for (int i = 0; i < size; ++i) { 316 349 // Iterate through the message parts 317 if(parsedStruct.elementAt(i) instanceof Vector) 318 subSections[i] = parseMessageStructureHelper(address, i+1, (Vector)parsedStruct.elementAt(i)); 319 else if(parsedStruct.elementAt(i) instanceof String) { 350 if (parsedStruct.elementAt(i) instanceof Vector) { 351 subSections[i] = parseMessageStructureHelper(address, 352 i + 1, (Vector) parsedStruct.elementAt(i)); 353 } else if (parsedStruct.elementAt(i) instanceof String) { 320 354 MessageSection section = new MessageSection(); 321 355 section.type = "multipart"; 322 section.subtype = ((String) parsedStruct.elementAt(i)).toLowerCase();356 section.subtype = ((String) parsedStruct.elementAt(i)).toLowerCase(); 323 357 section.subsections = subSections; 324 358 section.address = address; 359 325 360 return section; 326 361 } 327 362 } 328 363 } 364 329 365 return null; 330 366 } 331 332 private static MessageSection parseMessageStructureSection(Vector sectionList) { 367 368 private static MessageSection parseMessageStructureSection( 369 Vector sectionList) { 333 370 MessageSection sec = new MessageSection(); 334 371 Vector tmpVec; 335 336 if (sectionList.elementAt(0) instanceof String) {337 sec.type = ((String) sectionList.elementAt(0)).toLowerCase();338 } 339 340 if (sectionList.elementAt(1) instanceof String) {341 sec.subtype = ((String) sectionList.elementAt(1)).toLowerCase();372 373 if (sectionList.elementAt(0) instanceof String) { 374 sec.type = ((String) sectionList.elementAt(0)).toLowerCase(); 375 } 376 377 if (sectionList.elementAt(1) instanceof String) { 378 sec.subtype = ((String) sectionList.elementAt(1)).toLowerCase(); 342 379 } 343 380 344 381 sec.charset = null; 345 if(sectionList.elementAt(2) instanceof Vector) { 346 tmpVec = (Vector)sectionList.elementAt(2); 347 if(tmpVec.size() >= 2) { 348 if((tmpVec.elementAt(0) instanceof String) && 349 ((String)tmpVec.elementAt(0)).equalsIgnoreCase("charset") && 350 tmpVec.elementAt(1) instanceof String) { 351 sec.charset = (String)tmpVec.elementAt(1); 352 } 353 } 354 } 355 356 if(sectionList.elementAt(5) instanceof String) { 357 sec.encoding = ((String)sectionList.elementAt(5)).toLowerCase(); 358 } 359 360 if(sectionList.elementAt(6) instanceof String) { 382 383 if (sectionList.elementAt(2) instanceof Vector) { 384 tmpVec = (Vector) sectionList.elementAt(2); 385 386 if (tmpVec.size() >= 2) { 387 if ((tmpVec.elementAt(0) instanceof String) && 388 ((String) tmpVec.elementAt(0)).equalsIgnoreCase( 389 "charset") && 390 tmpVec.elementAt(1) instanceof String) { 391 sec.charset = (String) tmpVec.elementAt(1); 392 } 393 } 394 } 395 396 if (sectionList.elementAt(5) instanceof String) { 397 sec.encoding = ((String) sectionList.elementAt(5)).toLowerCase(); 398 } 399 400 if (sectionList.elementAt(6) instanceof String) { 361 401 try { 362 sec.size = Integer.parseInt((String) sectionList.elementAt(6));402 sec.size = Integer.parseInt((String) sectionList.elementAt(6)); 363 403 } catch (Exception exp) { 364 404 sec.size = -1; … … 368 408 return sec; 369 409 } 370 410 371 411 /** 372 412 * Takes in the raw IMAP folder name, and outputs a string that … … 383 423 int len = rawText.length(); 384 424 boolean usMode = true; 385 while(index < len) { 425 426 while (index < len) { 386 427 char ch = rawText.charAt(index); 387 if(usMode) { 388 if(ch != '&') { 428 429 if (usMode) { 430 if (ch != '&') { 389 431 buf.append(ch); 390 432 index++; 391 } 392 else if(ch == '&' && index < len - 1 && rawText.charAt(index+1) == '-') {433 } else if ((ch == '&') && (index < (len - 1)) && 434 (rawText.charAt(index + 1) == '-')) { 393 435 buf.append(ch); 394 436 index += 2; 395 } 396 else { 437 } else { 397 438 usMode = false; 398 439 index++; 399 440 } 400 } 401 else { 402 if(intlBuf == null) { 441 } else { 442 if (intlBuf == null) { 403 443 intlBuf = new StringBuffer(); 404 444 } 405 406 if (ch == '-') {445 446 if (ch == '-') { 407 447 buf.append(decodeModifiedBase64(intlBuf.toString())); 408 448 intlBuf = null; 409 449 usMode = true; 410 450 index++; 411 } 412 else { 451 } else { 413 452 intlBuf.append(ch); 414 453 &nbs
