001
014
015 package com.liferay.portal.util;
016
017 import com.liferay.mail.model.FileAttachment;
018 import com.liferay.mail.service.MailServiceUtil;
019 import com.liferay.portal.kernel.json.JSONFactoryUtil;
020 import com.liferay.portal.kernel.json.JSONObject;
021 import com.liferay.portal.kernel.log.Log;
022 import com.liferay.portal.kernel.log.LogFactoryUtil;
023 import com.liferay.portal.kernel.mail.MailMessage;
024 import com.liferay.portal.kernel.mail.SMTPAccount;
025 import com.liferay.portal.kernel.messaging.DestinationNames;
026 import com.liferay.portal.kernel.messaging.MessageBusUtil;
027 import com.liferay.portal.kernel.notifications.UserNotificationManagerUtil;
028 import com.liferay.portal.kernel.transaction.TransactionCommitCallbackRegistryUtil;
029 import com.liferay.portal.kernel.util.ArrayUtil;
030 import com.liferay.portal.kernel.util.ClassLoaderPool;
031 import com.liferay.portal.kernel.util.EscapableObject;
032 import com.liferay.portal.kernel.util.GetterUtil;
033 import com.liferay.portal.kernel.util.HtmlEscapableObject;
034 import com.liferay.portal.kernel.util.HtmlUtil;
035 import com.liferay.portal.kernel.util.LocaleUtil;
036 import com.liferay.portal.kernel.util.ObjectValuePair;
037 import com.liferay.portal.kernel.util.StringPool;
038 import com.liferay.portal.kernel.util.StringUtil;
039 import com.liferay.portal.kernel.util.Validator;
040 import com.liferay.portal.kernel.uuid.PortalUUIDUtil;
041 import com.liferay.portal.model.Company;
042 import com.liferay.portal.model.Group;
043 import com.liferay.portal.model.Subscription;
044 import com.liferay.portal.model.User;
045 import com.liferay.portal.model.UserNotificationDeliveryConstants;
046 import com.liferay.portal.security.permission.PermissionChecker;
047 import com.liferay.portal.security.permission.PermissionCheckerFactoryUtil;
048 import com.liferay.portal.service.CompanyLocalServiceUtil;
049 import com.liferay.portal.service.GroupLocalServiceUtil;
050 import com.liferay.portal.service.ServiceContext;
051 import com.liferay.portal.service.SubscriptionLocalServiceUtil;
052 import com.liferay.portal.service.UserLocalServiceUtil;
053 import com.liferay.portal.service.UserNotificationEventLocalServiceUtil;
054 import com.liferay.portal.service.permission.SubscriptionPermissionUtil;
055
056 import java.io.File;
057 import java.io.IOException;
058 import java.io.ObjectInputStream;
059 import java.io.ObjectOutputStream;
060 import java.io.Serializable;
061
062 import java.util.ArrayList;
063 import java.util.HashMap;
064 import java.util.HashSet;
065 import java.util.List;
066 import java.util.Locale;
067 import java.util.Map;
068 import java.util.Set;
069 import java.util.concurrent.Callable;
070
071 import javax.mail.internet.InternetAddress;
072
073
079 public class SubscriptionSender implements Serializable {
080
081 public void addFileAttachment(File file) {
082 addFileAttachment(file, null);
083 }
084
085 public void addFileAttachment(File file, String fileName) {
086 if (file == null) {
087 return;
088 }
089
090 if (fileAttachments == null) {
091 fileAttachments = new ArrayList<FileAttachment>();
092 }
093
094 FileAttachment attachment = new FileAttachment(file, fileName);
095
096 fileAttachments.add(attachment);
097 }
098
099 public void addPersistedSubscribers(String className, long classPK) {
100 ObjectValuePair<String, Long> ovp = new ObjectValuePair<String, Long>(
101 className, classPK);
102
103 _persistestedSubscribersOVPs.add(ovp);
104 }
105
106 public void addRuntimeSubscribers(String toAddress, String toName) {
107 ObjectValuePair<String, String> ovp =
108 new ObjectValuePair<String, String>(toAddress, toName);
109
110 _runtimeSubscribersOVPs.add(ovp);
111 }
112
113 public void flushNotifications() throws Exception {
114 initialize();
115
116 Thread currentThread = Thread.currentThread();
117
118 ClassLoader contextClassLoader = currentThread.getContextClassLoader();
119
120 try {
121 if ((_classLoader != null) &&
122 (contextClassLoader != _classLoader)) {
123
124 currentThread.setContextClassLoader(_classLoader);
125 }
126
127 for (ObjectValuePair<String, Long> ovp :
128 _persistestedSubscribersOVPs) {
129
130 String className = ovp.getKey();
131 long classPK = ovp.getValue();
132
133 List<Subscription> subscriptions =
134 SubscriptionLocalServiceUtil.getSubscriptions(
135 companyId, className, classPK);
136
137 for (Subscription subscription : subscriptions) {
138 try {
139 notifyPersistedSubscriber(subscription);
140 }
141 catch (Exception e) {
142 _log.error(
143 "Unable to process subscription: " + subscription);
144 }
145 }
146
147 if (bulk) {
148 Locale locale = LocaleUtil.getDefault();
149
150 InternetAddress to = new InternetAddress(
151 replaceContent(replyToAddress, locale),
152 replaceContent(replyToAddress, locale));
153
154 sendEmail(to, locale);
155 }
156 }
157
158 _persistestedSubscribersOVPs.clear();
159
160 for (ObjectValuePair<String, String> ovp :
161 _runtimeSubscribersOVPs) {
162
163 String toAddress = ovp.getKey();
164
165 if (Validator.isNull(toAddress)) {
166 continue;
167 }
168
169 if (_sentEmailAddresses.contains(toAddress)) {
170 if (_log.isDebugEnabled()) {
171 _log.debug(
172 "Do not send a duplicate email to " + toAddress);
173 }
174
175 continue;
176 }
177
178 if (_log.isDebugEnabled()) {
179 _log.debug(
180 "Add " + toAddress + " to the list of users who " +
181 "have received an email");
182 }
183
184 _sentEmailAddresses.add(toAddress);
185
186 String toName = ovp.getValue();
187
188 InternetAddress to = new InternetAddress(toAddress, toName);
189
190 notifyRuntimeSubscriber(to, LocaleUtil.getDefault());
191 }
192
193 _runtimeSubscribersOVPs.clear();
194 }
195 finally {
196 if ((_classLoader != null) &&
197 (contextClassLoader != _classLoader)) {
198
199 currentThread.setContextClassLoader(contextClassLoader);
200 }
201 }
202 }
203
204 public void flushNotificationsAsync() {
205 TransactionCommitCallbackRegistryUtil.registerCallback(
206 new Callable<Void>() {
207
208 @Override
209 public Void call() throws Exception {
210 Thread currentThread = Thread.currentThread();
211
212 _classLoader = currentThread.getContextClassLoader();
213
214 MessageBusUtil.sendMessage(
215 DestinationNames.SUBSCRIPTION_SENDER,
216 SubscriptionSender.this);
217
218 return null;
219 }
220 }
221 );
222 }
223
224 public Object getContextAttribute(String key) {
225 return _context.get(key);
226 }
227
228 public String getMailId() {
229 return this.mailId;
230 }
231
232 public void initialize() throws Exception {
233 if (_initialized) {
234 return;
235 }
236
237 _initialized = true;
238
239 if ((groupId == 0) && (serviceContext != null)) {
240 setScopeGroupId(serviceContext.getScopeGroupId());
241 }
242
243 Company company = CompanyLocalServiceUtil.getCompany(companyId);
244
245 setContextAttribute("[$COMPANY_ID$]", company.getCompanyId());
246 setContextAttribute("[$COMPANY_MX$]", company.getMx());
247 setContextAttribute("[$COMPANY_NAME$]", company.getName());
248 setContextAttribute("[$PORTAL_URL$]", company.getPortalURL(groupId));
249
250 if (groupId > 0) {
251 Group group = GroupLocalServiceUtil.getGroup(groupId);
252
253 setContextAttribute("[$SITE_NAME$]", group.getDescriptiveName());
254 }
255
256 if ((userId > 0) && Validator.isNotNull(_contextUserPrefix)) {
257 setContextAttribute(
258 "[$" + _contextUserPrefix + "_USER_ADDRESS$]",
259 PortalUtil.getUserEmailAddress(userId));
260 setContextAttribute(
261 "[$" + _contextUserPrefix + "_USER_NAME$]",
262 PortalUtil.getUserName(userId, StringPool.BLANK));
263 }
264
265 if (uniqueMailId) {
266 _mailIdIds = ArrayUtil.append(
267 _mailIdIds, PortalUUIDUtil.generate());
268 }
269
270 mailId = PortalUtil.getMailId(
271 company.getMx(), _mailIdPopPortletPrefix, _mailIdIds);
272 }
273
274 public void setBody(String body) {
275 this.body = body;
276 }
277
278 public void setBulk(boolean bulk) {
279 this.bulk = bulk;
280 }
281
282 public void setClassName(String className) {
283 _className = className;
284 }
285
286 public void setClassPK(long classPK) {
287 _classPK = classPK;
288 }
289
290 public void setCompanyId(long companyId) {
291 this.companyId = companyId;
292 }
293
294 public void setContextAttribute(String key, EscapableObject<String> value) {
295 _context.put(key, value);
296 }
297
298 public void setContextAttribute(String key, Object value) {
299 setContextAttribute(key, value, true);
300 }
301
302 public void setContextAttribute(String key, Object value, boolean escape) {
303 setContextAttribute(
304 key,
305 new HtmlEscapableObject<String>(String.valueOf(value), escape));
306 }
307
308 public void setContextAttributes(Object... values) {
309 for (int i = 0; i < values.length; i += 2) {
310 setContextAttribute(String.valueOf(values[i]), values[i + 1]);
311 }
312 }
313
314 public void setContextUserPrefix(String contextUserPrefix) {
315 _contextUserPrefix = contextUserPrefix;
316 }
317
318 public void setEntryTitle(String entryTitle) {
319 this._entryTitle = entryTitle;
320 }
321
322 public void setEntryURL(String entryURL) {
323 _entryURL = entryURL;
324 }
325
326 public void setFrom(String fromAddress, String fromName) {
327 this.fromAddress = fromAddress;
328 this.fromName = fromName;
329 }
330
331 public void setGroupId(long groupId) {
332 this.groupId = groupId;
333 }
334
335 public void setHtmlFormat(boolean htmlFormat) {
336 this.htmlFormat = htmlFormat;
337 }
338
339 public void setInReplyTo(String inReplyTo) {
340 this.inReplyTo = inReplyTo;
341 }
342
343 public void setLocalizedBodyMap(Map<Locale, String> localizedBodyMap) {
344 this.localizedBodyMap = localizedBodyMap;
345 }
346
347 public void setLocalizedSubjectMap(
348 Map<Locale, String> localizedSubjectMap) {
349
350 this.localizedSubjectMap = localizedSubjectMap;
351 }
352
353 public void setMailId(String popPortletPrefix, Object... ids) {
354 _mailIdPopPortletPrefix = popPortletPrefix;
355 _mailIdIds = ids;
356 }
357
358 public void setNotificationClassNameId(long notificationClassNameId) {
359 _notificationClassNameId = notificationClassNameId;
360 }
361
362
365 public void setNotificationType(int notificationType) {
366 _notificationType = notificationType;
367 }
368
369 public void setPortletId(String portletId) {
370 this.portletId = portletId;
371 }
372
373 public void setReplyToAddress(String replyToAddress) {
374 this.replyToAddress = replyToAddress;
375 }
376
377
380 public void setScopeGroupId(long scopeGroupId) {
381 try {
382 Group group = GroupLocalServiceUtil.getGroup(scopeGroupId);
383
384 if (group.isLayout()) {
385 groupId = group.getParentGroupId();
386 }
387 else {
388 groupId = scopeGroupId;
389 }
390 }
391 catch (Exception e) {
392 }
393
394 this.scopeGroupId = scopeGroupId;
395 }
396
397 public void setServiceContext(ServiceContext serviceContext) {
398 this.serviceContext = serviceContext;
399 }
400
401 public void setSMTPAccount(SMTPAccount smtpAccount) {
402 this.smtpAccount = smtpAccount;
403 }
404
405 public void setSubject(String subject) {
406 this.subject = subject;
407 }
408
409 public void setUniqueMailId(boolean uniqueMailId) {
410 this.uniqueMailId = uniqueMailId;
411 }
412
413 public void setUserId(long userId) {
414 this.userId = userId;
415 }
416
417 protected void deleteSubscription(Subscription subscription)
418 throws Exception {
419
420 SubscriptionLocalServiceUtil.deleteSubscription(
421 subscription.getSubscriptionId());
422 }
423
424 protected boolean hasPermission(
425 Subscription subscription, String className, long classPK,
426 User user)
427 throws Exception {
428
429 PermissionChecker permissionChecker =
430 PermissionCheckerFactoryUtil.create(user);
431
432 return SubscriptionPermissionUtil.contains(
433 permissionChecker, subscription.getClassName(),
434 subscription.getClassPK(), className, classPK);
435 }
436
437 protected boolean hasPermission(Subscription subscription, User user)
438 throws Exception {
439
440 return hasPermission(subscription, _className, _classPK, user);
441 }
442
443 protected void notifyPersistedSubscriber(Subscription subscription)
444 throws Exception {
445
446 notifyPersistedSubscriber(subscription, _className, _classPK);
447 }
448
449 protected void notifyPersistedSubscriber(
450 Subscription subscription, String className, long classPK)
451 throws Exception {
452
453 User user = UserLocalServiceUtil.fetchUserById(
454 subscription.getUserId());
455
456 if (user == null) {
457 if (_log.isInfoEnabled()) {
458 _log.info(
459 "Subscription " + subscription.getSubscriptionId() +
460 " is stale and will be deleted");
461 }
462
463 deleteSubscription(subscription);
464
465 return;
466 }
467
468 String emailAddress = user.getEmailAddress();
469
470 if (_sentEmailAddresses.contains(emailAddress)) {
471 if (_log.isDebugEnabled()) {
472 _log.debug("Do not send a duplicate email to " + emailAddress);
473 }
474
475 return;
476 }
477 else {
478 if (_log.isDebugEnabled()) {
479 _log.debug(
480 "Add " + emailAddress +
481 " to the list of users who have received an email");
482 }
483
484 _sentEmailAddresses.add(emailAddress);
485 }
486
487 if (!user.isActive()) {
488 if (_log.isDebugEnabled()) {
489 _log.debug("Skip inactive user " + user.getUserId());
490 }
491
492 return;
493 }
494
495 try {
496 if (!hasPermission(subscription, className, classPK, user)) {
497 if (_log.isDebugEnabled()) {
498 _log.debug("Skip unauthorized user " + user.getUserId());
499 }
500
501 return;
502 }
503 }
504 catch (Exception e) {
505 _log.error(e, e);
506
507 return;
508 }
509
510 if (bulk) {
511 if (UserNotificationManagerUtil.isDeliver(
512 user.getUserId(), portletId, _notificationClassNameId,
513 _notificationType,
514 UserNotificationDeliveryConstants.TYPE_EMAIL)) {
515
516 InternetAddress bulkAddress = new InternetAddress(
517 user.getEmailAddress(), user.getFullName());
518
519 if (_bulkAddresses == null) {
520 _bulkAddresses = new ArrayList<InternetAddress>();
521 }
522
523 _bulkAddresses.add(bulkAddress);
524 }
525
526 sendUserNotification(user);
527 }
528 else {
529 sendNotification(user);
530 }
531 }
532
533 protected void notifyRuntimeSubscriber(InternetAddress to, Locale locale)
534 throws Exception {
535
536 String emailAddress = to.getAddress();
537
538 User user = UserLocalServiceUtil.fetchUserByEmailAddress(
539 companyId, emailAddress);
540
541 if (user == null) {
542 if (_log.isInfoEnabled()) {
543 _log.info(
544 "User with email address " + emailAddress +
545 " does not exist for company " + companyId);
546 }
547
548 sendEmail(to, locale);
549 }
550 else {
551 sendNotification(user);
552 }
553 }
554
555
559 @Deprecated
560 protected void notifySubscriber(Subscription subscription)
561 throws Exception {
562
563 notifyPersistedSubscriber(subscription, null, 0);
564 }
565
566
570 @Deprecated
571 protected void notifySubscriber(
572 Subscription subscription, String inferredClassName,
573 long inferredClassPK)
574 throws Exception {
575
576 notifyPersistedSubscriber(
577 subscription, inferredClassName, inferredClassPK);
578 }
579
580 protected void processMailMessage(MailMessage mailMessage, Locale locale)
581 throws Exception {
582
583 InternetAddress from = mailMessage.getFrom();
584 InternetAddress to = mailMessage.getTo()[0];
585
586 String processedSubject = StringUtil.replace(
587 mailMessage.getSubject(),
588 new String[] {
589 "[$FROM_ADDRESS$]", "[$FROM_NAME$]", "[$TO_ADDRESS$]",
590 "[$TO_NAME$]"
591 },
592 new String[] {
593 from.getAddress(),
594 GetterUtil.getString(from.getPersonal(), from.getAddress()),
595 HtmlUtil.escape(to.getAddress()),
596 HtmlUtil.escape(
597 GetterUtil.getString(to.getPersonal(), to.getAddress()))
598 });
599
600 processedSubject = replaceContent(processedSubject, locale, false);
601
602 mailMessage.setSubject(processedSubject);
603
604 String processedBody = StringUtil.replace(
605 mailMessage.getBody(),
606 new String[] {
607 "[$FROM_ADDRESS$]", "[$FROM_NAME$]", "[$TO_ADDRESS$]",
608 "[$TO_NAME$]"
609 },
610 new String[] {
611 from.getAddress(),
612 GetterUtil.getString(from.getPersonal(), from.getAddress()),
613 HtmlUtil.escape(to.getAddress()),
614 HtmlUtil.escape(
615 GetterUtil.getString(to.getPersonal(), to.getAddress()))
616 });
617
618 processedBody = replaceContent(processedBody, locale, htmlFormat);
619
620 mailMessage.setBody(processedBody);
621 }
622
623 protected String replaceContent(String content, Locale locale)
624 throws Exception {
625
626 return replaceContent(content, locale, true);
627 }
628
629 protected String replaceContent(
630 String content, Locale locale, boolean escape)
631 throws Exception {
632
633 for (Map.Entry<String, EscapableObject<String>> entry :
634 _context.entrySet()) {
635
636 String key = entry.getKey();
637 EscapableObject<String> value = entry.getValue();
638
639 String valueString = null;
640
641 if (escape) {
642 valueString = value.getEscapedValue();
643 }
644 else {
645 valueString = value.getOriginalValue();
646 }
647
648 content = StringUtil.replace(content, key, valueString);
649 }
650
651 if (Validator.isNotNull(portletId)) {
652 String portletName = PortalUtil.getPortletTitle(portletId, locale);
653
654 content = StringUtil.replace(
655 content, "[$PORTLET_NAME$]", portletName);
656 }
657
658 Company company = CompanyLocalServiceUtil.getCompany(companyId);
659
660 content = StringUtil.replace(
661 content,
662 new String[] {
663 "href=\"/", "src=\"/"
664 },
665 new String[] {
666 "href=\"" + company.getPortalURL(groupId) + "/",
667 "src=\"" + company.getPortalURL(groupId) + "/"
668 });
669
670 return content;
671 }
672
673 protected void sendEmail(InternetAddress to, Locale locale)
674 throws Exception {
675
676 InternetAddress from = new InternetAddress(
677 replaceContent(fromAddress, locale),
678 replaceContent(fromName, locale));
679
680 String processedSubject = null;
681
682 if (localizedSubjectMap != null) {
683 String localizedSubject = localizedSubjectMap.get(locale);
684
685 if (Validator.isNull(localizedSubject)) {
686 Locale defaultLocale = LocaleUtil.getDefault();
687
688 processedSubject = localizedSubjectMap.get(defaultLocale);
689 }
690 else {
691 processedSubject = localizedSubject;
692 }
693 }
694 else {
695 processedSubject = this.subject;
696 }
697
698 String processedBody = null;
699
700 if (localizedBodyMap != null) {
701 String localizedBody = localizedBodyMap.get(locale);
702
703 if (Validator.isNull(localizedBody)) {
704 Locale defaultLocale = LocaleUtil.getDefault();
705
706 processedBody = localizedBodyMap.get(defaultLocale);
707 }
708 else {
709 processedBody = localizedBody;
710 }
711 }
712 else {
713 processedBody = this.body;
714 }
715
716 MailMessage mailMessage = new MailMessage(
717 from, to, processedSubject, processedBody, htmlFormat);
718
719 if (fileAttachments != null) {
720 for (FileAttachment fileAttachment : fileAttachments) {
721 mailMessage.addFileAttachment(
722 fileAttachment.getFile(), fileAttachment.getFileName());
723 }
724 }
725
726 if (bulk && (_bulkAddresses != null)) {
727 mailMessage.setBulkAddresses(
728 _bulkAddresses.toArray(
729 new InternetAddress[_bulkAddresses.size()]));
730
731 _bulkAddresses.clear();
732 }
733
734 if (inReplyTo != null) {
735 mailMessage.setInReplyTo(inReplyTo);
736 }
737
738 mailMessage.setMessageId(mailId);
739
740 if (replyToAddress != null) {
741 InternetAddress replyTo = new InternetAddress(
742 replaceContent(replyToAddress, locale),
743 replaceContent(replyToAddress, locale));
744
745 mailMessage.setReplyTo(new InternetAddress[] {replyTo});
746 }
747
748 if (smtpAccount != null) {
749 mailMessage.setSMTPAccount(smtpAccount);
750 }
751
752 processMailMessage(mailMessage, locale);
753
754 MailServiceUtil.sendEmail(mailMessage);
755 }
756
757 protected void sendEmailNotification(User user) throws Exception {
758 if (UserNotificationManagerUtil.isDeliver(
759 user.getUserId(), portletId, _notificationClassNameId,
760 _notificationType,
761 UserNotificationDeliveryConstants.TYPE_EMAIL)) {
762
763 InternetAddress to = new InternetAddress(
764 user.getEmailAddress(), user.getFullName());
765
766 sendEmail(to, user.getLocale());
767 }
768 }
769
770 protected void sendNotification(User user) throws Exception {
771 sendEmailNotification(user);
772 sendUserNotification(user);
773 }
774
775 protected void sendUserNotification(User user) throws Exception {
776 JSONObject notificationEventJSONObject =
777 JSONFactoryUtil.createJSONObject();
778
779 notificationEventJSONObject.put("className", _className);
780 notificationEventJSONObject.put("classPK", _classPK);
781 notificationEventJSONObject.put("entryTitle", _entryTitle);
782 notificationEventJSONObject.put("entryURL", _entryURL);
783 notificationEventJSONObject.put("notificationType", _notificationType);
784 notificationEventJSONObject.put("userId", user.getUserId());
785
786 if (UserNotificationManagerUtil.isDeliver(
787 user.getUserId(), portletId, _notificationClassNameId,
788 _notificationType,
789 UserNotificationDeliveryConstants.TYPE_PUSH)) {
790
791 UserNotificationEventLocalServiceUtil.sendUserNotificationEvents(
792 user.getUserId(), portletId,
793 UserNotificationDeliveryConstants.TYPE_PUSH,
794 notificationEventJSONObject);
795 }
796
797 if (UserNotificationManagerUtil.isDeliver(
798 user.getUserId(), portletId, _notificationClassNameId,
799 _notificationType,
800 UserNotificationDeliveryConstants.TYPE_WEBSITE)) {
801
802 UserNotificationEventLocalServiceUtil.sendUserNotificationEvents(
803 user.getUserId(), portletId,
804 UserNotificationDeliveryConstants.TYPE_WEBSITE,
805 notificationEventJSONObject);
806 }
807 }
808
809 protected String body;
810 protected boolean bulk;
811 protected long companyId;
812 protected List<FileAttachment> fileAttachments =
813 new ArrayList<FileAttachment>();
814 protected String fromAddress;
815 protected String fromName;
816 protected long groupId;
817 protected boolean htmlFormat;
818 protected String inReplyTo;
819 protected Map<Locale, String> localizedBodyMap;
820 protected Map<Locale, String> localizedSubjectMap;
821 protected String mailId;
822 protected String portletId;
823 protected String replyToAddress;
824 protected long scopeGroupId;
825 protected ServiceContext serviceContext;
826 protected SMTPAccount smtpAccount;
827 protected String subject;
828 protected boolean uniqueMailId = true;
829 protected long userId;
830
831 private void readObject(ObjectInputStream objectInputStream)
832 throws ClassNotFoundException, IOException {
833
834 objectInputStream.defaultReadObject();
835
836 String servletContextName = objectInputStream.readUTF();
837
838 if (!servletContextName.isEmpty()) {
839 _classLoader = ClassLoaderPool.getClassLoader(servletContextName);
840 }
841 }
842
843 private void writeObject(ObjectOutputStream objectOutputStream)
844 throws IOException {
845
846 objectOutputStream.defaultWriteObject();
847
848 String servletContextName = StringPool.BLANK;
849
850 if (_classLoader != null) {
851 servletContextName = ClassLoaderPool.getContextName(_classLoader);
852 }
853
854 objectOutputStream.writeUTF(servletContextName);
855 }
856
857 private static Log _log = LogFactoryUtil.getLog(SubscriptionSender.class);
858
859 private List<InternetAddress> _bulkAddresses;
860 private transient ClassLoader _classLoader;
861 private String _className;
862 private long _classPK;
863 private Map<String, EscapableObject<String>> _context =
864 new HashMap<String, EscapableObject<String>>();
865 private String _contextUserPrefix;
866 private String _entryTitle;
867 private String _entryURL;
868 private boolean _initialized;
869 private Object[] _mailIdIds;
870 private String _mailIdPopPortletPrefix;
871 private long _notificationClassNameId;
872 private int _notificationType;
873 private List<ObjectValuePair<String, Long>> _persistestedSubscribersOVPs =
874 new ArrayList<ObjectValuePair<String, Long>>();
875 private List<ObjectValuePair<String, String>> _runtimeSubscribersOVPs =
876 new ArrayList<ObjectValuePair<String, String>>();
877 private Set<String> _sentEmailAddresses = new HashSet<String>();
878
879 }