GridFsUpload.java
/*
* Copyright 2020-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.mongodb.gridfs;
import java.io.InputStream;
import java.util.function.Supplier;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.jspecify.annotations.Nullable;
import org.springframework.data.util.Lazy;
import org.springframework.lang.Contract;
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 GridFsUpload<ID> implements GridFsObject<ID, InputStream> {
private final @Nullable ID id;
private final Lazy<InputStream> dataStream;
private final String filename;
private final Options options;
private GridFsUpload(@Nullable ID id, Lazy<InputStream> 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. <br />
* 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
public @Nullable ID getFileId() {
return id;
}
@Override
public String getFilename() {
return filename;
}
@Override
@SuppressWarnings("NullAway")
public InputStream getContent() {
return dataStream.orElse(InputStream.nullInputStream());
}
@Override
public Options getOptions() {
return options;
}
/**
* Create a new instance of {@link GridFsUpload} for the given {@link InputStream}.
*
* @param stream must not be {@literal null}.
* @return new instance of {@link GridFsUpload}.
*/
public static GridFsUploadBuilder<ObjectId> fromStream(InputStream stream) {
return new GridFsUploadBuilder<ObjectId>().content(stream);
}
/**
* Builder to create {@link GridFsUpload} in a fluent way.
*
* @param <T> the target id type.
*/
public static class GridFsUploadBuilder<T> {
private @Nullable Object id;
private @Nullable Lazy<InputStream> dataStream;
private @Nullable String filename;
private Options options = Options.none();
private GridFsUploadBuilder() {}
/**
* Define the content of the file to upload.
*
* @param stream the upload content.
* @return this.
*/
public GridFsUploadBuilder<T> content(InputStream 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.
*/
@Contract("_ -> this")
public GridFsUploadBuilder<T> content(Supplier<InputStream> stream) {
Assert.notNull(stream, "InputStream Supplier must not be null");
this.dataStream = Lazy.of(stream);
return this;
}
/**
* Set the id to use.
*
* @param id the id to save the content to.
* @param <T1>
* @return this.
*/
@SuppressWarnings("unchecked")
@Contract("_ -> this")
public <T1> GridFsUploadBuilder<T1> id(T1 id) {
this.id = id;
return (GridFsUploadBuilder<T1>) this;
}
/**
* Set the filename.
*
* @param filename the filename to use.
* @return this.
*/
@Contract("_ -> this")
public GridFsUploadBuilder<T> filename(String filename) {
this.filename = filename;
return this;
}
/**
* Set additional file information.
*
* @param options must not be {@literal null}.
* @return this.
*/
@Contract("_ -> this")
public GridFsUploadBuilder<T> options(Options options) {
Assert.notNull(options, "Options must not be null");
this.options = options;
return this;
}
/**
* Set the file metadata.
*
* @param metadata must not be {@literal null}.
* @return this.
*/
@Contract("_ -> this")
public GridFsUploadBuilder<T> metadata(Document metadata) {
this.options = this.options.metadata(metadata);
return this;
}
/**
* Set the upload chunk size in bytes.
*
* @param chunkSize use negative number for default.
* @return this.
*/
@Contract("_ -> this")
public GridFsUploadBuilder<T> chunkSize(int 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.
*/
@Contract("_ -> this")
public GridFsUploadBuilder<T> gridFsFile(GridFSFile gridFSFile) {
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.
*/
@Contract("_ -> this")
public GridFsUploadBuilder<T> contentType(String contentType) {
this.options = this.options.contentType(contentType);
return this;
}
@Contract("-> new")
public GridFsUpload<T> build() {
Assert.notNull(dataStream, "DataStream must be set first");
Assert.notNull(filename, "Filename must be set first");
Assert.notNull(options, "Options must be set first");
return new GridFsUpload(id, dataStream, filename, options);
}
}
}