diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsObject.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsObject.java index 592bab940..fd158b82b 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsObject.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsObject.java @@ -21,7 +21,7 @@ import org.springframework.lang.Nullable; import com.mongodb.client.gridfs.model.GridFSFile; /** - * A common interface when dealing with GridFs items using Spring Data.o + * A common interface when dealing with GridFs items using Spring Data. * * @author Christoph Strobl * @since 3.0 @@ -31,7 +31,7 @@ public interface GridFsObject { /** * The {@link GridFSFile#getId()} value converted into its simple java type.
* A {@link org.bson.BsonString} will be converted to plain {@link String}. - * + * * @return can be {@literal null} depending on the implementation. */ @Nullable @@ -39,34 +39,35 @@ public interface GridFsObject { /** * The filename. - * + * * @return */ String getFilename(); /** * The actual file content. - * + * * @return + * @throws IllegalStateException if the content cannot be obtained. */ CONTENT getContent(); /** * Additional information like file metadata (eg. contentType). - * + * * @return never {@literal null}. */ Options getOptions(); /** * Additional, context relevant information. - * + * * @author Christoph Strobl */ class Options { - private Document metadata = new Document(); - private int chunkSize = -1; + private final Document metadata; + private final int chunkSize; private Options(Document metadata, int chunkSize) { @@ -83,16 +84,6 @@ public interface GridFsObject { return new Options(new Document(), -1); } - /** - * Static factory method to create {@link Options} with given chunk size. - * - * @param chunkSize - * @return new instance of {@link Options}. - */ - public static Options chunked(int chunkSize) { - return new Options(new Document(), chunkSize); - } - /** * Static factory method to create {@link Options} with given content type. * @@ -115,7 +106,7 @@ public interface GridFsObject { /** * Set the associated content type. - * + * * @param contentType must not be {@literal null}. * @return new instance of {@link Options}. */ diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsOperations.java index 5f7ee4ce9..036666857 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsOperations.java @@ -59,7 +59,9 @@ public interface GridFsOperations extends ResourcePatternResolver { * @param metadata can be {@literal null}. * @return the {@link ObjectId} of the {@link com.mongodb.client.gridfs.model.GridFSFile} just created. */ - ObjectId store(InputStream content, @Nullable Object metadata); + default ObjectId store(InputStream content, @Nullable Object metadata) { + return store(content, null, metadata); + } /** * Stores the given content into a file with the given name. @@ -80,7 +82,9 @@ public interface GridFsOperations extends ResourcePatternResolver { * @param contentType can be {@literal null}. * @return the {@link ObjectId} of the {@link com.mongodb.client.gridfs.model.GridFSFile} just created. */ - ObjectId store(InputStream content, @Nullable String filename, @Nullable String contentType); + default ObjectId store(InputStream content, @Nullable String filename, @Nullable String contentType) { + return store(content, filename, contentType, null); + } /** * Stores the given content into a file with the given name using the given metadata. The metadata object will be @@ -91,7 +95,9 @@ public interface GridFsOperations extends ResourcePatternResolver { * @param metadata can be {@literal null}. * @return the {@link ObjectId} of the {@link com.mongodb.client.gridfs.model.GridFSFile} just created. */ - ObjectId store(InputStream content, @Nullable String filename, @Nullable Object metadata); + default ObjectId store(InputStream content, @Nullable String filename, @Nullable Object metadata) { + return store(content, filename, null, metadata); + } /** * Stores the given content into a file with the given name and content type using the given metadata. The metadata @@ -141,21 +147,21 @@ public interface GridFsOperations extends ResourcePatternResolver { uploadBuilder.metadata(metadata); } - return save(uploadBuilder.build()); + return store(uploadBuilder.build()); } /** * Stores the given {@link GridFsObject}, likely a {@link GridFsUpload}, into into a file with given * {@link GridFsObject#getFilename() name}. If the {@link GridFsObject#getFileId()} is set, the file will be stored * with that id, otherwise the server auto creates a new id.
- * + * * @param upload the {@link GridFsObject} (most likely a {@link GridFsUpload}) to be stored. * @param id type of the underlying {@link com.mongodb.client.gridfs.model.GridFSFile} * @return the id of the stored file. Either an auto created value or {@link GridFsObject#getFileId()}, but never * {@literal null}. * @since 3.0 */ - T save(GridFsObject upload); + T store(GridFsObject upload); /** * Returns all files matching the given query. Note, that currently {@link Sort} criterias defined at the diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsTemplate.java index cf8b2211c..45702ef24 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsTemplate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsTemplate.java @@ -87,31 +87,6 @@ public class GridFsTemplate extends GridFsOperationsSupport implements GridFsOpe this.bucket = bucket; } - /* - * (non-Javadoc) - * @see org.springframework.data.mongodb.gridfs.GridFsOperations#store(java.io.InputStream, java.lang.Object) - */ - @Override - public ObjectId store(InputStream content, @Nullable Object metadata) { - return store(content, null, metadata); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.mongodb.gridfs.GridFsOperations#store(java.io.InputStream, java.lang.String, java.lang.String) - */ - public ObjectId store(InputStream content, @Nullable String filename, @Nullable String contentType) { - return store(content, filename, contentType, (Object) null); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.mongodb.gridfs.GridFsOperations#store(java.io.InputStream, java.lang.String, java.lang.Object) - */ - public ObjectId store(InputStream content, @Nullable String filename, @Nullable Object metadata) { - return store(content, filename, null, metadata); - } - /* * (non-Javadoc) * @see org.springframework.data.mongodb.gridfs.GridFsOperations#store(java.io.InputStream, java.lang.String, java.lang.String, java.lang.Object) @@ -125,7 +100,7 @@ public class GridFsTemplate extends GridFsOperationsSupport implements GridFsOpe * (non-Javadoc) * @see org.springframework.data.mongodb.gridfs.GridFsOperations#save(org.springframework.data.mongodb.gridfs.GridFsObject) */ - public T save(GridFsObject upload) { + public T store(GridFsObject upload) { GridFSUploadOptions uploadOptions = computeUploadOptionsFor(upload.getOptions().getContentType(), upload.getOptions().getMetadata()); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsUpload.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsUpload.java index ee80c7936..c86926db7 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsUpload.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsUpload.java @@ -15,42 +15,54 @@ */ package org.springframework.data.mongodb.gridfs; -import java.io.IOException; import java.io.InputStream; +import java.util.function.Supplier; import org.bson.Document; import org.bson.types.ObjectId; + import org.springframework.data.util.Lazy; import org.springframework.lang.Nullable; +import org.springframework.util.Assert; +import org.springframework.util.StreamUtils; import com.mongodb.client.gridfs.model.GridFSFile; /** + * Upload descriptor for a GridFS file upload. + * * @author Christoph Strobl + * @author Mark Paluch * @since 3.0 */ public class GridFsUpload implements GridFsObject { - private static final InputStream EMPTY_STREAM = new InputStream() { - @Override - public int read() throws IOException { - return -1; - } - }; + private final @Nullable ID id; + private final Lazy dataStream; + private final String filename; + private final Options options; - private ID id; - private Lazy dataStream; - private String filename; - private Options options; + private GridFsUpload(@Nullable ID id, Lazy dataStream, String filename, Options options) { + + Assert.notNull(dataStream, "Data Stream must not be null"); + Assert.notNull(filename, "Filename must not be null"); + Assert.notNull(options, "Options must not be null"); + + this.id = id; + this.dataStream = dataStream; + this.filename = filename; + this.options = options; + } /** * The {@link GridFSFile#getId()} value converted into its simple java type.
* A {@link org.bson.BsonString} will be converted to plain {@link String}. - * + * * @return can be {@literal null}. * @see org.springframework.data.mongodb.gridfs.GridFsObject#getFileId() */ @Override + @Nullable public ID getFileId() { return id; } @@ -70,7 +82,7 @@ public class GridFsUpload implements GridFsObject { */ @Override public InputStream getContent() { - return dataStream.orElse(EMPTY_STREAM); + return dataStream.orElse(StreamUtils.emptyInput()); } /* @@ -89,22 +101,22 @@ public class GridFsUpload implements GridFsObject { * @return new instance of {@link GridFsUpload}. */ public static GridFsUploadBuilder fromStream(InputStream stream) { - return new GridFsUploadBuilder().content(stream); + return new GridFsUploadBuilder().content(stream); } /** * Builder to create {@link GridFsUpload} in a fluent way. - * + * * @param the target id type. */ public static class GridFsUploadBuilder { - private GridFsUpload upload; + private Object id; + private Lazy dataStream; + private String filename; + private Options options = Options.none(); - public GridFsUploadBuilder() { - this.upload = new GridFsUpload(); - this.upload.options = Options.none(); - } + private GridFsUploadBuilder() {} /** * Define the content of the file to upload. @@ -114,7 +126,22 @@ public class GridFsUpload implements GridFsObject { */ public GridFsUploadBuilder content(InputStream stream) { - upload.dataStream = Lazy.of(() -> stream); + Assert.notNull(stream, "InputStream must not be null"); + + return content(() -> stream); + } + + /** + * Define the content of the file to upload. + * + * @param stream the upload content. + * @return this. + */ + public GridFsUploadBuilder content(Supplier stream) { + + Assert.notNull(stream, "InputStream Supplier must not be null"); + + this.dataStream = Lazy.of(stream); return this; } @@ -127,7 +154,7 @@ public class GridFsUpload implements GridFsObject { */ public GridFsUploadBuilder id(T1 id) { - upload.id = id; + this.id = id; return (GridFsUploadBuilder) this; } @@ -139,7 +166,7 @@ public class GridFsUpload implements GridFsObject { */ public GridFsUploadBuilder filename(String filename) { - upload.filename = filename; + this.filename = filename; return this; } @@ -151,7 +178,9 @@ public class GridFsUpload implements GridFsObject { */ public GridFsUploadBuilder options(Options options) { - upload.options = options; + Assert.notNull(options, "Options must not be null"); + + this.options = options; return this; } @@ -163,7 +192,7 @@ public class GridFsUpload implements GridFsObject { */ public GridFsUploadBuilder metadata(Document metadata) { - upload.options = upload.options.metadata(metadata); + this.options = this.options.metadata(metadata); return this; } @@ -175,40 +204,42 @@ public class GridFsUpload implements GridFsObject { */ public GridFsUploadBuilder chunkSize(int chunkSize) { - upload.options = upload.options.chunkSize(chunkSize); + this.options = this.options.chunkSize(chunkSize); return this; } /** * Set id, filename, metadata and chunk size from given file. - * + * * @param gridFSFile must not be {@literal null}. * @return this. */ public GridFsUploadBuilder gridFsFile(GridFSFile gridFSFile) { - upload.id = gridFSFile.getId(); - upload.filename = gridFSFile.getFilename(); - upload.options = upload.options.metadata(gridFSFile.getMetadata()); - upload.options = upload.options.chunkSize(gridFSFile.getChunkSize()); + Assert.notNull(gridFSFile, "GridFSFile must not be null"); + + this.id = gridFSFile.getId(); + this.filename = gridFSFile.getFilename(); + this.options = this.options.metadata(gridFSFile.getMetadata()); + this.options = this.options.chunkSize(gridFSFile.getChunkSize()); return this; } /** * Set the content type. - * + * * @param contentType must not be {@literal null}. * @return this. */ public GridFsUploadBuilder contentType(String contentType) { - upload.options = upload.options.contentType(contentType); + this.options = this.options.contentType(contentType); return this; } public GridFsUpload build() { - return (GridFsUpload) upload; + return new GridFsUpload(id, dataStream, filename, options); } } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsOperations.java index fa562582f..fe7f5bd14 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsOperations.java @@ -155,7 +155,7 @@ public interface ReactiveGridFsOperations { uploadBuilder.metadata(metadata); } - return save(uploadBuilder.build()); + return store(uploadBuilder.build()); } /** @@ -169,7 +169,7 @@ public interface ReactiveGridFsOperations { * {@link GridFsObject#getFileId()}. * @since 3.0 */ - Mono save(GridFsObject> upload); + Mono store(GridFsObject> upload); /** * Returns a {@link Flux} emitting all files matching the given query.
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsTemplate.java index 49cd83fba..524de7b9b 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsTemplate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsTemplate.java @@ -121,7 +121,7 @@ public class ReactiveGridFsTemplate extends GridFsOperationsSupport implements R * (non-Javadoc) * @see org.springframework.data.mongodb.gridfs.ReactiveGridFsOperations#save(org.springframework.data.mongodb.gridfs.GridFsObject) */ - public Mono save(GridFsObject> upload) { + public Mono store(GridFsObject> upload) { GridFSUploadOptions uploadOptions = computeUploadOptionsFor(upload.getOptions().getContentType(), upload.getOptions().getMetadata()); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsUpload.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsUpload.java index 30a33f3ae..9decedc78 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsUpload.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsUpload.java @@ -20,19 +20,35 @@ import org.bson.types.ObjectId; import org.reactivestreams.Publisher; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.lang.Nullable; +import org.springframework.util.Assert; import com.mongodb.client.gridfs.model.GridFSFile; /** + * Upload descriptor for a GridFS file upload. + * * @author Christoph Strobl + * @author Mark Paluch * @since 3.0 */ public class ReactiveGridFsUpload implements GridFsObject> { - private ID id; - private Publisher dataStream; - private String filename; - private Options options; + private final @Nullable ID id; + private final Publisher dataStream; + private final String filename; + private final Options options; + + private ReactiveGridFsUpload(@Nullable ID id, Publisher dataStream, String filename, Options options) { + + Assert.notNull(dataStream, "Data Stream must not be null"); + Assert.notNull(filename, "Filename must not be null"); + Assert.notNull(options, "Options must not be null"); + + this.id = id; + this.dataStream = dataStream; + this.filename = filename; + this.options = options; + } /** * The {@link GridFSFile#getId()} value converted into its simple java type.
@@ -42,6 +58,7 @@ public class ReactiveGridFsUpload implements GridFsObject implements GridFsObject fromPublisher(Publisher source) { - return new ReactiveGridFsUploadBuilder().content(source); + return new ReactiveGridFsUploadBuilder().content(source); } /** @@ -90,13 +107,12 @@ public class ReactiveGridFsUpload implements GridFsObject { - ReactiveGridFsUpload upload; + private @Nullable Object id; + private Publisher dataStream; + private String filename; + private Options options = Options.none(); - public ReactiveGridFsUploadBuilder() { - - this.upload = new ReactiveGridFsUpload(); - this.upload.options = Options.none(); - } + private ReactiveGridFsUploadBuilder() {} /** * Define the content of the file to upload. @@ -105,7 +121,7 @@ public class ReactiveGridFsUpload implements GridFsObject content(Publisher source) { - upload.dataStream = source; + this.dataStream = source; return this; } @@ -118,7 +134,7 @@ public class ReactiveGridFsUpload implements GridFsObject ReactiveGridFsUploadBuilder id(T1 id) { - upload.id = id; + this.id = id; return (ReactiveGridFsUploadBuilder) this; } @@ -130,7 +146,7 @@ public class ReactiveGridFsUpload implements GridFsObject filename(String filename) { - upload.filename = filename; + this.filename = filename; return this; } @@ -142,7 +158,9 @@ public class ReactiveGridFsUpload implements GridFsObject options(Options options) { - upload.options = options; + Assert.notNull(options, "Options must not be null"); + + this.options = options; return this; } @@ -154,7 +172,7 @@ public class ReactiveGridFsUpload implements GridFsObject metadata(Document metadata) { - upload.options = upload.options.metadata(metadata); + this.options = this.options.metadata(metadata); return this; } @@ -166,7 +184,7 @@ public class ReactiveGridFsUpload implements GridFsObject chunkSize(int chunkSize) { - upload.options = upload.options.chunkSize(chunkSize); + this.options = this.options.chunkSize(chunkSize); return this; } @@ -178,10 +196,12 @@ public class ReactiveGridFsUpload implements GridFsObject gridFsFile(GridFSFile gridFSFile) { - upload.id = gridFSFile.getId(); - upload.filename = gridFSFile.getFilename(); - upload.options = upload.options.metadata(gridFSFile.getMetadata()); - upload.options = upload.options.chunkSize(gridFSFile.getChunkSize()); + Assert.notNull(gridFSFile, "GridFSFile must not be null"); + + this.id = gridFSFile.getId(); + this.filename = gridFSFile.getFilename(); + this.options = this.options.metadata(gridFSFile.getMetadata()); + this.options = this.options.chunkSize(gridFSFile.getChunkSize()); return this; } @@ -194,12 +214,12 @@ public class ReactiveGridFsUpload implements GridFsObject contentType(String contentType) { - upload.options = upload.options.contentType(contentType); + this.options = this.options.contentType(contentType); return this; } public ReactiveGridFsUpload build() { - return (ReactiveGridFsUpload) upload; + return new ReactiveGridFsUpload(id, dataStream, filename, options); } } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java index e1e868da6..c2dcec68b 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java @@ -36,11 +36,11 @@ import org.bson.codecs.DocumentCodec; import org.bson.conversions.Bson; import org.bson.json.JsonParseException; import org.bson.types.ObjectId; + import org.springframework.core.convert.converter.Converter; import org.springframework.data.mongodb.CodecRegistryProvider; import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import org.springframework.util.NumberUtils; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -171,16 +171,12 @@ public class BsonUtils { return new BsonBoolean((Boolean) source); } - if(source instanceof Float) { + if (source instanceof Float) { return new BsonDouble((Float) source); } - if (source instanceof Double) { - return new BsonDouble((Double) source); - } - - throw new IllegalArgumentException( - String.format("Unable to convert % (%s) to BsonValue.", source, source != null ? source.getClass() : "null")); + throw new IllegalArgumentException(String.format("Unable to convert %s (%s) to BsonValue.", source, + source != null ? source.getClass().getName() : "null")); } /** diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/gridfs/GridFsTemplateIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/gridfs/GridFsTemplateIntegrationTests.java index 737f397f3..ac012f426 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/gridfs/GridFsTemplateIntegrationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/gridfs/GridFsTemplateIntegrationTests.java @@ -301,7 +301,7 @@ public class GridFsTemplateIntegrationTests { .contentType("xml") // .build(); - assertThat(operations.save(upload)).isEqualTo(id); + assertThat(operations.store(upload)).isEqualTo(id); GridFsResource fsFile = operations.getResource(operations.findOne(query(where("_id").is(id)))); byte[] content = StreamUtils.copyToByteArray(fsFile.getInputStream()); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsTemplateTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsTemplateTests.java index 236f3b78d..7ec42852c 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsTemplateTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsTemplateTests.java @@ -278,7 +278,7 @@ public class ReactiveGridFsTemplateTests { .contentType("xml") // .build(); - operations.save(upload).as(StepVerifier::create).expectNext(id).verifyComplete(); + operations.store(upload).as(StepVerifier::create).expectNext(id).verifyComplete(); operations.findOne(query(where("_id").is(id))).flatMap(operations::getResource) .flatMapMany(ReactiveGridFsResource::getDownloadStream) //