From 01d23297ad4ad162b58a6983125ecbf9c4a241f5 Mon Sep 17 00:00:00 2001 From: Johan Mynhardt Date: Mon, 7 Aug 2017 12:09:06 +0200 Subject: [PATCH] Use reflection to extract JSON field names from Post class when populating map for post creation. --- .../afrozaar/wordpress/wpapi/v2/Client.java | 72 +++++++++++++------ .../wpapi/v2/WordpressClientTest.java | 33 ++++++++- 2 files changed, 80 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/afrozaar/wordpress/wpapi/v2/Client.java b/src/main/java/com/afrozaar/wordpress/wpapi/v2/Client.java index b3891c1..c54b1ca 100644 --- a/src/main/java/com/afrozaar/wordpress/wpapi/v2/Client.java +++ b/src/main/java/com/afrozaar/wordpress/wpapi/v2/Client.java @@ -1,7 +1,6 @@ package com.afrozaar.wordpress.wpapi.v2; import static com.afrozaar.wordpress.wpapi.v2.util.FieldExtractor.extractField; -import static com.afrozaar.wordpress.wpapi.v2.util.FieldExtractor.renderableField; import static java.lang.String.format; import static java.net.URLDecoder.decode; @@ -28,6 +27,7 @@ import com.afrozaar.wordpress.wpapi.v2.model.Post; import com.afrozaar.wordpress.wpapi.v2.model.PostMeta; import com.afrozaar.wordpress.wpapi.v2.model.PostStatus; +import com.afrozaar.wordpress.wpapi.v2.model.RenderableField; import com.afrozaar.wordpress.wpapi.v2.model.Taxonomy; import com.afrozaar.wordpress.wpapi.v2.model.Term; import com.afrozaar.wordpress.wpapi.v2.model.User; @@ -59,17 +59,20 @@ import org.springframework.http.converter.xml.SourceHttpMessageConverter; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; +import org.springframework.util.ReflectionUtils; import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.HttpServerErrorException; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; +import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.beanutils.BeanUtils; +import org.assertj.core.util.VisibleForTesting; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -852,31 +855,54 @@ private String fixQuery(String href) { } + @VisibleForTesting @SuppressWarnings("unchecked") - private Map fieldsFrom(Post post) { + protected Map fieldsFrom(Post post) { ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); - BiConsumer biConsumer = (key, value) -> { - if (value != null) { - builder.put(key, value); - } - }; - - biConsumer.accept("date", post.getDate()); - biConsumer.accept("modified_gmt", post.getModified()); - // biConsumer.accept("slug", post.getSlug()); - // biConsumer.accept("status",post.getStatus()); - biConsumer.accept("title", renderableField.apply(Post::getTitle, post).orElse(null)); - biConsumer.accept("content", renderableField.apply(Post::getContent, post).orElse(null)); - biConsumer.accept("author", post.getAuthor()); - biConsumer.accept("excerpt", renderableField.apply(Post::getExcerpt, post).orElse(null)); - biConsumer.accept("comment_status", post.getCommentStatus()); - biConsumer.accept("ping_status", post.getPingStatus()); - biConsumer.accept("format", post.getFormat()); - biConsumer.accept("sticky", post.getSticky()); - biConsumer.accept("featured_media", post.getFeaturedMedia()); - biConsumer.accept("categories", post.getCategoryIds()); - //biConsumer.accept("type", post.getType()); + BiConsumer biConsumer = (key, value) -> ofNullable(value).ifPresent(v -> builder.put(key, v)); + + List processableFields = Arrays.asList( + "author", + "categories", + "comment_status", + "content", + "date", + "featured_media", + "format", + "excerpt", + "modified_gmt", + "ping_status", + //"slug", + //"status", + "sticky", + "title" + //"type" + ); + + // types ignored for now: slug, status, type + + Arrays.stream(post.getClass().getDeclaredFields()) + .filter(field -> field.getAnnotationsByType(JsonProperty.class).length > 0) + .map(field -> Tuple2.of(field, field.getAnnotationsByType(JsonProperty.class)[0])) + .filter(fieldTuple -> processableFields.contains(fieldTuple.b.value())) + .forEach(field -> { + try { + ReflectionUtils.makeAccessible(field.a); + Object theField = field.a.get(post); + if (nonNull(theField)) { + final Object value; + if (theField instanceof RenderableField) { + value = ((RenderableField) theField).getRendered(); + } else { + value = theField; + } + biConsumer.accept(field.b.value(), value); + } + } catch (IllegalAccessException e) { + LOG.error("Error populating post fields builder.", e); + } + }); return builder.build(); } diff --git a/src/test/java/com/afrozaar/wordpress/wpapi/v2/WordpressClientTest.java b/src/test/java/com/afrozaar/wordpress/wpapi/v2/WordpressClientTest.java index ddabccc..06fcbda 100644 --- a/src/test/java/com/afrozaar/wordpress/wpapi/v2/WordpressClientTest.java +++ b/src/test/java/com/afrozaar/wordpress/wpapi/v2/WordpressClientTest.java @@ -1,20 +1,49 @@ package com.afrozaar.wordpress.wpapi.v2; +import static org.assertj.core.api.Assertions.assertThat; + import com.afrozaar.wordpress.wpapi.v2.config.ClientConfig; import com.afrozaar.wordpress.wpapi.v2.config.ClientFactory; +import com.afrozaar.wordpress.wpapi.v2.model.Post; +import com.afrozaar.wordpress.wpapi.v2.model.builder.PostBuilder; +import com.afrozaar.wordpress.wpapi.v2.model.builder.TitleBuilder; import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.time.Instant; +import java.util.Map; /** * @author johan */ public class WordpressClientTest { + private static final Logger LOG = LoggerFactory.getLogger(WordpressClientTest.class); + Wordpress wordpress = ClientFactory.fromConfig(ClientConfig.of("http://localhost", "username", "password", false, true)); + @Test public void TestCreateClient() { - Wordpress wordpress = ClientFactory.fromConfig(ClientConfig.of("http://localhost", "username", "password", false, true)); - System.out.println("media = " + wordpress.getMedia(10L)); } + @Test + public void PostFieldProcessingTest() { + + Post post = PostBuilder.aPost() + .withTitle(TitleBuilder.aTitle().withRendered("foobar").build()) + .withModifiedGmt(Instant.now().toString()) + .withContent(null) + .withFormat("myformat") + .build(); + + final Map fieldMap = ((Client) wordpress).fieldsFrom(post); + + assertThat(fieldMap).containsOnlyKeys("title", "modified_gmt","format"); + + LOG.debug("map to post: {}", fieldMap); + + } + } \ No newline at end of file