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

File MailStorageScriptService.java

 

Coverage histogram

../../../../img/srcFileCovDistChart6.png
69% of files have more coverage

Code metrics

8
50
10
1
275
146
20
0.4
5
10
2

Classes

Class Line # Actions
MailStorageScriptService 57 50 0% 20 29
0.573529457.4%
 

Contributing tests

This file is covered by 4 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.HashMap;
25    import java.util.List;
26    import java.util.Map;
27   
28    import javax.inject.Inject;
29    import javax.inject.Named;
30    import javax.inject.Provider;
31    import javax.inject.Singleton;
32    import javax.mail.Session;
33    import javax.mail.internet.MimeMessage;
34   
35    import org.xwiki.component.annotation.Component;
36    import org.xwiki.component.manager.ComponentLookupException;
37    import org.xwiki.mail.MailContentStore;
38    import org.xwiki.mail.MailListener;
39    import org.xwiki.mail.MailStatus;
40    import org.xwiki.mail.MailStatusStore;
41    import org.xwiki.mail.MailStorageConfiguration;
42    import org.xwiki.mail.MailStoreException;
43    import org.xwiki.security.authorization.ContextualAuthorizationManager;
44    import org.xwiki.security.authorization.Right;
45   
46    import com.xpn.xwiki.XWikiContext;
47   
48    /**
49    * Expose Mail Storage API to scripts.
50    *
51    * @version $Id: 3a882b09d78d58f981cc38da6c63f46c3f9f17e5 $
52    * @since 6.4M3
53    */
54    @Component
55    @Named("mailstorage")
56    @Singleton
 
57    public class MailStorageScriptService extends AbstractMailScriptService
58    {
59    /**
60    * The key under which the last encountered error is stored in the current execution context.
61    */
62    private static final String ERROR_KEY = "scriptservice.mailstorage.error";
63   
64    private static final String SESSION_BATCHID_KEY = "xwiki.batchId";
65   
66    @Inject
67    @Named("filesystem")
68    private MailContentStore mailContentStore;
69   
70    @Inject
71    @Named("database")
72    private MailStatusStore mailStatusStore;
73   
74    @Inject
75    private Provider<XWikiContext> xwikiContextProvider;
76   
77    @Inject
78    private ContextualAuthorizationManager authorizationManager;
79   
80    @Inject
81    private MailStorageConfiguration storageConfiguration;
82   
83    /**
84    * Resend the serialized MimeMessage synchronously.
85    *
86    * @param batchId the name of the directory that contains serialized MimeMessage
87    * @param uniqueMessageId the unique id of the serialized MimeMessage
88    * @return the result and status of the send batch
89    */
 
90  3 toggle public ScriptMailResult resend(String batchId, String uniqueMessageId)
91    {
92    // Note: We don't need to check permissions since the caller already needs to know the batch id and mail id
93    // to be able to call this method and for it to have any effect.
94   
95  3 MailListener listener;
96  3 try {
97  3 listener = this.componentManagerProvider.get().getInstance(MailListener.class, "database");
98    } catch (ComponentLookupException e) {
99    // Save the exception for reporting through the script services's getLastError() API
100  1 setError(e);
101    // Don't send the mail!
102  1 return null;
103    }
104   
105  2 MimeMessage message;
106  2 try {
107    // Set the batch id so that no new batch id is generated when re-sending the mail
108  2 Session session = this.sessionFactory.create(Collections.singletonMap(SESSION_BATCHID_KEY, batchId));
109   
110  2 message = loadMessage(session, batchId, uniqueMessageId);
111   
112  1 ScriptMailResult scriptMailResult = new ScriptMailResult(this.mailSender.sendAsynchronously(
113    Arrays.asList(message), session, listener), listener.getMailStatusResult());
114   
115    // Wait for all messages from this batch to have been sent before returning
116  1 scriptMailResult.getStatusResult().waitTillProcessed(Long.MAX_VALUE);
117   
118  1 return scriptMailResult;
119    } catch (MailStoreException e) {
120    // Save the exception for reporting through the script services's getLastError() API
121  1 setError(e);
122  1 return null;
123    }
124    }
125   
126    /**
127    * Load message status for the message matching the given message Id.
128    *
129    * @param uniqueMessageId the unique identifier of the message.
130    * @return the loaded {@link org.xwiki.mail.MailStatus} or null if not allowed or an error happens
131    * @since 7.1M2
132    */
 
133  0 toggle public MailStatus load(String uniqueMessageId)
134    {
135    // Note: We don't need to check permissions since the caller already needs to know the message id
136    // to be able to call this method and for it to have any effect.
137   
138  0 try {
139  0 return this.mailStatusStore.load(uniqueMessageId);
140    } catch (MailStoreException e) {
141    // Save the exception for reporting through the script services's getLastError() API
142  0 setError(e);
143  0 return null;
144    }
145    }
146   
147    /**
148    * Loads all message statuses matching the passed filters.
149    *
150    * @param filterMap the map of Mail Status parameters to match (e.g. "status", "wiki", "batchId", etc)
151    * @param offset the number of rows to skip (0 means don't skip any row)
152    * @param count the number of rows to return. If 0 then all rows are returned
153    * @param sortField the name of the field used to order returned status
154    * @param sortAscending when true, sort is done in ascending order of sortField, else in descending order
155    * @return the loaded {@link org.xwiki.mail.MailStatus} instances or null if not allowed or an error happens
156    * @since 7.1M2
157    */
 
158  15 toggle public List<MailStatus> load(Map<String, Object> filterMap, int offset, int count, String sortField,
159    boolean sortAscending)
160    {
161    // Only admins are allowed
162  15 if (this.authorizationManager.hasAccess(Right.ADMIN)) {
163  14 try {
164  14 return this.mailStatusStore.load(normalizeFilterMap(filterMap), offset, count,
165    sortField, sortAscending);
166    } catch (MailStoreException e) {
167    // Save the exception for reporting through the script services's getLastError() API
168  0 setError(e);
169  0 return null;
170    }
171    } else {
172    // Save the exception for reporting through the script services's getLastError() API
173  1 setError(new MailStoreException("You need Admin rights to load mail statuses"));
174  1 return null;
175    }
176    }
177   
178    /**
179    * Count the number of message statuses matching the passed filters.
180    *
181    * @param filterMap the map of Mail Status parameters to match (e.g. "status", "wiki", "batchId", etc)
182    * @return the number of mail statuses or 0 if not allowed or an error happens
183    */
 
184  14 toggle public long count(Map<String, Object> filterMap)
185    {
186    // Only admins are allowed
187  14 if (this.authorizationManager.hasAccess(Right.ADMIN)) {
188  14 try {
189  14 return this.mailStatusStore.count(normalizeFilterMap(filterMap));
190    } catch (MailStoreException e) {
191    // Save the exception for reporting through the script services's getLastError() API
192  0 setError(e);
193  0 return 0;
194    }
195    } else {
196    // Save the exception for reporting through the script services's getLastError() API
197  0 setError(new MailStoreException("You need Admin rights to count mail statuses"));
198  0 return 0;
199    }
200    }
201   
202    /**
203    * Delete all messages from a batch (both the statuses in the database and the serialized messages on the file
204    * system).
205    *
206    * @param batchId the id of the batch for which to delete all messages
207    */
 
208  0 toggle public void delete(String batchId)
209    {
210    // Note: We don't need to check permissions since the caller already needs to know the batch id and mail id
211    // to be able to call this method and for it to have any effect.
212   
213  0 Map<String, Object> filterMap = Collections.<String, Object>singletonMap("batchId", batchId);
214  0 List<MailStatus> statuses = load(filterMap, 0, 0, null, false);
215  0 if (statuses != null) {
216  0 for (MailStatus status : statuses) {
217  0 delete(batchId, status.getMessageId());
218    }
219    }
220    }
221   
222    /**
223    * Delete a message (both the status in the database and the serialized messages on the file system).
224    *
225    * @param batchId the id of the batch for the message to delete
226    * @param uniqueMessageId the unique id of the message to delete
227    */
 
228  0 toggle public void delete(String batchId, String uniqueMessageId)
229    {
230    // Note: We don't need to check permissions since the caller already needs to know the batch id and mail id
231    // to be able to call this method and for it to have any effect.
232   
233  0 try {
234    // Step 1: Delete mail status from store
235  0 this.mailStatusStore.delete(uniqueMessageId, Collections.<String, Object>emptyMap());
236    // Step 2: Delete any matching serialized mail
237  0 this.mailContentStore.delete(batchId, uniqueMessageId);
238    } catch (MailStoreException e) {
239    // Save the exception for reporting through the script services's getLastError() API
240  0 setError(e);
241    }
242    }
243   
244    /**
245    * @return the configuration for the Mail Storage
246    */
 
247  0 toggle public MailStorageConfiguration getConfiguration()
248    {
249  0 return this.storageConfiguration;
250    }
251   
 
252  28 toggle private Map<String, Object> normalizeFilterMap(Map<String, Object> filterMap)
253    {
254    // Force the wiki to be the current wiki to prevent any subwiki to see the list of mail statuses from other
255    // wikis
256  28 Map<String, Object> normalizedMap = new HashMap<>(filterMap);
257  28 XWikiContext xwikiContext = this.xwikiContextProvider.get();
258  28 if (!xwikiContext.isMainWiki()) {
259  0 normalizedMap.put("wiki", xwikiContext.getWikiId());
260    }
261  28 return normalizedMap;
262    }
263   
 
264  2 toggle private MimeMessage loadMessage(Session session, String batchId, String mailId) throws MailStoreException
265    {
266  2 MimeMessage message = this.mailContentStore.load(session, batchId, mailId);
267  1 return message;
268    }
269   
 
270  6 toggle @Override
271    protected String getErrorKey()
272    {
273  6 return ERROR_KEY;
274    }
275    }