From a734365dfb4ddd0eba8c6339d3921d816acdfb6d Mon Sep 17 00:00:00 2001 From: "hbn.king" Date: Wed, 27 Dec 2023 17:23:25 +0800 Subject: [PATCH] try release icefrog --- .../codecs/internal/BsonTypeCodecMap.java | 6 +- .../mars/codecs/pojo/MarsBuilderHelper.java | 9 +- .../mars/codecs/pojo/annotations/Entity.java | 4 +- .../codecs/AggregationCodecProvider.java | 6 +- .../mars/core/aggregation/stages/Sort.java | 16 +- .../whaleal/mars/core/domain/PageRequest.java | 4 +- .../com/whaleal/mars/core/domain/Sort.java | 18 +- .../mars/core/gridfs/GridFsOperations.java | 6 +- .../com/whaleal/mars/core/index/Index.java | 18 +- .../core/messaging/ChangeStreamOptions.java | 16 +- .../core/messaging/ChangeStreamRequest.java | 38 +- .../whaleal/mars/core/query/Collation.java | 19 +- .../com/whaleal/mars/core/query/Meta.java | 6 +- .../com/whaleal/mars/core/query/Query.java | 24 +- .../whaleal/mars/core/query/TextCriteria.java | 6 +- .../com/whaleal/mars/core/query/Update.java | 20 +- .../core/validation/CriteriaValidator.java | 6 +- .../core/validation/DocumentValidator.java | 2 +- .../mars/monitor/CollStatsMetrics.java | 2 +- .../mars/monitor/CollTimeSeriesMetrics.java | 2 +- .../mars/monitor/ConnPoolStatsMetrics.java | 2 +- .../whaleal/mars/monitor/DocumentMetrics.java | 2 +- .../mars/monitor/OperationCounters.java | 4 +- .../mars/monitor/QueryExecutorMetrics.java | 2 +- .../mars/monitor/ReplicationInfoMetrics.java | 2 +- .../com/whaleal/mars/monitor/ServerInfo.java | 2 +- .../com/whaleal/mars/monitor/TTLMetrics.java | 2 +- .../mars/monitor/TransactionMetrics.java | 2 +- .../com/whaleal/mars/session/Datastore.java | 3 +- .../whaleal/mars/session/DatastoreImpl.java | 106 +- .../java/com/whaleal/mars/util/Assert.java | 3 +- .../com/whaleal/mars/util/ObjectUtil.java | 1427 +++++++++++++++++ 32 files changed, 1609 insertions(+), 176 deletions(-) create mode 100644 mars-core/src/main/java/com/whaleal/mars/util/ObjectUtil.java diff --git a/mars-core/src/main/java/com/whaleal/mars/codecs/internal/BsonTypeCodecMap.java b/mars-core/src/main/java/com/whaleal/mars/codecs/internal/BsonTypeCodecMap.java index 175195ab..7123e306 100644 --- a/mars-core/src/main/java/com/whaleal/mars/codecs/internal/BsonTypeCodecMap.java +++ b/mars-core/src/main/java/com/whaleal/mars/codecs/internal/BsonTypeCodecMap.java @@ -29,7 +29,7 @@ */ package com.whaleal.mars.codecs.internal; -import com.whaleal.icefrog.core.lang.Precondition; +import com.whaleal.mars.util.Assert; import org.bson.BsonType; import org.bson.codecs.Codec; import org.bson.codecs.configuration.CodecConfigurationException; @@ -42,8 +42,8 @@ public class BsonTypeCodecMap { private final Codec[] codecs = new Codec[256]; public BsonTypeCodecMap(BsonTypeClassMap bsonTypeClassMap, CodecRegistry codecRegistry) { - this.bsonTypeClassMap = (BsonTypeClassMap) Precondition.notNull("bsonTypeClassMap", bsonTypeClassMap); - Precondition.notNull("codecRegistry", codecRegistry); + this.bsonTypeClassMap = (BsonTypeClassMap) Assert.notNull(bsonTypeClassMap,"bsonTypeClassMap"); + Assert.notNull(codecRegistry,"codecRegistry"); Iterator var3 = bsonTypeClassMap.keys().iterator(); while (var3.hasNext()) { diff --git a/mars-core/src/main/java/com/whaleal/mars/codecs/pojo/MarsBuilderHelper.java b/mars-core/src/main/java/com/whaleal/mars/codecs/pojo/MarsBuilderHelper.java index a9676519..fcabe340 100755 --- a/mars-core/src/main/java/com/whaleal/mars/codecs/pojo/MarsBuilderHelper.java +++ b/mars-core/src/main/java/com/whaleal/mars/codecs/pojo/MarsBuilderHelper.java @@ -31,12 +31,13 @@ import com.whaleal.icefrog.core.util.ClassUtil; +import com.whaleal.mars.util.Assert; import java.lang.annotation.Annotation; import java.lang.reflect.*; import java.util.*; -import static com.whaleal.icefrog.core.lang.Precondition.notNull; + import static java.lang.String.format; import static java.lang.reflect.Modifier.isProtected; import static java.lang.reflect.Modifier.isPublic; @@ -67,7 +68,7 @@ final class MarsBuilderHelper { @SuppressWarnings("unchecked") static void configureClassModelBuilder(final EntityModelBuilder entityModelBuilder, final Class clazz) { // 断言 非空 并封装 type - entityModelBuilder.type(notNull("clazz", clazz)); + entityModelBuilder.type(Assert.notNull( clazz)); // 类对象上的 注解保存 List annotations = new ArrayList(); @@ -208,8 +209,8 @@ private static PropertyMetadata getOrCreateMethodPropertyMetadata(fina } private static boolean isAssignableClass(final Class propertyTypeClass, final Class typeDataClass) { - notNull("propertyTypeClass", propertyTypeClass); - notNull("typeDataClass", typeDataClass); + Assert.notNull(propertyTypeClass); + Assert.notNull( typeDataClass); return propertyTypeClass.isAssignableFrom(typeDataClass) || typeDataClass.isAssignableFrom(propertyTypeClass); } diff --git a/mars-core/src/main/java/com/whaleal/mars/codecs/pojo/annotations/Entity.java b/mars-core/src/main/java/com/whaleal/mars/codecs/pojo/annotations/Entity.java index 8e25d582..b93386e1 100644 --- a/mars-core/src/main/java/com/whaleal/mars/codecs/pojo/annotations/Entity.java +++ b/mars-core/src/main/java/com/whaleal/mars/codecs/pojo/annotations/Entity.java @@ -31,7 +31,7 @@ package com.whaleal.mars.codecs.pojo.annotations; -import com.whaleal.icefrog.core.util.StrUtil; + import java.lang.annotation.*; @@ -51,7 +51,7 @@ * 表名 标记 用于对象和实体之间的差异 * @return tableName */ - String value() default StrUtil.EMPTY; + String value() default ""; } diff --git a/mars-core/src/main/java/com/whaleal/mars/core/aggregation/codecs/AggregationCodecProvider.java b/mars-core/src/main/java/com/whaleal/mars/core/aggregation/codecs/AggregationCodecProvider.java index f3b43d4e..e59ce434 100644 --- a/mars-core/src/main/java/com/whaleal/mars/core/aggregation/codecs/AggregationCodecProvider.java +++ b/mars-core/src/main/java/com/whaleal/mars/core/aggregation/codecs/AggregationCodecProvider.java @@ -5,7 +5,9 @@ import com.whaleal.mars.core.aggregation.codecs.stages.*; import com.whaleal.mars.core.aggregation.expressions.impls.Expression; import com.whaleal.mars.core.aggregation.stages.*; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + + + import org.bson.codecs.Codec; import org.bson.codecs.configuration.CodecProvider; import org.bson.codecs.configuration.CodecRegistry; @@ -20,7 +22,7 @@ public class AggregationCodecProvider implements CodecProvider { private final MongoMappingContext mapper; private Map codecs; - @SuppressFBWarnings("EI_EXPOSE_REP2") + @SuppressWarnings("EI_EXPOSE_REP2") public AggregationCodecProvider( MongoMappingContext mapper) { this.mapper = mapper; expressionCodec = new ExpressionCodec(mapper); diff --git a/mars-core/src/main/java/com/whaleal/mars/core/aggregation/stages/Sort.java b/mars-core/src/main/java/com/whaleal/mars/core/aggregation/stages/Sort.java index 02c0de7d..f881071a 100644 --- a/mars-core/src/main/java/com/whaleal/mars/core/aggregation/stages/Sort.java +++ b/mars-core/src/main/java/com/whaleal/mars/core/aggregation/stages/Sort.java @@ -1,6 +1,6 @@ package com.whaleal.mars.core.aggregation.stages; -import com.whaleal.icefrog.core.lang.Precondition; +import com.whaleal.mars.util.Assert; import com.whaleal.mars.core.domain.Direction; import com.whaleal.mars.core.domain.ISort; import com.whaleal.mars.core.domain.SortType; @@ -58,7 +58,7 @@ public static Sort sort() { */ public static Sort by( SortType... orders) { - Precondition.notNull(orders, "Orders must not be null!"); + Assert.notNull(orders, "Orders must not be null!"); return new Sort(Arrays.asList(orders)); } @@ -72,9 +72,9 @@ public static Sort by( SortType... orders) { */ public static Sort by( Direction direction, String... properties) { - Precondition.notNull(direction, "Direction must not be null!"); - Precondition.notNull(properties, "Properties must not be null!"); - Precondition.isTrue(properties.length > 0, "At least one property must be given!"); + Assert.notNull(direction, "Direction must not be null!"); + Assert.notNull(properties, "Properties must not be null!"); + Assert.isTrue(properties.length > 0, "At least one property must be given!"); return Sort.by(Arrays.stream(properties)// .map(it -> new SortType(it ,direction))// @@ -108,7 +108,7 @@ private Sort( Direction direction, List properties) { */ public static Sort by( String... properties) { - Precondition.notNull(properties, "Properties must not be null!"); + Assert.notNull(properties, "Properties must not be null!"); return properties.length == 0 // ? Sort.unsorted() // @@ -123,7 +123,7 @@ public static Sort by( String... properties) { */ public static Sort by( List< SortType > orders) { - Precondition.notNull(orders, "Orders must not be null!"); + Assert.notNull(orders, "Orders must not be null!"); return orders.isEmpty() ? Sort.unsorted() : new Sort(orders); } @@ -216,7 +216,7 @@ public Sort meta(String field) { @Override public Sort and( ISort sort ) { - Precondition.notNull(sort, "Sort must not be null!"); + Assert.notNull(sort, "Sort must not be null!"); ArrayList these = new ArrayList<>(this.getSorts()); diff --git a/mars-core/src/main/java/com/whaleal/mars/core/domain/PageRequest.java b/mars-core/src/main/java/com/whaleal/mars/core/domain/PageRequest.java index 4effc536..cf7b8615 100644 --- a/mars-core/src/main/java/com/whaleal/mars/core/domain/PageRequest.java +++ b/mars-core/src/main/java/com/whaleal/mars/core/domain/PageRequest.java @@ -3,7 +3,7 @@ import com.mongodb.lang.Nullable; -import com.whaleal.icefrog.core.lang.Precondition; +import com.whaleal.mars.util.Assert; /** * Basic Java Bean implementation of {@link Pageable}. @@ -27,7 +27,7 @@ protected PageRequest(int page, int size, ISort sort) { super(page, size); - Precondition.notNull(sort, "Sort must not be null!"); + Assert.notNull(sort, "Sort must not be null!"); this.sort = sort; } diff --git a/mars-core/src/main/java/com/whaleal/mars/core/domain/Sort.java b/mars-core/src/main/java/com/whaleal/mars/core/domain/Sort.java index d3492119..eb47ac84 100644 --- a/mars-core/src/main/java/com/whaleal/mars/core/domain/Sort.java +++ b/mars-core/src/main/java/com/whaleal/mars/core/domain/Sort.java @@ -1,8 +1,8 @@ package com.whaleal.mars.core.domain; import com.mongodb.lang.Nullable; -import com.whaleal.icefrog.core.lang.Precondition; -import com.whaleal.icefrog.core.util.StrUtil; +import com.whaleal.mars.util.Assert; +import com.whaleal.mars.util.StrUtil; import org.bson.BsonWriter; import java.util.ArrayList; @@ -65,7 +65,7 @@ public static Sort sort() { */ public static Sort by(SortType... orders) { - Precondition.notNull(orders, "Orders must not be null!"); + Assert.notNull(orders, "Orders must not be null!"); return new Sort(Arrays.asList(orders)); } @@ -79,9 +79,9 @@ public static Sort by(SortType... orders) { */ public static Sort by(Direction direction, String... properties) { - Precondition.notNull(direction, "Direction must not be null!"); - Precondition.notNull(properties, "Properties must not be null!"); - Precondition.isTrue(properties.length > 0, "At least one property must be given!"); + Assert.notNull(direction, "Direction must not be null!"); + Assert.notNull(properties, "Properties must not be null!"); + Assert.isTrue(properties.length > 0, "At least one property must be given!"); return Sort.by(Arrays.stream(properties)// .map(it -> new SortType(it ,direction))// @@ -95,7 +95,7 @@ public static Sort by(Direction direction, String... properties) { */ public static Sort by(String... properties) { - Precondition.notNull(properties, "Properties must not be null!"); + Assert.notNull(properties, "Properties must not be null!"); return properties.length == 0 // ? Sort.unsorted() // @@ -110,7 +110,7 @@ public static Sort by(String... properties) { */ public static Sort by(List orders) { - Precondition.notNull(orders, "Orders must not be null!"); + Assert.notNull(orders, "Orders must not be null!"); return orders.isEmpty() ? Sort.unsorted() : new Sort(orders); } @@ -169,7 +169,7 @@ public Sort meta( String field ) { @Override public Sort and( ISort sort ) { - Precondition.notNull(sort, "Sort must not be null!"); + Assert.notNull(sort, "Sort must not be null!"); ArrayList these = new ArrayList<>(this.getSorts()); diff --git a/mars-core/src/main/java/com/whaleal/mars/core/gridfs/GridFsOperations.java b/mars-core/src/main/java/com/whaleal/mars/core/gridfs/GridFsOperations.java index 9f8e7075..8fcca30a 100644 --- a/mars-core/src/main/java/com/whaleal/mars/core/gridfs/GridFsOperations.java +++ b/mars-core/src/main/java/com/whaleal/mars/core/gridfs/GridFsOperations.java @@ -31,11 +31,13 @@ import com.mongodb.client.gridfs.GridFSFindIterable; import com.mongodb.client.gridfs.model.GridFSFile; -import com.whaleal.icefrog.core.util.ObjectUtil; + import com.whaleal.icefrog.core.util.ReUtil; -import com.whaleal.icefrog.core.util.StrUtil; + import com.whaleal.mars.core.query.Criteria; import com.whaleal.mars.core.query.Query; +import com.whaleal.mars.util.ObjectUtil; +import com.whaleal.mars.util.StrUtil; import org.bson.Document; import org.bson.types.ObjectId; diff --git a/mars-core/src/main/java/com/whaleal/mars/core/index/Index.java b/mars-core/src/main/java/com/whaleal/mars/core/index/Index.java index 077f2025..fddb6fc3 100644 --- a/mars-core/src/main/java/com/whaleal/mars/core/index/Index.java +++ b/mars-core/src/main/java/com/whaleal/mars/core/index/Index.java @@ -31,7 +31,7 @@ import com.mongodb.lang.Nullable; -import com.whaleal.icefrog.core.lang.Precondition; +import com.whaleal.mars.util.Assert; import com.whaleal.mars.session.option.IndexOptions; import org.bson.Document; @@ -63,16 +63,16 @@ public Index() { public Index( String field, IndexDirection direction ) { - Precondition.notNull("field can't be null in Index", field); - Precondition.notNull("direction can't be null in Index", direction); + Assert.notNull(field,"field can't be null in Index") ; + Assert.notNull(direction,"direction can't be null in Index"); key.put(field, direction); } public Index( String field, IndexDirection direction, IndexOptions options ) { - Precondition.notNull("field can't be null in Index", field); - Precondition.notNull("direction can't be null in Index", direction); - Precondition.notNull("IndexOptions can't be null in Index", options); + Assert.notNull(field,"field can't be null in Index" ); + Assert.notNull(direction,"direction can't be null in Index" ); + Assert.notNull(options, "IndexOptions can't be null in Index" ); key.put(field, direction); this.options = options; @@ -80,8 +80,8 @@ public Index( String field, IndexDirection direction, IndexOptions options ) { public Index on( String field, IndexDirection direction ) { - Precondition.notNull("field can't be null in Index", field); - Precondition.notNull("direction can't be null in Index", direction); + Assert.notNull(field, "field can't be null in Index"); + Assert.notNull(direction, "direction can't be null in Index"); key.put(field, direction); return this; } @@ -89,7 +89,7 @@ public Index on( String field, IndexDirection direction ) { public Index setOptions( IndexOptions options ) { - Precondition.notNull("IndexOptions can't be null", options); + Assert.notNull(options,"IndexOptions can't be null" ); this.options = options; return this; } diff --git a/mars-core/src/main/java/com/whaleal/mars/core/messaging/ChangeStreamOptions.java b/mars-core/src/main/java/com/whaleal/mars/core/messaging/ChangeStreamOptions.java index 56e01688..8d1f8127 100644 --- a/mars-core/src/main/java/com/whaleal/mars/core/messaging/ChangeStreamOptions.java +++ b/mars-core/src/main/java/com/whaleal/mars/core/messaging/ChangeStreamOptions.java @@ -31,7 +31,7 @@ import com.mongodb.client.model.Collation; import com.mongodb.client.model.changestream.FullDocument; -import com.whaleal.icefrog.core.lang.Precondition; +import com.whaleal.mars.util.Assert; import com.whaleal.icefrog.core.util.ObjectUtil; import com.whaleal.mars.core.aggregation.AggregationPipeline; import org.bson.BsonTimestamp; @@ -283,7 +283,7 @@ private ChangeStreamOptionsBuilder() { */ public ChangeStreamOptionsBuilder collation(Collation collation) { - Precondition.notNull(collation, "Collation must not be null nor empty!"); + Assert.notNull(collation, "Collation must not be null nor empty!"); this.collation = collation; return this; @@ -298,7 +298,7 @@ public ChangeStreamOptionsBuilder collation(Collation collation) { */ public ChangeStreamOptionsBuilder filter( AggregationPipeline filter) { - Precondition.notNull(filter, "Filter must not be null!"); + Assert.notNull(filter, "Filter must not be null!"); this.filter = filter; return this; @@ -312,7 +312,7 @@ public ChangeStreamOptionsBuilder filter( AggregationPipeline filter) { */ public ChangeStreamOptionsBuilder filter(Document... filter) { - Precondition.noNullElements(filter, "Filter must not contain null values"); + Assert.noNullElements(filter, "Filter must not contain null values"); this.filter = Arrays.asList(filter); return this; @@ -327,7 +327,7 @@ public ChangeStreamOptionsBuilder filter(Document... filter) { */ public ChangeStreamOptionsBuilder resumeToken(BsonValue resumeToken) { - Precondition.notNull(resumeToken, "ResumeToken must not be null!"); + Assert.notNull(resumeToken, "ResumeToken must not be null!"); this.resumeToken = resumeToken; @@ -356,7 +356,7 @@ public ChangeStreamOptionsBuilder returnFullDocumentOnUpdate() { */ public ChangeStreamOptionsBuilder fullDocumentLookup(FullDocument lookup) { - Precondition.notNull(lookup, "Lookup must not be null!"); + Assert.notNull(lookup, "Lookup must not be null!"); this.fullDocumentLookup = lookup; return this; @@ -370,7 +370,7 @@ public ChangeStreamOptionsBuilder fullDocumentLookup(FullDocument lookup) { */ public ChangeStreamOptionsBuilder resumeAt(Instant resumeTimestamp) { - Precondition.notNull(resumeTimestamp, "ResumeTimestamp must not be null!"); + Assert.notNull(resumeTimestamp, "ResumeTimestamp must not be null!"); this.resumeTimestamp = resumeTimestamp; return this; @@ -384,7 +384,7 @@ public ChangeStreamOptionsBuilder resumeAt(Instant resumeTimestamp) { */ public ChangeStreamOptionsBuilder resumeAt(BsonTimestamp resumeTimestamp) { - Precondition.notNull(resumeTimestamp, "ResumeTimestamp must not be null!"); + Assert.notNull(resumeTimestamp, "ResumeTimestamp must not be null!"); this.resumeTimestamp = resumeTimestamp; return this; diff --git a/mars-core/src/main/java/com/whaleal/mars/core/messaging/ChangeStreamRequest.java b/mars-core/src/main/java/com/whaleal/mars/core/messaging/ChangeStreamRequest.java index 260175a8..58449355 100644 --- a/mars-core/src/main/java/com/whaleal/mars/core/messaging/ChangeStreamRequest.java +++ b/mars-core/src/main/java/com/whaleal/mars/core/messaging/ChangeStreamRequest.java @@ -32,7 +32,7 @@ import com.mongodb.client.model.Collation; import com.mongodb.client.model.changestream.ChangeStreamDocument; import com.mongodb.client.model.changestream.FullDocument; -import com.whaleal.icefrog.core.lang.Precondition; +import com.whaleal.mars.util.Assert; import com.whaleal.mars.core.aggregation.AggregationPipeline; import org.bson.BsonValue; import org.bson.Document; @@ -56,8 +56,8 @@ public class ChangeStreamRequest public ChangeStreamRequest(MessageListener, ? super T> messageListener, RequestOptions options) { - Precondition.notNull(messageListener, "MessageListener must not be null!"); - Precondition.notNull(options, "Options must not be null!"); + Assert.notNull(messageListener, "MessageListener must not be null!"); + Assert.notNull(options, "Options must not be null!"); this.options = options instanceof ChangeStreamRequestOptions ? (ChangeStreamRequestOptions) options : ChangeStreamRequestOptions.of(options); @@ -135,7 +135,7 @@ public ChangeStreamRequestOptions( String databaseName, String collectionName, public ChangeStreamRequestOptions( String databaseName, String collectionName, Duration maxAwaitTime, ChangeStreamOptions options ) { - Precondition.notNull(options, "Options must not be null!"); + Assert.notNull(options, "Options must not be null!"); this.collectionName = collectionName; this.databaseName = databaseName; @@ -145,7 +145,7 @@ public ChangeStreamRequestOptions( String databaseName, String collectionName, public static ChangeStreamRequestOptions of(RequestOptions options) { - Precondition.notNull(options, "Options must not be null!"); + Assert.notNull(options, "Options must not be null!"); return new ChangeStreamRequestOptions(options.getDatabaseName(), options.getCollectionName(), ChangeStreamOptions.builder().build()); @@ -205,7 +205,7 @@ private ChangeStreamRequestBuilder() { */ public ChangeStreamRequestBuilder database(String databaseName) { - Precondition.hasText(databaseName, "DatabaseName must not be null!"); + Assert.hasText(databaseName, "DatabaseName must not be null!"); this.databaseName = databaseName; return this; @@ -219,7 +219,7 @@ public ChangeStreamRequestBuilder database(String databaseName) { */ public ChangeStreamRequestBuilder collection(String collectionName) { - Precondition.hasText(collectionName, "CollectionName must not be null!"); + Assert.hasText(collectionName, "CollectionName must not be null!"); this.collectionName = collectionName; return this; @@ -234,7 +234,7 @@ public ChangeStreamRequestBuilder collection(String collectionName) { public ChangeStreamRequestBuilder publishTo( MessageListener, ? super T> messageListener) { - Precondition.notNull(messageListener, "MessageListener must not be null!"); + Assert.notNull(messageListener, "MessageListener must not be null!"); this.listener = messageListener; return this; @@ -257,7 +257,7 @@ public ChangeStreamRequestBuilder publishTo( */ public ChangeStreamRequestBuilder filter( AggregationPipeline aggregation) { - Precondition.notNull(aggregation, "Aggregation must not be null!"); + Assert.notNull(aggregation, "Aggregation must not be null!"); this.delegate.filter(aggregation); return this; } @@ -271,8 +271,8 @@ public ChangeStreamRequestBuilder filter( AggregationPipeline aggregation) { */ public ChangeStreamRequestBuilder filter(Document... pipeline) { - Precondition.notNull(pipeline, "Aggregation pipeline must not be null!"); - Precondition.noNullElements(pipeline, "Aggregation pipeline must not contain null elements!"); + Assert.notNull(pipeline, "Aggregation pipeline must not be null!"); + Assert.noNullElements(pipeline, "Aggregation pipeline must not contain null elements!"); this.delegate.filter(pipeline); return this; @@ -287,7 +287,7 @@ public ChangeStreamRequestBuilder filter(Document... pipeline) { */ public ChangeStreamRequestBuilder collation(Collation collation) { - Precondition.notNull(collation, "Collation must not be null!"); + Assert.notNull(collation, "Collation must not be null!"); this.delegate.collation(collation); return this; @@ -303,7 +303,7 @@ public ChangeStreamRequestBuilder collation(Collation collation) { */ public ChangeStreamRequestBuilder resumeToken(BsonValue resumeToken) { - Precondition.notNull(resumeToken, "Resume token not be null!"); + Assert.notNull(resumeToken, "Resume token not be null!"); this.delegate.resumeToken(resumeToken); return this; @@ -318,7 +318,7 @@ public ChangeStreamRequestBuilder resumeToken(BsonValue resumeToken) { */ public ChangeStreamRequestBuilder resumeAt(Instant clusterTime) { - Precondition.notNull(clusterTime, "ClusterTime must not be null!"); + Assert.notNull(clusterTime, "ClusterTime must not be null!"); this.delegate.resumeAt(clusterTime); return this; @@ -332,7 +332,7 @@ public ChangeStreamRequestBuilder resumeAt(Instant clusterTime) { */ public ChangeStreamRequestBuilder resumeAfter(BsonValue resumeToken) { - Precondition.notNull(resumeToken, "ResumeToken must not be null!"); + Assert.notNull(resumeToken, "ResumeToken must not be null!"); this.delegate.resumeAfter(resumeToken); return this; @@ -346,7 +346,7 @@ public ChangeStreamRequestBuilder resumeAfter(BsonValue resumeToken) { */ public ChangeStreamRequestBuilder startAfter(BsonValue resumeToken) { - Precondition.notNull(resumeToken, "ResumeToken must not be null!"); + Assert.notNull(resumeToken, "ResumeToken must not be null!"); this.delegate.startAfter(resumeToken); return this; @@ -361,7 +361,7 @@ public ChangeStreamRequestBuilder startAfter(BsonValue resumeToken) { */ public ChangeStreamRequestBuilder fullDocumentLookup(FullDocument lookup) { - Precondition.notNull(lookup, "FullDocument not be null!"); + Assert.notNull(lookup, "FullDocument not be null!"); this.delegate.fullDocumentLookup(lookup); return this; @@ -374,7 +374,7 @@ public ChangeStreamRequestBuilder fullDocumentLookup(FullDocument lookup) { */ public ChangeStreamRequestBuilder maxAwaitTime(Duration timeout) { - Precondition.notNull(timeout, "timeout not be null!"); + Assert.notNull(timeout, "timeout not be null!"); this.maxAwaitTime = timeout; return this; @@ -385,7 +385,7 @@ public ChangeStreamRequestBuilder maxAwaitTime(Duration timeout) { */ public ChangeStreamRequest build() { - Precondition.notNull(listener, "MessageListener must not be null!"); + Assert.notNull(listener, "MessageListener must not be null!"); return new ChangeStreamRequest<>(listener, new ChangeStreamRequestOptions(databaseName, collectionName, maxAwaitTime, delegate.build())); diff --git a/mars-core/src/main/java/com/whaleal/mars/core/query/Collation.java b/mars-core/src/main/java/com/whaleal/mars/core/query/Collation.java index 68de8b39..597b5583 100644 --- a/mars-core/src/main/java/com/whaleal/mars/core/query/Collation.java +++ b/mars-core/src/main/java/com/whaleal/mars/core/query/Collation.java @@ -35,8 +35,9 @@ import com.mongodb.client.model.CollationMaxVariable; import com.mongodb.client.model.CollationStrength; import com.whaleal.icefrog.core.convert.Converter2; -import com.whaleal.icefrog.core.lang.Precondition; -import com.whaleal.icefrog.core.util.StrUtil; +import com.whaleal.mars.util.Assert; +import com.whaleal.mars.util.StrUtil; + import org.bson.Document; import java.util.Locale; @@ -79,7 +80,7 @@ public class Collation { @Deprecated private Collation(CollationLocale locale) { - Precondition.notNull(locale, "ICULocale must not be null!"); + Assert.notNull(locale, "ICULocale must not be null!"); this.locale = locale; } @@ -102,7 +103,7 @@ public static Collation simple() { public static Collation of(Locale locale) { - Precondition.notNull(locale, "Locale must not be null!"); + Assert.notNull(locale, "Locale must not be null!"); String format; @@ -145,7 +146,7 @@ public static Collation of(CollationLocale locale) { */ public static Collation parse(String collation) { - Precondition.notNull(collation, "Collation must not be null!"); + Assert.notNull(collation, "Collation must not be null!"); return StrUtil.trimLeadingWhitespace(collation).startsWith("{") ? from(Document.parse(collation)) : of(collation); @@ -161,7 +162,7 @@ public static Collation parse(String collation) { */ public static Collation from(Document source) { - Precondition.notNull(source, "Source must not be null!"); + Assert.notNull(source, "Source must not be null!"); Collation collation = Collation.of(source.getString("locale")); if (source.containsKey("strength")) { @@ -732,7 +733,7 @@ private TertiaryICUComparisonLevel(CaseFirst caseFirst) { */ public ComparisonLevel caseFirst(CaseFirst caseFirst) { - Precondition.notNull(caseFirst, "CaseFirst must not be null!"); + Assert.notNull(caseFirst, "CaseFirst must not be null!"); return new TertiaryICUComparisonLevel(caseFirst); } } @@ -870,7 +871,7 @@ private CollationLocale(String language, Optional variant) { */ public static CollationLocale of(String language) { - Precondition.notNull(language, "Code must not be null!"); + Assert.notNull(language, "Code must not be null!"); return new CollationLocale(language, Optional.empty()); } @@ -882,7 +883,7 @@ public static CollationLocale of(String language) { */ public CollationLocale variant(String variant) { - Precondition.notNull(variant, "Variant must not be null!"); + Assert.notNull(variant, "Variant must not be null!"); return new CollationLocale(language, Optional.of(variant)); } diff --git a/mars-core/src/main/java/com/whaleal/mars/core/query/Meta.java b/mars-core/src/main/java/com/whaleal/mars/core/query/Meta.java index 58f568eb..8e4c0527 100644 --- a/mars-core/src/main/java/com/whaleal/mars/core/query/Meta.java +++ b/mars-core/src/main/java/com/whaleal/mars/core/query/Meta.java @@ -29,10 +29,8 @@ */ package com.whaleal.mars.core.query; - - -import com.whaleal.icefrog.core.util.ObjectUtil; -import com.whaleal.icefrog.core.util.StrUtil; +import com.whaleal.mars.util.StrUtil; +import com.whaleal.mars.util.ObjectUtil; import com.whaleal.mars.util.Assert; import java.time.Duration; diff --git a/mars-core/src/main/java/com/whaleal/mars/core/query/Query.java b/mars-core/src/main/java/com/whaleal/mars/core/query/Query.java index d5db899e..83d024b5 100644 --- a/mars-core/src/main/java/com/whaleal/mars/core/query/Query.java +++ b/mars-core/src/main/java/com/whaleal/mars/core/query/Query.java @@ -34,7 +34,7 @@ import com.mongodb.ReadPreference; import com.mongodb.WriteConcern; -import com.whaleal.icefrog.core.util.ObjectUtil; + import com.whaleal.mars.codecs.writer.DocumentWriter; import com.whaleal.mars.core.aggregation.codecs.ExpressionHelper; import com.whaleal.mars.core.domain.IProjection; @@ -43,14 +43,14 @@ import com.whaleal.mars.core.domain.SortType; import com.whaleal.mars.core.internal.InvalidMongoDbApiUsageException; import com.whaleal.mars.util.Assert; +import com.whaleal.mars.util.ObjectUtil; import org.bson.Document; import java.time.Duration; import java.util.*; import java.util.concurrent.TimeUnit; -import static com.whaleal.icefrog.core.util.ObjectUtil.nullSafeEquals; -import static com.whaleal.icefrog.core.util.ObjectUtil.nullSafeHashCode; + /** @@ -610,13 +610,13 @@ public boolean equals(Object obj) { protected boolean querySettingsEquals(Query that) { boolean criteriaEqual = this.criteria.equals(that.criteria); - boolean fieldsEqual = nullSafeEquals(this.projectionSpec, that.projectionSpec); + boolean fieldsEqual = ObjectUtil.nullSafeEquals(this.projectionSpec, that.projectionSpec); boolean sortEqual = this.sorts.equals(that.sorts); - boolean hintEqual = nullSafeEquals(this.hint, that.hint); + boolean hintEqual = ObjectUtil.nullSafeEquals(this.hint, that.hint); boolean skipEqual = this.skip == that.skip; boolean limitEqual = this.limit == that.limit; - boolean metaEqual = nullSafeEquals(this.meta, that.meta); - boolean collationEqual = nullSafeEquals(this.collation.orElse(null), that.collation.orElse(null)); + boolean metaEqual = ObjectUtil.nullSafeEquals(this.meta, that.meta); + boolean collationEqual = ObjectUtil.nullSafeEquals(this.collation.orElse(null), that.collation.orElse(null)); return criteriaEqual && fieldsEqual && sortEqual && hintEqual && skipEqual && limitEqual && metaEqual && collationEqual; @@ -632,13 +632,13 @@ public int hashCode() { int result = 17; result += 31 * criteria.hashCode(); - result += 31 * nullSafeHashCode(projectionSpec); - result += 31 * nullSafeHashCode(sorts); - result += 31 * nullSafeHashCode(hint); + result += 31 * ObjectUtil.nullSafeHashCode(projectionSpec); + result += 31 * ObjectUtil.nullSafeHashCode(sorts); + result += 31 * ObjectUtil.nullSafeHashCode(hint); result += 31 * skip; result += 31 * limit; - result += 31 * nullSafeHashCode(meta); - result += 31 * nullSafeHashCode(collation.orElse(null)); + result += 31 * ObjectUtil.nullSafeHashCode(meta); + result += 31 * ObjectUtil.nullSafeHashCode(collation.orElse(null)); return result; } diff --git a/mars-core/src/main/java/com/whaleal/mars/core/query/TextCriteria.java b/mars-core/src/main/java/com/whaleal/mars/core/query/TextCriteria.java index 5c0a0aa9..2860ab03 100644 --- a/mars-core/src/main/java/com/whaleal/mars/core/query/TextCriteria.java +++ b/mars-core/src/main/java/com/whaleal/mars/core/query/TextCriteria.java @@ -30,7 +30,7 @@ package com.whaleal.mars.core.query; -import com.whaleal.icefrog.core.lang.Precondition; +import com.whaleal.mars.util.Assert; import com.whaleal.icefrog.core.util.ObjectUtil; import com.whaleal.icefrog.core.util.StrUtil; import org.bson.Document; @@ -85,7 +85,7 @@ public static TextCriteria forDefaultLanguage() { */ public static TextCriteria forLanguage(String language) { - Precondition.hasText(language, "Language must not be null or empty!"); + Assert.hasText(language, "Language must not be null or empty!"); return new TextCriteria(language); } @@ -111,7 +111,7 @@ public TextCriteria matchingAny(String... words) { */ public TextCriteria matching(Term term) { - Precondition.notNull(term, "Term to add must not be null."); + Assert.notNull(term, "Term to add must not be null."); this.terms.add(term); return this; diff --git a/mars-core/src/main/java/com/whaleal/mars/core/query/Update.java b/mars-core/src/main/java/com/whaleal/mars/core/query/Update.java index 3ee60f1e..eeac1a5c 100644 --- a/mars-core/src/main/java/com/whaleal/mars/core/query/Update.java +++ b/mars-core/src/main/java/com/whaleal/mars/core/query/Update.java @@ -30,7 +30,7 @@ package com.whaleal.mars.core.query; -import com.whaleal.icefrog.core.lang.Precondition; +import com.whaleal.mars.util.Assert; import com.whaleal.icefrog.core.map.MapUtil; import com.whaleal.icefrog.core.util.StrUtil; import com.whaleal.mars.codecs.writer.DocumentWriter; @@ -301,7 +301,7 @@ public Update currentTimestamp( String key) { */ public Update multiply( String key, Number multiplier) { - Precondition.notNull(multiplier, "Multiplier must not be null."); + Assert.notNull(multiplier, "Multiplier must not be null."); addMultiFieldOperation("$mul", key, multiplier.doubleValue()); return this; } @@ -315,7 +315,7 @@ public Update multiply( String key, Number multiplier) { */ public Update max( String key, Object value) { - Precondition.notNull(value, "Value for max operation must not be null."); + Assert.notNull(value, "Value for max operation must not be null."); addMultiFieldOperation("$max", key, value); return this; } @@ -329,7 +329,7 @@ public Update max( String key, Object value) { */ public Update min( String key, Object value) { - Precondition.notNull(value, "Value for min operation must not be null."); + Assert.notNull(value, "Value for min operation must not be null."); addMultiFieldOperation("$min", key, value); return this; } @@ -411,7 +411,7 @@ public Document getUpdateObject() { @Deprecated protected void addFieldOperation(String operator, String key, Object value) { - Precondition.hasText(key, "Key/Path for update must not be null or blank."); + Assert.hasText(key, "Key/Path for update must not be null or blank."); modifierOps.put(operator, new Document(key, value)); this.keysToUpdate.add(key); @@ -419,7 +419,7 @@ protected void addFieldOperation(String operator, String key, Object value) { protected void addMultiFieldOperation( String operator, String key, Object value ) { - Precondition.hasText(key, "Key/Path for update must not be null or blank."); + Assert.hasText(key, "Key/Path for update must not be null or blank."); Object existingValue = this.modifierOps.get(operator); Document keyValueMap; @@ -523,8 +523,8 @@ public static class BitwiseOperatorBuilder { */ protected BitwiseOperatorBuilder( Update reference, String key) { - Precondition.notNull(reference, "Reference must not be null!"); - Precondition.notNull(key, "Key must not be null!"); + Assert.notNull(reference, "Reference must not be null!"); + Assert.notNull(key, "Key must not be null!"); this.reference = reference; this.key = key; @@ -632,7 +632,7 @@ public PushOperatorBuilder slice(int count) { */ public PushOperatorBuilder sort( int direction) { - Precondition.notNull(direction, "Direction must not be null."); + Assert.notNull(direction, "Direction must not be null."); this.modifiers.put("$sort",direction); return this; } @@ -646,7 +646,7 @@ public PushOperatorBuilder sort( int direction) { */ public PushOperatorBuilder sort(Sort sort) { - Precondition.notNull(sort, "Sort must not be null."); + Assert.notNull(sort, "Sort must not be null."); DocumentWriter writer = new DocumentWriter() ; ExpressionHelper.document(writer, () -> { diff --git a/mars-core/src/main/java/com/whaleal/mars/core/validation/CriteriaValidator.java b/mars-core/src/main/java/com/whaleal/mars/core/validation/CriteriaValidator.java index ee913083..d109645e 100644 --- a/mars-core/src/main/java/com/whaleal/mars/core/validation/CriteriaValidator.java +++ b/mars-core/src/main/java/com/whaleal/mars/core/validation/CriteriaValidator.java @@ -29,8 +29,8 @@ */ package com.whaleal.mars.core.validation; -import com.whaleal.icefrog.core.lang.Precondition; -import com.whaleal.icefrog.core.util.ObjectUtil; +import com.whaleal.mars.util.Assert; +import com.whaleal.mars.util.ObjectUtil; import com.whaleal.mars.core.query.CriteriaDefinition; import org.bson.Document; @@ -55,7 +55,7 @@ private CriteriaValidator(CriteriaDefinition criteria) { */ static CriteriaValidator of(CriteriaDefinition criteria) { - Precondition.notNull(criteria, "Criteria must not be null!"); + Assert.notNull(criteria, "Criteria must not be null!"); return new CriteriaValidator(criteria); } diff --git a/mars-core/src/main/java/com/whaleal/mars/core/validation/DocumentValidator.java b/mars-core/src/main/java/com/whaleal/mars/core/validation/DocumentValidator.java index 2f265a62..7139db32 100644 --- a/mars-core/src/main/java/com/whaleal/mars/core/validation/DocumentValidator.java +++ b/mars-core/src/main/java/com/whaleal/mars/core/validation/DocumentValidator.java @@ -30,7 +30,7 @@ package com.whaleal.mars.core.validation; -import com.whaleal.icefrog.core.util.ObjectUtil; +import com.whaleal.mars.util.ObjectUtil; import com.whaleal.mars.util.Assert; import org.bson.Document; diff --git a/mars-core/src/main/java/com/whaleal/mars/monitor/CollStatsMetrics.java b/mars-core/src/main/java/com/whaleal/mars/monitor/CollStatsMetrics.java index 56466999..8cd436aa 100644 --- a/mars-core/src/main/java/com/whaleal/mars/monitor/CollStatsMetrics.java +++ b/mars-core/src/main/java/com/whaleal/mars/monitor/CollStatsMetrics.java @@ -2,7 +2,7 @@ import com.mongodb.client.MongoClient; import com.mongodb.client.MongoDatabase; -import com.whaleal.icefrog.core.util.ObjectUtil; +import com.whaleal.mars.util.ObjectUtil; import org.bson.Document; import java.util.List; diff --git a/mars-core/src/main/java/com/whaleal/mars/monitor/CollTimeSeriesMetrics.java b/mars-core/src/main/java/com/whaleal/mars/monitor/CollTimeSeriesMetrics.java index e65fac70..594e5dde 100644 --- a/mars-core/src/main/java/com/whaleal/mars/monitor/CollTimeSeriesMetrics.java +++ b/mars-core/src/main/java/com/whaleal/mars/monitor/CollTimeSeriesMetrics.java @@ -2,7 +2,7 @@ import com.mongodb.client.MongoClient; import com.mongodb.client.MongoDatabase; -import com.whaleal.icefrog.core.util.ObjectUtil; +import com.whaleal.mars.util.ObjectUtil; import org.bson.Document; /** diff --git a/mars-core/src/main/java/com/whaleal/mars/monitor/ConnPoolStatsMetrics.java b/mars-core/src/main/java/com/whaleal/mars/monitor/ConnPoolStatsMetrics.java index 622c7566..f329b227 100644 --- a/mars-core/src/main/java/com/whaleal/mars/monitor/ConnPoolStatsMetrics.java +++ b/mars-core/src/main/java/com/whaleal/mars/monitor/ConnPoolStatsMetrics.java @@ -1,7 +1,7 @@ package com.whaleal.mars.monitor; import com.mongodb.client.MongoClient; -import com.whaleal.icefrog.core.util.ObjectUtil; +import com.whaleal.mars.util.ObjectUtil; import org.bson.Document; /** diff --git a/mars-core/src/main/java/com/whaleal/mars/monitor/DocumentMetrics.java b/mars-core/src/main/java/com/whaleal/mars/monitor/DocumentMetrics.java index d23d709f..52e7f2d0 100644 --- a/mars-core/src/main/java/com/whaleal/mars/monitor/DocumentMetrics.java +++ b/mars-core/src/main/java/com/whaleal/mars/monitor/DocumentMetrics.java @@ -1,7 +1,7 @@ package com.whaleal.mars.monitor; import com.mongodb.client.MongoClient; -import com.whaleal.icefrog.core.util.ObjectUtil; +import com.whaleal.mars.util.ObjectUtil; import org.bson.Document; /** diff --git a/mars-core/src/main/java/com/whaleal/mars/monitor/OperationCounters.java b/mars-core/src/main/java/com/whaleal/mars/monitor/OperationCounters.java index 30e74730..100490b1 100644 --- a/mars-core/src/main/java/com/whaleal/mars/monitor/OperationCounters.java +++ b/mars-core/src/main/java/com/whaleal/mars/monitor/OperationCounters.java @@ -30,7 +30,7 @@ package com.whaleal.mars.monitor; import com.mongodb.client.MongoClient; -import com.whaleal.icefrog.core.util.NumberUtil; +import com.whaleal.mars.util.StrUtil; import org.bson.Document; /** @@ -70,6 +70,6 @@ public Integer getCommandCount() { private Integer getOpCounter(String key) { Document opCounters = (Document) serverStatus.get("opcounters"); - return NumberUtil.convertNumberToTargetClass((Number) opCounters.get(key), Integer.class); + return Integer.parseInt(StrUtil.toString(opCounters.get(key))); } } diff --git a/mars-core/src/main/java/com/whaleal/mars/monitor/QueryExecutorMetrics.java b/mars-core/src/main/java/com/whaleal/mars/monitor/QueryExecutorMetrics.java index afe325da..93b3e9da 100644 --- a/mars-core/src/main/java/com/whaleal/mars/monitor/QueryExecutorMetrics.java +++ b/mars-core/src/main/java/com/whaleal/mars/monitor/QueryExecutorMetrics.java @@ -1,7 +1,7 @@ package com.whaleal.mars.monitor; import com.mongodb.client.MongoClient; -import com.whaleal.icefrog.core.util.ObjectUtil; +import com.whaleal.mars.util.ObjectUtil; import org.bson.Document; diff --git a/mars-core/src/main/java/com/whaleal/mars/monitor/ReplicationInfoMetrics.java b/mars-core/src/main/java/com/whaleal/mars/monitor/ReplicationInfoMetrics.java index ddca72f7..1b70811a 100644 --- a/mars-core/src/main/java/com/whaleal/mars/monitor/ReplicationInfoMetrics.java +++ b/mars-core/src/main/java/com/whaleal/mars/monitor/ReplicationInfoMetrics.java @@ -4,7 +4,7 @@ import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import com.whaleal.icefrog.core.collection.CollUtil; -import com.whaleal.icefrog.core.util.ObjectUtil; +import com.whaleal.mars.util.ObjectUtil; import org.bson.BsonTimestamp; import org.bson.Document; diff --git a/mars-core/src/main/java/com/whaleal/mars/monitor/ServerInfo.java b/mars-core/src/main/java/com/whaleal/mars/monitor/ServerInfo.java index 02212bb6..a235d1d6 100644 --- a/mars-core/src/main/java/com/whaleal/mars/monitor/ServerInfo.java +++ b/mars-core/src/main/java/com/whaleal/mars/monitor/ServerInfo.java @@ -30,7 +30,7 @@ package com.whaleal.mars.monitor; import com.mongodb.client.MongoClient; -import com.whaleal.icefrog.core.util.StrUtil; +import com.whaleal.mars.util.StrUtil; import java.net.UnknownHostException; import java.util.Date; diff --git a/mars-core/src/main/java/com/whaleal/mars/monitor/TTLMetrics.java b/mars-core/src/main/java/com/whaleal/mars/monitor/TTLMetrics.java index 85b96999..570ed9bd 100644 --- a/mars-core/src/main/java/com/whaleal/mars/monitor/TTLMetrics.java +++ b/mars-core/src/main/java/com/whaleal/mars/monitor/TTLMetrics.java @@ -1,7 +1,7 @@ package com.whaleal.mars.monitor; import com.mongodb.client.MongoClient; -import com.whaleal.icefrog.core.util.ObjectUtil; +import com.whaleal.mars.util.ObjectUtil; import org.bson.Document; /** diff --git a/mars-core/src/main/java/com/whaleal/mars/monitor/TransactionMetrics.java b/mars-core/src/main/java/com/whaleal/mars/monitor/TransactionMetrics.java index f8129be2..7449577d 100644 --- a/mars-core/src/main/java/com/whaleal/mars/monitor/TransactionMetrics.java +++ b/mars-core/src/main/java/com/whaleal/mars/monitor/TransactionMetrics.java @@ -1,7 +1,7 @@ package com.whaleal.mars.monitor; import com.mongodb.client.MongoClient; -import com.whaleal.icefrog.core.util.ObjectUtil; +import com.whaleal.mars.util.ObjectUtil; import org.bson.Document; /** diff --git a/mars-core/src/main/java/com/whaleal/mars/session/Datastore.java b/mars-core/src/main/java/com/whaleal/mars/session/Datastore.java index 7ce37b4e..e729819d 100755 --- a/mars-core/src/main/java/com/whaleal/mars/session/Datastore.java +++ b/mars-core/src/main/java/com/whaleal/mars/session/Datastore.java @@ -939,7 +939,8 @@ default < T > T findAndReplace( Query query, T replacement, String collectionNam */ @Nullable default < T > T findAndReplace( Query query, T replacement, FindOneAndReplaceOptions options ) { - return findAndReplace(query, replacement, options, getCollectionName(ClassUtil.getClass(replacement))); + Class clazz = ((null == replacement) ? null : (Class) replacement.getClass()); + return findAndReplace(query, replacement, options, getCollectionName(clazz)); } /** diff --git a/mars-core/src/main/java/com/whaleal/mars/session/DatastoreImpl.java b/mars-core/src/main/java/com/whaleal/mars/session/DatastoreImpl.java index c0bf6b24..c1bb3cfc 100644 --- a/mars-core/src/main/java/com/whaleal/mars/session/DatastoreImpl.java +++ b/mars-core/src/main/java/com/whaleal/mars/session/DatastoreImpl.java @@ -47,8 +47,7 @@ import com.mongodb.client.result.InsertOneResult; import com.mongodb.client.result.UpdateResult; import com.mongodb.lang.Nullable; -import com.whaleal.icefrog.core.util.ObjectUtil; -import com.whaleal.icefrog.core.util.StrUtil; + import com.whaleal.mars.codecs.MarsOrmException; import com.whaleal.mars.codecs.MongoMappingContext; import com.whaleal.mars.codecs.pojo.EntityModel; @@ -79,6 +78,9 @@ import com.whaleal.mars.session.option.UpdateOptions; import com.whaleal.mars.session.option.*; import com.whaleal.mars.session.transactions.MarsTransaction; +import com.whaleal.mars.util.Assert; +import com.whaleal.mars.util.ObjectUtil; +import com.whaleal.mars.util.StrUtil; import org.bson.Document; import org.bson.codecs.EncoderContext; import org.bson.conversions.Bson; @@ -173,13 +175,13 @@ public MongoCollection< Document > getCollection( String collectionName ) { @Override public < T > boolean collectionExists( Class< T > entityClass ) { - notNull(entityClass, "Class must not be null"); + Assert.notNull(entityClass, "Class must not be null"); return collectionExists(getCollectionName(entityClass)); } @Override public boolean collectionExists( String collectionName ) { - notNull(collectionName, "CollectionName must not be null"); + Assert.notNull(collectionName, "CollectionName must not be null"); for (String name : this.getDatabase().listCollectionNames()) { if (collectionName.equals(name)) { return true; @@ -189,7 +191,7 @@ public boolean collectionExists( String collectionName ) { } public < T > MongoCollection< T > getCollection( Class< T > type ) { - notNull(type, "type can not be null"); + Assert.notNull(type, "type can not be null"); String nameCache = null; if ((nameCache = collectionNameCache.get(type)) != null) { @@ -230,26 +232,26 @@ public < T > MongoCollection< T > getCollection( Class< T > type, String collect @Override public Document executeCommand( String jsonCommand ) { - notNull(jsonCommand); + Assert.notNull(jsonCommand); return this.database.runCommand(Document.parse(jsonCommand)); } @Override public Document executeCommand( Document command ) { - notNull(command); + Assert.notNull(command); return this.database.runCommand(command); } @Override public Document executeCommand( Document command, ReadPreference readPreference ) { - notNull(command); + Assert.notNull(command); return this.database.runCommand(command, readPreference); } @Override public boolean exists( Query query, Class< ? > entityClass, String collectionName ) { - notNull(query, "Query can not be null"); + Assert.notNull(query, "Query can not be null"); hasText(collectionName, "CollectionName passed in to exist can't be null"); Optional< ? > o = doFindOne(query, entityClass, collectionName); @@ -260,10 +262,10 @@ public boolean exists( Query query, Class< ? > entityClass, String collectionNam @Override public < T > UpdateResult replace( Query query, T replacement, ReplaceOptions options, String collectionName ) { - notNull(query, "Query must not be null"); + Assert.notNull(query, "Query must not be null"); hasText(collectionName, "Collection name must not be null or empty"); - notNull(replacement, "Replacement must not be null!"); - notNull(options, "Options must not be null Use ReplaceOptions#new() instead"); + Assert.notNull(replacement, "Replacement must not be null!"); + Assert.notNull(options, "Options must not be null Use ReplaceOptions#new() instead"); MongoCollection< T > collection = this.getCollection((Class< T >) replacement.getClass(), collectionName); @@ -303,10 +305,10 @@ public < T > UpdateResult replace( Query query, T replacement, ReplaceOptions op //根据_id进行删除 @Override public com.mongodb.client.result.DeleteResult delete( Object object, String collectionName ) { - notNull(object, "object can not be null"); + Assert.notNull(object, "object can not be null"); Object id = this.mapper.getId(object); - notNull(id, "Object must has _id"); + Assert.notNull(id, "Object must has _id"); Query query = Query.query(Criteria.where("_id").is(id)); @@ -328,7 +330,7 @@ public com.mongodb.client.result.DeleteResult deleteMulti( Query query, Class< ? @SuppressWarnings("ConstantConditions") protected < T > com.mongodb.client.result.DeleteResult doDelete( Query query, @Nullable Class< T > entityClass, String collectionName, com.mongodb.client.model.DeleteOptions options, boolean multi ) { - notNull(query, "Query must not be null"); + Assert.notNull(query, "Query must not be null"); hasText(collectionName, "Collection name must not be null or empty"); if (query.getHint() != null) { @@ -384,7 +386,7 @@ protected < T > com.mongodb.client.result.DeleteResult doDelete( Query query, @N } protected < T > FindIterable< T > doFind( Query query, @Nullable Class< T > entityClass, String collectionName ) { - notNull(query, "Query must not be null"); + Assert.notNull(query, "Query must not be null"); hasText(collectionName, "CollectionName must not be null or empty"); MongoCollection< T > collection = this.getCollection(entityClass, collectionName); @@ -479,14 +481,14 @@ public < T > Optional< T > findOne( Query query, @Nullable Class< T > entityClas } public < T > Optional< T > findById( Object id, Class< T > entityClass, String collectionName ) { - notNull(id, "Id must not be null"); - notNull(collectionName, "CollectionName must not be null"); + Assert.notNull(id, "Id must not be null"); + Assert.notNull(collectionName, "CollectionName must not be null"); return doFindOne(Query.query(Criteria.where("_id").is(id)), entityClass, collectionName); } // @Override private < T > T doInsertOne( T entity, InsertOneOptions options, String collectionName ) { - notNull(entity, "entity must not be null"); + Assert.notNull(entity, "entity must not be null"); hasText(collectionName, "collectionName must not be null"); @@ -664,7 +666,7 @@ public UpdateResult upsert( Query query, UpdateDefinition update, String collect @Override public UpdateResult upsert( Query query, UpdateDefinition update, Class< ? > entityClass, String collectionName ) { - notNull(entityClass, "EntityClass must not be null"); + Assert.notNull(entityClass, "EntityClass must not be null"); return doUpdate(collectionName, query, update, entityClass, true, false); } @@ -682,7 +684,7 @@ public UpdateResult updateFirst( Query query, UpdateDefinition update, String co @Override public UpdateResult updateFirst( Query query, UpdateDefinition update, Class< ? > entityClass, String collectionName ) { - notNull(entityClass, "EntityClass must not be null"); + Assert.notNull(entityClass, "EntityClass must not be null"); return doUpdate(collectionName, query, update, entityClass, false, false); } @@ -700,7 +702,7 @@ public UpdateResult updateMulti( Query query, UpdateDefinition update, String co @Override public UpdateResult updateMulti( Query query, UpdateDefinition update, Class< ? > entityClass, String collectionName ) { - notNull(entityClass, "EntityClass must not be null"); + Assert.notNull(entityClass, "EntityClass must not be null"); return doUpdate(collectionName, query, update, entityClass, false, true); } @@ -735,9 +737,9 @@ public < T > T save( T entity, String collectionName ) { protected < T > UpdateResult doUpdate( String collectionName, Query query, UpdateDefinition update, @Nullable Class< ? > entityClass, boolean upsert, boolean multi ) { - notNull(collectionName, "CollectionName must not be null"); - notNull(query, "Query must not be null"); - notNull(update, "Update must not be null"); + Assert.notNull(collectionName, "CollectionName must not be null"); + Assert.notNull(query, "Query must not be null"); + Assert.notNull(update, "Update must not be null"); if (query.isSorted() && LOGGER.isWarnEnabled()) { @@ -803,11 +805,11 @@ public MongoMappingContext getMapper() { @Override public < T > T findAndModify( Query query, UpdateDefinition update, FindOneAndUpdateOptions options, Class< T > entityClass, String collectionName ) { - notNull(query, "Query must not be null!"); - notNull(update, "Update must not be null!"); - notNull(options, "Options must not be null!"); - notNull(entityClass, "EntityClass must not be null!"); - notNull(collectionName, "CollectionName must not be null!"); + Assert.notNull(query, "Query must not be null!"); + Assert.notNull(update, "Update must not be null!"); + Assert.notNull(options, "Options must not be null!"); + Assert.notNull(entityClass, "EntityClass must not be null!"); + Assert.notNull(collectionName, "CollectionName must not be null!"); // do with collation @@ -822,12 +824,12 @@ public < T > T findAndModify( Query query, UpdateDefinition update, FindOneAndUp @Override public < S, T > T findAndReplace( Query query, S replacement, FindOneAndReplaceOptions options, Class< S > entityType, String collectionName, Class< T > resultType ) { - notNull(query, "Query must not be null!"); - notNull(replacement, "Replacement must not be null!"); - notNull(options, "Options must not be null! Use FindOneAndReplaceOptions#new() instead."); - notNull(entityType, "EntityType must not be null!"); - notNull(collectionName, "CollectionName must not be null!"); - notNull(resultType, "ResultType must not be null! Use Object.class instead."); + Assert.notNull(query, "Query must not be null!"); + Assert.notNull(replacement, "Replacement must not be null!"); + Assert.notNull(options, "Options must not be null! Use FindOneAndReplaceOptions#new() instead."); + Assert.notNull(entityType, "EntityType must not be null!"); + Assert.notNull(collectionName, "CollectionName must not be null!"); + Assert.notNull(resultType, "ResultType must not be null! Use Object.class instead."); // sort skip 已经不重要了 可以呗忽略了 isTrue(query.getLimit() <= 1, "Query must not define a limit other than 1 ore none!"); @@ -875,9 +877,9 @@ public < S, T > T findAndReplace( Query query, S replacement, FindOneAndReplaceO @Override public < T > T findAndDelete( Query query, Class< T > entityClass, String collectionName, FindOneAndDeleteOptions options ) { - notNull(query, "Query must not be null!"); - notNull(entityClass, "EntityClass must not be null!"); - notNull(collectionName, "CollectionName must not be null!"); + Assert.notNull(query, "Query must not be null!"); + Assert.notNull(entityClass, "EntityClass must not be null!"); + Assert.notNull(collectionName, "CollectionName must not be null!"); @@ -1132,7 +1134,7 @@ public void rename( ObjectId id, String newFilename, String bucketName ) { @Override public GridFSFindIterable findGridFs( Query query, String bucketName ) { - notNull(query, "Query must not be null!"); + Assert.notNull(query, "Query must not be null!"); Document queryObject = query.getQueryObject(); Document sortObject = query.getSortObject(); @@ -1147,7 +1149,7 @@ public GridFSFindIterable findGridFs( Query query, String bucketName ) { } MongoCursor< GridFSFile > iterator = iterable.iterator(); - notNull(iterator.tryNext(), "No file found with the query"); + Assert.notNull(iterator.tryNext(), "No file found with the query"); return iterable; } @@ -1171,7 +1173,7 @@ public void deleteGridFs( Query query, String bucketName ) { GridFSFindIterable iterable = findGridFs(query); MongoCursor< GridFSFile > iterator = iterable.iterator(); - notNull(iterator.tryNext(), "no file found to delete"); + Assert.notNull(iterator.tryNext(), "no file found to delete"); while (iterator.hasNext()) { getGridFsBucket(bucketName).delete(iterator.next().getObjectId()); } @@ -1186,7 +1188,7 @@ private GridFSBucket getGridFsBucket( String bucketName ) { @Override public GridFsResource getResource( GridFSFile file, String bucketName ) { - notNull(file, "GridFSFile must not be null!"); + Assert.notNull(file, "GridFSFile must not be null!"); return new GridFsResource(file, getGridFsBucket(bucketName).openDownloadStream(file.getId())); } @@ -1295,7 +1297,7 @@ public < T > long count( Query query, String collectionName ) { //只传入实体类的方式,根据实体类的注解获取CollectionOptions @Override public < T > MongoCollection< Document > createCollection( Class< T > entityClass ) { - notNull(entityClass, "EntityClass must not be null!"); + Assert.notNull(entityClass, "EntityClass must not be null!"); return createCollection(entityClass, scanEntityCollectionOptions(entityClass)); } @@ -1330,7 +1332,7 @@ private GridFSUploadOptions computeUploadOptionsFor( String contentType, Documen public < T > MongoCollection< Document > createCollection( Class< T > entityClass, CreateCollectionOptions collectionOptions ) { - notNull(entityClass, "EntityClass must not be null!"); + Assert.notNull(entityClass, "EntityClass must not be null!"); //CreateCollectionOptions options = collectionOptions != null ? collectionOptions : new CreateCollectionOptions(); @@ -1341,14 +1343,14 @@ public < T > MongoCollection< Document > createCollection( Class< T > entityClas @Override public MongoCollection< Document > createCollection( String collectionName ) { - notNull(collectionName, "CollectionName must not be null!"); + Assert.notNull(collectionName, "CollectionName must not be null!"); return doCreateCollection(collectionName, new CreateCollectionOptions()); } @Override public MongoCollection< Document > createCollection( String collectionName, CreateCollectionOptions collectionOptions ) { - notNull(collectionName, "collectionName must not be null"); + Assert.notNull(collectionName, "collectionName must not be null"); return doCreateCollection(collectionName, collectionOptions); } @@ -1366,7 +1368,7 @@ public MongoCollection< Document > createView( String name, String source, Aggre public MongoCollection< Document > doCreateView( String name, String collectionName, AggregationPipeline pipeline, CreateViewOptions options ) { hasText(collectionName, "CollectionName can not be null"); - notNull(pipeline, "Pipeline can not be null"); + Assert.notNull(pipeline, "Pipeline can not be null"); lock.lock(); try { MongoDatabase database = this.getDatabase(); @@ -1402,13 +1404,13 @@ public < T > void dropCollection( Class< T > entityClass ) { @Deprecated public MongoCollection< Document > createCollection( String collectionName, CollectionOptions collectionOptions ) { - notNull(collectionName, "CollectionName must not be null!"); + Assert.notNull(collectionName, "CollectionName must not be null!"); return doCreateCollection(collectionName, convertToDocument(collectionOptions)); } @Override public void dropCollection( String collectionName ) { - notNull(collectionName, "CollectionName must not be null!"); + Assert.notNull(collectionName, "CollectionName must not be null!"); lock.lock(); try { MongoCollection< Document > collection = this.database.getCollection(collectionName); @@ -1653,7 +1655,7 @@ public < T > MongoCollection< T > withConcern( MongoCollection< T > collection, private CollectionOptions getCollectionOptions( Class< ? > entity ) { EntityModel entityModel = this.mapper.getEntityModel(entity); - notNull(entity, "EntityClass must not be null!"); + Assert.notNull(entity, "EntityClass must not be null!"); CollectionOptions options = CollectionOptions.empty(); @@ -1724,7 +1726,7 @@ private CollectionOptions getCollectionOptions( Class< ? > entity ) { private CreateCollectionOptions scanEntityCollectionOptions( Class< ? > entity ) { EntityModel entityModel = this.mapper.getEntityModel(entity); - notNull(entity, "EntityClass must not be null!"); + Assert.notNull(entity, "EntityClass must not be null!"); CreateCollectionOptions options = new CreateCollectionOptions(); //TODO it may contains some bug,so please use it carefully. diff --git a/mars-core/src/main/java/com/whaleal/mars/util/Assert.java b/mars-core/src/main/java/com/whaleal/mars/util/Assert.java index 9bcfe4ce..acd99b6d 100644 --- a/mars-core/src/main/java/com/whaleal/mars/util/Assert.java +++ b/mars-core/src/main/java/com/whaleal/mars/util/Assert.java @@ -38,7 +38,6 @@ import com.whaleal.icefrog.core.collection.CollectionUtil; import com.whaleal.icefrog.core.map.MapUtil; import com.whaleal.icefrog.core.util.ArrayUtil; -import com.whaleal.icefrog.core.util.StrUtil; import com.whaleal.mars.core.query.MarsQueryException; import java.math.BigInteger; @@ -46,7 +45,7 @@ import java.util.Map; import java.util.function.Supplier; -import static com.whaleal.icefrog.core.util.StrUtil.lenientFormat; +import static com.whaleal.mars.util.StrUtil.lenientFormat; import static java.lang.String.format; /** diff --git a/mars-core/src/main/java/com/whaleal/mars/util/ObjectUtil.java b/mars-core/src/main/java/com/whaleal/mars/util/ObjectUtil.java new file mode 100644 index 00000000..3b2ab303 --- /dev/null +++ b/mars-core/src/main/java/com/whaleal/mars/util/ObjectUtil.java @@ -0,0 +1,1427 @@ +package com.whaleal.mars.util; + +import com.whaleal.icefrog.core.collection.IterUtil; +import com.whaleal.icefrog.core.comparator.CompareUtil; +import com.whaleal.icefrog.core.convert.Convert; +import com.whaleal.icefrog.core.exceptions.UtilException; +import com.whaleal.icefrog.core.lang.Precondition; +import com.whaleal.icefrog.core.map.MapUtil; +import com.whaleal.icefrog.core.util.*; + +import java.lang.reflect.Array; +import java.math.BigDecimal; +import java.util.*; +import java.util.function.Supplier; + +/** + * 对象工具类,包括判空、克隆、序列化等操作 + * + * @author Looly + * @author wh + */ +public class ObjectUtil { + private static final int INITIAL_HASH = 7; + private static final int MULTIPLIER = 31; + private static final String EMPTY_STRING = ""; + private static final String NULL_STRING = "null"; + private static final String ARRAY_START = "{"; + private static final String ARRAY_END = "}"; + private static final String EMPTY_ARRAY = ARRAY_START + ARRAY_END; + private static final String ARRAY_ELEMENT_SEPARATOR = ", "; + + private ObjectUtil() { + } + + /** + * 比较两个对象是否相等,此方法是 {@link #equal(Object, Object)}的别名方法。
+ * 相同的条件有两个,满足其一即可:
+ *
    + *
  1. obj1 == null && obj2 == null
  2. + *
  3. obj1.equals(obj2)
  4. + *
  5. 如果是BigDecimal比较,0 == obj1.compareTo(obj2)
  6. + *
+ * + * @param obj1 对象1 + * @param obj2 对象2 + * @return 是否相等 + * @see #equal(Object, Object) + * @since 1.0.0 + */ + public static boolean equals( Object obj1, Object obj2 ) { + return equal(obj1, obj2); + } + + /** + * 比较两个对象是否相等。
+ * 相同的条件有两个,满足其一即可:
+ *
    + *
  1. obj1 == null && obj2 == null
  2. + *
  3. obj1.equals(obj2)
  4. + *
  5. 如果是BigDecimal比较,0 == obj1.compareTo(obj2)
  6. + *
+ * + * @param obj1 对象1 + * @param obj2 对象2 + * @return 是否相等 + * @see Objects#equals(Object, Object) + */ + public static boolean equal( Object obj1, Object obj2 ) { + if (obj1 instanceof BigDecimal && obj2 instanceof BigDecimal) { + return NumberUtil.equals((BigDecimal) obj1, (BigDecimal) obj2); + } + + return Objects.equals(obj1, obj2); + } + + /** + * 比较两个对象是否不相等。
+ * + * @param obj1 对象1 + * @param obj2 对象2 + * @return 是否不等 + * @since 1.0.0 + */ + public static boolean notEqual( Object obj1, Object obj2 ) { + return false == equal(obj1, obj2); + } + + /** + * 计算对象长度,如果是字符串调用其length函数,集合类调用其size函数,数组调用其length属性,其他可遍历对象遍历计算长度
+ * 支持的类型包括: + *
    + *
  • CharSequence
  • + *
  • Map
  • + *
  • Iterator
  • + *
  • Enumeration
  • + *
  • Array
  • + *
+ * + * @param obj 被计算长度的对象 + * @return 长度 + */ + public static int length( Object obj ) { + if (obj == null) { + return 0; + } + if (obj instanceof CharSequence) { + return ((CharSequence) obj).length(); + } + if (obj instanceof Collection) { + return ((Collection) obj).size(); + } + if (obj instanceof Map) { + return ((Map) obj).size(); + } + + int count; + if (obj instanceof Iterator) { + Iterator iter = (Iterator) obj; + count = 0; + while (iter.hasNext()) { + count++; + iter.next(); + } + return count; + } + if (obj instanceof Enumeration) { + Enumeration enumeration = (Enumeration) obj; + count = 0; + while (enumeration.hasMoreElements()) { + count++; + enumeration.nextElement(); + } + return count; + } + if (obj.getClass().isArray() == true) { + return Array.getLength(obj); + } + return -1; + } + + /** + * 对象中是否包含元素
+ * 支持的对象类型包括: + *
    + *
  • String
  • + *
  • Collection
  • + *
  • Map
  • + *
  • Iterator
  • + *
  • Enumeration
  • + *
  • Array
  • + *
+ * + * @param obj 对象 + * @param element 元素 + * @return 是否包含 + */ + public static boolean contains( Object obj, Object element ) { + if (obj == null) { + return false; + } + if (obj instanceof String) { + if (element == null) { + return false; + } + return ((String) obj).contains(element.toString()); + } + if (obj instanceof Collection) { + return ((Collection) obj).contains(element); + } + if (obj instanceof Map) { + return ((Map) obj).containsValue(element); + } + + if (obj instanceof Iterator) { + Iterator iter = (Iterator) obj; + while (iter.hasNext()) { + Object o = iter.next(); + if (equal(o, element)) { + return true; + } + } + return false; + } + if (obj instanceof Enumeration) { + Enumeration enumeration = (Enumeration) obj; + while (enumeration.hasMoreElements()) { + Object o = enumeration.nextElement(); + if (equal(o, element)) { + return true; + } + } + return false; + } + if (obj.getClass().isArray() == true) { + int len = Array.getLength(obj); + for (int i = 0; i < len; i++) { + Object o = Array.get(obj, i); + if (equal(o, element)) { + return true; + } + } + } + return false; + } + + /** + * 检查对象是否为null
+ * 判断标准为: + * + *
+     * 1. == null
+     * 2. equals(null)
+     * 
+ * 当使用 equals 是 必然返回 false; + * 需要两遍校验 ,因为在 json 中 + * 存在 str != null 但是 str.equals(null) when using org.json + * + * @param obj 对象 + * @return 是否为null + * @see Objects#equals(Object, Object) + * {@code Objects.equals(obj ,null);} + */ + public static boolean isNull( Object obj ) { + //noinspection ConstantConditions + return null == obj || obj.equals(null); + } + + /** + * 检查对象是否不为null + * + * @param obj 对象 + * @return 是否为null + */ + public static boolean isNotNull( Object obj ) { + return false == isNull(obj); + } + + /** + * 判断指定对象是否为空,支持: + * + *
+     * 1. CharSequence
+     * 2. Map
+     * 3. Iterable
+     * 4. Iterator
+     * 5. Array
+     * 
+ * + * @param obj 被判断的对象 + * @return 是否为空,如果类型不支持,返回false + * @since 1.0.0 + */ + @SuppressWarnings("rawtypes") + public static boolean isEmpty( Object obj ) { + + + if (null == obj) { + return true; + } + if (obj instanceof Optional) { + return !((Optional) obj).isPresent(); + } else if (obj instanceof CharSequence) { + return StrUtil.isEmpty((CharSequence) obj); + } else if (obj instanceof Map) { + return MapUtil.isEmpty((Map) obj); + } else if (obj instanceof Iterable) { + return IterUtil.isEmpty((Iterable) obj); + } else if (obj instanceof Iterator) { + return IterUtil.isEmpty((Iterator) obj); + } else if (ArrayUtil.isArray(obj)) { + return ArrayUtil.isEmpty(obj); + } + + return false; + } + + /** + * 判断指定对象是否为非空,支持: + * + *
+     * 1. CharSequence
+     * 2. Map
+     * 3. Iterable
+     * 4. Iterator
+     * 5. Array
+     * 
+ * + * @param obj 被判断的对象 + * @return 是否为空,如果类型不支持,返回true + * @since 1.0.0 + */ + public static boolean isNotEmpty( Object obj ) { + return false == isEmpty(obj); + } + + /** + * 如果给定对象为{@code null}返回默认值 + * + *
+     * ObjectUtil.defaultIfNull(null, null)      = null
+     * ObjectUtil.defaultIfNull(null, "")        = ""
+     * ObjectUtil.defaultIfNull(null, "zz")      = "zz"
+     * ObjectUtil.defaultIfNull("abc", *)        = "abc"
+     * ObjectUtil.defaultIfNull(Boolean.TRUE, *) = Boolean.TRUE
+     * 
+ * + * @param 对象类型 + * @param object 被检查对象,可能为{@code null} + * @param defaultValue 被检查对象为{@code null}返回的默认值,可以为{@code null} + * @return 被检查对象为{@code null}返回默认值,否则返回原值 + * @since 1.0.0 + */ + public static T defaultIfNull( final T object, final T defaultValue ) { + return (null != object) ? object : defaultValue; + } + + /** + * 如果给定对象为{@code null} 返回默认值, 如果不为null 返回自定义handle处理后的返回值 + * + * @param source Object 类型对象 + * @param handle 自定义的处理方法 + * @param defaultValue 默认为空的返回值 + * @param 被检查对象为{@code null}返回默认值,否则返回自定义handle处理后的返回值 + * @return 处理后的返回值 + * @since 1.0.0 + */ + public static T defaultIfNull( Object source, Supplier handle, final T defaultValue ) { + if (Objects.nonNull(source)) { + return handle.get(); + } + return defaultValue; + } + + /** + * 如果给定对象为{@code null}或者""返回默认值, 否则返回自定义handle处理后的返回值 + * + * @param str String 类型 + * @param handle 自定义的处理方法 + * @param defaultValue 默认为空的返回值 + * @param 被检查对象为{@code null}或者 ""返回默认值,否则返回自定义handle处理后的返回值 + * @return 处理后的返回值 + * @since 1.0.0 + */ + public static T defaultIfEmpty( String str, Supplier handle, final T defaultValue ) { + if (StrUtil.isNotEmpty(str)) { + return handle.get(); + } + return defaultValue; + } + + /** + * 如果给定对象为{@code null}或者 "" 返回默认值 + * + *
+     * ObjectUtil.defaultIfEmpty(null, null)      = null
+     * ObjectUtil.defaultIfEmpty(null, "")        = ""
+     * ObjectUtil.defaultIfEmpty("", "zz")      = "zz"
+     * ObjectUtil.defaultIfEmpty(" ", "zz")      = " "
+     * ObjectUtil.defaultIfEmpty("abc", *)        = "abc"
+     * 
+ * + * @param 对象类型(必须实现CharSequence接口) + * @param str 被检查对象,可能为{@code null} + * @param defaultValue 被检查对象为{@code null}或者 ""返回的默认值,可以为{@code null}或者 "" + * @return 被检查对象为{@code null}或者 ""返回默认值,否则返回原值 + * @since 1.0.0 + */ + public static T defaultIfEmpty( final T str, final T defaultValue ) { + return StrUtil.isEmpty(str) ? defaultValue : str; + } + + /** + * 如果给定对象为{@code null}或者""或者空白符返回默认值 + * + *
+     * ObjectUtil.defaultIfBlank(null, null)      = null
+     * ObjectUtil.defaultIfBlank(null, "")        = ""
+     * ObjectUtil.defaultIfBlank("", "zz")      = "zz"
+     * ObjectUtil.defaultIfBlank(" ", "zz")      = "zz"
+     * ObjectUtil.defaultIfBlank("abc", *)        = "abc"
+     * 
+ * + * @param 对象类型(必须实现CharSequence接口) + * @param str 被检查对象,可能为{@code null} + * @param defaultValue 被检查对象为{@code null}或者 ""或者空白符返回的默认值,可以为{@code null}或者 ""或者空白符 + * @return 被检查对象为{@code null}或者 ""或者空白符返回默认值,否则返回原值 + * @since 1.0.0 + */ + public static T defaultIfBlank( final T str, final T defaultValue ) { + return StrUtil.isBlank(str) ? defaultValue : str; + } + + /** + * 克隆对象
+ * 如果对象实现Cloneable接口,调用其clone方法
+ * 如果实现Serializable接口,执行深度克隆
+ * 否则返回{@code null} + * + * @param 对象类型 + * @param obj 被克隆对象 + * @return 克隆后的对象 + */ + public static T clone( T obj ) { + T result = ArrayUtil.clone(obj); + if (null == result) { + if (obj instanceof Cloneable) { + result = ReflectUtil.invoke(obj, "clone"); + } else { + result = cloneByStream(obj); + } + } + return result; + } + + /** + * 返回克隆后的对象,如果克隆失败,返回原对象 + * + * @param 对象类型 + * @param obj 对象 + * @return 克隆后或原对象 + */ + public static T cloneIfPossible( final T obj ) { + T clone = null; + try { + clone = clone(obj); + } catch (Exception e) { + // pass + } + return clone == null ? obj : clone; + } + + /** + * 序列化后拷贝流的方式克隆
+ * 对象必须实现Serializable接口 + * + * @param 对象类型 + * @param obj 被克隆对象 + * @return 克隆后的对象 + * @throws UtilException IO异常和ClassNotFoundException封装 + */ + public static T cloneByStream( T obj ) { + return SerializeUtil.clone(obj); + } + + /** + * 序列化
+ * 对象必须实现Serializable接口 + * + * @param 对象类型 + * @param obj 要被序列化的对象 + * @return 序列化后的字节码 + */ + public static byte[] serialize( T obj ) { + return SerializeUtil.serialize(obj); + } + + /** + * 反序列化
+ * 对象必须实现Serializable接口 + * + *

+ * 注意!!! 此方法不会检查反序列化安全,可能存在反序列化漏洞风险!!! + *

+ * + * @param 对象类型 + * @param bytes 反序列化的字节码 + * @return 反序列化后的对象 + */ + public static T deserialize( byte[] bytes ) { + return SerializeUtil.deserialize(bytes); + } + + /** + * 是否为基本类型,包括包装类型和非包装类型 + * + * @param object 被检查对象 + * @return 是否为基本类型 + * @see ClassUtil#isBasicType(Class) + */ + public static boolean isBasicType( Object object ) { + return ClassUtil.isBasicType(object.getClass()); + } + + /** + * 检查是否为有效的数字
+ * 检查Double和Float是否为无限大,或者Not a Number
+ * 非数字类型和Null将返回true + * + * @param obj 被检查类型 + * @return 检查结果,非数字类型和Null将返回true + */ + public static boolean isValidIfNumber( Object obj ) { + if (obj instanceof Number) { + return NumberUtil.isValidNumber((Number) obj); + } + return true; + } + + /** + * {@code null}安全的对象比较,{@code null}对象排在末尾 + * + * @param 被比较对象类型 + * @param c1 对象1,可以为{@code null} + * @param c2 对象2,可以为{@code null} + * @return 比较结果,如果c1 < c2,返回数小于0,c1==c2返回0,c1 > c2 大于0 + * @see java.util.Comparator#compare(Object, Object) + * @since 1.0.0 + */ + public static > int compare( T c1, T c2 ) { + return CompareUtil.compare(c1, c2); + } + + /** + * {@code null}安全的对象比较 + * + * @param 被比较对象类型 + * @param c1 对象1,可以为{@code null} + * @param c2 对象2,可以为{@code null} + * @param nullGreater 当被比较对象为null时是否排在前面 + * @return 比较结果,如果c1 < c2,返回数小于0,c1==c2返回0,c1 > c2 大于0 + * @see java.util.Comparator#compare(Object, Object) + * @since 1.0.0 + */ + public static > int compare( T c1, T c2, boolean nullGreater ) { + return CompareUtil.compare(c1, c2, nullGreater); + } + + /** + * 获得给定类的第一个泛型参数 + * + * @param obj 被检查的对象 + * @return {@link Class} + * @since 1.0.0 + */ + public static Class getTypeArgument( Object obj ) { + return getTypeArgument(obj, 0); + } + + /** + * 获得给定类的第一个泛型参数 + * + * @param obj 被检查的对象 + * @param index 泛型类型的索引号,即第几个泛型类型 + * @return {@link Class} + * @since 1.0.0 + */ + public static Class getTypeArgument( Object obj, int index ) { + return ClassUtil.getTypeArgument(obj.getClass(), index); + } + + /** + * 将Object转为String
+ * 策略为: + *
+     *  1、null转为"null"
+     *  2、调用Convert.toStr(Object)转换
+     * 
+ * + * @param obj Bean对象 + * @return Bean所有字段转为Map后的字符串 + * @since 1.0.0 + */ + public static String toString( Object obj ) { + if (null == obj) { + return StrUtil.NULL; + } + if (obj instanceof Map) { + return obj.toString(); + } + + return Convert.toStr(obj); + } + + /** + * 存在多少个{@code null}或空对象,通过{@link ObjectUtil#isEmpty(Object)} 判断元素 + * + * @param objs 被检查的对象,一个或者多个 + * @return 存在{@code null}的数量 + */ + public static int emptyCount( Object... objs ) { + return ArrayUtil.emptyCount(objs); + } + + /** + * 是否存在{@code null}对象,通过{@link ObjectUtil#isNull(Object)} 判断元素 + * + * @param objs 被检查对象 + * @return 是否存在 + * @see ArrayUtil#hasNull(Object[]) + * @since 1.0.0 + */ + public static boolean hasNull( Object... objs ) { + return ArrayUtil.hasNull(objs); + } + + /** + * 是否存在{@code null}或空对象,通过{@link ObjectUtil#isEmpty(Object)} 判断元素 + * + * @param objs 被检查对象 + * @return 是否存在 + * @see ArrayUtil#hasEmpty(Object...) + */ + public static boolean hasEmpty( Object... objs ) { + return ArrayUtil.hasEmpty(objs); + } + + /** + * 是否全都为{@code null}或空对象,通过{@link ObjectUtil#isEmpty(Object)} 判断元素 + * + * @param objs 被检查的对象,一个或者多个 + * @return 是否都为空 + */ + public static boolean isAllEmpty( Object... objs ) { + return ArrayUtil.isAllEmpty(objs); + } + + /** + * 是否全都不为{@code null}或空对象,通过{@link ObjectUtil#isEmpty(Object)} 判断元素 + * + * @param objs 被检查的对象,一个或者多个 + * @return 是否都不为空 + */ + public static boolean isAllNotEmpty( Object... objs ) { + return ArrayUtil.isAllNotEmpty(objs); + } + + /** + * Generates a hash code for multiple values. The hash code is generated by calling {@link + * Arrays#hashCode(Object[])}. Note that array arguments to this method, with the exception of a + * single Object array, do not get any special handling; their hash codes are based on identity + * and not contents. + * + *

This is useful for implementing {@link Object#hashCode()}. For example, in an object that + * has three properties, {@code x}, {@code y}, and {@code z}, one could write: + * + *

{@code
+     * public int hashCode() {
+     *   return Objects.hashCode(getX(), getY(), getZ());
+     * }
+     * }
+ * + *

Warning: When a single object is supplied, the returned hash code does not equal the + * hash code of that object. + * + *

Note for Java 7 and later: This method should be treated as deprecated; use {@link + * java.util.Objects#hash} instead. + * + * @param objects objects + * @return int + */ + public static int hashCode( Object... objects ) { + + return Objects.hash(objects); + } + + /** + * Return whether the given throwable is a checked exception: + * that is, neither a RuntimeException nor an Error. + * + * @param ex the throwable to check + * @return whether the throwable is a checked exception + * @see Exception + * @see RuntimeException + * @see Error + */ + public static boolean isCheckedException( Throwable ex ) { + return !(ex instanceof RuntimeException || ex instanceof Error); + } + + /** + * Check whether the given exception is compatible with the specified + * exception types, as declared in a throws clause. + * + * @param ex the exception to check + * @param declaredExceptions the exception types declared in the throws clause + * @return whether the given exception is compatible + */ + public static boolean isCompatibleWithThrowsClause( Throwable ex, Class... declaredExceptions ) { + if (!isCheckedException(ex)) { + return true; + } + if (declaredExceptions != null) { + for (Class declaredException : declaredExceptions) { + if (declaredException.isInstance(ex)) { + return true; + } + } + } + return false; + } + + /** + * 对象是否为数组对象 + * + * @param obj 对象 + * @return 是否为数组对象,如果为{@code null} 返回false + */ + public static boolean isArray( Object obj ) { + return ArrayUtil.isArray(obj); + } + + /** + * 数组是否为空 + * + * @param 数组元素类型 + * @param array 数组 + * @return 是否为空 + */ + public static boolean isEmpty( T[] array ) { + return ArrayUtil.isEmpty(array); + } + + + /** + * Unwrap the given object which is potentially a {@link Optional}. + * + * @param obj the candidate object + * @return either the value held within the {@code Optional}, {@code null} + * if the {@code Optional} is empty, or simply the given object as-is + */ + + public static Object unwrapOptional( Object obj ) { + if (obj instanceof Optional) { + Optional optional = (Optional) obj; + if (!optional.isPresent()) { + return null; + } + Object result = optional.get(); + Precondition.isTrue(!(result instanceof Optional), "Multi-level Optional usage not supported"); + return result; + } + return obj; + } + + /** + * Check whether the given array contains the given element. + * + * @param array the array to check (may be {@code null}, + * in which case the return value will always be {@code false}) + * @param element the element to check for + * @return whether the element has been found in the given array + */ + public static boolean containsElement( Object[] array, Object element ) { + if (array == null) { + return false; + } + for (Object arrayEle : array) { + if (nullSafeEquals(arrayEle, element)) { + return true; + } + } + return false; + } + + /** + * Check whether the given array of enum constants contains a constant with the given name, + * ignoring case when determining a match. + * + * @param enumValues the enum values to check, typically obtained via {@code MyEnum.values()} + * @param constant the constant name to find (must not be null or empty string) + * @return whether the constant has been found in the given array + */ + public static boolean containsConstant( Enum[] enumValues, String constant ) { + return containsConstant(enumValues, constant, false); + } + + /** + * Check whether the given array of enum constants contains a constant with the given name. + * + * @param enumValues the enum values to check, typically obtained via {@code MyEnum.values()} + * @param constant the constant name to find (must not be null or empty string) + * @param caseSensitive whether case is significant in determining a match + * @return whether the constant has been found in the given array + */ + public static boolean containsConstant( Enum[] enumValues, String constant, boolean caseSensitive ) { + for (Enum candidate : enumValues) { + if (caseSensitive ? candidate.toString().equals(constant) : + candidate.toString().equalsIgnoreCase(constant)) { + return true; + } + } + return false; + } + + /** + * Case insensitive alternative to {@link Enum#valueOf(Class, String)}. + * + * @param the concrete Enum type + * @param enumValues the array of all Enum constants in question, usually per {@code Enum.values()} + * @param constant the constant to get the enum value of + * @return E Enum type + * @throws IllegalArgumentException if the given constant is not found in the given array + * of enum values. Use {@link #containsConstant(Enum[], String)} as a guard to avoid this exception. + */ + public static > E caseInsensitiveValueOf( E[] enumValues, String constant ) { + for (E candidate : enumValues) { + if (candidate.toString().equalsIgnoreCase(constant)) { + return candidate; + } + } + throw new IllegalArgumentException("Constant [" + constant + "] does not exist in enum type " + + enumValues.getClass().getComponentType().getName()); + } + + + + + + //--------------------------------------------------------------------- + // Convenience methods for content-based equality/hash-code handling + //--------------------------------------------------------------------- + + /** + * Determine if the given objects are equal, returning {@code true} if + * both are {@code null} or {@code false} if only one is {@code null}. + *

Compares arrays with {@code Arrays.equals}, performing an equality + * check based on the array elements rather than the array reference. + * + * @param o1 first Object to compare + * @param o2 second Object to compare + * @return whether the given objects are equal + * @see Object#equals(Object) + * @see Arrays#equals + */ + public static boolean nullSafeEquals( Object o1, Object o2 ) { + if (o1 == o2) { + return true; + } + if (o1 == null || o2 == null) { + return false; + } + if (o1.equals(o2)) { + return true; + } + if (o1.getClass().isArray() && o2.getClass().isArray()) { + return arrayEquals(o1, o2); + } + return false; + } + + /** + * Compare the given arrays with {@code Arrays.equals}, performing an equality + * check based on the array elements rather than the array reference. + * + * @param o1 first array to compare + * @param o2 second array to compare + * @return whether the given objects are equal + * @see #nullSafeEquals(Object, Object) + * @see Arrays#equals + */ + private static boolean arrayEquals( Object o1, Object o2 ) { + if (o1 instanceof Object[] && o2 instanceof Object[]) { + return Arrays.equals((Object[]) o1, (Object[]) o2); + } + if (o1 instanceof boolean[] && o2 instanceof boolean[]) { + return Arrays.equals((boolean[]) o1, (boolean[]) o2); + } + if (o1 instanceof byte[] && o2 instanceof byte[]) { + return Arrays.equals((byte[]) o1, (byte[]) o2); + } + if (o1 instanceof char[] && o2 instanceof char[]) { + return Arrays.equals((char[]) o1, (char[]) o2); + } + if (o1 instanceof double[] && o2 instanceof double[]) { + return Arrays.equals((double[]) o1, (double[]) o2); + } + if (o1 instanceof float[] && o2 instanceof float[]) { + return Arrays.equals((float[]) o1, (float[]) o2); + } + if (o1 instanceof int[] && o2 instanceof int[]) { + return Arrays.equals((int[]) o1, (int[]) o2); + } + if (o1 instanceof long[] && o2 instanceof long[]) { + return Arrays.equals((long[]) o1, (long[]) o2); + } + if (o1 instanceof short[] && o2 instanceof short[]) { + return Arrays.equals((short[]) o1, (short[]) o2); + } + return false; + } + + /** + * Return as hash code for the given object; typically the value of + * {@code Object#hashCode()}}. If the object is an array, + * this method will delegate to any of the {@code nullSafeHashCode} + * methods for arrays in this class. If the object is {@code null}, + * this method returns 0. + * + * @param obj object + * @return int + * @see Object#hashCode() + * @see #nullSafeHashCode(Object[]) + * @see #nullSafeHashCode(boolean[]) + * @see #nullSafeHashCode(byte[]) + * @see #nullSafeHashCode(char[]) + * @see #nullSafeHashCode(double[]) + * @see #nullSafeHashCode(float[]) + * @see #nullSafeHashCode(int[]) + * @see #nullSafeHashCode(long[]) + * @see #nullSafeHashCode(short[]) + */ + public static int nullSafeHashCode( Object obj ) { + if (obj == null) { + return 0; + } + if (obj.getClass().isArray()) { + if (obj instanceof Object[]) { + return nullSafeHashCode((Object[]) obj); + } + if (obj instanceof boolean[]) { + return nullSafeHashCode((boolean[]) obj); + } + if (obj instanceof byte[]) { + return nullSafeHashCode((byte[]) obj); + } + if (obj instanceof char[]) { + return nullSafeHashCode((char[]) obj); + } + if (obj instanceof double[]) { + return nullSafeHashCode((double[]) obj); + } + if (obj instanceof float[]) { + return nullSafeHashCode((float[]) obj); + } + if (obj instanceof int[]) { + return nullSafeHashCode((int[]) obj); + } + if (obj instanceof long[]) { + return nullSafeHashCode((long[]) obj); + } + if (obj instanceof short[]) { + return nullSafeHashCode((short[]) obj); + } + } + return obj.hashCode(); + } + + /** + * Return a hash code based on the contents of the specified array. + * If {@code array} is {@code null}, this method returns 0. + * + * @param array array + * @return int + */ + public static int nullSafeHashCode( Object[] array ) { + if (array == null) { + return 0; + } + int hash = INITIAL_HASH; + for (Object element : array) { + hash = MULTIPLIER * hash + nullSafeHashCode(element); + } + return hash; + } + + /** + * Return a hash code based on the contents of the specified array. + * If {@code array} is {@code null}, this method returns 0. + * + * @param array array + * @return int + */ + public static int nullSafeHashCode( boolean[] array ) { + if (array == null) { + return 0; + } + int hash = INITIAL_HASH; + for (boolean element : array) { + hash = MULTIPLIER * hash + Boolean.hashCode(element); + } + return hash; + } + + /** + * Return a hash code based on the contents of the specified array. + * If {@code array} is {@code null}, this method returns 0. + * + * @param array array + * @return int + */ + public static int nullSafeHashCode( byte[] array ) { + if (array == null) { + return 0; + } + int hash = INITIAL_HASH; + for (byte element : array) { + hash = MULTIPLIER * hash + element; + } + return hash; + } + + /** + * Return a hash code based on the contents of the specified array. + * If {@code array} is {@code null}, this method returns 0. + * + * @param array array + * @return int + */ + public static int nullSafeHashCode( char[] array ) { + if (array == null) { + return 0; + } + int hash = INITIAL_HASH; + for (char element : array) { + hash = MULTIPLIER * hash + element; + } + return hash; + } + + /** + * Return a hash code based on the contents of the specified array. + * If {@code array} is {@code null}, this method returns 0. + * + * @param array array + * @return int + */ + public static int nullSafeHashCode( double[] array ) { + if (array == null) { + return 0; + } + int hash = INITIAL_HASH; + for (double element : array) { + hash = MULTIPLIER * hash + Double.hashCode(element); + } + return hash; + } + + /** + * Return a hash code based on the contents of the specified array. + * If {@code array} is {@code null}, this method returns 0. + * + * @param array array + * @return int + */ + public static int nullSafeHashCode( float[] array ) { + if (array == null) { + return 0; + } + int hash = INITIAL_HASH; + for (float element : array) { + hash = MULTIPLIER * hash + Float.hashCode(element); + } + return hash; + } + + /** + * Return a hash code based on the contents of the specified array. + * If {@code array} is {@code null}, this method returns 0. + * + * @param array array + * @return int + */ + public static int nullSafeHashCode( int[] array ) { + if (array == null) { + return 0; + } + int hash = INITIAL_HASH; + for (int element : array) { + hash = MULTIPLIER * hash + element; + } + return hash; + } + + /** + * Return a hash code based on the contents of the specified array. + * If {@code array} is {@code null}, this method returns 0. + * + * @param array array + * @return int + */ + public static int nullSafeHashCode( long[] array ) { + if (array == null) { + return 0; + } + int hash = INITIAL_HASH; + for (long element : array) { + hash = MULTIPLIER * hash + Long.hashCode(element); + } + return hash; + } + + /** + * Return a hash code based on the contents of the specified array. + * If {@code array} is {@code null}, this method returns 0. + * + * @param array array + * @return int + */ + public static int nullSafeHashCode( short[] array ) { + if (array == null) { + return 0; + } + int hash = INITIAL_HASH; + for (short element : array) { + hash = MULTIPLIER * hash + element; + } + return hash; + } + + + //--------------------------------------------------------------------- + // Convenience methods for toString output + //--------------------------------------------------------------------- + + /** + * Return a String representation of an object's overall identity. + * + * @param obj the object (may be {@code null}) + * @return the object's identity as String representation, + * or an empty String if the object was {@code null} + */ + public static String identityToString( Object obj ) { + if (obj == null) { + return EMPTY_STRING; + } + return obj.getClass().getName() + "@" + getIdentityHexString(obj); + } + + /** + * Return a hex String form of an object's identity hash code. + * + * @param obj the object + * @return the object's identity code in hex notation + */ + public static String getIdentityHexString( Object obj ) { + return Integer.toHexString(System.identityHashCode(obj)); + } + + /** + * Return a content-based String representation if {@code obj} is + * not {@code null}; otherwise returns an empty String. + *

Differs from {@link #nullSafeToString(Object)} in that it returns + * an empty String rather than "null" for a {@code null} value. + * + * @param obj the object to build a display String for + * @return a display String representation of {@code obj} + * @see #nullSafeToString(Object) + */ + public static String getDisplayString( Object obj ) { + if (obj == null) { + return EMPTY_STRING; + } + return nullSafeToString(obj); + } + + /** + * Determine the class name for the given object. + *

Returns a {@code "null"} String if {@code obj} is {@code null}. + * + * @param obj the object to introspect (may be {@code null}) + * @return the corresponding class name + */ + public static String nullSafeClassName( Object obj ) { + return (obj != null ? obj.getClass().getName() : NULL_STRING); + } + + /** + * Return a String representation of the specified Object. + *

Builds a String representation of the contents in case of an array. + * Returns a {@code "null"} String if {@code obj} is {@code null}. + * + * @param obj the object to build a String representation for + * @return a String representation of {@code obj} + */ + public static String nullSafeToString( Object obj ) { + if (obj == null) { + return NULL_STRING; + } + if (obj instanceof String) { + return (String) obj; + } + if (obj instanceof Object[]) { + return nullSafeToString((Object[]) obj); + } + if (obj instanceof boolean[]) { + return nullSafeToString((boolean[]) obj); + } + if (obj instanceof byte[]) { + return nullSafeToString((byte[]) obj); + } + if (obj instanceof char[]) { + return nullSafeToString((char[]) obj); + } + if (obj instanceof double[]) { + return nullSafeToString((double[]) obj); + } + if (obj instanceof float[]) { + return nullSafeToString((float[]) obj); + } + if (obj instanceof int[]) { + return nullSafeToString((int[]) obj); + } + if (obj instanceof long[]) { + return nullSafeToString((long[]) obj); + } + if (obj instanceof short[]) { + return nullSafeToString((short[]) obj); + } + String str = obj.toString(); + return (str != null ? str : EMPTY_STRING); + } + + /** + * Return a String representation of the contents of the specified array. + *

The String representation consists of a list of the array's elements, + * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated + * by the characters {@code ", "} (a comma followed by a space). + * Returns a {@code "null"} String if {@code array} is {@code null}. + * + * @param array the array to build a String representation for + * @return a String representation of {@code array} + */ + public static String nullSafeToString( Object[] array ) { + if (array == null) { + return NULL_STRING; + } + int length = array.length; + if (length == 0) { + return EMPTY_ARRAY; + } + StringJoiner stringJoiner = new StringJoiner(ARRAY_ELEMENT_SEPARATOR, ARRAY_START, ARRAY_END); + for (Object o : array) { + stringJoiner.add(String.valueOf(o)); + } + return stringJoiner.toString(); + } + + /** + * Return a String representation of the contents of the specified array. + *

The String representation consists of a list of the array's elements, + * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated + * by the characters {@code ", "} (a comma followed by a space). + * Returns a {@code "null"} String if {@code array} is {@code null}. + * + * @param array the array to build a String representation for + * @return a String representation of {@code array} + */ + public static String nullSafeToString( boolean[] array ) { + if (array == null) { + return NULL_STRING; + } + int length = array.length; + if (length == 0) { + return EMPTY_ARRAY; + } + StringJoiner stringJoiner = new StringJoiner(ARRAY_ELEMENT_SEPARATOR, ARRAY_START, ARRAY_END); + for (boolean b : array) { + stringJoiner.add(String.valueOf(b)); + } + return stringJoiner.toString(); + } + + /** + * Return a String representation of the contents of the specified array. + *

The String representation consists of a list of the array's elements, + * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated + * by the characters {@code ", "} (a comma followed by a space). + * Returns a {@code "null"} String if {@code array} is {@code null}. + * + * @param array the array to build a String representation for + * @return a String representation of {@code array} + */ + public static String nullSafeToString( byte[] array ) { + if (array == null) { + return NULL_STRING; + } + int length = array.length; + if (length == 0) { + return EMPTY_ARRAY; + } + StringJoiner stringJoiner = new StringJoiner(ARRAY_ELEMENT_SEPARATOR, ARRAY_START, ARRAY_END); + for (byte b : array) { + stringJoiner.add(String.valueOf(b)); + } + return stringJoiner.toString(); + } + + /** + * Return a String representation of the contents of the specified array. + *

The String representation consists of a list of the array's elements, + * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated + * by the characters {@code ", "} (a comma followed by a space). + * Returns a {@code "null"} String if {@code array} is {@code null}. + * + * @param array the array to build a String representation for + * @return a String representation of {@code array} + */ + public static String nullSafeToString( char[] array ) { + if (array == null) { + return NULL_STRING; + } + int length = array.length; + if (length == 0) { + return EMPTY_ARRAY; + } + StringJoiner stringJoiner = new StringJoiner(ARRAY_ELEMENT_SEPARATOR, ARRAY_START, ARRAY_END); + for (char c : array) { + stringJoiner.add('\'' + String.valueOf(c) + '\''); + } + return stringJoiner.toString(); + } + + /** + * Return a String representation of the contents of the specified array. + *

The String representation consists of a list of the array's elements, + * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated + * by the characters {@code ", "} (a comma followed by a space). + * Returns a {@code "null"} String if {@code array} is {@code null}. + * + * @param array the array to build a String representation for + * @return a String representation of {@code array} + */ + public static String nullSafeToString( double[] array ) { + if (array == null) { + return NULL_STRING; + } + int length = array.length; + if (length == 0) { + return EMPTY_ARRAY; + } + StringJoiner stringJoiner = new StringJoiner(ARRAY_ELEMENT_SEPARATOR, ARRAY_START, ARRAY_END); + for (double d : array) { + stringJoiner.add(String.valueOf(d)); + } + return stringJoiner.toString(); + } + + /** + * Return a String representation of the contents of the specified array. + *

The String representation consists of a list of the array's elements, + * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated + * by the characters {@code ", "} (a comma followed by a space). + * Returns a {@code "null"} String if {@code array} is {@code null}. + * + * @param array the array to build a String representation for + * @return a String representation of {@code array} + */ + public static String nullSafeToString( float[] array ) { + if (array == null) { + return NULL_STRING; + } + int length = array.length; + if (length == 0) { + return EMPTY_ARRAY; + } + StringJoiner stringJoiner = new StringJoiner(ARRAY_ELEMENT_SEPARATOR, ARRAY_START, ARRAY_END); + for (float f : array) { + stringJoiner.add(String.valueOf(f)); + } + return stringJoiner.toString(); + } + + /** + * Return a String representation of the contents of the specified array. + *

The String representation consists of a list of the array's elements, + * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated + * by the characters {@code ", "} (a comma followed by a space). + * Returns a {@code "null"} String if {@code array} is {@code null}. + * + * @param array the array to build a String representation for + * @return a String representation of {@code array} + */ + public static String nullSafeToString( int[] array ) { + if (array == null) { + return NULL_STRING; + } + int length = array.length; + if (length == 0) { + return EMPTY_ARRAY; + } + StringJoiner stringJoiner = new StringJoiner(ARRAY_ELEMENT_SEPARATOR, ARRAY_START, ARRAY_END); + for (int i : array) { + stringJoiner.add(String.valueOf(i)); + } + return stringJoiner.toString(); + } + + /** + * Return a String representation of the contents of the specified array. + *

The String representation consists of a list of the array's elements, + * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated + * by the characters {@code ", "} (a comma followed by a space). + * Returns a {@code "null"} String if {@code array} is {@code null}. + * + * @param array the array to build a String representation for + * @return a String representation of {@code array} + */ + public static String nullSafeToString( long[] array ) { + if (array == null) { + return NULL_STRING; + } + int length = array.length; + if (length == 0) { + return EMPTY_ARRAY; + } + StringJoiner stringJoiner = new StringJoiner(ARRAY_ELEMENT_SEPARATOR, ARRAY_START, ARRAY_END); + for (long l : array) { + stringJoiner.add(String.valueOf(l)); + } + return stringJoiner.toString(); + } + + /** + * Return a String representation of the contents of the specified array. + *

The String representation consists of a list of the array's elements, + * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated + * by the characters {@code ", "} (a comma followed by a space). + * Returns a {@code "null"} String if {@code array} is {@code null}. + * + * @param array the array to build a String representation for + * @return a String representation of {@code array} + */ + public static String nullSafeToString( short[] array ) { + if (array == null) { + return NULL_STRING; + } + int length = array.length; + if (length == 0) { + return EMPTY_ARRAY; + } + StringJoiner stringJoiner = new StringJoiner(ARRAY_ELEMENT_SEPARATOR, ARRAY_START, ARRAY_END); + for (short s : array) { + stringJoiner.add(String.valueOf(s)); + } + return stringJoiner.toString(); + } +}