1 17 18 package org.apache.james.imapserver; 19 20 import org.apache.avalon.framework.logger.AbstractLogEnabled; 21 import org.apache.james.util.RFC822DateFormat; 22 import org.apache.log.Logger; 23 import org.apache.mailet.MailAddress; 24 25 import javax.mail.BodyPart; 26 import javax.mail.MessagingException; 27 import javax.mail.internet.*; 28 import java.io.Serializable; 29 import java.util.*; 30 31 41 public class SimpleMessageAttributes 42 extends AbstractLogEnabled 43 implements MessageAttributes, Serializable { 44 45 private final static String SP = " "; 46 private final static String NIL = "NIL"; 47 private final static String Q = "\""; 48 private final static String LB = "("; 49 private final static String RB = ")"; 50 private final static boolean DEBUG = true; 51 private final static String MULTIPART = "MULTIPART"; 52 private final static String MESSAGE = "MESSAGE"; 53 54 private transient Logger logger; 56 57 private int uid; 58 private int messageSequenceNumber; 59 private Date internalDate; 60 private String internalDateString; 61 private String bodyStructure; 62 private String envelope; 63 private int size; 64 private int lineCount; 65 public MessageAttributes[] parts; 66 private List headers; 67 68 private String subject; 71 private String[] from; 72 private String[] sender; 73 private String[] replyTo; 74 private String[] to; 75 private String[] cc; 76 private String[] bcc; 77 private String[] inReplyTo; 78 private String[] date; 79 private String[] messageID; 80 private String contentType; 81 private String primaryType; private String secondaryType; private Set parameters; private String contentID; 85 private String contentDesc; 86 private String contentEncoding; 87 88 SimpleMessageAttributes() { 89 System.out.println("SimpleMessageAttributes()"); 90 } 92 93 void setAttributesFor(MimeMessage msg) throws MessagingException { 94 System.out.println("setAttributesFor msg.class: " + msg.getClass().getName()); 95 96 size = msg.getSize(); 97 System.out.println("setAttributesFor - size: " + size); 98 try { 99 internalDate = msg.getSentDate(); 100 if (DEBUG) getLogger().debug("setAttributesFor - getSentDate: " + internalDate); 101 System.out.println("setAttributesFor - getSentDate: " + internalDate); 102 } catch (MessagingException me) { 103 if (DEBUG) getLogger().debug("Messaging Exception for getSentDate: " + me); 104 System.out.println("Messaging Exception for getSentDate: " + me); 105 internalDate = new Date(); 106 } 107 108 getLogger().debug("HeaderLines received were: "); 110 System.out.println("HeaderLines received were: "); 111 Enumeration enum = msg.getAllHeaderLines(); 112 while(enum.hasMoreElements()) { 113 getLogger().debug((String)enum.nextElement()); 114 } 115 enum = msg.getAllHeaderLines(); 116 while(enum.hasMoreElements()) { 117 System.out.println((String)enum.nextElement()); 118 } 119 internalDateString = RFC822DateFormat.toString(internalDate); System.out.println("setting msg: "+msg); 129 parseMimePart(msg); 130 envelope = null; 131 bodyStructure = null; 132 } 133 134 void setUID(int thisUID) { 135 uid = thisUID; 136 } 137 138 141 void parseMimePart(MimePart part) { 142 System.out.println("parseMimePart("+part+")"); 144 if (part instanceof MimeMessage) { 145 try { 146 subject = ((MimeMessage)part).getSubject(); 147 if (DEBUG) getLogger().debug("parseMessage - subject: " + subject); 148 } catch (MessagingException me) { 149 if (DEBUG) getLogger().debug("Messaging Exception for getSubject: " + me); 150 } 151 } 152 try { 153 from = part.getHeader("From"); 154 if (DEBUG) getLogger().debug("parseMessage - from: " + from); 155 } catch (MessagingException me) { 156 if (DEBUG) getLogger().debug("Messaging Exception for getHeader(From): " + me); 157 } 158 try { 159 sender = part.getHeader("Sender"); 160 if (DEBUG) getLogger().debug("parseMessage - sender: " + sender); 161 } catch (MessagingException me) { 162 if (DEBUG) getLogger().debug("Messaging Exception for getHeader(Sender): " + me); 163 } 164 try { 165 replyTo = part.getHeader("Reply To"); 166 if (DEBUG) getLogger().debug("parseMessage - ReplyTo: " + replyTo); 167 } catch (MessagingException me) { 168 if (DEBUG) getLogger().debug("Messaging Exception for getHeader(Reply To): " + me); 169 } 170 try { 171 to = part.getHeader("To"); 172 if (DEBUG) getLogger().debug("parseMessage - To: " + to); 173 } catch (MessagingException me) { 174 if (DEBUG) getLogger().debug("Messaging Exception for getHeader(To): " + me); 175 } 176 try { 177 cc = part.getHeader("Cc"); 178 if (DEBUG) getLogger().debug("parseMessage - cc: " + cc); 179 } catch (MessagingException me) { 180 if (DEBUG) getLogger().debug("Messaging Exception for getHeader(To): " + me); 181 } 182 try { 183 bcc = part.getHeader("Bcc"); 184 if (DEBUG) getLogger().debug("parseMessage - bcc: " + bcc); 185 } catch (MessagingException me) { 186 if (DEBUG) getLogger().debug("Messaging Exception for getHeader(To): " + me); 187 } 188 try { 189 inReplyTo = part.getHeader("In Reply To"); 190 if (DEBUG) getLogger().debug("parseMessage - In Reply To: " + inReplyTo); 191 } catch (MessagingException me) { 192 if (DEBUG) getLogger().debug("Messaging Exception for getHeader(In Reply To): " + me); 193 } 194 try { 195 date = part.getHeader("Date"); 196 if (DEBUG) getLogger().debug("parseMessage - date: " + date); 197 } catch (MessagingException me) { 198 if (DEBUG) getLogger().debug("Messaging Exception for getHeader(Date): " + me); 199 } 200 try { 201 messageID = part.getHeader("Message-ID"); 202 if (DEBUG) getLogger().debug("parseMessage - messageID: " + messageID); 203 } catch (MessagingException me) { 204 if (DEBUG) getLogger().debug("Messaging Exception for getHeader(messageID): " + me); 205 } 206 String contentTypeLine = null; 207 try { 208 contentTypeLine = part.getContentType(); 209 if (DEBUG) getLogger().debug("parseMessage - contentType: " + contentTypeLine); 210 } catch (MessagingException me) { 211 if (DEBUG) getLogger().debug("Messaging Exception for getContentType(): " + me); 212 } 213 if (contentTypeLine !=null ) { 214 decodeContentType(contentTypeLine); 215 } 216 try { 217 contentID = part.getContentID(); 218 if (DEBUG) getLogger().debug("parseMessage - contentID: " + contentID); 219 } catch (MessagingException me) { 220 if (DEBUG) getLogger().debug("Messaging Exception for getContentUD(): " + me); 221 } 222 try { 223 contentDesc = part.getDescription(); 224 if (DEBUG) getLogger().debug("parseMessage - contentDesc: " + contentDesc); 225 } catch (MessagingException me) { 226 if (DEBUG) getLogger().debug("Messaging Exception for getDescription(): " + me); 227 } 228 try { 229 contentEncoding = part.getEncoding(); 230 if (DEBUG) getLogger().debug("parseMessage - contentEncoding: " + contentEncoding); 231 } catch (MessagingException me) { 232 if (DEBUG) getLogger().debug("Messaging Exception for getEncoding(): " + me); 233 } 234 if (DEBUG) { 235 try { 236 String contentDisposition = part.getDisposition(); 237 getLogger().debug("parseMessage - contentDisposition: " + contentEncoding); 238 } catch (MessagingException me) { 239 getLogger().debug("Messaging Exception for getEncoding(): " + me); 240 } 241 } 242 243 try { 244 lineCount = part.getLineCount(); 245 if (DEBUG) getLogger().debug("parseMessage - Line Count: " + lineCount); 246 System.out.println("parseMessage - Line Count: " + lineCount); 247 } catch (MessagingException me) { 248 if (DEBUG) getLogger().debug("Messaging Exception for getLineCount(): " + me); 249 if (DEBUG) getLogger().debug(me.getMessage()); 250 System.out.println("Messaging Exception for getLineCount(): " + me); 251 System.out.println(me.getMessage()); 252 } catch (Exception e) { 253 if (DEBUG) getLogger().debug("Exception for getLineCount(): " + e); 254 if (DEBUG) getLogger().debug("Exception message was: " + e.getMessage()); 255 System.out.println("Exception for getLineCount(): " + e); 256 System.out.println("Exception message was: " + e.getMessage()); 257 e.printStackTrace(); 258 } 259 260 if (primaryType.equalsIgnoreCase(MULTIPART)) { 262 MimeMultipart container; 263 System.out.println("parseMimePart: its a MULTIPART"); 264 try { 265 container =(MimeMultipart) part.getContent(); 266 int count = container.getCount(); 267 getLogger().info("This part contains " + count + " parts."); 268 System.out.println("This part contains " + count + " parts."); 269 parts = new SimpleMessageAttributes[count]; 270 for (int i = 0; i < count ; i ++) { 271 getLogger().info("Getting embedded part: " + i); 272 System.out.println("Getting embedded part: " + i); 273 BodyPart nextPart = container.getBodyPart(i); 274 275 if (nextPart instanceof MimePart) { 276 SimpleMessageAttributes partAttrs = new SimpleMessageAttributes(); 277 setupLogger(partAttrs); partAttrs.parseMimePart((MimePart)nextPart); 279 parts[i] = partAttrs; 280 281 } else { 282 getLogger().info("Found a non-Mime bodyPart"); 283 System.out.println("Found a non-Mime bodyPart"); 284 } 285 getLogger().info("Finished with embedded part: " + i); 286 System.out.println("Finished with embedded part: " + i); 287 } 288 } catch (Exception e) { 289 getLogger().debug("Messaging Exception for getContent(): " + e); 290 System.out.println("Messaging Exception for getContent(): " + e); 291 e.printStackTrace(); 292 } 293 } else if (primaryType.equalsIgnoreCase("message")) { 294 getLogger().info("This part contains an embedded message of subtype: " + secondaryType); 295 getLogger().info("Uses java class: " + part.getClass().getName()); 296 System.out.println("This part contains an embedded message of subtype: " + secondaryType); 297 System.out.println("Uses java class: " + part.getClass().getName()); 298 if (secondaryType.equalsIgnoreCase("RFC822")) { 299 301 317 } else { 322 getLogger().info("Unknown subtype of message encountered."); 323 System.out.println("Unknown subtype of message encountered."); 324 } 325 getLogger().info("Finished with embedded message. " ); 326 System.out.println("Finished with embedded message. " ); 327 } 328 else { 329 System.out.println("parseMimePart: its just a plain message"); 330 } 331 } 332 333 336 String parseEnvelope() { 337 List response = new ArrayList(); 338 response.add( LB + Q + internalDateString + Q + SP); 339 if (subject != null && (!subject.equals(""))) { 340 response.add( Q + subject + Q + SP ); 341 } else { 342 response.add( NIL + SP ); 343 } 344 if (from != null && from.length > 0) { 345 response.add(LB); 346 for (int i=0; i<from.length; i++) { 347 response.add(parseAddress( from[i]) ); 348 } 349 response.add(RB); 350 } else { 351 response.add( NIL); 352 } 353 response.add(SP); 354 if (sender != null && sender.length >0) { 355 if (DEBUG) getLogger().debug("parsingEnvelope - sender[0] is: " + sender[0]); 356 System.out.println("parsingEnvelope - sender[0] is: " + sender[0]); 357 if (sender[0].indexOf("@") == -1) { 359 response.add(LB + (String)response.get(3) + RB); } else { 361 response.add(LB); 362 for (int i=0; i<sender.length; i++) { 363 response.add( parseAddress(sender[i])); 364 } 365 response.add(RB); 366 } 367 } else { 368 if (from != null && from.length > 0) { 369 response.add(LB + (String)response.get(3) + RB); } else { 371 response.add( NIL); 372 } 373 } 374 response.add(SP); 375 if (replyTo != null && replyTo.length >0) { 376 if (replyTo[0].indexOf("@") == -1) { 377 response.add(LB + (String)response.get(3) + RB); } else { 379 response.add(LB); 380 for (int i=0; i<replyTo.length; i++) { 381 response.add( parseAddress(replyTo[i])); 382 } 383 response.add(RB); 384 } 385 } else { 386 if (from != null && from.length > 0) { 387 response.add(LB + (String)response.get(3) + RB); } else { 389 response.add( NIL); 390 } 391 } 392 response.add(SP); 393 if (to != null && to.length >0) { 394 response.add(LB); 395 for (int i=0; i<to.length; i++) { 396 response.add( parseAddress(to[i])); 397 } 398 response.add(RB); 399 } else { 400 response.add( NIL); 401 } 402 response.add(SP); 403 if (cc != null && cc.length >0) { 404 response.add(LB); 405 for (int i=0; i<cc.length; i++) { 406 response.add( parseAddress(cc[i])); 407 } 408 response.add(RB); 409 } else { 410 response.add( NIL); 411 } 412 response.add(SP); 413 if (bcc != null && bcc.length >0) { 414 response.add(LB); 415 for (int i=0; i<bcc.length; i++) { 416 response.add( parseAddress(bcc[i])); 417 } 418 response.add(RB); 419 } else { 420 response.add( NIL); 421 } 422 response.add(SP); 423 if (inReplyTo != null && inReplyTo.length>0) { 424 response.add( inReplyTo[0]); 425 } else { 426 response.add( NIL); 427 } 428 response.add(SP); 429 if (messageID != null && messageID.length>0) { 430 response.add(Q + messageID[0] + Q); 431 } else { 432 response.add( NIL); 433 } 434 response.add(RB); 435 436 StringBuffer buf = new StringBuffer(16 * response.size()); 437 for (int j=0; j<response.size(); j++) { 438 buf.append((String)response.get(j)); 439 } 440 441 return buf.toString(); 442 } 443 444 447 String parseAddress(String address) { 448 getLogger().info("Parsing address: " + address); 449 System.out.println("Parsing address: " + address); 450 int comma = address.indexOf(","); 451 StringBuffer buf = new StringBuffer(); 452 if (comma == -1) { buf.append(LB); 454 InternetAddress netAddr = null; 455 try { 456 netAddr = new InternetAddress(address); 457 } catch (AddressException ae) { 458 return null; 459 } 460 String personal = netAddr.getPersonal(); 461 if (personal != null && (!personal.equals(""))) { 462 buf.append(Q + personal + Q); 463 } else { 464 buf.append( NIL); 465 } 466 buf.append( SP); 467 buf.append( NIL) ; buf.append( SP); 469 try { 470 MailAddress mailAddr = new MailAddress(netAddr); 471 buf.append(Q + mailAddr.getUser() + Q); 472 buf.append(SP); 473 buf.append(Q + mailAddr.getHost() + Q); 474 } catch (ParseException pe) { 475 buf.append( NIL + SP + NIL); 476 } 477 buf.append(RB); 478 } else { 479 buf.append(parseAddress(address.substring(0, comma))); 480 buf.append(SP); 481 buf.append(parseAddress(address.substring(comma + 1))); 482 } 483 return buf.toString(); 484 } 485 486 489 void decodeContentType(String rawLine) { 490 if (DEBUG) getLogger().debug("decoding: " + rawLine); 491 System.out.println("decoding: " + rawLine); 492 int slash = rawLine.indexOf("/"); 493 if( slash == -1){ 494 if (DEBUG) getLogger().debug("decoding ... no slash found"); 495 System.out.println("decoding ... no slash found"); 496 return; 497 } else { 498 primaryType = rawLine.substring(0, slash).trim(); 499 } 500 int semicolon = rawLine.indexOf(";"); 501 if (semicolon == -1) { 502 if (DEBUG) getLogger().debug("decoding ... no semicolon found"); 503 System.out.println("decoding ... no semicolon found"); 504 secondaryType = rawLine.substring(slash + 1).trim(); 505 return; 506 } 507 parameters = new HashSet(); 509 secondaryType = rawLine.substring(slash + 1, semicolon).trim(); 510 int pos = semicolon; 511 int nextsemi = rawLine.indexOf(";", pos+1); 512 while (nextsemi != -1) { 513 if (DEBUG) getLogger().debug("decoding ... found another semicolon"); 514 System.out.println("decoding ... found another semicolon"); 515 String param = rawLine.substring(pos + 1, nextsemi); 516 int esign = param.indexOf("=") ; 517 if (esign == -1) { 518 if (DEBUG) getLogger().debug("Whacky parameter found: " + param); 519 System.out.println("Whacky parameter found: " + param); 520 } else { 521 String name = param.substring(0, esign).trim(); 522 String value = param.substring(esign + 1).trim(); 523 parameters.add(name + SP + value); 524 if (DEBUG) getLogger().debug("Found parameter: " + name + SP + value); 525 System.out.println("Found parameter: " + name + SP + value); 526 } 527 pos = nextsemi; 528 nextsemi = rawLine.indexOf(";", pos +1); 529 } 530 String lastParam = rawLine.substring(pos + 1); 531 int esign = lastParam.indexOf("=") ; 532 if (esign == -1) { 533 if (DEBUG) getLogger().debug("Whacky parameter found: " + lastParam); 534 System.out.println("Whacky parameter found: " + lastParam); 535 } else { 536 String name = lastParam.substring(0, esign).trim(); 537 String value = lastParam.substring(esign + 1).trim(); 538 parameters.add(Q + name + Q + SP + Q + value + Q); 539 if (DEBUG) getLogger().debug("Found parameter: " + name + SP + value); 540 System.out.println("Found parameter: " + name + SP + value); 541 } 542 } 543 544 String parseBodyFields() { 545 getLogger().debug("Parsing body fields"); 546 System.out.println("Parsing body fields"); 547 StringBuffer buf = new StringBuffer(); 548 if (parameters == null || parameters.isEmpty()) { 549 buf.append(NIL); 550 } else { 551 buf.append(LB); 552 Iterator it = parameters.iterator(); 553 while(it.hasNext()) { 554 buf.append((String)it.next()); 555 } 556 buf.append(RB); 557 } 558 buf.append(SP); 559 if(contentID == null) { 560 buf.append(NIL); 561 } else { 562 buf.append(Q + contentID + Q); 563 } 564 buf.append(SP); 565 if(contentDesc == null) { 566 buf.append(NIL); 567 } else { 568 buf.append(Q + contentDesc + Q); 569 } 570 buf.append(SP); 571 if(contentEncoding == null) { 572 buf.append(NIL); 573 } else { 574 buf.append(Q + contentEncoding + Q); 575 } 576 buf.append(SP); 577 buf.append(size); 578 return buf.toString(); 579 } 580 581 584 String parseBodyStructure() { 585 getLogger().debug("Parsing bodyStructure."); 586 System.out.println("Parsing bodyStructure."); 587 System.out.println("this.class="+this.getClass().getName()); 588 try { 589 String fields = parseBodyFields(); 590 StringBuffer buf = new StringBuffer(); 591 buf.append(LB); 592 if (primaryType.equalsIgnoreCase("Text")) { 593 getLogger().debug("Assembling bodystrucuture for type TEXT."); 594 System.out.println("Assembling bodystrucuture for type TEXT."); 595 System.out.println("secondaryType: '"+secondaryType+"'"); 596 System.out.println("fields: '"+fields+"'"); 597 System.out.println("lineCount: '"+lineCount+"'"); 598 buf.append("\"Text\" \"" + secondaryType + "\" "); 599 buf.append("NIL NIL NIL \"8bit\" 6" + " " + "1"); 601 606 } else if (primaryType.equalsIgnoreCase(MESSAGE) && secondaryType.equalsIgnoreCase("rfc822")) { 607 getLogger().debug("Assembling bodyStructure for type MESSAGE/FRC822"); 608 System.out.println("Assembling bodyStructure for type MESSAGE/FRC822"); 609 buf.append("\"MESSAGE\" \"RFC822\" "); 610 buf.append(fields + SP); 611 setupLogger(parts[0]); buf.append(parts[0].getEnvelope() + SP); 613 buf.append(parts[0].getBodyStructure() + SP); 614 buf.append(lineCount); 615 } else if (primaryType.equalsIgnoreCase(MULTIPART)) { 616 getLogger().debug("Assembling bodystructure for type MULTIPART"); 617 System.out.println("Assembling bodystructure for type MULTIPART"); 618 for (int i=0; i<parts.length; i++) { 619 getLogger().debug("Parsing part: " + i); 620 System.out.println("Parsing part: " + i + "/"+parts.length+" :"+parts[i]); 621 setupLogger(parts[i]); buf.append(parts[i].getBodyStructure()); 623 } 624 buf.append(SP + secondaryType); 625 } 626 buf.append(RB); 627 return buf.toString(); 628 } catch (Exception e) { 629 getLogger().error("Exception while parsing BodyStrucuture: " + e); 630 System.out.println("Exception while parsing BodyStrucuture: " + e); 631 e.printStackTrace(); 632 throw new RuntimeException("Exception in parseBodyStructure"); 633 } 634 } 635 636 642 public int getMessageSequenceNumber() { 643 return messageSequenceNumber; 644 } 645 646 void setMessageSequenceNumber(int newMsn) { 647 messageSequenceNumber = newMsn; 648 } 649 650 651 660 public int getUID() { 661 return uid; 662 } 663 664 675 public Date getInternalDate() { 676 return internalDate; 677 } 678 679 public String getInternalDateAsString() { 680 return internalDateString; 681 } 682 683 688 public int getSize() { 689 return size; 690 } 691 692 697 public String getEnvelope() { 698 return parseEnvelope(); 699 } 700 701 702 707 public String getBodyStructure() { 708 return parseBodyStructure(); 709 } 710 } 711 | Popular Tags |