Skip to content

Commit

Permalink
feat: content property now uses setAutoGrowNestedPaths when setting c…
Browse files Browse the repository at this point in the history
…ontent to provide better support for null embedded content objects

- filesystem storage only
  • Loading branch information
paulcwarren committed Jul 13, 2023
1 parent e9b6d1f commit be6092e
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.NullValueInNestedPathException;
import org.springframework.core.convert.TypeDescriptor;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.springframework.util.Assert;

@Getter
@Setter
Expand All @@ -16,39 +18,48 @@ public class ContentProperty {

private String contentPropertyPath;
private String contentIdPropertyPath;
private TypeDescriptor contentIdType;
private String contentLengthPropertyPath;
private String mimeTypePropertyPath;
private String originalFileNamePropertyPath;

public Object getCustomProperty(Object entity, String propertyName) {
String customContentPropertyPath = contentPropertyPath + StringUtils.capitalize(propertyName);

BeanWrapper wrapper = new BeanWrapperImpl(entity);
return wrapper.getPropertyValue(customContentPropertyPath);
BeanWrapper wrapper = getBeanWrapperForRead(entity);
try {
return wrapper.getPropertyValue(customContentPropertyPath);
} catch (NullValueInNestedPathException nvinpe) {
return null;
}
}

public void setCustomProperty(Object entity, String propertyName, Object value) {
String customContentPropertyPath = contentPropertyPath + StringUtils.capitalize(propertyName);

BeanWrapper wrapper = new BeanWrapperImpl(entity);
BeanWrapper wrapper = getBeanWrapperForWrite(entity);
wrapper.setPropertyValue(customContentPropertyPath, value);
}

public Object getContentId(Object entity) {
if (contentLengthPropertyPath == null) {
if (contentIdPropertyPath == null) {
return null;
}

BeanWrapper wrapper = new BeanWrapperImpl(entity);
return wrapper.getPropertyValue(contentIdPropertyPath);
BeanWrapper wrapper = getBeanWrapperForRead(entity);
try {
return wrapper.getPropertyValue(contentIdPropertyPath);
} catch (NullValueInNestedPathException nvinpe) {
return null;
}
}

public void setContentId(Object entity, Object value, Condition condition) {
if (contentIdPropertyPath == null) {
return;
}

BeanWrapper wrapper = new BeanWrapperImpl(entity);
BeanWrapper wrapper = getBeanWrapperForWrite(entity);

if (condition != null) {
TypeDescriptor t = wrapper.getPropertyTypeDescriptor(contentIdPropertyPath);
Expand All @@ -61,29 +72,38 @@ public void setContentId(Object entity, Object value, Condition condition) {
}

public TypeDescriptor getContentIdType(Object entity) {
if (contentIdPropertyPath == null) {
return null;
}
Assert.notNull(this.contentIdType, "content id property type must be set");
return this.contentIdType;
}

BeanWrapper wrapper = new BeanWrapperImpl(entity);
return wrapper.getPropertyTypeDescriptor(contentIdPropertyPath);
public TypeDescriptor getContentIdType() {
Assert.notNull(this.contentIdType, "content id property type must be set");
return this.contentIdType;
}

public void setContentIdType(TypeDescriptor descriptor) {
this.contentIdType = descriptor;
}

public Object getContentLength(Object entity) {
if (contentLengthPropertyPath == null) {
return 0L;
}

BeanWrapper wrapper = new BeanWrapperImpl(entity);
return wrapper.getPropertyValue(contentLengthPropertyPath);
BeanWrapper wrapper = getBeanWrapperForRead(entity);
try {
return wrapper.getPropertyValue(contentLengthPropertyPath);
} catch (NullValueInNestedPathException nvinpe) {
return null;
}
}

public void setContentLength(Object entity, Object value) {
if (contentLengthPropertyPath == null) {
return;
}

BeanWrapper wrapper = new BeanWrapperImpl(entity);
BeanWrapper wrapper = getBeanWrapperForWrite(entity);
wrapper.setPropertyValue(contentLengthPropertyPath, value);
}

Expand All @@ -92,16 +112,20 @@ public Object getMimeType(Object entity) {
return null;
}

BeanWrapper wrapper = new BeanWrapperImpl(entity);
return wrapper.getPropertyValue(mimeTypePropertyPath);
BeanWrapper wrapper = getBeanWrapperForRead(entity);
try {
return wrapper.getPropertyValue(mimeTypePropertyPath);
} catch (NullValueInNestedPathException nvinpe) {
return null;
}
}

public void setMimeType(Object entity, Object value) {
if (mimeTypePropertyPath == null) {
return;
}

BeanWrapper wrapper = new BeanWrapperImpl(entity);
BeanWrapper wrapper = getBeanWrapperForWrite(entity);
wrapper.setPropertyValue(mimeTypePropertyPath, value);
}

Expand All @@ -110,7 +134,7 @@ public void setOriginalFileName(Object entity, Object value) {
return;
}

BeanWrapper wrapper = new BeanWrapperImpl(entity);
BeanWrapper wrapper = getBeanWrapperForWrite(entity);
wrapper.setPropertyValue(originalFileNamePropertyPath, value);
}

Expand All @@ -119,7 +143,22 @@ public Object getOriginalFileName(Object entity) {
return null;
}

BeanWrapper wrapper = getBeanWrapperForRead(entity);
try {
return wrapper.getPropertyValue(originalFileNamePropertyPath);
} catch (NullValueInNestedPathException nvinpe) {
return null;
}
}

private BeanWrapper getBeanWrapperForRead(Object entity) {
BeanWrapper wrapper = new BeanWrapperImpl(entity);
return wrapper;
}

private BeanWrapper getBeanWrapperForWrite(Object entity) {
BeanWrapper wrapper = new BeanWrapperImpl(entity);
return wrapper.getPropertyValue(originalFileNamePropertyPath);
wrapper.setAutoGrowNestedPaths(true);
return wrapper;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.springframework.content.commons.annotations.ContentLength;
import org.springframework.content.commons.annotations.MimeType;
import org.springframework.content.commons.annotations.OriginalFileName;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.util.StringUtils;

import lombok.Getter;
Expand Down Expand Up @@ -82,6 +83,7 @@ public boolean visitClassEnd(String path, Class<?> klazz) {
if (property.getContentIdPropertyPath() != null) {
contentProperty.setContentPropertyPath(property.getContentPropertyPath());
contentProperty.setContentIdPropertyPath(property.getContentIdPropertyPath());
contentProperty.setContentIdType(property.getContentIdType());
}
if (property.getContentLengthPropertyPath() != null) {
contentProperty.setContentLengthPropertyPath(property.getContentLengthPropertyPath());
Expand Down Expand Up @@ -122,6 +124,7 @@ public boolean visitField(String path, Class<?> klazz, Field f) {
}
updateContentProperty(property::setContentPropertyPath, fullyQualify(path, this.propertyName(f.getName()), this.getContentPropertySeparator()));
updateContentProperty(property::setContentIdPropertyPath, fullyQualify(path, f.getName(), this.getContentPropertySeparator()));
property.setContentIdType(TypeDescriptor.valueOf(f.getType()));
}
} else if (f.isAnnotationPresent(ContentLength.class)) {
LOGGER.trace(String.format("%s.%s is @ContentLength", f.getDeclaringClass().getCanonicalName(), f.getName()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.springframework.content.commons.annotations.ContentLength;
import org.springframework.content.commons.annotations.MimeType;
import org.springframework.content.commons.annotations.OriginalFileName;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.data.mongodb.core.mapping.DBRef;
import org.springframework.util.ReflectionUtils;

Expand Down Expand Up @@ -47,6 +48,7 @@ public class ClassWalkerTest {
ContentProperty expectedProperty = new ContentProperty();
expectedProperty.setContentPropertyPath("content");
expectedProperty.setContentIdPropertyPath("contentId");
expectedProperty.setContentIdType(TypeDescriptor.valueOf(String.class));
expectedProperty.setContentLengthPropertyPath("contentLength");
expectedProperty.setMimeTypePropertyPath("contentMimeType");
expectedProperty.setOriginalFileNamePropertyPath("contentOriginalFileName");
Expand All @@ -55,6 +57,7 @@ public class ClassWalkerTest {
ContentProperty expectedSubClassProperty = new ContentProperty();
expectedSubClassProperty.setContentPropertyPath("child.content");
expectedSubClassProperty.setContentIdPropertyPath("child.contentId");
expectedSubClassProperty.setContentIdType(TypeDescriptor.valueOf(String.class));
expectedSubClassProperty.setContentLengthPropertyPath("child.contentLength");
expectedSubClassProperty.setMimeTypePropertyPath("child.contentMimeType");
expectedSubClassProperty.setOriginalFileNamePropertyPath("child.contentOriginalFileName");
Expand All @@ -63,6 +66,7 @@ public class ClassWalkerTest {
ContentProperty expectedSubSubClassProperty = new ContentProperty();
expectedSubSubClassProperty.setContentPropertyPath("child.subChild.content");
expectedSubSubClassProperty.setContentIdPropertyPath("child.subChild.contentId");
expectedSubSubClassProperty.setContentIdType(TypeDescriptor.valueOf(String.class));
expectedSubSubClassProperty.setContentLengthPropertyPath("child.subChild.contentLength");
expectedSubSubClassProperty.setMimeTypePropertyPath("child.subChild.contentMimeType");
expectedSubSubClassProperty.setOriginalFileNamePropertyPath("child.subChild.contentOriginalFileName");
Expand All @@ -71,6 +75,7 @@ public class ClassWalkerTest {
ContentProperty expectedCamelCaseProperty = new ContentProperty();
expectedCamelCaseProperty.setContentPropertyPath("camelCaseProperty.camelCaseProperty");
expectedCamelCaseProperty.setContentIdPropertyPath("camelCaseProperty.camelCasePropertyId");
expectedCamelCaseProperty.setContentIdType(TypeDescriptor.valueOf(UUID.class));
expectedCamelCaseProperty.setContentLengthPropertyPath("camelCaseProperty.camelCasePropertyLen");
expectedCamelCaseProperty.setMimeTypePropertyPath("camelCaseProperty.camelCasePropertyMimeType");
expectedCamelCaseProperty.setOriginalFileNamePropertyPath("camelCaseProperty.camelCasePropertyOriginalFileName");
Expand All @@ -79,6 +84,7 @@ public class ClassWalkerTest {
ContentProperty expectedOtherCamelCaseProperty = new ContentProperty();
expectedOtherCamelCaseProperty.setContentPropertyPath("otherCamelCaseProperty.camelCaseProperty");
expectedOtherCamelCaseProperty.setContentIdPropertyPath("otherCamelCaseProperty.camelCasePropertyIds");
expectedOtherCamelCaseProperty.setContentIdType(TypeDescriptor.valueOf(UUID.class));
expectedOtherCamelCaseProperty.setContentLengthPropertyPath("otherCamelCaseProperty.camelCasePropertyLens");
expectedOtherCamelCaseProperty.setMimeTypePropertyPath("otherCamelCaseProperty.camelCasePropertyMimetypes");
expectedOtherCamelCaseProperty.setOriginalFileNamePropertyPath("otherCamelCaseProperty.camelCasePropertyFilenames");
Expand All @@ -95,6 +101,7 @@ public class ClassWalkerTest {
ContentProperty expectedProperty2 = new ContentProperty();
expectedProperty2.setContentPropertyPath("content");
expectedProperty2.setContentIdPropertyPath("contentId");
expectedProperty2.setContentIdType(TypeDescriptor.valueOf(UUID.class));
expectedProperty2.setContentLengthPropertyPath("len");
expectedProperty2.setMimeTypePropertyPath("mimeType");
expectedProperty2.setOriginalFileNamePropertyPath("originalFileName");
Expand All @@ -111,6 +118,7 @@ public class ClassWalkerTest {
ContentProperty expectedProperty2 = new ContentProperty();
expectedProperty2.setContentPropertyPath("content");
expectedProperty2.setContentIdPropertyPath("contentId");
expectedProperty2.setContentIdType(TypeDescriptor.valueOf(UUID.class));
expectedProperty2.setContentLengthPropertyPath("contentLen");
expectedProperty2.setMimeTypePropertyPath("contentMimeType");
expectedProperty2.setOriginalFileNamePropertyPath("contentOriginalFileName");
Expand All @@ -127,6 +135,7 @@ public class ClassWalkerTest {
ContentProperty expectedProperty = new ContentProperty();
expectedProperty.setContentPropertyPath("child.content");
expectedProperty.setContentIdPropertyPath("child.contentId");
expectedProperty.setContentIdType(TypeDescriptor.valueOf(UUID.class));
expectedProperty.setContentLengthPropertyPath("child.len");
expectedProperty.setMimeTypePropertyPath("child.mimeType");
expectedProperty.setOriginalFileNamePropertyPath("child.originalFileName");
Expand All @@ -153,14 +162,15 @@ public class ClassWalkerTest {
ContentProperty expectedProperty = new ContentProperty();
expectedProperty.setContentPropertyPath("content");
expectedProperty.setContentIdPropertyPath("contentId");
expectedProperty.setContentIdType(TypeDescriptor.valueOf(String.class));
expectedProperty.setContentLengthPropertyPath("contentLength");
expectedProperty.setMimeTypePropertyPath("contentMimeType");
expectedProperty.setOriginalFileNamePropertyPath("contentOriginalFileName");
assertThat(visitor.getProperties(), hasEntry("content", expectedProperty));
});
});

Context("given a class with multple child content property objects", () -> {
Context("given a class with multiple child content property objects", () -> {
It("should return two content properties", () -> {
ContentPropertyMappingContextVisitor visitor = new ContentPropertyMappingContextVisitor("/", ".");
ClassWalker walker = new ClassWalker(visitor);
Expand All @@ -169,6 +179,7 @@ public class ClassWalkerTest {
ContentProperty expectedProperty = new ContentProperty();
expectedProperty.setContentPropertyPath("child1.content");
expectedProperty.setContentIdPropertyPath("child1.contentId");
expectedProperty.setContentIdType(TypeDescriptor.valueOf(UUID.class));
expectedProperty.setContentLengthPropertyPath("child1.len");
expectedProperty.setMimeTypePropertyPath("child1.mimeType");
expectedProperty.setOriginalFileNamePropertyPath("child1.originalFileName");
Expand All @@ -177,6 +188,7 @@ public class ClassWalkerTest {
ContentProperty expectedProperty3 = new ContentProperty();
expectedProperty3.setContentPropertyPath("child2.content");
expectedProperty3.setContentIdPropertyPath("child2.contentId");
expectedProperty3.setContentIdType(TypeDescriptor.valueOf(UUID.class));
expectedProperty3.setContentLengthPropertyPath("child2.len");
expectedProperty3.setMimeTypePropertyPath("child2.mimeType");
expectedProperty3.setOriginalFileNamePropertyPath("child2.originalFileName");
Expand All @@ -193,6 +205,7 @@ public class ClassWalkerTest {
ContentProperty expectedProperty = new ContentProperty();
expectedProperty.setContentPropertyPath("child.content");
expectedProperty.setContentIdPropertyPath("child.contentId");
expectedProperty.setContentIdType(TypeDescriptor.valueOf(UUID.class));
expectedProperty.setContentLengthPropertyPath("child.contentLen");
expectedProperty.setMimeTypePropertyPath("child.contentMimeType");
expectedProperty.setOriginalFileNamePropertyPath("child.contentOriginalFileName");
Expand All @@ -201,6 +214,7 @@ public class ClassWalkerTest {
ContentProperty expectedProperty3 = new ContentProperty();
expectedProperty3.setContentPropertyPath("child.preview");
expectedProperty3.setContentIdPropertyPath("child.previewId");
expectedProperty3.setContentIdType(TypeDescriptor.valueOf(UUID.class));
expectedProperty3.setContentLengthPropertyPath("child.previewLen");
expectedProperty3.setMimeTypePropertyPath("child.previewMimeType");
expectedProperty3.setOriginalFileNamePropertyPath("child.previewOriginalFileName");
Expand All @@ -217,6 +231,7 @@ public class ClassWalkerTest {
ContentProperty expectedProperty = new ContentProperty();
expectedProperty.setContentPropertyPath("child.child.content");
expectedProperty.setContentIdPropertyPath("child.child.contentId");
expectedProperty.setContentIdType(TypeDescriptor.valueOf(UUID.class));
expectedProperty.setContentLengthPropertyPath("child.child.contentLen");
expectedProperty.setMimeTypePropertyPath("child.child.contentMimeType");
expectedProperty.setOriginalFileNamePropertyPath("child.child.contentOriginalFileName");
Expand All @@ -225,6 +240,7 @@ public class ClassWalkerTest {
ContentProperty expectedProperty2 = new ContentProperty();
expectedProperty2.setContentPropertyPath("child.child.preview");
expectedProperty2.setContentIdPropertyPath("child.child.previewId");
expectedProperty2.setContentIdType(TypeDescriptor.valueOf(UUID.class));
expectedProperty2.setContentLengthPropertyPath("child.child.previewLen");
expectedProperty2.setMimeTypePropertyPath("child.child.previewMimeType");
expectedProperty2.setOriginalFileNamePropertyPath("child.child.previewOriginalFileName");
Expand Down
Loading

0 comments on commit be6092e

Please sign in to comment.