| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache 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.apache.org/licenses/LICENSE-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.apache.cocoon.mail.transformation; |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Properties; |
| import java.util.StringTokenizer; |
| |
| import javax.activation.DataHandler; |
| import javax.activation.DataSource; |
| import javax.mail.Address; |
| import javax.mail.BodyPart; |
| import javax.mail.Message; |
| import javax.mail.Multipart; |
| import javax.mail.SendFailedException; |
| import javax.mail.Session; |
| import javax.mail.Transport; |
| import javax.mail.internet.InternetAddress; |
| import javax.mail.internet.MimeBodyPart; |
| import javax.mail.internet.MimeMessage; |
| import javax.mail.internet.MimeMultipart; |
| import javax.xml.transform.OutputKeys; |
| |
| import org.apache.avalon.framework.configuration.Configuration; |
| import org.apache.avalon.framework.configuration.ConfigurationException; |
| import org.apache.avalon.framework.parameters.Parameters; |
| import org.apache.cocoon.ProcessingException; |
| import org.apache.cocoon.environment.SourceResolver; |
| import org.apache.cocoon.mail.datasource.SourceDataSource; |
| import org.apache.cocoon.transformation.AbstractSAXTransformer; |
| import org.apache.excalibur.source.Source; |
| import org.xml.sax.Attributes; |
| import org.xml.sax.SAXException; |
| import org.xml.sax.helpers.AttributesImpl; |
| |
| /** |
| * The <code>SendMailTransformer</code> send mails with optional attachments using a SMTP |
| * server and delivers furthermore a status report of each sent mail. |
| * |
| * <p> |
| * The SendMailTransformer requires the Sun's JavaMail API implementation. Please |
| * download and copy the following files to the Cocoon lib directory: |
| * <ul> |
| * <li><code>mail.jar</code> from |
| * <a href="http://java.sun.com/products/javamail/">http://java.sun.com/products/javamail/</a> |
| * </li> |
| * <li><code>activation.jar</code> from |
| * <a href="http://java.sun.com/products/javabeans/glasgow/jaf.html">http://java.sun.com/products/javabeans/glasgow/jaf.html</a> |
| * </li> |
| * </p> |
| * |
| * <p> |
| * Use the following sitemap component declaration to define, configure and |
| * parameterize the transformer. |
| * in the <code>map:sitemap/map:components/map:transformers</code>: |
| |
| * <pre> |
| * <map:transformer name="sendmail" src="org.apache.cocoon.mail.transformation.SendMailTransformer"> |
| * <smtphost>smtp.foo.com</smtphost> |
| * <from>sender@localhost</from> |
| * </map:transformer> |
| * </pre> |
| * |
| * where |
| * <ul> |
| * <li> |
| * <smtphost> is the SMTP server host name, e.g. smtp.foo.com |
| * </li> |
| * <li> |
| * <from> is the sender e-mail address |
| * </li> |
| * </ul> |
| * </p> |
| * |
| * <p> |
| * Furthermore, these parameters can be defined in the sitemap pipeline section: |
| * <ul> |
| * <li> |
| * <b>smtphost</b>, <b>from</b> - If they are defined, this values overwrite |
| * the values from component section described above. |
| * </li> |
| * <li> |
| * <b>to</b> - email addresses of recipients |
| * e.g.: <code><map:parameter name="to" value="customer1@target.com,customer2@target.com"/></code> |
| * </li> |
| * <li> |
| * <b>subject</b> - a string, can also come from an input module |
| * e.g.; <map:parameter name="subject" value="{request-param:subject}"/> |
| * </li> |
| * <li> |
| * <b>body</b> - a string, can also come from an input module |
| * e.g.; <map:parameter name="body" value="{request-param:body}"/> |
| * </li> |
| * <li> |
| * <b>sendpartial</b> - a boolean, define how to send the mails. When mail is being send |
| * to more than one recipient and the parameter is set to false, then all email addresses |
| * will appear concatenated in the address field at the mail client of the recipient. |
| * The default is true. |
| * </li> |
| * </ul> |
| * </p> |
| * |
| * <p> |
| * More configurations can be made in a specific configuration file, which |
| * can be retrieved with a |
| * <a href="http://cocoon.apache.org/2.1/userdocs/generators/generators.html">generator</a> as |
| * the input document. The input document should have the following configuration entities: |
| * <ul> |
| * <li> |
| * <b><email:smtphost></b>, <b><email:from></b> and |
| * <b><email:subject></b> can be set to overwrite values from the |
| * sitemap |
| * </li> |
| * <li> |
| * <b><email:to></b> - each entry will be append to the list of |
| * email addresses |
| * </li> |
| * <li> |
| * <b><email:body></b> - Overwrites the value from the sitemap. |
| * If there is a <b>src</b> attribute, the transformer will try to retrieve |
| * the file and place it instead of a text-string as the mail body. |
| * </li> |
| * <li> |
| * <b><email:attachment></b> - each entry defines a attachment. |
| * The attribute <b>name</b> defines the name of the attachment. The <b>mime-type</b> attribute |
| * defines the content of the attachment. |
| * If there is a nested <email:content> - element, text can be included and the |
| * attachment will then be a plain text-file. |
| * Is there a <b>url</b> attribute, the transformer tries to retrieve the |
| * appropriate file and handle it as an attachment. |
| * To use a file as an attachment, retrieved over a protocol like http or |
| * cocoon, use the <b>src</b> attribute. |
| * </li> |
| * </ul> |
| * </p> |
| * |
| * <p> |
| * Input document sample: |
| * <pre> |
| * <?xml version="1.0" encoding="UTF-8"?> |
| * <document xmlns:email="http://apache.org/cocoon/transformation/sendmail"> |
| * <email:sendmail> |
| * <email:smtphost>hostname.company.com</email:smtphost> |
| * <email:from>info@company.com</email:from> |
| * <email:to>customer3@target.com</email:to> |
| * <email:to>customer4@target.com</email:to> |
| * <email:to>customer5@target.com</email:to> |
| * <email:to>customer6@target.com</email:to> |
| * <email:subject>subject-content</email:subject> |
| * <email:body src="cocoon:/softwareupdate.html?locale=en&country=UK"/> |
| * <!-- <email:body>some Text</email:body> --> |
| * <email:attachment name="hello.html" mime-type="text/html"> |
| * <email:content> |
| * Dear Customer, please visit out new Product-Shop. |
| * </email:content> |
| * </email:attachment> |
| * <email:attachment name="hello2.html" mime-type="text/html" src="cocoon:/src1"/> |
| * <email:attachment name="hello3.html" mime-type="text/html" |
| * url="C:\path\softwareupdate.html"/> |
| * <email:attachment name="hello.gif" mime-type="image/gif" |
| * url="c:\path\powered.gif"/> |
| * </email:sendmail> |
| * </document> |
| * </pre> |
| * </p> |
| * |
| * <p> |
| * After the transformation a report will be generated, where the state for each sent mail can be seen. |
| * In case of an exception, the exception-message and a stacktrace will be reported. |
| * </p> |
| * |
| * <p> |
| * <b style="color: red;">FIXME: Known Issues:</b> |
| * <ul> |
| * <li>Refactor to use MailSender component</li> |
| * <li>No support for <a href="http://www.ietf.org/rfc/rfc2554.txt">RFC 2554: |
| * SMTP Service Extension for Authentication</a></li> |
| * <li>No support for different mail servers, first one will always be used</li> |
| * </ul> |
| * </p> |
| * |
| * @cocoon.sitemap.component.documentation |
| * The <code>SendMailTransformer</code> send mails with optional attachments using a SMTP |
| * server and delivers furthermore a status report of each sent mail. |
| * @cocoon.sitemap.component.documentation.caching No |
| * |
| * @version $Id$ |
| */ |
| public class SendMailTransformer extends AbstractSAXTransformer { |
| |
| /* |
| * constants, related to elements in configuration-file |
| */ |
| |
| public static final String NAMESPACE = "http://apache.org/cocoon/transformation/sendmail"; |
| public static final String ELEMENT_SENDMAIL = "sendmail"; |
| public static final String ELEMENT_SMTPHOST = "smtphost"; |
| public static final String ELEMENT_SMTPPORT = "smtpport"; |
| public static final String ELEMENT_MAILFROM = "from"; |
| public static final String ELEMENT_MAILTO = "to"; |
| public static final String ELEMENT_REPLYTO = "reply-to"; |
| public static final String ELEMENT_MAILSUBJECT = "subject"; |
| public static final String ELEMENT_MAILBODY = "body"; |
| public static final String ELEMENT_ATTACHMENT = "attachment"; |
| public static final String ELEMENT_ATTACHMENT_CONTENT = "content"; |
| public static final String ELEMENT_EMAIL_PREFIX = "email"; |
| public static final String ELEMENT_ERROR = "error"; |
| public static final String ELEMENT_SUCCESS = "success"; |
| public static final String ELEMENT_FAILURE = "failure"; |
| public static final String ELEMENT_RESULT = "result"; |
| |
| public static final String DEFAULT_BODY_MIMETYPE = "text/html"; |
| |
| /* |
| * mode-constants |
| */ |
| |
| protected static final int MODE_NONE = 0; |
| protected static final int MODE_SMTPHOST = 1; |
| protected static final int MODE_FROM = 2; |
| protected static final int MODE_TO = 3; |
| protected static final int MODE_SUBJECT = 4; |
| protected static final int MODE_BODY = 5; |
| protected static final int MODE_ATTACHMENT = 6; |
| protected static final int MODE_ATTACHMENT_CONTENT = 7; |
| protected static final int MODE_REPLY_TO = 8; |
| protected static final int MODE_SMTPPORT = 9; |
| |
| /* |
| * constants, related to parameter from request |
| */ |
| public final static String PARAM_SMTPHOST = "smtphost"; |
| public final static String PARAM_SMTPPORT = "smtpport"; |
| public final static String PARAM_FROM = "from"; |
| public final static String PARAM_TO = "to"; |
| public final static String PARAM_REPLY_TO = "reply-to"; |
| public final static String PARAM_SUBJECT = "subject"; |
| public final static String PARAM_BODY = "body"; |
| public final static String PARAM_SENDPARTIAL = "sendpartial"; |
| protected int mode; |
| |
| /* |
| * communication parameters, which will be used to send mails |
| */ |
| protected List toAddresses; |
| protected List replyToAddresses; |
| protected List defaultToAddresses; |
| protected List defaultReplyToAddresses; |
| protected List attachments; |
| protected String subject; |
| protected String body; |
| protected String bodyURI; |
| protected String bodyMimeType; |
| protected String mailHost; |
| protected int mailPort; |
| protected String fromAddress; |
| protected AttachmentDescriptor attachmentDescriptor; |
| protected int port; |
| protected String contextPath; |
| protected boolean sendPartial; |
| protected Message smtpMessage; |
| |
| protected String defaultSmtpHost; |
| protected int defaultSmtpPort; |
| protected String defaultFromAddress; |
| |
| protected List usedSources = new ArrayList(); |
| |
| /** |
| * create a new Transformer |
| */ |
| public SendMailTransformer() { |
| this.defaultNamespaceURI = NAMESPACE; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration) |
| */ |
| public void configure(Configuration configuration) |
| throws ConfigurationException { |
| super.configure(configuration); |
| this.defaultSmtpHost = configuration.getChild("smtphost").getValue(""); |
| this.defaultSmtpPort = configuration.getChild("smtpport").getValueAsInteger(25); |
| this.defaultFromAddress = configuration.getChild("from").getValue(""); |
| } |
| |
| /** |
| * invoked every time when the transformer is triggered by the pipeline |
| */ |
| public void setup(SourceResolver resolver, Map objectModel, String src, |
| Parameters par) |
| throws ProcessingException, SAXException, IOException { |
| super.setup(resolver, objectModel, src, par); |
| |
| this.mailHost = par.getParameter(PARAM_SMTPHOST, this.defaultSmtpHost); |
| this.mailPort = par.getParameterAsInteger(PARAM_SMTPPORT, this.defaultSmtpPort); |
| this.fromAddress = par.getParameter(PARAM_FROM, this.defaultFromAddress); |
| this.port = this.request.getServerPort(); |
| this.contextPath = this.request.getContextPath(); |
| this.sendPartial = par.getParameterAsBoolean(PARAM_SENDPARTIAL, true); |
| |
| if (getLogger().isDebugEnabled()) { |
| getLogger().debug("Using host " + mailHost + " on port " + mailPort + ", from address " + fromAddress); |
| } |
| |
| this.attachments = new ArrayList(); |
| this.defaultToAddresses = new ArrayList(); |
| appendToAddress(this.defaultToAddresses, par.getParameter(PARAM_TO, "")); |
| this.defaultReplyToAddresses = new ArrayList(); |
| appendToAddress(this.defaultReplyToAddresses, par.getParameter(PARAM_REPLY_TO, "")); |
| |
| this.subject = par.getParameter(PARAM_SUBJECT, null); |
| this.body = par.getParameter(PARAM_BODY, null); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.cocoon.transformation.AbstractSAXTransformer#startTransformingElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes) |
| */ |
| public void startTransformingElement(String uri, String name, String raw, |
| Attributes attr) |
| throws SAXException { |
| if (name.equals(ELEMENT_SENDMAIL)) { |
| // Clean from possible previous usage |
| this.toAddresses = new ArrayList(this.defaultToAddresses); |
| this.replyToAddresses = new ArrayList(this.defaultReplyToAddresses); |
| this.attachments.clear(); |
| } else if (name.equals(ELEMENT_SMTPHOST)) { |
| startTextRecording(); |
| this.mode = MODE_SMTPHOST; |
| } else if (name.equals(ELEMENT_SMTPPORT)) { |
| this.startTextRecording(); |
| this.mode = MODE_SMTPPORT; |
| } else if (name.equals(ELEMENT_MAILFROM)) { |
| startTextRecording(); |
| this.mode = MODE_FROM; |
| } else if (name.equals(ELEMENT_MAILTO)) { |
| startTextRecording(); |
| this.mode = MODE_TO; |
| } else if (name.equals(ELEMENT_REPLYTO)) { |
| startTextRecording(); |
| this.mode = MODE_REPLY_TO; |
| } else if (name.equals(ELEMENT_MAILSUBJECT)) { |
| startTextRecording(); |
| this.mode = MODE_SUBJECT; |
| } else if (name.equals(ELEMENT_MAILBODY)) { |
| String strBody = attr.getValue("src"); |
| if (strBody != null) { |
| this.bodyURI = strBody; |
| } |
| |
| String mType = attr.getValue("mime-type"); |
| if (mType != null) { |
| this.bodyMimeType = mType; |
| } else { |
| this.bodyMimeType = DEFAULT_BODY_MIMETYPE; |
| } |
| |
| Properties outputProperties = new Properties(); |
| if (this.bodyMimeType.startsWith("text/plain")) |
| outputProperties.put(OutputKeys.METHOD, "text"); |
| else if (this.bodyMimeType.startsWith("text/html")) |
| outputProperties.put(OutputKeys.METHOD, "html"); |
| startSerializedXMLRecording(outputProperties); |
| this.mode = MODE_BODY; |
| } else if (name.equals(ELEMENT_ATTACHMENT)) { |
| this.attachmentDescriptor = new AttachmentDescriptor(attr.getValue("name"), |
| attr.getValue("mime-type"), |
| attr.getValue("src"), |
| attr.getValue("url")); |
| this.mode = MODE_ATTACHMENT; |
| } else if (name.equals(ELEMENT_ATTACHMENT_CONTENT)) { |
| startSerializedXMLRecording(new Properties()); |
| this.mode = MODE_ATTACHMENT_CONTENT; |
| } else { |
| throw new SAXException("Unknown element <" + name + ">"); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.cocoon.transformation.AbstractSAXTransformer#endTransformingElement(java.lang.String, java.lang.String, java.lang.String) |
| */ |
| public void endTransformingElement(String uri, String name, String raw) |
| throws SAXException, ProcessingException { |
| if (name.equals(ELEMENT_SENDMAIL)) { |
| if (getLogger().isInfoEnabled()) { |
| getLogger().info("Mail Subject: " + this.subject + "\n" + |
| "Body: " + this.body); |
| } |
| sendMail(); |
| } else if (name.equals(ELEMENT_SMTPHOST) ) { |
| this.mailHost = endTextRecording(); |
| this.mode = MODE_NONE; |
| } else if (name.equals(ELEMENT_SMTPPORT) ) { |
| this.mailPort = Integer.parseInt(this.endTextRecording()); |
| this.mode = MODE_NONE; |
| } else if (name.equals(ELEMENT_MAILFROM)) { |
| this.fromAddress = endTextRecording(); |
| this.mode = MODE_NONE; |
| } else if (name.equals(ELEMENT_MAILTO)) { |
| this.toAddresses.add(endTextRecording()); |
| this.mode = MODE_NONE; |
| } else if (name.equals(ELEMENT_REPLYTO)) { |
| this.replyToAddresses.add(endTextRecording()); |
| this.mode = MODE_NONE; |
| } else if (name.equals(ELEMENT_MAILSUBJECT)) { |
| String strSubject = endTextRecording(); |
| if (strSubject != null) { |
| this.subject = strSubject; |
| } else { |
| getLogger().debug("Mail: No Subject"); |
| } |
| this.mode = MODE_NONE; |
| } else if (name.equals(ELEMENT_ATTACHMENT)) { |
| this.attachments.add(this.attachmentDescriptor.copy()); |
| this.attachmentDescriptor = null; |
| this.mode = MODE_NONE; |
| } else if (name.equals(ELEMENT_ATTACHMENT_CONTENT)) { |
| this.attachmentDescriptor.setContent(endSerializedXMLRecording()); |
| this.mode = MODE_NONE; |
| } else if (name.equals(ELEMENT_MAILBODY)) { |
| String strB = null; |
| try { |
| strB = endSerializedXMLRecording(); |
| } catch (Exception e) { |
| if (getLogger().isDebugEnabled()) { |
| getLogger().debug("Mail: No Body as String in config-file available"); |
| } |
| } |
| if (strB != null) { |
| this.body = strB; |
| } |
| this.mode = MODE_NONE; |
| } else { |
| throw new SAXException("Unknown element <" + name + ">"); |
| } |
| } |
| |
| private static void appendToAddress(List addresses, String s) { |
| StringTokenizer t = new StringTokenizer(s.trim(), ";"); |
| while (t.hasMoreElements()) { |
| addresses.add(t.nextToken()); |
| } |
| } |
| |
| /** |
| * |
| */ |
| private void sendMail() throws SAXException { |
| try { |
| this.ignoreHooksCount++; |
| super.sendStartElementEventNS(ELEMENT_RESULT); |
| Properties props = new Properties(); |
| props.put("mail.smtp.host", this.mailHost); |
| props.put("mail.smtp.port", String.valueOf(this.mailPort)); |
| |
| if (this.subject == null) { |
| this.ignoreHooksCount++; |
| super.sendStartElementEventNS(ELEMENT_ERROR); |
| super.sendTextEvent("Subject not available - sending mail aborted"); |
| super.sendEndElementEventNS(ELEMENT_ERROR); |
| this.ignoreHooksCount--; |
| return; |
| } |
| |
| if (this.body == null && this.bodyURI == null) { |
| this.ignoreHooksCount++; |
| super.sendStartElementEventNS(ELEMENT_ERROR); |
| super.sendTextEvent("Mailbody not available - sending mail aborted"); |
| super.sendEndElementEventNS(ELEMENT_ERROR); |
| this.ignoreHooksCount--; |
| return; |
| } |
| |
| Session session = Session.getDefaultInstance(props, null); |
| Transport trans = session.getTransport("smtp"); |
| trans.connect(); |
| |
| this.smtpMessage = setUpMessage(session); |
| |
| if (this.sendPartial) { |
| for (int i = 0; i < this.toAddresses.size(); i++) { |
| List v = new ArrayList(1); |
| v.add(this.toAddresses.get(i)); |
| sendMail(v, trans); |
| } |
| } else { |
| sendMail(this.toAddresses, trans); |
| } |
| |
| trans.close(); |
| } catch (SAXException e){ |
| throw e; |
| } catch (Exception e) { |
| getLogger().error("Exception sending mail", e); |
| sendExceptionElement(e); |
| } |
| finally { |
| super.sendEndElementEventNS(ELEMENT_RESULT); |
| this.ignoreHooksCount--; |
| } |
| } |
| |
| /** |
| * @see <a href="http://java.sun.com/products/javamail/1.3/docs/javadocs/com/sun/mail/smtp/package-summary.html">Sun Javamail Javadoc</a> |
| * @throws Exception |
| */ |
| private void sendMail(List newAddresses, Transport trans) |
| throws Exception { |
| AddressHandler[] iA = new AddressHandler[newAddresses.size()]; |
| |
| try { |
| for (int i = 0; i < newAddresses.size(); i++) { |
| InternetAddress inA = new InternetAddress((String) newAddresses.get(i)); |
| iA[i] = new AddressHandler(inA); |
| } |
| InternetAddress[] iaArr = SendMailTransformer.getAddresses(iA); |
| this.smtpMessage.setRecipients(Message.RecipientType.TO, iaArr); |
| trans.sendMessage(this.smtpMessage, iaArr); |
| } catch (SendFailedException e) { |
| getLogger().error("Exception during sending of mail", e); |
| |
| Address[] adr = e.getInvalidAddresses(); |
| for (int isfEx = 0; isfEx < iA.length; isfEx++) { |
| String tmpAddress = iA[isfEx].getAddress().getAddress(); |
| for (int sei = 0; sei < adr.length; sei++) { |
| if (((InternetAddress) adr[sei]).getAddress() |
| .equalsIgnoreCase(tmpAddress)) { |
| iA[isfEx].setSendMailResult("Invalid address"); |
| } |
| } |
| } |
| |
| Address[] ad = e.getValidUnsentAddresses(); |
| for (int isfEx = 0; isfEx < iA.length; isfEx++) { |
| String tmpAddress = iA[isfEx].getAddress().getAddress(); |
| for (int sei = 0; sei < ad.length; sei++) { |
| if (((InternetAddress) ad[sei]).getAddress() |
| .equalsIgnoreCase(tmpAddress)) { |
| iA[isfEx].setSendMailResult("Recipient not found"); |
| } |
| } |
| } |
| } catch (Exception e) { |
| getLogger().error("Exception sending mail", e); |
| sendExceptionElement(e); |
| return; |
| } |
| |
| generateSAXReportStatements(iA); |
| } |
| |
| private Message setUpMessage(Session session) throws Exception { |
| Message sm = new MimeMessage(session); |
| |
| //sm.setAllow8bitMIME(true); |
| Address[] replyTo = new Address[this.replyToAddresses.size()]; |
| for (int i = 0 ; i < this.replyToAddresses.size(); i++) { |
| replyTo[i] = new InternetAddress((String) this.replyToAddresses.get(i)); |
| } |
| sm.setReplyTo(replyTo); |
| sm.setFrom(new InternetAddress(this.fromAddress)); |
| sm.setSubject(this.subject); |
| |
| // process mail-body |
| BodyPart messageBodyPart = new MimeBodyPart(); |
| |
| // decide, if to take content from source or plain text |
| // from variable to build mailbody |
| String messageString; |
| if (this.bodyURI != null) { |
| Source inSrc = resolver.resolveURI(this.bodyURI); |
| this.usedSources.add(inSrc); |
| InputStream inStr = inSrc.getInputStream(); |
| byte[] byteArr = new byte[inStr.available()]; |
| inStr.read(byteArr); |
| |
| messageString = new String(byteArr); |
| |
| // String mailBody = new String(byteArr); |
| // this.setMessageBody(messageBodyPart, mailBody, this.bodyMimeType); |
| } else { |
| messageString = this.body; |
| // this.setMessageBody(messageBodyPart, this.body, this.bodyMimeType); |
| } |
| |
| // make it a simple plain text message in the case of a set plain/text |
| // mime-type and any attachements |
| if (("text/plain").equals(this.bodyMimeType) && this.attachments.size() == 0) { |
| sm.setText(messageString); |
| } |
| // add message as message body part |
| else { |
| messageBodyPart.setContent(messageString, this.bodyMimeType); |
| Multipart multipart = new MimeMultipart(); |
| multipart.addBodyPart(messageBodyPart); |
| |
| // process attachments |
| Iterator i = this.attachments.iterator(); |
| while (i.hasNext()) { |
| AttachmentDescriptor aD = (AttachmentDescriptor) i.next(); |
| messageBodyPart = new MimeBodyPart(); |
| |
| if (!aD.isTextContent()) { |
| Source inputSource = resolver.resolveURI(aD.isURLSource() ? aD.strAttrSrc : aD.strAttrFile); |
| this.usedSources.add(inputSource); |
| |
| DataSource dataSource = new SourceDataSource(inputSource, aD.strAttrMimeType, aD.strAttrName); |
| ((SourceDataSource) dataSource).enableLogging(getLogger()); |
| |
| messageBodyPart.setDataHandler(new DataHandler(dataSource)); |
| } else { |
| messageBodyPart.setContent(aD.strContent, aD.strAttrMimeType); |
| } |
| |
| messageBodyPart.setFileName(aD.strAttrName); |
| multipart.addBodyPart(messageBodyPart); |
| } |
| sm.setContent(multipart); |
| } |
| |
| //sm.setReturnOption(SMTPMessage.RETURN_FULL); |
| sm.saveChanges(); |
| |
| return sm; |
| } |
| |
| private void generateSAXReportStatements(AddressHandler[] addressArr) |
| throws SAXException { |
| AttributesImpl impl = new AttributesImpl(); |
| |
| for (int i = 0; i < addressArr.length; i++) { |
| String tmpAddress = addressArr[i].getAddress().getAddress(); |
| |
| if (addressArr[i].getSendMailResult() == null) { |
| impl.addAttribute("", "to", "to", |
| "CDATA", tmpAddress); |
| super.sendStartElementEventNS(ELEMENT_SUCCESS, impl); |
| super.sendTextEvent("Mail sent"); |
| super.sendEndElementEventNS(ELEMENT_SUCCESS); |
| } else { |
| impl.addAttribute("", "to", "to", |
| "CDATA", tmpAddress); |
| super.sendStartElementEventNS(ELEMENT_FAILURE, impl); |
| super.sendTextEvent(addressArr[i].getSendMailResult()); |
| super.sendEndElementEventNS(ELEMENT_FAILURE); |
| } |
| } |
| } |
| |
| private void sendExceptionElement(Exception ex) { |
| try { |
| this.ignoreHooksCount++; |
| super.sendStartElementEventNS("exception"); |
| super.sendStartElementEventNS("message"); |
| super.sendTextEvent(ex.getMessage()); |
| super.sendEndElementEventNS("message"); |
| |
| /* only with jdk 1.4 |
| super.sendStartElementEvent("email:stacktrace"); |
| |
| for (int i = 0; i < ex.getStackTrace().length; i++) { |
| String s = ((StackTraceElement) ex.getStackTrace()[i]).toString(); |
| super.sendTextEvent(s + "\n"); |
| } |
| |
| super.sendEndElementEvent("email:stacktrace");*/ |
| |
| super.sendEndElementEventNS("exception"); |
| this.ignoreHooksCount--; |
| } catch (SAXException e) { |
| getLogger().error("Error while sending a SAX-Event", e); |
| } |
| } |
| |
| public static InternetAddress[] getAddresses(AddressHandler[] handlerArr) { |
| InternetAddress[] iaArr = new InternetAddress[handlerArr.length]; |
| |
| for (int i = 0; i < handlerArr.length; i++) { |
| iaArr[i] = handlerArr[i].getAddress(); |
| } |
| |
| return iaArr; |
| } |
| |
| /** |
| * @see org.apache.avalon.excalibur.pool.Recyclable#recycle() |
| */ |
| public void recycle() { |
| this.toAddresses = null; |
| this.defaultToAddresses = null; |
| this.attachments = null; |
| this.subject = null; |
| this.body = null; |
| this.bodyURI = null; |
| this.mailHost = null; |
| this.mailPort = 0; |
| this.fromAddress = null; |
| this.attachmentDescriptor = null; |
| this.port = 0; |
| this.contextPath = null; |
| this.sendPartial = true; |
| this.smtpMessage = null; |
| final Iterator i = this.usedSources.iterator(); |
| while ( i.hasNext() ) { |
| final Source source = (Source)i.next(); |
| this.resolver.release(source); |
| } |
| this.usedSources.clear(); |
| super.recycle(); |
| } |
| |
| static class AttachmentDescriptor { |
| String strAttrName; |
| String strAttrMimeType; |
| String strAttrSrc; |
| String strAttrFile; |
| String strContent; |
| |
| protected AttachmentDescriptor(String newAttrName, |
| String newAttrMimeType, |
| String newAttrSrc, String newAttrFile) { |
| this.strAttrName = newAttrName; |
| this.strAttrMimeType = newAttrMimeType; |
| this.strAttrSrc = newAttrSrc; |
| this.strAttrFile = newAttrFile; |
| } |
| |
| protected void setContent(String newContent) { |
| this.strContent = newContent; |
| } |
| |
| protected AttachmentDescriptor copy() { |
| AttachmentDescriptor aD = new AttachmentDescriptor(this.strAttrName, |
| this.strAttrMimeType, |
| this.strAttrSrc, |
| this.strAttrFile); |
| aD.setContent(this.strContent); |
| |
| return aD; |
| } |
| |
| protected boolean isURLSource() { |
| return (this.strAttrSrc != null); |
| } |
| |
| protected boolean isFileSource() { |
| return (this.strAttrFile != null); |
| } |
| |
| protected boolean isTextContent() { |
| return (this.strContent != null); |
| } |
| } |
| |
| static class AddressHandler { |
| private InternetAddress address; |
| private String sendMailResult; |
| |
| protected AddressHandler(InternetAddress newAddress) { |
| this.address = newAddress; |
| } |
| |
| protected void setSendMailResult(String newSendMailResult) { |
| this.sendMailResult = newSendMailResult; |
| } |
| |
| /** |
| * @return mail-address |
| */ |
| public InternetAddress getAddress() { |
| return address; |
| } |
| |
| /** |
| * @return sendMailResult as String |
| */ |
| public String getSendMailResult() { |
| return sendMailResult; |
| } |
| } |
| } |