1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.mail.script

File ScriptMimeMessage.java

 

Coverage histogram

../../../../img/srcFileCovDistChart8.png
54% of files have more coverage

Code metrics

6
58
13
1
270
159
25
0.43
4.46
13
1.92

Classes

Class Line # Actions
ScriptMimeMessage 48 58 0% 25 15
0.805194880.5%
 

Contributing tests

This file is covered by 7 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.mail.script;
21   
22    import java.io.IOException;
23    import java.util.Collections;
24    import java.util.HashMap;
25    import java.util.Map;
26   
27    import javax.mail.Address;
28    import javax.mail.BodyPart;
29    import javax.mail.Message;
30    import javax.mail.MessagingException;
31    import javax.mail.Multipart;
32    import javax.mail.internet.MimeMessage;
33    import javax.mail.internet.MimeMultipart;
34   
35    import org.xwiki.component.manager.ComponentLookupException;
36    import org.xwiki.component.manager.ComponentManager;
37    import org.xwiki.component.util.DefaultParameterizedType;
38    import org.xwiki.context.Execution;
39    import org.xwiki.mail.ExtendedMimeMessage;
40    import org.xwiki.mail.MimeBodyPartFactory;
41   
42    /**
43    * Extends {@link javax.mail.internet.MimeMessage} with additional helper methods for scripts.
44    *
45    * @version $Id: 32e11f5f910fc48f43622e27cc8a7d1039ef68aa $
46    * @since 7.1M2
47    */
 
48    public class ScriptMimeMessage extends ExtendedMimeMessage
49    {
50    private ComponentManager componentManager;
51   
52    private Execution execution;
53   
54    /**
55    * @param execution used to get the Execution Context and store an error in it if the send fails
56    * @param componentManager used to dynamically load all {@link MimeBodyPartFactory} components
57    */
58    // Note: This method is package private voluntarily so that it's not part of the API (as this class is public),
59    // since it's only needed by the MailSenderScriptService and nobody else should be able to construct an instance
60    // of it!
 
61  2 toggle ScriptMimeMessage(MimeMessage sourceMessage, Execution execution, ComponentManager componentManager)
62    throws MessagingException
63    {
64  2 super(sourceMessage);
65  2 this.execution = execution;
66  2 this.componentManager = componentManager;
67    }
68   
69    /**
70    * @param execution used to get the Execution Context and store an error in it if the send fails
71    * @param componentManager used to dynamically load all {@link MimeBodyPartFactory} components
72    */
73    // Note: This method is package private voluntarily so that it's not part of the API (as this class is public),
74    // since it's only needed by the MailSenderScriptService and nobody else should be able to construct an instance
75    // of it!
 
76  10 toggle ScriptMimeMessage(Execution execution, ComponentManager componentManager)
77    {
78  10 super();
79  10 this.execution = execution;
80  10 this.componentManager = componentManager;
81    }
82   
83    /**
84    * Add some content to the mail to be sent. Can be called several times to add different content type to the mail.
85    *
86    * @return the Mime Body Part object that was added. Returning it allows script to make modifications to that body
87    * part after it's been set (get/set some headers, etc)
88    * @param mimeType the mime type of the content parameter
89    * @param content the content to include in the mail
90    */
 
91  5 toggle public BodyPart addPart(String mimeType, Object content)
92    {
93  5 return addPart(mimeType, content, Collections.<String, Object>emptyMap());
94    }
95   
96    /**
97    * Add some content to the mail to be sent. Can be called several times to add different content type to the mail.
98    *
99    * @return the Mime Body Part object that was added. Returning it allows script to make modifications to that body
100    * part after it's been set (get/set some headers, etc)
101    * @param mimeType the mime type of the content parameter
102    * @param content the content to include in the mail
103    * @param parameters the list of extra parameters. This is used for example to pass alternate content for the mail
104    * using the {@code alternate} key in the HTML Mime Body Part Factory. Mail headers can also be passed using
105    * the {@code headers} key with a {@code Map&lt;String, String&gt;} value containing header keys and values
106    */
 
107  6 toggle public BodyPart addPart(String mimeType, Object content, Map<String, Object> parameters)
108    {
109  6 BodyPart bodyPart;
110   
111  6 try {
112  6 MimeBodyPartFactory factory = getBodyPartFactory(mimeType, content.getClass());
113   
114    // Pass the mime type in the parameters so that generic Mime Body Part factories can use it.
115    // Note that if the user has already passed a "mimetype" parameter then we don't override it!
116  6 Map<String, Object> enhancedParameters = new HashMap<>();
117  6 enhancedParameters.put("mimetype", mimeType);
118  6 enhancedParameters.putAll(parameters);
119   
120  6 Multipart multipart = getMultipart();
121  6 bodyPart = factory.create(content, enhancedParameters);
122  6 multipart.addBodyPart(bodyPart);
123    } catch (Exception e) {
124    // Save the exception for reporting through the script services's getError() API
125  0 setError(e);
126  0 bodyPart = null;
127    }
128   
129  6 return bodyPart;
130    }
131   
132    /**
133    * @param subject the subject to set in the Mime Message
134    */
 
135  6 toggle @Override
136    public void setSubject(String subject)
137    {
138  6 try {
139  6 super.setSubject(subject);
140    } catch (Exception e) {
141  0 setError(e);
142    }
143    }
144   
145    /**
146    * @param address the address from which this message will be sent
147    */
 
148  7 toggle @Override
149    public void setFrom(Address address)
150    {
151  7 try {
152  7 super.setFrom(address);
153    } catch (Exception e) {
154  0 setError(e);
155    }
156    }
157   
158    /**
159    * @param type the type of recipients (to, cc, bcc, newsgroups)
160    * @param addresses the email addresses of the recipients
161    */
 
162  8 toggle @Override
163    public void addRecipients(Message.RecipientType type, Address[] addresses)
164    {
165  8 try {
166  8 super.addRecipients(type, addresses);
167    } catch (Exception e) {
168  0 setError(e);
169    }
170    }
171   
172    /**
173    * @param type the type of recipient (to, cc, bcc, newsgroups)
174    * @param address the email address of the recipient
175    */
 
176  1 toggle @Override
177    public void addRecipient(Message.RecipientType type, Address address)
178    {
179  1 try {
180  1 super.addRecipient(type, address);
181    } catch (Exception e) {
182  0 setError(e);
183    }
184    }
185   
186    /**
187    * Add a mail header.
188    *
189    * @param name the header's name (eg "Message-Id")
190    * @param value the header's value
191    */
 
192  3 toggle @Override
193    public void addHeader(String name, String value)
194    {
195  3 try {
196  3 super.addHeader(name, value);
197    } catch (Exception e) {
198  0 setError(e);
199    }
200    }
201   
 
202  0 toggle private void setError(Exception e)
203    {
204  0 this.execution.getContext().setProperty(MailSenderScriptService.ERROR_KEY, e);
205    }
206   
 
207  6 toggle private MimeBodyPartFactory getBodyPartFactory(String mimeType, Class contentClass) throws MessagingException
208    {
209  6 MimeBodyPartFactory factory;
210  6 try {
211    // Look for a specific MimeBodyPartFactory for the passed Mime Type and Content type.
212  6 factory = getSpecificBodyPartFactory(mimeType, contentClass);
213    } catch (ComponentLookupException e) {
214    // No factory found for the passed Mime Type and type of Content.
215    // If the content class is of type String then we default to the default MimeBodyPartFactory for String
216    // content.
217  6 if (String.class.isAssignableFrom(contentClass)) {
218  6 try {
219  6 factory = this.componentManager.getInstance(
220    new DefaultParameterizedType(null, MimeBodyPartFactory.class, String.class));
221    } catch (ComponentLookupException eee) {
222    // This shouldn't happen, if it does then it's an error and we want that error to bubble up till
223    // the user since it would be pretty bad to send an email with some missing body part!
224  0 throw new MessagingException(String.format(
225    "Failed to find default Mime Body Part Factory for mime type [%s] and Content type [%s]",
226    mimeType, contentClass.getName()), e);
227    }
228    } else {
229  0 throw new MessagingException(String.format(
230    "Failed to a Mime Body Part Factory matching the mime type [%s] and the Content type [%s]",
231    mimeType, contentClass.getName()), e);
232    }
233    }
234  6 return factory;
235    }
236   
 
237  6 toggle private MimeBodyPartFactory getSpecificBodyPartFactory(String mimeType, Class contentClass)
238    throws ComponentLookupException
239    {
240  6 MimeBodyPartFactory factory;
241  6 try {
242    // Look a secure version of a specific MimeBodyPartFactory for the passed Mime Type and Content type.
243  6 factory = this.componentManager.getInstance(new DefaultParameterizedType(null, MimeBodyPartFactory.class,
244    contentClass), String.format("%s/secure", mimeType));
245    } catch (ComponentLookupException e) {
246    // Look for a specific MimeBodyPartFactory for the passed Mime Type and Content type (non secure).
247  6 factory = this.componentManager.getInstance(
248    new DefaultParameterizedType(null, MimeBodyPartFactory.class, contentClass), mimeType);
249    }
250  0 return factory;
251    }
252   
 
253  6 toggle private Multipart getMultipart() throws MessagingException, IOException
254    {
255  6 Multipart multipart;
256  6 if (isEmpty()) {
257  5 multipart = new MimeMultipart("mixed");
258  5 setContent(multipart);
259    } else {
260  1 Object contentObject = getContent();
261  1 if (contentObject instanceof Multipart) {
262  1 multipart = (Multipart) contentObject;
263    } else {
264  0 throw new MessagingException(String.format("Unknown mail content type [%s]: [%s]",
265    contentObject.getClass().getName(), contentObject));
266    }
267    }
268  6 return multipart;
269    }
270    }