Browse Source

DATAMONGO-1914 - Polishing.

Throw FileNotFoundException on inherited methods throwing IOException if resource is absent. Retain filename for absent resources to provide context through GridFsResource.getFilename(). Switch exists() to determine presence/absence based on GridFSFile presence. Extend tests.

Original pull request: #555.
pull/555/merge
Mark Paluch 8 years ago
parent
commit
364f266a3a
  1. 87
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsResource.java
  2. 2
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/gridfs/GridFsTemplate.java
  3. 28
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/gridfs/GridFsResourceUnitTests.java
  4. 2
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/gridfs/GridFsTemplateIntegrationTests.java

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

@ -16,6 +16,7 @@
package org.springframework.data.mongodb.gridfs; package org.springframework.data.mongodb.gridfs;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Optional; import java.util.Optional;
@ -24,6 +25,7 @@ import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
import org.springframework.data.util.Optionals; import org.springframework.data.util.Optionals;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import com.mongodb.MongoGridFSException; import com.mongodb.MongoGridFSException;
import com.mongodb.client.gridfs.model.GridFSFile; import com.mongodb.client.gridfs.model.GridFSFile;
@ -38,23 +40,24 @@ import com.mongodb.client.gridfs.model.GridFSFile;
*/ */
public class GridFsResource extends InputStreamResource { 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"; static final String CONTENT_TYPE_FIELD = "_contentType";
private static final ByteArrayInputStream EMPTY_INPUT_STREAM = new ByteArrayInputStream(new byte[0]);
private final @Nullable GridFSFile file; private final @Nullable GridFSFile file;
private final String filename;
private GridFsResource() { /**
* Creates a new, absent {@link GridFsResource}.
*
* @param filename filename of the absent resource.
* @since 2.1
*/
private GridFsResource(String filename) {
super(new ByteArrayInputStream(new byte[] {})); super(EMPTY_INPUT_STREAM, String.format("GridFs resource [%s]", filename));
file = null;
this.file = null;
this.filename = filename;
} }
/** /**
@ -74,18 +77,35 @@ public class GridFsResource extends InputStreamResource {
*/ */
public GridFsResource(GridFSFile file, InputStream inputStream) { public GridFsResource(GridFSFile file, InputStream inputStream) {
super(inputStream); super(inputStream, String.format("GridFs resource [%s]", file.getFilename()));
this.file = file; this.file = file;
this.filename = file.getFilename();
} }
/** /**
* Obtain an absent {@link GridFsResource}. * Obtain an absent {@link GridFsResource}.
* *
* @param filename filename of the absent resource, must not be {@literal null}.
* @return never {@literal null}. * @return never {@literal null}.
* @since 2.1 * @since 2.1
*/ */
public static GridFsResource absent() { public static GridFsResource absent(String filename) {
return ABSENT;
Assert.notNull(filename, "Filename must not be null");
return new GridFsResource(filename);
}
/*
* (non-Javadoc)
* @see org.springframework.core.io.InputStreamResource#getInputStream()
*/
@Override
public InputStream getInputStream() throws IOException, IllegalStateException {
verifyExists();
return super.getInputStream();
} }
/* /*
@ -105,15 +125,22 @@ public class GridFsResource extends InputStreamResource {
*/ */
@Override @Override
public String getFilename() throws IllegalStateException { public String getFilename() throws IllegalStateException {
return filename;
}
verifyExists(); /*
return file.getFilename(); * (non-Javadoc)
* @see org.springframework.core.io.AbstractResource#exists()
*/
@Override
public boolean exists() {
return file != null;
} }
/* /*
* (non-Javadoc) * (non-Javadoc)
* @see org.springframework.core.io.AbstractResource#lastModified() * @see org.springframework.core.io.AbstractResource#lastModified()
*/ */
@Override @Override
public long lastModified() throws IOException { public long lastModified() throws IOException {
@ -121,14 +148,25 @@ public class GridFsResource extends InputStreamResource {
return file.getUploadDate().getTime(); return file.getUploadDate().getTime();
} }
/*
* (non-Javadoc)
* @see org.springframework.core.io.AbstractResource#getDescription()
*/
@Override
public String getDescription() {
return String.format("GridFs resource [%s]", this.getFilename());
}
/** /**
* Returns the {@link Resource}'s id. * Returns the {@link Resource}'s id.
* *
* @return never {@literal null}. * @return never {@literal null}.
* @throws IllegalStateException if the file does not {@link #exists()}.
*/ */
public Object getId() { public Object getId() {
verifyExists(); Assert.state(exists(), () -> String.format("%s does not exist.", getDescription()));
return file.getId(); return file.getId();
} }
@ -138,11 +176,12 @@ public class GridFsResource extends InputStreamResource {
* @return never {@literal null}. * @return never {@literal null}.
* @throws com.mongodb.MongoGridFSException in case no content type declared on {@link GridFSFile#getMetadata()} nor * @throws com.mongodb.MongoGridFSException in case no content type declared on {@link GridFSFile#getMetadata()} nor
* provided via {@link GridFSFile#getContentType()}. * provided via {@link GridFSFile#getContentType()}.
* @throws IllegalStateException if the file does not {@link #exists()}.
*/ */
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public String getContentType() { public String getContentType() {
verifyExists(); Assert.state(exists(), () -> String.format("%s does not exist.", getDescription()));
return Optionals return Optionals
.firstNonEmpty( .firstNonEmpty(
@ -151,10 +190,10 @@ public class GridFsResource extends InputStreamResource {
.orElseThrow(() -> new MongoGridFSException("No contentType data for this GridFS file")); .orElseThrow(() -> new MongoGridFSException("No contentType data for this GridFS file"));
} }
private void verifyExists() { private void verifyExists() throws FileNotFoundException {
if (!exists()) { if (!exists()) {
throw new IllegalStateException("The resource does not exist."); throw new FileNotFoundException(String.format("%s does not exist.", getDescription()));
} }
} }
} }

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

@ -229,7 +229,7 @@ public class GridFsTemplate implements GridFsOperations, ResourcePatternResolver
public GridFsResource getResource(String location) { public GridFsResource getResource(String location) {
return Optional.ofNullable(findOne(query(whereFilename().is(location)))).map(this::getResource) return Optional.ofNullable(findOne(query(whereFilename().is(location)))).map(this::getResource)
.orElseGet(GridFsResource::absent); .orElseGet(() -> GridFsResource.absent(location));
} }
/* /*

28
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/gridfs/GridFsResourceUnitTests.java

@ -17,6 +17,7 @@ package org.springframework.data.mongodb.gridfs;
import static org.assertj.core.api.Assertions.*; import static org.assertj.core.api.Assertions.*;
import java.io.FileNotFoundException;
import java.util.Date; import java.util.Date;
import org.bson.BsonObjectId; import org.bson.BsonObjectId;
@ -65,8 +66,29 @@ public class GridFsResourceUnitTests {
@Test // DATAMONGO-1914 @Test // DATAMONGO-1914
public void gettersThrowExceptionForAbsentResource() { public void gettersThrowExceptionForAbsentResource() {
assertThatExceptionOfType(IllegalStateException.class).isThrownBy(() -> GridFsResource.absent().getContentType()); GridFsResource absent = GridFsResource.absent("foo");
assertThatExceptionOfType(IllegalStateException.class).isThrownBy(() -> GridFsResource.absent().getFilename());
assertThatExceptionOfType(IllegalStateException.class).isThrownBy(() -> GridFsResource.absent().contentLength()); assertThat(absent.exists()).isFalse();
assertThat(absent.getDescription()).contains("GridFs resource [foo]");
assertThatExceptionOfType(IllegalStateException.class).isThrownBy(absent::getContentType);
assertThatExceptionOfType(IllegalStateException.class).isThrownBy(absent::getId);
assertThatExceptionOfType(FileNotFoundException.class).isThrownBy(absent::contentLength);
assertThatExceptionOfType(FileNotFoundException.class).isThrownBy(absent::getInputStream);
assertThatExceptionOfType(FileNotFoundException.class).isThrownBy(absent::lastModified);
assertThatExceptionOfType(FileNotFoundException.class).isThrownBy(absent::getURI);
assertThatExceptionOfType(FileNotFoundException.class).isThrownBy(absent::getURL);
}
@Test // DATAMONGO-1914
public void shouldReturnFilenameForAbsentResource() {
GridFsResource absent = GridFsResource.absent("foo");
assertThat(absent.exists()).isFalse();
assertThat(absent.getDescription()).contains("GridFs resource [foo]");
assertThat(absent.getFilename()).isEqualTo("foo");
} }
} }

2
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/gridfs/GridFsTemplateIntegrationTests.java

@ -179,7 +179,7 @@ public class GridFsTemplateIntegrationTests {
@Test // DATAMONGO-813, DATAMONGO-1914 @Test // DATAMONGO-813, DATAMONGO-1914
public void getResourceShouldReturnAbsentResourceForNonExistingResource() { public void getResourceShouldReturnAbsentResourceForNonExistingResource() {
assertThat(operations.getResource("doesnotexist")).isEqualTo(GridFsResource.absent()); assertThat(operations.getResource("doesnotexist")).isEqualTo(GridFsResource.absent("doesnotexist"));
} }
@Test // DATAMONGO-809 @Test // DATAMONGO-809

Loading…
Cancel
Save