Resource Mapping SPI
diff --git a/src/main/java/org/apache/sling/api/resource/ResourceResolver.java b/src/main/java/org/apache/sling/api/resource/ResourceResolver.java
index 8a2b27d..965d1d6 100644
--- a/src/main/java/org/apache/sling/api/resource/ResourceResolver.java
+++ b/src/main/java/org/apache/sling/api/resource/ResourceResolver.java
@@ -22,12 +22,13 @@
import java.util.Iterator;
import java.util.Map;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.annotations.NotNull;
import javax.servlet.http.HttpServletRequest;
import org.apache.sling.api.adapter.Adaptable;
import org.apache.sling.api.resource.mapping.ResourceMapper;
+import org.apache.sling.api.resource.uri.ResourceURI;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.osgi.annotation.versioning.ProviderType;
/**
@@ -331,6 +332,10 @@
*/
@Nullable String map(@NotNull HttpServletRequest request, @NotNull String resourcePath);
+ /** Same as map(request, resourcePath) but returns a {@link ResourceURI} */
+ @Nullable
+ ResourceURI mapToURI(@NotNull HttpServletRequest request, @NotNull String resourcePath);
+
/**
* Returns a {@link Resource} object for data located at the given path.
* <p>
diff --git a/src/main/java/org/apache/sling/api/resource/mapping/spi/ResourceMapping.java b/src/main/java/org/apache/sling/api/resource/mapping/spi/ResourceMapping.java
new file mode 100644
index 0000000..6a3d2e4
--- /dev/null
+++ b/src/main/java/org/apache/sling/api/resource/mapping/spi/ResourceMapping.java
@@ -0,0 +1,54 @@
+/*
+ * 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.api.resource.mapping.spi;
+
+import java.util.Map;
+
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.uri.ResourceURI;
+import org.jetbrains.annotations.NotNull;
+import org.osgi.annotation.versioning.ConsumerType;
+
+/** SPI interface that contributes to resource mapping and resolving of the resource resolver's map() and resolve() methods.
+ *
+ * All registered services are sorted by service ranking and put in a list that forms a pipeline. The resource link is passed through the
+ * pipeline while any ResourceMapping pipeline member may or may not make adjustments to the resource link.
+ *
+ * rr.resolve() passes through the pipeline starting at the ResourceMapping with the <strong>highest</strong> service ranking rr.map()
+ * passes through the pipeline starting at the ResourceMapping with the <strong>lowest</strong> service ranking */
+@ConsumerType
+public interface ResourceMapping {
+
+ /** Contributes to the resolve process, may or may not make adjustments to the resource link
+ *
+ * @param resourceURI the URI to be resolved
+ * @param request the servlet request
+ * @param pipelineContext can be used for sharing state between instances of ResourceMapping
+ * @return true if no other ResourceMapping services should be considered after this, false if the pipeline should continue */
+ boolean resolve(@NotNull ResourceURI resourceURI, SlingHttpServletRequest request, Map<String, Object> pipelineContext);
+
+ /** Contributes to the map process, may or may not make adjustments to the resource link.
+ *
+ * @param resourceURI the URI to be mapped
+ * @param request the servlet request
+ * @param pipelineContext can be used for sharing state between instances of ResourceMapping
+ * @return true if no other ResourceMapping services should be considered after this, false if the pipeline should continue */
+ boolean map(@NotNull ResourceURI resourceURI, SlingHttpServletRequest request, Map<String, Object> pipelineContext);
+
+}
diff --git a/src/main/java/org/apache/sling/api/resource/mapping/spi/package-info.java b/src/main/java/org/apache/sling/api/resource/mapping/spi/package-info.java
new file mode 100644
index 0000000..a58f5b5
--- /dev/null
+++ b/src/main/java/org/apache/sling/api/resource/mapping/spi/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+@Version("1.0.0")
+package org.apache.sling.api.resource.mapping.spi;
+
+import org.osgi.annotation.versioning.Version;
+
diff --git a/src/main/java/org/apache/sling/api/resource/uri/ResourceURI.java b/src/main/java/org/apache/sling/api/resource/uri/ResourceURI.java
new file mode 100644
index 0000000..13cebcc
--- /dev/null
+++ b/src/main/java/org/apache/sling/api/resource/uri/ResourceURI.java
@@ -0,0 +1,156 @@
+/*
+ * 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.api.resource.uri;
+
+import java.net.URI;
+
+import org.apache.sling.api.request.RequestPathInfo;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.mapping.spi.ResourceMapping;
+
+/** Represents a link (or anything that can be used in markup href/src/etc. attributes). A link can be one of the following:
+ *
+ * <ul>
+ * <li>URI</li>
+ * <li>absolute path</li>
+ * <li>relative path</li>
+ * <li>special link like 'javascript:...' or 'mailto:...'</li>
+ * <li>anchor #</li>
+ * </ul>
+ *
+ * ResourceLink supports changing any part of the link by a clean interface <strong>without using error-prone string operations</strong> on
+ * strings.
+ *
+ * ResourceLinks are meant to be used in regular application code but are also used in {@link ResourceMapping} pipelines. */
+public interface ResourceURI extends RequestPathInfo {
+
+ /** @return returns true if the link is either a relative or absolute path (this is the case if scheme and host is empty and the URI
+ * path is set) */
+ public boolean isPath();
+
+ /** @return true if the link is a absolute path starting with a slash ('/'). This is the default case for all links to pages and assets
+ * in AEM. */
+ public boolean isAbsolutePath();
+
+ /** @return true if link is relative (not an URL and not starting with '/') */
+ public boolean isRelativePath();
+
+ /** @return true if the link is an absolute URI containing a scheme. */
+ public boolean isAbsoluteUri();
+
+ /** @return returns the URI. */
+ public URI getUri();
+
+ /** @return returns the resource path or null if link does not contain path. */
+ @Override
+ public String getResourcePath();
+
+ /** @return returns the selector string */
+ @Override
+ public String getSelectorString();
+
+ /** @return returns the selector array */
+ @Override
+ public String[] getSelectors();
+
+ /** @return returns the extension of the link */
+ @Override
+ public String getExtension();
+
+ /** @return returns the suffix of the link */
+ @Override
+ public String getSuffix();
+
+ /** @return returns the query part of the link */
+ public String getQuery();
+
+ /** @return returns the url fragment of the link */
+ public String getFragment();
+
+ /** @return returns the scheme of the link */
+ public String getScheme();
+
+ /** @return returns the host of the link */
+ public String getHost();
+
+ /** @return returns the port of the link */
+ public int getPort();
+
+ /** @return returns the corresponding */
+ @Override
+ public Resource getSuffixResource();
+
+ // -- Currently the implementation is designed gto be mutable (easier to use, smaller memory footprint)
+ // mutable vs. immutable to be discussed
+
+ /** Resets the entire link to the given string.
+ *
+ * @param linkStrParam link to be used for setting the request */
+ public void setLinkString(String linkStrParam);
+
+ /** Sets the resource path of the link (leaving selectors, extension, suffix and query unchanged)
+ *
+ * @param resourcePath the resource path */
+ public void setResourcePath(final String resourcePath);
+
+ /** Sets selectors of the link (leaving path, extension, suffix and query unchanged)
+ *
+ * @param selectors the new selectors for the link */
+ public void setSelectors(final String[] selectors);
+
+ /** Adds a selector to the existing selectors of the link (leaving path, extension, suffix and query unchanged)
+ *
+ * @param selector adds a selector to the existing selectors of the list */
+ public void addSelector(final String selector);
+
+ /** Sets the extension of the link (leaving path, selectors, suffix and query unchanged)
+ *
+ * @param extension the extension */
+ public void setExtension(final String extension);
+
+ /** Sets the suffix of the link (leaving path, selectors, extension and query unchanged)
+ *
+ * @param suffix suffix to be set */
+ public void setSuffix(final String suffix);
+
+ /** Sets the query of the link (leaving path, selectors, extension and suffix unchanged).
+ *
+ * @param query the query */
+ public void setQuery(final String query);
+
+ /** Sets the url fragment of the link (leaving path, selectors, extension, suffix and query unchanged).
+ *
+ * @param urlFragment url fragment */
+ public void setFragment(final String urlFragment);
+
+ /** Sets the scheme of the link
+ *
+ * @param scheme scheme */
+ public void setScheme(final String scheme);
+
+ /** Sets the host of the link
+ *
+ * @param host host */
+ public void setHost(final String host);
+
+ /** Sets the port of the link
+ *
+ * @param port port */
+ public void setPort(final int port);
+}
diff --git a/src/main/java/org/apache/sling/api/resource/uri/package-info.java b/src/main/java/org/apache/sling/api/resource/uri/package-info.java
new file mode 100644
index 0000000..9e5c56b
--- /dev/null
+++ b/src/main/java/org/apache/sling/api/resource/uri/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+@Version("1.0.0")
+package org.apache.sling.api.resource.uri;
+
+import org.osgi.annotation.versioning.Version;
+
diff --git a/src/main/java/org/apache/sling/api/wrappers/ResourceResolverWrapper.java b/src/main/java/org/apache/sling/api/wrappers/ResourceResolverWrapper.java
index 67c2fbf..3762ae9 100644
--- a/src/main/java/org/apache/sling/api/wrappers/ResourceResolverWrapper.java
+++ b/src/main/java/org/apache/sling/api/wrappers/ResourceResolverWrapper.java
@@ -18,7 +18,7 @@
import java.util.Iterator;
import java.util.Map;
-import org.jetbrains.annotations.NotNull;
+
import javax.servlet.http.HttpServletRequest;
import org.apache.sling.api.resource.LoginException;
@@ -26,6 +26,8 @@
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceWrapper;
+import org.apache.sling.api.resource.uri.ResourceURI;
+import org.jetbrains.annotations.NotNull;
import org.osgi.annotation.versioning.ConsumerType;
/**
@@ -107,6 +109,11 @@
return wrapped.map(request, resourcePath);
}
+ /** Same as map(request, resourcePath) but returns a {@link ResourceURI} */
+ public ResourceURI mapToURI(@NotNull HttpServletRequest request, @NotNull String resourcePath) {
+ throw new UnsupportedOperationException("");
+ }
+
/**
* Wraps and returns the {@code Resource} obtained by calling {@code getResource} on the wrapped resource resolver.
*