Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: rest and store mappingcontext now use a common property naming convention #1573

Merged
merged 1 commit into from
Aug 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
package org.springframework.content.commons.mappingcontext;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;
import java.util.UUID;

import lombok.AllArgsConstructor;
import lombok.Getter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.content.commons.utils.ContentPropertyUtils;
import org.springframework.util.StringUtils;

import lombok.AllArgsConstructor;
import lombok.Getter;
import java.lang.reflect.Field;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ClassWalker {

Expand All @@ -25,6 +22,46 @@ public ClassWalker(ClassVisitor visitor) {
this.visitor = visitor;
}

public static String propertyName(String name) {
if (!StringUtils.hasLength(name)) {
return name;
}

String propertyName = calculateName(name);
if (propertyName != null) {
return propertyName;
}

String[] segments = split(name);
if (segments.length == 1) {
return segments[0];
}
else {
StringBuilder b = new StringBuilder();
for (int i=0; i < segments.length - 1; i++) {
b.append(segments[i]);
}
return b.toString();
}
}

public static String calculateName(String name) {
Pattern p = Pattern.compile("^(.+)(Id|Len|Length|MimeType|Mimetype|ContentType|(?<!Mime|Content)Type|(?<!Original)FileName|(?<!Original)Filename|OriginalFileName|OriginalFilename)$");
Matcher m = p.matcher(name);
if (m.matches() == false) {
return null;
}
return m.group(1);
}

public static String[] split(String name) {
if (!StringUtils.hasLength(name)) {
return new String[]{};
}

return name.split("(?<!(^|[A-Z]))(?=[A-Z])|(?<!^)(?=[A-Z][a-z])");
}

public void accept(Class<?> klazz) {

boolean fContinue = true;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
package org.springframework.content.commons.mappingcontext;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import lombok.Getter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.content.commons.annotations.ContentId;
Expand All @@ -16,7 +10,10 @@
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.util.StringUtils;

import lombok.Getter;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;

/**
* Returns a map of "path"'s to content properties for the given class.
Expand Down Expand Up @@ -115,21 +112,21 @@ public boolean visitField(String path, Class<?> klazz, Field f) {

if (f.isAnnotationPresent(ContentId.class)) {
LOGGER.trace(String.format("%s.%s is @ContentId", f.getDeclaringClass().getCanonicalName(), f.getName()));
String propertyName = fullyQualify(path, this.propertyName(f.getName()), this.getKeySeparator());
String propertyName = fullyQualify(path, ClassWalker.propertyName(f.getName()), this.getKeySeparator());
if (StringUtils.hasLength(propertyName)) {
Map<String,ContentProperty> classProperties = properties.get(key(path, klazz));
ContentProperty property = classProperties.get(propertyName);
if (property == null) {
property = new ContentProperty();
classProperties.put(propertyName, property);
}
updateContentProperty(property::setContentPropertyPath, fullyQualify(path, this.propertyName(f.getName()), this.getContentPropertySeparator()));
updateContentProperty(property::setContentPropertyPath, fullyQualify(path, ClassWalker.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()));
String propertyName = fullyQualify(path, this.propertyName(f.getName()), this.getKeySeparator());
String propertyName = fullyQualify(path, ClassWalker.propertyName(f.getName()), this.getKeySeparator());
if (StringUtils.hasLength(propertyName)) {
Map<String,ContentProperty> classProperties = properties.get(key(path, klazz));
ContentProperty property = classProperties.get(propertyName);
Expand All @@ -142,7 +139,7 @@ public boolean visitField(String path, Class<?> klazz, Field f) {
}
} else if (f.isAnnotationPresent(MimeType.class)) {
LOGGER.trace(String.format("%s.%s is @MimeType", f.getDeclaringClass().getCanonicalName(), f.getName()));
String propertyName = fullyQualify(path, this.propertyName(f.getName()), this.getKeySeparator());
String propertyName = fullyQualify(path, ClassWalker.propertyName(f.getName()), this.getKeySeparator());
if (StringUtils.hasLength(propertyName)) {
Map<String,ContentProperty> classProperties = properties.get(key(path, klazz));
ContentProperty property = classProperties.get(propertyName);
Expand All @@ -154,7 +151,7 @@ public boolean visitField(String path, Class<?> klazz, Field f) {
}
} else if (f.isAnnotationPresent(OriginalFileName.class)) {
LOGGER.trace(String.format("%s.%s is @OriginalFileName", f.getDeclaringClass().getCanonicalName(), f.getName()));
String propertyName = fullyQualify(path, this.propertyName(f.getName()), this.getKeySeparator());
String propertyName = fullyQualify(path, ClassWalker.propertyName(f.getName()), this.getKeySeparator());
if (StringUtils.hasLength(propertyName)) {
Map<String,ContentProperty> classProperties = properties.get(key(path, klazz));
ContentProperty property = classProperties.get(propertyName);
Expand Down Expand Up @@ -182,47 +179,7 @@ protected String fullyQualify(String path, String name, CharSequence separator)
return fqName;
}

protected String propertyName(String name) {
if (!StringUtils.hasLength(name)) {
return name;
}

String propertyName = calculateName(name);
if (propertyName != null) {
return propertyName;
}

String[] segments = split(name);
if (segments.length == 1) {
return segments[0];
}
else {
StringBuilder b = new StringBuilder();
for (int i=0; i < segments.length - 1; i++) {
b.append(segments[i]);
}
return b.toString();
}
}

protected boolean isNotRootContentProperty(String path) {
return StringUtils.hasLength(path);
}

protected String calculateName(String name) {
Pattern p = Pattern.compile("^(.+)(Id|Len|Length|MimeType|Mimetype|ContentType|(?<!Mime|Content)Type|(?<!Original)FileName|(?<!Original)Filename|OriginalFileName|OriginalFilename)$");
Matcher m = p.matcher(name);
if (m.matches() == false) {
return null;
}
return m.group(1);
}

protected static String[] split(String name) {
if (!StringUtils.hasLength(name)) {
return new String[]{};
}

return name.split("(?<!(^|[A-Z]))(?=[A-Z])|(?<!^)(?=[A-Z][a-z])");
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,7 @@
package org.springframework.content.commons.mappingcontext;

import static com.github.paulcwarren.ginkgo4j.Ginkgo4jDSL.*;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.collection.IsMapContaining.hasEntry;

import java.lang.reflect.Field;
import java.util.UUID;

import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne;

import com.github.paulcwarren.ginkgo4j.Ginkgo4jRunner;
import jakarta.persistence.*;
import org.junit.runner.RunWith;
import org.springframework.content.commons.annotations.ContentId;
import org.springframework.content.commons.annotations.ContentLength;
Expand All @@ -24,7 +11,13 @@
import org.springframework.data.mongodb.core.mapping.DBRef;
import org.springframework.util.ReflectionUtils;

import com.github.paulcwarren.ginkgo4j.Ginkgo4jRunner;
import java.lang.reflect.Field;
import java.util.UUID;

import static com.github.paulcwarren.ginkgo4j.Ginkgo4jDSL.*;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.collection.IsMapContaining.hasEntry;

@RunWith(Ginkgo4jRunner.class)
public class ClassWalkerTest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.springframework.content.commons.annotations.ContentId;
import org.springframework.content.commons.mappingcontext.ClassVisitor;
import org.springframework.content.commons.mappingcontext.ClassWalker;
import org.springframework.content.commons.utils.ContentPropertyUtils;
import org.springframework.content.rest.RestResource;
import org.springframework.util.StringUtils;
Expand Down Expand Up @@ -50,20 +51,20 @@ public boolean visitFieldBefore(String path, Class<?> klazz, Field f) {
segments.push(segment);
} else {
if (f.isAnnotationPresent(ContentId.class)) {
segments.push(propertyName(f.getName()));
segments.push(ClassWalker.propertyName(f.getName()));
} else {
segments.push(f.getName());
}
}
} else {
if (f.isAnnotationPresent(ContentId.class)) {
segments.push(propertyName(f.getName()));
segments.push(ClassWalker.propertyName(f.getName()));
} else {
segments.push(f.getName());
}
}
if (f.isAnnotationPresent(ContentId.class)) {
uriSegments.push(propertyName(f.getName()));
uriSegments.push(ClassWalker.propertyName(f.getName()));
} else {
uriSegments.push(f.getName());
}
Expand Down Expand Up @@ -123,20 +124,4 @@ private String path(Stack<String> segments) {
}
return fqPath;
}

protected String propertyName(String name) {
if (!StringUtils.hasLength(name)) {
return name;
}
String[] segments = split(name);
return segments[0];
}

private static String[] split(String name) {
if (!StringUtils.hasLength(name)) {
return new String[]{};
}

return name.split("(?<!(^|[A-Z]))(?=[A-Z])|(?<!^)(?=[A-Z][a-z])");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,28 +30,36 @@ public class RestResourceMappingBuilderTest {
assertThat(visitor.getMappings(), hasEntry("child/child/content", "one/two/three"));
assertThat(visitor.getMappings(), hasEntry("child/child/preview", "one/two/preview"));
assertThat(visitor.getMappings(), hasEntry("child/child/thumbnail", "one/two/thumbnail"));
assertThat(visitor.getMappings(), hasEntry("child/child/idcardFront", "one/two/idcard-front"));
assertThat(visitor.getMappings(), hasEntry("child/childWithout/content", "one/childWithout/three"));
assertThat(visitor.getMappings(), hasEntry("child/childWithout/preview", "one/childWithout/preview"));
assertThat(visitor.getMappings(), hasEntry("child/childWithout/thumbnail", "one/childWithout/thumbnail"));
assertThat(visitor.getMappings(), hasEntry("child/childWithout/idcardFront", "one/childWithout/idcard-front"));
assertThat(visitor.getMappings(), hasEntry("childWithout/child/content", "childWithout/two/three"));
assertThat(visitor.getMappings(), hasEntry("childWithout/child/preview", "childWithout/two/preview"));
assertThat(visitor.getMappings(), hasEntry("childWithout/child/thumbnail", "childWithout/two/thumbnail"));
assertThat(visitor.getMappings(), hasEntry("childWithout/child/idcardFront", "childWithout/two/idcard-front"));
assertThat(visitor.getMappings(), hasEntry("childWithout/childWithout/content", "childWithout/childWithout/three"));
assertThat(visitor.getMappings(), hasEntry("childWithout/childWithout/preview", "childWithout/childWithout/preview"));
assertThat(visitor.getMappings(), hasEntry("childWithout/childWithout/thumbnail", "childWithout/childWithout/thumbnail"));
assertThat(visitor.getMappings(), hasEntry("childWithout/childWithout/idcardFront", "childWithout/childWithout/idcard-front"));

assertThat(visitor.getInverseMappings(), hasEntry("one/two/three", "child/child/content"));
assertThat(visitor.getInverseMappings(), hasEntry("one/two/preview", "child/child/preview"));
assertThat(visitor.getInverseMappings(), hasEntry("one/two/thumbnail", "child/child/thumbnail"));
assertThat(visitor.getInverseMappings(), hasEntry("one/two/idcard-front", "child/child/idcardFront"));
assertThat(visitor.getInverseMappings(), hasEntry("one/childWithout/three", "child/childWithout/content"));
assertThat(visitor.getInverseMappings(), hasEntry("one/childWithout/preview", "child/childWithout/preview"));
assertThat(visitor.getInverseMappings(), hasEntry("one/childWithout/thumbnail", "child/childWithout/thumbnail"));
assertThat(visitor.getInverseMappings(), hasEntry("one/childWithout/idcard-front", "child/childWithout/idcardFront"));
assertThat(visitor.getInverseMappings(), hasEntry("childWithout/two/three", "childWithout/child/content"));
assertThat(visitor.getInverseMappings(), hasEntry("childWithout/two/preview", "childWithout/child/preview"));
assertThat(visitor.getInverseMappings(), hasEntry("childWithout/two/thumbnail", "childWithout/child/thumbnail"));
assertThat(visitor.getInverseMappings(), hasEntry("childWithout/two/idcard-front", "childWithout/child/idcardFront"));
assertThat(visitor.getInverseMappings(), hasEntry("childWithout/childWithout/three", "childWithout/childWithout/content"));
assertThat(visitor.getInverseMappings(), hasEntry("childWithout/childWithout/preview", "childWithout/childWithout/preview"));
assertThat(visitor.getInverseMappings(), hasEntry("childWithout/childWithout/thumbnail", "childWithout/childWithout/thumbnail"));
assertThat(visitor.getInverseMappings(), hasEntry("childWithout/childWithout/idcard-front", "childWithout/childWithout/idcardFront"));
});
});
}
Expand Down Expand Up @@ -87,5 +95,10 @@ public static class TestSubSubClass {
private @ContentId UUID thumbnailId;
private @ContentLength Long thumbnailLen;
private @MimeType String thumbnailMimeType;

@RestResource(path="idcard-front")
private @ContentId UUID idcardFrontId;
private @ContentLength Long idcardFrontLen;
private @MimeType String idcardFrontMimeType;
}
}
Loading