From commits-return-89528-archive-asf-public=cust-asf.ponee.io@sling.apache.org Wed Sep 23 08:13:50 2020 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mailroute1-lw-us.apache.org (mailroute1-lw-us.apache.org [207.244.88.153]) by mx-eu-01.ponee.io (Postfix) with ESMTPS id A14661806D6 for ; Wed, 23 Sep 2020 10:13:50 +0200 (CEST) Received: from mail.apache.org (localhost [127.0.0.1]) by mailroute1-lw-us.apache.org (ASF Mail Server at mailroute1-lw-us.apache.org) with SMTP id D57EA124141 for ; Wed, 23 Sep 2020 08:13:49 +0000 (UTC) Received: (qmail 97519 invoked by uid 500); 23 Sep 2020 08:13:49 -0000 Mailing-List: contact commits-help@sling.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@sling.apache.org Delivered-To: mailing list commits@sling.apache.org Received: (qmail 97436 invoked by uid 99); 23 Sep 2020 08:13:49 -0000 Received: from ec2-52-202-80-70.compute-1.amazonaws.com (HELO gitbox.apache.org) (52.202.80.70) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 23 Sep 2020 08:13:49 +0000 Received: by gitbox.apache.org (ASF Mail Server at gitbox.apache.org, from userid 33) id 4B3F38DCA9; Wed, 23 Sep 2020 08:13:49 +0000 (UTC) Date: Wed, 23 Sep 2020 08:13:50 +0000 To: "commits@sling.apache.org" Subject: [sling-org-apache-sling-resourceresolver] 01/01: SLING-9662 Introduce Resource Mapping SPI MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit From: ghenzler@apache.org In-Reply-To: <160084882916.4811.8703291540552873396@gitbox.apache.org> References: <160084882916.4811.8703291540552873396@gitbox.apache.org> X-Git-Host: gitbox.apache.org X-Git-Repo: sling-org-apache-sling-resourceresolver X-Git-Refname: refs/heads/feature/SLING-9662-Introduce-SlingUri-Mapping-SPI_v3 X-Git-Reftype: branch X-Git-Rev: a8276102ad58485dbc34b042948fb21d59e877fb X-Git-NotificationType: diff X-Git-Multimail-Version: 1.5.dev Auto-Submitted: auto-generated Message-Id: <20200923081349.4B3F38DCA9@gitbox.apache.org> This is an automated email from the ASF dual-hosted git repository. ghenzler pushed a commit to branch feature/SLING-9662-Introduce-SlingUri-Mapping-SPI_v3 in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-resourceresolver.git commit a8276102ad58485dbc34b042948fb21d59e877fb Author: georg.henzler AuthorDate: Fri Aug 14 07:36:58 2020 +0200 SLING-9662 Introduce Resource Mapping SPI --- pom.xml | 2 +- .../impl/CommonResourceResolverFactoryImpl.java | 9 +- .../impl/ResourceResolverFactoryActivator.java | 9 + .../impl/ResourceResolverImpl.java | 7 +- .../impl/mapping/ResourceMapperImpl.java | 23 ++- .../urimapping/MappingChainContextInternal.java | 71 +++++++ .../impl/urimapping/MappingChainResult.java | 45 ++++ .../urimapping/PathToUriMappingServiceImpl.java | 226 +++++++++++++++++++++ .../urimapping/defaultmappers/BasePathMapper.java | 84 ++++++++ .../defaultmappers/EnsureHtmlExtensionMapper.java | 80 ++++++++ .../impl/EtcMappingResourceResolverTest.java | 56 ++--- .../impl/MockedResourceResolverImplTest.java | 9 +- .../resourceresolver/impl/ProviderHandlerTest.java | 2 + .../impl/ResourceDecoratorTestBase.java | 7 + .../impl/ResourceResolverImplTest.java | 2 + .../impl/ResourceResolverMangleNamespacesTest.java | 11 +- .../mapping/AbstractMappingMapEntriesTest.java | 51 ++--- .../impl/mapping/EtcMappingMapEntriesTest.java | 38 ++-- .../impl/mapping/ResourceMapperImplTest.java | 3 + .../sling/resourceresolver/util/MockTestUtil.java | 42 ++-- .../util/TestPathToUriMappingService.java | 59 ++++++ 21 files changed, 735 insertions(+), 101 deletions(-) diff --git a/pom.xml b/pom.xml index b056ab6..118a877 100644 --- a/pom.xml +++ b/pom.xml @@ -106,7 +106,7 @@ org.apache.sling org.apache.sling.api - 2.21.0 + 2.23.0-SNAPSHOT provided diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/CommonResourceResolverFactoryImpl.java b/src/main/java/org/apache/sling/resourceresolver/impl/CommonResourceResolverFactoryImpl.java index b925e65..4e423c2 100644 --- a/src/main/java/org/apache/sling/resourceresolver/impl/CommonResourceResolverFactoryImpl.java +++ b/src/main/java/org/apache/sling/resourceresolver/impl/CommonResourceResolverFactoryImpl.java @@ -31,12 +31,11 @@ import java.util.Stack; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; -import org.jetbrains.annotations.NotNull; - import org.apache.commons.collections4.BidiMap; import org.apache.sling.api.resource.LoginException; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.resource.ResourceResolverFactory; +import org.apache.sling.api.resource.mapping.PathToUriMappingService; import org.apache.sling.api.resource.path.Path; import org.apache.sling.resourceresolver.impl.console.ResourceResolverWebConsolePlugin; import org.apache.sling.resourceresolver.impl.helper.ResourceDecoratorTracker; @@ -48,6 +47,7 @@ import org.apache.sling.resourceresolver.impl.mapping.Mapping; import org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker; import org.apache.sling.serviceusermapping.ServiceUserMapper; import org.apache.sling.spi.resource.provider.ResourceProvider; +import org.jetbrains.annotations.NotNull; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.slf4j.Logger; @@ -405,6 +405,11 @@ public class CommonResourceResolverFactoryImpl implements ResourceResolverFactor return this.activator.getResourceAccessSecurityTracker(); } + /** gets PathToUriMappingServiceImpl */ + public PathToUriMappingService getPathToUriMappingService() { + return this.activator.getPathToUriMappingService(); + } + @NotNull @Override public ResourceResolver getServiceResourceResolver( diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java b/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java index 646a077..6de579a 100644 --- a/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java +++ b/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java @@ -34,9 +34,11 @@ import org.apache.commons.collections4.BidiMap; import org.apache.commons.collections4.bidimap.TreeBidiMap; import org.apache.sling.api.resource.ResourceDecorator; import org.apache.sling.api.resource.ResourceResolverFactory; +import org.apache.sling.api.resource.mapping.PathToUriMappingService; import org.apache.sling.api.resource.path.Path; import org.apache.sling.api.resource.runtime.RuntimeService; import org.apache.sling.resourceresolver.impl.helper.ResourceDecoratorTracker; +import org.apache.sling.resourceresolver.impl.mapping.MapEntries; import org.apache.sling.resourceresolver.impl.mapping.Mapping; import org.apache.sling.resourceresolver.impl.mapping.StringInterpolationProvider; import org.apache.sling.resourceresolver.impl.observation.ResourceChangeListenerWhiteboard; @@ -119,6 +121,9 @@ public class ResourceResolverFactoryActivator { @Reference ResourceAccessSecurityTracker resourceAccessSecurityTracker; + @Reference + PathToUriMappingService pathToUriMappingService; + volatile ResourceProviderTracker resourceProviderTracker; volatile ResourceChangeListenerWhiteboard changeListenerWhiteboard; @@ -153,6 +158,10 @@ public class ResourceResolverFactoryActivator { return this.resourceAccessSecurityTracker; } + public PathToUriMappingService getPathToUriMappingService() { + return this.pathToUriMappingService; + } + public EventAdmin getEventAdmin() { return this.eventAdmin; } diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java b/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java index 2fddf65..6a565b4 100644 --- a/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java +++ b/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java @@ -30,11 +30,10 @@ import java.util.Map; import java.util.Set; import java.util.StringTokenizer; -import org.apache.commons.lang3.StringUtils; -import org.jetbrains.annotations.Nullable; import javax.jcr.Session; import javax.servlet.http.HttpServletRequest; +import org.apache.commons.lang3.StringUtils; import org.apache.sling.adapter.annotations.Adaptable; import org.apache.sling.adapter.annotations.Adapter; import org.apache.sling.api.SlingException; @@ -48,6 +47,7 @@ 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.api.resource.ResourceWrapper; +import org.apache.sling.api.resource.mapping.PathToUriMappingService; import org.apache.sling.api.resource.mapping.ResourceMapper; import org.apache.sling.resourceresolver.impl.helper.RedirectResource; import org.apache.sling.resourceresolver.impl.helper.ResourceIteratorDecorator; @@ -62,6 +62,7 @@ import org.apache.sling.resourceresolver.impl.mapping.ResourceMapperImpl; import org.apache.sling.resourceresolver.impl.params.ParsedParameters; import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorageProvider; import org.apache.sling.spi.resource.provider.ResourceProvider; +import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -625,7 +626,7 @@ public class ResourceResolverImpl extends SlingAdaptable implements ResourceReso if ( type == ResourceMapper.class ) return (AdapterType) new ResourceMapperImpl(this, factory.getResourceDecoratorTracker(), factory.getMapEntries(), - factory.isOptimizeAliasResolutionEnabled(), factory.getNamespaceMangler()); + factory.isOptimizeAliasResolutionEnabled(), factory.getNamespaceMangler(), factory.getPathToUriMappingService()); final AdapterType result = this.control.adaptTo(this.context, type); if ( result != null ) { diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/ResourceMapperImpl.java b/src/main/java/org/apache/sling/resourceresolver/impl/mapping/ResourceMapperImpl.java index bc47c26..deda902 100644 --- a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/ResourceMapperImpl.java +++ b/src/main/java/org/apache/sling/resourceresolver/impl/mapping/ResourceMapperImpl.java @@ -33,7 +33,9 @@ import javax.servlet.http.HttpServletRequest; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceUtil; +import org.apache.sling.api.resource.mapping.PathToUriMappingService; import org.apache.sling.api.resource.mapping.ResourceMapper; +import org.apache.sling.api.uri.SlingUri; import org.apache.sling.resourceresolver.impl.JcrNamespaceMangler; import org.apache.sling.resourceresolver.impl.ResourceResolverImpl; import org.apache.sling.resourceresolver.impl.helper.ResourceDecoratorTracker; @@ -53,15 +55,17 @@ public class ResourceMapperImpl implements ResourceMapper { private final MapEntriesHandler mapEntries; private final boolean optimizedAliasResolutionEnabled; private final Object namespaceMangler; - + private final PathToUriMappingService pathToUriMappingService; public ResourceMapperImpl(ResourceResolverImpl resolver, ResourceDecoratorTracker resourceDecorator, - MapEntriesHandler mapEntries, boolean optimizedAliasResolutionEnabled, Object namespaceMangler) { + MapEntriesHandler mapEntries, boolean optimizedAliasResolutionEnabled, Object namespaceMangler, + PathToUriMappingService pathToUriMappingService) { this.resolver = resolver; this.resourceDecorator = resourceDecorator; this.mapEntries = mapEntries; this.optimizedAliasResolutionEnabled = optimizedAliasResolutionEnabled; this.namespaceMangler = namespaceMangler; + this.pathToUriMappingService = pathToUriMappingService; } @Override @@ -166,6 +170,13 @@ public class ResourceMapperImpl implements ResourceMapper { // vanity paths are prepended to make sure they get returned last mappings.addAll(0, vanityPaths); + + // Apply mappings from Resource Mappers + PathToUriMappingService.Result mappingResult = pathToUriMappingService.map(request, mappings.get(mappings.size() - 1)); + for (Map.Entry mappingFromChain : mappingResult.getIntermediateMappings().entrySet()) { + mappings.add(mappingFromChain.getValue().toString()); + } + // 7. apply context path if needed mappings.replaceAll(new ApplyContextPath(request)); @@ -174,10 +185,10 @@ public class ResourceMapperImpl implements ResourceMapper { mappings.replaceAll(path -> path.concat(fragmentQuery)); } - mappings.forEach( path -> - logger.debug("map: Returning URL {} as mapping for path {}", path, resourcePath) - ); - + mappings.forEach( path -> { + logger.debug("map: Returning URL {} as mapping for path {}", path, resourcePath); + }); + Collections.reverse(mappings); return new LinkedHashSet<>(mappings); diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/urimapping/MappingChainContextInternal.java b/src/main/java/org/apache/sling/resourceresolver/impl/urimapping/MappingChainContextInternal.java new file mode 100644 index 0000000..8ad49fa --- /dev/null +++ b/src/main/java/org/apache/sling/resourceresolver/impl/urimapping/MappingChainContextInternal.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.resourceresolver.impl.urimapping; + +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.apache.sling.api.resource.ResourceResolver; +import org.apache.sling.api.uri.SlingUri; +import org.apache.sling.spi.urimapping.MappingChainContext; + +class MappingChainContextInternal implements MappingChainContext { + + private final ResourceResolver resourceResolver; + private final Map attributes = new HashMap<>(); + private final Map intermediateMappings = new LinkedHashMap<>(); + private boolean skipRemainingChain = false; + + + MappingChainContextInternal(ResourceResolver resourceResolver) { + this.resourceResolver = resourceResolver; + } + + @Override + public void skipRemainingChain() { + skipRemainingChain = true; + } + + @Override + public Map getAttributes() { + return attributes; + } + + @Override + public Map getIntermediateMappings() { + return Collections.unmodifiableMap(intermediateMappings); + } + + @Override + public ResourceResolver getResourceResolver() { + return resourceResolver; + } + + boolean isMarkedAsSkipRemainingChain() { + return skipRemainingChain; + } + + void addIntermediateMapping(String name, SlingUri resourceUri) { + intermediateMappings.put(name, resourceUri); + } + + +} \ No newline at end of file diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/urimapping/MappingChainResult.java b/src/main/java/org/apache/sling/resourceresolver/impl/urimapping/MappingChainResult.java new file mode 100644 index 0000000..ad27faa --- /dev/null +++ b/src/main/java/org/apache/sling/resourceresolver/impl/urimapping/MappingChainResult.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.resourceresolver.impl.urimapping; + +import java.util.Map; + +import org.apache.sling.api.resource.mapping.PathToUriMappingService; +import org.apache.sling.api.uri.SlingUri; + +class MappingChainResult implements PathToUriMappingService.Result { + + private final SlingUri slingUri; + private final Map intermediateMappings; + + public MappingChainResult(SlingUri slingUri, Map intermediateMappings) { + this.slingUri = slingUri; + this.intermediateMappings = intermediateMappings; + } + + public SlingUri getUri() { + return slingUri; + } + + public Map getIntermediateMappings() { + return intermediateMappings; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/urimapping/PathToUriMappingServiceImpl.java b/src/main/java/org/apache/sling/resourceresolver/impl/urimapping/PathToUriMappingServiceImpl.java new file mode 100644 index 0000000..c0642c7 --- /dev/null +++ b/src/main/java/org/apache/sling/resourceresolver/impl/urimapping/PathToUriMappingServiceImpl.java @@ -0,0 +1,226 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.resourceresolver.impl.urimapping; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.lang3.StringUtils; +import org.apache.sling.api.resource.LoginException; +import org.apache.sling.api.resource.ResourceResolver; +import org.apache.sling.api.resource.ResourceResolverFactory; +import org.apache.sling.api.resource.mapping.PathToUriMappingService; +import org.apache.sling.api.uri.SlingUri; +import org.apache.sling.api.uri.SlingUriBuilder; +import org.apache.sling.resourceresolver.impl.JcrNamespaceMangler; +import org.apache.sling.spi.urimapping.SlingUriMapper; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.component.annotations.ReferenceCardinality; +import org.osgi.service.component.annotations.ReferencePolicy; +import org.osgi.service.component.annotations.ReferencePolicyOption; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Component +public class PathToUriMappingServiceImpl implements PathToUriMappingService { + + private static final Logger LOG = LoggerFactory.getLogger(PathToUriMappingServiceImpl.class); + + private static final String KEY_INTIAL = "intial"; + private static final String SUBSERVICE_NAME_MAPPING = "mapping"; + + @Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY) + volatile List resourceMappers; + + @Reference(cardinality = ReferenceCardinality.OPTIONAL, policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY) + volatile ResourceResolverFactory resourceResolverFactory; + + JcrNamespaceMangler jcrNamespaceMangler = new JcrNamespaceMangler(); + + @Activate + public void activate() { + + if (resourceMappers != null) { + String resourceMappersStr = resourceMappers.stream().map(rm -> rm.getClass().toString()).collect(Collectors.joining("\n")); + LOG.info("Available Resource Mappers:\n{}", resourceMappersStr); + } else { + LOG.info("No Resource Mappers available"); + } + } + + public List getAvailableResourceMappers() { + return resourceMappers.stream().map(rm -> rm.getClass().toString()).collect(Collectors.toList()); + } + + @NotNull + public MappingChainResult map(@Nullable HttpServletRequest request, @NotNull String resourcePath) { + + try (ResourceResolver rr = getResourceResolver()) { + MappingChainContextInternal mappingContext = new MappingChainContextInternal(rr); + SlingUri resourceUri = SlingUriBuilder.parse(resourcePath, rr).build(); + addIntermediateMapping(mappingContext, resourceUri, KEY_INTIAL); + if (resourceMappers != null) { + for (SlingUriMapper mapper : resourceMappers) { + String mapperName = mapper.getClass().getName(); + LOG.trace("map(): Using {} for {}", mapperName, resourceUri); + SlingUri input = resourceUri; + resourceUri = mapper.map(resourceUri, request, mappingContext); + if (input != resourceUri) { + addIntermediateMapping(mappingContext, resourceUri, mapperName); + } + + if (chancelChain(mappingContext, mapperName)) { + break; + } + } + } + + if (LOG.isDebugEnabled()) { + logResult(mappingContext, "map()"); + } + + return new MappingChainResult(resourceUri, mappingContext.getIntermediateMappings()); + } + } + + @NotNull + public MappingChainResult resolve(@Nullable HttpServletRequest request, @Nullable String path) { + + if (request == null) { + throw new IllegalArgumentException("Parameter HttpServletRequest must not be null"); + } + + try (ResourceResolver rr = getResourceResolver()) { + + MappingChainContextInternal mappingContext = new MappingChainContextInternal(rr); + + SlingUri resourceUri = path != null ? SlingUriBuilder.parse(unmangleNamespaces(path, rr), rr).build() + : getSlingUriFromRequest(request, rr); + addIntermediateMapping(mappingContext, resourceUri, KEY_INTIAL); + if (resourceMappers != null) { + for (SlingUriMapper mapper : reversedList(resourceMappers)) { + String mapperName = mapper.getClass().getName(); + LOG.trace("resolve(): Using {} for {}", mapperName, resourceUri); + SlingUri input = resourceUri; + resourceUri = mapper.resolve(resourceUri, request, mappingContext); + if (input != resourceUri) { + addIntermediateMapping(mappingContext, resourceUri, mapperName); + } + + if (chancelChain(mappingContext, mapperName)) { + break; + } + } + } + + if (LOG.isDebugEnabled()) { + logResult(mappingContext, "resolve()"); + } + + return new MappingChainResult(resourceUri, mappingContext.getIntermediateMappings()); + } + + } + + private String unmangleNamespaces(String path, ResourceResolver rr) { + return jcrNamespaceMangler.unmangleNamespaces(rr, LOG, path); + } + + + private boolean chancelChain(MappingChainContextInternal mappingContext, String name) { + if (mappingContext.isMarkedAsSkipRemainingChain()) { + LOG.debug("{} cancelled remaining chain", name); + return true; + } else { + return false; + } + } + + private void addIntermediateMapping(MappingChainContextInternal mappingContext, SlingUri resourceUri, String name) { + mappingContext.addIntermediateMapping(name, resourceUri); + LOG.trace("{} ajusted SlingUri: {}", name, resourceUri); + } + + private List reversedList(List list) { + List reversedList = new ArrayList<>(list); + Collections.reverse(reversedList); + return reversedList; + } + + private void logResult(MappingChainContextInternal mappingContext, String method) { + Map intermediateMappings = mappingContext.getIntermediateMappings(); + if (intermediateMappings.size() == 1) { + LOG.debug("\n{}:\nUNCHANGED {}", method, intermediateMappings.values().iterator().next()); + } else { + LOG.debug("\n{}:\n{}", method, + intermediateMappings.entrySet().stream() + .map(e -> StringUtils.leftPad(e.getKey().replaceAll("([a-z])[^.]*\\.(?=.*\\..*$)", "$1."), 50) + " -> " + + e.getValue()) + .collect(Collectors.joining("\n"))); + } + } + + protected ResourceResolver getResourceResolver() { + + try { + final Map authenticationInfo = new HashMap<>(); + authenticationInfo.put(ResourceResolverFactory.SUBSERVICE, SUBSERVICE_NAME_MAPPING); + ResourceResolver serviceResourceResolver = resourceResolverFactory.getServiceResourceResolver(authenticationInfo); + return serviceResourceResolver; + } catch (LoginException e) { + throw new IllegalStateException("Cannot create ResourceResolver: " + e, e); + } + } + + private SlingUri getSlingUriFromRequest(final HttpServletRequest request, ResourceResolver rr) { + final StringBuilder sb = new StringBuilder(); + if (request.getServletPath() != null) { + sb.append(request.getServletPath()); + } + if (request.getPathInfo() != null) { + sb.append(request.getPathInfo()); + } + String path = sb.toString(); + // Get the path used to select the authenticator, if the SlingServlet + // itself has been requested without any more info, this will be empty + // and we assume the root (SLING-722) + if (path.length() == 0) { + path = "/"; + } + + return SlingUriBuilder.create() + .setResourceResolver(rr) + .setScheme(request.getScheme()) + .setHost(request.getServerName()) + .setPort(request.getServerPort()) + .setPath(unmangleNamespaces(path, rr)) + .setQuery(request.getQueryString()) + .build(); + } +} diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/urimapping/defaultmappers/BasePathMapper.java b/src/main/java/org/apache/sling/resourceresolver/impl/urimapping/defaultmappers/BasePathMapper.java new file mode 100644 index 0000000..23bf26b --- /dev/null +++ b/src/main/java/org/apache/sling/resourceresolver/impl/urimapping/defaultmappers/BasePathMapper.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.resourceresolver.impl.urimapping.defaultmappers; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.lang3.StringUtils; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.resource.ResourceUtil; +import org.apache.sling.api.uri.SlingUri; +import org.apache.sling.spi.urimapping.MappingChainContext; +import org.apache.sling.spi.urimapping.SlingUriMapper; +import org.jetbrains.annotations.NotNull; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.ConfigurationPolicy; +import org.osgi.service.metatype.annotations.AttributeDefinition; +import org.osgi.service.metatype.annotations.Designate; +import org.osgi.service.metatype.annotations.ObjectClassDefinition; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Component(configurationPolicy = ConfigurationPolicy.REQUIRE) +@Designate(ocd = BasePathMapper.Config.class, factory = true) +public class BasePathMapper implements SlingUriMapper { + private static final Logger LOG = LoggerFactory.getLogger(BasePathMapper.class); + + @ObjectClassDefinition(name = "Apache Sling Resource Mapper: Base Path", description = "Maps a base path in both ways") + public @interface Config { + @AttributeDefinition(name = "Content Base Path", description = "Content Base Path to be remove when mapping and to be added when resolving.") + String basePath(); + } + + private String basePath; + + @Activate + public void activate(Config config) { + basePath = config.basePath(); + LOG.info("Automatic addition of html extension active for paths {}", basePath); + } + + @Override + public SlingUri resolve(@NotNull SlingUri slingUri, HttpServletRequest request, MappingChainContext context) { + + if (StringUtils.equals(slingUri.getResourcePath(), "/") || StringUtils.equals(slingUri.getResourcePath(), "")) { + return slingUri; + } + String expandedPath = basePath + slingUri.getResourcePath(); + Resource resource = context.getResourceResolver().resolve(expandedPath); + if (!ResourceUtil.isSyntheticResource(resource)) { + return slingUri.adjust(b -> b.setResourcePath(expandedPath)); + } else { + return slingUri; + } + } + + @Override + public SlingUri map(@NotNull SlingUri slingUri, HttpServletRequest request, MappingChainContext context) { + + if (StringUtils.startsWith(slingUri.getResourcePath(), basePath)) { + return slingUri.adjust(b -> b.setResourcePath(StringUtils.substringAfter(slingUri.getResourcePath(), basePath))); + } else { + return slingUri; + } + + } + +} diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/urimapping/defaultmappers/EnsureHtmlExtensionMapper.java b/src/main/java/org/apache/sling/resourceresolver/impl/urimapping/defaultmappers/EnsureHtmlExtensionMapper.java new file mode 100644 index 0000000..d11eb29 --- /dev/null +++ b/src/main/java/org/apache/sling/resourceresolver/impl/urimapping/defaultmappers/EnsureHtmlExtensionMapper.java @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.resourceresolver.impl.urimapping.defaultmappers; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.lang3.StringUtils; +import org.apache.sling.api.uri.SlingUri; +import org.apache.sling.spi.urimapping.MappingChainContext; +import org.apache.sling.spi.urimapping.SlingUriMapper; +import org.jetbrains.annotations.NotNull; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.ConfigurationPolicy; +import org.osgi.service.metatype.annotations.AttributeDefinition; +import org.osgi.service.metatype.annotations.Designate; +import org.osgi.service.metatype.annotations.ObjectClassDefinition; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Component(configurationPolicy = ConfigurationPolicy.REQUIRE) +@Designate(ocd = EnsureHtmlExtensionMapper.Config.class) +public class EnsureHtmlExtensionMapper implements SlingUriMapper { + private static final Logger LOG = LoggerFactory.getLogger(EnsureHtmlExtensionMapper.class); + + @ObjectClassDefinition(name = "Apache Sling Resource Mapper: Ensure HTML Extension", description = "Ensures html extension in links without extension") + public @interface Config { + + @AttributeDefinition(name = "Include Regex", description = "Regex to restrict paths where the extension should automatically be added") + String includeRegex(); + } + + private String includeRegex; + + @Activate + public void activate(Config config) { + includeRegex = config.includeRegex(); + LOG.info("Automatic addition of html extension active for paths {}", StringUtils.defaultIfBlank(includeRegex, "")); + } + + private boolean matchesRegex(String path) { + return StringUtils.isBlank(includeRegex) || path.matches(includeRegex); + } + + @Override + public SlingUri resolve(@NotNull SlingUri slingUri, HttpServletRequest request, MappingChainContext context) { + return slingUri; + } + + @Override + public SlingUri map(@NotNull SlingUri slingUri, HttpServletRequest request, MappingChainContext context) { + if (StringUtils.isNotBlank(slingUri.getResourcePath()) + && !StringUtils.contains(slingUri.getResourcePath(), ".") + && StringUtils.isBlank(slingUri.getExtension()) + && matchesRegex(slingUri.getResourcePath())) { + LOG.debug("Adding extension to URL {} with path={} and ext={}", slingUri, slingUri.getResourcePath(), + slingUri.getExtension()); + return slingUri.adjust(b -> b.setExtension("html")); + } else { + return slingUri; + } + } + +} diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/EtcMappingResourceResolverTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/EtcMappingResourceResolverTest.java index ca2d6a6..380be0a 100644 --- a/src/test/java/org/apache/sling/resourceresolver/impl/EtcMappingResourceResolverTest.java +++ b/src/test/java/org/apache/sling/resourceresolver/impl/EtcMappingResourceResolverTest.java @@ -16,6 +16,31 @@ */ package org.apache.sling.resourceresolver.impl; +import static java.util.Arrays.asList; +import static org.apache.sling.resourceresolver.impl.MockedResourceResolverImplTest.createRPHandler; +import static org.apache.sling.resourceresolver.impl.ResourceResolverImpl.PROP_REDIRECT_INTERNAL; +import static org.apache.sling.resourceresolver.impl.mapping.MapEntries.PROP_REDIRECT_EXTERNAL; +import static org.apache.sling.resourceresolver.util.MockTestUtil.buildResource; +import static org.apache.sling.resourceresolver.util.MockTestUtil.callInaccessibleMethod; +import static org.apache.sling.resourceresolver.util.MockTestUtil.checkInternalResource; +import static org.apache.sling.resourceresolver.util.MockTestUtil.checkRedirectResource; +import static org.apache.sling.resourceresolver.util.MockTestUtil.createRequestFromUrl; +import static org.apache.sling.resourceresolver.util.MockTestUtil.createStringInterpolationProviderConfiguration; +import static org.apache.sling.resourceresolver.util.MockTestUtil.setInaccessibleField; +import static org.apache.sling.resourceresolver.util.MockTestUtil.setupStringInterpolationProvider; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; + import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.resource.ResourceResolverFactory; @@ -23,12 +48,14 @@ import org.apache.sling.api.resource.observation.ResourceChange; import org.apache.sling.api.resource.path.Path; import org.apache.sling.resourceresolver.impl.mapping.MapConfigurationProvider; import org.apache.sling.resourceresolver.impl.mapping.MapEntries; -import org.apache.sling.resourceresolver.impl.mapping.StringInterpolationProviderConfiguration; import org.apache.sling.resourceresolver.impl.mapping.StringInterpolationProvider; +import org.apache.sling.resourceresolver.impl.mapping.StringInterpolationProviderConfiguration; import org.apache.sling.resourceresolver.impl.mapping.StringInterpolationProviderImpl; import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler; import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorage; import org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker; +import org.apache.sling.resourceresolver.util.MockTestUtil; +import org.apache.sling.resourceresolver.util.MockTestUtil.ExpectedEtcMapping; import org.apache.sling.serviceusermapping.ServiceUserMapper; import org.apache.sling.spi.resource.provider.ResourceProvider; import org.junit.Before; @@ -39,31 +66,6 @@ import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.service.event.EventAdmin; -import javax.servlet.http.HttpServletRequest; -import java.io.File; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import static java.util.Arrays.asList; -import static org.apache.sling.resourceresolver.impl.MockedResourceResolverImplTest.createRPHandler; -import static org.apache.sling.resourceresolver.impl.ResourceResolverImpl.PROP_REDIRECT_INTERNAL; -import static org.apache.sling.resourceresolver.impl.mapping.MapEntries.PROP_REDIRECT_EXTERNAL; -import static org.apache.sling.resourceresolver.util.MockTestUtil.ExpectedEtcMapping; -import static org.apache.sling.resourceresolver.util.MockTestUtil.buildResource; -import static org.apache.sling.resourceresolver.util.MockTestUtil.callInaccessibleMethod; -import static org.apache.sling.resourceresolver.util.MockTestUtil.checkInternalResource; -import static org.apache.sling.resourceresolver.util.MockTestUtil.checkRedirectResource; -import static org.apache.sling.resourceresolver.util.MockTestUtil.createRequestFromUrl; -import static org.apache.sling.resourceresolver.util.MockTestUtil.createStringInterpolationProviderConfiguration; -import static org.apache.sling.resourceresolver.util.MockTestUtil.setInaccessibleField; -import static org.apache.sling.resourceresolver.util.MockTestUtil.setupStringInterpolationProvider; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; - /** * These are the same tests as in the EtcMappingMapEntriesTest but in this * class we are actually mocking the Resource Resolver Factory and its classes @@ -130,6 +132,8 @@ public class EtcMappingResourceResolverTest { setInaccessibleField("observationPaths", activator, new Path[] {new Path("/")}); ServiceUserMapper serviceUserMapper = mock(ServiceUserMapper.class); setInaccessibleField("serviceUserMapper", activator, serviceUserMapper); + setInaccessibleField("pathToUriMappingService", activator, MockTestUtil.createPathToUriMappingServiceMock(resourceResolver)); + commonFactory = spy(new CommonResourceResolverFactoryImpl(activator)); when(bundleContext.getBundle()).thenReturn(bundle); when(bundleContext.getDataFile("vanityBloomFilter.txt")).thenReturn(vanityBloomFilterFile); diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/MockedResourceResolverImplTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/MockedResourceResolverImplTest.java index b960a82..b853473 100644 --- a/src/test/java/org/apache/sling/resourceresolver/impl/MockedResourceResolverImplTest.java +++ b/src/test/java/org/apache/sling/resourceresolver/impl/MockedResourceResolverImplTest.java @@ -42,6 +42,7 @@ import org.apache.sling.api.resource.ResourceMetadata; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.resource.ResourceResolverFactory; import org.apache.sling.api.resource.ValueMap; +import org.apache.sling.api.resource.mapping.PathToUriMappingService; import org.apache.sling.api.wrappers.ValueMapDecorator; import org.apache.sling.resourceresolver.impl.mapping.MapEntries; import org.apache.sling.resourceresolver.impl.observation.ResourceChangeListenerWhiteboard; @@ -49,6 +50,7 @@ import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler; import org.apache.sling.resourceresolver.impl.providers.ResourceProviderInfo; import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorage; import org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker; +import org.apache.sling.resourceresolver.util.MockTestUtil; import org.apache.sling.serviceusermapping.ServiceUserMapper; import org.apache.sling.spi.resource.provider.QueryLanguageProvider; import org.apache.sling.spi.resource.provider.ResolveContext; @@ -141,7 +143,12 @@ public class MockedResourceResolverImplTest { @SuppressWarnings("unchecked") @Before public void before() throws LoginException { - activator = new ResourceResolverFactoryActivator(); + activator = new ResourceResolverFactoryActivator() { + @Override + public PathToUriMappingService getPathToUriMappingService() { + return MockTestUtil.createPathToUriMappingServiceMock(null); + } + }; // system bundle access final Bundle systemBundle = Mockito.mock(Bundle.class); diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/ProviderHandlerTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/ProviderHandlerTest.java index d9592c4..20b3d17 100644 --- a/src/test/java/org/apache/sling/resourceresolver/impl/ProviderHandlerTest.java +++ b/src/test/java/org/apache/sling/resourceresolver/impl/ProviderHandlerTest.java @@ -34,6 +34,7 @@ import org.apache.sling.api.resource.ResourceUtil; import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler; import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorage; import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorageProvider; +import org.apache.sling.resourceresolver.util.MockTestUtil; import org.apache.sling.spi.resource.provider.ResolveContext; import org.apache.sling.spi.resource.provider.ResourceContext; import org.apache.sling.spi.resource.provider.ResourceProvider; @@ -67,6 +68,7 @@ public class ProviderHandlerTest { return new ResourceProviderStorage(Arrays.asList(h)); } }); + activator.pathToUriMappingService = MockTestUtil.createPathToUriMappingServiceMock(resolver); final Resource parent = resolver.getResource(ResourceUtil.getParent(servletpath)); assertNotNull("Parent must be available", parent); diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/ResourceDecoratorTestBase.java b/src/test/java/org/apache/sling/resourceresolver/impl/ResourceDecoratorTestBase.java index 8213179..6795875 100644 --- a/src/test/java/org/apache/sling/resourceresolver/impl/ResourceDecoratorTestBase.java +++ b/src/test/java/org/apache/sling/resourceresolver/impl/ResourceDecoratorTestBase.java @@ -36,10 +36,12 @@ import org.apache.sling.api.resource.ResourceMetadata; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.resource.ResourceUtil; import org.apache.sling.api.resource.ValueMap; +import org.apache.sling.api.resource.mapping.PathToUriMappingService; import org.apache.sling.resourceresolver.impl.helper.ResourceDecoratorTracker; import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler; import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorage; import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorageProvider; +import org.apache.sling.resourceresolver.util.MockTestUtil; import org.apache.sling.spi.resource.provider.QueryLanguageProvider; import org.apache.sling.spi.resource.provider.ResolveContext; import org.apache.sling.spi.resource.provider.ResourceContext; @@ -141,6 +143,11 @@ public abstract class ResourceDecoratorTestBase { public ResourceAccessSecurityTracker getResourceAccessSecurityTracker() { return new ResourceAccessSecurityTracker(); } + + @Override + public PathToUriMappingService getPathToUriMappingService() { + return MockTestUtil.createPathToUriMappingServiceMock(null); + } }; final List list = Arrays.asList(MockedResourceResolverImplTest.createRPHandler(provider, "A-provider", 0L, "/")); diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/ResourceResolverImplTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/ResourceResolverImplTest.java index 3eee2cf..fde657b 100644 --- a/src/test/java/org/apache/sling/resourceresolver/impl/ResourceResolverImplTest.java +++ b/src/test/java/org/apache/sling/resourceresolver/impl/ResourceResolverImplTest.java @@ -52,6 +52,7 @@ import org.apache.sling.api.resource.SyntheticResource; import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler; import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorage; import org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker; +import org.apache.sling.resourceresolver.util.MockTestUtil; import org.apache.sling.spi.resource.provider.ResolveContext; import org.apache.sling.spi.resource.provider.ResourceContext; import org.apache.sling.spi.resource.provider.ResourceProvider; @@ -91,6 +92,7 @@ public class ResourceResolverImplTest { ResourceResolverFactoryActivator activator = new ResourceResolverFactoryActivator(); activator.resourceProviderTracker = resourceProviderTracker; activator.resourceAccessSecurityTracker = new ResourceAccessSecurityTracker(); + activator.pathToUriMappingService = MockTestUtil.createPathToUriMappingServiceMock(null); commonFactory = new CommonResourceResolverFactoryImpl(activator); final Bundle usingBundle = mock(Bundle.class); resFac = new ResourceResolverFactoryImpl(commonFactory, usingBundle, null); diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/ResourceResolverMangleNamespacesTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/ResourceResolverMangleNamespacesTest.java index 8877882..dabc021 100644 --- a/src/test/java/org/apache/sling/resourceresolver/impl/ResourceResolverMangleNamespacesTest.java +++ b/src/test/java/org/apache/sling/resourceresolver/impl/ResourceResolverMangleNamespacesTest.java @@ -23,19 +23,21 @@ import static org.junit.Assert.assertEquals; import java.util.Arrays; import java.util.Iterator; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.NotNull; import javax.jcr.RepositoryException; import javax.jcr.Session; import org.apache.commons.collections4.IteratorUtils; import org.apache.sling.api.resource.LoginException; import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.resource.mapping.PathToUriMappingService; import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorage; import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorageProvider; +import org.apache.sling.resourceresolver.util.MockTestUtil; import org.apache.sling.spi.resource.provider.ResolveContext; import org.apache.sling.spi.resource.provider.ResourceContext; import org.apache.sling.spi.resource.provider.ResourceProvider; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; @@ -65,6 +67,11 @@ public class ResourceResolverMangleNamespacesTest { public boolean isMangleNamespacePrefixes() { return true; } + + @Override + public PathToUriMappingService getPathToUriMappingService() { + return MockTestUtil.createPathToUriMappingServiceMock(rr); + } }; Mockito.when(mockedSession.getNamespacePrefix(NS_PREFIX)).thenReturn(NS_URL); diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/AbstractMappingMapEntriesTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/AbstractMappingMapEntriesTest.java index 44e04a9..cf54a3b 100644 --- a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/AbstractMappingMapEntriesTest.java +++ b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/AbstractMappingMapEntriesTest.java @@ -16,6 +16,31 @@ */ package org.apache.sling.resourceresolver.impl.mapping; +import static org.apache.sling.resourceresolver.util.MockTestUtil.createStringInterpolationProviderConfiguration; +import static org.apache.sling.resourceresolver.util.MockTestUtil.setupStringInterpolationProvider; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyMap; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.withSettings; + +import java.io.File; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.Semaphore; + import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceMetadata; import org.apache.sling.api.resource.ResourceResolver; @@ -23,6 +48,7 @@ import org.apache.sling.api.resource.ResourceUtil; import org.apache.sling.api.resource.ValueMap; import org.apache.sling.api.resource.path.Path; import org.apache.sling.api.wrappers.ValueMapDecorator; +import org.apache.sling.resourceresolver.impl.ResourceResolverFactoryImpl; import org.junit.After; import org.junit.Before; import org.mockito.Mock; @@ -33,31 +59,6 @@ import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.service.event.EventAdmin; -import java.io.File; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; -import java.util.concurrent.Semaphore; - -import static org.apache.sling.resourceresolver.util.MockTestUtil.createStringInterpolationProviderConfiguration; -import static org.apache.sling.resourceresolver.util.MockTestUtil.setupStringInterpolationProvider; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyMap; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.mockito.Mockito.withSettings; - /** * These are tests that are testing the Sling Interpolation Feature (SLING-7768) * on the MapEntries level diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/EtcMappingMapEntriesTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/EtcMappingMapEntriesTest.java index a98ca6e..1f3fa13 100644 --- a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/EtcMappingMapEntriesTest.java +++ b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/EtcMappingMapEntriesTest.java @@ -16,6 +16,23 @@ */ package org.apache.sling.resourceresolver.impl.mapping; +import static java.util.Arrays.asList; +import static org.apache.sling.resourceresolver.impl.MockedResourceResolverImplTest.createRPHandler; +import static org.apache.sling.resourceresolver.impl.ResourceResolverImpl.PROP_REDIRECT_INTERNAL; +import static org.apache.sling.resourceresolver.impl.mapping.MapEntries.PROP_REDIRECT_EXTERNAL; +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +import java.lang.reflect.Method; +import java.util.Iterator; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; + import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.resource.path.Path; @@ -26,6 +43,8 @@ import org.apache.sling.resourceresolver.impl.ResourceResolverFactoryImpl; import org.apache.sling.resourceresolver.impl.providers.ResourceProviderHandler; import org.apache.sling.resourceresolver.impl.providers.ResourceProviderStorage; import org.apache.sling.resourceresolver.impl.providers.ResourceProviderTracker; +import org.apache.sling.resourceresolver.util.MockTestUtil; +import org.apache.sling.resourceresolver.util.MockTestUtil.ExpectedEtcMapping; import org.apache.sling.serviceusermapping.ServiceUserMapper; import org.apache.sling.spi.resource.provider.ResolveContext; import org.apache.sling.spi.resource.provider.ResourceContext; @@ -34,23 +53,6 @@ import org.junit.Test; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; -import javax.servlet.http.HttpServletRequest; -import java.lang.reflect.Method; -import java.util.Iterator; -import java.util.List; - -import static java.util.Arrays.asList; -import static org.apache.sling.resourceresolver.impl.MockedResourceResolverImplTest.createRPHandler; -import static org.apache.sling.resourceresolver.impl.ResourceResolverImpl.PROP_REDIRECT_INTERNAL; -import static org.apache.sling.resourceresolver.impl.mapping.MapEntries.PROP_REDIRECT_EXTERNAL; -import static org.apache.sling.resourceresolver.util.MockTestUtil.ExpectedEtcMapping; -import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; - /** * These tests are for the /etc/map setup of the Map Entries when * an /etc/map is present. @@ -191,7 +193,7 @@ public class EtcMappingMapEntriesTest extends AbstractMappingMapEntriesTest { final Bundle usingBundle = mock(Bundle.class); ResourceResolverFactoryImpl resFac = new ResourceResolverFactoryImpl(commonFactory, usingBundle, null); ResourceResolver resResolver = resFac.getAdministrativeResourceResolver(null); - + when(activator.getPathToUriMappingService()).thenReturn(MockTestUtil.createPathToUriMappingServiceMock(resResolver)); HttpServletRequest request = mock(HttpServletRequest.class); when(request.getScheme()).thenReturn("http"); when(request.getServerName()).thenReturn("localhost"); diff --git a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/ResourceMapperImplTest.java b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/ResourceMapperImplTest.java index 0e2cc54..fa71d15 100644 --- a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/ResourceMapperImplTest.java +++ b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/ResourceMapperImplTest.java @@ -39,9 +39,11 @@ 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.api.resource.mapping.PathToUriMappingService; import org.apache.sling.api.resource.mapping.ResourceMapper; import org.apache.sling.resourceresolver.impl.ResourceAccessSecurityTracker; import org.apache.sling.resourceresolver.impl.ResourceResolverFactoryActivator; +import org.apache.sling.resourceresolver.util.MockTestUtil; import org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl; import org.apache.sling.spi.resource.provider.ResourceProvider; import org.apache.sling.testing.mock.osgi.junit.OsgiContext; @@ -97,6 +99,7 @@ public class ResourceMapperImplTest { ctx.registerInjectActivateService(new ServiceUserMapperImpl()); ctx.registerInjectActivateService(new ResourceAccessSecurityTracker()); ctx.registerInjectActivateService(new StringInterpolationProviderImpl()); + ctx.registerService(PathToUriMappingService.class, MockTestUtil.createPathToUriMappingServiceMock(resolver)); InMemoryResourceProvider resourceProvider = new InMemoryResourceProvider(); resourceProvider.putResource("/"); // root diff --git a/src/test/java/org/apache/sling/resourceresolver/util/MockTestUtil.java b/src/test/java/org/apache/sling/resourceresolver/util/MockTestUtil.java index 5291b5b..f8e696f 100644 --- a/src/test/java/org/apache/sling/resourceresolver/util/MockTestUtil.java +++ b/src/test/java/org/apache/sling/resourceresolver/util/MockTestUtil.java @@ -16,12 +16,30 @@ */ package org.apache.sling.resourceresolver.util; -import junit.framework.TestCase; +import static java.util.Arrays.asList; +import static org.hamcrest.Matchers.instanceOf; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.withSettings; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; + import org.apache.sling.api.resource.NonExistingResource; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceMetadata; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.resource.ValueMap; +import org.apache.sling.api.resource.mapping.PathToUriMappingService; import org.apache.sling.api.wrappers.ValueMapDecorator; import org.apache.sling.resourceresolver.impl.SimpleValueMapImpl; import org.apache.sling.resourceresolver.impl.helper.RedirectResource; @@ -36,22 +54,7 @@ import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.osgi.framework.BundleContext; -import javax.servlet.http.HttpServletRequest; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; - -import static java.util.Arrays.asList; -import static org.hamcrest.Matchers.instanceOf; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.mockito.Mockito.withSettings; +import junit.framework.TestCase; public class MockTestUtil { @@ -424,4 +427,9 @@ public class MockTestUtil { assertEquals("Wrong Redirect Type (ext/int) for: " + title, this.internal, mapEntry.isInternal()); } } + + public static PathToUriMappingService createPathToUriMappingServiceMock(final ResourceResolver rr) { + return new TestPathToUriMappingService(); + } + } diff --git a/src/test/java/org/apache/sling/resourceresolver/util/TestPathToUriMappingService.java b/src/test/java/org/apache/sling/resourceresolver/util/TestPathToUriMappingService.java new file mode 100644 index 0000000..93ce2ec --- /dev/null +++ b/src/test/java/org/apache/sling/resourceresolver/util/TestPathToUriMappingService.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package org.apache.sling.resourceresolver.util; + +import java.util.Collections; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.sling.api.resource.mapping.PathToUriMappingService; +import org.apache.sling.api.uri.SlingUri; +import org.apache.sling.api.uri.SlingUriBuilder; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +class TestPathToUriMappingService implements PathToUriMappingService { + + static class MappingResult implements PathToUriMappingService.Result { + private final @NotNull SlingUri slingUri; + + MappingResult(@NotNull SlingUri slingUri) { + this.slingUri = slingUri; + } + + @Override + public @NotNull SlingUri getUri() { + return slingUri; + } + + @Override + public @NotNull Map getIntermediateMappings() { + return Collections.emptyMap(); + } + } + + @Override + public Result resolve(@Nullable HttpServletRequest request, @NotNull String path) { + return new MappingResult(SlingUriBuilder.parse(path, null).build()); + } + + @Override + public Result map(@Nullable HttpServletRequest request, @NotNull String path) { + return new MappingResult(SlingUriBuilder.parse(path, null).build()); + } +} \ No newline at end of file