From f462fb627a26aeea4ac5f2f919faca035a4a9bef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ko=C5=BEusznik?= Date: Sat, 26 Jan 2019 20:22:18 +0100 Subject: [PATCH 01/15] serializer for Interval --- .../java/net/imagej/server/mixins/Mixins.java | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/imagej/server/mixins/Mixins.java b/src/main/java/net/imagej/server/mixins/Mixins.java index 621967d6..61300e69 100644 --- a/src/main/java/net/imagej/server/mixins/Mixins.java +++ b/src/main/java/net/imagej/server/mixins/Mixins.java @@ -25,12 +25,18 @@ import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import java.io.IOException; import java.lang.reflect.Type; import java.util.Arrays; import java.util.List; +import net.imglib2.Interval; import net.imglib2.outofbounds.OutOfBoundsFactory; import net.imglib2.type.numeric.ComplexType; import net.imglib2.type.numeric.IntegerType; @@ -47,7 +53,7 @@ */ public class Mixins { - private static final Class[] SUPPORT = { ComplexType.class, + private static final Class[] SUPPORT = { Interval.class, ComplexType.class, ModuleInfo.class, ModuleItem.class }; private Mixins() {} @@ -188,7 +194,40 @@ protected static abstract class OutOfBoundsFactoryMixIn implements public abstract String toString(); } + private static class IntervalSerializer extends StdSerializer { + + protected IntervalSerializer(Class t) { + super(t); + } + + public IntervalSerializer() { + this(null); + } + + @Override + public void serialize(Interval value, JsonGenerator gen, + SerializerProvider provider) throws IOException + { + gen.writeStartObject(); + gen.writeArrayFieldStart("min"); + for (int i = 0; i < value.numDimensions(); i++) { + gen.writeNumber(value.min(i)); + } + gen.writeEndArray(); + gen.writeArrayFieldStart("max"); + for (int i = 0; i < value.numDimensions(); i++) { + gen.writeNumber(value.max(i)); + } + gen.writeEndArray(); + gen.writeEndObject(); + } + + } + public static void registerMixIns(final ObjectMapper mapper) { + SimpleModule mod = new SimpleModule(); + mod.addSerializer(Interval.class, new IntervalSerializer()); + mapper.registerModule(mod); mapper.addMixIn(ComplexType.class, ToStringMixIn.class); mapper.addMixIn(RealType.class, RealTypeMixIn.class); mapper.addMixIn(IntegerType.class, IntegerTypeMixIn.class); @@ -196,5 +235,6 @@ public static void registerMixIns(final ObjectMapper mapper) { mapper.addMixIn(ModuleItem.class, ModuleItemMixIn.class); mapper.addMixIn(Type.class, TypeMixIn.class); mapper.addMixIn(OutOfBoundsFactory.class, OutOfBoundsFactoryMixIn.class); + } } From 843a48814adea6d67c04068161e4f8617e0727c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ko=C5=BEusznik?= Date: Sun, 27 Jan 2019 12:33:22 +0100 Subject: [PATCH 02/15] define skipped classes by Mixins --- src/main/java/net/imagej/server/mixins/Mixins.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/imagej/server/mixins/Mixins.java b/src/main/java/net/imagej/server/mixins/Mixins.java index 61300e69..41ca6f36 100644 --- a/src/main/java/net/imagej/server/mixins/Mixins.java +++ b/src/main/java/net/imagej/server/mixins/Mixins.java @@ -36,6 +36,7 @@ import java.util.Arrays; import java.util.List; +import net.imagej.Dataset; import net.imglib2.Interval; import net.imglib2.outofbounds.OutOfBoundsFactory; import net.imglib2.type.numeric.ComplexType; @@ -56,6 +57,8 @@ public class Mixins { private static final Class[] SUPPORT = { Interval.class, ComplexType.class, ModuleInfo.class, ModuleItem.class }; + private static final Class[] NOT_SUPPORT = { Dataset.class }; + private Mixins() {} /** @@ -66,8 +69,9 @@ private Mixins() {} * @return true if the given class is supported. */ public static boolean support(Class beanClass) { - return Arrays.stream(SUPPORT).anyMatch(clazz -> clazz.isAssignableFrom( - beanClass)); + return Arrays.stream(NOT_SUPPORT).noneMatch(clazz -> clazz.isAssignableFrom( + beanClass)) && Arrays.stream(SUPPORT).anyMatch(clazz -> clazz + .isAssignableFrom(beanClass)); } @JsonAutoDetect(getterVisibility = Visibility.NONE) From 859fd3e82c2935ff57aebcdad4f78188325338e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ko=C5=BEusznik?= Date: Sun, 27 Jan 2019 16:05:17 +0100 Subject: [PATCH 03/15] create plugin for additional mixins and serializers --- .../java/net/imagej/server/ImageJServer.java | 8 +- .../java/net/imagej/server/mixins/Mixins.java | 123 +++++++++++------- .../server/services/DefaultJsonService.java | 10 +- .../imagej/server/AbstractResourceTest.java | 2 +- .../imagej/server/DefaultJsonServiceTest.java | 4 +- 5 files changed, 93 insertions(+), 54 deletions(-) diff --git a/src/main/java/net/imagej/server/ImageJServer.java b/src/main/java/net/imagej/server/ImageJServer.java index 32284934..9d65780f 100644 --- a/src/main/java/net/imagej/server/ImageJServer.java +++ b/src/main/java/net/imagej/server/ImageJServer.java @@ -49,22 +49,20 @@ * * @author Leon Yang */ -public class ImageJServer extends - Application -{ +public class ImageJServer extends Application { private final Context ctx; private final ObjectService objectService; private final JsonService jsonService; - + private Environment env; public ImageJServer(final Context ctx) { this.ctx = ctx; objectService = new DefaultObjectService(); - jsonService = new DefaultJsonService(objectService); + jsonService = new DefaultJsonService(ctx, objectService); } @Override diff --git a/src/main/java/net/imagej/server/mixins/Mixins.java b/src/main/java/net/imagej/server/mixins/Mixins.java index 41ca6f36..592b608f 100644 --- a/src/main/java/net/imagej/server/mixins/Mixins.java +++ b/src/main/java/net/imagej/server/mixins/Mixins.java @@ -25,26 +25,28 @@ import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonValue; -import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.ser.std.StdSerializer; -import java.io.IOException; import java.lang.reflect.Type; import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; import java.util.List; +import java.util.Set; +import java.util.function.Consumer; -import net.imagej.Dataset; -import net.imglib2.Interval; import net.imglib2.outofbounds.OutOfBoundsFactory; import net.imglib2.type.numeric.ComplexType; import net.imglib2.type.numeric.IntegerType; import net.imglib2.type.numeric.RealType; +import org.scijava.Context; import org.scijava.module.ModuleInfo; import org.scijava.module.ModuleItem; +import org.scijava.plugin.PluginService; +import org.scijava.plugin.SciJavaPlugin; /** * Jackson MixIns for some specific types in order to produce better output @@ -54,10 +56,63 @@ */ public class Mixins { - private static final Class[] SUPPORT = { Interval.class, ComplexType.class, - ModuleInfo.class, ModuleItem.class }; + public static abstract class ObjectMapperModificator implements SciJavaPlugin, + Consumer + { + + private Set> additionalSupport; + private Set> additionalNotSupport; + + public ObjectMapperModificator(Collection> additionalSupport, + Collection> additionalNotSupport) + { + super(); + this.additionalSupport = new HashSet<>(additionalSupport); + this.additionalNotSupport = new HashSet<>(additionalNotSupport); + } + + public Set> getAdditionSupport() { + return additionalSupport; + } + + public Set> getAdditionNotSupport() { + return additionalNotSupport; + + } + } + + public static class SerializerModificator extends ObjectMapperModificator { + + private StdSerializer serializer; + private Class clazz; + + public SerializerModificator(Collection> additionalSupport, + Collection> additionalNotSupport, StdSerializer serializer, + Class clazz) + { + super(additionalSupport, additionalNotSupport); + this.serializer = serializer; + this.clazz = clazz; + } + + @Override + public void accept(ObjectMapper mapper) { + SimpleModule mod = new SimpleModule(); + mod.addSerializer(clazz, serializer); + mapper.registerModule(mod); + } + + } - private static final Class[] NOT_SUPPORT = { Dataset.class }; + private static final Set> SUPPORT = new HashSet>() { + + { + addAll(Arrays.asList(ComplexType.class, ModuleInfo.class, + ModuleItem.class)); + } + }; + + private static final Set> NOT_SUPPORT = new HashSet<>(); private Mixins() {} @@ -69,9 +124,9 @@ private Mixins() {} * @return true if the given class is supported. */ public static boolean support(Class beanClass) { - return Arrays.stream(NOT_SUPPORT).noneMatch(clazz -> clazz.isAssignableFrom( - beanClass)) && Arrays.stream(SUPPORT).anyMatch(clazz -> clazz - .isAssignableFrom(beanClass)); + return NOT_SUPPORT.stream().noneMatch(clazz -> clazz.isAssignableFrom( + beanClass)) && SUPPORT.stream().anyMatch(clazz -> clazz.isAssignableFrom( + beanClass)); } @JsonAutoDetect(getterVisibility = Visibility.NONE) @@ -198,40 +253,8 @@ protected static abstract class OutOfBoundsFactoryMixIn implements public abstract String toString(); } - private static class IntervalSerializer extends StdSerializer { - - protected IntervalSerializer(Class t) { - super(t); - } - - public IntervalSerializer() { - this(null); - } - - @Override - public void serialize(Interval value, JsonGenerator gen, - SerializerProvider provider) throws IOException - { - gen.writeStartObject(); - gen.writeArrayFieldStart("min"); - for (int i = 0; i < value.numDimensions(); i++) { - gen.writeNumber(value.min(i)); - } - gen.writeEndArray(); - gen.writeArrayFieldStart("max"); - for (int i = 0; i < value.numDimensions(); i++) { - gen.writeNumber(value.max(i)); - } - gen.writeEndArray(); - gen.writeEndObject(); - } - - } - public static void registerMixIns(final ObjectMapper mapper) { - SimpleModule mod = new SimpleModule(); - mod.addSerializer(Interval.class, new IntervalSerializer()); - mapper.registerModule(mod); + mapper.addMixIn(ComplexType.class, ToStringMixIn.class); mapper.addMixIn(RealType.class, RealTypeMixIn.class); mapper.addMixIn(IntegerType.class, IntegerTypeMixIn.class); @@ -241,4 +264,16 @@ public static void registerMixIns(final ObjectMapper mapper) { mapper.addMixIn(OutOfBoundsFactory.class, OutOfBoundsFactoryMixIn.class); } + + public static void processObjectMapper(final Context ctx, + final ObjectMapper mapper) + { + for (ObjectMapperModificator omm : ctx.getService(PluginService.class) + .createInstancesOfType((ObjectMapperModificator.class))) + { + SUPPORT.addAll(omm.getAdditionSupport()); + NOT_SUPPORT.addAll(omm.getAdditionNotSupport()); + omm.accept(mapper); + } + } } diff --git a/src/main/java/net/imagej/server/services/DefaultJsonService.java b/src/main/java/net/imagej/server/services/DefaultJsonService.java index 9f2f3285..c8585318 100644 --- a/src/main/java/net/imagej/server/services/DefaultJsonService.java +++ b/src/main/java/net/imagej/server/services/DefaultJsonService.java @@ -51,6 +51,8 @@ import net.imagej.server.mixins.Mixins; import net.imglib2.EuclideanSpace; +import org.scijava.Context; + /** * Service that handle customized JSON serialization and deserialization. * @@ -78,8 +80,9 @@ public class DefaultJsonService implements JsonService { * * @param objectService */ - public DefaultJsonService(final ObjectService objectService) { - + public DefaultJsonService(final Context ctx, + final ObjectService objectService) + { idToObjDeserializer = new UntypedObjectDeserializer(null, null) { @Override @@ -101,7 +104,7 @@ public Object deserialize(JsonParser p, DeserializationContext ctxt) final JsonSerializer objToIdSerializer = new JsonSerializer() - { + { @Override public void serialize(Object value, JsonGenerator gen, @@ -136,6 +139,7 @@ public JsonSerializer modifySerializer(SerializationConfig config, // register Jackson MixIns to obtain better json output format for some // specific types + Mixins.processObjectMapper(ctx, objToIdMapper); Mixins.registerMixIns(objToIdMapper); } diff --git a/src/test/java/net/imagej/server/AbstractResourceTest.java b/src/test/java/net/imagej/server/AbstractResourceTest.java index 7f2429e9..28cbf03e 100644 --- a/src/test/java/net/imagej/server/AbstractResourceTest.java +++ b/src/test/java/net/imagej/server/AbstractResourceTest.java @@ -46,7 +46,7 @@ public abstract class AbstractResourceTest { protected static final ObjectService objectService = new DefaultObjectService(); - protected static final JsonService jsonService = new DefaultJsonService( + protected static final JsonService jsonService = new DefaultJsonService(ctx, objectService); protected static final ObjectMapper objectMapper = new ObjectMapper(); diff --git a/src/test/java/net/imagej/server/DefaultJsonServiceTest.java b/src/test/java/net/imagej/server/DefaultJsonServiceTest.java index 20c3482a..31756ad2 100644 --- a/src/test/java/net/imagej/server/DefaultJsonServiceTest.java +++ b/src/test/java/net/imagej/server/DefaultJsonServiceTest.java @@ -54,6 +54,7 @@ import org.junit.Before; import org.junit.Test; +import org.scijava.Context; /** * Test deserialization and serialization using DefaultJsonService. @@ -66,12 +67,13 @@ public class DefaultJsonServiceTest { private ObjectMapper modifiedMapper; private ListObjectService objectService; private DefaultJsonService jsonService; + protected static final Context ctx = new Context(); @Before public void setup() { modifiedMapper = Jackson.newObjectMapper(); objectService = new ListObjectService(); - jsonService = new DefaultJsonService(objectService); + jsonService = new DefaultJsonService(ctx, objectService); jsonService.addDeserializerTo(modifiedMapper); } From 827ef99f87a2ea4133cf7247512a9efbe83f4ecc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ko=C5=BEusznik?= Date: Fri, 1 Feb 2019 10:58:14 +0100 Subject: [PATCH 04/15] pom.xml - own version and distributionManagement --- pom.xml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f6fc9d06..a5c2ac3c 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ net.imagej imagej-server - 0.1.3-SNAPSHOT + 0.1.3-parallel-SNAPSHOT ImageJ Server A simple RESTful web server for ImageJ @@ -182,4 +182,14 @@ Wisconsin-Madison. + + + it4i + https://artifactory.cs.vsb.cz/it4i/ + + + it4i + https://artifactory.cs.vsb.cz/it4i/ + + From 5a9a3617ef03a33e95ad3336368c54adc14b8b0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ko=C5=BEusznik?= Date: Fri, 1 Feb 2019 11:39:01 +0100 Subject: [PATCH 05/15] pom.xml - subminor version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a5c2ac3c..d713bcb8 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ net.imagej imagej-server - 0.1.3-parallel-SNAPSHOT + 0.1.3.1-SNAPSHOT ImageJ Server A simple RESTful web server for ImageJ From c9b65f3c26573ceb72cd7c985c2caf59dc54cd4e Mon Sep 17 00:00:00 2001 From: Petr Bainar Date: Tue, 5 Feb 2019 22:55:22 +0100 Subject: [PATCH 06/15] intervalSerializerRefactor: move modifiers from Mixins (WIP, not tested) --- .../java/net/imagej/server/mixins/Mixins.java | 30 ++++--------------- .../server/services/DefaultJsonService.java | 30 ++++++++++++++++++- 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/src/main/java/net/imagej/server/mixins/Mixins.java b/src/main/java/net/imagej/server/mixins/Mixins.java index 592b608f..2ab55932 100644 --- a/src/main/java/net/imagej/server/mixins/Mixins.java +++ b/src/main/java/net/imagej/server/mixins/Mixins.java @@ -42,10 +42,8 @@ import net.imglib2.type.numeric.IntegerType; import net.imglib2.type.numeric.RealType; -import org.scijava.Context; import org.scijava.module.ModuleInfo; import org.scijava.module.ModuleItem; -import org.scijava.plugin.PluginService; import org.scijava.plugin.SciJavaPlugin; /** @@ -104,15 +102,8 @@ public void accept(ObjectMapper mapper) { } - private static final Set> SUPPORT = new HashSet>() { - - { - addAll(Arrays.asList(ComplexType.class, ModuleInfo.class, - ModuleItem.class)); - } - }; - - private static final Set> NOT_SUPPORT = new HashSet<>(); + private static final Class[] SUPPORT = { ComplexType.class, + ModuleInfo.class, ModuleItem.class }; private Mixins() {} @@ -124,9 +115,11 @@ private Mixins() {} * @return true if the given class is supported. */ public static boolean support(Class beanClass) { - return NOT_SUPPORT.stream().noneMatch(clazz -> clazz.isAssignableFrom( + /* return NOT_SUPPORT.stream().noneMatch(clazz -> clazz.isAssignableFrom( beanClass)) && SUPPORT.stream().anyMatch(clazz -> clazz.isAssignableFrom( - beanClass)); + beanClass)); */ + return Arrays.stream(SUPPORT).anyMatch(clazz -> clazz.isAssignableFrom( + beanClass)); } @JsonAutoDetect(getterVisibility = Visibility.NONE) @@ -265,15 +258,4 @@ public static void registerMixIns(final ObjectMapper mapper) { } - public static void processObjectMapper(final Context ctx, - final ObjectMapper mapper) - { - for (ObjectMapperModificator omm : ctx.getService(PluginService.class) - .createInstancesOfType((ObjectMapperModificator.class))) - { - SUPPORT.addAll(omm.getAdditionSupport()); - NOT_SUPPORT.addAll(omm.getAdditionNotSupport()); - omm.accept(mapper); - } - } } diff --git a/src/main/java/net/imagej/server/services/DefaultJsonService.java b/src/main/java/net/imagej/server/services/DefaultJsonService.java index c8585318..0115eb1d 100644 --- a/src/main/java/net/imagej/server/services/DefaultJsonService.java +++ b/src/main/java/net/imagej/server/services/DefaultJsonService.java @@ -47,11 +47,16 @@ import java.io.IOException; import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import net.imagej.server.mixins.Mixins; +import net.imagej.server.mixins.Mixins.ObjectMapperModificator; import net.imglib2.EuclideanSpace; import org.scijava.Context; +import org.scijava.plugin.PluginService; /** * Service that handle customized JSON serialization and deserialization. @@ -60,6 +65,9 @@ */ public class DefaultJsonService implements JsonService { + private static final Set> SERIALIZABLE_BY_MAPPER_MODIFIERS = + new HashSet<>(); + private static final Class[] NOT_SERIALIZED = { EuclideanSpace.class }; /** @@ -123,13 +131,21 @@ public void serialize(Object value, JsonGenerator gen, public JsonSerializer modifySerializer(SerializationConfig config, BeanDescription beanDesc, JsonSerializer serializer) { + // If the serialized class is supported by mixins, let's go for one if (Mixins.support(beanDesc.getBeanClass())) return serializer; + + // If the serialized class is supported thanks to a modification to + // ObjectMapper, let's do it that way + if (SERIALIZABLE_BY_MAPPER_MODIFIERS.stream().anyMatch(clazz -> clazz + .isAssignableFrom(beanDesc.getBeanClass()))) return serializer; + // If the serialized class is unknown (i.e. serialized using the general // BeanSerializer) or should not be serialized (i.e. complicated class // implemented interfaces such as Iterable), would be serialized as an // ID. if (serializer instanceof BeanSerializer) return objToIdSerializer; if (notSerialized(beanDesc.getBeanClass())) return objToIdSerializer; + return serializer; } @@ -137,9 +153,11 @@ public JsonSerializer modifySerializer(SerializationConfig config, objToIdMapper = new ObjectMapper(); objToIdMapper.registerModule(objToIdModule); + applyModifiers(objToIdMapper, ctx.getService(PluginService.class) + .createInstancesOfType((ObjectMapperModificator.class))); + // register Jackson MixIns to obtain better json output format for some // specific types - Mixins.processObjectMapper(ctx, objToIdMapper); Mixins.registerMixIns(objToIdMapper); } @@ -160,4 +178,14 @@ public boolean notSerialized(final Class target) { .isAssignableFrom(target)); } + private void applyModifiers(ObjectMapper mapper, + List modifiers) + { + for (ObjectMapperModificator modifier : modifiers) { + modifier.accept(mapper); + SERIALIZABLE_BY_MAPPER_MODIFIERS.addAll(modifier.getAdditionSupport()); + } + + } + } From df7cf683d3a81b1e037ca68be48955ce15b30fe3 Mon Sep 17 00:00:00 2001 From: Petr Bainar Date: Mon, 11 Feb 2019 00:05:03 +0100 Subject: [PATCH 07/15] IntervalSerializerRefactor: amend logic a bit (WIP, not tested) --- .../java/net/imagej/server/mixins/Mixins.java | 26 +++++++++--------- .../server/services/DefaultJsonService.java | 27 ++++++++++++------- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/src/main/java/net/imagej/server/mixins/Mixins.java b/src/main/java/net/imagej/server/mixins/Mixins.java index 2ab55932..3bdf491d 100644 --- a/src/main/java/net/imagej/server/mixins/Mixins.java +++ b/src/main/java/net/imagej/server/mixins/Mixins.java @@ -58,23 +58,23 @@ public static abstract class ObjectMapperModificator implements SciJavaPlugin, Consumer { - private Set> additionalSupport; - private Set> additionalNotSupport; + private Class supportedClass; + private Set> excludedClasses; - public ObjectMapperModificator(Collection> additionalSupport, - Collection> additionalNotSupport) + public ObjectMapperModificator(Class supportedClass, + Collection> excludedClasses) { super(); - this.additionalSupport = new HashSet<>(additionalSupport); - this.additionalNotSupport = new HashSet<>(additionalNotSupport); + this.supportedClass = supportedClass; + this.excludedClasses = new HashSet<>(excludedClasses); } - public Set> getAdditionSupport() { - return additionalSupport; + public Class getSupportedClass() { + return supportedClass; } - public Set> getAdditionNotSupport() { - return additionalNotSupport; + public Set> getExcludedClasses() { + return excludedClasses; } } @@ -84,11 +84,11 @@ public static class SerializerModificator extends ObjectMapperModificator { private StdSerializer serializer; private Class clazz; - public SerializerModificator(Collection> additionalSupport, - Collection> additionalNotSupport, StdSerializer serializer, + public SerializerModificator(Class supportedClass, + Collection> excludedClasses, StdSerializer serializer, Class clazz) { - super(additionalSupport, additionalNotSupport); + super(supportedClass, excludedClasses); this.serializer = serializer; this.clazz = clazz; } diff --git a/src/main/java/net/imagej/server/services/DefaultJsonService.java b/src/main/java/net/imagej/server/services/DefaultJsonService.java index 0115eb1d..c4549ebe 100644 --- a/src/main/java/net/imagej/server/services/DefaultJsonService.java +++ b/src/main/java/net/imagej/server/services/DefaultJsonService.java @@ -47,9 +47,10 @@ import java.io.IOException; import java.util.Arrays; -import java.util.HashSet; +import java.util.Collection; +import java.util.HashMap; import java.util.List; -import java.util.Set; +import java.util.Map; import net.imagej.server.mixins.Mixins; import net.imagej.server.mixins.Mixins.ObjectMapperModificator; @@ -65,8 +66,8 @@ */ public class DefaultJsonService implements JsonService { - private static final Set> SERIALIZABLE_BY_MAPPER_MODIFIERS = - new HashSet<>(); + private static final Map, Collection>> SERIALIZABLE_BY_MAPPER_MODIFIERS = + new HashMap<>(); private static final Class[] NOT_SERIALIZED = { EuclideanSpace.class }; @@ -131,20 +132,24 @@ public void serialize(Object value, JsonGenerator gen, public JsonSerializer modifySerializer(SerializationConfig config, BeanDescription beanDesc, JsonSerializer serializer) { + final Class desiredClass = beanDesc.getBeanClass(); + // If the serialized class is supported by mixins, let's go for one - if (Mixins.support(beanDesc.getBeanClass())) return serializer; + if (Mixins.support(desiredClass)) return serializer; // If the serialized class is supported thanks to a modification to // ObjectMapper, let's do it that way - if (SERIALIZABLE_BY_MAPPER_MODIFIERS.stream().anyMatch(clazz -> clazz - .isAssignableFrom(beanDesc.getBeanClass()))) return serializer; + if (SERIALIZABLE_BY_MAPPER_MODIFIERS.entrySet().stream().anyMatch(e -> e + .getKey().isAssignableFrom(desiredClass) && e.getValue().stream() + .noneMatch(v -> v.isAssignableFrom(desiredClass)))) + return serializer; // If the serialized class is unknown (i.e. serialized using the general // BeanSerializer) or should not be serialized (i.e. complicated class // implemented interfaces such as Iterable), would be serialized as an // ID. if (serializer instanceof BeanSerializer) return objToIdSerializer; - if (notSerialized(beanDesc.getBeanClass())) return objToIdSerializer; + if (notSerialized(desiredClass)) return objToIdSerializer; return serializer; @@ -183,7 +188,11 @@ private void applyModifiers(ObjectMapper mapper, { for (ObjectMapperModificator modifier : modifiers) { modifier.accept(mapper); - SERIALIZABLE_BY_MAPPER_MODIFIERS.addAll(modifier.getAdditionSupport()); + + // TODO: Add logic on two modifiers for the same class but with different + // exclusions etc. + SERIALIZABLE_BY_MAPPER_MODIFIERS.put(modifier.getSupportedClass(), + modifier.getExcludedClasses()); } } From 32dd83f9fa977ba25507286e26c3ac1db501d734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ko=C5=BEusznik?= Date: Thu, 14 Feb 2019 10:56:38 +0100 Subject: [PATCH 08/15] IntervalSerializerRefactor: extract modifiers to own file and package --- .../java/net/imagej/server/mixins/Mixins.java | 58 ------------------- .../modifiers/ObjectMapperModifier.java | 41 +++++++++++++ .../server/modifiers/SerializerModifier.java | 30 ++++++++++ .../server/services/DefaultJsonService.java | 26 ++++----- 4 files changed, 82 insertions(+), 73 deletions(-) create mode 100644 src/main/java/net/imagej/server/modifiers/ObjectMapperModifier.java create mode 100644 src/main/java/net/imagej/server/modifiers/SerializerModifier.java diff --git a/src/main/java/net/imagej/server/mixins/Mixins.java b/src/main/java/net/imagej/server/mixins/Mixins.java index 3bdf491d..d9471831 100644 --- a/src/main/java/net/imagej/server/mixins/Mixins.java +++ b/src/main/java/net/imagej/server/mixins/Mixins.java @@ -26,16 +26,10 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonValue; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.module.SimpleModule; -import com.fasterxml.jackson.databind.ser.std.StdSerializer; import java.lang.reflect.Type; import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; import java.util.List; -import java.util.Set; -import java.util.function.Consumer; import net.imglib2.outofbounds.OutOfBoundsFactory; import net.imglib2.type.numeric.ComplexType; @@ -44,7 +38,6 @@ import org.scijava.module.ModuleInfo; import org.scijava.module.ModuleItem; -import org.scijava.plugin.SciJavaPlugin; /** * Jackson MixIns for some specific types in order to produce better output @@ -54,54 +47,6 @@ */ public class Mixins { - public static abstract class ObjectMapperModificator implements SciJavaPlugin, - Consumer - { - - private Class supportedClass; - private Set> excludedClasses; - - public ObjectMapperModificator(Class supportedClass, - Collection> excludedClasses) - { - super(); - this.supportedClass = supportedClass; - this.excludedClasses = new HashSet<>(excludedClasses); - } - - public Class getSupportedClass() { - return supportedClass; - } - - public Set> getExcludedClasses() { - return excludedClasses; - - } - } - - public static class SerializerModificator extends ObjectMapperModificator { - - private StdSerializer serializer; - private Class clazz; - - public SerializerModificator(Class supportedClass, - Collection> excludedClasses, StdSerializer serializer, - Class clazz) - { - super(supportedClass, excludedClasses); - this.serializer = serializer; - this.clazz = clazz; - } - - @Override - public void accept(ObjectMapper mapper) { - SimpleModule mod = new SimpleModule(); - mod.addSerializer(clazz, serializer); - mapper.registerModule(mod); - } - - } - private static final Class[] SUPPORT = { ComplexType.class, ModuleInfo.class, ModuleItem.class }; @@ -115,9 +60,6 @@ private Mixins() {} * @return true if the given class is supported. */ public static boolean support(Class beanClass) { - /* return NOT_SUPPORT.stream().noneMatch(clazz -> clazz.isAssignableFrom( - beanClass)) && SUPPORT.stream().anyMatch(clazz -> clazz.isAssignableFrom( - beanClass)); */ return Arrays.stream(SUPPORT).anyMatch(clazz -> clazz.isAssignableFrom( beanClass)); } diff --git a/src/main/java/net/imagej/server/modifiers/ObjectMapperModifier.java b/src/main/java/net/imagej/server/modifiers/ObjectMapperModifier.java new file mode 100644 index 00000000..7388f9a2 --- /dev/null +++ b/src/main/java/net/imagej/server/modifiers/ObjectMapperModifier.java @@ -0,0 +1,41 @@ + +package net.imagej.server.modifiers; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; +import java.util.function.Consumer; + +import org.scijava.plugin.SciJavaPlugin; + +public abstract class ObjectMapperModifier implements SciJavaPlugin, + Consumer +{ + + private Class supportedClass; + private Set> excludedClasses; + + public ObjectMapperModifier(Class supportedClass, + Collection> excludedClasses) + { + super(); + this.supportedClass = supportedClass; + this.excludedClasses = new HashSet<>(excludedClasses); + } + + protected Class getSupportedClass() { + return supportedClass; + } + + protected Set> getExcludedClasses() { + return excludedClasses; + } + + public boolean isSupportedBy(Class desiredClass) { + return getSupportedClass().isAssignableFrom(desiredClass) && + getExcludedClasses().stream().noneMatch(v -> v.isAssignableFrom( + desiredClass)); + } +} diff --git a/src/main/java/net/imagej/server/modifiers/SerializerModifier.java b/src/main/java/net/imagej/server/modifiers/SerializerModifier.java new file mode 100644 index 00000000..c2cc4f4f --- /dev/null +++ b/src/main/java/net/imagej/server/modifiers/SerializerModifier.java @@ -0,0 +1,30 @@ + +package net.imagej.server.modifiers; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +import java.util.Collection; + +public class SerializerModifier extends ObjectMapperModifier { + + private StdSerializer serializer; + + public SerializerModifier(Class supportedClass, + Collection> excludedClasses, StdSerializer serializer) + { + super(supportedClass, excludedClasses); + this.serializer = serializer; + + } + + @SuppressWarnings("unchecked") + @Override + public void accept(ObjectMapper mapper) { + SimpleModule mod = new SimpleModule(); + mod.addSerializer((Class) getSupportedClass(), serializer); + mapper.registerModule(mod); + } + +} diff --git a/src/main/java/net/imagej/server/services/DefaultJsonService.java b/src/main/java/net/imagej/server/services/DefaultJsonService.java index c4549ebe..c8f626c6 100644 --- a/src/main/java/net/imagej/server/services/DefaultJsonService.java +++ b/src/main/java/net/imagej/server/services/DefaultJsonService.java @@ -48,12 +48,11 @@ import java.io.IOException; import java.util.Arrays; import java.util.Collection; -import java.util.HashMap; +import java.util.LinkedList; import java.util.List; -import java.util.Map; import net.imagej.server.mixins.Mixins; -import net.imagej.server.mixins.Mixins.ObjectMapperModificator; +import net.imagej.server.modifiers.ObjectMapperModifier; import net.imglib2.EuclideanSpace; import org.scijava.Context; @@ -66,9 +65,6 @@ */ public class DefaultJsonService implements JsonService { - private static final Map, Collection>> SERIALIZABLE_BY_MAPPER_MODIFIERS = - new HashMap<>(); - private static final Class[] NOT_SERIALIZED = { EuclideanSpace.class }; /** @@ -84,6 +80,9 @@ public class DefaultJsonService implements JsonService { */ private final UntypedObjectDeserializer idToObjDeserializer; + private final Collection objectMapperModifiers = + new LinkedList<>(); + /** * Constructs and initializes a JsonService with an {@link ObjectService}. * @@ -139,10 +138,8 @@ public JsonSerializer modifySerializer(SerializationConfig config, // If the serialized class is supported thanks to a modification to // ObjectMapper, let's do it that way - if (SERIALIZABLE_BY_MAPPER_MODIFIERS.entrySet().stream().anyMatch(e -> e - .getKey().isAssignableFrom(desiredClass) && e.getValue().stream() - .noneMatch(v -> v.isAssignableFrom(desiredClass)))) - return serializer; + if (objectMapperModifiers.stream().anyMatch(e -> e.isSupportedBy( + desiredClass))) return serializer; // If the serialized class is unknown (i.e. serialized using the general // BeanSerializer) or should not be serialized (i.e. complicated class @@ -159,7 +156,7 @@ public JsonSerializer modifySerializer(SerializationConfig config, objToIdMapper.registerModule(objToIdModule); applyModifiers(objToIdMapper, ctx.getService(PluginService.class) - .createInstancesOfType((ObjectMapperModificator.class))); + .createInstancesOfType((ObjectMapperModifier.class))); // register Jackson MixIns to obtain better json output format for some // specific types @@ -184,15 +181,14 @@ public boolean notSerialized(final Class target) { } private void applyModifiers(ObjectMapper mapper, - List modifiers) + List modifiers) { - for (ObjectMapperModificator modifier : modifiers) { + for (ObjectMapperModifier modifier : modifiers) { modifier.accept(mapper); // TODO: Add logic on two modifiers for the same class but with different // exclusions etc. - SERIALIZABLE_BY_MAPPER_MODIFIERS.put(modifier.getSupportedClass(), - modifier.getExcludedClasses()); + objectMapperModifiers.add(modifier); } } From 146d8ac62fc8a041ee537960275bb9e405dc8196 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ko=C5=BEusznik?= Date: Sat, 16 Feb 2019 08:59:48 +0100 Subject: [PATCH 09/15] simplify method applyModifiers --- .../server/services/DefaultJsonService.java | 25 ++++++------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/src/main/java/net/imagej/server/services/DefaultJsonService.java b/src/main/java/net/imagej/server/services/DefaultJsonService.java index c8f626c6..8ec91ab9 100644 --- a/src/main/java/net/imagej/server/services/DefaultJsonService.java +++ b/src/main/java/net/imagej/server/services/DefaultJsonService.java @@ -48,8 +48,6 @@ import java.io.IOException; import java.util.Arrays; import java.util.Collection; -import java.util.LinkedList; -import java.util.List; import net.imagej.server.mixins.Mixins; import net.imagej.server.modifiers.ObjectMapperModifier; @@ -80,8 +78,7 @@ public class DefaultJsonService implements JsonService { */ private final UntypedObjectDeserializer idToObjDeserializer; - private final Collection objectMapperModifiers = - new LinkedList<>(); + private final Collection objectMapperModifiers; /** * Constructs and initializes a JsonService with an {@link ObjectService}. @@ -155,8 +152,10 @@ public JsonSerializer modifySerializer(SerializationConfig config, objToIdMapper = new ObjectMapper(); objToIdMapper.registerModule(objToIdModule); - applyModifiers(objToIdMapper, ctx.getService(PluginService.class) - .createInstancesOfType((ObjectMapperModifier.class))); + objectMapperModifiers = ctx.getService(PluginService.class) + .createInstancesOfType((ObjectMapperModifier.class)); + + applyModifiers(); // register Jackson MixIns to obtain better json output format for some // specific types @@ -180,17 +179,9 @@ public boolean notSerialized(final Class target) { .isAssignableFrom(target)); } - private void applyModifiers(ObjectMapper mapper, - List modifiers) - { - for (ObjectMapperModifier modifier : modifiers) { - modifier.accept(mapper); - - // TODO: Add logic on two modifiers for the same class but with different - // exclusions etc. - objectMapperModifiers.add(modifier); + private void applyModifiers() { + for (ObjectMapperModifier modifier : objectMapperModifiers) { + modifier.accept(objToIdMapper); } - } - } From ef0b48b90a655f1c9af6e8fded528bbbb85429be Mon Sep 17 00:00:00 2001 From: Petr Bainar Date: Sun, 24 Feb 2019 21:15:16 +0100 Subject: [PATCH 10/15] preparingForMergeRequest: reverting two temporary changes --- pom.xml | 12 +----------- src/main/java/net/imagej/server/mixins/Mixins.java | 3 --- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/pom.xml b/pom.xml index d713bcb8..f6fc9d06 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ net.imagej imagej-server - 0.1.3.1-SNAPSHOT + 0.1.3-SNAPSHOT ImageJ Server A simple RESTful web server for ImageJ @@ -182,14 +182,4 @@ Wisconsin-Madison. - - - it4i - https://artifactory.cs.vsb.cz/it4i/ - - - it4i - https://artifactory.cs.vsb.cz/it4i/ - - diff --git a/src/main/java/net/imagej/server/mixins/Mixins.java b/src/main/java/net/imagej/server/mixins/Mixins.java index d9471831..621967d6 100644 --- a/src/main/java/net/imagej/server/mixins/Mixins.java +++ b/src/main/java/net/imagej/server/mixins/Mixins.java @@ -189,7 +189,6 @@ protected static abstract class OutOfBoundsFactoryMixIn implements } public static void registerMixIns(final ObjectMapper mapper) { - mapper.addMixIn(ComplexType.class, ToStringMixIn.class); mapper.addMixIn(RealType.class, RealTypeMixIn.class); mapper.addMixIn(IntegerType.class, IntegerTypeMixIn.class); @@ -197,7 +196,5 @@ public static void registerMixIns(final ObjectMapper mapper) { mapper.addMixIn(ModuleItem.class, ModuleItemMixIn.class); mapper.addMixIn(Type.class, TypeMixIn.class); mapper.addMixIn(OutOfBoundsFactory.class, OutOfBoundsFactoryMixIn.class); - } - } From 2a78e86bbc764e46a72fda83729133735f1cad9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ko=C5=BEusznik?= Date: Wed, 27 Feb 2019 11:02:41 +0100 Subject: [PATCH 11/15] substitute ObjectMapperModifier by SciJavaJsonSerializer --- .../server/json/JsonSerializerAdapter.java | 29 +++++++++++++ .../server/json/SciJavaJsonSerializer.java | 32 +++++++++++++++ .../modifiers/ObjectMapperModifier.java | 41 ------------------- .../server/modifiers/SerializerModifier.java | 30 -------------- .../server/services/DefaultJsonService.java | 22 +++++----- 5 files changed, 72 insertions(+), 82 deletions(-) create mode 100644 src/main/java/net/imagej/server/json/JsonSerializerAdapter.java create mode 100644 src/main/java/net/imagej/server/json/SciJavaJsonSerializer.java delete mode 100644 src/main/java/net/imagej/server/modifiers/ObjectMapperModifier.java delete mode 100644 src/main/java/net/imagej/server/modifiers/SerializerModifier.java diff --git a/src/main/java/net/imagej/server/json/JsonSerializerAdapter.java b/src/main/java/net/imagej/server/json/JsonSerializerAdapter.java new file mode 100644 index 00000000..804599e4 --- /dev/null +++ b/src/main/java/net/imagej/server/json/JsonSerializerAdapter.java @@ -0,0 +1,29 @@ +package net.imagej.server.json; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +import java.io.IOException; + +class JsonSerializerAdapter extends StdSerializer { + + private SciJavaJsonSerializer serializedDelegate; + + public JsonSerializerAdapter( + SciJavaJsonSerializer serializedDelegate) + { + super(serializedDelegate.handleType()); + this.serializedDelegate = serializedDelegate; + } + + + @Override + public void serialize(T value, JsonGenerator gen, + SerializerProvider provider) throws IOException + { + serializedDelegate.serialize(value, gen, provider); + } + + +} \ No newline at end of file diff --git a/src/main/java/net/imagej/server/json/SciJavaJsonSerializer.java b/src/main/java/net/imagej/server/json/SciJavaJsonSerializer.java new file mode 100644 index 00000000..28e413d0 --- /dev/null +++ b/src/main/java/net/imagej/server/json/SciJavaJsonSerializer.java @@ -0,0 +1,32 @@ + +package net.imagej.server.json; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.module.SimpleModule; + +import java.io.IOException; + +import org.scijava.plugin.SciJavaPlugin; + +public interface SciJavaJsonSerializer extends SciJavaPlugin + +{ + + void serialize(T value, JsonGenerator gen, + SerializerProvider serializers) + throws IOException; + + Class handleType(); + + default boolean isSupportedBy(Class desiredClass) { + return handleType().isAssignableFrom(desiredClass); + } + + default public void register(ObjectMapper mapper) { + SimpleModule mod = new SimpleModule(); + mod.addSerializer(new JsonSerializerAdapter<>(this)); + mapper.registerModule(mod); + } +} diff --git a/src/main/java/net/imagej/server/modifiers/ObjectMapperModifier.java b/src/main/java/net/imagej/server/modifiers/ObjectMapperModifier.java deleted file mode 100644 index 7388f9a2..00000000 --- a/src/main/java/net/imagej/server/modifiers/ObjectMapperModifier.java +++ /dev/null @@ -1,41 +0,0 @@ - -package net.imagej.server.modifiers; - -import com.fasterxml.jackson.databind.ObjectMapper; - -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; -import java.util.function.Consumer; - -import org.scijava.plugin.SciJavaPlugin; - -public abstract class ObjectMapperModifier implements SciJavaPlugin, - Consumer -{ - - private Class supportedClass; - private Set> excludedClasses; - - public ObjectMapperModifier(Class supportedClass, - Collection> excludedClasses) - { - super(); - this.supportedClass = supportedClass; - this.excludedClasses = new HashSet<>(excludedClasses); - } - - protected Class getSupportedClass() { - return supportedClass; - } - - protected Set> getExcludedClasses() { - return excludedClasses; - } - - public boolean isSupportedBy(Class desiredClass) { - return getSupportedClass().isAssignableFrom(desiredClass) && - getExcludedClasses().stream().noneMatch(v -> v.isAssignableFrom( - desiredClass)); - } -} diff --git a/src/main/java/net/imagej/server/modifiers/SerializerModifier.java b/src/main/java/net/imagej/server/modifiers/SerializerModifier.java deleted file mode 100644 index c2cc4f4f..00000000 --- a/src/main/java/net/imagej/server/modifiers/SerializerModifier.java +++ /dev/null @@ -1,30 +0,0 @@ - -package net.imagej.server.modifiers; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.module.SimpleModule; -import com.fasterxml.jackson.databind.ser.std.StdSerializer; - -import java.util.Collection; - -public class SerializerModifier extends ObjectMapperModifier { - - private StdSerializer serializer; - - public SerializerModifier(Class supportedClass, - Collection> excludedClasses, StdSerializer serializer) - { - super(supportedClass, excludedClasses); - this.serializer = serializer; - - } - - @SuppressWarnings("unchecked") - @Override - public void accept(ObjectMapper mapper) { - SimpleModule mod = new SimpleModule(); - mod.addSerializer((Class) getSupportedClass(), serializer); - mapper.registerModule(mod); - } - -} diff --git a/src/main/java/net/imagej/server/services/DefaultJsonService.java b/src/main/java/net/imagej/server/services/DefaultJsonService.java index 8ec91ab9..e2c2c466 100644 --- a/src/main/java/net/imagej/server/services/DefaultJsonService.java +++ b/src/main/java/net/imagej/server/services/DefaultJsonService.java @@ -47,10 +47,10 @@ import java.io.IOException; import java.util.Arrays; -import java.util.Collection; +import java.util.List; +import net.imagej.server.json.SciJavaJsonSerializer; import net.imagej.server.mixins.Mixins; -import net.imagej.server.modifiers.ObjectMapperModifier; import net.imglib2.EuclideanSpace; import org.scijava.Context; @@ -78,7 +78,7 @@ public class DefaultJsonService implements JsonService { */ private final UntypedObjectDeserializer idToObjDeserializer; - private final Collection objectMapperModifiers; + private final List jsonSerializers; /** * Constructs and initializes a JsonService with an {@link ObjectService}. @@ -135,7 +135,8 @@ public JsonSerializer modifySerializer(SerializationConfig config, // If the serialized class is supported thanks to a modification to // ObjectMapper, let's do it that way - if (objectMapperModifiers.stream().anyMatch(e -> e.isSupportedBy( + if (jsonSerializers.stream().map(obj -> (SciJavaJsonSerializer) obj) + .anyMatch(e -> e.isSupportedBy( desiredClass))) return serializer; // If the serialized class is unknown (i.e. serialized using the general @@ -152,10 +153,10 @@ public JsonSerializer modifySerializer(SerializationConfig config, objToIdMapper = new ObjectMapper(); objToIdMapper.registerModule(objToIdModule); - objectMapperModifiers = ctx.getService(PluginService.class) - .createInstancesOfType((ObjectMapperModifier.class)); + jsonSerializers = ctx.getService(PluginService.class).createInstancesOfType( + SciJavaJsonSerializer.class); - applyModifiers(); + registerSerializers(); // register Jackson MixIns to obtain better json output format for some // specific types @@ -179,9 +180,8 @@ public boolean notSerialized(final Class target) { .isAssignableFrom(target)); } - private void applyModifiers() { - for (ObjectMapperModifier modifier : objectMapperModifiers) { - modifier.accept(objToIdMapper); - } + private void registerSerializers() { + jsonSerializers.stream().map(obj -> (SciJavaJsonSerializer) obj).forEach( + serializer -> serializer.register(objToIdMapper)); } } From 47afd38625a7356c9a53d6e3945831f0adb7e8a4 Mon Sep 17 00:00:00 2001 From: Petr Bainar Date: Sun, 10 Mar 2019 21:53:31 +0100 Subject: [PATCH 12/15] preparingForMergeRequest: add a test (and an example too) for Serializer Still WIP --- .../server/SciJavaJsonSerializerTest.java | 94 +++++++++++++++++++ .../fixtures/outputs/finalIntervalType.json | 6 ++ 2 files changed, 100 insertions(+) create mode 100644 src/test/java/net/imagej/server/SciJavaJsonSerializerTest.java create mode 100644 src/test/resources/fixtures/outputs/finalIntervalType.json diff --git a/src/test/java/net/imagej/server/SciJavaJsonSerializerTest.java b/src/test/java/net/imagej/server/SciJavaJsonSerializerTest.java new file mode 100644 index 00000000..5a4e9dba --- /dev/null +++ b/src/test/java/net/imagej/server/SciJavaJsonSerializerTest.java @@ -0,0 +1,94 @@ + +package net.imagej.server; + +import static io.dropwizard.testing.FixtureHelpers.fixture; +import static org.junit.Assert.assertEquals; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializerProvider; + +import io.dropwizard.jackson.Jackson; + +import java.io.IOException; +import java.util.LinkedHashMap; +import java.util.Map; + +import net.imagej.Dataset; +import net.imagej.server.json.SciJavaJsonSerializer; +import net.imagej.server.services.DefaultJsonService; +import net.imagej.server.services.DefaultObjectService; +import net.imglib2.FinalInterval; +import net.imglib2.Interval; + +import org.junit.Test; +import org.scijava.Context; +import org.scijava.plugin.Plugin; + +public class SciJavaJsonSerializerTest { + + @Test + public void serializeIntervalUsingSciJavaJsonSerializer() throws Exception { + + final ObjectMapper mapper = Jackson.newObjectMapper(); + final DefaultObjectService objectService = new DefaultObjectService(); + final DefaultJsonService jsonService = new DefaultJsonService(new Context(), + objectService); + final ExampleIntervalJsonSerializer serializer = + new ExampleIntervalJsonSerializer(); + serializer.register(mapper); + jsonService.addDeserializerTo(mapper); + + final Interval testInterval = new FinalInterval(new long[] { 0, 1 }, + new long[] { 8, 9 }); + final LinkedHashMap outputs = new LinkedHashMap<>(); + outputs.put("testInterval", testInterval); + + final String parsed = jsonService.parseObject(outputs); + + final String expected = mapper.writeValueAsString(mapper.readValue(fixture( + "fixtures/outputs/finalIntervalType.json"), Map.class)); + + assertEquals(expected, parsed); + + } + + @Plugin(type = SciJavaJsonSerializer.class) + public static class ExampleIntervalJsonSerializer implements + SciJavaJsonSerializer + { + + @Override + public boolean isSupportedBy(Class desiredClass) { + return SciJavaJsonSerializer.super.isSupportedBy(desiredClass) && + !Dataset.class.isAssignableFrom(desiredClass); + } + + @Override + public void serialize(Interval interval, JsonGenerator gen, + SerializerProvider serializers) throws IOException + { + + gen.writeStartObject(); + gen.writeArrayFieldStart("min"); + for (int i = 0; i < interval.numDimensions(); i++) { + gen.writeNumber(interval.min(i)); + } + gen.writeEndArray(); + gen.writeArrayFieldStart("max"); + for (int i = 0; i < interval.numDimensions(); i++) { + gen.writeNumber(interval.max(i)); + } + gen.writeEndArray(); + gen.writeEndObject(); + + } + + @Override + public Class handleType() { + return Interval.class; + } + + } + +} diff --git a/src/test/resources/fixtures/outputs/finalIntervalType.json b/src/test/resources/fixtures/outputs/finalIntervalType.json new file mode 100644 index 00000000..55594752 --- /dev/null +++ b/src/test/resources/fixtures/outputs/finalIntervalType.json @@ -0,0 +1,6 @@ +{ + "testInterval": { + "min": [0, 1], + "max": [8, 9] + } +} \ No newline at end of file From cfcaec0152a3df010d569903ca66680fb42d91a9 Mon Sep 17 00:00:00 2001 From: Petr Bainar Date: Sun, 10 Mar 2019 22:17:30 +0100 Subject: [PATCH 13/15] preparingForMergeRequest: remove unused code --- src/test/java/net/imagej/server/SciJavaJsonSerializerTest.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/test/java/net/imagej/server/SciJavaJsonSerializerTest.java b/src/test/java/net/imagej/server/SciJavaJsonSerializerTest.java index 5a4e9dba..3d3f7f58 100644 --- a/src/test/java/net/imagej/server/SciJavaJsonSerializerTest.java +++ b/src/test/java/net/imagej/server/SciJavaJsonSerializerTest.java @@ -34,9 +34,6 @@ public void serializeIntervalUsingSciJavaJsonSerializer() throws Exception { final DefaultObjectService objectService = new DefaultObjectService(); final DefaultJsonService jsonService = new DefaultJsonService(new Context(), objectService); - final ExampleIntervalJsonSerializer serializer = - new ExampleIntervalJsonSerializer(); - serializer.register(mapper); jsonService.addDeserializerTo(mapper); final Interval testInterval = new FinalInterval(new long[] { 0, 1 }, From f85de2f07d06cf5e193428c57f8c071774b3849f Mon Sep 17 00:00:00 2001 From: Petr Bainar Date: Sun, 24 Mar 2019 21:58:44 +0100 Subject: [PATCH 14/15] preparingForMergeRequest: address comments --- .../java/net/imagej/server/SciJavaJsonSerializerTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/net/imagej/server/SciJavaJsonSerializerTest.java b/src/test/java/net/imagej/server/SciJavaJsonSerializerTest.java index 3d3f7f58..55e1625a 100644 --- a/src/test/java/net/imagej/server/SciJavaJsonSerializerTest.java +++ b/src/test/java/net/imagej/server/SciJavaJsonSerializerTest.java @@ -11,7 +11,7 @@ import io.dropwizard.jackson.Jackson; import java.io.IOException; -import java.util.LinkedHashMap; +import java.util.HashMap; import java.util.Map; import net.imagej.Dataset; @@ -38,7 +38,7 @@ public void serializeIntervalUsingSciJavaJsonSerializer() throws Exception { final Interval testInterval = new FinalInterval(new long[] { 0, 1 }, new long[] { 8, 9 }); - final LinkedHashMap outputs = new LinkedHashMap<>(); + final Map outputs = new HashMap<>(); outputs.put("testInterval", testInterval); final String parsed = jsonService.parseObject(outputs); From 967f973cf870ce600f630f6fc4ba7327230be6f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ko=C5=BEusznik?= Date: Fri, 29 Mar 2019 20:55:40 +0100 Subject: [PATCH 15/15] allow ExampleIntervalJsonSerializer only for FinalInterval --- .../java/net/imagej/server/SciJavaJsonSerializerTest.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/test/java/net/imagej/server/SciJavaJsonSerializerTest.java b/src/test/java/net/imagej/server/SciJavaJsonSerializerTest.java index 55e1625a..383cd579 100644 --- a/src/test/java/net/imagej/server/SciJavaJsonSerializerTest.java +++ b/src/test/java/net/imagej/server/SciJavaJsonSerializerTest.java @@ -14,7 +14,6 @@ import java.util.HashMap; import java.util.Map; -import net.imagej.Dataset; import net.imagej.server.json.SciJavaJsonSerializer; import net.imagej.server.services.DefaultJsonService; import net.imagej.server.services.DefaultObjectService; @@ -57,8 +56,7 @@ public static class ExampleIntervalJsonSerializer implements @Override public boolean isSupportedBy(Class desiredClass) { - return SciJavaJsonSerializer.super.isSupportedBy(desiredClass) && - !Dataset.class.isAssignableFrom(desiredClass); + return desiredClass.equals(FinalInterval.class); } @Override