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 2020/07/13 21:00:44 UTC

[juneau] branch master updated: Cleanup of MediaType class.

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 5328f48  Cleanup of MediaType class.
5328f48 is described below

commit 5328f481eb3f913fff4085170cc701c6925fd695
Author: JamesBognar <ja...@salesforce.com>
AuthorDate: Mon Jul 13 17:00:36 2020 -0400

    Cleanup of MediaType class.
---
 .../src/main/java/org/apache/juneau/Session.java   |   2 +-
 .../java/org/apache/juneau/http/MediaType.java     | 107 +++++++--------------
 .../org/apache/juneau/http/MediaTypeRange.java     |  10 +-
 .../juneau/http/header/AcceptExtensionsTest.java   |  22 ++---
 .../apache/juneau/rest/client2/RestRequest.java    |  10 +-
 .../apache/juneau/rest/client2/RestResponse.java   |   4 +-
 6 files changed, 60 insertions(+), 95 deletions(-)

diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Session.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Session.java
index 9f5c373..29c0844 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Session.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Session.java
@@ -312,7 +312,7 @@ public abstract class Session {
 	 * @return
 	 * 	<jk>true</jk> if debug mode is enabled.
 	 */
-	protected final boolean isDebug() {
+	public boolean isDebug() {
 		return debug;
 	}
 
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 cf1ff08..b861a02 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
@@ -17,8 +17,9 @@ import static org.apache.juneau.internal.StringUtils.*;
 
 import java.util.*;
 
+import org.apache.http.*;
+import org.apache.http.message.*;
 import org.apache.juneau.annotation.*;
-import org.apache.juneau.collections.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.json.*;
 
@@ -36,6 +37,8 @@ public class MediaType implements Comparable<MediaType>  {
 
 	private static final Cache<String,MediaType> CACHE = new Cache<>(NOCACHE, CACHE_MAX_SIZE);
 
+	private static final HeaderElement DEFAULT_ELEMENT = new BasicHeaderElement("", "");
+
 	/** Reusable predefined media type */
 	@SuppressWarnings("javadoc")
 	public static final MediaType
@@ -56,15 +59,15 @@ public class MediaType implements Comparable<MediaType>  {
 		N3 = of("text/n3")
 	;
 
-	private final String mediaType;
-	private final String type;								     // The media type (e.g. "text" for Accept, "utf-8" for Accept-Charset)
+	private final String value;                          // The entire unparsed value.
+	private final String mediaType;                      // The "type/subtype" portion of the media type..
+	private final String type;                           // The media type (e.g. "text" for Accept, "utf-8" for Accept-Charset)
 	private final String subType;                        // The media sub-type (e.g. "json" for Accept, not used for Accept-Charset)
 	private final String[] subTypes;                     // The media sub-type (e.g. "json" for Accept, not used for Accept-Charset)
 	private final String[] subTypesSorted;               // Same as subTypes, but sorted so that it can be used for comparison.
-	private final List<String> subTypesList;             // The media sub-type (e.g. "json" for Accept, not used for Accept-Charset)
-	private final Map<String,Set<String>> parameters;    // The media type parameters (e.g. "text/html;level=1").  Does not include q!
 	private final boolean hasSubtypeMeta;                // The media subtype contains meta-character '*'.
-	private String asString;
+
+	private final NameValuePair[] parameters;            // The media type parameters (e.g. "text/html;level=1").  Does not include q!
 
 	/**
 	 * Returns the media type for the specified string.
@@ -119,61 +122,30 @@ public class MediaType implements Comparable<MediaType>  {
 	 * @param mt The media type string.
 	 */
 	public MediaType(String mt) {
-		Builder b = new Builder(mt);
-		this.mediaType = b.mediaType;
-		this.type = b.type;
-		this.subType = b.subType;
-		this.subTypes = b.subTypes;
-		this.subTypesSorted = b.subTypesSorted;
-		this.subTypesList = AList.unmodifiable(subTypes);
-		this.parameters = AMap.unmodifiable(b.parameters);
-		this.hasSubtypeMeta = b.hasSubtypeMeta;
-	}
+		mt = trim(mt);
+		value = mt;
+
+		HeaderElement[] elements = BasicHeaderValueParser.parseElements(mt, null);
+		HeaderElement element = (elements.length > 0 ? elements[0] : DEFAULT_ELEMENT);
 
-	static final class Builder {
-		String mediaType, type, subType;
-		String[] subTypes, subTypesSorted;
-		Map<String,Set<String>> parameters;
-		boolean hasSubtypeMeta;
-
-		Builder(String mt) {
-			mt = mt.trim();
-			int i = mt.indexOf(',');
-			if (i != -1)
-				mt = mt.substring(0, i);
-
-			i = mt.indexOf(';');
-			if (i == -1) {
-				this.parameters = Collections.emptyMap();
-			} else {
-				this.parameters = new TreeMap<>();
-				String[] tokens = mt.substring(i+1).split(";");
-
-				for (int j = 0; j < tokens.length; j++) {
-					String[] parm = tokens[j].split("=");
-					if (parm.length == 2) {
-						String k = parm[0].trim(), v = parm[1].trim();
-						if (! parameters.containsKey(k))
-							parameters.put(k, new TreeSet<String>());
-						parameters.get(k).add(v);
-					}
-				}
-
-				mt = mt.substring(0, i);
-			}
-
-			this.mediaType = mt;
-			if (mt != null) {
-				mt = mt.replace(' ', '+');
-				i = mt.indexOf('/');
-				type = (i == -1 ? mt : mt.substring(0, i));
-				subType = (i == -1 ? "*" : mt.substring(i+1));
-			}
-			this.subTypes = StringUtils.split(subType, '+');
-			this.subTypesSorted = Arrays.copyOf(subTypes, subTypes.length);
-			Arrays.sort(this.subTypesSorted);
-			hasSubtypeMeta = ArrayUtils.contains("*", this.subTypes);
+		mediaType = element.getName();
+		parameters = element.getParameters();
+
+		// Convert the parameters to BasicNameValuePair.
+		for (int j = 0; j < parameters.length; j++) {
+			NameValuePair p = parameters[j];
+			parameters[j] = BasicNameValuePair.of(p.getName(), p.getValue());
 		}
+
+		String x = mediaType.replace(' ', '+');
+		int i = x.indexOf('/');
+		type = (i == -1 ? x : x.substring(0, i));
+		subType = (i == -1 ? "*" : x.substring(i+1));
+
+		subTypes = StringUtils.split(subType, '+');
+		subTypesSorted = Arrays.copyOf(subTypes, subTypes.length);
+		Arrays.sort(this.subTypesSorted);
+		hasSubtypeMeta = ArrayUtils.contains("*", this.subTypes);
 	}
 
 	/**
@@ -220,7 +192,7 @@ public class MediaType implements Comparable<MediaType>  {
 	 * @return An unmodifiable list of subtype fragments.  Never <jk>null</jk>.
 	 */
 	public final List<String> getSubTypes() {
-		return subTypesList;
+		return Collections.unmodifiableList(Arrays.asList(subTypes));
 	}
 
 	/**
@@ -328,24 +300,13 @@ public class MediaType implements Comparable<MediaType>  {
 	 *
 	 * @return The map of additional parameters, or an empty map if there are no parameters.
 	 */
-	public final Map<String,Set<String>> getParameters() {
+	public NameValuePair[] getParameters() {
 		return parameters;
 	}
 
 	@Override /* Object */
 	public final String toString() {
-		if (asString == null) {
-			if (parameters.isEmpty())
-				asString = mediaType;
-			else {
-				StringBuilder sb = new StringBuilder(mediaType);
-				for (Map.Entry<String,Set<String>> e : parameters.entrySet())
-					for (String value : e.getValue())
-						sb.append(';').append(e.getKey()).append('=').append(value);
-				asString = sb.toString();
-			}
-		}
-		return asString;
+		return value;
 	}
 
 	@Override /* Object */
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 3a20b0e..508392d 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
@@ -12,11 +12,11 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.http;
 
+import static org.apache.juneau.http.Constants.*;
 import static org.apache.juneau.internal.ObjectUtils.*;
 
 import java.util.*;
 import java.util.Map.*;
-import java.util.concurrent.*;
 
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.collections.*;
@@ -34,8 +34,7 @@ import org.apache.juneau.internal.*;
 public 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 static final Cache<String,MediaTypeRange[]> CACHE = new Cache<>(NOCACHE, CACHE_MAX_SIZE);
 
 	private final MediaType mediaType;
 	private final Float qValue;
@@ -92,10 +91,7 @@ public class MediaTypeRange implements Comparable<MediaTypeRange>  {
 			}
 			mtr = ranges.toArray(new MediaTypeRange[ranges.size()]);
 		}
-		if (NOCACHE)
-			return mtr;
-		CACHE.putIfAbsent(value, mtr);
-		return CACHE.get(value);
+		return CACHE.put(value, mtr);
 	}
 
 	private MediaTypeRange(String token) {
diff --git a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/http/header/AcceptExtensionsTest.java b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/http/header/AcceptExtensionsTest.java
index 51fc19a..68f5af6 100644
--- a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/http/header/AcceptExtensionsTest.java
+++ b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/http/header/AcceptExtensionsTest.java
@@ -37,7 +37,7 @@ public class AcceptExtensionsTest {
 		mr = accept.asRanges().get(0);
 		assertString(mr).is("text/json");
 		assertString(mr.getMediaType()).is("text/json");
-		assertObject(mr.getMediaType().getParameters()).json().is("{}");
+		assertObject(mr.getMediaType().getParameters()).json().is("[]");
 		assertString(mr.getQValue()).is("1.0");
 		assertObject(mr.getExtensions()).json().is("{}");
 
@@ -45,7 +45,7 @@ public class AcceptExtensionsTest {
 		mr = accept.asRanges().get(0);
 		assertString(mr).is("foo");
 		assertString(mr.getMediaType()).is("foo");
-		assertObject(mr.getMediaType().getParameters()).json().is("{}");
+		assertObject(mr.getMediaType().getParameters()).json().is("[]");
 		assertString(mr.getQValue()).is("1.0");
 		assertObject(mr.getExtensions()).json().is("{}");
 
@@ -53,7 +53,7 @@ public class AcceptExtensionsTest {
 		mr = accept.asRanges().get(0);
 		assertString(mr).is("foo");
 		assertString(mr.getMediaType()).is("foo");
-		assertObject(mr.getMediaType().getParameters()).json().is("{}");
+		assertObject(mr.getMediaType().getParameters()).json().is("[]");
 		assertString(mr.getQValue()).is("1.0");
 		assertObject(mr.getExtensions()).json().is("{}");
 
@@ -61,7 +61,7 @@ public class AcceptExtensionsTest {
 		mr = accept.asRanges().get(0);
 		assertString(mr).is("text/json;a=1;q=0.9;b=2");
 		assertString(mr.getMediaType()).is("text/json;a=1");
-		assertObject(mr.getMediaType().getParameters()).json().is("{a:['1']}");
+		assertObject(mr.getMediaType().getParameters()).json().is("['a=1']");
 		assertString(mr.getQValue()).is("0.9");
 		assertObject(mr.getExtensions()).json().is("{b:['2']}");
 
@@ -69,7 +69,7 @@ public class AcceptExtensionsTest {
 		mr = accept.asRanges().get(0);
 		assertString(mr).is("text/json;a=1;a=2;q=0.9;b=3;b=4");
 		assertString(mr.getMediaType()).is("text/json;a=1;a=2");
-		assertObject(mr.getMediaType().getParameters()).json().is("{a:['1','2']}");
+		assertObject(mr.getMediaType().getParameters()).json().is("['a=1','a=2']");
 		assertString(mr.getQValue()).is("0.9");
 		assertObject(mr.getExtensions()).json().is("{b:['3','4']}");
 
@@ -77,15 +77,15 @@ public class AcceptExtensionsTest {
 		mr = accept.asRanges().get(0);
 		assertString(mr).is("text/json;a=1");
 		assertString(mr.getMediaType()).is("text/json;a=1");
-		assertObject(mr.getMediaType().getParameters()).json().is("{a:['1']}");
+		assertObject(mr.getMediaType().getParameters()).json().is("['a=1']");
 		assertString(mr.getQValue()).is("1.0");
 		assertObject(mr.getExtensions()).json().is("{}");
 
 		accept = Accept.of("text/json;a=1;");
 		mr = accept.asRanges().get(0);
-		assertString(mr).is("text/json;a=1");
-		assertString(mr.getMediaType()).is("text/json;a=1");
-		assertObject(mr.getMediaType().getParameters()).json().is("{a:['1']}");
+		assertString(mr).is("text/json;a=1;");
+		assertString(mr.getMediaType()).is("text/json;a=1;");
+		assertObject(mr.getMediaType().getParameters()).json().is("['a=1']");
 		assertString(mr.getQValue()).is("1.0");
 		assertObject(mr.getExtensions()).json().is("{}");
 
@@ -93,7 +93,7 @@ public class AcceptExtensionsTest {
 		mr = accept.asRanges().get(0);
 		assertString(mr).is("text/json;q=0.9");
 		assertString(mr.getMediaType()).is("text/json");
-		assertObject(mr.getMediaType().getParameters()).json().is("{}");
+		assertObject(mr.getMediaType().getParameters()).json().is("[]");
 		assertString(mr.getQValue()).is("0.9");
 		assertObject(mr.getExtensions()).json().is("{}");
 
@@ -101,7 +101,7 @@ public class AcceptExtensionsTest {
 		mr = accept.asRanges().get(0);
 		assertString(mr).is("text/json;q=0.9");
 		assertString(mr.getMediaType()).is("text/json");
-		assertObject(mr.getMediaType().getParameters()).json().is("{}");
+		assertObject(mr.getMediaType().getParameters()).json().is("[]");
 		assertString(mr.getQValue()).is("0.9");
 		assertObject(mr.getExtensions()).json().is("{}");
 	}
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestRequest.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestRequest.java
index cf1340d..6204e74 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestRequest.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestRequest.java
@@ -702,6 +702,14 @@ public class RestRequest extends BeanSession implements HttpUriRequest, Configur
 	}
 
 	/**
+	 * Returns <jk>true</jk> if debug mode is currently enabled.
+	 */
+	@Override
+	public boolean isDebug() {
+		return getHeader("Debug", "false").equalsIgnoreCase("true");
+	}
+
+	/**
 	 * Specifies the target host for the request.
 	 *
 	 * @param target The target host for the request.
@@ -2874,7 +2882,7 @@ public class RestRequest extends BeanSession implements HttpUriRequest, Configur
 				throw e;
 			}
 
-			if (client.logRequests == DetailLevel.FULL)
+			if (isDebug() || client.logRequests == DetailLevel.FULL)
 				response.cacheBody();
 
 			for (RestCallInterceptor rci : interceptors)
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestResponse.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestResponse.java
index 906d80b..3151146 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestResponse.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestResponse.java
@@ -998,10 +998,10 @@ public class RestResponse implements HttpResponse {
 		isClosed = true;
 		EntityUtils.consumeQuietly(response.getEntity());
 
-		if (client.logRequestsPredicate.test(request, this)) {
+		if (request.isDebug() || client.logRequestsPredicate.test(request, this)) {
 			if (client.logRequests == DetailLevel.SIMPLE) {
 				client.log(client.logRequestsLevel, "HTTP {0} {1}, {2}", request.getMethod(), request.getURI(), this.getStatusLine());
-			} else if (client.logRequests == DetailLevel.FULL) {
+			} else if (request.isDebug() || client.logRequests == DetailLevel.FULL) {
 				String output = getBody().asString();
 				StringBuilder sb = new StringBuilder();
 				sb.append("\n=== HTTP Call (outgoing) ======================================================");