1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
8 |
|
|
9 |
|
|
10 |
|
|
11 |
|
|
12 |
|
|
13 |
|
|
14 |
|
|
15 |
|
|
16 |
|
|
17 |
|
|
18 |
|
|
19 |
|
|
20 |
|
package org.xwiki.watchlist.internal.notification; |
21 |
|
|
22 |
|
import java.util.ArrayList; |
23 |
|
import java.util.Collections; |
24 |
|
import java.util.HashSet; |
25 |
|
import java.util.Iterator; |
26 |
|
import java.util.List; |
27 |
|
import java.util.Map; |
28 |
|
import java.util.Set; |
29 |
|
|
30 |
|
import javax.mail.Message; |
31 |
|
import javax.mail.MessagingException; |
32 |
|
import javax.mail.Session; |
33 |
|
import javax.mail.internet.InternetAddress; |
34 |
|
import javax.mail.internet.MimeMessage; |
35 |
|
|
36 |
|
import org.apache.commons.codec.digest.DigestUtils; |
37 |
|
import org.xwiki.mail.MimeMessageFactory; |
38 |
|
import org.xwiki.mail.SessionFactory; |
39 |
|
import org.xwiki.model.reference.DocumentReference; |
40 |
|
import org.xwiki.model.reference.EntityReferenceSerializer; |
41 |
|
import org.xwiki.watchlist.internal.UserAvatarAttachmentExtractor; |
42 |
|
import org.xwiki.watchlist.internal.api.WatchListEvent; |
43 |
|
|
44 |
|
import com.xpn.xwiki.api.Attachment; |
45 |
|
|
46 |
|
|
47 |
|
@link@link |
48 |
|
|
49 |
|
@version |
50 |
|
@since |
51 |
|
|
|
|
| 85.7% |
Uncovered Elements: 12 (84) |
Complexity: 16 |
Complexity Density: 0.25 |
|
52 |
|
public class WatchListEventMimeMessageIterator implements Iterator<MimeMessage>, Iterable<MimeMessage> |
53 |
|
{ |
54 |
|
|
55 |
|
|
56 |
|
|
57 |
|
public static final String XWIKI_USER_CLASS_FIRST_NAME_PROP = "first_name"; |
58 |
|
|
59 |
|
|
60 |
|
|
61 |
|
|
62 |
|
public static final String XWIKI_USER_CLASS_LAST_NAME_PROP = "last_name"; |
63 |
|
|
64 |
|
|
65 |
|
|
66 |
|
|
67 |
|
public static final String SUBSCRIBER_REFERENCE = "subscriberReference"; |
68 |
|
|
69 |
|
|
70 |
|
|
71 |
|
|
72 |
|
public static final String TEMPLATE_FACTORY_ATTACHMENTS_PARAMETER = "attachments"; |
73 |
|
|
74 |
|
private MimeMessageFactory<MimeMessage> factory; |
75 |
|
|
76 |
|
private Iterator<WatchListMessageData> subscriberIterator; |
77 |
|
|
78 |
|
private Map<String, Object> parameters; |
79 |
|
|
80 |
|
private Map<String, Object> factoryParameters; |
81 |
|
|
82 |
|
private UserAvatarAttachmentExtractor avatarExtractor; |
83 |
|
|
84 |
|
private List<Attachment> originalTemplateExtraParameters; |
85 |
|
|
86 |
|
private EntityReferenceSerializer<String> serializer; |
87 |
|
|
88 |
|
private SessionFactory sessionFactory; |
89 |
|
|
90 |
|
|
91 |
|
@param |
92 |
|
@link |
93 |
|
@param |
94 |
|
@param |
95 |
|
@param@link |
96 |
|
|
97 |
|
@param@link |
98 |
|
@param |
99 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (8) |
Complexity: 1 |
Complexity Density: 0.12 |
|
100 |
30 |
public WatchListEventMimeMessageIterator(Iterator<WatchListMessageData> subscriberIterator,... |
101 |
|
MimeMessageFactory<MimeMessage> factory, Map<String, Object> parameters, |
102 |
|
UserAvatarAttachmentExtractor avatarExtractor, EntityReferenceSerializer<String> serializer, |
103 |
|
SessionFactory sessionFactory) |
104 |
|
{ |
105 |
30 |
this.subscriberIterator = subscriberIterator; |
106 |
30 |
this.factory = factory; |
107 |
30 |
this.parameters = parameters; |
108 |
30 |
this.avatarExtractor = avatarExtractor; |
109 |
30 |
this.serializer = serializer; |
110 |
30 |
this.sessionFactory = sessionFactory; |
111 |
|
|
112 |
30 |
this.factoryParameters = |
113 |
|
(Map<String, Object>) this.parameters.get(WatchListEventMimeMessageFactory.PARAMETERS_PARAMETER); |
114 |
|
|
115 |
|
|
116 |
|
|
117 |
30 |
this.originalTemplateExtraParameters = |
118 |
|
(List<Attachment>) this.factoryParameters.get(TEMPLATE_FACTORY_ATTACHMENTS_PARAMETER); |
119 |
|
} |
120 |
|
|
|
|
| 0% |
Uncovered Elements: 1 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
121 |
0 |
@Override... |
122 |
|
public Iterator<MimeMessage> iterator() |
123 |
|
{ |
124 |
0 |
return this; |
125 |
|
} |
126 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
127 |
32 |
@Override... |
128 |
|
public boolean hasNext() |
129 |
|
{ |
130 |
32 |
return this.subscriberIterator.hasNext(); |
131 |
|
} |
132 |
|
|
|
|
| 90% |
Uncovered Elements: 1 (10) |
Complexity: 2 |
Complexity Density: 0.2 |
|
133 |
2 |
@Override... |
134 |
|
public MimeMessage next() |
135 |
|
{ |
136 |
2 |
MimeMessage message; |
137 |
2 |
WatchListMessageData watchListMessageData = this.subscriberIterator.next(); |
138 |
|
|
139 |
2 |
try { |
140 |
|
|
141 |
2 |
updateFactoryParameters(factoryParameters, watchListMessageData); |
142 |
|
|
143 |
2 |
DocumentReference factorySource = watchListMessageData.getTemplateReference(); |
144 |
|
|
145 |
|
|
146 |
2 |
message = this.factory.createMessage(factorySource, factoryParameters); |
147 |
2 |
message.addRecipient(Message.RecipientType.TO, watchListMessageData.getAddress()); |
148 |
|
|
149 |
|
|
150 |
2 |
message = setConversationHeaders(message, watchListMessageData); |
151 |
|
} catch (MessagingException e) { |
152 |
0 |
throw new RuntimeException("Failed to create Mime Message, aborting mail sending for this batch", e); |
153 |
|
} |
154 |
|
|
155 |
2 |
return message; |
156 |
|
} |
157 |
|
|
158 |
|
|
159 |
|
|
160 |
|
|
161 |
|
@param |
162 |
|
@param |
163 |
|
|
|
|
| 94.4% |
Uncovered Elements: 1 (18) |
Complexity: 3 |
Complexity Density: 0.21 |
|
164 |
2 |
private void updateFactoryParameters(Map<String, Object> factoryParameters,... |
165 |
|
WatchListMessageData watchListMessageData) |
166 |
|
{ |
167 |
2 |
Map<String, Object> velocityVariables = (Map<String, Object>) factoryParameters.get("velocityVariables"); |
168 |
|
|
169 |
|
|
170 |
2 |
List<WatchListEvent> events = watchListMessageData.getEvents(); |
171 |
2 |
velocityVariables.put("events", events); |
172 |
|
|
173 |
|
|
174 |
2 |
List<String> modifiedDocuments = new ArrayList<>(); |
175 |
2 |
for (WatchListEvent event : events) { |
176 |
3 |
if (!modifiedDocuments.contains(event.getPrefixedFullName())) { |
177 |
3 |
modifiedDocuments.add(event.getPrefixedFullName()); |
178 |
|
} |
179 |
|
} |
180 |
2 |
velocityVariables.put("modifiedDocuments", modifiedDocuments); |
181 |
|
|
182 |
2 |
velocityVariables.put(XWIKI_USER_CLASS_FIRST_NAME_PROP, watchListMessageData.getFirstName()); |
183 |
2 |
velocityVariables.put(XWIKI_USER_CLASS_LAST_NAME_PROP, watchListMessageData.getLastName()); |
184 |
2 |
velocityVariables.put(SUBSCRIBER_REFERENCE, watchListMessageData.getUserReference()); |
185 |
|
|
186 |
|
|
187 |
2 |
if (parameters.get(WatchListEventMimeMessageFactory.ATTACH_AUTHOR_AVATARS_PARAMETER) == Boolean.TRUE) { |
188 |
1 |
List<Attachment> templateExtraAttachments = getTemplateExtraAttachments(factoryParameters, events); |
189 |
1 |
factoryParameters.put(TEMPLATE_FACTORY_ATTACHMENTS_PARAMETER, templateExtraAttachments); |
190 |
|
} |
191 |
|
|
192 |
|
} |
193 |
|
|
|
|
| 77.8% |
Uncovered Elements: 4 (18) |
Complexity: 4 |
Complexity Density: 0.33 |
|
194 |
1 |
private List<Attachment> getTemplateExtraAttachments(Map<String, Object> factoryParameters,... |
195 |
|
List<WatchListEvent> events) |
196 |
|
{ |
197 |
|
|
198 |
1 |
List<Attachment> templateExtraAttachments = new ArrayList<>(); |
199 |
1 |
if (originalTemplateExtraParameters != null) { |
200 |
0 |
templateExtraAttachments.addAll(originalTemplateExtraParameters); |
201 |
|
} |
202 |
|
|
203 |
1 |
Set<DocumentReference> processedAuthors = new HashSet<DocumentReference>(); |
204 |
1 |
for (WatchListEvent event : events) { |
205 |
1 |
for (DocumentReference authorReference : event.getAuthorReferences()) { |
206 |
|
|
207 |
|
|
208 |
|
|
209 |
1 |
if (!processedAuthors.contains(authorReference)) { |
210 |
1 |
Attachment avatarAttachment = avatarExtractor.getUserAvatar(authorReference); |
211 |
1 |
if (avatarAttachment != null) { |
212 |
1 |
templateExtraAttachments.add(avatarAttachment); |
213 |
|
} |
214 |
1 |
processedAuthors.add(authorReference); |
215 |
|
} |
216 |
|
} |
217 |
|
} |
218 |
1 |
return templateExtraAttachments; |
219 |
|
} |
220 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (9) |
Complexity: 1 |
Complexity Density: 0.11 |
|
221 |
2 |
private MimeMessage setConversationHeaders(MimeMessage originalMessage, WatchListMessageData watchListMessageData)... |
222 |
|
throws MessagingException |
223 |
|
{ |
224 |
|
|
225 |
|
|
226 |
2 |
MimeMessage result = new MimeMessage(originalMessage); |
227 |
|
|
228 |
2 |
DocumentReference documentReference = watchListMessageData.getEvents().get(0).getDocumentReference(); |
229 |
2 |
String serializedReference = serializer.serialize(documentReference); |
230 |
|
|
231 |
|
|
232 |
|
|
233 |
|
|
234 |
2 |
String conversationIDPart = DigestUtils.md5Hex(serializedReference); |
235 |
2 |
String suffix = getConversationSuffix(); |
236 |
2 |
String conversationID = String.format("<%s.XWiki.%s>", conversationIDPart, suffix); |
237 |
|
|
238 |
|
|
239 |
2 |
result.setHeader("References", conversationID); |
240 |
2 |
result.setHeader("In-Reply-To", conversationID); |
241 |
|
|
242 |
2 |
return result; |
243 |
|
} |
244 |
|
|
245 |
|
|
246 |
|
|
247 |
|
|
248 |
|
|
249 |
|
|
|
|
| 77.8% |
Uncovered Elements: 2 (9) |
Complexity: 2 |
Complexity Density: 0.29 |
|
250 |
2 |
private String getConversationSuffix()... |
251 |
|
{ |
252 |
2 |
String suffix = null; |
253 |
|
|
254 |
2 |
Session session = this.sessionFactory.create(Collections.<String, String>emptyMap()); |
255 |
2 |
InternetAddress addr = InternetAddress.getLocalAddress(session); |
256 |
2 |
if (addr != null) { |
257 |
2 |
suffix = addr.getAddress(); |
258 |
|
} else { |
259 |
|
|
260 |
0 |
suffix = "xwiki@localhost"; |
261 |
|
} |
262 |
|
|
263 |
2 |
return suffix; |
264 |
|
} |
265 |
|
|
|
|
| 0% |
Uncovered Elements: 1 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
266 |
0 |
@Override... |
267 |
|
public void remove() |
268 |
|
{ |
269 |
0 |
throw new UnsupportedOperationException("remove"); |
270 |
|
} |
271 |
|
} |