You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 09:59:35 UTC

[sling-org-apache-sling-resourceresolver] 05/47: SLING-2396 : Add new resourceresolver project

This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.resourceresolver-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-resourceresolver.git

commit 2f0f1e52299ea485f2e5e7ad5531be9c6dc457b2
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Fri Jun 15 17:57:49 2012 +0000

    SLING-2396 : Add new resourceresolver project
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/resourceresolver@1350717 13f79535-47bb-0310-9956-ffa450edef68
---
 .../impl/helper/ResourceResolverContext.java       | 116 ++++++++++++
 .../impl/helper/SortedProviderList.java            | 208 +++++++++++++++++++++
 .../impl/tree/ResourceProviderFactoryHandler.java  | 169 +++++++++++++++++
 .../impl/tree/ResourceProviderHandler.java         |  99 ++++++++++
 4 files changed, 592 insertions(+)

diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverContext.java b/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverContext.java
new file mode 100644
index 0000000..dfabaa0
--- /dev/null
+++ b/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverContext.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The SF licenses this file
+ * to you 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 org.apache.sling.resourceresolver.impl.helper;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.sling.api.resource.DynamicResourceProvider;
+import org.apache.sling.api.resource.ResourceProvider;
+
+/**
+ * This class keeps track of the used resource providers for a
+ * resource resolver.
+ * Like a resource resolver itself, this class is not thread safe.
+ */
+public class ResourceResolverContext {
+
+    /** A map of all used providers created by a factory. */
+    private final Map<Long, ResourceProvider> providers = new HashMap<Long, ResourceProvider>();
+
+    /** A set of all dynamic providers (for closing them later on) */
+    private final Set<DynamicResourceProvider> dynamicProviders = new HashSet<DynamicResourceProvider>();
+
+    /** Is this a resource resolver for an admin? */
+    private final boolean isAdmin;
+
+    /**
+     * The original authentication information - this is used for cloning and lazy logins.
+     */
+    private final Map<String, Object> originalAuthInfo;
+
+    /**
+     * Create a new resource resolver context.
+     */
+    public ResourceResolverContext(final boolean isAdmin, final Map<String, Object> originalAuthInfo) {
+        this.isAdmin = isAdmin;
+        this.originalAuthInfo = originalAuthInfo;
+    }
+
+    /**
+     * Is this an admin resource resolver.
+     */
+    public boolean isAdmin() {
+        return this.isAdmin;
+    }
+
+    /**
+     * Return the authentication info.
+     */
+    public Map<String, Object> getAuthenticationInfo() {
+        return this.originalAuthInfo;
+    }
+
+    /**
+     * Add a new resource provider
+     * @param key      The unique key of the provider
+     * @param provider The provider.
+     */
+    public void addFactoryResourceProvider(final Long key, final ResourceProvider provider) {
+        this.providers.put(key, provider);
+        if (provider instanceof DynamicResourceProvider) {
+            this.dynamicProviders.add((DynamicResourceProvider) provider);
+        }
+    }
+
+    /**
+     * Return a resource provider for a given key
+     * @param key The unique key of a provider
+     * @return The resource provider or <code>null</code>
+     */
+    public ResourceProvider getFactoryResourceProvider(final Long key) {
+        return this.providers.get(key);
+    }
+
+    /**
+     * Check all active dynamic resource providers.
+     */
+    public boolean isLive() {
+        boolean result = true;
+        for (final DynamicResourceProvider provider : this.dynamicProviders) {
+            if (!provider.isLive()) {
+                result = false;
+                break;
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Close all dynamic resource providers.
+     */
+    public void close() {
+        for (final DynamicResourceProvider provider : this.dynamicProviders) {
+            provider.close();
+        }
+        this.dynamicProviders.clear();
+        this.providers.clear();
+    }
+}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/helper/SortedProviderList.java b/src/main/java/org/apache/sling/resourceresolver/impl/helper/SortedProviderList.java
new file mode 100644
index 0000000..c2fb142
--- /dev/null
+++ b/src/main/java/org/apache/sling/resourceresolver/impl/helper/SortedProviderList.java
@@ -0,0 +1,208 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.sling.resourceresolver.impl.helper;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import org.apache.sling.resourceresolver.impl.tree.ResourceProviderFactoryHandler;
+import org.apache.sling.resourceresolver.impl.tree.ResourceProviderHandler;
+
+/**
+ * Helper class to get a sorted list of resource providers which implement
+ * a specific feature interface.
+ */
+//TODO - Implement sorting
+public class SortedProviderList<T> {
+
+    /** The feature interface class. */
+    private final Class<T> genericClass;
+
+    /** Sorted list of providers and factories. */
+    private Entry[] sortedList = new Entry[0];
+
+    /**
+     * We need the class to do the instanceof test for providers
+     * returned by the factory.
+     */
+    public SortedProviderList(final Class<T> genericClass) {
+        this.genericClass = genericClass;
+    }
+
+    /**
+     * Return an iterator for the current sorted list of providers
+     * implementing the feature interface.
+     */
+    public Iterator<T> getProviders(final ResourceResolverContext ctx) {
+        return new Iterator<T>() {
+
+            private final Entry[] list = sortedList;
+
+            private int index = 0;
+
+            private Object nextObject = seek();
+
+            private Object seek() {
+                Object result;
+                if ( this.index < list.length ) {
+                    result = list[this.index].object;
+                    this.index++;
+                    if ( result instanceof ResourceProviderFactoryHandler ) {
+                        result = ((ResourceProviderFactoryHandler)result).getResourceProvider(ctx);
+                        if ( !genericClass.isAssignableFrom(result.getClass())) {
+                            result = null;
+                        }
+                        if ( result == null ) {
+                            result = seek();
+                        }
+                    }
+                } else {
+                    result = null;
+                }
+                return result;
+            }
+
+            /**
+             * @see java.util.Iterator#hasNext()
+             */
+            public boolean hasNext() {
+                return this.nextObject != null;
+            }
+
+            /**
+             * @see java.util.Iterator#next()
+             */
+            @SuppressWarnings("unchecked")
+            public T next() {
+                if ( this.nextObject == null ) {
+                    throw new NoSuchElementException();
+                }
+                final Object result = this.nextObject;
+                this.nextObject = seek();
+                return (T)result;
+            }
+
+            /**
+             * @see java.util.Iterator#remove()
+             */
+            public void remove() {
+                throw new UnsupportedOperationException();
+            }
+        };
+    }
+
+    /**
+     * Add an object to the list
+     */
+    private synchronized void addToList(final Object obj,
+                    final String[] roots,
+                    final Long serviceId) {
+        final List<Entry> list = new ArrayList<Entry>();
+        list.addAll(Arrays.asList(this.sortedList));
+        list.add(new Entry(obj, roots, serviceId));
+        Collections.sort(list);
+        this.sortedList = list.toArray(new Entry[list.size()]);
+    }
+
+    /**
+     * Remove an object from the list
+     */
+    private synchronized void removeFromList(final Object obj) {
+        final List<Entry> list = new ArrayList<Entry>();
+        list.addAll(Arrays.asList(this.sortedList));
+        final Iterator<Entry> i = list.iterator();
+        while ( i.hasNext() ) {
+            final Entry entry = i.next();
+            if ( entry.object.equals(obj) ) {
+                i.remove();
+                break;
+            }
+        }
+        this.sortedList = list.toArray(new Entry[list.size()]);
+    }
+
+    /**
+     * Add a resource provider
+     * This first checks if it implements the feature interface.
+     */
+    public void add(final ResourceProviderHandler rpHandler) {
+        if ( genericClass.isAssignableFrom(rpHandler.getResourceProvider().getClass())) {
+            this.addToList(rpHandler.getResourceProvider(), rpHandler.getRoots(), rpHandler.getServiceId());
+        }
+    }
+
+    /**
+     * Add a resource provider factory. We don't know yet if the
+     * resource provider implements the feature interface.
+     * This will be checked on demand.
+     */
+    public void add(final ResourceProviderFactoryHandler factory) {
+        this.addToList(factory, factory.getRoots(), factory.getServiceId());
+    }
+
+    /**
+     * Remove a resource provider.
+     */
+    public void remove(final ResourceProviderHandler rpHandler) {
+        if ( genericClass.isAssignableFrom(rpHandler.getResourceProvider().getClass())) {
+            this.removeFromList(rpHandler.getResourceProvider());
+        }
+    }
+
+    /**
+     * Remove a resource provider factory.
+     */
+    public void remove(final ResourceProviderFactoryHandler factory) {
+        this.removeFromList(factory);
+    }
+
+    private static final class Entry implements Comparable<Entry> {
+
+        private final String path;
+        private final Long   id;
+
+        public final Object object;
+
+        public Entry(final Object object, final String[] roots, final Long serviceId) {
+            this.id = serviceId;
+            this.object = object;
+            if ( roots != null ) {
+                this.path = roots[0];
+            } else {
+                this.path = "";
+            }
+        }
+
+        /**
+         * @see java.lang.Comparable#compareTo(java.lang.Object)
+         */
+        public int compareTo(final Entry other) {
+            int result = this.path.compareTo(other.path);
+            if ( result == 0 ) {
+                result = this.id.compareTo(other.id);
+            }
+            return result;
+        }
+
+    }
+}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderFactoryHandler.java b/src/main/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderFactoryHandler.java
new file mode 100644
index 0000000..1927f1a
--- /dev/null
+++ b/src/main/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderFactoryHandler.java
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The SF licenses this file
+ * to you 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 org.apache.sling.resourceresolver.impl.tree;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceProvider;
+import org.apache.sling.api.resource.ResourceProviderFactory;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.resourceresolver.impl.helper.ResourceResolverContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The resource provider factory handler handles access to
+ * resource provider factories.
+ */
+public class ResourceProviderFactoryHandler extends ProviderHandler {
+
+    /** The logger. */
+    private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    /**
+     * A do nothing resource provider.
+     */
+    private static final ResourceProvider NULL_PROVIDER = new ResourceProvider() {
+
+        public Iterator<Resource> listChildren(final Resource parent) {
+            return null;
+        }
+
+        public Resource getResource(final ResourceResolver resourceResolver, final String path) {
+            return null;
+        }
+
+        public Resource getResource(final ResourceResolver resourceResolver, final HttpServletRequest request, final String path) {
+            return null;
+        }
+    };
+
+    /**
+     * A resource provider fractory
+     */
+    private final ResourceProviderFactory resourceProviderFactory;
+
+    /**
+     * Create a new handler
+     */
+    public ResourceProviderFactoryHandler(final ResourceProviderFactory factory,
+                                          final Map<String, Object> properties) {
+        super(properties);
+        this.resourceProviderFactory = factory;
+    }
+
+    /**
+     * Get a resource provider
+     * If the user can't be authenticated <code>null</code> is returned.
+     * @param ctx The user context.
+     * @return A resource provider or <code>null</code>
+     */
+    public ResourceProvider getResourceProvider(final ResourceResolverContext ctx) {
+        ResourceProvider rp = ctx.getFactoryResourceProvider(this.getServiceId());
+        if ( rp == null ) {
+            try {
+                rp = this.login(ctx);
+            } catch (final LoginException le ) {
+                // for now we log to debug, as a failed login for not required resource provider
+                // is expected
+                // TODO - we could introduce a service property controlling this?
+                logger.debug("Unable to login to " + this.getName(), le);
+            }
+            if ( rp == null ) {
+                ctx.addFactoryResourceProvider(this.getServiceId(), NULL_PROVIDER);
+            }
+        } else if ( rp == NULL_PROVIDER ) {
+            rp = null;
+        }
+        return rp;
+    }
+
+    /**
+     * @see ResourceProvider#getResource(ResourceResolver, String)
+     */
+    public Resource getResource(final ResourceResolverContext ctx, final ResourceResolver resourceResolver, final String path) {
+        final ResourceProvider rp = this.getResourceProvider(ctx);
+        if ( rp != null ) {
+            return rp.getResource(resourceResolver, path);
+        }
+        return null;
+    }
+
+    /**
+     * @see ResourceProvider#listChildren(Resource)
+     */
+    public Iterator<Resource> listChildren(final ResourceResolverContext ctx, final Resource parent) {
+        final ResourceProvider rp = this.getResourceProvider(ctx);
+        if ( rp != null ) {
+            return rp.listChildren(parent);
+        }
+        return null;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        return resourceProviderFactory.hashCode();
+    }
+
+    /**
+     * {@inheritDoc}
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(final Object obj) {
+        if ( obj instanceof ResourceProviderFactoryHandler ) {
+            return resourceProviderFactory.equals(((ResourceProviderFactoryHandler) obj).resourceProviderFactory);
+        } else if ( obj instanceof ResourceProviderFactory) {
+            return resourceProviderFactory.equals(obj);
+        }
+        return super.equals(obj);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return resourceProviderFactory.toString();
+    }
+
+    /**
+     * Login to a resource resolver factory.
+     */
+    public ResourceProvider login(final ResourceResolverContext ctx) throws LoginException {
+        final ResourceProvider rp;
+        if (ctx.isAdmin()) {
+            rp = this.resourceProviderFactory.getAdministrativeResourceProvider(ctx.getAuthenticationInfo());
+        } else {
+            rp = this.resourceProviderFactory.getResourceProvider(ctx.getAuthenticationInfo());
+        }
+        ctx.addFactoryResourceProvider(this.getServiceId(), rp);
+        return rp;
+    }
+}
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderHandler.java b/src/main/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderHandler.java
new file mode 100644
index 0000000..eb5b67b
--- /dev/null
+++ b/src/main/java/org/apache/sling/resourceresolver/impl/tree/ResourceProviderHandler.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The SF licenses this file
+ * to you 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 org.apache.sling.resourceresolver.impl.tree;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceProvider;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.resourceresolver.impl.helper.ResourceResolverContext;
+
+/**
+ * The resource provider handler handles access to
+ * resource providers.
+ */
+public class ResourceProviderHandler extends ProviderHandler {
+
+    /** The handled resource provider.*/
+    private final ResourceProvider resourceProvider;
+
+    /**
+     * Create a new handler.
+     */
+    public ResourceProviderHandler(final ResourceProvider resourceProvider,
+                                   final Map<String, Object> properties) {
+        super(properties);
+        this.resourceProvider = resourceProvider;
+    }
+
+    /**
+     * @see ResourceProvider#getResource(ResourceResolver, String)
+     */
+    public Resource getResource(final ResourceResolverContext ctx, final ResourceResolver resourceResolver, final String path) {
+        return this.resourceProvider.getResource(resourceResolver, path);
+    }
+
+    /**
+     * @see ResourceProvider#listChildren(Resource)
+     */
+    public Iterator<Resource> listChildren(final ResourceResolverContext ctx, final Resource parent) {
+        return this.resourceProvider.listChildren(parent);
+    }
+
+    /**
+     * Return the resource provider.
+     */
+    public ResourceProvider getResourceProvider() {
+        return this.resourceProvider;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        return resourceProvider.hashCode();
+    }
+
+    /**
+     * {@inheritDoc}
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(final Object obj) {
+        if ( obj instanceof ResourceProviderHandler ) {
+            return resourceProvider.equals(((ResourceProviderHandler) obj).resourceProvider);
+        } else if ( obj instanceof ResourceProvider) {
+            return resourceProvider.equals(obj);
+        }
+        return super.equals(obj);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return resourceProvider.toString();
+    }
+}

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.