All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.adobe.cq.social.scf.core.AbstractUser 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.scf.core;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import javax.jcr.RepositoryException;
import javax.jcr.ValueFormatException;

import org.apache.commons.lang3.StringUtils;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.security.user.UserManager;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
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.badging.api.BadgingService;
import com.adobe.cq.social.badging.api.UserBadge;
import com.adobe.cq.social.community.api.CommunityContext;
import com.adobe.cq.social.scf.ClientUtilities;
import com.adobe.cq.social.scf.User;
import com.adobe.cq.social.scoring.api.ScoringService;
import com.adobe.cq.social.ugcbase.CollabUser;
import com.adobe.cq.social.ugcbase.SocialUtils;
import com.adobe.cq.social.ugcbase.SocialUtils.AVATAR_SIZE;
import com.adobe.cq.social.ugcbase.core.SocialResourceUtils;
import com.adobe.granite.security.user.UserProperties;
import com.adobe.granite.security.user.UserPropertiesManager;
import com.day.cq.wcm.api.Page;

public abstract class AbstractUser extends BaseSocialComponent implements User {
    /** Default avatar path. */
    static final String DEFAULT_AVATAR_PATH = SocialUtils.DEFAULT_AVATAR;
    private static final Logger LOG = LoggerFactory.getLogger(AbstractUser.class);

    private static final String PN_NUMBER_OF_POSTS = "numberOfPosts";

    private static final String FORUM_PATH = "forum";

    private static final String HTML_EXT = ".html";

    private static final String PROFILE_PATH = "profile";

    private static final String JCR_TITLE_PROP = "jcr:title";
    private static final String DISPLAY_NAME_PROP = "displayName";
    private static final String PROPERTY_LIMIT_USER_UGC = "limitUserUGC";

    private UserProperties userProps;

    private Authorizable user;

    private String name;
    private String avatarPath;
    private String userId;
    private String largeAvatarPath;
    private ScoringService scoring;
    private String profileUrl;
    private BadgingService badging;

    /**
     * Create a user based on the resource. The resource should be User.SOCIAL_AUTHORS_PREFIX + /userid.
     * @param resource the resource to try and get a User for
     * @param clientUtils client utils used for the social component
     * @param upm user properties manager for getting profile details
     * @param scoring used to determine badging in real time.
     */
    @Deprecated
    public AbstractUser(final Resource resource, final ClientUtilities clientUtils, final UserPropertiesManager upm,
        @Nullable final ScoringService scoring) {
        this(resource, clientUtils, upm);
        this.scoring = scoring;
    }

    /**
     * Create a user based on the resource. The resource should be User.SOCIAL_AUTHORS_PREFIX + /userid.
     * @param resource the resource to try and get a User for
     * @param clientUtils client utils used for the social component
     * @param upm user properties manager for getting profile details
     * @param scoring used to determine scoring in real time.
     * @param badging used to determine badging in real time.
     */
    public AbstractUser(final Resource resource, final ClientUtilities clientUtils, final UserPropertiesManager upm,
        @Nullable final ScoringService scoring, @Nullable final BadgingService badging) {
        this(resource, clientUtils, upm);
        this.scoring = scoring;
        this.badging = badging;
    }

    private boolean initialized = false;
    private final UserPropertiesManager upm;

    private void init() {
        if (initialized) {
            return;
        }
        initialized = true;
        try {
            userProps = getUserProperties(resource, upm);
        } catch (final RepositoryException e) {
            LOG.warn("Unable to get user properties from resource ", e);
        }

        if (null == userProps) {
            LOG.debug("Unable to get user properties from resource {}.  Setting up Anonymous User.",
                resource.getPath());
            setUpDefaults();
        } else {
            String avatarpath = clientUtils.externalLink(DEFAULT_AVATAR_PATH);
            String largeAvatarpath = avatarpath;
            this.name = CollabUser.ANONYMOUS;
            this.userId = userProps.getAuthorizableID();
            if (this.userId != null && this.userId.length() > 0) {
                avatarpath = clientUtils.getSocialUtils().getAvatar(userProps, avatarpath);
                largeAvatarpath =
                    clientUtils.getSocialUtils().getAvatar(userProps, largeAvatarpath, AVATAR_SIZE.FOURTY_EIGHT);
                try {
                    this.name = userProps.getDisplayName();
                } catch (final RepositoryException e) {
                    LOG.error("Unable to get username for {}", userId, e);
                }
            }

            final UserManager userManager = resource.adaptTo(UserManager.class);
            if (userManager != null) {
                try {
                    user = userManager.getAuthorizable(userId);
                } catch (final RepositoryException e) {
                    LOG.warn("Unable to get jackrabbit user from userId {}", userId, e);
                }
            } else {
                LOG.warn("Unable to adapt resource [{}] to UserManager", resource.getPath());
            }
            this.avatarPath = avatarpath;
            this.largeAvatarPath = largeAvatarpath;
        }
    }

    /**
     * Create a user based on the resource. The resource should be User.SOCIAL_AUTHORS_PREFIX + /userid.
     * @param resource the resource to try and get a User for
     * @param clientUtils client utils used for the social component
     * @param upm user properties manager for getting profile details
     */
    public AbstractUser(final Resource resource, final ClientUtilities clientUtils, final UserPropertiesManager upm) {
        super(resource, clientUtils);
        this.upm = upm;
        init();
    }

    private void setUpDefaults() {
        this.userId = "anonymous";
        this.avatarPath = DEFAULT_AVATAR_PATH;
        this.largeAvatarPath = DEFAULT_AVATAR_PATH;
        this.name = "Unknown";

    }

    @CheckForNull
    private UserProperties getUserProperties(final Resource resource, final UserPropertiesManager upm)
        throws RepositoryException {

        final String resourcePath = resource.getPath();
        if (StringUtils.contains(resourcePath, User.SOCIAL_AUTHORS_PREFIX)) {
            final String userId = resourcePath.substring(resourcePath.lastIndexOf("/") + 1);
            return clientUtils.getUserProperties(userId, PROFILE_PATH);
        }

        return null;
    }

    @Override
    public String getName() {
        init();
        return this.name;
    }

    @Override
    public String getAvatarUrl() {
        init();
        if (this.clientUtils == null) {
            return this.avatarPath;
        }
        if (this.avatarPath.contains("www.gravatar.com/avatar/")) {
            return this.avatarPath;
        }
        return this.clientUtils.externalLink(this.avatarPath, false);
    }

    @Override
    public String getLargeAvatarUrl() {
        init();
        if (this.clientUtils == null) {
            return this.largeAvatarPath;
        }
        if (this.avatarPath.contains("www.gravatar.com/avatar/")) {
            return this.avatarPath;
        }
        return this.clientUtils.externalLink(this.largeAvatarPath, false);
    }

    @Override
    public String getAuthorizableId() {
        init();
        return this.userId;
    }

    @Override
    public String getPath() {
        init();
        String path = null;
        if (user != null) {
            try {
                path = user.getPath();
            } catch (final RepositoryException e) {
                LOG.error("Unable to get the user's path.", e);
            }
        }
        return path;
    }

    @Override
    public String getUserId() {
        init();
        return this.userId;
    }

    @Override
    public String getProfileUrl() {
        init();
        if (profileUrl == null) {
            String result = "";
            if (clientUtils.getRequest() != null) {
                final String socialProfilePage = clientUtils.getSocialProfilePath();
                if (!(userProps == null || StringUtils.isEmpty(socialProfilePage))) {
                    Resource resource = clientUtils.getRequest().getResource();
                    String profilePath;
                    if (socialProfilePage.startsWith("/")) {
                        profilePath = socialProfilePage + HTML_EXT;
                    } else {
                        String contentPath = clientUtils.getSocialUtils().UGCToResourcePath(resource);
                        if (!StringUtils.equals(contentPath, resource.getPath())) {
                            contentPath = clientUtils.getSocialUtils().getPagePath(contentPath);
                            final Resource content = resource.getResourceResolver().getResource(contentPath);
                            if (content != null) {
                                resource = content;
                            }
                        }
                        final CommunityContext communityContext = resource.adaptTo(CommunityContext.class);
                        if (communityContext != null && communityContext.getSiteId() != null) {
                            profilePath = communityContext.getSitePagePath() + "/" + socialProfilePage + HTML_EXT;
                        } else {
                            profilePath = resource.getPath() + "/" + socialProfilePage + HTML_EXT;
                        }
                    }
                    try {
                        final String url = profilePath + userProps.getNode().getPath();
                        result = clientUtils.externalLink(url, false);
                    } catch (final RepositoryException e) {
                        LOG.error("Error retrieving profile url for " + userProps.getAuthorizableID(), e);
                        result = null;
                    }
                }
                profileUrl = result;
            }
        }
        return profileUrl;
    }

    @Override
    public String getFriendlyUrl() {
        return getProfileUrl();
    }

    @Override
    @Deprecated
    public Long getNumberOfPosts() {
        init();
        if (userProps == null) {
            return 0L;
        }
        Resource profileResource;
        try {
            profileResource = userProps.getResource(FORUM_PATH);
        } catch (final RepositoryException e) {
            LOG.error("Error retrieving post count for " + userProps.getAuthorizableID(), e);
            return 0L;
        }
        if (null != profileResource) {
            final ValueMap props = ResourceUtil.getValueMap(profileResource);
            return props.get(PN_NUMBER_OF_POSTS, 0L);
        }
        return 0L;
    }

    @Override
    public List getBadges() {
        init();
        final List badges = new ArrayList();

        if (badging == null) {
            LOG.debug("No reference to BadgingService");
            return badges;
        }

        // get the request, so we can look up the requesting resource
        final SlingHttpServletRequest request = clientUtils.getRequest();
        if (request == null) {
            LOG.debug("AbstractUser object has no request object.");
            return badges;
        }

        // get requesting resource, and not this synthetic user resource
        Resource compResource = clientUtils.getRequest().getResource();
        if (compResource == null) {
            LOG.debug("Request has no resource");
            return badges;
        }

        ValueMap compVM = compResource.getValueMap();
        if (compVM == null) {
            LOG.debug("Component has no ValueMap {}", compResource.getPath());
            return badges;
        }

        // check if component has allowBadges flag before looking up badges
        if (!compVM.get(BadgingService.ALLOW_BADGES_PROP, false)) {
            // not in current resource but check CommentSystem root, if any. e.g. a forum post resource is not the
            // forum component.
            final String csRoot = compVM.get(SocialUtils.PN_CS_ROOT, String.class);
            if (csRoot == null) {
                return badges;
            }
            compResource = compResource.getResourceResolver().getResource(csRoot);
            if (compResource == null) {
                return badges;
            }
            compVM = compResource.getValueMap();
            if (!compVM.get(BadgingService.ALLOW_BADGES_PROP, false)) {
                return badges;
            }
            // if we get here, it means the CS Root has the allowBadges property set to true
        }

        final Page badgeMapContainingPage = clientUtils.getContainingPage("");
        if (badgeMapContainingPage == null) {
            LOG.debug("Component has not containing Page {}", compResource.getPath());
            return badges;
        }

        final Resource pageResource;
        if (compVM.get(BadgingService.FILTER_BY_COMP_PROP, true)) {
            pageResource = compResource.getResourceResolver().getResource(badgeMapContainingPage.getPath());
        } else {
            pageResource = null;
        }

        try {
            final List userBadges =
                badging.getBadges(compResource.getResourceResolver(), this.userId, pageResource, null,
                    BadgingService.ALL_TOP_BADGES);

            for (final UserBadge badge : userBadges) {
                final String title;

                String displayName = null;
                final String badgeImagePath = badge.getImagePath();

                final Page badgePage = clientUtils.getContainingPage(badgeImagePath);
                // if badge is contained in a page, get the title from the Page (old badge content format)
                if (badgePage != null) {
                    displayName = badgePage.getTitle();
                } else {
                    // new format - image is not enclosed in a Page,
                    // so get the image's parent resource and look for displayName or title
                    final Resource badgeImageResource =
                        compResource.getResourceResolver().getResource(badgeImagePath);

                    if (badgeImageResource != null) {
                        final Resource badgeParent = badgeImageResource.getParent();
                        if (badgeParent != null) {
                            displayName = badgeParent.getValueMap().get(DISPLAY_NAME_PROP, String.class);
                            if (displayName == null) {
                                displayName = badgeParent.getValueMap().get(JCR_TITLE_PROP, String.class);
                            }
                        }
                    }
                }

                if (displayName != null) {
                    title = displayName;
                } else {
                    LOG.debug("Badge image {} has no title or display name.", badgeImagePath);
                    title = "";
                }

                badges.add(new Badge() {
                    @Override
                    public String getTitle() {
                        return title;
                    }

                    @Override
                    public String getImageUrl() {
                        return clientUtils.externalLink(badgeImagePath, false);
                    }

                    @Override
                    public boolean getIsAssigned() {
                        return badge.isAssigned();
                    }

                });
            }
        } catch (final RepositoryException e) {
            LOG.error("Error looking up user badges", e);
        }

        return badges;
    }

    @Override
    public Boolean getDisabled() {
        init();
        if (user != null && user instanceof org.apache.jackrabbit.api.security.user.User) {
            try {
                return ((org.apache.jackrabbit.api.security.user.User) user).isDisabled();
            } catch (final RepositoryException e) {
                return false;
            }
        } else {
            return false;
        }
    }

    @Override
    public Boolean isUserUGCLimited() {
        init();
        if (user != null) {
            try {
                if (user.hasProperty(PROPERTY_LIMIT_USER_UGC)) {
                    return Boolean.valueOf(user.getProperty(PROPERTY_LIMIT_USER_UGC)[0].getBoolean());
                } else {
                    return false;
                }
            } catch (ValueFormatException e) {
                LOG.error("Error fetching the value of property {} of user {}", PROPERTY_LIMIT_USER_UGC, name);
                return false;
            } catch (RepositoryException e) {
                LOG.error("Error fetching the value of property {} of user {}", PROPERTY_LIMIT_USER_UGC, name);
                return false;
            }
        } else {
            return false;
        }
    }

    @Override
    public String getDisabledReason() {
        init();
        if (user != null && user instanceof org.apache.jackrabbit.api.security.user.User) {
            try {
                return ((org.apache.jackrabbit.api.security.user.User) user).getDisabledReason();
            } catch (final RepositoryException e) {
                return null;
            }
        } else {
            return null;
        }
    }

    /**
     * @return  UserProperties the {@link com.adobe.granite.security.user.UserProperties} object associated with the the user that is represented by this instance.
     */
    protected UserProperties getUserProperties() {
        init();
        return userProps;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy