This is an automated email from the ASF dual-hosted git repository.
cziegeler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-api.git
The following commit(s) were added to refs/heads/master by this push:
new 04ece2c SLING-13421 Add header-only Jakarta media range parsing (#89)
04ece2c is described below
commit 04ece2c98e5d4c4bf154262f3b768b268520b59e
Author: Carsten Ziegeler <[email protected]>
AuthorDate: Wed Nov 11 16:10:16 2026 +0100
SLING-13421 Add header-only Jakarta media range parsing (#89)
* SLING-13421 Add header-only Jakarta media range parsing
Co-authored-by: Copilot <[email protected]>
* Fix javadoc errors
---------
Co-authored-by: Copilot <[email protected]>
---
.../api/request/header/JakartaMediaRangeList.java | 41 +++++++++++++++++++++-
.../sling/api/request/header/MediaRangeList.java | 2 +-
.../sling/api/request/header/package-info.java | 2 +-
.../request/header/JakartaMediaRangeListTest.java | 31 ++++++++++++++++
4 files changed, 73 insertions(+), 3 deletions(-)
diff --git
a/src/main/java/org/apache/sling/api/request/header/JakartaMediaRangeList.java
b/src/main/java/org/apache/sling/api/request/header/JakartaMediaRangeList.java
index 4a98646..953a7da 100644
---
a/src/main/java/org/apache/sling/api/request/header/JakartaMediaRangeList.java
+++
b/src/main/java/org/apache/sling/api/request/header/JakartaMediaRangeList.java
@@ -42,13 +42,40 @@ import org.slf4j.LoggerFactory;
@ConsumerType
public class JakartaMediaRangeList extends
TreeSet<JakartaMediaRangeList.MediaRange> {
+ /**
+ * The HTTP header name for the Accept header.
+ */
public static final String HEADER_ACCEPT = "Accept";
+
+ /**
+ * The request parameter name for the Accept header override.
+ * @deprecated Use {@link #HEADER_ACCEPT} instead.
+ */
+ @Deprecated
public static final String PARAM_ACCEPT = ":http-equiv-accept";
+
+ /**
+ * The wildcard character for media ranges.
+ */
public static final String WILDCARD = "*";
+
boolean matchesAll = false;
private static final Logger log =
LoggerFactory.getLogger(JakartaMediaRangeList.class);
+ /**
+ * Creates a <code>MediaRangeList</code> from the {@link #HEADER_ACCEPT}
header of the supplied request.
+ * Request parameters, including {@link #PARAM_ACCEPT}, are ignored.
+ * If the header is missing or empty, the client is assumed to accept all
media types.
+ *
+ * @param request The request to read the Accept header from
+ * @return The media ranges accepted by the client
+ * @since 1.2.0
+ */
+ public static @NotNull JakartaMediaRangeList fromRequest(@NotNull
HttpServletRequest request) {
+ return new JakartaMediaRangeList(request.getHeader(HEADER_ACCEPT));
+ }
+
/**
* Constructs a <code>MediaRangeList</code> using information from the
supplied <code>HttpServletRequest</code>.
* if the request contains a {@link #PARAM_ACCEPT} query parameter, the
query parameter value overrides any
@@ -57,7 +84,10 @@ public class JakartaMediaRangeList extends
TreeSet<JakartaMediaRangeList.MediaRa
* {@link #HEADER_ACCEPT} is used. If both values are missing, it is
assumed that the client accepts all media types,
* as per the RFC. See also {@link
#JakartaMediaRangeList(java.lang.String)}
* @param request The <code>HttpServletRequest</code> to extract a
<code>MediaRangeList</code> from
+ * @deprecated Use {@link #fromRequest(HttpServletRequest)} to read only
the Accept header without
+ * allowing request parameters to override it.
*/
+ @Deprecated
public JakartaMediaRangeList(HttpServletRequest request) {
String queryParam = request.getParameter(PARAM_ACCEPT);
if (queryParam != null && queryParam.trim().length() != 0) {
@@ -111,6 +141,15 @@ public class JakartaMediaRangeList extends
TreeSet<JakartaMediaRangeList.MediaRa
}
}
+ /**
+ * Whether this <code>MediaRangeList</code> matches all media types.
+ * @return <code>true</code> if this <code>MediaRangeList</code> matches
all media types, <code>false</code> otherwise
+ * @since 1.2.0
+ */
+ public boolean matchesAll() {
+ return this.matchesAll;
+ }
+
/**
* Determines if this MediaRangeList contains a given media type.
* @param mediaType A string on the form <code>type/subtype</code>.
Neither <code>type</code>
@@ -162,10 +201,10 @@ public class JakartaMediaRangeList extends
TreeSet<JakartaMediaRangeList.MediaRa
/**
* Determines which of the <code>mediaRanges</code> specifications is
preferred by this <code>MediaRangeList</code>.
+ * Offered order breaks ties when multiple types match the same range.
* @param mediaRanges String representations of <code>MediaRange</code>s.
The strings must be
* on the form required by {@link MediaRange#MediaRange(String)}
* @see #prefer(java.util.Set)
- * @implNote Offered order breaks ties when multiple types match the same
range.
* @return the <code>toString()</code> representation of the preferred
<code>MediaRange</code>, or <code>null</code>
* if this <code>MediaRangeList</code> does not contain any of the
<code>mediaRanges</code>
*/
diff --git
a/src/main/java/org/apache/sling/api/request/header/MediaRangeList.java
b/src/main/java/org/apache/sling/api/request/header/MediaRangeList.java
index b626521..21f8f2e 100644
--- a/src/main/java/org/apache/sling/api/request/header/MediaRangeList.java
+++ b/src/main/java/org/apache/sling/api/request/header/MediaRangeList.java
@@ -164,10 +164,10 @@ public class MediaRangeList extends
TreeSet<MediaRangeList.MediaRange> {
/**
* Determines which of the <code>mediaRanges</code> specifications is
preferred by this <code>MediaRangeList</code>.
+ * Offered order breaks ties when multiple types match the same range.
* @param mediaRanges String representations of <code>MediaRange</code>s.
The strings must be
* on the form required by {@link MediaRange#MediaRange(String)}
* @see #prefer(java.util.Set)
- * @implNote Offered order breaks ties when multiple types match the same
range.
* @return the <code>toString()</code> representation of the preferred
<code>MediaRange</code>, or <code>null</code>
* if this <code>MediaRangeList</code> does not contain any of the
<code>mediaRanges</code>
*/
diff --git
a/src/main/java/org/apache/sling/api/request/header/package-info.java
b/src/main/java/org/apache/sling/api/request/header/package-info.java
index 24cb520..09b8624 100644
--- a/src/main/java/org/apache/sling/api/request/header/package-info.java
+++ b/src/main/java/org/apache/sling/api/request/header/package-info.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-@Version("1.1.1")
+@Version("1.2.0")
package org.apache.sling.api.request.header;
import org.osgi.annotation.versioning.Version;
diff --git
a/src/test/java/org/apache/sling/api/request/header/JakartaMediaRangeListTest.java
b/src/test/java/org/apache/sling/api/request/header/JakartaMediaRangeListTest.java
index 6557641..f8625d9 100644
---
a/src/test/java/org/apache/sling/api/request/header/JakartaMediaRangeListTest.java
+++
b/src/test/java/org/apache/sling/api/request/header/JakartaMediaRangeListTest.java
@@ -25,6 +25,7 @@ import junit.framework.TestCase;
import org.apache.sling.api.SlingJakartaHttpServletRequest;
import org.mockito.Mockito;
+@SuppressWarnings("deprecation")
public class JakartaMediaRangeListTest extends TestCase {
protected JakartaMediaRangeList rangeList;
@@ -158,6 +159,36 @@ public class JakartaMediaRangeListTest extends TestCase {
assertFalse("Contained media type from overridden Accept header",
rangeList.contains("text/plain"));
}
+ public void testFromRequestIgnoresHttpEquivParam() {
+ SlingJakartaHttpServletRequest req =
Mockito.mock(SlingJakartaHttpServletRequest.class);
+ Mockito.when(req.getHeader(JakartaMediaRangeList.HEADER_ACCEPT))
+ .thenReturn("text/plain;q=0.8, application/json");
+
Mockito.when(req.getParameter(JakartaMediaRangeList.PARAM_ACCEPT)).thenReturn("text/html");
+
+ JakartaMediaRangeList rangeList =
JakartaMediaRangeList.fromRequest(req);
+
+ assertEquals("text/plain", rangeList.prefer("text/plain"));
+ assertTrue(rangeList.contains("application/json"));
+ assertFalse(rangeList.contains("text/html"));
+ assertEquals("application/json", rangeList.prefer("text/plain",
"application/json"));
+ Mockito.verify(req, Mockito.never()).getParameter(Mockito.anyString());
+ }
+
+ public void testFromRequestWithoutAcceptHeader() {
+ for (String header : new String[] {null, "", " "}) {
+ SlingJakartaHttpServletRequest req =
Mockito.mock(SlingJakartaHttpServletRequest.class);
+
Mockito.when(req.getHeader(JakartaMediaRangeList.HEADER_ACCEPT)).thenReturn(header);
+
Mockito.when(req.getParameter(JakartaMediaRangeList.PARAM_ACCEPT)).thenReturn("text/html");
+
+ JakartaMediaRangeList rangeList =
JakartaMediaRangeList.fromRequest(req);
+
+ assertEquals(1, rangeList.size());
+ assertTrue(rangeList.contains("text/plain"));
+ assertTrue(rangeList.contains("application/json"));
+ Mockito.verify(req,
Mockito.never()).getParameter(Mockito.anyString());
+ }
+ }
+
public void testInvalidJdkAcceptHeader() {
// This header is sent by Java client which make use of URLConnection
on Oracle JDK
// See acceptHeader at