pjs/grendel/TestFolderViewer.java

280 строки
8.7 KiB
Java

/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is the Grendel mail/news client.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1997
* Netscape Communications Corporation. All Rights Reserved.
*
* Created: Jamie Zawinski <jwz@mozilla.org>, 7-Sep-98.
*/
package grendel;
import java.io.File;
import java.io.RandomAccessFile;
import java.io.IOException;
import java.io.InputStream;
import java.io.DataInputStream;
import java.io.InputStreamReader;
import java.util.Properties;
import java.util.Hashtable;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Folder;
import javax.mail.Session;
import java.util.Vector;
import java.util.Enumeration;
import java.util.NoSuchElementException;
import java.util.Date;
import calypso.util.ByteBuf;
import calypso.util.ArrayEnumeration;
import calypso.util.QSort;
import calypso.util.Comparer;
import calypso.util.NetworkDate;
import grendel.storage.BerkeleyStore;
import grendel.storage.MessageExtra;
import grendel.view.FolderView;
import grendel.view.FolderViewFactory;
import grendel.view.MessageSetView;
import grendel.view.ViewedMessage;
class TestFolderViewer {
public static void main(String args[])
throws IOException, MessagingException {
if (args.length != 1) {
System.out.println("usage: TestFolderViewer <mail-folder-pathname>\n");
return;
}
// First, split the directory and file name, and store the directory
// in the "mail.directory" property (since JavaMail expects that.)
//
File pathname = new File(new File(args[0]).getAbsolutePath());
String dir = pathname.getParent();
String name = pathname.getName();
Properties props = new Properties();
props.put("mail.directory", dir);
// Make the global "session" and "store" object.
//
Session session = Session.getDefaultInstance(props, null);
BerkeleyStore store = new BerkeleyStore(session);
// Parse the folder. This will use a .summary file if one exists and is
// up to date; otherwise, it will parse the whole folder. The `list'
// array will hold Message (really, BerkeleyMessage) objects representing
// each of the messages in the folder. Message objects are lightweight:
// really they are just info like sender/subject/offset-in-file, etc.
//
System.out.println("Folder " + new File(dir, name));
Folder folder = store.getDefaultFolder().getFolder(name);
Message list[] = folder.getMessages();
System.out.println("Found " + list.length + " messages.");
// Print out a summary of the contents of the folder.
threadAndPrint(folder, MessageSetView.DATE, true);
// Interact with the user.
mainLoop(folder);
}
// Gag -- for some reason our Message objects don't have getMessageNumber()
// set in them (see FolderBase.noticeInitialMessage()) so until this is
// fixed, let's kludge around it by keeping track of the index of the
// message in its folder externally, in this hash table. This is totally
// the wrong thing, but for now, it's expedient.
//
static Hashtable msgnum_kludge;
static void threadAndPrint(Folder folder, int sort_type, boolean thread_p) {
FolderView view = FolderViewFactory.Make(folder);
int order[] = { sort_type, MessageSetView.NUMBER };
// See "gag" comment above.
// Populate the msgnum_kludge with message -> folder-index numbers.
msgnum_kludge = new Hashtable();
try {
for (int i = 0; i < folder.getMessageCount(); i++)
msgnum_kludge.put(folder.getMessage(i+1), new Integer(i+1));
} catch (MessagingException e) {
System.out.println("Error: " + e);
}
System.out.println("Sorting by " +
(sort_type == MessageSetView.NUMBER ? "number" :
sort_type == MessageSetView.DATE ? "date" :
sort_type == MessageSetView.SUBJECT ? "subject" :
sort_type == MessageSetView.AUTHOR ? "author" :
sort_type == MessageSetView.READ ? "read" :
sort_type == MessageSetView.FLAGGED ? "flagged" :
sort_type == MessageSetView.SIZE ? "size" :
sort_type == MessageSetView.DELETED ? "deleted" :"?")
+ ".");
System.out.println(thread_p ? "Threading." : "Not threading.");
// Tell the FolderView how to sort/thread, and then do it.
//
view.setSortOrder(order);
view.setIsThreaded(thread_p);
view.reThread();
// Now show the result.
printThread(view.getMessageRoot(), 0);
}
static void printThread(ViewedMessage vm, int depth) {
Message msg = (Message) vm.getMessage();
String str = "";
for (int i = 0; i < depth; i++)
str += " ";
if (msg == null) {
// A ViewedMessage with no Message inside is a dummy container, holding
// a thread together (for example, when the parent message of two
// siblings is not present in the folder (expired or deleted.))
//
str += " [dummy]";
} else {
// Construct a string describing this message.
//
String a = "", s = "", n = "";
Date d = null;
try {
a = ((MessageExtra) msg).getAuthor();
} catch (MessagingException e) {
}
try {
s = msg.getSubject();
} catch (MessagingException e) {
}
// See "gag" comment, above.
int ni = ((Integer) msgnum_kludge.get(msg)).intValue() - 1;
// int ni = msg.getMessageNumber();
n = "" + ni;
if (ni < 10) n += " ";
else if (ni < 100) n += " ";
else if (ni < 1000) n += " ";
else if (ni < 10000) n += " ";
str = n + str;
int L = str.length();
if (a.length() > 23-L) a = a.substring(0, 23-L);
if (s.length() > 23) s = s.substring(0, 23);
str += a;
for (int i = L+a.length(); i < 25; i++)
str += " ";
str += s;
for (int i = s.length(); i < 25; i++)
str += " ";
try {
d = msg.getSentDate();
} catch (MessagingException e) {
}
if (d != null && d.getTime() != 0)
str += d;
else
str += "date unknown";
}
// Print the string describing this message.
System.out.println(str);
// If this message has children, print them now (indented.)
// After printing this message's children/grandchildren,
// move on and print the next message in the list. (Note
// that we're walking the list by recursing, but that's
// probably ok, as its tail-recursion.)
//
ViewedMessage next = vm.getNext();
ViewedMessage kid = vm.getChild();
if (kid != null) printThread(kid, depth+1);
if (next != null) printThread(next, depth);
}
static void mainLoop(Folder f) throws IOException {
DataInputStream in = new DataInputStream(System.in);
while (true) {
// Read a line from the user; parse an integer from it; and dump
// the selected message to stdout. Then repeat.
//
System.out.print("\nDisplay which message: ");
String s = in.readLine();
try {
int n = Integer.parseInt(s, 10);
System.out.println("Displaying message " + n + ".");
try {
Message m = f.getMessage(n+1);
try {
InputStream stream =
((MessageExtra)m).getInputStreamWithHeaders();
// if (makeRealHTML) {
// stream = new MakeItHTML(stream).getHTMLInputStream();
// }
InputStreamReader reader = new InputStreamReader(stream);
char buff[] = new char[4096];
int count;
System.out.println("\n-----------");
while ((count = reader.read(buff, 0, 4096)) != -1) {
System.out.println(new String(buff, 0, count));
}
System.out.println("\n-----------");
} catch (MessagingException e) {
System.out.println("Error: " + e);
} catch (IOException e) {
System.out.println("Error: " + e);
}
} catch (MessagingException e) {
System.out.println("Error: " + e);
}
} catch (NumberFormatException e) {
System.out.println("That's not a number.");
}
}
}
}