Java tutorial
/* * 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, "/")); } } }