diff --git a/CHANGELOG.md b/CHANGELOG.md index fe2b9eb..6db14f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [v1.18.0-SNAPSHOT] - 2022-09-13 + + - Refactored some classes ## [v1.17.0] - 2022-05-13 diff --git a/pom.xml b/pom.xml index f7dc7ec..4200c75 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ org.gcube.portal social-networking-library - 1.17.0 + 1.18.0-SNAPSHOT gCube Social Networking Library The gCube Social Networking Library is the 'bridge' between your gCube Applications and the social networking facilities. @@ -32,7 +32,7 @@ org.gcube.distribution maven-portal-bom - 3.6.3 + 3.6.4 pom import diff --git a/src/main/java/org/gcube/portal/databook/server/CassandraClusterConnection.java b/src/main/java/org/gcube/portal/databook/server/CassandraClusterConnection.java index 47c2386..7627070 100644 --- a/src/main/java/org/gcube/portal/databook/server/CassandraClusterConnection.java +++ b/src/main/java/org/gcube/portal/databook/server/CassandraClusterConnection.java @@ -47,7 +47,7 @@ public class CassandraClusterConnection { /** * * @param dropSchema set true if you want do drop the current and set up new one - * @return the connection to cassandra cluster + * the connection to cassandra cluster */ protected CassandraClusterConnection(boolean dropSchema) { if (clusterName == null || host == null || keyspaceName == null) { @@ -97,7 +97,7 @@ public class CassandraClusterConnection { /** * * @param dropSchema set true if you want do drop the current and set up new one - * @return the connection to cassandra cluster + * the connection to cassandra cluster */ protected CassandraClusterConnection(boolean dropSchema, String infrastructureName) { if (clusterName == null || host == null || keyspaceName == null) { @@ -171,8 +171,8 @@ public class CassandraClusterConnection { /** * - * @param cluster - * @param dropIfExists + * @param clusterContext + * @param dropSchema * @throws ConnectionException */ public void SetUpKeySpaces(AstyanaxContext clusterContext, boolean dropSchema) { diff --git a/src/main/java/org/gcube/portal/databook/server/DBCassandraAstyanaxImpl.java b/src/main/java/org/gcube/portal/databook/server/DBCassandraAstyanaxImpl.java index 22469f0..38c1db8 100644 --- a/src/main/java/org/gcube/portal/databook/server/DBCassandraAstyanaxImpl.java +++ b/src/main/java/org/gcube/portal/databook/server/DBCassandraAstyanaxImpl.java @@ -27,8 +27,11 @@ import org.gcube.portal.databook.shared.Like; import org.gcube.portal.databook.shared.Notification; import org.gcube.portal.databook.shared.NotificationChannelType; import org.gcube.portal.databook.shared.NotificationType; +import org.gcube.portal.databook.shared.Post; +import org.gcube.portal.databook.shared.PostType; import org.gcube.portal.databook.shared.PrivacyLevel; import org.gcube.portal.databook.shared.RangeFeeds; +import org.gcube.portal.databook.shared.RangePosts; import org.gcube.portal.databook.shared.ex.ColumnNameNotFoundException; import org.gcube.portal.databook.shared.ex.CommentIDNotFoundException; import org.gcube.portal.databook.shared.ex.FeedIDNotFoundException; @@ -328,6 +331,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { */ /** * common part to save a feed + * @deprecated * @param feed * @return the partial mutation batch instance */ @@ -356,9 +360,40 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { .putColumn("multiFileUpload", feed.isMultiFileUpload(), null); return m; } + /** + * common part to save a feed + * @param post + * @return the partial mutation batch instance + */ + private MutationBatch initSavePost(Post post) { + // Inserting data + MutationBatch m = conn.getKeyspace().prepareMutationBatch(); + //an entry in the feed CF + m.withRow(cf_Feeds, post.getKey().toString()) + .putColumn("Entityid", post.getEntityId(), null) + .putColumn("Time", post.getTime().getTime()+"", null) + .putColumn("Vreid", post.getVreid(), null) + .putColumn("Uri", post.getUri(), null) + .putColumn("UriThumbnail", post.getUriThumbnail(), null) + .putColumn("Description", post.getDescription(), null) + .putColumn("Privacy", post.getPrivacy().toString(), null) + .putColumn("FullName", post.getFullName(), null) + .putColumn("Type", post.getType().toString(), null) + .putColumn("Email", post.getEmail(), null) + .putColumn("ThumbnailURL", post.getThumbnailURL(), null) + .putColumn("CommentsNo", post.getCommentsNo(), null) + .putColumn("LikesNo", post.getLikesNo(), null) + .putColumn("LinkTitle", post.getLinkTitle(), null) + .putColumn("LinkDescription", post.getLinkDescription(), null) + .putColumn("LinkHost", post.getLinkHost(), null) + .putColumn("IsApplicationFeed", post.isApplicationFeed(), null) + .putColumn("multiFileUpload", post.isMultiFileUpload(), null); + return m; + } /** * {@inheritDoc} */ + @Deprecated @Override public boolean saveUserFeed(Feed feed) { MutationBatch m = initSaveFeed(feed); @@ -379,6 +414,26 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { * {@inheritDoc} */ @Override + public boolean saveUserPost(Post post) { + MutationBatch m = initSavePost(post); + + //an entry in the user Timeline + m.withRow(cf_UserTline, post.getEntityId()) + .putColumn(post.getTime().getTime()+"", post.getKey().toString(), null); + + //an entry in the VRES Timeline iff vreid field is not empty + if (post.getVreid() != null && post.getVreid().compareTo("") != 0) { + //an entry in the VRES Timeline + m.withRow(cf_VRETline, post.getVreid()) + .putColumn(post.getTime().getTime()+"", post.getKey().toString(), null); + } + return execute(m); + } + /** + * {@inheritDoc} + */ + @Deprecated + @Override public boolean saveUserFeed(Feed feed, List attachments) { if (attachments != null && !attachments.isEmpty()) feed.setMultiFileUpload(true); @@ -394,11 +449,31 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { } else return false; } + /** + * {@inheritDoc} + */ + @Override + public boolean saveUserPost(Post post, List attachments) { + if (attachments != null && !attachments.isEmpty()) + post.setMultiFileUpload(true); + boolean saveFeedResult = saveUserPost(post); + if (saveFeedResult) { + String postkey = post.getKey(); + for (Attachment attachment : attachments) { + boolean attachSaveResult = saveAttachmentEntry(postkey, attachment); + if (!attachSaveResult) + _log.warn("Some of the attachments failed to be saved: " + attachment.getName()); + } + return true; + } + else return false; + } /** * {@inheritDoc} */ @Override + @Deprecated public boolean saveAppFeed(Feed feed) { MutationBatch m = initSaveFeed(feed); @@ -421,6 +496,29 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { * {@inheritDoc} */ @Override + public boolean saveAppPost(Post post) { + MutationBatch m = initSavePost(post); + + //an entry in the Applications Timeline + m.withRow(cf_AppTline, post.getEntityId()) + .putColumn(post.getTime().getTime()+"", post.getKey().toString(), null); + + //an entry in the VRES Timeline iff vreid field is not empty + if (post.getVreid() != null && post.getVreid().compareTo("") != 0) { + //an entry in the VRES Timeline + m.withRow(cf_VRETline, post.getVreid()) + .putColumn(post.getTime().getTime()+"", post.getKey().toString(), null); + } + boolean result = execute(m); + if (result) + _log.trace("saveAppFeed OK!"); + return result; + } + /** + * {@inheritDoc} + */ + @Deprecated + @Override public boolean saveAppFeed(Feed feed, List attachments) { if (attachments != null && !attachments.isEmpty()) feed.setMultiFileUpload(true); @@ -440,6 +538,26 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { * {@inheritDoc} */ @Override + public boolean saveAppPost(Post post, List attachments) { + if (attachments != null && !attachments.isEmpty()) + post.setMultiFileUpload(true); + boolean saveFeedResult = saveAppPost(post); + if (saveFeedResult) { + String feedKey = post.getKey(); + for (Attachment attachment : attachments) { + boolean attachSaveResult = saveAttachmentEntry(feedKey, attachment); + if (!attachSaveResult) + _log.warn("Some of the attachments failed to be saved: " + attachment.getName()); + } + return true; + } + else return false; + } + /** + * {@inheritDoc} + */ + @Deprecated + @Override public boolean saveFeedToVRETimeline(String feedKey, String vreid) throws FeedIDNotFoundException { String feedId = feedKey; Feed toCheck = null; @@ -462,6 +580,29 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { * {@inheritDoc} */ @Override + public boolean savePostToVRETimeline(String postKey, String vreid) throws FeedIDNotFoundException { + String postId = postKey; + Post toCheck = null; + try { + toCheck = readPost(postId); + if (toCheck == null) + throw new FeedIDNotFoundException("Could not find Post with id " + postId, postId); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + MutationBatch m = conn.getKeyspace().prepareMutationBatch(); + + //an entry in the user Timeline + m.withRow(cf_VRETline, vreid) + .putColumn(toCheck.getTime().getTime()+"", postKey, null); + return execute(m); + } + /** + * {@inheritDoc} + */ + @Deprecated + @Override public Feed readFeed(String feedid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException { @@ -516,6 +657,61 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { * {@inheritDoc} */ @Override + public Post readPost(String postid) + throws PrivacyLevelTypeNotFoundException, + FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException { + Post toReturn = new Post(); + OperationResult> result; + try { + result = conn.getKeyspace().prepareQuery(cf_Feeds) + .getKey(postid) + .execute(); + + ColumnList columns = result.getResult(); + if (columns.size() == 0) { + throw new FeedIDNotFoundException("The requested feedid: " + postid + " is not existing", postid); + } + + toReturn.setKey(postid); + toReturn.setDescription(columns.getColumnByName("Description").getStringValue()); + toReturn.setEmail(columns.getColumnByName("Email").getStringValue()); + toReturn.setFullName(columns.getColumnByName("FullName").getStringValue()); + toReturn.setPrivacy(getPrivacyLevel(columns.getColumnByName("Privacy").getStringValue())); + toReturn.setThumbnailURL(columns.getColumnByName("ThumbnailURL").getStringValue()); + toReturn.setTime(getDateFromTimeInMillis(columns.getColumnByName("Time").getStringValue())); + + PostType ptype = getPostType(columns.getColumnByName("Type").getStringValue()); + + toReturn.setType(ptype); + toReturn.setUri(columns.getColumnByName("Uri").getStringValue()); + toReturn.setUriThumbnail(columns.getColumnByName("UriThumbnail").getStringValue()); + toReturn.setVreid(columns.getColumnByName("Vreid").getStringValue()); + toReturn.setEntityId(columns.getColumnByName("Entityid").getStringValue()); + toReturn.setCommentsNo(columns.getColumnByName("CommentsNo").getStringValue()); + toReturn.setLikesNo(columns.getColumnByName("LikesNo").getStringValue()); + + toReturn.setLinkTitle(columns.getColumnByName("LinkTitle").getStringValue()); + toReturn.setLinkDescription(columns.getColumnByName("LinkDescription").getStringValue()); + toReturn.setLinkHost(columns.getColumnByName("LinkHost").getStringValue()); + toReturn.setApplicationFeed(columns.getColumnByName("IsApplicationFeed").getBooleanValue()); + boolean isMultiFileUpload = false; + try { + isMultiFileUpload = columns.getColumnByName("multiFileUpload").getBooleanValue(); + } + catch (NullPointerException e) { } + toReturn.setMultiFileUpload(isMultiFileUpload); + + } catch (ConnectionException e) { + e.printStackTrace(); + return null; + } + return toReturn; + } + /** + * {@inheritDoc} + */ + @Override + @Deprecated public List getRecentFeedsByUserAndDate(String userid, long timeInMillis) throws IllegalArgumentException { Date now = new Date(); if (timeInMillis > now.getTime()) @@ -554,6 +750,45 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { * {@inheritDoc} */ @Override + public List getRecentPostsByUserAndDate(String userid, long timeInMillis) throws IllegalArgumentException { + Date now = new Date(); + if (timeInMillis > now.getTime()) + throw new IllegalArgumentException("the timeInMillis must be before today"); + + OperationResult> result = null; + try { + result = conn.getKeyspace().prepareQuery(cf_UserTline) + .getKeySlice(userid) + .execute(); + } catch (ConnectionException e) { + e.printStackTrace(); + } + List toReturn = new ArrayList<>(); + // Iterate rows and their columns + for (Row row : result.getResult()) { + for (Column column : row.getColumns()) { + long feedTime = Long.parseLong(column.getName()); + if (feedTime > timeInMillis) { + try { + Post toCheck = readPost(column.getStringValue()); + if (toCheck.getType() != PostType.DISABLED) + toReturn.add(toCheck); + } catch (PrivacyLevelTypeNotFoundException + | FeedTypeNotFoundException + | FeedIDNotFoundException + | ColumnNameNotFoundException e) { + e.printStackTrace(); + } + } + } + } + return toReturn; + } + /** + * {@inheritDoc} + */ + @Deprecated + @Override public boolean deleteFeed(String feedId) throws FeedIDNotFoundException, PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException { Feed toDelete = readFeed(feedId); MutationBatch m = conn.getKeyspace().prepareMutationBatch(); @@ -572,6 +807,25 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { * {@inheritDoc} */ @Override + public boolean deletePost(String postid) throws FeedIDNotFoundException, PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException { + Post toDelete = readPost(postid); + MutationBatch m = conn.getKeyspace().prepareMutationBatch(); + //edit the entry in the feed CF + m.withRow(cf_Feeds, toDelete.getKey().toString()).putColumn("Type", ""+PostType.DISABLED, null); + try { + m.execute(); + } catch (ConnectionException e) { + _log.error("Delete Post ERROR for postid " + postid); + return false; + } + _log.info("Delete Post OK"); + return true; + } + /** + * {@inheritDoc} + */ + @Deprecated + @Override public List getAllFeedsByUser(String userid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException { return getFeedsByIds(getUserFeedIds(userid)); } @@ -579,13 +833,28 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { * {@inheritDoc} */ @Override + public List getAllPostsByUser(String userid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException { + return getPostsByIds(getUserPostIds(userid)); + } + /** + * {@inheritDoc} + */ + @Override public List getAllFeedsByApp(String appid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException { return getFeedsByIds(getAppFeedIds(appid)); } + /** + * {@inheritDoc} + */ + @Override + public List getAllPostsByApp(String appid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException { + return getPostsByIds(getAppPostIds(appid)); + } /** * {@inheritDoc} * @throws Exception */ + @Deprecated @Override public List getRecentCommentedFeedsByUserAndDate(String userid, long timeInMillis) throws Exception { @@ -621,6 +890,45 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { return toReturn; } /** + * {@inheritDoc} + * @throws Exception + */ + @Override + public List getRecentCommentedPostsByUserAndDate(String userid, + long timeInMillis) throws Exception { + + List toReturn = new ArrayList(); + + Date now = new Date(); + if (timeInMillis > now.getTime()) + throw new IllegalArgumentException("the timeInMillis must be before today"); + + if(userid == null || userid.isEmpty()) + throw new IllegalArgumentException("the userId parameter cannot be null/empty"); + + // get the last comments by the user (it is not needed to get them sorted) + List lastComments = getRecentCommentsByUserAndDateBody(userid, timeInMillis, false); + + // evaluate unique feeds' ids + HashSet postIds = new HashSet(); + + for (Comment comment : lastComments) { + String postId = comment.getFeedid(); + try{ + if(!postIds.contains(postId)){ + postIds.add(postId); + toReturn.add(readPost(postId)); + } + }catch(Exception e){ + _log.error("Unable to retrieve feed with id " + postId, e); + } + } + + Collections.sort(toReturn, Collections.reverseOrder()); + return toReturn; + } + /** + * @deprecated * helper method that retrieve all the feeds belongin to a list of Ids * @param feedIds * @return @@ -638,11 +946,30 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { } return toReturn; } + /** + * helper method that retrieve all the feeds belongin to a list of Ids + * @param postIds + * @return + * @throws ColumnNameNotFoundException + * @throws FeedIDNotFoundException + * @throws FeedTypeNotFoundException + * @throws PrivacyLevelTypeNotFoundException + */ + private List getPostsByIds(List postIds) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException { + ArrayList toReturn = new ArrayList(); + for (String feedid : postIds) { + Post toAdd = readPost(feedid); + if (toAdd.getType() == PostType.TWEET || toAdd.getType() == PostType.SHARE || toAdd.getType() == PostType.PUBLISH) + toReturn.add(toAdd); + } + return toReturn; + } /** * helper method that retrieve all the feed Ids belonging to a user * @param userid user identifier * @return simply return a list of user feed UUID in chronological order from the oldest to the more recent */ + @Deprecated private ArrayList getUserFeedIds(String userid) { OperationResult> result = null; try { @@ -663,6 +990,31 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { } return toReturn; } + /** + * helper method that retrieve all the post Ids belonging to a user + * @param userid user identifier + * @return simply return a list of user post UUID in chronological order from the oldest to the more recent + */ + private ArrayList getUserPostIds(String userid) { + OperationResult> result = null; + try { + result = conn.getKeyspace().prepareQuery(cf_UserTline) + .getKeySlice(userid) + .execute(); + } catch (ConnectionException e) { + e.printStackTrace(); + } + + ArrayList toReturn = new ArrayList(); + + // Iterate rows and their columns + for (Row row : result.getResult()) { + for (Column column : row.getColumns()) { + toReturn.add(column.getStringValue()); + } + } + return toReturn; + } /** * helper method that return whether the user @@ -696,6 +1048,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { * @param appid application identifier * @return simply return a list of app feed UUID in chronological order from the oldest to the more recent */ + @Deprecated private ArrayList getAppFeedIds(String appid) { OperationResult> result = null; try { @@ -716,10 +1069,36 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { } return toReturn; } + /** + * helper method that retrieve all the post Ids belonging to an application + * @param appid application identifier + * @return simply return a list of app post UUID in chronological order from the oldest to the more recent + */ + private ArrayList getAppPostIds(String appid) { + OperationResult> result = null; + try { + result = conn.getKeyspace().prepareQuery(cf_AppTline) + .getKeySlice(appid) + .execute(); + } catch (ConnectionException e) { + e.printStackTrace(); + } + + ArrayList toReturn = new ArrayList(); + + // Iterate rows and their columns + for (Row row : result.getResult()) { + for (Column column : row.getColumns()) { + toReturn.add(column.getStringValue()); + } + } + return toReturn; + } + /** * {@inheritDoc} */ - @SuppressWarnings("deprecation") + @Deprecated @Override public List getAllPortalPrivacyLevelFeeds() throws FeedTypeNotFoundException, ColumnNameNotFoundException, PrivacyLevelTypeNotFoundException { ArrayList toReturn = new ArrayList(); @@ -785,10 +1164,76 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { } return toReturn; } + @Override + public List getAllPortalPrivacyLevelPosts() throws FeedTypeNotFoundException, ColumnNameNotFoundException, PrivacyLevelTypeNotFoundException { + ArrayList toReturn = new ArrayList(); + OperationResult> result; + try { + result = conn.getKeyspace().prepareQuery(cf_Feeds) + .searchWithIndex() + .setLimit(20) // Number of rows returned + .addExpression() + .whereColumn("Privacy").equals().value(PrivacyLevel.PORTAL.toString()) + .execute(); + // Iterate rows and their columns + for (Row row : result.getResult()) { + Post toAdd = new Post(); + toAdd.setKey(row.getKey()); + for (Column col : row.getColumns()) { + if (col.getName().compareTo("Description") == 0) + toAdd.setDescription(col.getStringValue()); + else if (col.getName().compareTo("FullName") == 0) + toAdd.setFullName(col.getStringValue()); + else if (col.getName().compareTo("Email") == 0) + toAdd.setEmail(col.getStringValue()); + else if (col.getName().compareTo("Privacy") == 0) + toAdd.setPrivacy(getPrivacyLevel(col.getStringValue())); + else if (col.getName().compareTo("ThumbnailURL") == 0) + toAdd.setThumbnailURL(col.getStringValue()); + else if (col.getName().compareTo("Time") == 0) + toAdd.setTime(getDateFromTimeInMillis(col.getStringValue())); + else if (col.getName().compareTo("Type") == 0) { + PostType ft = getPostType(col.getStringValue()); + toAdd.setType(ft); + } + else if (col.getName().compareTo("Uri") == 0) + toAdd.setUri(col.getStringValue()); + else if (col.getName().compareTo("UriThumbnail") == 0) + toAdd.setUriThumbnail(col.getStringValue()); + else if (col.getName().compareTo("Vreid") == 0) + toAdd.setVreid(col.getStringValue()); + else if (col.getName().compareTo("Entityid") == 0) + toAdd.setEntityId(col.getStringValue()); + else if (col.getName().compareTo("CommentsNo") == 0) + toAdd.setCommentsNo(col.getStringValue()); + else if (col.getName().compareTo("LikesNo") == 0) + toAdd.setLikesNo(col.getStringValue()); + else if (col.getName().compareTo("LinkDescription") == 0) + toAdd.setLinkDescription(col.getStringValue()); + else if (col.getName().compareTo("LinkHost") == 0) + toAdd.setLinkHost(col.getStringValue()); + else if (col.getName().compareTo("LinkTitle") == 0) + toAdd.setLinkTitle(col.getStringValue()); + else if (col.getName().compareTo("IsApplicationFeed") == 0) + toAdd.setApplicationFeed(col.getBooleanValue()); + else { + _log.warn("getAllPortalPrivacyLevelFeeds(): Could not assign variable to this Feed for column name: " + col.getName()); + } + } + if (toAdd.getType() == PostType.TWEET || toAdd.getType() == PostType.SHARE || toAdd.getType() == PostType.PUBLISH) + toReturn.add(toAdd); + } + } catch (ConnectionException e) { + e.printStackTrace(); + return toReturn; + } + return toReturn; + } /** * {@inheritDoc} */ @Override + @Deprecated public List getRecentFeedsByUser(String userid, int quantity) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException { ArrayList toReturn = new ArrayList(); ArrayList feedIDs = getUserFeedIds(userid); @@ -810,10 +1255,33 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { } return toReturn; } + @Override + public List getRecentPostsByUser(String userid, int quantity) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException { + ArrayList toReturn = new ArrayList(); + ArrayList postIDs = getUserPostIds(userid); + //check if quantity is greater than user feeds + quantity = (quantity > postIDs.size()) ? postIDs.size() : quantity; + + //need them in reverse order + for (int i = postIDs.size()-1; i >= (postIDs.size()-quantity); i--) { + Post toAdd = readPost(postIDs.get(i)); + if (toAdd.getType() == PostType.TWEET || toAdd.getType() == PostType.SHARE || toAdd.getType() == PostType.PUBLISH) { + toReturn.add(toAdd); + _log.trace("Read recent post: " + postIDs.get(i)); + } else { + _log.trace("Read and skipped post: " + postIDs.get(i) + " (Removed Post)"); + quantity += 1; //increase the quantity in case of removed post + //check if quantity is greater than user feeds + quantity = (quantity > postIDs.size()) ? postIDs.size() : quantity; + } + } + return toReturn; + } /** * {@inheritDoc} */ - @Override + @Override + @Deprecated public List getAllFeedsByVRE(String vreid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException { return getFeedsByIds(getVREFeedIds(vreid)); } @@ -821,6 +1289,14 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { * {@inheritDoc} */ @Override + public List getAllPostsByVRE(String vreid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException { + return getPostsByIds(getVREPostIds(vreid)); + } + /** + * {@inheritDoc} + */ + @Deprecated + @Override public List getRecentFeedsByVRE(String vreid, int quantity) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException { ArrayList toReturn = new ArrayList(); ArrayList feedIDs = getVREFeedIds(vreid); @@ -842,6 +1318,28 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { } return toReturn; } + @Override + public List getRecentPostsByVRE(String vreid, int quantity) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException { + ArrayList toReturn = new ArrayList(); + ArrayList postIDs = getVREPostIds(vreid); + //check if quantity is greater than user posts + quantity = (quantity > postIDs.size()) ? postIDs.size() : quantity; + + //need them in reverse order + for (int i = postIDs.size()-1; i >= (postIDs.size()-quantity); i--) { + Post toAdd = readPost(postIDs.get(i)); + if (toAdd.getType() == PostType.TWEET || toAdd.getType() == PostType.SHARE || toAdd.getType() == PostType.PUBLISH) { + toReturn.add(toAdd); + _log.trace("Read recent Post: " + postIDs.get(i)); + } else { + _log.trace("Read and skipped Post: " + postIDs.get(i) + " (Removed Post) ."); + quantity += 1; //increase the quantity in case of removed Post + //check if quantity is greater than user Posts + quantity = (quantity > postIDs.size()) ? postIDs.size() : quantity; + } + } + return toReturn; + } /** * {@inheritDoc} */ @@ -886,6 +1384,50 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { return new RangeFeeds(howMany+1, feedsToReturn); } /** + * {@inheritDoc} + */ + @Override + public RangePosts getRecentPostsByVREAndRange(String vreid, int from, int quantity) throws IllegalArgumentException, PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException { + if (from < 1) { + throw new IllegalArgumentException("From must be greather than 0"); + } + ArrayList feedsToReturn = new ArrayList(); + ArrayList feedIDs = getVREPostIds(vreid); + + //if from is greater than feeds size return empty + if (from >= feedIDs.size()) { + _log.warn("The starting point of the range is greather than the total number of feeds for this timeline: " + from + " >= " + feedIDs.size()); + return new RangePosts(); + } + + int rangeStart = feedIDs.size()-from; + int rangeEnd = rangeStart-quantity; + + //check that you reached the end + if (rangeEnd<1) + rangeEnd = 0; + + _log.debug("BEFORE starting Point=" + rangeStart + " rangeEnd= " + rangeEnd); + //need them in reverse order + int howMany = from; + for (int i = rangeStart; i > rangeEnd; i--) { + Post toAdd = readPost(feedIDs.get(i)); + if (toAdd.getType() == PostType.TWEET || toAdd.getType() == PostType.SHARE || toAdd.getType() == PostType.PUBLISH) { + feedsToReturn.add(toAdd); + _log.trace("Read recent post, i=" + i + " id= " + feedIDs.get(i)); + } else { + _log.trace("Read and skipped post, i=" + i + " id=: " + feedIDs.get(i) + " (Removed post) ."); + rangeEnd -= 1; //increase the upTo in case of removed feed + //check if quantity is greater than user feeds + rangeEnd = (rangeEnd > 0) ? rangeEnd : 0; + } + howMany++; + } + _log.debug("AFTER: starting Point==" + rangeStart + " rangeEnd= " + rangeEnd); + return new RangePosts(howMany+1, feedsToReturn); + } + /** + * @deprecated * get a list of user vre feed UUIDs in chronological order from the oldest to the more recent * @param vreid vreid identifier (scope) * @return simply return a list of user vre feed UUIDs in chronological order from the oldest to the more recent @@ -910,6 +1452,31 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { } return toReturn; } + /** + * get a list of user vre post UUIDs in chronological order from the oldest to the more recent + * @param vreid vreid identifier (scope) + * @return simply return a list of user vre post UUIDs in chronological order from the oldest to the more recent + */ + private ArrayList getVREPostIds(String vreid) { + OperationResult> result = null; + try { + result = conn.getKeyspace().prepareQuery(cf_VRETline) + .getKeySlice(vreid) + .execute(); + } catch (ConnectionException e) { + e.printStackTrace(); + } + + ArrayList toReturn = new ArrayList(); + + // Iterate rows and their columns + for (Row row : result.getResult()) { + for (Column column : row.getColumns()) { + toReturn.add(column.getStringValue()); + } + } + return toReturn; + } /* * ********************** NOTIFICATIONS *********************** @@ -1413,10 +1980,18 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { * {@inheritDoc} */ @Override + @Deprecated public List getAllCommentByFeed(String feedid) { + return getAllCommentByPost(feedid); + } + /** + * {@inheritDoc} + */ + @Override + public List getAllCommentByPost(String postid) { List toReturn = new ArrayList(); - PreparedIndexExpression clause = cf_Comments.newIndexClause().whereColumn("Feedid").equals().value(feedid); + PreparedIndexExpression clause = cf_Comments.newIndexClause().whereColumn("Feedid").equals().value(postid); OperationResult> result; try { result = conn.getKeyspace().prepareQuery(cf_Comments) @@ -1447,7 +2022,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { else if(col.getName().compareTo("LastEditTime") == 0) toAdd.setLastEditTime(getDateFromTimeInMillis(col.getStringValue())); else { - _log.error("getAllCommentByFeed(): Could not assign variable to this Comment for column name: " + col.getName()); + _log.error("getAllCommentByPost(): Could not assign variable to this Comment for column name: " + col.getName()); } } toReturn.add(toAdd); @@ -1682,7 +2257,15 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { * {@inheritDoc} */ @Override + @Deprecated public List getAllLikedFeedIdsByUser(String userid) { + return getAllLikedPostIdsByUser(userid); + } + /** + * {@inheritDoc} + */ + @Override + public List getAllLikedPostIdsByUser(String userid) { OperationResult> result = null; try { result = conn.getKeyspace().prepareQuery(cf_UserLikedFeeds) @@ -1728,6 +2311,32 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { } return toReturn; } + /** + * {@inheritDoc} + */ + @Override + public List getAllLikedPostsByUser(String userid, int limit) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException { + ArrayList toReturn = new ArrayList(); + List likedPostIDs = getAllLikedPostIdsByUser(userid); + + //check if quantity is greater than user feeds + limit = (limit > likedPostIDs.size()) ? likedPostIDs.size() : limit; + + //need them in reverse order + for (int i = likedPostIDs.size()-1; i >= (likedPostIDs.size()-limit); i--) { + Post toAdd = readPost(likedPostIDs.get(i)); + if (toAdd.getType() == PostType.TWEET || toAdd.getType() == PostType.SHARE || toAdd.getType() == PostType.PUBLISH) { + toReturn.add(toAdd); + _log.trace("Read recent post: " + likedPostIDs.get(i)); + } else { + _log.trace("Read and skipped post: " + likedPostIDs.get(i) + " (Removed post)"); + limit += 1; //increase the quantity in case of removed feed + //check if quantity is greater than user feeds + limit = (limit > likedPostIDs.size()) ? likedPostIDs.size() : limit; + } + } + return toReturn; + } /** * {@inheritDoc} @@ -1759,7 +2368,7 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { // retrieve the like of the user for the feed if(isFeedOk){ - List likes = getAllLikesByFeed(feedId); + List likes = getAllLikesByPost(feedId); for (Like like : likes) { if(like.getTime().getTime() >= timeInMillis && like.getUserid().equals(userid)) toReturn.add(toCheck); @@ -1778,12 +2387,61 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { return toReturn; } + /** + * {@inheritDoc} + */ + @Override + public List getRecentLikedPostsByUserAndDate(String userid, + long timeInMillis) throws IllegalArgumentException { + + List toReturn = new ArrayList<>(); + + Date now = new Date(); + if (timeInMillis > now.getTime()) + throw new IllegalArgumentException("the timeInMillis must be before today"); + + if(userid == null || userid.isEmpty()) + throw new IllegalArgumentException("the userId parameter cannot be null/empty"); + + // get the list of liked feeds + List likedPostsIdsByUser = getAllLikedPostIdsByUser(userid); + + if(likedPostsIdsByUser != null && !likedPostsIdsByUser.isEmpty()){ + for(int i = likedPostsIdsByUser.size() - 1; i >= 0; i--){ + String postid = likedPostsIdsByUser.get(i); + try{ + + // retrieve the Post + Post toCheck = readPost(postid); + boolean isPostOk = (toCheck.getType() == PostType.TWEET || toCheck.getType() == PostType.SHARE || toCheck.getType() == PostType.PUBLISH); + + // retrieve the like of the user for the post + if(isPostOk){ + List likes = getAllLikesByPost(postid); + for (Like like : likes) { + if(like.getTime().getTime() >= timeInMillis && like.getUserid().equals(userid)) + toReturn.add(toCheck); + } + } + + }catch(Exception e){ + _log.error("Skipped post with id " + postid, e); + } + } + } + + // please check consider that if a user made like recently to an old post, well it could happen that this + // post comes first than a newer post in the toReturn list. Thus we need to sort it. + Collections.sort(toReturn, Collections.reverseOrder()); + + return toReturn; + } /** * {@inheritDoc} */ @Override - public List getAllLikesByFeed(String feedid) { + public List getAllLikesByPost(String feedid) { List toReturn = new ArrayList(); OperationResult> result; PreparedIndexExpression clause = cf_Likes.newIndexClause().whereColumn("Feedid").equals().value(feedid); @@ -2048,6 +2706,52 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { toReturn = getFeedsByIds(new ArrayList(feedIds)); return toReturn; } + /** + * {@inheritDoc} + */ + @Override + public List getVREPostsByHashtag(String vreid, String hashtag) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException { + List toReturn = new ArrayList<>(); + OperationResult> resultPost = null; + OperationResult> resultComment = null; + try { + resultPost = conn.getKeyspace().prepareQuery(cf_HashtagTimelineFeed) + .getKeySlice(hashtag) + .execute(); + } catch (ConnectionException e) { + e.printStackTrace(); + } + try { + resultComment = conn.getKeyspace().prepareQuery(cf_HashtagTimelineComment) + .getKeySlice(hashtag) + .execute(); + } catch (ConnectionException e) { + e.printStackTrace(); + } + Set postIds = new HashSet<>(); + // Iterate rows and their columns (feed) + for (Row row : resultPost.getResult()) { + for (Column column : row.getColumns()) { + if (column.getStringValue().compareTo(vreid)==0) + postIds.add(column.getName()); + } + } + // Iterate rows and their columns (comments) + for (Row row : resultComment.getResult()) { + for (Column column : row.getColumns()) { + if (column.getStringValue().compareTo(vreid)==0){ + try { + Comment c = readCommentById(column.getName()); + postIds.add(c.getFeedid()); + } catch (CommentIDNotFoundException e) { + _log.warn("Failed to fetch comment with id " + column.getName()); + } + } + } + } + toReturn = getPostsByIds(new ArrayList(postIds)); + return toReturn; + } /* * ********************** Invites *********************** @@ -2389,6 +3093,34 @@ public final class DBCassandraAstyanaxImpl implements DatabookStore { else throw new FeedTypeNotFoundException("The Feed Type was not recognized should be one of " + FeedType.values() + " asked for: " + type); } + /** + * simply return an enum representing the feed type + * @param type . + * @return correct enum representing the feed type + * @throws TypeNotFoundException . + */ + private PostType getPostType(String type) throws FeedTypeNotFoundException { + if (type.compareTo("TWEET") == 0) { + return PostType.TWEET; + } + else if (type.compareTo("JOIN") == 0) { + return PostType.JOIN; + } + else if (type.compareTo("PUBLISH") == 0) { + return PostType.PUBLISH; + } + else if (type.compareTo("SHARE") == 0) { + return PostType.SHARE; + } + else if (type.compareTo("ACCOUNTING") == 0) { + return PostType.ACCOUNTING; + } + else if (type.compareTo("DISABLED") == 0) { + return PostType.DISABLED; + } + else + throw new FeedTypeNotFoundException("The Feed Type was not recognized should be one of " + PostType.values() + " asked for: " + type); + } /** * simply return an enum representing the invite status type diff --git a/src/main/java/org/gcube/portal/databook/server/DatabookStore.java b/src/main/java/org/gcube/portal/databook/server/DatabookStore.java index 09c8531..b7bfaa8 100644 --- a/src/main/java/org/gcube/portal/databook/server/DatabookStore.java +++ b/src/main/java/org/gcube/portal/databook/server/DatabookStore.java @@ -15,7 +15,9 @@ import org.gcube.portal.databook.shared.Like; import org.gcube.portal.databook.shared.Notification; import org.gcube.portal.databook.shared.NotificationChannelType; import org.gcube.portal.databook.shared.NotificationType; +import org.gcube.portal.databook.shared.Post; import org.gcube.portal.databook.shared.RangeFeeds; +import org.gcube.portal.databook.shared.RangePosts; import org.gcube.portal.databook.shared.ex.ColumnNameNotFoundException; import org.gcube.portal.databook.shared.ex.CommentIDNotFoundException; import org.gcube.portal.databook.shared.ex.FeedIDNotFoundException; @@ -62,46 +64,91 @@ public interface DatabookStore { */ List getPendingFriendRequests(String userid); /** + * @deprecated use saveUserPost * save a Feed instance in the store * @return true if everything went fine */ boolean saveUserFeed(Feed feed); + /** + * save a Post instance in the store + * @return true if everything went fine + */ + boolean saveUserPost(Post feed); /** * Save a Feed instance in the store having more than one attachment * Use this if you need to attach more than one file to the post * - * @param attachments, a list of attachments starting from the second + * @deprecated use saveUserPost + * @param attachments a list of attachments starting from the second * @return true if everything went fine */ boolean saveUserFeed(Feed feed, List attachments); /** - * delete a Feed from the store + * Save a Post instance in the store having more than one attachment + * Use this if you need to attach more than one file to the post + * + * @param attachments a list of attachments starting from the second + * @return true if everything went fine + */ + boolean saveUserPost(Post post, List attachments); + /** + * Delete a Feed from the store + * @deprecated use saveUserPost * @throws FeedIDNotFoundException * @return true if everything went fine */ boolean deleteFeed(String feedid) throws FeedIDNotFoundException, PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException; /** - * save a post in the VRES TimeLine in the store + * delete a Feed from the store + * @throws FeedIDNotFoundException + * @return true if everything went fine + */ + boolean deletePost(String postid) throws FeedIDNotFoundException, PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException; + /** + * Save a post in the VRES TimeLine in the store + * @deprecated use savePostToVRETimeline * @param feedKey feedKey * @param vreid vre identifier - * @return * @throws FeedIDNotFoundException */ boolean saveFeedToVRETimeline(String feedKey, String vreid) throws FeedIDNotFoundException; /** + * save a post in the VRES TimeLine in the store + * @param postKey the post id + * @param vreid vre identifier + * @throws FeedIDNotFoundException + */ + boolean savePostToVRETimeline(String postKey, String vreid) throws FeedIDNotFoundException; + /** + * @deprecated use saveAppPost * save a Post instance in the store * @return true if everything went fine */ boolean saveAppFeed(Feed feed); /** - * Save a feed instance in the store + * save a Post instance in the store + * @return true if everything went fine + */ + boolean saveAppPost(Post feed); + /** + * @deprecated use saveAppPost + * Save a Post instance in the store * Use this if your app needs to attach more than one file to the post * - * @param attachments, a list of attachments starting from the second + * @param attachments a list of attachments starting from the second * @return true if everything went fine */ boolean saveAppFeed(Feed feed, List attachments); /** + * Save a Post instance in the store + * Use this if your app needs to attach more than one file to the post + * + * @param attachments a list of attachments starting from the second + * @return true if everything went fine + */ + boolean saveAppPost(Post feed, List attachments); + /** + * @deprecated use readPost * read a feed from a given id * @throws PrivacyLevelTypeNotFoundException * @throws FeedTypeNotFoundException @@ -109,6 +156,14 @@ public interface DatabookStore { */ Feed readFeed(String feedid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException; /** + * read a feed from a given id + * @throws PrivacyLevelTypeNotFoundException + * @throws FeedTypeNotFoundException + * @throws ColumnNameNotFoundException + */ + Post readPost(String postid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException; + /** + * @deprecated use getAllPostsByUser instead * @param userid user identifier * return all the feeds belonging to the userid * @throws FeedTypeNotFoundException @@ -117,6 +172,15 @@ public interface DatabookStore { */ List getAllFeedsByUser(String userid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException; /** + * @param userid user identifier + * return all the feeds belonging to the userid + * @throws FeedTypeNotFoundException + * @throws PrivacyLevelTypeNotFoundException + * @throws ColumnNameNotFoundException + */ + List getAllPostsByUser(String userid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException; + /** + * @deprecated use getAllPostsByApp instead * @param appid application identifier * return all the feeds belonging to the appid * @throws FeedTypeNotFoundException @@ -125,6 +189,15 @@ public interface DatabookStore { */ List getAllFeedsByApp(String appid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException; /** + * @param appid application identifier + * return all the feeds belonging to the appid + * @throws FeedTypeNotFoundException + * @throws PrivacyLevelTypeNotFoundException + * @throws ColumnNameNotFoundException + */ + List getAllPostsByApp(String appid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException; + /** + * @deprecated use getRecentCommentedPostsByUserAndDate instead * @param userid the user identifier like andrea.rossi * @param timeInMillis the initial time in millis to be considered * @return a list of feeds commented by userid starting from timeInMillis @@ -132,15 +205,31 @@ public interface DatabookStore { */ List getRecentCommentedFeedsByUserAndDate(String userid, long timeInMillis) throws Exception; /** + * @param userid the user identifier like andrea.rossi + * @param timeInMillis the initial time in millis to be considered + * @return a list of feeds commented by userid starting from timeInMillis + * @throws Exception + */ + List getRecentCommentedPostsByUserAndDate(String userid, long timeInMillis) throws Exception; + /** + * @deprecated use getAllPortalPrivacyLevelPosts instead * return all the feeds whose Level is PORTAL * @throws PrivacyLevelTypeNotFoundException * @throws ColumnNameNotFoundException * @throws PrivacyLevelTypeNotFoundException */ List getAllPortalPrivacyLevelFeeds() throws FeedTypeNotFoundException, ColumnNameNotFoundException, PrivacyLevelTypeNotFoundException; + /** + * return all the feeds whose Level is PORTAL + * @throws PrivacyLevelTypeNotFoundException + * @throws ColumnNameNotFoundException + * @throws PrivacyLevelTypeNotFoundException + */ + List getAllPortalPrivacyLevelPosts() throws FeedTypeNotFoundException, ColumnNameNotFoundException, PrivacyLevelTypeNotFoundException; /** * return the most recent feeds for this user up to quantity param + * @deprecated * @param userid user identifier * @param quantity the number of most recent feeds for this user * @return a List of most recent feeds for this user @@ -150,6 +239,17 @@ public interface DatabookStore { */ List getRecentFeedsByUser(String userid, int quantity) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException; /** + * return the most recent feeds for this user up to quantity param + * @param userid user identifier + * @param quantity the number of most recent feeds for this user + * @return a List of most recent feeds for this user + * @throws FeedTypeNotFoundException + * @throws PrivacyLevelTypeNotFoundException + * @throws ColumnNameNotFoundException + */ + List getRecentPostsByUser(String userid, int quantity) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException; + /** + * @deprecated use getAllPostsByVRE * @param vreid vre identifier * return all the feeds belonging to the userid * @throws FeedTypeNotFoundException @@ -157,8 +257,17 @@ public interface DatabookStore { * @throws ColumnNameNotFoundException */ List getAllFeedsByVRE(String vreid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException; + /** + * @param vreid vre identifier + * return all the feeds belonging to the userid + * @throws FeedTypeNotFoundException + * @throws PrivacyLevelTypeNotFoundException + * @throws ColumnNameNotFoundException + */ + List getAllPostsByVRE(String vreid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException; /** + * @deprecated use getRecentPostsByVRE * return the most recent feeds for this vre up to quantity param * @param vreid VRES identifier * @param quantity the number of most recent feeds for this vre @@ -169,7 +278,33 @@ public interface DatabookStore { */ List getRecentFeedsByVRE(String vreid, int quantity) throws IllegalArgumentException, PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException; /** - * return the most recent feeds for this vre up to quantity param and the last index of the feeds in the timeline + * return the most recent posts for this vre up to quantity param + * @param vreid VRES identifier + * @param quantity the number of most recent posts for this vre + * @return a List of most recent posts for this vre + * @throws FeedTypeNotFoundException + * @throws PrivacyLevelTypeNotFoundException + * @throws ColumnNameNotFoundException + */ + List getRecentPostsByVRE(String vreid, int quantity) throws IllegalArgumentException, PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException; + + /** + * return the most recent posts for this vre up to quantity param and the last index of the feeds in the timeline + * lastReturnedFeedTimelineIndex is usuful to know from where to start the range the second time you ask + * because there are deletions + * + * @deprecated use getRecentPostsByVREAndRange + * @param vreid VRES identifier + * @param from the range start (most recent feeds for this vre) has to be greater than 0 + * @param quantity the number of most recent feeds for this vre starting from "from" param + * @return a lastReturnedFeedTimelineIndex containing of most recent feeds for this vre + * @throws FeedTypeNotFoundException + * @throws PrivacyLevelTypeNotFoundException + * @throws ColumnNameNotFoundException + */ + RangeFeeds getRecentFeedsByVREAndRange(String vreid, int from, int quantity) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException; + /** + * return the most recent posts for this vre up to quantity param and the last index of the feeds in the timeline * lastReturnedFeedTimelineIndex is usuful to know from where to start the range the second time you ask * because there are deletions * @@ -181,13 +316,21 @@ public interface DatabookStore { * @throws PrivacyLevelTypeNotFoundException * @throws ColumnNameNotFoundException */ - RangeFeeds getRecentFeedsByVREAndRange(String vreid, int from, int quantity) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException; + RangePosts getRecentPostsByVREAndRange(String vreid, int from, int quantity) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException; + /** + * @deprecated use getRecentPostsByUserAndDate * @param userid user identifier * @param timeInMillis time in milliseconds from which you want to start retrieve the feeds * @return the number of feeds in the range from: today to: timeInMillis */ List getRecentFeedsByUserAndDate(String userid, long timeInMillis) throws IllegalArgumentException; + /** + * @param userid user identifier + * @param timeInMillis time in milliseconds from which you want to start retrieve the feeds + * @return the number of feeds in the range from: today to: timeInMillis + */ + List getRecentPostsByUserAndDate(String userid, long timeInMillis) throws IllegalArgumentException; /** * save a Notification instance in the store * @return true if everything went fine @@ -272,7 +415,6 @@ public interface DatabookStore { /** * set the notification preferences map (enable or disable the channels to be used for notifying the user) * @param userid user identifier - * @param notificationType the type of the notification * @param enabledChannels a map of the channels to which reach the user per notification, empty array or null values to set the key notification type off * @return true if everything was fine */ @@ -298,10 +440,16 @@ public interface DatabookStore { */ boolean addComment(Comment comment) throws FeedIDNotFoundException; /** + * @deprecated use getAllCommentByPost * @param feedid feed identifier * return all the comments belonging to the feedid */ List getAllCommentByFeed(String feedid); + /** + * @param postid the post identifier + * return all the comments belonging to the postid + */ + List getAllCommentByPost(String postid); /** * @param userid user identifier * @param timeInMillis time in milliseconds from which you want to start retrieve the feeds @@ -310,20 +458,20 @@ public interface DatabookStore { List getRecentCommentsByUserAndDate(String userid, long timeInMillis) throws Exception; /** * edit a comment - * @param commentid the comment identifier to edit + * @param comment the comment to edit * @return true if success, false otherwise */ boolean editComment(Comment comment) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, CommentIDNotFoundException, FeedIDNotFoundException; /** - * delete a comment + * deletes a comment * @param commentid the comment identifier to delete - * @parma feedid the feedid to which the comment is associated + * @param feedid the feedid to which the comment is associated * @return true if success, false otherwise */ boolean deleteComment(String commentid, String feedid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, CommentIDNotFoundException, FeedIDNotFoundException; /** * add a like to a feed - * @param the like instance + * @param like instance * @throws FeedIDNotFoundException */ boolean like(Like like) throws FeedIDNotFoundException; @@ -336,11 +484,18 @@ public interface DatabookStore { */ boolean unlike(String userid, String likeid, String feedid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, LikeIDNotFoundException, FeedIDNotFoundException; /** + * @deprecated use getAllLikedPostIdsByUser * @param userid user identifier * return all the feedids a user has liked */ List getAllLikedFeedIdsByUser(String userid); /** + * @param userid user identifier + * return all the feedids a user has liked + */ + List getAllLikedPostIdsByUser(String userid); + /** + * @deprecated use getAllLikedPostsByUser * @param userid user identifier * @param limit set 0 to get everything, an int to get the most recent -limit- liked feeds * @throws ColumnNameNotFoundException . @@ -353,25 +508,44 @@ public interface DatabookStore { List getAllLikedFeedsByUser(String userid, int limit) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException; /** + * @param userid user identifier + * @param limit set 0 to get everything, an int to get the most recent -limit- liked posts + * @throws ColumnNameNotFoundException . + * @throws FeedIDNotFoundException . + * @throws FeedTypeNotFoundException . + * @throws PrivacyLevelTypeNotFoundException + * @throws FeedIDNotFoundException . + * return all the feeds a user has liked + */ + List getAllLikedPostsByUser(String userid, int limit) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException; + + /** + * @deprecated use getRecentLikedPostsByUserAndDate * @param userid user identifier * @param timeInMillis time in milliseconds from which you want to start retrieve the feeds * @return the likes made to feeds in the range from: today to: timeInMillis */ List getRecentLikedFeedsByUserAndDate(String userid, long timeInMillis) throws IllegalArgumentException; /** - * @param feedid feed identifier - * return all the likes belonging to the feedid + * @param userid user identifier + * @param timeInMillis time in milliseconds from which you want to start retrieve the feeds + * @return the likes made to feeds in the range from: today to: timeInMillis */ - List getAllLikesByFeed(String feedid); + List getRecentLikedPostsByUserAndDate(String userid, long timeInMillis) throws IllegalArgumentException; + /** + * @param postid postid identifier + * return all the likes belonging to the postid + */ + List getAllLikesByPost(String postid); /** * * @param hashtags the hashtag including the '#' - * @param feedid the feedid to which the hashtag is associated + * @param postid the postid to which the hashtag is associated * @param vreid VRE identifier * @return true if success, false otherwise * @throws FeedIDNotFoundException */ - boolean saveHashTags(String feedid, String vreid, List hashtags) throws FeedIDNotFoundException; + boolean saveHashTags(String postid, String vreid, List hashtags) throws FeedIDNotFoundException; /** * * @param hashtags the hashtag including the '#' @@ -384,12 +558,12 @@ public interface DatabookStore { /** * * @param hashtags the hashtag including the '#' - * @param feedid the feedid to which the hashtag is associated + * @param postid the postid to which the hashtag is associated * @param vreid VRE identifier * @return true if success, false otherwise * @throws FeedIDNotFoundException */ - boolean deleteHashTags(String feedid, String vreid, List hashtags) throws FeedIDNotFoundException; + boolean deleteHashTags(String postid, String vreid, List hashtags) throws FeedIDNotFoundException; /** * * @param hashtags the hashtag including the '#' @@ -413,7 +587,7 @@ public interface DatabookStore { */ Map getVREHashtagsWithOccurrenceFilteredByTime(String vreid, long timestamp); /** - * + * @deprecated use getVREPostsByHashtag * @param vreid VRE identifier * @param hashtag the hashtag to look for including the '#', it is case sensitive * @throws ColumnNameNotFoundException . @@ -424,6 +598,19 @@ public interface DatabookStore { * @return all the feeds having the hashtag passed as parameter */ List getVREFeedsByHashtag(String vreid, String hashtag) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException; + /** + * + * @param vreid VRE identifier + * @param hashtag the hashtag to look for including the '#', it is case sensitive + * @throws ColumnNameNotFoundException . + * @throws FeedIDNotFoundException . + * @throws FeedTypeNotFoundException . + * @throws PrivacyLevelTypeNotFoundException + * @throws FeedIDNotFoundException . + * @return all the feeds having the hashtag passed as parameter + */ + List getVREPostsByHashtag(String vreid, String hashtag) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException; + /** * Save the invite for a given email into a given vre * @param invite the invite object instanc to save diff --git a/src/main/java/org/gcube/portal/databook/shared/Comment.java b/src/main/java/org/gcube/portal/databook/shared/Comment.java index 83bc5ed..f8042e8 100644 --- a/src/main/java/org/gcube/portal/databook/shared/Comment.java +++ b/src/main/java/org/gcube/portal/databook/shared/Comment.java @@ -32,7 +32,7 @@ public class Comment implements Serializable, Comparable { * * @param key * @param userid - * @param timestamp + * @param time * @param feedid * @param text * @param fullName diff --git a/src/main/java/org/gcube/portal/databook/shared/Feed.java b/src/main/java/org/gcube/portal/databook/shared/Feed.java index 3f6bba1..514a0db 100644 --- a/src/main/java/org/gcube/portal/databook/shared/Feed.java +++ b/src/main/java/org/gcube/portal/databook/shared/Feed.java @@ -6,7 +6,7 @@ import java.util.Date; /** * * @author Massimiliano Assante, ISTI-CNR - * + * @deprecated use org.gcube.portal.databook.shared.Post instead */ @SuppressWarnings("serial") public class Feed implements Serializable, Comparable { @@ -46,7 +46,7 @@ public class Feed implements Serializable, Comparable { * @param key a UUID * @param type an instance of FeedType * @param entityId the user or the app unique indentifier - * @param timestamp when + * @param time when * @param vreid a unique vre id * @param uri optional uri * @param uriThumbnail the thumbnail for the link posted @@ -87,7 +87,7 @@ public class Feed implements Serializable, Comparable { * @param key a UUID * @param type an instance of FeedType * @param entityId the user or the app unique indentifier - * @param timestamp when + * @param time when * @param vreid a unique vre id * @param uri optional uri * @param uriThumbnail the thumbnail for the link posted @@ -113,7 +113,7 @@ public class Feed implements Serializable, Comparable { * @param key a UUID * @param type an instance of FeedType * @param entityId the user or the app unique indentifier - * @param timestamp when + * @param time when * @param vreid a unique vre id * @param uri optional uri * @param uriThumbnail the thumbnail for the link posted @@ -152,7 +152,7 @@ public class Feed implements Serializable, Comparable { } /** * - * @return + * @return the key */ public String getKey() { return key; diff --git a/src/main/java/org/gcube/portal/databook/shared/FeedType.java b/src/main/java/org/gcube/portal/databook/shared/FeedType.java index 6e03358..71fe688 100644 --- a/src/main/java/org/gcube/portal/databook/shared/FeedType.java +++ b/src/main/java/org/gcube/portal/databook/shared/FeedType.java @@ -2,7 +2,7 @@ package org.gcube.portal.databook.shared; /** * @author Massimiliano Assante ISTI-CNR - * + * @deprecated use PostType * @version 1.2 October 2012 */ public enum FeedType { diff --git a/src/main/java/org/gcube/portal/databook/shared/Post.java b/src/main/java/org/gcube/portal/databook/shared/Post.java new file mode 100644 index 0000000..3dc59f1 --- /dev/null +++ b/src/main/java/org/gcube/portal/databook/shared/Post.java @@ -0,0 +1,322 @@ +package org.gcube.portal.databook.shared; + +import java.io.Serializable; +import java.util.Date; + +/** + * + * @author Massimiliano Assante, ISTI-CNR + * + */ +@SuppressWarnings("serial") +public class Post implements Serializable, Comparable { + + private String key; + private PostType type; + private String entityId; + private Date time; + private String vreid; + private String uri; + private String uriThumbnail; + private String description; + private PrivacyLevel privacy; + private String fullName; + private String email; + private String thumbnailURL; + private String commentsNo; + private String likesNo; + private String linkTitle; + private String linkDescription; + private String linkHost; + boolean applicationFeed; + /** + * this boolean indicates that the attachments to the post are > 1 + */ + boolean multiFileUpload; + /** + * default constructor + */ + public Post() { + super(); + } + /** + * To use ONLY for USER Feeds + * + * + * @param key a UUID + * @param type an instance of PostType + * @param entityId the user or the app unique indentifier + * @param time when + * @param vreid a unique vre id + * @param uri optional uri + * @param uriThumbnail the thumbnail for the link posted + * @param description optional description + * @param privacy the privacy level of PrivacyLevel + * @param fullName + * @param email + * @param thumbnailURL this is the user thumbnail url + * @param linkTitle optional to be used when posting links + * @param linkDescription optional to be used when posting links + * @param linkHost option to be used when posting linkgs + */ + public Post(String key, PostType type, String entityId, Date time, + String vreid, String uri, String uriThumbnail, String description, PrivacyLevel privacy, + String fullName, String email, String thumbnailURL, String linkTitle, String linkDescription, String linkHost) { + this.key = key; + this.type = type; + this.entityId = entityId; + this.time = time; + this.vreid = vreid; + this.uri = uri; + this.uriThumbnail = uriThumbnail; + this.description = description; + this.privacy = privacy; + this.fullName = fullName; + this.email = email; + this.thumbnailURL = thumbnailURL; + this.commentsNo = "0"; + this.likesNo = "0"; + this.linkDescription = linkDescription; + this.linkTitle = linkTitle; + this.linkHost = linkHost; + this.applicationFeed = false; + } + /** + * To use for USER and ApplicationProfile Feeds + * + * @param key a UUID + * @param type an instance of FeedType + * @param entityId the user or the app unique indentifier + * @param time when + * @param vreid a unique vre id + * @param uri optional uri + * @param uriThumbnail the thumbnail for the link posted + * @param description optional description + * @param privacy the privacy level of PrivacyLevel + * @param fullName + * @param email + * @param thumbnailURL this is the user thumbnail url + * @param linkTitle optional to be used when posting links + * @param linkDescription optional to be used when posting links + * @param applicationFeed tell if this is an application feed or a user feed + */ + public Post(String key, PostType type, String entityId, Date time, + String vreid, String uri, String uriThumbnail, String description, PrivacyLevel privacy, + String fullName, String email, String thumbnailURL, String linkTitle, String linkDescription, String linkHost, boolean applicationFeed) { + this(key, type, entityId, time, vreid, uri, uriThumbnail, description, privacy, fullName, email, thumbnailURL, linkTitle, linkDescription, linkHost); + this.applicationFeed = applicationFeed; + } + + + /** + * for serialization purposes + * @param key a UUID + * @param type an instance of PostType + * @param entityId the user or the app unique indentifier + * @param time when + * @param vreid a unique vre id + * @param uri optional uri + * @param uriThumbnail the thumbnail for the link posted + * @param description optional description + * @param privacy the privacy level of PrivacyLevel + * @param fullName + * @param email + * @param thumbnailURL this is the user thumbnail url + * @param linkTitle optional to be used when posting links + * @param linkDescription optional to be used when posting links + */ + public Post(String key, PostType type, String entityId, Date time, + String vreid, String uri, String uriThumbnail, String description, PrivacyLevel privacy, + String fullName, String email, String thumbnailURL, String commentsNo, + String likesNo, String linkTitle, String linkDescription, String linkHost, boolean applicationFeed, boolean multiFileUpload) { + super(); + this.key = key; + this.type = type; + this.entityId = entityId; + this.time = time; + this.vreid = vreid; + this.uri = uri; + this.uriThumbnail = uriThumbnail; + this.description = description; + this.privacy = privacy; + this.fullName = fullName; + this.email = email; + this.thumbnailURL = thumbnailURL; + this.commentsNo = commentsNo; + this.likesNo = likesNo; + this.linkDescription = linkDescription; + this.linkTitle = linkTitle; + this.linkHost = linkHost; + this.applicationFeed = applicationFeed; + this.multiFileUpload = multiFileUpload; + } + /** + * + * @return post id + */ + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public PostType getType() { + return type; + } + + public void setType(PostType type) { + this.type = type; + } + /** + * + * @return the User or the App id + */ + public String getEntityId() { + return entityId; + } + /** + * set the User or the App id + * @param entityId the UserId or the AppId id + */ + public void setEntityId(String entityId) { + this.entityId = entityId; + } + + public Date getTime() { + return time; + } + + public void setTime(Date time) { + this.time = time; + } + + public String getVreid() { + return vreid; + } + + public void setVreid(String vreid) { + this.vreid = vreid; + } + + public String getUri() { + return uri; + } + + public void setUri(String uri) { + this.uri = uri; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public PrivacyLevel getPrivacy() { + return privacy; + } + + public void setPrivacy(PrivacyLevel privacy) { + this.privacy = privacy; + } + + public String getFullName() { + return fullName; + } + + public void setFullName(String fullName) { + this.fullName = fullName; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getThumbnailURL() { + return thumbnailURL; + } + + public void setThumbnailURL(String thumbnailURL) { + this.thumbnailURL = thumbnailURL; + } + + public String getCommentsNo() { + return commentsNo; + } + public void setCommentsNo(String commentsNo) { + this.commentsNo = commentsNo; + } + public String getLikesNo() { + return likesNo; + } + public void setLikesNo(String likesNo) { + this.likesNo = likesNo; + } + public String getUriThumbnail() { + return uriThumbnail; + } + public void setUriThumbnail(String uriThumbnail) { + this.uriThumbnail = uriThumbnail; + } + + public String getLinkTitle() { + return linkTitle; + } + public void setLinkTitle(String linkTitle) { + this.linkTitle = linkTitle; + } + public String getLinkDescription() { + return linkDescription; + } + public void setLinkDescription(String linkDescription) { + this.linkDescription = linkDescription; + } + public int compareTo(Post toCompare) { + if (this.time.after(toCompare.getTime())) + return 1; + if (this.time.before(toCompare.getTime())) + return -1; + return 0; + } + public String getLinkHost() { + return linkHost; + } + public void setLinkHost(String linkHost) { + this.linkHost = linkHost; + } + + public boolean isApplicationFeed() { + return applicationFeed; + } + public void setApplicationFeed(boolean applicationFeed) { + this.applicationFeed = applicationFeed; + } + public boolean isMultiFileUpload() { + return multiFileUpload; + } + public void setMultiFileUpload(boolean multiFileUpload) { + this.multiFileUpload = multiFileUpload; + } + @Override + public String toString() { + return "Feed [key=" + key + ", type=" + type + ", entityId=" + entityId + + ", time=" + time + ", vreid=" + vreid + ", uri=" + uri + + ", uriThumbnail=" + uriThumbnail + ", description=" + + description + ", privacy=" + privacy + ", fullName=" + + fullName + ", email=" + email + ", thumbnailURL=" + + thumbnailURL + ", commentsNo=" + commentsNo + ", likesNo=" + + likesNo + ", linkTitle=" + linkTitle + ", linkDescription=" + + linkDescription + ", linkHost=" + linkHost + + ", applicationFeed=" + applicationFeed + + ", multiFileUpload=" + multiFileUpload + "]"; + } + +} diff --git a/src/main/java/org/gcube/portal/databook/shared/PostType.java b/src/main/java/org/gcube/portal/databook/shared/PostType.java new file mode 100644 index 0000000..b86c0c7 --- /dev/null +++ b/src/main/java/org/gcube/portal/databook/shared/PostType.java @@ -0,0 +1,18 @@ +package org.gcube.portal.databook.shared; + +/** + * @author Massimiliano Assante ISTI-CNR + * + */ +public enum PostType { + JOIN, SHARE, PUBLISH, TWEET, CONNECTED, + /** + * Special case used when accounting + */ + ACCOUNTING, + /** + * Special case used when a Feed is removed + */ + DISABLED; +} + diff --git a/src/main/java/org/gcube/portal/databook/shared/RangeFeeds.java b/src/main/java/org/gcube/portal/databook/shared/RangeFeeds.java index 58e8a6d..50d90bb 100644 --- a/src/main/java/org/gcube/portal/databook/shared/RangeFeeds.java +++ b/src/main/java/org/gcube/portal/databook/shared/RangeFeeds.java @@ -5,7 +5,7 @@ import java.util.ArrayList; /** * * @author Massimiliano Assante, ISTI-CNR - * + * @deprecated use RangePosts */ @SuppressWarnings("serial") public class RangeFeeds implements Serializable { diff --git a/src/main/java/org/gcube/portal/databook/shared/RangePosts.java b/src/main/java/org/gcube/portal/databook/shared/RangePosts.java new file mode 100644 index 0000000..4e645b5 --- /dev/null +++ b/src/main/java/org/gcube/portal/databook/shared/RangePosts.java @@ -0,0 +1,40 @@ +package org.gcube.portal.databook.shared; + +import java.io.Serializable; +import java.util.ArrayList; +/** + * + * @author Massimiliano Assante, ISTI-CNR + * + */ +@SuppressWarnings("serial") +public class RangePosts implements Serializable { + + private int lastReturnedPostTimelineIndex; + private ArrayList posts; + + public RangePosts() { + super(); + } + + public RangePosts(int lastReturnedPostTimelineIndex, ArrayList feeds) { + super(); + this.lastReturnedPostTimelineIndex = lastReturnedPostTimelineIndex; + this.posts = feeds; + } + + public int getLastReturnedPostTimelineIndex() { + return lastReturnedPostTimelineIndex; + } + public void setLastReturnedPostTimelineIndex(int lastReturnedPostTimelineIndex) { + this.lastReturnedPostTimelineIndex = lastReturnedPostTimelineIndex; + } + public ArrayList getPosts() { + return posts; + } + public void setPosts(ArrayList posts) { + this.posts = posts; + } + + +}