001/*
002 * $Source: f:/cvsroot2/open/projects/WebARTS/ca/bc/webarts/servlet/webmail/JavaMailServlet.java,v $
003 * $Revision: 1.10 $  $Date: 2005-04-10 11:53:16 -0700 (Sun, 10 Apr 2005) $  $Locker:  $
004 * Copyright (C) 2001,2002 WebARTS Design,
005 * North Vancouver Canada. All Rights Reserved.
006 *
007 * Written by Tom Gutwin - WebARTS Design.
008 * http://www..webarts.bc.ca
009 *
010 * This program is free software; you can redistribute it and/or modify
011 * it under the terms of the GNU General Public License as published by
012 * the Free Software Foundation; either version 2 of the License, or
013 * (at your option) any later version.
014 *
015 * This program is distributed in the hope that it will be useful,
016 * but WITHOUT ANY WARRANTY; without even the implied warranty of
017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
018 * GNU General Public License for more details.
019 *
020 * You should have received a copy of the GNU General Public License
021 * along with this program; if not, write to the Free Software
022 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
023 */
024
025/*
026 * Here is the revision log
027 * ------------------------
028 * $Log: JavaMailServlet.java,v $
029 * Revision 1.10  2002/07/18 01:18:48  tgutwin
030 * Fixed some upper/lower case image filenaming issues.
031 * Slightly changed soe of the setup variables to be able to get them to the point of being user configurable.
032 *
033 * Revision 1.9  2001/12/14 07:21:57  tgutwin
034 *
035 * Reply to now adds the original msg text to reply text area. without a hang.
036 * Added Icons for the commands.
037 *
038 * Revision 1.5  2001/08/18 21:42:00  tgutwin
039 *
040 * Added Javadocs.
041 * Clened up the Logging in... reusing the exidting mud if it is already available.
042 *
043 * Revision 1.3  2001/08/09 06:22:53  tgutwin
044 * Fixed the Compose Window Not Sending Message.
045 * Altered the Showing of text/html messages.
046 * Some bug fixxes.
047 */
048
049
050package ca.bc.webarts.servlet.webmail;
051
052import ca.bc.webarts.tools.Log;
053import ca.bc.webarts.widgets.Util;
054import com.oreilly.servlet.ParameterParser;
055
056import com.oreilly.servlet.ServletUtils;
057
058import java.io.*;
059import java.net.InetAddress;
060import java.net.UnknownHostException;
061import java.text.*;
062import java.util.*;
063import java.util.Calendar;
064import javax.activation.*;
065import javax.mail.*;
066import javax.mail.internet.*;
067
068import javax.servlet.*;
069import javax.servlet.http.*;
070
071/**
072 *  This is a servlet that demonstrates the use of JavaMail APIs in a
073 *  3-tier application.<P>
074 *  It allows the user to login to an IMAP/Pop store, list all the messages in
075 *  the INBOX folder, view selected messages, compose and send a message,
076 *  and logout.
077 *  <p>
078 *
079 *  For more information on servlets, see
080 * <a href="http://java.sun.com/products/java-server/servlets/index.html">
081 *  http://java.sun.com/products/java-server/servlets/index.html</a>
082 *
083 * @created    August 9, 2001
084 */
085public class JavaMailServlet extends HttpServlet implements SingleThreadModel
086{
087
088  private static final String SYSTEM_FILE_SEPERATOR = File.separator;
089
090  /**
091   *  The name of the Mailbox to Display/use.
092   */
093  String                 mbox = "INBOX";
094  /**
095   *  A holder of the current time.
096   */
097  String                 currTime = (new java.util.Date()).toString();
098  /**
099   *  The string representing the html page background colour (ie #000066).
100   */
101  String                 bodyBackColour_ = "#000066";
102  /**
103   *  The string representing the html link colour (ie #000066).
104   */
105  String                 linkColour_ = "yellow";
106  /**
107   *  The string representing the html link colour (ie #000066).
108   */
109  String                 htmlMessageLinkColour_ = "#0000aa";
110  /**
111   *  The string representing the html text colour (ie #000066).
112   */
113  String                 textColour_ = "#ffffff";
114  /**
115   *  The string representing the html colour for the message text(ie #000066).
116   */
117  String                 messageTextColour_ = "#000000";
118  /**
119   *  The string representing the html table background colour for
120   *  NEW messages (ie #000066).
121   */
122  String                 rowColour_ = "#222299";
123  /**
124   *  The string representing the html table background colour (ie #000066).
125   */
126  private String         tableBackColour_ = "#111188";
127  /**
128   *  The string representing the html table background colour for
129   *  NEW messages (ie #000066).
130   */
131  String                 newMessageBackColour = "#4444ff";
132  /**
133   *  The string representing the html table background colour for the actual
134   *  message text (ie #000066).
135   */
136  String                 messageBackColour_ = "#dddddd";
137  /**
138   *  The string representing the html table background colour for
139   *  message headers (ie #000066).
140   */
141  String                 messageHeadBackColour_ = "#888899";
142  /**
143   *  The string representing the html table background colour for
144   *  message attachments (ie #000066).
145   */
146  String                 attachmentBackColour_ = "#aaaaaa";
147  /**
148   *  The string representing the html text colour (ie #000066).
149   */
150  String                 tableTextColour = "#ffffff";
151  /**
152   * The title to put on the folder view page. The words that go into the
153   * &lt;TITLE&gt; tag.
154   **/
155  String folderViewTitle_ = "Java Servlet WebMail Interface";
156  /**
157   *  The html header string (&lt;head&gt;) that is included on all folder view
158   *  pages.  It is the place where any javascript fuction are included.
159   */
160  String                 folderViewHead =
161      "<HEAD>\n" +
162      "<META HTTP-EQUIV=\"Content-Type\" " +
163      "CONTENT=\"text/html;CHARSET=iso-8859-1\">\n" +
164      "<TITLE>" + folderViewTitle_ + "</TITLE>\n" +
165      "<SCRIPT LANGUAGE=\"JavaScript\">\n" +
166      "<!-- Begin\nvar compose_window = null;\n" +
167      "function CloseCompose()\n{\n  "+
168      "if (compose_window != null && parseInt(navigator.appVersion) >= 4)\n  {\n    "+
169      "compose_window.window.focus();\n    "+
170      "compose_window.window.close();\n  }\n}\n" +
171
172      "function NewWindow(mypage, myname, w, h, scroll)\n{\n  " +
173      "  var winl = (screen.width - w) / 2;\n  " +
174      "  var wint = (screen.height - h) / 2;\n  " +
175      "  winprops = 'height='+h+',width='+w+',top='+wint+',left='+winl+'," +
176      "  scrollbars='+scroll+',resizable'\n  " +
177      "  win = window.open('', myname, winprops)\n  compose_window = win;\n  " +
178      "  win.document.open();\n  win.document.clear;\n  " +
179      "  win.document.write(mypage)\n  " +
180      "  if (parseInt(navigator.appVersion) >= 4) {\n" +
181      "    win.window.focus();\n"+
182      "  }\n  " +
183      "}\n\n" +
184
185      "function DeleteMessages(url)\n{\n" +
186      "  var numBoxes = 0;\n" +
187      "  deleteDocNumbers = '';\n" +
188      "  for (var i = 0; i < document.msgList.elements.length; i++) {\n" +
189      "    if (document.msgList.elements[i].type='Checkbox') {\n" +
190      "      numBoxes++;\n" +
191      "      if (document.msgList.elements[i].checked) {\n" +
192      "         deleteDocNumbers += document.msgList.elements[i].name+','\n" +
193      "      }\n" +
194      "    }\n" +
195      "  }\n" +
196      "  document.location.href = url+'?replyToSelected=false&deleteSelected=true" +
197      "&selected='+deleteDocNumbers;\n" +
198      "}\n\n" +
199
200      "function ReplyToMessages(url)\n{\n" +
201      "  var numBoxes = 0;\n" +
202      "  selectedDocNumbers = '';\n" +
203      "  for (var i = 0; i < document.msgList.elements.length;i++) {\n" +
204      "    if (document.msgList.elements[i].type='Checkbox') {\n" +
205      "      numBoxes++;\n" +
206      "      if (document.msgList.elements[i].checked && document.msgList.elements[i].name.substring(0,9)=='msgSelect') {\n" +
207      "        window.open(url+'?replyToSelected=true&deleteSelected=false" +
208      "&selected='+document.msgList.elements[i].name,'ReplyToWindow'+numBoxes,\"toolbar=yes,"+
209      "location=no,directories=no,status=yes,menubar=yes,resizable=yes,"+
210      "copyhistory=no,scrollbars=yes,width=800,height=600,left=80,top=40\");\n" +
211      "      }\n" +
212      "    }\n" +
213      "  }\n" +
214      "}\n\n" +
215      "//  End -->\n" +
216      "</script>\n" +
217      "</HEAD>\n";
218
219
220  /**
221   *  The DEFAULT name of the graphic that gets used at the top of all
222
223   *  the pages if one is not specified at runtime.
224   */
225  private final static String DEFAULT_HEAD_GRAPHIC
226       = "WebArtsTransparentLogoNoBackLarge.png";
227  /**
228   *  The default mail protocal to use.
229   */
230  private final static String DEFAULT_PROTOCOL = "imap";
231
232  /**
233   *  The default number of mail messages to show per page .
234   */
235  private final static int DEFAULT_MESSAGES_PER_PAGE = 25;
236
237  /**
238   *  The default servlet pathname to use in the URL to call this mail servlet.
239   */
240  private final static String DEFAULT_SERVLET_PATHNAME = "JavaMail";
241  /**
242   *  The default html/jsp page to use as the home login page for this servlet.
243   *  It will get appended to the end of the homeUrl_;
244   */
245  private final static String DEFAULT_HOME_PAGE = "/mail/";
246  /**
247   *  The default URL to use as the home login page for this servlet.
248   */
249  private final static String DEFAULT_HOME_URL =
250      "http://www.webarts.bc.ca"+DEFAULT_HOME_PAGE;
251  /**
252   *  Version String.
253   */
254  private final static String SERVLET_VERSION = "a0.7.2";
255
256  /**
257   *  Build String. (yymmddhhss)
258   */
259  private final static String BUILD_TAG = "0303172207";
260
261  private static Calendar calendar_ = Calendar.getInstance();
262
263  /**
264   *  Log File Name.
265   */
266  private final static String DEFAULT_LOG_FILE =
267                              SYSTEM_FILE_SEPERATOR +
268                              "log" +
269                              SYSTEM_FILE_SEPERATOR +
270                              calendar_.get(calendar_.YEAR) + "-" +
271                              calendar_.get(calendar_.DAY_OF_YEAR) + "_" +
272                              "MailServletLog.txt";
273
274  /**
275   *  The debug logger.
276   */
277  private static Log log = null; // new Log(Log.CONSOLE, Log.FULL);
278
279  /**
280   *  The current URL to use as the home login page for this servlet. It gets
281   *  used when a user logs out etc. It can be specified at runtime with the
282   * 'homeurl' parameter.
283   */
284  private static String         homeUrl_ = DEFAULT_HOME_URL;
285  /**
286   *  The name of the graphic that gets used at the top of all
287   *  the pages. It can be specified at runtime with the 'titlegraphic'
288   *  parameter.
289   */
290  private static String         headGraphicName_ = "/images/"+DEFAULT_HEAD_GRAPHIC;
291  /**
292   *  The current mail server being used. It can be changed at runtime via
293   * setting the 'hostname' parameter.
294   */
295  private static String         mailServerHostName_ = "mail";
296  /**
297   *  This servers name.
298   */
299  private static String         webServerHostName_ = "";
300  /**
301   *  The string representing the URL path to this servlet.
302   */
303  private static String         servletName_ = DEFAULT_SERVLET_PATHNAME;
304  /**
305   *  The string representing the FULL URL path to this servlet.
306   */
307  private static String         servletUrl_ = "/" + servletName_;
308  /**
309   *  The string representing the path for the home page to serve for webmail.
310   */
311  private static String         homePage_ = DEFAULT_HOME_PAGE;
312  /**
313   * the class copy of the next mailto address used in the compose form.
314   **/
315  String mailToAddr_ = "";
316  /**
317   * the class copy of the next subject used in the compose form.
318   **/
319  String replySubject_ = "";
320  String composeBody_ = "";
321
322  Properties props = System.getProperties();
323
324  private String composeBodyHeader_ =
325        "<BODY onLoad=\"self.resizeTo(560,700);self.setResizable(false)\"" +
326        " bgcolor=\"" + bodyBackColour_ + "\" text=\"" + textColour_ +
327        "\" link=" + linkColour_ + " " +
328        "VLINK=\"#ffffaa\">\n" +
329        "<table>\n" +
330        "<TR>\n" +
331        "  <TD height=\"100\">" +
332        "    <img SRC=\"/" + headGraphicName_ + "\" \n" +
333        "    ALT=\"Company Logo\" height=\"90\" width=\"135\" border=\"0\">\n" +
334        "  </TD>\n" +
335        "  <TD>\n" +
336        "    <B><FONT SIZE=+1 FACE=\"Arial, Helvetica\">" +
337        "Java WebMail Compose Message</FONT></B>\n" +
338        "    <P><FONT FACE=\"Arial, Helvetica\">The current time in Vancouver is: \n" +
339        "    " + currTime + "\n" +
340        "  </TD>\n" +
341        "</TR>\n" +
342        "</table>\n" +
343        "<HR align=left>\n";
344
345
346  private String folderViewBodyClose_ =
347        "<BR clear=left><HR WIDTH=\"40%\" align=left>\n" +
348        "    <p><A href=\"http://jetty.mortbay.org\">\n" +
349        "    <img SRC=\"http://www.webarts.bc.ca/images/powered.png\" ALT=\"jetty logo\"" +
350        "    border=\"0\" width=\"109\" height=\"48\"></a></p>\n" +
351        "</body>\n" +
352        "</html>\n";
353
354  /**
355   *  Gets the ServletInfo attribute of the JavaMailServlet object
356   *
357   * @return    The ServletInfo value
358   */
359  public String getServletInfo()
360  {
361    final String methodName = "getServletInfo";
362    log.startMethod(methodName);
363
364    log.endMethod();
365    return "WebARTS Design mail servlet. Version:" + SERVLET_VERSION +
366           "  Build:" + BUILD_TAG;
367  }
368
369
370  /**
371   * The one time servlet init stuff goes here.
372   */
373  public void init(ServletConfig config) throws ServletException
374  {
375    super.init(config);
376    System.out.println("Initializing webarts.servlet.webmail.JavaMailServlet");
377    if (log == null)
378    {
379      System.out.println("TBGDEBUG: Creating Log File: " + DEFAULT_LOG_FILE);
380      log = Log.createLog(Log.FULL, DEFAULT_LOG_FILE);
381    }
382    final String methodName = "init";
383    log.startMethod(methodName);
384
385    String initServletName = "JavaMail";
386    String initServer = "warp2.webarts.bc.ca";
387    String initServerPort = "80";
388    String initMailServer = "aurora1";
389    String initBackColour = "";
390    String homePage = "";
391    String portNum = "";
392    if (config !=null)
393    {
394      initServletName = config.getInitParameter("servletName");
395      initServer = config.getInitParameter("serverUrl");
396      initServerPort = config.getInitParameter("serverPort");
397      initMailServer = config.getInitParameter("mailServerName");
398      initBackColour = config.getInitParameter("backColour");
399      homePage = config.getInitParameter("homePage");
400      portNum = "";
401    }
402
403    if (initServerPort != null && !initServerPort.equals(""))
404      portNum = ":"+initServerPort;
405    if (initServer != null && !initServer.equals(""))
406    {
407      webServerHostName_ = initServer + portNum;
408    }
409    else
410      try
411      {
412        webServerHostName_ = InetAddress.getLocalHost().getHostName();
413      }
414      catch (UnknownHostException ex)
415      {
416        webServerHostName_ = "localhost";
417      }
418
419    if (homePage != null && !homePage.equals(""))
420      homePage_ = homePage;
421
422    homeUrl_ = "http://"+webServerHostName_+homePage_;
423    servletUrl_ = "http://"+webServerHostName_+"/";
424    System.out.println("homeUrl_=" + homeUrl_);
425    log.debug("homeUrl_=" + homeUrl_);
426
427    if (initBackColour != null && !initBackColour.equals(""))
428      bodyBackColour_ = initBackColour;
429    if (initServletName != null && !initServletName.equals(""))
430      servletName_ = initServletName;
431    servletUrl_ += servletName_;
432
433    if (initMailServer != null && !initMailServer.equals(""))
434      mailServerHostName_ = initMailServer;
435
436    props.put("mail.smtp.host", mailServerHostName_);
437
438    log.endMethod();
439  }
440
441
442  /** Override to close the Log **/
443  public void destroy()
444  {
445    super.destroy();
446    final String methodName = "destroy";
447    if (log != null)
448    {
449      log.startMethod(methodName);
450      log.endMethod();
451      log.close();
452    }
453  }
454
455
456  /**
457   *  This method handles the "POST" submission from two forms: the login form
458   *  and the message compose form. The login form has the following parameters:
459   *  <code>hostname</code> , <code>username</code>, and <code>password</code>.
460   *  The <code>send</code> parameter denotes that the method is processing the
461   *  compose form submission.
462   *
463   * @param  req                   Description of Parameter
464   * @param  res                   Description of Parameter
465   * @exception  ServletException  Description of Exception
466   * @exception  IOException       Description of Exception
467   */
468  public void doPost(HttpServletRequest req, HttpServletResponse res)
469       throws ServletException, IOException
470  {
471    final String methodName = "doPost";
472    log.startMethod(methodName);
473
474    currTime = (new java.util.Date()).toString();
475    // get the session
476    HttpSession ssn = req.getSession(true);
477    ParameterParser parser = new ParameterParser(req);
478
479    String logFileName = parser.getStringParameter("logfile", DEFAULT_LOG_FILE);
480    if (log == null)
481    {
482      System.out.println("TBGDEBUG: Creating Log File:" + logFileName);
483      log = Log.createLog(Log.FULL, logFileName);
484    }
485
486    String userWebmailDir = ".webmail";
487    String username = "";
488    if (true || ssn.isNew())
489    {
490      // get all the one time parameter settings to configure thissession
491      log.debug("TBGDEBUG: NEW SESSION.");
492
493      homeUrl_ = parser.getStringParameter("homeurl", DEFAULT_HOME_URL);
494      bodyBackColour_ = parser.getStringParameter("backcolour", bodyBackColour_);
495      headGraphicName_ = parser.getStringParameter("titlegraphic",
496          DEFAULT_HEAD_GRAPHIC);
497      mailServerHostName_ = parser.getStringParameter("hostname",
498          mailServerHostName_);
499      username = parser.getStringParameter("username", "");
500      userWebmailDir = parser.getStringParameter("userWebmailDir", "") +
501                       SYSTEM_FILE_SEPERATOR +
502                       username + SYSTEM_FILE_SEPERATOR + ".webmail";
503
504      ssn.setAttribute("titlegraphic", headGraphicName_);
505      ssn.setAttribute("username", username );
506      ssn.setAttribute("userWebmailDir", userWebmailDir);
507    }
508    else
509    {
510      log.debug("TBGDEBUG: Using Existing SESSION.");
511      String tempName = (String) ssn.getAttribute("titlegraphic");
512      if (tempName != null)
513        headGraphicName_ = tempName;
514      tempName = (String) ssn.getAttribute("homeurl");
515      if (tempName != null)
516        homeUrl_ = tempName;
517      tempName = (String) ssn.getAttribute("hostname");
518      if (tempName != null)
519        mailServerHostName_ = tempName;
520      tempName = (String) ssn.getAttribute("username");
521      if (tempName != null)
522        username = tempName;
523      tempName = (String) ssn.getAttribute("userWebmailDir");
524      if (tempName != null)
525        userWebmailDir = tempName;
526    }
527
528    // get the paramaters specific to this Post Request.
529    boolean send = parser.getBooleanParameter("send", false);
530    String passwd = parser.getStringParameter("password", "");
531    boolean logout = parser.getBooleanParameter("logout", false);
532    String protocol = parser.getStringParameter("protocol", DEFAULT_PROTOCOL);
533
534    URLName url = (URLName)ssn.getAttribute("mailUrl");
535    if (url == null)
536    {
537      log.debug("Creating the Login URLname: " + protocol + " " +
538                 mailServerHostName_ + " " + mbox + " " +
539                 username + " " + passwd);
540      url = new URLName(protocol, mailServerHostName_, -1, mbox, username, passwd);
541      ssn.setAttribute("mailUrl", url);
542    }
543
544    ServletOutputStream out = res.getOutputStream();
545    res.setContentType("text/html");
546    out.println("<html>\n" + folderViewHead + getFolderListBodyHeader());
547
548
549    /* Now start processing the Post */
550    if (send)
551    {
552      // create mud IF NEEDED
553      log.debug("TBGDEBUG: Getting MUD");
554      MailUserData mud = (MailUserData)ssn.getAttribute("javamailservlet");
555      if (mud == null)
556      {
557        log.debug("TBGDEBUG: ... creating NEW MUD");
558        mud = new MailUserData(url);
559        ssn.setAttribute("javamailservlet", mud);
560      }
561      // process message sending
562      log.debug("TBGDEBUG: attempting SEND");
563
564      send(req, res, out, ssn);
565    }
566    else
567    {
568      short stage = 0;
569      // create mud IF NEEDED
570      log.debug("TBGDEBUG: Getting MUD");
571      MailUserData mud = (MailUserData)ssn.getAttribute("javamailservlet");
572      if (mud == null)
573      {
574        stage = 1;
575        log.debug("TBGDEBUG: ... creating NEW MUD");
576        mud = new MailUserData(url);
577        ssn.setAttribute("javamailservlet", mud);
578      }
579
580      if (!logout)
581      {
582        // initial login and get the mail store setup
583        try
584        {
585          Session mailSession = null;
586          Store store = null;
587          if (!mud.getIsLoggedIn())
588          {
589            // track who logged in
590            mailSession = Session.getDefaultInstance(props);
591            mailSession.setDebug(false);
592            ssn.setAttribute("mailSession", mailSession);
593            stage = 4;
594            store = mailSession.getStore(url);
595            ssn.setAttribute("store", store);
596            // save stuff into MUD
597            mud.setSession(mailSession);
598            mud.setStore(store);
599            mud.setIsLoggedIn(true);
600            log.debug("Login from: " + store.getURLName());
601          }
602          else
603          {
604            mailSession = (Session) ssn.getAttribute("mailSession");
605            store = (Store) ssn.getAttribute("store");
606          }
607
608          stage = 5;
609          if (store != null && !store.isConnected())
610          {
611            //try
612            //{
613            stage = 55;
614            //store.close();
615            stage = 56;
616            //}
617            //catch (MessagingException ex)
618            //{
619            //}
620            stage = 6;
621            if (url != null)
622            {
623              stage = 65;
624              if (!store.isConnected())
625              {
626                //store.connect(url.getHost(),url.getUsername(),url.getPassword());
627                log.debug("Connecting to Mail Store:" + mailServerHostName_ +
628                          " " + username + " " + passwd);
629                store.connect(mailServerHostName_, username, passwd);
630              }
631            }
632            else
633            {
634              stage = 66;
635              if (!store.isConnected())
636              {
637                store.connect(mailServerHostName_, username, passwd);
638              }
639            }
640          }
641          if (store != null)
642          {
643            stage = 7;
644            log.debug("Getting Default Folder.");
645            Folder folder = store.getDefaultFolder();
646            if (folder == null)
647            {
648              throw new MessagingException("No default folder");
649            }
650
651            folder = folder.getFolder(mbox);
652            if (folder == null)
653            {
654              throw new MessagingException("Invalid folder");
655            }
656
657            stage = 8;
658            folder.open(Folder.READ_WRITE);
659            int totalMessages = folder.getMessageCount();
660            stage = 9;
661            log.debug("Getting " + totalMessages +" Messages.");
662            //Message[] msgs = folder.getMessages();
663            //stage = 10;
664            //FetchProfile fp = new FetchProfile();
665            //stage = 11;
666            //fp.add(FetchProfile.Item.ENVELOPE);
667            //stage = 12;
668            //folder.fetch(msgs, fp);
669
670
671            // save stuff into MUD
672            mud.setFolder(folder);
673            Folder f = mud.getFolder();
674            int msgCount = f.getMessageCount();
675            int newMsgCount = 0;
676            Message m = null;
677
678            // for each message, show its headers
679            for (int i = 1; i <= msgCount; i++)
680            {
681              m = f.getMessage(i);
682              // Count the NEW msgs
683              if (!m.isSet(Flags.Flag.DELETED) &&
684                  !m.isSet(Flags.Flag.ANSWERED) &&
685                  !m.isSet(Flags.Flag.DRAFT) &&
686                  !m.isSet(Flags.Flag.SEEN))
687              {
688                newMsgCount++;
689              }
690            }
691
692            displayCommandBarHtml(req, out);
693            out.println(buildFolderTableHTML(HttpUtils.getRequestURL(req),
694                store.getURLName(),
695                msgCount, newMsgCount));
696          }
697          else
698          {
699            out.println("Could Not Authnticate User: " + username + "<BR>\n");
700            out.println("<BR>\n<a href=\"" +
701                HttpUtils.getRequestURL(req) +
702                "?logout=true\"> Try Again? </a>] <BR>");
703          }
704        }
705        catch (NoSuchProviderException provEx)
706        {
707          out.println("No Provider for : " + url + "<BR>Stage: " + stage +
708              "<BR>\n" + provEx.toString());
709        }
710        catch (AuthenticationFailedException authEx)
711        {
712          out.println("Could Not Authnticate User: Stage " + stage +
713              "<BR>\n" + authEx.toString());
714          out.println("<BR>\n<a href=\"" +
715              HttpUtils.getRequestURL(req) +
716              "?logout=true\"> Try Again? </a>] <BR>");
717          authEx.printStackTrace();
718        }
719        catch (IllegalStateException connEx)
720        {
721          out.println("Store Is Already Connected: Stage " + stage +
722              "<BR>\n" + connEx.toString());
723          out.println("<BR>\n<a href=\"" +
724              HttpUtils.getRequestURL(req) +
725              "?logout=true\"> Try Again? </a>] ");
726        }
727        catch (Exception ex)
728        {
729          out.println("While Logging In: Stage " + stage + "<BR>\n" +
730            ex.toString());
731          out.println("<BR>\n<a href=\"" +
732              HttpUtils.getRequestURL(req) +
733              "?logout=true\"> Try Again? </a>] ");
734          ex.printStackTrace(System.out);
735          log.debug("While Logging In: Stage " + stage + "<BR>\n" +
736            ex.toString());
737          log.minor("Exception thrown", ex);
738
739        }
740        finally
741        {
742          out.println(getFolderViewBodyClose());
743          out.close();
744        }
745      }
746      else
747      { // logout
748
749        // process logout
750        try
751        {
752          log.debug("TBGDEBUG: Logout.");
753          mud.getFolder().close(false);
754          mud.getStore().close();
755          mud.setIsLoggedIn(false);;
756          ssn.invalidate();
757          out.println("<html><body>Logged out OK</body></html>");
758        }
759        catch (MessagingException mex)
760        {
761          out.println("While Logging Out <BR>\n" + mex.toString());
762        }
763        finally
764        {
765          out.println("</body></html>");
766          out.close();
767        }
768      }
769    } // not send
770    log.endMethod();
771  }
772
773
774  /**
775   *  This method handles the GET requests for the client.
776   *
777   * @param  req                   Description of Parameter
778   * @param  res                   Description of Parameter
779   * @exception  ServletException  Description of Exception
780   * @exception  IOException       Description of Exception
781   */
782  public void doGet(HttpServletRequest req, HttpServletResponse res)
783       throws ServletException, IOException
784  {
785    final String methodName = "doGet";
786    log.startMethod(methodName);
787
788    HttpSession ses = req.getSession(false); // before we write to out
789    ServletOutputStream out = res.getOutputStream();
790
791    log.debug("Request = "+ HttpUtils.getRequestURL(req));
792    log.debug("Query = "+ req.getQueryString());
793    if (ses == null)
794    {
795      res.setContentType("text/html");
796      out.println("<html><body>" +
797          "\n<HEAD>" +
798          "<META HTTP-EQUIV=\"refresh\" content=\"2;URL=" +
799          homeUrl_ + "\"></head>" +
800          "Your Session Has Expired <BR>\nPlease Re-Login</body></html>");
801      out.close();
802      return;
803    }
804
805    MailUserData mud = getMUD(ses);
806    res.setContentType("text/html");
807
808    if (mud == null)
809    {
810      res.setContentType("text/html");
811      out.println("<html><body>" +
812          "\n<HEAD>" +
813          "<META HTTP-EQUIV=\"refresh\" content=\"2;URL=" +
814          homeUrl_ + "\"></head>" +
815          "Please Login (no mailSession)</body></html>");
816      out.close();
817      ses.invalidate();
818      return;
819    }
820
821    if (mud.getStore() != null && !mud.getStore().isConnected())
822    {
823      res.setContentType("text/html");
824      out.println("<html><body>" +
825          "\n<HEAD>" +
826          "<META HTTP-EQUIV=\"refresh\" content=\"2;URL=" +
827          homeUrl_ + "\"></head>" +
828          "Not Connected To Store</body></html>");
829      out.close();
830      mud = null;
831      ses.invalidate();
832      return;
833    }
834    else
835    {
836      if (mud.getStore() == null)
837      {
838        Session mailSession = (Session)ses.getAttribute("mailSession");
839        URLName url = (URLName)ses.getAttribute("mailUrl");
840        try
841        {
842          Store store = mailSession.getStore(url);
843          if (store != null)
844          {
845            mud.setStore(store);
846            if (!store.isConnected())
847            {
848              res.setContentType("text/html");
849              out.println("<html><body>" +
850                  "\n<HEAD>" +
851                  "<META HTTP-EQUIV=\"refresh\" content=\"2;URL=" +
852                  homeUrl_ + "\"></head>" +
853                  "Not Connected To Store</body></html>");
854              out.close();
855              ses.invalidate();
856              return;
857            }
858          }
859          else
860          {
861            res.setContentType("text/html");
862            out.println("<html><body>" +
863                "\n<HEAD>" +
864                "<META HTTP-EQUIV=\"refresh\" content=\"2;URL=" +
865                homeUrl_ + "\"></head>" +
866                "Can't get the Store</body></html>");
867            out.close();
868            ses.invalidate();
869            return;
870          }
871        }
872        catch (NoSuchProviderException provEx)
873        {
874          out.println("No Provider for : " + url +
875              "<BR>\n" + provEx.toString());
876        }
877      }
878    }
879
880    // mux that takes a GET request, based on parameters figures
881    // out what it should do, and routes it to the
882    // appropriate method
883
884    // get url parameters
885    ParameterParser parser = new ParameterParser(req);
886    boolean logout = parser.getBooleanParameter("logout", false);
887    boolean refresh = parser.getBooleanParameter("refresh", false);
888    boolean deleteSelected = parser.getBooleanParameter("deleteSelected", false);
889    boolean replyToSelected = parser.getBooleanParameter("replyToSelected", false);
890    String selected = parser.getStringParameter("selected", "");
891    boolean composeParm = parser.getBooleanParameter("compose", false);
892    int msgNum = parser.getIntParameter("message", -1);
893    int partNum = parser.getIntParameter("part", -1);
894    int messagesPerPage = parser.getIntParameter("messagesPerPage",
895                                                 DEFAULT_MESSAGES_PER_PAGE);
896    int messageStartPage = parser.getIntParameter("messageStartPage", 1);
897
898    String userWebmailDir = ".webmail";
899    String username = "";
900    String tempName = (String) ses.getAttribute("titlegraphic");
901    if (tempName != null)
902      headGraphicName_ = tempName;
903
904    tempName = (String) ses.getAttribute("homeurl");
905    if (tempName != null)
906      homeUrl_ = tempName;
907
908    tempName = (String) ses.getAttribute("hostname");
909    if (tempName != null)
910      mailServerHostName_ = tempName;
911
912    tempName = (String) ses.getAttribute("username");
913    if (tempName != null)
914      username = tempName;
915
916    tempName = (String) ses.getAttribute("userWebmailDir");
917    if (tempName != null)
918      userWebmailDir = tempName;
919
920
921    log.debug("doGet Parms: ");
922    log.debug("  logout: " +logout);
923    log.debug("  deleteSelected: " +deleteSelected);
924    log.debug("  replyToSelected: " +replyToSelected);
925    log.debug("  selected: " +selected);
926    log.debug("  compose: " +composeParm);
927    log.debug("  logout: " +logout);
928    log.debug("  messagesPerPage: " +messagesPerPage);
929    log.debug("  messageStartPage: " +messageStartPage);
930    // process url params
931    if (msgNum != -1)
932    {
933      if (partNum == -1)
934      {
935        log.debug("Displaying Msg: "+msgNum);
936        // display message "msgStr"
937        res.setContentType("text/html");
938        displayMessage(mud, req, out, msgNum);
939      }
940      else
941      {
942        log.debug("Displaying Msg/Part: "+msgNum+"/"+partNum);
943        displayPart(mud, msgNum, partNum, out, res);
944      }
945    }
946    else if (composeParm)
947    {
948      // display compose form
949      log.debug("Processing the Compose: ");
950      compose(mud, res, out);
951    }
952    else if (deleteSelected)
953    {
954      log.debug("Processing the Delete Selected: "+ selected);
955
956      try
957      {
958        Folder f = mud.getFolder();
959        Message msg;
960        String currMsgNum = "-1";
961        StringTokenizer st = new StringTokenizer(selected, ",");
962        String token = "";
963        while (st.hasMoreTokens())
964        {
965          token =  st.nextToken();
966          if ( token.length() > 8)
967            currMsgNum = token.substring(9).trim();
968          if (Integer.parseInt(currMsgNum) < 0)
969            currMsgNum = selected;
970          log.debug("Deleting Number:" + currMsgNum);
971          msg = f.getMessage(Integer.parseInt(currMsgNum));
972          msg.setFlag(Flags.Flag.DELETED, true); // set the DELETED flag
973        }
974
975        log.debug("  Expunging");
976        f.expunge();
977
978        out.println("<html>" +
979            "\n<HEAD>\n  " +
980            "<META HTTP-EQUIV=\"refresh\" content=\"0;URL=" +
981            HttpUtils.getRequestURL(req) + "\">\n  " +
982            "</head><body>" +
983            "Message Deleted - " + selected + "</body></html>");
984      }
985      catch (MessagingException mex)
986      {
987        log.minor("Cannot delete Message num:"+selected);
988      }
989
990    }
991    else if (replyToSelected)
992    {
993      log.debug("Processing the Reply To Selected: "+ selected);
994      Folder f = mud.getFolder();
995      Message msg;
996      String currMsgNum = "0";
997      StringTokenizer st = new StringTokenizer(selected, ",");
998      String fromStr = "";
999      String replySubject = "";
1000      /*out.println("<html>" +
1001          "\n<HEAD>\n  " +
1002          "<META HTTP-EQUIV=\"refresh\" content=\"0;URL=" +
1003          HttpUtils.getRequestURL(req) + "?compose=true\">\n  " +
1004          "</head><body>" +
1005          "Opening Reply Compose Windows<BR>");*/
1006      String nextToken = "";
1007      while (st.hasMoreTokens())
1008      {
1009        nextToken = st.nextToken();
1010        if (nextToken.length()>4)
1011          currMsgNum = nextToken.substring(9).trim();
1012        else
1013          currMsgNum = nextToken;
1014        System.out.println(currMsgNum);
1015        try
1016        {
1017          msg = f.getMessage(Integer.parseInt(currMsgNum));
1018          fromStr =
1019            ((msg.getFrom() != null) ? msg.getFrom()[0].toString() : "");
1020          replySubject =
1021            ((msg.getSubject() != null) ? msg.getSubject().toString() : "");
1022          log.debug("Replying to Number:" + currMsgNum + " From: "+ fromStr );
1023          mailToAddr_ = fromStr;
1024          replySubject_ = "RE: " + replySubject;
1025          Object o = msg.getContent();
1026          composeBody_ = "\n\n\n>\n>Reply To:\n>-----------------------------------------------\n>";
1027          if (msg.isMimeType("text/plain") && ((String)o).length() >0)
1028          {
1029            log.debug("Adding Original Message (" + ((String)o).length() +
1030              ")to reply");
1031
1032            composeBody_ += Util.tokenReplace((String)o,"\n","\n> ");
1033          }
1034          replyCompose(mud, res, out, mailToAddr_, replySubject_);
1035        }
1036        catch (MessagingException mex)
1037        {
1038          log.minor("Cannot Reply to Message num:" + currMsgNum,mex);
1039        }
1040        catch (Exception ex)
1041        {
1042          log.major("Choked trying to reply :" + currMsgNum,ex);
1043        }
1044
1045      }
1046      //out.println("Msgs: " + selected + "</body></html>");
1047    }
1048    else if (logout)
1049    {
1050      // process logout
1051      try
1052      {
1053        log.debug("Processing the logout:");
1054        mud.getFolder().close(false);
1055        mud.getStore().close();
1056        ses.invalidate();
1057        res.sendRedirect(res.encodeRedirectURL(homeUrl_));
1058        /*out.println("<html>" +
1059            "\n<HEAD>" +
1060            "<META HTTP-EQUIV=\"refresh\" content=\"2;URL=" +
1061            homeUrl_ + "\"></head><body>" +
1062            "Logged out OK</body></html>");*/
1063      }
1064      catch (MessagingException mex)
1065      {
1066        out.println(mex.toString());
1067      }
1068    }
1069    else if (refresh)
1070    {
1071      // process logout
1072      try
1073      {
1074        log.debug("Processing the refresh logout:");
1075        mud.getFolder().close(false);
1076        mud.getStore().close();
1077        ses.invalidate();
1078
1079
1080        this.doPost(req,res);
1081
1082      }
1083      catch (MessagingException mex)
1084      {
1085        out.println(mex.toString());
1086      }
1087    }
1088    else
1089    {
1090      // display headers
1091      displayHeaderTableHtml(mud, req, out, messagesPerPage, messageStartPage);
1092    }
1093    log.endMethod();
1094  }
1095
1096
1097  /**
1098   * A simple String token replacement routine. Replaces all occurences of the
1099   * token parameter with the replacement value in the passed in sentence
1100   * parameter.
1101   *
1102   * @param sentence     The String to perform the token replacement on
1103   * @param token        the token String to seartch for and replace
1104   * @param replacement  the tokens replacement value
1105   * @return             The new token replaced string
1106   */
1107  public static String tokenReplace(String sentence,
1108    String token,
1109    String replacement)
1110  {
1111    final String methodName = "tokenReplace";
1112    log.startMethod(methodName);
1113    int a = 0;
1114
1115    while ((a = sentence.indexOf(token)) > -1)
1116    {
1117      sentence = sentence.substring(0, a) + replacement +
1118        sentence.substring(a + token.length());
1119    } // if a > -1
1120
1121    log.endMethod();
1122    return sentence;
1123  }
1124
1125
1126  /**
1127   *  A helper method that returns the Body tag with any predefined body header
1128   *  info.
1129   *
1130   * @return    a String representing the start body tag.
1131   */
1132  private String getComposeBodyHeader()
1133  {
1134    final String methodName = "getComposeBodyHeader";
1135    log.startMethod(methodName);
1136
1137    currTime = (new java.util.Date()).toString();
1138    log.endMethod();
1139    return composeBodyHeader_;
1140  }
1141
1142
1143  /**
1144   *  A helper method that returns the Body tag with any predefined body header
1145   *  info.
1146   *
1147   * @return    a String representing the start body tag.
1148   */
1149  private String getFolderListBodyHeader()
1150  {
1151    final String methodName = "getFolderListBodyHeader";
1152    log.startMethod(methodName);
1153
1154    currTime = (new java.util.Date()).toString();
1155    log.endMethod();
1156    return "<BODY bgcolor=\"" + bodyBackColour_ + "\" text=\"" + textColour_ +
1157        "\" link=" + linkColour_ + " " +
1158        "VLINK=\"#ffffaa\">\n" +
1159        "<table>\n" +
1160        "<TR>\n" +
1161        "  <TD height=\"100\">" +
1162        "    <img SRC=\"" + headGraphicName_ + "\" \n" +
1163        "    ALT=\"Company Logo\" height=\"90\" width=\"135\" border=\"0\" >\n" +
1164        "  </TD>\n" +
1165        "  <TD>\n" +
1166        "    <B><FONT SIZE=+1 FACE=\"Arial, Helvetica\">" +
1167        "Java WebMail Folder View</FONT></B>\n" +
1168        "    <BR><I><FONT SIZE=-1 FACE=\"Arial, Helvetica\">" +
1169        "(Servlet Version: " + SERVLET_VERSION + " - " + BUILD_TAG +
1170        ")</FONT></I>\n    <P><FONT FACE=\"Arial, Helvetica\">" +
1171        "The current time in Vancouver is: \n" +
1172        "    " + currTime + "\n" +
1173        "  </TD>\n" +
1174        "</TR>\n" +
1175        "</table>\n" +
1176        "<HR align=left>\n";
1177  }
1178
1179
1180  /**
1181   *  A helper method that returns the Body tag with any predefined body header
1182   *  info.
1183   *
1184   * @param  folderName  Description of Parameter
1185   * @return             a String representing the start body tag.
1186   */
1187  private String getFolderViewBodyHeader(String folderName)
1188  {
1189    final String methodName = "getFolderViewBodyHeader";
1190    log.startMethod(methodName);
1191
1192    currTime = (new java.util.Date()).toString();
1193    log.endMethod();
1194    return "<BODY bgcolor=\"" + bodyBackColour_ + "\" text=\"" + textColour_ +
1195        "\" link=" + linkColour_ + " " +
1196        "VLINK=\"#ffffaa\">\n" +
1197        "<table>\n" +
1198        "<TR>\n" +
1199        "  <TD height=\"100\">" +
1200        "    <img SRC=\"" + headGraphicName_ + "\" \n" +
1201        "    ALT=\"Company Logo\" height=\"90\" width=\"135\" border=\"0\" >\n" +
1202        "  </TD>\n" +
1203        "  <TD>\n" +
1204        "    <B><FONT SIZE=+1 FACE=\"Arial, Helvetica\">" +
1205        "Java WebMail <BR>\n" + folderName +
1206        " </FONT></B>\n" +
1207        "    <P><FONT FACE=\"Arial, Helvetica\">" +
1208        "The current time in Vancouver is: \n" +
1209        "    " + currTime + "</FONT>\n" +
1210        "  </TD>\n" +
1211        "</TR>\n" +
1212        "</table>\n" +
1213        "<HR align=left>\n";
1214  }
1215
1216
1217  /**
1218   *  A helper method that returns the Body tag with any predefined body header
1219   *  info.
1220   *
1221   * @param  folderName  Description of Parameter
1222   * @return             a String representing the start body tag.
1223   */
1224  private String getMessageViewBodyHeader(String folderName)
1225  {
1226    final String methodName = "getMessageViewBodyHeader";
1227    log.startMethod(methodName);
1228
1229    currTime = (new java.util.Date()).toString();
1230    log.endMethod();
1231    return
1232        "<BODY bgcolor=\"" + bodyBackColour_ + "\" text=\"" +
1233        messageTextColour_ +
1234        "\" link=" + linkColour_ + " " +
1235        "VLINK=\"#ffffaa\">\n" +
1236        "<table>\n" +
1237        "<TR>\n" +
1238        "  <TD height=\"100\">" +
1239        "    <img SRC=\"" + headGraphicName_ + "\" \n" +
1240        "    ALT=\"Company Logo\" height=\"90\" width=\"135\" border=\"0\" >\n" +
1241        "  </TD>\n" +
1242        "  <TD>\n" +
1243        "    <B><FONT SIZE=+1 color=\"" + textColour_ +
1244        "\" FACE=\"Arial, Helvetica\">Java WebMail<BR>\n" + folderName +
1245        " </FONT></B>\n" +
1246        "    <P><FONT color=\"" + textColour_ + "\" FACE=\"Arial, Helvetica\">" +
1247        "The current time in Vancouver is: \n" +
1248        "    " + currTime + "</FONT>\n" +
1249        "  </TD>\n" +
1250        "</TR>\n" +
1251        "</table>\n" +
1252        "<HR align=left>\n";
1253  }
1254
1255
1256  /**
1257   *  A helper method that returns the ENDING Body tag with any predefined closing
1258   *  body info.
1259   *
1260   * @return    a String representing the ending body tag.
1261   */
1262  private String getFolderViewBodyClose()
1263  {
1264    final String methodName = "getFolderViewBodyClose";
1265    log.startMethod(methodName);
1266
1267    log.endMethod();
1268    return folderViewBodyClose_;
1269  }
1270
1271
1272  /**
1273   *  A helper method that returns the ENDING Body tag with any predefined closing
1274   *  body info.
1275   *
1276   * @return    a String representing the ending body tag.
1277   */
1278  private String getMessageViewBodyClose()
1279  {
1280    final String methodName = "getMessageViewBodyClose";
1281    log.startMethod(methodName);
1282
1283    log.endMethod();
1284    return "<BR clear=left><HR WIDTH=\"40%\" align=left>\n" +
1285        "<FONT color=\"" + textColour_ + "\" FACE=\"Arial,Helvetica\">" +
1286        "    <p><A href=\"http://jetty.mortbay.org\">\n" +
1287        "    <img SRC=\"http://www.webarts.bc.ca/images/powered.png\" ALT=\"jetty logo\"" +
1288        "    border=\"0\" width=\"109\" height=\"48\"></a></p>\n" +
1289        "</font>\n" +
1290        "</body>\n" +
1291        "</html>\n";
1292  }
1293
1294
1295  /**
1296   *  Gets the SelectedNums attribute of the JavaMailServlet object
1297   *
1298   * @return    The SelectedNums value
1299   */
1300  private String getSelectedNums()
1301  {
1302    return "";
1303  }
1304
1305
1306  // utility method; returns a string suitable for msg header display
1307  /**
1308   *  Gets the DisplayAddress attribute of the JavaMailServlet object
1309   *
1310   * @param  a  Description of Parameter
1311   * @return    The DisplayAddress value
1312   */
1313  private String getDisplayAddress(Address a)
1314  {
1315    final String methodName = "getDisplayAddress";
1316    log.startMethod(methodName);
1317
1318    String pers = null;
1319    String addr = null;
1320    if (a instanceof InternetAddress &&
1321        ((pers = ((InternetAddress)a).getPersonal()) != null))
1322    {
1323
1324      addr = pers + "  " + "<" + ((InternetAddress)a).getAddress() + ">";
1325    }
1326    else
1327    {
1328      addr = a.toString();
1329    }
1330
1331    log.endMethod();
1332    return addr;
1333  }
1334
1335  /**
1336   *  Utility method for retrieving the MailUserData from the HttpSession
1337   * and return it.
1338   *
1339   * @param  ses              The Session to retrieve the MUD from
1340   * @return                  The MUD value
1341   * @exception  IOException  Description of Exception
1342   */
1343  private MailUserData getMUD(HttpSession ses) throws IOException
1344  {
1345    final String methodName = "getMUD";
1346    log.startMethod(methodName);
1347
1348    MailUserData mud = null;
1349
1350    if (ses == null)
1351    {
1352      return null;
1353    }
1354    else
1355    {
1356      if ((mud = (MailUserData)ses.getAttribute("javamailservlet")) == null)
1357      {
1358        return null;
1359      }
1360    }
1361    log.endMethod();
1362    return mud;
1363  }
1364
1365
1366  /**
1367   *  A method to display messages in the folder.
1368   *
1369   * @param  reqUrl       Description of Parameter
1370   * @param  urlName      Description of Parameter
1371   * @param  msgCount     Description of Parameter
1372   * @param  newMsgCount  Description of Parameter
1373   * @return              Description of the Returned Value
1374   */
1375  private String buildFolderTableHTML(StringBuffer reqUrl, URLName urlName,
1376      int msgCount, int newMsgCount)
1377  {
1378    final String methodName = "buildFolderTableHTML";
1379    log.startMethod(methodName);
1380    StringBuffer retVal = new StringBuffer();
1381    // folder table
1382    retVal.append("<table width=\"50%\" border=0 align=left>");
1383    // Title header
1384    retVal.append("\n");
1385    retVal.append("<tr><td colspan=2 width=\"100%\" bgcolor=\"" +
1386                  tableBackColour_ + "\">");
1387    retVal.append("\n");
1388    retVal.append("<font face=\"Arial,Helvetica\" font size=+1>");
1389    retVal.append("<b>Login from: " + urlName + "</b></font></td><br>");
1390    // folder name column header
1391    retVal.append("\n");
1392    retVal.append("<tr><td width=\"75%\" bgcolor=\"" + tableBackColour_ + "\">");
1393    retVal.append("\n");
1394    retVal.append("<font face=\"Arial,Helvetica\" font size=+0>");
1395    retVal.append("<b>FolderName</b></font></td><br>");
1396    // msg count column header
1397    retVal.append("\n");
1398    retVal.append("<td width=\"25%\" bgcolor=\"" + tableBackColour_ +"\">");
1399    retVal.append("\n");
1400    retVal.append("<font face=\"Arial,Helvetica\" font size=+0>");
1401    retVal.append("<b>Messages</b></font></td><br>");
1402    retVal.append("</tr>");
1403    // folder name
1404    retVal.append("\n");
1405    retVal.append("<tr><td width=\"75%\" bgcolor=\"" + rowColour_ +"\">");
1406    // HttpUtils is from javax.servlet.http
1407    retVal.append("\n");
1408    retVal.append("<font face=\"Arial,Helvetica\" color=\"" +
1409                  tableTextColour + "\">");
1410    retVal.append("\n");
1411    retVal.append("<a href=\"" + reqUrl + "\">Inbox</a></font> ");
1412    retVal.append("\n");
1413    retVal.append("<font size=\"-1\" face=\"Arial,Helvetica\"color=\"" +
1414                   tableTextColour + "\">");
1415    retVal.append("\n");
1416    retVal.append("<I>(" + msgCount + " messages, " + newMsgCount +
1417                  "new)</I></font>");
1418    retVal.append("\n");
1419    retVal.append("</td><br>");
1420    // msg count
1421    retVal.append("<td width=\"25%\" bgcolor=\"" + rowColour_ + "\">" +
1422                   msgCount + "</td>");
1423    retVal.append("</tr>");
1424    retVal.append("</table><BR clear=left>");
1425    log.endMethod();
1426    return retVal.toString();
1427  }
1428
1429
1430  /**
1431   *  The main method to display a message.
1432   *
1433   * @param  mud              Description of Parameter
1434   * @param  req              Description of Parameter
1435   * @param  out              Description of Parameter
1436   * @param  msgNum           The Message number to display.
1437   * @exception  IOException  Description of Exception
1438   */
1439  private void displayMessage(MailUserData mud,
1440                              HttpServletRequest req,
1441                              ServletOutputStream out,
1442                              int msgNum)
1443                              throws IOException
1444  {
1445
1446    final String methodName = "displayMessage";
1447    log.startMethod(methodName);
1448
1449    out.println("<html>");
1450    out.println(folderViewHead);
1451    out.println(getMessageViewBodyHeader(
1452        "<BR><I>Message " + msgNum + " in folder " +mud.getStore().getURLName() +
1453        "/INBOX</I>"));
1454    try
1455    {
1456      Folder f = mud.getFolder();
1457      int msgCount = f.getMessageCount();
1458
1459      StringBuffer reqUrl = HttpUtils.getRequestURL(req);
1460      // URL's for the commands that are available
1461      out.println("<font face=\"Arial,Helvetica\" color=\"" +
1462        textColour_ + "size=\"+1\">");
1463      out.print("\n<a href=\"" + reqUrl + "\">\n ");
1464      out.print("\n <img SRC=\"/images/Home.gif\" ALT=\"Back To Inbox\"");
1465      out.print(" hspace=\"3\" vspace=\"5\" ");
1466      out.print(" border=\"0\" width=\"20\" height=\"20\"></a>\n");
1467      out.print("</a>");
1468      out.print("\n<a href=\"" + reqUrl + "?logout=true\">");
1469      out.print("\n <img SRC=\"/images/UnPlug.gif\" ALT=\"Logout\"");
1470      out.print(" hspace=\"3\" vspace=\"5\" ");
1471      out.print(" border=\"0\" width=\"20\" height=\"20\"></a>\n");
1472      out.print("</a>");
1473      out.println("\n <a href=\"" + reqUrl +
1474                  "?compose=true\"  TARGET=\"compose\">");
1475      out.print("\n <img SRC=\"/images/NewEnvelope.gif\" ALT=\"Compose\"");
1476      out.print(" hspace=\"3\" vspace=\"5\" ");
1477      out.print(" border=\"0\" width=\"20\" height=\"20\"></a>\n");
1478      out.print("</a>\n<BR>\n ");
1479      if (msgNum > 1)
1480      {
1481        out.print("<a href=\"" + reqUrl + "?message=" + (msgNum - 1) +"\">");
1482      }
1483      out.print("\n <img SRC=\"/images/Left.gif\" ALT=\"Previous Message\"");
1484      out.print(" hspace=\"3\" vspace=\"5\" ");
1485      out.print(" border=\"0\" width=\"20\" height=\"20\"></a>\n");
1486      if (msgNum > 1)
1487      {
1488        out.print("</a>");
1489      }
1490      out.print(" ");
1491      out.print("\n ");
1492      out.print("<a href=\"" + reqUrl +
1493          "?replyToSelected=false&deleteSelected=true&selected=" + (msgNum) + "\">");
1494      out.print("\n <img SRC=\"/images/DeleteSheet.gif\" ALT=\"Delete\"");
1495      out.print(" hspace=\"3\" vspace=\"5\" ");
1496      out.print(" border=\"0\" width=\"20\" height=\"20\"></a>\n");
1497      out.print("</a>");
1498      out.print(" ");
1499      out.print("\n ");
1500      out.print("<a href=\"" + reqUrl +
1501          "?replyToSelected=true&deleteSelected=false&selected=" + (msgNum) + "\">");
1502      out.print("\n <img SRC=\"/images/Reply.gif\" ALT=\"reply\"");
1503      out.print(" hspace=\"3\" vspace=\"5\" ");
1504      out.print(" border=\"0\" width=\"20\" height=\"20\"></a>\n");
1505      out.print("</a>");
1506      out.print(" ");
1507      out.print("\n ");
1508      if (msgNum < msgCount)
1509      {
1510        out.print("<a href=\"" + reqUrl + "?message=" + (msgNum + 1) + "\">");
1511      }
1512      out.print("\n <img SRC=\"/images/Right.gif\" ALT=\"Next Message\"");
1513      out.print(" hspace=\"3\" vspace=\"5\" ");
1514      out.print(" border=\"0\" width=\"20\" height=\"20\"></a>\n");
1515      if (msgNum < msgCount)
1516      {
1517        out.print("</a>");
1518      }
1519      out.print(" ");
1520      out.println("</font><BR>");
1521
1522      Message msg = mud.getFolder().getMessage(msgNum);
1523
1524      // and now, handle the content
1525      Object o = msg.getContent();
1526
1527      // first, display this message's headers
1528      out.println("\n\n<table width=\"80%\" border=1 align=left cellpadding=4>" +
1529          "<TR><td width=\"100%\" bgcolor=\"" + messageHeadBackColour_ + "\">");
1530      out.print("<font color=\"" + textColour_ + "\" face=\"Arial,Helvetica\">");
1531      if (msg.isMimeType("multipart/*"))
1532      {
1533        Multipart mp = (Multipart)o;
1534        int cnt = mp.getCount();
1535        out.println("Multpart Message: " + cnt + " parts.<BR>\n");
1536      }
1537      displayMessageHeaders(mud, msg, out);
1538      out.print("</font>");
1539      out.println("</td></TR>");
1540
1541      //if (o instanceof String) {
1542      if (msg.isMimeType("text/plain"))
1543      {
1544        out.println("<TR><td bgcolor=\"" + messageBackColour_ + "\">");
1545        out.println("<pre>");
1546        out.println((String)o);
1547        out.println("</pre>");
1548        out.println("</td></TR>");
1549      }
1550      else if (msg.isMimeType("multipart/*"))
1551      {
1552        Multipart mp = (Multipart)o;
1553        int cnt = mp.getCount();
1554        for (int i = 0; i < cnt; i++)
1555        {
1556          displayPart(mud, msgNum, mp.getBodyPart(i), i, req, out);
1557        }
1558      }
1559      else if (msg.isMimeType("text/html"))
1560      {
1561        out.println("<TR><td bgcolor=\"" + messageBackColour_ + "\">");
1562        out.println((String)o);
1563        out.println("</td></TR>");
1564      }
1565      else
1566      {
1567        out.println("<TR><td bgcolor=\"" + messageBackColour_ + "\">");
1568        out.println(msg.getContentType());
1569        out.println("</td></TR>");
1570      }
1571
1572    }
1573    catch (MessagingException mex)
1574    {
1575      log.minor(mex.toString());
1576    }
1577    out.println("</table>");
1578
1579    out.println(getMessageViewBodyClose());
1580    out.close();
1581    log.endMethod();
1582  }
1583
1584
1585  /**
1586   *  This method displays a message part. <code>text/plain</code> content parts
1587   *  are displayed inline. For all other parts, a URL is generated and displayed;
1588   *  clicking on the URL brings up the part in a separate page.
1589   *
1590   * @param  mud              Description of Parameter
1591   * @param  msgNum           Description of Parameter
1592   * @param  part             Description of Parameter
1593   * @param  partNum          Description of Parameter
1594   * @param  req              Description of Parameter
1595   * @param  out              Description of Parameter
1596   * @exception  IOException  Description of Exception
1597   */
1598  private void displayPart(MailUserData mud, int msgNum, Part part,
1599      int partNum, HttpServletRequest req,
1600      ServletOutputStream out)
1601       throws IOException
1602  {
1603    final String methodName = "displayPart";
1604    log.startMethod(methodName);
1605
1606    if (partNum != 0)
1607    {
1608      out.println("<p><hr>");
1609    }
1610
1611    try
1612    {
1613      String sct = part.getContentType();
1614      if (sct == null)
1615      {
1616        out.println("invalid part");
1617        return;
1618      }
1619      ContentType ct = new ContentType(sct);
1620
1621      if (ct.match("text/plain"))
1622      {
1623        // display text/plain inline
1624        out.println("<TR><td bgcolor=\"" + messageBackColour_ + "\">");
1625        if (partNum != 0)
1626        {
1627          out.println("<b>Attachment Type:</b> " +
1628              ct.getBaseType());
1629        }
1630        out.println("<pre>");
1631        out.println((String)part.getContent());
1632        out.println("</pre>");
1633        out.println("</td></TR>\n");
1634      }
1635      else if (ct.match("text/html"))
1636      {
1637        // display text/html inline
1638        out.println("<TR><td bgcolor=\"" + messageHeadBackColour_ + "\">");
1639        if (partNum != 0)
1640        {
1641          out.println("<b>Attachment Type:</b> " +
1642              ct.getBaseType() + "<BR>");
1643        }
1644        out.println((String)part.getContent());
1645        out.println("</td></TR>\n");
1646      }
1647      else
1648      {
1649        // generate a url for this OTHER part
1650        out.println("<TR><td bgcolor=\"" + attachmentBackColour_ + "\">");
1651        String s;
1652        if (partNum != 0)
1653        {
1654          out.println("<b>Attachment Type:</b> " +
1655              ct.getBaseType());
1656        }
1657        if ((s = part.getFileName()) != null)
1658        {
1659          out.println("<b>Filename:</b> " + s + "<br>");
1660        }
1661        s = null;
1662        if ((s = part.getDescription()) != null)
1663        {
1664          out.println("<b>Description:</b> " + s + "<br>");
1665        }
1666
1667        out.println("<a href=\"" +
1668            HttpUtils.getRequestURL(req) +
1669            "?message=" +
1670            msgNum + "&part=" +
1671            partNum + "\">Display Attachment</a>");
1672        out.println("</td></TR>\n");
1673      }
1674    }
1675    catch (MessagingException mex)
1676    {
1677      out.println(mex.toString());
1678    }
1679    log.endMethod();
1680  }
1681
1682
1683  /**
1684   *  This method gets the stream from for a given msg part and pushes it out to
1685   *  the browser with the correct content type. Used to display attachments and
1686   *  relies on the browser's content handling capabilities.
1687   *
1688   * @param  mud              Description of Parameter
1689   * @param  msgNum           Description of Parameter
1690   * @param  partNum          Description of Parameter
1691   * @param  out              Description of Parameter
1692   * @param  res              Description of Parameter
1693   * @exception  IOException  Description of Exception
1694   */
1695  private void displayPart(MailUserData mud,
1696                           int msgNum,
1697                           int partNum,
1698                           ServletOutputStream out,
1699                           HttpServletResponse res)
1700                           throws IOException
1701  {
1702    final String methodName = "displayPart.2";
1703    log.startMethod(methodName);
1704
1705    Part part = null;
1706
1707    try
1708    {
1709      Message msg = mud.getFolder().getMessage(msgNum);
1710
1711      Multipart mp = (Multipart)msg.getContent();
1712      part = mp.getBodyPart(partNum);
1713
1714      String sct = part.getContentType();
1715      if (sct == null)
1716      {
1717        out.println("invalid part");
1718        return;
1719      }
1720      ContentType ct = new ContentType(sct);
1721
1722      res.setContentType(ct.getBaseType());
1723      InputStream is = part.getInputStream();
1724      int i;
1725      while ((i = is.read()) != -1)
1726      {
1727        out.write(i);
1728      }
1729      out.flush();
1730      out.close();
1731    }
1732    catch (MessagingException mex)
1733    {
1734      out.println(mex.toString());
1735    }
1736    log.endMethod();
1737  }
1738
1739
1740  /**
1741   *  This is a utility method that pretty-prints the message headers for message
1742   *  that is being displayed.
1743   *
1744   * @param  mud              The Mail User Data Object to use
1745   * @param  msg              The message to display the headers for.
1746   * @param  out              The ServletOutputStream
1747   * @exception  IOException  Description of Exception
1748   */
1749  private void displayMessageHeaders(MailUserData mud,
1750                                     Message msg,
1751                                     ServletOutputStream out)
1752                                     throws IOException
1753  {
1754    final String methodName = "displayMessageHeaders";
1755    log.startMethod(methodName);
1756
1757    try
1758    {
1759      out.println("<b>Date:</b> " + msg.getSentDate() + "<br>");
1760
1761      Address[] fr = msg.getFrom();
1762      if (fr != null)
1763      {
1764        boolean tf = true;
1765        out.print("<b>From:</b> ");
1766        for (int i = 0; i < fr.length; i++)
1767        {
1768          out.print(((tf) ? " " : ", ") + getDisplayAddress(fr[i]));
1769          tf = false;
1770        }
1771        out.println("<br>");
1772      }
1773
1774      Address[] to = msg.getRecipients(Message.RecipientType.TO);
1775      if (to != null)
1776      {
1777        boolean tf = true;
1778        out.print("<b>To:</b> ");
1779        for (int i = 0; i < to.length; i++)
1780        {
1781          out.print(((tf) ? " " : ", ") + getDisplayAddress(to[i]));
1782          tf = false;
1783        }
1784        out.println("<br>");
1785      }
1786
1787      Address[] cc = msg.getRecipients(Message.RecipientType.CC);
1788      if (cc != null)
1789      {
1790        boolean cf = true;
1791        out.print("<b>CC:</b> ");
1792        for (int i = 0; i < cc.length; i++)
1793        {
1794          out.print(((cf) ? " " : ", ") + getDisplayAddress(cc[i]));
1795          cf = false;
1796        }
1797        out.println("<br>");
1798      }
1799
1800      out.print("<b>Subject:</b> " +
1801          ((msg.getSubject() != null) ? msg.getSubject() : "") +
1802          "<br>");
1803
1804    }
1805    catch (MessagingException mex)
1806    {
1807      out.println(msg.toString());
1808    }
1809    log.endMethod();
1810  }
1811
1812
1813  /**
1814   *  This method displays the INBOX headerlist.
1815   *
1816   * @param  mud              The Mail User Data object to get the data from.
1817   * @param  req              Description of Parameter
1818   * @param  out              Description of Parameter
1819   * @param  numShowing       The number of msgs to show per page.
1820   * @param  pageNum          The page to display.
1821   * @exception  IOException  Description of Exception
1822   */
1823  private void displayInboxHtml(MailUserData mud,
1824                                HttpServletRequest req,
1825                                ServletOutputStream out,
1826                                int numShowing,
1827                                int pageNum)
1828                         throws IOException
1829  {
1830    final String methodName = "displayInboxHtml";
1831    log.startMethod(methodName);
1832    int msgCount = 0;
1833    int numPages = pageNum;
1834    int leftOvers = 0;
1835    int endSpot = 0;
1836    int startSpot = 0;
1837
1838    try
1839    {
1840      // calculate the pageing variables
1841      String currRowColour = rowColour_;
1842      Folder folder = mud.getFolder();
1843      msgCount = folder.getMessageCount();
1844      numPages = msgCount / numShowing + 1;
1845      leftOvers = msgCount % numShowing;
1846      startSpot = (numPages - pageNum) * numShowing + leftOvers;
1847      endSpot = startSpot - numShowing;
1848      if (endSpot < 0)
1849        endSpot = 0;
1850      log.debug("  msgCount="+msgCount+"\n  numPages="+numPages+
1851                "\n  leftOvers="+leftOvers+"\n  startSpot="+startSpot+
1852                "\n  endSpot="+endSpot);
1853
1854
1855      // now add some back and next links (if needed)
1856      if (pageNum > 1 || endSpot > 1)
1857      {
1858        if (pageNum > 1)
1859          out.print("\n<BR><A href=\""+HttpUtils.getRequestURL(req) +
1860                "?messageStartPage=" + (pageNum-1) + "&messagesPerPage=" +
1861                numShowing + "\">");
1862        else
1863          out.println("<BR>");
1864        out.println("&lt;&lt;--Previous Page </A>");
1865        out.println(" | ");
1866        if (endSpot > 1) // still more
1867          out.print("<A href=\""+HttpUtils.getRequestURL(req) +
1868                "?messageStartPage=" + (pageNum+1) + "&messagesPerPage=" +
1869                numShowing + "\">");
1870        out.println(" Next Page--&gt;&gt;</A>");
1871      }
1872
1873      // Form up the Message List Table
1874      // List headers in the table
1875      out.println("<FORM METHOD=\"POST\" name=\"msgList\" ACTION=\"" +
1876          HttpUtils.getRequestURL(req) +
1877          "\">");
1878
1879      out.print("<table cellpadding=1 cellspacing=1 "); // table
1880      out.println("width=\"800\" border=1>"); // settings
1881
1882      out.println("  <tr>");
1883
1884      // selected column header
1885      out.println("    <td width=\"30\" bgcolor=\"" + tableBackColour_ + "\">");
1886      out.println("     </td>");
1887      // subject column header
1888      out.println("    <td width=\"410\"bgcolor=\"" + tableBackColour_ + "\">");
1889      out.println("      <font face=\"Arial,Helvetica\" font size=\"+1\">");
1890      out.println("      <b>Subject</b></font>");
1891      out.println("    </td>");
1892      // sender column header
1893      out.println("    <td width=\"260\" bgcolor=\"" + tableBackColour_ + "\">");
1894      out.println("      <font face=\"Arial,Helvetica\" font size=\"+1\">");
1895      out.println("      <b>Sender</b></font>");
1896      out.println("    </td>");
1897      // date column header
1898      out.println("    <td width=\"100\" bgcolor=\"" + tableBackColour_ + "\">");
1899      out.println("      <font face=\"Arial,Helvetica\" font size=\"+1\">");
1900      out.println("      <b>Date</b></font>");
1901      out.println("    </td>");
1902      out.println("  </tr>");
1903
1904
1905      // Now on with the messages
1906      Message msg = null;
1907      String sender = "";
1908      String fontSize = "+0";
1909      // for each message, show its headers
1910      for (int i = startSpot; i > endSpot; i--)
1911      {
1912        msg = folder.getMessage(i);
1913
1914        if (msg != null)
1915        {
1916          // if message has the DELETED flag set, don't display it
1917          if (msg.isSet(Flags.Flag.DELETED))
1918          {
1919            log.debug("Message " + i + " is set as deleted - Don't show");
1920            endSpot--;
1921          }
1922          else
1923          {
1924            // higlight NEW message rows with a brighter colour
1925            if (!msg.isSet(Flags.Flag.ANSWERED) &&
1926                !msg.isSet(Flags.Flag.DRAFT) &&
1927                !msg.isSet(Flags.Flag.SEEN))
1928            {
1929              currRowColour = newMessageBackColour;
1930            }
1931            else
1932            {
1933              currRowColour = rowColour_;
1934            }
1935
1936            // CheckBox
1937            out.println("\n<tr valigh=middle>");
1938            out.println("  <td width=\"30\" bgcolor=\"" + currRowColour + "\">");
1939            out.println("    <INPUT NAME=\"msgSelect" + i +
1940                "\" TYPE=\"checkbox\"> ");
1941            out.println("  </td>");
1942
1943            // subject & link
1944            out.println("  <td width=\"410\" bgcolor=\"" + currRowColour + "\">");
1945            // wrap the next in a try block in case of weird unhandled encodings
1946            try
1947            {
1948              out.println("    <font face=\"Arial,Helvetica\">" +
1949                  "\n          <a href=\"" +
1950                  HttpUtils.getRequestURL(req) +
1951                  "?message=" + i + "\">\n            " +
1952                  ((msg.getSubject() != null) ?
1953                  msg.getSubject() :
1954                  "<i>No Subject</i>") +
1955                  "</a>" +
1956                  "</font>\n");
1957            }
1958            catch (Exception ex)
1959            {
1960              out.println("<i>Error with message subject.</i>");
1961            }
1962            out.println("  </td>");
1963
1964
1965            // from
1966            StringBuffer sb = new StringBuffer();
1967            try
1968            {
1969              sender = ((msg.getFrom() != null) ? msg.getFrom()[0].toString() : "");
1970              if (sender.length() > 40 )
1971                fontSize = "-1";
1972              else
1973                fontSize = "+0";
1974              if (sender.length() > 45 )
1975                sender = sender.substring(0,45); //anything longer than 45 get chopped
1976
1977              sender = tokenReplace(sender, "<", "&lt;");
1978              sender = tokenReplace(sender, ">", "&gt;");
1979              sb.append("  <td width=\"260\" bgcolor=\"");
1980              sb.append(currRowColour);
1981              sb.append("\">\n");
1982              sb.append("    <font face=\"Arial,Helvetica\" size=\"");
1983              sb.append(fontSize);
1984              sb.append("\">\n");
1985              sb.append(sender);
1986              sb.append("</font>\n  </td>");
1987              out.println(sb.toString());
1988            }
1989            catch (Exception ex)
1990            {
1991              sb = new StringBuffer();
1992              sb.append("  <td width=\"260\" bgcolor=\"");
1993              sb.append(currRowColour);
1994              sb.append("\">\n");
1995              sb.append("    <font face=\"Arial,Helvetica\" size=\"");
1996              sb.append(fontSize);
1997              sb.append("\">\n");
1998              sb.append("Error With sender.");
1999              sb.append("</font>\n  </td>");
2000              out.println(sb.toString());
2001            }
2002
2003            // date
2004            SimpleDateFormat df = new SimpleDateFormat("EE M/d/yy");
2005
2006            out.println("  <td nowrap width=\"100\" bgcolor=\"" +
2007                currRowColour + "\">");
2008            Date sentDate = msg.getSentDate();
2009            Date receivedDate = msg.getReceivedDate();
2010            out.println("    <font face=\"Arial,Helvetica\">" +
2011                df.format((sentDate != null) ? sentDate :
2012                (receivedDate != null ? receivedDate : new Date())) +
2013                "</font>");
2014            out.println("  </td>");
2015
2016            out.println("</tr>");
2017          }
2018        }
2019        else
2020        {
2021          log.debug("Message " + i + " is null - don't show.");
2022        }
2023
2024      }
2025      out.println("</table></form>");
2026
2027      // now add some back and next links (if needed)
2028      if (pageNum > 1 || endSpot > 1)
2029      {
2030        if (pageNum > 1)
2031          out.print("<A href=\""+HttpUtils.getRequestURL(req) +
2032                "?messageStartPage=" + (pageNum-1) + "&messagesPerPage=" +
2033                numShowing + "\">");
2034        out.println("&lt;&lt;--Previous Page </A>");
2035        out.println(" | ");
2036        if (endSpot > 1) // still more
2037          out.print("<A href=\""+HttpUtils.getRequestURL(req) +
2038                "?messageStartPage=" + (pageNum+1) + "&messagesPerPage=" +
2039                numShowing + "\">");
2040        out.println(" Next Page--&gt;&gt;</A>\n");
2041      }
2042    }
2043    catch (MessagingException mex)
2044    {
2045      out.println("<tr><td>" + mex.toString() + "</td></tr>");
2046      mex.printStackTrace();
2047      out.println("</table></form>");
2048    }
2049
2050
2051    out.println(getFolderViewBodyClose());
2052    log.endMethod();
2053  }
2054
2055
2056  /**
2057   *  This method displays the URLs for the available commands in a html.
2058   *
2059   * @param  req              Description of Parameter
2060   * @param  out              Description of Parameter
2061   * @exception  IOException  Description of Exception
2062   */
2063  private void displayCommandBarHtml(HttpServletRequest req,
2064                                     ServletOutputStream out)
2065                              throws IOException
2066  {
2067    final String methodName = "displayCommandBarHtml";
2068    log.startMethod(methodName);
2069
2070    StringBuffer url = HttpUtils.getRequestURL(req);
2071    // URL's for the commands that are available
2072      out.println("<font face=\"Arial,Helvetica\" color=\"" +
2073        textColour_ + "size=\"+1\">");
2074      out.print("\n<a href=\"" + url + "?logout=true\">");
2075      out.print("\n <img SRC=\"/images/UnPlug.gif\" ALT=\"Logout\"");
2076      out.print(" hspace=\"3\" vspace=\"5\" ");
2077      out.print(" border=\"0\" width=\"20\" height=\"20\"></a>\n");
2078      out.print("</a>");
2079      out.println("\n <a href=\"" + url +
2080                  "?compose=true\"  TARGET=\"compose\">");
2081      out.print("\n <img SRC=\"/images/NewEnvelope.gif\" ALT=\"Compose\"");
2082      out.print(" hspace=\"3\" vspace=\"5\" ");
2083      out.print(" border=\"0\" width=\"20\" height=\"20\"></a>\n");
2084      out.print("</a>\n&nbsp;&nbsp;&nbsp;\n ");
2085      out.println("<font face=\"Arial,Helvetica\" font size=\"+0\">");
2086      out.println("<a href=\"" +
2087        "javascript:ReplyToMessages('" + url + "')\">");
2088      out.print("\n <img SRC=\"/images/Reply.gif\" ALT=\"reply\"");
2089      out.print(" hspace=\"3\" vspace=\"5\" ");
2090      out.print(" border=\"0\" width=\"20\" height=\"20\"></a>\n");
2091      out.print("</a>");
2092      out.print(" ");
2093      out.print("\n ");
2094    out.println("<a href=\"" +
2095        "javascript:DeleteMessages('" + url + "')\">");
2096      out.print("\n <img SRC=\"/images/DeleteSheet.gif\" ALT=\"delete selected\"");
2097      out.print(" hspace=\"3\" vspace=\"5\" ");
2098      out.print(" border=\"0\" width=\"20\" height=\"20\"></a>\n");
2099      out.print("</a>");
2100      out.print(" ");
2101      out.print("\n ");
2102    out.println("</font>\n");
2103
2104    log.endMethod();
2105  }
2106
2107
2108  /**
2109   *  This method displays the URL's for the available commands and
2110   * the INBOX headerlist.
2111   *
2112   * @param  mud              The Mail User data for the logged in user
2113   * @param  req              This Sessions current request
2114   * @param  out              The req out stream
2115   * @exception  IOException  Description of Exception
2116   */
2117  private void displayHeaderTableHtml(MailUserData mud,
2118                                      HttpServletRequest req,
2119                                      ServletOutputStream out,
2120                                      int messagesPerPage,
2121                                      int messageStartPage)
2122                                      throws IOException
2123  {
2124    final String methodName = "displayHeaderTableHtml";
2125    log.startMethod(methodName);
2126
2127    out.println("<html>");
2128    out.println(folderViewHead);
2129    out.println(getFolderViewBodyHeader("Folder " + mud.getStore().getURLName() +
2130        "/INBOX<p>"));
2131
2132    displayCommandBarHtml(req, out);
2133
2134    displayInboxHtml(mud, req, out, messagesPerPage, messageStartPage);
2135
2136    out.flush();
2137    out.close();
2138    log.endMethod();
2139  }
2140
2141
2142  /**
2143   *  This method handles the request when the user hits the <i>ReplyTo</i> link.
2144   *  It send the compose form to the browser.
2145   *
2146   * @param  mud              Description of Parameter
2147   * @param  res              Description of Parameter
2148   * @param  out              Description of Parameter
2149   * @param  replyToAddr      The email addr to prload into the to field
2150   * @exception  IOException  Description of Exception
2151   */
2152  private void replyCompose(MailUserData mud, HttpServletResponse res,
2153      ServletOutputStream out, String replyToAddr, String replySubject)
2154       throws IOException
2155  {
2156    final String methodName = "replyCompose";
2157    log.startMethod(methodName);
2158
2159    res.setContentType("text/html");
2160
2161    // need to assign the reply addr here first
2162    mailToAddr_ = replyToAddr;
2163    replySubject_ = replySubject;
2164    out.println(getComposeFormHtml());
2165    out.close();
2166    log.endMethod();
2167  }
2168
2169
2170  /**
2171   * Returns the Latest updated Compose Form HTML String.
2172   **/
2173  private String getComposeFormHtml()
2174  {
2175      return folderViewHead + composeBodyHeader_ +
2176      "<FORM ACTION=\"" + servletName_ + "\" METHOD=\"POST\">\n" +
2177      "<input type=\"hidden\" name=\"send\" value=\"true\">\n" +
2178      "<P><TABLE BORDER=\"0\" align=left>\n" +
2179      "<TR><TD WIDTH=\"16%\" HEIGHT=\"22\">\n <P ALIGN=\"RIGHT\">" +
2180      "<B><FONT FACE=\"Verdana, Arial, Helvetica\">To:</FONT></B></TD>" +
2181      "<TD WIDTH=\"84%\" HEIGHT=\"22\">\n" +
2182      "<INPUT TYPE=\"TEXT\" NAME=\"to\" SIZE=\"30\" value=\"" + mailToAddr_ +
2183      "\"><FONT SIZE=\"1\" FACE=\"Verdana, Arial, Helvetica\">" +
2184      " (separate addresses with commas)</FONT></TD>" +
2185      "</TR><TR><TD WIDTH=\"16%\">\n" +
2186      "<P ALIGN=\"RIGHT\"><B><FONT FACE=\"Verdana, Arial, Helvetica\">" +
2187      "CC:</FONT></B></TD><TD WIDTH=\"84%\">\n" +
2188      "<INPUT TYPE=\"TEXT\" NAME=\"cc\" SIZE=\"30\"> " +
2189      "<FONT SIZE=\"1\" FACE=\"Verdana, Arial, Helvetica\"> " +
2190      "(separate addresses with commas)</FONT></TD></TR>" +
2191      "<TR><TD WIDTH=\"16%\">\n" +
2192      "<P ALIGN=\"RIGHT\"><B><FONT FACE=\"Verdana, Arial, Helvetica\">" +
2193      "Subject:</FONT></B></TD><TD WIDTH=\"84%\">\n" +
2194      "<INPUT TYPE=\"TEXT\" NAME=\"subject\" SIZE=\"55\" value=\"" +
2195      replySubject_+"\"></TD></TR>\n" +
2196      "<TR><TD WIDTH=\"16%\"> </TD>\n" +
2197      "<TD WIDTH=\"84%\">\n" +
2198      "<TEXTAREA NAME=\"text\" ROWS=\"15\" COLS=\"53\">"+
2199      composeBody_ +"</TEXTAREA></TD></TR>\n" +
2200      "<TR><TD WIDTH=\"16%\" HEIGHT=\"32\"> </TD>\n" +
2201      "<TD WIDTH=\"84%\" HEIGHT=\"32\">\n" +
2202      "<INPUT TYPE=\"SUBMIT\" NAME=\"Send\" VALUE=\"Send\"\n>" +
2203      "<INPUT TYPE=\"RESET\" NAME=\"Reset\" VALUE=\"Reset\">\n" +
2204      "</TD></TR></TABLE></FORM>\n" + folderViewBodyClose_;
2205  }
2206
2207
2208  /**
2209   *  This method handles the request when the user hits the <i>Compose</i> link.
2210   *  It send the compose form to the browser.
2211   *
2212   * @param  mud              Description of Parameter
2213   * @param  res              Description of Parameter
2214   * @param  out              Description of Parameter
2215   * @exception  IOException  Description of Exception
2216   */
2217  private void compose(MailUserData mud, HttpServletResponse res,
2218      ServletOutputStream out)
2219       throws IOException
2220  {
2221    final String methodName = "compose";
2222    log.startMethod(methodName);
2223
2224    res.setContentType("text/html");
2225    out.println(getComposeFormHtml());
2226    out.close();
2227    log.endMethod();
2228  }
2229
2230
2231  /**
2232   *  This method processes the send request from the compose form
2233   *
2234   * @param  req              Description of Parameter
2235   * @param  res              Description of Parameter
2236   * @param  out              Description of Parameter
2237   * @param  ssn              Description of Parameter
2238   * @exception  IOException  Description of Exception
2239   */
2240  private void send(HttpServletRequest req,
2241                    HttpServletResponse res,
2242                    ServletOutputStream out,
2243                    HttpSession ssn)
2244             throws IOException
2245  {
2246    final String methodName = "send";
2247    log.startMethod(methodName);
2248
2249    String to = req.getParameter("to");
2250    String cc = req.getParameter("cc");
2251    String subj = req.getParameter("subject");
2252    String text = req.getParameter("text");
2253
2254    try
2255    {
2256      MailUserData mud = getMUD(ssn);
2257      if (mud == null)
2258      {
2259        throw new Exception("trying to send, but not logged in");
2260      }
2261
2262      Message msg = new MimeMessage(mud.getSession());
2263      InternetAddress[] toAddrs = null;
2264      InternetAddress[] ccAddrs = null;
2265
2266      if (to != null)
2267      {
2268        toAddrs = InternetAddress.parse(to, false);
2269        msg.setRecipients(Message.RecipientType.TO, toAddrs);
2270      }
2271      else
2272      {
2273        throw new MessagingException("No \"To\" address specified");
2274      }
2275
2276      if (cc != null)
2277      {
2278        ccAddrs = InternetAddress.parse(cc, false);
2279        msg.setRecipients(Message.RecipientType.CC, ccAddrs);
2280      }
2281
2282      msg.setSentDate(new Date());
2283
2284      if (subj != null)
2285      {
2286        msg.setSubject(subj);
2287      }
2288
2289      URLName u = mud.getURLName();
2290      msg.setFrom(new InternetAddress(u.getUsername() + "@" + u.getHost()));
2291
2292      if (text != null)
2293      {
2294        msg.setText(text);
2295      }
2296
2297      Transport.send(msg);
2298
2299      out.println("<h1>Message sent successfully</h1>\n" +
2300      "<p><b><a href=\"javascript:window.close()\">&laquo;Close</a>"+
2301      "</b>\n</body></html>");
2302      out.close();
2303
2304    }
2305    catch (Exception mex)
2306    {
2307      out.println("<h1>Error sending message.</h1>");
2308      out.println(mex.toString() +
2309        "<p><b><a href=\"javascript:window.close()\">&laquo;Close</a>"+
2310        "</b>\n</body></html>");
2311    }
2312    log.endMethod();
2313  }
2314
2315}
2316
2317/**
2318 *  This class is used to store mailSession data for each user's
2319mailSession. It
2320 *  is stored in the HttpSession.
2321 *
2322 * @created    August 9, 2001
2323 */
2324class MailUserData
2325{
2326  /**
2327   * Flags if the User has already logged in.
2328   **/
2329   boolean isLoggedIn = false;
2330  /**
2331   *  The original Login URL.
2332   */
2333  URLName                url;
2334  /**
2335   *  This users curreent Mail Session.
2336   */
2337  Session                mailSession;
2338  /**
2339   *  This Users logged in Message Store.
2340   */
2341  Store                  store;
2342  /**
2343   *  The mail folder.
2344   */
2345  Folder                 folder;
2346
2347  /**
2348   * This users username.
2349   **/
2350  String username = "";
2351
2352  /**
2353   * This users server-side webmail settings dir.
2354   **/
2355  String userWebmailDir = ".webmail";
2356
2357  /**
2358   *  Constructor for the MailUserData object
2359   *
2360   * @param  urlname  Description of Parameter
2361   */
2362  public MailUserData(URLName urlname)
2363  {
2364    System.out.println("Creating MUD for url: " + urlname);
2365
2366    url = urlname;
2367  }
2368
2369
2370  /**
2371   * Getter method for loggedIn. It tells if the user with this MUD has already
2372   * logged in and initiated its mail session.
2373   **/
2374   public boolean getIsLoggedIn() {return isLoggedIn;}
2375
2376  /**
2377   * Setter method for loggedIn. It tells if the user with this MUD has already
2378   * logged in and initiated its mail session.
2379   **/
2380   public void setIsLoggedIn(boolean val) {isLoggedIn = val;}
2381
2382  /**
2383   *  Sets the Session attribute of the MailUserData object
2384   *
2385   * @param  s  The new Session value
2386   */
2387  public void setSession(Session s)
2388  {
2389    mailSession = s;
2390  }
2391
2392
2393  /**
2394   *  Sets the Store attribute of the MailUserData object
2395   *
2396   * @param  s  The new Store value
2397   */
2398  public void setStore(Store s)
2399  {
2400    store = s;
2401  }
2402
2403
2404  /**
2405   *  Sets the Folder attribute of the MailUserData object
2406   *
2407   * @param  f  The new Folder value
2408   */
2409  public void setFolder(Folder f)
2410  {
2411    folder = f;
2412  }
2413
2414
2415  /**
2416   *  Gets the URLName attribute of the MailUserData object
2417   *
2418   * @return    The URLName value
2419   */
2420  public URLName getURLName()
2421  {
2422    return url;
2423  }
2424
2425
2426  /**
2427   *  Gets the Session attribute of the MailUserData object
2428   *
2429   * @return    The Session value
2430   */
2431  public Session getSession()
2432  {
2433    return mailSession;
2434  }
2435
2436
2437  /**
2438   *  Gets the Store attribute of the MailUserData object
2439   *
2440   * @return    The Store value
2441   */
2442  public Store getStore()
2443  {
2444    return store;
2445  }
2446
2447
2448  /**
2449   *  Gets the Folder attribute of the MailUserData object
2450   *
2451   * @return    The Folder value
2452   */
2453  public Folder getFolder()
2454  {
2455    return folder;
2456  }
2457}
2458
2459
2460