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.review.client.api.AbstractReviewCollection Maven / Gradle / Ivy
/*************************************************************************
*
* ADOBE CONFIDENTIAL
* __________________
*
* Copyright 2012 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.review.client.api;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.resource.NonExistingResource;
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.ValueMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.adobe.cq.social.commons.comments.api.AbstractCommentCollection;
import com.adobe.cq.social.commons.comments.api.CommentCollection;
import com.adobe.cq.social.commons.comments.api.CommentCollectionConfiguration;
import com.adobe.cq.social.commons.comments.listing.CommentSocialComponentListProviderManager;
import com.adobe.cq.social.scf.ClientUtilities;
import com.adobe.cq.social.scf.QueryRequestInfo;
import com.adobe.cq.social.scf.SocialComponentFactory;
import com.adobe.cq.social.scf.SocialComponentFactoryManager;
import com.adobe.cq.social.tally.client.api.ResponseValue;
import com.adobe.cq.social.tally.client.api.TallyException;
import com.adobe.cq.social.tally.client.api.RatingSocialComponent;
import com.adobe.cq.social.ugc.api.PathConstraint;
import com.adobe.cq.social.ugc.api.PathConstraintType;
import com.adobe.cq.social.ugc.api.SearchResults;
import com.adobe.cq.social.ugc.api.UgcFilter;
import com.adobe.cq.social.ugc.api.UgcSearch;
import com.adobe.cq.social.ugc.api.ValueConstraint;
import com.adobe.cq.social.ugcbase.SocialUtils;
public abstract class AbstractReviewCollection
extends AbstractCommentCollection implements ReviewCollectionSocialComponent {
protected final ResourceResolver resolver;
protected Resource ugcResource;
protected final String authorizableUserID;
protected Map ratings;
protected RatingSocialComponent overallRating;
private final UgcSearch search;
private List> allowedRatings;
private String[] requiredRatingTitles;
private boolean includeHistogram = false;
protected static final String NAME_KEY = "name";
protected static final String REQUIRED_KEY = "required";
/** Logger for this class. */
private static final Logger LOG = LoggerFactory.getLogger(AbstractReviewCollection.class);
/**
* Construct a {@link CommentCollection} using the specified {@link Resource} which should be the root of the
* collection.
* @param resource the resource where the CommentCollection
is located
* @param listProviderManager the list provider manager
* @param clientUtils the clientUtilities instance
*/
public AbstractReviewCollection(final Resource resource, final ClientUtilities clientUtils,
final CommentSocialComponentListProviderManager listProviderManager) {
this(resource, clientUtils, QueryRequestInfo.DEFAULT_QUERY_INFO_FACTORY.create(), listProviderManager);
}
public AbstractReviewCollection(final Resource resource, final ClientUtilities clientUtils,
final CommentSocialComponentListProviderManager listProviderManager, final UgcSearch search) {
this(resource, clientUtils, QueryRequestInfo.DEFAULT_QUERY_INFO_FACTORY.create(), listProviderManager, search);
}
public AbstractReviewCollection(final Resource resource, final ClientUtilities clientUtils,
final QueryRequestInfo queryInfo, final CommentSocialComponentListProviderManager listProviderManager) {
this(resource, clientUtils, queryInfo, listProviderManager, null);
}
/**
* Construct a {@link CommentCollection} using the specified {@link Resource} which should be the root of the
* collection with specified pagination for the children listing.
* @param resource the resource where the CommentCollection
is located
* @param clientUtils the clientUtilities instance
* @param queryInfo the query parameters, if any
* @param listProviderManager the list provider manager
* @param search the ugc search service
*/
public AbstractReviewCollection(final Resource resource, final ClientUtilities clientUtils,
final QueryRequestInfo queryInfo, final CommentSocialComponentListProviderManager listProviderManager,
final UgcSearch search) {
super(resource, clientUtils, queryInfo, listProviderManager);
this.resolver = resource.getResourceResolver();
String path = clientUtils.getSocialUtils().resourceToUGCStoragePath(resource);
this.ugcResource = resolver.getResource(path);
if (this.ugcResource == null) {
this.ugcResource = new NonExistingResource(resolver, path);
}
this.search = search;
this.authorizableUserID = getLoggedInUser();
this.ratings = getRatings(clientUtils);
this.overallRating = getOverallRating(clientUtils);
}
private RatingSocialComponent getOverallRating(final ClientUtilities clientUtils) {
final String overallRatingTitle =
(this.requiredRatingTitles == null) ? ReviewConstants.PATH_OVERALL_RATING : requiredRatingTitles[0];
Resource baseResource = ugcResource.getParent();
if (baseResource != null) {
// assume the first required rating is the overall rating or equivalent
baseResource = baseResource.getChild(this.resource.getName() + "_" + overallRatingTitle);
} else {
final Resource parentResource =
this.resolver.getResource(StringUtils.substringBeforeLast(ugcResource.getPath(), "/"));
if (parentResource != null) {
baseResource = parentResource.getChild(this.resource.getName() + "_" + overallRatingTitle);
} else {
baseResource = null;
}
}
return getRatingSocialComponentFromResource(baseResource, clientUtils);
}
public RatingSocialComponent getOverallRating() {
return this.overallRating;
}
private Map getRatings(final ClientUtilities clientUtils) {
final Map results = new HashMap();
final Resource parentResource = ugcResource.getParent();
Iterator children = Collections.emptyList().iterator();
if (parentResource != null) {
children = parentResource.getChildren().iterator();
} else {
// If a parent is not available use the ugcResource as it might be a dynamic include
// This should cause a list children to be invoked inside the SRP which will get all the children. Might
// need to change when we get
// atomic incrementers.
List ratingResources = new ArrayList();
String resourceName = StringUtils.substringAfterLast(ugcResource.getPath(), "/");
String resourceBasePath = StringUtils.substringBeforeLast(ugcResource.getPath(), "/");
List> ratings = getAllowedRatings();
// If we're using the new search constructors we can skip the slower iteration pattern and save some round
// trips
// to the storage layer.
if (search != null) {
UgcFilter resourceTypeAndParentFilter = new UgcFilter();
// final ConstraintGroup pathGroup = new ConstraintGroup();
// pathGroup.or(new PathConstraint(resourceBasePath, PathConstraintType.IsChildNode));
// pathGroup.or(new PathConstraint(StringUtils.substringBeforeLast(this.resource.getPath(), "/"),
// PathConstraintType.IsChildNode));
resourceTypeAndParentFilter.addConstraint(new PathConstraint(resourceBasePath,
PathConstraintType.IsDescendantNode));
ValueConstraint resourceTypeConstraint =
new ValueConstraint(SocialUtils.PN_SLING_RESOURCETYPE,
RatingSocialComponent.RATING_RESOURCE_TYPE);
resourceTypeAndParentFilter.addConstraint(resourceTypeConstraint);
try {
SearchResults childrenResources =
search.find(null, ugcResource.getResourceResolver(), resourceTypeAndParentFilter, 0,
ratings.size(), false);
ratingResources = childrenResources.getResults();
children = ratingResources.iterator();
} catch (final RepositoryException e) {
LOG.error("Could not perform search to find ratings for {}", ugcResource.getPath());
}
} else {
for (Map rating : ratings) {
final String childResourcePath = resourceBasePath + "/" + resourceName + "_" + rating.get("name");
Resource child = ugcResource.getResourceResolver().getResource(childResourcePath);
if (child != null) {
ratingResources.add(child);
}
}
children = ratingResources.iterator();
}
}
while (children.hasNext()) {
final Resource child = children.next();
if (resolver.isResourceType(child, RatingSocialComponent.RATING_RESOURCE_TYPE)) {
final String name = StringUtils.substringAfterLast(child.getName(), "_");
final RatingSocialComponent rating = getRatingSocialComponentFromResource(child, clientUtils);
results.put(name, rating);
}
}
return results;
}
private boolean isRatingAllowed(final String name) {
final List> allowed = getAllowedRatings();
for (final Map map : allowed) {
if (map != null && StringUtils.equals(map.get(NAME_KEY), name)) {
return true;
}
}
return false;
}
private RatingSocialComponent getRatingSocialComponentFromResource(final Resource resource,
final ClientUtilities clientUtils) {
if (resource != null) {
final SocialComponentFactoryManager scfMgr = clientUtils.getSocialComponentFactoryManager();
if (scfMgr != null) {
final SocialComponentFactory scf = scfMgr.getSocialComponentFactory(resource);
if (scf != null) {
return (RatingSocialComponent) scf.getSocialComponent(resource);
}
}
}
return null;
}
private String getLoggedInUser() {
if (this.resolver == null) {
return null;
}
return this.resolver.adaptTo(Session.class).getUserID();
}
@Override
public String getName() {
return getProperty(ReviewConstants.NAME_PROPERTY, String.class);
}
@Override
public Long getTotalNumberOfResponses() {
return new Long(getTotalSize());
}
@Override
public Map getCurrentUserResponse() throws TallyException, RepositoryException {
final Map results = new HashMap();
final ResponseValue comment = new ResponseValue() {
@Override
public String getResponseValue() {
return getCurrentUserComment();
}
};
results.put(ReviewConstants.KEY_COMMENT, comment);
if (overallRating != null && overallRating.getCurrentUserResponse() != null) {
results.put(overallRating.getName(), overallRating.getCurrentUserResponse());
return results;
} else {
return null;
}
}
private String getCurrentUserComment() {
// TODO: currently comment is not needed by client side
return "";
}
@Override
public Map getRatings() {
return ratings;
}
@Override
public Map getRatingAverages() {
final Map results = new LinkedHashMap();
for (final Map map : allowedRatings) {
if (map != null && map.get(NAME_KEY) != null) {
final String name = map.get(NAME_KEY);
if (ratings.get(name) != null) {
results.put(name, ratings.get(name).getFormattedAverageRating());
} else {
results.put(name, null);
}
}
}
return results;
}
private void buildAllowedRatings() {
Resource allowedRatingResource = null;
if (this.resource.isResourceType(ReviewConstants.REVIEW_SUMMARY_RESOURCE_TYPE)) {
final ValueMap summaryVM = ResourceUtil.getValueMap(this.resource);
if (summaryVM.containsKey(ReviewConstants.REVIEW_PATH_PROPERTY)) {
allowedRatingResource =
resolver.resolve((String) summaryVM.get(ReviewConstants.REVIEW_PATH_PROPERTY));
}
}
if (allowedRatingResource == null) {
allowedRatingResource = resolver.resolve(this.resource.getPath());
}
final ValueMap values =
(allowedRatingResource.adaptTo(ValueMap.class) != null) ? allowedRatingResource.adaptTo(ValueMap.class)
: clientUtils.getDesignProperties(allowedRatingResource, ReviewConstants.REVIEWS_RESOURCE_TYPE);
final String[] ratings =
values.get(ReviewConstants.ALLOWED_RATINGS_PROPERTY, new String[]{ReviewConstants.PATH_OVERALL_RATING});
this.allowedRatings = new ArrayList>(ratings.length);
this.requiredRatingTitles =
values.get(ReviewConstants.REQUIRED_RATINGS_PROPERTY, new String[]{ReviewConstants.PATH_OVERALL_RATING});
final List requiredList = Arrays.asList(requiredRatingTitles);
for (final String subrating : ratings) {
final Map map = new HashMap(2);
map.put(NAME_KEY, subrating);
if (requiredList.contains(subrating)) {
map.put(REQUIRED_KEY, "true");
}
this.allowedRatings.add(map);
}
}
@Override
public List> getAllowedRatings() {
if (null == this.allowedRatings) {
this.buildAllowedRatings();
}
return this.allowedRatings;
}
@Override
public boolean isCompositeRating() {
if (getAllowedRatings() == null) {
return false;
}
return getAllowedRatings().size() != 1;
}
@Override
public boolean isIncludeHistogram() {
return includeHistogram;
}
protected void setIncludeHistogram(final boolean include) {
includeHistogram = include;
}
}