You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2018/05/10 18:45:42 UTC
[juneau] branch master updated: Add support for q-values for
matching against multiple serializers.
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 699c7d6 Add support for q-values for matching against multiple serializers.
699c7d6 is described below
commit 699c7d6dad40129e3e1352827295c17160086e40
Author: JamesBognar <ja...@apache.org>
AuthorDate: Thu May 10 14:45:28 2018 -0400
Add support for q-values for matching against multiple serializers.
---
.../juneau/serializer/SerializerGroupTest.java | 10 ++---
.../java/org/apache/juneau/jena/RdfSerializer.java | 19 ++++-----
.../java/org/apache/juneau/csv/CsvSerializer.java | 2 +-
.../org/apache/juneau/html/HtmlDocSerializer.java | 8 ++--
.../org/apache/juneau/html/HtmlSerializer.java | 8 ++--
.../juneau/html/HtmlStrippedDocSerializer.java | 6 ++-
.../juneau/htmlschema/HtmlSchemaDocSerializer.java | 6 ++-
.../main/java/org/apache/juneau/http/Accept.java | 41 +++++++++++++++++++
.../java/org/apache/juneau/http/MediaType.java | 25 +++++++-----
.../org/apache/juneau/http/MediaTypeRange.java | 38 ++++++++++-------
.../java/org/apache/juneau/jso/JsoSerializer.java | 2 +-
.../org/apache/juneau/json/JsonSerializer.java | 11 ++---
.../juneau/jsonschema/JsonSchemaSerializer.java | 3 +-
.../apache/juneau/msgpack/MsgPackSerializer.java | 2 +-
.../juneau/plaintext/PlainTextSerializer.java | 8 ++--
.../juneau/serializer/OutputStreamSerializer.java | 8 ++--
.../org/apache/juneau/serializer/Serializer.java | 47 ++++++++++++++++------
.../apache/juneau/serializer/SerializerGroup.java | 24 ++++++-----
.../apache/juneau/serializer/WriterSerializer.java | 8 ++--
.../java/org/apache/juneau/uon/UonSerializer.java | 8 ++--
.../juneau/urlencoding/UrlEncodingSerializer.java | 8 ++--
.../java/org/apache/juneau/utils/StringObject.java | 2 +-
.../java/org/apache/juneau/xml/XmlSerializer.java | 8 ++--
.../apache/juneau/yaml/proto/YamlSerializer.java | 8 ++--
juneau-doc/src/main/javadoc/overview.html | 9 +++++
.../juneau/examples/rest/PhotosResource.java | 2 +-
.../juneau/rest/test/AcceptCharsetResource.java | 2 +-
.../juneau/rest/test/CharsetEncodingsResource.java | 2 +-
.../rest/test/DefaultContentTypesResource.java | 2 +-
.../apache/juneau/rest/test/GroupsResource.java | 2 +-
.../juneau/rest/test/InheritanceResource.java | 2 +-
.../juneau/rest/test/NlsPropertyResource.java | 2 +-
.../juneau/rest/test/OnPostCallResource.java | 2 +-
.../juneau/rest/test/SerializersResource.java | 8 ++--
.../apache/juneau/rest/BasicRestInfoProvider.java | 2 +-
.../java/org/apache/juneau/rest/RestContext.java | 2 +-
.../rest/{util => mock}/MockHttpSession.java | 9 ++++-
.../juneau/rest/{util => mock}/MockRest.java | 33 ++++++++++++++-
.../rest/{util => mock}/MockServletRequest.java | 10 ++++-
.../rest/{util => mock}/MockServletResponse.java | 12 ++++--
.../juneau/rest/widget/ContentTypeMenuItem.java | 2 +-
.../juneau/rest/BasicRestInfoProviderTest.java | 2 +-
.../apache/juneau/rest/annotation/BodyTest.java | 2 +-
43 files changed, 287 insertions(+), 130 deletions(-)
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/serializer/SerializerGroupTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/serializer/SerializerGroupTest.java
index 6732e14..a443d6d 100755
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/serializer/SerializerGroupTest.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/serializer/SerializerGroupTest.java
@@ -52,19 +52,19 @@ public class SerializerGroupTest {
public static class SA1 extends JsonSerializer {
public SA1(PropertyStore ps) {
- super(ps, "application/json", "text/foo+*", "text/foo_a+*");
+ super(ps, "application/json", "text/foo+*,text/foo_a+*");
}
}
public static class SA2 extends JsonSerializer {
public SA2(PropertyStore ps) {
- super(ps, "application/json", "text/foo+bar+*", "text/foo+bar_a+*");
+ super(ps, "application/json", "text/foo+bar+*,text/foo+bar_a+*");
}
}
public static class SA3 extends JsonSerializer {
public SA3(PropertyStore ps) {
- super(ps, "application/json", "text/baz+*", "text/baz_a+*");
+ super(ps, "application/json", "text/baz+*,text/baz_a+*");
}
}
@@ -97,7 +97,7 @@ public class SerializerGroupTest {
public static class SB2 extends JsonSerializer {
public SB2(PropertyStore ps) {
- super(ps, "application/json", "text/2", "text/2a");
+ super(ps, "application/json", "text/2,text/2a");
}
}
@@ -109,7 +109,7 @@ public class SerializerGroupTest {
public static class SB4 extends JsonSerializer {
public SB4(PropertyStore ps) {
- super(ps, "application/json", "text/4", "text/4a");
+ super(ps, "application/json", "text/4,text/4a");
}
}
diff --git a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
index 0771783..1b6b349 100644
--- a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
+++ b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
@@ -213,7 +213,7 @@ public class RdfSerializer extends WriterSerializer implements RdfCommon {
ps.builder()
.set(RDF_language, LANG_RDF_XML)
.build(),
- "text/xml+rdf"
+ "text/xml+rdf", "text/xml+rdf,text/xml+rdf+abbrev;q=0.9"
);
}
}
@@ -231,8 +231,7 @@ public class RdfSerializer extends WriterSerializer implements RdfCommon {
ps.builder()
.set(RDF_language, LANG_RDF_XML_ABBREV)
.build(),
- "text/xml+rdf",
- "text/xml+rdf+abbrev"
+ "text/xml+rdf", "text/xml+rdf+abbrev,text/xml+rdf;q=0.9"
);
}
}
@@ -250,7 +249,7 @@ public class RdfSerializer extends WriterSerializer implements RdfCommon {
ps.builder()
.set(RDF_language, LANG_NTRIPLE)
.build(),
- "text/n-triple"
+ "text/n-triple", null
);
}
}
@@ -268,7 +267,7 @@ public class RdfSerializer extends WriterSerializer implements RdfCommon {
ps.builder()
.set(RDF_language, LANG_TURTLE)
.build(),
- "text/turtle"
+ "text/turtle", null
);
}
}
@@ -286,7 +285,7 @@ public class RdfSerializer extends WriterSerializer implements RdfCommon {
ps.builder()
.set(RDF_language, LANG_N3)
.build(),
- "text/n3"
+ "text/n3", null
);
}
}
@@ -328,14 +327,16 @@ public class RdfSerializer extends WriterSerializer implements RdfCommon {
* For example, if this serializer produces <js>"application/json"</js> but should handle media types of
* <js>"application/json"</js> and <js>"text/json"</js>, then the arguments should be:
* <p class='bcode'>
- * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"application/json"</js>, <js>"text/json"</js>);
+ * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"application/json,text/json"</js>);
* </p>
* <br>...or...
* <p class='bcode'>
* <jk>super</jk>(ps, <js>"application/json"</js>, <js>"*​/json"</js>);
* </p>
+ * <p>
+ * The accept value can also contain q-values.
*/
- public RdfSerializer(PropertyStore ps, String produces, String...accept) {
+ public RdfSerializer(PropertyStore ps, String produces, String accept) {
super(ps, produces, accept);
addLiteralTypes = getBooleanProperty(RDF_addLiteralTypes, false);
addRootProperty = getBooleanProperty(RDF_addRootProperty, false);
@@ -363,7 +364,7 @@ public class RdfSerializer extends WriterSerializer implements RdfCommon {
* The property store containing all the settings for this object.
*/
public RdfSerializer(PropertyStore ps) {
- this(ps, "text/xml+rdf");
+ this(ps, "text/xml+rdf", null);
}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvSerializer.java
index 5239dfc..7bf040c 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvSerializer.java
@@ -38,7 +38,7 @@ public final class CsvSerializer extends WriterSerializer {
* @param ps The property store containing all the settings for this object.
*/
public CsvSerializer(PropertyStore ps) {
- super(ps, "text/csv");
+ super(ps, "text/csv", null);
}
@Override /* Context */
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java
index 48abe4d..b5da3e4 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java
@@ -530,7 +530,7 @@ public class HtmlDocSerializer extends HtmlStrippedDocSerializer {
* @param ps The property store containing all the settings for this object.
*/
public HtmlDocSerializer(PropertyStore ps) {
- this(ps, "text/html");
+ this(ps, "text/html", null);
}
/**
@@ -551,14 +551,16 @@ public class HtmlDocSerializer extends HtmlStrippedDocSerializer {
* For example, if this serializer produces <js>"application/json"</js> but should handle media types of
* <js>"application/json"</js> and <js>"text/json"</js>, then the arguments should be:
* <p class='bcode'>
- * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"application/json"</js>, <js>"text/json"</js>);
+ * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"application/json",text/json"</js>);
* </p>
* <br>...or...
* <p class='bcode'>
* <jk>super</jk>(ps, <js>"application/json"</js>, <js>"*​/json"</js>);
* </p>
+ * <p>
+ * The accept value can also contain q-values.
*/
- public HtmlDocSerializer(PropertyStore ps, String produces, String...accept) {
+ public HtmlDocSerializer(PropertyStore ps, String produces, String accept) {
super(ps, produces, accept);
style = getArrayProperty(HTMLDOC_style, String.class);
stylesheet = getArrayProperty(HTMLDOC_stylesheet, String.class);
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializer.java
index a463138..eff57f5 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializer.java
@@ -645,7 +645,7 @@ public class HtmlSerializer extends XmlSerializer {
* The property store containing all the settings for this object.
*/
public HtmlSerializer(PropertyStore ps) {
- this(ps, "text/html");
+ this(ps, "text/html", null);
}
/**
@@ -666,14 +666,16 @@ public class HtmlSerializer extends XmlSerializer {
* For example, if this serializer produces <js>"application/json"</js> but should handle media types of
* <js>"application/json"</js> and <js>"text/json"</js>, then the arguments should be:
* <p class='bcode'>
- * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"application/json"</js>, <js>"text/json"</js>);
+ * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"application/json,text/json"</js>);
* </p>
* <br>...or...
* <p class='bcode'>
* <jk>super</jk>(ps, <js>"application/json"</js>, <js>"*​/json"</js>);
* </p>
+ * <p>
+ * The accept value can also contain q-values.
*/
- public HtmlSerializer(PropertyStore ps, String produces, String...accept) {
+ public HtmlSerializer(PropertyStore ps, String produces, String accept) {
super(ps, produces, accept);
uriAnchorText = getProperty(HTML_uriAnchorText, AnchorText.class, AnchorText.TO_STRING);
lookForLabelParameters = getBooleanProperty(HTML_detectLabelParameters, true);
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlStrippedDocSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlStrippedDocSerializer.java
index 7af5da5..cc68f8a 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlStrippedDocSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlStrippedDocSerializer.java
@@ -59,14 +59,16 @@ public class HtmlStrippedDocSerializer extends HtmlSerializer {
* For example, if this serializer produces <js>"application/json"</js> but should handle media types of
* <js>"application/json"</js> and <js>"text/json"</js>, then the arguments should be:
* <p class='bcode'>
- * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"application/json"</js>, <js>"text/json"</js>);
+ * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"application/json,text/json"</js>);
* </p>
* <br>...or...
* <p class='bcode'>
* <jk>super</jk>(ps, <js>"application/json"</js>, <js>"*​/json"</js>);
* </p>
+ * <p>
+ * The accept value can also contain q-values.
*/
- public HtmlStrippedDocSerializer(PropertyStore ps, String produces, String...accept) {
+ public HtmlStrippedDocSerializer(PropertyStore ps, String produces, String accept) {
super(ps, produces, accept);
}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/htmlschema/HtmlSchemaDocSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/htmlschema/HtmlSchemaDocSerializer.java
index b521d36..3200ec7 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/htmlschema/HtmlSchemaDocSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/htmlschema/HtmlSchemaDocSerializer.java
@@ -66,14 +66,16 @@ public final class HtmlSchemaDocSerializer extends HtmlDocSerializer {
* For example, if this serializer produces <js>"application/json"</js> but should handle media types of
* <js>"application/json"</js> and <js>"text/json"</js>, then the arguments should be:
* <p class='bcode'>
- * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"application/json"</js>, <js>"text/json"</js>);
+ * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"application/json,text/json"</js>);
* </p>
* <br>...or...
* <p class='bcode'>
* <jk>super</jk>(ps, <js>"application/json"</js>, <js>"*​/json"</js>);
* </p>
+ * <p>
+ * The accept value can also contain q-values.
*/
- public HtmlSchemaDocSerializer(PropertyStore ps, String produces, String...accept) {
+ public HtmlSchemaDocSerializer(PropertyStore ps, String produces, String accept) {
super(
ps.builder()
.set(SERIALIZER_detectRecursions, true)
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Accept.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Accept.java
index ca94279..7f87704 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Accept.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Accept.java
@@ -230,6 +230,47 @@ public final class Accept {
}
/**
+ * Same as {@link #findMatch(MediaType[])} but matching against media type ranges.
+ *
+ * <p>
+ * Note that the q-types on both the <code>mediaTypeRanges</code> parameter and this header
+ * are taken into account when trying to find the best match.
+ * <br>When both this header and the matching range have q-values, the q-value for the match is the result of multiplying them.
+ * <br>(e.g. Accept=<js>"text/html;q=0.9"</js> and mediaTypeRange=<js>"text/html;q=0.9"</js> ==>, q-value=<code>0.81</code>).
+ *
+ * @param mediaTypeRanges The media type ranges to match against.
+ * @return The index into the array of the best match, or <code>-1</code> if no suitable matches could be found.
+ */
+ public int findMatch(MediaTypeRange[] mediaTypeRanges) {
+ float matchQuant = 0;
+ int matchIndex = -1;
+ float q = 0f;
+
+ // Media ranges are ordered by 'q'.
+ // So we only need to search until we've found a match.
+ for (MediaTypeRange mr : mediaRanges) {
+ float q2 = mr.getQValue();
+
+ if (q2 < q || q2 == 0)
+ break;
+
+ for (int i = 0; i < mediaTypeRanges.length; i++) {
+ MediaTypeRange mt = mediaTypeRanges[i];
+ float matchQuant2 = mr.getMediaType().match(mt.getMediaType(), false) * mt.getQValue();
+
+ if (matchQuant2 > matchQuant) {
+ matchIndex = i;
+ matchQuant = matchQuant2;
+ q = q2;
+ }
+ }
+ }
+
+ return matchIndex;
+ }
+
+
+ /**
* Convenience method for searching through all of the subtypes of all the media ranges in this header for the
* presence of a subtype fragment.
*
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/MediaType.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/MediaType.java
index f09eeba..05a7c05 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/MediaType.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/MediaType.java
@@ -35,8 +35,8 @@ import org.apache.juneau.json.*;
@BeanIgnore
public class MediaType implements Comparable<MediaType> {
- private static final boolean nocache = Boolean.getBoolean("juneau.nocache");
- private static final ConcurrentHashMap<String,MediaType> cache = new ConcurrentHashMap<>();
+ private static final boolean NOCACHE = Boolean.getBoolean("juneau.nocache");
+ private static final ConcurrentHashMap<String,MediaType> CACHE = new ConcurrentHashMap<>();
/** Reusable predefined media type */
@SuppressWarnings("javadoc")
@@ -92,14 +92,14 @@ public class MediaType implements Comparable<MediaType> {
public static MediaType forString(String s) {
if (isEmpty(s))
return null;
- MediaType mt = cache.get(s);
- if (mt == null) {
- mt = new MediaType(s);
- if (nocache)
- return mt;
- cache.putIfAbsent(s, mt);
- }
- return cache.get(s);
+ MediaType mt = CACHE.get(s);
+ if (mt != null)
+ return mt;
+ mt = new MediaType(s);
+ if (NOCACHE)
+ return mt;
+ CACHE.putIfAbsent(s, mt);
+ return CACHE.get(s);
}
/**
@@ -139,8 +139,11 @@ public class MediaType implements Comparable<MediaType> {
Builder(String mt) {
mt = mt.trim();
+ int i = mt.indexOf(',');
+ if (i != -1)
+ mt = mt.substring(0, i);
- int i = mt.indexOf(';');
+ i = mt.indexOf(';');
if (i == -1) {
this.parameters = Collections.EMPTY_MAP;
} else {
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/MediaTypeRange.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/MediaTypeRange.java
index ccbfd01..96249f1 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/MediaTypeRange.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/MediaTypeRange.java
@@ -16,6 +16,7 @@ import static org.apache.juneau.internal.CollectionUtils.*;
import java.util.*;
import java.util.Map.*;
+import java.util.concurrent.*;
import org.apache.juneau.annotation.*;
import org.apache.juneau.internal.*;
@@ -33,6 +34,8 @@ import org.apache.juneau.internal.*;
public final class MediaTypeRange implements Comparable<MediaTypeRange> {
private static final MediaTypeRange[] DEFAULT = new MediaTypeRange[]{new MediaTypeRange("*/*")};
+ private static final boolean NOCACHE = Boolean.getBoolean("juneau.nocache");
+ private static final ConcurrentHashMap<String,MediaTypeRange[]> CACHE = new ConcurrentHashMap<>();
private final MediaType mediaType;
private final Float qValue;
@@ -72,22 +75,27 @@ public final class MediaTypeRange implements Comparable<MediaTypeRange> {
if (value == null || value.length() == 0)
return DEFAULT;
-
- if (value.indexOf(',') == -1)
- return new MediaTypeRange[]{new MediaTypeRange(value)};
-
- Set<MediaTypeRange> ranges = new TreeSet<>();
-
- for (String r : StringUtils.split(value)) {
- r = r.trim();
-
- if (r.isEmpty())
- continue;
-
- ranges.add(new MediaTypeRange(r));
+
+ MediaTypeRange[] mtr = CACHE.get(value);
+ if (mtr != null)
+ return mtr;
+
+ if (value.indexOf(',') == -1) {
+ mtr = new MediaTypeRange[]{new MediaTypeRange(value)};
+ } else {
+ Set<MediaTypeRange> ranges = new TreeSet<>();
+ for (String r : StringUtils.split(value)) {
+ r = r.trim();
+ if (r.isEmpty())
+ continue;
+ ranges.add(new MediaTypeRange(r));
+ }
+ mtr = ranges.toArray(new MediaTypeRange[ranges.size()]);
}
-
- return ranges.toArray(new MediaTypeRange[ranges.size()]);
+ if (NOCACHE)
+ return mtr;
+ CACHE.putIfAbsent(value, mtr);
+ return CACHE.get(value);
}
private MediaTypeRange(String token) {
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoSerializer.java
index c6820dc..8416b99 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jso/JsoSerializer.java
@@ -46,7 +46,7 @@ public class JsoSerializer extends OutputStreamSerializer {
* @param ps The property store containing all the settings for this object.
*/
public JsoSerializer(PropertyStore ps) {
- super(ps, "application/x-java-serialized-object");
+ super(ps, "application/x-java-serialized-object", null);
}
@Override /* Context */
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializer.java
index a0bad2b..290090a 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializer.java
@@ -306,8 +306,7 @@ public class JsonSerializer extends WriterSerializer {
.set(JSON_simpleMode, true)
.set(WSERIALIZER_quoteChar, '\'')
.build(),
- "application/json",
- "application/json+simple", "text/json+simple"
+ "application/json", "application/json+simple,text/json+simple,application/json;q=0.9,text/json;q=0.9"
);
}
}
@@ -373,7 +372,7 @@ public class JsonSerializer extends WriterSerializer {
* The property store containing all the settings for this object.
*/
public JsonSerializer(PropertyStore ps) {
- this(ps, "application/json", "application/json", "text/json");
+ this(ps, "application/json", "application/json,text/json");
}
/**
@@ -394,14 +393,16 @@ public class JsonSerializer extends WriterSerializer {
* For example, if this serializer produces <js>"application/json"</js> but should handle media types of
* <js>"application/json"</js> and <js>"text/json"</js>, then the arguments should be:
* <p class='bcode'>
- * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"application/json"</js>, <js>"text/json"</js>);
+ * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"application/json,text/json"</js>);
* </p>
* <br>...or...
* <p class='bcode'>
* <jk>super</jk>(ps, <js>"application/json"</js>, <js>"*​/json"</js>);
* </p>
+ * <p>
+ * The accept value can also contain q-values.
*/
- public JsonSerializer(PropertyStore ps, String produces, String...accept) {
+ public JsonSerializer(PropertyStore ps, String produces, String accept) {
super(ps, produces, accept);
simpleMode = getBooleanProperty(JSON_simpleMode, false);
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaSerializer.java
index 89bca6a..b586c0d 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaSerializer.java
@@ -338,8 +338,7 @@ public class JsonSchemaSerializer extends JsonSerializer {
.set(SERIALIZER_detectRecursions, true)
.set(SERIALIZER_ignoreRecursions, true)
.build(),
- "application/json",
- "application/json+schema", "text/json+schema"
+ "application/json", "application/json+schema,text/json+schema"
);
useBeanDefs = getBooleanProperty(JSONSCHEMA_useBeanDefs, false);
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
index 7a06304..4ca9988 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
@@ -119,7 +119,7 @@ public class MsgPackSerializer extends OutputStreamSerializer {
* @param ps The property store containing all the settings for this object.
*/
public MsgPackSerializer(PropertyStore ps) {
- super(ps, "octal/msgpack");
+ super(ps, "octal/msgpack", null);
this.addBeanTypes = getBooleanProperty(MSGPACK_addBeanTypes, getBooleanProperty(SERIALIZER_addBeanTypes, false));
}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextSerializer.java
index e64437d..39c8b45 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextSerializer.java
@@ -54,7 +54,7 @@ public class PlainTextSerializer extends WriterSerializer {
* The property store containing all the settings for this object.
*/
public PlainTextSerializer(PropertyStore ps) {
- this(ps, "text/plain");
+ this(ps, "text/plain", null);
}
/**
@@ -75,14 +75,16 @@ public class PlainTextSerializer extends WriterSerializer {
* For example, if this serializer produces <js>"application/json"</js> but should handle media types of
* <js>"application/json"</js> and <js>"text/json"</js>, then the arguments should be:
* <p class='bcode'>
- * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"application/json"</js>, <js>"text/json"</js>);
+ * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"application/json,text/json"</js>);
* </p>
* <br>...or...
* <p class='bcode'>
* <jk>super</jk>(ps, <js>"application/json"</js>, <js>"*​/json"</js>);
* </p>
+ * <p>
+ * The accept value can also contain q-values.
*/
- public PlainTextSerializer(PropertyStore ps, String produces, String...accept) {
+ public PlainTextSerializer(PropertyStore ps, String produces, String accept) {
super(ps, produces, accept);
}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/OutputStreamSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/OutputStreamSerializer.java
index 4240531..ef2c984 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/OutputStreamSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/OutputStreamSerializer.java
@@ -69,7 +69,7 @@ public abstract class OutputStreamSerializer extends Serializer {
*/
public static final String OSSERIALIZER_binaryFormat = PREFIX + "binaryFormat.s";
- static final OutputStreamSerializer DEFAULT = new OutputStreamSerializer(PropertyStore.create().build(), "") {
+ static final OutputStreamSerializer DEFAULT = new OutputStreamSerializer(PropertyStore.create().build(), "", "") {
@Override
public OutputStreamSerializerSession createSession(SerializerSessionArgs args) {
throw new NoSuchMethodError();
@@ -100,14 +100,16 @@ public abstract class OutputStreamSerializer extends Serializer {
* For example, if this serializer produces <js>"application/json"</js> but should handle media types of
* <js>"application/json"</js> and <js>"text/json"</js>, then the arguments should be:
* <p class='bcode'>
- * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"application/json"</js>, <js>"text/json"</js>);
+ * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"application/json,text/json"</js>);
* </p>
* <br>...or...
* <p class='bcode'>
* <jk>super</jk>(ps, <js>"application/json"</js>, <js>"*​/json"</js>);
* </p>
+ * <p>
+ * The accept value can also contain q-values.
*/
- protected OutputStreamSerializer(PropertyStore ps, String produces, String...accept) {
+ protected OutputStreamSerializer(PropertyStore ps, String produces, String accept) {
super(ps, produces, accept);
binaryFormat = getProperty(OSSERIALIZER_binaryFormat, BinaryFormat.class, BinaryFormat.HEX);
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/Serializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/Serializer.java
index 83445e5..4567a68 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/Serializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/Serializer.java
@@ -17,6 +17,7 @@ import java.io.*;
import org.apache.juneau.*;
import org.apache.juneau.annotation.*;
import org.apache.juneau.http.*;
+import org.apache.juneau.internal.*;
import org.apache.juneau.parser.*;
/**
@@ -831,7 +832,7 @@ public abstract class Serializer extends BeanContext {
public static final String SERIALIZER_uriResolution = PREFIX + "uriResolution.s";
- static final Serializer DEFAULT = new Serializer(PropertyStore.create().build(), "") {
+ static final Serializer DEFAULT = new Serializer(PropertyStore.create().build(), "", "") {
@Override
public SerializerSession createSession(SerializerSessionArgs args) {
throw new NoSuchMethodError();
@@ -859,11 +860,12 @@ public abstract class Serializer extends BeanContext {
final UriRelativity uriRelativity;
final Class<? extends SerializerListener> listener;
- private final MediaType[] accept;
+ private final MediaTypeRange[] accept;
+ private final MediaType[] accepts;
private final MediaType produces;
// Hidden constructors to force subclass from OuputStreamSerializer or WriterSerializer.
- Serializer(PropertyStore ps, String produces, String...accept) {
+ Serializer(PropertyStore ps, String produces, String accept) {
super(ps);
maxDepth = getIntegerProperty(SERIALIZER_maxDepth, 100);
@@ -884,14 +886,8 @@ public abstract class Serializer extends BeanContext {
listener = getClassProperty(SERIALIZER_listener, SerializerListener.class, null);
this.produces = MediaType.forString(produces);
- if (accept.length == 0) {
- this.accept = new MediaType[]{this.produces};
- } else {
- this.accept = new MediaType[accept.length];
- for (int i = 0; i < accept.length; i++) {
- this.accept[i] = MediaType.forString(accept[i]);
- }
- }
+ this.accept = accept == null ? MediaTypeRange.parse(produces) : MediaTypeRange.parse(accept);
+ this.accepts = accept == null ? new MediaType[] {this.produces} : MediaType.forStrings(StringUtils.split(accept, ','));
}
@Override /* Context */
@@ -1005,11 +1001,38 @@ public abstract class Serializer extends BeanContext {
/**
* Returns the media types handled based on the value of the <code>accept</code> parameter passed into the constructor.
*
+ * <p>
+ * Note that the order of these ranges are from high to low q-value.
+ *
* @return The list of media types. Never <jk>null</jk>.
*/
- public final MediaType[] getMediaTypes() {
+ public final MediaTypeRange[] getMediaTypeRanges() {
return accept;
}
+
+ /**
+ * Returns the first entry in the <code>accept</code> parameter passed into the constructor.
+ *
+ * <p>
+ * This signifies the 'primary' media type for this serializer.
+ *
+ * @return The media type. Never <jk>null</jk>.
+ */
+ public final MediaType getPrimaryMediaType() {
+ return accepts[0];
+ }
+
+ /**
+ * Returns the media types handled based on the value of the <code>accept</code> parameter passed into the constructor.
+ *
+ * <p>
+ * The order of the media types are the same as those in the <code>accept</code> parameter.
+ *
+ * @return The list of media types. Never <jk>null</jk>.
+ */
+ public final MediaType[] getAcceptMediaTypes() {
+ return accepts;
+ }
/**
* Optional method that returns the response <code>Content-Type</code> for this serializer if it is different from
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerGroup.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerGroup.java
index 98fb82b..073fbe8 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerGroup.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerGroup.java
@@ -68,9 +68,10 @@ public final class SerializerGroup extends BeanContext {
// Maps Accept headers to matching serializers.
private final ConcurrentHashMap<String,SerializerMatch> cache = new ConcurrentHashMap<>();
- private final MediaType[] mediaTypes;
+ private final MediaTypeRange[] mediaTypeRanges;
+ private final Serializer[] mediaTypeRangeSerializers;
+
private final List<MediaType> mediaTypesList;
- private final Serializer[] mediaTypeSerializers;
private final List<Serializer> serializers;
/**
@@ -110,18 +111,21 @@ public final class SerializerGroup extends BeanContext {
super(ps);
this.serializers = immutableList(serializers);
- List<MediaType> lmt = new ArrayList<>();
+ List<MediaTypeRange> lmtr = new ArrayList<>();
+ LinkedHashSet<MediaType> lmt = new LinkedHashSet<>();
List<Serializer> l = new ArrayList<>();
for (Serializer s : serializers) {
- for (MediaType m: s.getMediaTypes()) {
- lmt.add(m);
+ for (MediaTypeRange m: s.getMediaTypeRanges()) {
+ lmtr.add(m);
l.add(s);
}
+ for (MediaType mt : s.getAcceptMediaTypes())
+ lmt.add(mt);
}
- this.mediaTypes = lmt.toArray(new MediaType[lmt.size()]);
- this.mediaTypesList = unmodifiableList(lmt);
- this.mediaTypeSerializers = l.toArray(new Serializer[l.size()]);
+ this.mediaTypeRanges = lmtr.toArray(new MediaTypeRange[lmt.size()]);
+ this.mediaTypesList = unmodifiableList(new ArrayList<>(lmt));
+ this.mediaTypeRangeSerializers = l.toArray(new Serializer[l.size()]);
}
/**
@@ -153,9 +157,9 @@ public final class SerializerGroup extends BeanContext {
return sm;
Accept a = Accept.forString(acceptHeader);
- int match = a.findMatch(mediaTypes);
+ int match = a.findMatch(mediaTypeRanges);
if (match >= 0) {
- sm = new SerializerMatch(mediaTypes[match], mediaTypeSerializers[match]);
+ sm = new SerializerMatch(mediaTypeRanges[match].getMediaType(), mediaTypeRangeSerializers[match]);
cache.putIfAbsent(acceptHeader, sm);
}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/WriterSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/WriterSerializer.java
index 03f3eb5..c706abd 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/WriterSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/WriterSerializer.java
@@ -146,7 +146,7 @@ public abstract class WriterSerializer extends Serializer {
*/
public static final String WSERIALIZER_useWhitespace = PREFIX + "useWhitespace.b";
- static final WriterSerializer DEFAULT = new WriterSerializer(PropertyStore.create().build(), "") {
+ static final WriterSerializer DEFAULT = new WriterSerializer(PropertyStore.create().build(), "", "") {
@Override
public WriterSerializerSession createSession(SerializerSessionArgs args) {
throw new NoSuchMethodError();
@@ -179,14 +179,16 @@ public abstract class WriterSerializer extends Serializer {
* For example, if this serializer produces <js>"application/json"</js> but should handle media types of
* <js>"application/json"</js> and <js>"text/json"</js>, then the arguments should be:
* <p class='bcode'>
- * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"application/json"</js>, <js>"text/json"</js>);
+ * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"application/json,text/json"</js>);
* </p>
* <br>...or...
* <p class='bcode'>
* <jk>super</jk>(ps, <js>"application/json"</js>, <js>"*​/json"</js>);
* </p>
+ * <p>
+ * The accept value can also contain q-values.
*/
- protected WriterSerializer(PropertyStore ps, String produces, String...accept) {
+ protected WriterSerializer(PropertyStore ps, String produces, String accept) {
super(ps, produces, accept);
useWhitespace = getBooleanProperty(WSERIALIZER_useWhitespace, false);
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializer.java
index 8fb6d47..9bca5f7 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializer.java
@@ -317,7 +317,7 @@ public class UonSerializer extends WriterSerializer {
* The property store containing all the settings for this object.
*/
public UonSerializer(PropertyStore ps) {
- this(ps, "text/uon");
+ this(ps, "text/uon", null);
}
/**
@@ -338,14 +338,16 @@ public class UonSerializer extends WriterSerializer {
* For example, if this serializer produces <js>"application/json"</js> but should handle media types of
* <js>"application/json"</js> and <js>"text/json"</js>, then the arguments should be:
* <p class='bcode'>
- * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"application/json"</js>, <js>"text/json"</js>);
+ * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"application/json,text/json"</js>);
* </p>
* <br>...or...
* <p class='bcode'>
* <jk>super</jk>(ps, <js>"application/json"</js>, <js>"*​/json"</js>);
* </p>
+ * <p>
+ * The accept value can also contain q-values.
*/
- public UonSerializer(PropertyStore ps, String produces, String...accept) {
+ public UonSerializer(PropertyStore ps, String produces, String accept) {
super(ps, produces, accept);
encodeChars = getBooleanProperty(UON_encoding, false);
addBeanTypes = getBooleanProperty(UON_addBeanTypes, getBooleanProperty(SERIALIZER_addBeanTypes, false));
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
index ee8f811..11a58bb 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
@@ -256,7 +256,7 @@ public class UrlEncodingSerializer extends UonSerializer {
* The property store containing all the settings for this object.
*/
public UrlEncodingSerializer(PropertyStore ps) {
- this(ps, "application/x-www-form-urlencoded");
+ this(ps, "application/x-www-form-urlencoded", null);
}
/**
@@ -277,14 +277,16 @@ public class UrlEncodingSerializer extends UonSerializer {
* For example, if this serializer produces <js>"application/json"</js> but should handle media types of
* <js>"application/json"</js> and <js>"text/json"</js>, then the arguments should be:
* <p class='bcode'>
- * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"application/json"</js>, <js>"text/json"</js>);
+ * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"application/json,text/json"</js>);
* </p>
* <br>...or...
* <p class='bcode'>
* <jk>super</jk>(ps, <js>"application/json"</js>, <js>"*​/json"</js>);
* </p>
+ * <p>
+ * The accept value can also contain q-values.
*/
- public UrlEncodingSerializer(PropertyStore ps, String produces, String...accept) {
+ public UrlEncodingSerializer(PropertyStore ps, String produces, String accept) {
super(
ps.builder()
.set(UON_encoding, true)
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/StringObject.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/StringObject.java
index 18546ab..56f3ba7 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/StringObject.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/StringObject.java
@@ -94,6 +94,6 @@ public class StringObject implements CharSequence, Writable {
@Override /* Writable */
public MediaType getMediaType() {
- return s.getMediaTypes()[0];
+ return s.getPrimaryMediaType();
}
}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializer.java
index cee7b90..17dcf8c 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializer.java
@@ -472,7 +472,7 @@ public class XmlSerializer extends WriterSerializer {
* The property store containing all the settings for this object.
*/
public XmlSerializer(PropertyStore ps) {
- this(ps, "text/xml");
+ this(ps, "text/xml", null);
}
/**
@@ -493,14 +493,16 @@ public class XmlSerializer extends WriterSerializer {
* For example, if this serializer produces <js>"application/json"</js> but should handle media types of
* <js>"application/json"</js> and <js>"text/json"</js>, then the arguments should be:
* <p class='bcode'>
- * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"application/json"</js>, <js>"text/json"</js>);
+ * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"application/json,text/json"</js>);
* </p>
* <br>...or...
* <p class='bcode'>
* <jk>super</jk>(ps, <js>"application/json"</js>, <js>"*​/json"</js>);
* </p>
+ * <p>
+ * The accept value can also contain q-values.
*/
- public XmlSerializer(PropertyStore ps, String produces, String...accept) {
+ public XmlSerializer(PropertyStore ps, String produces, String accept) {
super(ps, produces, accept);
autoDetectNamespaces = getBooleanProperty(XML_autoDetectNamespaces, true);
enableNamespaces = getBooleanProperty(XML_enableNamespaces, false);
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/yaml/proto/YamlSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/yaml/proto/YamlSerializer.java
index 2dc7618..b561a2f 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/yaml/proto/YamlSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/yaml/proto/YamlSerializer.java
@@ -265,7 +265,7 @@ public class YamlSerializer extends WriterSerializer {
* The property store containing all the settings for this object.
*/
public YamlSerializer(PropertyStore ps) {
- this(ps, "application/yaml", "application/yaml", "text/yaml");
+ this(ps, "application/yaml", "application/yaml,text/yaml");
}
/**
@@ -286,14 +286,16 @@ public class YamlSerializer extends WriterSerializer {
* For example, if this serializer produces <js>"application/json"</js> but should handle media types of
* <js>"application/json"</js> and <js>"text/json"</js>, then the arguments should be:
* <p class='bcode'>
- * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"application/json"</js>, <js>"text/json"</js>);
+ * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"application/json,text/json"</js>);
* </p>
* <br>...or...
* <p class='bcode'>
* <jk>super</jk>(ps, <js>"application/json"</js>, <js>"*​/json"</js>);
* </p>
+ * <p>
+ * The accept value can also contain q-values.
*/
- public YamlSerializer(PropertyStore ps, String produces, String...accept) {
+ public YamlSerializer(PropertyStore ps, String produces, String accept) {
super(ps, produces, accept);
simpleMode = getBooleanProperty(YAML_simpleMode, false);
escapeSolidus = getBooleanProperty(YAML_escapeSolidus, false);
diff --git a/juneau-doc/src/main/javadoc/overview.html b/juneau-doc/src/main/javadoc/overview.html
index c4f0d2a..4d88d55 100644
--- a/juneau-doc/src/main/javadoc/overview.html
+++ b/juneau-doc/src/main/javadoc/overview.html
@@ -21263,6 +21263,10 @@
<li class='jf'>{@link org.apache.juneau.html.annotation.HtmlFormat#HTML_CDC} - Format collections as comma-delimited lists.
<li class='jf'>{@link org.apache.juneau.html.annotation.HtmlFormat#HTML_SDC} - Format collections as space-delimited lists.
</ul>
+ <li>
+ Serializers now allow for q-values on the media types they handle.
+ <br>For example, the accept media type on <code>JsonSerializer.Simple</code> is <js>"application/json+simple,application/json;q=0.9"</js>.
+ <br>This means the serializer CAN handle requests for <js>"application/json"</js> if no other serializers provide a better match.
</ul>
<h5 class='topic w800'>juneau-dto</h5>
@@ -21385,6 +21389,11 @@
<br>Having it as a string allows us to differentiate between a set and unset value so that it can be overridden in subclasses.
<li>
The {@link org.apache.juneau.rest.annotation.Path#name()} annotation parameter is now required.
+ <li>
+ New class for mock unit testing of REST resources:
+ <ul>
+ <li class='jc'>{@link org.apache.juneau.rest.mock.MockRest}
+ </ul>
</ul>
<h5 class='topic w800'>juneau-rest-client</h5>
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java
index eb5a66e..f8511b8 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java
@@ -141,7 +141,7 @@ public class PhotosResource extends BasicRestServlet {
* @param ps The property store containing all the settings for this object.
*/
public ImageSerializer(PropertyStore ps) {
- super(ps, null, "image/png", "image/jpeg");
+ super(ps, null, "image/png,image/jpeg");
}
@Override /* Serializer */
diff --git a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/AcceptCharsetResource.java b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/AcceptCharsetResource.java
index 148616a..9f474fa 100644
--- a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/AcceptCharsetResource.java
+++ b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/AcceptCharsetResource.java
@@ -73,7 +73,7 @@ public class AcceptCharsetResource extends RestServlet {
public static class TestSerializer extends OutputStreamSerializer {
public TestSerializer(PropertyStore ps) {
- super(ps, "text/plain");
+ super(ps, "text/plain", null);
}
@Override /* Serializer */
diff --git a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/CharsetEncodingsResource.java b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/CharsetEncodingsResource.java
index af3ff65..d386ee7 100644
--- a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/CharsetEncodingsResource.java
+++ b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/CharsetEncodingsResource.java
@@ -54,7 +54,7 @@ public class CharsetEncodingsResource extends RestServlet {
public static class ASerializer extends WriterSerializer {
public ASerializer(PropertyStore ps) {
- super(ps, "text/s");
+ super(ps, "text/s", null);
}
@Override /* Serializer */
diff --git a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/DefaultContentTypesResource.java b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/DefaultContentTypesResource.java
index db4250a..c15a0d7 100644
--- a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/DefaultContentTypesResource.java
+++ b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/DefaultContentTypesResource.java
@@ -122,7 +122,7 @@ public class DefaultContentTypesResource extends RestServlet {
private String name;
private DummySerializer(PropertyStore ps, String name, String produces) {
- super(ps, produces);
+ super(ps, produces, null);
this.name = name;
}
diff --git a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/GroupsResource.java b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/GroupsResource.java
index f9cca1a..d049c30 100644
--- a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/GroupsResource.java
+++ b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/GroupsResource.java
@@ -39,7 +39,7 @@ public class GroupsResource extends RestServlet {
public static class SSerializer extends WriterSerializer {
public SSerializer(PropertyStore ps) {
- super(ps, "text/s1", "text/s1", "text/s2");
+ super(ps, "text/s1", "text/s1,text/s2");
}
@Override /* Serializer */
diff --git a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/InheritanceResource.java b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/InheritanceResource.java
index 3d25407..797ff7e 100644
--- a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/InheritanceResource.java
+++ b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/InheritanceResource.java
@@ -240,7 +240,7 @@ public class InheritanceResource extends RestServlet {
public static class DummySerializer extends WriterSerializer {
public DummySerializer(String produces) {
- super(PropertyStore.DEFAULT, produces);
+ super(PropertyStore.DEFAULT, produces, null);
}
@Override /* Serializer */
diff --git a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/NlsPropertyResource.java b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/NlsPropertyResource.java
index 98f78c9..d8e4f5d 100644
--- a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/NlsPropertyResource.java
+++ b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/NlsPropertyResource.java
@@ -56,7 +56,7 @@ public class NlsPropertyResource extends RestServlet {
public static class TestSerializer extends WriterSerializer {
public TestSerializer(PropertyStore ps) {
- super(ps, "text/plain");
+ super(ps, "text/plain", null);
}
@Override /* Serializer */
diff --git a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/OnPostCallResource.java b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/OnPostCallResource.java
index c55b1ed..6ec2414 100644
--- a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/OnPostCallResource.java
+++ b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/OnPostCallResource.java
@@ -43,7 +43,7 @@ public class OnPostCallResource extends RestServlet {
public static class TestSerializer extends WriterSerializer {
public TestSerializer(PropertyStore ps) {
- super(ps, "test/s1", "text/s1", "text/s2", "text/s3");
+ super(ps, "test/s1", "text/s1,text/s2,text/s3");
}
@Override /* Serializer */
diff --git a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/SerializersResource.java b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/SerializersResource.java
index 25ce7f9..5a67893 100644
--- a/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/SerializersResource.java
+++ b/juneau-microservice/juneau-microservice-test/src/main/java/org/apache/juneau/rest/test/SerializersResource.java
@@ -32,7 +32,7 @@ public class SerializersResource extends BasicRestServlet {
public static class TestSerializerA extends WriterSerializer {
public TestSerializerA(PropertyStore ps) {
- super(ps, "text/a");
+ super(ps, "text/a", null);
}
@Override /* Serializer */
@@ -50,7 +50,7 @@ public class SerializersResource extends BasicRestServlet {
public static class TestSerializerB extends WriterSerializer {
public TestSerializerB(PropertyStore ps) {
- super(ps, "text/b");
+ super(ps, "text/b", null);
}
@Override /* Serializer */
@@ -92,7 +92,7 @@ public class SerializersResource extends BasicRestServlet {
public static class TestSerializerC extends WriterSerializer {
public TestSerializerC(PropertyStore ps) {
- super(ps, "text/a");
+ super(ps, "text/a", null);
}
@Override /* Serializer */
@@ -118,7 +118,7 @@ public class SerializersResource extends BasicRestServlet {
public static class TestSerializerD extends WriterSerializer {
public TestSerializerD(PropertyStore ps) {
- super(ps, "text/d", "text/a", "text/d");
+ super(ps, "text/d", "text/a,text/d");
}
@Override /* Serializer */
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestInfoProvider.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestInfoProvider.java
index 8c9cc6f..4481961 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestInfoProvider.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestInfoProvider.java
@@ -644,7 +644,7 @@ public class BasicRestInfoProvider implements RestInfoProvider {
SerializerSessionArgs args = new SerializerSessionArgs(sprops, req.getJavaMethod(), req.getLocale(), null, mt, req.getUriContext());
try {
String eVal = s2.createSession(args).serializeToString(example);
- examples.put(s2.getMediaTypes()[0].toString(), eVal);
+ examples.put(s2.getPrimaryMediaType().toString(), eVal);
} catch (Exception e) {
System.err.println("Could not serialize to media type ["+mt+"]: " + e.getLocalizedMessage());
}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
index b81705d..097138a 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
@@ -2221,7 +2221,7 @@ public final class RestContext extends BeanContext {
* <br>The serializer selected is based on the request <code>Accept</code> header matched against the values returned by the following method
* using a best-match algorithm:
* <ul>
- * <li class='jm'>{@link Serializer#getMediaTypes()}
+ * <li class='jm'>{@link Serializer#getMediaTypeRanges()}
* </ul>
*
* <h5 class='section'>Example:</h5>
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/MockHttpSession.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/mock/MockHttpSession.java
similarity index 94%
rename from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/MockHttpSession.java
rename to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/mock/MockHttpSession.java
index 9184df0..5e4be3c 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/MockHttpSession.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/mock/MockHttpSession.java
@@ -10,7 +10,7 @@
// * "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.rest.util;
+package org.apache.juneau.rest.mock;
import java.util.*;
@@ -18,7 +18,12 @@ import javax.servlet.*;
import javax.servlet.http.*;
/**
- * An implementation of {@link HttpSession} for testing purposes.
+ * An implementation of {@link HttpSession} for mocking purposes.
+ *
+ * <h5 class='section'>See Also:</h5>
+ * <ul>
+ * <li class='link'>TODO
+ * </ul>
*/
public class MockHttpSession implements HttpSession {
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/MockRest.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/mock/MockRest.java
similarity index 69%
rename from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/MockRest.java
rename to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/mock/MockRest.java
index 452e6fa..1199068 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/MockRest.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/mock/MockRest.java
@@ -10,17 +10,46 @@
// * "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.rest.util;
+package org.apache.juneau.rest.mock;
import java.util.*;
+import java.util.concurrent.*;
import org.apache.juneau.rest.*;
/**
* Creates a mocked interface against a REST resource class.
+ *
+ * <p>
+ * Allows you to test your REST resource classes without a running servlet container.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bcode'>
+ * <jk>public class</jk> MockTest {
+ *
+ * <jc>// Our REST resource to test.</jc>
+ * <ja>@RestResource</ja>(serializers=JsonSerializer.Simple.<jk>class</jk>, parsers=JsonParser.<jk>class</jk>)
+ * <jk>public static class</jk> M {
+ *
+ * <ja>@RestMethod</ja>(name=<jsf>PUT</jsf>, path=<js>"/String"</js>)
+ * <jk>public</jk> String echo(<ja>@Body</ja> String b) {
+ * <jk>return</jk> b;
+ * }
+ * }
+ *
+ * <ja>@Test</js>
+ * <jk>public void</jk> testEcho() <jk>throws</jk> Exception {
+ * <jsm>assertEquals</jsm>(<js>"'foo'"</js>, MockRest.<jsf>create</jsf>(M.<jk>class</jk>).request(<js>"PUT"</js>, <js>"/String"</js>).body(<js>"'foo'"</js>).execute().getBodyAsString());
+ * }
+ * </p>
+ *
+ * <h5 class='section'>See Also:</h5>
+ * <ul>
+ * <li class='link'>TODO
+ * </ul>
*/
public class MockRest {
- private static Map<Class<?>,RestContext> CONTEXTS = new HashMap<>();
+ private static Map<Class<?>,RestContext> CONTEXTS = new ConcurrentHashMap<>();
private final RestContext rc;
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/MockServletRequest.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/mock/MockServletRequest.java
similarity index 98%
rename from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/MockServletRequest.java
rename to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/mock/MockServletRequest.java
index 54da1c2..4730eb6 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/MockServletRequest.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/mock/MockServletRequest.java
@@ -10,7 +10,7 @@
// * "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.rest.util;
+package org.apache.juneau.rest.mock;
import java.io.*;
import java.security.*;
@@ -21,9 +21,15 @@ import javax.servlet.http.*;
import org.apache.juneau.internal.*;
import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.util.*;
/**
- * An implementation of {@link HttpServletRequest} for testing purposes.
+ * An implementation of {@link HttpServletRequest} for mocking purposes.
+ *
+ * <h5 class='section'>See Also:</h5>
+ * <ul>
+ * <li class='link'>TODO
+ * </ul>
*/
public class MockServletRequest implements HttpServletRequest {
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/MockServletResponse.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/mock/MockServletResponse.java
similarity index 96%
rename from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/MockServletResponse.java
rename to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/mock/MockServletResponse.java
index 374f524..0e5efb2 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/MockServletResponse.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/mock/MockServletResponse.java
@@ -10,7 +10,7 @@
// * "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.rest.util;
+package org.apache.juneau.rest.mock;
import java.io.*;
import java.util.*;
@@ -19,10 +19,16 @@ import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.juneau.internal.*;
+import org.apache.juneau.rest.util.*;
/**
- * An implementation of {@link HttpServletResponse} for testing purposes.
- */
+ * An implementation of {@link HttpServletResponse} for mocking purposes.
+ *
+ * <h5 class='section'>See Also:</h5>
+ * <ul>
+ * <li class='link'>TODO
+ * </ul>
+*/
public class MockServletResponse implements HttpServletResponse {
private String characterEncoding = "UTF-8";
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/ContentTypeMenuItem.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/ContentTypeMenuItem.java
index cf31d83..d6173ff 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/ContentTypeMenuItem.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/ContentTypeMenuItem.java
@@ -74,7 +74,7 @@ public class ContentTypeMenuItem extends MenuItemWidget {
Div div = div();
Set<MediaType> l = new TreeSet<>();
for (Serializer s : req.getSerializers().getSerializers())
- l.add(s.getMediaTypes()[0]);
+ l.add(s.getPrimaryMediaType());
for (MediaType mt : l) {
URI uri = req.getUri(true, new AMap<String,String>().append("plainText","true").append("Accept",mt.toString()));
div.children(a(uri, mt), br());
diff --git a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/BasicRestInfoProviderTest.java b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/BasicRestInfoProviderTest.java
index 17867f8..7d2b17c 100644
--- a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/BasicRestInfoProviderTest.java
+++ b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/BasicRestInfoProviderTest.java
@@ -25,7 +25,7 @@ import org.apache.juneau.xml.*;
import org.apache.juneau.annotation.*;
import org.apache.juneau.dto.swagger.*;
import org.apache.juneau.rest.annotation.*;
-import org.apache.juneau.rest.util.*;
+import org.apache.juneau.rest.mock.*;
import org.apache.juneau.utils.*;
import org.junit.*;
import org.junit.runners.*;
diff --git a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/BodyTest.java b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/BodyTest.java
index 40a070f..5147f11 100644
--- a/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/BodyTest.java
+++ b/juneau-rest/juneau-rest-server/src/test/java/org/apache/juneau/rest/annotation/BodyTest.java
@@ -21,7 +21,7 @@ import java.util.*;
import org.apache.juneau.internal.*;
import org.apache.juneau.json.*;
-import org.apache.juneau.rest.util.*;
+import org.apache.juneau.rest.mock.*;
import org.junit.*;
import org.junit.runners.*;
--
To stop receiving notification emails like this one, please contact
jamesbognar@apache.org.