/********************************************************************************** * $URL: https://source.sakaiproject.org/svn/sam/trunk/samigo-app/src/java/org/sakaiproject/tool/assessment/util/SamigoEmailService.java $ * $Id: SamigoEmailService.java 106463 2012-04-02 12:20:09Z david.horwitz@uct.ac.za $ *********************************************************************************** * * Copyright (c) 2006, 2007, 2008, 2009 The Sakai Foundation * * Licensed under the Educational Community License, Version 2.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.opensource.org/licenses/ECL-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * **********************************************************************************/ package org.sakaiproject.tool.assessment.util; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Properties; import java.util.Vector; import javax.activation.DataHandler; import javax.activation.FileDataSource; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Multipart; import javax.mail.SendFailedException; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.sakaiproject.component.cover.ServerConfigurationService; import org.sakaiproject.content.api.ContentResource; import org.sakaiproject.exception.IdUnusedException; import org.sakaiproject.exception.PermissionException; import org.sakaiproject.exception.ServerOverloadException; import org.sakaiproject.exception.TypeException; import org.sakaiproject.tool.assessment.data.dao.assessment.AttachmentData; import org.sakaiproject.tool.assessment.services.assessment.AssessmentService; import org.sakaiproject.tool.assessment.ui.bean.util.EmailBean; import org.sakaiproject.tool.assessment.ui.listener.util.ContextUtil; /** * The ItemService calls persistent service locator to reach the * manager on the back end. */ public class SamigoEmailService { private static Log log = LogFactory.getLog(SamigoEmailService.class); private String fromName; private String fromEmailAddress; private String toName; private String toEmailAddress; private ArrayList toEmailAddressList; private String ccMe; private String subject; private String message; private String smtpServer; private String smtpPort; private String prefixedPath; /** * Creates a new SamigoEmailService object. */ public SamigoEmailService(String fromName, String fromEmailAddress, String toName, String toEmailAddress, ArrayList toEmailAddressList, String ccMe, String subject, String message) { this.fromName = fromName; this.fromEmailAddress = fromEmailAddress; this.toName = toName; this.toEmailAddress = toEmailAddress; this.toEmailAddressList = toEmailAddressList; this.ccMe = ccMe; this.subject = subject; this.message = message; this.smtpServer = ServerConfigurationService.getString("samigo.smtp.server"); this.smtpPort = ServerConfigurationService.getString("samigo.smtp.port"); this.prefixedPath = ServerConfigurationService.getString("samigo.email.prefixedPath"); } public SamigoEmailService(String fromName, String fromEmailAddress, String toName, String toEmailAddress, String ccMe, String subject, String message) { this(fromName, fromEmailAddress, toName, toEmailAddress, null, ccMe, subject, message); } public SamigoEmailService(String fromEmailAddress, ArrayList toEmailAddressList, String ccMe, String subject, String message) { this(null, fromEmailAddress, null, null, toEmailAddressList, ccMe, subject, message); } // Not sure if we are going to obsolete/change this email flow. I keep this here and make a new one sendMail() public String send() { List attachmentList = null; AttachmentData a = null; try { Properties props = new Properties(); // Server if (smtpServer == null || smtpServer.equals("")) { log.info("samigo.email.smtpServer is not set"); smtpServer = ServerConfigurationService.getString("smtp@org.sakaiproject.email.api.EmailService"); if (smtpServer == null || smtpServer.equals("")) { log.info("smtp@org.sakaiproject.email.api.EmailService is not set"); log.error("Please set the value of samigo.email.smtpServer or smtp@org.sakaiproject.email.api.EmailService"); return "error"; } } props.setProperty("mail.smtp.host", smtpServer); // Port if (smtpPort == null || smtpPort.equals("")) { log.warn("samigo.email.smtpPort is not set. The default port 25 will be used."); } else { props.setProperty("mail.smtp.port", smtpPort); } Session session; session = Session.getInstance(props); session.setDebug(true); MimeMessage msg = new MimeMessage(session); InternetAddress fromIA = new InternetAddress(fromEmailAddress, fromName); msg.setFrom(fromIA); InternetAddress[] toIA = { new InternetAddress(toEmailAddress, toName) }; msg.setRecipients(Message.RecipientType.TO, toIA); if ("yes".equals(ccMe)) { InternetAddress[] ccIA = { new InternetAddress(fromEmailAddress, fromName) }; msg.setRecipients(Message.RecipientType.CC, ccIA); } msg.setSubject(subject); EmailBean emailBean = (EmailBean) ContextUtil.lookupBean("email"); attachmentList = emailBean.getAttachmentList(); StringBuilder content = new StringBuilder(message); ArrayList fileList = new ArrayList(); ArrayList fileNameList = new ArrayList(); if (attachmentList != null) { if (prefixedPath == null || prefixedPath.equals("")) { log.error("samigo.email.prefixedPath is not set"); return "error"; } Iterator iter = attachmentList.iterator(); while (iter.hasNext()) { a = (AttachmentData) iter.next(); if (a.getIsLink().booleanValue()) { log.debug("send(): url"); content.append("<br/>\n\r"); content.append("<br/>"); // give a new line content.append(a.getFilename()); } else { log.debug("send(): file"); File attachedFile = getAttachedFile(a.getResourceId()); fileList.add(attachedFile); fileNameList.add(a.getFilename()); } } } Multipart multipart = new MimeMultipart(); MimeBodyPart messageBodyPart = new MimeBodyPart(); messageBodyPart.setContent(content.toString(), "text/html"); multipart.addBodyPart(messageBodyPart); msg.setContent(multipart); for (int i = 0; i < fileList.size(); i++) { messageBodyPart = new MimeBodyPart(); FileDataSource source = new FileDataSource((File)fileList.get(i)); messageBodyPart.setDataHandler(new DataHandler(source)); messageBodyPart.setFileName((String)fileNameList.get(i)); multipart.addBodyPart(messageBodyPart); } msg.setContent(multipart); Transport.send(msg); } catch (UnsupportedEncodingException e) { log.error("Exception throws from send()" + e.getMessage()); return "error"; } catch (MessagingException e) { log.error("Exception throws from send()" + e.getMessage()); return "error"; } catch (ServerOverloadException e) { log.error("Exception throws from send()" + e.getMessage()); return "error"; } catch (PermissionException e) { log.error("Exception throws from send()" + e.getMessage()); return "error"; } catch (IdUnusedException e) { log.error("Exception throws from send()" + e.getMessage()); return "error"; } catch (TypeException e) { log.error("Exception throws from send()" + e.getMessage()); return "error"; } catch (IOException e) { log.error("Exception throws from send()" + e.getMessage()); return "error"; } finally { if (attachmentList != null) { if (prefixedPath != null && !prefixedPath.equals("")) { StringBuilder sbPrefixedPath; Iterator iter = attachmentList.iterator(); while (iter.hasNext()) { sbPrefixedPath = new StringBuilder(prefixedPath); sbPrefixedPath.append("/email_tmp/"); a = (AttachmentData) iter.next(); if (!a.getIsLink().booleanValue()) { deleteAttachedFile(sbPrefixedPath.append(a.getResourceId()).toString()); } } } } } return "send"; } public String sendMail() { try { Properties props = new Properties(); // Server if (smtpServer == null || smtpServer.equals("")) { log.info("samigo.email.smtpServer is not set"); smtpServer = ServerConfigurationService.getString("smtp@org.sakaiproject.email.api.EmailService"); if (smtpServer == null || smtpServer.equals("")) { log.info("smtp@org.sakaiproject.email.api.EmailService is not set"); log.error("Please set the value of samigo.email.smtpServer or smtp@org.sakaiproject.email.api.EmailService"); return "error"; } } props.setProperty("mail.smtp.host", smtpServer); // Port if (smtpPort == null || smtpPort.equals("")) { log.warn("samigo.email.smtpPort is not set. The default port 25 will be used."); } else { props.setProperty("mail.smtp.port", smtpPort); } props.put("mail.smtp.sendpartial", "true"); Session session = Session.getInstance(props, null); session.setDebug(true); MimeMessage msg = new MimeMessage(session); InternetAddress fromIA = new InternetAddress(fromEmailAddress, fromName); msg.setFrom(fromIA); //msg.addHeaderLine("Subject: " + subject); msg.setSubject(subject, "UTF-8"); String noReplyEmaillAddress = "no-reply@" + ServerConfigurationService.getServerName(); msg.addHeaderLine("To: " + noReplyEmaillAddress); msg.setText(message, "UTF-8"); msg.addHeaderLine("Content-Type: text/html"); ArrayList<InternetAddress> toIAList = new ArrayList<InternetAddress>(); String email = ""; Iterator iter = toEmailAddressList.iterator(); while (iter.hasNext()) { try { email = (String) iter.next(); toIAList.add(new InternetAddress(email)); } catch (AddressException ae) { log.error("invalid email address: " + email); } } InternetAddress[] toIA = new InternetAddress[toIAList.size()]; int count = 0; Iterator iter2 = toIAList.iterator(); while (iter2.hasNext()) { toIA[count++] = (InternetAddress) iter2.next(); } try { Transport transport = session.getTransport("smtp"); msg.saveChanges(); transport.connect(); try { transport.sendMessage(msg, toIA); } catch (SendFailedException e) { log.debug("SendFailedException: " + e); return "error"; } catch (MessagingException e) { log.warn("1st MessagingException: " + e); return "error"; } transport.close(); } catch (MessagingException e) { log.warn("2nd MessagingException:" + e); return "error"; } } catch (UnsupportedEncodingException ue) { log.warn("UnsupportedEncodingException:" + ue); ue.printStackTrace(); } catch (MessagingException me) { log.warn("3rd MessagingException:" + me); return "error"; } return "send"; } private File getAttachedFile(String resourceId) throws PermissionException, IdUnusedException, TypeException, ServerOverloadException, IOException { ContentResource cr = AssessmentService.getContentHostingService().getResource(resourceId); log.debug("getAttachedFile(): resourceId = " + resourceId); byte[] data = cr.getContent(); StringBuilder sbPrefixedPath = new StringBuilder(prefixedPath); sbPrefixedPath.append("/email_tmp/"); sbPrefixedPath.append(resourceId); String filename = sbPrefixedPath.toString().replace(" ", ""); log.debug("getAttachedFile(): filename = " + filename); String path = filename.substring(0, filename.lastIndexOf("/")); log.debug("getAttachedFile(): path = " + path); File dir = new File(path); boolean success = dir.mkdirs(); // Shouldn't come to here because resourceId is unique if (!success) { log.error("getAttachedFile(): File exists already! This should not heppen. Please check for resourceId."); } File file = new File(filename); success = file.createNewFile(); // Shouldn't come to here because resourceId is unique if (!success) { log.error("getAttachedFile(): File exists already! This should not heppen. Please check for resourceId."); } FileOutputStream fileOutputStream = null; try { fileOutputStream = new FileOutputStream(file); fileOutputStream.write(data); } catch (FileNotFoundException e) { throw e; } catch (IOException e) { throw e; } finally { if (fileOutputStream != null) { fileOutputStream.close(); } } return file; } private void deleteAttachedFile(String filename) { log.debug("deleteAttachedFile(): filename = " + filename); // delete the file String tunedFilename = filename.replace(" ", ""); log.debug("deleteAttachedFile(): tunedFilename = " + tunedFilename); File file = new File(tunedFilename); boolean success = file.delete(); if (!success) { log.error("Fail to delete file: " + tunedFilename); } // delete the last directory String directoryName = tunedFilename.substring(0, tunedFilename.lastIndexOf("/")); log.debug("deleteAttachedFile(): directoryName = " + directoryName); File dir = new File(directoryName); success = dir.delete(); if (!success) { log.error("Fail to delete directory: " + directoryName); } } }