Skip to content

Commit

Permalink
Add AssociativeStore.getResource implementation to SC FS
Browse files Browse the repository at this point in the history
  • Loading branch information
Paul Warren committed Apr 26, 2018
1 parent 47c3409 commit 804f7a5
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,31 @@ public DefaultFilesystemStoreImpl(FileSystemResourceLoader loader, ConversionSer

@Override
public Resource getResource(SID id) {
String location = conversion.convert(id, String.class);
Resource resource = loader.getResource(location);
return resource;
return getResourceInternal(id);
}

@Override
public Resource getResource(S entity) {
return null;
Object contentId = BeanUtils.getFieldWithAnnotation(entity, ContentId.class);
if (contentId == null) {
contentId = UUID.randomUUID();
contentId = convertToExternalContentIdType(entity, contentId);
BeanUtils.setFieldWithAnnotation(entity, ContentId.class, contentId);
}

return getResourceInternal(contentId);
}

protected Resource getResourceInternal(Object id) {
String location = conversion.convert(id, String.class);
Resource resource = loader.getResource(location);
return resource;
}

@Override
public void associate(S entity, SID id) {
BeanUtils.setFieldWithAnnotation(entity, ContentId.class, id.toString());
String location = conversion.convert(id, String.class);
Resource resource = loader.getResource(location);
Resource resource = getResourceInternal(id);
try {
BeanUtils.setFieldWithAnnotation(entity, ContentLength.class, resource.contentLength());
} catch (IOException e) {
Expand All @@ -70,21 +80,23 @@ public void associate(S entity, SID id) {

@Override
public void unassociate(S entity) {
BeanUtils.setFieldWithAnnotation(entity, ContentId.class, null);
BeanUtils.setFieldWithAnnotation(entity, ContentLength.class, 0L);
BeanUtils.setFieldWithAnnotationConditionally(entity, ContentId.class, null, new Condition() {
@Override
public boolean matches(Field field) {
for (Annotation annotation : field.getAnnotations()) {
if ("javax.persistence.Id".equals(annotation.annotationType().getCanonicalName()) ||
"org.springframework.data.annotation.Id".equals(annotation.annotationType().getCanonicalName())) {
return false;
}
}
return true;
}});
BeanUtils.setFieldWithAnnotation(entity, ContentLength.class, 0);
}

@Override
public void setContent(S property, InputStream content) {
Object contentId = BeanUtils.getFieldWithAnnotation(property, ContentId.class);
if (contentId == null) {
contentId = UUID.randomUUID();
contentId = convertToExternalContentIdType(property, contentId);
BeanUtils.setFieldWithAnnotation(property, ContentId.class, contentId);
}

String location = conversion.convert(contentId, String.class);
Resource resource = loader.getResource(location);
Resource resource = getResource(property);
OutputStream os = null;
try {
if (resource.exists() == false) {
Expand All @@ -97,7 +109,7 @@ public void setContent(S property, InputStream content) {
IOUtils.copy(content, os);
}
} catch (IOException e) {
logger.error(String.format("Unexpected error setting content %s", contentId.toString()), e);
logger.error(String.format("Unexpected error setting content for resource %s", property.toString()), e);
} finally {
try {
if (os != null) {
Expand All @@ -111,7 +123,7 @@ public void setContent(S property, InputStream content) {
try {
BeanUtils.setFieldWithAnnotation(property, ContentLength.class, resource.contentLength());
} catch (IOException e) {
logger.error(String.format("Unexpected error setting content length for content %s", contentId.toString()), e);
logger.error(String.format("Unexpected error setting content length for content for resource %s", resource.toString()), e);
}
}

Expand All @@ -123,8 +135,7 @@ public InputStream getContent(S property) {
if (contentId == null)
return null;

String location = conversion.convert(contentId, String.class);
Resource resource = loader.getResource(location);
Resource resource = getResourceInternal(contentId);

try {
if (resource.exists()) {
Expand All @@ -141,31 +152,20 @@ public InputStream getContent(S property) {
public void unsetContent(S property) {
if (property == null)
return;

Object contentId = BeanUtils.getFieldWithAnnotation(property, ContentId.class);
if (contentId == null)
return;

// delete any existing content object
String location = conversion.convert(contentId, String.class);
Resource resource = loader.getResource(location);
Resource resource = getResourceInternal(contentId);

if (resource.exists() && resource instanceof DeletableResource) {
((DeletableResource)resource).delete();
}

// reset content fields
BeanUtils.setFieldWithAnnotationConditionally(property, ContentId.class, null, new Condition() {
@Override
public boolean matches(Field field) {
for (Annotation annotation : field.getAnnotations()) {
if ("javax.persistence.Id".equals(annotation.annotationType().getCanonicalName()) ||
"org.springframework.data.annotation.Id".equals(annotation.annotationType().getCanonicalName())) {
return false;
}
}
return true;
}});
BeanUtils.setFieldWithAnnotation(property, ContentLength.class, 0);
unassociate(property);
}

private Object convertToExternalContentIdType(S property, Object contentId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;

import org.junit.runner.RunWith;
import org.mockito.InOrder;
Expand All @@ -15,13 +16,15 @@
import org.springframework.content.commons.utils.FileService;
import org.springframework.content.fs.io.FileSystemResourceLoader;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.io.Resource;
import org.springframework.core.io.WritableResource;

import com.github.paulcwarren.ginkgo4j.Ginkgo4jConfiguration;
import com.github.paulcwarren.ginkgo4j.Ginkgo4jRunner;

import static com.github.paulcwarren.ginkgo4j.Ginkgo4jDSL.*;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.nullValue;
Expand All @@ -34,6 +37,7 @@
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.hamcrest.MockitoHamcrest.argThat;

@RunWith(Ginkgo4jRunner.class)
@Ginkgo4jConfiguration(threads=1)
Expand Down Expand Up @@ -74,7 +78,7 @@ public class DefaultFilesystemStoresImplTest {
BeforeEach(() -> {
deletableResource = mock(DeletableResource.class);
});
Context("#getResource", () -> {
Context("#getResource with content ID", () -> {
BeforeEach(() -> {
id = "12345-67890";

Expand All @@ -88,6 +92,36 @@ public class DefaultFilesystemStoresImplTest {
verify(loader).getResource(eq("12345-67890"));
});
});
Context("#getResource with entity", () -> {
JustBeforeEach(() -> {
resource = filesystemContentRepoImpl.getResource(entity);
});
Context("when the entity is not already associated with a resource", () -> {
BeforeEach(() -> {
entity = new TestEntity();

when(conversion.canConvert((TypeDescriptor)argThat(is(instanceOf(TypeDescriptor.class))), argThat(is(instanceOf(TypeDescriptor.class))))).thenReturn(true);
when(conversion.convert(argThat(is(instanceOf(UUID.class))), argThat(is(instanceOf(TypeDescriptor.class))), argThat(is(instanceOf(TypeDescriptor.class))))).thenReturn("12345-67890");
when(conversion.convert(eq("12345-67890"), eq(String.class))).thenReturn("/12345/67890");
});
It("should use the conversion service to get a resource path", () -> {
verify(conversion).convert(eq("12345-67890"), eq(String.class));
verify(loader).getResource(eq("/12345/67890"));
});
});
Context("when the entity is already associated with a resource", () -> {
BeforeEach(() -> {
entity = new TestEntity();
entity.setContentId("12345-67890");

when(conversion.convert(eq("12345-67890"), eq(String.class))).thenReturn("/12345/67890");
});
It("should use the conversion service to get a resource path", () -> {
verify(conversion).convert(eq("12345-67890"), eq(String.class));
verify(loader).getResource(eq("/12345/67890"));
});
});
});
Context("#associate", () -> {
BeforeEach(() -> {
id = "12345-67890";
Expand Down Expand Up @@ -326,22 +360,7 @@ public class DefaultFilesystemStoresImplTest {
});
});
});

Context("#getResource", () -> {
BeforeEach(() -> {
when(conversion.convert(eq("abcd-efgh"), eq(String.class))).thenReturn("/abcd/efgh");

resource = mock(Resource.class);
when(loader.getResource(eq("/abcd/efgh"))).thenReturn(resource);
});
JustBeforeEach(() -> {
filesystemContentRepoImpl.getResource("abcd-efgh");
});
It("should load resource from the placement provided location", () -> {
verify(loader).getResource(eq("/abcd/efgh"));
});
});
});
});
});
}

Expand Down

0 comments on commit 804f7a5

Please sign in to comment.