You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@johnzon.apache.org by rm...@apache.org on 2018/07/03 08:25:08 UTC
johnzon git commit: JOHNZON-176 adding a FieldFilteringStrategy for
ignored fields
Repository: johnzon
Updated Branches:
refs/heads/master 07a04d383 -> a2cbd4375
JOHNZON-176 adding a FieldFilteringStrategy for ignored fields
Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/a2cbd437
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/a2cbd437
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/a2cbd437
Branch: refs/heads/master
Commit: a2cbd4375fcb361a8805e598e51656f34134dfad
Parents: 07a04d3
Author: Romain Manni-Bucau <rm...@gmail.com>
Authored: Tue Jul 3 10:24:11 2018 +0200
Committer: Romain Manni-Bucau <rm...@gmail.com>
Committed: Tue Jul 3 10:24:11 2018 +0200
----------------------------------------------------------------------
.../jaxrs/ConfigurableJohnzonProvider.java | 9 +++
.../WildcardConfigurableJohnzonProvider.java | 9 +++
.../apache/johnzon/mapper/MapperBuilder.java | 43 ++++++++++--
.../johnzon/mapper/access/BaseAccessMode.java | 70 +++++++++++++++-----
.../org/apache/johnzon/mapper/MapperTest.java | 27 ++++++++
5 files changed, 135 insertions(+), 23 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/johnzon/blob/a2cbd437/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/ConfigurableJohnzonProvider.java
----------------------------------------------------------------------
diff --git a/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/ConfigurableJohnzonProvider.java b/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/ConfigurableJohnzonProvider.java
index 18e6466..30a452d 100644
--- a/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/ConfigurableJohnzonProvider.java
+++ b/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/ConfigurableJohnzonProvider.java
@@ -21,6 +21,7 @@ package org.apache.johnzon.jaxrs;
import org.apache.johnzon.mapper.MapperBuilder;
import org.apache.johnzon.mapper.SerializeValueFilter;
import org.apache.johnzon.mapper.access.AccessMode;
+import org.apache.johnzon.mapper.access.BaseAccessMode;
import javax.json.JsonReaderFactory;
import javax.json.stream.JsonGeneratorFactory;
@@ -150,6 +151,14 @@ public class ConfigurableJohnzonProvider<T> implements MessageBodyWriter<T>, Mes
builder.setAccessModeName(mode);
}
+ public void setAccessModeFieldFilteringStrategy(final BaseAccessMode.FieldFilteringStrategy strategy) {
+ builder.setAccessModeFieldFilteringStrategy(strategy);
+ }
+
+ public void setAccessModeFieldFilteringStrategyName(final String mode) {
+ builder.setAccessModeFieldFilteringStrategyName(mode);
+ }
+
public void setSupportHiddenAccess(final boolean supportHiddenAccess) {
builder.setSupportHiddenAccess(supportHiddenAccess);
}
http://git-wip-us.apache.org/repos/asf/johnzon/blob/a2cbd437/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/WildcardConfigurableJohnzonProvider.java
----------------------------------------------------------------------
diff --git a/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/WildcardConfigurableJohnzonProvider.java b/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/WildcardConfigurableJohnzonProvider.java
index 34bc456..aa71150 100644
--- a/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/WildcardConfigurableJohnzonProvider.java
+++ b/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/WildcardConfigurableJohnzonProvider.java
@@ -21,6 +21,7 @@ package org.apache.johnzon.jaxrs;
import org.apache.johnzon.mapper.MapperBuilder;
import org.apache.johnzon.mapper.SerializeValueFilter;
import org.apache.johnzon.mapper.access.AccessMode;
+import org.apache.johnzon.mapper.access.BaseAccessMode;
import javax.json.JsonReaderFactory;
import javax.json.stream.JsonGeneratorFactory;
@@ -158,6 +159,14 @@ public class WildcardConfigurableJohnzonProvider<T> implements MessageBodyWriter
builder.setAccessModeName(mode);
}
+ public void setAccessModeFieldFilteringStrategy(final BaseAccessMode.FieldFilteringStrategy strategy) {
+ builder.setAccessModeFieldFilteringStrategy(strategy);
+ }
+
+ public void setAccessModeFieldFilteringStrategyName(final String mode) {
+ builder.setAccessModeFieldFilteringStrategyName(mode);
+ }
+
public void setSupportHiddenAccess(final boolean supportHiddenAccess) {
builder.setSupportHiddenAccess(supportHiddenAccess);
}
http://git-wip-us.apache.org/repos/asf/johnzon/blob/a2cbd437/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperBuilder.java
----------------------------------------------------------------------
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperBuilder.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperBuilder.java
index 387f3e6..126ff0a 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperBuilder.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperBuilder.java
@@ -18,6 +18,9 @@
*/
package org.apache.johnzon.mapper;
+import static java.util.Arrays.asList;
+import static java.util.Locale.ROOT;
+
import org.apache.johnzon.core.JsonParserFactoryImpl;
import org.apache.johnzon.mapper.access.AccessMode;
import org.apache.johnzon.mapper.access.BaseAccessMode;
@@ -129,6 +132,7 @@ public class MapperBuilder {
private Map<Class<?>, ObjectConverter.Reader<?>> objectConverterReaders = new HashMap<Class<?>, ObjectConverter.Reader<?>>();
private Map<Class<?>, ObjectConverter.Writer<?>> objectConverterWriters = new HashMap<Class<?>, ObjectConverter.Writer<?>>();
private Map<Class<?>, String[]> ignoredForFields = new HashMap<Class<?>, String[]>();
+ private BaseAccessMode.FieldFilteringStrategy fieldFilteringStrategy = null;
private boolean primitiveConverters;
private boolean failOnUnknownProperties;
private SerializeValueFilter serializeValueFilter;
@@ -181,15 +185,26 @@ public class MapperBuilder {
throw new IllegalArgumentException("Unsupported access mode: " + accessModeName);
}
}
+ if (fieldFilteringStrategy != null) {
+ if (!BaseAccessMode.class.isInstance(accessMode)) {
+ throw new IllegalArgumentException("fieldFilteringStrategy can't be set with this access mode: " + accessMode);
+ }
+ BaseAccessMode.class.cast(accessMode).setFieldFilteringStrategy(fieldFilteringStrategy);
+ }
if (!ignoredForFields.isEmpty()) {
if (BaseAccessMode.class.isInstance(accessMode)) {
final BaseAccessMode baseAccessMode = BaseAccessMode.class.cast(accessMode);
- for (final Map.Entry<Class<?>, String[]> ignored : ignoredForFields.entrySet()) {
- final String[] fields = ignored.getValue();
- if (fields == null || fields.length == 0) {
- baseAccessMode.getFieldsToRemove().remove(ignored.getKey());
- } else {
- baseAccessMode.getFieldsToRemove().put(ignored.getKey(), fields);
+ final BaseAccessMode.FieldFilteringStrategy strategy = baseAccessMode.getFieldFilteringStrategy();
+ if (BaseAccessMode.ConfiguredFieldFilteringStrategy.class.isInstance(strategy)) {
+ final BaseAccessMode.ConfiguredFieldFilteringStrategy filteringStrategy =
+ BaseAccessMode.ConfiguredFieldFilteringStrategy.class.cast(strategy);
+ for (final Map.Entry<Class<?>, String[]> ignored : ignoredForFields.entrySet()) {
+ final String[] fields = ignored.getValue();
+ if (fields == null || fields.length == 0) {
+ filteringStrategy.getFieldsToRemove().remove(ignored.getKey());
+ } else {
+ filteringStrategy.getFieldsToRemove().put(ignored.getKey(), asList(fields));
+ }
}
}
} else {
@@ -287,6 +302,22 @@ public class MapperBuilder {
return this;
}
+ public MapperBuilder setAccessModeFieldFilteringStrategy(final BaseAccessMode.FieldFilteringStrategy strategy) {
+ this.fieldFilteringStrategy = strategy;
+ return this;
+ }
+
+ public MapperBuilder setAccessModeFieldFilteringStrategyName(final String mode) {
+ switch (mode.toLowerCase(ROOT)) {
+ case "all":
+ return setAccessModeFieldFilteringStrategy(new BaseAccessMode.AllEntriesFieldFilteringStrategy());
+ case "single":
+ return setAccessModeFieldFilteringStrategy(new BaseAccessMode.SingleEntryFieldFilteringStrategy());
+ default:
+ throw new IllegalArgumentException("Unknown field filter strategy: " + mode);
+ }
+ }
+
public MapperBuilder setSupportHiddenAccess(final boolean supportHiddenAccess) {
this.supportHiddenAccess = supportHiddenAccess;
return this;
http://git-wip-us.apache.org/repos/asf/johnzon/blob/a2cbd437/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/BaseAccessMode.java
----------------------------------------------------------------------
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/BaseAccessMode.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/BaseAccessMode.java
index 5661ee2..0eba849 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/BaseAccessMode.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/BaseAccessMode.java
@@ -18,6 +18,9 @@
*/
package org.apache.johnzon.mapper.access;
+import static java.util.Arrays.asList;
+import static java.util.Collections.emptySet;
+import static java.util.stream.Collectors.toSet;
import static org.apache.johnzon.mapper.reflection.Converters.matches;
import java.beans.ConstructorProperties;
@@ -27,8 +30,9 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
+import java.util.Collection;
import java.util.Comparator;
-import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.johnzon.mapper.Adapter;
@@ -43,16 +47,13 @@ import org.apache.johnzon.mapper.internal.ConverterAdapter;
public abstract class BaseAccessMode implements AccessMode {
private static final Type[] NO_PARAMS = new Type[0];
- private final Map<Class<?>, String[]> fieldsToRemove = new HashMap<Class<?>, String[]>();
+ private FieldFilteringStrategy fieldFilteringStrategy = new SingleEntryFieldFilteringStrategy();
private final boolean acceptHiddenConstructor;
private final boolean useConstructor;
protected BaseAccessMode(final boolean useConstructor, final boolean acceptHiddenConstructor) {
this.useConstructor = useConstructor;
this.acceptHiddenConstructor = acceptHiddenConstructor;
-
- // mainly built it in the JVM types == user cant handle them
- fieldsToRemove.put(Throwable.class, new String[]{"suppressedExceptions", "cause"});
}
protected abstract Map<String,Reader> doFindReaders(Class<?> clazz);
@@ -73,9 +74,12 @@ public abstract class BaseAccessMode implements AccessMode {
return sanitize(clazz, doFindWriters(clazz));
}
- // editable during builder time, dont do it at runtime or you get no guarantee
- public Map<Class<?>, String[]> getFieldsToRemove() {
- return fieldsToRemove;
+ public void setFieldFilteringStrategy(final FieldFilteringStrategy fieldFilteringStrategy) {
+ this.fieldFilteringStrategy = fieldFilteringStrategy;
+ }
+
+ public FieldFilteringStrategy getFieldFilteringStrategy() {
+ return fieldFilteringStrategy;
}
@Override
@@ -182,9 +186,7 @@ public abstract class BaseAccessMode implements AccessMode {
}
try {
return params == null ? cons.newInstance() : cons.newInstance(params);
- } catch (final InstantiationException e) {
- throw new IllegalStateException(e);
- } catch (final IllegalAccessException e) {
+ } catch (final InstantiationException | IllegalAccessException e) {
throw new IllegalStateException(e);
} catch (final InvocationTargetException e) {
throw new IllegalStateException(e.getCause());
@@ -255,14 +257,48 @@ public abstract class BaseAccessMode implements AccessMode {
}
private <T> Map<String, T> sanitize(final Class<?> type, final Map<String, T> delegate) {
- for (final Map.Entry<Class<?>, String[]> entry : fieldsToRemove.entrySet()) {
- if (entry.getKey().isAssignableFrom(type)) {
- for (final String field : entry.getValue()) {
- delegate.remove(field);
+ for (final String field : fieldFilteringStrategy.select(type)) {
+ delegate.remove(field);
+ }
+ return delegate;
+ }
+
+ public interface FieldFilteringStrategy {
+ Collection<String> select(final Class<?> type);
+ }
+
+ public static abstract class ConfiguredFieldFilteringStrategy implements FieldFilteringStrategy {
+ private final Map<Class<?>, Collection<String>> fieldsToRemove = new LinkedHashMap<>();
+
+ public ConfiguredFieldFilteringStrategy() {
+ // mainly built it in the JVM types == user cant handle them
+ fieldsToRemove.put(Throwable.class, asList("suppressedExceptions", "cause"));
+ }
+
+ public Map<Class<?>, Collection<String>> getFieldsToRemove() {
+ return fieldsToRemove;
+ }
+ }
+
+ public static class SingleEntryFieldFilteringStrategy extends ConfiguredFieldFilteringStrategy {
+ @Override
+ public Collection<String> select(final Class<?> type) {
+ for (final Map.Entry<Class<?>, Collection<String>> entry : getFieldsToRemove().entrySet()) {
+ if (entry.getKey().isAssignableFrom(type)) {
+ return entry.getValue();
}
- return delegate;
}
+ return emptySet();
+ }
+ }
+
+ public static class AllEntriesFieldFilteringStrategy extends ConfiguredFieldFilteringStrategy {
+ @Override
+ public Collection<String> select(final Class<?> type) {
+ return getFieldsToRemove().entrySet().stream()
+ .filter(entry -> entry.getKey().isAssignableFrom(type))
+ .flatMap(entry -> entry.getValue().stream())
+ .collect(toSet());
}
- return delegate;
}
}
http://git-wip-us.apache.org/repos/asf/johnzon/blob/a2cbd437/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperTest.java
----------------------------------------------------------------------
diff --git a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperTest.java b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperTest.java
index c3d90cf..3582460 100644
--- a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperTest.java
+++ b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperTest.java
@@ -32,6 +32,7 @@ import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
@@ -59,6 +60,22 @@ public class MapperTest {
+ "\"primitives\":[1,2,3,4,5]," + "\"collectionWrapper\":[1,2,3,4,5]," + "\"map\":{\"uno\":true,\"duos\":false}" + "}";
@Test
+ public void ignoreAllStrategy() {
+ final StringWriter writer = new StringWriter();
+ final Child object = new Child();
+ object.children = Collections.singletonList("first");
+ object.a = 5;
+ object.b = 6;
+ object.c = 7;
+ new MapperBuilder().setAccessModeFieldFilteringStrategyName("all")
+ .setIgnoreFieldsForType(Child.class, "children")
+ .setIgnoreFieldsForType(Parent.class, "a", "b")
+ .build()
+ .writeObject(object, writer);
+ assertEquals("{\"c\":7}", writer.toString());
+ }
+
+ @Test
public void writeEmptyObject() {
final StringWriter writer = new StringWriter();
new MapperBuilder().build().writeObject(null, writer);
@@ -1098,4 +1115,14 @@ public class MapperTest {
public static class PrimitiveObject {
public Object bool;
}
+
+ public static class Parent {
+ public int a;
+ public int b;
+ public int c;
+ }
+
+ public static class Child extends Parent {
+ public List<String> children;
+ }
}