diff --git a/nitrite-jackson-mapper/pom.xml b/nitrite-jackson-mapper/pom.xml index dd1c22012..d8d548ee4 100644 --- a/nitrite-jackson-mapper/pom.xml +++ b/nitrite-jackson-mapper/pom.xml @@ -40,7 +40,7 @@ slf4j-api - com.fasterxml.jackson.core + tools.jackson.core jackson-databind @@ -95,11 +95,6 @@ snakeyaml test - - com.fasterxml.jackson.datatype - jackson-datatype-jsr310 - test - diff --git a/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/jackson/JacksonMapper.java b/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/jackson/JacksonMapper.java index bafbadbca..c96dc8d39 100644 --- a/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/jackson/JacksonMapper.java +++ b/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/jackson/JacksonMapper.java @@ -16,31 +16,37 @@ package org.dizitart.no2.mapper.jackson; +import static org.dizitart.no2.common.util.ValidationUtils.notNull; import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.Module; -import com.fasterxml.jackson.databind.*; import org.dizitart.no2.NitriteConfig; import org.dizitart.no2.collection.Document; import org.dizitart.no2.common.mapper.NitriteMapper; -import org.dizitart.no2.mapper.jackson.modules.NitriteIdModule; import org.dizitart.no2.exceptions.ObjectMappingException; import org.dizitart.no2.exceptions.ValidationException; - -import java.io.IOException; -import java.util.*; - -import static org.dizitart.no2.common.util.ValidationUtils.notNull; +import org.dizitart.no2.mapper.jackson.modules.NitriteIdModule; +import tools.jackson.core.json.JsonReadFeature; +import tools.jackson.databind.DatabindException; +import tools.jackson.databind.JacksonModule; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; /** * A {@link org.dizitart.no2.common.mapper.NitriteMapper} implementation that uses Jackson ObjectMapper to * convert objects to and from Nitrite document. - * - * @since 4.0 - * @see org.dizitart.no2.common.mapper.NitriteMapper + * * @author Anindya Chatterjee + * @see org.dizitart.no2.common.mapper.NitriteMapper + * @since 4.0 */ public class JacksonMapper implements NitriteMapper { + private final List modules = new ArrayList<>(); private ObjectMapper objectMapper; /** @@ -50,30 +56,37 @@ public class JacksonMapper implements NitriteMapper { */ protected ObjectMapper getObjectMapper() { if (objectMapper == null) { - objectMapper = new ObjectMapper(); - objectMapper.setVisibility( - objectMapper.getSerializationConfig().getDefaultVisibilityChecker() - .withFieldVisibility(JsonAutoDetect.Visibility.ANY) - .withGetterVisibility(JsonAutoDetect.Visibility.NONE) - .withIsGetterVisibility(JsonAutoDetect.Visibility.NONE)); - objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); - objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); - objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true); - objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - objectMapper.registerModule(new NitriteIdModule()); + objectMapper = JsonMapper.builder() + .changeDefaultVisibility(visibilityChecker -> visibilityChecker + .withFieldVisibility(JsonAutoDetect.Visibility.ANY) + .withGetterVisibility(JsonAutoDetect.Visibility.NONE) + .withIsGetterVisibility(JsonAutoDetect.Visibility.NONE) + ) + .configure(JsonReadFeature.ALLOW_UNQUOTED_PROPERTY_NAMES, true) + .configure(JsonReadFeature.ALLOW_SINGLE_QUOTES, true) + .configure(JsonReadFeature.ALLOW_JAVA_COMMENTS, true) + .addModule(new NitriteIdModule()) + .addModules(modules) + .build(); + modules.clear(); } return objectMapper; } /** * Registers a Jackson module with the object mapper. + * Can only register modules as long as the underlying ObjectMapper is still un-initialized. * * @param module the Jackson module to register + * * @throws ValidationException if the module is null */ - public void registerJacksonModule(Module module) { + public void registerJacksonModule(JacksonModule module) { + if (objectMapper != null) { + throw new IllegalStateException("Can not register modules after object mapper initialization."); + } notNull(module, "module cannot be null"); - getObjectMapper().registerModule(module); + modules.add(module); } /** @@ -86,11 +99,13 @@ public void registerJacksonModule(Module module) { * already a Document, converts it to the target type. If the conversion fails, * throws an ObjectMappingException. * - * @param source the source object to convert - * @param type the target type to convert to + * @param source the source object to convert + * @param type the target type to convert to * @param the type of the source object * @param the type of the target object + * * @return the converted object of the target type + * * @throws ObjectMappingException if the conversion fails */ @Override @@ -101,8 +116,9 @@ public Object tryConvert(Source source, Class type) { try { JsonNode node = getObjectMapper().convertValue(source, JsonNode.class); - if (node == null) + if (node == null) { return null; + } if (node.isValueNode()) { return getNodeValue(node); @@ -115,11 +131,11 @@ public Object tryConvert(Source source, Class type) { } } catch (Exception e) { throw new ObjectMappingException("Failed to convert object of type " - + source.getClass() + " to type " + type, e); + + source.getClass() + " to type " + type, e); } throw new ObjectMappingException("Can't convert object to type " + type - + ", try registering a jackson Module for it."); + + ", try registering a jackson Module for it."); } @Override @@ -130,21 +146,23 @@ public void initialize(NitriteConfig nitriteConfig) { * Converts a Nitrite Document to an object of the specified class type using * Jackson ObjectMapper. * - * @param source the Nitrite Document to be converted - * @param type the class type of the object to be converted to + * @param source the Nitrite Document to be converted + * @param type the class type of the object to be converted to * @param the type of the object to be converted to + * * @return the converted object of the specified class type + * * @throws ObjectMappingException if there is an error in the object mapping - * process + * process */ protected Target convertFromDocument(Document source, Class type) { try { return getObjectMapper().convertValue(source, type); } catch (IllegalArgumentException iae) { - if (iae.getCause() instanceof JsonMappingException) { - JsonMappingException jme = (JsonMappingException) iae.getCause(); - if (jme.getMessage().contains("Cannot construct instance")) { - throw new ObjectMappingException(jme.getMessage()); + if (iae.getCause() instanceof DatabindException) { + DatabindException cause = (DatabindException) iae.getCause(); + if (cause.getMessage().contains("Cannot construct instance")) { + throw new ObjectMappingException(cause.getMessage()); } } throw iae; @@ -155,8 +173,9 @@ protected Target convertFromDocument(Document source, Class typ * Converts the given source object to a Nitrite {@link Document} using * Jackson's {@link ObjectMapper}. * - * @param source the source object to convert + * @param source the source object to convert * @param the type of the source object + * * @return the converted Nitrite {@link Document} */ protected Document convertToDocument(Source source) { @@ -170,7 +189,7 @@ private T getNodeValue(JsonNode node) { case NUMBER: return (T) node.numberValue(); case STRING: - return (T) node.textValue(); + return (T) node.stringValue(); case BOOLEAN: return (T) Boolean.valueOf(node.booleanValue()); default: @@ -180,9 +199,7 @@ private T getNodeValue(JsonNode node) { private Document readDocument(JsonNode node) { Map objectMap = new LinkedHashMap<>(); - Iterator> fields = node.fields(); - while (fields.hasNext()) { - Map.Entry entry = fields.next(); + for (Map.Entry entry : node.properties()) { String name = entry.getKey(); JsonNode value = entry.getValue(); Object object = readObject(value); @@ -193,47 +210,34 @@ private Document readDocument(JsonNode node) { } private Object readObject(JsonNode node) { - if (node == null) - return null; - try { - switch (node.getNodeType()) { - case ARRAY: - return readArray(node); - case BINARY: - return node.binaryValue(); - case BOOLEAN: - return node.booleanValue(); - case MISSING: - case NULL: - return null; - case NUMBER: - return node.numberValue(); - case OBJECT: - case POJO: - return readDocument(node); - case STRING: - return node.textValue(); - } - } catch (IOException e) { + if (node == null) { return null; } - return null; + + switch (node.getNodeType()) { + case ARRAY: + return readArray(node); + case BINARY: + return node.binaryValue(); + case BOOLEAN: + return node.booleanValue(); + case NUMBER: + return node.numberValue(); + case OBJECT: + case POJO: + return readDocument(node); + case STRING: + return node.stringValue(); + default: + return null; + } } - @SuppressWarnings({ "unchecked", "rawtypes" }) - private List readArray(JsonNode array) { + private List readArray(JsonNode array) { if (array.isArray()) { - List list = new ArrayList(); - Iterator iterator = array.elements(); - while (iterator.hasNext()) { - Object element = iterator.next(); - if (element instanceof JsonNode) { - list.add(readObject((JsonNode) element)); - } else { - list.add(element); - } - } - return list; + return array.valueStream() + .map(this::readObject) + .collect(Collectors.toList()); } return null; } diff --git a/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/jackson/JacksonMapperModule.java b/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/jackson/JacksonMapperModule.java index 0759dfd9e..6f3f72d6b 100644 --- a/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/jackson/JacksonMapperModule.java +++ b/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/jackson/JacksonMapperModule.java @@ -16,14 +16,13 @@ package org.dizitart.no2.mapper.jackson; -import com.fasterxml.jackson.databind.Module; +import static org.dizitart.no2.common.util.Iterables.setOf; import org.dizitart.no2.common.module.NitriteModule; import org.dizitart.no2.common.module.NitritePlugin; +import tools.jackson.databind.JacksonModule; import java.util.Set; -import static org.dizitart.no2.common.util.Iterables.setOf; - /** * A Nitrite module that provides a jackson based {@link org.dizitart.no2.common.mapper.NitriteMapper} * implementation for object to document conversion. @@ -49,9 +48,9 @@ public JacksonMapperModule() { * * @param jacksonModules the jackson modules */ - public JacksonMapperModule(Module... jacksonModules) { + public JacksonMapperModule(JacksonModule... jacksonModules) { jacksonMapper = new JacksonMapper(); - for (Module jacksonModule : jacksonModules) { + for (JacksonModule jacksonModule : jacksonModules) { jacksonMapper.registerJacksonModule(jacksonModule); } } diff --git a/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/jackson/modules/NitriteIdDeserializer.java b/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/jackson/modules/NitriteIdDeserializer.java index 647409a1b..9e850ce99 100644 --- a/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/jackson/modules/NitriteIdDeserializer.java +++ b/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/jackson/modules/NitriteIdDeserializer.java @@ -16,12 +16,10 @@ package org.dizitart.no2.mapper.jackson.modules; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer; import org.dizitart.no2.collection.NitriteId; - -import java.io.IOException; +import tools.jackson.core.JsonParser; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.deser.std.StdScalarDeserializer; /** * @since 4.0 @@ -34,7 +32,7 @@ class NitriteIdDeserializer extends StdScalarDeserializer { } @Override - public NitriteId deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + public NitriteId deserialize(JsonParser p, DeserializationContext ctxt) { return NitriteId.createId(p.getValueAsString()); } } diff --git a/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/jackson/modules/NitriteIdModule.java b/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/jackson/modules/NitriteIdModule.java index ed05554bb..1ff9baddd 100644 --- a/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/jackson/modules/NitriteIdModule.java +++ b/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/jackson/modules/NitriteIdModule.java @@ -16,8 +16,8 @@ package org.dizitart.no2.mapper.jackson.modules; -import com.fasterxml.jackson.databind.module.SimpleModule; import org.dizitart.no2.collection.NitriteId; +import tools.jackson.databind.module.SimpleModule; /** * Class that registers capability of serializing {@link NitriteId} with the Jackson core. diff --git a/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/jackson/modules/NitriteIdSerializer.java b/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/jackson/modules/NitriteIdSerializer.java index ce7571158..990812001 100644 --- a/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/jackson/modules/NitriteIdSerializer.java +++ b/nitrite-jackson-mapper/src/main/java/org/dizitart/no2/mapper/jackson/modules/NitriteIdSerializer.java @@ -16,16 +16,14 @@ package org.dizitart.no2.mapper.jackson.modules; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer; import org.dizitart.no2.collection.NitriteId; - -import java.io.IOException; +import tools.jackson.core.JsonGenerator; +import tools.jackson.databind.SerializationContext; +import tools.jackson.databind.ser.std.StdScalarSerializer; /** - * @since 4.0 * @author Anindya Chatterjee + * @since 4.0 */ class NitriteIdSerializer extends StdScalarSerializer { @@ -34,7 +32,7 @@ protected NitriteIdSerializer() { } @Override - public void serialize(NitriteId value, JsonGenerator gen, SerializerProvider provider) throws IOException { + public void serialize(NitriteId value, JsonGenerator gen, SerializationContext context) { gen.writeString(Long.toString(value.getIdValue())); } } diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/mapper/jackson/JacksonMapperTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/mapper/jackson/JacksonMapperTest.java index 9dd3ceb0c..2f29c33c5 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/mapper/jackson/JacksonMapperTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/mapper/jackson/JacksonMapperTest.java @@ -17,19 +17,20 @@ package org.dizitart.no2.mapper.jackson; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.BinaryNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThrows; import org.dizitart.no2.NitriteConfig; import org.dizitart.no2.exceptions.ObjectMappingException; import org.junit.Test; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.BinaryNode; +import tools.jackson.databind.node.JsonNodeFactory; -import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; -import static org.junit.Assert.*; - public class JacksonMapperTest { @Test public void testGetObjectMapper() { @@ -41,8 +42,6 @@ public void testGetObjectMapper() { public void testConvert() { JacksonMapper jacksonMapper = new JacksonMapper(); assertEquals("Source", jacksonMapper.tryConvert("Source", Object.class)); - assertTrue(jacksonMapper.getObjectMapper() - .getSerializerProviderInstance() instanceof com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.Impl); } @Test @@ -55,19 +54,17 @@ public void testConvert3() { public void testConvert4() { JacksonMapper jacksonMapper = new JacksonMapper(); assertEquals(0, ((Integer) jacksonMapper.tryConvert(0, Object.class)).intValue()); - assertTrue(jacksonMapper.getObjectMapper() - .getSerializerProviderInstance() instanceof com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.Impl); } @Test public void testConvert5() { JacksonMapper jacksonMapper = new JacksonMapper(); - ArrayNode source = new ArrayNode(new JsonNodeFactory(true)); + ArrayNode source = new ArrayNode(new JsonNodeFactory()); assertThrows(ObjectMappingException.class, () -> jacksonMapper.tryConvert(source, Object.class)); } @Test - public void testConvert6() throws UnsupportedEncodingException { + public void testConvert6() { JacksonMapper jacksonMapper = new JacksonMapper(); BinaryNode source = new BinaryNode("AAAAAAAAAAAAAAAAAAAAAAAA".getBytes(StandardCharsets.UTF_8)); assertNull(jacksonMapper.tryConvert(source, Object.class)); @@ -91,8 +88,6 @@ public void testConvertFromDocument() { public void testConvertToDocument() { JacksonMapper jacksonMapper = new JacksonMapper(); jacksonMapper.convertToDocument("Source"); - assertTrue(jacksonMapper.getObjectMapper() - .getSerializerProviderInstance() instanceof com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.Impl); } } diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/mapper/jackson/integration/repository/JacksonModuleTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/mapper/jackson/integration/repository/JacksonModuleTest.java index aa8011968..ac10c321e 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/mapper/jackson/integration/repository/JacksonModuleTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/mapper/jackson/integration/repository/JacksonModuleTest.java @@ -1,11 +1,12 @@ package org.dizitart.no2.mapper.jackson.integration.repository; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import static org.dizitart.no2.mapper.jackson.integration.repository.BaseObjectRepositoryTest.getRandomTempDbFile; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import lombok.Data; import org.dizitart.no2.Nitrite; import org.dizitart.no2.NitriteBuilder; import org.dizitart.no2.mapper.jackson.JacksonMapperModule; -import org.dizitart.no2.exceptions.ObjectMappingException; import org.dizitart.no2.mvstore.MVStoreModule; import org.dizitart.no2.repository.ObjectRepository; import org.junit.After; @@ -15,10 +16,6 @@ import java.time.LocalDateTime; import java.util.UUID; -import static org.dizitart.no2.mapper.jackson.integration.repository.BaseObjectRepositoryTest.getRandomTempDbFile; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - /** * @author Anindya Chatterjee */ @@ -34,34 +31,6 @@ public void cleanUp() { TestUtil.deleteDb(fileName); } - @Test(expected = ObjectMappingException.class) - public void testJavaTime() { - MVStoreModule storeModule = MVStoreModule.withConfig() - .filePath(fileName) - .build(); - - NitriteBuilder nitriteBuilder = Nitrite.builder() - .loadModule(new JacksonMapperModule()) - .fieldSeparator(".") - .loadModule(storeModule); - - db = nitriteBuilder.openOrCreate(); - - ObjectRepository repository = db.getRepository(TestData.class); - for (int i = 0; i < 10; i++) { - TestData testData = new TestData(); - testData.setId(UUID.randomUUID().toString()); - testData.setLocalDateTime(LocalDateTime.now()); - testData.setDuration(Duration.ofDays(i)); - repository.insert(testData); - } - - assertEquals(repository.find().size(), 10); - for (TestData testData : repository.find()) { - assertNotNull(testData.localDateTime); - } - } - @Test public void testJavaTimeModule() { MVStoreModule storeModule = MVStoreModule.withConfig() @@ -69,7 +38,7 @@ public void testJavaTimeModule() { .build(); NitriteBuilder nitriteBuilder = Nitrite.builder() - .loadModule(new JacksonMapperModule(new JavaTimeModule())) + .loadModule(new JacksonMapperModule()) .fieldSeparator(".") .loadModule(storeModule); @@ -84,7 +53,7 @@ public void testJavaTimeModule() { repository.insert(testData); } - assertEquals(repository.find().size(), 10); + assertEquals(10, repository.find().size()); for (TestData testData : repository.find()) { assertNotNull(testData.localDateTime); } diff --git a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/mapper/jackson/modules/NitriteIdDeserializerTest.java b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/mapper/jackson/modules/NitriteIdDeserializerTest.java index 70000b87a..e40114c7a 100644 --- a/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/mapper/jackson/modules/NitriteIdDeserializerTest.java +++ b/nitrite-jackson-mapper/src/test/java/org/dizitart/no2/mapper/jackson/modules/NitriteIdDeserializerTest.java @@ -17,11 +17,10 @@ package org.dizitart.no2.mapper.jackson.modules; -import org.dizitart.no2.collection.NitriteId; -import org.junit.Test; - import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; +import org.dizitart.no2.collection.NitriteId; +import org.junit.Test; public class NitriteIdDeserializerTest { @Test @@ -29,7 +28,7 @@ public void testConstructor() { NitriteIdDeserializer actualNitriteIdDeserializer = new NitriteIdDeserializer(); assertNull(actualNitriteIdDeserializer.getValueType()); Class expectedValueClass = NitriteId.class; - assertSame(expectedValueClass, actualNitriteIdDeserializer.getValueClass()); + assertSame(expectedValueClass, actualNitriteIdDeserializer.handledType()); } } diff --git a/nitrite-mvstore-adapter/pom.xml b/nitrite-mvstore-adapter/pom.xml index 5c7b33b36..0fc424644 100644 --- a/nitrite-mvstore-adapter/pom.xml +++ b/nitrite-mvstore-adapter/pom.xml @@ -100,7 +100,7 @@ test - com.fasterxml.jackson.core + tools.jackson.core jackson-databind test diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/TestUtil.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/TestUtil.java index 0da8214de..a6e79d8bf 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/TestUtil.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/TestUtil.java @@ -17,25 +17,31 @@ package org.dizitart.no2.integration; +import static org.junit.Assert.assertTrue; import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; import org.dizitart.no2.common.mapper.EntityConverter; import org.dizitart.no2.exceptions.ObjectMappingException; import org.dizitart.no2.mvstore.MVStoreModule; +import tools.jackson.core.exc.JacksonIOException; +import tools.jackson.core.json.JsonReadFeature; +import tools.jackson.databind.DeserializationFeature; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; import java.io.File; -import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; -import java.util.*; - -import static org.junit.Assert.assertTrue; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.stream.Collectors; /** * @author Anindya Chatterjee @@ -145,7 +151,7 @@ public static Document parse(String json) { ObjectMapper objectMapper = createObjectMapper(); JsonNode node = objectMapper.readValue(json, JsonNode.class); return loadDocument(node); - } catch (IOException e) { + } catch (JacksonIOException e) { log.error("Error while parsing json", e); throw new ObjectMappingException("failed to parse json " + json); } @@ -153,9 +159,7 @@ public static Document parse(String json) { private static Document loadDocument(JsonNode node) { Map objectMap = new LinkedHashMap<>(); - Iterator> fields = node.fields(); - while (fields.hasNext()) { - Map.Entry entry = fields.next(); + for (Map.Entry entry : node.properties()) { String name = entry.getKey(); JsonNode value = entry.getValue(); Object object = loadObject(value); @@ -166,64 +170,52 @@ private static Document loadDocument(JsonNode node) { } private static Object loadObject(JsonNode node) { - if (node == null) - return null; - try { - switch (node.getNodeType()) { - case ARRAY: - return loadArray(node); - case BINARY: - return node.binaryValue(); - case BOOLEAN: - return node.booleanValue(); - case MISSING: - case NULL: - return null; - case NUMBER: - return node.numberValue(); - case OBJECT: - case POJO: - return loadDocument(node); - case STRING: - return node.textValue(); - } - } catch (IOException e) { + if (node == null) { return null; } - return null; + + switch (node.getNodeType()) { + case ARRAY: + return loadArray(node); + case BINARY: + return node.binaryValue(); + case BOOLEAN: + return node.booleanValue(); + case MISSING: + case NUMBER: + return node.numberValue(); + case OBJECT: + case POJO: + return loadDocument(node); + case STRING: + return node.stringValue(); + default: + return null; + } } - @SuppressWarnings({"unchecked", "rawtypes"}) - private static List loadArray(JsonNode array) { + private static List loadArray(JsonNode array) { if (array.isArray()) { - List list = new ArrayList(); - Iterator iterator = array.elements(); - while (iterator.hasNext()) { - Object element = iterator.next(); - if (element instanceof JsonNode) { - list.add(loadObject((JsonNode) element)); - } else { - list.add(element); - } - } - return list; + return array.valueStream() + .map(TestUtil::loadObject) + .collect(Collectors.toList()); } return null; } private static ObjectMapper createObjectMapper() { - ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.setVisibility( - objectMapper.getSerializationConfig().getDefaultVisibilityChecker() + return JsonMapper.builder() + .changeDefaultVisibility(visibilityChecker -> visibilityChecker .withFieldVisibility(JsonAutoDetect.Visibility.ANY) .withGetterVisibility(JsonAutoDetect.Visibility.NONE) - .withIsGetterVisibility(JsonAutoDetect.Visibility.NONE)); - objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); - objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); - objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true); - objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - - objectMapper.findAndRegisterModules(); - return objectMapper; + .withIsGetterVisibility(JsonAutoDetect.Visibility.NONE) + ) + .configure(JsonReadFeature.ALLOW_UNQUOTED_PROPERTY_NAMES, true) + .configure(JsonReadFeature.ALLOW_SINGLE_QUOTES, true) + .configure(JsonReadFeature.ALLOW_JAVA_COMMENTS, true) + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .configure(DeserializationFeature.FAIL_ON_TRAILING_TOKENS, false) + .findAndAddModules() + .build(); } } diff --git a/nitrite-rocksdb-adapter/pom.xml b/nitrite-rocksdb-adapter/pom.xml index 2e47a127d..760a7ee30 100644 --- a/nitrite-rocksdb-adapter/pom.xml +++ b/nitrite-rocksdb-adapter/pom.xml @@ -104,7 +104,7 @@ test - com.fasterxml.jackson.core + tools.jackson.core jackson-databind test diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/TestUtil.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/TestUtil.java index e51892291..ebc001ba5 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/TestUtil.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/TestUtil.java @@ -17,23 +17,28 @@ package org.dizitart.no2.integration; +import static org.junit.Assert.assertTrue; import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FileUtils; import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; import org.dizitart.no2.exceptions.ObjectMappingException; import org.dizitart.no2.rocksdb.RocksDBModule; +import tools.jackson.core.exc.JacksonIOException; +import tools.jackson.core.json.JsonReadFeature; +import tools.jackson.databind.DeserializationFeature; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; import java.io.File; -import java.io.IOException; -import java.util.*; - -import static org.junit.Assert.assertTrue; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.stream.Collectors; /** * @author Anindya Chatterjee @@ -124,7 +129,7 @@ public static Document parse(String json) { ObjectMapper objectMapper = createObjectMapper(); JsonNode node = objectMapper.readValue(json, JsonNode.class); return loadDocument(node); - } catch (IOException e) { + } catch (JacksonIOException e) { log.error("Error while parsing json", e); throw new ObjectMappingException("Failed to parse json " + json); } @@ -132,9 +137,7 @@ public static Document parse(String json) { private static Document loadDocument(JsonNode node) { Map objectMap = new LinkedHashMap<>(); - Iterator> fields = node.fields(); - while (fields.hasNext()) { - Map.Entry entry = fields.next(); + for (Map.Entry entry : node.properties()) { String name = entry.getKey(); JsonNode value = entry.getValue(); Object object = loadObject(value); @@ -145,64 +148,52 @@ private static Document loadDocument(JsonNode node) { } private static Object loadObject(JsonNode node) { - if (node == null) - return null; - try { - switch (node.getNodeType()) { - case ARRAY: - return loadArray(node); - case BINARY: - return node.binaryValue(); - case BOOLEAN: - return node.booleanValue(); - case MISSING: - case NULL: - return null; - case NUMBER: - return node.numberValue(); - case OBJECT: - case POJO: - return loadDocument(node); - case STRING: - return node.textValue(); - } - } catch (IOException e) { + if (node == null) { return null; } - return null; + + switch (node.getNodeType()) { + case ARRAY: + return loadArray(node); + case BINARY: + return node.binaryValue(); + case BOOLEAN: + return node.booleanValue(); + case MISSING: + case NUMBER: + return node.numberValue(); + case OBJECT: + case POJO: + return loadDocument(node); + case STRING: + return node.stringValue(); + default: + return null; + } } - @SuppressWarnings({"unchecked", "rawtypes"}) - private static List loadArray(JsonNode array) { + private static List loadArray(JsonNode array) { if (array.isArray()) { - List list = new ArrayList(); - Iterator iterator = array.elements(); - while (iterator.hasNext()) { - Object element = iterator.next(); - if (element instanceof JsonNode) { - list.add(loadObject((JsonNode) element)); - } else { - list.add(element); - } - } - return list; + return array.valueStream() + .map(TestUtil::loadObject) + .collect(Collectors.toList()); } return null; } - private static ObjectMapper createObjectMapper() { - ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.setVisibility( - objectMapper.getSerializationConfig().getDefaultVisibilityChecker() +private static ObjectMapper createObjectMapper() { + return JsonMapper.builder() + .changeDefaultVisibility(visibilityChecker -> visibilityChecker .withFieldVisibility(JsonAutoDetect.Visibility.ANY) .withGetterVisibility(JsonAutoDetect.Visibility.NONE) - .withIsGetterVisibility(JsonAutoDetect.Visibility.NONE)); - objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); - objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); - objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true); - objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - - objectMapper.findAndRegisterModules(); - return objectMapper; + .withIsGetterVisibility(JsonAutoDetect.Visibility.NONE) + ) + .configure(JsonReadFeature.ALLOW_UNQUOTED_PROPERTY_NAMES, true) + .configure(JsonReadFeature.ALLOW_SINGLE_QUOTES, true) + .configure(JsonReadFeature.ALLOW_JAVA_COMMENTS, true) + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .configure(DeserializationFeature.FAIL_ON_TRAILING_TOKENS, false) + .findAndAddModules() + .build(); } } diff --git a/nitrite-spatial/pom.xml b/nitrite-spatial/pom.xml index 346d8da7c..169c8554d 100644 --- a/nitrite-spatial/pom.xml +++ b/nitrite-spatial/pom.xml @@ -49,7 +49,7 @@ provided - com.fasterxml.jackson.core + tools.jackson.core jackson-databind diff --git a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/jackson/GeometryDeserializer.java b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/jackson/GeometryDeserializer.java index 7fdbdf12d..949224de8 100644 --- a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/jackson/GeometryDeserializer.java +++ b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/jackson/GeometryDeserializer.java @@ -16,13 +16,11 @@ package org.dizitart.no2.spatial.jackson; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer; import org.dizitart.no2.spatial.GeometryUtils; import org.locationtech.jts.geom.Geometry; - -import java.io.IOException; +import tools.jackson.core.JsonParser; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.deser.std.StdScalarDeserializer; /** * @since 4.0 @@ -35,7 +33,7 @@ protected GeometryDeserializer() { } @Override - public Geometry deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + public Geometry deserialize(JsonParser p, DeserializationContext ctxt) { String value = p.getValueAsString(); return GeometryUtils.fromString(value); } diff --git a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/jackson/GeometryModule.java b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/jackson/GeometryModule.java index c90fd3e54..15e5d41e3 100644 --- a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/jackson/GeometryModule.java +++ b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/jackson/GeometryModule.java @@ -16,7 +16,7 @@ package org.dizitart.no2.spatial.jackson; -import com.fasterxml.jackson.databind.module.SimpleModule; +import tools.jackson.databind.module.SimpleModule; import org.locationtech.jts.geom.Geometry; /** diff --git a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/jackson/GeometrySerializer.java b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/jackson/GeometrySerializer.java index 81ebc7717..2c26e40d6 100644 --- a/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/jackson/GeometrySerializer.java +++ b/nitrite-spatial/src/main/java/org/dizitart/no2/spatial/jackson/GeometrySerializer.java @@ -16,13 +16,11 @@ package org.dizitart.no2.spatial.jackson; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer; import org.dizitart.no2.spatial.GeometryUtils; import org.locationtech.jts.geom.Geometry; - -import java.io.IOException; +import tools.jackson.core.JsonGenerator; +import tools.jackson.databind.SerializationContext; +import tools.jackson.databind.ser.std.StdScalarSerializer; /** * @since 4.0 @@ -35,7 +33,7 @@ protected GeometrySerializer() { } @Override - public void serialize(Geometry value, JsonGenerator gen, SerializerProvider provider) throws IOException { + public void serialize(Geometry value, JsonGenerator gen, SerializationContext context) { if (value != null) { gen.writeString(GeometryUtils.toString(value)); } diff --git a/nitrite-support/pom.xml b/nitrite-support/pom.xml index b145b1797..347b407ae 100644 --- a/nitrite-support/pom.xml +++ b/nitrite-support/pom.xml @@ -41,7 +41,7 @@ ${project.version} - com.fasterxml.jackson.core + tools.jackson.core jackson-databind diff --git a/nitrite-support/src/main/java/org/dizitart/no2/support/exchange/ExportOptions.java b/nitrite-support/src/main/java/org/dizitart/no2/support/exchange/ExportOptions.java index ede9cab64..d6d867a5e 100644 --- a/nitrite-support/src/main/java/org/dizitart/no2/support/exchange/ExportOptions.java +++ b/nitrite-support/src/main/java/org/dizitart/no2/support/exchange/ExportOptions.java @@ -16,15 +16,17 @@ package org.dizitart.no2.support.exchange; -import com.fasterxml.jackson.core.JsonFactory; import lombok.Getter; import lombok.Setter; +import tools.jackson.databind.json.JsonMapper; -import java.util.*; +import java.util.List; +import java.util.Map; +import java.util.Set; /** * The options used for exporting Nitrite database collections and data. - * + * * @author Anindya Chatterjee * @see Exporter * @since 1.0 @@ -41,28 +43,22 @@ public class ExportOptions { * {@link org.dizitart.no2.Nitrite}, so the database must not be open elsewhere. * Upon completion of the export operation, the {@link org.dizitart.no2.Nitrite} * instance will be closed. - * + * *

* NOTE: This is a mandatory field. If not specified, the export operation will * fail. - * - * @param nitriteFactory the nitriteFactory. - * @return the nitriteFactory. */ private NitriteFactory nitriteFactory; /** - * Specifies a {@link JsonFactory} to create a - * {@link com.fasterxml.jackson.core.JsonGenerator} instance. + * Specifies a {@link JsonMapper} to create a + * {@link tools.jackson.core.JsonGenerator} instance. * This instance will be used to write the export data to a file. *

* NOTE: This is an optional field. If not specified, a default one will be * created. - * - * @param jsonFactory the jsonFactory. - * @return the jsonFactory. */ - private JsonFactory jsonFactory; + private JsonMapper jsonMapper; /** * Indicates if the export operation exports indices information. @@ -73,11 +69,6 @@ public class ExportOptions { *

* This is an optional field. If not specified, it will be set to * true. - * - * @param exportIndices a value indicating if indices information will be - * exported. - * @return true if indices information is exported; otherwise, - * false. */ private boolean exportIndices = true; @@ -89,10 +80,6 @@ public class ExportOptions { *

* This is an optional field. If not specified, it will be set to * true. - * - * @param exportData a value indicating if collection data will be exported. - * @return true if collection data is exported; otherwise, - * false. */ private boolean exportData = true; @@ -108,9 +95,6 @@ public class ExportOptions { *

  • If a non-empty list is specified, only the collections in the list will * be exported
  • * - * - * @param collections list of all collection names to be exported. - * @return list of collection names. */ private List collections; @@ -125,9 +109,6 @@ public class ExportOptions { *
  • If a non-empty list is specified, only the repositories in the list will * be exported
  • * - * - * @param repositories list of all repositories names to be exported. - * @return list of repositories names. */ private List repositories; @@ -143,9 +124,6 @@ public class ExportOptions { *
  • If a non-empty map is specified, only the keyed-repositories in the map * will be exported
  • * - * - * @param keyedRepositories list of all keyed repositories names to be exported. - * @return list of keyed repositories names. */ private Map> keyedRepositories; } diff --git a/nitrite-support/src/main/java/org/dizitart/no2/support/exchange/Exporter.java b/nitrite-support/src/main/java/org/dizitart/no2/support/exchange/Exporter.java index 12ca97db3..52b2d7cec 100644 --- a/nitrite-support/src/main/java/org/dizitart/no2/support/exchange/Exporter.java +++ b/nitrite-support/src/main/java/org/dizitart/no2/support/exchange/Exporter.java @@ -16,24 +16,26 @@ package org.dizitart.no2.support.exchange; -import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.dizitart.no2.exceptions.NitriteIOException; - -import java.io.*; - import static org.dizitart.no2.common.util.ValidationUtils.notNull; +import org.dizitart.no2.exceptions.NitriteIOException; +import tools.jackson.core.JsonGenerator; +import tools.jackson.core.exc.JacksonIOException; +import tools.jackson.core.json.JsonReadFeature; +import tools.jackson.databind.json.JsonMapper; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; /** * The Exporter class provides methods to export Nitrite database data to a file * or an output stream in JSON format. *

    * It uses the provided ExportOptions to configure the export process. - * + * * @author Anindya Chatterjee * @since 1.0 */ @@ -47,7 +49,7 @@ private Exporter() { * Creates an Exporter instance with the specified export options. * * @param exportOptions the export options to be set - * (must not be null and must have a valid nitrite factory) + * (must not be null and must have a valid nitrite factory) * * @return the Exporter instance with the specified export options */ @@ -56,8 +58,8 @@ public static Exporter withOptions(ExportOptions exportOptions) { notNull(exportOptions, "exportOptions cannot be null"); notNull(exportOptions.getNitriteFactory(), "nitriteFactory cannot be null"); - if (exportOptions.getJsonFactory() == null) { - exportOptions.setJsonFactory(createObjectMapper().getFactory()); + if (exportOptions.getJsonMapper() == null) { + exportOptions.setJsonMapper(createJsonMapper()); } exporter.options = exportOptions; @@ -65,22 +67,16 @@ public static Exporter withOptions(ExportOptions exportOptions) { } /** - * Creates and returns an instance of ObjectMapper with custom configurations. + * Creates and returns an instance of JsonMapper with custom configurations. * - * @return an instance of ObjectMapper with custom configurations. + * @return an instance of JsonMapper with custom configurations. */ - public static ObjectMapper createObjectMapper() { - ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); - objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); - objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true); - objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - objectMapper.setVisibility( - objectMapper.getSerializationConfig().getDefaultVisibilityChecker() - .withFieldVisibility(JsonAutoDetect.Visibility.ANY) - .withGetterVisibility(JsonAutoDetect.Visibility.NONE) - .withIsGetterVisibility(JsonAutoDetect.Visibility.NONE)); - return objectMapper; + public static JsonMapper createJsonMapper() { + return JsonMapper.builder() + .configure(JsonReadFeature.ALLOW_UNQUOTED_PROPERTY_NAMES, true) + .configure(JsonReadFeature.ALLOW_SINGLE_QUOTES, true) + .configure(JsonReadFeature.ALLOW_JAVA_COMMENTS, true) + .build(); } /** @@ -96,6 +92,7 @@ public void exportTo(String file) { * Exports the content to the specified file. * * @param file the file to export the content to + * * @throws NitriteIOException if there is an I/O error while writing content to the file */ public void exportTo(File file) { @@ -124,6 +121,7 @@ public void exportTo(File file) { * Exports the data to the specified output stream. * * @param stream the output stream to export the data to + * * @throws IOException if an I/O error occurs */ public void exportTo(OutputStream stream) throws IOException { @@ -136,15 +134,17 @@ public void exportTo(OutputStream stream) throws IOException { * Exports the data to the specified writer using JSON format. * * @param writer the writer to export the data to + * * @throws NitriteIOException if there is an I/O error while writing data with writer * @throws NitriteIOException if there is an error while exporting data */ public void exportTo(Writer writer) { JsonGenerator generator; try { - generator = options.getJsonFactory().createGenerator(writer); - generator.setPrettyPrinter(new DefaultPrettyPrinter()); - } catch (IOException ioe) { + generator = options.getJsonMapper() + .writerWithDefaultPrettyPrinter() + .createGenerator(writer); + } catch (JacksonIOException ioe) { throw new NitriteIOException("I/O error while writing data with writer", ioe); } diff --git a/nitrite-support/src/main/java/org/dizitart/no2/support/exchange/ImportOptions.java b/nitrite-support/src/main/java/org/dizitart/no2/support/exchange/ImportOptions.java index 8e1a9a2a4..c22413b9b 100644 --- a/nitrite-support/src/main/java/org/dizitart/no2/support/exchange/ImportOptions.java +++ b/nitrite-support/src/main/java/org/dizitart/no2/support/exchange/ImportOptions.java @@ -1,12 +1,12 @@ package org.dizitart.no2.support.exchange; -import com.fasterxml.jackson.core.JsonFactory; import lombok.Getter; import lombok.Setter; +import tools.jackson.databind.json.JsonMapper; /** * The options for importing collections and data into a Nitrite database. - * + * * @author Anindya Chatterjee * @see Importer * @since 4.0 @@ -23,25 +23,19 @@ public class ImportOptions { * {@link org.dizitart.no2.Nitrite}, so the database must not be open elsewhere. * Upon completion of the import operation, the {@link org.dizitart.no2.Nitrite} * instance will be closed. - * + * *

    * NOTE: This is a mandatory field. If not specified, the import operation will * fail. - * - * @param nitriteFactory the nitriteFactory. - * @return the nitriteFactory. */ private NitriteFactory nitriteFactory; /** - * Specifies a {@link JsonFactory} to create a - * {@link com.fasterxml.jackson.core.JsonParser} instance. + * Specifies a {@link JsonMapper} to create a + * {@link tools.jackson.core.JsonParser} instance. * This instance will be used to read the exported data from a file. *

    * This is an optional field. If not specified, a default one will be created. - * - * @param jsonFactory the jsonFactory. - * @return the jsonFactory. */ - private JsonFactory jsonFactory; + private JsonMapper jsonMapper; } diff --git a/nitrite-support/src/main/java/org/dizitart/no2/support/exchange/Importer.java b/nitrite-support/src/main/java/org/dizitart/no2/support/exchange/Importer.java index d2bd2ff11..21cc37945 100644 --- a/nitrite-support/src/main/java/org/dizitart/no2/support/exchange/Importer.java +++ b/nitrite-support/src/main/java/org/dizitart/no2/support/exchange/Importer.java @@ -16,21 +16,26 @@ package org.dizitart.no2.support.exchange; -import com.fasterxml.jackson.core.JsonParser; +import static org.dizitart.no2.common.util.ValidationUtils.notNull; +import static org.dizitart.no2.support.exchange.Exporter.createJsonMapper; import org.dizitart.no2.exceptions.NitriteIOException; import org.dizitart.no2.exceptions.ValidationException; +import tools.jackson.core.JsonParser; +import tools.jackson.core.exc.JacksonIOException; -import java.io.*; - -import static org.dizitart.no2.common.util.ValidationUtils.notNull; -import static org.dizitart.no2.support.exchange.Exporter.createObjectMapper; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; /** * The Importer class provides methods to import data from a file or stream into * Nitrite database. *

    * It uses the provided ImportOptions to configure the import process. - * + * * @author Anindya Chatterjee * @since 1.0 */ @@ -44,7 +49,9 @@ private Importer() { * Creates a new instance of {@link Importer} with the specified import options. * * @param importOptions the import options to use + * * @return a new instance of {@link Importer} with the specified import options + * * @throws ValidationException if the import options or nitrite factory is null */ public static Importer withOptions(ImportOptions importOptions) { @@ -52,8 +59,8 @@ public static Importer withOptions(ImportOptions importOptions) { notNull(importOptions, "importOptions cannot be null"); notNull(importOptions.getNitriteFactory(), "nitriteFactory cannot be null"); - if (importOptions.getJsonFactory() == null) { - importOptions.setJsonFactory(createObjectMapper().getFactory()); + if (importOptions.getJsonMapper() == null) { + importOptions.setJsonMapper(createJsonMapper()); } importer.options = importOptions; @@ -73,6 +80,7 @@ public void importFrom(String file) { * Imports data from a file. * * @param file the file to import data from + * * @throws NitriteIOException if there is an I/O error while reading content from the file */ public void importFrom(File file) { @@ -87,6 +95,7 @@ public void importFrom(File file) { * Imports data from the specified input stream. * * @param stream the input stream to import data from + * * @throws IOException if an I/O error occurs */ public void importFrom(InputStream stream) throws IOException { @@ -99,13 +108,14 @@ public void importFrom(InputStream stream) throws IOException { * Imports data from a Reader object using a JSON parser. * * @param reader the Reader object to import data from + * * @throws NitriteIOException if there is an I/O error while creating the parser from the reader or while importing data */ public void importFrom(Reader reader) { JsonParser parser; try { - parser = options.getJsonFactory().createParser(reader); - } catch (IOException ioe) { + parser = options.getJsonMapper().createParser(reader); + } catch (JacksonIOException ioe) { throw new NitriteIOException("I/O error while creating parser from reader", ioe); } @@ -115,7 +125,7 @@ public void importFrom(Reader reader) { jsonImporter.setOptions(options); try { jsonImporter.importData(); - } catch (IOException | ClassNotFoundException e) { + } catch (JacksonIOException | ClassNotFoundException e) { throw new NitriteIOException("Error while importing data", e); } } diff --git a/nitrite-support/src/main/java/org/dizitart/no2/support/exchange/NitriteJsonExporter.java b/nitrite-support/src/main/java/org/dizitart/no2/support/exchange/NitriteJsonExporter.java index 04cfd0e35..45f3bc077 100644 --- a/nitrite-support/src/main/java/org/dizitart/no2/support/exchange/NitriteJsonExporter.java +++ b/nitrite-support/src/main/java/org/dizitart/no2/support/exchange/NitriteJsonExporter.java @@ -14,9 +14,18 @@ * limitations under the License. */ - package org.dizitart.no2.support.exchange; - -import com.fasterxml.jackson.core.JsonGenerator; +package org.dizitart.no2.support.exchange; + +import static org.dizitart.no2.common.Constants.TAG_COLLECTIONS; +import static org.dizitart.no2.common.Constants.TAG_DATA; +import static org.dizitart.no2.common.Constants.TAG_INDEX; +import static org.dizitart.no2.common.Constants.TAG_INDICES; +import static org.dizitart.no2.common.Constants.TAG_KEY; +import static org.dizitart.no2.common.Constants.TAG_KEYED_REPOSITORIES; +import static org.dizitart.no2.common.Constants.TAG_NAME; +import static org.dizitart.no2.common.Constants.TAG_REPOSITORIES; +import static org.dizitart.no2.common.Constants.TAG_VALUE; +import static org.dizitart.no2.common.util.ObjectUtils.findRepositoryName; import lombok.Setter; import org.apache.commons.codec.binary.Base64; import org.dizitart.no2.Nitrite; @@ -28,178 +37,182 @@ import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.store.NitriteMap; import org.dizitart.no2.store.NitriteStore; +import tools.jackson.core.JsonGenerator; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; -import static org.dizitart.no2.common.Constants.*; -import static org.dizitart.no2.common.util.ObjectUtils.findRepositoryName; - - /** - * @author Anindya Chatterjee - */ - @Setter - class NitriteJsonExporter { - private JsonGenerator generator; - private ExportOptions options; - - public void exportData() throws IOException, ClassNotFoundException { - try(Nitrite db = options.getNitriteFactory().create()) { - Set collectionNames = options.getCollections() == null ? db.listCollectionNames() : new HashSet<>(); - Set repositoryNames = options.getRepositories() == null ? db.listRepositories() : new HashSet<>(); - Map> keyedRepositoryNames = options.getKeyedRepositories() == null - ? db.listKeyedRepositories() : new HashMap<>(); - - List indexDescriptors = new ArrayList<>(); - if (options.getCollections() != null && !options.getCollections().isEmpty()) { - collectionNames = new HashSet<>(options.getCollections()); - } - - if (options.getRepositories() != null && !options.getRepositories().isEmpty()) { - repositoryNames = new HashSet<>(options.getRepositories()); - } - - if (options.getKeyedRepositories() != null && !options.getKeyedRepositories().isEmpty()) { - keyedRepositoryNames = options.getKeyedRepositories(); - } - - if (options.isExportIndices()) { - for (String collectionName : collectionNames) { - try(IndexManager indexManager = new IndexManager(collectionName, db.getConfig())) { - indexDescriptors.addAll(indexManager.getIndexDescriptors()); - } - } - - for (String repositoryName : repositoryNames) { - try(IndexManager indexManager = new IndexManager(repositoryName, db.getConfig())) { - indexDescriptors.addAll(indexManager.getIndexDescriptors()); - } - } - - for (Map.Entry> entry : keyedRepositoryNames.entrySet()) { - String key = entry.getKey(); - Set entityNameSet = entry.getValue(); - for (String entityName : entityNameSet) { - String repositoryName = findRepositoryName(key, entityName); - try(IndexManager indexManager = new IndexManager(repositoryName, db.getConfig())) { - indexDescriptors.addAll(indexManager.getIndexDescriptors()); - } - } - } - } - - exportData(db, collectionNames, repositoryNames, keyedRepositoryNames, indexDescriptors); - generator.close(); - } - } - - private void exportData(Nitrite db, - Set collectionNames, - Set repositoryNames, - Map> keyedRepositoryNames, - List indexDescriptors) throws IOException { - NitriteStore nitriteStore = db.getStore(); - - generator.writeStartObject(); - - writeMaps(collectionNames, indexDescriptors, nitriteStore, TAG_COLLECTIONS); - - writeMaps(repositoryNames, indexDescriptors, nitriteStore, TAG_REPOSITORIES); - - writeKeyedMaps(keyedRepositoryNames, indexDescriptors, nitriteStore); - - generator.writeEndObject(); - } - - private void writeMaps(Set mapNames, List indexDescriptors, - NitriteStore nitriteStore, String tagName) throws IOException { - generator.writeFieldName(tagName); - generator.writeStartArray(); - for (String mapName : mapNames) { - try(NitriteMap nitriteMap - = nitriteStore.openMap(mapName, NitriteId.class, Document.class)) { - List indexes = indexDescriptors.stream().filter(d -> - mapName.equalsIgnoreCase(d.getCollectionName())).collect(Collectors.toList()); - writeNitriteMap(nitriteMap, indexes); - } - } - generator.writeEndArray(); - } - - private void writeKeyedMaps(Map> keyedMapNames, List indexDescriptors, - NitriteStore nitriteStore) throws IOException { - generator.writeFieldName(TAG_KEYED_REPOSITORIES); - generator.writeStartArray(); - for (Map.Entry> entry : keyedMapNames.entrySet()) { - String key = entry.getKey(); - Set typeNames = entry.getValue(); - for (String typeName : typeNames) { - String repoName = findRepositoryName(typeName, key); - try(NitriteMap nitriteMap +/** + * @author Anindya Chatterjee + */ +@Setter +class NitriteJsonExporter { + private JsonGenerator generator; + private ExportOptions options; + + public void exportData() throws IOException, ClassNotFoundException { + try (Nitrite db = options.getNitriteFactory().create()) { + Set collectionNames = options.getCollections() == null ? db.listCollectionNames() : new HashSet<>(); + Set repositoryNames = options.getRepositories() == null ? db.listRepositories() : new HashSet<>(); + Map> keyedRepositoryNames = options.getKeyedRepositories() == null + ? db.listKeyedRepositories() : new HashMap<>(); + + List indexDescriptors = new ArrayList<>(); + if (options.getCollections() != null && !options.getCollections().isEmpty()) { + collectionNames = new HashSet<>(options.getCollections()); + } + + if (options.getRepositories() != null && !options.getRepositories().isEmpty()) { + repositoryNames = new HashSet<>(options.getRepositories()); + } + + if (options.getKeyedRepositories() != null && !options.getKeyedRepositories().isEmpty()) { + keyedRepositoryNames = options.getKeyedRepositories(); + } + + if (options.isExportIndices()) { + for (String collectionName : collectionNames) { + try (IndexManager indexManager = new IndexManager(collectionName, db.getConfig())) { + indexDescriptors.addAll(indexManager.getIndexDescriptors()); + } + } + + for (String repositoryName : repositoryNames) { + try (IndexManager indexManager = new IndexManager(repositoryName, db.getConfig())) { + indexDescriptors.addAll(indexManager.getIndexDescriptors()); + } + } + + for (Map.Entry> entry : keyedRepositoryNames.entrySet()) { + String key = entry.getKey(); + Set entityNameSet = entry.getValue(); + for (String entityName : entityNameSet) { + String repositoryName = findRepositoryName(key, entityName); + try (IndexManager indexManager = new IndexManager(repositoryName, db.getConfig())) { + indexDescriptors.addAll(indexManager.getIndexDescriptors()); + } + } + } + } + + exportData(db, collectionNames, repositoryNames, keyedRepositoryNames, indexDescriptors); + generator.close(); + } + } + + private void exportData(Nitrite db, + Set collectionNames, + Set repositoryNames, + Map> keyedRepositoryNames, + List indexDescriptors) throws IOException { + NitriteStore nitriteStore = db.getStore(); + + generator.writeStartObject(); + + writeMaps(collectionNames, indexDescriptors, nitriteStore, TAG_COLLECTIONS); + + writeMaps(repositoryNames, indexDescriptors, nitriteStore, TAG_REPOSITORIES); + + writeKeyedMaps(keyedRepositoryNames, indexDescriptors, nitriteStore); + + generator.writeEndObject(); + } + + private void writeMaps(Set mapNames, List indexDescriptors, + NitriteStore nitriteStore, String tagName) throws IOException { + generator.writeName(tagName); + generator.writeStartArray(); + for (String mapName : mapNames) { + try (NitriteMap nitriteMap + = nitriteStore.openMap(mapName, NitriteId.class, Document.class)) { + List indexes = indexDescriptors.stream().filter(d -> + mapName.equalsIgnoreCase(d.getCollectionName())).collect(Collectors.toList()); + writeNitriteMap(nitriteMap, indexes); + } + } + generator.writeEndArray(); + } + + private void writeKeyedMaps(Map> keyedMapNames, List indexDescriptors, + NitriteStore nitriteStore) throws IOException { + generator.writeName(TAG_KEYED_REPOSITORIES); + generator.writeStartArray(); + for (Map.Entry> entry : keyedMapNames.entrySet()) { + String key = entry.getKey(); + Set typeNames = entry.getValue(); + for (String typeName : typeNames) { + String repoName = findRepositoryName(typeName, key); + try (NitriteMap nitriteMap = nitriteStore.openMap(repoName, NitriteId.class, Document.class)) { - List indexes = indexDescriptors.stream().filter(d -> - repoName.equalsIgnoreCase(d.getCollectionName())).collect(Collectors.toList()); - writeNitriteMap(nitriteMap, indexes); - } - } - } - generator.writeEndArray(); - } - - private void writeNitriteMap(NitriteMap nitriteMap, - List indexes) throws IOException { - generator.writeStartObject(); - generator.writeFieldName(TAG_NAME); - generator.writeString(nitriteMap.getName()); - writeIndices(indexes); - writeContent(nitriteMap); - generator.writeEndObject(); - } - - private void writeIndices(Collection indices) throws IOException { - generator.writeFieldName(TAG_INDICES); - generator.writeStartArray(); - if (options.isExportIndices()) { - for (IndexDescriptor index : indices) { - generator.writeStartObject(); - generator.writeFieldName(TAG_INDEX); - generator.writeObject(writeEncodedObject(index)); - generator.writeEndObject(); - } - } - generator.writeEndArray(); - } - - private void writeContent(NitriteMap nitriteMap) throws IOException { - generator.writeFieldName(TAG_DATA); - generator.writeStartArray(); - if (options.isExportData()) { - for (Pair entry : nitriteMap.entries()) { - generator.writeStartObject(); - generator.writeFieldName(TAG_KEY); - generator.writeObject(writeEncodedObject(entry.getFirst())); - - generator.writeFieldName(TAG_VALUE); - generator.writeObject(writeEncodedObject(entry.getSecond())); - generator.writeEndObject(); - } - } - generator.writeEndArray(); - } - - private String writeEncodedObject(Object object) { - try (ByteArrayOutputStream os = new ByteArrayOutputStream()) { - try (ObjectOutputStream oos = new ObjectOutputStream(os)) { - oos.writeObject(object); - byte[] data = os.toByteArray(); - return Base64.encodeBase64URLSafeString(data); - } - } catch (IOException e) { - throw new NitriteIOException("Failed to write object", e); - } - } - } + List indexes = indexDescriptors.stream().filter(d -> + repoName.equalsIgnoreCase(d.getCollectionName())).collect(Collectors.toList()); + writeNitriteMap(nitriteMap, indexes); + } + } + } + generator.writeEndArray(); + } + + private void writeNitriteMap(NitriteMap nitriteMap, + List indexes) throws IOException { + generator.writeStartObject(); + generator.writeName(TAG_NAME); + generator.writeString(nitriteMap.getName()); + writeIndices(indexes); + writeContent(nitriteMap); + generator.writeEndObject(); + } + + private void writeIndices(Collection indices) throws IOException { + generator.writeName(TAG_INDICES); + generator.writeStartArray(); + if (options.isExportIndices()) { + for (IndexDescriptor index : indices) { + generator.writeStartObject(); + generator.writeName(TAG_INDEX); + generator.writeString(writeEncodedObject(index)); + generator.writeEndObject(); + } + } + generator.writeEndArray(); + } + + private void writeContent(NitriteMap nitriteMap) throws IOException { + generator.writeName(TAG_DATA); + generator.writeStartArray(); + if (options.isExportData()) { + for (Pair entry : nitriteMap.entries()) { + generator.writeStartObject(); + generator.writeName(TAG_KEY); + generator.writeString(writeEncodedObject(entry.getFirst())); + + generator.writeName(TAG_VALUE); + generator.writeString(writeEncodedObject(entry.getSecond())); + generator.writeEndObject(); + } + } + generator.writeEndArray(); + } + + private String writeEncodedObject(Object object) { + try (ByteArrayOutputStream os = new ByteArrayOutputStream()) { + try (ObjectOutputStream oos = new ObjectOutputStream(os)) { + oos.writeObject(object); + byte[] data = os.toByteArray(); + return Base64.encodeBase64URLSafeString(data); + } + } catch (IOException e) { + throw new NitriteIOException("Failed to write object", e); + } + } +} \ No newline at end of file diff --git a/nitrite-support/src/main/java/org/dizitart/no2/support/exchange/NitriteJsonImporter.java b/nitrite-support/src/main/java/org/dizitart/no2/support/exchange/NitriteJsonImporter.java index 32bc275d5..ddcb15561 100644 --- a/nitrite-support/src/main/java/org/dizitart/no2/support/exchange/NitriteJsonImporter.java +++ b/nitrite-support/src/main/java/org/dizitart/no2/support/exchange/NitriteJsonImporter.java @@ -16,8 +16,15 @@ package org.dizitart.no2.support.exchange; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; +import static org.dizitart.no2.common.Constants.TAG_COLLECTIONS; +import static org.dizitart.no2.common.Constants.TAG_DATA; +import static org.dizitart.no2.common.Constants.TAG_INDEX; +import static org.dizitart.no2.common.Constants.TAG_INDICES; +import static org.dizitart.no2.common.Constants.TAG_KEY; +import static org.dizitart.no2.common.Constants.TAG_KEYED_REPOSITORIES; +import static org.dizitart.no2.common.Constants.TAG_NAME; +import static org.dizitart.no2.common.Constants.TAG_REPOSITORIES; +import static org.dizitart.no2.common.Constants.TAG_VALUE; import lombok.Setter; import org.apache.commons.codec.binary.Base64; import org.dizitart.no2.Nitrite; @@ -28,15 +35,14 @@ import org.dizitart.no2.index.IndexDescriptor; import org.dizitart.no2.store.NitriteMap; import org.dizitart.no2.store.NitriteStore; +import tools.jackson.core.JsonParser; +import tools.jackson.core.JsonToken; import java.io.ByteArrayInputStream; -import java.io.IOException; import java.io.ObjectInputStream; import java.util.ArrayList; import java.util.List; -import static org.dizitart.no2.common.Constants.*; - /** * @author Anindya Chatterjee. */ @@ -45,10 +51,10 @@ class NitriteJsonImporter { private JsonParser parser; private ImportOptions options; - public void importData() throws IOException, ClassNotFoundException { + public void importData() throws ClassNotFoundException { try (Nitrite db = options.getNitriteFactory().create()) { while (parser.nextToken() != JsonToken.END_OBJECT) { - String fieldName = parser.getCurrentName(); + String fieldName = parser.currentName(); if (TAG_COLLECTIONS.equals(fieldName)) { readNitriteMap(db); @@ -65,7 +71,7 @@ public void importData() throws IOException, ClassNotFoundException { } } - private void readNitriteMap(Nitrite db) throws IOException { + private void readNitriteMap(Nitrite db) { // move to [ parser.nextToken(); NitriteStore nitriteStore = db.getStore(); @@ -77,13 +83,13 @@ private void readNitriteMap(Nitrite db) throws IOException { List indexDescriptors = new ArrayList<>(); while (parser.nextToken() != JsonToken.END_OBJECT) { - String fieldName = parser.getCurrentName(); + String fieldName = parser.currentName(); if (TAG_NAME.equals(fieldName)) { // move to next token parser.nextToken(); - String mapName = parser.getText(); + String mapName = parser.getString(); nitriteMap = nitriteStore.openMap(mapName, NitriteId.class, Document.class); } @@ -104,7 +110,7 @@ private void readNitriteMap(Nitrite db) throws IOException { } } - private List readIndices() throws IOException { + private List readIndices() { List indexDescriptors = new ArrayList<>(); // move to [ parser.nextToken(); @@ -113,7 +119,7 @@ private List readIndices() throws IOException { while (parser.nextToken() != JsonToken.END_ARRAY) { // loop until end of collection object while (parser.nextToken() != JsonToken.END_OBJECT) { - String fieldName = parser.getCurrentName(); + String fieldName = parser.currentName(); if (TAG_INDEX.equals(fieldName)) { parser.nextToken(); @@ -126,7 +132,7 @@ private List readIndices() throws IOException { return indexDescriptors; } - private void readNitriteMapData(NitriteMap nitriteMap) throws IOException { + private void readNitriteMapData(NitriteMap nitriteMap) { // move to [ parser.nextToken(); @@ -135,7 +141,7 @@ private void readNitriteMapData(NitriteMap nitriteMap) thro // loop until end of collection object NitriteId nitriteId = null; while (parser.nextToken() != JsonToken.END_OBJECT) { - String fieldName = parser.getCurrentName(); + String fieldName = parser.currentName(); if (TAG_KEY.equals(fieldName)) { parser.nextToken(); diff --git a/nitrite-support/src/test/java/org/dizitart/no2/support/TestUtil.java b/nitrite-support/src/test/java/org/dizitart/no2/support/TestUtil.java index 2aa2d3050..c2e2edb44 100644 --- a/nitrite-support/src/test/java/org/dizitart/no2/support/TestUtil.java +++ b/nitrite-support/src/test/java/org/dizitart/no2/support/TestUtil.java @@ -17,24 +17,29 @@ package org.dizitart.no2.support; +import static org.junit.Assert.assertTrue; import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; import org.dizitart.no2.exceptions.ObjectMappingException; import org.dizitart.no2.mvstore.MVStoreModule; +import tools.jackson.core.exc.JacksonIOException; +import tools.jackson.core.json.JsonReadFeature; +import tools.jackson.databind.DeserializationFeature; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; import java.io.File; -import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; -import java.util.*; - -import static org.junit.Assert.assertTrue; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.stream.Collectors; /** * @author Anindya Chatterjee @@ -130,7 +135,7 @@ public static Document parse(String json) { ObjectMapper objectMapper = createObjectMapper(); JsonNode node = objectMapper.readValue(json, JsonNode.class); return loadDocument(node); - } catch (IOException e) { + } catch (JacksonIOException e) { log.error("Error while parsing json", e); throw new ObjectMappingException("failed to parse json " + json); } @@ -138,9 +143,7 @@ public static Document parse(String json) { private static Document loadDocument(JsonNode node) { Map objectMap = new LinkedHashMap<>(); - Iterator> fields = node.fields(); - while (fields.hasNext()) { - Map.Entry entry = fields.next(); + for (Map.Entry entry : node.properties()) { String name = entry.getKey(); JsonNode value = entry.getValue(); Object object = loadObject(value); @@ -151,64 +154,52 @@ private static Document loadDocument(JsonNode node) { } private static Object loadObject(JsonNode node) { - if (node == null) - return null; - try { - switch (node.getNodeType()) { - case ARRAY: - return loadArray(node); - case BINARY: - return node.binaryValue(); - case BOOLEAN: - return node.booleanValue(); - case MISSING: - case NULL: - return null; - case NUMBER: - return node.numberValue(); - case OBJECT: - case POJO: - return loadDocument(node); - case STRING: - return node.textValue(); - } - } catch (IOException e) { + if (node == null) { return null; } - return null; + + switch (node.getNodeType()) { + case ARRAY: + return loadArray(node); + case BINARY: + return node.binaryValue(); + case BOOLEAN: + return node.booleanValue(); + case MISSING: + case NUMBER: + return node.numberValue(); + case OBJECT: + case POJO: + return loadDocument(node); + case STRING: + return node.stringValue(); + default: + return null; + } } - @SuppressWarnings({"unchecked", "rawtypes"}) - private static List loadArray(JsonNode array) { + private static List loadArray(JsonNode array) { if (array.isArray()) { - List list = new ArrayList(); - Iterator iterator = array.elements(); - while (iterator.hasNext()) { - Object element = iterator.next(); - if (element instanceof JsonNode) { - list.add(loadObject((JsonNode) element)); - } else { - list.add(element); - } - } - return list; + return array.valueStream() + .map(TestUtil::loadObject) + .collect(Collectors.toList()); } return null; } private static ObjectMapper createObjectMapper() { - ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.setVisibility( - objectMapper.getSerializationConfig().getDefaultVisibilityChecker() + return JsonMapper.builder() + .changeDefaultVisibility(visibilityChecker -> visibilityChecker .withFieldVisibility(JsonAutoDetect.Visibility.ANY) .withGetterVisibility(JsonAutoDetect.Visibility.NONE) - .withIsGetterVisibility(JsonAutoDetect.Visibility.NONE)); - objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); - objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); - objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true); - objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - - objectMapper.findAndRegisterModules(); - return objectMapper; + .withIsGetterVisibility(JsonAutoDetect.Visibility.NONE) + ) + .configure(JsonReadFeature.ALLOW_UNQUOTED_PROPERTY_NAMES, true) + .configure(JsonReadFeature.ALLOW_SINGLE_QUOTES, true) + .configure(JsonReadFeature.ALLOW_JAVA_COMMENTS, true) + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .configure(DeserializationFeature.FAIL_ON_TRAILING_TOKENS, false) + .findAndAddModules() + .build(); } } diff --git a/nitrite-support/src/test/java/org/dizitart/no2/support/exchange/ExporterTest.java b/nitrite-support/src/test/java/org/dizitart/no2/support/exchange/ExporterTest.java index 1d1dee735..5d07d972f 100644 --- a/nitrite-support/src/test/java/org/dizitart/no2/support/exchange/ExporterTest.java +++ b/nitrite-support/src/test/java/org/dizitart/no2/support/exchange/ExporterTest.java @@ -1,15 +1,14 @@ package org.dizitart.no2.support.exchange; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.Test; - import static org.junit.Assert.assertNotNull; +import org.junit.Test; +import tools.jackson.databind.json.JsonMapper; public class ExporterTest { @Test public void testCreateObjectMapper() { - ObjectMapper actualCreateObjectMapperResult = Exporter.createObjectMapper(); - assertNotNull(actualCreateObjectMapperResult); + JsonMapper actualCreateJsonMapperResult = Exporter.createJsonMapper(); + assertNotNull(actualCreateJsonMapperResult); } } diff --git a/nitrite/pom.xml b/nitrite/pom.xml index c109b7390..bffe8041e 100644 --- a/nitrite/pom.xml +++ b/nitrite/pom.xml @@ -98,7 +98,7 @@ test - com.fasterxml.jackson.core + tools.jackson.core jackson-databind test diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/NitriteDocumentTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/NitriteDocumentTest.java index f0b49379d..0faf37cff 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/NitriteDocumentTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/collection/NitriteDocumentTest.java @@ -1,6 +1,6 @@ package org.dizitart.no2.collection; -import com.fasterxml.jackson.databind.introspect.AnnotatedMethodMap; +import tools.jackson.databind.introspect.AnnotatedMethodMap; import org.dizitart.no2.exceptions.InvalidIdException; import org.dizitart.no2.exceptions.InvalidOperationException; import org.dizitart.no2.exceptions.ValidationException; diff --git a/nitrite/src/test/java/org/dizitart/no2/common/streams/FilteredStreamTest.java b/nitrite/src/test/java/org/dizitart/no2/common/streams/FilteredStreamTest.java index e61dbba61..5ce75181d 100644 --- a/nitrite/src/test/java/org/dizitart/no2/common/streams/FilteredStreamTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/common/streams/FilteredStreamTest.java @@ -17,7 +17,7 @@ package org.dizitart.no2.common.streams; -import com.fasterxml.jackson.databind.util.ArrayIterator; +import tools.jackson.databind.util.ArrayIterator; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; import org.dizitart.no2.common.RecordStream; diff --git a/nitrite/src/test/java/org/dizitart/no2/common/streams/ProjectedDocumentStreamTest.java b/nitrite/src/test/java/org/dizitart/no2/common/streams/ProjectedDocumentStreamTest.java index 2e0cea9ab..219c9d120 100644 --- a/nitrite/src/test/java/org/dizitart/no2/common/streams/ProjectedDocumentStreamTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/common/streams/ProjectedDocumentStreamTest.java @@ -17,7 +17,7 @@ package org.dizitart.no2.common.streams; -import com.fasterxml.jackson.databind.util.ArrayIterator; +import tools.jackson.databind.util.ArrayIterator; import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; diff --git a/nitrite/src/test/java/org/dizitart/no2/common/streams/SortedDocumentStreamTest.java b/nitrite/src/test/java/org/dizitart/no2/common/streams/SortedDocumentStreamTest.java index 0dbc085ae..2de85b730 100644 --- a/nitrite/src/test/java/org/dizitart/no2/common/streams/SortedDocumentStreamTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/common/streams/SortedDocumentStreamTest.java @@ -17,7 +17,7 @@ package org.dizitart.no2.common.streams; -import com.fasterxml.jackson.databind.util.ArrayIterator; +import tools.jackson.databind.util.ArrayIterator; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.FindPlan; import org.dizitart.no2.collection.NitriteId; diff --git a/nitrite/src/test/java/org/dizitart/no2/common/util/ComparablesTest.java b/nitrite/src/test/java/org/dizitart/no2/common/util/ComparablesTest.java index 7284d1a54..62cab10c7 100644 --- a/nitrite/src/test/java/org/dizitart/no2/common/util/ComparablesTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/common/util/ComparablesTest.java @@ -1,11 +1,10 @@ package org.dizitart.no2.common.util; -import com.fasterxml.jackson.databind.type.ClassKey; +import static org.junit.Assert.assertEquals; import org.apache.commons.lang3.mutable.MutableByte; import org.apache.commons.lang3.mutable.MutableDouble; import org.junit.Test; - -import static org.junit.Assert.assertEquals; +import tools.jackson.databind.type.ClassKey; public class ComparablesTest { @Test diff --git a/nitrite/src/test/java/org/dizitart/no2/common/util/ObjectUtilsTest.java b/nitrite/src/test/java/org/dizitart/no2/common/util/ObjectUtilsTest.java index 4e2b58dec..55506463f 100644 --- a/nitrite/src/test/java/org/dizitart/no2/common/util/ObjectUtilsTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/common/util/ObjectUtilsTest.java @@ -16,7 +16,7 @@ package org.dizitart.no2.common.util; -import com.fasterxml.jackson.databind.introspect.AnnotatedMethodMap; +import tools.jackson.databind.introspect.AnnotatedMethodMap; import junit.framework.JUnit4TestAdapterCache; import lombok.Data; import org.apache.commons.lang3.mutable.MutableByte; diff --git a/nitrite/src/test/java/org/dizitart/no2/integration/TestUtil.java b/nitrite/src/test/java/org/dizitart/no2/integration/TestUtil.java index 39e5a39d1..5251647bc 100644 --- a/nitrite/src/test/java/org/dizitart/no2/integration/TestUtil.java +++ b/nitrite/src/test/java/org/dizitart/no2/integration/TestUtil.java @@ -18,17 +18,22 @@ package org.dizitart.no2.integration; import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; import org.dizitart.no2.exceptions.ObjectMappingException; +import tools.jackson.core.exc.JacksonIOException; +import tools.jackson.core.json.JsonReadFeature; +import tools.jackson.databind.DeserializationFeature; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; -import java.io.IOException; -import java.util.*; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; /** * @author Anindya Chatterjee @@ -39,9 +44,10 @@ public class TestUtil { /** * Determines whether the supplied `iterable` is sorted. * - * @param the type parameter - * @param iterable the iterable + * @param the type parameter + * @param iterable the iterable * @param ascending a boolean value indicating whether to sort in ascending order + * * @return the boolean value indicating if `iterable` is sorted or not. */ public static > boolean isSorted(Iterable iterable, boolean ascending) { @@ -83,7 +89,7 @@ public static Document parse(String json) { ObjectMapper objectMapper = createObjectMapper(); JsonNode node = objectMapper.readValue(json, JsonNode.class); return loadDocument(node); - } catch (IOException e) { + } catch (JacksonIOException e) { log.error("Error while parsing json", e); throw new ObjectMappingException("Failed to parse json " + json); } @@ -91,9 +97,7 @@ public static Document parse(String json) { private static Document loadDocument(JsonNode node) { Map objectMap = new LinkedHashMap<>(); - Iterator> fields = node.fields(); - while (fields.hasNext()) { - Map.Entry entry = fields.next(); + for (Map.Entry entry : node.properties()) { String name = entry.getKey(); JsonNode value = entry.getValue(); Object object = loadObject(value); @@ -104,65 +108,53 @@ private static Document loadDocument(JsonNode node) { } private static Object loadObject(JsonNode node) { - if (node == null) - return null; - try { - switch (node.getNodeType()) { - case ARRAY: - return loadArray(node); - case BINARY: - return node.binaryValue(); - case BOOLEAN: - return node.booleanValue(); - case MISSING: - case NULL: - return null; - case NUMBER: - return node.numberValue(); - case OBJECT: - case POJO: - return loadDocument(node); - case STRING: - return node.textValue(); - } - } catch (IOException e) { + if (node == null) { return null; } - return null; + + switch (node.getNodeType()) { + case ARRAY: + return loadArray(node); + case BINARY: + return node.binaryValue(); + case BOOLEAN: + return node.booleanValue(); + case MISSING: + case NUMBER: + return node.numberValue(); + case OBJECT: + case POJO: + return loadDocument(node); + case STRING: + return node.stringValue(); + default: + return null; + } } - @SuppressWarnings({"unchecked", "rawtypes"}) - private static List loadArray(JsonNode array) { + private static List loadArray(JsonNode array) { if (array.isArray()) { - List list = new ArrayList(); - Iterator iterator = array.elements(); - while (iterator.hasNext()) { - Object element = iterator.next(); - if (element instanceof JsonNode) { - list.add(loadObject((JsonNode) element)); - } else { - list.add(element); - } - } - return list; + return array.valueStream() + .map(TestUtil::loadObject) + .collect(Collectors.toList()); } return null; } private static ObjectMapper createObjectMapper() { - ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.setVisibility( - objectMapper.getSerializationConfig().getDefaultVisibilityChecker() + return JsonMapper.builder() + .changeDefaultVisibility(visibilityChecker -> visibilityChecker .withFieldVisibility(JsonAutoDetect.Visibility.ANY) .withGetterVisibility(JsonAutoDetect.Visibility.NONE) - .withIsGetterVisibility(JsonAutoDetect.Visibility.NONE)); - objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); - objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); - objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true); - objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - - objectMapper.findAndRegisterModules(); - return objectMapper; + .withIsGetterVisibility(JsonAutoDetect.Visibility.NONE) + ) + .configure(JsonReadFeature.ALLOW_UNQUOTED_PROPERTY_NAMES, true) + .configure(JsonReadFeature.ALLOW_SINGLE_QUOTES, true) + .configure(JsonReadFeature.ALLOW_JAVA_COMMENTS, true) + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .configure(DeserializationFeature.FAIL_ON_TRAILING_TOKENS, false) + .findAndAddModules() + .build(); } } diff --git a/nitrite/src/test/java/org/dizitart/no2/repository/ObjectCursorTest.java b/nitrite/src/test/java/org/dizitart/no2/repository/ObjectCursorTest.java index 64d0370c8..792e91d94 100644 --- a/nitrite/src/test/java/org/dizitart/no2/repository/ObjectCursorTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/repository/ObjectCursorTest.java @@ -17,7 +17,7 @@ package org.dizitart.no2.repository; -import com.fasterxml.jackson.databind.util.ArrayIterator; +import tools.jackson.databind.util.ArrayIterator; import org.dizitart.no2.NitriteBuilderTest; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.NitriteId; diff --git a/pom.xml b/pom.xml index c4f22ac4d..39c44277d 100644 --- a/pom.xml +++ b/pom.xml @@ -52,7 +52,7 @@ 11 11 UTF-8 - 2.21.2 + 3.1.0 2.0.17 1.9.3 2.4.240 @@ -98,22 +98,12 @@ - com.fasterxml.jackson.core + tools.jackson.core jackson-databind ${jackson.version} - com.fasterxml.jackson.datatype - jackson-datatype-jsr310 - ${jackson.version} - - - com.fasterxml.jackson.datatype - jackson-datatype-jdk8 - ${jackson.version} - - - com.fasterxml.jackson.module + tools.jackson.module jackson-module-kotlin ${jackson.version} @@ -367,9 +357,6 @@ org.apache.maven.plugins maven-surefire-plugin ${surefire.version} - - @{argLine} -Duser.language=en -Duser.region=US - org.jacoco diff --git a/potassium-nitrite/pom.xml b/potassium-nitrite/pom.xml index 80d5f6455..7e5a0b70e 100644 --- a/potassium-nitrite/pom.xml +++ b/potassium-nitrite/pom.xml @@ -47,21 +47,13 @@ ${project.version} - com.fasterxml.jackson.core + tools.jackson.core jackson-databind - com.fasterxml.jackson.module + tools.jackson.module jackson-module-kotlin - - com.fasterxml.jackson.datatype - jackson-datatype-jdk8 - - - com.fasterxml.jackson.datatype - jackson-datatype-jsr310 - org.jetbrains.kotlin kotlin-stdlib diff --git a/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/KNO2JacksonMapper.kt b/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/KNO2JacksonMapper.kt index 93a297d8b..54a196fed 100644 --- a/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/KNO2JacksonMapper.kt +++ b/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/KNO2JacksonMapper.kt @@ -16,14 +16,10 @@ package org.dizitart.kno2 -import com.fasterxml.jackson.databind.Module -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.databind.SerializationFeature -import com.fasterxml.jackson.datatype.jdk8.Jdk8Module -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule -import com.fasterxml.jackson.module.kotlin.KotlinModule import org.dizitart.no2.mapper.jackson.JacksonMapper import org.dizitart.no2.spatial.jackson.GeometryModule +import tools.jackson.databind.JacksonModule +import tools.jackson.module.kotlin.KotlinModule /** * A custom Jackson mapper for Potassium Nitrite (KNO2) library that extends [JacksonMapper] class. @@ -33,21 +29,14 @@ import org.dizitart.no2.spatial.jackson.GeometryModule * @author Stefan Mandel * @since 2.1.0 */ -open class KNO2JacksonMapper(private vararg val modules: Module) : JacksonMapper() { +open class KNO2JacksonMapper(private vararg val modules: JacksonModule) : JacksonMapper() { - override fun getObjectMapper(): ObjectMapper { - val objectMapper = super.getObjectMapper() - objectMapper.registerModule(KotlinModule.Builder().build()) - objectMapper.registerModule(Jdk8Module()) - objectMapper.registerModule(JavaTimeModule()) - objectMapper.registerModule(GeometryModule()) + init { + registerJacksonModule(KotlinModule.Builder().build()) + registerJacksonModule(GeometryModule()) for (module in modules) { - objectMapper.registerModule(module) + registerJacksonModule(module) } - - objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) - - return objectMapper } } diff --git a/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/KNO2Module.kt b/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/KNO2Module.kt index 5beb5dd32..86d300f15 100644 --- a/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/KNO2Module.kt +++ b/potassium-nitrite/src/main/kotlin/org/dizitart/kno2/KNO2Module.kt @@ -16,11 +16,11 @@ package org.dizitart.kno2 -import com.fasterxml.jackson.databind.Module -import org.dizitart.no2.common.util.Iterables.setOf import org.dizitart.no2.common.module.NitriteModule import org.dizitart.no2.common.module.NitritePlugin +import org.dizitart.no2.common.util.Iterables.setOf import org.dizitart.no2.spatial.SpatialIndexer +import tools.jackson.databind.JacksonModule /** * A module for Nitrite database that allows registering additional extensions. @@ -29,7 +29,7 @@ import org.dizitart.no2.spatial.SpatialIndexer * @since 4.0 * @author Anindya Chatterjee */ -open class KNO2Module(private vararg val extensions: Module) : NitriteModule { +open class KNO2Module(private vararg val extensions: JacksonModule) : NitriteModule { override fun plugins(): MutableSet { return setOf(KNO2JacksonMapper(*extensions), SpatialIndexer()) diff --git a/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/BackportJavaTimeTest.kt b/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/BackportJavaTimeTest.kt index e5dfafdf5..1e678f81f 100644 --- a/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/BackportJavaTimeTest.kt +++ b/potassium-nitrite/src/test/kotlin/org/dizitart/kno2/BackportJavaTimeTest.kt @@ -16,10 +16,10 @@ package org.dizitart.kno2 -import com.fasterxml.jackson.core.JsonGenerator -import com.fasterxml.jackson.core.JsonParser -import com.fasterxml.jackson.databind.* -import com.fasterxml.jackson.databind.module.SimpleModule +import tools.jackson.core.JsonGenerator +import tools.jackson.core.JsonParser +import tools.jackson.databind.* +import tools.jackson.databind.module.SimpleModule import lombok.extern.slf4j.Slf4j import org.dizitart.no2.index.IndexType import org.dizitart.no2.repository.annotations.Id @@ -29,6 +29,8 @@ import org.junit.Test import org.slf4j.LoggerFactory import org.threeten.bp.LocalDateTime import org.threeten.bp.ZoneOffset +import tools.jackson.databind.deser.std.StdDeserializer +import tools.jackson.databind.ser.std.StdSerializer import java.nio.file.Files import java.nio.file.Paths import java.util.* @@ -49,7 +51,7 @@ class BackportJavaTimeTest { class ThreeTenAbpModule : SimpleModule() { override fun setupModule(context: SetupContext?) { - addDeserializer(LocalDateTime::class.java, object : JsonDeserializer() { + addDeserializer(LocalDateTime::class.java, object : StdDeserializer(LocalDateTime::class.java) { override fun deserialize(p: JsonParser?, ctxt: DeserializationContext?): LocalDateTime? { val timeStamp = p?.longValue return if (timeStamp == -1L || timeStamp == null) null else { @@ -58,8 +60,8 @@ class BackportJavaTimeTest { } }) - addSerializer(LocalDateTime::class.java, object : JsonSerializer() { - override fun serialize(value: LocalDateTime?, gen: JsonGenerator?, serializers: SerializerProvider?) { + addSerializer(LocalDateTime::class.java, object : StdSerializer(LocalDateTime::class.java) { + override fun serialize(value: LocalDateTime?, gen: JsonGenerator?, ctxt: SerializationContext?) { if (value == null) { gen?.writeNull() } else {