package org.jblooming.messaging;
import org.jblooming.tracer.Tracer;
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;
import java.io.*;
import java.util.Enumeration;
import java.util.Vector;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* (c) Open Lab - www.open-lab.com
* Date: Apr 10, 2007
* Time: 6:09:35 PM
*/
public class MailMessageUtilities {
/**
* This wrapper is used to work around a bug in the sun io inside
* sun.io.ByteToCharConverter.getConverterClass().
* <p/>
* The programmer uses a cute coding trick
* that appends the charset to a prefix to create a Class name that
* they then attempt to load. The problem is that if the charset is
* not one that they "recognize", and the name has something like a
* dash character in it, the resulting Class name has an invalid
* character in it. This results in an IllegalArgumentException
* instead of the UnsupportedEncodingException that is documented.
* Thus, we need to catch the undocumented exception.
*
* @param part The part from which to get the content.
* @return The content.
* @throws MessagingException if the content charset is unsupported.
*/
public static Object getPartContent(Part part) throws MessagingException {
Object result = null;
try {
result = part.getContent();
} catch (IllegalArgumentException ex) {
throw new MessagingException("content charset is not recognized: " + ex.getMessage());
} catch (IOException ex) {
throw new MessagingException("getPartContent(): " + ex.getMessage());
}
return result;
}
/**
* This wrapper is used to work around a bug in the sun io inside
* sun.io.ByteToCharConverter.getConverterClass().
* <p/>
* The programmer uses a cute coding trick
* that appends the charset to a prefix to create a Class name that
* they then attempt to load. The problem is that if the charset is
* not one that they "recognize", and the name has something like a
* dash character in it, the resulting Class name has an invalid
* character in it. This results in an IllegalArgumentException
* instead of the UnsupportedEncodingException that is documented.
* Thus, we need to catch the undocumented exception.
*
* @param dh The DataHandler from which to get the content.
* @return The content.
* @throws MessagingException if the content charset is unsupported.
*/
public static Object getDataHandlerContent(DataHandler dh) throws MessagingException {
Object result = null;
try {
result = dh.getContent();
} catch (IllegalArgumentException ex) {
throw new MessagingException("content charset is not recognized: " + ex.getMessage());
} catch (IOException ex) {
throw new MessagingException("getDataHandlerContent(): " + ex.getMessage());
}
return result;
}
/**
* Create a reply message to the given message.
* The reply message is addressed to only the from / reply address or
* all receipients based on the replyToAll flag.
*
* @param message The message which to reply
* @param body The attached text to include in the reply
* @param replyToAll Reply to all receipients of the original message
* @return Message Reply message
* @exception MessagingException if the message contents are invalid
*/
/*
public static Message createReply(Message message, String body, boolean replyToAll) throws MessagingException {
// create an empty reply message
Message xreply = message.reply(replyToAll);
// set the default from address
xreply.setFrom(getDefaultFromAddress());
// UNDONE should any extra headers be replied to?
if (message instanceof MimeMessage) {
((MimeMessage) xreply).setText(body, "UTF-8");
} else {
xreply.setText(body);
}
// Message.reply() may set the "replied to" flag, so
// attempt to save that new state and fail silently...
try {
message.saveChanges();
} catch (MessagingException ex) {
}
return xreply;
}
*/
/**
* Create a forward message to the given message.
* The forward message addresses no receipients but
* contains all the contents of the given message.
* Another missing method in JavaMail!!!
*
* @param message The message which to forward
* @return Message Forwarding message
* @exception MessagingException if the message contents are invalid
*/
/*
public static Message createForward(Message message) throws MessagingException {
// create an initial message without addresses, subject, or content
MimeMessage xforward = new MimeMessage(ICEMail.getDefaultSession());
// create forwarding headers
InternetHeaders xheaders = getHeaders(message);
xheaders.removeHeader("from");
xheaders.removeHeader("to");
xheaders.removeHeader("cc");
xheaders.removeHeader("bcc");
xheaders.removeHeader("received");
addHeaders(xforward, xheaders);
// set the default from address
xforward.setFrom(getDefaultFromAddress());
// create the subject
String xsubject = message.getSubject().trim();
if (xsubject.toUpperCase().indexOf("FW") != 0) {
xsubject = "FW: " + xsubject;
}
xforward.setSubject(xsubject, "UTF-8");
// create the contents
ContentType xctype = getContentType(message);
Object xcont = getPartContent(message);
xforward.setContent(xcont, xctype.toString());
// REVIEW - why would we need to save here?!
// xforward.saveChanges();
return xforward;
} */
//............................................................
/**
* Decode from address(es) of the message into UTF strings.
* This is a convenience method provided to simplify application code.
*
* @param message The message to interogate
* @return String List of decoded addresses
* @throws MessagingException if the message contents are invalid
*/
public static String decodeFrom(javax.mail.Message message) throws MessagingException {
Address[] xaddresses = message.getFrom();
return decodeAddresses(xaddresses);
}
/**
* Decode recipent addresses of the message into UTF strings.
* This is a convenience method provided to simplify application code.
*
* @param message The message to interogate
* @param type The type of message recipients to decode, i.e. from, to, cc, etc
* @return String List of decoded addresses
* @throws MessagingException if the message contents are invalid
*/
public static String
decodeAddresses(javax.mail.Message message, javax.mail.Message.RecipientType type) throws MessagingException {
Address[] xaddresses = message.getRecipients(type);
return decodeAddresses(xaddresses);
}
/**
* Decode mail addresses into UTF strings.
* <p/>
* This routine is necessary because Java Mail Address.toString() routines
* convert into MIME encoded strings (ASCII C and B encodings), not UTF.
* Of course, the returned string is in the same format as MIME, but converts
* to UTF character encodings.
*
* @param addresses The list of addresses to decode
* @return String List of decoded addresses
*/
public static String decodeAddresses(Address[] addresses) {
StringBuffer xlist = new StringBuffer();
if (addresses != null) {
for (int xindex = 0; xindex < addresses.length; xindex++) {
// at this time, only internet addresses can be decoded
if (xlist.length() > 0)
xlist.append(", ");
if (addresses[xindex] instanceof InternetAddress) {
InternetAddress xinet = (InternetAddress) addresses[xindex];
if (xinet.getPersonal() == null) {
xlist.append(xinet.getAddress());
} else {
// If the address has a ',' in it, we must
// wrap it in quotes, or it will confuse the
// code that parses addresses separated by commas.
String personal = xinet.getPersonal();
int idx = personal.indexOf(",");
String qStr = (idx == -1 ? "" : "\"");
xlist.append(qStr);
xlist.append(personal);
xlist.append(qStr);
xlist.append(" <");
xlist.append(xinet.getAddress());
xlist.append(">");
}
} else {
// generic, and probably not portable,
// but what's a man to do...
xlist.append(addresses[xindex].toString());
}
}
}
return xlist.toString();
}
/**
* Encode UTF strings into mail addresses.
*/
public static InternetAddress[] encodeAddresses(String string, String charset) throws MessagingException {
// parse the string into the internet addresses
// NOTE: these will NOT be character encoded
InternetAddress[] xaddresses = InternetAddress.parse(string);
// now encode each to the given character set
for (int xindex = 0; xindex < xaddresses.length; xindex++) {
String xpersonal = xaddresses[xindex].getPersonal();
try {
if (xpersonal != null) {
xaddresses[xindex].setPersonal(xpersonal, charset);
}
} catch (UnsupportedEncodingException xex) {
throw new MessagingException(xex.toString());
}
}
return xaddresses;
}
/*
public static InternetAddress getDefaultFromAddress() throws MessagingException {
// encode the address
String xcharset = "UTF-8";
InternetAddress[] xaddresses = encodeAddresses(getDefaultFromString(), xcharset);
return xaddresses[0];
}
public static String getDefaultFromString() {
// build a string from the user defined From personal and address
String xstring = UserProperties.getProperty("fromPersonal", null);
String xaddress = UserProperties.getProperty("fromAddress", null);
if (xaddress == null) {
xaddress = UserProperties.getProperty(".user.name", "unknown");
}
if (xstring != null && xstring.length() > 0) {
xstring = xstring + " <" + xaddress + ">";
} else {
xstring = xaddress;
}
return xstring;
}
public static InternetAddress getDefaultReplyTo() throws MessagingException {
// build a string from the user defined ReplyTo personal and address
String xstring = UserProperties.getProperty("replyToPersonal", null);
String xaddress = UserProperties.getProperty("replyToAddress", null);
if (xaddress == null) {
xaddress = UserProperties.getProperty(".user.name", "unknown");
}
if (xstring != null && xstring.length() > 0) {
xstring = xstring + " <" + xaddress + ">";
} else {
xstring = xaddress;
}
// encode the address
String xcharset = "UTF-8";
InternetAddress[] xaddresses = encodeAddresses(xstring, xcharset);
return xaddresses[0];
}
*/
//............................................................
public static InternetHeaders getHeadersWithFrom(javax.mail.Message message) throws MessagingException {
Header xheader;
InternetHeaders xheaders = new InternetHeaders();
Enumeration xe = message.getAllHeaders();
for (; xe.hasMoreElements();) {
xheader = (Header) xe.nextElement();
xheaders.addHeader(xheader.getName(), xheader.getValue());
}
return xheaders;
}
public static InternetHeaders getHeaders(javax.mail.Message message) throws MessagingException {
Header xheader;
InternetHeaders xheaders = new InternetHeaders();
Enumeration xe = message.getAllHeaders();
for (; xe.hasMoreElements();) {
xheader = (Header) xe.nextElement();
if (!xheader.getName().startsWith("From ")) {
xheaders.addHeader(xheader.getName(), xheader.getValue());
}
}
return xheaders;
}
public static void addHeaders(javax.mail.Message message, InternetHeaders headers) throws MessagingException {
Header xheader;
Enumeration xe = headers.getAllHeaders();
for (; xe.hasMoreElements();) {
xheader = (Header) xe.nextElement();
message.addHeader(xheader.getName(), xheader.getValue());
}
}
//............................................................
/* public static void
attach(MimeMultipart multipart, Vector attachments, String charset)
throws MessagingException {
for (int xindex = 0; xindex < attachments.size(); xindex++) {
Object xobject = attachments.elementAt(xindex);
// attach based on type of object
if (xobject instanceof Part) {
attach(multipart, (Part) xobject, charset);
} else if (xobject instanceof File) {
attach(multipart, (File) xobject, charset);
} else if (xobject instanceof String) {
attach(multipart, (String) xobject, charset, Part.ATTACHMENT);
} else {
throw new MessagingException("Cannot attach objects of type " +
xobject.getClass().getName());
}
}
}
public static void attach(MimeMultipart multipart, Part part, String charset) throws MessagingException {
MimeBodyPart xbody = new MimeBodyPart();
PartDataSource xds = new PartDataSource(part);
DataHandler xdh = new DataHandler(xds);
xbody.setDataHandler(xdh);
int xid = multipart.getCount() + 1;
String xtext;
// UNDONE
//xbody.setContentLanguage( String ); // this could be language from Locale
//xbody.setContentMD5( String md5 ); // don't know about this yet
xtext = part.getDescription();
if (xtext == null) {
xtext = "Part Attachment: " + xid;
}
xbody.setDescription(xtext, charset);
xtext = getContentDisposition(part).getType();
xbody.setDisposition(xtext);
xtext = getFileName(part);
if (xtext == null || xtext.length() < 1) {
xtext = "PART" + xid;
}
setFileName(xbody, xtext, charset);
multipart.addBodyPart(xbody);
} */
public static void attach(MimeMultipart multipart, File file, String charset) throws MessagingException {
// UNDONE how to specify the character set of the file???
MimeBodyPart xbody = new MimeBodyPart();
FileDataSource xds = new FileDataSource(file);
DataHandler xdh = new DataHandler(xds);
xbody.setDataHandler(xdh);
// UNDONE
// xbody.setContentLanguage( String ); // this could be language from Locale
// xbody.setContentMD5( String md5 ); // don't know about this yet
xbody.setDescription("File Attachment: " + file.getName(), charset);
xbody.setDisposition(Part.ATTACHMENT);
setFileName(xbody, file.getName(), charset);
multipart.addBodyPart(xbody);
}
public static void attach(MimeMultipart multipart, String text, String charset, String disposition) throws MessagingException {
int xid = multipart.getCount() + 1;
String xname = "TEXT" + xid + ".TXT";
MimeBodyPart xbody = new MimeBodyPart();
xbody.setText(text, charset);
// UNDONE
//xbody.setContentLanguage( String ); // this could be language from Locale
//xbody.setContentMD5( String md5 ); // don't know about this yet
xbody.setDescription("Text Attachment: " + xname, charset);
xbody.setDisposition(disposition);
setFileName(xbody, xname, charset);
multipart.addBodyPart(xbody);
}
//............................................................
/**
* Decode the contents of the Part into text and attachments.
*/
public static StringBuffer decodeContent(Part part, StringBuffer buffer, Vector attachments, Vector names) throws MessagingException {
subDecodeContent(part, buffer, attachments, names);
// If we did not get any body text, scan on more time
// for a text/plain part that is not 'inline', and use
// that as a proxy...
if (buffer.length() == 0 && attachments != null) {
for (int i = 0, sz = attachments.size(); i < sz; ++i) {
Part p = (Part) attachments.elementAt(i);
ContentType xctype = getContentType(p);
if (xctype.match("text/plain")) {
decodeTextPlain(buffer, p);
attachments.removeElementAt(i);
if (names != null) {
names.removeElementAt(i);
}
break;
}
}
}
return buffer;
}
/**
* Given a message that we are replying to, or forwarding,
*
* @param part The part to decode.
* @param buffer The new message body text buffer.
* @param attachments Vector for new message's attachments.
* @param names Vector for new message's attachment descriptions.
* @return The buffer being filled in with the body.
*/
protected static StringBuffer subDecodeContent(Part part, StringBuffer buffer, Vector attachments, Vector names) throws MessagingException {
boolean attachIt = true;
// decode based on content type and disposition
ContentType xctype = getContentType(part);
ContentDisposition xcdisposition = getContentDisposition(part);
if (xctype.match("multipart/*")) {
attachIt = false;
Multipart xmulti = (Multipart) getPartContent(part);
int xparts = xmulti.getCount();
for (int xindex = 0; xindex < xparts; xindex++) {
subDecodeContent(xmulti.getBodyPart(xindex),
buffer, attachments, names);
}
} else if (xctype.match("text/plain")) {
//if (xcdisposition.equals(Part.INLINE)) {
attachIt = false;
decodeTextPlain(buffer, part);
//}
}
if (attachIt) {
// UNDONE should simple single line entries be
// created for other types and attachments?
//
// UNDONE should attachements only be created for "attachments" or all
// unknown content types?
if (attachments != null) {
attachments.addElement(part);
}
if (names != null) {
names.addElement(getPartName(part) +
" (" + xctype.getBaseType() + ") " + part.getSize() + " bytes");
}
}
return buffer;
}
/**
* Get the name of a part.
* The part is interogated for a valid name from the provided file name
* or description.
*
* @param part The part to interogate
* @return String containing the name of the part
* @throws MessagingException if contents of the part are invalid
* @see javax.mail.Part
*/
public static String getPartName(Part part) throws MessagingException {
String xdescription = getFileName(part);
if (xdescription == null || xdescription.length() < 1) {
xdescription = part.getDescription();
}
if ((xdescription == null || xdescription.length() < 1) && part instanceof MimePart) {
xdescription = ((MimePart) part).getContentID();
}
if (xdescription == null || xdescription.length() < 1) {
xdescription = "Message Part";
}
return xdescription;
}
/**
* Decode contents of TEXT/PLAIN message parts into UTF encoded strings.
* Why can't JAVA Mail provide this method?? Who knows!?!?!?
*/
public static StringBuffer decodeTextPlain(StringBuffer buffer, Part part) throws MessagingException {
// pick off the individual lines of text
// and append to the buffer
//
BufferedReader xreader = getTextReader(part);
return decodeTextPlain(buffer, xreader);
}
public static StringBuffer decodeTextPlain(StringBuffer buffer, BufferedReader xreader) throws MessagingException {
// pick off the individual lines of text
// and append to the buffer
//
try {
for (String xline; (xline = xreader.readLine()) != null;) {
buffer.append(xline + '\n');
}
xreader.close();
return buffer;
} catch (IOException xex) {
throw new MessagingException(xex.toString());
}
}
public static BufferedReader getTextReader(Part part) throws MessagingException {
try {
InputStream xis = part.getInputStream(); // transfer decoded only
// pick the character set off of the content type
ContentType xct = getContentType(part);
String xjcharset = xct.getParameter("charset");
if (xjcharset == null) {
// not present, assume ASCII character encoding
xjcharset = "ISO-8859-1"; // US-ASCII in JAVA terms
}
// now construct a reader from the decoded stream
return getTextReader(xis, xjcharset);
} catch (IOException xex) {
throw new MessagingException(xex.toString());
}
}
public static BufferedReader getTextReader(InputStream xis, ContentType xct) throws MessagingException {
try {
String xjcharset = xct.getParameter("charset");
if (xjcharset == null) {
// not present, assume ASCII character encoding
xjcharset = "ISO-8859-1"; // US-ASCII in JAVA terms
}
// now construct a reader from the decoded stream
return getTextReader(xis, xjcharset);
} catch (IOException xex) {
throw new MessagingException(xex.toString());
}
}
public static BufferedReader getTextReader(InputStream stream, String charset) throws UnsupportedEncodingException {
// Sun has a HUGE bug in their io code. They use a cute coding trick
// that appends the charset to a prefix to create a Class name that
// they then attempt to load. The problem is that if the charset is
// not one that they "recognize", and the name has something like a
// dash character in it, the resulting Class name has an invalid
// character in it. This results in an IllegalArgumentException
// instead of the UnsupportedEncodingException that we expect. Thus,
// we need to catch the undocumented exception.
InputStreamReader inReader;
try {
charset = MimeUtility.javaCharset(charset); // just to be sure
inReader = new InputStreamReader(stream, charset);
} catch (UnsupportedEncodingException ex) {
inReader = null;
} catch (IllegalArgumentException ex) {
inReader = null;
}
if (inReader == null) {
// This is the "bug" case, and we need to do something
// that will at least put text in front of the user...
inReader = new InputStreamReader(stream, "ISO-8859-1");
}
return new BufferedReader(inReader);
}
//............................................................
/**
* Get a textual description of a message.
* This is a helper method for applications.
*
* @param msg The message to interogate
* @return String containing the description of the message
*/
public static String getMessageDescription(javax.mail.Message msg) throws MessagingException {
StringBuffer xbuffer = new StringBuffer(1024);
getPartDescription(msg, xbuffer, "", true);
return xbuffer.toString();
}
/**
* Get a textual description of a part.
*
* @param part The part to interogate
* @param buf a string buffer for the description
* @param prefix a prefix for each line of the description
* @param recurse boolean specifying wether to recurse through sub-parts or not
* @return StringBuffer containing the description of the part
*/
public static StringBuffer getPartDescription(Part part, StringBuffer buf, String prefix, boolean recurse) throws MessagingException {
if (buf == null)
return buf;
ContentType xctype = getContentType(part);
String xvalue = xctype.toString();
buf.append(prefix);
buf.append("Content-Type: ");
buf.append(xvalue);
buf.append('\n');
xvalue = part.getDisposition();
buf.append(prefix);
buf.append("Content-Disposition: ");
buf.append(xvalue);
buf.append('\n');
xvalue = part.getDescription();
buf.append(prefix);
buf.append("Content-Description: ");
buf.append(xvalue);
buf.append('\n');
xvalue = getFileName(part);
buf.append(prefix);
buf.append("Content-Filename: ");
buf.append(xvalue);
buf.append('\n');
if (part instanceof MimePart) {
MimePart xmpart = (MimePart) part;
xvalue = xmpart.getContentID();
buf.append(prefix);
buf.append("Content-ID: ");
buf.append(xvalue);
buf.append('\n');
String[] langs = xmpart.getContentLanguage();
if (langs != null) {
buf.append(prefix);
buf.append("Content-Language: ");
for (int pi = 0; pi < langs.length; ++pi) {
if (pi > 0)
buf.append(", ");
buf.append(xvalue);
}
buf.append('\n');
}
xvalue = xmpart.getContentMD5();
buf.append(prefix);
buf.append("Content-MD5: ");
buf.append(xvalue);
buf.append('\n');
xvalue = xmpart.getEncoding();
buf.append(prefix);
buf.append("Content-Encoding: ");
buf.append(xvalue);
buf.append('\n');
}
buf.append('\n');
if (recurse && xctype.match("multipart/*")) {
Multipart xmulti = (Multipart) getPartContent(part);
int xparts = xmulti.getCount();
for (int xindex = 0; xindex < xparts; xindex++) {
getPartDescription(xmulti.getBodyPart(xindex),
buf, (prefix + " "), true);
}
}
return buf;
}
/**
* Get the content dispostion of a part.
* The part is interogated for a valid content disposition. If the
* content disposition is missing, a default disposition is created
* based on the type of the part.
*
* @param part The part to interogate
* @return ContentDisposition of the part
* @see javax.mail.Part
*/
public static ContentDisposition getContentDisposition(Part part) throws MessagingException {
String xheaders[] = part.getHeader("Content-Disposition");
try {
if (xheaders != null) {
return new ContentDisposition(xheaders[0]);
}
} catch (ParseException xex) {
throw new MessagingException(xex.toString());
}
// set default disposition based on part type
if (part instanceof MimeBodyPart) {
return new ContentDisposition("attachment");
}
return new ContentDisposition("inline");
}
/**
* A 'safe' version of JavaMail getContentType(), i.e. don't throw exceptions.
* The part is interogated for a valid content type. If the content type is
* missing or invalid, a default content type of "text/plain" is assumed,
* which is suggested by the MIME standard.
*
* @param part The part to interogate
* @return ContentType of the part
* @see javax.mail.Part
*/
public static ContentType getContentType(Part part) {
String xtype = null;
try {
xtype = part.getContentType();
} catch (MessagingException xex) {
}
return getContentType(xtype);
}
public static ContentType getContentType(String xtype) {
if (xtype == null) {
xtype = "text/plain"; // MIME default content type if missing
}
ContentType xctype = null;
try {
xctype = new ContentType(xtype.toLowerCase());
} catch (ParseException xex) {
}
if (xctype == null) {
xctype = new ContentType("text", "plain", null);
}
return xctype;
}
/**
* Determin if the message is high-priority.
*
* @param message the message to examine
* @return true if the message is high-priority
*/
public static boolean isHighPriority(javax.mail.Message message) throws MessagingException {
if (message instanceof MimeMessage) {
MimeMessage xmime = (MimeMessage) message;
String xpriority = xmime.getHeader("Importance", null);
if (xpriority != null) {
xpriority = xpriority.toLowerCase();
if (xpriority.indexOf("high") == 0) {
return true;
}
}
// X Standard: X-Priority: 1 | 2 | 3 | 4 | 5 (lowest)
xpriority = xmime.getHeader("X-Priority", null);
if (xpriority != null) {
xpriority = xpriority.toLowerCase();
if (xpriority.indexOf("1") == 0 ||
xpriority.indexOf("2") == 0) {
return true;
}
}
}
return false;
}
/**
* Determin if the message is low-priority.
*
* @param message the message to examine
* @return true if the message is low-priority
*/
public static boolean isLowPriority(javax.mail.Message message) throws MessagingException {
if (message instanceof MimeMessage) {
MimeMessage xmime = (MimeMessage) message;
String xpriority = xmime.getHeader("Importance", null);
if (xpriority != null) {
xpriority = xpriority.toLowerCase();
if (xpriority.indexOf("low") == 0) {
return true;
}
}
// X Standard: X-Priority: 1 | 2 | 3 | 4 | 5 (lowest)
xpriority = xmime.getHeader("X-Priority", null);
if (xpriority != null) {
xpriority = xpriority.toLowerCase();
if (xpriority.indexOf("4") == 0 ||
xpriority.indexOf("5") == 0) {
return true;
}
}
}
return false;
}
/**
* A 'safe' version of JavaMail getFileName() which doesn't throw exceptions.
* Encoded filenames are also decoded if necessary.
* Why doesn't JAVA Mail do this?
*
* @param part The part to interogate
* @return File name of the part, or null if missing or invalid
* @see javax.mail.Part
*/
public static String getFileName(Part part) {
String xname = null;
try {
xname = part.getFileName();
} catch (MessagingException xex) {
}
// decode the file name if necessary
if (xname != null && xname.startsWith("=?")) {
try {
xname = MimeUtility.decodeWord(xname);
} catch (Exception xex) {
}
}
return xname;
}
/**
* A better version of setFileName() which will encode the name if necessary.
* Why doesn't JAVA Mail do this?
*
* @param part the part to manipulate
* @param name the give file name encoded in UTF (JAVA)
* @param charset the encoding character set
*/
public static void setFileName(Part part, String name, String charset) throws MessagingException {
try {
name = MimeUtility.encodeWord(name, charset, null);
} catch (Exception xex) {
}
part.setFileName(name);
}
public static String getPrintableMD5(StringBuffer xmlSync) {
MessageDigest md = null;
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
Tracer.emailLogger.error(e);
}
md.reset();
md.update(xmlSync.toString().getBytes());
byte md5b[] = md.digest();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < md5b.length; ++i)
sb.append(Integer.toString((md5b[i] & 0xff) + 0x100, 16).substring(1));
String md5 = sb.toString();
return md5;
}
}