incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cziege...@apache.org
Subject svn commit: r1350171 [1/2] - in /sling/trunk/bundles: jcr/resource/ jcr/resource/src/main/appended-resources/ jcr/resource/src/main/java/org/apache/sling/jcr/resource/ jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/ jcr/resource/src/...
Date Thu, 14 Jun 2012 10:06:31 GMT
Author: cziegeler
Date: Thu Jun 14 10:06:30 2012
New Revision: 1350171

URL: http://svn.apache.org/viewvc?rev=1350171&view=rev
Log:
SLING-2396 : Add new resourceresolver project

Added:
    sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProviderFactory.java   (with props)
Removed:
    sling/trunk/bundles/jcr/resource/src/main/appended-resources/
    sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolver.java
    sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/WorkspaceAuthInfoPostProcessor.java
    sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/WorkspaceDecoratedResource.java
    sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProviderEntry.java
    sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/starresource/
    sling/trunk/bundles/jcr/resource/src/main/resources/OSGI-INF/
    sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverTest.java
    sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/MapEntryTest.java
    sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/RedirectResourceTest.java
    sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourcePathIteratorTest.java
    sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntryTest.java
    sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/starresource/
Modified:
    sling/trunk/bundles/jcr/resource/README.txt
    sling/trunk/bundles/jcr/resource/pom.xml
    sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrPropertyMap.java
    sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceConstants.java
    sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceUtil.java
    sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrItemAdapterFactory.java
    sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceListener.java
    sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverFactoryImpl.java
    sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/JcrPropertyMapCacheEntry.java
    sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/LazyInputStream.java
    sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResource.java
    sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrPropertyResource.java
    sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProvider.java
    sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/scripting/JcrObjectsBindingsValuesProvider.java
    sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrResourceListenerTest.java
    sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/SynchronousJcrResourceListener.java
    sling/trunk/bundles/resourceresolver/src/main/resources/OSGI-INF/metatype/metatype.properties

Modified: sling/trunk/bundles/jcr/resource/README.txt
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/README.txt?rev=1350171&r1=1350170&r2=1350171&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/resource/README.txt (original)
+++ sling/trunk/bundles/jcr/resource/README.txt Thu Jun 14 10:06:30 2012
@@ -1,23 +1,23 @@
-Apache Sling Resource Resolver
+Apache Sling JCR Resource Resolver
 
 This bundle provides the JCR based Resource Resolver.
 
 Getting Started
 ===============
 
-This component uses a Maven 2 (http://maven.apache.org/) build
+This component uses a Maven 3 (http://maven.apache.org/) build
 environment. It requires a Java 5 JDK (or higher) and Maven (http://maven.apache.org/)
-2.0.7 or later. We recommend to use the latest Maven version.
+3.0.3 or later. We recommend to use the latest Maven version.
 
-If you have Maven 2 installed, you can compile and
+If you have Maven 3 installed, you can compile and
 package the jar using the following command:
 
     mvn package
 
-See the Maven 2 documentation for other build features.
+See the Maven 3 documentation for other build features.
 
 The latest source code for this component is available in the
-Subversion (http://subversion.tigris.org/) source repository of
+Subversion (http://subversion.apache.org/) source repository of
 the Apache Software Foundation. If you have Subversion installed,
 you can checkout the latest source using the following command:
 

Modified: sling/trunk/bundles/jcr/resource/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/pom.xml?rev=1350171&r1=1350170&r2=1350171&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/resource/pom.xml (original)
+++ sling/trunk/bundles/jcr/resource/pom.xml Thu Jun 14 10:06:30 2012
@@ -146,7 +146,7 @@
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.api</artifactId>
-            <version>2.1.0</version>
+            <version>2.2.5-SNAPSHOT</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
@@ -174,7 +174,7 @@
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.commons.osgi</artifactId>
-            <version>2.0.6</version>
+            <version>2.1.0</version>
             <scope>provided</scope>
         </dependency>
         <dependency>

Modified: sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrPropertyMap.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrPropertyMap.java?rev=1350171&r1=1350170&r2=1350171&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrPropertyMap.java (original)
+++ sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrPropertyMap.java Thu Jun 14 10:06:30 2012
@@ -517,7 +517,7 @@ public class JcrPropertyMap
                 && jcrValue.getType() == PropertyType.BINARY) {
             ObjectInputStream ois = null;
             try {
-                ois = new ObjectInputStream(jcrValue.getStream(), this.dynamicClassLoader);
+                ois = new ObjectInputStream(jcrValue.getBinary().getStream(), this.dynamicClassLoader);
                 final Object obj = ois.readObject();
                 if ( type.isInstance(obj) ) {
                     return (T)obj;

Modified: sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceConstants.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceConstants.java?rev=1350171&r1=1350170&r2=1350171&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceConstants.java (original)
+++ sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceConstants.java Thu Jun 14 10:06:30 2012
@@ -81,6 +81,7 @@ public class JcrResourceConstants {
      * The type of this property, if present, is <code>String</code>.
      *
      * @since 2.1
+     * @deprecated
      */
     public static final String AUTHENTICATION_INFO_WORKSPACE = "user.jcr.workspace";
 

Modified: sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceUtil.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceUtil.java?rev=1350171&r1=1350170&r2=1350171&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceUtil.java (original)
+++ sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceUtil.java Thu Jun 14 10:06:30 2012
@@ -119,7 +119,7 @@ public class JcrResourceUtil {
         if(value instanceof Calendar) {
             val = fac.createValue((Calendar)value);
         } else if (value instanceof InputStream) {
-            val = fac.createValue((InputStream)value);
+            val = fac.createValue(fac.createBinary((InputStream)value));
         } else if (value instanceof Node) {
             val = fac.createValue((Node)value);
         } else if (value instanceof Long) {

Modified: sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrItemAdapterFactory.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrItemAdapterFactory.java?rev=1350171&r1=1350170&r2=1350171&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrItemAdapterFactory.java (original)
+++ sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrItemAdapterFactory.java Thu Jun 14 10:06:30 2012
@@ -83,9 +83,8 @@ class JcrItemAdapterFactory implements A
                 logger.error("Unable to adapt JCR Item to a Resource", e);
             }
             return null;
-        } else {
-            return getAdapter(adaptable, Resource.class).adaptTo(type);
         }
+        return getAdapter(adaptable, Resource.class).adaptTo(type);
     }
 
 }

Modified: sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceListener.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceListener.java?rev=1350171&r1=1350170&r2=1350171&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceListener.java (original)
+++ sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceListener.java Thu Jun 14 10:06:30 2012
@@ -34,17 +34,21 @@ import javax.jcr.observation.Event;
 import javax.jcr.observation.EventIterator;
 import javax.jcr.observation.EventListener;
 
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Properties;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Reference;
 import org.apache.jackrabbit.api.observation.JackrabbitEvent;
 import org.apache.sling.api.SlingConstants;
 import org.apache.sling.api.resource.LoginException;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.resource.ResourceResolverFactory;
-import org.apache.sling.api.resource.ResourceUtil;
-import org.apache.sling.jcr.resource.JcrResourceConstants;
+import org.osgi.framework.Constants;
 import org.osgi.service.event.EventAdmin;
 import org.osgi.service.event.EventConstants;
-import org.osgi.util.tracker.ServiceTracker;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -53,28 +57,34 @@ import org.slf4j.LoggerFactory;
  * events and creates resource events which are sent through the
  * OSGi event admin.
  */
+@Component(immediate = true)
+@Properties({
+    @Property(name = Constants.SERVICE_DESCRIPTION, value = "Apache Sling JcrResourceListener"),
+    @Property(name = Constants.SERVICE_VENDOR, value = "The Apache Software Foundation")
+
+})
 public class JcrResourceListener implements EventListener {
 
     /** Logger */
     private final Logger logger = LoggerFactory.getLogger(JcrResourceListener.class);
 
-    /** The workspace for observation. */
-    private final String workspaceName;
+    @Reference
+    private EventAdmin eventAdmin;
+
+    @Reference
+    private ResourceResolverFactory resourceResolverFactory;
+
+    /** The admin resource resolver. */
+    private ResourceResolver resourceResolver;
 
     /** The session for observation. */
-    private final Session session;
+    private Session session;
 
     /** Everything below this path is observed. */
-    private final String startPath;
+    private String startPath;
 
     /** The repository is mounted under this path. */
-    private final String mountPrefix;
-
-    /** The resource resolver. */
-    private final ResourceResolver resolver;
-
-    /** The event admin tracker. */
-    private final ServiceTracker eventAdminTracker;
+    private String mountPrefix;
 
     /** Is the Jackrabbit event class available? */
     private final boolean hasJackrabbitEventClass;
@@ -85,7 +95,7 @@ public class JcrResourceListener impleme
      * waiting for actual dispatching to the OSGi Event Admin in
      * {@link #processOsgiEventQueue()}
      */
-    private final LinkedBlockingQueue<Dictionary<String, Object>> osgiEventQueue;
+    private LinkedBlockingQueue<Dictionary<String, Object>> osgiEventQueue;
 
     /**
      * Marker event for {@link #processOsgiEventQueue()} to be signaled to
@@ -93,44 +103,7 @@ public class JcrResourceListener impleme
      */
     private final Dictionary<String, Object> TERMINATE_PROCESSING = new Hashtable<String, Object>(1);
 
-    /**
-     * Constructor.
-     * @param workspaceName The workspace name to observe
-     * @param factory    The resource resolver factory.
-     * @param startPath  The observation root path
-     * @param mountPrefix The mount path in the repository
-     * @param eventAdminTracker The service tracker for the event admin.
-     * @throws RepositoryException
-     */
-    public JcrResourceListener(final String workspaceName,
-                               final ResourceResolverFactory factory,
-                               final String startPath,
-                               final String mountPrefix,
-                               final ServiceTracker eventAdminTracker)
-    throws LoginException, RepositoryException {
-        this.workspaceName = workspaceName;
-        final Map<String,Object> authInfo = new HashMap<String,Object>();
-        if (workspaceName != null) {
-            authInfo.put(JcrResourceConstants.AUTHENTICATION_INFO_WORKSPACE,
-                workspaceName);
-        }
-        this.resolver = factory.getAdministrativeResourceResolver(authInfo);
-        this.session = resolver.adaptTo(Session.class);
-        this.startPath = startPath;
-        this.eventAdminTracker = eventAdminTracker;
-        this.mountPrefix = (mountPrefix.equals("/") ? null : mountPrefix);
-
-        this.osgiEventQueue = new LinkedBlockingQueue<Dictionary<String,Object>>();
-        Thread oeqt = new Thread(new Runnable() {
-            public void run() {
-                processOsgiEventQueue();
-            }
-        }, "JCR Resource Event Queue Processor");
-        oeqt.start();
-
-        this.session.getWorkspace().getObservationManager().addEventListener(this,
-            Event.NODE_ADDED|Event.NODE_REMOVED|Event.PROPERTY_ADDED|Event.PROPERTY_CHANGED|Event.PROPERTY_REMOVED,
-            this.startPath, true, null, null, false);
+    public JcrResourceListener() {
         boolean foundClass = false;
         try {
             this.getClass().getClassLoader().loadClass(JackrabbitEvent.class.getName());
@@ -141,18 +114,48 @@ public class JcrResourceListener impleme
         this.hasJackrabbitEventClass = foundClass;
     }
 
+    @Activate
+    protected void activate() throws RepositoryException, LoginException {
+        this.resourceResolver = this.resourceResolverFactory.getAdministrativeResourceResolver(null);
+        try {
+            this.session = this.resourceResolver.adaptTo(Session.class);
+            this.startPath = "/";
+            this.mountPrefix = null;
+
+            this.osgiEventQueue = new LinkedBlockingQueue<Dictionary<String,Object>>();
+            Thread oeqt = new Thread(new Runnable() {
+                public void run() {
+                    processOsgiEventQueue();
+                }
+            }, "JCR Resource Event Queue Processor");
+            oeqt.start();
+
+            this.session.getWorkspace().getObservationManager().addEventListener(this,
+                Event.NODE_ADDED|Event.NODE_REMOVED|Event.PROPERTY_ADDED|Event.PROPERTY_CHANGED|Event.PROPERTY_REMOVED,
+                this.startPath, true, null, null, false);
+        } catch (final RepositoryException re) {
+            this.resourceResolver.close();
+            this.resourceResolver = null;
+            throw re;
+        }
+    }
+
     /**
      * Dispose this listener.
      */
-    public void dispose() {
-
+    @Deactivate
+    protected void deactivate() {
         // unregister from observations
-        try {
-            this.session.getWorkspace().getObservationManager().removeEventListener(this);
-        } catch (RepositoryException e) {
-            logger.warn("Unable to remove session listener: " + this, e);
+        if ( this.session != null ) {
+            try {
+                this.session.getWorkspace().getObservationManager().removeEventListener(this);
+            } catch (RepositoryException e) {
+                logger.warn("Unable to remove session listener: " + this, e);
+            }
+        }
+        if ( this.resourceResolver != null ) {
+            this.resourceResolver.close();
         }
-        this.resolver.close();
 
         // drop any remaining OSGi Events not processed yet
         this.osgiEventQueue.clear();
@@ -164,7 +167,7 @@ public class JcrResourceListener impleme
      */
     public void onEvent(EventIterator events) {
         // if the event admin is currently not available, we just skip this
-        final EventAdmin localEA = (EventAdmin) this.eventAdminTracker.getService();
+        final EventAdmin localEA = this.eventAdmin;
         if ( localEA == null ) {
             return;
         }
@@ -293,11 +296,9 @@ public class JcrResourceListener impleme
      * @param event The JCR observation event.
      * @param topic The topic that should be used for the OSGi event.
      */
-    private void sendOsgiEvent(String path, final Event event, final String topic,
+    private void sendOsgiEvent(final String path, final Event event, final String topic,
             final ChangedAttributes changedAttributes) {
 
-        path = createWorkspacePath(path);
-
         final Dictionary<String, Object> properties = new Hashtable<String, Object>();
         properties.put(SlingConstants.PROPERTY_USERID, event.getUserID());
         if (this.isExternal(event)) {
@@ -335,52 +336,60 @@ public class JcrResourceListener impleme
             }
 
             try {
-                final EventAdmin localEa = (EventAdmin) this.eventAdminTracker.getService();
+                final EventAdmin localEa = this.eventAdmin;
                 if (localEa != null) {
                     final String topic = (String) event.remove(EventConstants.EVENT_TOPIC);
+                    boolean sendEvent = true;
                     if (!SlingConstants.TOPIC_RESOURCE_REMOVED.equals(topic)) {
                         final String path = (String) event.get(SlingConstants.PROPERTY_PATH);
-                        Resource resource = this.resolver.getResource(path);
+                        Resource resource = this.resourceResolver.getResource(path);
                         if (resource != null) {
-                            // check for nt:file nodes
-                            if (path.endsWith("/jcr:content")) {
-                                final Node node = resource.adaptTo(Node.class);
-                                if (node != null) {
+                            // check if this is a JCR backed resource, otherwise it is not visible!
+                            final Node node = resource.adaptTo(Node.class);
+                            if (node != null) {
+                                // check for nt:file nodes
+                                if (path.endsWith("/jcr:content")) {
                                     try {
                                         if (node.getParent().isNodeType("nt:file")) {
-                                            @SuppressWarnings("deprecation")
-                                            final Resource parentResource = ResourceUtil.getParent(resource);
+                                            final Resource parentResource = resource.getParent();
                                             if (parentResource != null) {
                                                 resource = parentResource;
                                                 event.put(SlingConstants.PROPERTY_PATH, resource.getPath());
                                             }
                                         }
-                                    } catch (RepositoryException re) {
+                                    } catch (final RepositoryException re) {
                                         // ignore this
                                     }
                                 }
-                            }
 
-                            final String resourceType = resource.getResourceType();
-                            if (resourceType != null) {
-                                event.put(SlingConstants.PROPERTY_RESOURCE_TYPE, resource.getResourceType());
-                            }
-                            final String resourceSuperType = resource.getResourceSuperType();
-                            if (resourceSuperType != null) {
-                                event.put(SlingConstants.PROPERTY_RESOURCE_SUPER_TYPE, resource.getResourceSuperType());
+                                final String resourceType = resource.getResourceType();
+                                if (resourceType != null) {
+                                    event.put(SlingConstants.PROPERTY_RESOURCE_TYPE, resource.getResourceType());
+                                }
+                                final String resourceSuperType = resource.getResourceSuperType();
+                                if (resourceSuperType != null) {
+                                    event.put(SlingConstants.PROPERTY_RESOURCE_SUPER_TYPE, resource.getResourceSuperType());
+                                }
+                            } else {
+                                // this is not a jcr backed resource
+                                sendEvent = false;
                             }
+
                         } else {
                             // take a quite silent note of not being able to
                             // resolve the resource
                             logger.debug(
                                 "processOsgiEventQueue: Resource at {} not found, which is not expected for an added or modified node",
                                 path);
+                            sendEvent = false;
                         }
                     }
 
-                    localEa.sendEvent(new org.osgi.service.event.Event(topic, event));
+                    if ( sendEvent ) {
+                        localEa.sendEvent(new org.osgi.service.event.Event(topic, event));
+                    }
                 }
-            } catch (Exception e) {
+            } catch (final Exception e) {
                 logger.warn("processOsgiEventQueue: Unexpected problem processing event " + event, e);
             }
         }
@@ -395,11 +404,4 @@ public class JcrResourceListener impleme
         }
         return false;
     }
-
-    private String createWorkspacePath(final String path) {
-        if (workspaceName == null) {
-            return path;
-        }
-        return workspaceName + ":" + path;
-    }
 }

Modified: sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverFactoryImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverFactoryImpl.java?rev=1350171&r1=1350170&r2=1350171&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverFactoryImpl.java (original)
+++ sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverFactoryImpl.java Thu Jun 14 10:06:30 2012
@@ -18,53 +18,27 @@
  */
 package org.apache.sling.jcr.resource.internal;
 
-import java.util.ArrayList;
-import java.util.Dictionary;
 import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
 import java.util.Map;
-import java.util.Set;
-import java.util.regex.Pattern;
 
-import javax.jcr.Credentials;
-import javax.jcr.RepositoryException;
 import javax.jcr.Session;
-import javax.jcr.SimpleCredentials;
 
-import org.apache.commons.collections.BidiMap;
-import org.apache.commons.collections.bidimap.TreeBidiMap;
+import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Properties;
 import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.PropertyUnbounded;
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.apache.felix.scr.annotations.ReferencePolicy;
-import org.apache.felix.scr.annotations.References;
 import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.api.resource.LoginException;
-import org.apache.sling.api.resource.ResourceDecorator;
-import org.apache.sling.api.resource.ResourceProvider;
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.resource.ResourceResolverFactory;
 import org.apache.sling.commons.classloader.DynamicClassLoaderManager;
-import org.apache.sling.commons.osgi.OsgiUtil;
-import org.apache.sling.jcr.api.SlingRepository;
 import org.apache.sling.jcr.resource.JcrResourceConstants;
 import org.apache.sling.jcr.resource.JcrResourceResolverFactory;
-import org.apache.sling.jcr.resource.internal.helper.MapEntries;
-import org.apache.sling.jcr.resource.internal.helper.Mapping;
-import org.apache.sling.jcr.resource.internal.helper.ResourceProviderEntry;
-import org.apache.sling.jcr.resource.internal.helper.RootResourceProviderEntry;
-import org.apache.sling.jcr.resource.internal.helper.jcr.JcrResourceProviderEntry;
 import org.osgi.framework.Constants;
 import org.osgi.service.component.ComponentContext;
-import org.osgi.service.event.EventAdmin;
-import org.osgi.util.tracker.ServiceTracker;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * The <code>JcrResourceResolverFactoryImpl</code> is the
@@ -72,162 +46,55 @@ import org.slf4j.LoggerFactory;
  * functionality:
  * <ul>
  * <li><code>JcrResourceResolverFactory</code> service
- * <li>Bundle listener to load initial content and manage OCM mapping
- * descriptors provided by bundles.
- * <li>Fires OSGi EventAdmin events on behalf of internal helper objects
  * </ul>
- *
- * First attempt of an resource resolver factory implementation.
- * WORK IN PROGRESS - see SLING-1262
  */
-@Component(immediate=true, label="%resource.resolver.name", description="%resource.resolver.description", specVersion="1.1", metatype=true)
-@Service(value={JcrResourceResolverFactory.class, ResourceResolverFactory.class})
+@Component(name = "org.apache.sling.jcr.resource.internal.LegacyJcrResourceResolverFactoryImpl")
+@Service(value = JcrResourceResolverFactory.class)
 @Properties({
-    @Property(name = Constants.SERVICE_DESCRIPTION, value="Sling JcrResourceResolverFactory Implementation"),
-    @Property(name = Constants.SERVICE_VENDOR, value="The Apache Software Foundation")
-    
-})
-@References({
-    @Reference(name="ResourceProvider", referenceInterface=ResourceProvider.class, cardinality=ReferenceCardinality.OPTIONAL_MULTIPLE, policy=ReferencePolicy.DYNAMIC),
-    @Reference(name="ResourceDecorator", referenceInterface=ResourceDecorator.class, cardinality=ReferenceCardinality.OPTIONAL_MULTIPLE, policy=ReferencePolicy.DYNAMIC)    
+        @Property(name = Constants.SERVICE_DESCRIPTION, value = "Apache Sling JcrResourceResolverFactory Implementation"),
+        @Property(name = Constants.SERVICE_VENDOR, value = "The Apache Software Foundation")
+
 })
 public class JcrResourceResolverFactoryImpl implements
-        JcrResourceResolverFactory, ResourceResolverFactory {
-
-    public final static class ResourcePattern {
-        public final Pattern pattern;
-
-        public final String replacement;
-
-        public ResourcePattern(final Pattern p, final String r) {
-            this.pattern = p;
-            this.replacement = r;
-        }
-    }
-
-    private static final boolean DEFAULT_MULTIWORKSPACE = false;
-
-    /**
-     * Special value which, if passed to listener.workspaces, will have resource
-     * events fired for all workspaces.
-     */
-    public static final String ALL_WORKSPACES = "*";
-
-    @Property(value={"/apps", "/libs" })
-    public static final String PROP_PATH = "resource.resolver.searchpath";
-
-    /**
-     * Defines whether namespace prefixes of resource names inside the path
-     * (e.g. <code>jcr:</code> in <code>/home/path/jcr:content</code>) are
-     * mangled or not.
-     * <p>
-     * Mangling means that any namespace prefix contained in the path is replaced
-     * as per the generic substitution pattern <code>/([^:]+):/_$1_/</code>
-     * when calling the <code>map</code> method of the resource resolver.
-     * Likewise the <code>resolve</code> methods will unmangle such namespace
-     * prefixes according to the substituation pattern
-     * <code>/_([^_]+)_/$1:/</code>.
-     * <p>
-     * This feature is provided since there may be systems out there in the wild
-     * which cannot cope with URLs containing colons, even though they are
-     * perfectly valid characters in the path part of URI references with a
-     * scheme.
-     * <p>
-     * The default value of this property if no configuration is provided is
-     * <code>true</code>.
-     *
-     */
-    @Property(boolValue=true)
-    private static final String PROP_MANGLE_NAMESPACES = "resource.resolver.manglenamespaces";
-
-
-    @Property(boolValue=true)
-    private static final String PROP_ALLOW_DIRECT = "resource.resolver.allowDirect";
-
-    /**
-     * The resolver.virtual property has no default configuration. But the sling
-     * maven plugin and the sling management console cannot handle empty
-     * multivalue properties at the moment. So we just add a dummy direct
-     * mapping.
-     */
-    @Property(value="/:/", unbounded=PropertyUnbounded.ARRAY)
-    private static final String PROP_VIRTUAL = "resource.resolver.virtual";
-
-    @Property(value={"/:/", "/content/:/", "/system/docroot/:/"})
-    private static final String PROP_MAPPING = "resource.resolver.mapping";
-
-    @Property(value=MapEntries.DEFAULT_MAP_ROOT)
-    private static final String PROP_MAP_LOCATION = "resource.resolver.map.location";
-
-    @Property(boolValue=DEFAULT_MULTIWORKSPACE)
-    private static final String PROP_MULTIWORKSPACE = "resource.resolver.multiworkspace";
-
-    /** default log */
-    private final Logger log = LoggerFactory.getLogger(getClass());
+        JcrResourceResolverFactory {
 
     @Reference
-    private SlingRepository repository;
-
-    /** Tracker for the resource decorators. */
-    private final ResourceDecoratorTracker resourceDecoratorTracker = new ResourceDecoratorTracker();
-
-    // helper for the new JcrResourceResolver
-    private MapEntries mapEntries = MapEntries.EMPTY;
-
-    /** all mappings */
-    private Mapping[] mappings;
-
-    /** The fake urls */
-    private BidiMap virtualURLMap;
-
-    /** <code>true</code>, if direct mappings from URI to handle are allowed */
-    private boolean allowDirect = false;
-
-    // the search path for ResourceResolver.getResource(String)
-    private String[] searchPath;
-
-    // the root location of the /etc/map entries
-    private String mapRoot;
-
-    private final RootResourceProviderEntry rootProviderEntry;
-
-    // whether to mangle paths with namespaces or not
-    private boolean mangleNamespacePrefixes;
-
-    private boolean useMultiWorkspaces;
-
-    /** The resource listeners for the observation events. */
-    private Set<JcrResourceListener> resourceListeners;
-
-    /** The service tracker for the event admin
-     */
-    private ServiceTracker eventAdminTracker;
+    private ResourceResolverFactory delegatee;
 
     /** The dynamic class loader */
-    @Reference(cardinality=ReferenceCardinality.OPTIONAL_UNARY, policy=ReferencePolicy.DYNAMIC)
+    @Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY, policy = ReferencePolicy.DYNAMIC)
     private DynamicClassLoaderManager dynamicClassLoaderManager;
 
     private JcrItemAdapterFactory jcrItemAdapterFactory;
 
-    public JcrResourceResolverFactoryImpl() {
-        this.rootProviderEntry = new RootResourceProviderEntry();
-
+    @Activate
+    protected void activate(final ComponentContext componentContext) {
+        jcrItemAdapterFactory = new JcrItemAdapterFactory(
+                componentContext.getBundleContext(), this);
     }
 
-    public ResourceDecoratorTracker getResourceDecoratorTracker() {
-        return this.resourceDecoratorTracker;
+    /** Deativates this component, called by SCR to take out of service */
+    protected void deactivate(final ComponentContext componentContext) {
+        if (jcrItemAdapterFactory != null) {
+            jcrItemAdapterFactory.dispose();
+            jcrItemAdapterFactory = null;
+        }
     }
 
-    // ---------- JcrResourceResolverFactory -----------------------------------
+    /** Get the dynamic class loader if available */
+    ClassLoader getDynamicClassLoader() {
+        final DynamicClassLoaderManager dclm = this.dynamicClassLoaderManager;
+        if (dclm != null) {
+            return dclm.getDynamicClassLoader();
+        }
+        return null;
+    }
 
     /**
-     * Returns a new <code>ResourceResolve</code> for the given session. Note
-     * that each call to this method returns a new resource manager instance.
-     *
      * @see org.apache.sling.jcr.resource.JcrResourceResolverFactory#getResourceResolver(javax.jcr.Session)
      */
-    public ResourceResolver getResourceResolver(Session session) {
-        Map<String, Object> authInfo = new HashMap<String, Object>(1);
+    public ResourceResolver getResourceResolver(final Session session) {
+        final Map<String, Object> authInfo = new HashMap<String, Object>(1);
         authInfo.put(JcrResourceConstants.AUTHENTICATION_INFO_SESSION, session);
         try {
             return getResourceResolver(authInfo);
@@ -238,521 +105,19 @@ public class JcrResourceResolverFactoryI
         }
     }
 
-    // ---------- Resource Resolver Factory ------------------------------------
-
     /**
      * @see org.apache.sling.api.resource.ResourceResolverFactory#getAdministrativeResourceResolver(java.util.Map)
      */
     public ResourceResolver getAdministrativeResourceResolver(
-            final Map<String, Object> authenticationInfo) throws LoginException {
-        return getResourceResolverInternal(authenticationInfo, true);
+            final Map<String, Object> arg0) throws LoginException {
+        return delegatee.getAdministrativeResourceResolver(arg0);
     }
 
     /**
      * @see org.apache.sling.api.resource.ResourceResolverFactory#getResourceResolver(java.util.Map)
      */
-    public ResourceResolver getResourceResolver(
-            final Map<String, Object> authenticationInfo) throws LoginException {
-        return getResourceResolverInternal(authenticationInfo, false);
-    }
-
-    /**
-     * Create a new ResourceResolver wrapping a Session object. Carries map of
-     * authentication info in order to create a new resolver as needed.
-     */
-    private ResourceResolver getResourceResolverInternal(
-            final Map<String, Object> authenticationInfo, final boolean isAdmin)
+    public ResourceResolver getResourceResolver(final Map<String, Object> arg0)
             throws LoginException {
-
-        // by default any session used by the resource resolver returned is
-        // closed when the resource resolver is closed
-        boolean logoutSession = true;
-
-        // derive the session to be used
-        Session session;
-        try {
-            final String workspace = getWorkspace(authenticationInfo);
-            if (isAdmin) {
-                // requested admin session to any workspace (or default)
-                session = getRepository().loginAdministrative(workspace);
-
-            } else {
-
-                session = getSession(authenticationInfo);
-                if (session == null) {
-                    // requested non-admin session to any workspace (or default)
-                    final Credentials credentials = getCredentials(authenticationInfo);
-                    session = getRepository().login(credentials, workspace);
-
-                } else if (workspace != null) {
-                    // session provided by map; but requested a different
-                    // workspace impersonate can only change the user not switch
-                    // the workspace as a workaround we login to the requested
-                    // workspace with admin and then switch to the provided
-                    // session's user (if required)
-                    Session tmpSession = null;
-                    try {
-                        tmpSession = getRepository().loginAdministrative(
-                            workspace);
-                        if (tmpSession.getUserID().equals(session.getUserID())) {
-                            session = tmpSession;
-                            tmpSession = null;
-                        } else {
-                            session = tmpSession.impersonate(new SimpleCredentials(
-                                session.getUserID(), new char[0]));
-                        }
-                    } finally {
-                        if (tmpSession != null) {
-                            tmpSession.logout();
-                        }
-                    }
-
-                } else {
-                    // session provided; no special workspace; just make sure
-                    // the session is not logged out when the resolver is closed
-                    logoutSession = false;
-                }
-            }
-        } catch (RepositoryException re) {
-            throw getLoginException(re);
-        }
-
-        session = handleImpersonation(session, authenticationInfo, logoutSession);
-
-        final JcrResourceProviderEntry sessionRoot = new JcrResourceProviderEntry(
-            session, rootProviderEntry, this.getDynamicClassLoader(),
-            useMultiWorkspaces);
-
-        if (logoutSession) {
-            return new JcrResourceResolver(sessionRoot, this, isAdmin,
-                authenticationInfo, useMultiWorkspaces);
-        }
-
-        return new JcrResourceResolver(sessionRoot, this, isAdmin,
-            authenticationInfo, useMultiWorkspaces) {
-            protected void closeSession() {
-            }
-        };
-    }
-
-    // ---------- Implementation helpers --------------------------------------
-
-    /** Get the dynamic class loader if available */
-    ClassLoader getDynamicClassLoader() {
-        final DynamicClassLoaderManager dclm = this.dynamicClassLoaderManager;
-        if ( dclm != null ) {
-            return dclm.getDynamicClassLoader();
-        }
-        return null;
-    }
-
-    /**
-     * This method is called from {@link MapEntries}
-     */
-    public BidiMap getVirtualURLMap() {
-        return virtualURLMap;
+        return delegatee.getResourceResolver(arg0);
     }
-
-    /**
-     * This method is called from {@link MapEntries}
-     */
-    public Mapping[] getMappings() {
-        return mappings;
-    }
-
-    String[] getSearchPath() {
-        return searchPath;
-    }
-
-    boolean isMangleNamespacePrefixes() {
-        return mangleNamespacePrefixes;
-
-    }
-
-    public String getMapRoot() {
-        return mapRoot;
-    }
-
-    MapEntries getMapEntries() {
-        return mapEntries;
-    }
-
-    String getDefaultWorkspaceName() {
-        return this.repository.getDefaultWorkspace();
-    }
-
-    /**
-     * Getter for rootProviderEntry, making it easier to extend
-     * JcrResourceResolverFactoryImpl. See <a
-     * href="https://issues.apache.org/jira/browse/SLING-730">SLING-730</a>
-     *
-     * @return Our rootProviderEntry
-     */
-    protected ResourceProviderEntry getRootProviderEntry() {
-        return rootProviderEntry;
-    }
-
-    // ---------- SCR Integration ---------------------------------------------
-
-    /** Activates this component, called by SCR before registering as a service */
-    protected void activate(final ComponentContext componentContext) {
-        // setup tracker first as this is used in the bind/unbind methods
-        this.eventAdminTracker = new ServiceTracker(componentContext.getBundleContext(),
-                EventAdmin.class.getName(), null);
-        this.eventAdminTracker.open();
-
-        final Dictionary<?, ?> properties = componentContext.getProperties();
-
-        BidiMap virtuals = new TreeBidiMap();
-        String[] virtualList = OsgiUtil.toStringArray(properties.get(PROP_VIRTUAL));
-        for (int i = 0; virtualList != null && i < virtualList.length; i++) {
-            String[] parts = Mapping.split(virtualList[i]);
-            virtuals.put(parts[0], parts[2]);
-        }
-        virtualURLMap = virtuals;
-
-        List<Mapping> maps = new ArrayList<Mapping>();
-        String[] mappingList = (String[]) properties.get(PROP_MAPPING);
-        for (int i = 0; mappingList != null && i < mappingList.length; i++) {
-            maps.add(new Mapping(mappingList[i]));
-        }
-        Mapping[] tmp = maps.toArray(new Mapping[maps.size()]);
-
-        // check whether direct mappings are allowed
-        Boolean directProp = (Boolean) properties.get(PROP_ALLOW_DIRECT);
-        allowDirect = (directProp != null) ? directProp.booleanValue() : true;
-        if (allowDirect) {
-            Mapping[] tmp2 = new Mapping[tmp.length + 1];
-            tmp2[0] = Mapping.DIRECT;
-            System.arraycopy(tmp, 0, tmp2, 1, tmp.length);
-            mappings = tmp2;
-        } else {
-            mappings = tmp;
-        }
-
-        // from configuration if available
-        searchPath = OsgiUtil.toStringArray(properties.get(PROP_PATH));
-        if (searchPath != null && searchPath.length > 0) {
-            for (int i = 0; i < searchPath.length; i++) {
-                // ensure leading slash
-                if (!searchPath[i].startsWith("/")) {
-                    searchPath[i] = "/" + searchPath[i];
-                }
-                // ensure trailing slash
-                if (!searchPath[i].endsWith("/")) {
-                    searchPath[i] += "/";
-                }
-            }
-        }
-        if (searchPath == null) {
-            searchPath = new String[] { "/" };
-        }
-
-        // namespace mangling
-        mangleNamespacePrefixes = OsgiUtil.toBoolean(
-            properties.get(PROP_MANGLE_NAMESPACES), false);
-
-        // the root of the resolver mappings
-        mapRoot = OsgiUtil.toString(properties.get(PROP_MAP_LOCATION),
-            MapEntries.DEFAULT_MAP_ROOT);
-
-        // set up the map entries from configuration
-        try {
-            mapEntries = new MapEntries(this, componentContext.getBundleContext(), this.eventAdminTracker);
-        } catch (Exception e) {
-            log.error(
-                "activate: Cannot access repository, failed setting up Mapping Support",
-                e);
-        }
-
-
-        // start observation listener
-        try {
-            this.resourceListeners = new HashSet<JcrResourceListener>();
-
-            // first - add a listener for the default workspace
-            this.resourceListeners.add(new JcrResourceListener(null, this, "/", "/", this.eventAdminTracker));
-
-            // check if multi workspace support is enabled
-            this.useMultiWorkspaces = OsgiUtil.toBoolean(properties.get(PROP_MULTIWORKSPACE), DEFAULT_MULTIWORKSPACE);
-            if (this.useMultiWorkspaces) {
-                final String[] listenerWorkspaces = getAllWorkspaces();
-                for (final String wspName : listenerWorkspaces) {
-                    if (!wspName.equals(this.repository.getDefaultWorkspace())) {
-                        this.resourceListeners.add(
-                            new JcrResourceListener(wspName, this, "/", "/", this.eventAdminTracker));
-                    }
-                }
-            }
-        } catch (Exception e) {
-            log.error(
-                "activate: Cannot create resource listener; resource events for JCR resources will be disabled.",
-                e);
-        }
-
-        try {
-            plugin = new JcrResourceResolverWebConsolePlugin(componentContext.getBundleContext(), this);
-        } catch (Throwable ignore) {
-            // an exception here propably means the web console plugin is not available
-            log.debug(
-                    "activate: unable to setup web console plugin.", ignore);
-        }
-        
-        jcrItemAdapterFactory = new JcrItemAdapterFactory(componentContext.getBundleContext(), this);
-    }
-
-    private JcrResourceResolverWebConsolePlugin plugin;
-
-    /** Deativates this component, called by SCR to take out of service */
-    protected void deactivate(final ComponentContext componentContext) {
-        if (jcrItemAdapterFactory != null) {
-            jcrItemAdapterFactory.dispose();
-            jcrItemAdapterFactory = null;
-        }
-        
-        if (plugin != null) {
-            plugin.dispose();
-            plugin = null;
-        }
-
-        if (mapEntries != null) {
-            mapEntries.dispose();
-            mapEntries = MapEntries.EMPTY;
-        }
-        if ( this.eventAdminTracker != null ) {
-            this.eventAdminTracker.close();
-            this.eventAdminTracker = null;
-        }
-        if ( this.resourceListeners != null && !this.resourceListeners.isEmpty() ) {
-            for ( JcrResourceListener resourceListener : this.resourceListeners ) {
-                resourceListener.dispose();
-            }
-            this.resourceListeners = null;
-        }
-        this.resourceDecoratorTracker.close();
-    }
-
-    protected void bindResourceProvider(final ResourceProvider provider, final Map<String, Object> props) {
-        this.rootProviderEntry.bindResourceProvider(provider, props, this.eventAdminTracker);
-    }
-
-    protected void unbindResourceProvider(final ResourceProvider provider, final Map<String, Object> props) {
-        this.rootProviderEntry.unbindResourceProvider(provider, props, this.eventAdminTracker);
-    }
-
-    protected void bindResourceDecorator(final ResourceDecorator decorator, final Map<String, Object> props) {
-        this.resourceDecoratorTracker.bindResourceDecorator(decorator, props);
-    }
-
-    protected void unbindResourceDecorator(final ResourceDecorator decorator, final Map<String, Object> props) {
-        this.resourceDecoratorTracker.unbindResourceDecorator(decorator, props);
-    }
-
-    // ---------- internal helper ----------------------------------------------
-
-    /** Returns the JCR repository used by this factory */
-    protected SlingRepository getRepository() {
-        return repository;
-    }
-
-    /**
-     * Create a login exception from a repository exception.
-     * If the repository exception is a  {@link javax.jcr.LoginException}
-     * a {@link LoginException} is created with the same information.
-     * Otherwise a {@link LoginException} is created which wraps the
-     * repository exception.
-     * @param re The repository exception.
-     * @return The login exception.
-     */
-    private LoginException getLoginException(final RepositoryException re) {
-        if ( re instanceof javax.jcr.LoginException ) {
-            return new LoginException(re.getMessage(), re.getCause());
-        }
-        return new LoginException("Unable to login " + re.getMessage(), re);
-    }
-
-    /**
-     * Get an array of all workspaces.
-     */
-    private String[] getAllWorkspaces() throws RepositoryException {
-        Session session =  null;
-        try {
-            session = repository.loginAdministrative(null);
-            return session.getWorkspace().getAccessibleWorkspaceNames();
-        } finally {
-            if (session != null) {
-                session.logout();
-            }
-        }
-    }
-
-    /**
-     * Returns the session provided as the user.jcr.session property of the
-     * <code>authenticationInfo</code> map or <code>null</code> if the
-     * property is not contained in the map or is not a <code>javax.jcr.Session</code>.
-     * @param authenticationInfo Optional authentication info.
-     * @return The user.jcr.session property or <code>null</code>
-     */
-    private Session getSession(final Map<String, Object> authenticationInfo) {
-        if (authenticationInfo != null) {
-            final Object sessionObject = authenticationInfo.get(JcrResourceConstants.AUTHENTICATION_INFO_SESSION);
-            if (sessionObject instanceof Session) {
-                return (Session) sessionObject;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Return the workspace name.
-     * If the workspace name is provided, it is returned, otherwise
-     * <code>null</code> is returned.
-     * @param authenticationInfo Optional authentication info.
-     * @return The configured workspace name or <code>null</code>
-     */
-    private String getWorkspace(final Map<String, Object> authenticationInfo) {
-        if (authenticationInfo != null) {
-            final Object workspaceObject = authenticationInfo.get(JcrResourceConstants.AUTHENTICATION_INFO_WORKSPACE);
-            if (workspaceObject instanceof String) {
-                return (String) workspaceObject;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Return the sudo user information.
-     * If the sudo user info is provided, it is returned, otherwise
-     * <code>null</code> is returned.
-     * @param authenticationInfo Optional authentication info.
-     * @return The configured sudo user information or <code>null</code>
-     */
-    private String getSudoUser(final Map<String, Object> authenticationInfo) {
-        if (authenticationInfo != null) {
-            final Object sudoObject = authenticationInfo.get(ResourceResolverFactory.USER_IMPERSONATION);
-            if (sudoObject instanceof String) {
-                return (String) sudoObject;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Handle the sudo if configured. If the authentication info does not
-     * contain a sudo info, this method simply returns the passed in session. If
-     * a sudo user info is available, the session is tried to be impersonated.
-     * The new impersonated session is returned. The original session is closed.
-     * The session is also closed if the impersonation fails.
-     *
-     * @param session The session.
-     * @param authenticationInfo The optional authentication info.
-     * @param logoutSession whether to logout the <code>session</code> after
-     *            impersonation or not.
-     * @return The original session or impersonated session.
-     * @throws LoginException If something goes wrong.
-     */
-    private Session handleImpersonation(final Session session,
-            final Map<String, Object> authenticationInfo, boolean logoutSession)
-            throws LoginException {
-        final String sudoUser = getSudoUser(authenticationInfo);
-        if (sudoUser != null && !session.getUserID().equals(sudoUser)) {
-            try {
-                final SimpleCredentials creds = new SimpleCredentials(sudoUser,
-                    new char[0]);
-                copyAttributes(creds, authenticationInfo);
-                creds.setAttribute(ResourceResolver.USER_IMPERSONATOR,
-                    session.getUserID());
-                return session.impersonate(creds);
-            } catch (RepositoryException re) {
-                throw getLoginException(re);
-            } finally {
-                if (logoutSession) {
-                    session.logout();
-                }
-            }
-        }
-        return session;
-    }
-
-    /**
-     * Create a credentials object from the provided authentication info.
-     * If no map is provided, <code>null</code> is returned.
-     * If a map is provided and contains a credentials object, this object is
-     * returned.
-     * If a map is provided but does not contain a credentials object nor a
-     * user, <code>null</code> is returned.
-     * if a map is provided with a user name but without a credentials object
-     * a new credentials object is created and all values from the authentication
-     * info are added as attributes.
-     * @param authenticationInfo Optional authentication info
-     * @return A credentials object or <code>null</code>
-     */
-    private Credentials getCredentials(final Map<String, Object> authenticationInfo) {
-        if (authenticationInfo == null) {
-            return null;
-        }
-
-        final Object credentialsObject = authenticationInfo.get(JcrResourceConstants.AUTHENTICATION_INFO_CREDENTIALS);
-        if (credentialsObject instanceof Credentials) {
-            return (Credentials) credentialsObject;
-        }
-
-        // otherwise try to create SimpleCredentials if the userId is set
-        final Object userId = authenticationInfo.get(USER);
-        if (userId instanceof String) {
-            final Object password = authenticationInfo.get(PASSWORD);
-            final SimpleCredentials credentials = new SimpleCredentials(
-                (String) userId, ((password instanceof char[])
-                        ? (char[]) password
-                        : new char[0]));
-
-            // add attributes
-            copyAttributes(credentials, authenticationInfo);
-
-            return credentials;
-        }
-
-        // no user id (or not a String)
-        return null;
-    }
-
-    /**
-     * Copies the contents of the source map as attributes into the target
-     * <code>SimpleCredentials</code> object with the exception of the
-     * <code>user.jcr.credentials</code> and <code>user.password</code>
-     * attributes to prevent leaking passwords into the JCR Session attributes
-     * which might be used for break-in attempts.
-     *
-     * @param target The <code>SimpleCredentials</code> object whose attributes
-     *            are to be augmented.
-     * @param source The map whose entries (except the ones listed above) are
-     *            copied as credentials attributes.
-     */
-    private void copyAttributes(final SimpleCredentials target,
-            final Map<String, Object> source) {
-        final Iterator<Map.Entry<String, Object>> i = source.entrySet().iterator();
-        while (i.hasNext()) {
-            final Map.Entry<String, Object> current = i.next();
-            if (isAttributeVisible(current.getKey())) {
-                target.setAttribute(current.getKey(), current.getValue());
-            }
-        }
-    }
-
-    /**
-     * Returns <code>true</code> unless the name is
-     * <code>user.jcr.credentials</code> (
-     * {@link JcrResourceConstants#AUTHENTICATION_INFO_CREDENTIALS}) or contains
-     * the string <code>password</code> as in <code>user.password</code> (
-     * {@link org.apache.sling.api.resource.ResourceResolverFactory#PASSWORD})
-     *
-     * @param name The name to check whether it is visible or not
-     * @return <code>true</code> if the name is assumed visible
-     * @throws NullPointerException if <code>name</code> is <code>null</code>
-     */
-    static boolean isAttributeVisible(final String name) {
-        return !name.equals(JcrResourceConstants.AUTHENTICATION_INFO_CREDENTIALS)
-            && !name.contains("password");
-    }
-
 }
\ No newline at end of file

Modified: sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/JcrPropertyMapCacheEntry.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/JcrPropertyMapCacheEntry.java?rev=1350171&r1=1350170&r2=1350171&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/JcrPropertyMapCacheEntry.java (original)
+++ sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/JcrPropertyMapCacheEntry.java Thu Jun 14 10:06:30 2012
@@ -5,9 +5,9 @@
  * 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
@@ -53,7 +53,7 @@ public class JcrPropertyMapCacheEntry {
                 oos.writeObject(obj);
                 oos.close();
                 final ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
-                value = session.getValueFactory().createValue(bais);
+                value = session.getValueFactory().createValue(session.getValueFactory().createBinary(bais));
             } catch (IOException ioe) {
                 // we ignore this here and return null
             }
@@ -123,6 +123,6 @@ public class JcrPropertyMapCacheEntry {
     private boolean isDefaultValueCacheable() throws RepositoryException {
         return property.getType() != PropertyType.BINARY;
     }
-    
-    
+
+
 }
\ No newline at end of file

Modified: sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/LazyInputStream.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/LazyInputStream.java?rev=1350171&r1=1350170&r2=1350171&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/LazyInputStream.java (original)
+++ sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/LazyInputStream.java Thu Jun 14 10:06:30 2012
@@ -103,7 +103,7 @@ public class LazyInputStream extends Inp
     private InputStream getStream() throws IOException {
         if (delegatee == null) {
             try {
-                delegatee = value.getStream();
+                delegatee = value.getBinary().getStream();
             } catch (RepositoryException re) {
                 throw (IOException) new IOException(re.getMessage()).initCause(re);
             }

Modified: sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResource.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResource.java?rev=1350171&r1=1350170&r2=1350171&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResource.java (original)
+++ sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResource.java Thu Jun 14 10:06:30 2012
@@ -206,7 +206,7 @@ public class JcrNodeResource extends Jcr
                 }
 
                 if (data != null) {
-                    return data.getStream();
+                    return data.getBinary().getStream();
                 }
 
             } catch (RepositoryException re) {

Modified: sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrPropertyResource.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrPropertyResource.java?rev=1350171&r1=1350170&r2=1350171&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrPropertyResource.java (original)
+++ sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrPropertyResource.java Thu Jun 14 10:06:30 2012
@@ -52,9 +52,9 @@ public class JcrPropertyResource extends
 
     private final String resourceType;
 
-    public JcrPropertyResource(ResourceResolver resourceResolver,
-                               String path,
-                               Property property)
+    public JcrPropertyResource(final ResourceResolver resourceResolver,
+                               final String path,
+                               final Property property)
     throws RepositoryException {
         super(resourceResolver, path);
         this.property = property;
@@ -68,8 +68,8 @@ public class JcrPropertyResource extends
         this.setContentLength(property);
     }
 
-    public JcrPropertyResource(ResourceResolver resourceResolver,
-                               Property property)
+    public JcrPropertyResource(final ResourceResolver resourceResolver,
+                               final Property property)
     throws RepositoryException {
         this(resourceResolver, property.getPath(), property);
     }
@@ -221,7 +221,7 @@ public class JcrPropertyResource extends
         Property prop = getProperty();
 
         try {
-            return prop.getStream();
+            return prop.getBinary().getStream();
         } catch (RepositoryException re) {
             LOGGER.error("getInputStream: Problem accessing the property "
                 + getPath() + " stream", re);

Modified: sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProvider.java?rev=1350171&r1=1350170&r2=1350171&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProvider.java (original)
+++ sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProvider.java Thu Jun 14 10:06:30 2012
@@ -18,20 +18,36 @@
  */
 package org.apache.sling.jcr.resource.internal.helper.jcr;
 
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
 
 import javax.jcr.Item;
 import javax.jcr.Node;
 import javax.jcr.Property;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
+import javax.jcr.Value;
+import javax.jcr.query.Query;
+import javax.jcr.query.QueryResult;
+import javax.jcr.query.Row;
+import javax.jcr.query.RowIterator;
 import javax.servlet.http.HttpServletRequest;
 
 import org.apache.sling.api.SlingException;
+import org.apache.sling.api.adapter.SlingAdaptable;
+import org.apache.sling.api.resource.AttributableResourceProvider;
+import org.apache.sling.api.resource.DynamicResourceProvider;
+import org.apache.sling.api.resource.QueriableResourceProvider;
+import org.apache.sling.api.resource.QuerySyntaxException;
 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.api.resource.ResourceWrapper;
+import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.jcr.resource.JcrResourceUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -41,37 +57,57 @@ import org.slf4j.LoggerFactory;
  * for each <code>JcrResourceResolver</code> instance and is bound to the JCR
  * session for a single request.
  */
-public class JcrResourceProvider implements ResourceProvider {
+public class JcrResourceProvider
+    extends SlingAdaptable
+    implements ResourceProvider,
+               DynamicResourceProvider,
+               AttributableResourceProvider,
+               QueriableResourceProvider {
+
+    /** column name for node path */
+    private static final String QUERY_COLUMN_PATH = "jcr:path";
 
-    /** default log */
+    /** column name for score value */
+    private static final String QUERY_COLUMN_SCORE = "jcr:score";
+
+    @SuppressWarnings("deprecation")
+    private static final String DEFAULT_QUERY_LANGUAGE = Query.XPATH;
+
+    /** Default logger */
     private final Logger log = LoggerFactory.getLogger(getClass());
 
+    /** Flag for closing. */
+    private boolean closed = false;
+
     private final Session session;
     private final ClassLoader dynamicClassLoader;
-    private final boolean useMultiWorkspaces;
+    private final boolean closeSession;
 
     public JcrResourceProvider(final Session session,
                                final ClassLoader dynamicClassLoader,
-                               boolean useMultiWorkspaces) {
+                               final boolean closeSession) {
         this.session = session;
         this.dynamicClassLoader = dynamicClassLoader;
-        this.useMultiWorkspaces = useMultiWorkspaces;
+        this.closeSession = closeSession;
     }
 
     // ---------- ResourceProvider interface ----------------------------------
 
-    public String[] getRoots() {
-        return new String[] { "/" };
-    }
-
+    /**
+     * @see org.apache.sling.api.resource.ResourceProvider#getResource(org.apache.sling.api.resource.ResourceResolver, javax.servlet.http.HttpServletRequest, java.lang.String)
+     */
+    @SuppressWarnings("javadoc")
     public Resource getResource(ResourceResolver resourceResolver,
             HttpServletRequest request, String path) throws SlingException {
         return getResource(resourceResolver, path);
     }
 
+    /**
+     * @see org.apache.sling.api.resource.ResourceProvider#getResource(org.apache.sling.api.resource.ResourceResolver, java.lang.String)
+     */
     public Resource getResource(ResourceResolver resourceResolver, String path)
-            throws SlingException {
-
+    throws SlingException {
+        this.checkClosed();
         try {
             return createResource(resourceResolver, path);
         } catch (RepositoryException re) {
@@ -81,7 +117,11 @@ public class JcrResourceProvider impleme
 
     }
 
-    public Iterator<Resource> listChildren(Resource parent) {
+    /**
+     * @see org.apache.sling.api.resource.ResourceProvider#listChildren(org.apache.sling.api.resource.Resource)
+     */
+    public Iterator<Resource> listChildren(final Resource parent) {
+        this.checkClosed();
 
         JcrItemResource parentItemResource;
 
@@ -90,10 +130,6 @@ public class JcrResourceProvider impleme
 
             parentItemResource = (JcrItemResource) parent;
 
-        } else if (parent instanceof ResourceWrapper) {
-
-            return listChildren(((ResourceWrapper) parent).getResource());
-
         } else {
 
             // try to get the JcrItemResource for the parent path to list
@@ -113,10 +149,6 @@ public class JcrResourceProvider impleme
                 : null;
     }
 
-    public Session getSession() {
-        return session;
-    }
-
     // ---------- implementation helper ----------------------------------------
 
     /**
@@ -130,24 +162,10 @@ public class JcrResourceProvider impleme
      * @throws RepositoryException If an error occurrs accessingor checking the
      *             item in the repository.
      */
-    private JcrItemResource createResource(ResourceResolver resourceResolver,
-            String path) throws RepositoryException {
-        if (useMultiWorkspaces) {
-            final int wsSepPos = path.indexOf(":/");
-            if (wsSepPos != -1) {
-                final String workspaceName = path.substring(0, wsSepPos);
-                final String expectedWorkspaceName = getSession().getWorkspace().getName();
-                if (workspaceName.equals(expectedWorkspaceName)) {
-                    path = path.substring(wsSepPos + 1);
-                } else {
-                    throw new RepositoryException("Unexpected workspace name. Expected " +
-                            expectedWorkspaceName + ". Actual " + workspaceName);
-                }
-            }
-        }
-
+    private JcrItemResource createResource(final ResourceResolver resourceResolver,
+            final String path) throws RepositoryException {
         if (itemExists(path)) {
-            Item item = getSession().getItem(path);
+            Item item = session.getItem(path);
             if (item.isNode()) {
                 log.debug(
                     "createResource: Found JCR Node Resource at path '{}'",
@@ -176,15 +194,183 @@ public class JcrResourceProvider impleme
      *         session has read access. If the item does not exist,
      *         <code>false</code> is returned ignoring access control.
      */
-    public boolean itemExists(String path) {
+    private boolean itemExists(final String path) {
 
         try {
-            return getSession().itemExists(path);
+            return session.itemExists(path);
         } catch (RepositoryException re) {
             log.debug("itemExists: Error checking for existence of {}: {}",
                 path, re.toString());
             return false;
         }
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.DynamicResourceProvider#isLive()
+     */
+    public boolean isLive() {
+        return !closed && session.isLive();
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.DynamicResourceProvider#close()
+     */
+    public void close() {
+        if ( this.closeSession && !closed) {
+            session.logout();
+        }
+        this.closed = true;
+    }
+
+    /**
+     * Check if the resource resolver is already closed.
+     *
+     * @throws IllegalStateException If the resolver is already closed
+     */
+    private void checkClosed() {
+        if ( this.closed ) {
+            throw new IllegalStateException("Resource resolver is already closed.");
+        }
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.QueriableResourceProvider#findResources(ResourceResolver, java.lang.String, java.lang.String)
+     */
+    public Iterator<Resource> findResources(final ResourceResolver resolver,
+                    final String query, final String language) {
+        checkClosed();
+
+        try {
+            final QueryResult res = JcrResourceUtil.query(session, query, language);
+            return new JcrNodeResourceIterator(resolver, res.getNodes(), this.dynamicClassLoader);
+        } catch (final javax.jcr.query.InvalidQueryException iqe) {
+            throw new QuerySyntaxException(iqe.getMessage(), query, language, iqe);
+        } catch (final RepositoryException re) {
+            throw new SlingException(re.getMessage(), re);
+        }
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.QueriableResourceProvider#queryResources(java.lang.String, java.lang.String)
+     */
+    public Iterator<Map<String, Object>> queryResources(final String query, final String language) {
+        checkClosed();
+
+        final String queryLanguage = isSupportedQueryLanguage(language) ? language : DEFAULT_QUERY_LANGUAGE;
+
+        try {
+            QueryResult result = JcrResourceUtil.query(session, query,
+                queryLanguage);
+            final String[] colNames = result.getColumnNames();
+            final RowIterator rows = result.getRows();
+            return new Iterator<Map<String, Object>>() {
+                public boolean hasNext() {
+                    return rows.hasNext();
+                };
+
+                public Map<String, Object> next() {
+                    Map<String, Object> row = new HashMap<String, Object>();
+                    try {
+                        Row jcrRow = rows.nextRow();
+                        boolean didPath = false;
+                        boolean didScore = false;
+                        Value[] values = jcrRow.getValues();
+                        for (int i = 0; i < values.length; i++) {
+                            Value v = values[i];
+                            if (v != null) {
+                                String colName = colNames[i];
+                                row.put(colName,
+                                    JcrResourceUtil.toJavaObject(values[i]));
+                                if (colName.equals(QUERY_COLUMN_PATH)) {
+                                    didPath = true;
+                                }
+                                if (colName.equals(QUERY_COLUMN_SCORE)) {
+                                    didScore = true;
+                                }
+                            }
+                        }
+                        if (!didPath) {
+                            row.put(QUERY_COLUMN_PATH, jcrRow.getPath());
+                        }
+                        if (!didScore) {
+                            row.put(QUERY_COLUMN_SCORE, jcrRow.getScore());
+                        }
+
+                    } catch (RepositoryException re) {
+                        log.error(
+                            "queryResources$next: Problem accessing row values",
+                            re);
+                    }
+                    return row;
+                }
+
+                public void remove() {
+                    throw new UnsupportedOperationException("remove");
+                }
+            };
+        } catch (final javax.jcr.query.InvalidQueryException iqe) {
+            throw new QuerySyntaxException(iqe.getMessage(), query, language,
+                iqe);
+        } catch (final RepositoryException re) {
+            throw new SlingException(re.getMessage(), re);
+        }
+    }
 
+    private boolean isSupportedQueryLanguage(final String language) {
+        try {
+            String[] supportedLanguages = session.getWorkspace().
+                getQueryManager().getSupportedQueryLanguages();
+            for (String lang : supportedLanguages) {
+                if (lang.equals(language)) {
+                    return true;
+                }
+            }
+        } catch (final RepositoryException e) {
+            log.error("Unable to discover supported query languages", e);
+        }
+        return false;
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.AttributableResourceProvider#getAttributeNames()
+     */
+    public Collection<String> getAttributeNames() {
+        this.checkClosed();
+
+        final Set<String> names = new HashSet<String>();
+        final String[] sessionNames = session.getAttributeNames();
+        for(final String name : sessionNames) {
+            if ( JcrResourceProviderFactory.isAttributeVisible(name) ) {
+                names.add(name);
+            }
+        }
+        return names;
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.AttributableResourceProvider#getAttribute(java.lang.String)
+     */
+    public Object getAttribute(final String name) {
+        this.checkClosed();
+
+        if ( JcrResourceProviderFactory.isAttributeVisible(name) ) {
+            if ( ResourceResolverFactory.USER.equals(name) ) {
+                return this.session.getUserID();
+            }
+            return session.getAttribute(name);
+        }
+        return null;
+    }
+
+    /**
+     * @see org.apache.sling.api.adapter.SlingAdaptable#adaptTo(java.lang.Class)
+     */
+    @SuppressWarnings("unchecked")
+    @Override
+    public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
+        if (type == Session.class) {
+            return (AdapterType) session;
+        }
+        return super.adaptTo(type);
     }
 }



Mime
View raw message