0001: /*
0002: * Copyright 2002-2007 the original author or authors.
0003: *
0004: * Licensed under the Apache License, Version 2.0 (the "License");
0005: * you may not use this file except in compliance with the License.
0006: * You may obtain a copy of the License at
0007: *
0008: * http://www.apache.org/licenses/LICENSE-2.0
0009: *
0010: * Unless required by applicable law or agreed to in writing, software
0011: * distributed under the License is distributed on an "AS IS" BASIS,
0012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013: * See the License for the specific language governing permissions and
0014: * limitations under the License.
0015: */
0016:
0017: package org.springframework.mail.javamail;
0018:
0019: import java.io.File;
0020: import java.io.IOException;
0021: import java.io.InputStream;
0022: import java.io.OutputStream;
0023: import java.io.UnsupportedEncodingException;
0024: import java.util.Date;
0025:
0026: import javax.activation.DataHandler;
0027: import javax.activation.DataSource;
0028: import javax.activation.FileDataSource;
0029: import javax.activation.FileTypeMap;
0030: import javax.mail.BodyPart;
0031: import javax.mail.Message;
0032: import javax.mail.MessagingException;
0033: import javax.mail.internet.AddressException;
0034: import javax.mail.internet.InternetAddress;
0035: import javax.mail.internet.MimeBodyPart;
0036: import javax.mail.internet.MimeMessage;
0037: import javax.mail.internet.MimeMultipart;
0038: import javax.mail.internet.MimePart;
0039:
0040: import org.springframework.core.io.InputStreamSource;
0041: import org.springframework.core.io.Resource;
0042: import org.springframework.util.Assert;
0043:
0044: /**
0045: * Helper class for populating a {@link javax.mail.internet.MimeMessage}.
0046: *
0047: * <p>Mirrors the simple setters of {@link org.springframework.mail.SimpleMailMessage},
0048: * directly applying the values to the underlying MimeMessage. Allows for defining
0049: * a character encoding for the entire message, automatically applied by all methods
0050: * of this helper class.
0051: *
0052: * <p>Offers support for HTML text content, inline elements such as images, and typical
0053: * mail attachments. Also supports personal names that accompany mail addresses. Note that
0054: * advanced settings can still be applied directly to the underlying MimeMessage object!
0055: *
0056: * <p>Typically used in {@link MimeMessagePreparator} implementations or
0057: * {@link JavaMailSender} client code: simply instantiating it as a MimeMessage wrapper,
0058: * invoking setters on the wrapper, using the underlying MimeMessage for mail sending.
0059: * Also used internally by {@link JavaMailSenderImpl}.
0060: *
0061: * <p>Sample code for an HTML mail with an inline image and a PDF attachment:
0062: *
0063: * <pre class="code">
0064: * mailSender.send(new MimeMessagePreparator() {
0065: * public void prepare(MimeMessage mimeMessage) throws MessagingException {
0066: * MimeMessageHelper message = new MimeMessageHelper(mimeMessage, true, "UTF-8");
0067: * message.setFrom("me@mail.com");
0068: * message.setTo("you@mail.com");
0069: * message.setSubject("my subject");
0070: * message.setText("my text <img src='cid:myLogo'>", true);
0071: * message.addInline("myLogo", new ClassPathResource("img/mylogo.gif"));
0072: * message.addAttachment("myDocument.pdf", new ClassPathResource("doc/myDocument.pdf"));
0073: * }
0074: * });</pre>
0075: *
0076: * Consider using {@link MimeMailMessage} (which implements the common
0077: * {@link org.springframework.mail.MailMessage} interface, just like
0078: * {@link org.springframework.mail.SimpleMailMessage}) on top of this helper,
0079: * in order to let message population code interact with a simple message
0080: * or a MIME message through a common interface.
0081: *
0082: * <p><b>Warning regarding multipart mails:</b> Simple MIME messages that
0083: * just contain HTML text but no inline elements or attachments will work on
0084: * more or less any email client that is capable of HTML rendering. However,
0085: * inline elements and attachments are still a major compatibility issue
0086: * between email clients: It's virtually impossible to get inline elements
0087: * and attachments working across Microsoft Outlook, Lotus Notes and Mac Mail.
0088: * Consider choosing a specific multipart mode for your needs: The javadoc
0089: * on the MULTIPART_MODE constants contains more detailed information.
0090: *
0091: * @author Juergen Hoeller
0092: * @since 19.01.2004
0093: * @see #setText(String, boolean)
0094: * @see #setText(String, String)
0095: * @see #addInline(String, org.springframework.core.io.Resource)
0096: * @see #addAttachment(String, org.springframework.core.io.InputStreamSource)
0097: * @see #MULTIPART_MODE_MIXED_RELATED
0098: * @see #MULTIPART_MODE_RELATED
0099: * @see #getMimeMessage()
0100: * @see JavaMailSender
0101: */
0102: public class MimeMessageHelper {
0103:
0104: /**
0105: * Constant indicating a non-multipart message.
0106: */
0107: public static final int MULTIPART_MODE_NO = 0;
0108:
0109: /**
0110: * Constant indicating a multipart message with a single root multipart
0111: * element of type "mixed". Texts, inline elements and attachements
0112: * will all get added to that root element.
0113: * <p>This was Spring 1.0's default behavior. It is known to work properly
0114: * on Outlook. However, other mail clients tend to misinterpret inline
0115: * elements as attachments and/or show attachments inline as well.
0116: */
0117: public static final int MULTIPART_MODE_MIXED = 1;
0118:
0119: /**
0120: * Constant indicating a multipart message with a single root multipart
0121: * element of type "related". Texts, inline elements and attachements
0122: * will all get added to that root element.
0123: * <p>This was the default behavior from Spring 1.1 up to 1.2 final.
0124: * This is the "Microsoft multipart mode", as natively sent by Outlook.
0125: * It is known to work properly on Outlook, Outlook Express, Yahoo Mail, and
0126: * to a large degree also on Mac Mail (with an additional attachment listed
0127: * for an inline element, despite the inline element also shown inline).
0128: * Does not work properly on Lotus Notes (attachments won't be shown there).
0129: */
0130: public static final int MULTIPART_MODE_RELATED = 2;
0131:
0132: /**
0133: * Constant indicating a multipart message with a root multipart element
0134: * "mixed" plus a nested multipart element of type "related". Texts and
0135: * inline elements will get added to the nested "related" element,
0136: * while attachments will get added to the "mixed" root element.
0137: * <p>This is the default since Spring 1.2.1. This is arguably the most correct
0138: * MIME structure, according to the MIME spec: It is known to work properly
0139: * on Outlook, Outlook Express, Yahoo Mail, and Lotus Notes. Does not work
0140: * properly on Mac Mail. If you target Mac Mail or experience issues with
0141: * specific mails on Outlook, consider using MULTIPART_MODE_RELATED instead.
0142: */
0143: public static final int MULTIPART_MODE_MIXED_RELATED = 3;
0144:
0145: private static final String MULTIPART_SUBTYPE_MIXED = "mixed";
0146:
0147: private static final String MULTIPART_SUBTYPE_RELATED = "related";
0148:
0149: private static final String MULTIPART_SUBTYPE_ALTERNATIVE = "alternative";
0150:
0151: private static final String CONTENT_TYPE_ALTERNATIVE = "text/alternative";
0152:
0153: private static final String CONTENT_TYPE_HTML = "text/html";
0154:
0155: private static final String CONTENT_TYPE_CHARSET_SUFFIX = ";charset=";
0156:
0157: private static final String HEADER_PRIORITY = "X-Priority";
0158:
0159: private static final String HEADER_CONTENT_ID = "Content-ID";
0160:
0161: private final MimeMessage mimeMessage;
0162:
0163: private MimeMultipart rootMimeMultipart;
0164:
0165: private MimeMultipart mimeMultipart;
0166:
0167: private final String encoding;
0168:
0169: private FileTypeMap fileTypeMap;
0170:
0171: private boolean validateAddresses = false;
0172:
0173: /**
0174: * Create a new MimeMessageHelper for the given MimeMessage,
0175: * assuming a simple text message (no multipart content,
0176: * i.e. no alternative texts and no inline elements or attachments).
0177: * <p>The character encoding for the message will be taken from
0178: * the passed-in MimeMessage object, if carried there. Else,
0179: * JavaMail's default encoding will be used.
0180: * @param mimeMessage MimeMessage to work on
0181: * @see #MimeMessageHelper(javax.mail.internet.MimeMessage, boolean)
0182: * @see #getDefaultEncoding(javax.mail.internet.MimeMessage)
0183: * @see JavaMailSenderImpl#setDefaultEncoding
0184: */
0185: public MimeMessageHelper(MimeMessage mimeMessage) {
0186: this (mimeMessage, null);
0187: }
0188:
0189: /**
0190: * Create a new MimeMessageHelper for the given MimeMessage,
0191: * assuming a simple text message (no multipart content,
0192: * i.e. no alternative texts and no inline elements or attachments).
0193: * @param mimeMessage MimeMessage to work on
0194: * @param encoding the character encoding to use for the message
0195: * @see #MimeMessageHelper(javax.mail.internet.MimeMessage, boolean)
0196: */
0197: public MimeMessageHelper(MimeMessage mimeMessage, String encoding) {
0198: this .mimeMessage = mimeMessage;
0199: this .encoding = (encoding != null ? encoding
0200: : getDefaultEncoding(mimeMessage));
0201: this .fileTypeMap = getDefaultFileTypeMap(mimeMessage);
0202: }
0203:
0204: /**
0205: * Create a new MimeMessageHelper for the given MimeMessage,
0206: * in multipart mode (supporting alternative texts, inline
0207: * elements and attachments) if requested.
0208: * <p>Consider using the MimeMessageHelper constructor that
0209: * takes a multipartMode argument to choose a specific multipart
0210: * mode other than MULTIPART_MODE_MIXED_RELATED.
0211: * <p>The character encoding for the message will be taken from
0212: * the passed-in MimeMessage object, if carried there. Else,
0213: * JavaMail's default encoding will be used.
0214: * @param mimeMessage MimeMessage to work on
0215: * @param multipart whether to create a multipart message that
0216: * supports alternative texts, inline elements and attachments
0217: * (corresponds to MULTIPART_MODE_MIXED_RELATED)
0218: * @throws MessagingException if multipart creation failed
0219: * @see #MimeMessageHelper(javax.mail.internet.MimeMessage, int)
0220: * @see #getDefaultEncoding(javax.mail.internet.MimeMessage)
0221: * @see JavaMailSenderImpl#setDefaultEncoding
0222: */
0223: public MimeMessageHelper(MimeMessage mimeMessage, boolean multipart)
0224: throws MessagingException {
0225: this (mimeMessage, multipart, null);
0226: }
0227:
0228: /**
0229: * Create a new MimeMessageHelper for the given MimeMessage,
0230: * in multipart mode (supporting alternative texts, inline
0231: * elements and attachments) if requested.
0232: * <p>Consider using the MimeMessageHelper constructor that
0233: * takes a multipartMode argument to choose a specific multipart
0234: * mode other than MULTIPART_MODE_MIXED_RELATED.
0235: * @param mimeMessage MimeMessage to work on
0236: * @param multipart whether to create a multipart message that
0237: * supports alternative texts, inline elements and attachments
0238: * (corresponds to MULTIPART_MODE_MIXED_RELATED)
0239: * @param encoding the character encoding to use for the message
0240: * @throws MessagingException if multipart creation failed
0241: * @see #MimeMessageHelper(javax.mail.internet.MimeMessage, int, String)
0242: */
0243: public MimeMessageHelper(MimeMessage mimeMessage,
0244: boolean multipart, String encoding)
0245: throws MessagingException {
0246:
0247: this (mimeMessage, (multipart ? MULTIPART_MODE_MIXED_RELATED
0248: : MULTIPART_MODE_NO), encoding);
0249: }
0250:
0251: /**
0252: * Create a new MimeMessageHelper for the given MimeMessage,
0253: * in multipart mode (supporting alternative texts, inline
0254: * elements and attachments) if requested.
0255: * <p>The character encoding for the message will be taken from
0256: * the passed-in MimeMessage object, if carried there. Else,
0257: * JavaMail's default encoding will be used.
0258: * @param mimeMessage MimeMessage to work on
0259: * @param multipartMode which kind of multipart message to create
0260: * (MIXED, RELATED, MIXED_RELATED, or NO)
0261: * @throws MessagingException if multipart creation failed
0262: * @see #MULTIPART_MODE_NO
0263: * @see #MULTIPART_MODE_MIXED
0264: * @see #MULTIPART_MODE_RELATED
0265: * @see #MULTIPART_MODE_MIXED_RELATED
0266: * @see #getDefaultEncoding(javax.mail.internet.MimeMessage)
0267: * @see JavaMailSenderImpl#setDefaultEncoding
0268: */
0269: public MimeMessageHelper(MimeMessage mimeMessage, int multipartMode)
0270: throws MessagingException {
0271: this (mimeMessage, multipartMode, null);
0272: }
0273:
0274: /**
0275: * Create a new MimeMessageHelper for the given MimeMessage,
0276: * in multipart mode (supporting alternative texts, inline
0277: * elements and attachments) if requested.
0278: * @param mimeMessage MimeMessage to work on
0279: * @param multipartMode which kind of multipart message to create
0280: * (MIXED, RELATED, MIXED_RELATED, or NO)
0281: * @param encoding the character encoding to use for the message
0282: * @throws MessagingException if multipart creation failed
0283: * @see #MULTIPART_MODE_NO
0284: * @see #MULTIPART_MODE_MIXED
0285: * @see #MULTIPART_MODE_RELATED
0286: * @see #MULTIPART_MODE_MIXED_RELATED
0287: */
0288: public MimeMessageHelper(MimeMessage mimeMessage,
0289: int multipartMode, String encoding)
0290: throws MessagingException {
0291:
0292: this .mimeMessage = mimeMessage;
0293: createMimeMultiparts(mimeMessage, multipartMode);
0294: this .encoding = (encoding != null ? encoding
0295: : getDefaultEncoding(mimeMessage));
0296: this .fileTypeMap = getDefaultFileTypeMap(mimeMessage);
0297: }
0298:
0299: /**
0300: * Return the underlying MimeMessage object.
0301: */
0302: public final MimeMessage getMimeMessage() {
0303: return this .mimeMessage;
0304: }
0305:
0306: /**
0307: * Determine the MimeMultipart objects to use, which will be used
0308: * to store attachments on the one hand and text(s) and inline elements
0309: * on the other hand.
0310: * <p>Texts and inline elements can either be stored in the root element
0311: * itself (MULTIPART_MODE_MIXED, MULTIPART_MODE_RELATED) or in a nested element
0312: * rather than the root element directly (MULTIPART_MODE_MIXED_RELATED).
0313: * <p>By default, the root MimeMultipart element will be of type "mixed"
0314: * (MULTIPART_MODE_MIXED) or "related" (MULTIPART_MODE_RELATED).
0315: * The main multipart element will either be added as nested element of
0316: * type "related" (MULTIPART_MODE_MIXED_RELATED) or be identical to the root
0317: * element itself (MULTIPART_MODE_MIXED, MULTIPART_MODE_RELATED).
0318: * @param mimeMessage the MimeMessage object to add the root MimeMultipart
0319: * object to
0320: * @param multipartMode the multipart mode, as passed into the constructor
0321: * (MIXED, RELATED, MIXED_RELATED, or NO)
0322: * @throws MessagingException if multipart creation failed
0323: * @see #setMimeMultiparts
0324: * @see #MULTIPART_MODE_NO
0325: * @see #MULTIPART_MODE_MIXED
0326: * @see #MULTIPART_MODE_RELATED
0327: * @see #MULTIPART_MODE_MIXED_RELATED
0328: */
0329: protected void createMimeMultiparts(MimeMessage mimeMessage,
0330: int multipartMode) throws MessagingException {
0331: switch (multipartMode) {
0332: case MULTIPART_MODE_NO:
0333: setMimeMultiparts(null, null);
0334: break;
0335: case MULTIPART_MODE_MIXED:
0336: MimeMultipart mixedMultipart = new MimeMultipart(
0337: MULTIPART_SUBTYPE_MIXED);
0338: mimeMessage.setContent(mixedMultipart);
0339: setMimeMultiparts(mixedMultipart, mixedMultipart);
0340: break;
0341: case MULTIPART_MODE_RELATED:
0342: MimeMultipart relatedMultipart = new MimeMultipart(
0343: MULTIPART_SUBTYPE_RELATED);
0344: mimeMessage.setContent(relatedMultipart);
0345: setMimeMultiparts(relatedMultipart, relatedMultipart);
0346: break;
0347: case MULTIPART_MODE_MIXED_RELATED:
0348: MimeMultipart rootMixedMultipart = new MimeMultipart(
0349: MULTIPART_SUBTYPE_MIXED);
0350: mimeMessage.setContent(rootMixedMultipart);
0351: MimeMultipart nestedRelatedMultipart = new MimeMultipart(
0352: MULTIPART_SUBTYPE_RELATED);
0353: MimeBodyPart relatedBodyPart = new MimeBodyPart();
0354: relatedBodyPart.setContent(nestedRelatedMultipart);
0355: rootMixedMultipart.addBodyPart(relatedBodyPart);
0356: setMimeMultiparts(rootMixedMultipart,
0357: nestedRelatedMultipart);
0358: break;
0359: default:
0360: throw new IllegalArgumentException(
0361: "Only multipart modes MIXED_RELATED, RELATED and NO supported");
0362: }
0363: }
0364:
0365: /**
0366: * Set the given MimeMultipart objects for use by this MimeMessageHelper.
0367: * @param root the root MimeMultipart object, which attachments will be added to;
0368: * or <code>null</code> to indicate no multipart at all
0369: * @param main the main MimeMultipart object, which text(s) and inline elements
0370: * will be added to (can be the same as the root multipart object, or an element
0371: * nested underneath the root multipart element)
0372: */
0373: protected final void setMimeMultiparts(MimeMultipart root,
0374: MimeMultipart main) {
0375: this .rootMimeMultipart = root;
0376: this .mimeMultipart = main;
0377: }
0378:
0379: /**
0380: * Return whether this helper is in multipart mode,
0381: * i.e. whether it holds a multipart message.
0382: * @see #MimeMessageHelper(MimeMessage, boolean)
0383: */
0384: public final boolean isMultipart() {
0385: return (this .rootMimeMultipart != null);
0386: }
0387:
0388: /**
0389: * Throw an IllegalStateException if this helper is not in multipart mode.
0390: */
0391: private void checkMultipart() throws IllegalStateException {
0392: if (!isMultipart()) {
0393: throw new IllegalStateException(
0394: "Not in multipart mode - "
0395: + "create an appropriate MimeMessageHelper via a constructor that takes a 'multipart' flag "
0396: + "if you need to set alternative texts or add inline elements or attachments.");
0397: }
0398: }
0399:
0400: /**
0401: * Return the root MIME "multipart/mixed" object, if any.
0402: * Can be used to manually add attachments.
0403: * <p>This will be the direct content of the MimeMessage,
0404: * in case of a multipart mail.
0405: * @throws IllegalStateException if this helper is not in multipart mode
0406: * @see #isMultipart
0407: * @see #getMimeMessage
0408: * @see javax.mail.internet.MimeMultipart#addBodyPart
0409: */
0410: public final MimeMultipart getRootMimeMultipart()
0411: throws IllegalStateException {
0412: checkMultipart();
0413: return this .rootMimeMultipart;
0414: }
0415:
0416: /**
0417: * Return the underlying MIME "multipart/related" object, if any.
0418: * Can be used to manually add body parts, inline elements, etc.
0419: * <p>This will be nested within the root MimeMultipart,
0420: * in case of a multipart mail.
0421: * @throws IllegalStateException if this helper is not in multipart mode
0422: * @see #isMultipart
0423: * @see #getRootMimeMultipart
0424: * @see javax.mail.internet.MimeMultipart#addBodyPart
0425: */
0426: public final MimeMultipart getMimeMultipart()
0427: throws IllegalStateException {
0428: checkMultipart();
0429: return this .mimeMultipart;
0430: }
0431:
0432: /**
0433: * Determine the default encoding for the given MimeMessage.
0434: * @param mimeMessage the passed-in MimeMessage
0435: * @return the default encoding associated with the MimeMessage,
0436: * or <code>null</code> if none found
0437: */
0438: protected String getDefaultEncoding(MimeMessage mimeMessage) {
0439: if (mimeMessage instanceof SmartMimeMessage) {
0440: return ((SmartMimeMessage) mimeMessage)
0441: .getDefaultEncoding();
0442: }
0443: return null;
0444: }
0445:
0446: /**
0447: * Return the specific character encoding used for this message, if any.
0448: */
0449: public String getEncoding() {
0450: return this .encoding;
0451: }
0452:
0453: /**
0454: * Determine the default Java Activation FileTypeMap for the given MimeMessage.
0455: * @param mimeMessage the passed-in MimeMessage
0456: * @return the default FileTypeMap associated with the MimeMessage,
0457: * or a default ConfigurableMimeFileTypeMap if none found for the message
0458: * @see ConfigurableMimeFileTypeMap
0459: */
0460: protected FileTypeMap getDefaultFileTypeMap(MimeMessage mimeMessage) {
0461: if (mimeMessage instanceof SmartMimeMessage) {
0462: FileTypeMap fileTypeMap = ((SmartMimeMessage) mimeMessage)
0463: .getDefaultFileTypeMap();
0464: if (fileTypeMap != null) {
0465: return fileTypeMap;
0466: }
0467: }
0468: ConfigurableMimeFileTypeMap fileTypeMap = new ConfigurableMimeFileTypeMap();
0469: fileTypeMap.afterPropertiesSet();
0470: return fileTypeMap;
0471: }
0472:
0473: /**
0474: * Set the Java Activation Framework <code>FileTypeMap</code> to use
0475: * for determining the content type of inline content and attachments
0476: * that get added to the message.
0477: * <p>Default is the <code>FileTypeMap</code> that the underlying
0478: * MimeMessage carries, if any, or the Activation Framework's default
0479: * <code>FileTypeMap</code> instance else.
0480: * @see #addInline
0481: * @see #addAttachment
0482: * @see #getDefaultFileTypeMap(javax.mail.internet.MimeMessage)
0483: * @see JavaMailSenderImpl#setDefaultFileTypeMap
0484: * @see javax.activation.FileTypeMap#getDefaultFileTypeMap
0485: * @see ConfigurableMimeFileTypeMap
0486: */
0487: public void setFileTypeMap(FileTypeMap fileTypeMap) {
0488: this .fileTypeMap = (fileTypeMap != null ? fileTypeMap
0489: : getDefaultFileTypeMap(getMimeMessage()));
0490: }
0491:
0492: /**
0493: * Return the <code>FileTypeMap</code> used by this MimeMessageHelper.
0494: */
0495: public FileTypeMap getFileTypeMap() {
0496: return this .fileTypeMap;
0497: }
0498:
0499: /**
0500: * Set whether to validate all addresses which get passed to this helper.
0501: * Default is "false".
0502: * <p>Note that this is by default just available for JavaMail >= 1.3.
0503: * You can override the default <code>validateAddress method</code> for
0504: * validation on older JavaMail versions (or for custom validation).
0505: * @see #validateAddress
0506: */
0507: public void setValidateAddresses(boolean validateAddresses) {
0508: this .validateAddresses = validateAddresses;
0509: }
0510:
0511: /**
0512: * Return whether this helper will validate all addresses passed to it.
0513: */
0514: public boolean isValidateAddresses() {
0515: return this .validateAddresses;
0516: }
0517:
0518: /**
0519: * Validate the given mail address.
0520: * Called by all of MimeMessageHelper's address setters and adders.
0521: * <p>Default implementation invokes <code>InternetAddress.validate()</code>,
0522: * provided that address validation is activated for the helper instance.
0523: * <p>Note that this method will just work on JavaMail >= 1.3. You can override
0524: * it for validation on older JavaMail versions or for custom validation.
0525: * @param address the address to validate
0526: * @throws AddressException if validation failed
0527: * @see #isValidateAddresses()
0528: * @see javax.mail.internet.InternetAddress#validate()
0529: */
0530: protected void validateAddress(InternetAddress address)
0531: throws AddressException {
0532: if (isValidateAddresses()) {
0533: address.validate();
0534: }
0535: }
0536:
0537: /**
0538: * Validate all given mail addresses.
0539: * Default implementation simply delegates to validateAddress for each address.
0540: * @param addresses the addresses to validate
0541: * @throws AddressException if validation failed
0542: * @see #validateAddress(InternetAddress)
0543: */
0544: protected void validateAddresses(InternetAddress[] addresses)
0545: throws AddressException {
0546: for (int i = 0; i < addresses.length; i++) {
0547: validateAddress(addresses[i]);
0548: }
0549: }
0550:
0551: public void setFrom(InternetAddress from) throws MessagingException {
0552: Assert.notNull(from, "From address must not be null");
0553: validateAddress(from);
0554: this .mimeMessage.setFrom(from);
0555: }
0556:
0557: public void setFrom(String from) throws MessagingException {
0558: Assert.notNull(from, "From address must not be null");
0559: setFrom(new InternetAddress(from));
0560: }
0561:
0562: public void setFrom(String from, String personal)
0563: throws MessagingException, UnsupportedEncodingException {
0564: Assert.notNull(from, "From address must not be null");
0565: setFrom(getEncoding() != null ? new InternetAddress(from,
0566: personal, getEncoding()) : new InternetAddress(from,
0567: personal));
0568: }
0569:
0570: public void setReplyTo(InternetAddress replyTo)
0571: throws MessagingException {
0572: Assert.notNull(replyTo, "Reply-to address must not be null");
0573: validateAddress(replyTo);
0574: this .mimeMessage.setReplyTo(new InternetAddress[] { replyTo });
0575: }
0576:
0577: public void setReplyTo(String replyTo) throws MessagingException {
0578: Assert.notNull(replyTo, "Reply-to address must not be null");
0579: setReplyTo(new InternetAddress(replyTo));
0580: }
0581:
0582: public void setReplyTo(String replyTo, String personal)
0583: throws MessagingException, UnsupportedEncodingException {
0584: Assert.notNull(replyTo, "Reply-to address must not be null");
0585: InternetAddress replyToAddress = (getEncoding() != null) ? new InternetAddress(
0586: replyTo, personal, getEncoding())
0587: : new InternetAddress(replyTo, personal);
0588: setReplyTo(replyToAddress);
0589: }
0590:
0591: public void setTo(InternetAddress to) throws MessagingException {
0592: Assert.notNull(to, "To address must not be null");
0593: validateAddress(to);
0594: this .mimeMessage.setRecipient(Message.RecipientType.TO, to);
0595: }
0596:
0597: public void setTo(InternetAddress[] to) throws MessagingException {
0598: Assert.notNull(to, "To address array must not be null");
0599: validateAddresses(to);
0600: this .mimeMessage.setRecipients(Message.RecipientType.TO, to);
0601: }
0602:
0603: public void setTo(String to) throws MessagingException {
0604: Assert.notNull(to, "To address must not be null");
0605: setTo(new InternetAddress(to));
0606: }
0607:
0608: public void setTo(String[] to) throws MessagingException {
0609: Assert.notNull(to, "To address array must not be null");
0610: InternetAddress[] addresses = new InternetAddress[to.length];
0611: for (int i = 0; i < to.length; i++) {
0612: addresses[i] = new InternetAddress(to[i]);
0613: }
0614: setTo(addresses);
0615: }
0616:
0617: public void addTo(InternetAddress to) throws MessagingException {
0618: Assert.notNull(to, "To address must not be null");
0619: validateAddress(to);
0620: this .mimeMessage.addRecipient(Message.RecipientType.TO, to);
0621: }
0622:
0623: public void addTo(String to) throws MessagingException {
0624: Assert.notNull(to, "To address must not be null");
0625: addTo(new InternetAddress(to));
0626: }
0627:
0628: public void addTo(String to, String personal)
0629: throws MessagingException, UnsupportedEncodingException {
0630: Assert.notNull(to, "To address must not be null");
0631: addTo(getEncoding() != null ? new InternetAddress(to, personal,
0632: getEncoding()) : new InternetAddress(to, personal));
0633: }
0634:
0635: public void setCc(InternetAddress cc) throws MessagingException {
0636: Assert.notNull(cc, "Cc address must not be null");
0637: validateAddress(cc);
0638: this .mimeMessage.setRecipient(Message.RecipientType.CC, cc);
0639: }
0640:
0641: public void setCc(InternetAddress[] cc) throws MessagingException {
0642: Assert.notNull(cc, "Cc address array must not be null");
0643: validateAddresses(cc);
0644: this .mimeMessage.setRecipients(Message.RecipientType.CC, cc);
0645: }
0646:
0647: public void setCc(String cc) throws MessagingException {
0648: Assert.notNull(cc, "Cc address must not be null");
0649: setCc(new InternetAddress(cc));
0650: }
0651:
0652: public void setCc(String[] cc) throws MessagingException {
0653: Assert.notNull(cc, "Cc address array must not be null");
0654: InternetAddress[] addresses = new InternetAddress[cc.length];
0655: for (int i = 0; i < cc.length; i++) {
0656: addresses[i] = new InternetAddress(cc[i]);
0657: }
0658: setCc(addresses);
0659: }
0660:
0661: public void addCc(InternetAddress cc) throws MessagingException {
0662: Assert.notNull(cc, "Cc address must not be null");
0663: validateAddress(cc);
0664: this .mimeMessage.addRecipient(Message.RecipientType.CC, cc);
0665: }
0666:
0667: public void addCc(String cc) throws MessagingException {
0668: Assert.notNull(cc, "Cc address must not be null");
0669: addCc(new InternetAddress(cc));
0670: }
0671:
0672: public void addCc(String cc, String personal)
0673: throws MessagingException, UnsupportedEncodingException {
0674: Assert.notNull(cc, "Cc address must not be null");
0675: addCc(getEncoding() != null ? new InternetAddress(cc, personal,
0676: getEncoding()) : new InternetAddress(cc, personal));
0677: }
0678:
0679: public void setBcc(InternetAddress bcc) throws MessagingException {
0680: Assert.notNull(bcc, "Bcc address must not be null");
0681: validateAddress(bcc);
0682: this .mimeMessage.setRecipient(Message.RecipientType.BCC, bcc);
0683: }
0684:
0685: public void setBcc(InternetAddress[] bcc) throws MessagingException {
0686: Assert.notNull(bcc, "Bcc address array must not be null");
0687: validateAddresses(bcc);
0688: this .mimeMessage.setRecipients(Message.RecipientType.BCC, bcc);
0689: }
0690:
0691: public void setBcc(String bcc) throws MessagingException {
0692: Assert.notNull(bcc, "Bcc address must not be null");
0693: setBcc(new InternetAddress(bcc));
0694: }
0695:
0696: public void setBcc(String[] bcc) throws MessagingException {
0697: Assert.notNull(bcc, "Bcc address array must not be null");
0698: InternetAddress[] addresses = new InternetAddress[bcc.length];
0699: for (int i = 0; i < bcc.length; i++) {
0700: addresses[i] = new InternetAddress(bcc[i]);
0701: }
0702: setBcc(addresses);
0703: }
0704:
0705: public void addBcc(InternetAddress bcc) throws MessagingException {
0706: Assert.notNull(bcc, "Bcc address must not be null");
0707: validateAddress(bcc);
0708: this .mimeMessage.addRecipient(Message.RecipientType.BCC, bcc);
0709: }
0710:
0711: public void addBcc(String bcc) throws MessagingException {
0712: Assert.notNull(bcc, "Bcc address must not be null");
0713: addBcc(new InternetAddress(bcc));
0714: }
0715:
0716: public void addBcc(String bcc, String personal)
0717: throws MessagingException, UnsupportedEncodingException {
0718: Assert.notNull(bcc, "Bcc address must not be null");
0719: addBcc(getEncoding() != null ? new InternetAddress(bcc,
0720: personal, getEncoding()) : new InternetAddress(bcc,
0721: personal));
0722: }
0723:
0724: /**
0725: * Set the priority ("X-Priority" header) of the message.
0726: * @param priority the priority value;
0727: * typically between 1 (highest) and 5 (lowest)
0728: * @throws MessagingException in case of errors
0729: */
0730: public void setPriority(int priority) throws MessagingException {
0731: this .mimeMessage.setHeader(HEADER_PRIORITY, Integer
0732: .toString(priority));
0733: }
0734:
0735: /**
0736: * Set the sent-date of the message.
0737: * @param sentDate the date to set (never <code>null</code>)
0738: * @throws MessagingException in case of errors
0739: */
0740: public void setSentDate(Date sentDate) throws MessagingException {
0741: Assert.notNull(sentDate, "Sent date must not be null");
0742: this .mimeMessage.setSentDate(sentDate);
0743: }
0744:
0745: /**
0746: * Set the subject of the message, using the correct encoding.
0747: * @param subject the subject text
0748: * @throws MessagingException in case of errors
0749: */
0750: public void setSubject(String subject) throws MessagingException {
0751: Assert.notNull(subject, "Subject must not be null");
0752: if (getEncoding() != null) {
0753: this .mimeMessage.setSubject(subject, getEncoding());
0754: } else {
0755: this .mimeMessage.setSubject(subject);
0756: }
0757: }
0758:
0759: /**
0760: * Set the given text directly as content in non-multipart mode
0761: * or as default body part in multipart mode.
0762: * Always applies the default content type "text/plain".
0763: * <p><b>NOTE:</b> Invoke {@link #addInline} <i>after</i> <code>setText</code>;
0764: * else, mail readers might not be able to resolve inline references correctly.
0765: * @param text the text for the message
0766: * @throws MessagingException in case of errors
0767: */
0768: public void setText(String text) throws MessagingException {
0769: setText(text, false);
0770: }
0771:
0772: /**
0773: * Set the given text directly as content in non-multipart mode
0774: * or as default body part in multipart mode.
0775: * The "html" flag determines the content type to apply.
0776: * <p><b>NOTE:</b> Invoke {@link #addInline} <i>after</i> <code>setText</code>;
0777: * else, mail readers might not be able to resolve inline references correctly.
0778: * @param text the text for the message
0779: * @param html whether to apply content type "text/html" for an
0780: * HTML mail, using default content type ("text/plain") else
0781: * @throws MessagingException in case of errors
0782: */
0783: public void setText(String text, boolean html)
0784: throws MessagingException {
0785: Assert.notNull(text, "Text must not be null");
0786: MimePart partToUse = null;
0787: if (isMultipart()) {
0788: partToUse = getMainPart();
0789: } else {
0790: partToUse = this .mimeMessage;
0791: }
0792: if (html) {
0793: setHtmlTextToMimePart(partToUse, text);
0794: } else {
0795: setPlainTextToMimePart(partToUse, text);
0796: }
0797: }
0798:
0799: /**
0800: * Set the given plain text and HTML text as alternatives, offering
0801: * both options to the email client. Requires multipart mode.
0802: * <p><b>NOTE:</b> Invoke {@link #addInline} <i>after</i> <code>setText</code>;
0803: * else, mail readers might not be able to resolve inline references correctly.
0804: * @param plainText the plain text for the message
0805: * @param htmlText the HTML text for the message
0806: * @throws MessagingException in case of errors
0807: */
0808: public void setText(String plainText, String htmlText)
0809: throws MessagingException {
0810: Assert.notNull(plainText, "Plain text must not be null");
0811: Assert.notNull(htmlText, "HTML text must not be null");
0812:
0813: MimeMultipart messageBody = new MimeMultipart(
0814: MULTIPART_SUBTYPE_ALTERNATIVE);
0815: getMainPart().setContent(messageBody, CONTENT_TYPE_ALTERNATIVE);
0816:
0817: // Create the plain text part of the message.
0818: MimeBodyPart plainTextPart = new MimeBodyPart();
0819: setPlainTextToMimePart(plainTextPart, plainText);
0820: messageBody.addBodyPart(plainTextPart);
0821:
0822: // Create the HTML text part of the message.
0823: MimeBodyPart htmlTextPart = new MimeBodyPart();
0824: setHtmlTextToMimePart(htmlTextPart, htmlText);
0825: messageBody.addBodyPart(htmlTextPart);
0826: }
0827:
0828: private MimeBodyPart getMainPart() throws MessagingException {
0829: MimeMultipart mimeMultipart = getMimeMultipart();
0830: MimeBodyPart bodyPart = null;
0831: for (int i = 0; i < mimeMultipart.getCount(); i++) {
0832: BodyPart bp = mimeMultipart.getBodyPart(i);
0833: if (bp.getFileName() == null) {
0834: bodyPart = (MimeBodyPart) bp;
0835: }
0836: }
0837: if (bodyPart == null) {
0838: MimeBodyPart mimeBodyPart = new MimeBodyPart();
0839: mimeMultipart.addBodyPart(mimeBodyPart);
0840: bodyPart = mimeBodyPart;
0841: }
0842: return bodyPart;
0843: }
0844:
0845: private void setPlainTextToMimePart(MimePart mimePart, String text)
0846: throws MessagingException {
0847: if (getEncoding() != null) {
0848: mimePart.setText(text, getEncoding());
0849: } else {
0850: mimePart.setText(text);
0851: }
0852: }
0853:
0854: private void setHtmlTextToMimePart(MimePart mimePart, String text)
0855: throws MessagingException {
0856: if (getEncoding() != null) {
0857: mimePart.setContent(text, CONTENT_TYPE_HTML
0858: + CONTENT_TYPE_CHARSET_SUFFIX + getEncoding());
0859: } else {
0860: mimePart.setContent(text, CONTENT_TYPE_HTML);
0861: }
0862: }
0863:
0864: /**
0865: * Add an inline element to the MimeMessage, taking the content from a
0866: * <code>javax.activation.DataSource</code>.
0867: * <p>Note that the InputStream returned by the DataSource implementation
0868: * needs to be a <i>fresh one on each call</i>, as JavaMail will invoke
0869: * <code>getInputStream()</code> multiple times.
0870: * <p><b>NOTE:</b> Invoke <code>addInline</code> <i>after</i> {@link #setText};
0871: * else, mail readers might not be able to resolve inline references correctly.
0872: * @param contentId the content ID to use. Will end up as "Content-ID" header
0873: * in the body part, surrounded by angle brackets: e.g. "myId" -> "<myId>".
0874: * Can be referenced in HTML source via src="cid:myId" expressions.
0875: * @param dataSource the <code>javax.activation.DataSource</code> to take
0876: * the content from, determining the InputStream and the content type
0877: * @throws MessagingException in case of errors
0878: * @see #addInline(String, java.io.File)
0879: * @see #addInline(String, org.springframework.core.io.Resource)
0880: */
0881: public void addInline(String contentId, DataSource dataSource)
0882: throws MessagingException {
0883: Assert.notNull(contentId, "Content ID must not be null");
0884: Assert.notNull(dataSource, "DataSource must not be null");
0885: MimeBodyPart mimeBodyPart = new MimeBodyPart();
0886: mimeBodyPart.setDisposition(MimeBodyPart.INLINE);
0887: // We're using setHeader here to remain compatible with JavaMail 1.2,
0888: // rather than JavaMail 1.3's setContentID.
0889: mimeBodyPart
0890: .setHeader(HEADER_CONTENT_ID, "<" + contentId + ">");
0891: mimeBodyPart.setDataHandler(new DataHandler(dataSource));
0892: getMimeMultipart().addBodyPart(mimeBodyPart);
0893: }
0894:
0895: /**
0896: * Add an inline element to the MimeMessage, taking the content from a
0897: * <code>java.io.File</code>.
0898: * <p>The content type will be determined by the name of the given
0899: * content file. Do not use this for temporary files with arbitrary
0900: * filenames (possibly ending in ".tmp" or the like)!
0901: * <p><b>NOTE:</b> Invoke <code>addInline</code> <i>after</i> {@link #setText};
0902: * else, mail readers might not be able to resolve inline references correctly.
0903: * @param contentId the content ID to use. Will end up as "Content-ID" header
0904: * in the body part, surrounded by angle brackets: e.g. "myId" -> "<myId>".
0905: * Can be referenced in HTML source via src="cid:myId" expressions.
0906: * @param file the File resource to take the content from
0907: * @throws MessagingException in case of errors
0908: * @see #setText
0909: * @see #addInline(String, org.springframework.core.io.Resource)
0910: * @see #addInline(String, javax.activation.DataSource)
0911: */
0912: public void addInline(String contentId, File file)
0913: throws MessagingException {
0914: Assert.notNull(file, "File must not be null");
0915: FileDataSource dataSource = new FileDataSource(file);
0916: dataSource.setFileTypeMap(getFileTypeMap());
0917: addInline(contentId, dataSource);
0918: }
0919:
0920: /**
0921: * Add an inline element to the MimeMessage, taking the content from a
0922: * <code>org.springframework.core.io.Resource</code>.
0923: * <p>The content type will be determined by the name of the given
0924: * content file. Do not use this for temporary files with arbitrary
0925: * filenames (possibly ending in ".tmp" or the like)!
0926: * <p>Note that the InputStream returned by the Resource implementation
0927: * needs to be a <i>fresh one on each call</i>, as JavaMail will invoke
0928: * <code>getInputStream()</code> multiple times.
0929: * <p><b>NOTE:</b> Invoke <code>addInline</code> <i>after</i> {@link #setText};
0930: * else, mail readers might not be able to resolve inline references correctly.
0931: * @param contentId the content ID to use. Will end up as "Content-ID" header
0932: * in the body part, surrounded by angle brackets: e.g. "myId" -> "<myId>".
0933: * Can be referenced in HTML source via src="cid:myId" expressions.
0934: * @param resource the resource to take the content from
0935: * @throws MessagingException in case of errors
0936: * @see #setText
0937: * @see #addInline(String, java.io.File)
0938: * @see #addInline(String, javax.activation.DataSource)
0939: */
0940: public void addInline(String contentId, Resource resource)
0941: throws MessagingException {
0942: Assert.notNull(resource, "Resource must not be null");
0943: String contentType = getFileTypeMap().getContentType(
0944: resource.getFilename());
0945: addInline(contentId, resource, contentType);
0946: }
0947:
0948: /**
0949: * Add an inline element to the MimeMessage, taking the content from an
0950: * <code>org.springframework.core.InputStreamResource</code>, and
0951: * specifying the content type explicitly.
0952: * <p>You can determine the content type for any given filename via a Java
0953: * Activation Framework's FileTypeMap, for example the one held by this helper.
0954: * <p>Note that the InputStream returned by the InputStreamSource implementation
0955: * needs to be a <i>fresh one on each call</i>, as JavaMail will invoke
0956: * <code>getInputStream()</code> multiple times.
0957: * <p><b>NOTE:</b> Invoke <code>addInline</code> <i>after</i> <code>setText</code>;
0958: * else, mail readers might not be able to resolve inline references correctly.
0959: * @param contentId the content ID to use. Will end up as "Content-ID" header
0960: * in the body part, surrounded by angle brackets: e.g. "myId" -> "<myId>".
0961: * Can be referenced in HTML source via src="cid:myId" expressions.
0962: * @param inputStreamSource the resource to take the content from
0963: * @param contentType the content type to use for the element
0964: * @throws MessagingException in case of errors
0965: * @see #setText
0966: * @see #getFileTypeMap
0967: * @see #addInline(String, org.springframework.core.io.Resource)
0968: * @see #addInline(String, javax.activation.DataSource)
0969: */
0970: public void addInline(String contentId,
0971: InputStreamSource inputStreamSource, String contentType)
0972: throws MessagingException {
0973:
0974: Assert.notNull(inputStreamSource,
0975: "InputStreamSource must not be null");
0976: if (inputStreamSource instanceof Resource
0977: && ((Resource) inputStreamSource).isOpen()) {
0978: throw new IllegalArgumentException(
0979: "Passed-in Resource contains an open stream: invalid argument. "
0980: + "JavaMail requires an InputStreamSource that creates a fresh stream for every call.");
0981: }
0982: DataSource dataSource = createDataSource(inputStreamSource,
0983: contentType, "inline");
0984: addInline(contentId, dataSource);
0985: }
0986:
0987: /**
0988: * Add an attachment to the MimeMessage, taking the content from a
0989: * <code>javax.activation.DataSource</code>.
0990: * <p>Note that the InputStream returned by the DataSource implementation
0991: * needs to be a <i>fresh one on each call</i>, as JavaMail will invoke
0992: * <code>getInputStream()</code> multiple times.
0993: * @param attachmentFilename the name of the attachment as it will
0994: * appear in the mail (the content type will be determined by this)
0995: * @param dataSource the <code>javax.activation.DataSource</code> to take
0996: * the content from, determining the InputStream and the content type
0997: * @throws MessagingException in case of errors
0998: * @see #addAttachment(String, org.springframework.core.io.InputStreamSource)
0999: * @see #addAttachment(String, java.io.File)
1000: */
1001: public void addAttachment(String attachmentFilename,
1002: DataSource dataSource) throws MessagingException {
1003: Assert.notNull(attachmentFilename,
1004: "Attachment filename must not be null");
1005: Assert.notNull(dataSource, "DataSource must not be null");
1006: MimeBodyPart mimeBodyPart = new MimeBodyPart();
1007: mimeBodyPart.setDisposition(MimeBodyPart.ATTACHMENT);
1008: mimeBodyPart.setFileName(attachmentFilename);
1009: mimeBodyPart.setDataHandler(new DataHandler(dataSource));
1010: getRootMimeMultipart().addBodyPart(mimeBodyPart);
1011: }
1012:
1013: /**
1014: * Add an attachment to the MimeMessage, taking the content from a
1015: * <code>java.io.File</code>.
1016: * <p>The content type will be determined by the name of the given
1017: * content file. Do not use this for temporary files with arbitrary
1018: * filenames (possibly ending in ".tmp" or the like)!
1019: * @param attachmentFilename the name of the attachment as it will
1020: * appear in the mail
1021: * @param file the File resource to take the content from
1022: * @throws MessagingException in case of errors
1023: * @see #addAttachment(String, org.springframework.core.io.InputStreamSource)
1024: * @see #addAttachment(String, javax.activation.DataSource)
1025: */
1026: public void addAttachment(String attachmentFilename, File file)
1027: throws MessagingException {
1028: Assert.notNull(file, "File must not be null");
1029: FileDataSource dataSource = new FileDataSource(file);
1030: dataSource.setFileTypeMap(getFileTypeMap());
1031: addAttachment(attachmentFilename, dataSource);
1032: }
1033:
1034: /**
1035: * Add an attachment to the MimeMessage, taking the content from an
1036: * <code>org.springframework.core.io.InputStreamResource</code>.
1037: * <p>The content type will be determined by the given filename for
1038: * the attachment. Thus, any content source will be fine, including
1039: * temporary files with arbitrary filenames.
1040: * <p>Note that the InputStream returned by the InputStreamSource
1041: * implementation needs to be a <i>fresh one on each call</i>, as
1042: * JavaMail will invoke <code>getInputStream()</code> multiple times.
1043: * @param attachmentFilename the name of the attachment as it will
1044: * appear in the mail
1045: * @param inputStreamSource the resource to take the content from
1046: * (all of Spring's Resource implementations can be passed in here)
1047: * @throws MessagingException in case of errors
1048: * @see #addAttachment(String, java.io.File)
1049: * @see #addAttachment(String, javax.activation.DataSource)
1050: * @see org.springframework.core.io.Resource
1051: */
1052: public void addAttachment(String attachmentFilename,
1053: InputStreamSource inputStreamSource)
1054: throws MessagingException {
1055:
1056: String contentType = getFileTypeMap().getContentType(
1057: attachmentFilename);
1058: addAttachment(attachmentFilename, inputStreamSource,
1059: contentType);
1060: }
1061:
1062: /**
1063: * Add an attachment to the MimeMessage, taking the content from an
1064: * <code>org.springframework.core.io.InputStreamResource</code>.
1065: * <p>Note that the InputStream returned by the InputStreamSource
1066: * implementation needs to be a <i>fresh one on each call</i>, as
1067: * JavaMail will invoke <code>getInputStream()</code> multiple times.
1068: * @param attachmentFilename the name of the attachment as it will
1069: * appear in the mail
1070: * @param inputStreamSource the resource to take the content from
1071: * (all of Spring's Resource implementations can be passed in here)
1072: * @param contentType the content type to use for the element
1073: * @throws MessagingException in case of errors
1074: * @see #addAttachment(String, java.io.File)
1075: * @see #addAttachment(String, javax.activation.DataSource)
1076: * @see org.springframework.core.io.Resource
1077: */
1078: public void addAttachment(String attachmentFilename,
1079: InputStreamSource inputStreamSource, String contentType)
1080: throws MessagingException {
1081:
1082: Assert.notNull(inputStreamSource,
1083: "InputStreamSource must not be null");
1084: if (inputStreamSource instanceof Resource
1085: && ((Resource) inputStreamSource).isOpen()) {
1086: throw new IllegalArgumentException(
1087: "Passed-in Resource contains an open stream: invalid argument. "
1088: + "JavaMail requires an InputStreamSource that creates a fresh stream for every call.");
1089: }
1090: DataSource dataSource = createDataSource(inputStreamSource,
1091: contentType, attachmentFilename);
1092: addAttachment(attachmentFilename, dataSource);
1093: }
1094:
1095: /**
1096: * Create an Activation Framework DataSource for the given InputStreamSource.
1097: * @param inputStreamSource the InputStreamSource (typically a Spring Resource)
1098: * @param contentType the content type
1099: * @param name the name of the DataSource
1100: * @return the Activation Framework DataSource
1101: */
1102: protected DataSource createDataSource(
1103: final InputStreamSource inputStreamSource,
1104: final String contentType, final String name) {
1105:
1106: return new DataSource() {
1107: public InputStream getInputStream() throws IOException {
1108: return inputStreamSource.getInputStream();
1109: }
1110:
1111: public OutputStream getOutputStream() {
1112: throw new UnsupportedOperationException(
1113: "Read-only javax.activation.DataSource");
1114: }
1115:
1116: public String getContentType() {
1117: return contentType;
1118: }
1119:
1120: public String getName() {
1121: return name;
1122: }
1123: };
1124: }
1125:
1126: }
|