For a bit of fun, and to demonstrate a novel use of the JavaMail APIs, I now briefly turn to my talking email project. To try this out you'll need
lotontalk.jar
File (supplied), and you'll need to include it in your classpath, as in:
set CLASSPATH=%CLASSPATH%;lotontalk.jar
Set CLASSPATH = % CLASSPATH %; lotontalk. jar
You'll also need to make two code changes withinSimpleReceiver
Class. First, insidereceive(...)
Method, replace this code:
// -- Get the message wrappers and process them --
Message[] msgs = folder.getMessages();
for (int msgNum = 0; msgNum < msgs.length; msgNum++)
{
printMessage(msgs[msgNum]);
}
// -- Get the message wrappers and process them --
Message [] msgs = folder. getMessages ();
For (int msgNum = 0; msgNum <msgs. length; msgNum ++)
{
PrintMessage (msgs [msgNum]);
}
With:
// -- Get the message wrappers and process them --
Message[] msgs = folder.getMessages();
for (int msgNum = 0; msgNum < msgs.length; msgNum++)
{
printMessage(msgs[msgNum]);
speakMessage(msgs[msgNum]);
}
// -- Get the message wrappers and process them --
Message [] msgs = folder. getMessages ();
For (int msgNum = 0; msgNum <msgs. length; msgNum ++)
{
Printmessage (MSGs [msgnum]);
Speakmessage (MSGs [msgnum]);
}
Now add the following new method,speakMessage(...)
, Which is similar to the originalprintMessage()
Method:
/**
* "speakMessage", a talking version of printMessage().
*/
public static void speakMessage(Message message)
{
String speech="";
try
{
com.lotontech.talk.LOTONtalk speaker
=new com.lotontech.talk.LOTONtalk();
String from=((InternetAddress)message.getFrom()[0]).getPersonal();
if (from==null) from=((InternetAddress)message.getFrom()[0])
.getAddress();
speech=speech+"from "+from+", ";
String subject=message.getSubject();
speech=speech+"subject "+subject+", ";
// -- Get the message part (i.e., the message itself) --
Part messagePart=message;
Object content=messagePart.getContent();
// -- ...or its first body part if it is a multipart message --
if (content instanceof Multipart)
messagePart=((Multipart)content).getBodyPart(0);
String contentType=messagePart.getContentType();
if (contentType.startsWith("text/plain")
|| contentType.startsWith("text/html"))
{
InputStream is = messagePart.getInputStream();
BufferedReader reader
=new BufferedReader(new InputStreamReader(is));
String thisLine=reader.readLine();
while (thisLine!=null)
{
speech=speech+thisLine+". ";
thisLine=reader.readLine();
}
// -- SPEAK --
speaker.speak(speech,true);
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
/**
* "Speakmessage", a talking version of printmessage ().
*/
Public static void speakmessage (message)
{
String speech = "";
Try
{
Com. lotontech. Talk. lotontalk speaker
= New COM. lotontech. Talk. lotontalk ();
String from = (internetaddress) message. getfrom () [0]). getpersonal ();
If (from = NULL) from = (internetaddress) message. getfrom () [0])
. Getaddress ();
Speech = speech + "from" + from + ",";
String subject = message. getsubject ();
Speech = speech + "subject" + Subject + ",";
// -- Get the message part (I. e., the message itself )--
Part messagepart = message;
Object content = messagepart. getcontent ();
// --... Or its first body part if it is a multipart message --
If (content instanceof multipart)
Messagepart = (multipart) content). getbodypart (0 );
String contenttype = messagepart. getcontenttype ();
If (contenttype. startswith ("text/plain ")
| Contenttype. startswith ("text/html "))
{
Inputstream is = messagepart. getinputstream ();
Bufferedreader
= New bufferedreader (New inputstreamreader (is ));
String thisline = reader. Readline ();
While (thisline! = NULL)
{
Speech = speech + thisline + ".";
Thisline = reader. Readline ();
}
// -- Speak --
Speaker. Speak (speech, true );
}
}
Catch (Exception ex)
{
Ex. printStackTrace ();
}
}
Because you're accumulating the whole message text in a string before speaking it, this solution may be suitable only for small messages. Alternatively, you cocould speak each line of text as you read it.
Of course, it's impossible for me to show the result exactly, so you'll have to try it for yourself. you have everything you need, and, though it's not yet half as good as I 'd like it to be, you'll get a feel for where it's heading.
With a little experimentation, possibly outside of this example, you will discover some interesting features of the speech synthesis: how it handles numbers, and how it assumes wholly capitalized words to be acronyms, thus S-P-E-L-L-I-N-G them out.
For further consideration
We 've covered quite a bit of ground here, putting in place the basic building blocks for applications that send and receive email messages. as a starting point, it's not difficult to get messages into -- and out of -- your Java applications, is it?
Yet there is more to learn if you look deeper. Here is a rundown of what we 've covered and what you might look at next.
Send messages
We looked at how to send single-part messages via the SMTP protocol, though I did hint at how you cocould send nontext content -- I. e ., a Java serialized object -- as the single message part.
Later, we looked atPart
Interface in the context of multipart messages. You might now like to apply that knowledge to sending messages. How about sending a multipart message comprising some plain text and a file attachment?
Receive messages
We looked at processing ing multipart messages, but for viewing only. the messages we receive remain on the server, to be reread as frequently times as we like, until we remove them. how wocould we do that? To change the status of messages on the server, consider this line of code:
message.setFlag(Flags.Flag.ANSWERED,true);
Message. setFlag (Flags. Flag. ANSWERED, true );
As an authentication for sending nontext content, I introduced the idea of writing a Java serialized object into a mail message. cocould you complete the picture by now grouping such objects, as the basis of a kind of asynchronous Object Request Broker for disconnected applications? Believe it or not, I did something like that, and it's not as ridiculous as it sounds for field engineers who need to send batches of updates to client records whenever they get the chance to go online. before you all start shouting, I know it's more fashionable these days to use XML -- rather than serialized objects -- for that! If you're interested, the processing code looks like this:
InputStream is = (InputStream) message.getContent();
ObjectInputStream objectStream=new ObjectInputStream(is);
Object theObject=objectStream.readObject();
InputStream is = (InputStream) message. getContent ();
ObjectInputStream objectStream = new ObjectInputStream (is );
Object theObject = objectStream. readObject ();
Talking email
Talking email may interest you in terms of a desktop application that reads incoming messages, but I have another idea. several ISPs -- in the UK at least -- provide a speechmail service that allows you to dial a telephone number from anywhere in the world and have your inbox messages spoken to you. you can see the kind of service I mean at http://www.btinternet.com.
I don't think that this service is built with Java, but it is possible -- and the speech sounds distinctly allophonic, meaning that the BT Internet developers have taken more or less the same approach to speech synthesis as I have.
Finally
I hope I 've provided a good starting point for your email-enabled Java applications, with a few ideas thrown in for where to take it next. i'll judge the usefulness of this article by the number of Java-based email clients and Webmail sites that spring up over the coming months!