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>.