You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2012/05/24 08:42:54 UTC

svn commit: r1342154 [4/5] - in /sling/whiteboard/SLING-2396/resourceresolver: ./ src/main/java/org/apache/sling/jcr/resource/ src/main/java/org/apache/sling/jcr/resource/internal/ src/main/java/org/apache/sling/jcr/resource/internal/helper/ src/main/j...

Copied: sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceProviderEntry.java (from r1339051, sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntry.java)
URL: http://svn.apache.org/viewvc/sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceProviderEntry.java?p2=sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceProviderEntry.java&p1=sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntry.java&r1=1339051&r2=1342154&rev=1342154&view=diff
==============================================================================
--- sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntry.java (original)
+++ sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceProviderEntry.java Thu May 24 06:42:52 2012
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.jcr.resource.internal.helper;
+package org.apache.sling.resourceresolver.impl.helper;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -39,16 +39,9 @@ import org.slf4j.LoggerFactory;
  * The <code>ResourceProviderEntry</code> class represents a node in the tree of
  * resource providers spanned by the root paths of the provider resources.
  * <p>
- * This class is comparable to itself to help keep the child entries list sorted
- * by their prefix.
+ * This class is comparable to itself to help keep the child entries list sorted by their prefix.
  */
-public class ResourceProviderEntry implements
-        Comparable<ResourceProviderEntry> {
-
-    /**
-     *
-     */
-    private static final long serialVersionUID = 7420631325909144862L;
+public class ResourceProviderEntry implements Comparable<ResourceProviderEntry> {
 
     private static Logger LOGGER = LoggerFactory.getLogger(ResourceProviderEntry.class);
 
@@ -64,7 +57,7 @@ public class ResourceProviderEntry imple
 
     // the resource provider kept in this entry supporting resources at and
     // below the path of this entry.
-    private WrappedResourceProvider[] providers = new WrappedResourceProvider[0];
+    private AbstractWrappedResourceProvider[] providers = new AbstractWrappedResourceProvider[0];
 
     private long ttime = 0L;
 
@@ -74,7 +67,7 @@ public class ResourceProviderEntry imple
 
     private long nreal = 0L;
 
-    private FastTreeMap storageMap = new FastTreeMap();
+    private final FastTreeMap storageMap = new FastTreeMap();
 
     private Collection<ResourceProviderEntry> storageMapValues = new ArrayList<ResourceProviderEntry>();
 
@@ -82,13 +75,13 @@ public class ResourceProviderEntry imple
      * Creates an instance of this class with the given path relative to the
      * parent resource provider entry, encapsulating the given ResourceProvider,
      * and a number of inital child entries.
-     *
+     * 
      * @param path
      *            The relative path supported by the provider
      * @param providerList
      *            The resource provider to encapsulate by this entry.
      */
-    public ResourceProviderEntry(String path, ResourceProvider[] providerList) {
+    public ResourceProviderEntry(final String path, final AbstractWrappedResourceProvider[] providerList) {
         if (path.endsWith("/")) {
             this.path = path.substring(0, path.length() - 1);
             this.prefix = path;
@@ -96,15 +89,11 @@ public class ResourceProviderEntry imple
             this.path = path;
             this.prefix = path + "/";
         }
-        if ( providerList != null ) {
-          providers = new WrappedResourceProvider[providerList.length];
-          for ( int i = 0; i < providerList.length; i++ ) {
-            if ( providerList[i] instanceof WrappedResourceProvider ) {
-              providers[i] = (WrappedResourceProvider) providerList[i];
-            } else {
-              providers[i] = new WrappedResourceProvider(providerList[i], null);
+        if (providerList != null) {
+            providers = new AbstractWrappedResourceProvider[providerList.length];
+            for (int i = 0; i < providerList.length; i++) {
+                providers[i] = providerList[i];
             }
-          }
         }
 
         // this will consume slightly more memory but ensures read is fast.
@@ -117,9 +106,9 @@ public class ResourceProviderEntry imple
     }
 
     /**
-     * Returns the resource provider contained in this entry
+     * Returns the resource providers contained in this entry
      */
-    public ResourceProvider[] getResourceProviders() {
+    public AbstractWrappedResourceProvider[] getResourceProviders() {
         return providers;
     }
 
@@ -127,7 +116,7 @@ public class ResourceProviderEntry imple
      * Returns the resource with the given path or <code>null</code> if neither
      * the resource provider of this entry nor the resource provider of any of
      * the child entries can provide the resource.
-     *
+     * 
      * @param path
      *            The path to the resource to return.
      * @return The resource for the path or <code>null</code> if no resource can
@@ -135,49 +124,47 @@ public class ResourceProviderEntry imple
      * @throws org.apache.sling.api.SlingException
      *             if an error occurrs trying to access an existing resource.
      */
-    public Resource getResource(ResourceResolver resourceResolver, String path) {
-        return getInternalResource(resourceResolver, path);
+    public Resource getResource(final ResourceResolverContext ctx, final ResourceResolver resourceResolver, final String path) {
+        return getInternalResource(ctx, resourceResolver, path);
     }
 
     /**
      * Adds the given resource provider into the tree for the given prefix.
-     *
+     * 
      * @return <code>true</code> if the provider could be entered into the
      *         subtree below this entry. Otherwise <code>false</code> is
      *         returned.
      */
-    public boolean addResourceProvider(String prefix, ResourceProvider provider, Comparable<?> comparable) {
-        synchronized (this) {
-            String[] elements = split(prefix, '/');
-            List<ResourceProviderEntry> entryPath = new ArrayList<ResourceProviderEntry>();
-            entryPath.add(this); // add this the start so if the list is empty we have a position to add to
-            populateProviderPath(entryPath, elements);
-            for (int i = entryPath.size() - 1; i < elements.length; i++) {
-                String stubPrefix = elements[i];
-                ResourceProviderEntry rpe2 = new ResourceProviderEntry(
-                        stubPrefix, new ResourceProvider[0]);
-                entryPath.get(i).put(elements[i], rpe2);
-                entryPath.add(rpe2);
-            }
-            return entryPath.get(elements.length).addInternalProvider(new WrappedResourceProvider(provider, comparable));
-
+    public synchronized boolean addResourceProvider(final String prefix, final AbstractWrappedResourceProvider provider) {
+        final String[] elements = split(prefix, '/');
+        final List<ResourceProviderEntry> entryPath = new ArrayList<ResourceProviderEntry>();
+        entryPath.add(this); // add this the start so if the list is empty
+        // we have a position to add to
+        populateProviderPath(entryPath, elements);
+        for (int i = entryPath.size() - 1; i < elements.length; i++) {
+            final String stubPrefix = elements[i];
+            final ResourceProviderEntry rpe2 = new ResourceProviderEntry(stubPrefix, new AbstractWrappedResourceProvider[0]);
+            entryPath.get(i).put(stubPrefix, rpe2);
+            entryPath.add(rpe2);
         }
+        return entryPath.get(elements.length).addInternalProvider(provider);
     }
 
-
-    //------------------ Map methods, here so that we can delegate 2 maps together
+    // ------------------ Map methods, here so that we can delegate 2 maps
+    // together
     @SuppressWarnings("unchecked")
-    public void put(String key, ResourceProviderEntry value) {
-        storageMap.put(key,value);
-        // get a thread safe copy, the ArrayList constructor does a toArray which is thread safe.
+    public void put(final String key, final ResourceProviderEntry value) {
+        storageMap.put(key, value);
+        // get a thread safe copy, the ArrayList constructor does a toArray
+        // which is thread safe.
         storageMapValues = new ArrayList<ResourceProviderEntry>(storageMap.values());
     }
 
-    public boolean containsKey(String key) {
+    public boolean containsKey(final String key) {
         return storageMap.containsKey(key);
     }
 
-    public ResourceProviderEntry get(String key) {
+    public ResourceProviderEntry get(final String key) {
         return (ResourceProviderEntry) storageMap.get(key);
     }
 
@@ -185,23 +172,20 @@ public class ResourceProviderEntry imple
         return storageMapValues;
     }
 
-    public boolean removeResourceProvider(String prefix,
-            ResourceProvider resourceProvider, Comparable<?> comparable) {
-        synchronized (this) {
-            String[] elements = split(prefix, '/');
-            List<ResourceProviderEntry> entryPath = new ArrayList<ResourceProviderEntry>();
-            populateProviderPath(entryPath, elements);
-            if (entryPath.size() > 0 && entryPath.size() == elements.length) {
-                // the last element is a perfect match;
-                return entryPath.get(entryPath.size()-1).removeInternalProvider(new WrappedResourceProvider(resourceProvider, comparable));
-            }
-            return false;
+    public synchronized boolean removeResourceProvider(final String prefix, final AbstractWrappedResourceProvider resourceProvider) {
+        final String[] elements = split(prefix, '/');
+        final List<ResourceProviderEntry> entryPath = new ArrayList<ResourceProviderEntry>();
+        populateProviderPath(entryPath, elements);
+        if (entryPath.size() > 0 && entryPath.size() == elements.length) {
+            // the last element is a perfect match;
+            return entryPath.get(entryPath.size() - 1).removeInternalProvider(resourceProvider);
         }
+        return false;
     }
 
     // ---------- Comparable<ResourceProviderEntry> interface ------------------
 
-    public int compareTo(ResourceProviderEntry o) {
+    public int compareTo(final ResourceProviderEntry o) {
         return prefix.compareTo(o.prefix);
     }
 
@@ -209,84 +193,80 @@ public class ResourceProviderEntry imple
 
     /**
      * Adds a list of providers to this entry.
-     *
+     * 
+     * No sync required as this is called by a sync method!
+     * 
      * @param provider
      */
-    private boolean addInternalProvider(WrappedResourceProvider provider) {
-        synchronized (providers) {
-            int before = providers.length;
-            Set<WrappedResourceProvider> set = new HashSet<WrappedResourceProvider>();
-            if (providers != null) {
-                set.addAll(Arrays.asList(providers));
-            }
-            LOGGER.debug("Adding provider {} at {} ",provider,path);
-            set.add(provider);
-            providers = conditionalSort(set);
-            return providers.length > before;
-        }
-
+    private boolean addInternalProvider(final AbstractWrappedResourceProvider provider) {
+        final int before = providers.length;
+        final Set<AbstractWrappedResourceProvider> set = new HashSet<AbstractWrappedResourceProvider>();
+        if (providers != null) {
+            set.addAll(Arrays.asList(providers));
+        }
+        LOGGER.debug("Adding provider {} at {} ", provider, path);
+        set.add(provider);
+        providers = conditionalSort(set);
+        return providers.length > before;
     }
 
     /**
-     * @param provider
-     * @return
-     */
-    private boolean removeInternalProvider(WrappedResourceProvider provider) {
-        synchronized (providers) {
-            int before = providers.length;
-            Set<WrappedResourceProvider> set = new HashSet<WrappedResourceProvider>();
-            if (providers != null) {
-                set.addAll(Arrays.asList(providers));
-            }
-            set.remove(provider);
-            providers = conditionalSort(set);
-            return providers.length < before;
-        }
+     * Remove a provider from the list of entries.
+     * 
+     * No sync required as this is called by a sync method!
+     */
+    private boolean removeInternalProvider(final AbstractWrappedResourceProvider provider) {
+        final int before = providers.length;
+        final Set<AbstractWrappedResourceProvider> set = new HashSet<AbstractWrappedResourceProvider>();
+        if (providers != null) {
+            set.addAll(Arrays.asList(providers));
+        }
+        set.remove(provider);
+        providers = conditionalSort(set);
+        return providers.length < before;
     }
 
     /**
      * @param set
      * @return
      */
-    private WrappedResourceProvider[] conditionalSort(Set<WrappedResourceProvider> set) {
+    private AbstractWrappedResourceProvider[] conditionalSort(final Set<AbstractWrappedResourceProvider> set) {
 
-        List<WrappedResourceProvider> providerList = new ArrayList<WrappedResourceProvider>(
-                set);
+        final List<AbstractWrappedResourceProvider> providerList = new ArrayList<AbstractWrappedResourceProvider>(set);
 
-        Collections.sort(providerList, new Comparator<WrappedResourceProvider>() {
+        Collections.sort(providerList, new Comparator<AbstractWrappedResourceProvider>() {
 
-            @SuppressWarnings("unchecked")
-            public int compare(WrappedResourceProvider o1, WrappedResourceProvider o2) {
-                Comparable c1 = o1.getComparable();
-                Comparable c2 = o2.getComparable();
-                if ( c1 == null && c2 == null ) {
-                  return 0;
+            @SuppressWarnings({ "rawtypes", "unchecked" })
+            public int compare(final AbstractWrappedResourceProvider o1, final AbstractWrappedResourceProvider o2) {
+                final Comparable c1 = o1.getComparable();
+                final Comparable c2 = o2.getComparable();
+                if (c1 == null && c2 == null) {
+                    return 0;
                 }
-                if ( c1 == null ) {
-                  return -1;
+                if (c1 == null) {
+                    return -1;
                 }
-                if ( c2 == null ) {
-                  return 1;
+                if (c2 == null) {
+                    return 1;
                 }
                 return c1.compareTo(c2);
             }
         });
 
-        return set.toArray(new WrappedResourceProvider[set.size()]);
+        return providerList.toArray(new AbstractWrappedResourceProvider[providerList.size()]);
     }
 
     /**
      * Get a of ResourceProvidersEntries leading to the fullPath in reverse
      * order.
-     *
+     * 
      * @param fullPath
      *            the full path
      */
-    private void populateProviderPath(
-        List<ResourceProviderEntry> providerEntryPath, String[] elements) {
+    private void populateProviderPath(final List<ResourceProviderEntry> providerEntryPath, final String[] elements) {
         ResourceProviderEntry base = this;
         if (elements != null) {
-            for (String element : elements) {
+            for (final String element : elements) {
                 if (element != null) {
                     if (base.containsKey(element)) {
                         base = base.get(element);
@@ -299,51 +279,45 @@ public class ResourceProviderEntry imple
         }
     }
 
-
     /**
      * Resolve a resource from a path into a Resource
-     *
+     * 
      * @param resolver
      *            the ResourceResolver.
      * @param fullPath
      *            the Full path
      * @return null if no resource was found, a resource if one was found.
      */
-    private Resource getInternalResource(ResourceResolver resourceResolver,
-            String fullPath) {
-        long start = System.currentTimeMillis();
+    private Resource getInternalResource(final ResourceResolverContext ctx, final ResourceResolver resourceResolver, final String fullPath) {
+        final long start = System.currentTimeMillis();
         try {
 
-            if (fullPath == null || fullPath.length() == 0
-                    || fullPath.charAt(0) != '/') {
+            if (fullPath == null || fullPath.length() == 0 || fullPath.charAt(0) != '/') {
                 nmiss++;
-                LOGGER.debug("Not absolute {} :{}",fullPath,(System.currentTimeMillis() - start));
+                LOGGER.debug("Not absolute {} :{}", fullPath, (System.currentTimeMillis() - start));
                 return null; // fullpath must be absolute
             }
-            String[] elements = split(fullPath, '/');
+            final String[] elements = split(fullPath, '/');
 
-            List<ResourceProviderEntry> list = new ArrayList<ResourceProviderEntry>();
+            final List<ResourceProviderEntry> list = new ArrayList<ResourceProviderEntry>();
             populateProviderPath(list, elements);
             // the path is in reverse order end first
 
-            for(int i = list.size()-1; i >= 0; i--) {
-                ResourceProvider[] rps = list.get(i).getResourceProviders();
-                for (ResourceProvider rp : rps) {
+            for (int i = list.size() - 1; i >= 0; i--) {
+                final AbstractWrappedResourceProvider[] rps = list.get(i).getResourceProviders();
+                for (final AbstractWrappedResourceProvider rp : rps) {
 
-                    Resource resource = rp.getResource(resourceResolver,
-                            fullPath);
+                    final Resource resource = rp.getResource(ctx, resourceResolver, fullPath);
                     if (resource != null) {
                         nreal++;
-                        LOGGER.debug("Resolved Full {} using {} from {} ",new Object[]{
-                                fullPath, rp, Arrays.toString(rps)});
+                        LOGGER.debug("Resolved Full {} using {} from {} ", new Object[] { fullPath, rp, Arrays.toString(rps) });
                         return resource;
                     }
                 }
             }
 
             // resolve against this one
-            final Resource resource = getResourceFromProviders(
-                resourceResolver, fullPath);
+            final Resource resource = getResourceFromProviders(ctx, resourceResolver, fullPath);
             if (resource != null) {
                 return resource;
             }
@@ -352,34 +326,29 @@ public class ResourceProviderEntry imple
             // resource Provider: libs/sling/servlet/default/GET.servlet
             // list will match libs, sling, servlet, default
             // and there will be no resource provider at the end
-            if (list.size() > 0 && list.size() == elements.length ) {
-                if ( list.get(list.size()-1).getResourceProviders().length == 0 ) {
+            if (list.size() > 0 && list.size() == elements.length) {
+                if (list.get(list.size() - 1).getResourceProviders().length == 0) {
                     nsynthetic++;
                     LOGGER.debug("Resolved Synthetic {}", fullPath);
-                    return new SyntheticResource(resourceResolver,
-                            fullPath,
-                            ResourceProvider.RESOURCE_TYPE_SYNTHETIC);
+                    return new SyntheticResource(resourceResolver, fullPath, ResourceProvider.RESOURCE_TYPE_SYNTHETIC);
                 }
             }
 
-
-
             LOGGER.debug("Resource null {} ", fullPath);
             nmiss++;
             return null;
-        } catch (Exception ex) {
-            LOGGER.debug("Failed! ",ex);
+        } catch (final Exception ex) {
+            LOGGER.debug("Failed! ", ex);
             return null;
         } finally {
             ttime += System.currentTimeMillis() - start;
         }
     }
 
-    Resource getResourceFromProviders(final ResourceResolver resourceResolver,
-            final String fullPath) {
-        ResourceProvider[] rps = getResourceProviders();
-        for (ResourceProvider rp : rps) {
-            Resource resource = rp.getResource(resourceResolver, fullPath);
+    Resource getResourceFromProviders(final ResourceResolverContext ctx, final ResourceResolver resourceResolver, final String fullPath) {
+        final AbstractWrappedResourceProvider[] rps = getResourceProviders();
+        for (final AbstractWrappedResourceProvider rp : rps) {
+            final Resource resource = rp.getResource(ctx, resourceResolver, fullPath);
             if (resource != null) {
                 nreal++;
                 LOGGER.debug("Resolved Base {} using {} ", fullPath, rp);
@@ -394,12 +363,12 @@ public class ResourceProviderEntry imple
      * @param sep
      * @return an array of the strings between the separator
      */
-    static String[] split(String st, char sep) {
+    static String[] split(final String st, final char sep) {
 
         if (st == null) {
             return new String[0];
         }
-        char[] pn = st.toCharArray();
+        final char[] pn = st.toCharArray();
         if (pn.length == 0) {
             return new String[0];
         }
@@ -418,7 +387,7 @@ public class ResourceProviderEntry imple
                 n++;
             }
         }
-        String[] e = new String[n];
+        final String[] e = new String[n];
         int s = start;
         int j = 0;
         for (int i = start; i < end; i++) {
@@ -434,31 +403,31 @@ public class ResourceProviderEntry imple
     }
 
     public String getResolutionStats() {
-        long tot = nreal + nsynthetic + nmiss;
+        final long tot = nreal + nsynthetic + nmiss;
         if (tot == 0) {
             return null;
         }
-        float n = tot;
-        float t = ttime;
-        float persec = 1000 * n / t;
-        float avgtime = t / n;
-
-        String stat = "Resolved: Real(" + nreal + ") Synthetic(" + nsynthetic
-                + ") Missing(" + nmiss + ") Total(" + tot + ") at " + persec
-                + " ops/sec avg " + avgtime + " ms";
+        final float n = tot;
+        final float t = ttime;
+        final float persec = 1000 * n / t;
+        final float avgtime = t / n;
+
+        final String stat = "Resolved: Real(" + nreal + ") Synthetic(" + nsynthetic + ") Missing(" + nmiss + ") Total(" + tot + ") at "
+                        + persec + " ops/sec avg " + avgtime + " ms";
         ttime = nmiss = nsynthetic = nreal = 0L;
         return stat;
     }
 
     /**
      * {@inheritDoc}
-     *
+     * 
      * @see java.util.AbstractMap#toString()
      */
     @Override
     public String toString() {
         return this.path;
-        //"{path:\"" + this.path + "\", providers:"+Arrays.toString(getResourceProviders())+", map:" + storageMap.toString() + "}";
+        // "{path:\"" + this.path +
+        // "\", providers:"+Arrays.toString(getResourceProviders())+", map:" +
+        // storageMap.toString() + "}";
     }
-
 }

Propchange: sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceProviderEntry.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverContext.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverContext.java?rev=1342154&view=auto
==============================================================================
--- sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverContext.java (added)
+++ sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverContext.java Thu May 24 06:42:52 2012
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ */
+public class ResourceResolverContext {
+
+    /** A map of all used providers created by a factory. */
+    private final Map<String, ResourceProvider> providers = new HashMap<String, 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.
+     */
+    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> getAuthInfo() {
+        return this.originalAuthInfo;
+    }
+
+    /**
+     * Add a new resource provider
+     * @param key      The unique key of the provider
+     * @param provider The provider.
+     */
+    public void addFactoryResourceProvider(final String 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 String 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();
+    }
+}

Propchange: sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverContext.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Propchange: sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/ResourceResolverContext.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Copied: sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/RootResourceProviderEntry.java (from r1339051, sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/RootResourceProviderEntry.java)
URL: http://svn.apache.org/viewvc/sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/RootResourceProviderEntry.java?p2=sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/RootResourceProviderEntry.java&p1=sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/RootResourceProviderEntry.java&r1=1339051&r2=1342154&rev=1342154&view=diff
==============================================================================
--- sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/RootResourceProviderEntry.java (original)
+++ sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/RootResourceProviderEntry.java Thu May 24 06:42:52 2012
@@ -16,118 +16,304 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.jcr.resource.internal.helper;
+package org.apache.sling.resourceresolver.impl.helper;
 
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.Dictionary;
+import java.util.HashSet;
 import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import org.apache.sling.api.SlingConstants;
+import org.apache.sling.api.adapter.Adaptable;
+import org.apache.sling.api.resource.AttributesProvider;
+import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.api.resource.QueriableResourceProvider;
+import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceProvider;
-import org.apache.sling.commons.osgi.OsgiUtil;
+import org.apache.sling.api.resource.ResourceProviderFactory;
+import org.apache.sling.commons.osgi.PropertiesUtil;
 import org.osgi.framework.Constants;
 import org.osgi.service.event.Event;
 import org.osgi.service.event.EventAdmin;
-import org.osgi.util.tracker.ServiceTracker;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * This is the root resource provider entry which keeps track
- * of the resource providers.
+ * This is the root resource provider entry which keeps track of the resource
+ * providers.
  */
 public class RootResourceProviderEntry extends ResourceProviderEntry {
 
-    /** default logger */
+    /** Default logger */
     private final Logger logger = LoggerFactory.getLogger(getClass());
 
+    /** Event admin. */
+    private EventAdmin eventAdmin;
+
+    /** Array of required factories. */
+    private WrappedResourceProviderFactory[] requiredFactories = new WrappedResourceProviderFactory[0];
+
+    /** All adaptable resource providers. */
+    private final SortedProviderList<Adaptable> adaptableProviders = new SortedProviderList<Adaptable>(Adaptable.class);
+
+    /** All queriable resource providers. */
+    private final SortedProviderList<QueriableResourceProvider> queriableProviders = new SortedProviderList<QueriableResourceProvider>(QueriableResourceProvider.class);
+
+    /** All attribute resource providers. */
+    private final SortedProviderList<AttributesProvider> attributeProviders = new SortedProviderList<AttributesProvider>(AttributesProvider.class);
+
     public RootResourceProviderEntry() {
         super("/", null);
     }
 
-    public void bindResourceProvider(final ResourceProvider provider,
-                                     final Map<String, Object> props,
-                                     final ServiceTracker eventAdminTracker) {
-
-        final String serviceName = getServiceName(provider, props);
+    /**
+     * Set or unset the event admin.
+     */
+    public void setEventAdmin(final EventAdmin ea) {
+        this.eventAdmin = ea;
+    }
 
-        logger.debug("bindResourceProvider: Binding {}", serviceName);
+    /**
+     * Login into all required factories
+     * @throws LoginException If login fails.
+     */
+    public void loginToRequiredFactories(final ResourceResolverContext ctx) throws LoginException {
+        try {
+            final WrappedResourceProviderFactory[] factories = this.requiredFactories;
+            for (final WrappedResourceProviderFactory wrapper : factories) {
+                wrapper.login(ctx);
+            }
+        } catch (final LoginException le) {
+            // login failed, so logout if already logged in providers
+            ctx.close();
+            throw le;
+        }
+    }
 
-        String[] roots = OsgiUtil.toStringArray(props.get(ResourceProvider.ROOTS));
-        if (roots != null && roots.length > 0) {
-            final EventAdmin localEA = (EventAdmin) ( eventAdminTracker != null ? eventAdminTracker.getService() : null);
+    /**
+     * Invoke all resource providers and find an adaption
+     * @see Adaptable
+     */
+    public <AdapterType> AdapterType adaptTo(final ResourceResolverContext ctx, final Class<AdapterType> type) {
+        final Iterator<Adaptable> i = this.adaptableProviders.getProviders(ctx);
+        AdapterType result = null;
+        while ( result == null && i.hasNext() ) {
+            final Adaptable adap = i.next();
+            result = adap.adaptTo(type);
+        }
+        return result;
+    }
 
-            for (String root : roots) {
-                // cut off trailing slash
-                if (root.endsWith("/") && root.length() > 1) {
-                    root = root.substring(0, root.length() - 1);
-                }
+    /**
+     * Invoke all queriable resource providers.
+     * @see QueriableResourceProvider#findResources(String, String)
+     */
+    public Iterator<Resource> findResources(final ResourceResolverContext ctx, final String query, final String language) {
+        final Iterator<QueriableResourceProvider> i = this.queriableProviders.getProviders(ctx);
+        while ( i.hasNext() ) {
+            final QueriableResourceProvider adap = i.next();
+        }
+        return null;
+    }
 
-                // synchronized insertion of new resource providers into
-                // the tree to not inadvertently loose an entry
-                synchronized (this) {
+    /**
+     * Invoke all queriable resource providers.
+     * @see QueriableResourceProvider#queryResources(String, String)
+     */
+    public Iterator<Map<String, Object>> queryResources(final ResourceResolverContext ctx, final String query, final String language) {
+        final Iterator<QueriableResourceProvider> i = this.queriableProviders.getProviders(ctx);
+        while ( i.hasNext() ) {
+            final QueriableResourceProvider adap = i.next();
+        }
+        return null;
+    }
 
-                    this.addResourceProvider(root,
-                        provider, OsgiUtil.getComparableForServiceRanking(props));
-                }
-                logger.debug("bindResourceProvider: {}={} ({})",
-                    new Object[] { root, provider, serviceName });
-                if ( localEA != null ) {
-                    final Dictionary<String, Object> eventProps = new Hashtable<String, Object>();
-                    eventProps.put(SlingConstants.PROPERTY_PATH, root);
-                    localEA.postEvent(new Event(SlingConstants.TOPIC_RESOURCE_PROVIDER_ADDED,
-                            eventProps));
-                }
+    /**
+     * Invoke all attributes providers and combine the result
+     * @see AttributesProvider#getAttributeNames()
+     */
+    public Iterator<String> getAttributeNames(final ResourceResolverContext ctx) {
+        final Set<String> names = new HashSet<String>();
+        final Iterator<AttributesProvider> i = this.attributeProviders.getProviders(ctx);
+        while ( i.hasNext() ) {
+            final AttributesProvider adap = i.next();
+            final Collection<String> newNames = adap.getAttributeNames();
+            if ( newNames != null ) {
+                names.addAll(newNames);
             }
         }
+        return names.iterator();
+    }
 
-        logger.debug("bindResourceProvider: Bound {}", serviceName);
+    /**
+     * Return the result from the first matching attributes provider
+     * @see AttributesProvider#getAttribute(String)
+     */
+    public Object getAttribute(final ResourceResolverContext ctx, final String name) {
+        final Iterator<AttributesProvider> i = this.attributeProviders.getProviders(ctx);
+        Object result = null;
+        while ( result == null && i.hasNext() ) {
+            final AttributesProvider adap = i.next();
+            result = adap.getAttribute(name);
+        }
+        return result;
     }
 
-    public void unbindResourceProvider(final ResourceProvider provider,
-                                       final Map<String, Object> props,
-                                       final ServiceTracker eventAdminTracker) {
+    /**
+     * Bind a resource provider.
+     */
+    public void bindResourceProvider(final ResourceProvider provider, final Map<String, Object> props) {
+        this.bindWrapper(new WrappedResourceProvider(provider, props));
+        if ( provider instanceof Adaptable ) {
+            this.adaptableProviders.add((Adaptable)provider);
+        }
+        if ( provider instanceof QueriableResourceProvider ) {
+            this.queriableProviders.add((QueriableResourceProvider)provider);
+        }
+        if ( provider instanceof AttributesProvider ) {
+            this.attributeProviders.add((AttributesProvider)provider);
+        }
+    }
 
-        final String serviceName = getServiceName(provider, props);
+    /**
+     * Unbind a resource provider.
+     */
+    public void unbindResourceProvider(final ResourceProvider provider, final Map<String, Object> props) {
+        this.unbindWrapper(new WrappedResourceProvider(provider, props));
+        if ( provider instanceof Adaptable ) {
+            this.adaptableProviders.remove((Adaptable)provider);
+        }
+        if ( provider instanceof QueriableResourceProvider ) {
+            this.queriableProviders.remove((QueriableResourceProvider)provider);
+        }
+        if ( provider instanceof AttributesProvider ) {
+            this.attributeProviders.remove((AttributesProvider)provider);
+        }
+    }
 
-        logger.debug("unbindResourceProvider: Unbinding {}", serviceName);
+    /**
+     * Bind a resource provider factory.
+     */
+    public void bindResourceProviderFactory(final ResourceProviderFactory factory, final Map<String, Object> props) {
+        final WrappedResourceProviderFactory wrapper = new WrappedResourceProviderFactory(factory, props);
+
+        this.bindWrapper(wrapper);
+        this.adaptableProviders.add(wrapper);
+        this.queriableProviders.add(wrapper);
+        this.attributeProviders.add(wrapper);
+
+        final boolean required = PropertiesUtil.toBoolean(props.get(ResourceProviderFactory.PROPERTY_REQUIRED), false);
+        if (required) {
+            synchronized (this) {
+                final List<WrappedResourceProviderFactory> factories = new LinkedList<WrappedResourceProviderFactory>();
+                factories.addAll(Arrays.asList(this.requiredFactories));
+                factories.add(wrapper);
+                this.requiredFactories = factories.toArray(new WrappedResourceProviderFactory[factories.size()]);
+            }
+        }
+    }
 
-        String[] roots = OsgiUtil.toStringArray(props.get(ResourceProvider.ROOTS));
-        if (roots != null && roots.length > 0) {
+    /**
+     * Unbind a resource provider factory
+     */
+    public void unbindResourceProviderFactory(final ResourceProviderFactory factory, final Map<String, Object> props) {
+        final WrappedResourceProviderFactory wrapper = new WrappedResourceProviderFactory(factory, props);
+
+        this.unbindWrapper(new WrappedResourceProvider(null, props));
+        this.adaptableProviders.remove(wrapper);
+        this.queriableProviders.remove(wrapper);
+        this.attributeProviders.remove(wrapper);
+
+        final boolean required = PropertiesUtil.toBoolean(props.get(ResourceProviderFactory.PROPERTY_REQUIRED), false);
+        if (required) {
+            synchronized (this) {
+                final List<WrappedResourceProviderFactory> factories = new LinkedList<WrappedResourceProviderFactory>();
+                factories.addAll(Arrays.asList(this.requiredFactories));
+                factories.remove(wrapper);
+                this.requiredFactories = factories.toArray(new WrappedResourceProviderFactory[factories.size()]);
+            }
+        }
+    }
 
-            final EventAdmin localEA = (EventAdmin) ( eventAdminTracker != null ? eventAdminTracker.getService() : null);
+    /**
+     * Bind a resource provider wrapper
+     */
+    private void bindWrapper(final AbstractWrappedResourceProvider provider) {
+        // this is just used for debug logging
+        final String debugServiceName = getDebugServiceName(provider, provider.getProperties());
 
+        logger.debug("bindResourceProvider: Binding {}", debugServiceName);
+
+        final String[] roots = PropertiesUtil.toStringArray(provider.getProperties().get(ResourceProvider.ROOTS));
+        if (roots != null && roots.length > 0) {
+            final EventAdmin localEA = this.eventAdmin;
             for (String root : roots) {
-                // cut off trailing slash
-                if (root.endsWith("/") && root.length() > 1) {
-                    root = root.substring(0, root.length() - 1);
+                if (root != null && root.length() > 0) {
+                    // cut off trailing slash
+                    if (root.endsWith("/") && root.length() > 1) {
+                        root = root.substring(0, root.length() - 1);
+                    }
+
+                    this.addResourceProvider(root, provider);
+
+                    logger.debug("bindResourceProvider: {}={} ({})", new Object[] { root, provider, debugServiceName });
+                    if (localEA != null) {
+                        final Dictionary<String, Object> eventProps = new Hashtable<String, Object>();
+                        eventProps.put(SlingConstants.PROPERTY_PATH, root);
+                        localEA.postEvent(new Event(SlingConstants.TOPIC_RESOURCE_PROVIDER_ADDED, eventProps));
+                    }
                 }
+            }
+        }
 
-                // synchronized insertion of new resource providers into
-                // the tree to not inadvertently loose an entry
-                synchronized (this) {
-                    // TODO: Do not remove this path, if another resource
-                    // owns it. This may be the case if adding the provider
-                    // yielded an ResourceProviderEntryException
-                    this.removeResourceProvider(root, provider, OsgiUtil.getComparableForServiceRanking(props));
-                }
-                logger.debug("unbindResourceProvider: root={} ({})", root,
-                    serviceName);
-                if ( localEA != null ) {
-                    final Dictionary<String, Object> eventProps = new Hashtable<String, Object>();
-                    eventProps.put(SlingConstants.PROPERTY_PATH, root);
-                    localEA.postEvent(new Event(SlingConstants.TOPIC_RESOURCE_PROVIDER_REMOVED,
-                            eventProps));
+        logger.debug("bindResourceProvider: Bound {}", debugServiceName);
+    }
+
+    /**
+     * Unbind a resource provider wrapper
+     */
+    private void unbindWrapper(final AbstractWrappedResourceProvider provider) {
+        // this is just used for debug logging
+        final String debugServiceName = getDebugServiceName(provider, provider.getProperties());
+
+        logger.debug("unbindResourceProvider: Unbinding {}", debugServiceName);
+
+        final String[] roots = PropertiesUtil.toStringArray(provider.getProperties().get(ResourceProvider.ROOTS));
+        if (roots != null && roots.length > 0) {
+
+            final EventAdmin localEA = this.eventAdmin;
+
+            for (String root : roots) {
+                if (root != null && root.length() > 0) {
+                    // cut off trailing slash
+                    if (root.endsWith("/") && root.length() > 1) {
+                        root = root.substring(0, root.length() - 1);
+                    }
+
+                    this.removeResourceProvider(root, provider);
+
+                    logger.debug("unbindResourceProvider: root={} ({})", root, debugServiceName);
+                    if (localEA != null) {
+                        final Dictionary<String, Object> eventProps = new Hashtable<String, Object>();
+                        eventProps.put(SlingConstants.PROPERTY_PATH, root);
+                        localEA.postEvent(new Event(SlingConstants.TOPIC_RESOURCE_PROVIDER_REMOVED, eventProps));
+                    }
                 }
             }
         }
 
-        logger.debug("unbindResourceProvider: Unbound {}", serviceName);
+        logger.debug("unbindResourceProvider: Unbound {}", debugServiceName);
     }
 
-    private String getServiceName(final ResourceProvider provider, final Map<String, Object> props) {
+    private String getDebugServiceName(final AbstractWrappedResourceProvider provider, final Map<String, Object> props) {
         if (logger.isDebugEnabled()) {
-            StringBuilder snBuilder = new StringBuilder(64);
+            final StringBuilder snBuilder = new StringBuilder(64);
             snBuilder.append('{');
             snBuilder.append(provider.toString());
             snBuilder.append('/');

Propchange: sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/RootResourceProviderEntry.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/RootResourceProviderEntry.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Propchange: sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/RootResourceProviderEntry.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/SortedProviderList.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/SortedProviderList.java?rev=1342154&view=auto
==============================================================================
--- sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/SortedProviderList.java (added)
+++ sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/SortedProviderList.java Thu May 24 06:42:52 2012
@@ -0,0 +1,128 @@
+/*
+ * 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.Arrays;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.sling.api.resource.LoginException;
+
+
+public class SortedProviderList<T> {
+
+    private final Class<T> genericClass;
+
+    private Object[] sortedList = new Object[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;
+    }
+
+    public Iterator<T> getProviders(final ResourceResolverContext ctx) {
+        return new Iterator<T>() {
+
+            private final Object[] list = sortedList;
+
+            private int index = 0;
+
+            private Object nextObject = seek();
+
+            private Object seek() {
+                Object result;
+                if ( this.index < list.length ) {
+                    result = list[this.index];
+                    this.index++;
+                    if ( result instanceof WrappedResourceProviderFactory ) {
+                        try {
+                            result = ((WrappedResourceProviderFactory)result).login(ctx);
+                            if ( !genericClass.isAssignableFrom(result.getClass())) {
+                                result = null;
+                            }
+                        } catch (final LoginException e) {
+                            // TODO Should we log?
+                        }
+                        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()
+             */
+            public T next() {
+                final Object result = this.nextObject;
+                this.nextObject = seek();
+                return (T)result;
+            }
+
+            /**
+             * @see java.util.Iterator#remove()
+             */
+            public void remove() {
+                throw new UnsupportedOperationException();
+            }
+        };
+    }
+
+    public void add(final T provider) {
+        synchronized ( this ) {
+            final List<Object> list = new LinkedList<Object>();
+            list.addAll(Arrays.asList(this.sortedList));
+            list.add(provider);
+            this.sortedList = list.toArray(new Object[list.size()]);
+        }
+    }
+
+    public void add(final WrappedResourceProviderFactory factory) {
+        synchronized ( this ) {
+            final List<Object> list = new LinkedList<Object>();
+            list.addAll(Arrays.asList(this.sortedList));
+            list.add(factory);
+            this.sortedList = list.toArray(new Object[list.size()]);
+        }
+    }
+
+    public void remove(final T provider) {
+        // TODO Auto-generated method stub
+
+    }
+
+    public void remove(final WrappedResourceProviderFactory wrapper) {
+        // TODO Auto-generated method stub
+
+    }
+}

Propchange: sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/SortedProviderList.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/SortedProviderList.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Propchange: sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/SortedProviderList.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Copied: sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/StarResource.java (from r1339051, sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/starresource/StarResource.java)
URL: http://svn.apache.org/viewvc/sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/StarResource.java?p2=sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/StarResource.java&p1=sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/starresource/StarResource.java&r1=1339051&r2=1342154&rev=1342154&view=diff
==============================================================================
--- sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/starresource/StarResource.java (original)
+++ sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/StarResource.java Thu May 24 06:42:52 2012
@@ -16,9 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.jcr.resource.internal.helper.starresource;
-
-import java.util.Map;
+package org.apache.sling.resourceresolver.impl.helper;
 
 import org.apache.sling.adapter.annotations.Adaptable;
 import org.apache.sling.adapter.annotations.Adapter;
@@ -28,10 +26,10 @@ import org.apache.sling.api.resource.Res
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.resource.ResourceUtil;
 import org.apache.sling.api.resource.SyntheticResource;
-import org.apache.sling.api.resource.ValueMap;
 
-/** Used to provide the equivalent of an empty Node for GET requests
- *  to *.something (SLING-344)
+/**
+ * Used to provide the equivalent of an empty Node for GET requests to
+ * *.something (SLING-344)
  */
 @Adaptable(adaptableClass = Resource.class, adapters = @Adapter(value = { String.class }))
 public class StarResource extends SyntheticResource {
@@ -50,35 +48,39 @@ public class StarResource extends Synthe
         }
     }
 
-    /** True if a StarResource should be used for the given request, if
-     *  a real Resource was not found */
+    /**
+     * True if a StarResource should be used for the given request, if a real
+     * Resource was not found
+     */
     public static boolean appliesTo(String path) {
         return path.contains(SLASH_STAR) || path.endsWith(SLASH_STAR);
     }
 
     /**
      * Returns true if the path of the resource ends with the
-     * {@link #SLASH_STAR} and therefore should be considered a star
-     * resource.
+     * {@link #SLASH_STAR} and therefore should be considered a star resource.
      */
     public static boolean isStarResource(Resource res) {
         return res.getPath().endsWith(SLASH_STAR);
     }
 
     public StarResource(ResourceResolver resourceResolver, String path) {
-        super(resourceResolver, getResourceMetadata(path), DEFAULT_RESOURCE_TYPE);
+        super(resourceResolver, getResourceMetadata(path),
+                DEFAULT_RESOURCE_TYPE);
         resourceSuperType = UNSET_RESOURCE_SUPER_TYPE;
     }
 
     /**
-     * Calls {@link ResourceUtil#getResourceSuperType(ResourceResolver, String)} method
-     * to dynamically resolve the resource super type of this star resource.
+     * Calls {@link ResourceUtil#getResourceSuperType(ResourceResolver, String)}
+     * method to dynamically resolve the resource super type of this star
+     * resource.
      */
     public String getResourceSuperType() {
-        // Yes, this isn't how you're supposed to compare Strings, but this is intentional.
+        // Yes, this isn't how you're supposed to compare Strings, but this is
+        // intentional.
         if (resourceSuperType == UNSET_RESOURCE_SUPER_TYPE) {
-            resourceSuperType = ResourceUtil.getResourceSuperType(this.getResourceResolver(),
-                    this.getResourceType());
+            resourceSuperType = ResourceUtil.getResourceSuperType(
+                    this.getResourceResolver(), this.getResourceType());
         }
         return resourceSuperType;
     }
@@ -86,21 +88,22 @@ public class StarResource extends Synthe
     @Override
     @SuppressWarnings("unchecked")
     public <Type> Type adaptTo(Class<Type> type) {
-        if ( type == String.class ) {
-            return (Type)"";
+        if (type == String.class) {
+            return (Type) "";
         }
         return super.adaptTo(type);
     }
 
     /** Get our ResourceMetadata for given path */
     static ResourceMetadata getResourceMetadata(String path) {
-    	ResourceMetadata result = new ResourceMetadata();
+        ResourceMetadata result = new ResourceMetadata();
 
-    	// The path is up to /*, what follows is pathInfo
+        // The path is up to /*, what follows is pathInfo
         final int index = path.indexOf(SLASH_STAR);
-        if(index >= 0) {
+        if (index >= 0) {
             result.setResolutionPath(path.substring(0, index) + SLASH_STAR);
-            result.setResolutionPathInfo(path.substring(index + SLASH_STAR.length()));
+            result.setResolutionPathInfo(path.substring(index
+                    + SLASH_STAR.length()));
         } else {
             result.setResolutionPath(path);
         }

Propchange: sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/StarResource.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/StarResource.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Copied: sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/URI.java (from r1339051, sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/URI.java)
URL: http://svn.apache.org/viewvc/sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/URI.java?p2=sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/URI.java&p1=sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/URI.java&r1=1339051&r2=1342154&rev=1342154&view=diff
==============================================================================
--- sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/URI.java (original)
+++ sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/URI.java Thu May 24 06:42:52 2012
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.jcr.resource.internal.helper;
+package org.apache.sling.resourceresolver.impl.helper;
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;

Propchange: sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/URI.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/URI.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Copied: sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/URIException.java (from r1339051, sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/URIException.java)
URL: http://svn.apache.org/viewvc/sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/URIException.java?p2=sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/URIException.java&p1=sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/URIException.java&r1=1339051&r2=1342154&rev=1342154&view=diff
==============================================================================
--- sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/URIException.java (original)
+++ sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/URIException.java Thu May 24 06:42:52 2012
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.jcr.resource.internal.helper;
+package org.apache.sling.resourceresolver.impl.helper;
 
 import org.apache.sling.api.SlingException;
 

Propchange: sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/URIException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/URIException.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Copied: sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/WrappedResourceProvider.java (from r1339051, sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/WrappedResourceProvider.java)
URL: http://svn.apache.org/viewvc/sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/WrappedResourceProvider.java?p2=sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/WrappedResourceProvider.java&p1=sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/WrappedResourceProvider.java&r1=1339051&r2=1342154&rev=1342154&view=diff
==============================================================================
--- sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/WrappedResourceProvider.java (original)
+++ sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/WrappedResourceProvider.java Thu May 24 06:42:52 2012
@@ -15,61 +15,52 @@
  * KIND, either express or implied. See the License for the
  * specific language governing permissions and limitations under the License.
  */
-package org.apache.sling.jcr.resource.internal.helper;
+package org.apache.sling.resourceresolver.impl.helper;
 
 import java.util.Iterator;
+import java.util.Map;
 
 import javax.servlet.http.HttpServletRequest;
 
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceProvider;
 import org.apache.sling.api.resource.ResourceResolver;
+import org.osgi.framework.Constants;
 
 /**
  *
  */
-public class WrappedResourceProvider  implements ResourceProvider {
+public class WrappedResourceProvider extends AbstractWrappedResourceProvider {
 
-    private ResourceProvider resourceProvider;
-    private Comparable<?> serviceReference;
+    private final ResourceProvider resourceProvider;
 
     /**
      *
      */
-    public WrappedResourceProvider(ResourceProvider resourceProvider, Comparable<?> serviceReference) {
+    public WrappedResourceProvider(final ResourceProvider resourceProvider, final Map<String, Object> properties) {
+        super(properties, "p-" + String.valueOf(properties.get(Constants.SERVICE_ID)));
         this.resourceProvider = resourceProvider;
-        this.serviceReference = serviceReference;
     }
 
     /**
-     * {@inheritDoc}
-     * @see org.apache.sling.api.resource.ResourceProvider#getResource(org.apache.sling.api.resource.ResourceResolver, java.lang.String)
-     */
-    public Resource getResource(ResourceResolver arg0, String arg1) {
-        return resourceProvider.getResource(arg0, arg1);
-    }
-
-    /**
-     * {@inheritDoc}
-     * @see org.apache.sling.api.resource.ResourceProvider#getResource(org.apache.sling.api.resource.ResourceResolver, javax.servlet.http.HttpServletRequest, java.lang.String)
+     * @see ResourceProvider#getResource(ResourceResolver, String)
      */
-    public Resource getResource(ResourceResolver arg0, HttpServletRequest arg1, String arg2) {
-        return resourceProvider.getResource(arg0, arg1, arg2);
+    public Resource getResource(final ResourceResolverContext ctx, final ResourceResolver resourceResolver, final HttpServletRequest request, final String path) {
+        return this.resourceProvider.getResource(resourceResolver, request, path);
     }
 
     /**
-     * {@inheritDoc}
-     * @see org.apache.sling.api.resource.ResourceProvider#listChildren(org.apache.sling.api.resource.Resource)
+     * @see ResourceProvider#getResource(ResourceResolver, HttpServletRequest, String)
      */
-    public Iterator<Resource> listChildren(Resource arg0) {
-        return resourceProvider.listChildren(arg0);
+    public Resource getResource(final ResourceResolverContext ctx, final ResourceResolver resourceResolver, final String path) {
+        return this.resourceProvider.getResource(resourceResolver, path);
     }
 
     /**
-     *
+     * @see ResourceProvider#listChildren(Resource)
      */
-    public Comparable<?> getComparable() {
-        return serviceReference;
+    public Iterator<Resource> listChildren(final ResourceResolverContext ctx, final Resource parent) {
+        return this.resourceProvider.listChildren(parent);
     }
 
     /**
@@ -86,7 +77,7 @@ public class WrappedResourceProvider  im
      * @see java.lang.Object#equals(java.lang.Object)
      */
     @Override
-    public boolean equals(Object obj) {
+    public boolean equals(final Object obj) {
         if ( obj instanceof WrappedResourceProvider ) {
             return resourceProvider.equals(((WrappedResourceProvider) obj).resourceProvider);
         } else if ( obj instanceof ResourceProvider) {

Propchange: sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/WrappedResourceProvider.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/WrappedResourceProviderFactory.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/WrappedResourceProviderFactory.java?rev=1342154&view=auto
==============================================================================
--- sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/WrappedResourceProviderFactory.java (added)
+++ sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/WrappedResourceProviderFactory.java Thu May 24 06:42:52 2012
@@ -0,0 +1,151 @@
+/*
+ * 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.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.osgi.framework.Constants;
+
+/**
+ *
+ */
+public class WrappedResourceProviderFactory extends AbstractWrappedResourceProvider {
+
+    /**
+     * 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;
+
+    /**
+     *
+     */
+    public WrappedResourceProviderFactory(final ResourceProviderFactory factory, final Map<String, Object> properties) {
+        super(properties, "f-" + String.valueOf(properties.get(Constants.SERVICE_ID)));
+        this.resourceProviderFactory = factory;
+    }
+
+    private ResourceProvider getResourceProvider(final ResourceResolverContext ctx) {
+        ResourceProvider rp = ctx.getFactoryResourceProvider(this.getKey());
+        if ( rp == null ) {
+            try {
+                rp = this.login(ctx);
+            } catch (final LoginException le ) {
+                // SHOULD WE LOG? (TODO)
+            }
+            if ( rp == null ) {
+                rp = NULL_PROVIDER;
+                ctx.addFactoryResourceProvider(this.getKey(), rp);
+            }
+        }
+        return rp;
+    }
+
+    /**
+     * @see ResourceProvider#getResource(ResourceResolver, String)
+     */
+    public Resource getResource(final ResourceResolverContext ctx, final ResourceResolver resourceResolver, final HttpServletRequest request, final String path) {
+        return this.getResourceProvider(ctx).getResource(resourceResolver, request, path);
+    }
+
+    /**
+     * @see ResourceProvider#getResource(ResourceResolver, HttpServletRequest, String)
+     */
+    public Resource getResource(final ResourceResolverContext ctx, final ResourceResolver resourceResolver, final String path) {
+        return this.getResourceProvider(ctx).getResource(resourceResolver, path);
+    }
+
+    /**
+     * @see ResourceProvider#listChildren(Resource)
+     */
+    public Iterator<Resource> listChildren(final ResourceResolverContext ctx, final Resource parent) {
+        return this.getResourceProvider(ctx).listChildren(parent);
+    }
+
+    /**
+     * {@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 WrappedResourceProviderFactory ) {
+            return resourceProviderFactory.equals(((WrappedResourceProviderFactory) 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.getAuthInfo());
+        } else {
+            rp = this.resourceProviderFactory.getResourceProvider(ctx.getAuthInfo());
+        }
+        ctx.addFactoryResourceProvider(this.getKey(), rp);
+        return rp;
+    }
+}

Propchange: sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/WrappedResourceProviderFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/WrappedResourceProviderFactory.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Propchange: sling/whiteboard/SLING-2396/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/helper/WrappedResourceProviderFactory.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain