com.activecq.experiments.redis.impl.RedisResourceProviderImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.activecq.experiments.redis.impl.RedisResourceProviderImpl.java

Source

/*
 * Copyright 2013 david gonzalez.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.activecq.experiments.redis.impl;

import com.activecq.experiments.redis.RedisUtil;
import com.activecq.experiments.redis.RedisResource;
import org.apache.commons.lang.StringUtils;
import org.apache.felix.scr.annotations.*;
import org.apache.felix.scr.annotations.Properties;
import org.apache.jackrabbit.JcrConstants;
import org.apache.sling.api.resource.*;
import org.apache.sling.commons.osgi.PropertiesUtil;
import org.osgi.framework.Constants;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 *
 * @author david
 */
@Component(label = "Experiments - Sling Resource Provider for Redis", description = "Sling Resource Provider for Redis", metatype = false, immediate = false)
@Properties({
        @Property(label = "Vendor", name = Constants.SERVICE_VENDOR, value = "ActiveCQ", propertyPrivate = true),
        @Property(label = "Root paths", description = "Root paths this Sling Resource Provider will respond to", name = ResourceProvider.ROOTS, value = {
                "/var/redis" }) })
@Service
public class RedisResourceProviderImpl implements ResourceProvider {
    private final Logger log = LoggerFactory.getLogger(this.getClass());

    private static final String DEFAULT_PRIMARY_TYPE = JcrConstants.NT_UNSTRUCTURED;
    private static final String DEFAULT_RESOURCE_TYPE = "redis";
    private List<String> roots;

    @Reference
    private RedisUtil redis;

    @Override
    public Resource getResource(ResourceResolver resourceResolver, HttpServletRequest request, String path) {
        // For this example the Request is not taken into consideration when evaluating
        // the Resource request, so we just call getResource(rr, path)

        // Remember, since this is a Synthetic resource there are no ACLs applied to this
        // resource. If you would like to restrict access, it must be done programmatically by checking
        // the ResourceResolver's user.
        return getResource(resourceResolver, path);
    }

    @Override
    public Resource getResource(ResourceResolver resourceResolver, String path) {
        return getResource(resourceResolver, path, DEFAULT_RESOURCE_TYPE);
    }

    public Resource getResource(ResourceResolver resourceResolver, String path, String resourceType) {
        // Make getResource() return as fast as possible!
        // Return null early if getResource() cannot/should not process the resource request

        // Check the user/group issuing the resource resolution request
        if (!accepts(resourceResolver)) {
            return null;
        }

        // Reject any paths that do not match the roots
        if (!accepts(path)) {
            return null;
        }

        // If path is a root, return a Synthetic Folder
        // This could be any "type" of Synthetic Resource
        if (isRoot(path)) {
            return new SyntheticResource(resourceResolver, path, JcrConstants.NT_FOLDER);
        }

        // If path does not exist in Redis, then return null immediately
        if (!redis.exists(path)) {
            return null;
        }

        Map<String, String> redisMap = setDefaultProperties(new HashMap<String, String>());
        redisMap.putAll((Map<String, String>) redis.get(path));

        final ResourceMetadata resourceMetaData = new ResourceMetadata();
        resourceMetaData.setResolutionPath(path);

        return new RedisResource(resourceResolver, resourceMetaData, resourceType, redisMap);
    }

    @Override
    public Iterator<Resource> listChildren(Resource parent) {
        final String path = parent.getPath();

        // Check the user/group issuing the resource resolution request
        if (!accepts(parent.getResourceResolver())) {
            return null;
        }

        // Reject any paths that do not match the roots
        if (!accepts(path)) {
            return null;
        }

        final ResourceResolver resourceResolver = parent.getResourceResolver();
        final List<Resource> children = new ArrayList<Resource>();

        final Set<String> redisChildren = redis.getChildren(path);
        for (final String redisChild : redisChildren) {
            final Resource resource = this.getResource(resourceResolver, redisChild, RESOURCE_TYPE_SYNTHETIC);

            if (resource != null) {
                children.add(resource);
            }
        }

        return children.iterator();
    }

    /**
     * Checks if the provided path is a defined Root path
     *
     * @param path
     * @return
     */
    protected boolean isRoot(String path) {
        for (String root : this.roots) {
            if (StringUtils.equals(path, root)) {
                return true;
            }
        }

        return false;
    }

    /**
     * Checks if this Resource Provider is willing to handle the resource path
     *
     * @param path
     * @return
     */
    protected boolean accepts(String path) {
        for (String root : this.roots) {
            if (StringUtils.startsWith(path, root.concat("/")) || this.isRoot(path)) {
                return true;
            }
        }

        return false;
    }

    /**
     * Checks if this Resource Provider is willing to handle the resolution request
     *
     * @param resourceResolver
     * @return
     */
    protected boolean accepts(ResourceResolver resourceResolver) {
        if (resourceResolver == null) {
            return false;
        }
        if (StringUtils.equals("anonymous", resourceResolver.getUserID())) {
            return false;
        }

        return true;
    }

    /**
     *
     * @param redisMap
     * @return
     */
    protected String getResourceType(Map<String, String> redisMap) {
        //if(redisMap.containsKey(JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY)) {
        //   return redisMap.get(JcrResourceConstants.SLING_RESOURCE_SUPER_TYPE_PROPERTY);
        //}

        return DEFAULT_RESOURCE_TYPE;
    }

    /**
     *
     * @return
     */
    protected String getWorkspace() {
        return redis.getWorkspace();
    }

    /**
     *
     * @param redisMap
     * @return
     */
    protected Map<String, String> setDefaultProperties(Map<String, String> redisMap) {
        if (!redisMap.containsKey(JcrConstants.JCR_PRIMARYTYPE)) {
            redisMap.put(JcrConstants.JCR_PRIMARYTYPE, DEFAULT_PRIMARY_TYPE);
        }

        /*
        if(!redisMap.containsKey(JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY)) {
        redisMap.put(JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY, DEFAULT_RESOURCE_TYPE);
        }
        */

        return redisMap;
    }

    /**
     * OSGi Component Methods *
     */
    @Activate
    protected void activate(final ComponentContext componentContext) throws Exception {
        configure(componentContext);
    }

    @Deactivate
    protected void deactivate(ComponentContext ctx) {
        this.roots = new ArrayList<String>();
    }

    private void configure(final ComponentContext componentContext) {
        final Map<String, String> properties = (Map<String, String>) componentContext.getProperties();

        // Get Roots from Service properties
        this.roots = new ArrayList<String>();

        String[] rootsArray = PropertiesUtil.toStringArray(properties.get(ResourceProvider.ROOTS), new String[] {});
        for (String root : rootsArray) {
            root = StringUtils.strip(root);
            if (StringUtils.isBlank(root)) {
                continue;
            } else if (StringUtils.equals(root, "/")) {
                // Cowardly refusing to mount the root
                continue;
            }

            this.roots.add(StringUtils.removeEnd(root, "/"));
        }
    }
}