package com.idega.block.article.business; import java.net.URLEncoder; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import org.directwebremoting.WebContextFactory; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; import com.idega.block.article.bean.CommentsViewerProperties; import com.idega.block.article.component.ArticleCommentAttachmentStatisticsViewer; import com.idega.block.article.component.CommentsViewer; import com.idega.block.article.data.Comment; import com.idega.block.article.data.CommentHome; import com.idega.block.article.media.CommentAttachmentDownloader; import com.idega.builder.bean.AdvancedProperty; import com.idega.business.file.FileDownloadNotificationProperties; import com.idega.core.accesscontrol.business.AccessController; import com.idega.core.accesscontrol.business.LoginBusinessBean; import com.idega.core.accesscontrol.business.LoginSession; import com.idega.core.business.DefaultSpringBean; import com.idega.core.contact.data.Email; import com.idega.core.file.data.ICFile; import com.idega.core.file.data.ICFileHome; import com.idega.idegaweb.IWApplicationContext; import com.idega.idegaweb.IWMainApplication; import com.idega.io.MediaWritable; import com.idega.presentation.IWContext; import com.idega.user.business.NoEmailFoundException; import com.idega.user.business.UserBusiness; import com.idega.user.data.Group; 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.StringUtil; import com.idega.util.URIUtil; import com.idega.util.expression.ELUtil; import com.sun.syndication.feed.atom.Entry; import com.sun.syndication.feed.atom.Feed; import com.sun.syndication.feed.atom.Person; import com.sun.syndication.feed.module.DCModule; import com.sun.syndication.feed.module.Module; import com.sun.syndication.io.WireFeedOutput; @Scope(BeanDefinition.SCOPE_SINGLETON) @Service(DefaultCommentsPersistenceManager.BEAN_IDENTIFIER) public class DefaultCommentsPersistenceManager extends DefaultSpringBean implements CommentsPersistenceManager { static final String BEAN_IDENTIFIER = "defaultCommentsPersistenceManager"; private static final Logger LOGGER = Logger.getLogger(DefaultCommentsPersistenceManager.class.getName()); private WireFeedOutput wfo = new WireFeedOutput(); public Object addComment(CommentsViewerProperties properties) { if (properties == null || properties.getEntryId() == null) { LOGGER.warning("Properties are not provided or entry ID is unknown: " + properties); return null; } try { boolean hasFullRightsForComments = hasFullRightsForComments(properties.getIdentifier()); CommentHome commentHome = getCommentHome(); Comment comment = commentHome.create(); comment.setEntryId(properties.getEntryId()); comment.setCommentHolder(String.valueOf(properties.getIdentifier())); boolean hasReplyToId = properties.getReplyForComment() == null ? false : properties.getReplyForComment() < 0 ? false : true; boolean privateComment = hasReplyToId || !hasFullRightsForComments; comment.setPrivateComment(privateComment); comment.setReplyForCommentId(properties.getReplyForComment()); comment.setAnnouncedToPublic(hasFullRightsForComments && !privateComment); User author = getLoggedInUser(); if (author != null) { comment.setAuthorId(Integer.valueOf(author.getId())); } comment.store(); addAttachment(properties, comment); return comment.getPrimaryKey(); } catch(Exception e) { LOGGER.log(Level.WARNING, "Error creating " + Comment.class, e); } return null; } private boolean addAttachment(CommentsViewerProperties properties, Comment comment) { if (ListUtil.isEmpty(properties.getUploadedFiles())) { return true; } try { ICFileHome fileHome = getFileHome(); for (String uploadedFile: properties.getUploadedFiles()) { if (!uploadedFile.startsWith(CoreConstants.WEBDAV_SERVLET_URI)) { uploadedFile = new StringBuilder(CoreConstants.WEBDAV_SERVLET_URI).append(uploadedFile).toString(); } ICFile file = fileHome.create(); file.setName(URLEncoder.encode(uploadedFile.substring(uploadedFile.lastIndexOf(CoreConstants.SLASH) + 1), CoreConstants.ENCODING_UTF8)); file.setFileUri(URLEncoder.encode(uploadedFile, CoreConstants.ENCODING_UTF8)); file.store(); comment.addAttachment(file); } comment.store(); return true; } catch(Exception e) { LOGGER.log(Level.WARNING, "Unable to add attachments: " + properties.getUploadedFiles(), e); } return false; } public Feed getCommentsFeed(String processInstanceId) { throw new UnsupportedOperationException("This method is not implemented by default manager"); } public String getFeedSubtitle(IWContext iwc, String processInstanceId) { throw new UnsupportedOperationException("This method is not implemented by default manager"); } public String getFeedTitle(IWContext iwc, String processInstanceId) { throw new UnsupportedOperationException("This method is not implemented by default manager"); } public String getLinkToCommentsXML(String processInstanceId) { throw new UnsupportedOperationException("This method is not implemented by default manager"); } public User getUserAvailableToReadWriteCommentsFeed(IWContext iwc) { throw new UnsupportedOperationException("This method is not implemented by default manager"); } public boolean hasFullRightsForComments(String processInstanceId) { throw new UnsupportedOperationException("This method is not implemented by default manager"); } public boolean hasFullRightsForComments(Long processInstanceId) { throw new UnsupportedOperationException("This method is not implemented by default manager"); } public boolean hasRightsToViewComments(String processInstanceId) { throw new UnsupportedOperationException("This method is not implemented by default manager"); } public boolean hasRightsToViewComments(Long processInstanceId) { throw new UnsupportedOperationException("This method is not implemented by default manager"); } public boolean storeFeed(String processInstanceId, Feed comments) { throw new UnsupportedOperationException("This method is not implemented by default manager"); } private CommentHome getCommentHome() { return getHomeForEntity(Comment.class); } public Comment getComment(Object primaryKey) { if (primaryKey == null) { return null; } try { return getCommentHome().findByPrimaryKey(primaryKey); } catch (Exception e) { LOGGER.log(Level.WARNING, "Nothing found by: " + primaryKey, e); } return null; } public boolean markCommentAsRead(Object primaryKey) { Comment comment = getComment(primaryKey); if (comment == null) { return false; } User reader = getLoggedInUser(); if (reader == null) { return false; } try { comment.addReadBy(reader); comment.store(); } catch(Exception e) { LOGGER.log(Level.WARNING, "Error marking comment ('"+primaryKey+"') as read by reader: " + reader, e); return false; } return true; } public List<? extends Entry> getEntriesToFormat(Feed comments, CommentsViewerProperties properties) { throw new UnsupportedOperationException("This method is not implemented by default manager"); } protected User getLoggedInUser() { try { LoginSession loginSession = ELUtil.getInstance().getBean(LoginSession.class); return loginSession.isLoggedIn() ? loginSession.getUser() : null; } catch(Exception e) { LOGGER.log(Level.WARNING, "Error getting logged in user", e); } return null; } public boolean setCommentPublished(Object primaryKey, boolean makePublic) { Comment comment = getComment(primaryKey); if (comment == null) { return false; } comment.setAnnouncedToPublic(makePublic); comment.store(); return true; } public boolean setCommentRead(Object primaryKey) { Comment comment = getComment(primaryKey); if (comment == null) { return false; } User currentUser = getLoggedInUser(); if (currentUser == null) { return false; } try { comment.addReadBy(currentUser); comment.store(); } catch(Exception e) { LOGGER.log(Level.WARNING, "Error adding user " + currentUser + " as have red comment: " + primaryKey, e); } return true; } public String getCommentFilesPath(CommentsViewerProperties properties) { throw new UnsupportedOperationException("This method is not implemented by default manager"); } public boolean isCommentsCreationEnabled(CommentsViewerProperties properties) { return true; } public String getTaskNameForAttachments() { LOGGER.info("This method is not implemented by default manager"); return null; } private ICFileHome getFileHome() { return getHomeForEntity(ICFile.class); } public ICFile getCommentAttachment(String icFileId) { try { ICFileHome fileHome = getFileHome(); return fileHome.findByPrimaryKey(icFileId); } catch(Exception e) { LOGGER.log(Level.WARNING, "Error getting ICFile: " + icFileId, e); } return null; } public String getUriToAttachment(String commentId, ICFile attachment, User user) { URIUtil uri = new URIUtil(IWMainApplication.getDefaultIWMainApplication().getMediaServletURI()); uri.setParameter(MediaWritable.PRM_WRITABLE_CLASS, IWMainApplication.getEncryptedClassName(CommentAttachmentDownloader.class)); uri.setParameter(ArticleCommentAttachmentStatisticsViewer.COMMENT_ID_PARAMETER, commentId); uri.setParameter(ArticleCommentAttachmentStatisticsViewer.COMMENT_ATTACHMENT_ID_PARAMETER, attachment.getPrimaryKey().toString()); if (user != null) { uri.setParameter(LoginBusinessBean.PARAM_LOGIN_BY_UNIQUE_ID, user.getUniqueId()); uri.setParameter(LoginBusinessBean.LoginStateParameter, LoginBusinessBean.LOGIN_EVENT_LOGIN); } return uri.getUri(); } public boolean isNotificationsAutoEnabled(CommentsViewerProperties properties) { return false; } public List<String> getPersonsToNotifyAboutComment(CommentsViewerProperties properties, Object commentId, boolean justPublished) { throw new UnsupportedOperationException("This method is not implemented by default manager"); } @SuppressWarnings("unchecked") public List<String> getEmails(List<? extends Entry> entries, String commentAuthorEmail) { if (entries == null) { return null; } if (commentAuthorEmail == null) { commentAuthorEmail = CoreConstants.EMPTY; } List<String> emails = new ArrayList<String>(); List<Person> authors = null; String email = null; for (Entry entry: entries) { authors = entry.getAuthors(); if (authors != null) { for (Person author: authors) { email = author.getEmail(); if (email != null) { email = CoreUtil.getDecodedValue(email); if (!email.equals(commentAuthorEmail) && !emails.contains(email)) { emails.add(email); } } } } } return emails; } @SuppressWarnings("unchecked") protected List<String> getAllFeedSubscribers(String processInstanceId, Integer authorId) { Feed comments = getCommentsFeed(processInstanceId); if (comments == null) { return null; } return getEmails(comments.getEntries(), getUserMail(authorId)); } protected String getUserMail(Integer userId) { if (userId == null) { return null; } UserBusiness userBusiness = getUserBusiness(); if (userBusiness == null) { return null; } User user = null; try { user = userBusiness.getUser(userId); } catch(Exception e) { LOGGER.log(Level.WARNING, "Error getting user by id: " + userId, e); } if (user == null) { return null; } Email email = getEmail(user); return email == null ? null : email.getEmailAddress(); } private Email getEmail(User user) { try { return getUserBusiness().getUsersMainEmail(user); } catch(NoEmailFoundException e) { } catch(Exception e) { LOGGER.log(Level.WARNING, "Error getting main email for user: " + user, e); } return null; } protected List<String> getEmails(Collection<User> users) { if (ListUtil.isEmpty(users)) { return null; } UserBusiness userBusiness = getUserBusiness(); if (userBusiness == null) { return null; } List<String> emails = new ArrayList<String>(users.size()); for (User user: users) { Email email = getEmail(user); String emailAddress = email == null ? null : email.getEmailAddress(); if (!StringUtil.isEmpty(emailAddress) && !emails.contains(emailAddress)) { emails.add(emailAddress); } } return emails; } protected List<User> getUsersHavingHandlerRole() { String roleKey = getHandlerRoleKey(); if (StringUtil.isEmpty(roleKey)) { return null; } IWApplicationContext iwac = IWMainApplication.getDefaultIWApplicationContext(); AccessController accessControler = IWMainApplication.getDefaultIWMainApplication().getAccessController(); Collection<Group> groupsWithRole = accessControler.getAllGroupsForRoleKey(roleKey, iwac); if (ListUtil.isEmpty(groupsWithRole)) { return null; } UserBusiness userBusiness = getUserBusiness(); if (userBusiness == null) { return null; } List<User> users = new ArrayList<User>(); for (Group group: groupsWithRole) { if (group instanceof User) { User user = (User) group; if (!users.contains(user)) { users.add(user); } } else { Collection<User> usersInGroup = null; try { usersInGroup = userBusiness.getUsersInGroup(group); } catch(Exception e) { LOGGER.log(Level.WARNING, "Error getting users in group: " + group, e); } if (!ListUtil.isEmpty(usersInGroup)) { for (User user: usersInGroup) { if (!users.contains(user)) { users.add(user); } } } } } return users; } protected List<User> getCaseHandlers(String identifier) { throw new UnsupportedOperationException("This method is not implemented by default manager"); } protected UserBusiness getUserBusiness() { return getServiceInstance(UserBusiness.class); } public String getHandlerRoleKey() { throw new UnsupportedOperationException("This method is not implemented by default manager"); } public boolean canWriteComments(CommentsViewerProperties properties) { return true; } public List<AdvancedProperty> getLinksForRecipients(List<String> recipients, CommentsViewerProperties properties) { List<AdvancedProperty> links = new ArrayList<AdvancedProperty>(recipients.size()); for (String recipient: recipients) { links.add(new AdvancedProperty(recipient, getLinkForRecipient(recipient, properties))); } return links; } protected String getLinkForRecipient(String recipient, CommentsViewerProperties properties) { return properties.getCommentsPageUrl(); } public Map<String, String> getUriToDocument(FileDownloadNotificationProperties properties, String identifier, List<User> users) { if (properties == null || ListUtil.isEmpty(users)) { return null; } Map<String, String> uris = new HashMap<String, String>(users.size()); for (User user: users) { uris.put(user.getId(), properties.getUrl()); } return uris; } public String getUriForCommentLink(CommentsViewerProperties properties) { try { URIUtil uri = new URIUtil(WebContextFactory.get().getCurrentPage()); uri.setParameter(CommentsViewer.AUTO_SHOW_COMMENTS, Boolean.TRUE.toString()); return uri.getUri(); } catch (Exception e) { LOGGER.log(Level.WARNING, "Error getting link for comment", e); } return null; } @SuppressWarnings("unchecked") public String getFeedContent(Feed feed) { if (feed == null) { LOGGER.warning("Feed is unknown!"); return null; } Date updated = new Date(System.currentTimeMillis()); feed.setUpdated(updated); List<Module> modules = feed.getModules(); if (!ListUtil.isEmpty(modules)) { for (Module module: modules) { if (module instanceof DCModule) { ((DCModule) module).setDate(updated); } } } try { return wfo.outputString(feed); } catch (Exception e) { LOGGER.log(Level.WARNING, "Error while outputing feed to string: " + feed, e); return null; } } @Override public boolean hasRightsToWriteComments(Long identifier) { User currentUser = getCurrentUser(); return currentUser != null; } }