Java tutorial
/* * Copyright (C) 2003-2015 eXo Platform SAS. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see<http://www.gnu.org/licenses/>. */ package org.exoplatform.social.addons.storage; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.persistence.LockModeType; import org.apache.commons.lang.ArrayUtils; import org.exoplatform.commons.api.persistence.ExoTransactional; import org.exoplatform.commons.persistence.impl.EntityManagerHolder; import org.exoplatform.commons.utils.PropertyManager; import org.exoplatform.container.component.BaseComponentPlugin; import org.exoplatform.services.log.ExoLogger; import org.exoplatform.services.log.Log; import org.exoplatform.social.addons.storage.dao.ActivityDAO; import org.exoplatform.social.addons.storage.dao.CommentDAO; import org.exoplatform.social.addons.storage.dao.ConnectionDAO; import org.exoplatform.social.addons.storage.dao.StreamItemDAO; import org.exoplatform.social.addons.storage.entity.ActivityEntity; import org.exoplatform.social.addons.storage.entity.CommentEntity; import org.exoplatform.social.addons.storage.entity.StreamItemEntity; import org.exoplatform.social.addons.storage.entity.StreamType; import org.exoplatform.social.core.ActivityProcessor; import org.exoplatform.social.core.activity.filter.ActivityFilter; import org.exoplatform.social.core.activity.filter.ActivityUpdateFilter; import org.exoplatform.social.core.activity.model.ActivityStream; import org.exoplatform.social.core.activity.model.ActivityStreamImpl; import org.exoplatform.social.core.activity.model.ExoSocialActivity; import org.exoplatform.social.core.activity.model.ExoSocialActivityImpl; import org.exoplatform.social.core.identity.model.Identity; import org.exoplatform.social.core.identity.provider.OrganizationIdentityProvider; import org.exoplatform.social.core.identity.provider.SpaceIdentityProvider; import org.exoplatform.social.core.storage.ActivityStorageException; import org.exoplatform.social.core.storage.ActivityStorageException.Type; import org.exoplatform.social.core.storage.api.IdentityStorage; import org.exoplatform.social.core.storage.api.RelationshipStorage; import org.exoplatform.social.core.storage.api.SpaceStorage; import org.exoplatform.social.core.storage.impl.ActivityBuilderWhere; import org.exoplatform.social.core.storage.impl.ActivityStorageImpl; public class RDBMSActivityStorageImpl extends ActivityStorageImpl { private static final Log LOG = ExoLogger.getLogger(RDBMSActivityStorageImpl.class); private final ActivityDAO activityDAO; private final CommentDAO commentDAO; private final StreamItemDAO streamItemDAO; private IdentityStorage identityStorage; private final SpaceStorage spaceStorage; private final SortedSet<ActivityProcessor> activityProcessors; private static final Pattern MENTION_PATTERN = Pattern.compile("@([^\\s]+)|@([^\\s]+)$"); public final static String COMMENT_PREFIX = "comment"; private final static int TITLE_MAX_LENGTH = 1000; public RDBMSActivityStorageImpl(RelationshipStorage relationshipStorage, IdentityStorage identityStorage, SpaceStorage spaceStorage, ActivityDAO activityDAO, CommentDAO commentDAO, ConnectionDAO connectionDAO, StreamItemDAO streamItemDAO) { super(relationshipStorage, identityStorage, spaceStorage); // this.identityStorage = identityStorage; this.activityProcessors = new TreeSet<ActivityProcessor>(processorComparator()); this.activityDAO = activityDAO; this.commentDAO = commentDAO; this.streamItemDAO = streamItemDAO; this.spaceStorage = spaceStorage; } private static Comparator<ActivityProcessor> processorComparator() { return new Comparator<ActivityProcessor>() { public int compare(ActivityProcessor p1, ActivityProcessor p2) { if (p1 == null || p2 == null) { throw new IllegalArgumentException("Cannot compare null ActivityProcessor"); } return p1.getPriority() - p2.getPriority(); } }; } @Override public void addPlugin(BaseComponentPlugin baseComponent) { super.addPlugin(baseComponent); } @Override public void setInjectStreams(boolean mustInject) { super.setInjectStreams(mustInject); } private ExoSocialActivity convertActivityEntityToActivity(ActivityEntity activityEntity) { if (activityEntity == null) return null; // ExoSocialActivity activity = new ExoSocialActivityImpl(activityEntity.getPosterId(), activityEntity.getType(), activityEntity.getTitle(), activityEntity.getBody(), false); activity.setId(String.valueOf(activityEntity.getId())); activity.setLikeIdentityIds(activityEntity.getLikerIds().toArray(new String[] {})); activity.setTemplateParams(activityEntity.getTemplateParams() != null ? new LinkedHashMap<String, String>(activityEntity.getTemplateParams()) : new HashMap<String, String>()); String ownerIdentityId = activityEntity.getOwnerId(); ActivityStream stream = new ActivityStreamImpl(); Identity owner = identityStorage.findIdentityById(ownerIdentityId); stream.setType(owner.getProviderId()); stream.setPrettyId(owner.getRemoteId()); stream.setId(owner.getId()); // activity.setActivityStream(stream); activity.setStreamOwner(owner.getRemoteId()); activity.setPosterId(activityEntity.getPosterId()); // activity.isLocked(activityEntity.getLocked()); activity.isHidden(activityEntity.getHidden()); activity.setTitleId(activityEntity.getTitleId()); activity.setPostedTime(activityEntity.getPosted()); activity.setUpdated(activityEntity.getUpdatedDate().getTime()); // List<String> commentIds = new ArrayList<String>(); List<String> replyToIds = new ArrayList<String>(); List<CommentEntity> comments = activityEntity.getComments() != null ? activityEntity.getComments() : new ArrayList<CommentEntity>(); for (CommentEntity comment : comments) { if (!commentIds.contains(comment.getPosterId())) { commentIds.add(comment.getPosterId()); } replyToIds.add(getExoCommentID(comment.getId())); } activity.setCommentedIds(commentIds.toArray(new String[commentIds.size()])); activity.setReplyToId(replyToIds.toArray(new String[replyToIds.size()])); activity.setMentionedIds( activityEntity.getMentionerIds().toArray(new String[activityEntity.getMentionerIds().size()])); // // processActivity(activity); return activity; } private ActivityEntity convertActivityToActivityEntity(ExoSocialActivity activity, String ownerId) { ActivityEntity activityEntity = new ActivityEntity(); if (activity.getId() != null) { activityEntity = activityDAO.find(Long.valueOf(activity.getId())); } if (needTruncated(activity.getTitle())) { activityEntity.setTitle(activity.getTitle().substring(0, TITLE_MAX_LENGTH)); } else { activityEntity.setTitle(activity.getTitle()); } activityEntity.setTitleId(activity.getTitleId()); activityEntity.setType(activity.getType()); activityEntity.setBody(activity.getBody()); if (ownerId != null) { activityEntity.setPosterId(activity.getUserId() != null ? activity.getUserId() : ownerId); } if (activity.getLikeIdentityIds() != null) { activityEntity.setLikerIds(new HashSet<String>(Arrays.asList(activity.getLikeIdentityIds()))); } Map<String, String> params = activity.getTemplateParams(); if (params != null) { for (Entry<String, String> param : params.entrySet()) { String key = param.getKey(); String value = param.getValue(); if (needTruncated(value)) { value = value.substring(0, TITLE_MAX_LENGTH); params.put(key, value); } } activityEntity.setTemplateParams(params); } // if (activity.getPostedTime() == null || activity.getPostedTime() <= 0) { activity.setPostedTime(System.currentTimeMillis()); } activityEntity.setPosted(activity.getPostedTime()); activityEntity.setLocked(activity.isLocked()); activityEntity.setHidden(activity.isHidden()); activityEntity.setUpdatedDate(activity.getUpdated()); activityEntity.setMentionerIds(new HashSet<String>(Arrays.asList(processMentions(activity.getTitle())))); // return activityEntity; } private boolean needTruncated(String value) { if (value != null && value.length() > TITLE_MAX_LENGTH) { LOG.warn("Input value too long - the length is greater than 1000 charaters- so it will be truncated."); return true; } return false; } private ExoSocialActivity convertCommentEntityToComment(CommentEntity comment) { ExoSocialActivity exoComment = new ExoSocialActivityImpl(comment.getPosterId(), null, comment.getTitle(), comment.getBody(), false); exoComment.setId(getExoCommentID(comment.getId())); exoComment.setTitle(comment.getTitle()); exoComment.setType(comment.getType()); exoComment.setTitleId(comment.getTitleId()); exoComment.setBody(comment.getBody()); exoComment.setTemplateParams( comment.getTemplateParams() != null ? new LinkedHashMap<String, String>(comment.getTemplateParams()) : new HashMap<String, String>()); exoComment.setPosterId(comment.getPosterId()); exoComment.isComment(true); // exoComment.isLocked(comment.getLocked().booleanValue()); exoComment.isHidden(comment.getHidden().booleanValue()); exoComment.setUpdated(comment.getUpdatedDate().getTime()); // exoComment.setParentId(comment.getActivity().getId() + ""); // exoComment.setPostedTime(comment.getPosted()); exoComment.setUpdated(comment.getUpdatedDate().getTime()); // processActivity(exoComment); return exoComment; } private List<ExoSocialActivity> convertCommentEntitiesToComments(List<CommentEntity> comments) { List<ExoSocialActivity> exoSocialActivities = new ArrayList<ExoSocialActivity>(); if (comments == null) return exoSocialActivities; for (CommentEntity comment : comments) { exoSocialActivities.add(convertCommentEntityToComment(comment)); } return exoSocialActivities; } private CommentEntity convertCommentToCommentEntity(ExoSocialActivity comment) { CommentEntity commentEntity = new CommentEntity(); if (comment.getId() != null) { commentEntity = commentDAO.find(getCommentID(comment.getId())); } commentEntity.setTitle(comment.getTitle()); commentEntity.setTitleId(comment.getTitleId()); commentEntity.setType(comment.getType()); commentEntity.setBody(comment.getBody()); commentEntity.setPosterId(comment.getPosterId() != null ? comment.getPosterId() : comment.getUserId()); if (comment.getTemplateParams() != null) { commentEntity.setTemplateParams(comment.getTemplateParams()); } // commentEntity.setLocked(comment.isLocked()); commentEntity.setHidden(comment.isHidden()); // long commentMillis = (comment.getPostedTime() != null ? comment.getPostedTime() : System.currentTimeMillis()); commentEntity.setPosted(commentMillis); commentEntity.setUpdatedDate(new Date(commentMillis)); // return commentEntity; } private List<ExoSocialActivity> convertActivityEntitiesToActivities(List<ActivityEntity> activities) { List<ExoSocialActivity> exoSocialActivities = new ArrayList<ExoSocialActivity>(); if (activities == null) return exoSocialActivities; for (ActivityEntity activity : activities) { exoSocialActivities.add(convertActivityEntityToActivity(activity)); } return exoSocialActivities; } @Override @ExoTransactional public ExoSocialActivity getActivity(String activityId) throws ActivityStorageException { if (activityId == null || activityId.isEmpty()) { return null; } if (activityId != null && activityId.startsWith(COMMENT_PREFIX)) { return getComment(activityId); } try { ActivityEntity entity = activityDAO.find(Long.valueOf(activityId)); return convertActivityEntityToActivity(entity); } catch (Exception e) { if (PropertyManager.isDevelopping()) { throw new ActivityStorageException(Type.FAILED_TO_GET_ACTIVITY, e.getMessage(), e); } return null; } } public ExoSocialActivity getComment(String commentId) throws ActivityStorageException { try { CommentEntity entity = commentDAO.find(getCommentID(commentId)); return convertCommentEntityToComment(entity); } catch (Exception e) { if (PropertyManager.isDevelopping()) { throw new ActivityStorageException(Type.FAILED_TO_GET_ACTIVITY, e.getMessage(), e); } return null; } } @Override public List<ExoSocialActivity> getUserActivities(Identity owner) throws ActivityStorageException { return getUserActivities(owner, 0, -1); } @Override public List<ExoSocialActivity> getUserActivities(Identity owner, long offset, long limit) throws ActivityStorageException { return getUserActivitiesForUpgrade(owner, offset, limit); } @Override public List<String> getUserSpacesActivityIds(Identity ownerIdentity, int offset, int limit) { return activityDAO.getUserSpacesActivityIds(ownerIdentity, offset, limit, memberOfSpaceIds(ownerIdentity)); } @Override public List<String> getUserIdsActivities(Identity owner, long offset, long limit) throws ActivityStorageException { return activityDAO.getUserIdsActivities(owner, offset, limit); } @Override @ExoTransactional public List<ExoSocialActivity> getUserActivitiesForUpgrade(Identity owner, long offset, long limit) throws ActivityStorageException { return convertActivityEntitiesToActivities(activityDAO.getUserActivities(owner, offset, limit)); } @Override @ExoTransactional public List<ExoSocialActivity> getActivities(Identity owner, Identity viewer, long offset, long limit) throws ActivityStorageException { return convertActivityEntitiesToActivities(activityDAO.getActivities(owner, viewer, offset, limit)); } @Override @ExoTransactional public void saveComment(ExoSocialActivity activity, ExoSocialActivity eXoComment) throws ActivityStorageException { ActivityEntity activityEntity = activityDAO.find(Long.valueOf(activity.getId())); try { EntityManagerHolder.get().lock(activityEntity, LockModeType.PESSIMISTIC_WRITE); CommentEntity commentEntity = convertCommentToCommentEntity(eXoComment); commentEntity.setActivity(activityEntity); // Identity commenter = identityStorage.findIdentityById(commentEntity.getPosterId()); saveStreamItemForCommenter(commenter, activityEntity); mention(commenter, activityEntity, processMentions(eXoComment.getTitle())); // activityEntity.addComment(commentEntity); commentEntity = commentDAO.create(commentEntity); eXoComment.setId(getExoCommentID(commentEntity.getId())); // activityEntity.setMentionerIds(processMentionOfComment(activityEntity, commentEntity, activity.getMentionedIds(), processMentions(eXoComment.getTitle()), true)); activityEntity.setUpdatedDate(new Date(System.currentTimeMillis())); activityDAO.update(activityEntity); // updateLastUpdatedForStreamItem(activityEntity); // activity = convertActivityEntityToActivity(activityEntity); } finally { EntityManagerHolder.get().lock(activityEntity, LockModeType.NONE); } } /** * Creates the StreamItem for commenter * @param commenter * @param activityEntity */ private void saveStreamItemForCommenter(Identity commenter, ActivityEntity activityEntity) { Identity ownerActivity = identityStorage.findIdentityById(activityEntity.getOwnerId()); if (!SpaceIdentityProvider.NAME.equals(ownerActivity.getProviderId())) { createStreamItem(StreamType.COMMENTER, activityEntity, commenter.getId()); } } private void updateLastUpdatedForStreamItem(ActivityEntity activity) { List<StreamItemEntity> items = streamItemDAO.findStreamItemByActivityId(activity.getId()); for (StreamItemEntity item : items) { item.setUpdatedDate(activity.getUpdatedDate()); streamItemDAO.update(item); } } private Set<String> processMentionOfComment(ActivityEntity activityEntity, CommentEntity commentEntity, String[] activityMentioners, String[] commentMentioners, boolean isAdded) { Set<String> mentioners = new HashSet<String>(Arrays.asList(activityMentioners)); if (commentMentioners.length == 0) return mentioners; // for (String mentioner : commentMentioners) { if (!mentioners.contains(mentioner) && isAdded) { mentioners.add(mentioner); } if (mentioners.contains(mentioner) && !isAdded) { if (isAllowedToRemove(activityEntity, commentEntity, mentioner)) { mentioners.remove(mentioner); //remove stream item StreamItemEntity item = new StreamItemEntity(StreamType.MENTIONER); item.setOwnerId(mentioner); activityEntity.removeStreamItem(item); } } } return mentioners; } private boolean isAllowedToRemove(ActivityEntity activity, CommentEntity comment, String mentioner) { if (ArrayUtils.contains(processMentions(activity.getTitle()), mentioner)) { return false; } List<CommentEntity> comments = activity.getComments(); comments.remove(comment); for (CommentEntity cmt : comments) { if (ArrayUtils.contains(processMentions(cmt.getTitle()), mentioner)) { return false; } } return true; } @Override public ExoSocialActivity saveActivity(Identity owner, ExoSocialActivity activity) throws ActivityStorageException { ActivityEntity entity = convertActivityToActivityEntity(activity, owner.getId()); // entity.setOwnerId(owner.getId()); entity.setProviderId(owner.getProviderId()); saveStreamItem(owner, entity); // activityDAO.create(entity); activity.setId(Long.toString(entity.getId())); // return activity; } /** * Creates the StreamIteam for Space Member * @param spaceOwner * @param activity */ private void spaceMembers(Identity spaceOwner, ActivityEntity activity) { createStreamItem(StreamType.SPACE, activity, spaceOwner.getId()); createStreamItem(StreamType.SPACE, activity, activity.getPosterId()); } private void saveStreamItem(Identity owner, ActivityEntity activity) { //create StreamItem if (OrganizationIdentityProvider.NAME.equals(owner.getProviderId())) { //poster poster(owner, activity); } else { //for SPACE spaceMembers(owner, activity); } //mention mention(owner, activity, processMentions(activity.getTitle())); } /** * Creates the StreamItem for poster and stream owner * @param owner * @param activity */ private void poster(Identity owner, ActivityEntity activity) { createStreamItem(StreamType.POSTER, activity, activity.getPosterId()); //User A posts a new activity on user B stream (A connected B) if (!owner.getId().equals(activity.getPosterId())) { createStreamItem(StreamType.POSTER, activity, owner.getId()); } } /** * Creates StreamItem for each user who has mentioned on the activity * * @param owner * @param activity */ private void mention(Identity owner, ActivityEntity activity, String[] mentions) { for (String mentioner : mentions) { Identity identity = identityStorage.findIdentityById(mentioner); if (identity != null) { createStreamItem(StreamType.MENTIONER, activity, identity.getId()); } } } private void createStreamItem(StreamType streamType, ActivityEntity activity, String ownerId) { StreamItemEntity streamItem = new StreamItemEntity(streamType); streamItem.setOwnerId(ownerId); streamItem.setUpdatedDate(activity.getUpdatedDate()); boolean isExist = false; if (activity.getId() != null) { //TODO need to improve it for (StreamItemEntity item : activity.getStreamItems()) { if (item.getOwnerId().equals(ownerId) && streamType.equals(item.getStreamType())) { isExist = true; break; } } } if (!isExist) { activity.addStreamItem(streamItem); } } /** * Processes Mentioners who has been mentioned via the Activity. * * @param title */ private String[] processMentions(String title) { if (title == null || title.length() == 0) { return ArrayUtils.EMPTY_STRING_ARRAY; } Set<String> mentions = new HashSet<>(); Matcher matcher = MENTION_PATTERN.matcher(title); while (matcher.find()) { String remoteId = matcher.group().substring(1); if (!USER_NAME_VALIDATOR_REGEX.matcher(remoteId).matches()) { continue; } Identity identity = identityStorage.findIdentity(OrganizationIdentityProvider.NAME, remoteId); // if not the right mention then ignore if (identity != null && !mentions.contains(identity.getId())) { mentions.add(identity.getId()); } } return mentions.toArray(new String[mentions.size()]); } @Override @ExoTransactional public ExoSocialActivity getParentActivity(ExoSocialActivity comment) throws ActivityStorageException { try { Long commentId = getCommentID(comment.getId()); return convertActivityEntityToActivity(commentDAO.findActivity(commentId)); } catch (NumberFormatException e) { LOG.warn("The input ExoSocialActivity is not comment, it is Activity"); return null; } } @Override public void deleteActivity(String activityId) throws ActivityStorageException { ActivityEntity a = activityDAO.find(Long.valueOf(activityId)); if (a != null) { activityDAO.delete(a); } else { LOG.warn("The activity's " + activityId + " is not found!"); } } @Override @ExoTransactional public void deleteComment(String activityId, String commentId) throws ActivityStorageException { CommentEntity comment = commentDAO.find(getCommentID(commentId)); commentDAO.delete(comment); // ActivityEntity activity = activityDAO.find(Long.valueOf(activityId)); activity.getComments().remove(comment); // activity.setMentionerIds(processMentionOfComment(activity, comment, activity.getMentionerIds().toArray(new String[activity.getMentionerIds().size()]), processMentions(comment.getTitle()), false)); // if (!hasOtherComment(activity, comment.getPosterId())) { StreamItemEntity item = new StreamItemEntity(StreamType.COMMENTER); item.setOwnerId(comment.getPosterId()); activity.removeStreamItem(item); } // activityDAO.update(activity); } private boolean hasOtherComment(ActivityEntity activity, String poster) { for (CommentEntity comment : activity.getComments()) { if (poster.equals(comment.getPosterId())) { return true; } } return false; } @Override public List<ExoSocialActivity> getActivitiesOfIdentities(List<Identity> connectionList, long offset, long limit) throws ActivityStorageException { return null; } @Override public List<ExoSocialActivity> getActivitiesOfIdentities(List<Identity> connectionList, TimestampType type, long offset, long limit) throws ActivityStorageException { return null; } @Override public int getNumberOfUserActivities(Identity owner) throws ActivityStorageException { return getNumberOfUserActivitiesForUpgrade(owner); } @Override public int getNumberOfUserActivitiesForUpgrade(Identity owner) throws ActivityStorageException { return activityDAO.getNumberOfUserActivities(owner); } @Override public int getNumberOfNewerOnUserActivities(Identity ownerIdentity, ExoSocialActivity baseActivity) { return getNumberOfNewerOnUserActivities(ownerIdentity, baseActivity.getUpdated().getTime()); } @Override public List<ExoSocialActivity> getNewerOnUserActivities(Identity ownerIdentity, ExoSocialActivity baseActivity, int limit) { return getNewerUserActivities(ownerIdentity, baseActivity.getUpdated().getTime(), limit); } @Override public int getNumberOfOlderOnUserActivities(Identity ownerIdentity, ExoSocialActivity baseActivity) { return getNumberOfOlderOnUserActivities(ownerIdentity, baseActivity.getUpdated().getTime()); } @Override public List<ExoSocialActivity> getOlderOnUserActivities(Identity ownerIdentity, ExoSocialActivity baseActivity, int limit) { return getOlderUserActivities(ownerIdentity, baseActivity.getUpdated().getTime(), limit); } @Override public List<ExoSocialActivity> getActivityFeed(Identity ownerIdentity, int offset, int limit) { return getActivityFeedForUpgrade(ownerIdentity, offset, limit); } @Override public List<String> getActivityIdsFeed(Identity ownerIdentity, int offset, int limit) { return activityDAO.getActivityIdsFeed(ownerIdentity, offset, limit, memberOfSpaceIds(ownerIdentity)); } @Override @ExoTransactional public List<ExoSocialActivity> getActivityFeedForUpgrade(Identity ownerIdentity, int offset, int limit) { return convertActivityEntitiesToActivities( activityDAO.getActivityFeed(ownerIdentity, offset, limit, memberOfSpaceIds(ownerIdentity))); } @Override public int getNumberOfActivitesOnActivityFeed(Identity ownerIdentity) { return getNumberOfActivitesOnActivityFeedForUpgrade(ownerIdentity); } @Override public int getNumberOfActivitesOnActivityFeedForUpgrade(Identity ownerIdentity) { return activityDAO.getNumberOfActivitesOnActivityFeed(ownerIdentity, memberOfSpaceIds(ownerIdentity)); } @Override public int getNumberOfNewerOnActivityFeed(Identity ownerIdentity, ExoSocialActivity baseActivity) { return getNumberOfNewerOnActivityFeed(ownerIdentity, baseActivity.getUpdated().getTime()); } @Override public List<ExoSocialActivity> getNewerOnActivityFeed(Identity ownerIdentity, ExoSocialActivity baseActivity, int limit) { return getNewerFeedActivities(ownerIdentity, baseActivity.getUpdated().getTime(), limit); } @Override public int getNumberOfOlderOnActivityFeed(Identity ownerIdentity, ExoSocialActivity baseActivity) { return getNumberOfOlderOnActivityFeed(ownerIdentity, baseActivity.getUpdated().getTime()); } @Override public List<ExoSocialActivity> getOlderOnActivityFeed(Identity ownerIdentity, ExoSocialActivity baseActivity, int limit) { return getOlderFeedActivities(ownerIdentity, baseActivity.getUpdated().getTime(), limit); } @Override public List<ExoSocialActivity> getActivitiesOfConnections(Identity ownerIdentity, int offset, int limit) { return getActivitiesOfConnectionsForUpgrade(ownerIdentity, offset, limit); } @Override public List<String> getActivityIdsOfConnections(Identity ownerIdentity, int offset, int limit) { return activityDAO.getActivityIdsOfConnections(ownerIdentity, offset, limit); } @Override @ExoTransactional public List<ExoSocialActivity> getActivitiesOfConnectionsForUpgrade(Identity ownerIdentity, int offset, int limit) { return convertActivityEntitiesToActivities( activityDAO.getActivitiesOfConnections(ownerIdentity, offset, limit)); } @Override public int getNumberOfActivitiesOfConnections(Identity ownerIdentity) { return getNumberOfActivitiesOfConnectionsForUpgrade(ownerIdentity); } @Override public int getNumberOfActivitiesOfConnectionsForUpgrade(Identity ownerIdentity) { return activityDAO.getNumberOfActivitiesOfConnections(ownerIdentity); } @Override public List<ExoSocialActivity> getActivitiesOfIdentity(Identity ownerIdentity, long offset, long limit) { return getUserActivities(ownerIdentity, offset, limit); } @Override public int getNumberOfNewerOnActivitiesOfConnections(Identity ownerIdentity, ExoSocialActivity baseActivity) { return getNumberOfNewerOnActivitiesOfConnections(ownerIdentity, baseActivity.getUpdated().getTime()); } @Override public List<ExoSocialActivity> getNewerOnActivitiesOfConnections(Identity ownerIdentity, ExoSocialActivity baseActivity, long limit) { return getNewerActivitiesOfConnections(ownerIdentity, baseActivity.getUpdated().getTime(), (int) limit); } @Override public int getNumberOfOlderOnActivitiesOfConnections(Identity ownerIdentity, ExoSocialActivity baseActivity) { return getNumberOfOlderOnActivitiesOfConnections(ownerIdentity, baseActivity.getUpdated().getTime()); } @Override public List<ExoSocialActivity> getOlderOnActivitiesOfConnections(Identity ownerIdentity, ExoSocialActivity baseActivity, int limit) { return getOlderActivitiesOfConnections(ownerIdentity, baseActivity.getUpdated().getTime(), limit); } @Override public List<ExoSocialActivity> getUserSpacesActivities(Identity ownerIdentity, int offset, int limit) { return getUserSpacesActivitiesForUpgrade(ownerIdentity, offset, limit); } @Override public List<String> getSpaceActivityIds(Identity spaceIdentity, int offset, int limit) { return activityDAO.getSpaceActivityIds(spaceIdentity, offset, limit); } @Override @ExoTransactional public List<ExoSocialActivity> getUserSpacesActivitiesForUpgrade(Identity ownerIdentity, int offset, int limit) { return convertActivityEntitiesToActivities( activityDAO.getUserSpacesActivities(ownerIdentity, offset, limit, memberOfSpaceIds(ownerIdentity))); } @Override public int getNumberOfUserSpacesActivities(Identity ownerIdentity) { return getNumberOfUserSpacesActivitiesForUpgrade(ownerIdentity); } @Override public int getNumberOfUserSpacesActivitiesForUpgrade(Identity ownerIdentity) { return activityDAO.getNumberOfUserSpacesActivities(ownerIdentity, memberOfSpaceIds(ownerIdentity)); } @Override public int getNumberOfNewerOnUserSpacesActivities(Identity ownerIdentity, ExoSocialActivity baseActivity) { return getNumberOfNewerOnUserSpacesActivities(ownerIdentity, baseActivity.getUpdated().getTime()); } @Override public List<ExoSocialActivity> getNewerOnUserSpacesActivities(Identity ownerIdentity, ExoSocialActivity baseActivity, int limit) { return getNewerUserSpacesActivities(ownerIdentity, baseActivity.getUpdated().getTime(), limit); } @Override public int getNumberOfOlderOnUserSpacesActivities(Identity ownerIdentity, ExoSocialActivity baseActivity) { return getNumberOfOlderOnUserSpacesActivities(ownerIdentity, baseActivity.getUpdated().getTime()); } @Override public List<ExoSocialActivity> getOlderOnUserSpacesActivities(Identity ownerIdentity, ExoSocialActivity baseActivity, int limit) { return getOlderUserSpacesActivities(ownerIdentity, baseActivity.getUpdated().getTime(), limit); } @Override public List<ExoSocialActivity> getComments(ExoSocialActivity existingActivity, int offset, int limit) { List<CommentEntity> comments = commentDAO .getComments(activityDAO.find(Long.valueOf(existingActivity.getId())), offset, limit); return convertCommentEntitiesToComments(comments); } @Override public int getNumberOfComments(ExoSocialActivity existingActivity) { return commentDAO.getNumberOfComments(activityDAO.find(Long.valueOf(existingActivity.getId()))); } @Override public int getNumberOfNewerComments(ExoSocialActivity existingActivity, ExoSocialActivity baseComment) { return getNewerComments(existingActivity, baseComment, 0).size(); } @Override public List<ExoSocialActivity> getNewerComments(ExoSocialActivity existingActivity, ExoSocialActivity baseComment, int limit) { return getNewerComments(existingActivity, baseComment.getPostedTime(), limit); } @Override public int getNumberOfOlderComments(ExoSocialActivity existingActivity, ExoSocialActivity baseComment) { return getOlderComments(existingActivity, baseComment, 0).size(); } @Override public List<ExoSocialActivity> getOlderComments(ExoSocialActivity existingActivity, ExoSocialActivity baseComment, int limit) { return getOlderComments(existingActivity, baseComment.getPostedTime(), limit); } @Override @ExoTransactional public List<ExoSocialActivity> getNewerComments(ExoSocialActivity existingActivity, Long sinceTime, int limit) { List<CommentEntity> comments = commentDAO .getNewerOfComments(activityDAO.find(Long.valueOf(existingActivity.getId())), sinceTime, limit); // return convertCommentEntitiesToComments(comments); } @Override @ExoTransactional public List<ExoSocialActivity> getOlderComments(ExoSocialActivity existingActivity, Long sinceTime, int limit) { List<CommentEntity> comments = commentDAO .getOlderOfComments(activityDAO.find(Long.valueOf(existingActivity.getId())), sinceTime, limit); return convertCommentEntitiesToComments(comments); } @Override public int getNumberOfNewerComments(ExoSocialActivity existingActivity, Long sinceTime) { return getNewerComments(existingActivity, sinceTime, 0).size(); } @Override public int getNumberOfOlderComments(ExoSocialActivity existingActivity, Long sinceTime) { return getOlderComments(existingActivity, sinceTime, 0).size(); } @Override public SortedSet<ActivityProcessor> getActivityProcessors() { return activityProcessors; } @Override public void updateActivity(ExoSocialActivity existingActivity) throws ActivityStorageException { ExoSocialActivity updatedActivity = getActivity(existingActivity.getId()); if (existingActivity.getTitle() == null) existingActivity.setTitle(updatedActivity.getTitle()); if (existingActivity.getBody() == null) existingActivity.setBody(updatedActivity.getBody()); if (existingActivity.getTemplateParams() == null) existingActivity.setTemplateParams(updatedActivity.getTemplateParams()); if (existingActivity.getId().startsWith(COMMENT_PREFIX)) { // update comment CommentEntity comment = convertCommentToCommentEntity(existingActivity); //comment.setLastUpdated(System.currentTimeMillis()); commentDAO.update(comment); } else { ActivityEntity activityEntity = convertActivityToActivityEntity(existingActivity, null); //create or remove liker if exist processLikerActivity(new HashSet<String>(Arrays.asList(existingActivity.getLikeIdentityIds())), new HashSet<String>(Arrays.asList(updatedActivity.getLikeIdentityIds())), activityEntity); activityDAO.update(activityEntity); } } private void processLikerActivity(Set<String> newLikerList, Set<String> oldLikerList, ActivityEntity activity) { for (String id : newLikerList) { if (!oldLikerList.contains(id)) {//new like ==> create stream item createStreamItem(StreamType.LIKER, activity, id); } else { oldLikerList.remove(id); } } if (oldLikerList.size() > 0) {//unlike ==> remove stream item for (String id : oldLikerList) { StreamItemEntity item = new StreamItemEntity(StreamType.LIKER); item.setOwnerId(id); activity.removeStreamItem(item); } } } @Override public int getNumberOfNewerOnActivityFeed(Identity ownerIdentity, Long sinceTime) { return activityDAO.getNumberOfNewerOnActivityFeed(ownerIdentity, sinceTime, memberOfSpaceIds(ownerIdentity)); } @Override public int getNumberOfNewerOnUserActivities(Identity ownerIdentity, Long sinceTime) { return activityDAO.getNumberOfNewerOnUserActivities(ownerIdentity, sinceTime); } @Override public int getNumberOfNewerOnActivitiesOfConnections(Identity ownerIdentity, Long sinceTime) { return activityDAO.getNumberOfNewerOnActivitiesOfConnections(ownerIdentity, sinceTime); } @Override public int getNumberOfNewerOnUserSpacesActivities(Identity ownerIdentity, Long sinceTime) { return activityDAO.getNumberOfNewerOnUserSpacesActivities(ownerIdentity, sinceTime, memberOfSpaceIds(ownerIdentity)); } @Override public List<ExoSocialActivity> getActivitiesOfIdentities(ActivityBuilderWhere where, ActivityFilter filter, long offset, long limit) throws ActivityStorageException { return null; } @Override public int getNumberOfSpaceActivities(Identity spaceIdentity) { return getNumberOfSpaceActivitiesForUpgrade(spaceIdentity); } @Override public int getNumberOfSpaceActivitiesForUpgrade(Identity spaceIdentity) { return activityDAO.getNumberOfSpaceActivities(spaceIdentity); } @Override @ExoTransactional public List<ExoSocialActivity> getSpaceActivities(Identity spaceIdentity, int offset, int limit) { return convertActivityEntitiesToActivities(activityDAO.getSpaceActivities(spaceIdentity, offset, limit)); } @Override @ExoTransactional public List<ExoSocialActivity> getSpaceActivitiesForUpgrade(Identity spaceIdentity, int offset, int limit) { return convertActivityEntitiesToActivities(activityDAO.getSpaceActivities(spaceIdentity, offset, limit)); } @Override public List<ExoSocialActivity> getActivitiesByPoster(Identity posterIdentity, int offset, int limit) { return getActivitiesByPoster(posterIdentity, offset, limit, new String[] {}); } @Override public List<ExoSocialActivity> getActivitiesByPoster(Identity posterIdentity, int offset, int limit, String... activityTypes) { return convertActivityEntitiesToActivities( activityDAO.getActivitiesByPoster(posterIdentity, offset, limit, activityTypes)); } @Override public int getNumberOfActivitiesByPoster(Identity posterIdentity) { return activityDAO.getNumberOfActivitiesByPoster(posterIdentity, new String[] {}); } @Override public int getNumberOfActivitiesByPoster(Identity ownerIdentity, Identity viewerIdentity) { return 0; } @Override public List<ExoSocialActivity> getNewerOnSpaceActivities(Identity spaceIdentity, ExoSocialActivity baseActivity, int limit) { return getNewerSpaceActivities(spaceIdentity, baseActivity.getUpdated().getTime(), limit); } @Override public int getNumberOfNewerOnSpaceActivities(Identity spaceIdentity, ExoSocialActivity baseActivity) { return getNumberOfNewerOnSpaceActivities(spaceIdentity, baseActivity.getUpdated().getTime()); } @Override public List<ExoSocialActivity> getOlderOnSpaceActivities(Identity spaceIdentity, ExoSocialActivity baseActivity, int limit) { return getOlderSpaceActivities(spaceIdentity, baseActivity.getUpdated().getTime(), limit); } @Override public int getNumberOfOlderOnSpaceActivities(Identity spaceIdentity, ExoSocialActivity baseActivity) { return getNumberOfOlderOnSpaceActivities(spaceIdentity, baseActivity.getUpdated().getTime()); } @Override public int getNumberOfNewerOnSpaceActivities(Identity spaceIdentity, Long sinceTime) { return activityDAO.getNumberOfNewerOnSpaceActivities(spaceIdentity, sinceTime); } @Override public int getNumberOfUpdatedOnActivityFeed(Identity owner, ActivityUpdateFilter filter) { return 0; } @Override public int getNumberOfUpdatedOnUserActivities(Identity owner, ActivityUpdateFilter filter) { return 0; } @Override public int getNumberOfUpdatedOnActivitiesOfConnections(Identity owner, ActivityUpdateFilter filter) { return 0; } @Override public int getNumberOfUpdatedOnUserSpacesActivities(Identity owner, ActivityUpdateFilter filter) { return 0; } @Override public int getNumberOfUpdatedOnSpaceActivities(Identity owner, ActivityUpdateFilter filter) { return 0; } @Override public int getNumberOfMultiUpdated(Identity owner, Map<String, Long> sinceTimes) { return 0; } @Override @ExoTransactional public List<ExoSocialActivity> getNewerFeedActivities(Identity owner, Long sinceTime, int limit) { return convertActivityEntitiesToActivities( activityDAO.getNewerOnActivityFeed(owner, sinceTime, limit, memberOfSpaceIds(owner))); } @Override @ExoTransactional public List<ExoSocialActivity> getNewerUserActivities(Identity owner, Long sinceTime, int limit) { return convertActivityEntitiesToActivities(activityDAO.getNewerOnUserActivities(owner, sinceTime, limit)); } @Override @ExoTransactional public List<ExoSocialActivity> getNewerUserSpacesActivities(Identity owner, Long sinceTime, int limit) { return convertActivityEntitiesToActivities( activityDAO.getNewerOnUserSpacesActivities(owner, sinceTime, limit, memberOfSpaceIds(owner))); } @Override @ExoTransactional public List<ExoSocialActivity> getNewerActivitiesOfConnections(Identity owner, Long sinceTime, int limit) { return convertActivityEntitiesToActivities( activityDAO.getNewerOnActivitiesOfConnections(owner, sinceTime, limit)); } @Override @ExoTransactional public List<ExoSocialActivity> getNewerSpaceActivities(Identity owner, Long sinceTime, int limit) { return convertActivityEntitiesToActivities(activityDAO.getNewerOnSpaceActivities(owner, sinceTime, limit)); } @Override @ExoTransactional public List<ExoSocialActivity> getOlderFeedActivities(Identity owner, Long sinceTime, int limit) { return convertActivityEntitiesToActivities( activityDAO.getOlderOnActivityFeed(owner, sinceTime, limit, memberOfSpaceIds(owner))); } @Override @ExoTransactional public List<ExoSocialActivity> getOlderUserActivities(Identity owner, Long sinceTime, int limit) { return convertActivityEntitiesToActivities(activityDAO.getOlderOnUserActivities(owner, sinceTime, limit)); } @Override @ExoTransactional public List<ExoSocialActivity> getOlderUserSpacesActivities(Identity owner, Long sinceTime, int limit) { return convertActivityEntitiesToActivities( activityDAO.getOlderOnUserSpacesActivities(owner, sinceTime, limit, memberOfSpaceIds(owner))); } @Override @ExoTransactional public List<ExoSocialActivity> getOlderActivitiesOfConnections(Identity owner, Long sinceTime, int limit) { return convertActivityEntitiesToActivities( activityDAO.getOlderOnActivitiesOfConnections(owner, sinceTime, limit)); } @Override @ExoTransactional public List<ExoSocialActivity> getOlderSpaceActivities(Identity owner, Long sinceTime, int limit) { return convertActivityEntitiesToActivities(activityDAO.getOlderOnSpaceActivities(owner, sinceTime, limit)); } @Override public int getNumberOfOlderOnActivityFeed(Identity ownerIdentity, Long sinceTime) { return activityDAO.getNumberOfOlderOnActivityFeed(ownerIdentity, sinceTime, memberOfSpaceIds(ownerIdentity)); } @Override public int getNumberOfOlderOnUserActivities(Identity ownerIdentity, Long sinceTime) { return activityDAO.getNumberOfOlderOnUserActivities(ownerIdentity, sinceTime); } @Override public int getNumberOfOlderOnActivitiesOfConnections(Identity ownerIdentity, Long sinceTime) { return activityDAO.getNumberOfOlderOnActivitiesOfConnections(ownerIdentity, sinceTime); } @Override public int getNumberOfOlderOnUserSpacesActivities(Identity ownerIdentity, Long sinceTime) { return activityDAO.getNumberOfOlderOnUserSpacesActivities(ownerIdentity, sinceTime, memberOfSpaceIds(ownerIdentity)); } @Override public int getNumberOfOlderOnSpaceActivities(Identity ownerIdentity, Long sinceTime) { return activityDAO.getNumberOfOlderOnSpaceActivities(ownerIdentity, sinceTime); } private Long getCommentID(String commentId) { return (commentId == null || commentId.trim().isEmpty()) ? null : Long.valueOf(commentId.replace(COMMENT_PREFIX, "")); } private String getExoCommentID(Long commentId) { return String.valueOf(COMMENT_PREFIX + commentId); } private void processActivity(ExoSocialActivity existingActivity) { Iterator<ActivityProcessor> it = activityProcessors.iterator(); while (it.hasNext()) { try { it.next().processActivity(existingActivity); } catch (Exception e) { LOG.debug("activity processing failed "); } } } /** * Gets the list of spaceIds what the given identify is member * * @param ownerIdentity * @return */ private List<String> memberOfSpaceIds(Identity ownerIdentity) { return spaceStorage.getMemberSpaceIds(ownerIdentity.getId(), 0, -1); } public void setIdentityStorage(IdentityStorage identityStorage) { this.identityStorage = identityStorage; } }