diff --git a/CHANGELOG.md b/CHANGELOG.md index 5bc3052..ef390ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,14 +1,14 @@ # Changelog -## [v2.9.0-SNAPSHOT] - 2023-02-02 +## [v2.9.0-SNAPSHOT] - 2023-02-13 -- Feature #24456 get a specific post by ID + - Feature #24456 social-networking rest api endpoints (comments, Likes, GetPost) -## [v2.8.0] - 2022-10-20 +## [v2.8.0-SNAPSHOT] - 2022-10-20 - Feature #23891 Refactored following updates social lib - Feature #23847 Social service: temporarily block of notifications for given username(s) -- Feature #23439: Please allow an IAM client to send notifications OPEN +- Feature #23439 Please allow an IAM client to send notifications OPEN - Feature #23991 Support attachments through notification / message API - Feature #23995 added support for set Message read / unread - Feature #24022 added get posts By PostId with range filter parameters and get Comments By PostId diff --git a/src/main/java/org/gcube/portal/social/networking/ws/methods/v1/Messages.java b/src/main/java/org/gcube/portal/social/networking/ws/methods/v1/Messages.java deleted file mode 100644 index f63e2a0..0000000 --- a/src/main/java/org/gcube/portal/social/networking/ws/methods/v1/Messages.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.gcube.portal.social.networking.ws.methods.v1; - -import javax.ws.rs.FormParam; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; - -import org.gcube.portal.social.networking.liferay.ws.UserManagerWSBuilder; -import org.gcube.portal.social.networking.ws.utils.ErrorMessages; -import org.gcube.vomanagement.usermanagement.UserManager; -import org.slf4j.LoggerFactory; - -/** - * Messages services REST interface - * @author Costantino Perciante at ISTI-CNR - * (costantino.perciante@isti.cnr.it) - */ -@Path("/messages") -@Deprecated -public class Messages { - // Logger - private static final org.slf4j.Logger logger = LoggerFactory.getLogger(Messages.class); - - public Messages() { - } - - @POST - @Path("writeMessageToUsers/") - @Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN}) - /** - * Try to send a message to recipientsIds. The sender is the owner of the gcube-token if not otherwise stated. - * @param body - * @param subject - * @return ok on success, error otherwise - */ - @Deprecated - public Response writeMessageToUsers( - @FormParam("sender") String sender, // the optional sender, if missing the sender will be the token's owner. - @FormParam("body") String body, - @FormParam("subject") String subject, - @FormParam("recipients") String recipientsIds) { - - if(body == null || body.isEmpty() || subject == null || subject.isEmpty() || recipientsIds == null || recipientsIds.isEmpty()){ - logger.error("Missing/wrong request parameters"); - return Response.status(Status.BAD_REQUEST).entity(ErrorMessages.MISSING_PARAMETERS).build(); - } - - return Response.status(Status.METHOD_NOT_ALLOWED).entity(ErrorMessages.DEPRECATED_METHOD).build(); - } -} diff --git a/src/main/java/org/gcube/portal/social/networking/ws/methods/v1/Users.java b/src/main/java/org/gcube/portal/social/networking/ws/methods/v1/Users.java deleted file mode 100644 index 074d313..0000000 --- a/src/main/java/org/gcube/portal/social/networking/ws/methods/v1/Users.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.gcube.portal.social.networking.ws.methods.v1; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; - -import org.gcube.common.authorization.library.provider.AuthorizationProvider; -import org.gcube.common.authorization.library.utils.Caller; -import org.gcube.portal.social.networking.liferay.ws.UserManagerWSBuilder; -import org.gcube.portal.social.networking.ws.utils.ErrorMessages; -import org.gcube.portal.social.networking.ws.utils.TokensUtils; -import org.gcube.vomanagement.usermanagement.model.GCubeUser; -import org.slf4j.LoggerFactory; - -/** - * REST interface for the social networking library (users). - */ -@Path("/users") -@Deprecated -public class Users { - @GET - @Path("getUserFullname") - @Produces(MediaType.TEXT_PLAIN) - @Deprecated - public Response getUserUsername(){ - return Response.status(Status.METHOD_NOT_ALLOWED).entity(ErrorMessages.DEPRECATED_METHOD).build(); - } - - @GET - @Path("getUserEmail") - @Produces(MediaType.TEXT_PLAIN) - @Deprecated - public Response getUserEmail(){ - return Response.status(Status.METHOD_NOT_ALLOWED).entity(ErrorMessages.DEPRECATED_METHOD).build(); - } -} diff --git a/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Comments.java b/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Comments.java index fbe9552..60f1b71 100644 --- a/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Comments.java +++ b/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Comments.java @@ -38,6 +38,7 @@ import org.gcube.vomanagement.usermanagement.UserManager; import org.gcube.vomanagement.usermanagement.model.GCubeUser; import org.slf4j.LoggerFactory; +import com.liferay.portlet.journal.FeedIdException; import com.webcohesion.enunciate.metadata.rs.RequestHeader; import com.webcohesion.enunciate.metadata.rs.RequestHeaders; import com.webcohesion.enunciate.metadata.rs.ResponseCode; @@ -48,14 +49,14 @@ import com.webcohesion.enunciate.metadata.rs.StatusCodes; */ @Path("2/comments") @RequestHeaders ({ - @RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"), - @RequestHeader( name = "Content-Type", description = "application/json") - }) + @RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"), + @RequestHeader( name = "Content-Type", description = "application/json") +}) public class Comments { // Logger private static final org.slf4j.Logger logger = LoggerFactory.getLogger(Comments.class); - + /* * Retrieve the list of comments belonging to the post id (key) of the token in the related context * @param key the key as in the POST JSON representation @@ -133,7 +134,7 @@ public class Comments { } /* - * Retrieve comments of the gcube-token's owner in the context bound to the token itself and filter them by date + * Retrieve comments of the token owner in the context bound to the token itself and filter them by date */ @GET @Produces(MediaType.APPLICATION_JSON) @@ -167,6 +168,7 @@ public class Comments { return Response.status(status).entity(responseBean).build(); } +<<<<<<< HEAD /** * Create a new comment to a post having as owner the auth token's owner @@ -248,4 +250,69 @@ public class Comments { } +======= + + /** + * Create a new comment to a post having as owner the auth token's owner + * @param comment The CommentInputBean object + * @return + * @throws ValidationException + */ + @POST + @Path("comment-post") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @StatusCodes ({ + @ResponseCode ( code = 201, condition = "Successfull created, the new comment is reported in the 'result' field of the returned object"), + @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) + }) + public Response writeComment( + @NotNull(message="Comment to write is missing") + @Valid + CommentInputBean comment) throws ValidationException { + Caller caller = AuthorizationProvider.instance.get(); + String username = caller.getClient().getId(); + logger.debug("Request of writing a comment coming from user " + username); + String context = ScopeProvider.instance.get(); + ResponseBean responseBean = new ResponseBean(); + Status status = Status.OK; + + try { + String postId = comment.getPostid(); + String commentText = comment.getText(); + String userid = username; + Date time = new Date(); + + String postOwnerId = CassandraConnection.getInstance().getDatabookStore().readPost(postId).getEntityId(); + Comment theComment = SocialUtils.commentPost(userid, time, postId, commentText, postOwnerId, context); + if (theComment != null) + logger.info("Added comment " + theComment.toString()); + else { + logger.error("Unable to write comment"); + responseBean.setMessage("Unable to write comment, something went wrong please see server log"); + responseBean.setSuccess(false); + status = Status.INTERNAL_SERVER_ERROR; + return Response.status(status).entity(responseBean).build(); + } + + responseBean.setResult(true); + responseBean.setSuccess(true); + return Response.status(status).entity(responseBean).build(); + } catch(FeedIDNotFoundException ex) { + logger.error("Unable to find a post comment", ex); + responseBean.setMessage("Could not reach the DB to write the comment, something went wrong"); + responseBean.setSuccess(false); + status = Status.INTERNAL_SERVER_ERROR; + return Response.status(status).entity(responseBean).build(); + } + catch(Exception e) { + logger.error("Unable to write comment", e); + responseBean.setMessage("Could not reach the DB to write the comment, something went wrong"); + responseBean.setSuccess(false); + status = Status.INTERNAL_SERVER_ERROR; + return Response.status(status).entity(responseBean).build(); + } + } + +>>>>>>> refs/remotes/origin/Feature/24456 } diff --git a/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Likes.java b/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Likes.java index b49eb0f..3f1d849 100644 --- a/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Likes.java +++ b/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Likes.java @@ -1,12 +1,16 @@ package org.gcube.portal.social.networking.ws.methods.v2; +import java.util.Date; import java.util.List; +import javax.validation.Valid; import javax.validation.ValidationException; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; +import javax.ws.rs.Consumes; import javax.ws.rs.GET; +import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; @@ -17,11 +21,15 @@ import javax.ws.rs.core.Response.Status; import org.gcube.common.authorization.library.provider.AuthorizationProvider; import org.gcube.common.authorization.library.utils.Caller; import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.portal.databook.shared.Comment; import org.gcube.portal.databook.shared.Like; +import org.gcube.portal.databook.shared.ex.FeedIDNotFoundException; +import org.gcube.portal.social.networking.ws.inputs.CommentInputBean; import org.gcube.portal.social.networking.ws.outputs.ResponseBean; import org.gcube.portal.social.networking.ws.utils.CassandraConnection; import org.gcube.portal.social.networking.ws.utils.ErrorMessages; import org.gcube.portal.social.networking.ws.utils.Filters; +import org.gcube.portal.social.networking.ws.utils.SocialUtils; import org.slf4j.LoggerFactory; import com.webcohesion.enunciate.metadata.rs.RequestHeader; @@ -34,14 +42,14 @@ import com.webcohesion.enunciate.metadata.rs.StatusCodes; */ @Path("2/likes") @RequestHeaders ({ - @RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"), - @RequestHeader( name = "Content-Type", description = "application/json") - }) + @RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"), + @RequestHeader( name = "Content-Type", description = "application/json") +}) public class Likes { // Logger private static final org.slf4j.Logger logger = LoggerFactory.getLogger(Likes.class); - + /* * Retrieve the list of likes belonging to the post id (key) of the token in the related context * @param key the key as in the POST JSON representation @@ -68,7 +76,7 @@ public class Likes { List likes = null; try{ - logger.info("Retrieving comments for user id " + username); + logger.info("Retrieving likes for user id " + username); likes = CassandraConnection.getInstance().getDatabookStore().getAllLikesByPost(key); responseBean.setResult(likes); responseBean.setSuccess(true); @@ -81,4 +89,83 @@ public class Likes { return Response.status(status).entity(responseBean).build(); } + + /** + * Create a new like to a post in the context of the token + * @param postid The post id to be liked + * @return true if everything is OK + * @throws ValidationException + */ + @POST + @Path("like-post") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @StatusCodes ({ + @ResponseCode ( code = 201, condition = "Successful created, the like operation result is reported in the 'result' field of the returned object"), + @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) + }) + public Response like( + @NotNull(message="Post to like is missing") + @Valid + String postId) throws ValidationException { + Caller caller = AuthorizationProvider.instance.get(); + String username = caller.getClient().getId(); + logger.debug("Request of like coming from user " + username); + String context = ScopeProvider.instance.get(); + ResponseBean responseBean = new ResponseBean(); + Status status = Status.OK; + boolean likeResultOperation = SocialUtils.like(username, postId, context); + if (likeResultOperation) + logger.info("Added like OK to postId " + postId); + else { + logger.error("Unable to like this post"+ postId); + responseBean.setMessage("Unable to like, something went wrong please see server log"); + responseBean.setSuccess(false); + status = Status.INTERNAL_SERVER_ERROR; + return Response.status(status).entity(responseBean).build(); + } + + responseBean.setResult(true); + responseBean.setSuccess(true); + return Response.status(status).entity(responseBean).build(); + } + + /** + * Unlike to a post in the context of the token + * @param postid The post id to be liked + * @return true if everything is OK + * @throws ValidationException + */ + @POST + @Path("unlike-post") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @StatusCodes ({ + @ResponseCode ( code = 201, condition = "The unlike operation result is reported in the 'result' field of the returned object"), + @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) + }) + public Response unlike( + @NotNull(message="Post to unlike is missing") + @Valid + String postId) throws ValidationException { + Caller caller = AuthorizationProvider.instance.get(); + String username = caller.getClient().getId(); + logger.debug("Request of unlike coming from user " + username); + ResponseBean responseBean = new ResponseBean(); + Status status = Status.OK; + boolean likeResultOperation = SocialUtils.unlike(username, postId); + if (likeResultOperation) + logger.info("Unlike OK to postId " + postId); + else { + logger.error("Unable to unlike this post"+ postId); + responseBean.setMessage("Unable to unlike, something went wrong please see server log"); + responseBean.setSuccess(false); + status = Status.INTERNAL_SERVER_ERROR; + return Response.status(status).entity(responseBean).build(); + } + + responseBean.setResult(true); + responseBean.setSuccess(true); + return Response.status(status).entity(responseBean).build(); + } } diff --git a/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Posts.java b/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Posts.java index 424ce18..0e4060a 100644 --- a/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Posts.java +++ b/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Posts.java @@ -151,8 +151,13 @@ public class Posts { @ResponseCode ( code = 500, condition = ErrorMessages.ERROR_IN_API_RESULT) }) public Response getPost(@QueryParam("id") String id) { +<<<<<<< HEAD Caller caller = AuthorizationProvider.instance.get(); String context = ScopeProvider.instance.get(); +======= + String context = ScopeProvider.instance.get(); + Caller caller = AuthorizationProvider.instance.get(); +>>>>>>> refs/remotes/origin/Feature/24456 ResponseBean responseBean = new ResponseBean(); Status status = Status.OK; List posts = new ArrayList<>(); @@ -284,7 +289,7 @@ public class Posts { // try to share logger.debug("Trying to share user post..."); - Feed res = SocialUtils.shareUserUpdate( + Post res = SocialUtils.shareUserUpdate( username, postText, context, @@ -415,8 +420,8 @@ public class Posts { else logger.debug("Disable notification for this application post."); - // write feed + notification if it is the case - Feed written = SocialUtils.shareApplicationUpdate( + // write post + notification if it is the case + Post written = SocialUtils.shareApplicationUpdate( postText, params, previewTitle, diff --git a/src/main/java/org/gcube/portal/social/networking/ws/utils/SocialUtils.java b/src/main/java/org/gcube/portal/social/networking/ws/utils/SocialUtils.java index 6dbca20..e948880 100644 --- a/src/main/java/org/gcube/portal/social/networking/ws/utils/SocialUtils.java +++ b/src/main/java/org/gcube/portal/social/networking/ws/utils/SocialUtils.java @@ -6,8 +6,12 @@ import java.io.StringReader; import java.util.ArrayList; import java.util.Collection; import java.util.Date; +import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import java.util.UUID; @@ -28,12 +32,21 @@ import org.gcube.common.resources.gcore.utils.XPathHelper; import org.gcube.common.scope.api.ScopeProvider; import org.gcube.common.scope.impl.ScopeBean; import org.gcube.portal.databook.shared.ApplicationProfile; +<<<<<<< HEAD import org.gcube.portal.databook.shared.Feed; import org.gcube.portal.databook.shared.FeedType; import org.gcube.portal.databook.shared.Post; +======= +import org.gcube.portal.databook.shared.Comment; +import org.gcube.portal.databook.shared.Like; +import org.gcube.portal.databook.shared.Post; +import org.gcube.portal.databook.shared.PostType; +>>>>>>> refs/remotes/origin/Feature/24456 import org.gcube.portal.databook.shared.PrivacyLevel; import org.gcube.portal.databook.shared.ex.FeedIDNotFoundException; import org.gcube.portal.notifications.bean.GenericItemBean; +import org.gcube.portal.notifications.thread.CommentNotificationsThread; +import org.gcube.portal.notifications.thread.LikeNotificationsThread; import org.gcube.portal.notifications.thread.MentionNotificationsThread; import org.gcube.portal.notifications.thread.PostNotificationsThread; import org.gcube.portal.social.networking.caches.SocialNetworkingSiteFinder; @@ -48,6 +61,10 @@ import org.gcube.social_networking.socialutillibrary.Utils; import org.gcube.socialnetworking.socialtoken.SocialMessageParser; import org.gcube.vomanagement.usermanagement.GroupManager; import org.gcube.vomanagement.usermanagement.UserManager; +import org.gcube.vomanagement.usermanagement.exception.TeamRetrievalFault; +import org.gcube.vomanagement.usermanagement.exception.UserManagementSystemException; +import org.gcube.vomanagement.usermanagement.exception.UserRetrievalFault; +import org.gcube.vomanagement.usermanagement.impl.LiferayUserManager; import org.gcube.vomanagement.usermanagement.model.GCubeUser; import org.slf4j.LoggerFactory; import org.w3c.dom.Node; @@ -56,6 +73,7 @@ import org.xml.sax.InputSource; /** * Utility class. */ +@SuppressWarnings("deprecation") public class SocialUtils { // Logger @@ -64,7 +82,7 @@ public class SocialUtils { public final static String NO_TEXT_FILE_SHARE = "_N0_73X7_SH4R3_"; public final static int CACHING_TIME_TO_EXPIRATION = 2506000;//29 days 6 minutes 40 seconds public final static String DISABLED_USERS_NOTIFICATIONS_NAMESPACE = "dun:"; - + // name of the portlet for vre notification public static final String NEWS_FEED_PORTLET_CLASSNAME = "org.gcube.portlets.user.newsfeed.server.NewsServiceImpl"; @@ -108,7 +126,7 @@ public class SocialUtils { * @param httpImageUrl * @return true upon success, false on failure */ - public static Feed shareApplicationUpdate( + public static Post shareApplicationUpdate( String postText, String uriParams, String previewTitle, @@ -133,7 +151,7 @@ public class SocialUtils { String scope = ScopeProvider.instance.get(); String appId = caller.getClient().getId(); - Feed toWrite = + Post toWrite = buildPost( escapedPostText, uriParams == null ? "" : uriParams, @@ -144,7 +162,7 @@ public class SocialUtils { scope); // try to save it - boolean res = CassandraConnection.getInstance().getDatabookStore().saveAppFeed(toWrite); + boolean res = CassandraConnection.getInstance().getDatabookStore().saveAppPost(toWrite); if(res){ logger.info("Feed correctly written by application " + appId); @@ -222,7 +240,7 @@ public class SocialUtils { * @param previewThumbnailUrl the image url to show in the preview * @return a feed instance ready to be written */ - private static Feed buildPost( + private static Post buildPost( String description, String uriParams, String previewTitle, @@ -237,9 +255,9 @@ public class SocialUtils { if (uriParams != null && uriParams.compareTo("") != 0) uri += "?"+uriParams; - Feed toReturn = new Feed( + Post toReturn = new Post( UUID.randomUUID().toString(), - FeedType.PUBLISH, + PostType.PUBLISH, applicationProfile.getKey(), new Date(), scopeApp, @@ -378,7 +396,7 @@ public class SocialUtils { * @param notifyGroup * @return The written Feed */ - public static Feed shareUserUpdate( + public static Post shareUserUpdate( String userId, String postText, String vreId, @@ -429,12 +447,12 @@ public class SocialUtils { textToPost = escapedPostText; } - Feed toShare = new Feed(UUID.randomUUID().toString(), FeedType.PUBLISH, userId, new Date(), + Post toShare = new Post(UUID.randomUUID().toString(), PostType.PUBLISH, userId, new Date(), vreId, url, urlThumbnail, textToPost, PrivacyLevel.SINGLE_VRE, fullName, email, thumbnailURL, linkTitle, linkDesc, host); logger.info("Attempting to save Post with text: " + textToPost + " Level = " + PrivacyLevel.SINGLE_VRE + " Timeline = " + vreId); - boolean result = CassandraConnection.getInstance().getDatabookStore().saveUserFeed(toShare); + boolean result = CassandraConnection.getInstance().getDatabookStore().saveUserPost(toShare); if(vreId != null && vreId.compareTo("") != 0 && result) { @@ -501,5 +519,220 @@ public class SocialUtils { } return toShare; } +<<<<<<< HEAD +======= + /** + * Allows to comment post in a certain vre. + + * @param userid the username + * @param time the date and time of the comment + * @param postId the key of the post that was commented + * @param commentText the text as it is, it will be parsed + * @param postOwnerId the username of the user who created the post that was commented + * @param context the VRE context + * + * @return the Comment instance if ok, null if somwthign went KO + * @throws FeedIDNotFoundException + */ + public static Comment commentPost(String userid, Date time, String postId, String commentText, String postOwnerId, String context) throws FeedIDNotFoundException { + + SocialMessageParser messageParser = new SocialMessageParser(commentText); + String escapedCommentText = messageParser.getParsedMessage(); + //check if any mention exists + ArrayList mentionedUsers = getUsersFromUsernames(Utils.getMentionedUsernames(commentText)); + ArrayList mentionedUsersToConvertInHTML = convertToItemBean(mentionedUsers); + SocialNetworkingSite site = SocialNetworkingSiteFinder.getSocialNetworkingSiteFromScope(ScopeProvider.instance.get()); + + escapedCommentText = Utils.convertMentionUsernamesAnchorHTML(escapedCommentText, mentionedUsersToConvertInHTML, site.getSiteURL(), site.getSiteLandingPagePath()); + + // retrieve user information + GCubeUser user; + UserManager uManager = UserManagerWSBuilder.getInstance().getUserManager(); + try { + user = uManager.getUserByUsername(userid); + } catch(Exception e){ + logger.error("Unable to get user informations, comment write fails.", e); + return null; + } + String commentKey = UUID.randomUUID().toString(); // a unique id that goes in the DB + String email = user.getEmail(); + String fullName = user.getFirstName() + " " + user.getLastName(); + String thumbnailURL = user.getUserAvatarURL(); + + Comment theComment = new Comment(commentKey, userid, time, postId, escapedCommentText, fullName, thumbnailURL); + logger.info("Attempting to save Comment with text: " + commentText + " postid="+postId); + + boolean result = CassandraConnection.getInstance().getDatabookStore().addComment(theComment); + logger.info("Added comment? " + theComment.toString() + " Result is " +result); + + if (!result) + return null; + + //if the comment was correctly delivered notify users involved + SocialNetworkingUser socialUser = new SocialNetworkingUser(userid, email, fullName, thumbnailURL); + + NotificationsManager nm = new ApplicationNotificationsManager(uManager, site, context, socialUser, NEWS_FEED_PORTLET_CLASSNAME); + + //if the user who commented this post is not the user who posted it notify the poster user (Post owner) + logger.info("The post creator is " + postOwnerId); + if (! user.getUsername().equals(postOwnerId)) { + boolean resultNotifyOwnComment = nm.notifyOwnCommentReply(postOwnerId, postId, escapedCommentText, theComment.getKey()); + logger.info("Comment Notification to post creator added? " + resultNotifyOwnComment); + } + //if there are users who liked this post they get notified, asynchronously with this thread + ArrayList likes = getAllLikesByPost(postId); + Thread likesThread = new Thread(new LikeNotificationsThread(escapedCommentText, nm, likes, postOwnerId, theComment.getKey())); + likesThread.start(); + + //notify the other users who commented this post (excluding the ones above) + Thread commentsNotificationthread = new Thread(new CommentNotificationsThread( + CassandraConnection.getInstance().getDatabookStore(), + uManager, user.getUsername(), theComment.getFeedid(), escapedCommentText, nm, postOwnerId, theComment.getKey(), likes)); + commentsNotificationthread.start(); + + //send the notification to the mentioned users, if any + if (mentionedUsers != null && mentionedUsers.size() > 0) { + ArrayList toPass = new ArrayList(); + + + // among the mentionedUsers there could be groups of people + Map uniqueUsersToNotify = new HashMap<>(); + UserManager um = new LiferayUserManager(); + + for (ItemBean bean : mentionedUsersToConvertInHTML) { + + if(bean.isItemGroup()){ + + // retrieve the users of this group + try { + List teamUsers = um.listUsersByTeam(Long.parseLong(bean.getId())); + + for (GCubeUser userTeam : teamUsers) { + if(!uniqueUsersToNotify.containsKey(userTeam.getUsername())) + uniqueUsersToNotify.put(userTeam.getUsername(), new ItemBean(userTeam.getUserId()+"", + userTeam.getUsername(), userTeam.getFullname(), userTeam.getUserAvatarURL())); + } + + } catch (NumberFormatException + | UserManagementSystemException + | TeamRetrievalFault | UserRetrievalFault e) { + logger.error("Unable to retrieve team information", e); + } + + }else{ + // it is a user, just add to the hashmap + if(!uniqueUsersToNotify.containsKey(bean.getName())) + uniqueUsersToNotify.put(bean.getName(), bean); + + } + } + + // iterate over the hashmap + Iterator> userMapIterator = uniqueUsersToNotify.entrySet().iterator(); + while (userMapIterator.hasNext()) { + Map.Entry userEntry = (Map.Entry) userMapIterator + .next(); + ItemBean userBean = userEntry.getValue(); + toPass.add(new GenericItemBean(userBean.getId(), userBean.getName(), userBean.getAlternativeName(), userBean.getThumbnailURL())); + } + + Thread thread = new Thread(new MentionNotificationsThread(theComment.getFeedid(), escapedCommentText, nm, null, toPass)); + thread.start(); + } + return theComment; + } + + private static ArrayList getAllLikesByPost(String postid) { + ArrayList toReturn = (ArrayList) CassandraConnection.getInstance().getDatabookStore().getAllLikesByPost(postid); + logger.debug("Asking likes for " + postid); + for (Like like : toReturn) { + // retrieve user information + GCubeUser user; + UserManager uManager = UserManagerWSBuilder.getInstance().getUserManager(); + try { + user = uManager.getUserByUsername(like.getUserid()); + } catch(Exception e){ + logger.error("Unable to get user informations, comment write fails.", e); + return null; + } + String thumbnailURL = user.getUserAvatarURL(); + + like.setThumbnailURL(thumbnailURL == null ? "" : thumbnailURL); + } + return toReturn; + } + + public static boolean like(String username, String postid, String context) { + boolean likeCommitResult = false; + // retrieve user information + GCubeUser user; + UserManager uManager = UserManagerWSBuilder.getInstance().getUserManager(); + try { + user = uManager.getUserByUsername(username); + } catch(Exception e){ + logger.error("Unable to get user informations, like write fails.", e); + return false; + } + String email = user.getEmail(); + String fullName = user.getFirstName() + " " + user.getLastName(); + String thumbnailURL = user.getUserAvatarURL(); + SocialNetworkingUser socialUser = new SocialNetworkingUser(user.getUsername(), email, fullName, thumbnailURL); + + Like toLike = new Like(UUID.randomUUID().toString(), user.getUsername(), + new Date(), postid, user.getFullname(), user.getUserAvatarURL()); + Post thePost = null; + try { + thePost = CassandraConnection.getInstance().getDatabookStore().readPost(postid); + likeCommitResult = CassandraConnection.getInstance().getDatabookStore().like(toLike); + } catch (Exception e) { + logger.error("Post not Found for this like ot could not like the post " + e.getMessage()); + return false; + } + //if the like was correctly delivered notify the user who made the post + + boolean resultNotifyLike =false; + if (likeCommitResult) { + SocialNetworkingSite site = SocialNetworkingSiteFinder.getSocialNetworkingSiteFromScope(ScopeProvider.instance.get()); + NotificationsManager nm = new ApplicationNotificationsManager(UserManagerWSBuilder.getInstance().getUserManager(), site, context, socialUser, NEWS_FEED_PORTLET_CLASSNAME); + + String postText = thePost.getDescription(); + String postOwnerId = thePost.getEntityId(); + SocialMessageParser messageParser = new SocialMessageParser(postText); + String escapedPostText = messageParser.getParsedMessage(); + + //if the user who liked this post is not the user who posted it notify the poster user (Post owner) + logger.info("The post creator is " + postOwnerId); + if (! user.getUsername().equals(postOwnerId)) { + resultNotifyLike = nm.notifyLikedPost(postOwnerId, postid, escapedPostText); + logger.info("Like Notification to post creator added? " + resultNotifyLike); + } + } + return likeCommitResult && resultNotifyLike; + } + + public static boolean unlike(String username, String postid) { + boolean unlikeCommitResult = false; + // retrieve user information + GCubeUser user; + UserManager uManager = UserManagerWSBuilder.getInstance().getUserManager(); + try { + user = uManager.getUserByUsername(username); + } catch(Exception e){ + logger.error("Unable to get user informations, unlike write fails.", e); + return false; + } + String fullName = user.getFirstName() + " " + user.getLastName(); + String thumbnailURL = user.getUserAvatarURL(); + try { + + unlikeCommitResult = CassandraConnection.getInstance().getDatabookStore().unlike(username, fullName, thumbnailURL); + } catch (Exception e) { + logger.error("Post not Found for this like ot could not unlike the post " + e.getMessage()); + return false; + } + + return unlikeCommitResult; + } +>>>>>>> refs/remotes/origin/Feature/24456 }