package com.idega.business.file; import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import com.idega.builder.bean.AdvancedProperty; import com.idega.business.IBOLookup; import com.idega.business.IBOLookupException; import com.idega.core.contact.data.Email; import com.idega.core.file.data.ICFile; import com.idega.core.file.data.ICFileHome; import com.idega.data.IDOLookup; import com.idega.idegaweb.IWMainApplication; import com.idega.idegaweb.IWMainApplicationSettings; import com.idega.idegaweb.IWResourceBundle; import com.idega.presentation.IWContext; import com.idega.user.business.UserBusiness; import com.idega.user.data.User; import com.idega.util.CoreConstants; import com.idega.util.CoreUtil; import com.idega.util.ListUtil; import com.idega.util.SendMail; import com.idega.util.StringUtil; public abstract class FileDownloadNotifier implements Serializable { private static final long serialVersionUID = -5759650675280042585L; private static final Logger LOGGER = Logger.getLogger(FileDownloadNotifier.class.getName()); public AdvancedProperty sendNotifications(FileDownloadNotificationProperties properties) { AdvancedProperty result = new AdvancedProperty(Boolean.FALSE.toString(), "Unable to send notifications"); if (properties == null || StringUtil.isEmpty(properties.getUrl())) { LOGGER.warning("Invalid properties!"); return result; } IWContext iwc = CoreUtil.getIWContext(); if (iwc == null) { LOGGER.warning(IWContext.class + " is unavailable"); return result; } IWResourceBundle iwrb = iwc.getIWMainApplication().getBundle(CoreConstants.CORE_IW_BUNDLE_IDENTIFIER).getResourceBundle(iwc); AdvancedProperty file = getFile(properties); List<String> usersIds = properties.getUsers(); if (ListUtil.isEmpty(usersIds)) { LOGGER.warning("There are no recipients of this notification!"); return result; } List<User> users = getUsers(usersIds); if (ListUtil.isEmpty(users)) { LOGGER.warning("There are no recipients of this notification!"); return result; } Map<String, AdvancedProperty> emailsAndLinks = getEmails(file, properties, users); if (emailsAndLinks == null || emailsAndLinks.isEmpty()) { LOGGER.warning("Unable to resolve e-mail addresses for recipients: " + usersIds); return result; } Map<String, String> uris = getUriToDocument(properties, users); if (uris == null || uris.isEmpty()) { LOGGER.warning("Unable to resolve links to documents for recipients: " + usersIds); return result; } String subject = new StringBuilder(iwrb.getLocalizedString("file_download_notifier.reminder_to_download_document", "Reminder to download document")) .toString(); if (file != null) { try { subject = new StringBuilder(subject).append(": ").append(URLDecoder.decode(file.getValue(), CoreConstants.ENCODING_UTF8)).toString(); } catch(UnsupportedEncodingException e) { LOGGER.log(Level.WARNING, "Error decoding: " + file.getValue(), e); } } String pageMessagePart1 = new StringBuilder(iwrb.getLocalizedString("file_download_notifier.reminder_message_for_document_to_download", "Please download document. You can find it: ")).toString(); String pageMessagePart2 = iwrb.getLocalizedString("file_download_notifier.or_directly_download", "Or directly download from: "); IWMainApplicationSettings settings = iwc.getApplicationSettings(); String host = settings.getProperty(CoreConstants.PROP_SYSTEM_SMTP_MAILSERVER); String from = settings.getProperty(CoreConstants.PROP_SYSTEM_MAIL_FROM_ADDRESS); if (StringUtil.isEmpty(from)) { LOGGER.warning("Address 'from' is not defined, unable to send message: " + subject + " to: " + emailsAndLinks); return result; } for (String userId: emailsAndLinks.keySet()) { AdvancedProperty emailAndLink = emailsAndLinks.get(userId); if (emailAndLink == null) { LOGGER.warning("No email and/or link to attachment found for user: " + userId); continue; } String uriToDocument = uris.get(userId); if (StringUtil.isEmpty(uriToDocument)) { LOGGER.warning("No uri found to the document for user: " + userId); continue; } String message = new StringBuilder(pageMessagePart1).append(uriToDocument).append(CoreConstants.SPACE).append(pageMessagePart2) .append(emailAndLink.getValue()).toString(); if (!sendNotification(emailAndLink.getId(), subject, message, host, from)) { return result; } } result.setId(Boolean.TRUE.toString()); result.setValue(iwrb.getLocalizedString("file_download_notifier.reminders_sent_successfully", "Reminders were sent successfully")); return result; } private boolean sendNotification(String recipient, String subject, String message, String host, String from) { if (StringUtil.isEmpty(recipient) || StringUtil.isEmpty(subject) || StringUtil.isEmpty(message)) { LOGGER.warning("Some of fields are not provided: recipient: '"+recipient+"', subject: '"+subject+"', message: '"+message+"'"); return false; } try { SendMail.send(from, recipient, null, null, host, subject, message); } catch(Exception e) { LOGGER.log(Level.WARNING, "Error sending message: " + subject + " to: " + recipient, e); return false; } return true; } private AdvancedProperty getFile(String id) { try { ICFileHome fileHome = (ICFileHome) IDOLookup.getHome(ICFile.class); ICFile icFile = fileHome.findByPrimaryKey(id); if (icFile == null) { return null; } AdvancedProperty file = new AdvancedProperty(icFile.getId(), icFile.getName()); return file; } catch(Exception e) { LOGGER.log(Level.WARNING, "File was not found by id: " + id); } return null; } protected AdvancedProperty getFile(Integer hash) { try { ICFileHome fileHome = (ICFileHome) IDOLookup.getHome(ICFile.class); ICFile icFile = fileHome.findByHash(hash); if (icFile == null) { return null; } AdvancedProperty file = new AdvancedProperty(icFile.getId(), icFile.getName()); return file; } catch(Exception e) { LOGGER.log(Level.WARNING, "File was not found by hash: " + hash); } return null; } private Map<String, AdvancedProperty> getEmails(AdvancedProperty attachment, FileDownloadNotificationProperties properties, List<User> users) { if (StringUtil.isEmpty(properties.getServer())) { return null; } UserBusiness userBusiness = null; try { userBusiness = IBOLookup.getServiceInstance(IWMainApplication.getDefaultIWApplicationContext(), UserBusiness.class); } catch (IBOLookupException e) { LOGGER.log(Level.WARNING, "Error getting UserBusiness", e); } if (userBusiness == null) { return null; } Map<String, AdvancedProperty> emailsAndLinks = new HashMap<String, AdvancedProperty>(users.size()); for (User user: users) { Email email = null; try { email = userBusiness.getEmailHome().findMainEmailForUser(user); } catch(Exception e) { LOGGER.log(Level.WARNING, "Error getting email for user: " + user, e); } if (email != null) { String uri = getUriToAttachment(properties, user); if (StringUtil.isEmpty(uri)) { LOGGER.warning("Unable to resolve file uri for user: " + user + " and email: " + email + attachment == null ? "" : " and file: " + attachment.getId()); } else { emailsAndLinks.put(user.getId(), new AdvancedProperty(email.getEmailAddress(), new StringBuilder(properties.getServer()).append(uri).toString())); } } } return emailsAndLinks; } private List<User> getUsers(List<String> usersIds) { UserBusiness userBusiness = null; try { userBusiness = IBOLookup.getServiceInstance(IWMainApplication.getDefaultIWApplicationContext(), UserBusiness.class); } catch (IBOLookupException e) { LOGGER.log(Level.WARNING, "Error getting UserBusiness", e); } if (userBusiness == null) { return null; } List<User> users = new ArrayList<User>(usersIds.size()); for (String userId: usersIds) { User user = null; try { user = userBusiness.getUser(Integer.valueOf(userId)); } catch(Exception e) { LOGGER.log(Level.WARNING, "Error getting user by id: " + userId); } if (user != null) { users.add(user); } } return users; } public abstract String getUriToAttachment(FileDownloadNotificationProperties properties, User user); public abstract Map<String, String> getUriToDocument(FileDownloadNotificationProperties properties, List<User> users); protected AdvancedProperty getFile(FileDownloadNotificationProperties properties) { return getFile(properties.getFile()); } }