com.adobe.cq.social.graph.client.api.AbstractFollowing 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.graph.client.api;
import org.apache.commons.lang.StringUtils;
import org.apache.jackrabbit.util.Text;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.adobe.cq.social.graph.Edge;
import com.adobe.cq.social.graph.SocialGraph;
import com.adobe.cq.social.graph.Vertex;
import com.adobe.cq.social.graph.client.api.Following;
import com.adobe.cq.social.graph.client.api.MutableFollowing;
import com.adobe.cq.social.scf.ClientUtilities;
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.User;
import com.adobe.cq.social.scf.core.BaseSocialComponent;
import com.adobe.granite.socialgraph.Direction;
/**
* Base class of SCF Following component. A Following represents a relationship between two users. The value of the
* userId and the followedId is obtained in the following order: If the request is a Post request, then the userId and
* the followedId are obtained from the request parameters. If the request is a Get request, then:
*
* 1. The userId is obtained from the resource {@link Following#PROP_USERID} property; If this property does not
* exist, the userId is obtained from the request's session user id.
*
* 2. The followedId is obtained from the resource {@link Following#PROP_FOLLOWEDID} property; If this property does
* not exist, the userId is obtained from the resource name
*/
public class AbstractFollowing extends BaseSocialComponent implements MutableFollowing {
private final ResourceResolver resolver;
private final SocialGraph graph;
private String userId;
private String otherId;
private boolean isFollowed;
private final Edge edge;
private final Vertex vertex;
private final Vertex otherVertex;
private final boolean isFollowedUser;
private final boolean mayFollow;
private static final Logger LOG = LoggerFactory.getLogger(AbstractFollowing.class);
public AbstractFollowing(final Resource resource, final ClientUtilities clientUtils, final QueryRequestInfo q) {
super(resource, clientUtils);
// 1. Get the param value from the request first. This only apply to POST request
final SlingHttpServletRequest request = clientUtils.getRequest();
if (request != null) {
this.userId = clientUtils.getUserId(request.getParameter(Following.PROP_USERID));
this.otherId = clientUtils.getUserId(request.getParameter(Following.PROP_FOLLOWEDID));
}
ValueMap properties = null;
// 2. If userId is not defined from the request,
// get the userId from the resource property (this only apply to GET request).
// If it is not defined, use the session user id
if (StringUtils.isBlank(this.userId)) {
properties = resource.getValueMap();
final String value = properties.get(PROP_USERID, "");
if (StringUtils.isNotEmpty(value)) {
this.userId = value;
} else {
this.userId = resource.getResourceResolver().getUserID();
}
}
// 3. if the followedId is not defined, get this value form the resource property.
// if this value is not defined as the resource property, check if we can obtain it from the
// resource path itself
if (StringUtils.isBlank(this.otherId)) {
if (properties == null) {
properties = resource.getValueMap();
}
this.otherId = properties.get(PROP_FOLLOWEDID, "");
if (StringUtils.isBlank(otherId)) {
final String resourceId = resource.getPath();
if (resourceId.startsWith(ClientUtilities.USER_ROOTPATH)) {
otherId = clientUtils.getUserId(resourceId);
} else {
otherId = Text.getRelativeParent(resourceId, 1);
}
}
}
if (StringUtils.isBlank(this.userId)) {
throw new IllegalArgumentException("Invalid value of userId.");
}
if (StringUtils.isBlank(this.otherId)) {
throw new IllegalArgumentException("Invalid value of followedId.");
}
resolver = resource.getResourceResolver();
mayFollow = !this.userId.equals(this.otherId);
graph = resolver.adaptTo(SocialGraph.class);
vertex = graph.getVertex(this.userId);
otherVertex = graph.getVertex(this.otherId);
edge = (Edge) vertex.getRelationship(Direction.OUTGOING, otherVertex, getRelationshipType());
isFollowed = (edge != null);
isFollowedUser = otherId.startsWith(ClientUtilities.USER_ROOTPATH) || !otherId.startsWith("/");
}
@Override
public User getUser() {
return clientUtils.getUser(this.userId, resolver);
}
@Override
public boolean getIsFollowed() {
return isFollowed;
}
@Override
public SocialGraph socialGraph() {
return graph;
}
@Override
public Edge edge() {
return edge;
}
@Override
public Vertex userNode() {
return vertex;
}
@Override
public Vertex followedNode() {
return otherVertex;
}
@Override
public boolean getIsFollowedUser() {
return isFollowedUser;
}
protected String getRelationshipType() {
return Edge.FOLLOWING_RELATIONSHIP_TYPE;
}
private SocialComponent createFollowedSocialComponent(final String id) {
if (isFollowedUser) {
return clientUtils.getUser(id, resolver);
} else {
final SocialComponentFactoryManager scfMgr = clientUtils.getSocialComponentFactoryManager();
if (scfMgr != null) {
final Resource resource = resolver.getResource(id);
final SocialComponentFactory scf = scfMgr.getSocialComponentFactory(resource);
if (scf != null) {
try {
return scf.getSocialComponent(resource, clientUtils,
QueryRequestInfo.DEFAULT_QUERY_INFO_FACTORY.create());
} catch (final Throwable e) {
LOG.error("Failed to retrieve social component.", e);
}
}
}
return null;
}
}
@Override
public boolean getMayFollow() {
return mayFollow;
}
@Override
public void setFollowingState(boolean newState) {
this.isFollowed = newState;
}
@Override
public String getFollowedId() {
return otherId;
}
@Override
public String getFollowedResourceType() {
return (isFollowedUser) ? User.RESOURCE_TYPE : otherVertex.get("sling:resourceType", String.class);
}
}