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 b7b5c6463..a6db1a015 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 @@ -153,7 +153,8 @@ public interface GridFsOperations extends ResourcePatternResolver { * Returns the {@link GridFsResource} with the given file name. * * @param filename must not be {@literal null}. - * @return the resource if it exists or {@literal null}. + * @return the resource. Use {@link org.springframework.core.io.Resource#exists()} to check if the returned + * {@link GridFsResource} is actually present. * @see ResourcePatternResolver#getResource(String) */ GridFsResource getResource(String filename); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsResource.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsResource.java index d96e34f45..e0190d458 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsResource.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsResource.java @@ -23,6 +23,7 @@ import java.util.Optional; import org.springframework.core.io.InputStreamResource; import org.springframework.core.io.Resource; import org.springframework.data.util.Optionals; +import org.springframework.lang.Nullable; import com.mongodb.MongoGridFSException; import com.mongodb.client.gridfs.model.GridFSFile; @@ -37,9 +38,24 @@ import com.mongodb.client.gridfs.model.GridFSFile; */ public class GridFsResource extends InputStreamResource { + private static final GridFsResource ABSENT = new GridFsResource() { + + @Override + public boolean exists() { + return false; + } + + }; + static final String CONTENT_TYPE_FIELD = "_contentType"; - private final GridFSFile file; + private final @Nullable GridFSFile file; + + private GridFsResource() { + + super(new ByteArrayInputStream(new byte[] {})); + file = null; + } /** * Creates a new {@link GridFsResource} from the given {@link GridFSFile}. @@ -62,12 +78,24 @@ public class GridFsResource extends InputStreamResource { this.file = file; } + /** + * Obtain an absent {@link GridFsResource}. + * + * @return never {@literal null}. + * @since 2.1 + */ + public static GridFsResource absent() { + return ABSENT; + } + /* * (non-Javadoc) * @see org.springframework.core.io.AbstractResource#contentLength() */ @Override public long contentLength() throws IOException { + + verifyExists(); return file.getLength(); } @@ -77,15 +105,19 @@ public class GridFsResource extends InputStreamResource { */ @Override public String getFilename() throws IllegalStateException { + + verifyExists(); return file.getFilename(); } /* - * (non-Javadoc) - * @see org.springframework.core.io.AbstractResource#lastModified() - */ + * (non-Javadoc) + * @see org.springframework.core.io.AbstractResource#lastModified() + */ @Override public long lastModified() throws IOException { + + verifyExists(); return file.getUploadDate().getTime(); } @@ -95,6 +127,8 @@ public class GridFsResource extends InputStreamResource { * @return never {@literal null}. */ public Object getId() { + + verifyExists(); return file.getId(); } @@ -108,10 +142,19 @@ public class GridFsResource extends InputStreamResource { @SuppressWarnings("deprecation") public String getContentType() { + verifyExists(); + return Optionals .firstNonEmpty( () -> Optional.ofNullable(file.getMetadata()).map(it -> it.get(CONTENT_TYPE_FIELD, String.class)), () -> Optional.ofNullable(file.getContentType())) .orElseThrow(() -> new MongoGridFSException("No contentType data for this GridFS file")); } + + private void verifyExists() { + + if (!exists()) { + throw new IllegalStateException("The resource does not exist."); + } + } } 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 e7abd3d70..f8051d9c7 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 @@ -227,7 +227,9 @@ public class GridFsTemplate implements GridFsOperations, ResourcePatternResolver * @see org.springframework.core.io.ResourceLoader#getResource(java.lang.String) */ public GridFsResource getResource(String location) { - return Optional.ofNullable(findOne(query(whereFilename().is(location)))).map(this::getResource).orElse(null); + + return Optional.ofNullable(findOne(query(whereFilename().is(location)))).map(this::getResource) + .orElseGet(GridFsResource::absent); } /* diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/gridfs/GridFsResourceUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/gridfs/GridFsResourceUnitTests.java index a159ca7da..b9879c53c 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/gridfs/GridFsResourceUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/gridfs/GridFsResourceUnitTests.java @@ -61,4 +61,12 @@ public class GridFsResourceUnitTests { assertThatThrownBy(resource::getContentType).isInstanceOf(MongoGridFSException.class); } + + @Test // DATAMONGO-1914 + public void gettersThrowExceptionForAbsentResource() { + + assertThatExceptionOfType(IllegalStateException.class).isThrownBy(() -> GridFsResource.absent().getContentType()); + assertThatExceptionOfType(IllegalStateException.class).isThrownBy(() -> GridFsResource.absent().getFilename()); + assertThatExceptionOfType(IllegalStateException.class).isThrownBy(() -> GridFsResource.absent().contentLength()); + } } 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 5ddf1f24d..4eb6051c2 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 @@ -177,9 +177,9 @@ public class GridFsTemplateIntegrationTests { operations.find(null); } - @Test // DATAMONGO-813 - public void getResourceShouldReturnNullForNonExistingResource() { - assertThat(operations.getResource("doesnotexist")).isNull(); + @Test // DATAMONGO-813, DATAMONGO-1914 + public void getResourceShouldReturnAbsentResourceForNonExistingResource() { + assertThat(operations.getResource("doesnotexist")).isEqualTo(GridFsResource.absent()); } @Test // DATAMONGO-809