diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..5e8fabe
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,13 @@
+#FROM d4science/smartgears-distribution:4.0.0-SNAPSHOT-java11-tomcat9
+FROM smartgears-distribution:4.0.0-java11-tomcat9
+
+ARG REPOUSER=admin
+ARG REPOPWD=admin
+
+COPY ./target/social-service.war /usr/local/tomcat/webapps/
+
+COPY ./docker/logback.xml /etc/
+COPY ./docker/container.ini /etc/
+RUN unzip /usr/local/tomcat/webapps/social-service.war -d /usr/local/tomcat/webapps/social-service
+RUN rm /usr/local/tomcat/webapps/social-service.war
+EXPOSE 8080
diff --git a/docker/container.ini b/docker/container.ini
new file mode 100644
index 0000000..e8cd44e
--- /dev/null
+++ b/docker/container.ini
@@ -0,0 +1,28 @@
+[node]
+mode = offline
+hostname = socialservice
+protocol= http
+port = 8080
+infrastructure = gcube
+authorizeChildrenContext = true
+publicationFrequencyInSeconds = 60
+
+[properties]
+SmartGearsDistribution = 4.0.0-SNAPSHOT
+SmartGearsDistributionBundle = UnBundled
+
+[site]
+country = it
+location = pisa
+
+[authorization]
+factory = org.gcube.smartgears.security.defaults.DefaultAuthorizationProviderFactory
+factory.endpoint = https://accounts.dev.d4science.org/auth/realms/d4science/protocol/openid-connect/token
+credentials.class = org.gcube.smartgears.security.SimpleCredentials
+//for smartgears
+credentials.clientID = social-service-hosting-node-client
+credentials.secret = 979bd3bc-5cc4-11ec-bf63-0242ac130002
+
+//for interacting with alfredo's service
+socialservice
+yqMpmqwlcu9o2mZTWMyDq0om8QMcjUEb
\ No newline at end of file
diff --git a/docker/logback.xml b/docker/logback.xml
new file mode 100644
index 0000000..f125098
--- /dev/null
+++ b/docker/logback.xml
@@ -0,0 +1,23 @@
+
+
+
+ Ï
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docker/properties b/docker/properties
new file mode 100644
index 0000000..2c035d9
--- /dev/null
+++ b/docker/properties
@@ -0,0 +1,2 @@
+${{adminId}}=social
+${{adminPwd}}=social
\ No newline at end of file
diff --git a/enunciate.xml b/enunciate.xml
index 3524ef4..97526b3 100644
--- a/enunciate.xml
+++ b/enunciate.xml
@@ -2,22 +2,36 @@
-
-
-
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
-
-
+
+
\ No newline at end of file
diff --git a/gcube/extra-resources/WEB-INF/application.yaml b/gcube/extra-resources/WEB-INF/application.yaml
new file mode 100644
index 0000000..a1502f1
--- /dev/null
+++ b/gcube/extra-resources/WEB-INF/application.yaml
@@ -0,0 +1,7 @@
+name: ${artifactId}
+group: ${groupId}
+version: ${version}
+description: ${description}
+excludes:
+ - path: /docs.*
+ - path: /api-docs.*
\ No newline at end of file
diff --git a/gcube/extra-resources/WEB-INF/docker.md b/gcube/extra-resources/WEB-INF/docker.md
new file mode 100644
index 0000000..f83ff28
--- /dev/null
+++ b/gcube/extra-resources/WEB-INF/docker.md
@@ -0,0 +1,5 @@
+mvn clean package
+docker build -t idm .
+docker compose up -d --build --force-recreate
+
+#docker run -it -d -p 9090:8080 --name idm idm
diff --git a/gcube/extra-resources/WEB-INF/web.xml b/gcube/extra-resources/WEB-INF/web.xml
new file mode 100644
index 0000000..243fb96
--- /dev/null
+++ b/gcube/extra-resources/WEB-INF/web.xml
@@ -0,0 +1,20 @@
+
+
+
+ admin-username
+ {{adminId}}
+
+
+ admin-pwd
+ {{adminPwd}}
+
+
+ org.gcube.social_networking.SocialService
+
+
+
+ org.gcube.social_networking.SocialService
+ /social-service/*
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 9d1d8d2..3ba5e06 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.gcube.tools
maven-parent
- 1.1.0
+ 1.2.0
org.gcube.social_networking
social-service
@@ -16,6 +16,9 @@
UTF-8
+ 11
+ 11
+
${project.basedir}${file.separator}src${file.separator}main${file.separator}webapp${file.separator}WEB-INF
2.14.0
@@ -35,7 +38,7 @@
org.gcube.distribution
gcube-smartgears-bom
- 2.5.0
+ 3.0.1-SNAPSHOT
pom
import
@@ -47,6 +50,7 @@
import
+
@@ -54,33 +58,46 @@
org.slf4j
slf4j-api
-
- org.gcube.common
- authorization-utils
- [2.2.0, 3.0.0-SNAPSHOT)
-
-
- org.glassfish.jersey.media
- jersey-media-multipart
-
+
+
org.glassfish.jersey.containers
jersey-container-servlet
+
+ org.glassfish.jersey.containers
+ jersey-container-servlet-core
+
+
javax.ws.rs
javax.ws.rs-api
- org.gcube.common.portal
- portal-manager
- provided
+ org.gcube.core
+ common-smartgears-app
-
+
+ org.gcube.core
+ common-smartgears
+
+
+ org.gcube.core
+ common-scope
+
+
+ org.gcube.core
+ common-scope-maps
+
+
+ org.gcube.common
+ authorization-client
+
+
org.gcube.social-networking
social-service-model
- [1.2.0-SNAPSHOT, 2.0.0)
+ 2.0.0-SNAPSHOT
com.datastax.oss
@@ -92,6 +109,11 @@
java-driver-mapper-runtime
${cassandra.driver.oss.version}
+
+ commons-lang
+ commons-lang
+ 2.6
+
com.sun.mail
javax.mail
@@ -99,33 +121,9 @@
compile
- commons-lang
- commons-lang
- 2.6
+ org.gcube.common.portal
+ portal-manager
-
- org.gcube.core
- common-smartgears-app
-
-
-
-
- javax.xml.ws
- jaxws-api
- provided
-
-
- org.projectlombok
- lombok
- provided
-
-
-
-
- org.gcube.core
- common-smartgears
-
-
@@ -144,7 +142,6 @@
javax.servlet
javax.servlet-api
3.1.0
- provided
@@ -152,7 +149,7 @@
junit
junit
- 4.11
+ 4.13.2
test
@@ -161,32 +158,12 @@
test
-
-
-
-
-
- kr.motd.maven
- sphinx-maven-plugin
- 2.10.0
-
-
- ${project.build.directory}/${project.artifactId}-${project.version}/docs
- html
- ${basedir}/docs
- ${basedir}/docs
-
-
-
- process-resources
-
- generate
-
-
-
-
-
+
+ ${project.artifactId}
+
+
+
+
org.apache.maven.plugins
maven-resources-plugin
@@ -227,7 +203,7 @@
-
+-->
org.apache.maven.plugins
@@ -240,4 +216,4 @@
-
+
\ No newline at end of file
diff --git a/src/main/java/org/gcube/social_networking/DBCassandraAstyanaxImpl.java b/src/main/java/org/gcube/social_networking/DBCassandraAstyanaxImpl.java
new file mode 100644
index 0000000..59f1725
--- /dev/null
+++ b/src/main/java/org/gcube/social_networking/DBCassandraAstyanaxImpl.java
@@ -0,0 +1,4084 @@
+package org.gcube.social_networking;
+
+import java.time.Instant;
+import java.util.*;
+import java.util.stream.Collectors;
+
+import javax.mail.internet.AddressException;
+import javax.mail.internet.InternetAddress;
+import javax.print.attribute.standard.MediaSize;
+
+import com.datastax.oss.driver.api.core.CqlSession;
+import com.datastax.oss.driver.api.core.cql.*;
+import com.datastax.oss.driver.api.querybuilder.QueryBuilder;
+import org.apache.commons.lang.NullArgumentException;
+import org.gcube.portal.databook.shared.*;
+import org.gcube.portal.databook.shared.ex.*;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.gcube.portal.databook.server.CassandraClusterConnection.closeSession;
+import static org.gcube.portal.databook.server.Schema.*;
+/**
+ * @author Massimiliano Assante ISTI-CNR
+ * @author Costantino Perciante ISTI-CNR
+ * @author Ahmed Ibrahim ISTI-CNR
+ * This class is used for querying and adding data to Cassandra via Datastax High Level API
+ */
+public final class DBCassandraAstyanaxImpl implements DatabookStore {
+
+ /**
+ * logger
+ */
+ private static final Logger _log = LoggerFactory.getLogger(DBCassandraAstyanaxImpl.class);
+
+ /**
+ * connection instance
+ */
+ private CassandraClusterConnection conn;
+
+ protected CassandraClusterConnection getConnection() {
+ return conn;
+ }
+ /**
+ * use this constructor carefully from test classes
+ * @param dropSchema set true if you want do drop the current and set up new one
+ */
+ protected DBCassandraAstyanaxImpl(boolean dropSchema) {
+ try {
+ conn = new CassandraClusterConnection(dropSchema);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ /**
+ * public constructor, no dropping schema is allowed
+ */
+ public DBCassandraAstyanaxImpl() {
+ try {
+ conn = new CassandraClusterConnection(false);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * public constructor, no dropping schema is allowed, infrastructureName is given.
+ */
+ public DBCassandraAstyanaxImpl(String infrastructureName) {
+ try {
+ conn = new CassandraClusterConnection(false, infrastructureName);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /*
+ Utility Functions
+ */
+ private static boolean existRecordbyId(CqlSession session, String id, String tableName, String colName) {
+ PreparedStatement stmt = session.prepare(QueryBuilder
+ .selectFrom(tableName).column(colName)
+ .whereColumn(colName)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ return session.execute(stmt.bind(id)).getAvailableWithoutFetching() > 0;
+ }
+
+ private static boolean existRecordbyCompId(CqlSession session, String col1, String col2, String id1, String id2, String tableName) {
+ PreparedStatement stmt = session.prepare(QueryBuilder
+ .selectFrom(tableName).all()
+ .whereColumn(col1)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .whereColumn(col2)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ return session.execute(stmt.bind(id1, id2)).getAvailableWithoutFetching() > 0;
+ }
+
+ private static PreparedStatement updatePostEntry(CqlSession session, String colName){
+ return session.prepare(QueryBuilder.update(POSTS)
+ .setColumn(colName, QueryBuilder.bindMarker())
+ .whereColumn(POST_ID).isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ }
+ private static Optional < Post > findPostById(String postid, CqlSession session) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException {
+ PreparedStatement stmtFindPost = session.prepare(QueryBuilder
+ .selectFrom(POSTS).all()
+ .whereColumn(POST_ID)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ ResultSet rs = session.execute(stmtFindPost.bind(UUID.fromString(postid)));
+ // We query by the primary key ensuring unicity
+ Row record = rs.one();
+ return (null != record) ? Optional.of(readPostFromRow(record)) :Optional.empty();
+ }
+
+ private static Attachment readAttachmentFromRow(Row record) {
+ Attachment a = new Attachment();
+ a.setId(Objects.requireNonNull(record.getUuid(ATTACH_ID)).toString());
+ a.setUri(record.getString(URI));
+ a.setName(record.getString(NAME));
+ a.setDescription(record.getString(DESCRIPTION));
+ a.setThumbnailURL(record.getString(URI_THUMBNAIL));
+ a.setMimeType(record.getString(MIME_TYPE));
+ return a;
+ }
+ private static Notification readNotificationFromRow(Row record) throws NotificationTypeNotFoundException {
+ Notification a = new Notification();
+ a.setKey(Objects.requireNonNull(record.getUuid(NOT_ID)).toString());
+ a.setType(getNotificationType(Objects.requireNonNull(record.getString(TYPE))));
+ a.setUserid(record.getString(USER_ID));
+ a.setSubjectid(record.getString(SUBJECT_ID));
+ a.setTime(Date.from(Objects.requireNonNull(record.getInstant(TIMESTAMP))));
+ a.setUri(record.getString(URI));
+ a.setDescription(record.getString(DESCRIPTION));
+ a.setRead(record.getBoolean(IS_READ));
+ a.setSenderid(record.getString(SENDER_ID));
+ a.setSenderFullName(record.getString(SENDER_FULL_NAME));
+ a.setSenderThumbnail(record.getString(SENDER_THUMBNAIL_URL));
+ return a;
+ }
+ private static Post readPostFromRow(Row record) throws FeedTypeNotFoundException, PrivacyLevelTypeNotFoundException {
+ Post a = new Post();
+
+ a.setKey(Objects.requireNonNull(record.getUuid(POST_ID)).toString());
+ a.setType(getPostType(Objects.requireNonNull(record.getString(TYPE))));
+ a.setEntityId(record.getString(ENTITY_ID));
+ a.setTime(Date.from(Objects.requireNonNull(record.getInstant(TIMESTAMP))));
+ a.setVreid(record.getString(VRE_ID));
+ a.setUri(record.getString(URI));
+ a.setUriThumbnail(record.getString(URI_THUMBNAIL));
+ a.setDescription(record.getString(DESCRIPTION));
+ a.setPrivacy(getPrivacyLevel(Objects.requireNonNull(record.getString(PRIVACY))));
+ a.setFullName(record.getString(FULL_NAME));
+ a.setEmail(record.getString(EMAIL));
+ a.setThumbnailURL(record.getString(THUMBNAIL_URL));
+ a.setCommentsNo(String.valueOf(record.getLong(COMMENTS_NO)));
+ a.setLikesNo(String.valueOf(record.getLong(LIKES_NO)));
+ a.setLinkDescription(record.getString(LINK_DESCRIPTION));
+ a.setLinkTitle(record.getString(LINK_TITLE));
+ a.setLinkHost(record.getString(LINK_HOST));
+ a.setApplicationFeed(record.getBoolean(IS_APPLICATION_POST));
+ a.setMultiFileUpload(record.getBoolean(MULTI_FILE_UPLOAD));
+
+ return a;
+ }
+ private static Like readLikeFromRow(Row record) {
+ Like a = new Like();
+ a.setKey(Objects.requireNonNull(record.getUuid(LIKE_ID)).toString());
+ a.setUserid(record.getString(USER_ID));
+ a.setTime(Date.from(Objects.requireNonNull(record.getInstant(TIMESTAMP))));
+ a.setFeedid(Objects.requireNonNull(record.getUuid(POST_ID)).toString());
+ a.setFullName(record.getString(FULL_NAME));
+ a.setThumbnailURL(record.getString(THUMBNAIL_URL));
+ return a;
+ }
+ private static Comment readCommentFromRow(Row record) {
+ Comment a = new Comment();
+ a.setKey(Objects.requireNonNull(record.getUuid(COMMENT_ID)).toString());
+ a.setUserid(record.getString(USER_ID));
+ a.setTime(Date.from(Objects.requireNonNull(record.getInstant(TIMESTAMP))));
+ a.setFeedid(Objects.requireNonNull(record.getUuid(POST_ID)).toString());
+ a.setFullName(record.getString(FULL_NAME));
+ a.setThumbnailURL(record.getString(THUMBNAIL_URL));
+ a.setText(record.getString(COMMENT));
+ a.setEdit(!record.isNull(IS_EDIT) && record.getBoolean(IS_EDIT));
+ a.setLastEditTime(record.isNull(LAST_EDIT_TIME)? null : Date.from(Objects.requireNonNull(record.getInstant(LAST_EDIT_TIME))));
+ return a;
+ }
+ private static Invite readAInviteFromRow(Row record) throws InviteStatusNotFoundException {
+ Invite a = new Invite();
+ a.setKey(Objects.requireNonNull(record.getUuid(INVITE_ID)).toString());
+ a.setSenderUserId(record.getString(SENDER_USER_ID));
+ a.setVreid(record.getString(VRE_ID));
+ a.setInvitedEmail(record.getString(EMAIL));
+ a.setControlCode(record.getString(CONTROL_CODE));
+ a.setStatus(getInviteStatusType(Objects.requireNonNull(record.getString(STATUS))));
+ a.setTime(Date.from(Objects.requireNonNull(record.getInstant(TIMESTAMP))));
+ a.setSenderFullName(record.getString(SENDER_FULL_NAME));
+ return a;
+ }
+ private static Feed readFeedFromRow(Row record) throws FeedTypeNotFoundException, PrivacyLevelTypeNotFoundException {
+ Feed a = new Feed();
+
+ a.setKey(Objects.requireNonNull(record.getUuid(POST_ID)).toString());
+ a.setType(getFeedType(Objects.requireNonNull(record.getString(TYPE))));
+ a.setEntityId(record.getString(ENTITY_ID));
+ a.setTime(Date.from(Objects.requireNonNull(record.getInstant(TIMESTAMP))));
+ a.setVreid(record.getString(VRE_ID));
+ a.setUri(record.getString(URI));
+ a.setUriThumbnail(record.getString(URI_THUMBNAIL));
+ a.setDescription(record.getString(DESCRIPTION));
+ a.setPrivacy(getPrivacyLevel(Objects.requireNonNull(record.getString(PRIVACY))));
+ a.setFullName(record.getString(FULL_NAME));
+ a.setEmail(record.getString(EMAIL));
+ a.setThumbnailURL(record.getString(THUMBNAIL_URL));
+ a.setCommentsNo(String.valueOf(record.getLong(COMMENTS_NO)));
+ a.setLikesNo(String.valueOf(record.getLong(LIKES_NO)));
+ a.setLinkDescription(record.getString(LINK_DESCRIPTION));
+ a.setLinkTitle(record.getString(LINK_TITLE));
+ a.setLinkHost(record.getString(LINK_HOST));
+ a.setApplicationFeed(record.getBoolean(IS_APPLICATION_POST));
+ a.setMultiFileUpload(record.getBoolean(MULTI_FILE_UPLOAD));
+
+ return a;
+ }
+
+
+ private static Optional < Feed > findFeedById(String postid, CqlSession session) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException {
+ PreparedStatement stmtFindPost = session.prepare(QueryBuilder
+ .selectFrom(POSTS).all()
+ .whereColumn(POST_ID)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ ResultSet rs = session.execute(stmtFindPost.bind(UUID.fromString(postid)));
+ // We query by the primary key ensuring unicity
+ Row record = rs.one();
+ return (null != record) ? Optional.of(readFeedFromRow(record)) :Optional.empty();
+ }
+ private static Optional < Notification > findNotById(String notid, CqlSession session) throws NotificationTypeNotFoundException {
+ PreparedStatement stmtFind = session.prepare(QueryBuilder
+ .selectFrom(NOTIFICATIONS).all()
+ .whereColumn(NOT_ID)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ ResultSet rs = session.execute(stmtFind.bind(UUID.fromString(notid)));
+ // We query by the primary key ensuring unicity
+ Row record = rs.one();
+ return (null != record) ? Optional.of(readNotificationFromRow(record)) :Optional.empty();
+ }
+
+
+ private static PreparedStatement updateInviteEntry(CqlSession session, String colName){
+ return session.prepare(QueryBuilder.update(INVITES)
+ .setColumn(colName, QueryBuilder.bindMarker())
+ .whereColumn(INVITE_ID).isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ }
+
+ private static PreparedStatement updateVreInviteEntry(CqlSession session, String colName){
+ return session.prepare(QueryBuilder.update(VRE_INVITES)
+ .setColumn(colName, QueryBuilder.bindMarker())
+ .whereColumn(VRE_ID).isEqualTo(QueryBuilder.bindMarker())
+ .whereColumn(INVITE_ID).isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ }
+
+ private static PreparedStatement deleteHashtagEntry(CqlSession session){
+ return session.prepare(QueryBuilder.deleteFrom(HASHTAGGED_POSTS)
+ .whereColumn(HASHTAG)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .whereColumn(POST_ID)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ }
+ private static PreparedStatement deleteHashtagCommentEntry(CqlSession session){
+ return session.prepare(QueryBuilder.deleteFrom(HASHTAGGED_COMMENTS)
+ .whereColumn(HASHTAG)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .whereColumn(COMMENT_ID)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ }
+ private static PreparedStatement deleteLikeEntry(CqlSession session){
+ return session.prepare(QueryBuilder.deleteFrom(LIKES)
+ .whereColumn(LIKE_ID).isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ }
+ private static PreparedStatement deleteUserLikeEntry(CqlSession session){
+ return session.prepare(QueryBuilder.deleteFrom(USER_LIKED_POSTS)
+ .whereColumn(USER_ID)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .whereColumn(LIKE_ID)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ }
+
+ private static PreparedStatement updateCommentEntry(CqlSession session, String colName){
+ return session.prepare(QueryBuilder.update(COMMENTS)
+ .setColumn(colName, QueryBuilder.bindMarker())
+ .whereColumn(COMMENT_ID).isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ }
+
+ private static PreparedStatement deleteCommentEntry(CqlSession session){
+ return session.prepare(QueryBuilder.deleteFrom(COMMENTS)
+ .whereColumn(COMMENT_ID).isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ }
+
+ private static PreparedStatement updateNotificationEntry(CqlSession session, String colName){
+ return session.prepare(QueryBuilder.update(NOTIFICATIONS)
+ .setColumn(colName, QueryBuilder.bindMarker())
+ .whereColumn(NOT_ID).isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ }
+
+ private static PreparedStatement deleteUnreadNotEntry(CqlSession session){
+ return session.prepare(QueryBuilder.deleteFrom(USER_NOTIFICATIONS_UNREAD)
+ .whereColumn(USER_ID)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .whereColumn(TIMESTAMP)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ }
+ private static BatchStatement getBatch(){
+ return BatchStatement.builder(BatchType.LOGGED).build();
+ }
+
+ private static PreparedStatement createPostEntry(CqlSession session){
+ return session.prepare(
+ QueryBuilder.insertInto(POSTS)
+ .value(POST_ID, QueryBuilder.bindMarker())
+ .value(LINK_HOST, QueryBuilder.bindMarker())
+ .value(DESCRIPTION, QueryBuilder.bindMarker())
+ .value(EMAIL, QueryBuilder.bindMarker())
+ .value(LIKES_NO, QueryBuilder.bindMarker())
+ .value(THUMBNAIL_URL, QueryBuilder.bindMarker())
+ .value(LINK_DESCRIPTION, QueryBuilder.bindMarker())
+ .value(TIMESTAMP, QueryBuilder.bindMarker())
+ .value(URI, QueryBuilder.bindMarker())
+ .value(IS_APPLICATION_POST, QueryBuilder.bindMarker())
+ .value(ENTITY_ID, QueryBuilder.bindMarker())
+ .value(PRIVACY, QueryBuilder.bindMarker())
+ .value(TYPE, QueryBuilder.bindMarker())
+ .value(URI_THUMBNAIL, QueryBuilder.bindMarker())
+ .value(VRE_ID, QueryBuilder.bindMarker())
+ .value(MULTI_FILE_UPLOAD, QueryBuilder.bindMarker())
+ .value(FULL_NAME, QueryBuilder.bindMarker())
+ .value(COMMENTS_NO, QueryBuilder.bindMarker())
+ .value(LINK_TITLE, QueryBuilder.bindMarker())
+ .build());
+ }
+ private static PreparedStatement createUserTimelineEntry(CqlSession session){
+ return session.prepare(
+ QueryBuilder.insertInto(USER_TIMELINE_POSTS)
+ .value(USER_ID, QueryBuilder.bindMarker())
+ .value(TIMESTAMP, QueryBuilder.bindMarker())
+ .value(POST_ID, QueryBuilder.bindMarker())
+ .build());
+ }
+ private static PreparedStatement createVreTimelineEntry(CqlSession session){
+ return session.prepare(
+ QueryBuilder.insertInto(VRE_TIMELINE_POSTS)
+ .value(VRE_ID, QueryBuilder.bindMarker())
+ .value(TIMESTAMP, QueryBuilder.bindMarker())
+ .value(POST_ID, QueryBuilder.bindMarker())
+ .build());
+ }
+ private static PreparedStatement createAppTimelineEntry(CqlSession session){
+ return session.prepare(
+ QueryBuilder.insertInto(APP_TIMELINE_POSTS)
+ .value(APP_ID, QueryBuilder.bindMarker())
+ .value(TIMESTAMP, QueryBuilder.bindMarker())
+ .value(POST_ID, QueryBuilder.bindMarker())
+ .build());
+ }
+ private static PreparedStatement createNotificationEntry(CqlSession session){
+ return session.prepare(
+ QueryBuilder.insertInto(NOTIFICATIONS)
+ .value(NOT_ID, QueryBuilder.bindMarker())
+ .value(TYPE, QueryBuilder.bindMarker())
+ .value(USER_ID, QueryBuilder.bindMarker())
+ .value(SUBJECT_ID, QueryBuilder.bindMarker())
+ .value(TIMESTAMP, QueryBuilder.bindMarker())
+ .value(DESCRIPTION, QueryBuilder.bindMarker())
+ .value(URI, QueryBuilder.bindMarker())
+ .value(SENDER_ID, QueryBuilder.bindMarker())
+ .value(SENDER_FULL_NAME, QueryBuilder.bindMarker())
+ .value(SENDER_THUMBNAIL_URL, QueryBuilder.bindMarker())
+ .value(IS_READ, QueryBuilder.bindMarker())
+ .build());
+ }
+ private static PreparedStatement createUserNotificationsEntry(CqlSession session){
+ return session.prepare(
+ QueryBuilder.insertInto(USER_NOTIFICATIONS)
+ .value(USER_ID, QueryBuilder.bindMarker())
+ .value(TIMESTAMP, QueryBuilder.bindMarker())
+ .value(NOT_ID, QueryBuilder.bindMarker())
+ .build());
+ }
+ private static PreparedStatement createUnreadNotificationEntry(CqlSession session){
+ return session.prepare(
+ QueryBuilder.insertInto(USER_NOTIFICATIONS_UNREAD)
+ .value(USER_ID, QueryBuilder.bindMarker())
+ .value(TIMESTAMP, QueryBuilder.bindMarker())
+ .value(NOT_ID, QueryBuilder.bindMarker())
+ .build());
+ }
+ private static PreparedStatement createNotificationPreferenceEntry(CqlSession session){
+ return session.prepare(
+ QueryBuilder.insertInto(USER_NOTIFICATIONS_PREFERENCES)
+ .value(USER_ID, QueryBuilder.bindMarker())
+ .value(TYPE, QueryBuilder.bindMarker())
+ .value(PREFERENCE, QueryBuilder.bindMarker())
+ .build());
+ }
+
+ private static PreparedStatement createNewCommentEntry(CqlSession session){
+ return session.prepare(
+ QueryBuilder.insertInto(COMMENTS)
+ .value(COMMENT_ID, QueryBuilder.bindMarker())
+ .value(USER_ID, QueryBuilder.bindMarker())
+ .value(FULL_NAME, QueryBuilder.bindMarker())
+ .value(THUMBNAIL_URL, QueryBuilder.bindMarker())
+ .value(COMMENT, QueryBuilder.bindMarker())
+ .value(POST_ID, QueryBuilder.bindMarker())
+ .value(TIMESTAMP, QueryBuilder.bindMarker())
+ .value(IS_EDIT, QueryBuilder.bindMarker())
+ .value(LAST_EDIT_TIME, QueryBuilder.bindMarker())
+ .build());
+ }
+ private static PreparedStatement createNewLikeEntry(CqlSession session){
+ return session.prepare(
+ QueryBuilder.insertInto(LIKES)
+ .value(LIKE_ID, QueryBuilder.bindMarker())
+ .value(USER_ID, QueryBuilder.bindMarker())
+ .value(FULL_NAME, QueryBuilder.bindMarker())
+ .value(THUMBNAIL_URL, QueryBuilder.bindMarker())
+ .value(POST_ID, QueryBuilder.bindMarker())
+ .value(TIMESTAMP, QueryBuilder.bindMarker())
+ .build());
+ }
+ private static PreparedStatement createNewUserLikesEntry(CqlSession session){
+ return session.prepare(
+ QueryBuilder.insertInto(USER_LIKED_POSTS)
+ .value(USER_ID, QueryBuilder.bindMarker())
+ .value(LIKE_ID, QueryBuilder.bindMarker())
+ .value(POST_ID, QueryBuilder.bindMarker())
+ .build());
+ }
+ private static PreparedStatement createNewHashtagTimelineEntry(CqlSession session){
+ return session.prepare(
+ QueryBuilder.insertInto(HASHTAGGED_POSTS)
+ .value(HASHTAG, QueryBuilder.bindMarker())
+ .value(POST_ID, QueryBuilder.bindMarker())
+ .value(VRE_ID, QueryBuilder.bindMarker())
+ .build());
+ }
+ private static PreparedStatement createNewHashtagCommentEntry(CqlSession session){
+ return session.prepare(
+ QueryBuilder.insertInto(HASHTAGGED_COMMENTS)
+ .value(HASHTAG, QueryBuilder.bindMarker())
+ .value(COMMENT_ID, QueryBuilder.bindMarker())
+ .value(VRE_ID, QueryBuilder.bindMarker())
+ .build());
+ }
+ private static PreparedStatement createNewEmailInviteEntry(CqlSession session){
+ return session.prepare(
+ QueryBuilder.insertInto(EMAIL_INVITES)
+ .value(EMAIL, QueryBuilder.bindMarker())
+ .value(VRE_ID, QueryBuilder.bindMarker())
+ .value(INVITE_ID, QueryBuilder.bindMarker())
+ .build());
+ }
+ private static PreparedStatement createNewInviteEntry(CqlSession session){
+ return session.prepare(
+ QueryBuilder.insertInto(INVITES)
+ .value(INVITE_ID, QueryBuilder.bindMarker())
+ .value(SENDER_USER_ID, QueryBuilder.bindMarker())
+ .value(VRE_ID, QueryBuilder.bindMarker())
+ .value(EMAIL, QueryBuilder.bindMarker())
+ .value(CONTROL_CODE, QueryBuilder.bindMarker())
+ .value(STATUS, QueryBuilder.bindMarker())
+ .value(TIMESTAMP, QueryBuilder.bindMarker())
+ .value(SENDER_FULL_NAME, QueryBuilder.bindMarker())
+ .build());
+ }
+ private static PreparedStatement createNewVreInviteEntry(CqlSession session){
+ return session.prepare(
+ QueryBuilder.insertInto(VRE_INVITES)
+ .value(VRE_ID, QueryBuilder.bindMarker())
+ .value(INVITE_ID, QueryBuilder.bindMarker())
+ .value(STATUS, QueryBuilder.bindMarker())
+ .build());
+ }
+ private static PreparedStatement createNewaAttachEntry(CqlSession session){
+ return session.prepare(
+ QueryBuilder.insertInto(ATTACHMENTS)
+ .value(ATTACH_ID, QueryBuilder.bindMarker())
+ .value(POST_ID, QueryBuilder.bindMarker())
+ .value(URI, QueryBuilder.bindMarker())
+ .value(NAME, QueryBuilder.bindMarker())
+ .value(DESCRIPTION, QueryBuilder.bindMarker())
+ .value(URI_THUMBNAIL, QueryBuilder.bindMarker())
+ .value(MIME_TYPE, QueryBuilder.bindMarker())
+ .build());
+ }
+ private static PreparedStatement createNewUHashtagCounterEntry(CqlSession session){
+ return session.prepare(
+ QueryBuilder.insertInto(HASHTAGS_COUNTER)
+ .value(VRE_ID, QueryBuilder.bindMarker())
+ .value(HASHTAG, QueryBuilder.bindMarker())
+ .value(COUNT, QueryBuilder.bindMarker())
+ .build());
+ }
+
+
+ /*
+ *
+ ********************** FRIENDSHIPS (CONNECTIONS) ***********************
+ *
+ */
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean requestFriendship(String from, String to) {
+ return true;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean approveFriendship(String from, String to) {
+ return true;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean denyFriendship(String from, String to) {
+ return true;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List getFriends(String userid) {
+ ArrayList toReturn = new ArrayList();
+ return toReturn;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List getPendingFriendRequests(String userid) {
+ ArrayList toReturn = new ArrayList();
+ return toReturn;
+ }
+ /*
+ *
+ ********************** FEEDS ***********************
+ *
+ */
+
+ private static Post feed2post(Feed feed){
+ Post post = new Post();
+ if (feed.getKey()!=null)post.setKey(feed.getKey());
+ if (feed.getType()!=null)post.setType(PostType.valueOf(feed.getType().toString()));
+ if (feed.getEntityId()!=null)post.setEntityId(feed.getEntityId());
+ if (feed.getTime()!=null)post.setTime(feed.getTime());
+ if (feed.getVreid()!=null)post.setVreid(feed.getVreid());
+ if (feed.getUri()!=null)post.setUri(feed.getUri());
+ if (feed.getUriThumbnail()!=null)post.setUriThumbnail(feed.getUriThumbnail());
+ if (feed.getDescription()!=null)post.setDescription(feed.getDescription());
+ if (feed.getPrivacy()!=null)post.setPrivacy(feed.getPrivacy());
+ if (feed.getFullName()!=null)post.setFullName(feed.getFullName());
+ if (feed.getEmail()!=null)post.setEmail(feed.getEmail());
+ if (feed.getThumbnailURL()!=null)post.setThumbnailURL(feed.getThumbnailURL());
+ if (feed.getCommentsNo()!=null)post.setCommentsNo(feed.getCommentsNo());
+ if (feed.getLikesNo()!=null)post.setLikesNo(feed.getLikesNo());
+ if (feed.getLinkTitle()!=null)post.setLinkTitle(feed.getLinkTitle());
+ if (feed.getLinkDescription()!=null)post.setLinkDescription(feed.getLinkDescription());
+ if (feed.getLinkHost()!=null)post.setLinkHost(feed.getLinkHost());
+ post.setApplicationFeed(feed.isApplicationFeed());
+ post.setMultiFileUpload(feed.isMultiFileUpload());
+ return post;
+ }
+
+ private static Feed post2feed(Post post){
+ Feed feed = new Feed();
+
+ if (post.getKey()!=null)feed.setKey(post.getKey());
+ if (post.getType()!=null)feed.setType(FeedType.valueOf(post.getType().toString()));
+ if (post.getEntityId()!=null)feed.setEntityId(post.getEntityId());
+ if (post.getTime()!=null)feed.setTime(post.getTime());
+ if (post.getVreid()!=null)feed.setVreid(post.getVreid());
+ if (post.getUri()!=null)feed.setUri(post.getUri());
+ if (post.getUriThumbnail()!=null)feed.setUriThumbnail(post.getUriThumbnail());
+ if (post.getDescription()!=null)feed.setDescription(post.getDescription());
+ if (post.getPrivacy()!=null)feed.setPrivacy(post.getPrivacy());
+ if (post.getFullName()!=null)feed.setFullName(post.getFullName());
+ if (post.getEmail()!=null)feed.setEmail(post.getEmail());
+ if (post.getThumbnailURL()!=null)feed.setThumbnailURL(post.getThumbnailURL());
+ if (post.getCommentsNo()!=null)feed.setCommentsNo(post.getCommentsNo());
+ if (post.getLikesNo()!=null)feed.setLikesNo(post.getLikesNo());
+ if (post.getLinkTitle()!=null)feed.setLinkTitle(post.getLinkTitle());
+ if (post.getLinkDescription()!=null)feed.setLinkDescription(post.getLinkDescription());
+ if (post.getLinkHost()!=null)feed.setLinkHost(post.getLinkHost());
+ feed.setApplicationFeed(post.isApplicationFeed());
+ feed.setMultiFileUpload(post.isMultiFileUpload());
+
+ return feed;
+ }
+ private List insertIntoPosts(CqlSession session, Post post){
+ PreparedStatement prepStmt1 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(LINK_HOST, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt2 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(DESCRIPTION, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt3 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(EMAIL, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt4 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(LIKES_NO, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt5 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(THUMBNAIL_URL, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt6 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(LINK_DESCRIPTION, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt7 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(TIMESTAMP, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt8 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(URI, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt9 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(IS_APPLICATION_POST, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt10 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(ENTITY_ID, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt11 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(PRIVACY, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt12 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(TYPE, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt13 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(URI_THUMBNAIL, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt14 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(VRE_ID, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt15 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(MULTI_FILE_UPLOAD, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt16 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(FULL_NAME, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt17 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(COMMENTS_NO, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt18 = session.prepare(QueryBuilder.insertInto(POSTS).value(POST_ID, QueryBuilder.bindMarker()).value(LINK_TITLE, QueryBuilder.bindMarker()).build());
+
+/*
+ PreparedStatement prepStmt1 = session.prepare("INSERT INTO posts("+POST_ID+","+ LINK_HOST+") values(?, ?)");
+ PreparedStatement prepStmt2 = session.prepare("INSERT INTO posts("+POST_ID+","+ DESCRIPTION+") values(?, ?)");
+ PreparedStatement prepStmt3 = session.prepare("INSERT INTO posts("+POST_ID+","+ EMAIL+") values(?, ?)");
+ PreparedStatement prepStmt4 = session.prepare("INSERT INTO posts("+POST_ID+","+ LIKES_NO+") values(?, ?)");
+ PreparedStatement prepStmt5 = session.prepare("INSERT INTO posts("+POST_ID+","+ THUMBNAIL_URL+") values(?, ?)");
+ PreparedStatement prepStmt6 = session.prepare("INSERT INTO posts("+POST_ID+","+ LINK_DESCRIPTION+") values(?, ?)");
+ PreparedStatement prepStmt7 = session.prepare("INSERT INTO posts("+POST_ID+","+ TIMESTAMP+") values(?, ?)");
+ PreparedStatement prepStmt8 = session.prepare("INSERT INTO posts("+POST_ID+","+ URI+") values(?, ?)");
+ PreparedStatement prepStmt9 = session.prepare("INSERT INTO posts("+POST_ID+","+ IS_APPLICATION_POST+") values(?, ?)");
+ PreparedStatement prepStmt10 = session.prepare("INSERT INTO posts("+POST_ID+","+ ENTITY_ID+") values(?, ?)");
+ PreparedStatement prepStmt11 = session.prepare("INSERT INTO posts("+POST_ID+","+ PRIVACY+") values(?, ?)");
+ PreparedStatement prepStmt12 = session.prepare("INSERT INTO posts("+POST_ID+","+ TYPE+") values(?, ?)");
+ PreparedStatement prepStmt13 = session.prepare("INSERT INTO posts("+POST_ID+","+ URI_THUMBNAIL+") values(?, ?)");
+ PreparedStatement prepStmt14 = session.prepare("INSERT INTO posts("+POST_ID+","+ VRE_ID+") values(?, ?)");
+ PreparedStatement prepStmt15 = session.prepare("INSERT INTO posts("+POST_ID+","+ MULTI_FILE_UPLOAD+") values(?, ?)");
+ PreparedStatement prepStmt16 = session.prepare("INSERT INTO posts("+POST_ID+","+ FULL_NAME+") values(?, ?)");
+ PreparedStatement prepStmt17 = session.prepare("INSERT INTO posts("+POST_ID+","+ COMMENTS_NO+") values(?, ?)");
+ PreparedStatement prepStmt18 = session.prepare("INSERT INTO posts("+POST_ID+","+ LINK_TITLE+") values(?, ?)");
+*/
+ List boundStatements = new ArrayList<>();
+
+ if(post.getLinkHost()!=null){
+ boundStatements.add(prepStmt1.bind(UUID.fromString(post.getKey()), post.getLinkHost()));
+ }
+
+ if(post.getDescription()!=null){
+ boundStatements.add(prepStmt2.bind(UUID.fromString(post.getKey()), post.getDescription()));
+ }
+
+ if(post.getEmail()!=null){
+ boundStatements.add(prepStmt3.bind(UUID.fromString(post.getKey()), post.getEmail()));
+ }
+ if(post.getLikesNo()!=null){
+ boundStatements.add(prepStmt4.bind(UUID.fromString(post.getKey()), Long.parseLong(post.getLikesNo())));
+ }if(post.getThumbnailURL()!=null){
+ boundStatements.add(prepStmt5.bind(UUID.fromString(post.getKey()), post.getThumbnailURL()));
+ }if(post.getLinkDescription()!=null){
+ boundStatements.add(prepStmt6.bind(UUID.fromString(post.getKey()), post.getLinkDescription()));
+ }if(post.getTime()!=null){
+ boundStatements.add(prepStmt7.bind(UUID.fromString(post.getKey()), post.getTime().toInstant()));
+ }if(post.getUri()!=null){
+ boundStatements.add(prepStmt8.bind(UUID.fromString(post.getKey()), post.getUri()));
+ }
+ boundStatements.add(prepStmt9.bind(UUID.fromString(post.getKey()), post.isApplicationFeed()));
+ if(post.getEntityId()!=null){
+ boundStatements.add(prepStmt10.bind(UUID.fromString(post.getKey()), post.getEntityId()));
+ }if(post.getPrivacy()!=null){
+ boundStatements.add(prepStmt11.bind(UUID.fromString(post.getKey()), post.getPrivacy().toString()));
+ }if(post.getType()!=null){
+ boundStatements.add(prepStmt12.bind(UUID.fromString(post.getKey()), post.getType().toString()));
+ }if(post.getUriThumbnail()!=null){
+ boundStatements.add(prepStmt13.bind(UUID.fromString(post.getKey()), post.getUriThumbnail()));
+ }if(post.getVreid()!=null){
+ boundStatements.add(prepStmt14.bind(UUID.fromString(post.getKey()), post.getVreid()));
+ }
+ boundStatements.add(prepStmt15.bind(UUID.fromString(post.getKey()), post.isMultiFileUpload()));
+ if(post.getFullName()!=null){
+ boundStatements.add(prepStmt16.bind(UUID.fromString(post.getKey()), post.getFullName()));
+ }if(post.getCommentsNo()!=null){
+ boundStatements.add(prepStmt17.bind(UUID.fromString(post.getKey()), Long.parseLong(post.getCommentsNo())));
+ }if(post.getLinkTitle()!=null){
+ boundStatements.add(prepStmt18.bind(UUID.fromString(post.getKey()), post.getLinkTitle()));
+ }
+ return boundStatements;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Deprecated
+ @Override
+ public boolean saveUserFeed(Feed post) {
+ CqlSession session = conn.getKeyspaceSession();
+ List boundStatements = insertIntoPosts(session, feed2post(post));
+
+
+ //boundStatements.forEach(stmt -> writeBatch.add(stmt));
+
+ //an entry in posts
+ /*PreparedStatement stmt1 = createPostEntry(session);
+ writeBatch.add(stmt1.bind(UUID.fromString(post.getKey()),
+ post.getLinkHost(),
+ post.getDescription(),
+ post.getEmail(),
+ post.getLikesNo()!=null?Long.parseLong(post.getLikesNo()):null,
+ post.getThumbnailURL(),
+ post.getLinkDescription(),
+ post.getTime()!=null?post.getTime().toInstant():null,
+ post.getUri(),
+ post.isApplicationFeed(),
+ post.getEntityId(),
+ post.getPrivacy()!=null?post.getPrivacy().toString():null,
+ post.getType()!=null?post.getType().toString():null,
+ post.getUriThumbnail(),
+ post.getVreid(),
+ post.isMultiFileUpload(),
+ post.getFullName(),
+ post.getCommentsNo()!=null?Long.parseLong(post.getCommentsNo()):null,
+ post.getLinkTitle()));
+ */
+
+ //an entry in the user Timeline
+ BoundStatement stmt2 = createUserTimelineEntry(session).bind(post.getEntityId(), post.getTime().toInstant(), UUID.fromString(post.getKey()));
+ boundStatements.add(stmt2);
+ //an entry in the VRES Timeline iff vreid field is not empty
+ if (post.getVreid() != null && post.getVreid().compareTo("") != 0){
+ BoundStatement stmt3 = createVreTimelineEntry(session).bind(post.getVreid(), post.getTime().toInstant(), UUID.fromString(post.getKey()));
+ boundStatements.add(stmt3);
+ }
+ BatchStatement writeBatch = getBatch().addAll(boundStatements);
+
+ Boolean result = session.execute(writeBatch).wasApplied();
+ if (result){
+ _log.debug("Wrote user post with id " + post.getKey());
+ }
+
+
+ return result;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean saveUserPost(Post post) {
+ CqlSession session = conn.getKeyspaceSession();
+ List boundStatements = insertIntoPosts(session, post);
+ //boundStatements.forEach(stmt -> writeBatch.add(stmt));
+ //an entry in posts
+ /*PreparedStatement stmt1 = createPostEntry(session);
+ writeBatch.add(stmt1.bind(UUID.fromString(post.getKey()),
+ post.getLinkHost(),
+ post.getDescription(),
+ post.getEmail(),
+ post.getLikesNo()!=null?Long.parseLong(post.getLikesNo()):null,
+ post.getThumbnailURL(),
+ post.getLinkDescription(),
+ post.getTime()!=null?post.getTime().toInstant():null,
+ post.getUri(),
+ post.isApplicationFeed(),
+ post.getEntityId(),
+ post.getPrivacy()!=null?post.getPrivacy().toString():null,
+ post.getType()!=null?post.getType().toString():null,
+ post.getUriThumbnail(),
+ post.getVreid(),
+ post.isMultiFileUpload(),
+ post.getFullName(),
+ post.getCommentsNo()!=null?Long.parseLong(post.getCommentsNo()):null,
+ post.getLinkTitle()));*/
+
+ //an entry in the user Timeline
+ BoundStatement stmt2 = createUserTimelineEntry(session).bind(post.getEntityId(), post.getTime().toInstant(), UUID.fromString(post.getKey()));
+ boundStatements.add(stmt2);
+ //an entry in the VRES Timeline iff vreid field is not empty
+ if (post.getVreid() != null && post.getVreid().compareTo("") != 0){
+ BoundStatement stmt3 = createVreTimelineEntry(session).bind(post.getVreid(), post.getTime().toInstant(), UUID.fromString(post.getKey()));
+ boundStatements.add(stmt3);
+ }
+ BatchStatement writeBatch = getBatch().addAll(boundStatements);
+
+ Boolean result = session.execute(writeBatch).wasApplied();
+ if (result){
+ _log.debug("Wrote user post with id " + post.getKey());
+ }
+
+
+ return result;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Deprecated
+ @Override
+ public boolean saveUserFeed(Feed feed, List attachments) {
+ if (attachments != null && !attachments.isEmpty())
+ feed.setMultiFileUpload(true);
+ boolean saveFeedResult = saveUserFeed(feed);
+ if (saveFeedResult) {
+ String feedKey = feed.getKey();
+ for (Attachment attachment : attachments) {
+ boolean attachSaveResult = saveAttachmentEntry(feedKey, attachment);
+ if (!attachSaveResult)
+ _log.warn("Some of the attachments failed to me saved: " + attachment.getName());
+ }
+ return true;
+ }
+ else return false;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean saveUserPost(Post post, List attachments) {
+ if (attachments != null && !attachments.isEmpty())
+ post.setMultiFileUpload(true);
+ boolean savePostResult = saveUserPost(post);
+ if (savePostResult) {
+ _log.debug("Post has been saved");
+ String postkey = post.getKey();
+ for (Attachment attachment : attachments) {
+ boolean attachSaveResult = saveAttachmentEntry(postkey, attachment);
+ if (!attachSaveResult)
+ _log.info("Some of the attachments failed to be saved: " + attachment.getName());
+ }
+ return true;
+ }
+ else return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ @Deprecated
+ public boolean saveAppFeed(Feed post) {
+ CqlSession session = conn.getKeyspaceSession();
+
+ List boundStatements = insertIntoPosts(session, feed2post(post));
+ //boundStatements.forEach(stmt -> writeBatch.add(stmt));
+ //an entry to posts
+ /*PreparedStatement stmt1 = createPostEntry(session);
+ writeBatch.add(stmt1.bind(UUID.fromString(post.getKey()),
+ post.getLinkHost(),
+ post.getDescription(),
+ post.getEmail(),
+ post.getLikesNo()!=null?Long.parseLong(post.getLikesNo()):null,
+ post.getThumbnailURL(),
+ post.getLinkDescription(),
+ post.getTime()!=null?post.getTime().toInstant():null,
+ post.getUri(),
+ post.isApplicationFeed(),
+ post.getEntityId(),
+ post.getPrivacy()!=null?post.getPrivacy().toString():null,
+ post.getType()!=null?post.getType().toString():null,
+ post.getUriThumbnail(),
+ post.getVreid(),
+ post.isMultiFileUpload(),
+ post.getFullName(),
+ post.getCommentsNo()!=null?Long.parseLong(post.getCommentsNo()):null,
+ post.getLinkTitle()));*/
+
+
+ //an entry in the Applications Timeline
+ BoundStatement stmt2 = createAppTimelineEntry(session).bind(post.getEntityId(), post.getTime().toInstant(), UUID.fromString(post.getKey()));
+ boundStatements.add(stmt2);
+ //an entry in the VRES Timeline iff vreid field is not empty
+ if (post.getVreid() != null && post.getVreid().compareTo("") != 0){
+ BoundStatement stmt3 = createVreTimelineEntry(session).bind(post.getVreid(), post.getTime().toInstant(), UUID.fromString(post.getKey()));
+ boundStatements.add(stmt3);
+ }
+ BatchStatement writeBatch = getBatch().addAll(boundStatements);
+
+ boolean result = session.execute(writeBatch).wasApplied();
+ if (result)
+ _log.debug("Wrote app post with id " + post.getKey());
+
+ return result;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean saveAppPost(Post post) {
+ CqlSession session = conn.getKeyspaceSession();
+
+ List boundStatements = insertIntoPosts(session, post);
+ //boundStatements.forEach(stmt -> writeBatch.add(stmt));
+ //an entry to posts
+ /*PreparedStatement stmt1 = createPostEntry(session);
+ writeBatch.add(stmt1.bind(UUID.fromString(post.getKey()),
+ post.getLinkHost(),
+ post.getDescription(),
+ post.getEmail(),
+ post.getLikesNo()!=null?Long.parseLong(post.getLikesNo()):null,
+ post.getThumbnailURL(),
+ post.getLinkDescription(),
+ post.getTime()!=null?post.getTime().toInstant():null,
+ post.getUri(),
+ post.isApplicationFeed(),
+ post.getEntityId(),
+ post.getPrivacy()!=null?post.getPrivacy().toString():null,
+ post.getType()!=null?post.getType().toString():null,
+ post.getUriThumbnail(),
+ post.getVreid(),
+ post.isMultiFileUpload(),
+ post.getFullName(),
+ post.getCommentsNo()!=null?Long.parseLong(post.getCommentsNo()):null,
+ post.getLinkTitle()));*/
+
+
+ //an entry in the Applications Timeline
+ BoundStatement stmt2 = createAppTimelineEntry(session).bind(post.getEntityId(), post.getTime().toInstant(), UUID.fromString(post.getKey()));
+ boundStatements.add(stmt2);
+ //an entry in the VRES Timeline iff vreid field is not empty
+ if (post.getVreid() != null && post.getVreid().compareTo("") != 0){
+ BoundStatement stmt3 = createVreTimelineEntry(session).bind(post.getVreid(), post.getTime().toInstant(), UUID.fromString(post.getKey()));
+ boundStatements.add(stmt3);
+ }
+ BatchStatement writeBatch = getBatch().addAll(boundStatements);
+
+ boolean result = session.execute(writeBatch).wasApplied();
+ if (result)
+ _log.debug("Wrote app post with id " + post.getKey());
+
+ return result;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Deprecated
+ @Override
+ public boolean saveAppFeed(Feed feed, List attachments) {
+ if (attachments != null && !attachments.isEmpty())
+ feed.setMultiFileUpload(true);
+ boolean saveFeedResult = saveAppFeed(feed);
+ if (saveFeedResult) {
+ String feedKey = feed.getKey();
+ for (Attachment attachment : attachments) {
+ boolean attachSaveResult = saveAttachmentEntry(feedKey, attachment);
+ if (!attachSaveResult)
+ _log.warn("Some of the attachments failed to me saved: " + attachment.getName());
+ }
+ return true;
+ }
+ else return false;
+ }
+ /**
+ * {@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 {
+ Feed toCheck;
+ try {
+ toCheck = readFeed(feedKey);
+ if (toCheck == null)
+ throw new FeedIDNotFoundException("Could not find Post with id " + feedKey, feedKey);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ CqlSession session = conn.getKeyspaceSession();
+ BatchStatement writeBatch = getBatch().add(
+ createVreTimelineEntry(session).bind(vreid, toCheck.getTime().toInstant(), UUID.fromString(toCheck.getKey())));
+
+ try{
+ boolean res = session.execute(writeBatch).wasApplied();
+
+ return res;
+ }catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean savePostToVRETimeline(String postKey, String vreid) throws FeedIDNotFoundException {
+ Post toCheck;
+ try {
+ toCheck = readPost(postKey);
+ if (toCheck == null)
+ throw new FeedIDNotFoundException("Could not find Post with id " + postKey, postKey);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ CqlSession session = conn.getKeyspaceSession();
+ BatchStatement writeBatch = getBatch().add(createVreTimelineEntry(session).bind(vreid, toCheck.getTime().toInstant(), UUID.fromString(toCheck.getKey())));
+
+ try{
+ boolean res = session.execute(writeBatch).wasApplied();
+
+ return res;
+ }catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Deprecated
+ @Override
+ public Feed readFeed(String feedid)
+ throws PrivacyLevelTypeNotFoundException,
+ FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException {
+ CqlSession session = conn.getKeyspaceSession();
+ Feed post;
+ try{
+ post = findFeedById(feedid, session).get();
+
+ } catch (Exception e){
+ e.printStackTrace();
+
+ return null;
+ }
+ return post;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Post readPost(String postid)
+ throws PrivacyLevelTypeNotFoundException,
+ FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException {
+ CqlSession session = conn.getKeyspaceSession();
+ Post post;
+ try{
+ post = findPostById(postid, session).get();
+
+ } catch (Exception e){
+ e.printStackTrace();
+
+ return null;
+ }
+ return post;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ @Deprecated
+ public List getRecentFeedsByUserAndDate(String userid, long timeInMillis) throws IllegalArgumentException {
+ Date now = new Date();
+ if (timeInMillis > now.getTime())
+ throw new IllegalArgumentException("the timeInMillis must be before today");
+
+ ResultSet result = null;
+ try {
+ CqlSession session = conn.getKeyspaceSession();
+ PreparedStatement stmtFind = session.prepare(QueryBuilder
+ .selectFrom(USER_TIMELINE_POSTS).all()
+ .whereColumn(USER_ID)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ result = session.execute(stmtFind.bind(userid));
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ ListtoReturn = new ArrayList<>();
+ Listrows=result.all();
+ for (Row row: rows){
+ Instant postTime = row.getInstant(TIMESTAMP);
+ if (Date.from(postTime).getTime() > timeInMillis){
+ try{
+ Feed toCheck = readFeed(row.getUuid(POST_ID).toString());
+ if (toCheck.getType() != FeedType.DISABLED)
+ toReturn.add(toCheck);
+ } catch (ColumnNameNotFoundException | PrivacyLevelTypeNotFoundException | FeedTypeNotFoundException |
+ FeedIDNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ return toReturn;
+ }
+ /**
+ * {@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");
+
+ ResultSet result = null;
+ try {
+ CqlSession session = conn.getKeyspaceSession();
+ PreparedStatement stmtFind = session.prepare(QueryBuilder
+ .selectFrom(USER_TIMELINE_POSTS).all()
+ .whereColumn(USER_ID)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ result = session.execute(stmtFind.bind(userid));
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ Listrows = result.all();
+ List toReturn = new ArrayList<>();
+ for (Row row: rows){
+ Instant postTime = row.getInstant(TIMESTAMP);
+ if (Date.from(postTime).getTime() > timeInMillis){
+ try{
+ Post toCheck = readPost(row.getUuid(POST_ID).toString());
+ if (toCheck.getType() != PostType.DISABLED)
+ toReturn.add(toCheck);
+ } catch (ColumnNameNotFoundException | PrivacyLevelTypeNotFoundException | FeedIDNotFoundException |
+ FeedTypeNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ return toReturn;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Deprecated
+ @Override
+ public boolean deleteFeed(String feedId) throws FeedIDNotFoundException, PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException {
+ Feed toDelete = readFeed(feedId);
+ CqlSession session = conn.getKeyspaceSession();
+ BatchStatement writeBatch = getBatch().add(updatePostEntry(session, TYPE).bind(FeedType.DISABLED.toString(), UUID.fromString(toDelete.getKey())));
+
+ try {
+ session.execute(writeBatch);
+
+ } catch (Exception e) {
+ _log.error("Delete Post ERROR for postid " + feedId);
+
+ return false;
+ }
+ _log.debug("Delete Post OK");
+ return true;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean deletePost(String postid) throws FeedIDNotFoundException, PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException {
+ Post toDelete = readPost(postid);
+ CqlSession session = conn.getKeyspaceSession();
+ BatchStatement writeBatch = getBatch().add(updatePostEntry(session, TYPE).bind(PostType.DISABLED.toString(), UUID.fromString(toDelete.getKey())));
+
+ try {
+ session.execute(writeBatch);
+
+ } catch (Exception e) {
+ _log.error("Delete Post ERROR for postid " + postid);
+
+ return false;
+ }
+ _log.debug("Delete Post OK");
+ return true;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Deprecated
+ @Override
+ public List getAllFeedsByUser(String userid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException {
+ return getFeedsByIds(getUserFeedIds(userid));
+ }
+ /**
+ * {@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 {
+
+ 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(readFeed(postId));
+ }
+ }catch(Exception e){
+ _log.error("Unable to retrieve feed with id " + postId, e);
+ }
+ }
+
+ Collections.sort(toReturn, Collections.reverseOrder());
+ 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
+ * @throws ColumnNameNotFoundException
+ * @throws FeedIDNotFoundException
+ * @throws FeedTypeNotFoundException
+ * @throws PrivacyLevelTypeNotFoundException
+ */
+ private List getFeedsByIds(List feedIds) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException {
+ ArrayList toReturn = new ArrayList();
+ for (String feedid : feedIds) {
+ Feed toAdd = readFeed(feedid);
+ if (toAdd.getType() == FeedType.TWEET || toAdd.getType() == FeedType.SHARE || toAdd.getType() == FeedType.PUBLISH)
+ toReturn.add(toAdd);
+ }
+ 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) {
+ ResultSet result = null;
+ CqlSession session = conn.getKeyspaceSession();
+ PreparedStatement stmtFind = session.prepare(QueryBuilder
+ .selectFrom(USER_TIMELINE_POSTS).all()
+ .whereColumn(USER_ID)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ try {
+ result = session.execute(stmtFind.bind(userid));
+
+ } catch (Exception e){
+ e.printStackTrace();
+
+ }
+ Listrows = result.all();
+ ListtoReturn = new ArrayList<>();
+ for (Row row: rows){
+ try {
+ String postid = row.getUuid(POST_ID).toString();
+ toReturn.add(postid);
+ } catch (RuntimeException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return (ArrayList) 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) {
+ ResultSet result = null;
+ CqlSession session = conn.getKeyspaceSession();
+ PreparedStatement stmtFind = session.prepare(QueryBuilder
+ .selectFrom(USER_TIMELINE_POSTS).all()
+ .whereColumn(USER_ID)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ try {
+ result = session.execute(stmtFind.bind(userid));
+
+ } catch (Exception e){
+ e.printStackTrace();
+
+ }
+ ArrayList toReturn = new ArrayList<>();
+ Listrows = result.all();
+ for(Row row: rows){
+ try {
+ String postid = row.getUuid(POST_ID).toString();
+ toReturn.add(postid);
+ } catch (RuntimeException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return toReturn;
+ }
+
+ /**
+ * helper method that return whether the user
+ * @param userid user identifier
+ * @param postid the feed identifier
+ * @return true if the feed id liked already
+ */
+ private boolean isPostLiked(String userid, String postid) {
+
+ ResultSet result = null;
+ CqlSession session = conn.getKeyspaceSession();
+ PreparedStatement stmtFind = session.prepare(QueryBuilder
+ .selectFrom(USER_LIKED_POSTS).all()
+ .whereColumn(USER_ID)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+
+ try {
+ result = session.execute(stmtFind.bind(userid));
+
+ } catch (Exception e){
+ e.printStackTrace();
+
+ }
+ Listrows = result.all();
+ for (Row row: rows){
+ if (row.getUuid(POST_ID).toString().equals(postid)){
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+
+ /**
+ * helper method that retrieve all the feed Ids belonging to an application
+ * @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) {
+ ResultSet result = null;
+ CqlSession session = conn.getKeyspaceSession();
+ PreparedStatement stmtFind = session.prepare(QueryBuilder
+ .selectFrom(APP_TIMELINE_POSTS).all()
+ .whereColumn(APP_ID)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ try {
+ result = session.execute(stmtFind.bind(appid));
+
+ } catch (Exception e){
+ e.printStackTrace();
+
+ }
+ Listrows=result.all();
+ ArrayList toReturn=new ArrayList<>();
+ for(Row row: rows){
+ try {
+ String postid = row.getUuid(POST_ID).toString();
+ toReturn.add(postid);
+ } catch (RuntimeException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+
+ 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) {
+ ResultSet result = null;
+ CqlSession session = conn.getKeyspaceSession();
+ PreparedStatement stmtFind = session.prepare(QueryBuilder
+ .selectFrom(APP_TIMELINE_POSTS).all()
+ .whereColumn(APP_ID)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ try {
+ result = session.execute(stmtFind.bind(appid));
+
+ } catch (Exception e){
+ e.printStackTrace();
+
+ }
+
+ Listrows=result.all();
+ ArrayList toReturn=new ArrayList<>();
+ for(Row row: rows){
+ try {
+ String postid = row.getUuid(POST_ID).toString();
+ toReturn.add(postid);
+ } catch (RuntimeException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+
+ return toReturn;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Deprecated
+ @Override
+ public List getAllPortalPrivacyLevelFeeds() throws FeedTypeNotFoundException, ColumnNameNotFoundException, PrivacyLevelTypeNotFoundException {
+ //possible error index
+ ArrayList toReturn = new ArrayList();
+ ResultSet result = null;
+ CqlSession session = conn.getKeyspaceSession();
+ PreparedStatement stmtFind = session.prepare(QueryBuilder
+ .selectFrom(POSTS).all()
+ .whereColumn(PRIVACY).isEqualTo(QueryBuilder.bindMarker())
+ .limit(20)
+ .build());
+ try {
+ result = session.execute(stmtFind.bind(PrivacyLevel.PORTAL.toString()));
+
+ } catch (Exception e){
+ e.printStackTrace();
+
+ }
+ Listrows=result.all();
+ for (Row row: rows) {
+ Feed toAdd = readFeedFromRow(row);
+ if (toAdd.getType() == FeedType.TWEET || toAdd.getType() == FeedType.SHARE || toAdd.getType() == FeedType.PUBLISH)
+ toReturn.add(toAdd);
+ }
+ return toReturn;
+ }
+ @Override
+ public List getAllPortalPrivacyLevelPosts() throws FeedTypeNotFoundException, ColumnNameNotFoundException, PrivacyLevelTypeNotFoundException {
+ //possible error index
+ ArrayList toReturn = new ArrayList();
+ ResultSet result = null;
+ CqlSession session = conn.getKeyspaceSession();
+ PreparedStatement stmtFind = session.prepare(QueryBuilder
+ .selectFrom(POSTS).all()
+ .whereColumn(PRIVACY).isEqualTo(QueryBuilder.bindMarker())
+ .limit(20)
+ .build());
+ try {
+ result = session.execute(stmtFind.bind(PrivacyLevel.PORTAL.toString()));
+
+ } catch (Exception e){
+ e.printStackTrace();
+
+ }
+ Listrows=result.all();
+ for (Row row: rows) {
+ Post toAdd = readPostFromRow(row);
+ if (toAdd.getType() == PostType.TWEET || toAdd.getType() == PostType.SHARE || toAdd.getType() == PostType.PUBLISH)
+ toReturn.add(toAdd);
+ }
+ 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);
+ //check if quantity is greater than user feeds
+ quantity = (quantity > feedIDs.size()) ? feedIDs.size() : quantity;
+
+ //need them in reverse order
+ for (int i = feedIDs.size()-1; i >= (feedIDs.size()-quantity); i--) {
+ Feed toAdd = readFeed(feedIDs.get(i));
+ if (toAdd.getType() == FeedType.TWEET || toAdd.getType() == FeedType.SHARE || toAdd.getType() == FeedType.PUBLISH) {
+ toReturn.add(toAdd);
+ _log.trace("Read recent feed: " + feedIDs.get(i));
+ } else {
+ _log.trace("Read and skipped feed: " + feedIDs.get(i) + " (Removed Feed)");
+ quantity += 1; //increase the quantity in case of removed feed
+ //check if quantity is greater than user feeds
+ quantity = (quantity > feedIDs.size()) ? feedIDs.size() : quantity;
+ }
+ }
+ 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
+ @Deprecated
+ public List getAllFeedsByVRE(String vreid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, FeedIDNotFoundException {
+ return getFeedsByIds(getVREFeedIds(vreid));
+ }
+ /**
+ * {@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);
+ //check if quantity is greater than user feeds
+ quantity = (quantity > feedIDs.size()) ? feedIDs.size() : quantity;
+
+ //need them in reverse order
+ for (int i = feedIDs.size()-1; i >= (feedIDs.size()-quantity); i--) {
+ Feed toAdd = readFeed(feedIDs.get(i));
+ if (toAdd.getType() == FeedType.TWEET || toAdd.getType() == FeedType.SHARE || toAdd.getType() == FeedType.PUBLISH) {
+ toReturn.add(toAdd);
+ _log.trace("Read recent feed: " + feedIDs.get(i));
+ } else {
+ _log.trace("Read and skipped feed: " + feedIDs.get(i) + " (Removed Feed) .");
+ quantity += 1; //increase the quantity in case of removed feed
+ //check if quantity is greater than user feeds
+ quantity = (quantity > feedIDs.size()) ? feedIDs.size() : quantity;
+ }
+ }
+ 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}
+ */
+ @Override
+ public RangeFeeds getRecentFeedsByVREAndRange(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 = getVREFeedIds(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 RangeFeeds();
+ }
+
+ 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--) {
+ Feed toAdd = readFeed(feedIDs.get(i));
+ if (toAdd.getType() == FeedType.TWEET || toAdd.getType() == FeedType.SHARE || toAdd.getType() == FeedType.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 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
+ */
+ private ArrayList getVREFeedIds(String vreid) {
+ ResultSet result = null;
+ CqlSession session = conn.getKeyspaceSession();
+ PreparedStatement stmtFind = session.prepare(QueryBuilder
+ .selectFrom(VRE_TIMELINE_POSTS).all()
+ .whereColumn(VRE_ID)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ try {
+ result = session.execute(stmtFind.bind(vreid));
+
+ } catch (Exception e){
+ e.printStackTrace();
+
+ }
+
+ Listrows=result.all();
+ ArrayList toReturn=new ArrayList<>();
+ for(Row row: rows){
+ try {
+ String postid = row.getUuid(POST_ID).toString();
+ toReturn.add(postid);
+ } catch (RuntimeException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ 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) {
+ ResultSet result = null;
+ CqlSession session = conn.getKeyspaceSession();
+ PreparedStatement stmtFind = session.prepare(QueryBuilder
+ .selectFrom(VRE_TIMELINE_POSTS).all()
+ .whereColumn(VRE_ID)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ try {
+ result = session.execute(stmtFind.bind(vreid));
+
+ } catch (Exception e){
+ e.printStackTrace();
+
+ }
+
+ Listrows=result.all();
+ ArrayList toReturn=new ArrayList<>();
+ for(Row row: rows){
+ try {
+ String postid = row.getUuid(POST_ID).toString();
+ toReturn.add(postid);
+ } catch (RuntimeException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+
+ return toReturn;
+ }
+ /*
+ *
+ ********************** NOTIFICATIONS ***********************
+ *
+ */
+ private List insertIntoNotifications(CqlSession session, Notification notification){
+ PreparedStatement prepStmt1 = session.prepare(QueryBuilder.insertInto(NOTIFICATIONS).value(NOT_ID, QueryBuilder.bindMarker()).value(TYPE, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt2 = session.prepare(QueryBuilder.insertInto(NOTIFICATIONS).value(NOT_ID, QueryBuilder.bindMarker()).value(USER_ID, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt3 = session.prepare(QueryBuilder.insertInto(NOTIFICATIONS).value(NOT_ID, QueryBuilder.bindMarker()).value(SUBJECT_ID, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt4 = session.prepare(QueryBuilder.insertInto(NOTIFICATIONS).value(NOT_ID, QueryBuilder.bindMarker()).value(TIMESTAMP, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt5 = session.prepare(QueryBuilder.insertInto(NOTIFICATIONS).value(NOT_ID, QueryBuilder.bindMarker()).value(DESCRIPTION, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt6 = session.prepare(QueryBuilder.insertInto(NOTIFICATIONS).value(NOT_ID, QueryBuilder.bindMarker()).value(URI, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt7 = session.prepare(QueryBuilder.insertInto(NOTIFICATIONS).value(NOT_ID, QueryBuilder.bindMarker()).value(SENDER_ID, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt8 = session.prepare(QueryBuilder.insertInto(NOTIFICATIONS).value(NOT_ID, QueryBuilder.bindMarker()).value(SENDER_FULL_NAME, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt9 = session.prepare(QueryBuilder.insertInto(NOTIFICATIONS).value(NOT_ID, QueryBuilder.bindMarker()).value(SENDER_THUMBNAIL_URL, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt10 = session.prepare(QueryBuilder.insertInto(NOTIFICATIONS).value(NOT_ID, QueryBuilder.bindMarker()).value(IS_READ, QueryBuilder.bindMarker()).build());
+
+ /*
+ PreparedStatement prepStmt1 = session.prepare("INSERT INTO notifications("+NOT_ID+","+ TYPE+") values(?, ?)");
+ PreparedStatement prepStmt2 = session.prepare("INSERT INTO notifications("+NOT_ID+","+ USER_ID+") values(?, ?)");
+ PreparedStatement prepStmt3 = session.prepare("INSERT INTO notifications("+NOT_ID+","+ SUBJECT_ID+") values(?, ?)");
+ PreparedStatement prepStmt4 = session.prepare("INSERT INTO notifications("+NOT_ID+","+ TIMESTAMP+") values(?, ?)");
+ PreparedStatement prepStmt5 = session.prepare("INSERT INTO notifications("+NOT_ID+","+ DESCRIPTION+") values(?, ?)");
+ PreparedStatement prepStmt6 = session.prepare("INSERT INTO notifications("+NOT_ID+","+ URI+") values(?, ?)");
+ PreparedStatement prepStmt7 = session.prepare("INSERT INTO notifications("+NOT_ID+","+ SENDER_ID+") values(?, ?)");
+ PreparedStatement prepStmt8 = session.prepare("INSERT INTO notifications("+NOT_ID+","+ SENDER_FULL_NAME+") values(?, ?)");
+ PreparedStatement prepStmt9 = session.prepare("INSERT INTO notifications("+NOT_ID+","+ SENDER_THUMBNAIL_URL+") values(?, ?)");
+ PreparedStatement prepStmt10 = session.prepare("INSERT INTO notifications("+NOT_ID+","+ IS_READ+") values(?, ?)");
+*/
+ List boundStatements = new ArrayList<>();
+
+ if(notification.getType()!=null){
+ boundStatements.add(prepStmt1.bind(UUID.fromString(notification.getKey()),notification.getType().toString()));
+ }
+
+ if(notification.getUserid()!=null){
+ boundStatements.add(prepStmt2.bind(UUID.fromString(notification.getKey()), notification.getUserid()));
+ }
+
+ if(notification.getSubjectid()!=null){
+ boundStatements.add(prepStmt3.bind(UUID.fromString(notification.getKey()), notification.getSubjectid()));
+ }
+ if(notification.getTime()!=null){
+ boundStatements.add(prepStmt4.bind(UUID.fromString(notification.getKey()),notification.getTime().toInstant()));
+ }
+ if(notification.getDescription()!=null){
+ boundStatements.add(prepStmt5.bind(UUID.fromString(notification.getKey()),notification.getDescription()));
+ }if(notification.getUri()!=null){
+ boundStatements.add(prepStmt6.bind(UUID.fromString(notification.getKey()),notification.getUri()));
+ }if(notification.getSenderid()!=null){
+ boundStatements.add(prepStmt7.bind(UUID.fromString(notification.getKey()),notification.getSenderid()));
+ }if(notification.getSenderFullName()!=null){
+ boundStatements.add(prepStmt8.bind(UUID.fromString(notification.getKey()),notification.getSenderFullName()));
+ }if(notification.getSenderThumbnail()!=null){
+ boundStatements.add(prepStmt9.bind(UUID.fromString(notification.getKey()),notification.getSenderThumbnail()));
+ }
+
+ boundStatements.add(prepStmt10.bind(UUID.fromString(notification.getKey()),notification.isRead()));
+
+ return boundStatements;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean saveNotification(Notification n) {
+ CqlSession session = conn.getKeyspaceSession();
+
+ List boundStatements = insertIntoNotifications(session, n);
+ //boundStatements.forEach(stmt -> writeBatch.add(stmt));
+
+ /*
+ //notification entry
+ PreparedStatement stmt1 = createNotificationEntry(session);
+ writeBatch.add(stmt1.bind(UUID.fromString(n.getKey()),
+ n.getType().toString(),
+ n.getUserid(),
+ n.getSubjectid(),
+ n.getTime().toInstant(),
+ n.getDescription(),
+ n.getUri(),
+ n.getSenderid(),
+ n.getSenderFullName(),
+ n.getSenderThumbnail(),
+ n.isRead()));
+*/
+
+ //an entry in the user Notifications Timeline
+ BoundStatement stmt2 = createUserNotificationsEntry(session).bind(n.getUserid(), n.getTime().toInstant(), UUID.fromString(n.getKey()));
+ boundStatements.add(stmt2);
+
+ // save key in the unread notifications column family too
+ BoundStatement stmt3 = createUnreadNotificationEntry(session).bind(n.getUserid(), n.getTime().toInstant(), UUID.fromString(n.getKey()));
+ boundStatements.add(stmt3);
+ BatchStatement writeBatch = getBatch().addAll(boundStatements);
+ try{
+ boolean res = session.execute(writeBatch).wasApplied();
+
+ return res;
+ }catch (Exception e){
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Notification readNotification(String notificationid) throws NotificationIDNotFoundException, NotificationTypeNotFoundException, ColumnNameNotFoundException {
+ Notification toReturn = new Notification();
+ CqlSession session = conn.getKeyspaceSession();
+ try {
+ toReturn = findNotById(notificationid, session).get();
+
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+
+ }
+ return toReturn;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean setNotificationRead(String notificationidToSet) throws NotificationIDNotFoundException, NotificationTypeNotFoundException, ColumnNameNotFoundException {
+ Notification toSet = readNotification(notificationidToSet);
+ if (toSet == null)
+ throw new NotificationIDNotFoundException("The specified notification to set Read with id: " + notificationidToSet + " does not exist");
+
+ CqlSession session = conn.getKeyspaceSession();
+ BatchStatement writeBatch = getBatch()
+
+ //update the entry in notifications
+ .add(updateNotificationEntry(session,IS_READ).bind(true,UUID.fromString(notificationidToSet)))
+
+ // delete the notification's key from the unread notifications column family
+ .add(deleteUnreadNotEntry(session).bind(toSet.getUserid(), toSet.getTime().toInstant()));
+
+ // execute the operations
+ try {
+ boolean res = session.execute(writeBatch).wasApplied();
+
+ return res;
+ } catch (Exception e) {
+ _log.error("ERROR while setting Notification " + notificationidToSet + " to read.");
+ return false;
+ }
+ }
+ /**
+ *
+ * @param userid user identifier
+ * @return simply return a list of user notifications UUID in chronological order from the oldest to the more recent
+ */
+ private ArrayList getUserNotificationsIds(String userid) {
+ ResultSet result = null;
+ CqlSession session = conn.getKeyspaceSession();
+ PreparedStatement stmtFind = session.prepare(QueryBuilder
+ .selectFrom(USER_NOTIFICATIONS).all()
+ .whereColumn(USER_ID)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ try {
+ result = session.execute(stmtFind.bind(userid));
+
+ } catch (Exception e){
+ e.printStackTrace();
+
+ }
+
+ ArrayList toReturn = new ArrayList();
+
+ // Iterate rows and their columns
+ Listrows=result.all();
+ for (Row row : rows) {
+ toReturn.add(row.getUuid(NOT_ID).toString());
+ }
+ return toReturn;
+ }
+ /**
+ * Return a list of not read notifications by user userid (messages as well as other notifications)
+ * @param userid user identifier
+ * @return simply return a list of not read user notifications UUID in chronological order from the oldest to the more recent
+ */
+ private ArrayList getUnreadUserNotificationsIds(String userid) {
+ ResultSet result = null;
+ CqlSession session = conn.getKeyspaceSession();
+ PreparedStatement stmtFind = session.prepare(QueryBuilder
+ .selectFrom(USER_NOTIFICATIONS_UNREAD).all()
+ .whereColumn(USER_ID)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ try {
+ result = session.execute(stmtFind.bind(userid));
+
+ } catch (Exception e){
+ e.printStackTrace();
+
+ }
+
+ ArrayList toReturn = new ArrayList();
+
+ // Iterate rows and their columns
+ Listrows=result.all();
+ for (Row row : rows) {
+ toReturn.add(row.getUuid(NOT_ID).toString());
+ }
+ return toReturn;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List getAllNotificationByUser(String userid, int limit) throws NotificationTypeNotFoundException, ColumnNameNotFoundException {
+ ArrayList toReturn = new ArrayList();
+ ArrayList notificationsIDs = getUserNotificationsIds(userid);
+ //check if quantity is greater than user feeds
+ limit = (limit > notificationsIDs.size()) ? notificationsIDs.size() : limit;
+
+ //need them in reverse order
+ for (int i = notificationsIDs.size()-1; i >= (notificationsIDs.size()-limit); i--) {
+ Notification toAdd = null;
+ try {
+ toAdd = readNotification(notificationsIDs.get(i));
+ toReturn.add(toAdd);
+ } catch (NotificationIDNotFoundException e) {
+ _log.error("Notification not found id=" + notificationsIDs.get(i));
+ }
+ }
+ return toReturn;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List getUnreadNotificationsByUser(String userid) throws NotificationTypeNotFoundException, ColumnNameNotFoundException, NotificationIDNotFoundException {
+ ArrayList toReturn = new ArrayList();
+ ArrayList notificationsIDs = getUnreadUserNotificationsIds(userid);
+
+ //need them in reverse order
+ for (int i = notificationsIDs.size()-1; i >= 0; i--) {
+ try{
+ toReturn.add(readNotification(notificationsIDs.get(i)));
+ }catch(Exception e){
+ _log.error("Unable to read notification with key " + notificationsIDs.get(i));
+ }
+ }
+
+ return toReturn;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List getRangeNotificationsByUser(String userid,int from, int quantity) throws NotificationTypeNotFoundException, ColumnNameNotFoundException, NotificationIDNotFoundException {
+ if (from < 1) {
+ throw new IllegalArgumentException("From must be greather than 0");
+ }
+ ArrayList toReturn = new ArrayList();
+ ArrayList notificationsIDs = getUserNotificationsIds(userid);
+
+ //if from is greater than feeds size return empty
+ if (from >= notificationsIDs.size()) {
+ _log.warn("The starting point of the range is greather than the total number of feeds for this timeline: " + from + " >= " + notificationsIDs.size());
+ return new ArrayList();
+ }
+
+ int rangeStart = notificationsIDs.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
+ for (int i = rangeStart; i > rangeEnd; i--) {
+ Notification toAdd = readNotification(notificationsIDs.get(i));
+ toReturn.add(toAdd);
+ }
+ return toReturn;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean setAllNotificationReadByUser(String userid) throws NotificationTypeNotFoundException, ColumnNameNotFoundException {
+
+ // get the list of unread notifications
+ ArrayList notificationsIDs = getUnreadUserNotificationsIds(userid);
+
+ for (int i = notificationsIDs.size()-1; i >= 0; i--) {
+ try{
+
+ // set to read (and automatically remove from the unread column family)
+ setNotificationRead(notificationsIDs.get(i));
+
+ } catch (NotificationIDNotFoundException e) {
+ _log.error("Could not set read notification with id =" + notificationsIDs.get(i));
+ }
+ }
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean checkUnreadNotifications(String userid) throws NotificationTypeNotFoundException, ColumnNameNotFoundException {
+
+ ArrayList unreadNotifications = getUnreadUserNotificationsIds(userid);
+
+ for (int i = unreadNotifications.size() - 1; i >= 0; i--) {
+ Notification toAdd;
+ try {
+ toAdd = readNotification(unreadNotifications.get(i));
+ if (toAdd.getType() != NotificationType.MESSAGE)
+ return true;
+ } catch (NotificationIDNotFoundException e) {
+ _log.error("Notification not found with id = " + unreadNotifications.get(i));
+ }
+ }
+
+ return false;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean checkUnreadMessagesNotifications(String userid) throws NotificationIDNotFoundException, NotificationTypeNotFoundException, ColumnNameNotFoundException {
+
+ ArrayList unreadNotifications = getUnreadUserNotificationsIds(userid);
+
+ for (int i = unreadNotifications.size() - 1; i >= 0; i--) {
+ Notification toAdd;
+ try {
+ toAdd = readNotification(unreadNotifications.get(i));
+ if (toAdd.getType() == NotificationType.MESSAGE)
+ return true;
+ } catch (NotificationIDNotFoundException e) {
+ _log.error("Notification not found with id = " + unreadNotifications.get(i));
+ }
+ }
+
+ return false;
+ }
+ /*
+ *
+ ********************** NOTIFICATION SETTINGS ***********************
+ *
+ */
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List getUserNotificationChannels(String userid, NotificationType notificationType) throws NotificationChannelTypeNotFoundException, NotificationTypeNotFoundException {
+ _log.debug("Asking for Single Notification preference of " + userid + " Type: " + notificationType);
+ List toReturn = new ArrayList();
+ Map userNotPref = getUserNotificationPreferences(userid);
+ if(userNotPref!=null){
+ if(userNotPref.containsKey(notificationType)){
+ NotificationChannelType[] toProcess = userNotPref.get(notificationType);
+ //_log.debug("size of user notification preferences" + toProcess.length);
+ if (toProcess == null) {
+ _log.debug("Single Notification preference of " + userid + " Type: " + notificationType + " not existing ... creating default");
+ return createNewNotificationType(userid, notificationType);
+ }
+ else if (toProcess.length == 0){
+ _log.debug("size of user notification preferences " + 0);
+ return toReturn;
+ }
+ else
+ {
+ _log.debug("size of user notification preferences " + toProcess.length);
+ for (int i = 0; i < toProcess.length; i++) {
+ toReturn.add(toProcess[i]);
+ }
+ return toReturn;
+ }
+ }
+ return toReturn;
+ }
+ return toReturn;
+
+ }
+ /**
+ * called when you add new notification types where the setting does not exist yet
+ * please note: by default we set all notifications
+ */
+ private List createNewNotificationType(String userid, NotificationType notificationType) {
+ List toReturn = new ArrayList();
+ _log.debug("Create new notification type");
+ CqlSession session = conn.getKeyspaceSession();
+
+ String valueToInsert = "";
+ NotificationChannelType[] wpTypes = NotificationChannelType.values();
+
+ for (int i = 0; i < wpTypes.length; i++) {
+ valueToInsert += wpTypes[i];
+ if (i < wpTypes.length-1)
+ valueToInsert += ",";
+ toReturn.add(wpTypes[i]); //add the new added notification type
+ }
+
+ BatchStatement writeBatch = getBatch().add(
+ createNotificationPreferenceEntry(session).bind(userid, notificationType.toString(), valueToInsert)
+ );
+ boolean res = false;
+ try{
+ res = session.execute(writeBatch).wasApplied();
+
+ } catch (Exception e){
+ e.printStackTrace();
+
+ }
+
+ if (res) {
+ _log.debug("Set New Notification Setting for " + userid + " OK");
+ _log.debug("toreturn:" + toReturn.toString());
+ return toReturn;
+ }
+ _log.debug("empty list");
+ return new ArrayList(); //no notification if sth fails
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean setUserNotificationPreferences(String userid, Map enabledChannels) {
+ CqlSession session = conn.getKeyspaceSession();
+ List boundStatements = new ArrayList<>();
+
+ for (NotificationType nType : enabledChannels.keySet()) {
+ String valueToInsert = "";
+ _log.debug("Type: " + nType.toString());
+ int channelsNo = (enabledChannels.get(nType) != null) ? enabledChannels.get(nType).length : 0;
+ for (int i = 0; i < channelsNo; i++) {
+ _log.debug(enabledChannels.get(nType)[i].toString());
+ valueToInsert += NotificationChannelType.valueOf(enabledChannels.get(nType)[i].toString());
+ if (i < channelsNo-1)
+ valueToInsert += ",";
+ }
+ if (channelsNo == 0) { //in case no channels were selected
+ valueToInsert = "";
+ _log.trace("No Channels selected for " + nType + " by " + userid);
+ }
+
+ boundStatements.add(createNotificationPreferenceEntry(session).bind(userid, nType.toString(), valueToInsert));
+ }
+
+ BatchStatement writeBatch = getBatch().addAll(boundStatements);
+ boolean overAllresult = session.execute(writeBatch).wasApplied();
+ if (overAllresult)
+ _log.debug("Set Notification Map for " + userid + " OK");
+ else
+ _log.debug("Set Notification Map for " + userid + " FAILED");
+ return overAllresult;
+ }
+ /**
+ * {@inheritDoc}
+ *
+ * by default Workspace and Calendar Notifications are set to Portal
+ */
+ @Override
+ public Map getUserNotificationPreferences(String userid) throws NotificationTypeNotFoundException, NotificationChannelTypeNotFoundException {
+ _log.debug("Asking for Notification preferences of " + userid);
+ Map toReturn = new HashMap();
+
+ ResultSet result = null;
+ CqlSession session = conn.getKeyspaceSession();
+ PreparedStatement stmtFind = session.prepare(QueryBuilder
+ .selectFrom(USER_NOTIFICATIONS_PREFERENCES).all()
+ .whereColumn(USER_ID)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ try {
+ result = session.execute(stmtFind.bind(userid));
+
+ } catch (Exception e){
+ e.printStackTrace();
+
+ }
+
+ //if there are no settings for this user create an entry and put all of them at true
+ List results = new ArrayList<>();
+ if(result!=null) results = result.all();
+ //_log.debug("Result set empty? " + results.isEmpty());
+ if (results.isEmpty()) {
+ _log.debug("Userid " + userid + " settings not found, initiating its preferences...");
+ HashMap toCreate = new HashMap();
+
+ for (int i = 0; i < NotificationType.values().length; i++) {
+ //TODO: Potential bug in NotificationType for workspace are refactored
+ //create a map with all notification enabled except for workspace notifications (They start with WP_) it was the only quick way
+ if (NotificationType.values()[i].toString().startsWith("WP_")) {
+ NotificationChannelType[] wpTypes = { NotificationChannelType.PORTAL };
+ toCreate.put(NotificationType.values()[i], wpTypes);
+ }
+ else
+ toCreate.put(NotificationType.values()[i], NotificationChannelType.values());
+ }
+ setUserNotificationPreferences(userid, toCreate); //commit the map
+
+ return toCreate;
+ }
+ else {
+ _log.debug("Notification preferences Found for " + userid + " : " + results.size()) ;
+ for (Row row: results){
+ String[] channels = row.getString(PREFERENCE).split(",");
+ //_log.debug("Row : " + row.getString(PREFERENCE));
+ if (channels != null && channels.length == 1 && channels[0].toString().equals("") ) { //it is empty, preference is set to no notification at all
+ //_log.debug("adding CHANNELS NULL: " + getNotificationType(row.getString(TYPE)) + ", " + new NotificationChannelType[0]);
+ toReturn.put(getNotificationType(row.getString(TYPE)), new NotificationChannelType[0]);
+ } else {
+ NotificationChannelType[] toAdd = new NotificationChannelType[channels.length];
+ for (int i = 0; i < channels.length; i++) {
+ if (channels[i].compareTo("") != 0) {
+ toAdd[i] = (getChannelType(channels[i]));
+ }
+ }
+ //_log.debug("adding channels not null: " + getNotificationType(row.getString(TYPE)) + ", " + toAdd.toString());
+ toReturn.put(getNotificationType(row.getString(TYPE)), toAdd);
+ }
+ }
+ }
+ _log.debug("Returning:"+toReturn.size());
+ return toReturn;
+ }
+ /*
+ *
+ ********************** COMMENTS ***********************
+ *
+ */
+ private List insertIntoComments(CqlSession session, Comment comment){
+ PreparedStatement prepStmt1 = session.prepare(QueryBuilder.insertInto(COMMENTS).value(COMMENT_ID, QueryBuilder.bindMarker()).value(USER_ID, QueryBuilder.bindMarker()).build());
+ // "INSERT INTO comments("+COMMENT_ID+","+ USER_ID+") values(?, ?)");
+ PreparedStatement prepStmt2 = session.prepare(QueryBuilder.insertInto(COMMENTS).value(COMMENT_ID, QueryBuilder.bindMarker()).value(FULL_NAME, QueryBuilder.bindMarker()).build());
+ //"INSERT INTO comments("+COMMENT_ID+","+ FULL_NAME+") values(?, ?)");
+ PreparedStatement prepStmt3 = session.prepare(QueryBuilder.insertInto(COMMENTS).value(COMMENT_ID, QueryBuilder.bindMarker()).value(THUMBNAIL_URL, QueryBuilder.bindMarker()).build());
+ //"INSERT INTO comments("+COMMENT_ID+","+ THUMBNAIL_URL+") values(?, ?)");
+ PreparedStatement prepStmt4 = session.prepare(QueryBuilder.insertInto(COMMENTS).value(COMMENT_ID, QueryBuilder.bindMarker()).value(COMMENT, QueryBuilder.bindMarker()).build());
+ //"INSERT INTO comments("+COMMENT_ID+","+ COMMENT+") values(?, ?)");
+ PreparedStatement prepStmt5 = session.prepare(QueryBuilder.insertInto(COMMENTS).value(COMMENT_ID, QueryBuilder.bindMarker()).value(POST_ID, QueryBuilder.bindMarker()).build());
+ //"INSERT INTO comments("+COMMENT_ID+","+ POST_ID+") values(?, ?)");
+ PreparedStatement prepStmt6 = session.prepare(QueryBuilder.insertInto(COMMENTS).value(COMMENT_ID, QueryBuilder.bindMarker()).value(TIMESTAMP, QueryBuilder.bindMarker()).build());
+ //"INSERT INTO comments("+COMMENT_ID+","+ TIMESTAMP+") values(?, ?)");
+ PreparedStatement prepStmt7 = session.prepare(QueryBuilder.insertInto(COMMENTS).value(COMMENT_ID, QueryBuilder.bindMarker()).value(IS_EDIT, QueryBuilder.bindMarker()).build());
+ //"INSERT INTO comments("+COMMENT_ID+","+ TIMESTAMP+") values(?, ?)");
+ PreparedStatement prepStmt8 = session.prepare(QueryBuilder.insertInto(COMMENTS).value(COMMENT_ID, QueryBuilder.bindMarker()).value(LAST_EDIT_TIME, QueryBuilder.bindMarker()).build());
+
+ List boundStatements = new ArrayList<>();
+
+ if(comment.getUserid()!=null){
+ boundStatements.add(prepStmt1.bind(UUID.fromString(comment.getKey()),comment.getUserid()));
+ }
+
+ if(comment.getFullName()!=null){
+ boundStatements.add(prepStmt2.bind(UUID.fromString(comment.getKey()), comment.getFullName()));
+ }
+
+ if(comment.getThumbnailURL()!=null){
+ boundStatements.add(prepStmt3.bind(UUID.fromString(comment.getKey()), comment.getThumbnailURL()));
+ }
+ if(comment.getText()!=null){
+ boundStatements.add(prepStmt4.bind(UUID.fromString(comment.getKey()),comment.getText()));
+ }
+ if(comment.getFeedid()!=null){
+ boundStatements.add(prepStmt5.bind(UUID.fromString(comment.getKey()),UUID.fromString(comment.getFeedid())));
+ }if(comment.getTime()!=null){
+ boundStatements.add(prepStmt6.bind(UUID.fromString(comment.getKey()),comment.getTime().toInstant()));
+ }
+ boundStatements.add(prepStmt7.bind(UUID.fromString(comment.getKey()),comment.isEdit()));
+
+ if(comment.getLastEditTime()!=null){
+ boundStatements.add(prepStmt8.bind(UUID.fromString(comment.getKey()),comment.getLastEditTime().toInstant()));
+ }
+
+ return boundStatements;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean addComment(Comment comment) throws FeedIDNotFoundException {
+ Feed toComment = null;
+ if (comment == null)
+ throw new NullArgumentException("Comment must be not null");
+ if (comment.getFeedid() == null)
+ throw new NullArgumentException("Comment feed id must be not null");
+
+ String postid = comment.getFeedid();
+ try {
+ toComment = readFeed(postid);
+ if (toComment == null)
+ throw new FeedIDNotFoundException("Could not find Feed with id " + postid + " to associate this comment", postid);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ _log.debug("Writing comment : {}", comment.toString());
+ CqlSession session = conn.getKeyspaceSession();
+
+ List boundStatements = insertIntoComments(session, comment);
+ //boundStatements.forEach(stmt->writeBatch.add(stmt));
+
+ BatchStatement writeBatch = getBatch().addAll(boundStatements);
+
+ try {
+ ResultSet res = session.execute(writeBatch);
+ for (ExecutionInfo ex: res.getExecutionInfos()){
+ _log.debug("Writing comment result errors: {}", ex.getErrors());
+ _log.debug("Writing comment result payload: {}", ex.getIncomingPayload());
+ }
+ _log.debug("Writing comment result executed?: {}", res.wasApplied());
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ //update the comment count
+ boolean updateCommentNoResult = updateFeedCommentsCount(toComment, true);
+ return updateCommentNoResult;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ public Comment readCommentById(String commentId) throws CommentIDNotFoundException {
+ Comment toReturn = null;
+
+ ResultSet result = null;
+ CqlSession session = conn.getKeyspaceSession();
+ PreparedStatement stmtFind = session.prepare(QueryBuilder
+ .selectFrom(COMMENTS).all()
+ .whereColumn(COMMENT_ID)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ try {
+ result = session.execute(stmtFind.bind(UUID.fromString(commentId)));
+ toReturn = readCommentFromRow(result.one());
+ if (toReturn==null) {
+ throw new CommentIDNotFoundException("The requested commentId: " + commentId + " is not existing");
+ }
+
+ } catch (Exception e){
+ e.printStackTrace();
+ }
+
+ return toReturn;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ @Deprecated
+ public List getAllCommentByFeed(String feedid) {
+ return getAllCommentByPost(feedid);
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List getAllCommentByPost(String postid) {
+ //possible error index
+ List toReturn = new ArrayList();
+ ResultSet result = null;
+ CqlSession session = conn.getKeyspaceSession();
+ PreparedStatement stmtFind = session.prepare("SELECT * FROM comments WHERE postid=?");
+ /*PreparedStatement stmtFind = session.prepare(QueryBuilder
+ .selectFrom(COMMENTS).all()
+ .where
+ .whereColumn(POST_ID).isEqualTo(QueryBuilder.bindMarker())
+ .build());*/
+ try {
+ result = session.execute(stmtFind.bind(UUID.fromString(postid)));
+ Listrows=result.all();
+ for (Row row : rows) {
+ Comment toAdd = readCommentFromRow(row);
+ toReturn.add(toAdd);
+ }
+ } catch (Exception e){
+ e.printStackTrace();
+
+ }
+
+ return toReturn;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @throws Exception
+ */
+ @Override
+ public List getRecentCommentsByUserAndDate(final String userid,
+ final long timeInMillis) throws Exception {
+
+ final List commentsByUser;
+
+ 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");
+
+
+ commentsByUser = getRecentCommentsByUserAndDateBody(userid, timeInMillis, true);
+
+ return commentsByUser; }
+
+ /**
+ * Private method that allows also to specify if the returned list must be sorted or not
+ * @param userid the user id
+ * @param timeInMillis the initial time to consider
+ * @param sort a boolean value to specify if the returned list must be sorted (from the most recent to the oldest comment)
+ * @return a list of comments recently made by the user
+ */
+ private List getRecentCommentsByUserAndDateBody(final String userid,
+ final long timeInMillis, boolean sort){
+
+ //possible error
+ final List commentsByUser = new ArrayList();
+
+ CqlSession session = conn.getKeyspaceSession();
+
+ ResultSet result = null;
+ PreparedStatement stmtFind = session.prepare(QueryBuilder
+ .selectFrom(COMMENTS)
+ .all()
+ .build());
+ try {
+ result = session.execute(stmtFind.bind());
+
+ List results = result.all();
+ if (!results.isEmpty()){
+ results.parallelStream().forEach( row->{
+ if(row.getString(USER_ID).equals(userid)){
+ try{
+ Comment c = readCommentById(row.getUuid(COMMENT_ID).toString());
+ Post p = readPost(c.getFeedid());
+ if(c.getTime().getTime() >= timeInMillis &&
+ (p.getType() == PostType.TWEET || p.getType() == PostType.SHARE || p.getType() == PostType.PUBLISH))
+ commentsByUser.add(c);
+ }catch(Exception e){
+ _log.error("Unable to read comment with id" + row.getString(COMMENT_ID), e);
+ }
+ }
+ }
+ );
+ }
+ } catch (Exception e){
+ e.printStackTrace();
+
+ }
+
+ if(sort)
+ Collections.sort(commentsByUser, Collections.reverseOrder());
+ return commentsByUser;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean editComment(Comment comment2Edit) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, CommentIDNotFoundException, FeedIDNotFoundException {
+ CqlSession session = conn.getKeyspaceSession();
+ BatchStatement writeBatch = getBatch().add(updateCommentEntry(session, COMMENT).bind(comment2Edit.getText(), UUID.fromString(comment2Edit.getKey())))
+ .add(updateCommentEntry(session, IS_EDIT).bind(true, UUID.fromString(comment2Edit.getKey())))
+ .add(updateCommentEntry(session, LAST_EDIT_TIME).bind(new Date().toInstant(), UUID.fromString(comment2Edit.getKey())));
+
+ try {
+ boolean res = session.execute(writeBatch).wasApplied();
+
+ _log.debug("Comments update OK to: " + comment2Edit.getText());
+ return res;
+ } catch (Exception e) {
+
+ _log.error("Comments update NOT OK ");
+ return false;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean deleteComment(String commentid, String feedid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, CommentIDNotFoundException, FeedIDNotFoundException {
+ Feed toUpdate = readFeed(feedid);
+ boolean updateCommentNoResult = false;
+
+ updateCommentNoResult = updateFeedCommentsCount(toUpdate, false);
+ if (updateCommentNoResult) {
+ CqlSession session = conn.getKeyspaceSession();
+ BatchStatement writeBatch = getBatch().add(deleteCommentEntry(session).bind(UUID.fromString(commentid)));
+
+ try {
+ session.execute(writeBatch);
+
+ } catch (Exception e) {
+
+ _log.error("Comment Delete FAILED for " + commentid + " from Feed " + feedid);
+ e.printStackTrace();
+ }
+ _log.trace("Comment Deleted " + commentid + " from Feed " + feedid);
+ }
+
+
+ return updateCommentNoResult;
+ }
+
+ private List insertIntoLikes(CqlSession session, Like like){
+
+ PreparedStatement prepStmt1 = session.prepare(QueryBuilder.insertInto(LIKES).value(LIKE_ID, QueryBuilder.bindMarker()).value(USER_ID, QueryBuilder.bindMarker()).build());
+ // "INSERT INTO comments("+COMMENT_ID+","+ USER_ID+") values(?, ?)");
+ PreparedStatement prepStmt2 = session.prepare(QueryBuilder.insertInto(LIKES).value(LIKE_ID, QueryBuilder.bindMarker()).value(FULL_NAME, QueryBuilder.bindMarker()).build());
+ //"INSERT INTO comments("+COMMENT_ID+","+ FULL_NAME+") values(?, ?)");
+ PreparedStatement prepStmt3 = session.prepare(QueryBuilder.insertInto(LIKES).value(LIKE_ID, QueryBuilder.bindMarker()).value(THUMBNAIL_URL, QueryBuilder.bindMarker()).build());
+ //"INSERT INTO comments("+COMMENT_ID+","+ THUMBNAIL_URL+") values(?, ?)");
+ PreparedStatement prepStmt4 = session.prepare(QueryBuilder.insertInto(LIKES).value(LIKE_ID, QueryBuilder.bindMarker()).value(POST_ID, QueryBuilder.bindMarker()).build());
+ //"INSERT INTO comments("+COMMENT_ID+","+ POST_ID+") values(?, ?)");
+ PreparedStatement prepStmt5 = session.prepare(QueryBuilder.insertInto(LIKES).value(LIKE_ID, QueryBuilder.bindMarker()).value(TIMESTAMP, QueryBuilder.bindMarker()).build());
+ //"INSERT INTO comments("+COMMENT_ID+","+ TIMESTAMP+") values(?, ?)");
+
+
+ /*PreparedStatement prepStmt1 = session.prepare("INSERT INTO likes("+LIKE_ID+","+ USER_ID+") values(?, ?)");
+ PreparedStatement prepStmt2 = session.prepare("INSERT INTO likes("+LIKE_ID+","+ FULL_NAME+") values(?, ?)");
+ PreparedStatement prepStmt3 = session.prepare("INSERT INTO likes("+LIKE_ID+","+ THUMBNAIL_URL+") values(?, ?)");
+ PreparedStatement prepStmt4 = session.prepare("INSERT INTO likes("+LIKE_ID+","+ POST_ID+") values(?, ?)");
+ PreparedStatement prepStmt5 = session.prepare("INSERT INTO likes("+LIKE_ID+","+ TIMESTAMP+") values(?, ?)");
+ */
+ List boundStatements = new ArrayList<>();
+
+ if(like.getUserid()!=null){
+ boundStatements.add(prepStmt1.bind(UUID.fromString(like.getKey()),like.getUserid()));
+ }
+
+ if(like.getFullName()!=null){
+ boundStatements.add(prepStmt2.bind(UUID.fromString(like.getKey()), like.getFullName()));
+ }
+
+ if(like.getThumbnailURL()!=null){
+ boundStatements.add(prepStmt3.bind(UUID.fromString(like.getKey()), like.getThumbnailURL()));
+ }
+
+ if(like.getFeedid()!=null){
+ boundStatements.add(prepStmt4.bind(UUID.fromString(like.getKey()),UUID.fromString(like.getFeedid())));
+ }if(like.getTime()!=null){
+ boundStatements.add(prepStmt5.bind(UUID.fromString(like.getKey()),like.getTime().toInstant()));
+ }
+
+ return boundStatements;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean like(Like like) throws FeedIDNotFoundException {
+ Feed toLike = null;
+ if (like == null)
+ throw new NullArgumentException("Like must be not null");
+ if (like.getFeedid() == null)
+ throw new NullArgumentException("Like feed id must be not null");
+
+ String feedId = like.getFeedid();
+ try {
+ toLike = readFeed(feedId);
+ if (toLike == null)
+ throw new FeedIDNotFoundException("Could not find Feed with id " + feedId + " to associate this like", feedId);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ if (isPostLiked(like.getUserid(), feedId)) {
+ _log.debug("User " + like.getUserid() + " already liked Feed " + feedId);
+ return true;
+ }
+ else {
+ CqlSession session = conn.getKeyspaceSession();
+ // Inserting data
+ //an entry in the feed CF
+ //and an entry in the UserLikesCF
+ List boundStatements = insertIntoLikes(session,like);
+ BoundStatement stmt2 = createNewUserLikesEntry(session).bind(like.getUserid(), UUID.fromString(like.getKey()), UUID.fromString(like.getFeedid()));
+ boundStatements.add(stmt2);
+
+ //boundStatements.forEach(stmt->writeBatch.add(stmt));
+ BatchStatement writeBatch = getBatch().addAll(boundStatements);
+
+ try {
+ session.execute(writeBatch);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ return updateFeedLikesCount(toLike, true);
+ }
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean unlike(String userid, String likeid, String feedid) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, ColumnNameNotFoundException, LikeIDNotFoundException, FeedIDNotFoundException {
+ Feed toUpdate = readFeed(feedid);
+ boolean updateLikeNoResult = false;
+
+ updateLikeNoResult = updateFeedLikesCount(toUpdate, false); //this remove 1 from the Feed CF LikeNO
+ if (updateLikeNoResult) {
+ CqlSession session = conn.getKeyspaceSession();
+ BatchStatement writeBatch = getBatch().add(deleteLikeEntry(session).bind(UUID.fromString(likeid)))
+ .add(deleteUserLikeEntry(session).bind(userid, UUID.fromString(likeid)));
+ try {
+ session.execute(writeBatch);
+
+ } catch (Exception e) {
+
+ _log.error("Like Delete FAILED for " + likeid + " from Feed " + feedid);
+ e.printStackTrace();
+ }
+ _log.trace("Unlike ok for " + likeid + " from Feed " + feedid);
+ }
+ return updateLikeNoResult;
+
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ @Deprecated
+ public List getAllLikedFeedIdsByUser(String userid) {
+ return getAllLikedPostIdsByUser(userid);
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List getAllLikedPostIdsByUser(String userid) {
+ ResultSet result = null;
+ CqlSession session = conn.getKeyspaceSession();
+ PreparedStatement stmtFind = session.prepare(QueryBuilder
+ .selectFrom(USER_LIKED_POSTS).all()
+ .whereColumn(USER_ID)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ try {
+ result = session.execute(stmtFind.bind(userid));
+
+ } catch (Exception e){
+ e.printStackTrace();
+
+ }
+
+ ArrayList toReturn = new ArrayList();
+ for (Row row: result){
+ toReturn.add(row.getUuid(POST_ID).toString());
+ }
+ return toReturn;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List getAllLikedFeedsByUser(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--) {
+ Feed toAdd = readFeed(likedPostIDs.get(i));
+ if (toAdd.getType() == FeedType.TWEET || toAdd.getType() == FeedType.SHARE || toAdd.getType() == FeedType.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}
+ */
+ @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}
+ */
+ @Override
+ public List getRecentLikedFeedsByUserAndDate(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 = getAllLikedFeedIdsByUser(userid);
+
+ if(likedPostsIdsByUser != null && !likedPostsIdsByUser.isEmpty()){
+ for(int i = likedPostsIdsByUser.size() - 1; i >= 0; i--){
+ String postid = likedPostsIdsByUser.get(i);
+ try{
+
+ // retrieve the Post
+ Feed toCheck = readFeed(postid);
+ boolean isPostOk = (toCheck.getType() == FeedType.TWEET || toCheck.getType() == FeedType.SHARE || toCheck.getType() == FeedType.PUBLISH);
+
+ // retrieve the like of the user for the post
+ if(isPostOk){
+ List likes = getAllLikesByFeed(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 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}
+ */
+ @Deprecated
+ @Override
+ public List getAllLikesByFeed(String feedid) {
+ return getAllLikesByPost(feedid);
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List getAllLikesByPost(String postid) {
+ //possible error index
+
+ List toReturn = new ArrayList();
+ ResultSet result = null;
+ CqlSession session = conn.getKeyspaceSession();
+ PreparedStatement stmtFind = session.prepare(QueryBuilder
+ .selectFrom(LIKES).all()
+ .whereColumn(POST_ID).isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ try {
+ result = session.execute(stmtFind.bind(UUID.fromString(postid)));
+ for (Row row: result) {
+ Like toAdd = readLikeFromRow(row);
+ toReturn.add(toAdd);
+ }
+
+ } catch (Exception e){
+ e.printStackTrace();
+
+ }
+ return toReturn;
+ }
+ /*
+ *
+ ********************** HASHTAGS ***********************
+ *
+ */
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean saveHashTags(String feedid, String vreid, List hashtags) throws FeedIDNotFoundException {
+ Set noduplicatesHashtags = null;
+ if (hashtags != null && !hashtags.isEmpty()) {
+ noduplicatesHashtags = new HashSet(hashtags);
+ }
+ // Inserting data
+ CqlSession session = conn.getKeyspaceSession();
+ for (String hashtag : noduplicatesHashtags) {
+ String lowerCaseHashtag = hashtag.toLowerCase();
+ boolean firstInsert = session.execute((createNewHashtagTimelineEntry(session).bind(lowerCaseHashtag, UUID.fromString(feedid), vreid))).wasApplied();
+ boolean secondInsert = updateVREHashtagCount(vreid, lowerCaseHashtag, true);
+ if (! (firstInsert && secondInsert)) {
+ _log.error("saveHashTags: Could not save the hashtag(s)");
+
+ return false;
+ }
+ }
+
+ return true;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean deleteHashTags(String feedid, String vreid, List hashtags) throws FeedIDNotFoundException {
+ Set noduplicatesHashtags = null;
+ if (hashtags != null && !hashtags.isEmpty()) {
+ noduplicatesHashtags = new HashSet(hashtags);
+ }
+ // Inserting data
+ CqlSession session = conn.getKeyspaceSession();
+ for (String hashtag : noduplicatesHashtags) {
+ String lowerCaseHashtag = hashtag.toLowerCase();
+ boolean firstDelete = session.execute(deleteHashtagEntry(session).bind(lowerCaseHashtag, UUID.fromString(feedid))).wasApplied();
+ boolean secondInsert = updateVREHashtagCount(vreid, lowerCaseHashtag, false);
+ if (! (firstDelete && secondInsert)) {
+ _log.error("deleteHashTags: Could not delete the hashtag(s)");
+
+ return false;
+
+ }
+ }
+
+ return true;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean saveHashTagsComment(String commentId, String vreid, List hashtags) throws CommentIDNotFoundException {
+ Set noduplicatesHashtags = null;
+ if (hashtags != null && !hashtags.isEmpty()) {
+ noduplicatesHashtags = new HashSet(hashtags);
+ }
+ // Inserting datacommentIdcommentId
+ CqlSession session = conn.getKeyspaceSession();
+ for (String hashtag : noduplicatesHashtags) {
+ String lowerCaseHashtag = hashtag.toLowerCase();
+ boolean firstInsert = session.execute(createNewHashtagCommentEntry(session).bind(hashtag, UUID.fromString(commentId), vreid)).wasApplied();
+ boolean secondInsert = false;
+ if(firstInsert)
+ secondInsert = updateVREHashtagCount(vreid, lowerCaseHashtag, true);
+ if (! (firstInsert && secondInsert)) {
+ _log.error("saveHashTags: Could not save the hashtag(s)");
+
+ return false;
+ }
+ }
+
+ return true;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean deleteHashTagsComment(String commentId, String vreid, List hashtags) throws CommentIDNotFoundException {
+ Set noduplicatesHashtags = null;
+ if (hashtags != null && !hashtags.isEmpty()) {
+ noduplicatesHashtags = new HashSet(hashtags);
+ }
+ // Inserting data
+ CqlSession session = conn.getKeyspaceSession();
+ for (String hashtag : noduplicatesHashtags) {
+ String lowerCaseHashtag = hashtag.toLowerCase();
+ boolean firstDelete = session.execute(deleteHashtagCommentEntry(session).bind(lowerCaseHashtag, UUID.fromString(commentId))).wasApplied();
+ if(firstDelete){
+ boolean secondInsert = updateVREHashtagCount(vreid, lowerCaseHashtag, false);
+ if (!(firstDelete && secondInsert)) {
+ _log.error("deleteHashTags: Could not delete the hashtag(s)");
+
+ return false;
+ }
+ }else{
+ _log.error("deleteHashTags: Could not delete the hashtag(s)");
+
+ return false;
+ }
+ }
+
+ return true;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Map getVREHashtagsWithOccurrence(String vreid) {
+ ResultSet result = null;
+ CqlSession session = conn.getKeyspaceSession();
+
+ PreparedStatement stmtFind = session.prepare(QueryBuilder
+ .selectFrom(HASHTAGS_COUNTER).all()
+ .whereColumn(VRE_ID)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ try {
+ result = session.execute(stmtFind.bind(vreid));
+
+ } catch (Exception e){
+ e.printStackTrace();
+
+ }
+
+
+ HashMap toReturn = new HashMap ();
+
+ List rows = result.all();
+ // Iterate rows and their columns
+ for (Row row : rows) {
+ Integer curValue = (int) row.getLong(COUNT);
+ if (curValue > 0)
+ toReturn.put(row.getString(HASHTAG), curValue);
+ }
+
+ return toReturn;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Map getVREHashtagsWithOccurrenceFilteredByTime(String vreid, long timestamp){
+ CqlSession session = conn.getKeyspaceSession();
+ ResultSet result = null;
+ PreparedStatement stmtFind = session.prepare(QueryBuilder
+ .selectFrom(HASHTAGS_COUNTER).all()
+ .whereColumn(VRE_ID)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ try {
+ result = session.execute(stmtFind.bind(vreid));
+
+ } catch (Exception e){
+ e.printStackTrace();
+
+ }
+
+ HashMap toReturn = new HashMap ();
+ List rows = result.all();
+ // Iterate rows and their columns
+ for (Row row : rows) {
+ // retrieve the feeds list for this hashtag
+ List feeds = null;
+ try{
+ feeds = getVREPostsByHashtag(vreid, row.getString(HASHTAG));
+ }catch(Exception e){
+ _log.error("Unable to retrieve the list of feeds for hashtag" + row.getString(HASHTAG) + " in vre " + vreid);
+ continue;
+ }
+
+ if(feeds.isEmpty()){
+
+ _log.debug("There are no feeds containing hashtag " + row.getString(HASHTAG) + " in vre " + vreid);
+ continue;
+
+ }
+
+ // retrieve the most recent one among these feeds
+ Collections.sort(feeds, Collections.reverseOrder());
+
+ if(feeds.get(0).getTime().getTime() < timestamp){
+ continue;
+ }
+
+ // else..
+ int curValue = (int) row.getLong(COUNT);
+
+ if (curValue > 0)
+ toReturn.put(row.getString(HASHTAG), curValue);
+ }
+ return toReturn;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List getVREFeedsByHashtag(String vreid, String hashtag) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException {
+ List toReturn = new ArrayList<>();
+ CqlSession session = conn.getKeyspaceSession();
+
+ ResultSet resultPost = null;
+ PreparedStatement stmtFind1 = session.prepare(QueryBuilder
+ .selectFrom(HASHTAGGED_POSTS).all()
+ .whereColumn(HASHTAG)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ try {
+ resultPost = session.execute(stmtFind1.bind(hashtag));
+ } catch (Exception e){
+ e.printStackTrace();
+
+ }
+
+ PreparedStatement stmtFind2 = session.prepare(QueryBuilder
+ .selectFrom(HASHTAGGED_COMMENTS).all()
+ .whereColumn(HASHTAG)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ ResultSet resultComment = null;
+ try {
+ resultComment = session.execute(stmtFind2.bind(hashtag));
+ } catch (Exception e){
+ e.printStackTrace();
+
+ }
+
+ Set postIds = new HashSet<>();
+ // Iterate rows and their columns (feed)
+ ListrowsPost=resultPost.all();
+ for (Row row : rowsPost) {
+ if (row.getString(VRE_ID).compareTo(vreid)==0)
+ postIds.add(row.getUuid(POST_ID).toString());
+ }
+ // Iterate rows and their columns (comments)
+ ListrowsComment=resultComment.all();
+ for (Row row : rowsComment) {
+ if (row.getString(VRE_ID).compareTo(vreid)==0){
+ try {
+ Comment c = readCommentById(row.getUuid(COMMENT_ID).toString());
+ postIds.add(c.getFeedid());
+ } catch (CommentIDNotFoundException e) {
+ _log.warn("Failed to fetch comment with id " + row.getString(COMMENT_ID));
+ }
+ }
+ }
+ toReturn = getFeedsByIds(new ArrayList<>(postIds));
+ return toReturn;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List getVREPostsByHashtag(String vreid, String hashtag) throws PrivacyLevelTypeNotFoundException, FeedTypeNotFoundException, FeedIDNotFoundException, ColumnNameNotFoundException {
+ List toReturn = new ArrayList<>();
+ CqlSession session = conn.getKeyspaceSession();
+
+ ResultSet resultPost = null;
+ PreparedStatement stmtFind1 = session.prepare(QueryBuilder
+ .selectFrom(HASHTAGGED_POSTS).all()
+ .whereColumn(HASHTAG)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ try {
+ resultPost = session.execute(stmtFind1.bind(hashtag));
+ } catch (Exception e){
+ e.printStackTrace();
+
+ }
+
+ PreparedStatement stmtFind2 = session.prepare(QueryBuilder
+ .selectFrom(HASHTAGGED_COMMENTS).all()
+ .whereColumn(HASHTAG)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ ResultSet resultComment = null;
+ try {
+ resultComment = session.execute(stmtFind2.bind(hashtag));
+ } catch (Exception e){
+ e.printStackTrace();
+
+ }
+
+ Set postIds = new HashSet<>();
+ // Iterate rows and their columns (feed)
+ ListrowsPost=resultPost.all();
+ for (Row row : rowsPost) {
+ if (row.getString(VRE_ID).compareTo(vreid)==0)
+ postIds.add(row.getUuid(POST_ID).toString());
+ }
+ // Iterate rows and their columns (comments)
+ ListrowsComment=resultComment.all();
+ for (Row row : rowsComment) {
+ if (row.getString(VRE_ID).compareTo(vreid)==0){
+ try {
+ Comment c = readCommentById(row.getUuid(COMMENT_ID).toString());
+ postIds.add(c.getFeedid());
+ } catch (CommentIDNotFoundException e) {
+ _log.warn("Failed to fetch comment with id " + row.getString(COMMENT_ID));
+ }
+ }
+ }
+ toReturn = getPostsByIds(new ArrayList<>(postIds));
+ return toReturn;
+ }
+ /*
+ *
+ ********************** Invites ***********************
+ *
+ */
+ private List insertIntoInvites(CqlSession session, Invite invite){
+
+ PreparedStatement prepStmt1 = session.prepare(QueryBuilder.insertInto(INVITES).value(INVITE_ID, QueryBuilder.bindMarker()).value(SENDER_USER_ID, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt2 = session.prepare(QueryBuilder.insertInto(INVITES).value(INVITE_ID, QueryBuilder.bindMarker()).value(VRE_ID, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt3 = session.prepare(QueryBuilder.insertInto(INVITES).value(INVITE_ID, QueryBuilder.bindMarker()).value(EMAIL, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt4 = session.prepare(QueryBuilder.insertInto(INVITES).value(INVITE_ID, QueryBuilder.bindMarker()).value(CONTROL_CODE, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt5 = session.prepare(QueryBuilder.insertInto(INVITES).value(INVITE_ID, QueryBuilder.bindMarker()).value(STATUS, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt6 = session.prepare(QueryBuilder.insertInto(INVITES).value(INVITE_ID, QueryBuilder.bindMarker()).value(TIMESTAMP, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt7 = session.prepare(QueryBuilder.insertInto(INVITES).value(INVITE_ID, QueryBuilder.bindMarker()).value(SENDER_FULL_NAME, QueryBuilder.bindMarker()).build());
+
+ /*PreparedStatement prepStmt1 = session.prepare("INSERT INTO invites("+INVITE_ID+","+ SENDER_USER_ID+") values(?, ?)");
+ PreparedStatement prepStmt2 = session.prepare("INSERT INTO invites("+INVITE_ID+","+ VRE_ID+") values(?, ?)");
+ PreparedStatement prepStmt3 = session.prepare("INSERT INTO invites("+INVITE_ID+","+ EMAIL+") values(?, ?)");
+ PreparedStatement prepStmt4 = session.prepare("INSERT INTO invites("+INVITE_ID+","+ CONTROL_CODE+") values(?, ?)");
+ PreparedStatement prepStmt5 = session.prepare("INSERT INTO invites("+INVITE_ID+","+ STATUS+") values(?, ?)");
+ PreparedStatement prepStmt6 = session.prepare("INSERT INTO invites("+INVITE_ID+","+ TIMESTAMP+") values(?, ?)");
+ PreparedStatement prepStmt7 = session.prepare("INSERT INTO invites("+INVITE_ID+","+ SENDER_FULL_NAME+") values(?, ?)");
+*/
+ List boundStatements = new ArrayList<>();
+
+ if(invite.getSenderUserId()!=null){
+ boundStatements.add(prepStmt1.bind(UUID.fromString(invite.getKey()),invite.getSenderUserId()));
+ }
+
+ if(invite.getVreid()!=null){
+ boundStatements.add(prepStmt2.bind(UUID.fromString(invite.getKey()), invite.getVreid()));
+ }
+
+ if(invite.getInvitedEmail()!=null){
+ boundStatements.add(prepStmt3.bind(UUID.fromString(invite.getKey()), invite.getInvitedEmail()));
+ }
+
+ if(invite.getControlCode()!=null){
+ boundStatements.add(prepStmt4.bind(UUID.fromString(invite.getKey()),invite.getControlCode()));
+ }
+ if(invite.getStatus()!=null){
+ boundStatements.add(prepStmt5.bind(UUID.fromString(invite.getKey()),invite.getStatus().toString()));
+ }
+ if(invite.getTime()!=null){
+ boundStatements.add(prepStmt6.bind(UUID.fromString(invite.getKey()),invite.getTime().toInstant()));
+ }
+
+ if(invite.getSenderFullName()!=null){
+ boundStatements.add(prepStmt7.bind(UUID.fromString(invite.getKey()),invite.getSenderFullName()));
+ }
+
+ return boundStatements;
+ }
+
+ /**
+ * common part to save a invite
+ * @param invite
+ * @return the partial mutation batch instance
+ */
+ private List initSaveInvite(Invite invite, CqlSession session) {
+ List boundStatements = insertIntoInvites(session, invite);
+
+
+ if (invite == null)
+ throw new NullArgumentException("Invite instance is null");
+ //insertIntoInvites(session,invite).forEach(stmt->writeBatch.add(stmt));
+ //BatchStatement writeBatch = getBatch().addAll(boundStatements);
+ // Inserting data
+ /*writeBatch.add(createNewInviteEntry(session).bind(
+ UUID.fromString(invite.getKey()),
+ invite.getSenderUserId(),
+ invite.getVreid(),
+ invite.getInvitedEmail(),
+ invite.getControlCode(),
+ invite.getStatus().toString(),
+ invite.getTime().toInstant(),
+ invite.getSenderFullName()
+ ));*/
+
+
+ return boundStatements;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String isExistingInvite(String vreid, String email) {
+ CqlSession session = conn.getKeyspaceSession();
+
+ ResultSet result = null;
+ PreparedStatement stmtFind1 = session.prepare(QueryBuilder
+ .selectFrom(EMAIL_INVITES).all()
+ .whereColumn(EMAIL)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ try {
+ result = session.execute(stmtFind1.bind(email));
+ } catch (Exception e){
+ e.printStackTrace();
+
+ }
+
+ // Iterate rows and their columns
+ Listrows=result.all();
+ for (Row row : rows) {
+ if (row.getString(VRE_ID).compareTo(vreid)==0)
+ return row.getUuid(INVITE_ID).toString();
+
+ }
+ return null;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public InviteOperationResult saveInvite(Invite invite) throws AddressException {
+ if (invite == null)
+ throw new NullArgumentException("Invite instance is null");
+ String email = invite.getInvitedEmail();
+ if (! verifyEmail(email))
+ throw new AddressException("Email is not valid ->" + email);
+ if (invite.getVreid() == null || invite.getVreid().equals(""))
+ throw new NullArgumentException("VREId is null or empty");
+ _log.debug("isExistingInvite? " + invite.getInvitedEmail() + " in " + invite.getVreid());
+ if (isExistingInvite(invite.getVreid(), invite.getInvitedEmail()) != null)
+ return InviteOperationResult.ALREADY_INVITED;
+ _log.debug("Invite not found, proceed to save it ...");
+ CqlSession session = conn.getKeyspaceSession();
+ List boundStatements = initSaveInvite(invite, session);
+ //an entry in the VRE Invites
+ boundStatements.add(createNewVreInviteEntry(session).bind(invite.getVreid(), UUID.fromString(invite.getKey()), InviteStatus.PENDING.toString()));
+ //an entry in the EMAIL Invites
+ boundStatements.add(createNewEmailInviteEntry(session).bind(email, invite.getVreid(), UUID.fromString(invite.getKey())));
+ BatchStatement writeBatch = getBatch().addAll(boundStatements);
+ boolean result = session.execute(writeBatch).wasApplied();
+
+ return result ? InviteOperationResult.SUCCESS : InviteOperationResult.FAILED;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Invite readInvite(String inviteid) throws InviteIDNotFoundException, InviteStatusNotFoundException {
+ Invite toReturn = null;
+ CqlSession session = conn.getKeyspaceSession();
+ ResultSet result = null;
+ PreparedStatement stmtFind = session.prepare(QueryBuilder
+ .selectFrom(INVITES).all()
+ .whereColumn(INVITE_ID)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ try {
+ result = session.execute(stmtFind.bind(UUID.fromString(inviteid)));
+ toReturn = readAInviteFromRow(result.one());
+ if (toReturn == null) {
+ throw new InviteStatusNotFoundException("The requested inviteid: " + inviteid + " is not existing");
+ }
+ //toReturn = readAInviteFromRow(result.all().get(0));
+
+ } catch (Exception e){
+ e.printStackTrace();
+
+ }
+ return toReturn;
+ }
+ /**
+ * helper method that retrieve all the Invites belonging to a list of Ids
+ * @param inviteIds the lisf of invites UUID
+ * @return all the invites belonging to a list of Ids
+ * @throws InviteIDNotFoundException
+ * @throws InviteStatusNotFoundException
+ */
+ private List getInvitesById(List inviteIds) throws InviteIDNotFoundException, InviteStatusNotFoundException {
+ ArrayList toReturn = new ArrayList();
+ for (String inviteid : inviteIds)
+ toReturn.add(readInvite(inviteid));
+
+ return toReturn;
+ }
+ /**
+ * {@inheritDoc}
+ * @throws InviteStatusNotFoundException
+ */
+ @Override
+ public boolean setInviteStatus(String vreid, String email, InviteStatus status) throws InviteIDNotFoundException, InviteStatusNotFoundException {
+ String inviteid = isExistingInvite(vreid, email);
+ Invite toSet = readInvite(inviteid);
+ if (toSet == null)
+ throw new InviteIDNotFoundException("The specified invite to set with id: " + inviteid + " does not exist");
+
+ CqlSession session = conn.getKeyspaceSession();
+ BatchStatement writeBatch = getBatch().add(updateInviteEntry(session, STATUS).bind(status.toString(), UUID.fromString(inviteid)))
+ .add(updateVreInviteEntry(session, STATUS).bind(status.toString(), vreid, UUID.fromString(inviteid)));
+ try {
+ session.execute(writeBatch);
+
+ } catch (Exception e) {
+ _log.error("ERROR while setting Invite " + inviteid + " to " + status.toString());
+
+ return false;
+ }
+ _log.trace("Invite Status Set to " + status.toString() + " OK");
+ return true;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List getInvitedEmailsByVRE(String vreid, InviteStatus... status) throws InviteIDNotFoundException, InviteStatusNotFoundException{
+ CqlSession session = conn.getKeyspaceSession();
+ ResultSet result = null;
+ PreparedStatement stmtFind = session.prepare(QueryBuilder
+ .selectFrom(VRE_INVITES).all()
+ .whereColumn(VRE_ID)
+ .isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ try {
+ result = session.execute(stmtFind.bind(vreid));
+
+ } catch (Exception e){
+ e.printStackTrace();
+
+ }
+
+ ArrayList invitesIds = new ArrayList();
+ // Iterate rows and their columns
+ Listrows=result.all();
+ for (Row row : rows) {
+ if (status != null) {
+ for (int i = 0; i < status.length; i++) {
+ if (row.getString(STATUS).compareTo(status[i].toString())==0)
+ invitesIds.add(row.getUuid(INVITE_ID).toString());
+ }
+ }
+ else {
+ invitesIds.add(row.getUuid(INVITE_ID).toString());
+ }
+ }
+ return getInvitesById(invitesIds);
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List getAttachmentsByFeedId(String feedId) throws FeedIDNotFoundException {
+ //index error
+ Post toCheck = null;
+ try {
+ toCheck = readPost(feedId);
+ if (toCheck == null)
+ throw new FeedIDNotFoundException("Could not find Feed with id " + feedId, feedId);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ List toReturn = new ArrayList();
+ CqlSession session = conn.getKeyspaceSession();
+ PreparedStatement stmtFind = session.prepare(QueryBuilder
+ .selectFrom(ATTACHMENTS).all()
+ .whereColumn(POST_ID).isEqualTo(QueryBuilder.bindMarker())
+ .build());
+ ResultSet result = null;
+ try {
+ result = session.execute(stmtFind.bind(UUID.fromString(feedId)));
+ // Iterate rows and their columns
+ Listrows=result.all();
+ for (Row row : rows) {
+ _log.trace("Reading attachment if feed=" + row.getUuid(POST_ID).toString());
+ Attachment toAdd = readAttachmentFromRow(row);
+ toReturn.add(toAdd);
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+
+ return null;
+ }
+ return toReturn;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void closeConnection() {
+ conn.closeConnection();
+ }
+ /*
+ *
+ ********************** Helper methods ***********************
+ *
+ */
+ private List insertIntoAttachments(CqlSession session, Attachment attachment, String feedId){
+
+
+ PreparedStatement prepStmt1 = session.prepare(QueryBuilder.insertInto(ATTACHMENTS).value(ATTACH_ID, QueryBuilder.bindMarker()).value(POST_ID, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt2 = session.prepare(QueryBuilder.insertInto(ATTACHMENTS).value(ATTACH_ID, QueryBuilder.bindMarker()).value(URI, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt3 = session.prepare(QueryBuilder.insertInto(ATTACHMENTS).value(ATTACH_ID, QueryBuilder.bindMarker()).value(NAME, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt4 = session.prepare(QueryBuilder.insertInto(ATTACHMENTS).value(ATTACH_ID, QueryBuilder.bindMarker()).value(DESCRIPTION, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt5 = session.prepare(QueryBuilder.insertInto(ATTACHMENTS).value(ATTACH_ID, QueryBuilder.bindMarker()).value(URI_THUMBNAIL, QueryBuilder.bindMarker()).build());
+ PreparedStatement prepStmt6 = session.prepare(QueryBuilder.insertInto(ATTACHMENTS).value(ATTACH_ID, QueryBuilder.bindMarker()).value(MIME_TYPE, QueryBuilder.bindMarker()).build());
+
+ /*PreparedStatement prepStmt1 = session.prepare("INSERT INTO attachments("+ATTACH_ID+","+ POST_ID+") values(?, ?)");
+ PreparedStatement prepStmt2 = session.prepare("INSERT INTO attachments("+ATTACH_ID+","+ URI+") values(?, ?)");
+ PreparedStatement prepStmt3 = session.prepare("INSERT INTO attachments("+ATTACH_ID+","+ NAME+") values(?, ?)");
+ PreparedStatement prepStmt4 = session.prepare("INSERT INTO attachments("+ATTACH_ID+","+ DESCRIPTION+") values(?, ?)");
+ PreparedStatement prepStmt5 = session.prepare("INSERT INTO attachments("+ATTACH_ID+","+ URI_THUMBNAIL+") values(?, ?)");
+ PreparedStatement prepStmt6 = session.prepare("INSERT INTO attachments("+ATTACH_ID+","+ MIME_TYPE+") values(?, ?)");
+*/
+ List boundStatements = new ArrayList<>();
+
+ boundStatements.add(prepStmt1.bind(UUID.fromString(attachment.getId()),UUID.fromString(feedId)));
+
+
+ if(attachment.getUri()!=null){
+ boundStatements.add(prepStmt2.bind(UUID.fromString(attachment.getId()), attachment.getUri()));
+ }
+
+ if(attachment.getName()!=null){
+ boundStatements.add(prepStmt3.bind(UUID.fromString(attachment.getId()), attachment.getName()));
+ }
+
+ if(attachment.getDescription()!=null){
+ boundStatements.add(prepStmt4.bind(UUID.fromString(attachment.getId()),attachment.getDescription()));
+ }
+ if(attachment.getThumbnailURL()!=null){
+ boundStatements.add(prepStmt5.bind(UUID.fromString(attachment.getId()),attachment.getThumbnailURL()));
+ }
+ if(attachment.getMimeType()!=null){
+ boundStatements.add(prepStmt6.bind(UUID.fromString(attachment.getId()),attachment.getMimeType()));
+ }
+
+
+ return boundStatements;
+ }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean saveAttachmentEntry(String feedId, Attachment toSave) {
+ // Inserting data
+ CqlSession session = conn.getKeyspaceSession();
+ //an entry in the Attachment CF
+ try {
+ List boundStatements = insertIntoAttachments(session, toSave, feedId);
+ BatchStatement writeBatch = getBatch().addAll(boundStatements);
+ //boundStatements.forEach(stmt->writeBatch.add(stmt));
+ ResultSet res = session.execute(writeBatch);
+ _log.debug(res.getExecutionInfos().toString());
+ _log.debug(""+res.wasApplied());
+ /*
+ session.execute(createNewaAttachEntry(session).bind(
+ UUID.fromString(toSave.getId()),
+ UUID.fromString(feedId),
+ toSave.getUri(),
+ toSave.getName(),
+ toSave.getDescription(),
+ toSave.getThumbnailURL(),
+ toSave.getMimeType()
+ ));*/
+
+ } catch (Exception e) {
+
+ e.printStackTrace();
+ return false;
+ }
+ return true;
+ }
+
+
+ /**
+ * simply return an enum representing the privacy level
+ * @return correct enum representing the privacy level
+ * @throws NotificationChannelTypeNotFoundException
+ * @throws FeedTypeNotFoundException
+ */
+ private NotificationChannelType getChannelType(String channelName) throws NotificationChannelTypeNotFoundException {
+ if (channelName.compareTo("PORTAL") == 0)
+ return NotificationChannelType.PORTAL;
+ else if (channelName.compareTo("EMAIL") == 0)
+ return NotificationChannelType.EMAIL;
+ else if (channelName.compareTo("TWITTER") == 0)
+ return NotificationChannelType.TWITTER;
+ else
+ throw new NotificationChannelTypeNotFoundException("The Notification Channel Type was not recognized should be one of " + NotificationChannelType.values() + " asked for: " + channelName);
+ }
+
+ /**
+ * simply return an enum representing the privacy level
+ * @param privacyLevel .
+ * @return correct enum representing the privacy level
+ * @throws FeedTypeNotFoundException
+ */
+ private static PrivacyLevel getPrivacyLevel(String privacyLevel) throws PrivacyLevelTypeNotFoundException {
+ if (privacyLevel.compareTo("CONNECTION") == 0)
+ return PrivacyLevel.CONNECTION;
+ else if (privacyLevel.compareTo("PRIVATE") == 0)
+ return PrivacyLevel.PRIVATE;
+ else if (privacyLevel.compareTo("PUBLIC") == 0)
+ return PrivacyLevel.PUBLIC;
+ else if (privacyLevel.compareTo("VRES") == 0)
+ return PrivacyLevel.VRES;
+ else if (privacyLevel.compareTo("SINGLE_VRE") == 0)
+ return PrivacyLevel.SINGLE_VRE;
+ else if (privacyLevel.compareTo("PORTAL") == 0)
+ return PrivacyLevel.PORTAL;
+ else
+ throw new PrivacyLevelTypeNotFoundException("The Privacy Level was not recognized should be one of " + PrivacyLevel.values() + " asked for: " + privacyLevel);
+ }
+ /**
+ * simply return an enum representing the feed type
+ * @param type .
+ * @return correct enum representing the feed type
+ * @throws FeedTypeNotFoundException .
+ */
+ private static FeedType getFeedType(String type) throws FeedTypeNotFoundException {
+ if (type.compareTo("TWEET") == 0) {
+ return FeedType.TWEET;
+ }
+ else if (type.compareTo("JOIN") == 0) {
+ return FeedType.JOIN;
+ }
+ else if (type.compareTo("PUBLISH") == 0) {
+ return FeedType.PUBLISH;
+ }
+ else if (type.compareTo("SHARE") == 0) {
+ return FeedType.SHARE;
+ }
+ else if (type.compareTo("ACCOUNTING") == 0) {
+ return FeedType.ACCOUNTING;
+ }
+ else if (type.compareTo("DISABLED") == 0) {
+ return FeedType.DISABLED;
+ }
+ 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 FeedTypeNotFoundException .
+ */
+ private static 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
+ * @param type .
+ * @return correct enum representing the feed type
+ * @throws InviteStatusNotFoundException .
+ */
+ private static InviteStatus getInviteStatusType(String type) throws InviteStatusNotFoundException {
+ switch (type) {
+ case "PENDING":
+ return InviteStatus.PENDING;
+ case "ACCEPTED":
+ return InviteStatus.ACCEPTED;
+ case "REJECTED":
+ return InviteStatus.REJECTED;
+ case "RETRACTED":
+ return InviteStatus.RETRACTED;
+ default:
+ throw new InviteStatusNotFoundException("The Invite Status was not recognized should be one of " + InviteStatus.values() + " asked for: " + type);
+ }
+
+ }
+
+ /**
+ * simply return an enum representing the feed type
+ * @param type .
+ * @return correct enum representing the feed type
+ * @throws NotificationTypeNotFoundException .
+ */
+ private static NotificationType getNotificationType(String type) throws NotificationTypeNotFoundException {
+ if (type.compareTo("WP_FOLDER_SHARE") == 0) {
+ return NotificationType.WP_FOLDER_SHARE;
+ }
+ else if (type.compareTo("WP_FOLDER_UNSHARE") == 0) {
+ return NotificationType.WP_FOLDER_UNSHARE;
+ }
+ else if (type.compareTo("WP_ADMIN_UPGRADE") == 0) {
+ return NotificationType.WP_ADMIN_UPGRADE;
+ }
+ else if (type.compareTo("WP_ADMIN_DOWNGRADE") == 0) {
+ return NotificationType.WP_ADMIN_DOWNGRADE;
+ }
+ else if (type.compareTo("WP_FOLDER_RENAMED") == 0) {
+ return NotificationType.WP_FOLDER_RENAMED;
+ }
+ else if (type.compareTo("WP_FOLDER_ADDEDUSER") == 0) {
+ return NotificationType.WP_FOLDER_ADDEDUSER;
+ }
+ else if (type.compareTo("WP_FOLDER_REMOVEDUSER") == 0) {
+ return NotificationType.WP_FOLDER_REMOVEDUSER;
+ }
+ else if (type.compareTo("WP_ITEM_DELETE") == 0) {
+ return NotificationType.WP_ITEM_DELETE;
+ }
+ else if (type.compareTo("WP_ITEM_UPDATED") == 0) {
+ return NotificationType.WP_ITEM_UPDATED;
+ }
+ else if (type.compareTo("WP_ITEM_NEW") == 0) {
+ return NotificationType.WP_ITEM_NEW;
+ }
+ else if (type.compareTo("WP_ITEM_RENAMED") == 0) {
+ return NotificationType.WP_ITEM_RENAMED;
+ }
+ else if (type.compareTo("OWN_COMMENT") == 0) {
+ return NotificationType.OWN_COMMENT;
+ }
+ else if (type.compareTo("COMMENT") == 0) {
+ return NotificationType.COMMENT;
+ }
+ else if (type.compareTo("MENTION") == 0) {
+ return NotificationType.MENTION;
+ }
+ else if (type.compareTo("LIKE") == 0) {
+ return NotificationType.LIKE;
+ }
+ else if (type.compareTo("CALENDAR_ADDED_EVENT") == 0) {
+ return NotificationType.CALENDAR_ADDED_EVENT;
+ }
+ else if (type.compareTo("CALENDAR_UPDATED_EVENT") == 0) {
+ return NotificationType.CALENDAR_UPDATED_EVENT;
+ }
+ else if (type.compareTo("CALENDAR_DELETED_EVENT") == 0) {
+ return NotificationType.CALENDAR_DELETED_EVENT;
+ }
+ else if (type.compareTo("CALENDAR_ADDED_EVENT") == 0) {
+ return NotificationType.CALENDAR_ADDED_EVENT;
+ }
+ else if (type.compareTo("CALENDAR_UPDATED_EVENT") == 0) {
+ return NotificationType.CALENDAR_UPDATED_EVENT;
+ }
+ else if (type.compareTo("CALENDAR_DELETED_EVENT") == 0) {
+ return NotificationType.CALENDAR_DELETED_EVENT;
+ }
+ else if (type.compareTo("MESSAGE") == 0) {
+ return NotificationType.MESSAGE;
+ }
+ else if (type.compareTo("POST_ALERT") == 0) {
+ return NotificationType.POST_ALERT;
+ }
+ else if (type.compareTo("REQUEST_CONNECTION") == 0) {
+ return NotificationType.REQUEST_CONNECTION;
+ }
+ else if (type.compareTo("JOB_COMPLETED_NOK") == 0) {
+ return NotificationType.JOB_COMPLETED_NOK;
+ }
+ else if (type.compareTo("JOB_COMPLETED_OK") == 0) {
+ return NotificationType.JOB_COMPLETED_OK;
+ }
+ else if (type.compareTo("DOCUMENT_WORKFLOW_EDIT") == 0) {
+ return NotificationType.DOCUMENT_WORKFLOW_EDIT;
+ }
+ else if (type.compareTo("DOCUMENT_WORKFLOW_VIEW") == 0) {
+ return NotificationType.DOCUMENT_WORKFLOW_VIEW;
+ }
+ else if (type.compareTo("DOCUMENT_WORKFLOW_FORWARD_STEP_COMPLETED_OWNER") == 0) {
+ return NotificationType.DOCUMENT_WORKFLOW_FORWARD_STEP_COMPLETED_OWNER;
+ }
+ else if (type.compareTo("DOCUMENT_WORKFLOW_STEP_FORWARD_PEER") == 0) {
+ return NotificationType.DOCUMENT_WORKFLOW_STEP_FORWARD_PEER;
+ }
+ else if (type.compareTo("DOCUMENT_WORKFLOW_STEP_REQUEST_TASK") == 0) {
+ return NotificationType.DOCUMENT_WORKFLOW_STEP_REQUEST_TASK;
+ }
+ else if (type.compareTo("DOCUMENT_WORKFLOW_USER_FORWARD_TO_OWNER") == 0) {
+ return NotificationType.DOCUMENT_WORKFLOW_USER_FORWARD_TO_OWNER;
+ }
+ else if (type.compareTo("DOCUMENT_WORKFLOW_FIRST_STEP_REQUEST_INVOLVMENT") == 0) {
+ return NotificationType.DOCUMENT_WORKFLOW_FIRST_STEP_REQUEST_INVOLVMENT;
+ }
+ else if (type.compareTo("TDM_TAB_RESOURCE_SHARE") == 0) {
+ return NotificationType.TDM_TAB_RESOURCE_SHARE;
+ }
+ else if (type.compareTo("TDM_RULE_SHARE") == 0) {
+ return NotificationType.TDM_RULE_SHARE;
+ }
+ else if (type.compareTo("TDM_TEMPLATE_SHARE") == 0) {
+ return NotificationType.TDM_TEMPLATE_SHARE;
+ }
+ else if (type.compareTo("CAT_ITEM_SUBMITTED") == 0) {
+ return NotificationType.CAT_ITEM_SUBMITTED;
+ }
+ else if (type.compareTo("CAT_ITEM_REJECTED") == 0) {
+ return NotificationType.CAT_ITEM_REJECTED;
+ }
+ else if (type.compareTo("CAT_ITEM_PUBLISHED") == 0) {
+ return NotificationType.CAT_ITEM_PUBLISHED;
+ }
+ else if (type.compareTo("CAT_ITEM_UPDATED") == 0) {
+ return NotificationType.CAT_ITEM_UPDATED;
+ }
+ else if (type.compareTo("CAT_ITEM_DELETE") == 0) {
+ return NotificationType.CAT_ITEM_DELETE;
+ }
+ else if (type.compareTo("GENERIC") == 0) {
+ return NotificationType.GENERIC;
+ }
+
+ else
+ throw new NotificationTypeNotFoundException("The Notification Type was not recognized should be one of " + NotificationType.values() + " asked for: " + type);
+ }
+ /**
+ *
+ * @param time in milliseconds
+ * @return a Date object
+ */
+ private Date getDateFromTimeInMillis(String time) {
+ Long timeInMillis = Long.parseLong(time);
+ Calendar toSet = Calendar.getInstance();
+ toSet.setTimeInMillis(timeInMillis);
+ return toSet.getTime();
+ }
+ /**
+ * update the feed by incrementing or decrementing by (1) the CommentsNo
+ * used when adding or removing a comment to a feed
+ * @param toUpdate the feedid
+ * @param increment set true if you want to add 1, false to subtract 1.
+ */
+ private boolean updateFeedCommentsCount(Feed toUpdate, boolean increment) {
+ int newCount = 0;
+ try {
+ int current = Integer.parseInt(toUpdate.getCommentsNo());
+ newCount = increment ? current+1 : current-1;
+ }
+ catch (NumberFormatException e) {
+ _log.error("Comments Number found is not a number: " + toUpdate.getCommentsNo());
+ }
+ CqlSession session = conn.getKeyspaceSession();
+ //an entry in the feed CF
+ try {
+ session.execute(updatePostEntry(session, COMMENTS_NO).bind((long) newCount, UUID.fromString(toUpdate.getKey())));
+
+ } catch (Exception e) {
+ _log.error("CommentsNo update NOT OK ");
+
+ return false;
+ }
+ _log.debug("CommentsNo update OK to: " + newCount);
+ return true;
+ }
+
+ /**
+ * update the feed by incrementing or decrementing by (1) the LikesNo
+ * used when adding or removing a comment to a feed
+ * @param toUpdate the feedid
+ * @param increment set true if you want to add 1, false to subtract 1.
+ */
+ private boolean updateFeedLikesCount(Feed toUpdate, boolean increment) {
+ int newCount = 0;
+ try {
+ int current = Integer.parseInt(toUpdate.getLikesNo());
+ newCount = increment ? current+1 : current-1;
+ }
+ catch (NumberFormatException e) {
+ _log.error("Likes Number found is not a number: " + toUpdate.getLikesNo());
+ }
+ CqlSession session = conn.getKeyspaceSession();
+ //an entry in the feed CF
+ try {
+ session.execute(updatePostEntry(session, LIKES_NO).bind((long)newCount, UUID.fromString(toUpdate.getKey())));
+
+ } catch (Exception e) {
+ _log.error("LikesNo update NOT OK ");
+
+ return false;
+ }
+ _log.debug("LikesNo update OK to: " + newCount);
+ return true;
+ }
+
+ /**
+ * update the hashtag count by incrementing or decrementing it by (1)
+ * used when adding or removing a hashtag in a feed
+ * @param vreid the vreid
+ * @param hashtag the hashtag
+ * @param increment set true if you want to add 1, false to subtract 1.
+ */
+ private boolean updateVREHashtagCount(String vreid, String hashtag, boolean increment) {
+ Map vreHashtags = getVREHashtagsWithOccurrence(vreid);
+ //if the hashtag not yet exist
+ int newCount = 0;
+
+ if (!vreHashtags.containsKey(hashtag)) {
+ newCount = 1;
+ }
+ else {
+ try {
+ int current = vreHashtags.get(hashtag);
+ newCount = increment ? current+1 : current-1;
+ }
+ catch (NumberFormatException e) {
+ _log.error("Hashtag Number found is not a number: " + newCount);
+ }
+ }
+ _log.debug("Updating counter for " + hashtag + " to " + newCount);
+ CqlSession session = conn.getKeyspaceSession();
+ BoundStatement stmt;
+
+ if (existRecordbyCompId(session, HASHTAG, VRE_ID, hashtag, vreid, HASHTAGS_COUNTER)){
+ stmt = session.prepare(QueryBuilder.update(HASHTAGS_COUNTER)
+ .setColumn(COUNT, QueryBuilder.bindMarker())
+ .whereColumn(HASHTAG).isEqualTo(QueryBuilder.bindMarker())
+ .whereColumn(VRE_ID).isEqualTo(QueryBuilder.bindMarker())
+ .build()).bind((long)newCount, hashtag, vreid);
+ }
+ else{
+ stmt = createNewUHashtagCounterEntry(session).bind(vreid, hashtag, (long)newCount);
+ }
+ BatchStatement writeBatch = getBatch().add(stmt);
+ try {
+ session.execute(writeBatch);
+
+ } catch (Exception e) {
+ _log.error("Hashtag Count update NOT OK ");
+
+ return false;
+ }
+ _log.debug("Hashtag Count update OK to: " + newCount);
+ return true;
+ }
+ /**
+ * verify an email address
+ * @param email
+ * @return true or false
+ */
+ private boolean verifyEmail(String email) {
+ boolean isValid = false;
+ try {
+ InternetAddress internetAddress = new InternetAddress(email);
+ internetAddress.validate();
+ isValid = true;
+ } catch (AddressException e) {
+ _log.error("Validation Exception Occurred for email: " + email);
+ }
+ return isValid;
+ }
+
+
+ @Override
+ public List getAllVREIds(){
+
+ Set ids = new HashSet<>();
+
+ CqlSession session = conn.getKeyspaceSession();
+ ResultSet result = null;
+ PreparedStatement stmtFind = session.prepare(QueryBuilder
+ .selectFrom(VRE_TIMELINE_POSTS).column(VRE_ID).all()
+ .build());
+ try {
+ result = session.execute(stmtFind.bind());
+
+ } catch (Exception e){
+ e.printStackTrace();
+
+ }
+
+ Listrows=result.all();
+ for (Row row : rows) {
+ ids.add(row.getString(VRE_ID));
+ }
+ List toReturn = new ArrayList<>();
+ toReturn.addAll(ids);
+ _log.debug("VRE ids are " + ids);
+
+ return toReturn;
+ }
+}
diff --git a/src/main/java/org/gcube/social_networking/ResourceInitializer.java b/src/main/java/org/gcube/social_networking/ResourceInitializer.java
deleted file mode 100644
index ab21eb5..0000000
--- a/src/main/java/org/gcube/social_networking/ResourceInitializer.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package org.gcube.social_networking;
-
-import javax.ws.rs.ApplicationPath;
-
-import org.gcube.smartgears.annotations.ManagedBy;
-import org.gcube.social_networking.rest.HelloWorld;
-import org.glassfish.jersey.server.ResourceConfig;
-
-/**
- * @author Luca Frosini (ISTI - CNR)
- */
-@ApplicationPath("/")
-@ManagedBy(HelloWorldInitializator.class)
-public class ResourceInitializer extends ResourceConfig {
-
- public ResourceInitializer() {
- packages(HelloWorld.class.getPackage().toString());
- }
-
-}
diff --git a/src/main/java/org/gcube/social_networking/SocialService.java b/src/main/java/org/gcube/social_networking/SocialService.java
new file mode 100644
index 0000000..e7fcdcc
--- /dev/null
+++ b/src/main/java/org/gcube/social_networking/SocialService.java
@@ -0,0 +1,25 @@
+package org.gcube.social_networking;
+
+import javax.ws.rs.Path;
+import javax.ws.rs.core.Application;
+import org.gcube.social_networking.rest.HelloWorld;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashSet;
+import java.util.Set;
+
+@Path("social-service")
+public class SocialService extends Application {
+ private static Logger logger = LoggerFactory.getLogger(SocialService.class);
+
+ @Override
+ public Set> getClasses() {
+ logger.info("/social-service/ here");
+ final Set> classes = new HashSet>();
+ // register resources and features
+ classes.add(HelloWorld.class);
+ return classes;
+ }
+
+}
diff --git a/src/main/java/org/gcube/social_networking/HelloWorldInitializator.java b/src/main/java/org/gcube/social_networking/SocialServiceApplicationManager.java
similarity index 59%
rename from src/main/java/org/gcube/social_networking/HelloWorldInitializator.java
rename to src/main/java/org/gcube/social_networking/SocialServiceApplicationManager.java
index 5e0ddda..8cd921a 100644
--- a/src/main/java/org/gcube/social_networking/HelloWorldInitializator.java
+++ b/src/main/java/org/gcube/social_networking/SocialServiceApplicationManager.java
@@ -1,6 +1,6 @@
package org.gcube.social_networking;
-import org.gcube.common.authorization.utils.manager.SecretManagerProvider;
+import org.gcube.common.security.providers.SecretManagerProvider;
import org.gcube.smartgears.ApplicationManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -8,12 +8,12 @@ import org.slf4j.LoggerFactory;
/**
* @author Luca Frosini (ISTI - CNR)
*/
-public class HelloWorldInitializator implements ApplicationManager {
+public class SocialServiceApplicationManager implements ApplicationManager {
/**
* Logger
*/
- private static Logger logger = LoggerFactory.getLogger(HelloWorldInitializator.class);
+ private static Logger logger = LoggerFactory.getLogger(SocialServiceApplicationManager.class);
public static boolean initialised;
@@ -22,24 +22,25 @@ public class HelloWorldInitializator implements ApplicationManager {
*/
@Override
public synchronized void onInit() {
+
+ logger.info("Starting social service");
+ try{
+ String context = SecretManagerProvider.instance.get().getContext();
+ logger.info(
+ "\n-------------------------------------------------------\n"
+ + "Social Service is Starting on context {}\n"
+ + "-------------------------------------------------------",
+ context);
+ }catch (Throwable e) {
+ logger.error("unexpected error initiliazing storagehub",e);
+ }
+
- String context = SecretManagerProvider.instance.get().getContext();
-
- logger.trace(
- "\n-------------------------------------------------------\n"
- + "Hello World Service is Starting on context {}\n"
- + "-------------------------------------------------------",
- context);
+
// ApplicationContext applicationContext = ContextProvider.get();
// String helloWorldEServiceID = applicationContext.id();
-
- logger.trace(
- "\n-------------------------------------------------------\n"
- + "Hello World Service Started Successfully on context {}\n"
- + "-------------------------------------------------------",
- context);
-
+
}
/**
diff --git a/src/main/java/org/gcube/social_networking/caches/CachesManager.java b/src/main/java/org/gcube/social_networking/caches/CachesManager.java
new file mode 100644
index 0000000..6fe5f80
--- /dev/null
+++ b/src/main/java/org/gcube/social_networking/caches/CachesManager.java
@@ -0,0 +1,34 @@
+package org.gcube.social_networking.caches;
+
+import net.sf.ehcache.CacheManager;
+import net.sf.ehcache.Ehcache;
+
+/**
+ * Handle caches via Ehcache
+ * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
+ */
+public class CachesManager {
+
+ private static CacheManager cacheManager;
+ public static final CachesManager singleton = new CachesManager();
+
+ // the following caches are declared within the ehcache.xml (no default is available)
+ public static final String SOCIAL_NETWORKING_SITES_CACHE = "social_networking_site_cache";
+ public static final String USERS_CACHE = "users_cache";
+ public static final String GROUPS_CACHE = "groups_cache";
+
+ private CachesManager(){
+ cacheManager = CacheManager.newInstance();
+ }
+
+ public static Ehcache getCache(String name){
+ return cacheManager.getEhcache(name);
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ super.finalize();
+ cacheManager.shutdown();
+ }
+
+}
diff --git a/src/main/java/org/gcube/social_networking/caches/GroupsCache.java b/src/main/java/org/gcube/social_networking/caches/GroupsCache.java
new file mode 100644
index 0000000..def0a52
--- /dev/null
+++ b/src/main/java/org/gcube/social_networking/caches/GroupsCache.java
@@ -0,0 +1,54 @@
+package org.gcube.social_networking.caches;
+
+import net.sf.ehcache.Ehcache;
+import net.sf.ehcache.Element;
+
+import org.gcube.vomanagement.usermanagement.model.GCubeGroup;
+import org.slf4j.LoggerFactory;
+
+public class GroupsCache {
+ private static final org.slf4j.Logger logger = LoggerFactory.getLogger(GroupsCache.class);
+ private static GroupsCache singleton = new GroupsCache();
+
+ /**
+ * Private constructor: build the cache
+ * @return
+ */
+ private GroupsCache(){
+
+ logger.debug("Building cache");
+ CachesManager.getCache(CachesManager.GROUPS_CACHE);
+
+ }
+
+ /**
+ * Get the singleton object
+ */
+ public static GroupsCache getSingleton() {
+ return singleton;
+ }
+
+ /**
+ * Retrieve an entry
+ * @param groupId
+ * @return user associated to the user
+ */
+ public GCubeGroup getGroup(long groupId){
+ Ehcache groupsCache = CachesManager.getCache(CachesManager.GROUPS_CACHE);
+ if(groupsCache.get(groupId) != null)
+ return (GCubeGroup) groupsCache.get(groupId).getObjectValue();
+ else
+ return null;
+ }
+
+ /**
+ * Save an entry into the cache
+ * @param id
+ * @param group
+ */
+ public void pushEntry(long id, GCubeGroup group){
+ Ehcache groupsCache = CachesManager.getCache(CachesManager.GROUPS_CACHE);
+ groupsCache.put(new Element(id, group));
+ }
+
+}
diff --git a/src/main/java/org/gcube/social_networking/caches/SocialNetworkingSiteFinder.java b/src/main/java/org/gcube/social_networking/caches/SocialNetworkingSiteFinder.java
new file mode 100644
index 0000000..61665ce
--- /dev/null
+++ b/src/main/java/org/gcube/social_networking/caches/SocialNetworkingSiteFinder.java
@@ -0,0 +1,249 @@
+package org.gcube.social_networking.caches;
+
+import static org.gcube.resources.discovery.icclient.ICFactory.clientFor;
+import static org.gcube.resources.discovery.icclient.ICFactory.queryFor;
+
+import java.io.InputStream;
+import java.util.List;
+import java.util.Properties;
+
+import net.sf.ehcache.Ehcache;
+import net.sf.ehcache.Element;
+
+import org.gcube.applicationsupportlayer.social.shared.SocialNetworkingSite;
+import org.gcube.common.portal.GCubePortalConstants;
+import org.gcube.common.resources.gcore.ServiceEndpoint;
+import org.gcube.common.scope.api.ScopeProvider;
+import org.gcube.portal.social.networking.liferay.ws.GroupManagerWSBuilder;
+import org.gcube.resources.discovery.client.api.DiscoveryClient;
+import org.gcube.resources.discovery.client.queries.api.SimpleQuery;
+import org.gcube.smartgears.ContextProvider;
+import org.gcube.smartgears.context.application.ApplicationContext;
+import org.gcube.vomanagement.usermanagement.GroupManager;
+import org.gcube.vomanagement.usermanagement.model.GCubeGroup;
+import org.gcube.vomanagement.usermanagement.model.VirtualGroup;
+import org.slf4j.LoggerFactory;
+
+/**
+ * When a notification needs to be sent, this class offers utility to discover (starting from the scope)
+ * the site information needed to build up the SocialNetworkingSite object (which, for instance, contains the
+ * portal email).
+ * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
+ */
+public class SocialNetworkingSiteFinder {
+
+ // Logger
+ private static final org.slf4j.Logger logger = LoggerFactory.getLogger(SocialNetworkingSiteFinder.class);
+
+ private static final String EMAIL_SENDER_SITE_CUSTOM_FIELD = "Emailsender";
+ private static final String CATEGORY = "Portal";
+
+ // these properties could be overwritten by the ones read from config.properties
+ private static String PROD_FALLBACK_GATEWAY = "D4Science.org Gateway";
+ private static String DEV_FALLBACK_GATEWAY = "gCube Snapshot Gateway";
+ private static String PREPROD_FALLBACK_GATEWAY = "D4Science Preproduction Gateway";
+
+ /**
+ * Singleton object
+ */
+ private static SocialNetworkingSiteFinder singleton = new SocialNetworkingSiteFinder();
+
+ /**
+ * Build the singleton instance
+ */
+ private SocialNetworkingSiteFinder(){
+
+ // read fallback properties
+ try{
+ logger.debug("Trying to read config.properties");
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ InputStream input = classLoader.getResourceAsStream("config.properties");
+ Properties properties = new Properties();
+ properties.load(input);
+ PROD_FALLBACK_GATEWAY = properties.getProperty("PROD_FALLBACK_GATEWAY");
+ DEV_FALLBACK_GATEWAY = properties.getProperty("DEV_FALLBACK_GATEWAY");
+ PREPROD_FALLBACK_GATEWAY = properties.getProperty("PREPROD_FALLBACK_GATEWAY");
+ }catch(Exception e){
+ logger.warn("Failed to read config.properties...", e);
+ }
+
+ }
+
+ /**
+ * Retrieve the singleton instance
+ */
+ public static SocialNetworkingSiteFinder getInstance(){
+
+ return singleton;
+
+ }
+
+ /**
+ * Retrieve the SocialNetworkingSite given the scope
+ * @param scope
+ * @return
+ */
+ public static SocialNetworkingSite getSocialNetworkingSiteFromScope(String scope){
+
+ Ehcache socialSitesCache = CachesManager.getCache(CachesManager.SOCIAL_NETWORKING_SITES_CACHE);
+
+ if(scope == null || scope.isEmpty())
+ throw new IllegalArgumentException("Scope cannot be null/empty");
+
+ if(socialSitesCache != null && socialSitesCache.get(scope) != null)
+ return (SocialNetworkingSite) socialSitesCache.get(scope).getObjectValue();
+ else{
+ SocialNetworkingSite site = discoverSite(scope);
+ if(socialSitesCache != null && site != null)
+ socialSitesCache.put(new Element(scope, site));
+ return site;
+ }
+
+ }
+
+ /**
+ * Discover the site for this scope
+ * @param scope
+ * @return
+ */
+ private static SocialNetworkingSite discoverSite(String scope) {
+
+ try{
+
+ logger.info("Requested site for scope " + scope);
+ GroupManager groupManager = GroupManagerWSBuilder.getInstance().getGroupManager();
+ long groupId = groupManager.getGroupIdFromInfrastructureScope(scope);
+
+ GCubeGroup matchingGateway = null;
+
+ if(groupManager.isVRE(groupId)){
+
+ // get the Virtual groups for the groupid related to the scope
+
+ List virtualGroupsOfGroup = groupManager.getVirtualGroups(groupId);
+
+ if(virtualGroupsOfGroup == null || virtualGroupsOfGroup.isEmpty())
+ throw new Exception("It seems that the VRE is not linked to any VirtualGroups");
+
+ // get the gateways
+ List gateways = groupManager.getGateways();
+
+ if(gateways == null || gateways.isEmpty())
+ throw new Exception("It seems there is no gateway here!");
+
+ logger.info("Retrieved Gateways are " + gateways);
+
+ // now, retrieve the virtual groups for each gateway and stop when a VG matches with one of the group
+ // then, it is the gateway of interest
+ ext_loop: for (GCubeGroup gateway : gateways) {
+ List gatewayVirtualGroups = groupManager.getVirtualGroups(gateway.getGroupId());
+ if(gatewayVirtualGroups != null && !gatewayVirtualGroups.isEmpty()){
+ for (VirtualGroup gatewayVirtualGroup : gatewayVirtualGroups) {
+ if(virtualGroupsOfGroup.contains(gatewayVirtualGroup)){
+ logger.debug("Matching gateway for scope " + scope + " is " + gateway);
+ matchingGateway = gateway;
+ break ext_loop;
+ }
+ }
+ }
+ }
+
+ }else{
+
+ List gateways = groupManager.getGateways();
+
+ // vo and root vo cases are treated separately: in production environment services.d4science.org is used, instead
+ // in dev next.d4science.org is used TODO better way...
+ ApplicationContext ctx = ContextProvider.get(); // get this info from SmartGears
+ String rootContext = "/"+ctx.container().configuration().infrastructure();
+ String matchingGatewayName = null;
+ if(isDevOrPreprod(rootContext)){
+ matchingGatewayName = DEV_FALLBACK_GATEWAY;
+ }else{
+ matchingGatewayName = PROD_FALLBACK_GATEWAY;
+ }
+
+ // find the matching one among the gateways
+ for (GCubeGroup gateway : gateways) {
+ if(gateway.getGroupName().equals(matchingGatewayName)){
+ matchingGateway = gateway;
+ break;
+ }
+ }
+
+ if(matchingGateway == null && isDevOrPreprod(rootContext)){
+
+ logger.warn("Checking if it is the preprod environment");
+ matchingGatewayName = PREPROD_FALLBACK_GATEWAY;
+ // find the matching one among the gateways
+ for (GCubeGroup gateway : gateways) {
+ if(gateway.getGroupName().equals(matchingGatewayName)){
+ matchingGateway = gateway;
+ break;
+ }
+ }
+
+ }
+
+ }
+
+ if(matchingGateway == null){
+ logger.warn("There is no gateway for such scope. Returning null");
+ return null;
+ }else{
+ String siteName = matchingGateway.getGroupName();
+ String emailSender = (String)groupManager.readCustomAttr(matchingGateway.getGroupId(), EMAIL_SENDER_SITE_CUSTOM_FIELD);
+ emailSender = emailSender.replace("\"", ""); //this is because otherwise it would contains double quotes and postfix would use it as first part before @ e.g. senderEmail="aginfra@d4science.org"@d4science.org
+ String siteLandingPagePath = GCubePortalConstants.PREFIX_GROUP_URL + matchingGateway.getFriendlyURL();
+ String siteUrl = discoverHostOfServiceEndpoint(siteName);
+ SocialNetworkingSite site = new SocialNetworkingSite(siteName, emailSender, siteUrl, siteLandingPagePath);
+ logger.info("Site is " + site);
+ return site;
+ }
+
+ }catch(Exception e){
+ logger.error("Failed to determine the SocialNetworkingSite for scope " + scope, e);
+ }
+
+ return null;
+ }
+
+ private static boolean isDevOrPreprod(String rootContext) {
+ return (rootContext.equals("/gcube") || rootContext.equals("/pred4s"));
+ }
+
+ /**
+ * Retrieve endpoint host from IS for this gateway
+ * @return the host for the gateway
+ * @throws Exception
+ */
+ private static String discoverHostOfServiceEndpoint(String gatewayName){
+
+ String currentScope = ScopeProvider.instance.get();
+ ApplicationContext ctx = ContextProvider.get(); // get this info from SmartGears
+ ScopeProvider.instance.set("/"+ctx.container().configuration().infrastructure());
+ String host = null;
+ try{
+
+ SimpleQuery query = queryFor(ServiceEndpoint.class);
+ query.addCondition("$resource/Profile/Name/text() eq '"+ gatewayName +"'");
+ query.addCondition("$resource/Profile/Category/text() eq '"+ CATEGORY +"'");
+ DiscoveryClient client = clientFor(ServiceEndpoint.class);
+ List toReturn = client.submit(query);
+ for (ServiceEndpoint serviceEndpoint : toReturn) {
+ host = "https://" + serviceEndpoint.profile().runtime().hostedOn();
+ logger.info("Gateway host is " + host);
+ break;
+ }
+
+ }catch(Exception e){
+ logger.error("Error while retrieving host for the gateway " + gatewayName);
+ }finally{
+ ScopeProvider.instance.set(currentScope);
+ }
+
+ return host;
+
+ }
+
+}
diff --git a/src/main/java/org/gcube/social_networking/caches/UsersCache.java b/src/main/java/org/gcube/social_networking/caches/UsersCache.java
new file mode 100644
index 0000000..5c9de82
--- /dev/null
+++ b/src/main/java/org/gcube/social_networking/caches/UsersCache.java
@@ -0,0 +1,83 @@
+package org.gcube.social_networking.caches;
+
+import java.util.List;
+
+import net.sf.ehcache.Ehcache;
+import net.sf.ehcache.Element;
+
+import org.gcube.portal.social.networking.liferay.ws.GroupManagerWSBuilder;
+import org.gcube.portal.social.networking.liferay.ws.UserManagerWSBuilder;
+import org.gcube.smartgears.ContextProvider;
+import org.gcube.smartgears.context.application.ApplicationContext;
+import org.gcube.vomanagement.usermanagement.GroupManager;
+import org.gcube.vomanagement.usermanagement.UserManager;
+import org.gcube.vomanagement.usermanagement.model.GCubeUser;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This cache will store GCubeUser of the users of the infrastructure as couples {user-id, user screename}
+ * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
+ */
+public class UsersCache{
+
+ private static final org.slf4j.Logger logger = LoggerFactory.getLogger(UsersCache.class);
+ private static UsersCache singleton = new UsersCache();
+
+ /**
+ * Private constructor: build the cache
+ * @return
+ */
+ private UsersCache(){
+
+ // create a thread to build the cache
+ new Thread(){
+ public void run() {
+ try{
+ logger.debug("Fetching users and putting them into cache");
+ Ehcache usersCache = CachesManager.getCache(CachesManager.USERS_CACHE);
+ GroupManager groupManager = GroupManagerWSBuilder.getInstance().getGroupManager();
+ UserManager userManager = UserManagerWSBuilder.getInstance().getUserManager();
+ ApplicationContext ctx = ContextProvider.get(); // get this info from SmartGears
+ List users = userManager.listUsersByGroup(groupManager.getGroupIdFromInfrastructureScope("/"+ctx.container().configuration().infrastructure()));
+ for (GCubeUser gCubeUser : users) {
+ usersCache.put(new Element(gCubeUser.getUserId(), gCubeUser));
+ }
+ }catch(Exception e){
+ logger.error("Unable to retrieve user's usernames. Other users will be discovered later on", e);
+ }
+ }
+ }.start();
+
+ }
+
+ /**
+ * Get the singleton object
+ */
+ public static UsersCache getSingleton() {
+ return singleton;
+ }
+
+ /**
+ * Retrieve an entry
+ * @param userId
+ * @return user associated to the user
+ */
+ public GCubeUser getUser(long userId){
+ Ehcache usersCache = CachesManager.getCache(CachesManager.USERS_CACHE);
+ if(usersCache.get(userId) != null)
+ return (GCubeUser) usersCache.get(userId).getObjectValue();
+ else
+ return null;
+ }
+
+ /**
+ * Save an entry into the cache
+ * @param id
+ * @param user
+ */
+ public void pushEntry(long id, GCubeUser user){
+ Ehcache usersCache = CachesManager.getCache(CachesManager.USERS_CACHE);
+ usersCache.put(new Element(id, user));
+ }
+
+}
diff --git a/src/main/java/org/gcube/social_networking/liferay/ws/GroupManagerWSBuilder.java b/src/main/java/org/gcube/social_networking/liferay/ws/GroupManagerWSBuilder.java
new file mode 100644
index 0000000..7906fc1
--- /dev/null
+++ b/src/main/java/org/gcube/social_networking/liferay/ws/GroupManagerWSBuilder.java
@@ -0,0 +1,50 @@
+package org.gcube.social_networking.liferay.ws;
+
+import org.gcube.vomanagement.usermanagement.GroupManager;
+import org.gcube.vomanagement.usermanagement.impl.ws.LiferayWSGroupManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Class that builds a (singleton) GroupManagerWS object.
+ * @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
+ */
+public class GroupManagerWSBuilder {
+
+ private static final Logger logger = LoggerFactory.getLogger(GroupManagerWSBuilder.class);
+ private static GroupManagerWSBuilder singleton = new GroupManagerWSBuilder();
+ private static GroupManager groupManagerWs;
+
+ private GroupManagerWSBuilder(){
+
+ logger.debug("Building GroupManager please wait");
+
+ try{
+ groupManagerWs = new LiferayWSGroupManager(
+ LiferayJSONWsCredentials.getSingleton().getUser(),
+ LiferayJSONWsCredentials.getSingleton().getPassword(),
+ LiferayJSONWsCredentials.getSingleton().getHost(),
+ LiferayJSONWsCredentials.getSingleton().getSchema(),
+ LiferayJSONWsCredentials.getSingleton().getPort());
+ }catch(Exception e){
+ logger.error("Failed to build the GroupManager. ", e);
+ return;
+ }
+
+ logger.debug("GroupManager instance built");
+
+ }
+
+ /**
+ * Get the user manager instance
+ * @return
+ */
+ public GroupManager getGroupManager(){
+ return groupManagerWs;
+ }
+
+ public static GroupManagerWSBuilder getInstance(){
+ return singleton;
+ }
+
+}
diff --git a/src/main/java/org/gcube/social_networking/liferay/ws/KeycloakAPICredentials.java b/src/main/java/org/gcube/social_networking/liferay/ws/KeycloakAPICredentials.java
new file mode 100644
index 0000000..887b520
--- /dev/null
+++ b/src/main/java/org/gcube/social_networking/liferay/ws/KeycloakAPICredentials.java
@@ -0,0 +1,143 @@
+package org.gcube.social_networking.liferay.ws;
+
+import static org.gcube.resources.discovery.icclient.ICFactory.clientFor;
+import static org.gcube.resources.discovery.icclient.ICFactory.queryFor;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.gcube.common.encryption.encrypter.StringEncrypter;
+import org.gcube.common.resources.gcore.ServiceEndpoint;
+import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint;
+import org.gcube.common.resources.gcore.ServiceEndpoint.Property;
+import org.gcube.common.scope.api.ScopeProvider;
+import org.gcube.resources.discovery.client.api.DiscoveryClient;
+import org.gcube.resources.discovery.client.queries.api.SimpleQuery;
+import org.gcube.smartgears.ContextProvider;
+import org.gcube.smartgears.context.application.ApplicationContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+
+public class KeycloakAPICredentials {
+
+ private static final Logger logger = LoggerFactory.getLogger(KeycloakAPICredentials.class);
+
+ // the singleton obj
+ private static KeycloakAPICredentials singleton = new KeycloakAPICredentials();
+
+ // properties that it contains
+ private String keycloakURL;
+ private String realm;
+ private String clientid;
+ private String password;
+
+
+ // Service endpoint properties
+ private final static String RUNTIME_RESOURCE_NAME = "IAM";
+ private final static String CATEGORY = "Service";
+
+ /**
+ * Private constructor
+ */
+ private KeycloakAPICredentials() {
+ logger.debug("Building KeycloakAPICredentials object");
+
+ lookupPropertiesFromIs();
+ logger.debug("KeycloakAPICredentials object built");
+ }
+
+ /**
+ * Read the properties from the infrastructure
+ */
+ private void lookupPropertiesFromIs() {
+
+ logger.debug("Starting creating KeycloakAPICredentials");
+
+ String oldContext = ScopeProvider.instance.get();
+ ApplicationContext ctx = ContextProvider.get(); // get this info from SmartGears
+ ScopeProvider.instance.set("/"+ctx.container().configuration().infrastructure());
+ logger.debug("Discovering liferay user's credentials in context " + ctx.container().configuration().infrastructure());
+
+ try{
+ List resources = getConfigurationFromIS();
+ if (resources.size() == 0){
+ logger.error("There is no Runtime Resource having name " + RUNTIME_RESOURCE_NAME +" and Category " + CATEGORY + " in this scope.");
+ throw new Exception("There is no Runtime Resource having name " + RUNTIME_RESOURCE_NAME +" and Category " + CATEGORY + " in this scope.");
+ }
+ else {
+ for (ServiceEndpoint res : resources) {
+ Iterator accessPointIterator = res.profile().accessPoints().iterator();
+ while (accessPointIterator.hasNext()) {
+ ServiceEndpoint.AccessPoint accessPoint = (ServiceEndpoint.AccessPoint) accessPointIterator
+ .next();
+
+ if(accessPoint.name().equals("d4science")){
+ keycloakURL = accessPoint.address();
+ realm = accessPoint.name();
+ clientid = accessPoint.username();
+ password = StringEncrypter.getEncrypter().decrypt(accessPoint.password());
+ logger.info("Found accesspoint URL = " + keycloakURL);
+ }
+ }
+ }
+ }
+ }catch(Exception e){
+ logger.error("Unable to retrieve such service endpoint information!", e);
+ return;
+ }finally{
+ if(oldContext != null)
+ ScopeProvider.instance.set(oldContext);
+ }
+
+ logger.debug("Bean built " + toString());
+ }
+
+ /**
+ * Retrieve endpoints information from IS for DB
+ * @return list of endpoints for ckan database
+ * @throws Exception
+ */
+ private List getConfigurationFromIS() throws Exception{
+
+ SimpleQuery query = queryFor(ServiceEndpoint.class);
+ query.addCondition("$resource/Profile/Name/text() eq '"+ RUNTIME_RESOURCE_NAME +"'");
+ query.addCondition("$resource/Profile/Category/text() eq '"+ CATEGORY +"'");
+ DiscoveryClient