2019-04-05 16:39:46 +02:00
package org.gcube.portal.social.networking.ws.utils ;
import static org.gcube.resources.discovery.icclient.ICFactory.client ;
import java.io.StringReader ;
2019-09-19 11:24:20 +02:00
import java.util.ArrayList ;
import java.util.Collection ;
2019-04-05 16:39:46 +02:00
import java.util.Date ;
2023-02-08 14:29:57 +01:00
import java.util.HashMap ;
2019-04-05 16:39:46 +02:00
import java.util.HashSet ;
2023-02-08 14:29:57 +01:00
import java.util.Iterator ;
2019-04-05 16:39:46 +02:00
import java.util.List ;
2023-02-08 14:29:57 +01:00
import java.util.Map ;
2023-02-09 12:47:01 +01:00
import java.util.Map.Entry ;
2019-09-19 11:24:20 +02:00
import java.util.Set ;
2019-04-05 16:39:46 +02:00
import java.util.UUID ;
import javax.xml.parsers.DocumentBuilder ;
import javax.xml.parsers.DocumentBuilderFactory ;
import org.gcube.applicationsupportlayer.social.ApplicationNotificationsManager ;
import org.gcube.applicationsupportlayer.social.NotificationsManager ;
import org.gcube.applicationsupportlayer.social.ex.ApplicationProfileNotFoundException ;
import org.gcube.applicationsupportlayer.social.shared.SocialNetworkingSite ;
import org.gcube.applicationsupportlayer.social.shared.SocialNetworkingUser ;
import org.gcube.common.authorization.library.utils.Caller ;
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 ;
2023-02-08 14:29:57 +01:00
import org.gcube.portal.databook.shared.Comment ;
import org.gcube.portal.databook.shared.Like ;
2023-02-07 11:42:49 +01:00
import org.gcube.portal.databook.shared.Post ;
import org.gcube.portal.databook.shared.PostType ;
2019-04-05 16:39:46 +02:00
import org.gcube.portal.databook.shared.PrivacyLevel ;
import org.gcube.portal.databook.shared.ex.FeedIDNotFoundException ;
2019-09-19 11:24:20 +02:00
import org.gcube.portal.notifications.bean.GenericItemBean ;
2023-02-08 14:29:57 +01:00
import org.gcube.portal.notifications.thread.CommentNotificationsThread ;
import org.gcube.portal.notifications.thread.LikeNotificationsThread ;
2019-09-19 11:24:20 +02:00
import org.gcube.portal.notifications.thread.MentionNotificationsThread ;
2019-04-05 16:39:46 +02:00
import org.gcube.portal.notifications.thread.PostNotificationsThread ;
import org.gcube.portal.social.networking.caches.SocialNetworkingSiteFinder ;
import org.gcube.portal.social.networking.liferay.ws.GroupManagerWSBuilder ;
import org.gcube.portal.social.networking.liferay.ws.UserManagerWSBuilder ;
2019-09-19 11:24:20 +02:00
import org.gcube.portlets.widgets.pickitem.shared.ItemBean ;
2019-04-05 16:39:46 +02:00
import org.gcube.resources.discovery.client.api.DiscoveryClient ;
import org.gcube.resources.discovery.client.queries.api.Query ;
import org.gcube.resources.discovery.client.queries.impl.QueryBox ;
2019-09-19 11:24:20 +02:00
import org.gcube.social_networking.socialutillibrary.Utils ;
2019-04-08 19:09:22 +02:00
import org.gcube.socialnetworking.socialtoken.SocialMessageParser ;
2019-04-05 16:39:46 +02:00
import org.gcube.vomanagement.usermanagement.GroupManager ;
import org.gcube.vomanagement.usermanagement.UserManager ;
2023-02-08 14:29:57 +01:00
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 ;
2019-04-05 16:39:46 +02:00
import org.gcube.vomanagement.usermanagement.model.GCubeUser ;
import org.slf4j.LoggerFactory ;
import org.w3c.dom.Node ;
import org.xml.sax.InputSource ;
/ * *
* Utility class .
* /
2023-02-08 14:29:57 +01:00
@SuppressWarnings ( " deprecation " )
2019-04-05 16:39:46 +02:00
public class SocialUtils {
// Logger
private static final org . slf4j . Logger logger = LoggerFactory . getLogger ( SocialUtils . class ) ;
public final static String NO_TEXT_FILE_SHARE = " _N0_73X7_SH4R3_ " ;
2022-09-15 14:24:04 +02:00
public final static int CACHING_TIME_TO_EXPIRATION = 2506000 ; //29 days 6 minutes 40 seconds
public final static String DISABLED_USERS_NOTIFICATIONS_NAMESPACE = " dun: " ;
2023-02-08 14:29:57 +01:00
2019-04-05 16:39:46 +02:00
// name of the portlet for vre notification
public static final String NEWS_FEED_PORTLET_CLASSNAME = " org.gcube.portlets.user.newsfeed.server.NewsServiceImpl " ;
2019-09-19 11:24:20 +02:00
/ * *
*
* @param mentions the set of string containing the usernames
* @return a list of existing usernames associated with their fullnames
* /
private static ArrayList < GenericItemBean > getUsersFromUsernames ( Set < String > mentions ) {
if ( mentions . isEmpty ( ) )
return new ArrayList < > ( ) ;
ArrayList < GenericItemBean > toReturn = new ArrayList < > ( ) ;
UserManager uManager = UserManagerWSBuilder . getInstance ( ) . getUserManager ( ) ;
for ( String username : mentions ) {
try {
GCubeUser user = uManager . getUserByUsername ( username ) ;
String fullName = user . getFirstName ( ) + " " + user . getLastName ( ) ;
toReturn . add ( new GenericItemBean ( " " + user . getUserId ( ) , username , fullName , " " ) ) ;
} catch ( Exception e ) {
logger . error ( " Unable to get user informations for username= " + username ) ;
}
}
return toReturn ;
}
// utility method
private static ArrayList < ItemBean > convertToItemBean ( Collection < GenericItemBean > items ) {
ArrayList < ItemBean > toReturn = new ArrayList < > ( items . size ( ) ) ;
for ( GenericItemBean item : items ) {
toReturn . add ( new ItemBean ( item . getId ( ) , item . getName ( ) , item . getAlternativeName ( ) , item . getThumbnailURL ( ) ) ) ;
}
return toReturn ;
}
2019-04-05 16:39:46 +02:00
/ * *
* Method used when an application needs to publish something .
2023-11-13 11:33:37 +01:00
* @param postText
2019-04-05 16:39:46 +02:00
* @param uriParams
* @param previewTitle
* @param previewDescription
* @param httpImageUrl
* @return true upon success , false on failure
* /
2023-02-08 14:29:57 +01:00
public static Post shareApplicationUpdate (
2019-04-05 16:39:46 +02:00
String postText ,
String uriParams ,
String previewTitle ,
String previewDescription ,
String httpImageUrl ,
ApplicationProfile applicationProfile ,
Caller caller ,
boolean notifyGroup
) {
2019-04-08 19:09:22 +02:00
SocialMessageParser messageParser = new SocialMessageParser ( postText ) ;
2019-09-19 11:24:20 +02:00
String escapedPostText = messageParser . getParsedMessage ( ) ;
2019-04-08 19:09:22 +02:00
List < String > hashtags = messageParser . getHashtags ( ) ;
2019-09-19 11:24:20 +02:00
ArrayList < GenericItemBean > mentionedUsers = getUsersFromUsernames ( Utils . getMentionedUsernames ( postText ) ) ;
ArrayList < ItemBean > mentionedUsersToConvertInHTML = convertToItemBean ( mentionedUsers ) ;
SocialNetworkingSite site = SocialNetworkingSiteFinder . getSocialNetworkingSiteFromScope ( ScopeProvider . instance . get ( ) ) ;
escapedPostText = Utils . convertMentionUsernamesAnchorHTML ( escapedPostText , mentionedUsersToConvertInHTML , site . getSiteURL ( ) , site . getSiteLandingPagePath ( ) ) ;
2024-04-22 11:19:17 +02:00
logger . debug ( " *** Escaped post text is " + escapedPostText ) ;
2019-09-19 11:24:20 +02:00
2019-04-08 19:09:22 +02:00
String scope = ScopeProvider . instance . get ( ) ;
2019-09-19 11:24:20 +02:00
String appId = caller . getClient ( ) . getId ( ) ;
2023-02-08 14:29:57 +01:00
Post toWrite =
2019-09-19 11:24:20 +02:00
buildPost (
escapedPostText ,
2019-04-05 16:39:46 +02:00
uriParams = = null ? " " : uriParams ,
previewTitle = = null ? " " : previewTitle ,
previewDescription = = null ? " " : previewDescription ,
httpImageUrl = = null ? " " : httpImageUrl ,
applicationProfile ,
scope ) ;
// try to save it
2023-02-08 14:29:57 +01:00
boolean res = CassandraConnection . getInstance ( ) . getDatabookStore ( ) . saveAppPost ( toWrite ) ;
2019-04-05 16:39:46 +02:00
if ( res ) {
2024-04-22 11:19:17 +02:00
logger . debug ( " Feed correctly written by application " + appId ) ;
2019-04-05 16:39:46 +02:00
2019-04-08 19:09:22 +02:00
// wait a bit before saving hashtags
if ( hashtags ! = null & & ! hashtags . isEmpty ( ) )
new Thread ( ( ) - > {
try {
Thread . sleep ( 1000 ) ;
CassandraConnection . getInstance ( ) . getDatabookStore ( ) . saveHashTags ( toWrite . getKey ( ) , scope , hashtags ) ;
} catch ( Exception e1 ) {
logger . error ( " Failed to save hashtags in Cassandra " , e1 ) ;
}
} ) . start ( ) ;
2019-04-05 16:39:46 +02:00
2019-09-19 11:24:20 +02:00
// build the notification manager
SocialNetworkingUser user = new SocialNetworkingUser ( appId , " " , applicationProfile . getName ( ) , applicationProfile . getImageUrl ( ) ) ;
NotificationsManager nm = new ApplicationNotificationsManager (
UserManagerWSBuilder . getInstance ( ) . getUserManager ( ) ,
site ,
scope ,
user ,
NEWS_FEED_PORTLET_CLASSNAME ) ;
if ( ! mentionedUsers . isEmpty ( ) )
new Thread ( new MentionNotificationsThread ( toWrite . getKey ( ) , toWrite . getDescription ( ) , nm , null , mentionedUsers ) ) . start ( ) ;
2019-04-05 16:39:46 +02:00
if ( notifyGroup ) {
logger . debug ( " Sending notifications for " + appId + " " + scope ) ;
try {
String name = new ScopeBean ( scope ) . name ( ) ; // scope such as devVRE
// retrieve group information
GroupManager gManager = GroupManagerWSBuilder . getInstance ( ) . getGroupManager ( ) ;
long groupId = gManager . getGroupId ( name ) ;
String groupName = gManager . getGroup ( groupId ) . getGroupName ( ) ;
logger . debug ( " Company id and name " + groupId + " " + groupName ) ;
// start notification thread
new Thread ( new PostNotificationsThread (
UserManagerWSBuilder . getInstance ( ) . getUserManager ( ) ,
toWrite . getKey ( ) ,
toWrite . getDescription ( ) ,
" " + groupId ,
nm ,
new HashSet < String > ( hashtags ) ,
new HashSet < String > ( ) )
) . start ( ) ;
} catch ( Exception e ) {
logger . debug ( " Feed succesfully created but unable to send notifications. " ) ;
}
}
return toWrite ;
}
else
return null ;
}
/ * *
* Build an ApplicationProfile Feed .
*
* @param description add a description for the update you are sharing
* @param uriParams the additional parameters your applicationProfile needs to open the subject of this update e . g . id = 12345 & type = foo
* @param previewTitle the title to show in the preview
* @param previewDescription the description to show in the preview
* @param previewThumbnailUrl the image url to show in the preview
* @return a feed instance ready to be written
* /
2023-02-08 14:29:57 +01:00
private static Post buildPost (
2019-04-05 16:39:46 +02:00
String description ,
String uriParams ,
String previewTitle ,
String previewDescription ,
String previewThumbnailUrl ,
ApplicationProfile applicationProfile ,
String scopeApp ) {
String uri = applicationProfile . getUrl ( ) ;
//add the GET params if necessary
if ( uriParams ! = null & & uriParams . compareTo ( " " ) ! = 0 )
uri + = " ? " + uriParams ;
2023-02-08 14:29:57 +01:00
Post toReturn = new Post (
2019-04-05 16:39:46 +02:00
UUID . randomUUID ( ) . toString ( ) ,
2023-02-08 14:29:57 +01:00
PostType . PUBLISH ,
2019-04-05 16:39:46 +02:00
applicationProfile . getKey ( ) ,
new Date ( ) ,
scopeApp ,
uri ,
previewThumbnailUrl ,
description ,
PrivacyLevel . SINGLE_VRE ,
applicationProfile . getName ( ) ,
" no-email " ,
applicationProfile . getImageUrl ( ) ,
previewTitle ,
previewDescription ,
" " ,
true ) ;
return toReturn ;
}
/ * *
* This method looks up the applicationProfile profile among the ones available in the infrastructure
* @param idApp as identifier of your application ( as reported in the ApplicationProfile )
* @param scopeApp the scope of the application
* /
public static ApplicationProfile getProfileFromInfrastrucure ( String idApp , String scopeApp ) {
ScopeBean scope = new ScopeBean ( scopeApp ) ;
logger . debug ( " Trying to fetch applicationProfile profile from the infrastructure for " + idApp + " scope: " + scope ) ;
// set the scope of the root infrastructure
String rootInfrastructure = scopeApp . split ( " / " ) [ 1 ] ;
ScopeProvider . instance . set ( " / " + rootInfrastructure ) ;
try {
ApplicationProfile toReturn = new ApplicationProfile ( ) ;
Query q = new QueryBox ( " for $profile in collection('/db/Profiles/GenericResource')//Resource " +
" where $profile/Profile/SecondaryType/string() eq 'ApplicationProfile' and $profile/Profile/Body/AppId/string() " +
" eq ' " + idApp + " ' " +
" return $profile " ) ;
DiscoveryClient < String > client = client ( ) ;
List < String > appProfile = client . submit ( q ) ;
if ( appProfile = = null | | appProfile . size ( ) = = 0 )
throw new Exception ( " Your applicationProfile is not registered in the infrastructure " ) ;
else {
String elem = appProfile . get ( 0 ) ;
DocumentBuilder docBuilder = DocumentBuilderFactory . newInstance ( ) . newDocumentBuilder ( ) ;
Node node = docBuilder . parse ( new InputSource ( new StringReader ( elem ) ) ) . getDocumentElement ( ) ;
XPathHelper helper = new XPathHelper ( node ) ;
List < String > currValue = null ;
currValue = helper . evaluate ( " /Resource/Profile/Name/text() " ) ;
if ( currValue ! = null & & currValue . size ( ) > 0 ) {
toReturn . setName ( currValue . get ( 0 ) ) ;
}
else throw new ApplicationProfileNotFoundException ( " Your applicationProfile NAME was not found in the profile " ) ;
currValue = helper . evaluate ( " /Resource/Profile/Description/text() " ) ;
if ( currValue ! = null & & currValue . size ( ) > 0 ) {
toReturn . setDescription ( currValue . get ( 0 ) ) ;
}
else logger . warn ( " No Description exists for " + toReturn . getName ( ) ) ;
currValue = helper . evaluate ( " /Resource/Profile/Body/AppId/text() " ) ;
if ( currValue ! = null & & currValue . size ( ) > 0 ) {
toReturn . setKey ( currValue . get ( 0 ) ) ;
}
else throw new ApplicationProfileNotFoundException ( " Your applicationProfile ID n was not found in the profile, consider adding <AppId> element in <Body> " ) ;
currValue = helper . evaluate ( " /Resource/Profile/Body/ThumbnailURL/text() " ) ;
if ( currValue ! = null & & currValue . size ( ) > 0 ) {
toReturn . setImageUrl ( currValue . get ( 0 ) ) ;
}
else throw new Exception ( " Your applicationProfile Image Url was not found in the profile, consider adding <ThumbnailURL> element in <Body> " ) ;
currValue = helper . evaluate ( " /Resource/Profile/Body/EndPoint/Scope/text() " ) ;
if ( currValue ! = null & & currValue . size ( ) > 0 ) {
List < String > scopes = currValue ;
boolean foundUrl = false ;
for ( int i = 0 ; i < scopes . size ( ) ; i + + ) {
if ( currValue . get ( i ) . trim ( ) . compareTo ( scope . toString ( ) ) = = 0 ) {
toReturn . setUrl ( helper . evaluate ( " /Resource/Profile/Body/EndPoint/URL/text() " ) . get ( i ) ) ;
toReturn . setScope ( scope . toString ( ) ) ;
foundUrl = true ;
break ;
}
}
if ( ! foundUrl )
throw new ApplicationProfileNotFoundException ( " Your applicationProfile URL was not found in the profile for Scope: " + scope . toString ( ) ) ;
}
else throw new ApplicationProfileNotFoundException ( " Your applicationProfile EndPoint was not found in the profile, consider adding <EndPoint><Scope> element in <Body> " ) ;
logger . debug ( " Returning " + toReturn ) ;
return toReturn ;
}
} catch ( Exception e ) {
logger . error ( " Error while trying to fetch applicationProfile profile from the infrastructure " , e ) ;
} finally {
// set the scope back
ScopeProvider . instance . set ( scopeApp ) ;
}
return null ;
}
/ * *
* Allows user to post a feed in a certain vre .
* @param userId
* @param postText
* @param vreId
* @param previewTitle
* @param previewDescription
* @param previewHost
* @param previewUrl
* @param urlThumbnail
* @param notifyGroup
* @return The written Feed
* /
2023-02-07 11:42:49 +01:00
public static Post shareUserUpdate (
2019-04-05 16:39:46 +02:00
String userId ,
String postText ,
String vreId ,
String previewTitle ,
String previewDescription ,
String previewHost ,
String previewUrl ,
String urlThumbnail ,
2019-09-19 11:24:20 +02:00
boolean notifyGroup ) {
2019-04-05 16:39:46 +02:00
2019-04-08 19:09:22 +02:00
SocialMessageParser messageParser = new SocialMessageParser ( postText ) ;
2019-09-19 11:24:20 +02:00
String escapedPostText = messageParser . getParsedMessage ( ) ;
2019-04-08 19:09:22 +02:00
List < String > hashtags = messageParser . getHashtags ( ) ;
2019-09-19 11:24:20 +02:00
//check if any mention exists
ArrayList < GenericItemBean > mentionedUsers = getUsersFromUsernames ( Utils . getMentionedUsernames ( postText ) ) ;
ArrayList < ItemBean > mentionedUsersToConvertInHTML = convertToItemBean ( mentionedUsers ) ;
SocialNetworkingSite site = SocialNetworkingSiteFinder . getSocialNetworkingSiteFromScope ( ScopeProvider . instance . get ( ) ) ;
escapedPostText = Utils . convertMentionUsernamesAnchorHTML ( escapedPostText , mentionedUsersToConvertInHTML , site . getSiteURL ( ) , site . getSiteLandingPagePath ( ) ) ;
2019-04-05 16:39:46 +02:00
GCubeUser user ;
// retrieve group information
UserManager uManager = UserManagerWSBuilder . getInstance ( ) . getUserManager ( ) ;
2019-09-19 11:24:20 +02:00
try {
2019-04-05 16:39:46 +02:00
user = uManager . getUserByUsername ( userId ) ;
2019-09-19 11:24:20 +02:00
} catch ( Exception e ) {
logger . error ( " Unable to get user informations, post write fails. " , e ) ;
2019-04-05 16:39:46 +02:00
return null ;
}
String email = user . getEmail ( ) ;
String fullName = user . getFirstName ( ) + " " + user . getLastName ( ) ;
String thumbnailURL = user . getUserAvatarURL ( ) ;
String linkTitle = previewTitle = = null ? " " : previewTitle ;
String linkDesc = previewDescription = = null ? " " : previewDescription ;
String host = previewHost = = null ? " " : previewHost ;
String url = previewUrl = = null ? " " : previewUrl ;
if ( urlThumbnail = = null )
urlThumbnail = " null " ;
//this means the user has shared a file without text in it.
String textToPost = " " ;
2019-09-19 11:24:20 +02:00
if ( escapedPostText . trim ( ) . compareTo ( NO_TEXT_FILE_SHARE ) = = 0 ) {
2019-04-05 16:39:46 +02:00
textToPost = org . gcube . social_networking . socialutillibrary . Utils . convertFileNameAnchorHTML ( url ) ;
} else {
2019-09-19 11:24:20 +02:00
textToPost = escapedPostText ;
2019-04-05 16:39:46 +02:00
}
2023-02-07 11:42:49 +01:00
Post toShare = new Post ( UUID . randomUUID ( ) . toString ( ) , PostType . PUBLISH , userId , new Date ( ) ,
2019-04-05 16:39:46 +02:00
vreId , url , urlThumbnail , textToPost , PrivacyLevel . SINGLE_VRE , fullName , email , thumbnailURL , linkTitle , linkDesc , host ) ;
2024-04-22 11:19:17 +02:00
logger . debug ( " Attempting to save Post with text: " + textToPost + " Level = " + PrivacyLevel . SINGLE_VRE + " Timeline = " + vreId ) ;
2019-04-05 16:39:46 +02:00
2023-02-07 11:42:49 +01:00
boolean result = CassandraConnection . getInstance ( ) . getDatabookStore ( ) . saveUserPost ( toShare ) ;
2019-04-05 16:39:46 +02:00
if ( vreId ! = null & & vreId . compareTo ( " " ) ! = 0 & & result ) {
logger . trace ( " Attempting to write onto " + vreId ) ;
try {
try {
2024-04-22 11:19:17 +02:00
logger . debug ( " Sleeping waiting for cassandra's update " ) ;
2019-04-05 16:39:46 +02:00
Thread . sleep ( 1000 ) ;
} catch ( Exception e ) {
logger . error ( e . toString ( ) ) ;
}
CassandraConnection . getInstance ( ) . getDatabookStore ( ) . saveFeedToVRETimeline ( toShare . getKey ( ) , vreId ) ;
if ( hashtags ! = null & & ! hashtags . isEmpty ( ) )
CassandraConnection . getInstance ( ) . getDatabookStore ( ) . saveHashTags ( toShare . getKey ( ) , vreId , hashtags ) ;
} catch ( FeedIDNotFoundException e ) {
logger . error ( " Error writing onto VRES Time Line " + vreId ) ;
}
logger . trace ( " Success writing onto " + vreId ) ;
}
if ( ! result )
return null ;
2019-09-19 11:24:20 +02:00
SocialNetworkingUser socialUser =
new SocialNetworkingUser ( userId , email , fullName , thumbnailURL ) ;
NotificationsManager nm = new ApplicationNotificationsManager ( UserManagerWSBuilder . getInstance ( ) . getUserManager ( ) , site , vreId , socialUser , NEWS_FEED_PORTLET_CLASSNAME ) ;
if ( ! mentionedUsers . isEmpty ( ) )
new Thread ( new MentionNotificationsThread ( toShare . getKey ( ) , toShare . getDescription ( ) , nm , null , mentionedUsers ) ) . start ( ) ;
2019-04-05 16:39:46 +02:00
//send the notification about this posts to everyone in the group if notifyGroup is true
if ( vreId ! = null & & vreId . compareTo ( " " ) ! = 0 & & notifyGroup ) {
2019-09-19 11:24:20 +02:00
try {
2019-04-05 16:39:46 +02:00
// retrieve group information
GroupManager gManager = GroupManagerWSBuilder . getInstance ( ) . getGroupManager ( ) ;
// handle the scope
String name = new ScopeBean ( vreId ) . name ( ) ; // scope such as devVR
long groupId = gManager . getGroupId ( name ) ;
String groupName = gManager . getGroup ( groupId ) . getGroupName ( ) ;
logger . debug ( " Company id and name " + groupId + " " + groupName ) ;
new Thread (
new PostNotificationsThread (
UserManagerWSBuilder . getInstance ( ) . getUserManager ( ) ,
toShare . getKey ( ) ,
toShare . getDescription ( ) ,
" " + groupId ,
nm ,
new HashSet < String > ( ) ,
new HashSet < String > ( hashtags ) )
) . start ( ) ;
2019-09-19 11:24:20 +02:00
logger . debug ( " Start sending notifications for post written by " + userId ) ;
2019-04-05 16:39:46 +02:00
} catch ( Exception e ) {
logger . error ( " Unable to notify users " , e ) ;
}
}
return toShare ;
}
2023-02-08 14:29:57 +01:00
/ * *
* 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 {
2023-02-09 12:47:01 +01:00
2023-02-08 14:29:57 +01:00
SocialMessageParser messageParser = new SocialMessageParser ( commentText ) ;
String escapedCommentText = messageParser . getParsedMessage ( ) ;
//check if any mention exists
ArrayList < GenericItemBean > mentionedUsers = getUsersFromUsernames ( Utils . getMentionedUsernames ( commentText ) ) ;
ArrayList < ItemBean > mentionedUsersToConvertInHTML = convertToItemBean ( mentionedUsers ) ;
SocialNetworkingSite site = SocialNetworkingSiteFinder . getSocialNetworkingSiteFromScope ( ScopeProvider . instance . get ( ) ) ;
escapedCommentText = Utils . convertMentionUsernamesAnchorHTML ( escapedCommentText , mentionedUsersToConvertInHTML , site . getSiteURL ( ) , site . getSiteLandingPagePath ( ) ) ;
2023-02-09 12:47:01 +01:00
2023-02-08 14:29:57 +01:00
// 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 ( ) ;
2023-02-09 12:47:01 +01:00
2023-02-08 14:29:57 +01:00
Comment theComment = new Comment ( commentKey , userid , time , postId , escapedCommentText , fullName , thumbnailURL ) ;
2024-04-22 11:19:17 +02:00
logger . debug ( " Attempting to save Comment with text: " + commentText + " postid= " + postId ) ;
2023-02-09 12:47:01 +01:00
2023-02-08 14:29:57 +01:00
boolean result = CassandraConnection . getInstance ( ) . getDatabookStore ( ) . addComment ( theComment ) ;
2024-04-22 11:19:17 +02:00
logger . debug ( " Added comment? " + theComment . toString ( ) + " Result is " + result ) ;
2023-02-09 12:47:01 +01:00
2023-02-08 14:29:57 +01:00
if ( ! result )
return null ;
2023-02-09 12:47:01 +01:00
2023-02-08 14:29:57 +01:00
//if the comment was correctly delivered notify users involved
SocialNetworkingUser socialUser = new SocialNetworkingUser ( userid , email , fullName , thumbnailURL ) ;
2023-02-09 12:47:01 +01:00
2023-02-08 16:21:17 +01:00
NotificationsManager nm = new ApplicationNotificationsManager ( uManager , site , context , socialUser , NEWS_FEED_PORTLET_CLASSNAME ) ;
2023-02-08 14:29:57 +01:00
//if the user who commented this post is not the user who posted it notify the poster user (Post owner)
2024-04-22 11:19:17 +02:00
logger . debug ( " The post creator is " + postOwnerId ) ;
2023-02-08 16:21:17 +01:00
if ( ! user . getUsername ( ) . equals ( postOwnerId ) ) {
2023-02-08 14:29:57 +01:00
boolean resultNotifyOwnComment = nm . notifyOwnCommentReply ( postOwnerId , postId , escapedCommentText , theComment . getKey ( ) ) ;
2024-04-22 11:19:17 +02:00
logger . debug ( " Comment Notification to post creator added? " + resultNotifyOwnComment ) ;
2023-02-08 14:29:57 +01:00
}
//if there are users who liked this post they get notified, asynchronously with this thread
ArrayList < Like > likes = getAllLikesByPost ( postId ) ;
Thread likesThread = new Thread ( new LikeNotificationsThread ( escapedCommentText , nm , likes , postOwnerId , theComment . getKey ( ) ) ) ;
likesThread . start ( ) ;
2023-02-09 12:47:01 +01:00
2023-02-08 14:29:57 +01:00
//notify the other users who commented this post (excluding the ones above)
2023-02-08 16:21:17 +01:00
Thread commentsNotificationthread = new Thread ( new CommentNotificationsThread (
CassandraConnection . getInstance ( ) . getDatabookStore ( ) ,
uManager , user . getUsername ( ) , theComment . getFeedid ( ) , escapedCommentText , nm , postOwnerId , theComment . getKey ( ) , likes ) ) ;
commentsNotificationthread . start ( ) ;
2023-02-08 14:29:57 +01:00
//send the notification to the mentioned users, if any
if ( mentionedUsers ! = null & & mentionedUsers . size ( ) > 0 ) {
ArrayList < GenericItemBean > toPass = new ArrayList < GenericItemBean > ( ) ;
// among the mentionedUsers there could be groups of people
Map < String , ItemBean > uniqueUsersToNotify = new HashMap < > ( ) ;
UserManager um = new LiferayUserManager ( ) ;
for ( ItemBean bean : mentionedUsersToConvertInHTML ) {
if ( bean . isItemGroup ( ) ) {
// retrieve the users of this group
try {
List < GCubeUser > 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 < Entry < String , ItemBean > > userMapIterator = uniqueUsersToNotify . entrySet ( ) . iterator ( ) ;
while ( userMapIterator . hasNext ( ) ) {
Map . Entry < String , ItemBean > userEntry = ( Map . Entry < String , ItemBean > ) 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 ;
}
2023-02-02 20:11:52 +01:00
2023-02-08 14:29:57 +01:00
private static ArrayList < Like > getAllLikesByPost ( String postid ) {
ArrayList < Like > toReturn = ( ArrayList < Like > ) 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 ;
}
2023-02-09 12:47:01 +01:00
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 {
2024-04-22 11:19:17 +02:00
logger . debug ( " Attempting to read post with id: " + postid ) ;
2023-02-09 12:47:01 +01:00
thePost = CassandraConnection . getInstance ( ) . getDatabookStore ( ) . readPost ( postid ) ;
likeCommitResult = CassandraConnection . getInstance ( ) . getDatabookStore ( ) . like ( toLike ) ;
} catch ( Exception e ) {
2023-02-09 15:09:38 +01:00
logger . error ( " Post not found for this like ot could not like the post " + e . getMessage ( ) ) ;
2023-02-09 12:47:01 +01:00
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)
2024-04-22 11:19:17 +02:00
logger . debug ( " The post creator is " + postOwnerId ) ;
2023-02-09 12:47:01 +01:00
if ( ! user . getUsername ( ) . equals ( postOwnerId ) ) {
resultNotifyLike = nm . notifyLikedPost ( postOwnerId , postid , escapedPostText ) ;
2024-04-22 11:19:17 +02:00
logger . debug ( " Like Notification to post creator added? " + resultNotifyLike ) ;
2023-02-09 12:47:01 +01:00
}
}
return likeCommitResult & & resultNotifyLike ;
}
2023-02-09 15:31:11 +01:00
public static boolean unlike ( String username , String likeid , String postid ) {
2023-02-09 12:47:01 +01:00
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 {
2023-02-09 15:31:11 +01:00
unlikeCommitResult = CassandraConnection . getInstance ( ) . getDatabookStore ( ) . unlike ( username , likeid , postid ) ;
2023-02-09 12:47:01 +01:00
} catch ( Exception e ) {
logger . error ( " Post not Found for this like ot could not unlike the post " + e . getMessage ( ) ) ;
return false ;
}
return unlikeCommitResult ;
}
2023-02-09 12:55:34 +01:00
2019-04-05 16:39:46 +02:00
}