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/25 16:50:23 UTC
svn commit: r1342656 - in /sling/whiteboard/SLING-2396/jcr.resource: ./
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/java/org/ap...
Author: cziegeler
Date: Fri May 25 14:50:22 2012
New Revision: 1342656
URL: http://svn.apache.org/viewvc?rev=1342656&view=rev
Log:
SLING-2396 : New resource resolver factory based on resource provider factories (WiP)
Added:
sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProviderFactory.java (with props)
Removed:
sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolver.java
sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverWebConsolePlugin.java
sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/ResourceDecoratorTracker.java
sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/ResourceIteratorDecorator.java
sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/WorkspaceAuthInfoPostProcessor.java
sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/WorkspaceDecoratedResource.java
sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/MapEntries.java
sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/MapEntry.java
sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/Mapping.java
sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/RedirectResource.java
sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourceIterator.java
sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourcePathIterator.java
sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntry.java
sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/RootResourceProviderEntry.java
sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/URI.java
sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/URIException.java
sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/WrappedResourceProvider.java
sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProviderEntry.java
sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/starresource/StarResource.java
Modified:
sling/whiteboard/SLING-2396/jcr.resource/pom.xml
sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceConstants.java
sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrItemAdapterFactory.java
sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceListener.java
sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverFactoryImpl.java
sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProvider.java
sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/scripting/JcrObjectsBindingsValuesProvider.java
sling/whiteboard/SLING-2396/jcr.resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverTest.java
sling/whiteboard/SLING-2396/jcr.resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/MapEntryTest.java
sling/whiteboard/SLING-2396/jcr.resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/RedirectResourceTest.java
sling/whiteboard/SLING-2396/jcr.resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourcePathIteratorTest.java
sling/whiteboard/SLING-2396/jcr.resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntryTest.java
sling/whiteboard/SLING-2396/jcr.resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/starresource/StarResourceTest.java
Modified: sling/whiteboard/SLING-2396/jcr.resource/pom.xml
URL: http://svn.apache.org/viewvc/sling/whiteboard/SLING-2396/jcr.resource/pom.xml?rev=1342656&r1=1342655&r2=1342656&view=diff
==============================================================================
--- sling/whiteboard/SLING-2396/jcr.resource/pom.xml (original)
+++ sling/whiteboard/SLING-2396/jcr.resource/pom.xml Fri May 25 14:50:22 2012
@@ -27,7 +27,7 @@
</parent>
<artifactId>org.apache.sling.jcr.resource</artifactId>
- <version>2.1.1-SNAPSHOT</version>
+ <version>2.1.1-WHITEBOARD-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>Apache Sling JCR Resource Resolver</name>
@@ -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-WHITEBOARD-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/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceConstants.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceConstants.java?rev=1342656&r1=1342655&r2=1342656&view=diff
==============================================================================
--- sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceConstants.java (original)
+++ sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceConstants.java Fri May 25 14:50:22 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/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrItemAdapterFactory.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrItemAdapterFactory.java?rev=1342656&r1=1342655&r2=1342656&view=diff
==============================================================================
--- sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrItemAdapterFactory.java (original)
+++ sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrItemAdapterFactory.java Fri May 25 14:50:22 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/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceListener.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceListener.java?rev=1342656&r1=1342655&r2=1342656&view=diff
==============================================================================
--- sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceListener.java (original)
+++ sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceListener.java Fri May 25 14:50:22 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
+@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());
@@ -138,21 +111,51 @@ public class JcrResourceListener impleme
} catch (final Throwable t) {
// we ignore this
}
- this.hasJackrabbitEventClass = foundClass;
+ 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 = (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);
+ } 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/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverFactoryImpl.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverFactoryImpl.java?rev=1342656&r1=1342655&r2=1342656&view=diff
==============================================================================
--- sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverFactoryImpl.java (original)
+++ sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverFactoryImpl.java Fri May 25 14:50:22 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
+@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/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProvider.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProvider.java?rev=1342656&r1=1342655&r2=1342656&view=diff
==============================================================================
--- sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProvider.java (original)
+++ sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProvider.java Fri May 25 14:50:22 2012
@@ -18,7 +18,11 @@
*/
package org.apache.sling.jcr.resource.internal.helper.jcr;
+import java.util.Collection;
+import java.util.HashSet;
import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
import javax.jcr.Item;
import javax.jcr.Node;
@@ -28,6 +32,9 @@ import javax.jcr.Session;
import javax.servlet.http.HttpServletRequest;
import org.apache.sling.api.SlingException;
+import org.apache.sling.api.resource.AttributesProvider;
+import org.apache.sling.api.resource.DynamicResourceProvider;
+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.api.resource.ResourceResolver;
@@ -41,34 +48,40 @@ 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
+ implements ResourceProvider,
+ DynamicResourceProvider,
+ AttributesProvider,
+ QueriableResourceProvider {
- /** default log */
+ /** Default logger */
private final Logger log = LoggerFactory.getLogger(getClass());
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)
+ */
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 {
@@ -81,6 +94,9 @@ public class JcrResourceProvider impleme
}
+ /**
+ * @see org.apache.sling.api.resource.ResourceProvider#listChildren(org.apache.sling.api.resource.Resource)
+ */
public Iterator<Resource> listChildren(Resource parent) {
JcrItemResource parentItemResource;
@@ -113,10 +129,6 @@ public class JcrResourceProvider impleme
: null;
}
- public Session getSession() {
- return session;
- }
-
// ---------- implementation helper ----------------------------------------
/**
@@ -132,22 +144,8 @@ public class JcrResourceProvider impleme
*/
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);
- }
- }
- }
-
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 +174,70 @@ 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(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 session.isLive();
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.DynamicResourceProvider#close()
+ */
+ public void close() {
+ if ( this.closeSession ) {
+ session.logout();
+ }
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.QueriableResourceProvider#findResources(java.lang.String, java.lang.String)
+ */
+ public Iterator<Resource> findResources(String query, String language) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.QueriableResourceProvider#queryResources(java.lang.String, java.lang.String)
+ */
+ public Iterator<Map<String, Object>> queryResources(String query, String language) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.AttributesProvider#getAttributeNames()
+ */
+ public Collection<String> getAttributeNames() {
+ 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.AttributesProvider#getAttribute(java.lang.String)
+ */
+ public Object getAttribute(final String name) {
+ if ( JcrResourceProviderFactory.isAttributeVisible(name) ) {
+ return session.getAttribute(name);
+ }
+ return null;
}
}
Added: sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProviderFactory.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProviderFactory.java?rev=1342656&view=auto
==============================================================================
--- sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProviderFactory.java (added)
+++ sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProviderFactory.java Fri May 25 14:50:22 2012
@@ -0,0 +1,301 @@
+/*
+ * 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.jcr.resource.internal.helper.jcr;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.jcr.Credentials;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+
+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.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.ReferencePolicy;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.api.resource.ResourceProvider;
+import org.apache.sling.api.resource.ResourceProviderFactory;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.commons.classloader.DynamicClassLoaderManager;
+import org.apache.sling.jcr.api.SlingRepository;
+import org.apache.sling.jcr.resource.JcrResourceConstants;
+import org.osgi.framework.Constants;
+
+/**
+ * The <code>JcrResourceProviderFactory</code> creates
+ * resource providers based on JCR.
+ */
+@Component
+@Service(value = ResourceProviderFactory.class )
+@Properties({
+ @Property(name=ResourceProviderFactory.PROPERTY_REQUIRED, boolValue=true),
+ @Property(name=ResourceProvider.ROOTS, value="/"),
+ @Property(name = Constants.SERVICE_DESCRIPTION, value = "Apache Sling JCR Resource Provider Factory"),
+ @Property(name = Constants.SERVICE_VENDOR, value = "The Apache Software Foundation")
+})
+public class JcrResourceProviderFactory implements ResourceProviderFactory {
+
+ /** The dynamic class loader */
+ @Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY, policy = ReferencePolicy.DYNAMIC)
+ private DynamicClassLoaderManager dynamicClassLoaderManager;
+
+ @Reference
+ private SlingRepository repository;
+
+ /** Get the dynamic class loader if available */
+ ClassLoader getDynamicClassLoader() {
+ final DynamicClassLoaderManager dclm = this.dynamicClassLoaderManager;
+ if (dclm != null) {
+ return dclm.getDynamicClassLoader();
+ }
+ return null;
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.ResourceProviderFactory#getResourceProvider(java.util.Map)
+ */
+ public ResourceProvider getResourceProvider(final Map<String, Object> authenticationInfo)
+ throws LoginException {
+ return getResourceProviderInternal(authenticationInfo, false);
+ }
+
+ /**
+ * @see org.apache.sling.api.resource.ResourceProviderFactory#getAdministrativeResourceProvider(java.util.Map)
+ */
+ public ResourceProvider getAdministrativeResourceProvider(final Map<String, Object> authenticationInfo)
+ throws LoginException {
+ return getResourceProviderInternal(authenticationInfo, true);
+ }
+
+ /**
+ * Create a new ResourceResolver wrapping a Session object. Carries map of
+ * authentication info in order to create a new resolver as needed.
+ */
+ private ResourceProvider getResourceProviderInternal(
+ final Map<String, Object> authenticationInfo, final boolean isAdmin)
+ 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 {
+ if (isAdmin) {
+ // requested admin session to any workspace (or default)
+ session = repository.loginAdministrative(null);
+
+ } else {
+
+ session = getSession(authenticationInfo);
+ if (session == null) {
+ // requested non-admin session to any workspace (or default)
+ final Credentials credentials = getCredentials(authenticationInfo);
+ session = repository.login(credentials, null);
+
+ } 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);
+
+ return new JcrResourceProvider(session, this.getDynamicClassLoader(), logoutSession);
+ }
+
+ /**
+ * 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 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);
+ }
+
+ /**
+ * 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(ResourceResolverFactory.USER);
+ if (userId instanceof String) {
+ final Object password = authenticationInfo.get(ResourceResolverFactory.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>
+ */
+ public static boolean isAttributeVisible(final String name) {
+ return !name.equals(JcrResourceConstants.AUTHENTICATION_INFO_CREDENTIALS)
+ && !name.contains("password");
+ }
+
+ /**
+ * 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;
+ }
+}
Propchange: sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProviderFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProviderFactory.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Propchange: sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrResourceProviderFactory.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/scripting/JcrObjectsBindingsValuesProvider.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/scripting/JcrObjectsBindingsValuesProvider.java?rev=1342656&r1=1342655&r2=1342656&view=diff
==============================================================================
--- sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/scripting/JcrObjectsBindingsValuesProvider.java (original)
+++ sling/whiteboard/SLING-2396/jcr.resource/src/main/java/org/apache/sling/jcr/resource/internal/scripting/JcrObjectsBindingsValuesProvider.java Fri May 25 14:50:22 2012
@@ -34,28 +34,27 @@ import org.osgi.framework.Constants;
@Component
@Service
@Properties({
- @Property(name=Constants.SERVICE_DESCRIPTION, value="Apache Sling CurrentNode BindingsValuesProvider"),
- @Property(name=Constants.SERVICE_VENDOR, value="The Apache Software Foundation")
-})
+ @Property(name = Constants.SERVICE_DESCRIPTION, value = "Apache Sling CurrentNode BindingsValuesProvider"),
+ @Property(name = Constants.SERVICE_VENDOR, value = "The Apache Software Foundation") })
public class JcrObjectsBindingsValuesProvider implements BindingsValuesProvider {
-
private static final String PROP_CURRENT_NODE = "currentNode";
private static final String PROP_CURRENT_SESSION = "currentSession";
/**
* {@inheritDoc}
*/
- public void addBindings(Bindings bindings) {
- Resource resource = (Resource) bindings.get("resource");
+ public void addBindings(final Bindings bindings) {
+ final Resource resource = (Resource) bindings.get("resource");
if (resource != null) {
- Node node = resource.adaptTo(Node.class);
+ final Node node = resource.adaptTo(Node.class);
if (node != null) {
bindings.put(PROP_CURRENT_NODE, node);
}
- if ( bindings.get(PROP_CURRENT_SESSION) == null ) {
- final Session session = resource.getResourceResolver().adaptTo(Session.class);
- if ( session != null ) {
+ if (bindings.get(PROP_CURRENT_SESSION) == null) {
+ final Session session = resource.getResourceResolver().adaptTo(
+ Session.class);
+ if (session != null) {
bindings.put(PROP_CURRENT_SESSION, session);
}
}
Modified: sling/whiteboard/SLING-2396/jcr.resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverTest.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/SLING-2396/jcr.resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverTest.java?rev=1342656&r1=1342655&r2=1342656&view=diff
==============================================================================
--- sling/whiteboard/SLING-2396/jcr.resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverTest.java (original)
+++ sling/whiteboard/SLING-2396/jcr.resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrResourceResolverTest.java Fri May 25 14:50:22 2012
@@ -59,10 +59,10 @@ import org.apache.sling.commons.testing.
import org.apache.sling.commons.testing.jcr.RepositoryUtil;
import org.apache.sling.jcr.base.util.AccessControlUtil;
import org.apache.sling.jcr.resource.JcrResourceConstants;
-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.RedirectResource;
-import org.apache.sling.jcr.resource.internal.helper.starresource.StarResource;
+import org.apache.sling.resourceresolver.impl.helper.MapEntries;
+import org.apache.sling.resourceresolver.impl.helper.Mapping;
+import org.apache.sling.resourceresolver.impl.helper.RedirectResource;
+import org.apache.sling.resourceresolver.impl.helper.StarResource;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Filter;
import org.osgi.service.event.Event;
Modified: sling/whiteboard/SLING-2396/jcr.resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/MapEntryTest.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/SLING-2396/jcr.resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/MapEntryTest.java?rev=1342656&r1=1342655&r2=1342656&view=diff
==============================================================================
--- sling/whiteboard/SLING-2396/jcr.resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/MapEntryTest.java (original)
+++ sling/whiteboard/SLING-2396/jcr.resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/MapEntryTest.java Fri May 25 14:50:22 2012
@@ -21,6 +21,8 @@ package org.apache.sling.jcr.resource.in
import java.lang.reflect.Method;
import java.net.URI;
+import org.apache.sling.resourceresolver.impl.helper.MapEntry;
+
import junit.framework.TestCase;
public class MapEntryTest extends TestCase {
Modified: sling/whiteboard/SLING-2396/jcr.resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/RedirectResourceTest.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/SLING-2396/jcr.resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/RedirectResourceTest.java?rev=1342656&r1=1342655&r2=1342656&view=diff
==============================================================================
--- sling/whiteboard/SLING-2396/jcr.resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/RedirectResourceTest.java (original)
+++ sling/whiteboard/SLING-2396/jcr.resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/RedirectResourceTest.java Fri May 25 14:50:22 2012
@@ -22,6 +22,7 @@ import java.util.Map;
import org.apache.sling.api.resource.PersistableValueMap;
import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.resourceresolver.impl.helper.RedirectResource;
import junit.framework.TestCase;
Modified: sling/whiteboard/SLING-2396/jcr.resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourcePathIteratorTest.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/SLING-2396/jcr.resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourcePathIteratorTest.java?rev=1342656&r1=1342655&r2=1342656&view=diff
==============================================================================
--- sling/whiteboard/SLING-2396/jcr.resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourcePathIteratorTest.java (original)
+++ sling/whiteboard/SLING-2396/jcr.resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourcePathIteratorTest.java Fri May 25 14:50:22 2012
@@ -21,6 +21,8 @@ package org.apache.sling.jcr.resource.in
import java.util.Iterator;
import java.util.NoSuchElementException;
+import org.apache.sling.resourceresolver.impl.helper.ResourcePathIterator;
+
import junit.framework.TestCase;
public class ResourcePathIteratorTest extends TestCase {
Modified: sling/whiteboard/SLING-2396/jcr.resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntryTest.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/SLING-2396/jcr.resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntryTest.java?rev=1342656&r1=1342655&r2=1342656&view=diff
==============================================================================
--- sling/whiteboard/SLING-2396/jcr.resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntryTest.java (original)
+++ sling/whiteboard/SLING-2396/jcr.resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/ResourceProviderEntryTest.java Fri May 25 14:50:22 2012
@@ -32,6 +32,7 @@ import org.apache.sling.api.resource.Res
import org.apache.sling.api.resource.ResourceMetadata;
import org.apache.sling.api.resource.ResourceProvider;
import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.resourceresolver.impl.helper.ResourceProviderEntry;
public class ResourceProviderEntryTest extends TestCase {
Modified: sling/whiteboard/SLING-2396/jcr.resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/starresource/StarResourceTest.java
URL: http://svn.apache.org/viewvc/sling/whiteboard/SLING-2396/jcr.resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/starresource/StarResourceTest.java?rev=1342656&r1=1342655&r2=1342656&view=diff
==============================================================================
--- sling/whiteboard/SLING-2396/jcr.resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/starresource/StarResourceTest.java (original)
+++ sling/whiteboard/SLING-2396/jcr.resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/starresource/StarResourceTest.java Fri May 25 14:50:22 2012
@@ -21,6 +21,7 @@ package org.apache.sling.jcr.resource.in
import junit.framework.TestCase;
import org.apache.sling.api.resource.ResourceMetadata;
+import org.apache.sling.resourceresolver.impl.helper.StarResource;
/** Test the StarResource */
public class StarResourceTest extends TestCase {