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 2021/02/06 16:00:42 UTC
[juneau] branch master updated: CollectionUtils refactoring.
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 3ddd7f7 CollectionUtils refactoring.
3ddd7f7 is described below
commit 3ddd7f7afe256278592d199536c3ea740e890110
Author: JamesBognar <ja...@salesforce.com>
AuthorDate: Sat Feb 6 11:00:11 2021 -0500
CollectionUtils refactoring.
---
.../org/apache/juneau/dto/swagger/HeaderInfo.java | 4 +-
.../java/org/apache/juneau/dto/swagger/Items.java | 4 +-
.../org/apache/juneau/dto/swagger/Operation.java | 48 +--
.../apache/juneau/dto/swagger/ParameterInfo.java | 12 +-
.../apache/juneau/dto/swagger/ResponseInfo.java | 14 +-
.../org/apache/juneau/dto/swagger/SchemaInfo.java | 20 +-
.../apache/juneau/dto/swagger/SecurityScheme.java | 6 +-
.../org/apache/juneau/dto/swagger/Swagger.java | 75 ++--
.../apache/juneau/internal/CollectionUtils.java | 465 ++-------------------
.../org/apache/juneau/internal/ListBuilder.java | 234 +++++++++++
.../org/apache/juneau/internal/MapBuilder.java | 222 ++++++++++
.../org/apache/juneau/internal/SetBuilder.java | 237 +++++++++++
.../java/org/apache/juneau/mstat/ThrownStats.java | 4 +-
.../java/org/apache/juneau/reflect/ClassInfo.java | 7 +-
.../java/org/apache/juneau/rest/RestContext.java | 21 +-
.../apache/juneau/dto/swagger/HeaderInfo_Test.java | 4 +-
.../apache/juneau/dto/swagger/Swagger_Test.java | 2 +-
.../apache/juneau/utils/CollectionUtilsTest.java | 64 ---
18 files changed, 857 insertions(+), 586 deletions(-)
diff --git a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/HeaderInfo.java b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/HeaderInfo.java
index 7076856..a80407c 100644
--- a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/HeaderInfo.java
+++ b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/HeaderInfo.java
@@ -382,7 +382,7 @@ public class HeaderInfo extends SwaggerElement {
* @return This object (for method chaining).
*/
public HeaderInfo addEnum(Collection<Object> value) {
- _enum = addToSet(_enum, value);
+ _enum = setBuilder(_enum).sparse().addAll(value).build();
return this;
}
@@ -421,7 +421,7 @@ public class HeaderInfo extends SwaggerElement {
* @return This object (for method chaining).
*/
public HeaderInfo _enum(Object...value) {
- setEnum(toSet(value, Object.class));
+ setEnum(setBuilder(Object.class).sparse().addAny(value).build());
return this;
}
diff --git a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Items.java b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Items.java
index f71d92d..a1e29c5 100644
--- a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Items.java
+++ b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Items.java
@@ -326,7 +326,7 @@ public class Items extends SwaggerElement {
* <br>Can be <jk>null</jk> to unset the property.
*/
public void addEnum(Collection<Object> value) {
- _enum = addToSet(_enum, value);
+ _enum = setBuilder(_enum).sparse().addAll(value).build();
}
/**
@@ -359,7 +359,7 @@ public class Items extends SwaggerElement {
* @return This object (for method chaining).
*/
public Items _enum(Object...value) {
- setEnum(toSet(value, Object.class));
+ setEnum(setBuilder(Object.class).sparse().addAny(value).build());
return this;
}
diff --git a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Operation.java b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Operation.java
index 7b9f85b..b7addf5 100644
--- a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Operation.java
+++ b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Operation.java
@@ -251,7 +251,7 @@ public class Operation extends SwaggerElement {
* <br>Can be <jk>null</jk> to unset the property.
*/
public void addConsumes(Collection<MediaType> value) {
- consumes = addToSet(consumes, value);
+ consumes = setBuilder(consumes).sparse().addAll(value).build();
}
/**
@@ -277,7 +277,7 @@ public class Operation extends SwaggerElement {
* @return This object (for method chaining).
*/
public Operation consumes(MediaType...value) {
- setConsumes(toSet(value, MediaType.class));
+ setConsumes(setBuilder(MediaType.class).sparse().add(value).build());
return this;
}
@@ -308,7 +308,7 @@ public class Operation extends SwaggerElement {
* @return This object (for method chaining).
*/
public Operation consumes(String...value) {
- setConsumes(toSet(value, MediaType.class));
+ setConsumes(setBuilder(MediaType.class).sparse().addJson(value).build());
return this;
}
@@ -682,7 +682,7 @@ public class Operation extends SwaggerElement {
* <br>Ignored if <jk>null</jk>.
*/
public void addParameters(Collection<ParameterInfo> value) {
- parameters = addToList(parameters, value);
+ parameters = listBuilder(parameters).sparse().addAll(value).build();
}
/**
@@ -708,7 +708,7 @@ public class Operation extends SwaggerElement {
* @return This object (for method chaining).
*/
public Operation parameters(ParameterInfo...value) {
- setParameters(toList(value, ParameterInfo.class));
+ setParameters(listBuilder(ParameterInfo.class).sparse().add(value).build());
return this;
}
@@ -739,7 +739,7 @@ public class Operation extends SwaggerElement {
* @return This object (for method chaining).
*/
public Operation parameters(String...value) {
- setParameters(toList(value, ParameterInfo.class));
+ setParameters(listBuilder(ParameterInfo.class).sparse().addJson(value).build());
return this;
}
@@ -785,7 +785,7 @@ public class Operation extends SwaggerElement {
* <br>Value MUST be as described under {@doc ExtSwaggerMimeTypes}.
*/
public void addProduces(Collection<MediaType> value) {
- produces = addToSet(produces, value);
+ produces = setBuilder(produces).sparse().addAll(value).build();
}
/**
@@ -811,7 +811,7 @@ public class Operation extends SwaggerElement {
* @return This object (for method chaining).
*/
public Operation produces(MediaType...value) {
- setProduces(toSet(value, MediaType.class));
+ setProduces(setBuilder(MediaType.class).sparse().add(value).build());
return this;
}
@@ -842,7 +842,7 @@ public class Operation extends SwaggerElement {
* @return This object (for method chaining).
*/
public Operation produces(String...value) {
- setProduces(toSet(value, MediaType.class));
+ setProduces(setBuilder(MediaType.class).sparse().addJson(value).build());
return this;
}
@@ -919,7 +919,7 @@ public class Operation extends SwaggerElement {
* <br>Ignored if <jk>null</jk>.
*/
public void addResponses(Map<String,ResponseInfo> values) {
- responses = addToMap(responses, values);
+ responses = mapBuilder(responses).sparse().addAll(values).build();
}
/**
@@ -977,7 +977,7 @@ public class Operation extends SwaggerElement {
* @return This object (for method chaining).
*/
public Operation responses(String json) {
- setResponses(toMap(json, String.class, ResponseInfo.class));
+ setResponses(mapBuilder(String.class,ResponseInfo.class).sparse().addJson(json).build());
return this;
}
@@ -1029,7 +1029,7 @@ public class Operation extends SwaggerElement {
* <br>Ignored if <jk>null</jk>.
*/
public void addSchemes(Collection<String> value) {
- schemes = addToSet(schemes, value);
+ schemes = setBuilder(schemes).sparse().addAll(value).build();
}
/**
@@ -1056,7 +1056,7 @@ public class Operation extends SwaggerElement {
* @return This object (for method chaining).
*/
public Operation schemes(String...value) {
- setSchemes(toSet(value, String.class));
+ setSchemes(setBuilder(String.class).sparse().addJson(value).build());
return this;
}
@@ -1118,7 +1118,7 @@ public class Operation extends SwaggerElement {
* The new value for this property.
*/
public void addSecurity(Collection<Map<String,List<String>>> values) {
- security = addToList(security, values);
+ security = listBuilder(security).sparse().addAll(values).build();
}
/**
@@ -1185,7 +1185,7 @@ public class Operation extends SwaggerElement {
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public Operation security(String value) {
- setSecurity((Collection)toList(value, Map.class, String.class, List.class, String.class));
+ setSecurity((Collection)listBuilder(Map.class,String.class,List.class,String.class).sparse().addJson(value).build());
return this;
}
@@ -1290,7 +1290,7 @@ public class Operation extends SwaggerElement {
* The values to add to this property.
*/
public void addTags(Collection<String> value) {
- tags = addToSet(tags, value);
+ tags = setBuilder(tags).sparse().addAll(value).build();
}
/**
@@ -1341,7 +1341,7 @@ public class Operation extends SwaggerElement {
* @return This object (for method chaining).
*/
public Operation tags(String...value) {
- setTags(toSet(value, String.class));
+ setTags(setBuilder(String.class).sparse().addJson(value).build());
return this;
}
@@ -1373,18 +1373,18 @@ public class Operation extends SwaggerElement {
if (property == null)
return this;
switch (property) {
- case "consumes": return consumes(toList(value, MediaType.class));
+ case "consumes": return consumes(listBuilder(MediaType.class).sparse().addAny(value).build());
case "deprecated": return deprecated(toBoolean(value));
case "description": return description(stringify(value));
case "externalDocs": return externalDocs(toType(value, ExternalDocumentation.class));
case "operationId": return operationId(stringify(value));
- case "parameters": return parameters(toList(value, ParameterInfo.class));
- case "produces": return produces(toList(value, MediaType.class));
- case "responses": return responses(toMap(value, String.class, ResponseInfo.class));
- case "schemes": return schemes(toList(value, String.class));
- case "security": return security((List)toList(value, Map.class, String.class, List.class, String.class));
+ case "parameters": return parameters(listBuilder(ParameterInfo.class).sparse().addAny(value).build());
+ case "produces": return produces(listBuilder(MediaType.class).sparse().addAny(value).build());
+ case "responses": return responses(mapBuilder(String.class,ResponseInfo.class).sparse().addAny(value).build());
+ case "schemes": return schemes(listBuilder(String.class).sparse().addAny(value).build());
+ case "security": return security((List)listBuilder(Map.class,String.class,List.class,String.class).sparse().addAny(value).build());
case "summary": return summary(stringify(value));
- case "tags": return tags(toList(value, String.class));
+ case "tags": return tags(listBuilder(String.class).sparse().addAny(value).build());
default:
super.set(property, value);
return this;
diff --git a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/ParameterInfo.java b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/ParameterInfo.java
index 3f4b501..94e683a 100644
--- a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/ParameterInfo.java
+++ b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/ParameterInfo.java
@@ -575,7 +575,7 @@ public class ParameterInfo extends SwaggerElement {
* @return This object (for method chaining).
*/
public ParameterInfo addEnum(Collection<Object> value) {
- _enum = addToSet(_enum, value);
+ _enum = setBuilder(_enum).sparse().addAll(value).build();
return this;
}
@@ -609,7 +609,7 @@ public class ParameterInfo extends SwaggerElement {
* @return This object (for method chaining).
*/
public ParameterInfo _enum(Object...value) {
- setEnum(toSet(value, Object.class));
+ setEnum(setBuilder(Object.class).sparse().addAny(value).build());
return this;
}
@@ -690,7 +690,7 @@ public class ParameterInfo extends SwaggerElement {
* @return This object (for method chaining).
*/
public ParameterInfo addExamples(Map<String,String> values) {
- examples = addToMap(examples, values);
+ examples = mapBuilder(examples).sparse().addAll(values).build();
return this;
}
@@ -705,7 +705,7 @@ public class ParameterInfo extends SwaggerElement {
* @return This object (for method chaining).
*/
public ParameterInfo example(String name, String value) {
- examples = addToMap(examples, name, value);
+ examples = mapBuilder(examples).sparse().add(name, value).build();
return this;
}
@@ -738,7 +738,7 @@ public class ParameterInfo extends SwaggerElement {
* @return This object (for method chaining).
*/
public ParameterInfo examples(String json) {
- setExamples(toMap(json, String.class, String.class));
+ setExamples(mapBuilder(String.class,String.class).sparse().addJson(json).build());
return this;
}
@@ -1939,7 +1939,7 @@ public class ParameterInfo extends SwaggerElement {
case "description": return description(stringify(value));
case "enum": return _enum(value);
case "example": return example(stringify(value));
- case "examples": return examples(toMap(value, String.class, String.class));
+ case "examples": return examples(mapBuilder(String.class,String.class).sparse().addAny(value).build());
case "exclusiveMaximum": return exclusiveMaximum(toBoolean(value));
case "exclusiveMinimum": return exclusiveMinimum(toBoolean(value));
case "format": return format(stringify(value));
diff --git a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/ResponseInfo.java b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/ResponseInfo.java
index c0cfad0..b3ac618 100644
--- a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/ResponseInfo.java
+++ b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/ResponseInfo.java
@@ -277,7 +277,7 @@ public class ResponseInfo extends SwaggerElement {
* @return This object (for method chaining).
*/
public ResponseInfo addExamples(Map<String,Object> values) {
- examples = addToMap(examples, values);
+ examples = mapBuilder(examples).sparse().addAll(values).build();
return this;
}
@@ -292,7 +292,7 @@ public class ResponseInfo extends SwaggerElement {
* @return This object (for method chaining).
*/
public ResponseInfo example(String mimeType, Object example) {
- examples = addToMap(examples, mimeType, example);
+ examples = mapBuilder(examples).sparse().add(mimeType, example).build();
return this;
}
@@ -330,7 +330,7 @@ public class ResponseInfo extends SwaggerElement {
* @return This object (for method chaining).
*/
public ResponseInfo examples(String value) {
- setExamples(toMap(value, String.class, Object.class));
+ setExamples(mapBuilder(String.class,Object.class).sparse().addJson(value).build());
return this;
}
@@ -373,7 +373,7 @@ public class ResponseInfo extends SwaggerElement {
* @return This object (for method chaining).
*/
public ResponseInfo addHeaders(Map<String,HeaderInfo> values) {
- headers = addToMap(headers, values);
+ headers = mapBuilder(headers).sparse().addAll(values).build();
return this;
}
@@ -432,7 +432,7 @@ public class ResponseInfo extends SwaggerElement {
* @return This object (for method chaining).
*/
public ResponseInfo headers(String json) {
- setHeaders(toMap(json, String.class, HeaderInfo.class));
+ setHeaders(mapBuilder(String.class,HeaderInfo.class).sparse().addJson(json).build());
return this;
}
@@ -558,8 +558,8 @@ public class ResponseInfo extends SwaggerElement {
switch (property) {
case "description": return description(stringify(value));
case "example": return example(value);
- case "examples": return examples(toMap(value, String.class, Object.class));
- case "headers": return headers(toMap(value, String.class, HeaderInfo.class));
+ case "examples": return examples(mapBuilder(String.class,Object.class).sparse().addAny(value).build());
+ case "headers": return headers(mapBuilder(String.class,HeaderInfo.class).sparse().addAny(value).build());
case "schema": return schema(stringify(value));
default:
super.set(property, value);
diff --git a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/SchemaInfo.java b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/SchemaInfo.java
index 2125e50..bb5a448 100644
--- a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/SchemaInfo.java
+++ b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/SchemaInfo.java
@@ -253,7 +253,7 @@ public class SchemaInfo extends SwaggerElement {
* @return This object (for method chaining).
*/
public SchemaInfo addAllOf(Collection<Object> values) {
- allOf = addToSet(allOf, values);
+ allOf = setBuilder(allOf).sparse().addAll(values).build();
return this;
}
@@ -288,7 +288,7 @@ public class SchemaInfo extends SwaggerElement {
* @return This object (for method chaining).
*/
public SchemaInfo allOf(Object...value) {
- setAllOf(toSet(value, Object.class));
+ setAllOf(setBuilder(Object.class).sparse().addAny(value).build());
return this;
}
@@ -474,7 +474,7 @@ public class SchemaInfo extends SwaggerElement {
* @return This object (for method chaining).
*/
public SchemaInfo addEnum(Collection<Object> value) {
- _enum = addToSet(_enum, value);
+ _enum = setBuilder(_enum).sparse().addAll(value).build();
return this;
}
@@ -496,7 +496,7 @@ public class SchemaInfo extends SwaggerElement {
* @return This object (for method chaining).
*/
public SchemaInfo _enum(Object...value) {
- setEnum(toSet(value, Object.class));
+ setEnum(setBuilder(Object.class).sparse().addAny(value).build());
return this;
}
@@ -1485,7 +1485,7 @@ public class SchemaInfo extends SwaggerElement {
* @return This object (for method chaining).
*/
public SchemaInfo addProperties(Map<String,SchemaInfo> values) {
- properties = addToMap(properties, values);
+ properties = mapBuilder(properties).sparse().addAll(values).build();
return this;
}
@@ -1518,7 +1518,7 @@ public class SchemaInfo extends SwaggerElement {
* @return This object (for method chaining).
*/
public SchemaInfo properties(String json) {
- setProperties(toMap(json, String.class, SchemaInfo.class));
+ setProperties(mapBuilder(String.class,SchemaInfo.class).sparse().addJson(json).build());
return this;
}
@@ -1678,7 +1678,7 @@ public class SchemaInfo extends SwaggerElement {
* @return This object (for method chaining).
*/
public SchemaInfo addRequired(Collection<String> value) {
- required = addToSet(required, value);
+ required = setBuilder(required).sparse().addAny(value).build();
return this;
}
@@ -1711,7 +1711,7 @@ public class SchemaInfo extends SwaggerElement {
* @return This object (for method chaining).
*/
public SchemaInfo required(String...value) {
- setRequired(toSet(value, String.class));
+ setRequired(setBuilder(String.class).sparse().addJson(value).build());
return this;
}
@@ -2017,10 +2017,10 @@ public class SchemaInfo extends SwaggerElement {
case "minProperties": return minProperties(toInteger(value));
case "multipleOf": return multipleOf(toNumber(value));
case "pattern": return pattern(stringify(value));
- case "properties": return properties(toMap(value,String.class,SchemaInfo.class));
+ case "properties": return properties(mapBuilder(String.class,SchemaInfo.class).sparse().addAny(value).build());
case "readOnly": return readOnly(toBoolean(value));
case "$ref": return ref(stringify(value));
- case "required": return required(toList(value,String.class));
+ case "required": return required(listBuilder(String.class).sparse().addAny(value).build());
case "title": return title(stringify(value));
case "type": return type(stringify(value));
case "uniqueItems": return uniqueItems(toBoolean(value));
diff --git a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/SecurityScheme.java b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/SecurityScheme.java
index de3b670..5e522fc 100644
--- a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/SecurityScheme.java
+++ b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/SecurityScheme.java
@@ -473,7 +473,7 @@ public class SecurityScheme extends SwaggerElement {
* @return This object (for method chaining).
*/
public SecurityScheme addScopes(Map<String,String> values) {
- scopes = addToMap(scopes, values);
+ scopes = mapBuilder(scopes).sparse().addAll(values).build();
return this;
}
@@ -515,7 +515,7 @@ public class SecurityScheme extends SwaggerElement {
* @return This object (for method chaining).
*/
public SecurityScheme scopes(String json) {
- setScopes(toMap(json, String.class, String.class));
+ setScopes(mapBuilder(String.class,String.class).sparse().addJson(json).build());
return this;
}
@@ -683,7 +683,7 @@ public class SecurityScheme extends SwaggerElement {
case "flow": return flow(stringify(value));
case "in": return in(stringify(value));
case "name": return name(stringify(value));
- case "scopes": return scopes(toMap(value, String.class, String.class));
+ case "scopes": return scopes(mapBuilder(String.class,String.class).sparse().addAny(value).build());
case "tokenUrl": return tokenUrl(stringify(value));
case "type": return type(stringify(value));
default:
diff --git a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Swagger.java b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Swagger.java
index e028260..f55884b 100644
--- a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Swagger.java
+++ b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Swagger.java
@@ -269,7 +269,7 @@ public class Swagger extends SwaggerElement {
* @return This object (for method chaining).
*/
public Swagger addConsumes(Collection<MediaType> values) {
- consumes = addToSet(consumes, values);
+ consumes = setBuilder(consumes).sparse().addAll(values).build();
return this;
}
@@ -311,7 +311,7 @@ public class Swagger extends SwaggerElement {
* @return This object (for method chaining).
*/
public Swagger consumes(MediaType...value) {
- setConsumes(toSet(value, MediaType.class));
+ setConsumes(setBuilder(MediaType.class).sparse().add(value).build());
return this;
}
@@ -327,7 +327,7 @@ public class Swagger extends SwaggerElement {
* @return This object (for method chaining).
*/
public Swagger consumes(String...value) {
- setConsumes(toSet(value, MediaType.class));
+ setConsumes(setBuilder(MediaType.class).sparse().addJson(value).build());
return this;
}
@@ -373,7 +373,7 @@ public class Swagger extends SwaggerElement {
* @return This object (for method chaining).
*/
public Swagger addDefinitions(Map<String,OMap> values) {
- definitions = addToMap(definitions, values);
+ definitions = mapBuilder(definitions).sparse().addAll(values).build();
return this;
}
@@ -388,7 +388,7 @@ public class Swagger extends SwaggerElement {
* @return This object (for method chaining).
*/
public Swagger definition(String name, OMap schema) {
- definitions = addToMap(definitions, name, schema);
+ definitions = mapBuilder(definitions).sparse().add(name, schema).build();
return this;
}
@@ -430,7 +430,7 @@ public class Swagger extends SwaggerElement {
* @return This object (for method chaining).
*/
public Swagger definitions(String json) {
- setDefinitions(toMap(json, String.class, OMap.class));
+ setDefinitions(mapBuilder(String.class,OMap.class).sparse().addJson(json).build());
return this;
}
@@ -698,7 +698,7 @@ public class Swagger extends SwaggerElement {
* @return This object (for method chaining).
*/
public Swagger addParameters(Map<String,ParameterInfo> values) {
- parameters = addToMap(parameters, values);
+ parameters = mapBuilder(parameters).sparse().addAll(values).build();
return this;
}
@@ -713,7 +713,7 @@ public class Swagger extends SwaggerElement {
* @return This object (for method chaining).
*/
public Swagger parameter(String name, ParameterInfo parameter) {
- parameters = addToMap(parameters, name, parameter);
+ parameters = mapBuilder(parameters).sparse().add(name, parameter).build();
return this;
}
@@ -752,7 +752,7 @@ public class Swagger extends SwaggerElement {
* @return This object (for method chaining).
*/
public Swagger parameters(String json) {
- setParameters(toMap(json, String.class, ParameterInfo.class));
+ setParameters(mapBuilder(String.class,ParameterInfo.class).sparse().addJson(json).build());
return this;
}
@@ -783,7 +783,7 @@ public class Swagger extends SwaggerElement {
* <br>Property value is required.
*/
public void setPaths(Map<String,OperationMap> value) {
- paths = newSortedMap(value, PATH_COMPARATOR);
+ paths = mapBuilder(String.class,OperationMap.class).sparse().sorted(PATH_COMPARATOR).addAll(value).build();
}
/**
@@ -798,7 +798,7 @@ public class Swagger extends SwaggerElement {
* @return This object (for method chaining).
*/
public Swagger addPaths(Map<String,OperationMap> values) {
- paths = addToSortedMap(paths, values, PATH_COMPARATOR);
+ paths = mapBuilder(paths).sparse().sorted(PATH_COMPARATOR).addAll(values).build();
return this;
}
@@ -862,9 +862,8 @@ public class Swagger extends SwaggerElement {
* The values to set on this property as JSON.
* @return This object (for method chaining).
*/
- @SuppressWarnings({ "unchecked", "rawtypes" })
public Swagger paths(String json) {
- setPaths(addToMap(new TreeMap(PATH_COMPARATOR), new Object[]{json}, String.class, Map.class, String.class, Operation.class));
+ setPaths(mapBuilder(String.class,OperationMap.class).sparse().sorted(PATH_COMPARATOR).addJson(json).build());
return this;
}
@@ -912,7 +911,7 @@ public class Swagger extends SwaggerElement {
* @return This object (for method chaining).
*/
public Swagger addProduces(Collection<MediaType> values) {
- produces = addToSet(produces, values);
+ produces = setBuilder(produces).sparse().addAll(values).build();
return this;
}
@@ -954,7 +953,7 @@ public class Swagger extends SwaggerElement {
* @return This object (for method chaining).
*/
public Swagger produces(MediaType...value) {
- setProduces(toSet(value, MediaType.class));
+ setProduces(setBuilder(MediaType.class).sparse().add(value).build());
return this;
}
@@ -970,7 +969,7 @@ public class Swagger extends SwaggerElement {
* @return This object (for method chaining).
*/
public Swagger produces(String...value) {
- setProduces(toSet(value, MediaType.class));
+ setProduces(setBuilder(MediaType.class).sparse().addJson(value).build());
return this;
}
@@ -1016,7 +1015,7 @@ public class Swagger extends SwaggerElement {
* @return This object (for method chaining).
*/
public Swagger addResponses(Map<String,ResponseInfo> values) {
- responses = addToMap(responses, values);
+ responses = mapBuilder(responses).sparse().addAll(values).build();
return this;
}
@@ -1031,7 +1030,7 @@ public class Swagger extends SwaggerElement {
* @return This object (for method chaining).
*/
public Swagger response(String name, ResponseInfo response) {
- responses = addToMap(responses, name, response);
+ responses = mapBuilder(responses).sparse().add(name, response).build();
return this;
}
@@ -1073,7 +1072,7 @@ public class Swagger extends SwaggerElement {
* @return This object (for method chaining).
*/
public Swagger responses(String json) {
- setResponses(toMap(json, String.class, ResponseInfo.class));
+ setResponses(mapBuilder(String.class,ResponseInfo.class).sparse().addJson(json).build());
return this;
}
@@ -1133,7 +1132,7 @@ public class Swagger extends SwaggerElement {
* @return This object (for method chaining).
*/
public Swagger addSchemes(Collection<String> values) {
- schemes = addToSet(schemes, values);
+ schemes = setBuilder(schemes).sparse().addAll(values).build();
return this;
}
@@ -1176,7 +1175,7 @@ public class Swagger extends SwaggerElement {
* @return This object (for method chaining).
*/
public Swagger schemes(String...value) {
- setSchemes(toSet(value, String.class));
+ setSchemes(setBuilder(String.class).sparse().addJson(value).build());
return this;
}
@@ -1222,7 +1221,7 @@ public class Swagger extends SwaggerElement {
* @return This object (for method chaining).
*/
public Swagger addSecurity(Collection<Map<String,List<String>>> values) {
- security = addToList(security, values);
+ security = listBuilder(security).sparse().addAll(values).build();
return this;
}
@@ -1282,7 +1281,7 @@ public class Swagger extends SwaggerElement {
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public Swagger security(String json) {
- setSecurity((List)toList(json, Map.class, String.class, List.class, String.class));
+ setSecurity((List)listBuilder(Map.class,String.class,List.class,String.class).sparse().addJson(json).build());
return this;
}
@@ -1328,7 +1327,7 @@ public class Swagger extends SwaggerElement {
* @return This object (for method chaining).
*/
public Swagger addSecurityDefinitions(Map<String,SecurityScheme> values) {
- securityDefinitions = addToMap(securityDefinitions, values);
+ securityDefinitions = mapBuilder(securityDefinitions).sparse().addAll(values).build();
return this;
}
@@ -1343,7 +1342,7 @@ public class Swagger extends SwaggerElement {
* @return This object (for method chaining).
*/
public Swagger securityDefinition(String name, SecurityScheme securityScheme) {
- securityDefinitions = addToMap(securityDefinitions, name, securityScheme);
+ securityDefinitions = mapBuilder(securityDefinitions).sparse().add(name, securityScheme).build();
return this;
}
@@ -1385,7 +1384,7 @@ public class Swagger extends SwaggerElement {
* @return This object (for method chaining).
*/
public Swagger securityDefinitions(String json) {
- setSecurityDefinitions(toMap(json, String.class, SecurityScheme.class));
+ setSecurityDefinitions(mapBuilder(String.class,SecurityScheme.class).sparse().addJson(json).build());
return this;
}
@@ -1497,7 +1496,7 @@ public class Swagger extends SwaggerElement {
* @return This object (for method chaining).
*/
public Swagger addTags(Collection<Tag> values) {
- tags = addToSet(tags, values);
+ tags = setBuilder(tags).sparse().addAll(values).build();
return this;
}
@@ -1539,7 +1538,7 @@ public class Swagger extends SwaggerElement {
* @return This object (for method chaining).
*/
public Swagger tags(String json) {
- setTags(toSet(json, Tag.class));
+ setTags(setBuilder(Tag.class).sparse().addJson(json).build());
return this;
}
@@ -1700,20 +1699,20 @@ public class Swagger extends SwaggerElement {
return this;
switch (property) {
case "basePath": return basePath(stringify(value));
- case "consumes": return consumes(toList(value, MediaType.class));
- case "definitions": return definitions(toMap(value, String.class, OMap.class));
+ case "consumes": return consumes(listBuilder(MediaType.class).sparse().addAny(value).build());
+ case "definitions": return definitions(mapBuilder(String.class,OMap.class).sparse().addAny(value).build());
case "externalDocs": return externalDocs(toType(value, ExternalDocumentation.class));
case "host": return host(stringify(value));
case "info": return info(toType(value, Info.class));
- case "parameters": return parameters(toMap(value, String.class, ParameterInfo.class));
- case "paths": return paths(toMap(value, String.class, OperationMap.class));
- case "produces": return produces(toList(value, MediaType.class));
- case "responses": return responses(toMap(value, String.class, ResponseInfo.class));
- case "schemes": return schemes(toList(value, String.class));
- case "security": return security((List)toList(value, Map.class, String.class, List.class, String.class));
- case "securityDefinitions": return securityDefinitions(toMap(value, String.class, SecurityScheme.class));
+ case "parameters": return parameters(mapBuilder(String.class,ParameterInfo.class).sparse().addAny(value).build());
+ case "paths": return paths(mapBuilder(String.class,OperationMap.class).sparse().addAny(value).build());
+ case "produces": return produces(listBuilder(MediaType.class).sparse().addAny(value).build());
+ case "responses": return responses(mapBuilder(String.class,ResponseInfo.class).sparse().addAny(value).build());
+ case "schemes": return schemes(listBuilder(String.class).sparse().addAny(value).build());
+ case "security": return security((List)listBuilder(Map.class,String.class,List.class,String.class).sparse().addAny(value).build());
+ case "securityDefinitions": return securityDefinitions(mapBuilder(String.class,SecurityScheme.class).sparse().addAny(value).build());
case "swagger": return swagger(stringify(value));
- case "tags": return tags(toList(value, Tag.class));
+ case "tags": return tags(listBuilder(Tag.class).sparse().addAny(value).build());
default:
super.set(property, value);
return this;
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/CollectionUtils.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/CollectionUtils.java
index d952730..25892ed 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/CollectionUtils.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/CollectionUtils.java
@@ -12,35 +12,15 @@
// ***************************************************************************************************************************
package org.apache.juneau.internal;
-import static org.apache.juneau.internal.StringUtils.*;
-import static org.apache.juneau.internal.ConverterUtils.*;
-
import java.lang.reflect.*;
import java.util.*;
-import org.apache.juneau.*;
-import org.apache.juneau.collections.*;
-import org.apache.juneau.parser.*;
-
/**
* Utility methods for collections.
*/
public final class CollectionUtils {
/**
- * Add a value to a list if the value is not null.
- *
- * @param l The list to add to.
- * @param o The element to add.
- * @return The same list.
- */
- public static <T> List<T> addIfNotNull(List<T> l, T o) {
- if (o != null)
- l.add(o);
- return l;
- }
-
- /**
* Returns an iterable over the specified enumeration.
*
* @param e The collection to iterate over.
@@ -107,238 +87,23 @@ public final class CollectionUtils {
}
/**
- * Adds a set of values to an existing list.
- *
- * @param appendTo
- * The list to append to.
- * <br>If <jk>null</jk>, a new {@link ArrayList} will be created.
- * @param values The values to add.
- * @param type The data type of the elements.
- * @param args The generic type arguments of the data type.
- * @return The converted value, or <jk>null</jk> if the input was null.
- */
- public static <T> List<T> addToList(List<T> appendTo, Object[] values, Class<T> type, Type...args) {
- if (values == null)
- return appendTo;
- try {
- List<T> l = appendTo;
- if (appendTo == null)
- l = new ArrayList<>();
- for (Object o : values) {
- if (o != null) {
- if (isJsonArray(o, false)) {
- for (Object o2 : new OList(o.toString()))
- l.add(toType(o2, type, args));
- } else if (o instanceof Collection) {
- for (Object o2 : (Collection<?>)o)
- l.add(toType(o2, type, args));
- } else if (o.getClass().isArray()) {
- for (int i = 0; i < Array.getLength(o); i++)
- l.add(toType(Array.get(o, i), type, args));
- } else {
- l.add(toType(o, type, args));
- }
- }
- }
- return l;
- } catch (ParseException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Adds a set of values to an existing set.
- *
- * @param appendTo
- * The set to append to.
- * <br>If <jk>null</jk>, a new {@link LinkedHashSet} will be created.
- * @param values The values to add.
- * @param type The data type of the elements.
- * @param args The generic type arguments of the data type.
- * @return The converted value, or <jk>null</jk> if the input was null.
- */
- public static <T> Set<T> addToSet(Set<T> appendTo, Object[] values, Class<T> type, Type...args) {
- if (values == null)
- return appendTo;
- try {
- Set<T> l = appendTo;
- if (appendTo == null)
- l = new LinkedHashSet<>();
- for (Object o : values) {
- if (o != null) {
- if (isJsonArray(o, false)) {
- for (Object o2 : new OList(o.toString()))
- l.add(toType(o2, type, args));
- } else if (o instanceof Collection) {
- for (Object o2 : (Collection<?>)o)
- l.add(toType(o2, type, args));
- } else if (o.getClass().isArray()) {
- for (int i = 0; i < Array.getLength(o); i++)
- l.add(toType(Array.get(o, i), type, args));
- } else {
- l.add(toType(o, type, args));
- }
- }
- }
- return l;
- } catch (ParseException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Creates a new list from the specified values.
- *
- * @param values The values to add.
- * @param type The data type of the elements.
- * @param args The generic type arguments of the data type.
- * @return The converted value, or <jk>null</jk> if the input was null.
- */
- public static <T> List<T> toList(Object[] values, Class<T> type, Type...args) {
- return addToList(new ArrayList<T>(), values, type, args);
- }
-
- /**
- * Creates a new list from the specified values.
- *
- * @param value The value to add.
- * @param type The data type of the elements.
- * @param args The generic type arguments of the data type.
- * @return The converted value, or <jk>null</jk> if the input was null.
- */
- public static <T> List<T> toList(Object value, Class<T> type, Type...args) {
- return addToList(new ArrayList<T>(), new Object[]{value}, type, args);
- }
-
- /**
- * Creates a new set from the specified values.
- *
- * @param values The values to add.
- * @param type The data type of the elements.
- * @param args The generic type arguments of the data type.
- * @return The converted value, or <jk>null</jk> if the input was null.
- */
- public static <T> Set<T> toSet(Object[] values, Class<T> type, Type...args) {
- return addToSet(new LinkedHashSet<T>(), values, type, args);
- }
-
- /**
- * Creates a new set from the specified value.
- *
- * @param value The value to add.
- * @param type The data type of the elements.
- * @param args The generic type arguments of the data type.
- * @return The converted value, or <jk>null</jk> if the input was null.
- */
- public static <T> Set<T> toSet(Object value, Class<T> type, Type...args) {
- return addToSet(new LinkedHashSet<T>(), new Object[]{value}, type, args);
- }
-
- /**
- * Adds a set of values to an existing map.
- *
- * @param appendTo
- * The map to append to.
- * <br>If <jk>null</jk>, a new {@link LinkedHashMap} will be created.
- * @param values The values to add.
- * @param keyType The data type of the keys.
- * @param valueType The data type of the values.
- * @param valueTypeArgs The generic type arguments of the data type of the values.
- * @return The converted value, or <jk>null</jk> if the input was null.
- */
- @SuppressWarnings("unchecked")
- public static <K,V> Map<K,V> addToMap(Map<K,V> appendTo, Object[] values, Class<K> keyType, Class<V> valueType, Type...valueTypeArgs) {
- if (values == null)
- return appendTo;
- try {
- Map<K,V> m = appendTo;
- if (m == null)
- m = new LinkedHashMap<>();
- for (Object o : values) {
- if (o != null) {
- if (isJsonObject(o, false)) {
- for (Map.Entry<String,Object> e : OMap.ofJson(o.toString()).entrySet())
- m.put(toType(e.getKey(), keyType), toType(e.getValue(), valueType, valueTypeArgs));
- } else if (o instanceof Map) {
- for (Map.Entry<Object,Object> e : ((Map<Object,Object>)o).entrySet())
- m.put(toType(e.getKey(), keyType), toType(e.getValue(), valueType, valueTypeArgs));
- } else {
- throw new BasicRuntimeException("Invalid object type {0} passed to addToMap()", o.getClass().getName());
- }
- }
- }
- return m.isEmpty() ? null : m;
- } catch (ParseException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Creates a new map from the specified values.
- *
- * @param values The values to add.
- * @param keyType The data type of the keys.
- * @param valueType The data type of the values.
- * @param valueTypeArgs The generic type arguments of the data type of the values.
- * @return The converted value, or <jk>null</jk> if the input was null.
- */
- public static <K,V> Map<K,V> toMap(Object[] values, Class<K> keyType, Class<V> valueType, Type...valueTypeArgs) {
- return addToMap(new LinkedHashMap<>(), values, keyType, valueType, valueTypeArgs);
- }
-
- /**
- * Creates a new map from the specified value.
- *
- * @param values The values to add.
- * @param keyType The data type of the keys.
- * @param valueType The data type of the values.
- * @param valueTypeArgs The generic type arguments of the data type of the values.
- * @return The converted value, or <jk>null</jk> if the input was null.
- */
- public static <K,V> Map<K,V> toMap(Object values, Class<K> keyType, Class<V> valueType, Type...valueTypeArgs) {
- return addToMap(new LinkedHashMap<>(), new Object[]{values}, keyType, valueType, valueTypeArgs);
- }
-
- /**
* Creates a new list from the specified collection.
*
* @param val The value to copy from.
* @return A new {@link ArrayList}, or <jk>null</jk> if the input was null.
*/
- public static <T> AList<T> newList(Collection<T> val) {
- return AList.nullable(val);
+ public static <T> List<T> newList(Collection<T> val) {
+ return val == null ? null : new ArrayList<>(val);
}
/**
- * Creates a new list from the specified array.
- *
- * @param val The value to copy from.
- * @return A new {@link ArrayList}, or <jk>null</jk> if the input was null.
- */
- @SafeVarargs
- public static <T> AList<T> newList(T...val) {
- return AList.of(val);
- }
-
- /**
- * Creates a new unmodifiable list from the specified collection.
- *
- * @param val The value to copy from.
- * @return A new {@link ArrayList}, or <jk>null</jk> if the input was null.
- */
- public static <T> List<T> newUnmodifiableList(Collection<T> val) {
- return Collections.unmodifiableList(newList(val));
- }
-
- /**
- * Creates a new unmodifiable list from the specified array.
+ * Creates a new list from the specified collection.
*
* @param val The value to copy from.
* @return A new {@link ArrayList}, or <jk>null</jk> if the input was null.
*/
- @SafeVarargs
- public static <T> List<T> newUnmodifiableList(T...val) {
- return Collections.unmodifiableList(newList(val));
+ public static <T> List<T> newList(List<T> val) {
+ return val == null ? null : new ArrayList<>(val);
}
/**
@@ -347,78 +112,18 @@ public final class CollectionUtils {
* @param val The value to copy from.
* @return A new {@link LinkedHashSet}, or <jk>null</jk> if the input was null.
*/
- public static <T> ASet<T> newSet(Collection<T> val) {
- return ASet.nullable(val);
+ public static <T> Set<T> newSet(Collection<T> val) {
+ return val == null ? null : new LinkedHashSet<>(val);
}
/**
- * Creates a new set from the specified array.
- *
- * @param val The value to copy from.
- * @return A new {@link LinkedHashSet}, or <jk>null</jk> if the input was null.
- */
- @SafeVarargs
- public static <T> ASet<T> newSet(T...val) {
- return ASet.of(val);
- }
-
- /**
- * Creates a new unmodifiable set from the specified collection.
- *
- * @param val The value to copy from.
- * @return A new {@link LinkedHashSet}, or <jk>null</jk> if the input was null.
- */
- public static <T> Set<T> newUnmodifiableSet(Collection<T> val) {
- return Collections.unmodifiableSet(newSet(val));
- }
-
- /**
- * Creates a new unmodifiable set from the specified array.
+ * Creates a new set from the specified collection.
*
* @param val The value to copy from.
* @return A new {@link LinkedHashSet}, or <jk>null</jk> if the input was null.
*/
- @SafeVarargs
- public static <T> Set<T> newUnmodifiableSet(T...val) {
- return Collections.unmodifiableSet(newSet(val));
- }
-
- /**
- * Copies the specified values into an existing list.
- *
- * @param l
- * The list to add to.
- * <br>If <jk>null</jk>, a new {@link ArrayList} will be created.
- * @param val The values to add.
- * @return The list with values copied into it.
- */
- public static <T> List<T> addToList(List<T> l, Collection<T> val) {
- if (val != null) {
- if (l == null)
- l = new ArrayList<>(val);
- else
- l.addAll(val);
- }
- return l;
- }
-
- /**
- * Copies the specified values into an existing list.
- *
- * @param l
- * The list to add to.
- * <br>If <jk>null</jk>, a new {@link ArrayList} will be created.
- * @param val The values to add.
- * @return The list with values copied into it.
- */
- public static <T> Set<T> addToSet(Set<T> l, Collection<T> val) {
- if (val != null) {
- if (l == null)
- l = new LinkedHashSet<>(val);
- else
- l.addAll(val);
- }
- return l;
+ public static <T> Set<T> newSet(Set<T> val) {
+ return val == null ? null : new LinkedHashSet<>(val);
}
/**
@@ -428,153 +133,73 @@ public final class CollectionUtils {
* @return A new {@link LinkedHashMap}, or <jk>null</jk> if the input was null.
*/
public static <K,V> Map<K,V> newMap(Map<K,V> val) {
- if (val == null)
- return null;
- return new LinkedHashMap<>(val);
- }
-
- /**
- * Creates a new unmodifiable map from the specified map.
- *
- * @param val The value to copy from.
- * @return A new {@link LinkedHashMap}, or <jk>null</jk> if the input was null.
- */
- public static <K,V> Map<K,V> newUnmodifiableMap(Map<K,V> val) {
- return Collections.unmodifiableMap(newMap(val));
- }
-
- /**
- * Copies the specified values into an existing map.
- *
- * @param m
- * The map to add to.
- * <br>If <jk>null</jk>, a new {@link LinkedHashMap} will be created.
- * @param val The values to add.
- * @return The list with values copied into it.
- */
- public static <K,V> Map<K,V> addToMap(Map<K,V> m, Map<K,V> val) {
- if (val != null) {
- if (m == null)
- m = new LinkedHashMap<>(val);
- else
- m.putAll(val);
- }
- return m;
+ return val == null ? null : new LinkedHashMap<>(val);
}
/**
- * Adds a single entry into an existing map.
+ * Instantiates a new builder on top of the specified map.
*
- * @param m
- * The map to add to.
- * <br>If <jk>null</jk>, a new {@link LinkedHashMap} will be created.
- * @param key The entry key.
- * @param value The entry value.
- * @return The list with values copied into it.
+ * @param addTo The map to add to.
+ * @return A new builder on top of the specified map.
*/
- public static <K,V> Map<K,V> addToMap(Map<K,V> m, K key, V value) {
- if (m == null)
- m = new LinkedHashMap<>();
- m.put(key, value);
- return m;
+ public static <K,V> MapBuilder<K,V> mapBuilder(Map<K,V> addTo) {
+ return new MapBuilder<>(addTo);
}
/**
- * Creates a new map from the specified map.
+ * Instantiates a new builder of the specified map type.
*
- * @param val The value to copy from.
- * @param comparator The key comparator to use, or <jk>null</jk> to use natural ordering.
- * @return A new {@link LinkedHashMap}, or <jk>null</jk> if the input was null.
+ * @param keyType The key type.
+ * @param valueType The value type.
+ * @param valueTypeArgs The value type args.
+ * @return A new builder on top of the specified map.
*/
- public static <K,V> Map<K,V> newSortedMap(Map<K,V> val, Comparator<K> comparator) {
- if (val == null)
- return null;
- Map<K,V> m = new TreeMap<>(comparator);
- m.putAll(val);
- return m;
+ public static <K,V> MapBuilder<K,V> mapBuilder(Class<K> keyType, Class<V> valueType, Type...valueTypeArgs) {
+ return new MapBuilder<>(keyType, valueType, valueTypeArgs);
}
/**
- * Creates a case-insensitive ordered set out of the specified string values.
+ * Instantiates a new builder on top of the specified list.
*
- * @param values The values to populate the set with.
- * @return A new ordered set.
+ * @param addTo The list to add to.
+ * @return A new builder on top of the specified list.
*/
- public static Set<String> newSortedCaseInsensitiveSet(String...values) {
- Set<String> s = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER) {
- private static final long serialVersionUID = 1L;
- @Override
- public boolean contains(Object v) {
- return v == null ? false : super.contains(v);
- }
- };
- for (String v : values)
- if (v != null)
- s.add(v);
- return s;
+ public static <E> ListBuilder<E> listBuilder(List<E> addTo) {
+ return new ListBuilder<>(addTo);
}
/**
- * Creates a case-insensitive ordered set out of the specified string values.
+ * Instantiates a new builder of the specified list type.
*
- * @param values
- * A comma-delimited list of the values to populate the set with.
- * @return A new ordered set.
+ * @param elementType The element type.
+ * @param elementTypeArgs The element type args.
+ * @return A new builder on top of the specified list.
*/
- public static Set<String> newSortedCaseInsensitiveSet(String values) {
- return newSortedCaseInsensitiveSet(StringUtils.split(StringUtils.emptyIfNull(values)));
+ public static <E> ListBuilder<E> listBuilder(Class<E> elementType, Type...elementTypeArgs) {
+ return new ListBuilder<>(elementType, elementTypeArgs);
}
/**
- * Same as {@link #newSortedCaseInsensitiveSet(String)} but makes the set unmodifiable.
+ * Instantiates a new builder on top of the specified set.
*
- * @param values
- * A comma-delimited list of the values to populate the set with.
- * @return A new ordered set.
+ * @param addTo The set to add to.
+ * @return A new builder on top of the specified set.
*/
- public static Set<String> newUnmodifiableSortedCaseInsensitiveSet(String values) {
- return Collections.unmodifiableSet(newSortedCaseInsensitiveSet(StringUtils.split(StringUtils.emptyIfNull(values))));
+ public static <E> SetBuilder<E> setBuilder(Set<E> addTo) {
+ return new SetBuilder<>(addTo);
}
/**
- * Copies the specified values into an existing map.
+ * Instantiates a new builder of the specified set.
*
- * @param m
- * The map to add to.
- * <br>If <jk>null</jk>, a new {@link LinkedHashMap} will be created.
- * @param val The values to add.
- * @param comparator The key comparator to use, or <jk>null</jk> to use natural ordering.
- * @return The list with values copied into it.
+ * @param elementType The element type.
+ * @param elementTypeArgs The element type args.
+ * @return A new builder on top of the specified set.
*/
- public static <K,V> Map<K,V> addToSortedMap(Map<K,V> m, Map<K,V> val, Comparator<K> comparator) {
- if (val != null) {
- if (m == null) {
- m = new TreeMap<>(comparator);
- m.putAll(val);
- } else {
- m.putAll(val);
- }
- }
- return m;
+ public static <E> SetBuilder<E> setBuilder(Class<E> elementType, Type...elementTypeArgs) {
+ return new SetBuilder<>(elementType, elementTypeArgs);
}
- /**
- * Adds a single entry into an existing map.
- *
- * @param m
- * The map to add to.
- * <br>If <jk>null</jk>, a new {@link LinkedHashMap} will be created.
- * @param key The entry key.
- * @param value The entry value.
- * @param comparator The key comparator to use, or <jk>null</jk> to use natural ordering.
- * @return The list with values copied into it.
- */
- public static <K,V> Map<K,V> addToSortedMap(Map<K,V> m, K key, V value, Comparator<K> comparator) {
- if (m == null)
- m = new TreeMap<>(comparator);
- m.put(key, value);
- return m;
- }
/**
* Simple passthrough to {@link Collections#emptySet()}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ListBuilder.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ListBuilder.java
new file mode 100644
index 0000000..1cb5791
--- /dev/null
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/ListBuilder.java
@@ -0,0 +1,234 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance *
+// * with the License. You may obtain a copy of the License at *
+// * *
+// * http://www.apache.org/licenses/LICENSE-2.0 *
+// * *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the *
+// * specific language governing permissions and limitations under the License. *
+// ***************************************************************************************************************************
+package org.apache.juneau.internal;
+
+import static org.apache.juneau.internal.ConverterUtils.*;
+import static org.apache.juneau.internal.StringUtils.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.apache.juneau.collections.*;
+import org.apache.juneau.parser.*;
+
+/**
+ * Builder for lists.
+ *
+ * @param <E> Element type.
+ */
+public class ListBuilder<E> {
+
+ private List<E> list;
+ private boolean unmodifiable = false, sparse = false;
+ private Comparator<E> comparator;
+
+ private Class<E> elementType;
+ private Type[] elementTypeArgs;
+
+ /**
+ * Constructor.
+ *
+ * @param elementType The element type.
+ * @param elementTypeArgs The element type generic arguments if there are any.
+ */
+ public ListBuilder(Class<E> elementType, Type...elementTypeArgs) {
+ this.elementType = elementType;
+ this.elementTypeArgs = elementTypeArgs;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param addTo The list to add to.
+ */
+ public ListBuilder(List<E> addTo) {
+ this.list = addTo;
+ }
+
+ /**
+ * Builds the list.
+ *
+ * @return A list conforming to the settings on this builder.
+ */
+ public List<E> build() {
+ if (sparse) {
+ if (list != null && list.isEmpty())
+ list = null;
+ } else {
+ if (list == null)
+ list = new ArrayList<>(0);
+ }
+ if (list != null) {
+ if (comparator != null)
+ Collections.sort(list, comparator);
+ if (unmodifiable)
+ list = Collections.unmodifiableList(list);
+ }
+ return list;
+ }
+
+ /**
+ * When specified, the {@link #build()} method will return <jk>null</jk> if the list is empty.
+ *
+ * <p>
+ * Otherwise {@link #build()} will never return <jk>null</jk>.
+ *
+ * @return This object (for method chaining).
+ */
+ public ListBuilder<E> sparse() {
+ this.sparse = true;
+ return this;
+ }
+
+ /**
+ * When specified, {@link #build()} will return an unmodifiable list.
+ *
+ * @return This object (for method chaining).
+ */
+ public ListBuilder<E> unmodifiable() {
+ this.unmodifiable = true;
+ return this;
+ }
+
+ /**
+ * Forces the existing list to be copied instead of appended to.
+ *
+ * @return This object (for method chaining).
+ */
+ public ListBuilder<E> copy() {
+ if (list != null)
+ list = new ArrayList<>(list);
+ return this;
+ }
+
+ /**
+ * Sorts the contents of the list.
+ *
+ * @return This object (for method chaining).
+ */
+ @SuppressWarnings("unchecked")
+ public ListBuilder<E> sorted() {
+ return sorted((Comparator<E>)Comparator.naturalOrder());
+ }
+
+ /**
+ * Sorts the contents of the list using the specified comparator.
+ *
+ * @param comparator The comparator to use for sorting.
+ * @return This object (for method chaining).
+ */
+ public ListBuilder<E> sorted(Comparator<E> comparator) {
+ this.comparator = comparator;
+ return this;
+ }
+
+ /**
+ * Appends the contents of the specified collection into this list.
+ *
+ * <p>
+ * This is a no-op if the value is <jk>null</jk>.
+ *
+ * @param value The collection to add to this list.
+ * @return This object (for method chaining).
+ */
+ public ListBuilder<E> addAll(Collection<E> value) {
+ if (value != null) {
+ if (list == null)
+ list = new LinkedList<>(value);
+ else
+ list.addAll(value);
+ }
+ return this;
+ }
+
+ /**
+ * Adds a single value to this list.
+ *
+ * @param value The value to add to this list.
+ * @return This object (for method chaining).
+ */
+ public ListBuilder<E> add(E value) {
+ if (list == null)
+ list = new ArrayList<>();
+ list.add(value);
+ return this;
+ }
+
+ /**
+ * Adds multiple values to this list.
+ *
+ * @param values The values to add to this list.
+ * @return This object (for method chaining).
+ */
+ @SuppressWarnings("unchecked")
+ public ListBuilder<E> add(E...values) {
+ for (E v : values)
+ add(v);
+ return this;
+ }
+
+ /**
+ * Adds entries to this list via JSON array strings.
+ *
+ * @param values The JSON array strings to parse and add to this list.
+ * @return This object (for method chaining).
+ */
+ public ListBuilder<E> addJson(String...values) {
+ return addAny((Object[])values);
+ }
+
+ /**
+ * Adds arbitrary values to this list.
+ *
+ * <p>
+ * Objects can be any of the following:
+ * <ul>
+ * <li>The same type or convertible to the element type of this list.
+ * <li>Collections or arrays of anything on this list.
+ * <li>JSON array strings parsed and convertible to the element type of this list.
+ * </ul>
+ *
+ * @param values The values to add.
+ * @return This object (for method chaining).
+ */
+ @SuppressWarnings("unchecked")
+ public ListBuilder<E> addAny(Object...values) {
+ if (elementType == null)
+ throw new RuntimeException("Unknown element type. Cannot use this method.");
+ try {
+ if (values != null) {
+ for (Object o : values) {
+ if (o != null) {
+ if (o instanceof Collection) {
+ for (Object o2 : (Collection<?>)o)
+ addAny(o2);
+ } else if (o.getClass().isArray()) {
+ for (int i = 0; i < Array.getLength(o); i++)
+ addAny(Array.get(o, i));
+ } else if (isJsonArray(o, false)) {
+ for (Object o2 : new OList(o.toString()))
+ addAny(o2);
+ } else if (elementType.isInstance(o)) {
+ add((E)o);
+ } else {
+ add(toType(o, elementType, elementTypeArgs));
+ }
+ }
+ }
+ }
+ } catch (ParseException e) {
+ throw new RuntimeException(e);
+ }
+ return this;
+ }
+}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/MapBuilder.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/MapBuilder.java
new file mode 100644
index 0000000..d27ddb4
--- /dev/null
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/MapBuilder.java
@@ -0,0 +1,222 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance *
+// * with the License. You may obtain a copy of the License at *
+// * *
+// * http://www.apache.org/licenses/LICENSE-2.0 *
+// * *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the *
+// * specific language governing permissions and limitations under the License. *
+// ***************************************************************************************************************************
+package org.apache.juneau.internal;
+
+import static org.apache.juneau.internal.ConverterUtils.*;
+import static org.apache.juneau.internal.StringUtils.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.collections.*;
+import org.apache.juneau.parser.*;
+
+/**
+ * Builder for maps.
+ *
+ * @param <K> Key type.
+ * @param <V> Value type.
+ */
+public class MapBuilder<K,V> {
+
+ private Map<K,V> map;
+ private boolean unmodifiable = false, sparse = false;
+ private Comparator<K> comparator = null;
+
+ private Class<K> keyType;
+ private Class<V> valueType;
+ private Type[] valueTypeArgs;
+
+ /**
+ * Constructor.
+ *
+ * @param keyType The key type.
+ * @param valueType The value type.
+ * @param valueTypeArgs The value type generic arguments if there are any.
+ */
+ public MapBuilder(Class<K> keyType, Class<V> valueType, Type...valueTypeArgs) {
+ this.keyType = keyType;
+ this.valueType = valueType;
+ this.valueTypeArgs = valueTypeArgs;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param addTo The map to add to.
+ */
+ public MapBuilder(Map<K,V> addTo) {
+ this.map = addTo;
+ }
+
+ /**
+ * Builds the map.
+ *
+ * @return A map conforming to the settings on this builder.
+ */
+ public Map<K,V> build() {
+ if (sparse) {
+ if (map != null && map.isEmpty())
+ map = null;
+ } else {
+ if (map == null)
+ map = new LinkedHashMap<>();
+ }
+ if (map != null) {
+ if (comparator != null) {
+ Map<K,V> m2 = new TreeMap<>(comparator);
+ m2.putAll(map);
+ map = m2;
+ }
+ if (unmodifiable)
+ map = Collections.unmodifiableMap(map);
+ }
+ return map;
+ }
+
+ /**
+ * When specified, the {@link #build()} method will return <jk>null</jk> if the map is empty.
+ *
+ * <p>
+ * Otherwise {@link #build()} will never return <jk>null</jk>.
+ *
+ * @return This object (for method chaining).
+ */
+ public MapBuilder<K,V> sparse() {
+ this.sparse = true;
+ return this;
+ }
+
+ /**
+ * When specified, {@link #build()} will return an unmodifiable map.
+ *
+ * @return This object (for method chaining).
+ */
+ public MapBuilder<K,V> unmodifiable() {
+ this.unmodifiable = true;
+ return this;
+ }
+
+ /**
+ * Forces the existing set to be copied instead of appended to.
+ *
+ * @return This object (for method chaining).
+ */
+ public MapBuilder<K,V> copy() {
+ if (map != null)
+ map = new LinkedHashMap<>(map);
+ return this;
+ }
+
+ /**
+ * Converts the set into a {@link SortedMap}.
+ *
+ * @return This object (for method chaining).
+ */
+ @SuppressWarnings("unchecked")
+ public MapBuilder<K,V> sorted() {
+ return sorted((Comparator<K>)Comparator.naturalOrder());
+ }
+
+ /**
+ * Converts the set into a {@link SortedMap} using the specified comparator.
+ *
+ * @param comparator The comparator to use for sorting.
+ * @return This object (for method chaining).
+ */
+ public MapBuilder<K,V> sorted(Comparator<K> comparator) {
+ this.comparator = comparator;
+ return this;
+ }
+
+ /**
+ * Appends the contents of the specified map into this map.
+ *
+ * <p>
+ * This is a no-op if the value is <jk>null</jk>.
+ *
+ * @param value The map to add to this map.
+ * @return This object (for method chaining).
+ */
+ public MapBuilder<K,V> addAll(Map<K,V> value) {
+ if (value != null) {
+ if (map == null)
+ map = new LinkedHashMap<>(value);
+ else
+ map.putAll(value);
+ }
+ return this;
+ }
+
+ /**
+ * Adds a single entry to this map.
+ *
+ * @param key The map key.
+ * @param value The map value.
+ * @return This object (for method chaining).
+ */
+ public MapBuilder<K,V> add(K key, V value) {
+ if (map == null)
+ map = new LinkedHashMap<>();
+ map.put(key, value);
+ return this;
+ }
+
+ /**
+ * Adds entries to this list via JSON object strings.
+ *
+ * @param values The JSON object strings to parse and add to this list.
+ * @return This object (for method chaining).
+ */
+ public MapBuilder<K,V> addJson(String...values) {
+ return addAny((Object[])values);
+ }
+
+ /**
+ * Adds arbitrary values to this list.
+ *
+ * <p>
+ * Objects can be any of the following:
+ * <ul>
+ * <li>Maps of key/value types convertible to the key/value types of this map.
+ * <li>JSON object strings parsed and convertible to the key/value types of this map.
+ * </ul>
+ *
+ * @param values The values to add.
+ * @return This object (for method chaining).
+ */
+ @SuppressWarnings("unchecked")
+ public MapBuilder<K,V> addAny(Object...values) {
+ if (keyType == null || valueType == null)
+ throw new RuntimeException("Unknown key and value types. Cannot use this method.");
+ try {
+ for (Object o : values) {
+ if (o != null) {
+ if (o instanceof Map) {
+ for (Map.Entry<Object,Object> e : ((Map<Object,Object>)o).entrySet())
+ add(toType(e.getKey(), keyType), toType(e.getValue(), valueType, valueTypeArgs));
+ } else if (isJsonObject(o, false)) {
+ for (Map.Entry<String,Object> e : OMap.ofJson(o.toString()).entrySet())
+ add(toType(e.getKey(), keyType), toType(e.getValue(), valueType, valueTypeArgs));
+ } else {
+ throw new BasicRuntimeException("Invalid object type {0} passed to addAny()", o.getClass().getName());
+ }
+ }
+ }
+ } catch (ParseException e) {
+ throw new RuntimeException(e);
+ }
+ return this;
+ }
+}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/SetBuilder.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/SetBuilder.java
new file mode 100644
index 0000000..add89ca
--- /dev/null
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/SetBuilder.java
@@ -0,0 +1,237 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance *
+// * with the License. You may obtain a copy of the License at *
+// * *
+// * http://www.apache.org/licenses/LICENSE-2.0 *
+// * *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the *
+// * specific language governing permissions and limitations under the License. *
+// ***************************************************************************************************************************
+package org.apache.juneau.internal;
+
+import static org.apache.juneau.internal.ConverterUtils.*;
+import static org.apache.juneau.internal.StringUtils.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.apache.juneau.collections.*;
+import org.apache.juneau.parser.*;
+
+/**
+ * Builder for sets.
+ *
+ * @param <E> Element type.
+ */
+public class SetBuilder<E> {
+
+ private Set<E> set;
+ private boolean unmodifiable, sparse;
+ private Comparator<E> comparator;
+
+ private Class<E> elementType;
+ private Type[] elementTypeArgs;
+
+ /**
+ * Constructor.
+ *
+ * @param elementType The element type.
+ * @param elementTypeArgs The element type generic arguments if there are any.
+ */
+ public SetBuilder(Class<E> elementType, Type...elementTypeArgs) {
+ this.elementType = elementType;
+ this.elementTypeArgs = elementTypeArgs;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param addTo The set to add to.
+ */
+ public SetBuilder(Set<E> addTo) {
+ this.set = addTo;
+ }
+
+ /**
+ * Builds the set.
+ *
+ * @return A set conforming to the settings on this builder.
+ */
+ public Set<E> build() {
+ if (sparse) {
+ if (set != null && set.isEmpty())
+ set = null;
+ } else {
+ if (set == null)
+ set = new LinkedHashSet<>(0);
+ }
+ if (set != null) {
+ if (comparator != null) {
+ Set<E> s = new TreeSet<>(comparator);
+ s.addAll(set);
+ set = s;
+ }
+ if (unmodifiable)
+ set = Collections.unmodifiableSet(set);
+ }
+ return set;
+ }
+
+ /**
+ * When specified, the {@link #build()} method will return <jk>null</jk> if the set is empty.
+ *
+ * <p>
+ * Otherwise {@link #build()} will never return <jk>null</jk>.
+ *
+ * @return This object (for method chaining).
+ */
+ public SetBuilder<E> sparse() {
+ this.sparse = true;
+ return this;
+ }
+
+ /**
+ * When specified, {@link #build()} will return an unmodifiable set.
+ *
+ * @return This object (for method chaining).
+ */
+ public SetBuilder<E> unmodifiable() {
+ this.unmodifiable = true;
+ return this;
+ }
+
+ /**
+ * Forces the existing set to be copied instead of appended to.
+ *
+ * @return This object (for method chaining).
+ */
+ public SetBuilder<E> copy() {
+ if (set != null)
+ set = new LinkedHashSet<>(set);
+ return this;
+ }
+
+ /**
+ * Converts the set into a {@link SortedSet}.
+ *
+ * @return This object (for method chaining).
+ */
+ @SuppressWarnings("unchecked")
+ public SetBuilder<E> sorted() {
+ return sorted((Comparator<E>)Comparator.naturalOrder());
+ }
+
+ /**
+ * Converts the set into a {@link SortedSet} using the specified comparator.
+ *
+ * @param comparator The comparator to use for sorting.
+ * @return This object (for method chaining).
+ */
+ public SetBuilder<E> sorted(Comparator<E> comparator) {
+ this.comparator = comparator;
+ return this;
+ }
+
+ /**
+ * Appends the contents of the specified collection into this set.
+ *
+ * <p>
+ * This is a no-op if the value is <jk>null</jk>.
+ *
+ * @param value The collection to add to this set.
+ * @return This object (for method chaining).
+ */
+ public SetBuilder<E> addAll(Collection<E> value) {
+ if (value != null) {
+ if (set == null)
+ set = new LinkedHashSet<>(value);
+ else
+ set.addAll(value);
+ }
+ return this;
+ }
+
+ /**
+ * Adds a single value to this set.
+ *
+ * @param value The value to add to this set.
+ * @return This object (for method chaining).
+ */
+ public SetBuilder<E> add(E value) {
+ if (set == null)
+ set = new LinkedHashSet<>();
+ set.add(value);
+ return this;
+ }
+
+ /**
+ * Adds multiple values to this set.
+ *
+ * @param values The values to add to this set.
+ * @return This object (for method chaining).
+ */
+ @SuppressWarnings("unchecked")
+ public SetBuilder<E> add(E...values) {
+ for (E v : values)
+ add(v);
+ return this;
+ }
+
+ /**
+ * Adds entries to this set via JSON array strings.
+ *
+ * @param values The JSON array strings to parse and add to this set.
+ * @return This object (for method chaining).
+ */
+ public SetBuilder<E> addJson(String...values) {
+ return addAny((Object[])values);
+ }
+
+ /**
+ * Adds arbitrary values to this set.
+ *
+ * <p>
+ * Objects can be any of the following:
+ * <ul>
+ * <li>The same type or convertible to the element type of this set.
+ * <li>Collections or arrays of anything on this set.
+ * <li>JSON array strings parsed and convertible to the element type of this set.
+ * </ul>
+ *
+ * @param values The values to add.
+ * @return This object (for method chaining).
+ */
+ @SuppressWarnings("unchecked")
+ public SetBuilder<E> addAny(Object...values) {
+ if (elementType == null)
+ throw new RuntimeException("Unknown element type. Cannot use this method.");
+ try {
+ if (values != null) {
+ for (Object o : values) {
+ if (o != null) {
+ if (o instanceof Collection) {
+ for (Object o2 : (Collection<?>)o)
+ addAny(o2);
+ } else if (o.getClass().isArray()) {
+ for (int i = 0; i < Array.getLength(o); i++)
+ addAny(Array.get(o, i));
+ } else if (isJsonArray(o, false)) {
+ for (Object o2 : new OList(o.toString()))
+ addAny(o2);
+ } else if (elementType.isInstance(o)) {
+ add((E)o);
+ } else {
+ add(toType(o, elementType, elementTypeArgs));
+ }
+ }
+ }
+ }
+ } catch (ParseException e) {
+ throw new RuntimeException(e);
+ }
+ return this;
+ }
+}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/mstat/ThrownStats.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/mstat/ThrownStats.java
index 2d54151..eb224e4 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/mstat/ThrownStats.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/mstat/ThrownStats.java
@@ -53,7 +53,7 @@ public class ThrownStats implements Cloneable {
this.guid = new Random().nextLong();
this.thrownClass = builder.throwable.getClass();
this.firstMessage = builder.throwable.getMessage();
- this.stackTrace = newUnmodifiableList(builder.stackTrace);
+ this.stackTrace = listBuilder(builder.stackTrace).copy().unmodifiable().build();
this.causedBy = ofNullable(builder.causedBy);
this.hash = builder.hash;
this.count = new AtomicInteger(0);
@@ -69,7 +69,7 @@ public class ThrownStats implements Cloneable {
this.guid = x.guid;
this.thrownClass = x.thrownClass;
this.firstMessage = x.firstMessage;
- this.stackTrace = newUnmodifiableList(x.stackTrace);
+ this.stackTrace = listBuilder(x.stackTrace).copy().unmodifiable().build();
this.causedBy = Optional.ofNullable(x.causedBy.isPresent() ? x.causedBy.get().clone() : null);
this.hash = x.hash;
this.count = new AtomicInteger(x.count.get());
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java
index d5d4a8b..862ba2f 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java
@@ -14,7 +14,6 @@ package org.apache.juneau.reflect;
import static org.apache.juneau.internal.StringUtils.*;
import static org.apache.juneau.reflect.ReflectFlags.*;
-import static org.apache.juneau.internal.CollectionUtils.*;
import static org.apache.juneau.internal.ObjectUtils.*;
import java.lang.annotation.*;
@@ -2479,6 +2478,12 @@ public final class ClassInfo {
}
}
+ private static <T> List<T> addIfNotNull(List<T> l, T o) {
+ if (o != null)
+ l.add(o);
+ return l;
+ }
+
//-----------------------------------------------------------------------------------------------------------------
// Other
//-----------------------------------------------------------------------------------------------------------------
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 e5ec8ff..4887238 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
@@ -13,7 +13,6 @@
package org.apache.juneau.rest;
import static javax.servlet.http.HttpServletResponse.*;
-import static org.apache.juneau.internal.CollectionUtils.*;
import static org.apache.juneau.internal.ObjectUtils.*;
import static org.apache.juneau.internal.IOUtils.*;
import static org.apache.juneau.internal.StringUtils.*;
@@ -51,6 +50,7 @@ import org.apache.juneau.http.*;
import org.apache.juneau.http.annotation.Response;
import org.apache.juneau.httppart.*;
import org.apache.juneau.httppart.bean.*;
+import org.apache.juneau.internal.*;
import org.apache.juneau.json.*;
import org.apache.juneau.jsonschema.*;
import org.apache.juneau.marshall.*;
@@ -3526,9 +3526,9 @@ public class RestContext extends BeanContext {
uriRelativity = getProperty(REST_uriRelativity, UriRelativity.class, UriRelativity.RESOURCE);
allowBodyParam = ! getBooleanProperty(REST_disableAllowBodyParam);
- allowedHeaderParams = newUnmodifiableSortedCaseInsensitiveSet(getStringPropertyWithNone(REST_allowedHeaderParams, "Accept,Content-Type"));
- allowedMethodParams = newUnmodifiableSortedCaseInsensitiveSet(getStringPropertyWithNone(REST_allowedMethodParams, "HEAD,OPTIONS"));
- allowedMethodHeaders = newUnmodifiableSortedCaseInsensitiveSet(getStringPropertyWithNone(REST_allowedMethodHeaders, ""));
+ allowedHeaderParams = newCaseInsensitiveSet(getStringPropertyWithNone(REST_allowedHeaderParams, "Accept,Content-Type"));
+ allowedMethodParams = newCaseInsensitiveSet(getStringPropertyWithNone(REST_allowedMethodParams, "HEAD,OPTIONS"));
+ allowedMethodHeaders = newCaseInsensitiveSet(getStringPropertyWithNone(REST_allowedMethodHeaders, ""));
renderResponseStackTraces = getBooleanProperty(REST_renderResponseStackTraces);
clientVersionHeader = getStringProperty(REST_clientVersionHeader, "X-Client-Version");
@@ -3580,6 +3580,19 @@ public class RestContext extends BeanContext {
return new RestOperationInvoker(m, findHookMethodParams(m, getBeanFactory()), getMethodExecStats(m));
}
+ private Set<String> newCaseInsensitiveSet(String value) {
+ Set<String> s = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER) {
+ private static final long serialVersionUID = 1L;
+ @Override
+ public boolean contains(Object v) {
+ return v == null ? false : super.contains(v);
+ }
+ };
+ for (String v : StringUtils.split(value))
+ s.add(v);
+ return Collections.unmodifiableSet(s);
+ }
+
/**
* Instantiates the bean factory for this REST resource.
*
diff --git a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/HeaderInfo_Test.java b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/HeaderInfo_Test.java
index 0fa39f4..0066e23 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/HeaderInfo_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/HeaderInfo_Test.java
@@ -308,7 +308,7 @@ public class HeaderInfo_Test {
assertObject(t._enum()).isType(Set.class).asJson().is("['foo','bar']");
t._enum(new Object[0]);
- assertObject(t._enum()).isType(Set.class).asJson().is("[]");
+ assertObject(t._enum()).isNull();
t._enum((Collection<Object>)null);
assertObject(t._enum()).isNull();
@@ -458,7 +458,7 @@ public class HeaderInfo_Test {
assertObject(t).asJson().is("{description:'d',type:'j',format:'g',items:{type:'h'},collectionFormat:'c','default':'a',maximum:123.0,exclusiveMaximum:true,minimum:123.0,exclusiveMinimum:true,maxLength:123,minLength:123,pattern:'i',maxItems:123,minItems:123,uniqueItems:true,'enum':['b'],multipleOf:123.0,'$ref':'ref',example:'e'}");
assertObject(t.get("default", Object.class)).isType(StringBuilder.class).asString().is("a");
- assertObject(t.get("enum", Object.class)).isType(Set.class).asString().is("['b']");
+ assertObject(t.get("enum", Object.class)).isType(Set.class).asJson().is("['b']");
assertObject(t.get("collectionFormat", Object.class)).isType(String.class).is("c");
assertObject(t.get("description", Object.class)).isType(String.class).is("d");
assertObject(t.get("example", Object.class)).isType(StringBuilder.class).asString().is("e");
diff --git a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Swagger_Test.java b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Swagger_Test.java
index 4de8d32..96e8381 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Swagger_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/dto/swagger/Swagger_Test.java
@@ -178,7 +178,7 @@ public class Swagger_Test {
assertObject(t.paths()).isType(Map.class).asJson().is("{foo:{bar:{summary:'baz'}}}");
t.paths(AMap.create());
- assertObject(t.paths()).isType(Map.class).asJson().is("{}");
+ assertObject(t.paths()).isNull();
t.paths((Map<String,OperationMap>)null);
assertObject(t.paths()).isNull();
diff --git a/juneau-utest/src/test/java/org/apache/juneau/utils/CollectionUtilsTest.java b/juneau-utest/src/test/java/org/apache/juneau/utils/CollectionUtilsTest.java
deleted file mode 100755
index c9ac26e..0000000
--- a/juneau-utest/src/test/java/org/apache/juneau/utils/CollectionUtilsTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-// ***************************************************************************************************************************
-// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file *
-// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file *
-// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance *
-// * with the License. You may obtain a copy of the License at *
-// * *
-// * http://www.apache.org/licenses/LICENSE-2.0 *
-// * *
-// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an *
-// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the *
-// * specific language governing permissions and limitations under the License. *
-// ***************************************************************************************************************************
-package org.apache.juneau.utils;
-
-import static org.apache.juneau.internal.CollectionUtils.*;
-import static org.junit.Assert.*;
-import static org.junit.runners.MethodSorters.*;
-
-import java.util.*;
-
-import org.apache.commons.lang3.*;
-import org.junit.*;
-
-@FixMethodOrder(NAME_ASCENDING)
-public class CollectionUtilsTest {
-
- private String[] strings(String s) {
- return StringUtils.split(s, ',');
- }
-
- @Test
- public void testSortedCaseInsensitiveSet() {
- Set<String> s = newSortedCaseInsensitiveSet("foo,Bar,BAZ");
- for (String ss : strings("foo,Foo,FOO,bar,Bar,BAR,baz,Baz,BAZ"))
- assertTrue(s.contains(ss));
- for (String ss : strings("qux"))
- assertFalse(s.contains(ss));
- }
-
- @Test
- public void testSortedCaseInsensitiveSet_empty() {
- Set<String> s = newSortedCaseInsensitiveSet("");
- assertFalse(s.contains("foo"));
- assertFalse(s.contains(""));
- assertFalse(s.contains(null));
- }
-
- @Test
- public void testSortedCaseInsensitiveSet_null() {
- String ss = null;
- Set<String> s = newSortedCaseInsensitiveSet(ss);
- assertFalse(s.contains("foo"));
- assertFalse(s.contains(""));
- assertFalse(s.contains(null));
- }
-
- @Test
- public void testSortedCaseInsensitiveSet_containsNull() {
- Set<String> s = newSortedCaseInsensitiveSet(null, "foo");
- assertTrue(s.contains("foo"));
- assertFalse(s.contains(""));
- assertFalse(s.contains(null));
- }
-}