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 2013/09/22 20:23:32 UTC
svn commit: r1525411 - in /sling/trunk/bundles/resourceresolver/src:
main/java/org/apache/sling/resourceresolver/impl/
main/java/org/apache/sling/resourceresolver/impl/mapping/ main/resources/
test/java/org/apache/sling/resourceresolver/impl/mapping/
Author: cziegeler
Date: Sun Sep 22 18:23:32 2013
New Revision: 1525411
URL: http://svn.apache.org/r1525411
Log:
SLING-2944 Implement Service User Mapper; create copy of authentication map
Removed:
sling/trunk/bundles/resourceresolver/src/main/resources/
Modified:
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryImpl.java
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapConfigurationProvider.java
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java
sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java
Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java?rev=1525411&r1=1525410&r2=1525411&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java Sun Sep 22 18:23:32 2013
@@ -64,8 +64,8 @@ import org.osgi.service.event.EventAdmin
*/
@Component(
name = "org.apache.sling.jcr.resource.internal.JcrResourceResolverFactoryImpl",
- label = "%resource.resolver.name",
- description = "%resource.resolver.description",
+ label = "Apache Sling Resource Resolver Factory",
+ description = "Configures the Resource Resolver for request URL and resource path rewriting.",
specVersion = "1.1",
metatype = true)
@Properties({
@@ -83,7 +83,12 @@ public class ResourceResolverFactoryActi
public volatile ServiceRegistration factoryRegistration;
}
- @Property(value = { "/apps", "/libs" })
+ @Property(value = { "/apps", "/libs" },
+ label = "Resource Search Path",
+ description = "The list of absolute path prefixes " +
+ "applied to find resources whose path is just specified with a relative path. " +
+ "The default value is [ \"/apps\", \"/libs\" ]. If an empty path is specified a " +
+ "single entry path of [ \"/\" ] is assumed.")
public static final String PROP_PATH = "resource.resolver.searchpath";
/**
@@ -103,13 +108,33 @@ public class ResourceResolverFactoryActi
* The default value of this property if no configuration is provided is <code>true</code>.
*
*/
- @Property(boolValue = true)
+ @Property(boolValue = true,
+ label = "Namespace Mangling",
+ description = "Defines whether namespace " +
+ "prefixes of resource names inside the path (e.g. \"jcr:\" in \"/home/path/jcr:content\") " +
+ "are mangled or not. Mangling means that any namespace prefix contained in the " +
+ "path is replaced as per the generic substitution pattern \"/([^:]+):/_$1_/\" " +
+ "when calling the \"map\" method of the resource resolver. Likewise the " +
+ "\"resolve\" methods will unmangle such namespace prefixes according to the " +
+ "substituation pattern \"/_([^_]+)_/$1:/\". 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. The default value of this property " +
+ "if no configuration is provided is \"true\".")
private static final String PROP_MANGLE_NAMESPACES = "resource.resolver.manglenamespaces";
- @Property(boolValue = true)
+ @Property(boolValue = true,
+ label = "Allow Direct Mapping",
+ description = "Whether to add a direct URL mapping to the front of the mapping list.")
private static final String PROP_ALLOW_DIRECT = "resource.resolver.allowDirect";
- @Property(unbounded=PropertyUnbounded.ARRAY, value = "org.apache.sling.jcr.resource.internal.helper.jcr.JcrResourceProviderFactory")
+ @Property(unbounded=PropertyUnbounded.ARRAY,
+ value = "org.apache.sling.jcr.resource.internal.helper.jcr.JcrResourceProviderFactory",
+ label = "Required Providers",
+ description = "A resource resolver factory is only " +
+ "available (registered) if all resource providers mentioned in this configuration " +
+ "are available. Each entry is either a service PID or a filter expression. " +
+ "Invalid filters are ignored.")
private static final String PROP_REQUIRED_PROVIDERS = "resource.resolver.required.providers";
/**
@@ -118,18 +143,45 @@ public class ResourceResolverFactoryActi
* multivalue properties at the moment. So we just add a dummy direct
* mapping.
*/
- @Property(value = "/:/", unbounded = PropertyUnbounded.ARRAY)
+ @Property(value = "/:/", unbounded = PropertyUnbounded.ARRAY,
+ label = "Virtual URLs",
+ description = "List of virtual URLs and there mappings to real URLs. " +
+ "Format is <externalURL>:<internalURL>. Mappings are " +
+ "applied on the complete request URL only.")
private static final String PROP_VIRTUAL = "resource.resolver.virtual";
- @Property(value = { "/:/", "/content/:/", "/system/docroot/:/" })
+ @Property(value = { "/:/", "/content/:/", "/system/docroot/:/" },
+ label = "URL Mappings",
+ description = "List of mappings to apply to paths. Incoming mappings are " +
+ "applied to request paths to map to resource paths, " +
+ "outgoing mappings are applied to map resource paths to paths used on subsequent " +
+ "requests. Form is <internalPathPrefix><op><externalPathPrefix> where <op> is " +
+ "\">\" for incoming mappings, \"<\" for outgoing mappings and \":\" for mappings " +
+ "applied in both directions. Mappings are applied in configuration order by " +
+ "comparing and replacing URL prefixes. Note: The use of \"-\" as the <op> value " +
+ "indicating a mapping in both directions is deprecated.")
private static final String PROP_MAPPING = "resource.resolver.mapping";
- @Property(value = MapEntries.DEFAULT_MAP_ROOT)
+ @Property(value = MapEntries.DEFAULT_MAP_ROOT,
+ label = "Mapping Location",
+ description = "The path to the root of the configuration to setup and configure " +
+ "the ResourceResolver mapping. The default value is /etc/map.")
private static final String PROP_MAP_LOCATION = "resource.resolver.map.location";
- @Property(intValue = MapEntries.DEFAULT_DEFAULT_VANITY_PATH_REDIRECT_STATUS)
+ @Property(intValue = MapEntries.DEFAULT_DEFAULT_VANITY_PATH_REDIRECT_STATUS,
+ label = "Default Vanity Path Redirect Status",
+ description = "The default status code used when a sling:vanityPath is configured to redirect " +
+ "and does not have a specific status code associated with it " +
+ "(via a sling:redirectStatus property)")
private static final String PROP_DEFAULT_VANITY_PATH_REDIRECT_STATUS = "resource.resolver.default.vanity.redirect.status";
+ private static final boolean DEFAULT_ENABLE_VANITY_PATH = true;
+ @Property(boolValue = DEFAULT_ENABLE_VANITY_PATH,
+ label = "Enable Vanity Paths",
+ description = "This flag controls whether all resources with a sling:vanityPath property " +
+ "are processed and added to the mappoing table.")
+ private static final String PROP_ENABLE_VANITY_PATH = "resource.resolver.enable.vanitypath";
+
/** Tracker for the resource decorators. */
private final ResourceDecoratorTracker resourceDecoratorTracker = new ResourceDecoratorTracker();
@@ -167,6 +219,9 @@ public class ResourceResolverFactoryActi
private int defaultVanityPathRedirectStatus;
+ /** vanityPath enabled? */
+ private boolean enableVanityPath = DEFAULT_ENABLE_VANITY_PATH;
+
private final FactoryPreconditions preconds = new FactoryPreconditions();
/** Factory registration. */
@@ -221,6 +276,10 @@ public class ResourceResolverFactoryActi
return defaultVanityPathRedirectStatus;
}
+ public boolean isVanityPathEnabled() {
+ return this.enableVanityPath;
+ }
+
// ---------- SCR Integration ---------------------------------------------
/** Activates this component, called by SCR before registering as a service */
@@ -283,6 +342,7 @@ public class ResourceResolverFactoryActi
defaultVanityPathRedirectStatus = PropertiesUtil.toInteger(properties.get(PROP_DEFAULT_VANITY_PATH_REDIRECT_STATUS),
MapEntries.DEFAULT_DEFAULT_VANITY_PATH_REDIRECT_STATUS);
+ this.enableVanityPath = PropertiesUtil.toBoolean(properties.get(PROP_ENABLE_VANITY_PATH), DEFAULT_ENABLE_VANITY_PATH);
final BundleContext bc = componentContext.getBundleContext();
Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryImpl.java?rev=1525411&r1=1525410&r2=1525411&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryImpl.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryImpl.java Sun Sep 22 18:23:32 2013
@@ -77,16 +77,16 @@ public class ResourceResolverFactoryImpl
// ---------- Resource Resolver Factory ------------------------------------
- public ResourceResolver getServiceResourceResolver(Map<String, Object> authenticationInfo) throws LoginException {
-
- // clean authentication from password and get service info
+ public ResourceResolver getServiceResourceResolver(final Map<String, Object> passedAuthenticationInfo) throws LoginException {
+ // create a copy of the passed authentication info as we modify the map
+ final Map<String, Object> authenticationInfo = new HashMap<String, Object>();
final String subServiceName;
- if (authenticationInfo != null) {
+ if ( passedAuthenticationInfo != null ) {
+ authenticationInfo.putAll(passedAuthenticationInfo);
authenticationInfo.remove(PASSWORD);
- final Object info = authenticationInfo.get(SUBSERVICE);
+ final Object info = passedAuthenticationInfo.get(SUBSERVICE);
subServiceName = (info instanceof String) ? (String) info : null;
} else {
- authenticationInfo = new HashMap<String, Object>();
subServiceName = null;
}
@@ -108,10 +108,12 @@ public class ResourceResolverFactoryImpl
return getResourceResolverInternal(authenticationInfo, false);
}
- public ResourceResolver getAdministrativeResourceResolver(final Map<String, Object> authenticationInfo) throws LoginException {
-
- // make sure there is no leaking of service bundle and info props
- if (authenticationInfo != null) {
+ public ResourceResolver getAdministrativeResourceResolver(final Map<String, Object> passedAuthenticationInfo) throws LoginException {
+ // create a copy of the passed authentication info as we modify the map
+ final Map<String, Object> authenticationInfo = new HashMap<String, Object>();
+ if ( passedAuthenticationInfo != null ) {
+ authenticationInfo.putAll(passedAuthenticationInfo);
+ // make sure there is no leaking of service bundle and info props
authenticationInfo.remove(ResourceProviderFactory.SERVICE_BUNDLE);
authenticationInfo.remove(SUBSERVICE);
}
@@ -119,10 +121,12 @@ public class ResourceResolverFactoryImpl
return getResourceResolverInternal(authenticationInfo, true);
}
- public ResourceResolver getResourceResolver(final Map<String, Object> authenticationInfo) throws LoginException {
-
- // make sure there is no leaking of service bundle and info props
- if (authenticationInfo != null) {
+ public ResourceResolver getResourceResolver(final Map<String, Object> passedAuthenticationInfo) throws LoginException {
+ // create a copy of the passed authentication info as we modify the map
+ final Map<String, Object> authenticationInfo = new HashMap<String, Object>();
+ if ( passedAuthenticationInfo != null ) {
+ authenticationInfo.putAll(passedAuthenticationInfo);
+ // make sure there is no leaking of service bundle and info props
authenticationInfo.remove(ResourceProviderFactory.SERVICE_BUNDLE);
authenticationInfo.remove(SUBSERVICE);
}
@@ -226,6 +230,10 @@ public class ResourceResolverFactoryImpl
return this.activator.getDefaultVanityPathRedirectStatus();
}
+ public boolean isVanityPathEnabled() {
+ return this.activator.isVanityPathEnabled();
+ }
+
/**
* get's the ServiceTracker of the ResourceAccessSecurity service
*/
Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapConfigurationProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapConfigurationProvider.java?rev=1525411&r1=1525410&r2=1525411&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapConfigurationProvider.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapConfigurationProvider.java Sun Sep 22 18:23:32 2013
@@ -23,7 +23,7 @@ import org.apache.sling.api.resource.Res
/**
* Internal interface representing the additional methods
* MapEntries needs from the ResourceResolverFactory.
- *
+ *
* Exists primarily to facilitate mocking of the ResourceResolverFactory
* when testing MapEntries.
*/
@@ -37,4 +37,5 @@ public interface MapConfigurationProvide
int getDefaultVanityPathRedirectStatus();
+ boolean isVanityPathEnabled();
}
Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java?rev=1525411&r1=1525410&r2=1525411&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java Sun Sep 22 18:23:32 2013
@@ -108,6 +108,8 @@ public class MapEntries implements Event
private final ReentrantLock initializing = new ReentrantLock();
+ private final boolean enabledVanityPaths;
+
@SuppressWarnings("unchecked")
private MapEntries() {
this.factory = null;
@@ -120,6 +122,7 @@ public class MapEntries implements Event
this.aliasMap = Collections.<String, Map<String, String>>emptyMap();
this.registration = null;
this.eventAdmin = null;
+ this.enabledVanityPaths = true;
}
@SuppressWarnings("unchecked")
@@ -128,6 +131,7 @@ public class MapEntries implements Event
this.resolver = factory.getAdministrativeResourceResolver(null);
this.factory = factory;
this.mapRoot = factory.getMapRoot();
+ this.enabledVanityPaths = factory.isVanityPathEnabled();
this.eventAdmin = eventAdmin;
this.resolveMapsMap = Collections.singletonMap(GLOBAL_LIST_KEY, (List<MapEntry>)Collections.EMPTY_LIST);
@@ -139,7 +143,7 @@ public class MapEntries implements Event
final Dictionary<String, String> props = new Hashtable<String, String>();
props.put(EventConstants.EVENT_TOPIC, "org/apache/sling/api/resource/*");
- props.put(EventConstants.EVENT_FILTER, createFilter());
+ props.put(EventConstants.EVENT_FILTER, createFilter(this.enabledVanityPaths));
props.put(Constants.SERVICE_DESCRIPTION, "Map Entries Observation");
props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
this.registration = bundleContext.registerService(EventHandler.class.getName(), this, props);
@@ -203,7 +207,7 @@ public class MapEntries implements Event
loadResolverMap(resolver, globalResolveMap, newMapMaps);
// load the configuration into the resolver map
- final Collection<String> vanityTargets = this.loadVanityPaths(resolver, newResolveMapsMap);
+ final Collection<String> vanityTargets = (this.enabledVanityPaths ? this.loadVanityPaths(resolver, newResolveMapsMap) : Collections.<String> emptySet());
loadConfiguration(factory, globalResolveMap);
// load the configuration into the mapper map
@@ -448,7 +452,7 @@ public class MapEntries implements Event
}catch (IllegalArgumentException iae){
//ignore this entry
log.debug("ignored entry due exception ",iae);
- }
+ }
if (childResolveEntry != null) {
entries.add(childResolveEntry);
}
@@ -765,8 +769,8 @@ public class MapEntries implements Event
* modified JCR properties) this allows to only get events interesting for
* updating the internal structure
*/
- private static String createFilter() {
- final String[] nodeProps = { "sling:vanityPath", "sling:vanityOrder",
+ private static String createFilter(final boolean vanityPathEnabled) {
+ final String[] nodeProps = {
PROP_REDIRECT_EXTERNAL_REDIRECT_STATUS, PROP_REDIRECT_EXTERNAL,
ResourceResolverImpl.PROP_REDIRECT_INTERNAL, PROP_REDIRECT_EXTERNAL_STATUS,
PROP_REG_EXP, ResourceResolverImpl.PROP_ALIAS };
@@ -775,6 +779,10 @@ public class MapEntries implements Event
filter.append("(|");
for (final String eventProp : eventProps) {
filter.append("(|");
+ if ( vanityPathEnabled ) {
+ filter.append('(').append(eventProp).append('=').append("sling:vanityPath").append(')');
+ filter.append('(').append(eventProp).append('=').append("sling:vanityOrder").append(')');
+ }
for (final String nodeProp : nodeProps) {
filter.append('(').append(eventProp).append('=').append(nodeProp).append(')');
}
@@ -883,18 +891,18 @@ public class MapEntries implements Event
}
}
};
-
+
private MapEntry getMapEntry(String url, final int status, final boolean trailingSlash,
final String... redirect){
-
+
MapEntry mapEntry = null;
try{
mapEntry = new MapEntry(url, status, trailingSlash, redirect);
}catch (IllegalArgumentException iae){
//ignore this entry
log.debug("ignored entry due exception ",iae);
- }
+ }
return mapEntry;
}
-
+
}
Modified: sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java?rev=1525411&r1=1525410&r2=1525411&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java (original)
+++ sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java Sun Sep 22 18:23:32 2013
@@ -16,9 +16,14 @@
*/
package org.apache.sling.resourceresolver.impl.mapping;
-import static org.junit.Assert.*;
-import static org.mockito.Matchers.*;
-import static org.mockito.Mockito.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.Arrays;
@@ -62,6 +67,7 @@ public class MapEntriesTest {
MockitoAnnotations.initMocks(this);
when(resourceResolverFactory.getAdministrativeResourceResolver(null)).thenReturn(resourceResolver);
+ when(resourceResolverFactory.isVanityPathEnabled()).thenReturn(true);
when(resourceResolver.findResources(anyString(), eq("sql"))).thenReturn(
Collections.<Resource> emptySet().iterator());
@@ -150,13 +156,13 @@ public class MapEntriesTest {
when(justVanityPath.getName()).thenReturn("justVanityPath");
when(justVanityPath.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/target/justVanityPath"));
resources.add(justVanityPath);
-
+
Resource badVanityPath = mock(Resource.class);
when(badVanityPath.getPath()).thenReturn("/badVanityPath");
when(badVanityPath.getName()).thenReturn("badVanityPath");
when(badVanityPath.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/content/mypage/en-us-{132"));
resources.add(badVanityPath);
-
+
Resource redirectingVanityPath = mock(Resource.class);
when(redirectingVanityPath.getPath()).thenReturn("/redirectingVanityPath");