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

File MailSenderScriptService.java

 

Coverage histogram

../../../../img/srcFileCovDistChart7.png
64% of files have more coverage

Code metrics

4
47
14
1
290
130
21
0.45
3.36
14
1.5

Classes

Class Line # Actions
MailSenderScriptService 60 47 0% 21 19
0.707692370.8%
 

Contributing tests

This file is covered by 2 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.util.Arrays;
23    import java.util.Collections;
24    import java.util.Iterator;
25    import java.util.Map;
26   
27    import javax.inject.Named;
28    import javax.inject.Singleton;
29    import javax.mail.Message;
30    import javax.mail.MessagingException;
31    import javax.mail.internet.InternetAddress;
32    import javax.mail.internet.MimeMessage;
33   
34    import org.xwiki.component.annotation.Component;
35    import org.xwiki.component.manager.ComponentLookupException;
36    import org.xwiki.component.util.DefaultParameterizedType;
37    import org.xwiki.mail.MailListener;
38    import org.xwiki.mail.MailSenderConfiguration;
39    import org.xwiki.mail.MimeMessageFactory;
40    import org.xwiki.mail.internal.script.MimeMessageFactoryProvider;
41   
42    /**
43    * Expose Mail Sending API to scripts.
44    * <p>
45    * Example for sending an HTML message with attachments and a text
46    * alternative:
47    * <pre><code>
48    * #set ($message = $services.mailSender.createMessage(to, subject))
49    * #set ($discard = $message.addPart("html", "html message", {"alternate" : "text message",
50    * "attachments" : $attachments}))
51    * #set ($mailResult = $services.mailsender.send($message))
52    * </code></pre>
53    *
54    * @version $Id: 5701ae00f983187a1dc45c5029bdb76a2dd8f3b4 $
55    * @since 6.1M2
56    */
57    @Component
58    @Named("mailsender")
59    @Singleton
 
60    public class MailSenderScriptService extends AbstractMailScriptService
61    {
62    /**
63    * The key under which the last encountered error is stored in the current execution context.
64    */
65    static final String ERROR_KEY = "scriptservice.mailsender.error";
66   
67    /**
68    * Creates a pre-filled Mime Message by running the Component implementation of {@link
69    * org.xwiki.mail.MimeMessageFactory} corresponding to the passed hint.
70    *
71    * @param hint the component hint of a {@link org.xwiki.mail.MimeMessageFactory} component
72    * @param source the source from which to prefill the Mime Message (depends on the implementation)
73    * @param parameters an optional generic list of parameters. The supported parameters depend on the implementation
74    * @return the pre-filled Mime Message wrapped in a {@link ScriptMimeMessage} instance
75    */
 
76  2 toggle public ScriptMimeMessage createMessage(String hint, Object source, Map<String, Object> parameters)
77    {
78  2 ScriptMimeMessage result;
79  2 try {
80  2 MimeMessageFactory<MimeMessage> factory = MimeMessageFactoryProvider.get(hint, MimeMessage.class,
81    this.componentManagerProvider.get());
82   
83  2 MimeMessage message = factory.createMessage(source, parameters);
84  2 result = new ScriptMimeMessage(message, this.execution, this.componentManagerProvider.get());
85    } catch (Exception e) {
86    // No factory found, set an error
87    // An error occurred, save it and return null
88  0 setError(e);
89  0 return null;
90    }
91   
92  2 return result;
93    }
94   
95    /**
96    * Construct an iterator of Mime Messages by running the Component implementation of {@link
97    * org.xwiki.mail.MimeMessageFactory} corresponding to the passed hint.
98    *
99    * @param hint the component hint of a {@link org.xwiki.mail.MimeMessageFactory} component
100    * @param source the source from which to prefill the Mime Messages (depends on the implementation)
101    * @return the pre-filled Mime Message iterator
102    */
 
103  0 toggle public Iterator<MimeMessage> createMessages(String hint, Object source)
104    {
105  0 return createMessages(hint, source, Collections.<String, Object>emptyMap());
106    }
107   
108    /**
109    * Construct an iterator of Mime Messages by running the Component implementation of {@link
110    * org.xwiki.mail.MimeMessageFactory} corresponding to the passed hint.
111    *
112    * @param hint the component hint of a {@link org.xwiki.mail.MimeMessageFactory} component
113    * @param source the source from which to prefill the Mime Messages (depends on the implementation)
114    * @param parameters an optional generic list of parameters. The supported parameters depend on the implementation
115    * @return the pre-filled Mime Message iterator
116    */
 
117  1 toggle public Iterator<MimeMessage> createMessages(String hint, Object source, Map<String, Object> parameters)
118    {
119  1 Iterator<MimeMessage> result;
120  1 try {
121  1 MimeMessageFactory<Iterator<MimeMessage>> factory = MimeMessageFactoryProvider.get(hint,
122    new DefaultParameterizedType(null, Iterator.class, MimeMessage.class),
123    this.componentManagerProvider.get());
124  1 result = factory.createMessage(source, parameters);
125    } catch (Exception e) {
126    // No factory found or error in constructing the message iterator, set an error
127    // An error occurred, save it and return null
128  0 setError(e);
129  0 return null;
130    }
131   
132  1 return result;
133    }
134   
135    /**
136    * Creates a pre-filled Mime Message by running the Component implementation of {@link
137    * org.xwiki.mail.MimeMessageFactory} corresponding to the passed hint.
138    *
139    * @param hint the component hint of a {@link org.xwiki.mail.MimeMessageFactory} component
140    * @param source the source from which to prefill the Mime Message (depends on the implementation)
141    * @return the pre-filled Mime Message wrapped in a {@link ScriptMimeMessage} instance
142    */
 
143  0 toggle public ScriptMimeMessage createMessage(String hint, Object source)
144    {
145  0 return createMessage(hint, source, Collections.<String, Object>emptyMap());
146    }
147   
148    /**
149    * Create an empty Mail message. The user of this API needs to set the recipients, the subject, and the message
150    * content (aka Parts) before sending the mail. Note that if not specified, the "From" sender name will be taken
151    * from the Mail Sender Configuration.
152    *
153    * @return the created Body Part or null if an error happened
154    */
 
155  0 toggle public ScriptMimeMessage createMessage()
156    {
157  0 return createMessage(null, null, (String) null);
158    }
159   
160    /**
161    * Create a Mail message with the "To" recipient and the mail subject set. The user of this API needs to set the
162    * message content (aka Parts) before sending the mail. Note that the "From" sender name is taken from the Mail
163    * Sender Configuration.
164    *
165    * @param to the "To" email address
166    * @param subject the subject of the mail to send
167    * @return the created Body Part or null if an error happened
168    */
 
169  4 toggle public ScriptMimeMessage createMessage(String to, String subject)
170    {
171  4 return createMessage(this.senderConfiguration.getFromAddress(), to, subject);
172    }
173   
174    /**
175    * Create a Mail message with the "To" recipient and the mail subject set. The user of this API needs to set the
176    * message content (aka Parts) before sending the mail. Note that the "From" sender name from the Mail Sender
177    * Configuration is overridden by the passed "From" parameter.
178    *
179    * @param from the email address of the sender
180    * @param to the "To" email address
181    * @param subject the subject of the mail to send
182    * @return the created Body Part or null if an error happened
183    */
 
184  5 toggle public ScriptMimeMessage createMessage(String from, String to, String subject)
185    {
186  5 ScriptMimeMessage scriptMessage = new ScriptMimeMessage(this.execution, this.componentManagerProvider.get());
187   
188  5 try {
189  5 if (from != null) {
190  5 scriptMessage.setFrom(InternetAddress.parse(from)[0]);
191    }
192  5 if (to != null) {
193  5 scriptMessage.addRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
194    }
195  5 scriptMessage.setSubject(subject);
196    } catch (Exception e) {
197    // An error occurred, save it and return null
198  0 setError(e);
199  0 return null;
200    }
201   
202  5 return scriptMessage;
203    }
204   
205    /**
206    * Send one mail synchronously with Memory MailListener .
207    *
208    * @param message the message that was tried to be sent
209    * @return the result and status of the send batch
210    */
 
211  0 toggle public ScriptMailResult send(MimeMessage message)
212    {
213  0 return send(Arrays.asList(message));
214    }
215   
216    /**
217    * Send the list of mails synchronously, using a Memory {@link }MailListener} to store the results.
218    *
219    * @param messages the list of messages to send
220    * @return the result and status of the send batch
221    */
 
222  1 toggle public ScriptMailResult send(Iterable<? extends MimeMessage> messages)
223    {
224  1 return send(messages, "memory");
225    }
226   
227    /**
228    * Send the mail synchronously (wait till the message is sent). Any error can be retrieved by using the
229    * returned {@link ScriptMailResult}.
230    *
231    * @param messages the list of messages to send
232    * @param hint the component hint of a {@link org.xwiki.mail.MailListener} component
233    * @return the result and status of the send batch
234    */
 
235  5 toggle public ScriptMailResult send(Iterable<? extends MimeMessage> messages, String hint)
236    {
237  5 ScriptMailResult scriptMailResult = sendAsynchronously(messages, hint);
238   
239    // Wait for all messages from this batch to have been sent before returning
240  5 scriptMailResult.getStatusResult().waitTillProcessed(Long.MAX_VALUE);
241   
242  5 return scriptMailResult;
243    }
244   
245    /**
246    * Send the mail asynchronously.
247    *
248    * @param messages the list of messages that was tried to be sent
249    * @param hint the component hint of a {@link org.xwiki.mail.MailListener} component
250    * @return the result and status of the send batch
251    */
 
252  6 toggle public ScriptMailResult sendAsynchronously(Iterable<? extends MimeMessage> messages, String hint)
253    {
254  6 final MailListener listener;
255  6 try {
256  6 listener = getListener(hint);
257    } catch (MessagingException e) {
258    // Save the exception for reporting through the script services's getLastError() API
259  0 setError(e);
260    // Don't send the mail!
261  0 return null;
262    }
263  6 return sendAsynchronously(messages, listener, true);
264    }
265   
 
266  6 toggle private MailListener getListener(String hint) throws MessagingException
267    {
268  6 MailListener listener;
269  6 try {
270  6 listener = this.componentManagerProvider.get().getInstance(MailListener.class, hint);
271    } catch (ComponentLookupException e) {
272  0 throw new MessagingException(String.format("Failed to locate [%s] Event listener. ", hint), e);
273    }
274  6 return listener;
275    }
276   
277    /**
278    * @return the configuration for sending mails (SMTP host, port, etc)
279    */
 
280  2 toggle public MailSenderConfiguration getConfiguration()
281    {
282  2 return this.senderConfiguration;
283    }
284   
 
285  6 toggle @Override
286    protected String getErrorKey()
287    {
288  6 return ERROR_KEY;
289    }
290    }