Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.adobe.cq.social.notifications.client.api.AbstractSocialNotificationCollection Maven / Gradle / Ivy
/*************************************************************************
*
* ADOBE CONFIDENTIAL
* __________________
*
* Copyright 2015 Adobe Systems Incorporated
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe Systems Incorporated and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Adobe Systems Incorporated and its
* suppliers and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe Systems Incorporated.
**************************************************************************/
package com.adobe.cq.social.notifications.client.api;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import org.apache.commons.lang.StringUtils;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.SyntheticResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.adobe.cq.social.activitystreams.client.api.SocialActivity;
import com.adobe.cq.social.commons.listing.QueryFilterUtil;
import com.adobe.cq.social.commons.listing.QueryFilterUtil.QueryFilterException;
import com.adobe.cq.social.community.api.CommunityContext;
import com.adobe.cq.social.notifications.api.Notification;
import com.adobe.cq.social.notifications.api.NotificationConstants;
import com.adobe.cq.social.notifications.api.NotificationManager;
import com.adobe.cq.social.scf.ClientUtilities;
import com.adobe.cq.social.scf.CollectionPagination;
import com.adobe.cq.social.scf.PageInfo;
import com.adobe.cq.social.scf.QueryRequestInfo;
import com.adobe.cq.social.scf.SocialComponent;
import com.adobe.cq.social.scf.SocialComponentFactory;
import com.adobe.cq.social.scf.SocialComponentFactoryManager;
import com.adobe.cq.social.scf.core.BaseSocialComponent;
import com.adobe.cq.social.scf.core.CollectionSortedOrder;
import com.adobe.cq.social.ugc.api.ComparisonType;
import com.adobe.cq.social.ugc.api.Constraint;
import com.adobe.cq.social.ugc.api.ConstraintGroup;
import com.adobe.cq.social.ugc.api.Operator;
import com.adobe.cq.social.ugc.api.UgcFilter;
import com.adobe.cq.social.ugc.api.ValueConstraint;
import com.adobe.cq.social.ugcbase.SocialUtils;
import com.adobe.granite.activitystreams.ActivityException;
public abstract class AbstractSocialNotificationCollection extends BaseSocialComponent implements
SocialNotificationCollection {
private static final Logger LOG = LoggerFactory.getLogger(AbstractSocialNotificationCollection.class);
private CollectionPagination pagination;
private CollectionSortedOrder sortOrder = CollectionSortedOrder.DEFAULT_ORDER;
private List notifications;
private PageInfo pageInfo;
private NotificationManager notificationManager;
private String userId;
private String channelId;
private int maxNumberNotifications;
private long numUnread = -1;
private UgcFilter ugcFilter;
private static String PROP_FILTER_NAME = "filter";
public AbstractSocialNotificationCollection(final Resource resource, final ClientUtilities clientUtils,
final NotificationManager notificationManager) {
this(resource, clientUtils, QueryRequestInfo.DEFAULT_QUERY_INFO_FACTORY.create(), notificationManager);
}
public AbstractSocialNotificationCollection(final Resource resource, final ClientUtilities clientUtilities,
final QueryRequestInfo queryRequestInfo, final NotificationManager notificationManager) {
super(resource, clientUtilities);
init(resource, clientUtilities, queryRequestInfo, notificationManager, getProperty(PROP_USER_ID, ""));
}
public AbstractSocialNotificationCollection(final Resource resource, final ClientUtilities clientUtilities,
final QueryRequestInfo queryRequestInfo, final NotificationManager notificationManager, final String userId) {
super(resource, clientUtilities);
init(resource, clientUtilities, queryRequestInfo, notificationManager, userId);
}
@Override
public long getUnreadCount() {
if (numUnread == -1) {
try {
if (StringUtils.isBlank(userId)) {
throw new IllegalStateException("UserId has not been set.");
}
numUnread =
notificationManager.getUnreadCount(resource.getResourceResolver(), getPathConstraint(resource),
channelId);
} catch (final RepositoryException e) {
LOG.error("Failed to obtain number of unread count.", e);
} catch (final ActivityException e) {
// there is no stream, so return 0
numUnread = 0;
}
}
return numUnread;
}
@Override
public int getTotalSize() {
if (this.maxNumberNotifications < 0) { // we use -1 as the default infinite scroll size
return (int) pageInfo.getPageSize() * (int) pageInfo.getSelectedPage() + 2;
} else {
getItems();
return notifications.size();
}
}
@Override
public void setPagination(final CollectionPagination pagination) {
this.pagination = pagination;
}
@Override
public void setSortedOrder(final CollectionSortedOrder sortedOrder) {
this.sortOrder = sortedOrder;
}
@Override
public List getItems() {
final ResourceResolver resolver = resource.getResourceResolver();
if (pagination.getSize() > 0 // don't want to fetch anything if user asks for 0 item
&& notifications == null // we already fetch once
&& notificationManager.isStreamExist(resolver) // no need to fetch if there is no stream for this
// current user
) {
Iterable notificationList = null;
notificationList =
notificationManager.getNotifications(resolver, ugcFilter, pagination.getOffset(),
pagination.getSize());
if (notificationList != null) {
notifications = new ArrayList();
for (final Notification notification : notificationList) {
final Resource notificationResource =
new SyntheticResource(resolver, notification.getPath(), SocialNotification.RESOURCE_TYPE);
final SocialComponentFactoryManager factoryManager =
clientUtils.getSocialComponentFactoryManager();
final SocialComponentFactory componentFactory =
factoryManager.getSocialComponentFactory(notificationResource);
SocialComponent sc = null;
if (componentFactory instanceof SocialNotificationComponentFactory) {
sc =
((SocialNotificationComponentFactory) componentFactory).getSocialComponent(
notificationResource, clientUtils, notification);
} else {
sc = componentFactory.getSocialComponent(notificationResource, clientUtils, null);
}
if (sc != null) {
notifications.add(sc);
}
}
return notifications;
}
}
// Return empty list if we failed to obtain the list
if (notifications == null) {
LOG.debug("Return empty list");
return Collections.emptyList();
} else {
LOG.debug("Returning existing notifications list");
return notifications;
}
}
@Override
public String getChannelId() {
return this.channelId;
}
@Override
public String getUserId() {
return this.userId;
}
@Override
public PageInfo getPageInfo() {
return this.pageInfo;
}
public int getUnreadCountConfigured(){
return notificationManager.getUnreadCountConfigured();
}
private void init(final Resource resource, final ClientUtilities clientUtilities,
final QueryRequestInfo queryRequestInfo, final NotificationManager notificationManager, final String userId) {
if (notificationManager == null) {
throw new IllegalArgumentException("NoficationManager can not be null.");
}
this.notificationManager = notificationManager;
if (StringUtils.isBlank(userId)) {
throw new IllegalArgumentException("UserId can not be null.");
}
this.userId = userId;
LOG.debug("userId: {}", userId);
if (getProperties().containsKey(PROP_CHANNEL_ID)) {
this.channelId = getProperty(PROP_CHANNEL_ID, SocialNotificationCollection.DEFAULT_CHANNEL);
LOG.debug("channelId: {}", channelId);
}
if (StringUtils.isEmpty(channelId)) {
channelId = SocialNotificationCollection.DEFAULT_CHANNEL;
}
this.pagination = queryRequestInfo.getPagination();
if (pagination == null) {
pagination = CollectionPagination.DEFAULT_PAGINATION;
}
pageInfo = new PageInfo(this, clientUtils, this.pagination, getQueryParams(queryRequestInfo));
maxNumberNotifications = Integer.parseInt(getProperty(PROP_MAX_NOTIFICATIONS, DEFAULT_MAX_NOTIFICATIONS));
try {
ugcFilter = getFilter(queryRequestInfo, resource);
} catch (final QueryFilterException e) {
LOG.error("Failed to parse query predicates", e);
ugcFilter = null;
}
}
private UgcFilter getFilter(final QueryRequestInfo queryRequestInfo, final Resource resource)
throws QueryFilterException {
final UgcFilter ugcfilters = new UgcFilter();
// only add the channel filter if it is not all channel id
if (StringUtils.isNotBlank(channelId) && !SocialNotificationCollection.ALL_CHANNEL_ID.equals(channelId)) {
final Constraint constraint =
new ValueConstraint(NotificationConstants.NOTIFICATION_CHANNELS_PROP, channelId);
ugcfilters.addConstraint(constraint);
}
ugcfilters.and(getPathConstraint(resource));
final Map predicates = queryRequestInfo.getPredicates();
if (predicates != null) {
final String filters[] = predicates.get(PROP_FILTER_NAME);
if (filters != null && filters.length > 0) {
final List constraints = QueryFilterUtil.parseFilter(filters);
if (constraints != null && !constraints.isEmpty()) {
for (final ConstraintGroup cg : constraints) {
ugcfilters.and(cg);
}
}
}
}
return ugcfilters;
}
public static Constraint getPathConstraint(final Resource resource) {
final CommunityContext context = resource.adaptTo(CommunityContext.class);
final ConstraintGroup cgTargetPaths = new ConstraintGroup();
final String siteId = context.getSiteId();
List pathConstraints = new ArrayList();
if (StringUtils.isNotEmpty(siteId)) {
if (StringUtils.isNotEmpty(context.getCommunityGroupId())) {
pathConstraints.add(context.getCommunityGroupPath() + "/");
} else {
pathConstraints = context.getSiteContentPaths();
}
} else {
pathConstraints.add(getApplicationPagePath(resource));
}
final SocialUtils socialUtils = resource.getResourceResolver().adaptTo((SocialUtils.class));
final String asiPath = socialUtils.getSocialResourceProvider(resource).getASIPath();
for (final String pathConstraint : pathConstraints) {
if (StringUtils.isNotEmpty(pathConstraint)) {
final String ending = pathConstraint.endsWith("/") ? "" : "/";
final Constraint constraint =
new ValueConstraint(SocialActivity.TARGET_ID_PROP, pathConstraint + ending,
ComparisonType.BeginsWith);
constraint.setOperator(Operator.Or);
cgTargetPaths.addConstraint(constraint);
final Constraint ugcconstraint =
new ValueConstraint(SocialActivity.TARGET_ID_PROP, asiPath + pathConstraint + ending,
ComparisonType.BeginsWith);
ugcconstraint.setOperator(Operator.Or);
cgTargetPaths.addConstraint(ugcconstraint);
}
}
return cgTargetPaths;
}
private static String getApplicationPagePath(final Resource resource) {
String path = resource.getPath();
final Session session = resource.getResourceResolver().adaptTo(Session.class);
String pagePath = null;
if (path.startsWith("/content")) { // only looking for page if the path is under /content
try {
for (; path != null;) {
final String parentPath = ResourceUtil.getParent(path);
if (parentPath != null) {
final Node parentNode = session.getNode(parentPath);
if (parentNode.isNodeType("cq:Page")) {
pagePath = parentNode.getPath();
}
}
path = parentPath;
}
} catch (final RepositoryException e) {
LOG.error("Failed to obtain application page path for " + path, e);
}
}
return pagePath;
}
private String getQueryParams(final QueryRequestInfo queryInfo) {
final Map params = queryInfo.getPredicates();
final StringBuilder sb = new StringBuilder();
boolean firstParam = true;
try {
for (final Entry ks : params.entrySet()) {
final String key = ks.getKey();
final String[] value = ks.getValue();
for (int i = 0; i < value.length; i++) {
if (!firstParam) {
sb.append("&");
} else {
firstParam = false;
}
sb.append(URLEncoder.encode(key, "UTF-8")).append("=")
.append(URLEncoder.encode(value[i], "UTF-8"));
}
}
final String retVal = sb.toString();
return (retVal.isEmpty()) ? null : retVal;
} catch (final UnsupportedEncodingException e) {
LOG.error("Error encoding params. " + sb.toString());
return null;
}
}
}