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

com.adobe.cq.social.srp.utilities.internal.InternalStaticResourceUtilities Maven / Gradle / Ivy

There is a newer version: 6.5.21
Show newest version
/*************************************************************************
 *
 * 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.srp.utilities.internal;

import javax.jcr.AccessDeniedException;
import javax.jcr.InvalidItemStateException;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;

import org.apache.commons.lang3.StringUtils;
import org.apache.jackrabbit.commons.JcrUtils;
import org.apache.jackrabbit.util.Text;
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.ResourceWrapper;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.util.tracker.ServiceTracker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.adobe.cq.social.srp.SocialResource;
import com.adobe.cq.social.srp.config.SRPConfigurationFactory;
import com.adobe.granite.security.user.UserProperties;
import com.adobe.granite.security.user.UserPropertiesManager;

public class InternalStaticResourceUtilities implements BundleActivator {

    private static String GRAVATAR_PREFIX = "http://www.gravatar.com/avatar/";

    private static final Logger LOG = LoggerFactory.getLogger(InternalStaticResourceUtilities.class);
    private static ServiceTracker tracker;

    /**
     * Don't ever instantiate this class.
     */
    private InternalStaticResourceUtilities() {
    }

    /**
     * Checks a path and an action based on the passed in resolver.
     * @param resolver the resource resolver to use to evaluate the permissions
     * @param path the path to the resource to check
     * @param action the action to check
     * @return True if the resolver is allowed to take the requested action, otherwise false
     */
    public static Boolean checkPermission(final ResourceResolver resolver, final String path, final String action) {
        if (StringUtils.isEmpty(path)) {
            return false;
        }
        try {
            final Session userSession = resolver.adaptTo(Session.class);
            return userSession.hasPermission(path, action);
        } catch (final RepositoryException e) {
            return checkPermission(resolver, StringUtils.substringBeforeLast(path, "/"), action);
        }
    }

    /**
     * Returns the user properties denoted by the given userId. The user props are looked for using the
     * provided resource resolver, so as to ensure that the user properties are only accessible to users having the
     * necessary access rights on the requested user properties.
     * @param resolver The {@link ResourceResolver}.
     * @param userId The user id for which to retrieve the user properties.
     * @return The {@link UserProperties} or null if not found.
     */
    public static UserProperties getUserProperties(final ResourceResolver resolver, final String userId) {
        UserProperties userProperties = null;
        final UserPropertiesManager upm = resolver.adaptTo(UserPropertiesManager.class);
        if (null != upm && null != userId) {
            try {
                userProperties = upm.getUserProperties(userId, "profile");
            } catch (final RepositoryException e) {
                LOG.warn("User cannot access the profile.", e);
            }
        }
        return userProperties;
    }

    /**
     * Check if path is non JCR based. Assume that all alternate storage paths have prefix
     * {@value com.adobe.cq.social.srp.utilities.internal.InternalSocialResourceUtilities#ASI_UGC_PREFIX}, which is enforced in the cloudconfig UI.
     * @param path the path to the ugc resource
     * @return true if path is of alternate storage type (non jcr)
     */
    public static boolean isCloudUGC(final String path) {
        return StringUtils.startsWith(path, InternalSocialResourceUtilities.ASI_UGC_PREFIX);
    }

    /**
     * Check if a given resource is an instance of SocialResource.
     * @param res the resource to check
     * @return true if resource is a SocialResource
     */
    public static boolean isSocialResource(final Resource res) {
        if (res instanceof SocialResource) {
            return true;
        } else if (res instanceof ResourceWrapper) {
            return isSocialResource(((ResourceWrapper) res).getResource());
        } else {
            return false;
        }
    }

    /**
     * Check if a resource is a wrapped resource, and unwrap until a SocialResource is found.
     * @param res resource to unwrap
     * @return an unwrap resource or null if no SocialResource found
     */
    public static SocialResource getSocialResource(final Resource res) {
        if (res == null) {
            return null;
        }
        if (res instanceof SocialResource) {
            return (SocialResource) res;
        } else if (res instanceof ResourceWrapper) {
            return getSocialResource(((ResourceWrapper) res).getResource());
        } else if (res instanceof NonExistingResource) {
            LOG.warn("Resource {} is a NonExistingResource, returning null", res);
            return null;
        } else {
            LOG.debug("Resource {} is unknown resource type, returning null", res);
            return null;
        }
    }

    /**
     * Check to see if the specified exception caused by a jcr InvalidItemStateException. This exception is thrown if
     * any of the changes to be persisted conflicts with a change already persisted through another session and the
     * implementation is such that this conflict can only be detected at save-time and therefore was not detected
     * earlier, at change-time.
     * @param e The exception
     * @return if caused by InvalidItemStateException
     */
    public static boolean causeByInvalidItemStateException(final Exception e) {
        Throwable cause = e;
        do {
            if (cause instanceof InvalidItemStateException) {
                return true;
            }
            cause = cause.getCause();
        } while (cause != null);
        return false;
    }

    /**
     * Creates or gets the {@link javax.jcr.Node Node} at the given path. In case it has to create the Node all
     * non-existent intermediate path-elements will be created with the given intermediate node type and the returned
     * node will be created with the given nodeType. This version exists to ensure creation only needs to read and
     * write the deepest of the existing ancestors of the target node. This allows creation of paths where some
     * ancestors exist but are not readable by the session in use. For further details see: {@link
     * org.apache.jackrabbit.commons.JcrUtils#getOrCreateByPath(Node, String, boolean, String, String, boolean) }
     * @param path the deep path to get or create
     * @param createUniqueLeaf not used?
     * @param intermediateNodeType node type to be used in creating any required intermediate nodes
     * @param nodeType the node type for the leaf node
     * @param session the session to create the nodes with
     * @param autoSave to save when done
     * @return the create leaf node
     * @throws RepositoryException when JCR cannot create either any of the intermediate nodes or the leaf node
     */
    public static Node getOrCreateByPathDepthFirst(final String path, final boolean createUniqueLeaf,
        final String intermediateNodeType, final String nodeType, final Session session, final boolean autoSave)
        throws RepositoryException {

        String workingPath = path.startsWith("/") ? path : ("/" + path);
        if (workingPath.endsWith("/")) {
            workingPath = workingPath.substring(0, workingPath.length() - 1);
        }
        String checkPath = Text.getRelativeParent(workingPath, 1);
        Node base = null;
        do {
            if (session.nodeExists(checkPath)) {
                base = session.getNode(checkPath);
                break;
            }
            checkPath = Text.getRelativeParent(checkPath, 1);
        } while (!checkPath.isEmpty() && !"/".equals(checkPath));

        if (base == null) {
            try {
                base = session.getRootNode();
            } catch (final AccessDeniedException ade) {
                throw new AccessDeniedException("Failed to access root node for the creation of " + path, ade);
            }
        }
        String createPath = workingPath.substring(checkPath.length());
        if (createPath.startsWith("/")) {
            createPath = createPath.substring(1);
        }
        return JcrUtils.getOrCreateByPath(base, createPath, false, intermediateNodeType, nodeType, autoSave);
    }

    @Override
    public void start(final BundleContext context) throws Exception {
        synchronized (InternalStaticResourceUtilities.class) {
            if (tracker == null) {
                tracker = new ServiceTracker(context, SRPConfigurationFactory.class.getName(), null);
                tracker.open();
            }
        }
    }

    @Override
    public synchronized void stop(final BundleContext context) throws Exception {
        synchronized (InternalStaticResourceUtilities.class) {
            if (tracker != null) {
                tracker.close();
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy