Skip to content

Commit 370b414

Browse files
committed
Polishing.
Add assertions and missing Override annotations. Avoid recursive self-call on getClassLoader. Extend documentation. See #1627 Original pull request: #4389
1 parent 4b78ef6 commit 370b414

File tree

3 files changed

+66
-49
lines changed

3 files changed

+66
-49
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsTemplate.java

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,14 @@
5858
*/
5959
public class GridFsTemplate extends GridFsOperationsSupport implements GridFsOperations, ResourcePatternResolver {
6060

61-
private Supplier<GridFSBucket> bucketSupplier;
61+
private final Supplier<GridFSBucket> bucketSupplier;
6262

6363
/**
6464
* Creates a new {@link GridFsTemplate} using the given {@link MongoDatabaseFactory} and {@link MongoConverter}.
65+
* <p>
66+
* Note that the {@link GridFSBucket} is obtained only once from {@link MongoDatabaseFactory#getMongoDatabase()
67+
* MongoDatabase}. Use {@link #GridFsTemplate(MongoConverter, Supplier)} if you want to use different buckets from the
68+
* same Template instance.
6569
*
6670
* @param dbFactory must not be {@literal null}.
6771
* @param converter must not be {@literal null}.
@@ -72,6 +76,10 @@ public GridFsTemplate(MongoDatabaseFactory dbFactory, MongoConverter converter)
7276

7377
/**
7478
* Creates a new {@link GridFsTemplate} using the given {@link MongoDatabaseFactory} and {@link MongoConverter}.
79+
* <p>
80+
* Note that the {@link GridFSBucket} is obtained only once from {@link MongoDatabaseFactory#getMongoDatabase()
81+
* MongoDatabase}. Use {@link #GridFsTemplate(MongoConverter, Supplier)} if you want to use different buckets from the
82+
* same Template instance.
7583
*
7684
* @param dbFactory must not be {@literal null}.
7785
* @param converter must not be {@literal null}.
@@ -93,14 +101,19 @@ public GridFsTemplate(MongoConverter converter, Supplier<GridFSBucket> gridFSBuc
93101

94102
super(converter);
95103

104+
Assert.notNull(gridFSBucket, "GridFSBucket supplier must not be null");
105+
96106
this.bucketSupplier = gridFSBucket;
97107
}
98108

109+
@Override
99110
public ObjectId store(InputStream content, @Nullable String filename, @Nullable String contentType,
100111
@Nullable Object metadata) {
101112
return store(content, filename, contentType, toDocument(metadata));
102113
}
103114

115+
@Override
116+
@SuppressWarnings("unchecked")
104117
public <T> T store(GridFsObject<T, InputStream> upload) {
105118

106119
GridFSUploadOptions uploadOptions = computeUploadOptionsFor(upload.getOptions().getContentType(),
@@ -119,6 +132,7 @@ public <T> T store(GridFsObject<T, InputStream> upload) {
119132
return upload.getFileId();
120133
}
121134

135+
@Override
122136
public GridFSFindIterable find(Query query) {
123137

124138
Assert.notNull(query, "Query must not be null");
@@ -139,35 +153,41 @@ public GridFSFindIterable find(Query query) {
139153
return iterable;
140154
}
141155

156+
@Override
142157
public GridFSFile findOne(Query query) {
143158
return find(query).first();
144159
}
145160

161+
@Override
146162
public void delete(Query query) {
147163

148164
for (GridFSFile gridFSFile : find(query)) {
149165
getGridFs().delete(gridFSFile.getId());
150166
}
151167
}
152168

169+
@Override
153170
public ClassLoader getClassLoader() {
154-
return this.getClassLoader();
171+
return null;
155172
}
156173

174+
@Override
157175
public GridFsResource getResource(String location) {
158176

159177
return Optional.ofNullable(findOne(query(whereFilename().is(location)))) //
160178
.map(this::getResource) //
161179
.orElseGet(() -> GridFsResource.absent(location));
162180
}
163181

182+
@Override
164183
public GridFsResource getResource(GridFSFile file) {
165184

166185
Assert.notNull(file, "GridFSFile must not be null");
167186

168187
return new GridFsResource(file, getGridFs().openDownloadStream(file.getId()));
169188
}
170189

190+
@Override
171191
public GridFsResource[] getResources(String locationPattern) {
172192

173193
if (!StringUtils.hasText(locationPattern)) {
@@ -191,12 +211,14 @@ public GridFsResource[] getResources(String locationPattern) {
191211
return new GridFsResource[] { getResource(locationPattern) };
192212
}
193213

194-
GridFSBucket getGridFs() {
214+
private GridFSBucket getGridFs() {
195215
return this.bucketSupplier.get();
196216
}
197217

198218
private static GridFSBucket getGridFs(MongoDatabaseFactory dbFactory, @Nullable String bucket) {
199219

220+
Assert.notNull(dbFactory, "MongoDatabaseFactory must not be null");
221+
200222
MongoDatabase db = dbFactory.getMongoDatabase();
201223
return bucket == null ? GridFSBuckets.create(db) : GridFSBuckets.create(db, bucket);
202224
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/ReactiveGridFsTemplate.java

Lines changed: 36 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,16 @@
6262
public class ReactiveGridFsTemplate extends GridFsOperationsSupport implements ReactiveGridFsOperations {
6363

6464
private final DataBufferFactory dataBufferFactory;
65-
private Mono<GridFSBucket> bucketSupplier;
65+
private final Mono<GridFSBucket> bucketSupplier;
6666

6767
/**
6868
* Creates a new {@link ReactiveGridFsTemplate} using the given {@link ReactiveMongoDatabaseFactory} and
6969
* {@link MongoConverter}.
70+
* <p>
71+
* Note that the {@link GridFSBucket} is obtained only once from
72+
* {@link ReactiveMongoDatabaseFactory#getMongoDatabase() MongoDatabase}. Use
73+
* {@link #ReactiveGridFsTemplate(MongoConverter, Mono, DataBufferFactory)} if you want to use different buckets from
74+
* the same Template instance.
7075
*
7176
* @param dbFactory must not be {@literal null}.
7277
* @param converter must not be {@literal null}.
@@ -78,10 +83,15 @@ public ReactiveGridFsTemplate(ReactiveMongoDatabaseFactory dbFactory, MongoConve
7883
/**
7984
* Creates a new {@link ReactiveGridFsTemplate} using the given {@link ReactiveMongoDatabaseFactory} and
8085
* {@link MongoConverter}.
86+
* <p>
87+
* Note that the {@link GridFSBucket} is obtained only once from
88+
* {@link ReactiveMongoDatabaseFactory#getMongoDatabase() MongoDatabase}. Use
89+
* {@link #ReactiveGridFsTemplate(MongoConverter, Mono, DataBufferFactory)} if you want to use different buckets from
90+
* the same Template instance.
8191
*
8292
* @param dbFactory must not be {@literal null}.
8393
* @param converter must not be {@literal null}.
84-
* @param bucket
94+
* @param bucket can be {@literal null}.
8595
*/
8696
public ReactiveGridFsTemplate(ReactiveMongoDatabaseFactory dbFactory, MongoConverter converter,
8797
@Nullable String bucket) {
@@ -91,11 +101,16 @@ public ReactiveGridFsTemplate(ReactiveMongoDatabaseFactory dbFactory, MongoConve
91101
/**
92102
* Creates a new {@link ReactiveGridFsTemplate} using the given {@link DataBufferFactory},
93103
* {@link ReactiveMongoDatabaseFactory} and {@link MongoConverter}.
104+
* <p>
105+
* Note that the {@link GridFSBucket} is obtained only once from
106+
* {@link ReactiveMongoDatabaseFactory#getMongoDatabase() MongoDatabase}. Use
107+
* {@link #ReactiveGridFsTemplate(MongoConverter, Mono, DataBufferFactory)} if you want to use different buckets from
108+
* the same Template instance.
94109
*
95110
* @param dataBufferFactory must not be {@literal null}.
96111
* @param dbFactory must not be {@literal null}.
97112
* @param converter must not be {@literal null}.
98-
* @param bucket
113+
* @param bucket can be {@literal null}.
99114
*/
100115
public ReactiveGridFsTemplate(DataBufferFactory dataBufferFactory, ReactiveMongoDatabaseFactory dbFactory,
101116
MongoConverter converter, @Nullable String bucket) {
@@ -105,7 +120,7 @@ public ReactiveGridFsTemplate(DataBufferFactory dataBufferFactory, ReactiveMongo
105120
/**
106121
* Creates a new {@link ReactiveGridFsTemplate} using the given {@link MongoConverter}, {@link Mono} emitting a
107122
* {@link ReactiveMongoDatabaseFactory} and {@link DataBufferFactory}.
108-
*
123+
*
109124
* @param converter must not be {@literal null}.
110125
* @param gridFSBucket must not be {@literal null}.
111126
* @param dataBufferFactory must not be {@literal null}.
@@ -116,6 +131,7 @@ public ReactiveGridFsTemplate(MongoConverter converter, Mono<GridFSBucket> gridF
116131

117132
super(converter);
118133

134+
Assert.notNull(gridFSBucket, "GridFSBucket Mono must not be null");
119135
Assert.notNull(dataBufferFactory, "DataBufferFactory must not be null");
120136

121137
this.bucketSupplier = gridFSBucket;
@@ -128,6 +144,8 @@ public Mono<ObjectId> store(Publisher<DataBuffer> content, @Nullable String file
128144
return store(content, filename, contentType, toDocument(metadata));
129145
}
130146

147+
@Override
148+
@SuppressWarnings("unchecked")
131149
public <T> Mono<T> store(GridFsObject<T, Publisher<DataBuffer>> upload) {
132150

133151
GridFSUploadOptions uploadOptions = computeUploadOptionsFor(upload.getOptions().getContentType(),
@@ -258,15 +276,18 @@ public <T> Flux<T> createFlux(ReactiveBucketCallback<T> callback) {
258276
return doGetBucket().flatMapMany(callback::doInBucket);
259277
}
260278

261-
static Mono<GridFSBucket> doGetBucket(ReactiveMongoDatabaseFactory dbFactory, @Nullable String bucket) {
262-
return dbFactory.getMongoDatabase()
263-
.map(db -> bucket == null ? GridFSBuckets.create(db) : GridFSBuckets.create(db, bucket));
264-
}
265-
266279
protected Mono<GridFSBucket> doGetBucket() {
267280
return bucketSupplier;
268281
}
269282

283+
private static Mono<GridFSBucket> doGetBucket(ReactiveMongoDatabaseFactory dbFactory, @Nullable String bucket) {
284+
285+
Assert.notNull(dbFactory, "ReactiveMongoDatabaseFactory must not be null");
286+
287+
return dbFactory.getMongoDatabase()
288+
.map(db -> bucket == null ? GridFSBuckets.create(db) : GridFSBuckets.create(db, bucket));
289+
}
290+
270291
/**
271292
* @param <T>
272293
* @author Mathieu Ouellet
@@ -289,6 +310,7 @@ public FindCallback(Query query, Document queryObject, Document sortObject) {
289310
this.sortObject = sortObject;
290311
}
291312

313+
@Override
292314
public GridFSFindPublisher doInBucket(GridFSBucket bucket) {
293315

294316
GridFSFindPublisher findPublisher = bucket.find(queryObject).sort(sortObject);
@@ -326,55 +348,25 @@ public GridFSFindPublisher doInBucket(GridFSBucket bucket) {
326348
}
327349
}
328350

329-
private static class UploadCallback implements ReactiveBucketCallback<Void> {
330-
331-
private final BsonValue fileId;
332-
private final String filename;
333-
private final Publisher<ByteBuffer> source;
334-
private final GridFSUploadOptions uploadOptions;
335-
336-
public UploadCallback(BsonValue fileId, String filename, Publisher<ByteBuffer> source,
337-
GridFSUploadOptions uploadOptions) {
338-
339-
this.fileId = fileId;
340-
this.filename = filename;
341-
this.source = source;
342-
this.uploadOptions = uploadOptions;
343-
}
351+
private record UploadCallback(BsonValue fileId, String filename, Publisher<ByteBuffer> source,
352+
GridFSUploadOptions uploadOptions) implements ReactiveBucketCallback<Void> {
344353

345354
@Override
346355
public GridFSUploadPublisher<Void> doInBucket(GridFSBucket bucket) {
347356
return bucket.uploadFromPublisher(fileId, filename, source, uploadOptions);
348357
}
349358
}
350359

351-
private static class AutoIdCreatingUploadCallback implements ReactiveBucketCallback<ObjectId> {
352-
353-
private final String filename;
354-
private final Publisher<ByteBuffer> source;
355-
private final GridFSUploadOptions uploadOptions;
356-
357-
public AutoIdCreatingUploadCallback(String filename, Publisher<ByteBuffer> source,
358-
GridFSUploadOptions uploadOptions) {
359-
360-
this.filename = filename;
361-
this.source = source;
362-
this.uploadOptions = uploadOptions;
363-
}
360+
private record AutoIdCreatingUploadCallback(String filename, Publisher<ByteBuffer> source,
361+
GridFSUploadOptions uploadOptions) implements ReactiveBucketCallback<ObjectId> {
364362

365363
@Override
366364
public GridFSUploadPublisher<ObjectId> doInBucket(GridFSBucket bucket) {
367365
return bucket.uploadFromPublisher(filename, source, uploadOptions);
368366
}
369367
}
370368

371-
private static class DeleteCallback implements ReactiveBucketCallback<Void> {
372-
373-
private final BsonValue id;
374-
375-
public DeleteCallback(BsonValue id) {
376-
this.id = id;
377-
}
369+
private record DeleteCallback(BsonValue id) implements ReactiveBucketCallback<Void> {
378370

379371
@Override
380372
public Publisher<Void> doInBucket(GridFSBucket bucket) {

src/main/asciidoc/reference/gridfs.adoc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
MongoDB supports storing binary files inside its filesystem, GridFS. Spring Data MongoDB provides a `GridFsOperations` interface as well as the corresponding implementation, `GridFsTemplate`, to let you interact with the filesystem. You can set up a `GridFsTemplate` instance by handing it a `MongoDatabaseFactory` as well as a `MongoConverter`, as the following example shows:
55

6-
76
====
87
.Java
98
[source,java,role="primary"]
@@ -82,7 +81,7 @@ class GridFsClient {
8281
8382
@Test
8483
public void findFilesInGridFs() {
85-
GridFSFindIterable result = operations.find(query(whereFilename().is("filename.txt")))
84+
GridFSFindIterable result = operations.find(query(whereFilename().is("filename.txt")));
8685
}
8786
}
8887
----
@@ -110,3 +109,7 @@ class GridFsClient {
110109
====
111110

112111
`GridFsOperations` extends `ResourcePatternResolver` and lets the `GridFsTemplate` (for example) to be plugged into an `ApplicationContext` to read Spring Config files from MongoDB database.
112+
113+
NOTE: By default, `GridFsTemplate` obtains `GridFSBucket` once upon the first GridFS interaction.
114+
After that, the Template instance reuses the cached bucket.
115+
To use different buckets, from the same Template instance use the constructor accepting `Supplier<GridFSBucket>`.

0 commit comments

Comments
 (0)