Skip to content

Commit aa8f207

Browse files
author
James Bognar
committed
Add support for setting serializer/parser session properties as HTTP headers and query parameters
1 parent 7f54e81 commit aa8f207

42 files changed

Lines changed: 2385 additions & 15 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/AnnotationInfo.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,27 @@ private static int findRank(Object a) {
127127
this.toString = memoize(this::findToString);
128128
}
129129

130+
/**
131+
* Returns the annotatable object (class, method, field, etc.) where this annotation was found.
132+
*
133+
* @return The annotatable object where this annotation was found.
134+
*/
135+
public Annotatable getAnnotatable() {
136+
return annotatable;
137+
}
138+
139+
/**
140+
* Returns the annotatable object cast to the specified type.
141+
*
142+
* @param <A> The annotatable type.
143+
* @param type The class to cast to.
144+
* @return The annotatable element cast to the specified type.
145+
* @throws ClassCastException If the annotatable element is not of the specified type.
146+
*/
147+
public <A extends Annotatable> A getAnnotatable(Class<A> type) {
148+
return type.cast(annotatable);
149+
}
150+
130151
/**
131152
* Returns the annotation type of this annotation.
132153
*

juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/CollectionUtils.java

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@
129129
public class CollectionUtils {
130130

131131
// Argument name constants for assertArgNotNull
132+
private static final String ARG_comparator = "comparator";
133+
private static final String ARG_input = "input";
132134
private static final String ARG_value = "value";
133135
private static final String ARG_array = "array";
134136
private static final String ARG_arrays = "arrays";
@@ -869,6 +871,26 @@ public static int[] ints(int...value) {
869871
return value;
870872
}
871873

874+
/**
875+
* Returns <jk>true</jk> if the specified collection is null or empty.
876+
*
877+
* @param c The collection to check.
878+
* @return <jk>true</jk> if the specified collection is null or empty.
879+
*/
880+
public static boolean isEmpty(Collection<?> c) {
881+
return c == null || c.isEmpty();
882+
}
883+
884+
/**
885+
* Returns <jk>true</jk> if the specified map is null or empty.
886+
*
887+
* @param m The map to check.
888+
* @return <jk>true</jk> if the specified map is null or empty.
889+
*/
890+
public static boolean isEmpty(Map<?,?> m) {
891+
return m == null || m.isEmpty();
892+
}
893+
872894
/**
873895
* Returns <jk>true</jk> if the specified array is null or has a length of zero.
874896
*
@@ -2015,6 +2037,64 @@ public static <T> Stream<T> rstream(List<T> value) {
20152037
return IntStream.range(0, value.size()).mapToObj(i -> value.get(value.size() - 1 - i));
20162038
}
20172039

2040+
/**
2041+
* Removes negation tokens from a list.
2042+
*
2043+
* <p>
2044+
* A negation token is a string starting with <js>'-'</js> followed by at least one character.
2045+
* When encountered, it removes the first prior occurrence of the corresponding positive token.
2046+
*
2047+
* <h5 class='section'>Example:</h5>
2048+
* <p class='bjava'>
2049+
* List&lt;String&gt; <jv>result</jv> = <jsm>removeNegations</jsm>(list(<js>"a"</js>, <js>"b"</js>, <js>"-a"</js>, <js>"c"</js>));
2050+
* <jc>// Produces: ["b", "c"]</jc>
2051+
* </p>
2052+
*
2053+
* @param input The input list. Cannot be <jk>null</jk>.
2054+
* @return The list with negation tokens applied, or the original list if no negation tokens were present.
2055+
*/
2056+
public static List<String> removeNegations(List<String> input) {
2057+
assertArgNotNull(ARG_input, input);
2058+
var hasNegation = false;
2059+
for (var token : input) {
2060+
if (token != null && token.length() > 1 && token.charAt(0) == '-') {
2061+
hasNegation = true;
2062+
break;
2063+
}
2064+
}
2065+
if (!hasNegation)
2066+
return input;
2067+
var out = new ArrayList<String>(input.size());
2068+
for (var token : input) {
2069+
if (token != null && token.length() > 1 && token.charAt(0) == '-')
2070+
out.remove(token.substring(1));
2071+
else
2072+
out.add(token);
2073+
}
2074+
return out;
2075+
}
2076+
2077+
/**
2078+
* Creates a {@link TreeSet} with a custom comparator from a collection of elements.
2079+
*
2080+
* <p>
2081+
* Null elements in the collection are silently skipped.
2082+
*
2083+
* @param <E> The element type.
2084+
* @param comparator The comparator to use for ordering. Cannot be <jk>null</jk>.
2085+
* @param elements The initial elements. Can be <jk>null</jk> (treated as empty).
2086+
* @return A new {@link TreeSet} containing all non-null elements from the collection.
2087+
*/
2088+
public static <E> SortedSet<E> treeSet(Comparator<? super E> comparator, Collection<? extends E> elements) {
2089+
assertArgNotNull(ARG_comparator, comparator);
2090+
var s = new TreeSet<E>(comparator);
2091+
if (elements != null)
2092+
for (var e : elements)
2093+
if (e != null)
2094+
s.add(e);
2095+
return s;
2096+
}
2097+
20182098
/**
20192099
* Shortcut for creating a modifiable set out of an array of values.
20202100
*

juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/StringUtils.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ public class StringUtils {
7777
/** Zero-length string constant. */
7878
public static final String EMPTY = "";
7979

80+
/** Zero-length string array constant. */
81+
public static final String[] EMPTY_STRING_ARRAY = new String[0];
82+
8083
/** Characters allowed at the beginning of a numeric literal. */
8184
public static final AsciiSet FIRST_NUMBER_CHARS = AsciiSet.of("+-.#0123456789");
8285

juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import static org.apache.juneau.http.HttpMethod.*;
3030
import static org.apache.juneau.http.HttpParts.*;
3131
import static org.apache.juneau.httppart.HttpPartType.*;
32+
import static org.apache.juneau.rest.RestSharedConstants.*;
3233
import static org.apache.juneau.rest.client.RestOperation.*;
3334

3435
import java.io.*;
@@ -2552,6 +2553,72 @@ public Builder headersDefault(Header...parts) {
25522553
return this;
25532554
}
25542555

2556+
/**
2557+
* Sets a default request header with serializer session options (JSON5 map) for all requests.
2558+
*
2559+
* <p>
2560+
* This is a shortcut for <c>headersDefault(basicHeader({@link org.apache.juneau.rest.RestSharedConstants#HEADER_JuneauSerializerOptions}, <jv>json5</jv>))</c>.
2561+
*
2562+
* @param json5
2563+
* Serializer session options in JSON5 form.
2564+
* <br>Can be <jk>null</jk> (default is not set by this method).
2565+
* @return This object.
2566+
*/
2567+
public Builder serializerSessionOptionsHeader(String json5) {
2568+
if (json5 != null)
2569+
headersDefault(basicHeader(HEADER_JuneauSerializerOptions, json5));
2570+
return this;
2571+
}
2572+
2573+
/**
2574+
* Sets a default request header with parser session options (JSON5 map) for all requests.
2575+
*
2576+
* <p>
2577+
* This is a shortcut for <c>headersDefault(basicHeader({@link org.apache.juneau.rest.RestSharedConstants#HEADER_JuneauParserOptions}, <jv>json5</jv>))</c>.
2578+
*
2579+
* @param json5
2580+
* Parser session options in JSON5 form.
2581+
* <br>Can be <jk>null</jk> (default is not set by this method).
2582+
* @return This object.
2583+
*/
2584+
public Builder parserSessionOptionsHeader(String json5) {
2585+
if (json5 != null)
2586+
headersDefault(basicHeader(HEADER_JuneauParserOptions, json5));
2587+
return this;
2588+
}
2589+
2590+
/**
2591+
* Convenience for {@link #serializerSessionOptionsHeader(String)} using a map serialized with JSON5.
2592+
*
2593+
* @param properties
2594+
* Property names and values for serializer session options.
2595+
* <br>Can be <jk>null</jk> (treated as an empty map).
2596+
* @return This object.
2597+
*/
2598+
public Builder serializerSessionOptionsHeader(Map<String,?> properties) {
2599+
try {
2600+
return serializerSessionOptionsHeader(isEmpty(properties) ? null : Json5.of(properties));
2601+
} catch (SerializeException e) {
2602+
throw rex(e, "Could not serialize serializer session options header");
2603+
}
2604+
}
2605+
2606+
/**
2607+
* Convenience for {@link #parserSessionOptionsHeader(String)} using a map serialized with JSON5.
2608+
*
2609+
* @param properties
2610+
* Property names and values for parser session options.
2611+
* <br>Can be <jk>null</jk> (treated as an empty map).
2612+
* @return This object.
2613+
*/
2614+
public Builder parserSessionOptionsHeader(Map<String,?> properties) {
2615+
try {
2616+
return parserSessionOptionsHeader(isEmpty(properties) ? null : Json5.of(properties));
2617+
} catch (SerializeException e) {
2618+
throw rex(e, "Could not serialize parser session options header");
2619+
}
2620+
}
2621+
25552622
/**
25562623
* Convenience method for specifying HTML as the marshalling transmission media type.
25572624
*
@@ -4639,6 +4706,72 @@ public Builder queryDataDefault(NameValuePair...parts) {
46394706
return this;
46404707
}
46414708

4709+
/**
4710+
* Sets a default query parameter with serializer session options (UON map) for all requests.
4711+
*
4712+
* <p>
4713+
* This is a shortcut for <c>queryDataDefault(stringPart({@link org.apache.juneau.rest.RestSharedConstants#QUERY_juneauSerializerOptions}, <jv>uon</jv>))</c>.
4714+
*
4715+
* @param uon
4716+
* Serializer session options in UON form.
4717+
* <br>Can be <jk>null</jk> (default is not set by this method).
4718+
* @return This object.
4719+
*/
4720+
public Builder serializerSessionOptionsQueryDefault(String uon) {
4721+
if (uon != null)
4722+
queryDataDefault(stringPart(QUERY_juneauSerializerOptions, uon));
4723+
return this;
4724+
}
4725+
4726+
/**
4727+
* Sets a default query parameter with parser session options (UON map) for all requests.
4728+
*
4729+
* <p>
4730+
* This is a shortcut for <c>queryDataDefault(stringPart({@link org.apache.juneau.rest.RestSharedConstants#QUERY_juneauParserOptions}, <jv>uon</jv>))</c>.
4731+
*
4732+
* @param uon
4733+
* Parser session options in UON form.
4734+
* <br>Can be <jk>null</jk> (default is not set by this method).
4735+
* @return This object.
4736+
*/
4737+
public Builder parserSessionOptionsQueryDefault(String uon) {
4738+
if (uon != null)
4739+
queryDataDefault(stringPart(QUERY_juneauParserOptions, uon));
4740+
return this;
4741+
}
4742+
4743+
/**
4744+
* Convenience for {@link #serializerSessionOptionsQueryDefault(String)} using {@link org.apache.juneau.marshaller.Uon#of(Object)}.
4745+
*
4746+
* @param properties
4747+
* Property names and values for serializer session options.
4748+
* <br>Can be <jk>null</jk> (treated as an empty map).
4749+
* @return This object.
4750+
*/
4751+
public Builder serializerSessionOptionsQueryDefault(Map<String,?> properties) {
4752+
try {
4753+
return serializerSessionOptionsQueryDefault(isEmpty(properties) ? null : Uon.of(properties));
4754+
} catch (SerializeException e) {
4755+
throw rex(e, "Could not serialize serializer session options query default");
4756+
}
4757+
}
4758+
4759+
/**
4760+
* Convenience for {@link #parserSessionOptionsQueryDefault(String)} using {@link org.apache.juneau.marshaller.Uon#of(Object)}.
4761+
*
4762+
* @param properties
4763+
* Property names and values for parser session options.
4764+
* <br>Can be <jk>null</jk> (treated as an empty map).
4765+
* @return This object.
4766+
*/
4767+
public Builder parserSessionOptionsQueryDefault(Map<String,?> properties) {
4768+
try {
4769+
return parserSessionOptionsQueryDefault(isEmpty(properties) ? null : Uon.of(properties));
4770+
} catch (SerializeException e) {
4771+
throw rex(e, "Could not serialize parser session options query default");
4772+
}
4773+
}
4774+
46424775
/**
46434776
* <i><l>WriterSerializer</l> configuration property:&emsp;</i> Quote character.
46444777
*

0 commit comments

Comments
 (0)