mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Optimize MediaType(MediaType, Charset) constructor
Prior to this commit, the `MediaType` and `MimeType` "copy" constructors would not leverage the fact that the existing instance has been validated already (types, subtype and parameters have been checked already for errors) and the entire validation would be performed again. This would also allocate map instances in the process. This commit ensures that the already validated information is reused directly and that we avoid unnessecary operations and allocations for such constructors. Closes gh-36318
This commit is contained in:
@@ -140,31 +140,6 @@ public class MimeType implements Comparable<MimeType>, Serializable {
|
||||
*/
|
||||
public MimeType(String type, String subtype, Charset charset) {
|
||||
this(type, subtype, Collections.singletonMap(PARAM_CHARSET, charset.name()));
|
||||
this.resolvedCharset = charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy-constructor that copies the type, subtype, parameters of the given {@code MimeType},
|
||||
* and allows to set the specified character set.
|
||||
* @param other the other MimeType
|
||||
* @param charset the character set
|
||||
* @throws IllegalArgumentException if any of the parameters contains illegal characters
|
||||
* @since 4.3
|
||||
*/
|
||||
public MimeType(MimeType other, Charset charset) {
|
||||
this(other.getType(), other.getSubtype(), addCharsetParameter(charset, other.getParameters()));
|
||||
this.resolvedCharset = charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy-constructor that copies the type and subtype of the given {@code MimeType},
|
||||
* and allows for different parameter.
|
||||
* @param other the other MimeType
|
||||
* @param parameters the parameters (may be {@code null})
|
||||
* @throws IllegalArgumentException if any of the parameters contains illegal characters
|
||||
*/
|
||||
public MimeType(MimeType other, @Nullable Map<String, String> parameters) {
|
||||
this(other.getType(), other.getSubtype(), parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -181,16 +156,43 @@ public class MimeType implements Comparable<MimeType>, Serializable {
|
||||
checkToken(subtype);
|
||||
this.type = type.toLowerCase(Locale.ROOT);
|
||||
this.subtype = subtype.toLowerCase(Locale.ROOT);
|
||||
if (!CollectionUtils.isEmpty(parameters)) {
|
||||
Map<String, String> map = new LinkedCaseInsensitiveMap<>(parameters.size(), Locale.ROOT);
|
||||
parameters.forEach((parameter, value) -> {
|
||||
checkParameters(parameter, value);
|
||||
map.put(parameter, value);
|
||||
});
|
||||
this.parameters = Collections.unmodifiableMap(map);
|
||||
this.parameters = createParametersMap(parameters);
|
||||
if (this.parameters.containsKey(PARAM_CHARSET)) {
|
||||
this.resolvedCharset = Charset.forName(unquote(this.parameters.get(PARAM_CHARSET)));
|
||||
}
|
||||
else {
|
||||
this.parameters = Collections.emptyMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy-constructor that copies the type, subtype, parameters of the given {@code MimeType},
|
||||
* and allows to set the specified character set.
|
||||
* @param other the other MimeType
|
||||
* @param charset the character set
|
||||
* @throws IllegalArgumentException if any of the parameters contains illegal characters
|
||||
* @since 4.3
|
||||
*/
|
||||
public MimeType(MimeType other, Charset charset) {
|
||||
this.type = other.type;
|
||||
this.subtype = other.subtype;
|
||||
Map<String, String> map = new LinkedCaseInsensitiveMap<>(other.parameters.size() + 1, Locale.ROOT);
|
||||
map.putAll(other.parameters);
|
||||
map.put(PARAM_CHARSET, charset.name());
|
||||
this.parameters = Collections.unmodifiableMap(map);
|
||||
this.resolvedCharset = charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy-constructor that copies the type and subtype of the given {@code MimeType},
|
||||
* and allows for different parameter.
|
||||
* @param other the other MimeType
|
||||
* @param parameters the parameters (may be {@code null})
|
||||
* @throws IllegalArgumentException if any of the parameters contains illegal characters
|
||||
*/
|
||||
public MimeType(MimeType other, @Nullable Map<String, String> parameters) {
|
||||
this.type = other.type;
|
||||
this.subtype = other.subtype;
|
||||
this.parameters = createParametersMap(parameters);
|
||||
if (this.parameters.containsKey(PARAM_CHARSET)) {
|
||||
this.resolvedCharset = Charset.forName(unquote(this.parameters.get(PARAM_CHARSET)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,16 +225,25 @@ public class MimeType implements Comparable<MimeType>, Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, String> createParametersMap(@Nullable Map<String, String> parameters) {
|
||||
if (!CollectionUtils.isEmpty(parameters)) {
|
||||
Map<String, String> map = new LinkedCaseInsensitiveMap<>(parameters.size(), Locale.ROOT);
|
||||
parameters.forEach((parameter, value) -> {
|
||||
checkParameters(parameter, value);
|
||||
map.put(parameter, value);
|
||||
});
|
||||
return Collections.unmodifiableMap(map);
|
||||
}
|
||||
else {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
|
||||
protected void checkParameters(String parameter, String value) {
|
||||
Assert.hasLength(parameter, "'parameter' must not be empty");
|
||||
Assert.hasLength(value, "'value' must not be empty");
|
||||
checkToken(parameter);
|
||||
if (PARAM_CHARSET.equals(parameter)) {
|
||||
if (this.resolvedCharset == null) {
|
||||
this.resolvedCharset = Charset.forName(unquote(value));
|
||||
}
|
||||
}
|
||||
else if (!isQuotedString(value)) {
|
||||
if (!isQuotedString(value)) {
|
||||
checkToken(value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -458,7 +458,7 @@ public class MediaType extends MimeType implements Serializable {
|
||||
* @throws IllegalArgumentException if any of the parameters contain illegal characters
|
||||
*/
|
||||
public MediaType(MediaType other, @Nullable Map<String, String> parameters) {
|
||||
super(other.getType(), other.getSubtype(), parameters);
|
||||
super(other, parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user