001: package org.claros.commons.mail.protocols;
002:
003: import java.io.ByteArrayInputStream;
004: import java.io.ByteArrayOutputStream;
005: import java.util.ArrayList;
006: import java.util.Date;
007: import java.util.HashMap;
008: import java.util.Properties;
009:
010: import javax.activation.DataHandler;
011: import javax.activation.DataSource;
012: import javax.mail.Address;
013: import javax.mail.BodyPart;
014: import javax.mail.Message;
015: import javax.mail.SendFailedException;
016: import javax.mail.Session;
017: import javax.mail.Transport;
018: import javax.mail.internet.MimeBodyPart;
019: import javax.mail.internet.MimeMultipart;
020: import javax.mail.internet.MimeUtility;
021: import javax.net.ssl.SSLException;
022:
023: import org.apache.commons.logging.Log;
024: import org.apache.commons.logging.LogFactory;
025: import org.claros.commons.auth.models.AuthProfile;
026: import org.claros.commons.configuration.PropertyFile;
027: import org.claros.commons.mail.models.ByteArrayDataSource;
028: import org.claros.commons.mail.models.ConnectionProfile;
029: import org.claros.commons.mail.models.Email;
030: import org.claros.commons.mail.models.EmailPart;
031: import org.claros.commons.mail.models.EmailPriority;
032: import org.claros.commons.mail.models.EmailSensitivity;
033: import org.claros.commons.mail.utility.SmtpAuthenticator;
034:
035: import com.sun.mail.smtp.SMTPMessage;
036:
037: /**
038: * @author Umut Gokbayrak
039: *
040: */
041: public class Smtp {
042: private static Log log = LogFactory.getLog(ImapProtocolImpl.class);
043: private Session session = null;
044: private ConnectionProfile profile;
045: private AuthProfile auth;
046:
047: public Smtp(ConnectionProfile profile, AuthProfile auth) {
048: Properties props = new Properties();
049: this .profile = profile;
050: this .auth = auth;
051:
052: if (log.isDebugEnabled()) {
053: props.setProperty("mail.debug", "true");
054: System.setProperty("javax.net.debug", "all");
055: }
056:
057: if (profile.getSmtpSSL() != null
058: && profile.getSmtpSSL().toLowerCase().equals("true")) {
059: props.put("mail.smtps.host", profile.getSmtpServer());
060: props.put("mail.smtps.port", Integer.toString(profile
061: .getISmtpPort()));
062: } else {
063: props.put("mail.smtp.host", profile.getSmtpServer());
064: props.put("mail.smtp.port", Integer.toString(profile
065: .getISmtpPort()));
066: }
067:
068: if (profile.getSmtpAuthenticated() != null
069: && profile.getSmtpAuthenticated().equals("true")) {
070: if (profile.getSmtpSSL() != null
071: && profile.getSmtpSSL().toLowerCase()
072: .equals("true")) {
073: props.setProperty("mail.smtps.auth", "true");
074: } else {
075: props.setProperty("mail.smtp.auth", "true");
076: }
077: SmtpAuthenticator authenticator = new SmtpAuthenticator(
078: auth.getUsername(), auth.getPassword());
079: session = Session.getInstance(props, authenticator);
080: } else {
081: session = Session.getInstance(props, null);
082: }
083:
084: if (log.isDebugEnabled()) {
085: session.setDebug(true);
086: }
087: }
088:
089: public HashMap send(Email msg, boolean simulate) throws Exception {
090: Address from = msg.getBaseHeader().getFrom()[0];
091: Address[] to = msg.getBaseHeader().getTo();
092: Address[] cc = msg.getBaseHeader().getCc();
093: Address[] bcc = msg.getBaseHeader().getBcc();
094: Address[] replyTo = msg.getBaseHeader().getReplyTo();
095: Boolean requestReceiptNotification = msg.getBaseHeader()
096: .getRequestReceiptNotification();
097: short priority = msg.getBaseHeader().getPriority();
098: short sensitivity = msg.getBaseHeader().getSensitivity();
099:
100: SMTPMessage mimeMsg = new SMTPMessage(session);
101: String subject = msg.getBaseHeader().getSubject();
102:
103: mimeMsg.setFrom(from);
104: if (to != null) {
105: mimeMsg.setRecipients(Message.RecipientType.TO, to);
106: }
107: if (cc != null) {
108: mimeMsg.setRecipients(Message.RecipientType.CC, cc);
109: }
110: if (bcc != null) {
111: mimeMsg.setRecipients(Message.RecipientType.BCC, bcc);
112: }
113: if (replyTo != null) {
114: mimeMsg.setReplyTo(replyTo);
115: }
116:
117: mimeMsg.setSentDate(new Date());
118: if (subject == null || subject.length() == 0) {
119: subject = "No subject";
120: }
121:
122: if (requestReceiptNotification != null) {
123: mimeMsg.addHeader("Disposition-Notification-To", from
124: .toString());
125: }
126:
127: if (priority > 0) {
128: mimeMsg.addHeader("X-Priority", String.valueOf(priority));
129: mimeMsg.addHeader("X-MSMail-Priority", EmailPriority
130: .toStringValue(priority));
131: }
132:
133: if (sensitivity > 0) {
134: mimeMsg.addHeader("Sensitivity", EmailSensitivity
135: .toStringValue(sensitivity));
136: }
137:
138: String charset = PropertyFile.getConfiguration(
139: "/config/config.xml")
140: .getString("common-params.charset");
141:
142: mimeMsg.setSubject(MimeUtility.encodeText(subject, charset,
143: null));
144: ArrayList parts = msg.getParts();
145: EmailPart bodyPart = (EmailPart) parts.get(0);
146:
147: boolean isTextBody = (bodyPart.isHTMLText()) ? false : true;
148:
149: if (parts.size() == 1 && isTextBody) {
150: mimeMsg.setText((String) bodyPart.getContent(), charset);
151: } else {
152: BodyPart bp = new MimeBodyPart();
153: bp.setContent((String) bodyPart.getContent(), bodyPart
154: .getContentType());
155: bp.setHeader("Content-Type", bodyPart.getContentType());
156:
157: // attachments are added here.
158: MimeMultipart multipart = new MimeMultipart();
159: multipart.addBodyPart(bp);
160:
161: // other attachments will follow
162: MimeBodyPart attPart = null;
163: EmailPart myPart = null;
164: DataSource ds = null;
165: String tmpContType = null;
166: int pos = -1;
167: for (int i = 1; i < msg.getParts().size(); i++) {
168: myPart = (EmailPart) msg.getParts().get(i);
169: attPart = new MimeBodyPart();
170:
171: ds = myPart.getDataSource();
172: if (ds == null) {
173: if (myPart.getContent() instanceof ByteArrayOutputStream) {
174: ByteArrayOutputStream bos = (ByteArrayOutputStream) myPart
175: .getContent();
176: ds = new ByteArrayDataSource(bos.toByteArray(),
177: myPart.getContentType(), myPart
178: .getFileName());
179: attPart.setDataHandler(new DataHandler(ds));
180: bos.close();
181: } else if (myPart.getContent() instanceof ByteArrayInputStream) {
182: ByteArrayInputStream bis = (ByteArrayInputStream) myPart
183: .getContent();
184: ByteArrayOutputStream bos = new ByteArrayOutputStream();
185: int j = -1;
186: while ((j = bis.read()) != -1) {
187: bos.write(j);
188: }
189: ds = new ByteArrayDataSource(bos.toByteArray(),
190: myPart.getContentType(), myPart
191: .getFileName());
192: attPart.setDataHandler(new DataHandler(ds));
193: bos.close();
194: bis.close();
195: } else {
196: attPart.setContent(myPart.getContent(), myPart
197: .getContentType());
198: }
199: } else {
200: attPart.setDataHandler(new DataHandler(ds));
201: }
202:
203: attPart.setDisposition(myPart.getDisposition());
204: attPart.setFileName(MimeUtility.encodeText(myPart
205: .getFilename(), charset, null));
206:
207: tmpContType = (myPart.getContentType() == null) ? "application/octet-stream"
208: : myPart.getContentType();
209:
210: pos = tmpContType.indexOf(";");
211: if (pos >= 0) {
212: tmpContType = tmpContType.substring(0, pos);
213: }
214: attPart.setHeader("Content-Type", tmpContType);
215: multipart.addBodyPart(attPart);
216: }
217:
218: // setting the content and finished
219: mimeMsg.setContent(multipart);
220: }
221: mimeMsg.addHeader("X-Mailer",
222: "Claros inTouch (http://www.claros.org)");
223: mimeMsg.saveChanges();
224:
225: // we are sending the message and generating a sent report on the fly.
226: HashMap out = new HashMap();
227: out.put("msg", mimeMsg);
228: if (!simulate) {
229: try {
230: mimeMsg.setSendPartial(true);
231: mimeMsg.setSentDate(new Date());
232:
233: if (profile.getSmtpSSL() != null
234: && profile.getSmtpSSL().toLowerCase().equals(
235: "true")) {
236: try {
237: Transport tr = session.getTransport("smtps");
238: tr.connect(profile.getSmtpServer(), auth
239: .getUsername(), auth.getPassword());
240: tr.sendMessage(mimeMsg, mimeMsg
241: .getAllRecipients());
242: tr.close();
243: } catch (Exception f) {
244: if (f.getCause() != null) {
245: if (f.getCause() instanceof SSLException) {
246: log
247: .error("an SSL exception occured. try to go on."
248: + f);
249: } else {
250: throw f;
251: }
252: } else {
253: throw f;
254: }
255: }
256: } else {
257: Transport.send(mimeMsg);
258: }
259: Address[] sent = mimeMsg.getAllRecipients();
260: out.put("sent", sent);
261: } catch (SendFailedException se) {
262: Address[] sent = se.getValidSentAddresses();
263: Address[] invalid = se.getInvalidAddresses();
264: Address[] fail = se.getValidUnsentAddresses();
265: out.put("sent", sent);
266: out.put("invalid", invalid);
267: out.put("fail", fail);
268: } catch (Exception f) {
269: // a bugfix for google mail.
270: if (f.getCause() instanceof SSLException) {
271: log.error("an SSL exception occured. try to go on."
272: + f);
273: Address[] sent = mimeMsg.getAllRecipients();
274: out.put("sent", sent);
275: } else {
276: throw f;
277: }
278: }
279: }
280: return out;
281: }
282: }
|