This is an automated email from the ASF dual-hosted git repository.
jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git
The following commit(s) were added to refs/heads/master by this push:
new 2cb8df3050 Moving schema annotations into juneau-common
2cb8df3050 is described below
commit 2cb8df3050149458447fa475081bfd33409b232b
Author: James Bognar <[email protected]>
AuthorDate: Mon Apr 13 15:10:24 2026 -0400
Moving schema annotations into juneau-common
---
.../juneau/commons/http/BasicNameValuePair.java | 64 +++++++
.../apache/juneau/commons/http/HeaderElement.java | 60 +++++++
.../juneau/commons/http/HeaderValueParser.java | 161 +++++++++++++++++
.../apache/juneau/commons/http/NameValuePair.java | 40 +++++
.../apache/juneau/commons/http/package-info.java | 20 +++
.../apache/juneau/commons/utils/StringUtils.java | 18 +-
juneau-core/juneau-marshall/pom.xml | 5 -
.../main/java/org/apache/juneau/MediaRange.java | 3 +-
.../main/java/org/apache/juneau/MediaRanges.java | 5 +-
.../src/main/java/org/apache/juneau/MediaType.java | 7 +-
.../main/java/org/apache/juneau/StringRange.java | 7 +-
.../main/java/org/apache/juneau/StringRanges.java | 5 +-
.../java/org/apache/juneau/httppart/HttpPart.java | 2 +-
.../java/org/apache/juneau/marshaller/Json5.java | 2 +-
.../juneau/http/header/BasicMediaTypeHeader.java | 2 +-
.../juneau/ng/http/header/HttpMediaTypeHeader.java | 2 +-
.../java/org/apache/juneau/MediaRange_Test.java | 21 +--
.../juneau/commons/http/CommonsHttp_Test.java | 190 +++++++++++++++++++++
18 files changed, 568 insertions(+), 46 deletions(-)
diff --git
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/BasicNameValuePair.java
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/BasicNameValuePair.java
new file mode 100644
index 0000000000..1bed25c995
--- /dev/null
+++
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/BasicNameValuePair.java
@@ -0,0 +1,64 @@
+/*
+ * 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.juneau.commons.http;
+
+import static org.apache.juneau.commons.utils.Utils.*;
+
+/**
+ * A simple immutable implementation of {@link NameValuePair}.
+ */
+public class BasicNameValuePair implements NameValuePair {
+
+ private final String name;
+ private final String value;
+
+ /**
+ * Constructor.
+ *
+ * @param name The name.
+ * @param value The value, may be <jk>null</jk>.
+ */
+ public BasicNameValuePair(String name, String value) {
+ this.name = name;
+ this.value = value;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public String getValue() {
+ return value;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return (o instanceof BasicNameValuePair o2) && eq(name,
o2.name) && eq(value, o2.value);
+ }
+
+ @Override
+ public int hashCode() {
+ return h(name, value);
+ }
+
+ @Override
+ public String toString() {
+ return name + "=" + value;
+ }
+}
diff --git
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/HeaderElement.java
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/HeaderElement.java
new file mode 100644
index 0000000000..9046dab64e
--- /dev/null
+++
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/HeaderElement.java
@@ -0,0 +1,60 @@
+/*
+ * 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.juneau.commons.http;
+
+/**
+ * Represents a parsed element from an HTTP header value.
+ *
+ * <p>
+ * An element consists of a name and zero or more parameters, as defined by
RFC 2616.
+ * For example, in the header value <js>"text/html;charset=UTF-8;q=0.9"</js>,
the element
+ * name is <js>"text/html"</js> and the parameters are
<js>"charset=UTF-8"</js> and <js>"q=0.9"</js>.
+ */
+public class HeaderElement {
+
+ private final String name;
+ private final NameValuePair[] parameters;
+
+ /**
+ * Constructor.
+ *
+ * @param name The element name.
+ * @param parameters The element parameters.
+ */
+ public HeaderElement(String name, NameValuePair... parameters) {
+ this.name = name;
+ this.parameters = parameters;
+ }
+
+ /**
+ * Returns the element name.
+ *
+ * @return The element name, never <jk>null</jk>.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the element parameters.
+ *
+ * @return The parameters array, never <jk>null</jk>.
+ */
+ public NameValuePair[] getParameters() {
+ return parameters;
+ }
+}
diff --git
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/HeaderValueParser.java
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/HeaderValueParser.java
new file mode 100644
index 0000000000..6413880785
--- /dev/null
+++
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/HeaderValueParser.java
@@ -0,0 +1,161 @@
+/*
+ * 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.juneau.commons.http;
+
+import java.util.*;
+
+/**
+ * Lightweight parser for HTTP header values as defined by RFC 2616.
+ *
+ * <p>
+ * Parses comma-delimited header values into {@link HeaderElement} objects,
where each element
+ * has a name and optional semicolon-delimited parameters.
+ *
+ * <p>
+ * For example, the header value <js>"text/html;charset=UTF-8;q=0.9,
text/json"</js> is parsed into two
+ * elements: <js>"text/html"</js> with parameters <js>"charset=UTF-8"</js> and
<js>"q=0.9"</js>,
+ * and <js>"text/json"</js> with no parameters.
+ */
+public final class HeaderValueParser {
+
+ /**
+ * Parses an HTTP header value into an array of {@link HeaderElement}
objects.
+ *
+ * <p>
+ * Elements are separated by commas. Each element may have parameters
separated by semicolons.
+ * Quoted strings are respected (commas and semicolons inside quotes
are not treated as delimiters).
+ *
+ * @param value The header value to parse. May be <jk>null</jk> or
empty.
+ * @return An array of parsed elements, never <jk>null</jk>.
+ */
+ @SuppressWarnings({
+ "java:S3776" // Cognitive complexity acceptable for parser logic
+ })
+ public static HeaderElement[] parseElements(String value) {
+ if (value == null || value.isEmpty())
+ return new HeaderElement[0];
+
+ var elements = new ArrayList<HeaderElement>();
+ var len = value.length();
+ var pos = 0;
+
+ while (pos < len) {
+ pos = skipWhitespace(value, pos);
+ if (pos >= len)
+ break;
+
+ var name = parseName(value, pos);
+ pos += name.length();
+ name = name.trim();
+
+ var params = new ArrayList<NameValuePair>();
+
+ while (pos < len && value.charAt(pos) == ';') {
+ pos++;
+ pos = skipWhitespace(value, pos);
+
+ var paramName = parseToken(value, pos, '=',
';', ',');
+ pos += paramName.length();
+ paramName = paramName.trim();
+
+ String paramValue = null;
+ if (pos < len && value.charAt(pos) == '=') {
+ pos++;
+ pos = skipWhitespace(value, pos);
+ if (pos < len && value.charAt(pos) ==
'"') {
+ var q =
parseQuotedString(value, pos);
+ paramValue = q.text();
+ pos = q.nextPos();
+ } else {
+ paramValue = parseToken(value,
pos, ';', ',');
+ pos += paramValue.length();
+ paramValue = paramValue.trim();
+ }
+ }
+
+ if (!paramName.isEmpty())
+ params.add(new
BasicNameValuePair(paramName, paramValue));
+ }
+
+ if (!name.isEmpty())
+ elements.add(new HeaderElement(name,
params.toArray(NameValuePair.EMPTY_ARRAY)));
+
+ if (pos < len && value.charAt(pos) == ',')
+ pos++;
+ }
+
+ return elements.toArray(new HeaderElement[0]);
+ }
+
+ private static String parseName(String value, int pos) {
+ return parseToken(value, pos, ';', ',');
+ }
+
+ private static String parseToken(String value, int pos, char...
delimiters) {
+ var start = pos;
+ var len = value.length();
+ var inQuotes = false;
+
+ while (pos < len) {
+ var c = value.charAt(pos);
+ if (c == '"')
+ inQuotes = !inQuotes;
+ if (!inQuotes) {
+ for (var d : delimiters)
+ if (c == d)
+ return value.substring(start,
pos);
+ }
+ pos++;
+ }
+ return value.substring(start, pos);
+ }
+
+ /**
+ * Parses a double-quoted header parameter value, honoring {@code \}
escapes.
+ *
+ * @param value Full header string.
+ * @param openQuoteIndex Index of the opening {@code "} character.
+ * @return Parsed text and the index immediately after the closing
{@code "}, or after the last character if
+ * the string is unterminated.
+ */
+ private static QuotedString parseQuotedString(String value, int
openQuoteIndex) {
+ var sb = new StringBuilder();
+ var pos = openQuoteIndex + 1;
+ var len = value.length();
+ while (pos < len) {
+ var c = value.charAt(pos);
+ if (c == '\\' && pos + 1 < len) {
+ sb.append(value.charAt(pos + 1));
+ pos += 2;
+ } else if (c == '"') {
+ return new QuotedString(sb.toString(), pos + 1);
+ } else {
+ sb.append(c);
+ pos++;
+ }
+ }
+ return new QuotedString(sb.toString(), pos);
+ }
+
+ private record QuotedString(String text, int nextPos) {}
+
+ private static int skipWhitespace(String value, int pos) {
+ while (pos < value.length() && (value.charAt(pos) == ' ' ||
value.charAt(pos) == '\t'))
+ pos++;
+ return pos;
+ }
+}
diff --git
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/NameValuePair.java
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/NameValuePair.java
new file mode 100644
index 0000000000..5ddbbcaa3d
--- /dev/null
+++
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/NameValuePair.java
@@ -0,0 +1,40 @@
+/*
+ * 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.juneau.commons.http;
+
+/**
+ * A name/value pair parameter, typically used in HTTP headers and request
parameters.
+ */
+public interface NameValuePair {
+
+ /** Shared empty array for header elements with no parameters. */
+ NameValuePair[] EMPTY_ARRAY = new NameValuePair[0];
+
+ /**
+ * Returns the name.
+ *
+ * @return The name, never <jk>null</jk>.
+ */
+ String getName();
+
+ /**
+ * Returns the value.
+ *
+ * @return The value, may be <jk>null</jk>.
+ */
+ String getValue();
+}
diff --git
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/package-info.java
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/package-info.java
new file mode 100644
index 0000000000..317bfbb754
--- /dev/null
+++
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/http/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+/**
+ * Lightweight HTTP header value types and parsing utilities.
+ */
+package org.apache.juneau.commons.http;
diff --git
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/StringUtils.java
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/StringUtils.java
index 553991049d..3273860de8 100644
---
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/StringUtils.java
+++
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/StringUtils.java
@@ -370,12 +370,12 @@ public class StringUtils {
var b3 = BASE64M2[i3 & 0xff];
var o0 = (b0 << 2) | (b1 >>> 4);
var o1 = ((b1 & 0xf) << 4) | (b2 >>> 2);
- var o2 = ((b2 & 3) << 6) | b3;
- out[iOut++] = (byte)o0;
+ var o2 = ((b2 & 3) << 6) | (b3 & 0xff);
+ out[iOut++] = (byte)(o0 & 0xff);
if (iOut < outLength)
- out[iOut++] = (byte)o1;
+ out[iOut++] = (byte)(o1 & 0xff);
if (iOut < outLength)
- out[iOut++] = (byte)o2;
+ out[iOut++] = (byte)(o2 & 0xff);
}
return out;
}
@@ -6323,6 +6323,8 @@ public class StringUtils {
* @return The tokens, or <jk>null</jk> if the string was null.
*/
public static List<String> split(String s, char c) {
+ if (s == null)
+ return null;
return split(s, c, Integer.MAX_VALUE);
}
@@ -6369,14 +6371,14 @@ public class StringUtils {
* @param s The string to split. Can be <jk>null</jk>.
* @param c The character to split on.
* @param limit The maximum number of tokens to return.
- * @return The tokens, or <jk>null</jk> if the string was null.
+ * @return The tokens, or an empty list if the string was <jk>null</jk>.
*/
public static List<String> split(String s, char c, int limit) {
var escapeChars = getEscapeSet(c);
if (s == null)
- return null;
+ return Collections.emptyList();
if (isEmpty(s))
return Collections.emptyList();
if (s.indexOf(c) == -1)
@@ -6466,8 +6468,10 @@ public class StringUtils {
"java:S1168" // TODO: splita used widely; null propagates
from split(). Consider empty array. See BasicCsvHeader, etc.
})
public static String[] splita(String s, char c, int limit) {
+ if (s == null)
+ return null;
var l = StringUtils.split(s, c, limit);
- return l == null ? null : l.toArray(new String[l.size()]);
+ return l.toArray(new String[l.size()]);
}
/**
diff --git a/juneau-core/juneau-marshall/pom.xml
b/juneau-core/juneau-marshall/pom.xml
index 5b77618e14..1cb26e77cb 100644
--- a/juneau-core/juneau-marshall/pom.xml
+++ b/juneau-core/juneau-marshall/pom.xml
@@ -40,11 +40,6 @@
<artifactId>juneau-commons</artifactId>
<version>${project.version}</version>
</dependency>
- <dependency>
- <groupId>org.apache.httpcomponents</groupId>
- <artifactId>httpcore</artifactId>
- <version>4.4.16</version>
- </dependency>
</dependencies>
<build>
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MediaRange.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MediaRange.java
index 146c16ed40..817104d8d0 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MediaRange.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MediaRange.java
@@ -22,8 +22,7 @@ import static org.apache.juneau.commons.utils.Utils.*;
import java.util.*;
import java.util.function.*;
-import org.apache.http.*;
-import org.apache.http.message.*;
+import org.apache.juneau.commons.http.*;
/**
* Describes a single type used in content negotiation between an HTTP client
and server, as described in
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MediaRanges.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MediaRanges.java
index b8fe79065f..b892c213c5 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MediaRanges.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MediaRanges.java
@@ -23,9 +23,8 @@ import static org.apache.juneau.commons.utils.Utils.*;
import java.util.*;
import java.util.function.*;
-import org.apache.http.*;
-import org.apache.http.message.*;
import org.apache.juneau.annotation.*;
+import org.apache.juneau.commons.http.*;
import org.apache.juneau.commons.collections.*;
/**
@@ -97,7 +96,7 @@ public class MediaRanges {
}
private static HeaderElement[] parse(String value) {
- return
BasicHeaderValueParser.parseElements(emptyIfNull(trim(value)), null);
+ return
HeaderValueParser.parseElements(emptyIfNull(trim(value)));
}
private final MediaRange[] ranges;
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MediaType.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MediaType.java
index df705011a6..f0d3911610 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MediaType.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/MediaType.java
@@ -23,9 +23,8 @@ import static org.apache.juneau.commons.utils.Utils.*;
import java.util.*;
import java.util.function.*;
-import org.apache.http.*;
-import org.apache.http.message.*;
import org.apache.juneau.annotation.*;
+import org.apache.juneau.commons.http.*;
import org.apache.juneau.commons.collections.*;
import org.apache.juneau.commons.utils.*;
import org.apache.juneau.json.*;
@@ -144,8 +143,8 @@ public class MediaType implements Comparable<MediaType> {
}
private static HeaderElement parse(String value) {
- HeaderElement[] elements =
BasicHeaderValueParser.parseElements(emptyIfNull(trim(value)), null);
- return (elements.length > 0 ? elements[0] : new
BasicHeaderElement("", ""));
+ HeaderElement[] elements =
HeaderValueParser.parseElements(emptyIfNull(trim(value)));
+ return (elements.length > 0 ? elements[0] : new
HeaderElement("", NameValuePair.EMPTY_ARRAY));
}
private final String string; // The entire
unparsed value.
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/StringRange.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/StringRange.java
index acbee76ae2..e16d521920 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/StringRange.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/StringRange.java
@@ -23,9 +23,8 @@ import static org.apache.juneau.commons.utils.Utils.*;
import java.util.*;
import java.util.function.*;
-import org.apache.http.*;
-import org.apache.http.message.*;
import org.apache.juneau.annotation.*;
+import org.apache.juneau.commons.http.*;
/**
* Represents a single value in a comma-delimited header value that optionally
contains a quality metric for
@@ -48,8 +47,8 @@ import org.apache.juneau.annotation.*;
public class StringRange {
private static HeaderElement parse(String value) {
- HeaderElement[] elements =
BasicHeaderValueParser.parseElements(emptyIfNull(trim(value)), null);
- return (elements.length > 0 ? elements[0] : new
BasicHeaderElement("*", ""));
+ HeaderElement[] elements =
HeaderValueParser.parseElements(emptyIfNull(trim(value)));
+ return (elements.length > 0 ? elements[0] : new
HeaderElement("*", NameValuePair.EMPTY_ARRAY));
}
private final NameValuePair[] extensions;
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/StringRanges.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/StringRanges.java
index 6554efcf9a..4abb2cf087 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/StringRanges.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/StringRanges.java
@@ -23,9 +23,8 @@ import static org.apache.juneau.commons.utils.Utils.*;
import java.util.*;
import java.util.function.*;
-import org.apache.http.*;
-import org.apache.http.message.*;
import org.apache.juneau.annotation.*;
+import org.apache.juneau.commons.http.*;
import org.apache.juneau.commons.collections.*;
/**
@@ -109,7 +108,7 @@ public class StringRanges {
}
private static HeaderElement[] parse(String value) {
- return value == null ? null :
BasicHeaderValueParser.parseElements(emptyIfNull(trim(value)), null);
+ return value == null ? null :
HeaderValueParser.parseElements(emptyIfNull(trim(value)));
}
private final StringRange[] value;
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPart.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPart.java
index 3cfbb0cf4f..e02f7bbaa3 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPart.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPart.java
@@ -19,7 +19,7 @@ package org.apache.juneau.httppart;
import static org.apache.juneau.commons.utils.ThrowableUtils.*;
import static org.apache.juneau.commons.utils.Utils.*;
-import org.apache.http.*;
+import org.apache.juneau.commons.http.*;
/**
* Represents an instance of an HTTP part.
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshaller/Json5.java
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshaller/Json5.java
index 219704a57f..552d7c502d 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshaller/Json5.java
+++
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/marshaller/Json5.java
@@ -20,9 +20,9 @@ import java.io.*;
import java.lang.reflect.*;
import java.nio.charset.Charset;
-import org.apache.http.*;
import org.apache.juneau.*;
import org.apache.juneau.json5.*;
+import org.apache.juneau.parser.*;
import org.apache.juneau.serializer.*;
/**
diff --git
a/juneau-rest/juneau-rest-common/src/main/java/org/apache/juneau/http/header/BasicMediaTypeHeader.java
b/juneau-rest/juneau-rest-common/src/main/java/org/apache/juneau/http/header/BasicMediaTypeHeader.java
index 0b5ececa0b..aaeda32a4c 100644
---
a/juneau-rest/juneau-rest-common/src/main/java/org/apache/juneau/http/header/BasicMediaTypeHeader.java
+++
b/juneau-rest/juneau-rest-common/src/main/java/org/apache/juneau/http/header/BasicMediaTypeHeader.java
@@ -21,8 +21,8 @@ import static org.apache.juneau.commons.utils.Utils.*;
import java.util.*;
import java.util.function.*;
-import org.apache.http.*;
import org.apache.juneau.*;
+import org.apache.juneau.commons.http.NameValuePair;
import org.apache.juneau.json.*;
import org.apache.juneau.json5.Json5Serializer;
diff --git
a/juneau-rest/juneau-rest-common/src/main/java/org/apache/juneau/ng/http/header/HttpMediaTypeHeader.java
b/juneau-rest/juneau-rest-common/src/main/java/org/apache/juneau/ng/http/header/HttpMediaTypeHeader.java
index d6675abdb9..4aed3d0f64 100644
---
a/juneau-rest/juneau-rest-common/src/main/java/org/apache/juneau/ng/http/header/HttpMediaTypeHeader.java
+++
b/juneau-rest/juneau-rest-common/src/main/java/org/apache/juneau/ng/http/header/HttpMediaTypeHeader.java
@@ -22,8 +22,8 @@ import static org.apache.juneau.commons.utils.Utils.*;
import java.util.*;
import java.util.function.*;
-import org.apache.http.*;
import org.apache.juneau.*;
+import org.apache.juneau.commons.http.NameValuePair;
/**
* Base type for headers whose value is a single {@link MediaType} (e.g.
{@code Content-Type}).
diff --git a/juneau-utest/src/test/java/org/apache/juneau/MediaRange_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/MediaRange_Test.java
index 0d1463f746..ea59d08e94 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/MediaRange_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/MediaRange_Test.java
@@ -21,8 +21,7 @@ import static org.junit.jupiter.api.Assertions.*;
import java.util.*;
-import org.apache.http.*;
-import org.apache.http.message.*;
+import org.apache.juneau.commons.http.*;
import org.junit.jupiter.api.*;
/**
@@ -31,8 +30,7 @@ import org.junit.jupiter.api.*;
class MediaRange_Test extends TestBase {
@Test void a01_basic() {
- // Test basic MediaRange creation
- HeaderElement element =
BasicHeaderValueParser.parseHeaderElement("text/html;charset=UTF-8;q=0.9",
null);
+ var element =
HeaderValueParser.parseElements("text/html;charset=UTF-8;q=0.9")[0];
var x = new MediaRange(element);
@@ -42,8 +40,7 @@ class MediaRange_Test extends TestBase {
}
@Test void a02_forEachParameter_fluentChaining() {
- // Test that forEachParameter returns MediaRange for fluent
chaining
- HeaderElement element =
BasicHeaderValueParser.parseHeaderElement("text/html;charset=UTF-8;level=1",
null);
+ var element =
HeaderValueParser.parseElements("text/html;charset=UTF-8;level=1")[0];
var x = new MediaRange(element);
@@ -61,8 +58,7 @@ class MediaRange_Test extends TestBase {
}
@Test void a03_forEachParameter_withConsumer() {
- // Test that forEachParameter properly iterates parameters
- HeaderElement element =
BasicHeaderValueParser.parseHeaderElement("application/json;charset=UTF-8;version=2",
null);
+ var element =
HeaderValueParser.parseElements("application/json;charset=UTF-8;version=2")[0];
var x = new MediaRange(element);
@@ -75,8 +71,7 @@ class MediaRange_Test extends TestBase {
}
@Test void a04_forEachParameter_emptyParameters() {
- // Test with no parameters
- HeaderElement element =
BasicHeaderValueParser.parseHeaderElement("text/plain", null);
+ var element = HeaderValueParser.parseElements("text/plain")[0];
var x = new MediaRange(element);
@@ -89,8 +84,7 @@ class MediaRange_Test extends TestBase {
}
@Test void a05_fluentChaining_combined() {
- // Test chaining forEachParameter multiple times
- HeaderElement element =
BasicHeaderValueParser.parseHeaderElement("text/html;charset=UTF-8;level=1",
null);
+ var element =
HeaderValueParser.parseElements("text/html;charset=UTF-8;level=1")[0];
var x = new MediaRange(element);
@@ -108,8 +102,7 @@ class MediaRange_Test extends TestBase {
}
@Test void a06_forEachParameter_withExtensions() {
- // Test that both forEachParameter and forEachExtension APIs
work
- HeaderElement element =
BasicHeaderValueParser.parseHeaderElement("text/html;q=0.9", null);
+ var element =
HeaderValueParser.parseElements("text/html;q=0.9")[0];
var x = new MediaRange(element);
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/commons/http/CommonsHttp_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/commons/http/CommonsHttp_Test.java
new file mode 100644
index 0000000000..ed8e04c1b2
--- /dev/null
+++
b/juneau-utest/src/test/java/org/apache/juneau/commons/http/CommonsHttp_Test.java
@@ -0,0 +1,190 @@
+/*
+ * 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.juneau.commons.http;
+
+import static org.apache.juneau.junit.bct.BctAssertions.*;
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.apache.juneau.*;
+import org.junit.jupiter.api.*;
+
+/**
+ * Unit tests for {@link HeaderValueParser}, {@link HeaderElement}, {@link
BasicNameValuePair},
+ * and {@link NameValuePair#EMPTY_ARRAY}.
+ */
+class CommonsHttp_Test extends TestBase {
+
+ @Test
+ void a01_parseElements_nullOrEmpty() {
+ assertEquals(0, HeaderValueParser.parseElements(null).length);
+ assertEquals(0, HeaderValueParser.parseElements("").length);
+ }
+
+ @Test
+ void a02_parseElements_whitespaceOnly() {
+ var a = HeaderValueParser.parseElements(" \t ");
+ assertEquals(0, a.length);
+ }
+
+ @Test
+ void a03_parseElements_singleTypeNoParams() {
+ var a = HeaderValueParser.parseElements("text/html");
+ assertEquals(1, a.length);
+ assertBean(a[0], "name", "text/html");
+ assertEquals(0, a[0].getParameters().length);
+ }
+
+ @Test
+ void a04_parseElements_typeWithParameters() {
+ var a =
HeaderValueParser.parseElements("application/json;charset=UTF-8;version=2");
+ assertEquals(1, a.length);
+ assertEquals("application/json", a[0].getName());
+ assertEquals(2, a[0].getParameters().length);
+ assertEquals("charset", a[0].getParameters()[0].getName());
+ assertEquals("UTF-8", a[0].getParameters()[0].getValue());
+ assertEquals("version", a[0].getParameters()[1].getName());
+ assertEquals("2", a[0].getParameters()[1].getValue());
+ }
+
+ @Test
+ void a05_parseElements_twoElementsCommaSeparated() {
+ var a = HeaderValueParser.parseElements("text/html,
application/json");
+ assertEquals(2, a.length);
+ assertEquals("text/html", a[0].getName());
+ assertEquals("application/json", a[1].getName());
+ }
+
+ @Test
+ void a06_parseElements_quotedParameterValue() {
+ var a = HeaderValueParser.parseElements("foo;bar=\"a,b;c\"");
+ assertEquals(1, a.length);
+ assertEquals("foo", a[0].getName());
+ assertEquals(1, a[0].getParameters().length);
+ assertEquals("bar", a[0].getParameters()[0].getName());
+ assertEquals("a,b;c", a[0].getParameters()[0].getValue());
+ }
+
+ @Test
+ void a07_parseElements_escapedBackslashInQuotedString() {
+ var a = HeaderValueParser.parseElements("p;q=\"a\\\\b\"");
+ assertEquals(1, a.length);
+ assertEquals("p", a[0].getName());
+ assertEquals(1, a[0].getParameters().length);
+ assertEquals("q", a[0].getParameters()[0].getName());
+ assertEquals("a\\b", a[0].getParameters()[0].getValue());
+ }
+
+ @Test
+ void a08_parseElements_mediaRangeStyle() {
+ var a =
HeaderValueParser.parseElements("text/html;charset=UTF-8;q=0.9");
+ assertEquals(1, a.length);
+ assertEquals("text/html", a[0].getName());
+ assertEquals(2, a[0].getParameters().length);
+ assertEquals("q", a[0].getParameters()[1].getName());
+ assertEquals("0.9", a[0].getParameters()[1].getValue());
+ }
+
+ @Test
+ void a09_parseElements_paramWithoutValue() {
+ var a = HeaderValueParser.parseElements("multipart/form-data;
boundary");
+ assertEquals(1, a.length);
+ assertEquals(1, a[0].getParameters().length);
+ assertEquals("boundary", a[0].getParameters()[0].getName());
+ assertNull(a[0].getParameters()[0].getValue());
+ }
+
+ @Test
+ void a10_parseElements_emptyQuotedParameterValue() {
+ var a = HeaderValueParser.parseElements("t;a=\"\"");
+ assertEquals(1, a.length);
+ assertEquals("", a[0].getParameters()[0].getValue());
+ }
+
+ @Test
+ void a11_parseElements_leadingTrailingWhitespace() {
+ var a = HeaderValueParser.parseElements(" text/plain ;
charset=utf-8 ");
+ assertEquals(1, a.length);
+ assertEquals("text/plain", a[0].getName());
+ assertEquals("utf-8", a[0].getParameters()[0].getValue());
+ }
+
+ @Test
+ void a12_parseElements_unterminatedQuotedValue() {
+ var a = HeaderValueParser.parseElements("x;y=\"no-close");
+ assertEquals(1, a.length);
+ assertEquals("no-close", a[0].getParameters()[0].getValue());
+ }
+
+ @Test
+ void b01_basicNameValuePair_gettersAndToString() {
+ var a = new BasicNameValuePair("n", "v");
+ assertEquals("n", a.getName());
+ assertEquals("v", a.getValue());
+ assertEquals("n=v", a.toString());
+ }
+
+ @Test
+ void b02_basicNameValuePair_nullValue() {
+ var a = new BasicNameValuePair("n", null);
+ assertNull(a.getValue());
+ assertEquals("n=null", a.toString());
+ }
+
+ @Test
+ void b03_basicNameValuePair_equalsAndHashCode() {
+ var a = new BasicNameValuePair("x", "1");
+ var b = new BasicNameValuePair("x", "1");
+ var c = new BasicNameValuePair("x", "2");
+ assertEquals(a, b);
+ assertEquals(a.hashCode(), b.hashCode());
+ assertNotEquals(a, c);
+ }
+
+ @Test
+ void b04_basicNameValuePair_equalsWithNullFields() {
+ var a = new BasicNameValuePair(null, null);
+ var b = new BasicNameValuePair(null, null);
+ assertEquals(a, b);
+ assertEquals(a.hashCode(), b.hashCode());
+ }
+
+ @Test
+ void b05_basicNameValuePair_notEqualToOtherType() {
+ assertNotEquals(new BasicNameValuePair("a", "b"), "a=b");
+ }
+
+ @Test
+ void c01_headerElement_noParameters() {
+ var a = new HeaderElement("text/plain",
NameValuePair.EMPTY_ARRAY);
+ assertEquals("text/plain", a.getName());
+ assertEquals(0, a.getParameters().length);
+ }
+
+ @Test
+ void c02_headerElement_withParameters() {
+ var a = new HeaderElement("t", new BasicNameValuePair("a",
"1"), new BasicNameValuePair("b", "2"));
+ assertEquals("t", a.getName());
+ assertEquals(2, a.getParameters().length);
+ assertBean(a.getParameters()[0], "name,value", "a,1");
+ }
+
+ @Test
+ void d01_nameValuePair_emptyArray() {
+ assertEquals(0, NameValuePair.EMPTY_ARRAY.length);
+ assertSame(NameValuePair.EMPTY_ARRAY,
NameValuePair.EMPTY_ARRAY);
+ }
+}