KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > james > imapserver > SimpleMessageAttributes


1 /***********************************************************************
2  * Copyright (c) 2000-2004 The Apache Software Foundation. *
3  * All rights reserved. *
4  * ------------------------------------------------------------------- *
5  * Licensed under the Apache License, Version 2.0 (the "License"); you *
6  * may not use this file except in compliance with the License. You *
7  * may obtain a copy of the License at: *
8  * *
9  * http://www.apache.org/licenses/LICENSE-2.0 *
10  * *
11  * Unless required by applicable law or agreed to in writing, software *
12  * distributed under the License is distributed on an "AS IS" BASIS, *
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or *
14  * implied. See the License for the specific language governing *
15  * permissions and limitations under the License. *
16  ***********************************************************************/

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 /**
32  * Attributes of a Message in IMAP4rev1 style. Message
33  * Attributes should be set when a message enters a mailbox.
34  * <p> Note that the message in a mailbox have the same order using either
35  * Message Sequence Numbers or UIDs.
36  * <p> reinitialize() must be called on deserialization to reset Logger
37  *
38  * Reference: RFC 2060 - para 2.3
39  * @version 0.2 on 04 Aug 2002
40  */

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     //Only available in first incarnation of object
55
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     //rfc822 or MIME header fields
69
//arrays only if multiple values allowed under rfc822
70
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; // parsed from contentType
82
private String secondaryType; // parsed from contentType
83
private Set parameters; // parsed from contentType
84
private String contentID;
85     private String contentDesc;
86     private String contentEncoding;
87
88     SimpleMessageAttributes() {
89     System.out.println("SimpleMessageAttributes()");
90       // new Throwable().printStackTrace();
91
}
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         //if (DEBUG) {
109
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             // getLogger().debug("Header objects available are:");
120
// Enumeration e = msg.getAllHeaders();
121
// while(e.hasMoreElements()) {
122
//Header h = (Header) e.nextElement();
123
//getLogger().debug("Name: " + h.getName());
124
//getLogger().debug("Value: " + h.getValue());
125
// }
126
// }
127
internalDateString = RFC822DateFormat.toString(internalDate); // not right format
128
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     /**
139      * Parses key data items from a MimeMessage for seperate storage.
140      */

141     void parseMimePart(MimePart part) {
142         // Section 1 - Message Headers
143
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         // Recurse through any embedded parts
261
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); // reset transient logger
278
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                 //try {
300

301                     /*
302                     MimeMessageWrapper message = new MimeMessageWrapper(part.getInputStream());
303                     SimpleMessageAttributes msgAttrs = new SimpleMessageAttributes();
304                     msgAttrs.setAttributesFor(message);
305
306                     if (part instanceof MimeMessage) {
307                         Comments out because I don't know what it should do here
308                         MimeMessage msg1 = (MimeMessage) part;
309                         MimeMessageWrapper message2 = new MimeMessageWrapper(msg1);
310                         SimpleMessageAttributes msgAttrs2 = new SimpleMessageAttributes();
311                         msgAttrs.setAttributesFor(message2);
312                     }
313
314                     parts = new SimpleMessageAttributes[1];
315                     parts[0] = msgAttrs;
316                     */

317                 //} catch (Exception e) {
318
//getLogger().error("Error interpreting a message/rfc822: " + e);
319
//e.printStackTrace();
320
//}
321
} 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     /**
334      * Builds IMAP envelope String from pre-parsed data.
335      */

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             //Check for Netscape feature - sender is local part only
358
if (sender[0].indexOf("@") == -1) {
359                 response.add(LB + (String)response.get(3) + RB); //first From address
360
} 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); //first From address
370
} 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); //first From address
378
} 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); //first From address
388
} 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     /**
445      * Parses a String email address to an IMAP address string.
446      */

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) { //single address
453
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) ; // should add route-addr
468
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     /**
487      * Decode a content Type header line into types and parameters pairs
488      */

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         // have parameters
508
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     /**
582      * Produce the IMAP formatted String for the BodyStructure of a pre-parsed MimeMessage
583      */

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(fields + " " + lineCount);
600
buf.append("NIL NIL NIL \"8bit\" 6" + " " + "1");
601              // buf.append(" NIL NIL NIL");
602
// is: * 1 FETCH (BODYSTRUCTURE ("Text" "plain" NIL NIL NIL NIL 4 -1))
603
// wants: * 1 FETCH (BODYSTRUCTURE ("text" "plain" NIL NIL NIL "8bit" 6 1 NIL NIL NIL))
604
// or: * 1 FETCH (BODYSTRUCTURE ("text" "plain" NIL NIL NIL "7bit" 28 1 NIL NIL NIL))
605

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]); // reset transient logger
612
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]); // reset transient getLogger()
622
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     /**
637      * Provides the current Message Sequence Number for this message. MSNs
638      * change when messages are expunged from the mailbox.
639      *
640      * @return int a positive non-zero integer
641      */

642     public int getMessageSequenceNumber() {
643         return messageSequenceNumber;
644     }
645
646     void setMessageSequenceNumber(int newMsn) {
647         messageSequenceNumber = newMsn;
648     }
649
650
651     /**
652      * Provides the unique identity value for this message. UIDs combined with
653      * a UIDValidity value form a unique reference for a message in a given
654      * mailbox. UIDs persist across sessions unless the UIDValidity value is
655      * incremented. UIDs are not copied if a message is copied to another
656      * mailbox.
657      *
658      * @return int a 32-bit value
659      */

660     public int getUID() {
661         return uid;
662     }
663
664     /**
665      * Provides the date and time at which the message was received. In the
666      * case of delivery by SMTP, this SHOULD be the date and time of final
667      * delivery as defined for SMTP. In the case of messages copied from
668      * another mailbox, it shuld be the internalDate of the source message. In
669      * the case of messages Appended to the mailbox, example drafts, the
670      * internalDate is either specified in the Append command or is the
671      * current dat and time at the time of the Append.
672      *
673      * @return Date imap internal date
674      */

675     public Date getInternalDate() {
676         return internalDate;
677     }
678
679     public String getInternalDateAsString() {
680         return internalDateString;
681     }
682
683     /**
684      * Provides the sizeof the message in octets.
685      *
686      * @return int number of octets in message.
687      */

688     public int getSize() {
689         return size;
690     }
691
692     /**
693      * Provides the Envelope structure information for this message. This is a parsed representation of the rfc-822 envelope information. This is not to be confused with the SMTP envelope!
694      *
695      * @return String satisfying envelope syntax in rfc 2060.
696      */

697     public String getEnvelope() {
698         return parseEnvelope();
699     }
700
701
702     /**
703      * Provides the Body Structure information for this message. This is a parsed representtion of the MIME structure of the message.
704      *
705      * @return String satisfying body syntax in rfc 2060.
706      */

707     public String getBodyStructure() {
708         return parseBodyStructure();
709     }
710 }
711
Popular Tags